1148 lines
30 KiB
PHP
1148 lines
30 KiB
PHP
<?php
|
|
/**
|
|
* Creative Elements - live Theme & Page Builder
|
|
*
|
|
* @author WebshopWorks, Elementor
|
|
* @copyright 2019-2023 WebshopWorks.com & Elementor.com
|
|
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
|
*/
|
|
|
|
namespace CE;
|
|
|
|
defined('_PS_VERSION_') or exit;
|
|
|
|
use CE\CoreXFilesXCSSXPost as PostCSS;
|
|
use CE\CoreXSettingsXManager as SettingsManager;
|
|
use CE\CoreXUtilsXExceptions as Exceptions;
|
|
|
|
/**
|
|
* Elementor document.
|
|
*
|
|
* An abstract class that provides the needed properties and methods to
|
|
* manage and handle documents in inheriting classes.
|
|
*
|
|
* @since 2.0.0
|
|
* @abstract
|
|
*/
|
|
abstract class CoreXBaseXDocument extends ControlsStack
|
|
{
|
|
// const TYPE_META_KEY = '_elementor_template_type';
|
|
const PAGE_META_KEY = '_elementor_page_settings';
|
|
|
|
private $main_id;
|
|
|
|
private static $properties = [];
|
|
|
|
/**
|
|
* Document post data.
|
|
*
|
|
* Holds the document post data.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @var WPPost Wrapper post data
|
|
*/
|
|
protected $post;
|
|
|
|
/**
|
|
* @since 2.1.0
|
|
* @static
|
|
*/
|
|
protected static function getEditorPanelCategories()
|
|
{
|
|
return Plugin::$instance->elements_manager->getCategories();
|
|
}
|
|
|
|
/**
|
|
* Get properties.
|
|
*
|
|
* Retrieve the document properties.
|
|
*
|
|
* @since 2.0.0
|
|
* @static
|
|
*
|
|
* @return array Document properties
|
|
*/
|
|
public static function getProperties()
|
|
{
|
|
return [
|
|
'has_elements' => true,
|
|
'is_editable' => true,
|
|
'edit_capability' => '',
|
|
'show_in_finder' => true,
|
|
// 'show_on_admin_bar' => true,
|
|
'support_kit' => false,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @since 2.1.0
|
|
* @static
|
|
*/
|
|
public static function getEditorPanelConfig()
|
|
{
|
|
return [
|
|
'title' => static::getTitle(), // JS Container title.
|
|
'widgets_settings' => [],
|
|
'elements_categories' => static::getEditorPanelCategories(),
|
|
'default_route' => 'panel/elements/categories',
|
|
'has_elements' => static::getProperty('has_elements'),
|
|
'support_kit' => static::getProperty('support_kit'),
|
|
'messages' => [
|
|
/* translators: %s: the document title. */
|
|
'publish_notification' => sprintf(__('Hurray! Your %s is live.'), static::getTitle()),
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Get element title.
|
|
*
|
|
* Retrieve the element title.
|
|
*
|
|
* @since 2.0.0
|
|
* @static
|
|
*
|
|
* @return string Element title
|
|
*/
|
|
public static function getTitle()
|
|
{
|
|
return __('Document');
|
|
}
|
|
|
|
/**
|
|
* Get property.
|
|
*
|
|
* Retrieve the document property.
|
|
*
|
|
* @since 2.0.0
|
|
* @static
|
|
*
|
|
* @param string $key The property key
|
|
*
|
|
* @return mixed The property value
|
|
*/
|
|
public static function getProperty($key)
|
|
{
|
|
$id = static::getClassFullName();
|
|
|
|
if (!isset(self::$properties[$id])) {
|
|
self::$properties[$id] = static::getProperties();
|
|
}
|
|
|
|
return self::getItems(self::$properties[$id], $key);
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
* @static
|
|
*/
|
|
public static function getClassFullName()
|
|
{
|
|
return get_called_class();
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*/
|
|
public function getUniqueName()
|
|
{
|
|
return $this->getName() . '-' . $this->post->ID;
|
|
}
|
|
|
|
/**
|
|
* @since 2.3.0
|
|
*/
|
|
public function getPostTypeTitle()
|
|
{
|
|
$post_type_object = get_post_type_object($this->post->post_type);
|
|
|
|
return $post_type_object->labels->singular_name;
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*/
|
|
public function getMainId()
|
|
{
|
|
if (!$this->main_id) {
|
|
$post_id = $this->post->ID;
|
|
|
|
$parent_post_id = wp_is_post_revision($post_id);
|
|
|
|
if ($parent_post_id) {
|
|
$post_id = $parent_post_id;
|
|
}
|
|
|
|
$this->main_id = $post_id;
|
|
}
|
|
|
|
return $this->main_id;
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*
|
|
* @param $data
|
|
*
|
|
* @return string
|
|
*
|
|
* @throws \Exception if the widget was not found
|
|
*/
|
|
public function renderElement($data)
|
|
{
|
|
// Start buffering
|
|
ob_start();
|
|
|
|
/* @var WidgetBase $widget */
|
|
$widget = Plugin::$instance->elements_manager->createElementInstance($data);
|
|
|
|
if (!$widget) {
|
|
throw new \Exception('Widget not found.');
|
|
}
|
|
|
|
$widget->renderContent();
|
|
|
|
$render_html = ob_get_clean();
|
|
|
|
return $render_html;
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*/
|
|
public function getMainPost()
|
|
{
|
|
return get_post($this->getMainId());
|
|
}
|
|
|
|
public function getContainerAttributes()
|
|
{
|
|
$id = $this->getMainId();
|
|
|
|
$attributes = [
|
|
'data-elementor-type' => $this->getName(),
|
|
'data-elementor-id' => $id,
|
|
'class' => 'elementor elementor-' . $id,
|
|
];
|
|
|
|
$version_meta = $this->getMainMeta('_elementor_version');
|
|
|
|
if (version_compare($version_meta, '2.5.0', '<')) {
|
|
$attributes['class'] .= ' elementor-bc-flex-widget';
|
|
}
|
|
|
|
if (Plugin::$instance->preview->isPreview()) {
|
|
$attributes['data-elementor-title'] = static::getTitle();
|
|
} else {
|
|
$attributes['data-elementor-settings'] = json_encode($this->getFrontendSettings());
|
|
}
|
|
|
|
return $attributes;
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*/
|
|
public function getWpPreviewUrl()
|
|
{
|
|
// $main_post_id = $this->getMainId();
|
|
$document = $this;
|
|
|
|
// Ajax request from editor.
|
|
if (!empty(${'_POST'}['initial_document_id'])) {
|
|
$document = Plugin::$instance->documents->get(${'_POST'}['initial_document_id']);
|
|
}
|
|
|
|
$url = get_preview_post_link(
|
|
$document->getMainId(),
|
|
[
|
|
// 'preview_id' => $main_post_id,
|
|
// 'preview_nonce' => wp_create_nonce('post_preview_' . $main_post_id),
|
|
'preview' => 'true',
|
|
]
|
|
);
|
|
|
|
/*
|
|
* Document "PrestaShop preview" URL.
|
|
*
|
|
* Filters the PrestaShop preview URL.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param string $url PrestaShop preview URL
|
|
* @param Document $this The document instance
|
|
*/
|
|
$url = apply_filters('elementor/document/urls/wp_preview', $url, $this);
|
|
|
|
return $url;
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*/
|
|
public function getExitToDashboardUrl()
|
|
{
|
|
$url = get_edit_post_link($this->getMainId(), 'raw');
|
|
|
|
/*
|
|
* Document "exit to dashboard" URL.
|
|
*
|
|
* Filters the "Exit To Dashboard" URL.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param string $url The exit URL
|
|
* @param Document $this The document instance
|
|
*/
|
|
$url = apply_filters('elementor/document/urls/exit_to_dashboard', $url, $this);
|
|
|
|
return $url;
|
|
}
|
|
|
|
/**
|
|
* Get auto-saved post revision.
|
|
*
|
|
* Retrieve the auto-saved post revision that is newer than current post.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @return bool|Document
|
|
*/
|
|
public function getNewerAutosave()
|
|
{
|
|
$autosave = $this->getAutosave();
|
|
|
|
// Detect if there exists an autosave newer than the post.
|
|
if ($autosave && strtotime($autosave->getPost()->post_modified) > strtotime($this->post->post_modified)) {
|
|
return $autosave;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*/
|
|
public function isAutosave()
|
|
{
|
|
return wp_is_post_autosave($this->post->ID);
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*
|
|
* @param int $user_id
|
|
* @param bool $create
|
|
*
|
|
* @return bool|Document
|
|
*/
|
|
public function getAutosave($user_id = 0, $create = false)
|
|
{
|
|
if (!$user_id) {
|
|
$user_id = get_current_user_id();
|
|
}
|
|
|
|
$autosave_id = $this->getAutosaveId($user_id);
|
|
|
|
if ($autosave_id) {
|
|
$document = Plugin::$instance->documents->get($autosave_id);
|
|
} elseif ($create) {
|
|
$autosave_id = wp_create_post_autosave([
|
|
'post_ID' => $this->post->uid->toDefault(),
|
|
'post_type' => $this->post->post_type,
|
|
'post_title' => $this->post->post_title,
|
|
'post_excerpt' => $this->post->post_excerpt,
|
|
// Hack to cause $autosave_is_different=true in `wp_create_post_autosave`.
|
|
'post_content' => '<!-- Created with Creative Elements -->',
|
|
'post_modified' => date('Y-m-d H:i:s'),
|
|
'template_type' => $this->post->template_type,
|
|
]);
|
|
|
|
Plugin::$instance->db->copyElementorMeta($this->post->ID, $autosave_id);
|
|
|
|
$document = Plugin::$instance->documents->get($autosave_id);
|
|
$document->saveTemplateType();
|
|
} else {
|
|
$document = false;
|
|
}
|
|
|
|
return $document;
|
|
}
|
|
|
|
// public function filterAdminRowActions($actions)
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*/
|
|
public function isEditableByCurrentUser()
|
|
{
|
|
// $edit_capability = static::getProperty( 'edit_capability' );
|
|
// if ( $edit_capability && ! current_user_can( $edit_capability ) ) {
|
|
// return false;
|
|
// }
|
|
|
|
return self::getProperty('is_editable') && User::isCurrentUserCanEdit($this->getMainId());
|
|
}
|
|
|
|
/**
|
|
* @since 2.9.0
|
|
*/
|
|
protected function getInitialConfig()
|
|
{
|
|
// Get document data *after* the scripts hook - so plugins can run compatibility before get data, but *before* enqueue the editor script - so elements can enqueue their own scripts that depended in editor script.
|
|
|
|
$locked_user = Plugin::$instance->editor->getLockedUser($this->getMainId());
|
|
|
|
if ($locked_user) {
|
|
$locked_user = $locked_user->display_name;
|
|
}
|
|
|
|
$post_type_object = get_post_type_object($this->getMainPost()->post_type);
|
|
|
|
$settings = SettingsManager::getSettingsManagersConfig();
|
|
|
|
$config = [
|
|
// 'id' => $this->getMainId(),
|
|
'id' => UId::parse($this->getMainId())->toDefault(),
|
|
'type' => $this->getName(),
|
|
'version' => $this->getMainMeta('_elementor_version'),
|
|
'settings' => $settings['page'],
|
|
'remoteLibrary' => $this->getRemoteLibraryConfig(),
|
|
'last_edited' => $this->getLastEdited(),
|
|
'panel' => static::getEditorPanelConfig(),
|
|
'container' => 'body',
|
|
'post_type_title' => $this->getPostTypeTitle(),
|
|
'user' => [
|
|
'can_publish' => current_user_can($post_type_object->cap->publish_posts),
|
|
|
|
// Deprecated config since 2.9.0.
|
|
'locked' => $locked_user,
|
|
],
|
|
'urls' => [
|
|
'exit_to_dashboard' => $this->getExitToDashboardUrl(),
|
|
'preview' => $this->getPreviewUrl(),
|
|
'wp_preview' => $this->getWpPreviewUrl(),
|
|
'permalink' => $this->getPermalink(),
|
|
'have_a_look' => $this->getHaveALookUrl(),
|
|
],
|
|
];
|
|
|
|
if (static::getProperty('has_elements')) {
|
|
$config['elements'] = $this->getElementsRawData(null, true);
|
|
$config['widgets'] = Plugin::$instance->widgets_manager->getWidgetTypesConfig();
|
|
}
|
|
|
|
$additional_config = apply_filters('elementor/document/config', [], $this->getMainId());
|
|
|
|
if (!empty($additional_config)) {
|
|
$config = array_replace_recursive($config, $additional_config);
|
|
}
|
|
|
|
return $config;
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*/
|
|
protected function _registerControls()
|
|
{
|
|
$this->registerDocumentControls();
|
|
|
|
/*
|
|
* Register document controls.
|
|
*
|
|
* Fires after Elementor registers the document controls.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param Document $this The document instance
|
|
*/
|
|
do_action('elementor/documents/register_controls', $this);
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*
|
|
* @param $data
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function save($data)
|
|
{
|
|
if (!$this->isEditableByCurrentUser()) {
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* Before document save.
|
|
*
|
|
* Fires when document save starts on Elementor.
|
|
*
|
|
* @since 2.5.12
|
|
*
|
|
* @param \Elementor\Core\Base\Document $this The current document
|
|
* @param $data
|
|
*/
|
|
do_action('elementor/document/before_save', $this, $data);
|
|
|
|
// if (!current_user_can('unfiltered_html')) {
|
|
// $data = wp_kses_post_deep($data);
|
|
// }
|
|
|
|
if (!empty($data['settings'])) {
|
|
if (isset($data['settings']['post_status']) && DB::STATUS_AUTOSAVE === $data['settings']['post_status']) {
|
|
if (!defined('DOING_AUTOSAVE')) {
|
|
define('DOING_AUTOSAVE', true);
|
|
}
|
|
}
|
|
|
|
$this->saveSettings($data['settings']);
|
|
|
|
// Refresh post after save settings.
|
|
$this->post = get_post($this->post->ID);
|
|
}
|
|
|
|
// Don't check is_empty, because an empty array should be saved.
|
|
if (isset($data['elements']) && is_array($data['elements'])) {
|
|
$this->saveElements($data['elements']);
|
|
}
|
|
|
|
$this->saveTemplateType();
|
|
|
|
$this->saveVersion();
|
|
|
|
// Create revision
|
|
wp_save_post_revision($this->post);
|
|
|
|
// Remove Post CSS
|
|
$post_css = PostCSS::create($this->post->ID);
|
|
|
|
$post_css->delete();
|
|
|
|
/*
|
|
* After document save.
|
|
*
|
|
* Fires when document save is complete.
|
|
*
|
|
* @since 2.5.12
|
|
*
|
|
* @param \Elementor\Core\Base\Document $this The current document
|
|
* @param $data
|
|
*/
|
|
do_action('elementor/document/after_save', $this, $data);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Is built with Elementor.
|
|
*
|
|
* Check whether the post was built with Elementor.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @return bool Whether the post was built with Elementor
|
|
*/
|
|
public function isBuiltWithElementor()
|
|
{
|
|
$id_type = (int) substr($this->post->ID, -6, 2);
|
|
|
|
if (in_array($id_type, [UId::REVISION, UId::TEMPLATE, UId::CONTENT, UId::THEME])) {
|
|
return true;
|
|
}
|
|
return (bool) get_post_meta($this->post->ID, '_elementor_edit_mode', true);
|
|
}
|
|
|
|
// public function getEditUrl()
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*/
|
|
public function getPreviewUrl()
|
|
{
|
|
/*
|
|
* Use a static var - to avoid change the `ver` parameter on every call.
|
|
*/
|
|
static $url;
|
|
|
|
if (empty($url)) {
|
|
// add_filter('pre_option_permalink_structure', '__return_empty_string');
|
|
|
|
$url = add_query_arg([
|
|
// 'elementor-preview' => $this->getMainId(),
|
|
'ctx' => \Shop::getContext(),
|
|
'ver' => time(),
|
|
], $this->getPermalink());
|
|
|
|
// remove_filter('pre_option_permalink_structure', '__return_empty_string');
|
|
|
|
/*
|
|
* Document preview URL.
|
|
*
|
|
* Filters the document preview URL.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param string $url The preview URL
|
|
* @param Document $this The document instance
|
|
*/
|
|
$url = apply_filters('elementor/document/urls/preview', $url, $this);
|
|
}
|
|
|
|
return $url;
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*
|
|
* @param string $key
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getJsonMeta($key)
|
|
{
|
|
$meta = get_post_meta($this->post->ID, $key, true);
|
|
|
|
if (is_string($meta) && !empty($meta)) {
|
|
$meta = json_decode($meta, true);
|
|
}
|
|
|
|
if (empty($meta)) {
|
|
$meta = [];
|
|
}
|
|
|
|
return $meta;
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*
|
|
* @param null $data
|
|
* @param bool $with_html_content
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getElementsRawData($data = null, $with_html_content = false)
|
|
{
|
|
if (!static::getProperty('has_elements')) {
|
|
return [];
|
|
}
|
|
|
|
if (is_null($data)) {
|
|
$data = $this->getElementsData();
|
|
}
|
|
|
|
// Change the current documents, so widgets can use `documents->get_current` and other post data
|
|
Plugin::$instance->documents->switchToDocument($this);
|
|
|
|
$editor_data = [];
|
|
|
|
foreach ($data as $element_data) {
|
|
$element = Plugin::$instance->elements_manager->createElementInstance($element_data);
|
|
|
|
if (!$element) {
|
|
continue;
|
|
}
|
|
|
|
$editor_data[] = $element->getRawData($with_html_content);
|
|
}
|
|
|
|
Plugin::$instance->documents->restoreDocument();
|
|
|
|
return $editor_data;
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*
|
|
* @param string $status
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getElementsData($status = DB::STATUS_PUBLISH)
|
|
{
|
|
$elements = $this->getJsonMeta('_elementor_data');
|
|
|
|
if (DB::STATUS_DRAFT === $status) {
|
|
$autosave = $this->getNewerAutosave();
|
|
|
|
if (is_object($autosave)) {
|
|
$autosave_elements = Plugin::$instance->documents
|
|
->get($autosave->getPost()->ID)
|
|
->getJsonMeta('_elementor_data');
|
|
}
|
|
}
|
|
|
|
if (Plugin::$instance->editor->isEditMode()) {
|
|
if (empty($elements) && empty($autosave_elements)) {
|
|
// Convert to Elementor.
|
|
$elements = $this->convertToElementor();
|
|
if ($this->isAutosave()) {
|
|
Plugin::$instance->db->copyElementorMeta($this->post->post_parent, $this->post->ID);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!empty($autosave_elements)) {
|
|
$elements = $autosave_elements;
|
|
}
|
|
|
|
return $elements;
|
|
}
|
|
|
|
/**
|
|
* @since 2.3.0
|
|
*/
|
|
public function convertToElementor()
|
|
{
|
|
$this->save([]);
|
|
|
|
if (empty($this->post->post_content)) {
|
|
return [];
|
|
}
|
|
|
|
$widget_type = Plugin::$instance->widgets_manager->getWidgetTypes('text-editor');
|
|
$settings = [
|
|
'editor' => $this->post->post_content,
|
|
];
|
|
|
|
// TODO: Better coding to start template for editor
|
|
return [
|
|
[
|
|
'id' => Utils::generateRandomString(),
|
|
'elType' => 'section',
|
|
'elements' => [
|
|
[
|
|
'id' => Utils::generateRandomString(),
|
|
'elType' => 'column',
|
|
'elements' => [
|
|
[
|
|
'id' => Utils::generateRandomString(),
|
|
'elType' => $widget_type::getType(),
|
|
'widgetType' => $widget_type->getName(),
|
|
'settings' => $settings,
|
|
],
|
|
],
|
|
],
|
|
],
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @since 2.1.3
|
|
*/
|
|
public function printElementsWithWrapper($elements_data = null)
|
|
{
|
|
if (!$elements_data) {
|
|
$elements_data = $this->getElementsData();
|
|
} ?>
|
|
<div <?php echo Utils::renderHtmlAttributes($this->getContainerAttributes()); ?>>
|
|
<div class="elementor-section-wrap"><?php $this->printElements($elements_data); ?></div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*/
|
|
public function getCssWrapperSelector()
|
|
{
|
|
return '';
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*/
|
|
public function getPanelPageSettings()
|
|
{
|
|
return [
|
|
/* translators: %s: Document title */
|
|
'title' => sprintf(__('%s Settings'), static::getTitle()),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*/
|
|
public function getPost()
|
|
{
|
|
return $this->post;
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*/
|
|
public function getPermalink()
|
|
{
|
|
return get_preview_post_link($this->getMainId());
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.8
|
|
*/
|
|
public function getContent($with_css = false)
|
|
{
|
|
return Plugin::$instance->frontend->getBuilderContent($this->post->ID, $with_css);
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*/
|
|
public function delete()
|
|
{
|
|
if ('revision' === $this->post->post_type) {
|
|
$deleted = wp_delete_post_revision($this->post);
|
|
} else {
|
|
$deleted = wp_delete_post($this->post->ID);
|
|
}
|
|
|
|
return $deleted && !is_wp_error($deleted);
|
|
}
|
|
|
|
/**
|
|
* Save editor elements.
|
|
*
|
|
* Save data from the editor to the database.
|
|
*
|
|
* @since 2.0.0
|
|
*
|
|
* @param array $elements
|
|
*/
|
|
protected function saveElements($elements)
|
|
{
|
|
$editor_data = $this->getElementsRawData($elements);
|
|
|
|
// We need the `wp_slash` in order to avoid the unslashing during the `update_post_meta`
|
|
// $json_value = wp_slash(wp_json_encode($editor_data));
|
|
|
|
$is_meta_updated = update_post_meta($this->post->ID, '_elementor_data', $editor_data);
|
|
|
|
/*
|
|
* Before saving data.
|
|
*
|
|
* Fires before Elementor saves data to the database.
|
|
*
|
|
* @since 1.0.0
|
|
*
|
|
* @param string $status Post status
|
|
* @param int|bool $is_meta_updated Meta ID if the key didn't exist, true on successful update, false on failure
|
|
*/
|
|
do_action('elementor/db/before_save', $this->post->post_status, $is_meta_updated);
|
|
|
|
Plugin::$instance->db->savePlainText($this->post->ID);
|
|
|
|
/*
|
|
* After saving data.
|
|
*
|
|
* Fires after Elementor saves data to the database.
|
|
*
|
|
* @since 1.0.0
|
|
*
|
|
* @param int $post_id The ID of the post
|
|
* @param array $editor_data Sanitize posted data
|
|
*/
|
|
do_action('elementor/editor/after_save', $this->post->ID, $editor_data);
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*
|
|
* @param int $user_id Optional. User ID. Default value is `0`
|
|
*
|
|
* @return bool|int
|
|
*/
|
|
public function getAutosaveId($user_id = 0)
|
|
{
|
|
if (!$user_id) {
|
|
$user_id = get_current_user_id();
|
|
}
|
|
|
|
$autosave = Utils::getPostAutosave($this->post->ID, $user_id);
|
|
if ($autosave) {
|
|
return $autosave->ID;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public function saveVersion()
|
|
{
|
|
if (!defined('IS_ELEMENTOR_UPGRADE')) {
|
|
// Save per revision.
|
|
$this->updateMeta('_elementor_version', _CE_VERSION_);
|
|
|
|
// Save update date if needed
|
|
if (!$this->post->post_modified) {
|
|
$this->updateMeta('_ce_date_upd', date('Y-m-d H:i:s'));
|
|
}
|
|
|
|
/*
|
|
* Document version save.
|
|
*
|
|
* Fires when document version is saved on Elementor.
|
|
* Will not fire during Elementor Upgrade.
|
|
*
|
|
* @since 2.5.12
|
|
*
|
|
* @param \Elementor\Core\Base\Document $this The current document
|
|
*
|
|
*/
|
|
do_action('elementor/document/save_version', $this);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @since 2.3.0
|
|
*/
|
|
public function saveTemplateType()
|
|
{
|
|
$template_type = $this->getName();
|
|
|
|
if ($template_type !== $this->post->template_type && (UId::TEMPLATE >= $this->post->uid->id_type || UId::THEME === $this->post->uid->id_type)) {
|
|
$this->post->template_type = $template_type;
|
|
|
|
$this->post->_obj->setFieldsToUpdate([
|
|
'type' => true,
|
|
]);
|
|
|
|
return $this->post->_obj->update();
|
|
}
|
|
// return $this->updateMainMeta(self::TYPE_META_KEY, $this->getName());
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @since 2.3.0
|
|
*/
|
|
public function getTemplateType()
|
|
{
|
|
// return $this->getMainMeta(self::TYPE_META_KEY);
|
|
return $this->post->template_type;
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*
|
|
* @param string $key Meta data key
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function getMainMeta($key)
|
|
{
|
|
return get_post_meta($this->getMainId(), $key, true);
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.4
|
|
*
|
|
* @param string $key Meta data key
|
|
* @param string $value Meta data value
|
|
*
|
|
* @return bool|int
|
|
*/
|
|
public function updateMainMeta($key, $value)
|
|
{
|
|
return update_post_meta($this->getMainId(), $key, $value);
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.4
|
|
*
|
|
* @param string $key Meta data key
|
|
* @param string $value Optional. Meta data value. Default is an empty string
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function deleteMainMeta($key, $value = '')
|
|
{
|
|
return delete_post_meta($this->getMainId(), $key, $value);
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*
|
|
* @param string $key Meta data key
|
|
*
|
|
* @return mixed
|
|
*/
|
|
public function getMeta($key)
|
|
{
|
|
return get_post_meta($this->post->ID, $key, true);
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*
|
|
* @param string $key Meta data key
|
|
* @param mixed $value Meta data value
|
|
*
|
|
* @return bool|int
|
|
*/
|
|
public function updateMeta($key, $value)
|
|
{
|
|
return update_post_meta($this->post->ID, $key, $value);
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.3
|
|
*
|
|
* @param string $key Meta data key
|
|
* @param string $value Meta data value
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function deleteMeta($key, $value = '')
|
|
{
|
|
return delete_post_meta($this->post->ID, $key, $value);
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*/
|
|
public function getLastEdited()
|
|
{
|
|
$post = $this->post;
|
|
$autosave_post = $this->getAutosave();
|
|
|
|
if ($autosave_post) {
|
|
$post = $autosave_post->getPost();
|
|
}
|
|
|
|
$date = \Tools::displayDate($post->post_modified, null, true);
|
|
$author = get_user_by('id', $post->post_author);
|
|
$display_name = isset($author->display_name) ? $author->display_name : __('Unknown');
|
|
|
|
if ($autosave_post || 'revision' === $post->post_type) {
|
|
/* translators: 1: Saving date, 2: Author display name */
|
|
$last_edited = sprintf(__('Draft saved on %1$s by %2$s'), '<time>' . $date . '</time>', $display_name);
|
|
} else {
|
|
/* translators: 1: Editing date, 2: Author display name */
|
|
$last_edited = sprintf(__('Last edited on %1$s by %2$s'), '<time>' . $date . '</time>', $display_name);
|
|
}
|
|
|
|
return $last_edited;
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.0
|
|
*
|
|
* @param array $data
|
|
*
|
|
* @throws \Exception if the post does not exist
|
|
*/
|
|
public function __construct(array $data = [])
|
|
{
|
|
if ($data) {
|
|
if (empty($data['post_id'])) {
|
|
$this->post = new WPPost((object) []);
|
|
} else {
|
|
$this->post = get_post($data['post_id']);
|
|
|
|
if (!$this->post) {
|
|
throw new \Exception(sprintf('Post ID #%s does not exist.', $data['post_id']), Exceptions::NOT_FOUND);
|
|
}
|
|
}
|
|
|
|
// Each Control_Stack is based on a unique ID.
|
|
$data['id'] = $data['post_id'];
|
|
|
|
if (!isset($data['settings'])) {
|
|
$data['settings'] = [];
|
|
}
|
|
|
|
$saved_settings = get_post_meta($this->post->ID, '_elementor_page_settings', true);
|
|
if (!empty($saved_settings) && is_array($saved_settings)) {
|
|
$data['settings'] += $saved_settings;
|
|
}
|
|
}
|
|
|
|
parent::__construct($data);
|
|
}
|
|
|
|
protected function getRemoteLibraryConfig()
|
|
{
|
|
$config = [
|
|
'type' => 'block',
|
|
'default_route' => 'templates/blocks',
|
|
'category' => $this->getName(),
|
|
'autoImportSettings' => false,
|
|
];
|
|
|
|
return $config;
|
|
}
|
|
|
|
/**
|
|
* @since 2.0.4
|
|
*
|
|
* @param $settings
|
|
*/
|
|
protected function saveSettings($settings)
|
|
{
|
|
$page_settings_manager = SettingsManager::getSettingsManagers('page');
|
|
$page_settings_manager->ajaxBeforeSaveSettings($settings, $this->post->ID);
|
|
$page_settings_manager->saveSettings($settings, $this->post->ID);
|
|
}
|
|
|
|
/**
|
|
* @since 2.1.3
|
|
*/
|
|
protected function printElements($elements_data)
|
|
{
|
|
foreach ($elements_data as $element_data) {
|
|
$element = Plugin::$instance->elements_manager->createElementInstance($element_data);
|
|
|
|
if (!$element) {
|
|
continue;
|
|
}
|
|
|
|
$element->printElement();
|
|
}
|
|
}
|
|
|
|
protected function registerDocumentControls()
|
|
{
|
|
$this->startControlsSection(
|
|
'document_settings',
|
|
[
|
|
'label' => __('General Settings'),
|
|
'tab' => ControlsManager::TAB_SETTINGS,
|
|
]
|
|
);
|
|
|
|
$this->addControl(
|
|
'post_title',
|
|
[
|
|
'label' => __('Title'),
|
|
'type' => ControlsManager::TEXT,
|
|
'default' => $this->post->post_title,
|
|
'label_block' => true,
|
|
'separator' => 'none',
|
|
]
|
|
);
|
|
|
|
$this->addControl(
|
|
'post_status',
|
|
[
|
|
'label' => __('Status'),
|
|
'type' => ControlsManager::SELECT,
|
|
'default' => $this->getMainPost()->post_status,
|
|
'options' => $this->getPostStatuses(),
|
|
]
|
|
);
|
|
|
|
$this->endControlsSection();
|
|
}
|
|
|
|
protected function getPostStatuses()
|
|
{
|
|
return get_post_statuses();
|
|
}
|
|
|
|
protected function getHaveALookUrl()
|
|
{
|
|
return $this->getPermalink();
|
|
}
|
|
}
|