update
This commit is contained in:
176
modules/creativeelements/classes/CEContent.php
Normal file
176
modules/creativeelements/classes/CEContent.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
class CEContent extends ObjectModel
|
||||
{
|
||||
public $id_employee;
|
||||
public $id_product = 0;
|
||||
public $title;
|
||||
public $hook;
|
||||
public $content;
|
||||
public $position;
|
||||
public $active;
|
||||
public $date_add;
|
||||
public $date_upd;
|
||||
|
||||
public static $definition = [
|
||||
'table' => 'ce_content',
|
||||
'primary' => 'id_ce_content',
|
||||
'multilang' => true,
|
||||
'multilang_shop' => true,
|
||||
'fields' => [
|
||||
'id_employee' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'],
|
||||
'id_product' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'],
|
||||
'hook' => ['type' => self::TYPE_STRING, 'validate' => 'isHookName', 'required' => true, 'size' => 64],
|
||||
// Shop fields
|
||||
'position' => ['type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedInt'],
|
||||
'active' => ['type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isBool'],
|
||||
'date_add' => ['type' => self::TYPE_DATE, 'shop' => true, 'validate' => 'isDate'],
|
||||
'date_upd' => ['type' => self::TYPE_DATE, 'shop' => true, 'validate' => 'isDate'],
|
||||
// Lang fields
|
||||
'title' => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 128],
|
||||
'content' => ['type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'],
|
||||
],
|
||||
];
|
||||
|
||||
public function __construct($id = null, $id_lang = null, $id_shop = null, $translator = null)
|
||||
{
|
||||
parent::__construct($id, $id_lang, $id_shop, $translator);
|
||||
|
||||
// Insert missing ce_content_lang row if new language was added
|
||||
if (!$this->id && $id && $id_lang && $id_shop && Shop::getShop($id_shop) && Language::getLanguage($id_lang) && self::getHookById($id) !== false) {
|
||||
$res = Db::getInstance()->insert('ce_content_lang', [
|
||||
'id_ce_content' => (int) $id,
|
||||
'id_lang' => (int) $id_lang,
|
||||
'id_shop' => (int) $id_shop,
|
||||
'title' => '',
|
||||
'content' => '',
|
||||
]);
|
||||
empty($res) or parent::__construct($id, $id_lang, $id_shop, $translator);
|
||||
}
|
||||
}
|
||||
|
||||
public function add($auto_date = true, $null_values = false)
|
||||
{
|
||||
$ctx = Context::getContext();
|
||||
$this->id_employee = $ctx->employee->id;
|
||||
|
||||
$res = parent::add($auto_date, $null_values);
|
||||
|
||||
if ($res && $this->hook && !empty($ctx->controller->module)) {
|
||||
$ctx->controller->module->registerHook($this->hook, Shop::getContextListShopID());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function update($null_values = false)
|
||||
{
|
||||
if ('0000-00-00 00:00:00' === $this->date_add) {
|
||||
$this->date_add = date('Y-m-d H:i:s');
|
||||
}
|
||||
$before = new self($this->id);
|
||||
|
||||
if ($res = parent::update($null_values)) {
|
||||
$module = Context::getContext()->controller->module;
|
||||
// handle hook changes
|
||||
if ($before->hook && !method_exists($module, 'hook' . $before->hook) && !self::hasHook($before->hook)) {
|
||||
$module->unregisterHook($before->hook, Shop::getContextListShopID());
|
||||
}
|
||||
empty($this->hook) or $module->registerHook($this->hook, Shop::getContextListShopID());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$res = parent::delete();
|
||||
|
||||
if ($res && $this->hook != 'displayFooterProduct') {
|
||||
$module = Context::getContext()->controller->module;
|
||||
$shops = Shop::getContextListShopID();
|
||||
|
||||
// unregister hook if needed
|
||||
if (!method_exists($module, 'hook' . $this->hook) && !self::hasHook($this->hook)) {
|
||||
$module->unregisterHook($this->hook, $shops);
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function displayFieldName($field, $class = __CLASS__, $htmlentities = true, Context $ctx = null)
|
||||
{
|
||||
return 'hook' == $field ? 'Position' : parent::displayFieldName($field, $class, $htmlentities, $ctx);
|
||||
}
|
||||
|
||||
public static function hasHook($hook)
|
||||
{
|
||||
$db = Db::getInstance();
|
||||
$table = _DB_PREFIX_ . 'ce_content';
|
||||
$hook = $db->escape($hook);
|
||||
|
||||
return $db->getValue("SELECT 1 FROM $table WHERE hook LIKE '$hook'");
|
||||
}
|
||||
|
||||
public static function getHookById($id)
|
||||
{
|
||||
$table = _DB_PREFIX_ . 'ce_content';
|
||||
|
||||
return Db::getInstance()->getValue(
|
||||
"SELECT hook FROM $table WHERE id_ce_content = " . (int) $id
|
||||
);
|
||||
}
|
||||
|
||||
public static function getIdsByHook($hook, $id_lang, $id_shop, $id_product = 0, $preview = false)
|
||||
{
|
||||
$db = Db::getInstance();
|
||||
$table = _DB_PREFIX_ . 'ce_content';
|
||||
$hook = $db->escape($hook);
|
||||
$id_lang = (int) $id_lang;
|
||||
$id_shop = (int) $id_shop;
|
||||
$id_product = (int) $id_product;
|
||||
$id_preview = isset($preview->id, $preview->id_type) && CE\UId::CONTENT == $preview->id_type
|
||||
? (int) $preview->id
|
||||
: 0
|
||||
;
|
||||
$res = $db->executeS(
|
||||
"SELECT a.id_ce_content as id FROM $table a
|
||||
LEFT JOIN {$table}_lang AS b ON a.id_ce_content = b.id_ce_content
|
||||
LEFT JOIN {$table}_shop sa ON sa.id_ce_content = a.id_ce_content AND sa.id_shop = b.id_shop
|
||||
WHERE b.id_lang = $id_lang AND sa.id_shop = $id_shop AND a.hook LIKE '$hook' " .
|
||||
($id_product ? "AND (a.id_product = 0 OR a.id_product = $id_product) " : "") .
|
||||
($id_preview ? "AND (a.active = 1 OR a.id_ce_content = $id_preview) " : "AND a.active = 1 ") .
|
||||
"ORDER BY a.id_product DESC"
|
||||
);
|
||||
|
||||
return $res ?: [];
|
||||
}
|
||||
|
||||
public static function getFooterProductId($id_product)
|
||||
{
|
||||
if (!$id_product = (int) $id_product) {
|
||||
return 0;
|
||||
}
|
||||
$table = _DB_PREFIX_ . 'ce_content';
|
||||
|
||||
return (int) Db::getInstance()->getValue(
|
||||
"SELECT id_ce_content FROM $table WHERE id_product = $id_product AND hook = 'displayFooterProduct'"
|
||||
);
|
||||
}
|
||||
|
||||
public static function getMaintenanceId()
|
||||
{
|
||||
$table = _DB_PREFIX_ . 'ce_content';
|
||||
|
||||
return (int) Db::getInstance()->getValue(
|
||||
"SELECT id_ce_content FROM $table WHERE hook LIKE 'displayMaintenance' ORDER BY active DESC"
|
||||
);
|
||||
}
|
||||
}
|
||||
319
modules/creativeelements/classes/CEDatabase.php
Normal file
319
modules/creativeelements/classes/CEDatabase.php
Normal file
@@ -0,0 +1,319 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
class CEDatabase
|
||||
{
|
||||
private static $hooks = [
|
||||
'displayBackOfficeHeader',
|
||||
'displayHeader',
|
||||
'displayFooterProduct',
|
||||
'overrideLayoutTemplate',
|
||||
'CETemplate',
|
||||
// Actions
|
||||
'actionFrontControllerAfterInit',
|
||||
'actionFrontControllerInitAfter',
|
||||
'actionObjectCERevisionDeleteAfter',
|
||||
'actionObjectCETemplateDeleteAfter',
|
||||
'actionObjectCEThemeDeleteAfter',
|
||||
'actionObjectCEContentDeleteAfter',
|
||||
'actionObjectProductDeleteAfter',
|
||||
'actionObjectCategoryDeleteAfter',
|
||||
'actionObjectManufacturerDeleteAfter',
|
||||
'actionObjectSupplierDeleteAfter',
|
||||
'actionObjectCmsDeleteAfter',
|
||||
'actionObjectCmsCategoryDeleteAfter',
|
||||
'actionObjectYbc_blog_post_classDeleteAfter',
|
||||
'actionObjectXipPostsClassDeleteAfter',
|
||||
'actionObjectStBlogClassDeleteAfter',
|
||||
'actionObjectBlogPostsDeleteAfter',
|
||||
'actionObjectNewsClassDeleteAfter',
|
||||
'actionObjectTvcmsBlogPostsClassDeleteAfter',
|
||||
'actionProductAdd',
|
||||
];
|
||||
|
||||
public static function initConfigs()
|
||||
{
|
||||
$defaults = [
|
||||
// General
|
||||
'elementor_frontend_edit' => 1,
|
||||
'elementor_max_revisions' => 10,
|
||||
// Style
|
||||
'elementor_default_generic_fonts' => 'sans-serif',
|
||||
'elementor_container_width' => 1140,
|
||||
'elementor_space_between_widgets' => 20,
|
||||
'elementor_page_title_selector' => 'header.page-header',
|
||||
'elementor_page_wrapper_selector' => '#content, #wrapper, #wrapper .container',
|
||||
'elementor_viewport_lg' => 1025,
|
||||
'elementor_viewport_md' => 768,
|
||||
'elementor_global_image_lightbox' => 1,
|
||||
// Advanced
|
||||
'elementor_edit_buttons' => 'on',
|
||||
'elementor_exclude_modules' => json_encode([
|
||||
'administration',
|
||||
'analytics_stats',
|
||||
'billing_invoicing',
|
||||
'checkout',
|
||||
'dashboard',
|
||||
'export',
|
||||
'emailing',
|
||||
'i18n_localization',
|
||||
'migration_tools',
|
||||
'payments_gateways',
|
||||
'payment_security',
|
||||
'quick_bulk_update',
|
||||
'seo',
|
||||
'shipping_logistics',
|
||||
'market_place',
|
||||
]),
|
||||
'elementor_load_fontawesome' => 1,
|
||||
'elementor_load_waypoints' => 1,
|
||||
'elementor_load_slick' => 1,
|
||||
];
|
||||
foreach ($defaults as $key => $value) {
|
||||
Configuration::hasKey($key) or Configuration::updateValue($key, $value);
|
||||
}
|
||||
copy(_CE_PATH_ . 'views/lib/filemanager/config.php', _PS_IMG_DIR_ . 'cms/config.php');
|
||||
copy(_CE_PATH_ . 'views/lib/filemanager/.htaccess', _PS_IMG_DIR_ . 'cms/.htaccess');
|
||||
}
|
||||
|
||||
public static function createTables()
|
||||
{
|
||||
$db = Db::getInstance();
|
||||
$ce_revision = _DB_PREFIX_ . 'ce_revision';
|
||||
$ce_template = _DB_PREFIX_ . 'ce_template';
|
||||
$ce_content = _DB_PREFIX_ . 'ce_content';
|
||||
$ce_theme = _DB_PREFIX_ . 'ce_theme';
|
||||
$ce_font = _DB_PREFIX_ . 'ce_font';
|
||||
$ce_meta = _DB_PREFIX_ . 'ce_meta';
|
||||
$engine = _MYSQL_ENGINE_;
|
||||
|
||||
return $db->execute("
|
||||
CREATE TABLE IF NOT EXISTS `$ce_revision` (
|
||||
`id_ce_revision` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`parent` bigint(20) UNSIGNED NOT NULL,
|
||||
`id_employee` int(10) UNSIGNED NOT NULL,
|
||||
`title` varchar(255) NOT NULL,
|
||||
`type` varchar(64) NOT NULL DEFAULT '',
|
||||
`content` longtext NOT NULL,
|
||||
`active` tinyint(1) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`date_upd` datetime NOT NULL,
|
||||
PRIMARY KEY (`id_ce_revision`),
|
||||
KEY `id` (`parent`),
|
||||
KEY `date_add` (`date_upd`)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8;
|
||||
") && $db->execute("
|
||||
CREATE TABLE IF NOT EXISTS `$ce_template` (
|
||||
`id_ce_template` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`id_employee` int(10) UNSIGNED NOT NULL,
|
||||
`title` varchar(128) NOT NULL DEFAULT '',
|
||||
`type` varchar(64) NOT NULL DEFAULT '',
|
||||
`content` longtext,
|
||||
`position` int(10) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`active` tinyint(1) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`date_add` datetime NOT NULL,
|
||||
`date_upd` datetime NOT NULL,
|
||||
PRIMARY KEY (`id_ce_template`)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8;
|
||||
") && $db->execute("
|
||||
CREATE TABLE IF NOT EXISTS `$ce_content` (
|
||||
`id_ce_content` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`id_employee` int(10) UNSIGNED NOT NULL,
|
||||
`id_product` int(10) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`hook` varchar(64) NOT NULL DEFAULT '',
|
||||
`position` int(10) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`active` tinyint(1) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`date_add` datetime NOT NULL,
|
||||
`date_upd` datetime NOT NULL,
|
||||
PRIMARY KEY (`id_ce_content`)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8;
|
||||
") && $db->execute("
|
||||
CREATE TABLE IF NOT EXISTS `{$ce_content}_shop` (
|
||||
`id_ce_content` int(10) UNSIGNED NOT NULL,
|
||||
`id_shop` int(10) UNSIGNED NOT NULL,
|
||||
`position` int(10) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`active` tinyint(1) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`date_add` datetime NOT NULL,
|
||||
`date_upd` datetime NOT NULL,
|
||||
PRIMARY KEY (`id_ce_content`,`id_shop`),
|
||||
KEY `id_shop` (`id_shop`)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8;
|
||||
") && $db->execute("
|
||||
CREATE TABLE IF NOT EXISTS `{$ce_content}_lang` (
|
||||
`id_ce_content` int(10) UNSIGNED NOT NULL,
|
||||
`id_lang` int(10) UNSIGNED NOT NULL,
|
||||
`id_shop` int(10) UNSIGNED NOT NULL DEFAULT 1,
|
||||
`title` varchar(128) NOT NULL DEFAULT '',
|
||||
`content` longtext,
|
||||
PRIMARY KEY (`id_ce_content`,`id_shop`,`id_lang`)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8;
|
||||
") && $db->execute("
|
||||
CREATE TABLE IF NOT EXISTS `$ce_theme` (
|
||||
`id_ce_theme` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`id_employee` int(10) UNSIGNED NOT NULL,
|
||||
`type` varchar(64) NOT NULL DEFAULT '',
|
||||
`position` int(10) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`active` tinyint(1) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`date_add` datetime NOT NULL,
|
||||
`date_upd` datetime NOT NULL,
|
||||
PRIMARY KEY (`id_ce_theme`)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8;
|
||||
") && $db->execute("
|
||||
CREATE TABLE IF NOT EXISTS `{$ce_theme}_shop` (
|
||||
`id_ce_theme` int(10) UNSIGNED NOT NULL,
|
||||
`id_shop` int(10) UNSIGNED NOT NULL,
|
||||
`position` int(10) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`active` tinyint(1) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`date_add` datetime NOT NULL,
|
||||
`date_upd` datetime NOT NULL,
|
||||
PRIMARY KEY (`id_ce_theme`,`id_shop`),
|
||||
KEY `id_shop` (`id_shop`)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8;
|
||||
") && $db->execute("
|
||||
CREATE TABLE IF NOT EXISTS `{$ce_theme}_lang` (
|
||||
`id_ce_theme` int(10) UNSIGNED NOT NULL,
|
||||
`id_lang` int(10) UNSIGNED NOT NULL,
|
||||
`id_shop` int(10) UNSIGNED NOT NULL DEFAULT 1,
|
||||
`title` varchar(128) NOT NULL DEFAULT '',
|
||||
`content` text,
|
||||
PRIMARY KEY (`id_ce_theme`,`id_shop`,`id_lang`)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8;
|
||||
") && $db->execute("
|
||||
CREATE TABLE IF NOT EXISTS `$ce_font` (
|
||||
`id_ce_font` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`family` varchar(128) NOT NULL DEFAULT '',
|
||||
`files` text,
|
||||
PRIMARY KEY (`id_ce_font`)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8;
|
||||
") && $db->execute("
|
||||
CREATE TABLE IF NOT EXISTS `$ce_meta` (
|
||||
`id_ce_meta` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`id` bigint(20) UNSIGNED NOT NULL DEFAULT 0,
|
||||
`name` varchar(255) DEFAULT NULL,
|
||||
`value` longtext,
|
||||
PRIMARY KEY (`id_ce_meta`),
|
||||
KEY `id` (`id`),
|
||||
KEY `name` (`name`)
|
||||
) ENGINE=$engine DEFAULT CHARSET=utf8;
|
||||
");
|
||||
}
|
||||
|
||||
public static function updateTabs()
|
||||
{
|
||||
$id = (int) Tab::getIdFromClassName('IMPROVE');
|
||||
|
||||
try {
|
||||
$pos = $id ? 1 : Tab::getInstanceFromClassName('AdminParentModules')->position;
|
||||
$parent = self::updateTab($id, $pos, 'AdminParentCEContent', true, ['en' => 'Creative Elements'], 'ce');
|
||||
|
||||
self::updateTab($parent->id, 1, 'AdminCEThemes', true, [
|
||||
'en' => 'Theme Builder',
|
||||
'fr' => 'Constructeur de thème',
|
||||
'es' => 'Maquetador de temas',
|
||||
'it' => 'Generatore di temi',
|
||||
'de' => 'Theme Builder',
|
||||
'pl' => 'Kreator motywów',
|
||||
]);
|
||||
self::updateTab($parent->id, 2, 'AdminCEContent', true, [
|
||||
'en' => 'Content Anywhere',
|
||||
'fr' => 'Contenu n’importe où',
|
||||
'es' => 'Contenido cualquier lugar',
|
||||
'it' => 'Contenuto Ovunque',
|
||||
'de' => 'Inhalt überall',
|
||||
'pl' => 'Treść w dowolnym miejscu',
|
||||
]);
|
||||
self::updateTab($parent->id, 3, 'AdminCETemplates', true, [
|
||||
'en' => 'Saved Templates',
|
||||
'fr' => 'Modèles enregistrés',
|
||||
'es' => 'Plantillas guardadas',
|
||||
'it' => 'Template salvati',
|
||||
'de' => 'Gespeicherte Templates',
|
||||
'pl' => 'Zapisane szablony',
|
||||
]);
|
||||
self::updateTab($parent->id, 4, 'AdminCEFonts', true, [
|
||||
'en' => 'Custom Fonts',
|
||||
'fr' => 'Polices personnalisées',
|
||||
'es' => 'Fuentes personalizadas',
|
||||
'it' => 'Font Personalizzati',
|
||||
'de' => 'Eigene Schriftarten',
|
||||
'pl' => 'Własne czcionki',
|
||||
]);
|
||||
self::updateTab($parent->id, 5, 'AdminCESettings', true, [
|
||||
'en' => 'Settings',
|
||||
'fr' => 'Réglages',
|
||||
'es' => 'Ajustes',
|
||||
'it' => 'Impostazioni',
|
||||
'de' => 'Einstellungen',
|
||||
'pl' => 'Ustawienia',
|
||||
]);
|
||||
self::updateTab($parent->id, 6, 'AdminCEEditor', false, [
|
||||
'en' => 'Live Editor',
|
||||
'fr' => 'Éditeur en direct',
|
||||
'es' => 'Editor en vivo',
|
||||
'it' => 'Editor live',
|
||||
'de' => 'Live Editor',
|
||||
'pl' => 'Edytor na żywo',
|
||||
]);
|
||||
} catch (Exception $ex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static function updateTab($id_parent, $position, $class, $active, array $name, $icon = '')
|
||||
{
|
||||
$id = (int) Tab::getIdFromClassName($class);
|
||||
$tab = new Tab($id);
|
||||
$tab->id_parent = $id_parent;
|
||||
$tab->position = (int) $position;
|
||||
$tab->module = 'creativeelements';
|
||||
$tab->class_name = $class;
|
||||
$tab->active = $active;
|
||||
$tab->icon = $icon;
|
||||
$tab->name = [];
|
||||
|
||||
foreach (Language::getLanguages(false) as $lang) {
|
||||
$tab->name[$lang['id_lang']] = isset($name[$lang['iso_code']]) ? $name[$lang['iso_code']] : $name['en'];
|
||||
}
|
||||
|
||||
if (!$tab->save()) {
|
||||
throw new Exception('Can not save Tab: ' . $class);
|
||||
}
|
||||
|
||||
if (!$id && $tab->position != $position) {
|
||||
$tab->position = (int) $position;
|
||||
$tab->update();
|
||||
}
|
||||
|
||||
return $tab;
|
||||
}
|
||||
|
||||
public static function getHooks($all = true)
|
||||
{
|
||||
$hooks = self::$hooks;
|
||||
|
||||
if ($all) {
|
||||
$ce_content = _DB_PREFIX_ . 'ce_content';
|
||||
$rows = Db::getInstance()->executeS("SELECT DISTINCT hook FROM $ce_content");
|
||||
|
||||
if (!empty($rows)) {
|
||||
foreach ($rows as &$row) {
|
||||
$hook = $row['hook'];
|
||||
|
||||
if ($hook && !in_array($hook, $hooks)) {
|
||||
$hooks[] = $hook;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $hooks;
|
||||
}
|
||||
}
|
||||
133
modules/creativeelements/classes/CEFont.php
Normal file
133
modules/creativeelements/classes/CEFont.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
class CEFont extends ObjectModel
|
||||
{
|
||||
public $family;
|
||||
public $files;
|
||||
|
||||
public static $definition = [
|
||||
'table' => 'ce_font',
|
||||
'primary' => 'id_ce_font',
|
||||
'fields' => [
|
||||
'family' => ['type' => self::TYPE_STRING, 'validate' => 'isImageTypeName', 'required' => true, 'size' => 128],
|
||||
'files' => ['type' => self::TYPE_STRING, 'validate' => 'isJson'],
|
||||
],
|
||||
];
|
||||
|
||||
protected static $format = [
|
||||
'woff' => 'woff',
|
||||
'woff2' => 'woff2',
|
||||
'ttf' => 'truetype',
|
||||
'otf' => 'opentype',
|
||||
];
|
||||
|
||||
public static function getAllowedExt()
|
||||
{
|
||||
return array_keys(self::$format);
|
||||
}
|
||||
|
||||
public static function familyAlreadyExists($family, $exclude_id = 0)
|
||||
{
|
||||
$db = Db::getInstance();
|
||||
$table = _DB_PREFIX_ . 'ce_font';
|
||||
$id_ce_font = (int) $exclude_id;
|
||||
$family = $db->escape($family);
|
||||
|
||||
return (bool) $db->getValue(
|
||||
"SELECT `id_ce_font` FROM `$table` WHERE `family` = '$family' AND `id_ce_font` != $id_ce_font"
|
||||
);
|
||||
}
|
||||
|
||||
public static function generateFontsList()
|
||||
{
|
||||
$fonts = [];
|
||||
$font_types = [];
|
||||
$db = Db::getInstance();
|
||||
$table = _DB_PREFIX_ . 'ce_font';
|
||||
$rows = $db->executeS("SELECT `family`, `files` FROM `$table` ORDER BY `family`");
|
||||
|
||||
if ($rows) {
|
||||
foreach ($rows as &$row) {
|
||||
if ($font_face = self::getFontFaceFromData($row['family'], $row['files'])) {
|
||||
$fonts[$row['family']] = ['font_face' => $font_face];
|
||||
}
|
||||
$font_types[$row['family']] = 'custom';
|
||||
}
|
||||
}
|
||||
CE\update_post_meta(0, 'elementor_fonts_manager_fonts', $fonts);
|
||||
CE\update_post_meta(0, 'elementor_fonts_manager_font_types', $font_types);
|
||||
}
|
||||
|
||||
public static function getFontFaceFromData($family, $data)
|
||||
{
|
||||
is_array($data) or $data = json_decode($data, true);
|
||||
|
||||
if (!$data) {
|
||||
return '';
|
||||
}
|
||||
ob_start();
|
||||
|
||||
foreach ($data as &$font) {
|
||||
$src = [];
|
||||
|
||||
foreach (self::$format as $ext => $format) {
|
||||
if (!empty($font[$ext]['url'])) {
|
||||
if (stripos($font[$ext]['url'], 'modules/') === 0 || stripos($font[$ext]['url'], 'themes/') === 0) {
|
||||
$url = '{{BASE}}' . trim($font[$ext]['url']);
|
||||
} else {
|
||||
$url = trim($font[$ext]['url']);
|
||||
}
|
||||
$src[] = "url('$url') format('$format')";
|
||||
}
|
||||
}
|
||||
$src = implode(",\n\t\t", $src);
|
||||
|
||||
echo "@font-face {\n";
|
||||
echo "\tfont-family: '$family';\n";
|
||||
echo "\tfont-weight: {$font['font_weight']};\n";
|
||||
echo "\tfont-style: {$font['font_style']};\n";
|
||||
echo "\tfont-display: swap;\n";
|
||||
echo "\tsrc: $src;\n";
|
||||
echo "}\n";
|
||||
}
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
public function add($auto_date = true, $null_values = false)
|
||||
{
|
||||
if ($result = parent::add($auto_date, $null_values)) {
|
||||
self::generateFontsList();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function update($null_values = false)
|
||||
{
|
||||
if ($result = parent::update($null_values)) {
|
||||
self::generateFontsList();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
if ($result = parent::delete()) {
|
||||
self::generateFontsList();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return self::getFontFaceFromData($this->family, $this->files);
|
||||
}
|
||||
}
|
||||
311
modules/creativeelements/classes/CEMigrate.php
Normal file
311
modules/creativeelements/classes/CEMigrate.php
Normal file
@@ -0,0 +1,311 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
class CEMigrate
|
||||
{
|
||||
const IDS_META_KEY = '_ce_migrate_ids';
|
||||
|
||||
const MOVE_TIMEOUT = 30;
|
||||
|
||||
private static $ids;
|
||||
|
||||
private static function searchIds()
|
||||
{
|
||||
$table = _DB_PREFIX_ . 'creativepage';
|
||||
$rows = Db::getInstance()->executeS("SELECT id, active FROM $table ORDER BY id");
|
||||
$ids = [
|
||||
'content' => [],
|
||||
'template' => [],
|
||||
];
|
||||
if (!empty($rows)) {
|
||||
foreach ($rows as &$row) {
|
||||
$ids[$row['active'] < 2 ? 'content' : 'template'][] = (int) $row['id'];
|
||||
}
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
||||
public static function storeIds()
|
||||
{
|
||||
$ids = self::searchIds();
|
||||
$count = count($ids['content']) + count($ids['template']);
|
||||
|
||||
if ($count > 0) {
|
||||
Configuration::updateGlobalValue('ce_migrate', $count);
|
||||
|
||||
CE\update_post_meta(0, self::IDS_META_KEY, $ids) && self::$ids = $ids;
|
||||
}
|
||||
return $count;
|
||||
}
|
||||
|
||||
public static function getIds()
|
||||
{
|
||||
if (null === self::$ids) {
|
||||
self::$ids = CE\get_post_meta(0, self::IDS_META_KEY, true);
|
||||
}
|
||||
return self::$ids;
|
||||
}
|
||||
|
||||
public static function removeIds($type, $done)
|
||||
{
|
||||
$ids = self::getIds();
|
||||
$ids[$type] = array_values(array_diff($ids[$type], $done));
|
||||
|
||||
if (!empty($ids['content']) || !empty($ids['template'])) {
|
||||
CE\update_post_meta(0, self::IDS_META_KEY, $ids) && self::$ids = $ids;
|
||||
} else {
|
||||
self::deleteIds();
|
||||
|
||||
Media::clearCache();
|
||||
}
|
||||
return [
|
||||
'type' => $type,
|
||||
'done' => $done,
|
||||
];
|
||||
}
|
||||
|
||||
private static function deleteIds()
|
||||
{
|
||||
Configuration::deleteByName('ce_migrate');
|
||||
|
||||
CE\delete_post_meta(0, self::IDS_META_KEY) && self::$ids = false;
|
||||
}
|
||||
|
||||
private static function getJsDef()
|
||||
{
|
||||
$link = Context::getContext()->link;
|
||||
|
||||
return [
|
||||
'ids' => self::getIds(),
|
||||
'count' => Configuration::getGlobalValue('ce_migrate'),
|
||||
'baseDir' => __PS_BASE_URI__,
|
||||
'ajaxUrl' => [
|
||||
'content' => $link->getAdminLink('AdminCEContent') . '&ajax=1',
|
||||
'template' => $link->getAdminLink('AdminCETemplates') . '&ajax=1',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public static function registerJavaScripts()
|
||||
{
|
||||
$context = Context::getContext();
|
||||
|
||||
if ($context->controller instanceof AdminController) {
|
||||
if (Tools::getValue('CEMigrate') === 'reset' && !self::storeIds()) {
|
||||
return;
|
||||
}
|
||||
Media::addJsDef([
|
||||
'ceMigrate' => self::getJsDef(),
|
||||
]);
|
||||
$context->controller->js_files[] = _MODULE_DIR_ . 'creativeelements/views/js/migrate.js?v=' . _CE_VERSION_;
|
||||
}
|
||||
}
|
||||
|
||||
public static function renderJavaScripts()
|
||||
{
|
||||
$ce_migrate = json_encode(self::getJsDef());
|
||||
|
||||
return CESmarty::sprintf(_CE_TEMPLATES_ . 'admin/admin.tpl', 'ce_inline_script', "
|
||||
$('#module-modal-import .modal-content').hide();
|
||||
window.ceMigrate = $ce_migrate;
|
||||
$.getScript(ceMigrate.baseDir + 'modules/creativeelements/views/js/migrate.js');
|
||||
");
|
||||
}
|
||||
|
||||
public static function moveConfigs()
|
||||
{
|
||||
$table = _DB_PREFIX_ . 'creativepage';
|
||||
// Get old data rows
|
||||
$rows = Db::getInstance()->executeS(
|
||||
"SELECT id_shop, meta_key, meta_value FROM {$table}_meta
|
||||
WHERE id = 0 AND meta_key LIKE 'elementor_scheme_%'"
|
||||
);
|
||||
// Update configs
|
||||
if (!empty($rows)) {
|
||||
foreach ($rows as &$row) {
|
||||
$id_shop = $row['id_shop'];
|
||||
$id_group = Shop::getGroupFromShop($id_shop);
|
||||
|
||||
Configuration::updateValue($row['meta_key'], $row['meta_value'], false, $id_group, $id_shop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static function isMoved($id)
|
||||
{
|
||||
$res = CE\get_post_meta($id, '_ce_migrated', true);
|
||||
|
||||
if (isset($res['started']) && $res['started'] + self::MOVE_TIMEOUT < time()) {
|
||||
return false;
|
||||
}
|
||||
return (bool) $res;
|
||||
}
|
||||
|
||||
private static function startMoving($id)
|
||||
{
|
||||
return CE\update_post_meta($id, '_ce_migrated', [
|
||||
'started' => time(),
|
||||
]);
|
||||
}
|
||||
|
||||
private static function setMoved($id)
|
||||
{
|
||||
return CE\update_post_meta($id, '_ce_migrated', time());
|
||||
}
|
||||
|
||||
public static function moveContent($id, $module)
|
||||
{
|
||||
if (self::isMoved($id)) {
|
||||
return true;
|
||||
} else {
|
||||
self::startMoving($id);
|
||||
}
|
||||
$db = Db::getInstance();
|
||||
$table = _DB_PREFIX_ . 'creativepage';
|
||||
|
||||
// Get old data rows
|
||||
$rows = $db->executeS(
|
||||
"SELECT * FROM $table AS a
|
||||
INNER JOIN {$table}_lang AS b ON a.id = b.id
|
||||
INNER JOIN {$table}_shop AS sa ON a.id = sa.id AND b.id_shop = sa.id_shop
|
||||
WHERE a.id = " . (int) $id
|
||||
);
|
||||
if (empty($rows)) {
|
||||
return false;
|
||||
}
|
||||
$res = true;
|
||||
$id_ce_content = null;
|
||||
$shops = [];
|
||||
// Re-structuring rows
|
||||
foreach ($rows as &$row) {
|
||||
$id_shop = $row['id_shop'];
|
||||
$id_lang = $row['id_lang'];
|
||||
|
||||
if (empty($shops[$id_shop])) {
|
||||
$shops[$id_shop] = $row;
|
||||
$shops[$id_shop]['title'] = [];
|
||||
$shops[$id_shop]['data'] = [];
|
||||
}
|
||||
$shops[$id_shop]['title'][$id_lang] = $row['title'];
|
||||
$shops[$id_shop]['data'][$id_lang] = $row['data'];
|
||||
}
|
||||
foreach ($shops as $id_shop => &$row) {
|
||||
// Create CEContent if needed
|
||||
if (!$row['id_page'] || 'displayFooterProduct' === $row['type']) {
|
||||
// Insert ce_content fields
|
||||
if (!$id_ce_content) {
|
||||
$ce_content = [
|
||||
'id_employee' => (int) $row['id_employee'],
|
||||
'id_product' => (int) $row['id_page'],
|
||||
'hook' => $db->escape($row['type']),
|
||||
'active' => $row['id_page'] ? 1 : (int) $row['active'],
|
||||
'date_add' => $db->escape($row['date_add']),
|
||||
'date_upd' => $db->escape($row['date_upd']),
|
||||
];
|
||||
if (!$db->insert('ce_content', $ce_content)) {
|
||||
return false;
|
||||
}
|
||||
$id_ce_content = $db->insert_ID();
|
||||
|
||||
// Register hook
|
||||
if (!$row['id_page']) {
|
||||
$module->registerHook($ce_content['hook'], array_keys($shops));
|
||||
}
|
||||
}
|
||||
// Insert ce_content_shop fields
|
||||
$ce_content_shop = [
|
||||
'id_ce_content' => (int) $id_ce_content,
|
||||
'id_shop' => (int) $id_shop,
|
||||
'active' => (int) $row['active'],
|
||||
'date_add' => $db->escape($row['date_add']),
|
||||
'date_upd' => $db->escape($row['date_upd']),
|
||||
];
|
||||
if (!$db->insert('ce_content_shop', $ce_content_shop)) {
|
||||
return false;
|
||||
}
|
||||
// Insert ce_content_lang fields
|
||||
foreach ($row['title'] as $id_lang => $title) {
|
||||
$ce_content_lang = [
|
||||
'id_ce_content' => (int) $id_ce_content,
|
||||
'id_lang' => (int) $id_lang,
|
||||
'id_shop' => (int) $id_shop,
|
||||
'title' => $db->escape($title),
|
||||
'content' => '',
|
||||
];
|
||||
if (!$db->insert('ce_content_lang', $ce_content_lang)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$id_page = $id_ce_content;
|
||||
$id_type = CE\UId::CONTENT;
|
||||
} else {
|
||||
$id_page = $row['id_page'];
|
||||
$id_type = CE\UId::getTypeId($row['type']);
|
||||
}
|
||||
// Update meta data
|
||||
foreach ($row['data'] as $id_lang => &$json) {
|
||||
if ($json) {
|
||||
$uid = new CE\UId($id_page, $id_type, $id_lang, $id_shop);
|
||||
$data = json_decode($json, true);
|
||||
|
||||
if ($id_ce_content || $row['id_page'] && $row['active']) {
|
||||
$res &= CE\update_post_meta($uid, '_elementor_edit_mode', 'builder');
|
||||
}
|
||||
$res &= CE\update_post_meta($uid, '_elementor_data', $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
empty($res) or self::setMoved($id);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public static function moveTemplate($id)
|
||||
{
|
||||
if (self::isMoved($id)) {
|
||||
return true;
|
||||
} else {
|
||||
self::startMoving($id);
|
||||
}
|
||||
$db = Db::getInstance();
|
||||
$table = _DB_PREFIX_ . 'creativepage';
|
||||
|
||||
// Get old data row
|
||||
$row = $db->getRow(
|
||||
"SELECT * FROM $table AS a
|
||||
INNER JOIN {$table}_lang AS b ON a.id = b.id AND b.id_lang = 1 AND b.id_shop = 1
|
||||
WHERE a.id = " . (int) $id
|
||||
);
|
||||
if (empty($row)) {
|
||||
return false;
|
||||
}
|
||||
// Insert ce_template fields
|
||||
$res = $db->insert('ce_template', [
|
||||
'id_employee' => (int) $row['id_employee'],
|
||||
'title' => $db->escape($row['title']),
|
||||
'type' => $db->escape($row['type']),
|
||||
'active' => true,
|
||||
'date_add' => $db->escape($row['date_add']),
|
||||
'date_upd' => $db->escape($row['date_upd']),
|
||||
]);
|
||||
// Update meta data
|
||||
if ($res) {
|
||||
$uid = new CE\UId($db->insert_ID(), CE\UId::TEMPLATE);
|
||||
$data = json_decode($row['data'], true);
|
||||
|
||||
$res &= CE\update_post_meta($uid, '_elementor_edit_mode', 'builder');
|
||||
$res &= CE\update_post_meta($uid, '_elementor_data', $data);
|
||||
}
|
||||
empty($res) or self::setMoved($id);
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
34
modules/creativeelements/classes/CERevision.php
Normal file
34
modules/creativeelements/classes/CERevision.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
class CERevision extends ObjectModel
|
||||
{
|
||||
public $parent;
|
||||
public $id_employee;
|
||||
public $title;
|
||||
public $content;
|
||||
public $active;
|
||||
public $date_upd;
|
||||
|
||||
public static $definition = [
|
||||
'table' => 'ce_revision',
|
||||
'primary' => 'id_ce_revision',
|
||||
'fields' => [
|
||||
'parent' => ['type' => self::TYPE_STRING, 'validate' => 'isIp2Long', 'required' => true],
|
||||
'id_employee' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'],
|
||||
'title' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 255],
|
||||
'type' => ['type' => self::TYPE_STRING, 'validate' => 'isHookName', 'size' => 64],
|
||||
'content' => ['type' => self::TYPE_HTML, 'validate' => 'isCleanHtml'],
|
||||
'active' => ['type' => self::TYPE_INT, 'validate' => 'isBool'],
|
||||
'date_upd' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'],
|
||||
],
|
||||
];
|
||||
}
|
||||
173
modules/creativeelements/classes/CESmarty.php
Normal file
173
modules/creativeelements/classes/CESmarty.php
Normal file
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
class CESmarty
|
||||
{
|
||||
protected static $tpls = [];
|
||||
|
||||
protected static function getTemplate($path)
|
||||
{
|
||||
if (isset(self::$tpls[$path])) {
|
||||
return self::$tpls[$path];
|
||||
}
|
||||
|
||||
$tpl = Context::getContext()->smarty->createTemplate($path);
|
||||
CE\do_action('smarty/before_fetch', $tpl->smarty);
|
||||
$tpl->fetch();
|
||||
CE\do_action('smarty/after_fetch', $tpl->smarty);
|
||||
|
||||
return self::$tpls[$path] = $tpl;
|
||||
}
|
||||
|
||||
public static function call($path, $func, array $params = [], $nocache = true)
|
||||
{
|
||||
$tpl = self::getTemplate($path);
|
||||
CE\do_action('smarty/before_call', $tpl->smarty);
|
||||
isset($tpl->smarty->ext->_tplFunction)
|
||||
? $tpl->smarty->ext->_tplFunction->callTemplateFunction($tpl, $func, $params, $nocache)
|
||||
: call_user_func("smarty_template_function_$func", $tpl, $params)
|
||||
;
|
||||
CE\do_action('smarty/after_call', $tpl->smarty);
|
||||
}
|
||||
|
||||
public static function capture($path, $func, array $params = [], $nocache = true)
|
||||
{
|
||||
ob_start();
|
||||
|
||||
self::call($path, $func, $params, $nocache);
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
public static function get($path, $buffer)
|
||||
{
|
||||
$tpl = self::getTemplate($path);
|
||||
|
||||
return isset($tpl->smarty->ext->_capture)
|
||||
? $tpl->smarty->ext->_capture->getBuffer($tpl, $buffer)
|
||||
: Smarty::$_smarty_vars['capture'][$buffer]
|
||||
;
|
||||
}
|
||||
|
||||
public static function write($path, $buffer)
|
||||
{
|
||||
$tpl = self::getTemplate($path);
|
||||
|
||||
echo isset($tpl->smarty->ext->_capture)
|
||||
? $tpl->smarty->ext->_capture->getBuffer($tpl, $buffer)
|
||||
: Smarty::$_smarty_vars['capture'][$buffer]
|
||||
;
|
||||
}
|
||||
|
||||
public static function printf($path, $buffer)
|
||||
{
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
$args[0] = self::get($path, $buffer);
|
||||
|
||||
call_user_func_array(__FUNCTION__, $args);
|
||||
}
|
||||
|
||||
public static function sprintf($path, $buffer)
|
||||
{
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
$args[0] = self::get($path, $buffer);
|
||||
|
||||
return call_user_func_array(__FUNCTION__, $args);
|
||||
}
|
||||
}
|
||||
|
||||
function smartyInclude(array $params)
|
||||
{
|
||||
if (empty($params['file'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$file = $params['file'];
|
||||
|
||||
try {
|
||||
if (strrpos($file, '../') !== false || strcasecmp(Tools::substr($file, -4), '.tpl') !== 0) {
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
if (stripos($file, 'module:') === 0) {
|
||||
$file = Tools::substr($file, 7);
|
||||
|
||||
if (!file_exists($path = _PS_THEME_DIR_ . "modules/$file") &&
|
||||
(!_PARENT_THEME_NAME_ || !file_exists($path = _PS_PARENT_THEME_DIR_ . "modules/$file")) &&
|
||||
!file_exists($path = _PS_MODULE_DIR_ . $file)
|
||||
) {
|
||||
throw new Exception();
|
||||
}
|
||||
} elseif (_PARENT_THEME_NAME_ && stripos($file, 'parent:') === 0) {
|
||||
$file = Tools::substr($file, 7);
|
||||
|
||||
if (!file_exists($path = _PS_PARENT_THEME_DIR_ . "templates/$file")) {
|
||||
throw new Exception();
|
||||
}
|
||||
} elseif (!file_exists($path = _PS_THEME_DIR_ . "templates/$file") &&
|
||||
(!_PARENT_THEME_NAME_ || !file_exists($path = _PS_PARENT_THEME_DIR_ . "templates/$file"))
|
||||
) {
|
||||
throw new Exception();
|
||||
}
|
||||
|
||||
$cache_id = isset($params['cache_id']) ? $params['cache_id'] : null;
|
||||
$compile_id = isset($params['compile_id']) ? $params['compile_id'] : null;
|
||||
unset($params['file'], $params['cache_id'], $params['compile_id']);
|
||||
|
||||
$out = Context::getContext()->smarty->fetch($path, $cache_id, $compile_id, $params);
|
||||
} catch (Exception $ex) {
|
||||
$out = "Failed including: '$file'";
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
function ce__($text, $module = 'creativeelements')
|
||||
{
|
||||
return CE\translate($text, $module);
|
||||
}
|
||||
|
||||
function ce_new($class)
|
||||
{
|
||||
$rc = new ReflectionClass($class);
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
|
||||
return $rc->newInstanceArgs($args);
|
||||
}
|
||||
|
||||
function ce_enqueue_miniature($uid)
|
||||
{
|
||||
static $enqueued = [];
|
||||
|
||||
if (isset($enqueued[$uid])) {
|
||||
return;
|
||||
}
|
||||
$enqueued[$uid] = true;
|
||||
|
||||
$forceInline = Tools::getValue('render') === 'widget';
|
||||
|
||||
if ($forceInline || !Context::getContext()->controller->ajax) {
|
||||
$css_file = new CE\ModulesXCatalogXFilesXCSSXProductMiniature($uid, $forceInline);
|
||||
$css_file->enqueue();
|
||||
}
|
||||
}
|
||||
|
||||
function array_export($array)
|
||||
{
|
||||
echo preg_replace(['/\barray\s*\(/i', '/,\r?(\n\s*)\)/'], ['[', '$1]'], var_export($array, true));
|
||||
}
|
||||
|
||||
function _q_c_($if, $then, $else)
|
||||
{
|
||||
return $if ? $then : $else;
|
||||
}
|
||||
53
modules/creativeelements/classes/CETemplate.php
Normal file
53
modules/creativeelements/classes/CETemplate.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
class CETemplate extends ObjectModel
|
||||
{
|
||||
public $id_employee;
|
||||
public $title;
|
||||
public $type;
|
||||
public $content;
|
||||
public $position;
|
||||
public $active;
|
||||
public $date_add;
|
||||
public $date_upd;
|
||||
|
||||
public static $definition = [
|
||||
'table' => 'ce_template',
|
||||
'primary' => 'id_ce_template',
|
||||
'fields' => [
|
||||
'id_employee' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'],
|
||||
'title' => ['type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 128],
|
||||
'type' => ['type' => self::TYPE_STRING, 'validate' => 'isHookName', 'required' => true, 'size' => 64],
|
||||
'content' => ['type' => self::TYPE_HTML, 'validate' => 'isCleanHtml'],
|
||||
'position' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedInt'],
|
||||
'active' => ['type' => self::TYPE_INT, 'validate' => 'isBool'],
|
||||
'date_add' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'],
|
||||
'date_upd' => ['type' => self::TYPE_DATE, 'validate' => 'isDate'],
|
||||
],
|
||||
];
|
||||
|
||||
public function add($auto_date = true, $null_values = false)
|
||||
{
|
||||
$this->id_employee = Context::getContext()->employee->id;
|
||||
|
||||
return parent::add($auto_date, $null_values);
|
||||
}
|
||||
|
||||
public static function getTypeById($id)
|
||||
{
|
||||
$table = _DB_PREFIX_ . 'ce_template';
|
||||
|
||||
return Db::getInstance()->getValue(
|
||||
"SELECT type FROM $table WHERE id_ce_template = " . (int) $id
|
||||
);
|
||||
}
|
||||
}
|
||||
97
modules/creativeelements/classes/CETheme.php
Normal file
97
modules/creativeelements/classes/CETheme.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
class CETheme extends ObjectModel
|
||||
{
|
||||
public $id_employee;
|
||||
public $title;
|
||||
public $type;
|
||||
public $content;
|
||||
public $position;
|
||||
public $active;
|
||||
public $date_add;
|
||||
public $date_upd;
|
||||
|
||||
public static $definition = [
|
||||
'table' => 'ce_theme',
|
||||
'primary' => 'id_ce_theme',
|
||||
'multilang' => true,
|
||||
'multilang_shop' => true,
|
||||
'fields' => [
|
||||
'id_employee' => ['type' => self::TYPE_INT, 'validate' => 'isUnsignedId'],
|
||||
'type' => ['type' => self::TYPE_STRING, 'validate' => 'isHookName', 'required' => true, 'size' => 64],
|
||||
// Shop fields
|
||||
'position' => ['type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedInt'],
|
||||
'active' => ['type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isBool'],
|
||||
'date_add' => ['type' => self::TYPE_DATE, 'shop' => true, 'validate' => 'isDate'],
|
||||
'date_upd' => ['type' => self::TYPE_DATE, 'shop' => true, 'validate' => 'isDate'],
|
||||
// Lang fields
|
||||
'title' => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 128],
|
||||
'content' => ['type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'],
|
||||
],
|
||||
];
|
||||
|
||||
public function add($auto_date = true, $null_values = false)
|
||||
{
|
||||
$this->id_employee = Context::getContext()->employee->id;
|
||||
|
||||
return parent::add($auto_date, $null_values);
|
||||
}
|
||||
|
||||
public function update($null_values = false)
|
||||
{
|
||||
if ('0000-00-00 00:00:00' === $this->date_add) {
|
||||
$this->date_add = date('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
return parent::update($null_values);
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
$result = parent::delete();
|
||||
|
||||
if ($result && 'product-miniature' === $this->type) {
|
||||
array_map(
|
||||
'unlink',
|
||||
glob(_CE_TEMPLATES_ . "front/theme/catalog/_partials/miniatures/product-{$this->id}17????.tpl")
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function getOptions($type, $id_lang, $id_shop)
|
||||
{
|
||||
$db = Db::getInstance();
|
||||
$table = _DB_PREFIX_ . 'ce_theme';
|
||||
$id_lang = (int) $id_lang;
|
||||
$id_shop = (int) $id_shop;
|
||||
$type = $db->escape($type);
|
||||
$res = $db->executeS(
|
||||
"SELECT t.id_ce_theme as `value`, CONCAT('#', t.id_ce_theme, ' ', tl.title) as `name` FROM $table AS t
|
||||
INNER JOIN {$table}_shop as ts ON t.id_ce_theme = ts.id_ce_theme
|
||||
INNER JOIN {$table}_lang as tl ON t.id_ce_theme = tl.id_ce_theme AND ts.id_shop = tl.id_shop
|
||||
WHERE ts.active = 1 AND ts.id_shop = $id_shop AND tl.id_lang = $id_lang AND t.type = '$type'
|
||||
ORDER BY tl.title"
|
||||
);
|
||||
return $res ?: [];
|
||||
}
|
||||
|
||||
public static function getTypeById($id)
|
||||
{
|
||||
$table = _DB_PREFIX_ . 'ce_theme';
|
||||
|
||||
return Db::getInstance()->getValue(
|
||||
"SELECT type FROM $table WHERE id_ce_theme = " . (int) $id
|
||||
);
|
||||
}
|
||||
}
|
||||
195
modules/creativeelements/classes/assets/CEAssetManager.php
Normal file
195
modules/creativeelements/classes/assets/CEAssetManager.php
Normal file
@@ -0,0 +1,195 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
use PrestaShop\PrestaShop\Adapter\Configuration as ConfigurationAdapter;
|
||||
use PrestaShop\PrestaShop\Core\ConfigurationInterface;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
|
||||
defined('_PS_VERSION_') or exit;
|
||||
|
||||
if (version_compare(_PS_VERSION_, '1.7.7', '<')) {
|
||||
require_once _CE_PATH_ . 'classes/assets/CEStylesheetManager5.php';
|
||||
require_once _CE_PATH_ . 'classes/assets/CEJavascriptManager5.php';
|
||||
} else {
|
||||
require_once _CE_PATH_ . 'classes/assets/CEStylesheetManager.php';
|
||||
require_once _CE_PATH_ . 'classes/assets/CEJavascriptManager.php';
|
||||
}
|
||||
require_once _CE_PATH_ . 'classes/assets/CECccReducer.php';
|
||||
|
||||
class CEAssetManager
|
||||
{
|
||||
protected $controller;
|
||||
|
||||
protected $stylesheetManager;
|
||||
protected $javascriptManager;
|
||||
|
||||
protected $template;
|
||||
|
||||
public static function instance()
|
||||
{
|
||||
static $instance;
|
||||
|
||||
if (null === $instance) {
|
||||
$instance = new self();
|
||||
|
||||
CE\add_action('wp_head', 'wp_enqueue_scripts', 1);
|
||||
CE\do_action('wp_register_scripts');
|
||||
}
|
||||
return $instance;
|
||||
}
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
$ctx = Context::getContext();
|
||||
$config = new ConfigurationAdapter();
|
||||
$this->controller = $ctx->controller;
|
||||
|
||||
$managers = [
|
||||
'stylesheetManager' => 'CEStylesheetManager',
|
||||
'javascriptManager' => 'CEJavascriptManager',
|
||||
];
|
||||
foreach ($managers as $prop => $class) {
|
||||
$managerRef = new ReflectionProperty($this->controller, $prop);
|
||||
$managerRef->setAccessible(true);
|
||||
$manager = $managerRef->getValue($this->controller);
|
||||
|
||||
$listRef = new ReflectionProperty($manager, 'list');
|
||||
$listRef->setAccessible(true);
|
||||
|
||||
$this->$prop = new $class([
|
||||
_PS_THEME_URI_,
|
||||
_PS_PARENT_THEME_URI_,
|
||||
__PS_BASE_URI__,
|
||||
], $config, $listRef->getValue($manager));
|
||||
|
||||
$managerRef->setValue($this->controller, $this->$prop);
|
||||
}
|
||||
|
||||
$reducerRef = new ReflectionProperty($this->controller, 'cccReducer');
|
||||
$reducerRef->setAccessible(true);
|
||||
$this->cccReducer = new CECccReducer(
|
||||
_PS_THEME_DIR_ . 'assets/cache/',
|
||||
$config,
|
||||
new Filesystem()
|
||||
);
|
||||
$reducerRef->setValue($this->controller, $this->cccReducer);
|
||||
|
||||
$this->template = &Closure::bind(function &() {
|
||||
return ${'this'}->template;
|
||||
}, $this->controller, $this->controller)->__invoke();
|
||||
|
||||
$ctx->smarty->registerPlugin('modifier', 'ce' . 'filter', [$this, 'modifierFilter']);
|
||||
$ctx->smarty->registerFilter('output', [$this, 'outputFilter']);
|
||||
}
|
||||
|
||||
public function registerStylesheet($id, $path, array $params = [])
|
||||
{
|
||||
$params = array_merge([
|
||||
'media' => AbstractAssetManager::DEFAULT_MEDIA,
|
||||
'priority' => AbstractAssetManager::DEFAULT_PRIORITY,
|
||||
'inline' => false,
|
||||
'server' => 'local',
|
||||
], $params);
|
||||
|
||||
if (_MEDIA_SERVER_1_ && 'remote' !== $params['server'] && !Configuration::get('PS_CSS_THEME_CACHE')) {
|
||||
$params['server'] = 'remote';
|
||||
$path = '//' . Tools::getMediaServer($path) . ($this->stylesheetManager->getFullPath($path) ?: $path);
|
||||
}
|
||||
$this->stylesheetManager->register($id, $path, $params['media'], $params['priority'], $params['inline'], $params['server']);
|
||||
}
|
||||
|
||||
public function registerJavascript($id, $path, array $params = [])
|
||||
{
|
||||
$params = array_merge([
|
||||
'position' => AbstractAssetManager::DEFAULT_JS_POSITION,
|
||||
'priority' => AbstractAssetManager::DEFAULT_PRIORITY,
|
||||
'inline' => false,
|
||||
'attributes' => null,
|
||||
'server' => 'local',
|
||||
], $params);
|
||||
|
||||
if (_MEDIA_SERVER_1_ && 'remote' !== $params['server'] && !Configuration::get('PS_JS_THEME_CACHE')) {
|
||||
$params['server'] = 'remote';
|
||||
$path = '//' . Tools::getMediaServer($path) . ($this->javascriptManager->getFullPath($path) ?: $path);
|
||||
}
|
||||
$this->javascriptManager->register($id, $path, $params['position'], $params['priority'], $params['inline'], $params['attributes'], $params['server']);
|
||||
}
|
||||
|
||||
public function modifierFilter($str)
|
||||
{
|
||||
echo $str;
|
||||
}
|
||||
|
||||
public function outputFilter($out, $tpl)
|
||||
{
|
||||
if ($this->template === $tpl->template_resource || 'errors/maintenance.tpl' === $tpl->template_resource) {
|
||||
$assets = $this->fetchAssets();
|
||||
|
||||
if (false !== $pos = strpos($out, '<!--CE-JS-->')) {
|
||||
$out = substr_replace($out, $assets->head, $pos, 0);
|
||||
}
|
||||
if (false !== $pos = strrpos($out, '<!--CE-JS-->')) {
|
||||
$out = substr_replace($out, $assets->bottom, $pos, 0);
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function fetchAssets()
|
||||
{
|
||||
$smarty = Context::getContext()->smarty;
|
||||
$assets = new stdClass();
|
||||
|
||||
ob_start();
|
||||
CE\do_action('wp_head');
|
||||
$assets->head = ob_get_clean();
|
||||
|
||||
ob_start();
|
||||
CE\do_action('wp_footer');
|
||||
$assets->bottom = ob_get_clean();
|
||||
|
||||
$styles = $this->stylesheetManager->listAll();
|
||||
|
||||
foreach ($styles['external'] as $id => &$style) {
|
||||
if (isset(CE\Helper::$inline_styles[$id])) {
|
||||
$styles['inline'][$id] = [
|
||||
'content' => implode("\n", CE\Helper::$inline_styles[$id])
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$scripts = $this->javascriptManager->listAll();
|
||||
$js_defs = Media::getJsDef();
|
||||
|
||||
if (!empty($smarty->tpl_vars['js_custom_vars'])) {
|
||||
foreach ($smarty->tpl_vars['js_custom_vars']->value as $key => &$val) {
|
||||
unset($js_defs[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
Configuration::get('PS_CSS_THEME_CACHE') && $styles = $this->cccReducer->reduceCss($styles);
|
||||
Configuration::get('PS_JS_THEME_CACHE') && $scripts = $this->cccReducer->reduceJs($scripts);
|
||||
|
||||
$smarty->assign([
|
||||
'stylesheets' => &$styles,
|
||||
'javascript' => &$scripts['head'],
|
||||
'js_custom_vars' => &$js_defs,
|
||||
]);
|
||||
$assets->head = $smarty->fetch(_CE_TEMPLATES_ . 'front/theme/_partials/assets.tpl') . $assets->head;
|
||||
|
||||
$smarty->assign([
|
||||
'stylesheets' => [],
|
||||
'javascript' => &$scripts['bottom'],
|
||||
'js_custom_vars' => [],
|
||||
]);
|
||||
$assets->bottom = $smarty->fetch(_CE_TEMPLATES_ . 'front/theme/_partials/assets.tpl') . $assets->bottom;
|
||||
|
||||
return $assets;
|
||||
}
|
||||
}
|
||||
28
modules/creativeelements/classes/assets/CECccReducer.php
Normal file
28
modules/creativeelements/classes/assets/CECccReducer.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or exit;
|
||||
|
||||
class CECccReducer extends CccReducer
|
||||
{
|
||||
public function reduceCss($cssFileList)
|
||||
{
|
||||
return empty($cssFileList['external']) ? $cssFileList : parent::reduceCss($cssFileList);
|
||||
}
|
||||
|
||||
protected function getPathFromUri($fullUri)
|
||||
{
|
||||
$fullUri = explode('?', $fullUri, 2)[0];
|
||||
|
||||
if (__PS_BASE_URI__ !== '/' && stripos($fullUri, __PS_BASE_URI__) === 0) {
|
||||
return _PS_ROOT_DIR_ . substr($fullUri, strlen(__PS_BASE_URI__) - 1);
|
||||
}
|
||||
return _PS_ROOT_DIR_ . $fullUri;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
use PrestaShop\PrestaShop\Core\ConfigurationInterface;
|
||||
|
||||
defined('_PS_VERSION_') or exit;
|
||||
|
||||
class CEJavascriptManager extends JavascriptManager
|
||||
{
|
||||
public function __construct(array $directories, ConfigurationInterface $configuration, $list = null)
|
||||
{
|
||||
parent::__construct($directories, $configuration);
|
||||
|
||||
is_null($list) or $this->list = $list;
|
||||
}
|
||||
|
||||
public function getFullPath(string $relativePath)
|
||||
{
|
||||
if (strrpos($relativePath, '?') !== false) {
|
||||
$path = explode('?', $relativePath, 2);
|
||||
$fullPath = parent::getFullPath($path[0]);
|
||||
|
||||
return $fullPath ? "$fullPath?$path[1]" : false;
|
||||
}
|
||||
return parent::getFullPath($relativePath);
|
||||
}
|
||||
|
||||
public function getList()
|
||||
{
|
||||
return parent::getDefaultList();
|
||||
}
|
||||
|
||||
public function listAll()
|
||||
{
|
||||
return parent::getList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
use PrestaShop\PrestaShop\Core\ConfigurationInterface;
|
||||
|
||||
defined('_PS_VERSION_') or exit;
|
||||
|
||||
class CEJavascriptManager extends JavascriptManager
|
||||
{
|
||||
public function __construct(array $directories, ConfigurationInterface $configuration, $list = null)
|
||||
{
|
||||
parent::__construct($directories, $configuration);
|
||||
|
||||
is_null($list) or $this->list = $list;
|
||||
}
|
||||
|
||||
public function getFullPath($relativePath)
|
||||
{
|
||||
if (strrpos($relativePath, '?') !== false) {
|
||||
$path = explode('?', $relativePath, 2);
|
||||
$fullPath = parent::getFullPath($path[0]);
|
||||
|
||||
return $fullPath ? "$fullPath?$path[1]" : false;
|
||||
}
|
||||
return parent::getFullPath($relativePath);
|
||||
}
|
||||
|
||||
public function getList()
|
||||
{
|
||||
return parent::getDefaultList();
|
||||
}
|
||||
|
||||
public function listAll()
|
||||
{
|
||||
return parent::getList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
use PrestaShop\PrestaShop\Core\ConfigurationInterface;
|
||||
|
||||
defined('_PS_VERSION_') or exit;
|
||||
|
||||
class CEStylesheetManager extends StylesheetManager
|
||||
{
|
||||
public function __construct(array $directories, ConfigurationInterface $configuration, $list = null)
|
||||
{
|
||||
parent::__construct($directories, $configuration);
|
||||
|
||||
is_null($list) or $this->list = $list;
|
||||
}
|
||||
|
||||
public function getFullPath(string $relativePath)
|
||||
{
|
||||
if (strrpos($relativePath, '?') !== false) {
|
||||
$path = explode('?', $relativePath, 2);
|
||||
$fullPath = parent::getFullPath($path[0]);
|
||||
|
||||
return $fullPath ? "$fullPath?$path[1]" : false;
|
||||
}
|
||||
return parent::getFullPath($relativePath);
|
||||
}
|
||||
|
||||
public function getList()
|
||||
{
|
||||
return parent::getDefaultList();
|
||||
}
|
||||
|
||||
public function listAll()
|
||||
{
|
||||
return parent::getList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
use PrestaShop\PrestaShop\Core\ConfigurationInterface;
|
||||
|
||||
defined('_PS_VERSION_') or exit;
|
||||
|
||||
class CEStylesheetManager extends StylesheetManager
|
||||
{
|
||||
public function __construct(array $directories, ConfigurationInterface $configuration, $list = null)
|
||||
{
|
||||
parent::__construct($directories, $configuration);
|
||||
|
||||
is_null($list) or $this->list = $list;
|
||||
}
|
||||
|
||||
public function getFullPath($relativePath)
|
||||
{
|
||||
if (strrpos($relativePath, '?') !== false) {
|
||||
$path = explode('?', $relativePath, 2);
|
||||
$fullPath = parent::getFullPath($path[0]);
|
||||
|
||||
return $fullPath ? "$fullPath?$path[1]" : false;
|
||||
}
|
||||
return parent::getFullPath($relativePath);
|
||||
}
|
||||
|
||||
public function getList()
|
||||
{
|
||||
return parent::getDefaultList();
|
||||
}
|
||||
|
||||
public function listAll()
|
||||
{
|
||||
return parent::getList();
|
||||
}
|
||||
}
|
||||
8
modules/creativeelements/classes/assets/index.php
Normal file
8
modules/creativeelements/classes/assets/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../');
|
||||
die;
|
||||
16
modules/creativeelements/classes/index.php
Normal file
16
modules/creativeelements/classes/index.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../');
|
||||
die;
|
||||
52
modules/creativeelements/classes/wrappers/Error.php
Normal file
52
modules/creativeelements/classes/wrappers/Error.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
class WPError
|
||||
{
|
||||
private $code;
|
||||
|
||||
private $message;
|
||||
|
||||
public function __construct($code = '', $message = '', $data = '')
|
||||
{
|
||||
if (!$code) {
|
||||
return;
|
||||
}
|
||||
if ($data) {
|
||||
throw new \RuntimeException('todo');
|
||||
}
|
||||
$this->code = $code;
|
||||
$this->message = $message;
|
||||
}
|
||||
|
||||
public function getErrorMessage($code = '')
|
||||
{
|
||||
if (!$this->code) {
|
||||
return '';
|
||||
}
|
||||
if ($code) {
|
||||
throw new \RuntimeException('todo');
|
||||
}
|
||||
return $this->code . ($this->message ? " - {$this->message}" : '');
|
||||
}
|
||||
}
|
||||
|
||||
function is_wp_error($error)
|
||||
{
|
||||
return $error instanceof WPError;
|
||||
}
|
||||
|
||||
function _doing_it_wrong($function, $message = '', $version = '')
|
||||
{
|
||||
die(\Tools::displayError($function . ' was called incorrectly. ' . $message . ' ' . $version));
|
||||
}
|
||||
1117
modules/creativeelements/classes/wrappers/Helper.php
Normal file
1117
modules/creativeelements/classes/wrappers/Helper.php
Normal file
File diff suppressed because it is too large
Load Diff
625
modules/creativeelements/classes/wrappers/Post.php
Normal file
625
modules/creativeelements/classes/wrappers/Post.php
Normal file
@@ -0,0 +1,625 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
class WPPost
|
||||
{
|
||||
private $id;
|
||||
private $uid;
|
||||
private $model;
|
||||
|
||||
public $_obj;
|
||||
|
||||
public $post_author = 0;
|
||||
public $post_parent = 0;
|
||||
public $post_date = '';
|
||||
public $post_modified = '';
|
||||
public $post_title = '';
|
||||
public $post_excerpt = '';
|
||||
public $post_content = '';
|
||||
public $template_type = 'post';
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public function __get($prop)
|
||||
{
|
||||
switch ($prop) {
|
||||
case 'uid':
|
||||
$val = $this->uid;
|
||||
break;
|
||||
case 'ID':
|
||||
case 'post_ID':
|
||||
$val = $this->id;
|
||||
break;
|
||||
case 'post_type':
|
||||
$val = $this->model;
|
||||
break;
|
||||
case 'post_status':
|
||||
$active = property_exists($this->_obj, 'active') ? 'active' : (
|
||||
property_exists($this->_obj, 'enabled') ? 'enabled' : 'actif'
|
||||
);
|
||||
$val = $this->_obj->$active ? 'publish' : 'private';
|
||||
break;
|
||||
default:
|
||||
throw new \RuntimeException('Unknown property: ' . $prop);
|
||||
}
|
||||
return $val;
|
||||
}
|
||||
|
||||
public function __set($prop, $val)
|
||||
{
|
||||
switch ($prop) {
|
||||
case 'ID':
|
||||
case 'post_ID':
|
||||
// allow change only when starts with zero
|
||||
empty($this->id[0]) && $this->id = "$val";
|
||||
break;
|
||||
case 'post_type':
|
||||
// readonly
|
||||
break;
|
||||
case 'post_status':
|
||||
$active = property_exists($this->_obj, 'active') ? 'active' : 'actif';
|
||||
$this->_obj->$active = 'publish' == $val;
|
||||
break;
|
||||
default:
|
||||
throw new \RuntimeException('Unknown property: ' . $prop);
|
||||
}
|
||||
}
|
||||
|
||||
public function getLangId()
|
||||
{
|
||||
return (int) \Tools::substr($this->id, -4, 2);
|
||||
}
|
||||
|
||||
public static function getInstance(UId $uid, array &$postarr = null)
|
||||
{
|
||||
$self = new self();
|
||||
$self->id = "$uid";
|
||||
$self->uid = $uid;
|
||||
$self->model = $uid->getModel();
|
||||
$objectModel = '\\' . $self->model;
|
||||
|
||||
if ($postarr) {
|
||||
$obj = (object) $postarr;
|
||||
} elseif ($uid->id_type <= UId::TEMPLATE) {
|
||||
$obj = new $objectModel($uid->id ? $uid->id : null);
|
||||
} elseif ($uid->id_type === UId::PRODUCT) {
|
||||
$obj = new \Product($uid->id, false, $uid->id_lang, $uid->id_shop);
|
||||
} else {
|
||||
$obj = new $objectModel($uid->id, $uid->id_lang, $uid->id_shop);
|
||||
}
|
||||
$self->_obj = $obj;
|
||||
|
||||
if (in_array($uid->id_type, [UId::REVISION, UId::TEMPLATE, UId::THEME])) {
|
||||
$self->template_type = &$obj->type;
|
||||
} elseif ($uid->id_type === UId::CONTENT) {
|
||||
$self->template_type = 'content';
|
||||
}
|
||||
|
||||
property_exists($obj, 'id_employee') && $self->post_author = &$obj->id_employee;
|
||||
property_exists($obj, 'parent') && $self->post_parent = &$obj->parent;
|
||||
property_exists($obj, 'date_add') && $self->post_date = &$obj->date_add;
|
||||
property_exists($obj, 'date_upd') && $self->post_modified = &$obj->date_upd;
|
||||
|
||||
if (property_exists($obj, 'title')) {
|
||||
$self->post_title = &$obj->title;
|
||||
} elseif (property_exists($obj, 'name')) {
|
||||
$self->post_title = &$obj->name;
|
||||
} elseif (property_exists($obj, 'meta_title')) {
|
||||
$self->post_title = &$obj->meta_title;
|
||||
}
|
||||
|
||||
if (property_exists($obj, 'content')) {
|
||||
$self->post_content = &$obj->content;
|
||||
} elseif (property_exists($obj, 'description')) {
|
||||
$self->post_content = &$obj->description;
|
||||
} elseif (property_exists($obj, 'post_content')) {
|
||||
$self->post_content = &$obj->post_content;
|
||||
}
|
||||
return $self;
|
||||
}
|
||||
}
|
||||
|
||||
function get_post($post = null, $output = 'OBJECT', $filter = 'raw')
|
||||
{
|
||||
if (null === $post || 0 === $post) {
|
||||
$post = get_the_ID();
|
||||
}
|
||||
|
||||
if (false === $post || $post instanceof WPPost) {
|
||||
$_post = $post;
|
||||
} elseif ($post instanceof UId) {
|
||||
$_post = WPPost::getInstance($post);
|
||||
} elseif (is_numeric($post)) {
|
||||
$_post = WPPost::getInstance(UId::parse($post));
|
||||
} else {
|
||||
_doing_it_wrong(__CLASS__ . '::' . __FUNCTION__, 'Invalid $post argument!');
|
||||
}
|
||||
|
||||
if (!$_post) {
|
||||
return null;
|
||||
}
|
||||
if ('OBJECT' !== $output || 'raw' !== $filter) {
|
||||
throw new \RuntimeException('todo');
|
||||
}
|
||||
return $_post;
|
||||
}
|
||||
|
||||
function get_post_status($post = null)
|
||||
{
|
||||
if ($_post = get_post($post)) {
|
||||
return $_post->post_status;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function wp_update_post($postarr = [], $wp_error = false)
|
||||
{
|
||||
if (is_array($postarr)) {
|
||||
$id_key = isset($postarr['ID']) ? 'ID' : 'post_ID';
|
||||
|
||||
if (empty($postarr[$id_key])) {
|
||||
_doing_it_wrong(__FUNCTION__, 'ID is missing!');
|
||||
}
|
||||
$post = get_post($postarr[$id_key]);
|
||||
|
||||
foreach ($postarr as $key => $value) {
|
||||
$post->$key = $value;
|
||||
}
|
||||
} elseif ($postarr instanceof WPPost) {
|
||||
$post = $postarr;
|
||||
}
|
||||
|
||||
if (!isset($post) || $wp_error) {
|
||||
throw new \RuntimeException('TODO');
|
||||
}
|
||||
// Fix for required lang properties must be defined on default language
|
||||
$id_lang_def = \Configuration::get('PS_LANG_DEFAULT');
|
||||
\Configuration::set('PS_LANG_DEFAULT', $post->uid->id_lang);
|
||||
|
||||
try {
|
||||
// Fix: category groups would lose after save
|
||||
if ($post->_obj instanceof \Category) {
|
||||
$post->_obj->groupBox = $post->_obj->getGroups();
|
||||
}
|
||||
$res = @$post->_obj->update();
|
||||
} catch (\Exception $ex) {
|
||||
$res = false;
|
||||
}
|
||||
\Configuration::set('PS_LANG_DEFAULT', $id_lang_def);
|
||||
|
||||
return $res ? $post->ID : 0;
|
||||
}
|
||||
|
||||
function wp_insert_post(array $postarr, $wp_error = false)
|
||||
{
|
||||
$is_revision = 'CERevision' === $postarr['post_type'];
|
||||
|
||||
if ($wp_error || !$is_revision && 'CETemplate' != $postarr['post_type']) {
|
||||
throw new \RuntimeException('TODO');
|
||||
}
|
||||
$uid = new UId(0, $is_revision ? UId::REVISION : UId::TEMPLATE);
|
||||
$post = WPPost::getInstance($uid);
|
||||
$postarr['post_author'] = \Context::getContext()->employee->id;
|
||||
|
||||
foreach ($postarr as $key => &$value) {
|
||||
$post->$key = $value;
|
||||
}
|
||||
if ($post->_obj->add()) {
|
||||
$uid->id = $post->_obj->id;
|
||||
$post->ID = "$uid";
|
||||
} else {
|
||||
$post->ID = 0;
|
||||
}
|
||||
return $post->ID;
|
||||
}
|
||||
|
||||
function wp_delete_post($postid, $force_delete = false)
|
||||
{
|
||||
$post = get_post($postid);
|
||||
|
||||
return $post->_obj->delete() || $force_delete ? $post : false;
|
||||
}
|
||||
|
||||
function get_post_meta($id, $key = '', $single = false)
|
||||
{
|
||||
if (false === $id) {
|
||||
return $id;
|
||||
}
|
||||
$table = _DB_PREFIX_ . 'ce_meta';
|
||||
$id = ($uid = UId::parse($id)) ? $uid->toDefault() : preg_replace('/\D+/', '', $id);
|
||||
|
||||
if (!is_numeric($id)) {
|
||||
_doing_it_wrong(__FUNCTION__, 'Id must be numeric!');
|
||||
}
|
||||
if (!$key) {
|
||||
$res = [];
|
||||
$rows = \Db::getInstance()->executeS("SELECT name, value FROM $table WHERE id = $id");
|
||||
|
||||
if (!empty($rows)) {
|
||||
foreach ($rows as &$row) {
|
||||
$key = &$row['name'];
|
||||
$val = &$row['value'];
|
||||
|
||||
isset($res[$key]) or $res[$key] = [];
|
||||
$res[$key][] = isset($val[0]) && ('{' == $val[0] || '[' == $val[0] || '"' == $val[0]) ? json_decode($val, true) : $val;
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
$key = preg_replace('/\W+/', '', $key);
|
||||
|
||||
if (!$single) {
|
||||
throw new \RuntimeException('TODO');
|
||||
}
|
||||
$val = \Db::getInstance()->getValue("SELECT value FROM $table WHERE id = $id AND name = '$key'");
|
||||
|
||||
return isset($val[0]) && ('{' == $val[0] || '[' == $val[0] || '"' == $val[0]) ? json_decode($val, true) : $val;
|
||||
}
|
||||
|
||||
function update_post_meta($id, $key, $value, $prev_value = '')
|
||||
{
|
||||
if ($prev_value) {
|
||||
throw new \RuntimeException('TODO');
|
||||
}
|
||||
$db = \Db::getInstance();
|
||||
$table = _DB_PREFIX_ . 'ce_meta';
|
||||
$res = true;
|
||||
$ids = ($uid = UId::parse($id)) ? $uid->getListByShopContext() : (array) $id;
|
||||
$data = [
|
||||
'name' => preg_replace('/\W+/', '', $key),
|
||||
'value' => $db->escape(is_array($value) || is_object($value) ? json_encode($value) : $value, true),
|
||||
];
|
||||
foreach ($ids as $id) {
|
||||
$data['id'] = preg_replace('/\D+/', '', $id);
|
||||
$id_ce_meta = $db->getValue("SELECT id_ce_meta FROM $table WHERE id = {$data['id']} AND name = '{$data['name']}'");
|
||||
|
||||
if ($id_ce_meta) {
|
||||
$data['id_ce_meta'] = (int) $id_ce_meta;
|
||||
$type = \Db::REPLACE;
|
||||
} else {
|
||||
unset($data['id_ce_meta']);
|
||||
$type = \Db::INSERT;
|
||||
}
|
||||
$res &= $db->insert($table, $data, false, true, $type, false);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
function delete_post_meta($id, $key, $value = '')
|
||||
{
|
||||
if ($value) {
|
||||
throw new \RuntimeException('TODO');
|
||||
}
|
||||
$ids = ($uid = UId::parse($id)) ? $uid->getListByShopContext() : (array) $id;
|
||||
|
||||
foreach ($ids as &$id) {
|
||||
$id = preg_replace('/\D+/', '', $id);
|
||||
}
|
||||
if (count($ids) > 1) {
|
||||
$in = 'IN';
|
||||
$ids = '(' . implode(', ', $ids) . ')';
|
||||
} else {
|
||||
$in = '=';
|
||||
$ids = $ids[0];
|
||||
}
|
||||
$key = preg_replace('/[^\w\%]+/', '', $key);
|
||||
$like = strrpos($key, '%') === false ? '=' : 'LIKE';
|
||||
|
||||
return \Db::getInstance()->delete('ce_meta', "id $in $ids AND name $like '$key'");
|
||||
}
|
||||
|
||||
function get_post_type($post = null)
|
||||
{
|
||||
$uid = uidval($post, null);
|
||||
|
||||
return $uid ? $uid->getModel() : false;
|
||||
}
|
||||
|
||||
function get_post_type_object($post_type)
|
||||
{
|
||||
// todo
|
||||
return !$post_type ? null : (object) [
|
||||
'cap' => (object) [
|
||||
'edit_post' => 'edit',
|
||||
'edit_posts' => 'edit',
|
||||
'publish_posts' => 'edit',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
function current_user_can($capability, $args = null)
|
||||
{
|
||||
if (is_admin()) {
|
||||
$employee = \Context::getContext()->employee;
|
||||
} elseif ($id_employee = get_current_user_id()) {
|
||||
$employee = new \Employee($id_employee);
|
||||
}
|
||||
|
||||
if (empty($employee->id_profile)) {
|
||||
return false;
|
||||
}
|
||||
if ('manage_options' === $capability) {
|
||||
return true;
|
||||
}
|
||||
if ($uid = uidval($args, false)) {
|
||||
$controller = $uid->getAdminController();
|
||||
} elseif (stripos($args, 'Admin') === 0) {
|
||||
$controller = $args;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ('AdminModules' === $controller) {
|
||||
$id_module = \Module::getModuleIdByName($uid->getModule());
|
||||
$action = 'view' === $capability ?: 'configure';
|
||||
$result = \Module::getPermissionStatic($id_module, $action, $employee);
|
||||
} else {
|
||||
$id_tab = \Tab::getIdFromClassName($controller);
|
||||
$access = \Profile::getProfileAccess($employee->id_profile, $id_tab);
|
||||
$result = '1' === $access[$capability];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function wp_set_post_lock($post_id)
|
||||
{
|
||||
if (!$user_id = get_current_user_id()) {
|
||||
return false;
|
||||
}
|
||||
$now = time();
|
||||
|
||||
update_post_meta($post_id, '_edit_lock', "$now:$user_id");
|
||||
|
||||
return [$now, $user_id];
|
||||
}
|
||||
|
||||
function wp_check_post_lock($post_id)
|
||||
{
|
||||
if (!$lock = get_post_meta($post_id, '_edit_lock', true)) {
|
||||
return false;
|
||||
}
|
||||
list($time, $user) = explode(':', $lock);
|
||||
|
||||
if (empty($user)) {
|
||||
return false;
|
||||
}
|
||||
$time_window = apply_filters('wp_check_post_lock_window', 150);
|
||||
|
||||
if ($time && $time > time() - $time_window && $user != get_current_user_id()) {
|
||||
return (int) $user;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function wp_create_post_autosave(array $post_data)
|
||||
{
|
||||
$post_id = isset($post_data['ID']) ? $post_data['ID'] : $post_data['post_ID'];
|
||||
|
||||
unset($post_data['ID'], $post_data['post_ID']);
|
||||
|
||||
// Autosave already deleted in saveEditor method
|
||||
$autosave = wp_get_post_autosave($post_id, get_current_user_id());
|
||||
|
||||
if ($autosave) {
|
||||
foreach ($post_data as $key => $value) {
|
||||
$autosave->$key = $value;
|
||||
}
|
||||
return $autosave->_obj->update() ? $autosave->ID : 0;
|
||||
}
|
||||
$post_data['post_type'] = 'CERevision';
|
||||
$post_data['post_status'] = 'private';
|
||||
$post_data['post_parent'] = $post_id;
|
||||
|
||||
$autosave_id = wp_insert_post($post_data);
|
||||
|
||||
if ($autosave_id) {
|
||||
do_action('_wp_put_post_revision', $autosave_id);
|
||||
|
||||
return $autosave_id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function wp_is_post_autosave($post)
|
||||
{
|
||||
$uid = uidval($post);
|
||||
|
||||
if (UId::REVISION !== $uid->id_type) {
|
||||
return false;
|
||||
}
|
||||
$table = _DB_PREFIX_ . 'ce_revision';
|
||||
|
||||
return \Db::getInstance()->getValue(
|
||||
"SELECT parent FROM $table WHERE id_ce_revision = {$uid->id} AND active = 0"
|
||||
);
|
||||
}
|
||||
|
||||
function wp_get_post_autosave($post_id, $user_id = 0)
|
||||
{
|
||||
$uid = uidval($post_id);
|
||||
|
||||
if (UId::REVISION === $uid->id_type) {
|
||||
return false;
|
||||
}
|
||||
$table = _DB_PREFIX_ . 'ce_revision';
|
||||
$parent = $uid->toDefault();
|
||||
$id_employee = (int) ($user_id ? $user_id : get_current_user_id());
|
||||
|
||||
$id = \Db::getInstance()->getValue(
|
||||
"SELECT id_ce_revision FROM $table WHERE parent = $parent AND active = 0 AND id_employee = $id_employee"
|
||||
);
|
||||
return $id ? WPPost::getInstance(new UId($id, UId::REVISION)) : false;
|
||||
}
|
||||
|
||||
function wp_get_post_parent_id($post_id)
|
||||
{
|
||||
if (!$post = get_post($post_id)) {
|
||||
return false;
|
||||
}
|
||||
return !empty($post->_obj->parent) ? $post->_obj->parent : 0;
|
||||
}
|
||||
|
||||
function wp_get_post_revisions($post_id, $args = null)
|
||||
{
|
||||
$uid = uidval($post_id);
|
||||
$parent = $uid->toDefault();
|
||||
$revisions = [];
|
||||
$table = _DB_PREFIX_ . 'ce_revision';
|
||||
$fields = !empty($args['fields']) && 'ids' === $args['fields'] ? 'id_ce_revision' : '*';
|
||||
$id_employee = (int) \Context::getContext()->employee->id;
|
||||
$limit = !empty($args['posts_per_page']) ? 'LIMIT 1, ' . (int) $args['posts_per_page'] : '';
|
||||
|
||||
$rows = \Db::getInstance()->executeS(
|
||||
"SELECT $fields FROM $table
|
||||
WHERE parent = $parent AND (active = 1 OR id_employee = $id_employee)
|
||||
ORDER BY date_upd DESC $limit"
|
||||
);
|
||||
if ($rows) {
|
||||
foreach ($rows as &$row) {
|
||||
$uid = new UId($row['id_ce_revision'], UId::REVISION);
|
||||
|
||||
if ('*' === $fields) {
|
||||
$row['id'] = $row['id_ce_revision'];
|
||||
$revisions[] = WPPost::getInstance($uid, $row);
|
||||
} else {
|
||||
$revisions[] = "$uid";
|
||||
}
|
||||
}
|
||||
}
|
||||
return $revisions;
|
||||
}
|
||||
|
||||
function wp_is_post_revision($post)
|
||||
{
|
||||
$revision = get_post($post);
|
||||
|
||||
return !empty($revision->_obj->parent) ? $revision->_obj->parent : false;
|
||||
}
|
||||
|
||||
function wp_save_post_revision(WPPost $post)
|
||||
{
|
||||
if (UId::REVISION === $post->uid->id_type) {
|
||||
return;
|
||||
}
|
||||
|
||||
$revisions_to_keep = (int) \Configuration::get('elementor_max_revisions');
|
||||
|
||||
if (!$revisions_to_keep) {
|
||||
return;
|
||||
}
|
||||
|
||||
$db = \Db::getInstance();
|
||||
$table = _DB_PREFIX_ . 'ce_revision';
|
||||
$id_employee = \Context::getContext()->employee->id;
|
||||
|
||||
foreach (array_reverse($post->uid->getListByShopContext(true)) as $parent) {
|
||||
$revisions = $db->executeS(
|
||||
"SELECT id_ce_revision AS id FROM $table WHERE parent = $parent AND active = 1 ORDER BY date_upd DESC"
|
||||
);
|
||||
$return = wp_insert_post([
|
||||
'post_type' => 'CERevision',
|
||||
'post_status' => 'publish',
|
||||
'post_author' => $id_employee,
|
||||
'post_parent' => "$parent",
|
||||
'post_title' => $post->post_title,
|
||||
'post_content' => $post->post_content,
|
||||
'template_type' => $post->template_type,
|
||||
]);
|
||||
if (!$return) {
|
||||
$return = 0;
|
||||
continue;
|
||||
}
|
||||
do_action('_wp_put_post_revision', $return);
|
||||
|
||||
for ($i = $revisions_to_keep - 1; isset($revisions[$i]); $i++) {
|
||||
wp_delete_post_revision(new UId($revisions[$i]['id'], UId::REVISION));
|
||||
}
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
function wp_delete_post_revision($revision_id)
|
||||
{
|
||||
$revision = get_post($revision_id);
|
||||
|
||||
if ('CERevision' !== $revision->post_type) {
|
||||
return false;
|
||||
}
|
||||
return $revision->_obj->delete();
|
||||
}
|
||||
|
||||
function get_post_statuses()
|
||||
{
|
||||
return [
|
||||
'private' => __('Disabled'),
|
||||
'publish' => __('Enabled'),
|
||||
];
|
||||
}
|
||||
|
||||
function get_page_templates(WPPost $post = null, $post_type = 'CMS')
|
||||
{
|
||||
$templates = [];
|
||||
|
||||
foreach (\Context::getContext()->shop->theme->get('meta.available_layouts') as $name => &$layout) {
|
||||
$templates[$name] = 'layout-full-width' === $name ? __('One Column') : $layout['name'];
|
||||
}
|
||||
$post_type = $post ? $post->post_type : $post_type;
|
||||
|
||||
if ('Product' === $post_type && \Configuration::get('CE_PRODUCT')) {
|
||||
$templates = [];
|
||||
}
|
||||
|
||||
return apply_filters("theme_{$post_type}_templates", $templates, $post);
|
||||
}
|
||||
|
||||
function current_theme_supports()
|
||||
{
|
||||
// todo
|
||||
return false;
|
||||
}
|
||||
|
||||
function get_post_types_by_support($feature, $operator = 'and')
|
||||
{
|
||||
if ('elementor' !== $feature || 'and' !== $operator) {
|
||||
throw new \RuntimeException('TODO');
|
||||
}
|
||||
return [
|
||||
'CETemplate',
|
||||
'CETheme',
|
||||
'CMS',
|
||||
'CMSCategory',
|
||||
];
|
||||
}
|
||||
|
||||
function post_type_supports($post_type, $feature)
|
||||
{
|
||||
if ('elementor' === $feature) {
|
||||
return true;
|
||||
}
|
||||
if ('excerpt' === $feature) {
|
||||
return false;
|
||||
}
|
||||
throw new \RuntimeException('TODO: ' . $feature);
|
||||
}
|
||||
|
||||
function post_type_exists($post_type)
|
||||
{
|
||||
return UId::getTypeId($post_type) >= 0 ? true : false;
|
||||
}
|
||||
|
||||
function setup_postdata($uid)
|
||||
{
|
||||
UId::$_ID = uidval($uid);
|
||||
}
|
||||
574
modules/creativeelements/classes/wrappers/UId.php
Normal file
574
modules/creativeelements/classes/wrappers/UId.php
Normal file
@@ -0,0 +1,574 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
/**
|
||||
* Unique Identifier
|
||||
*/
|
||||
class UId
|
||||
{
|
||||
const REVISION = 0;
|
||||
const TEMPLATE = 1;
|
||||
const CONTENT = 2;
|
||||
const PRODUCT = 3;
|
||||
const CATEGORY = 4;
|
||||
const MANUFACTURER = 5;
|
||||
const SUPPLIER = 6;
|
||||
const CMS = 7;
|
||||
const CMS_CATEGORY = 8;
|
||||
const YBC_BLOG_POST = 9;
|
||||
const XIPBLOG_POST = 10;
|
||||
const STBLOG_POST = 11;
|
||||
const ADVANCEBLOG_POST = 12;
|
||||
const PRESTABLOG_POST = 13;
|
||||
/** @deprecated */
|
||||
const SIMPLEBLOG_POST = 14;
|
||||
const PSBLOG_POST = 15;
|
||||
const HIBLOG_POST = 16;
|
||||
const THEME = 17;
|
||||
const TVCMSBLOG_POST = 18;
|
||||
|
||||
public $id;
|
||||
public $id_type;
|
||||
public $id_lang;
|
||||
public $id_shop;
|
||||
|
||||
private static $models = [
|
||||
'CERevision',
|
||||
'CETemplate',
|
||||
'CEContent',
|
||||
'Product',
|
||||
'Category',
|
||||
'Manufacturer',
|
||||
'Supplier',
|
||||
'CMS',
|
||||
'CMSCategory',
|
||||
'Ybc_blog_post_class',
|
||||
'XipPostsClass',
|
||||
'StBlogClass',
|
||||
'BlogPosts',
|
||||
'NewsClass',
|
||||
'SimpleBlogPost',
|
||||
'PsBlogBlog',
|
||||
'HiBlogPost',
|
||||
'CETheme',
|
||||
'TvcmsPostsClass',
|
||||
];
|
||||
private static $admins = [
|
||||
'AdminCEEditor',
|
||||
'AdminCETemplates',
|
||||
'AdminCEContent',
|
||||
'AdminProducts',
|
||||
'AdminCategories',
|
||||
'AdminManufacturers',
|
||||
'AdminSuppliers',
|
||||
'AdminCmsContent',
|
||||
'AdminCmsContent',
|
||||
'AdminModules',
|
||||
'AdminXipPost',
|
||||
'AdminStBlog',
|
||||
'AdminBlogPosts',
|
||||
'AdminModules',
|
||||
'AdminSimpleBlogPosts',
|
||||
'AdminPsblogBlogs',
|
||||
'AdminModules',
|
||||
'AdminCEThemes',
|
||||
'AdminTvcmsPost',
|
||||
];
|
||||
private static $modules = [
|
||||
self::YBC_BLOG_POST => 'ybc_blog',
|
||||
self::XIPBLOG_POST => 'xipblog',
|
||||
self::STBLOG_POST => 'stblog',
|
||||
self::ADVANCEBLOG_POST => 'advanceblog',
|
||||
self::PRESTABLOG_POST => 'prestablog',
|
||||
self::SIMPLEBLOG_POST => 'ph_simpleblog',
|
||||
self::PSBLOG_POST => 'psblog',
|
||||
self::HIBLOG_POST => 'hiblog',
|
||||
self::TVCMSBLOG_POST => 'tvcmsblog',
|
||||
];
|
||||
private static $shop_ids = [];
|
||||
|
||||
public static $_ID;
|
||||
|
||||
public function __construct($id, $id_type, $id_lang = null, $id_shop = null)
|
||||
{
|
||||
$this->id = abs((int) $id);
|
||||
$this->id_type = abs($id_type % 100);
|
||||
|
||||
if ($this->id_type <= self::TEMPLATE) {
|
||||
$this->id_lang = 0;
|
||||
$this->id_shop = 0;
|
||||
} else {
|
||||
is_null($id_lang) && $id_lang = \Context::getContext()->language->id;
|
||||
|
||||
$this->id_lang = abs($id_lang % 100);
|
||||
$this->id_shop = $id_shop ? abs($id_shop % 100) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
public function getModel()
|
||||
{
|
||||
if (empty(self::$models[$this->id_type])) {
|
||||
throw new \RuntimeException('Unknown ObjectModel');
|
||||
}
|
||||
return self::$models[$this->id_type];
|
||||
}
|
||||
|
||||
public function getAdminController()
|
||||
{
|
||||
if (empty(self::$admins[$this->id_type])) {
|
||||
throw new \RuntimeException('Unknown AdminController');
|
||||
}
|
||||
if ((int) \Tools::getValue('footerProduct')) {
|
||||
return self::$admins[self::PRODUCT];
|
||||
}
|
||||
return self::$admins[$this->id_type];
|
||||
}
|
||||
|
||||
public function getModule()
|
||||
{
|
||||
return isset(self::$modules[$this->id_type]) ? self::$modules[$this->id_type] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shop ID list where the object is allowed
|
||||
*
|
||||
* @param bool $all Get all or just by shop context
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getShopIdList($all = false)
|
||||
{
|
||||
if ($this->id_type <= self::TEMPLATE) {
|
||||
return [0];
|
||||
}
|
||||
if (isset(self::$shop_ids[$this->id_type][$this->id])) {
|
||||
return self::$shop_ids[$this->id_type][$this->id];
|
||||
}
|
||||
isset(self::$shop_ids[$this->id_type]) or self::$shop_ids[$this->id_type] = [];
|
||||
|
||||
$ids = [];
|
||||
$model = $this->getModel();
|
||||
$def = &$model::${'definition'};
|
||||
$db = \Db::getInstance();
|
||||
$table = $db->escape(_DB_PREFIX_ . $def['table'] . '_shop');
|
||||
$primary = $db->escape($def['primary']);
|
||||
$id = (int) $this->id;
|
||||
$ctx_ids = implode(', ', $all ? \Shop::getShops(true, null, true) : \Shop::getContextListShopID());
|
||||
$rows = $db->executeS(
|
||||
"SELECT id_shop FROM $table WHERE $primary = $id AND id_shop IN ($ctx_ids)"
|
||||
);
|
||||
if ($rows) {
|
||||
foreach ($rows as &$row) {
|
||||
$ids[] = $row['id_shop'];
|
||||
}
|
||||
}
|
||||
return self::$shop_ids[$this->id_type][$this->id] = $ids;
|
||||
}
|
||||
|
||||
public function getDefaultShopId()
|
||||
{
|
||||
return ($ids = $this->getShopIdList()) ? $ids[0] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get UId list by shop context
|
||||
*
|
||||
* @param bool $strict Collect only from allowed shops
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getListByShopContext($strict = false)
|
||||
{
|
||||
if ($this->id_shop || $this->id_type <= self::TEMPLATE) {
|
||||
return ["$this"];
|
||||
}
|
||||
$list = [];
|
||||
$ids = $strict ? $this->getShopIdList() : \Shop::getContextListShopID();
|
||||
|
||||
foreach ($ids as $id_shop) {
|
||||
$this->id_shop = $id_shop;
|
||||
$list[] = "$this";
|
||||
}
|
||||
$this->id_shop = 0;
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Language ID list of CE built contents
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBuiltLangIdList()
|
||||
{
|
||||
$ids = [];
|
||||
|
||||
if (self::TEMPLATE === $this->id_type) {
|
||||
$ids[] = 0;
|
||||
} elseif (self::CONTENT === $this->id_type || self::THEME === $this->id_type) {
|
||||
foreach (\Language::getLanguages(false) as $lang) {
|
||||
$ids[] = (int) $lang['id_lang'];
|
||||
}
|
||||
} else {
|
||||
$id_shop = $this->id_shop ?: $this->getDefaultShopId();
|
||||
$uids = self::getBuiltList($this->id, $this->id_type, $id_shop);
|
||||
|
||||
empty($uids[$id_shop]) or $ids = array_keys($uids[$id_shop]);
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
||||
public function toDefault()
|
||||
{
|
||||
$id_shop = $this->id_shop ?: $this->getDefaultShopId();
|
||||
|
||||
return sprintf('%d%02d%02d%02d', $this->id, $this->id_type, $this->id_lang, $id_shop);
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return sprintf('%d%02d%02d%02d', $this->id, $this->id_type, $this->id_lang, $this->id_shop);
|
||||
}
|
||||
|
||||
public static function parse($id)
|
||||
{
|
||||
if ($id instanceof UId) {
|
||||
return $id;
|
||||
}
|
||||
if (!is_numeric($id) || \Tools::strlen($id) <= 6) {
|
||||
return false;
|
||||
}
|
||||
return new self(
|
||||
\Tools::substr($id, 0, -6),
|
||||
\Tools::substr($id, -6, 2),
|
||||
\Tools::substr($id, -4, 2),
|
||||
\Tools::substr($id, -2)
|
||||
);
|
||||
}
|
||||
|
||||
public static function getTypeId($model)
|
||||
{
|
||||
$model = \Tools::strtolower($model);
|
||||
return 'cms_category' === $model
|
||||
? self::CMS_CATEGORY
|
||||
: array_search($model, array_map('strtolower', self::$models))
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get UId list of CE built contents grouped by shop(s)
|
||||
*
|
||||
* @param int $id
|
||||
* @param int $id_type
|
||||
* @param int|null $id_shop
|
||||
*
|
||||
* @return array [
|
||||
* id_shop => [
|
||||
* id_lang => UId,
|
||||
* ],
|
||||
* ]
|
||||
*/
|
||||
public static function getBuiltList($id, $id_type, $id_shop = null)
|
||||
{
|
||||
$uids = [];
|
||||
$table = _DB_PREFIX_ . 'ce_meta';
|
||||
$shop = null === $id_shop ? '__' : '%02d';
|
||||
$__id = sprintf("%d%02d__$shop", $id, $id_type, $id_shop);
|
||||
$rows = \Db::getInstance()->executeS(
|
||||
"SELECT id FROM $table WHERE id LIKE '$__id' AND name = '_elementor_edit_mode'"
|
||||
);
|
||||
if ($rows) {
|
||||
foreach ($rows as &$row) {
|
||||
$uid = self::parse($row['id']);
|
||||
isset($uids[$uid->id_shop]) or $uids[$uid->id_shop] = [];
|
||||
$uids[$uid->id_shop][$uid->id_lang] = $uid;
|
||||
}
|
||||
}
|
||||
return $uids;
|
||||
}
|
||||
}
|
||||
|
||||
function absint($num)
|
||||
{
|
||||
if ($num instanceof UId) {
|
||||
return $num;
|
||||
}
|
||||
$absint = preg_replace('/\D+/', '', $num);
|
||||
|
||||
return $absint ?: 0;
|
||||
}
|
||||
|
||||
function get_user_meta($user_id, $key = '', $single = false)
|
||||
{
|
||||
return get_post_meta($user_id, '_u_' . $key, $single);
|
||||
}
|
||||
|
||||
function update_user_meta($user_id, $key, $value, $prev_value = '')
|
||||
{
|
||||
return update_post_meta($user_id, '_u_' . $key, $value, $prev_value);
|
||||
}
|
||||
|
||||
function get_the_ID()
|
||||
{
|
||||
if (!UId::$_ID && $uid_preview = \CreativeElements::getPreviewUId(false)) {
|
||||
UId::$_ID = $uid_preview;
|
||||
}
|
||||
if (UId::$_ID) {
|
||||
return UId::$_ID;
|
||||
}
|
||||
$controller = \Context::getContext()->controller;
|
||||
|
||||
if ($controller instanceof \AdminCEEditorController ||
|
||||
$controller instanceof \CreativeElementsPreviewModuleFrontController
|
||||
) {
|
||||
$id_key = \Tools::getIsset('editor_post_id') ? 'editor_post_id' : 'template_id';
|
||||
|
||||
return UId::parse(\Tools::getValue('uid', \Tools::getValue($id_key)));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function get_preview_post_link($post = null, array $args = [], $relative = true)
|
||||
{
|
||||
$uid = uidval($post);
|
||||
$ctx = \Context::getContext();
|
||||
$id_shop = $uid->id_shop ?: $uid->getDefaultShopId();
|
||||
$args['id_employee'] = $ctx->employee->id;
|
||||
$args['adtoken'] = \Tools::getAdminTokenLite($uid->getAdminController());
|
||||
$args['preview_id'] = $uid->toDefault();
|
||||
|
||||
switch ($uid->id_type) {
|
||||
case UId::REVISION:
|
||||
throw new \RuntimeException('TODO');
|
||||
case UId::TEMPLATE:
|
||||
$type = \CETemplate::getTypeById($uid->id);
|
||||
$id_shop = $ctx->shop->id;
|
||||
// continue
|
||||
case UId::THEME:
|
||||
isset($type) or $type = \CETheme::getTypeById($uid->id);
|
||||
$id_lang = $uid->id_lang ?: $ctx->language->id;
|
||||
|
||||
if ('product' === $type || 'product-quick-view' === $type || 'product-miniature' === $type) {
|
||||
$document = Plugin::$instance->documents->getDocOrAutoSave($uid, get_current_user_id());
|
||||
$settings = $document->getData('settings');
|
||||
|
||||
empty($settings['preview_id']) or $prod = new \Product($settings['preview_id'], false, $id_lang);
|
||||
|
||||
if (empty($prod->id)) {
|
||||
$prods = \Product::getProducts($id_lang, 0, 1, 'date_upd', 'DESC', false, true);
|
||||
$prod = new \Product(!empty($prods[0]['id_product']) ? $prods[0]['id_product'] : null, false, $id_lang);
|
||||
}
|
||||
$prod_attr = empty($prod->cache_default_attribute) ? 0 : $prod->cache_default_attribute;
|
||||
empty($prod->active) && empty($args['preview']) && $args['preview'] = 1;
|
||||
|
||||
$link = $ctx->link->getProductLink($prod, null, null, null, $id_lang, $id_shop, $prod_attr, false, $relative);
|
||||
} elseif ('page-contact' === $type) {
|
||||
$link = $ctx->link->getPageLink('contact', null, $id_lang, null, false, $id_shop, $relative);
|
||||
} elseif ('page-not-found' === $type) {
|
||||
$link = $ctx->link->getPageLink('pagenotfound', null, $id_lang, null, false, $id_shop, $relative);
|
||||
} elseif ('page-index' === $type || 'header' === $type || 'footer' === $type) {
|
||||
$link = $ctx->link->getPageLink('index', null, $id_lang, null, false, $id_shop, $relative);
|
||||
|
||||
\Configuration::get('PS_REWRITING_SETTINGS') && $link = preg_replace('~[^/]+$~', '', $link);
|
||||
} else {
|
||||
$link = $ctx->link->getModuleLink('creativeelements', 'preview', [], null, null, null, $relative);
|
||||
}
|
||||
break;
|
||||
case UId::CONTENT:
|
||||
$hook = \Tools::strtolower(\CEContent::getHookById($uid->id));
|
||||
|
||||
if (in_array($hook, Helper::$productHooks)) {
|
||||
if ($id_product = (int) \Tools::getValue('footerProduct')) {
|
||||
$args['footerProduct'] = $id_product;
|
||||
$prod = new \Product($id_product, false, $uid->id_lang, $id_shop);
|
||||
} else {
|
||||
$prods = \Product::getProducts($uid->id_lang, 0, 1, 'date_upd', 'DESC', false, true);
|
||||
$prod = new \Product(!empty($prods[0]['id_product']) ? $prods[0]['id_product'] : null, false, $uid->id_lang);
|
||||
}
|
||||
$prod_attr = empty($prod->cache_default_attribute) ? 0 : $prod->cache_default_attribute;
|
||||
empty($prod->active) && empty($args['preview']) && $args['preview'] = 1;
|
||||
|
||||
$link = $ctx->link->getProductLink($prod, null, null, null, $uid->id_lang, $id_shop, $prod_attr, false, $relative);
|
||||
break;
|
||||
}
|
||||
$page = 'index';
|
||||
|
||||
if (stripos($hook, 'shoppingcart') !== false) {
|
||||
$page = 'cart';
|
||||
$args['action'] = 'show';
|
||||
} elseif ('displayleftcolumn' === $hook || 'displayrightcolumn' === $hook) {
|
||||
$layout = 'r' != $hook[7] ? 'layout-left-column' : 'layout-right-column';
|
||||
$layouts = $ctx->shop->theme->get('theme_settings')['layouts'];
|
||||
unset($layouts['category']);
|
||||
|
||||
if ($key = array_search($layout, $layouts)) {
|
||||
$page = $key;
|
||||
} elseif ($key = array_search('layout-both-columns', $layouts)) {
|
||||
$page = $key;
|
||||
}
|
||||
} elseif ('displaynotfound' === $hook) {
|
||||
$page = 'search';
|
||||
} elseif ('displaymaintenance' === $hook) {
|
||||
$args['maintenance'] = 1;
|
||||
}
|
||||
$link = $ctx->link->getPageLink($page, null, $uid->id_lang, null, false, $id_shop, $relative);
|
||||
|
||||
if ('index' === $page && \Configuration::get('PS_REWRITING_SETTINGS')) {
|
||||
// Remove rewritten URL if exists
|
||||
$link = preg_replace('~[^/]+$~', '', $link);
|
||||
}
|
||||
break;
|
||||
case UId::PRODUCT:
|
||||
$prod = new \Product($uid->id, false, $uid->id_lang, $id_shop);
|
||||
$prod_attr = !empty($prod->cache_default_attribute) ? $prod->cache_default_attribute : 0;
|
||||
empty($prod->active) && empty($args['preview']) && $args['preview'] = 1;
|
||||
|
||||
$link = $ctx->link->getProductLink($prod, null, null, null, $uid->id_lang, $id_shop, $prod_attr, false, $relative);
|
||||
break;
|
||||
case UId::CATEGORY:
|
||||
$link = $ctx->link->getCategoryLink($uid->id, null, $uid->id_lang, null, $id_shop, $relative);
|
||||
break;
|
||||
case UId::CMS:
|
||||
$link = $ctx->link->getCmsLink($uid->id, null, null, $uid->id_lang, $id_shop, $relative);
|
||||
break;
|
||||
case UId::YBC_BLOG_POST:
|
||||
$link = \Module::getInstanceByName('ybc_blog')->getLink('blog', ['id_post' => $uid->id], $uid->id_lang);
|
||||
break;
|
||||
case UID::XIPBLOG_POST:
|
||||
$link = call_user_func('XipBlog::xipBlogPostLink', ['id' => $uid->id]);
|
||||
break;
|
||||
case UId::STBLOG_POST:
|
||||
$post = new \StBlogClass($uid->id, $uid->id_lang);
|
||||
|
||||
$link = $ctx->link->getModuleLink('stblog', 'article', [
|
||||
'id_st_blog' => $uid->id,
|
||||
'id_blog' => $uid->id,
|
||||
'rewrite' => $post->link_rewrite,
|
||||
], null, $uid->id_lang, null, $relative);
|
||||
break;
|
||||
case UId::ADVANCEBLOG_POST:
|
||||
$post = new \BlogPosts($uid->id, $uid->id_lang);
|
||||
$args['blogtoken'] = $args['adtoken'];
|
||||
unset($args['adtoken']);
|
||||
|
||||
$link = $ctx->link->getModuleLink('advanceblog', 'detail', [
|
||||
'id' => $uid->id,
|
||||
'post' => $post->link_rewrite,
|
||||
], null, $uid->id_lang, null, $relative);
|
||||
break;
|
||||
case UId::PRESTABLOG_POST:
|
||||
$post = new \NewsClass($uid->id, $uid->id_lang);
|
||||
empty($post->actif) && $args['preview'] = \Module::getInstanceByName('prestablog')->generateToken($uid->id);
|
||||
|
||||
$link = call_user_func('PrestaBlog::prestablogUrl', [
|
||||
'id' => $uid->id,
|
||||
'seo' => $post->link_rewrite,
|
||||
'titre' => $post->title,
|
||||
'id_lang' => $uid->id_lang,
|
||||
]);
|
||||
break;
|
||||
case UId::SIMPLEBLOG_POST:
|
||||
$post = new \SimpleBlogPost($uid->id, $uid->id_lang, $uid->id_shop);
|
||||
$cat = new \SimpleBlogCategory($post->id_simpleblog_category, $uid->id_lang, $uid->id_shop);
|
||||
|
||||
$link = call_user_func('SimpleBlogPost::getLink', $post->link_rewrite, $cat->link_rewrite);
|
||||
break;
|
||||
case UId::PSBLOG_POST:
|
||||
$post = new \PsBlogBlog($uid->id, $uid->id_lang, $uid->id_shop);
|
||||
|
||||
$link = call_user_func('PsBlogHelper::getInstance')->getBlogLink([
|
||||
'id_psblog_blog' => $post->id,
|
||||
'link_rewrite' => $post->link_rewrite,
|
||||
]);
|
||||
break;
|
||||
case UId::HIBLOG_POST:
|
||||
$post = new \HiBlogPost($uid->id, $uid->id_lang, $uid->id_shop);
|
||||
|
||||
$link = \Module::getInstanceByName('hiblog')->returnBlogFrontUrl($post->id, $post->friendly_url, 'post');
|
||||
break;
|
||||
case UID::TVCMSBLOG_POST:
|
||||
$link = call_user_func('TvcmsBlog::tvcmsBlogPostLink', [
|
||||
'id' => $uid->id,
|
||||
'rewrite' => call_user_func('TvcmsPostsClass::getTheRewrite', $uid->id),
|
||||
]);
|
||||
break;
|
||||
default:
|
||||
$method = "get{$uid->getModel()}Link";
|
||||
|
||||
$link = $ctx->link->$method($uid->id, null, $uid->id_lang, $id_shop, $relative);
|
||||
break;
|
||||
}
|
||||
return explode('#', $link)[0] . (strrpos($link, '?') === false ? '?' : '&') . http_build_query($args);
|
||||
}
|
||||
|
||||
function uidval($var, $fallback = -1)
|
||||
{
|
||||
if (null === $var) {
|
||||
return get_the_ID();
|
||||
}
|
||||
if ($var instanceof UId) {
|
||||
return $var;
|
||||
}
|
||||
if ($var instanceof WPPost) {
|
||||
return $var->uid;
|
||||
}
|
||||
if (is_numeric($var)) {
|
||||
return UId::parse($var);
|
||||
}
|
||||
if ($fallback !== -1) {
|
||||
return $fallback;
|
||||
}
|
||||
throw new \RuntimeException('Can not convert to UId');
|
||||
}
|
||||
|
||||
function get_edit_post_link($post_id)
|
||||
{
|
||||
$uid = uidval($post_id);
|
||||
$ctx = \Context::getContext();
|
||||
$id = $uid->id;
|
||||
$model = $uid->getModel();
|
||||
$admin = $uid->getAdminController();
|
||||
|
||||
switch ($uid->id_type) {
|
||||
case UId::REVISION:
|
||||
throw new \RuntimeException('TODO');
|
||||
case UId::YBC_BLOG_POST:
|
||||
$link = $ctx->link->getAdminLink($admin) . '&' . http_build_query([
|
||||
'configure' => 'ybc_blog',
|
||||
'tab_module' => 'front_office_features',
|
||||
'module_name' => 'ybc_blog',
|
||||
'control' => 'post',
|
||||
'id_post' => $id,
|
||||
]);
|
||||
break;
|
||||
case UId::PRESTABLOG_POST:
|
||||
$link = $ctx->link->getAdminLink($admin) . "&configure=prestablog&editNews&idN=$id";
|
||||
break;
|
||||
case UId::CONTENT:
|
||||
if (\Tools::getIsset('footerProduct')) {
|
||||
$id = (int) \Tools::getValue('footerProduct');
|
||||
$model = 'Product';
|
||||
$admin = 'AdminProducts';
|
||||
}
|
||||
// Continue default case
|
||||
default:
|
||||
$def = &$model::${'definition'};
|
||||
$args = [
|
||||
$def['primary'] => $id,
|
||||
"update{$def['table']}" => 1,
|
||||
];
|
||||
$link = $ctx->link->getAdminLink($admin, true, $args) . '&' . http_build_query($args);
|
||||
break;
|
||||
}
|
||||
return $link;
|
||||
}
|
||||
8
modules/creativeelements/classes/wrappers/index.php
Normal file
8
modules/creativeelements/classes/wrappers/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../');
|
||||
die;
|
||||
12
modules/creativeelements/config.xml
Normal file
12
modules/creativeelements/config.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<module>
|
||||
<name>creativeelements</name>
|
||||
<displayName><![CDATA[Creative Elements - live PageBuilder [in-stock]]]></displayName>
|
||||
<version><![CDATA[2.5.0]]></version>
|
||||
<description><![CDATA[The most advanced frontend drag & drop page builder. Create high-end, pixel perfect websites at record speeds. Any theme, any page, any design. <a href="https://creativeelements.webshopworks.com/buy-license?utm_source=upgrade&utm_campaign=in-stock&utm_medium=backoffice&utm_term=alysum" target="_blank">[Upgrade to PREMIUM]</a>]]></description>
|
||||
<author><![CDATA[WebshopWorks]]></author>
|
||||
<tab><![CDATA[content_management]]></tab>
|
||||
<is_configurable>1</is_configurable>
|
||||
<need_instance>1</need_instance>
|
||||
<limited_countries></limited_countries>
|
||||
</module>
|
||||
12
modules/creativeelements/config_pl.xml
Normal file
12
modules/creativeelements/config_pl.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<module>
|
||||
<name>creativeelements</name>
|
||||
<displayName><![CDATA[Creative Elements - live Theme & Page Builder]]></displayName>
|
||||
<version><![CDATA[2.5.11]]></version>
|
||||
<description><![CDATA[The most advanced frontend drag & drop page builder. Create high-end, pixel perfect websites at record speeds. Any theme, any page, any design.]]></description>
|
||||
<author><![CDATA[WebshopWorks]]></author>
|
||||
<tab><![CDATA[content_management]]></tab>
|
||||
<is_configurable>1</is_configurable>
|
||||
<need_instance>1</need_instance>
|
||||
<limited_countries></limited_countries>
|
||||
</module>
|
||||
@@ -0,0 +1,309 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
require_once _PS_MODULE_DIR_ . 'creativeelements/classes/CEContent.php';
|
||||
|
||||
class AdminCEContentController extends ModuleAdminController
|
||||
{
|
||||
public $bootstrap = true;
|
||||
|
||||
public $table = 'ce_content';
|
||||
|
||||
public $identifier = 'id_ce_content';
|
||||
|
||||
public $className = 'CEContent';
|
||||
|
||||
public $lang = true;
|
||||
|
||||
protected $_defaultOrderBy = 'title';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
if ((Tools::getIsset('updatece_content') || Tools::getIsset('addce_content')) && Shop::getContextShopID() === null) {
|
||||
$this->displayWarning(
|
||||
$this->trans('You are in a multistore context: any modification will impact all your shops, or each shop of the active group.', [], 'Admin.Catalog.Notification')
|
||||
);
|
||||
}
|
||||
|
||||
$table_shop = _DB_PREFIX_ . $this->table . '_shop';
|
||||
$this->_select = 'sa.*';
|
||||
$this->_join = "LEFT JOIN $table_shop sa ON sa.id_ce_content = a.id_ce_content AND b.id_shop = sa.id_shop";
|
||||
$this->_where = "AND sa.id_shop = " . (int) $this->context->shop->id . " AND a.id_product = 0";
|
||||
|
||||
$this->fields_list = [
|
||||
'id_ce_content' => [
|
||||
'title' => $this->trans('ID', [], 'Admin.Global'),
|
||||
'class' => 'fixed-width-xs',
|
||||
'align' => 'center',
|
||||
],
|
||||
'title' => [
|
||||
'title' => $this->trans('Title', [], 'Admin.Global'),
|
||||
],
|
||||
'hook' => [
|
||||
'title' => $this->trans('Position', [], 'Admin.Global'),
|
||||
'class' => 'fixed-width-xl',
|
||||
],
|
||||
'date_add' => [
|
||||
'title' => $this->trans('Created on', [], 'Modules.Facetedsearch.Admin'),
|
||||
'filter_key' => 'sa!date_add',
|
||||
'class' => 'fixed-width-lg',
|
||||
'type' => 'datetime',
|
||||
],
|
||||
'date_upd' => [
|
||||
'title' => $this->l('Modified on'),
|
||||
'filter_key' => 'sa!date_upd',
|
||||
'class' => 'fixed-width-lg',
|
||||
'type' => 'datetime',
|
||||
],
|
||||
'active' => [
|
||||
'title' => $this->trans('Displayed', [], 'Admin.Global'),
|
||||
'filter_key' => 'sa!active',
|
||||
'class' => 'fixed-width-xs',
|
||||
'align' => 'center',
|
||||
'active' => 'status',
|
||||
'type' => 'bool',
|
||||
],
|
||||
];
|
||||
|
||||
$this->bulk_actions = [
|
||||
'delete' => [
|
||||
'text' => $this->trans('Delete selected', [], 'Admin.Notifications.Info'),
|
||||
'icon' => 'fa fa-icon-trash',
|
||||
'confirm' => $this->trans('Delete selected items?', [], 'Admin.Notifications.Info'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function ajaxProcessHideEditor()
|
||||
{
|
||||
$id = (int) Tools::getValue('id');
|
||||
$id_type = (int) Tools::getValue('idType');
|
||||
|
||||
$uids = CE\UId::getBuiltList($id, $id_type, $this->context->shop->id);
|
||||
$res = empty($uids) ? $uids : array_keys($uids[$this->context->shop->id]);
|
||||
|
||||
die(json_encode($res));
|
||||
}
|
||||
|
||||
public function ajaxProcessMigrate()
|
||||
{
|
||||
if ($ids = Tools::getValue('ids')) {
|
||||
require_once _CE_PATH_ . 'classes/CEMigrate.php';
|
||||
|
||||
$done = [];
|
||||
|
||||
foreach ($ids as $id) {
|
||||
CEMigrate::moveContent($id, $this->module) && $done[] = (int) $id;
|
||||
}
|
||||
$res = CEMigrate::removeIds('content', $done);
|
||||
|
||||
die(json_encode($res));
|
||||
}
|
||||
}
|
||||
|
||||
public function setMedia($isNewTheme = false)
|
||||
{
|
||||
parent::setMedia($isNewTheme);
|
||||
|
||||
$this->addJquery();
|
||||
$this->js_files[] = _MODULE_DIR_ . 'creativeelements/views/lib/e-select2/js/e-select2.full.min.js?v=4.0.6-rc1';
|
||||
$this->css_files[_MODULE_DIR_ . 'creativeelements/views/lib/e-select2/css/e-select2.min.css?v=4.0.6-rc1'] = 'all';
|
||||
}
|
||||
|
||||
public function initHeader()
|
||||
{
|
||||
parent::initHeader();
|
||||
|
||||
$display_suppliers = Configuration::get('PS_DISPLAY_SUPPLIERS');
|
||||
$display_manufacturers = version_compare(_PS_VERSION_, '1.7.7', '<')
|
||||
? $display_suppliers
|
||||
: Configuration::get('PS_DISPLAY_MANUFACTURERS');
|
||||
$id_lang = $this->context->language->id;
|
||||
$link = $this->context->link;
|
||||
$tabs = &$this->context->smarty->tpl_vars['tabs']->value;
|
||||
|
||||
foreach ($tabs as &$tab0) {
|
||||
foreach ($tab0['sub_tabs'] as &$tab1) {
|
||||
if ('AdminParentCEContent' === $tab1['class_name']) {
|
||||
foreach ($tab1['sub_tabs'] as &$tab2) {
|
||||
if ('AdminCEContent' === $tab2['class_name']) {
|
||||
$sub_tabs = &$tab2['sub_tabs'];
|
||||
|
||||
$tab = Tab::getTab($id_lang, Tab::getIdFromClassName('AdminCEContent'));
|
||||
$tab['current'] = true;
|
||||
$tab['href'] = $link->getAdminLink('AdminCEContent');
|
||||
$sub_tabs[] = $tab;
|
||||
|
||||
$tab = Tab::getTab($id_lang, Tab::getIdFromClassName('AdminCmsContent'));
|
||||
$tab['current'] = '';
|
||||
$tab['href'] = $link->getAdminLink('AdminCmsContent');
|
||||
$sub_tabs[] = $tab;
|
||||
|
||||
$tab = Tab::getTab($id_lang, Tab::getIdFromClassName('AdminProducts'));
|
||||
$tab['current'] = '';
|
||||
$tab['href'] = $link->getAdminLink('AdminProducts');
|
||||
$sub_tabs[] = $tab;
|
||||
|
||||
$tab = Tab::getTab($id_lang, Tab::getIdFromClassName('AdminCategories'));
|
||||
$tab['current'] = '';
|
||||
$tab['href'] = $link->getAdminLink('AdminCategories');
|
||||
$sub_tabs[] = $tab;
|
||||
|
||||
if ($display_manufacturers) {
|
||||
$tab = Tab::getTab($id_lang, Tab::getIdFromClassName('AdminManufacturers'));
|
||||
$tab['current'] = '';
|
||||
$tab['href'] = $link->getAdminLink('AdminManufacturers');
|
||||
$sub_tabs[] = $tab;
|
||||
}
|
||||
|
||||
if ($display_suppliers) {
|
||||
$tab = Tab::getTab($id_lang, Tab::getIdFromClassName('AdminSuppliers'));
|
||||
$tab['current'] = '';
|
||||
$tab['href'] = $link->getAdminLink('AdminSuppliers');
|
||||
$sub_tabs[] = $tab;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function initToolBarTitle()
|
||||
{
|
||||
$this->page_header_toolbar_title = $this->l('Place Content Anywhere');
|
||||
|
||||
$this->context->smarty->assign('icon', 'icon-list');
|
||||
|
||||
$this->toolbar_title[] = $this->l('Contents List');
|
||||
}
|
||||
|
||||
public function initPageHeaderToolbar()
|
||||
{
|
||||
if (empty($this->display)) {
|
||||
$this->page_header_toolbar_btn['addce_content'] = [
|
||||
'href' => self::$currentIndex . '&addce_content&token=' . $this->token,
|
||||
'desc' => $this->trans('Add new', [], 'Admin.Actions'),
|
||||
'icon' => 'process-icon-new',
|
||||
];
|
||||
}
|
||||
parent::initPageHeaderToolbar();
|
||||
}
|
||||
|
||||
public function initContent()
|
||||
{
|
||||
$this->context->smarty->assign('current_tab_level', 3);
|
||||
|
||||
return parent::initContent();
|
||||
}
|
||||
|
||||
public function renderList()
|
||||
{
|
||||
$this->addRowAction('edit');
|
||||
$this->addRowAction('delete');
|
||||
|
||||
return parent::renderList();
|
||||
}
|
||||
|
||||
public function renderForm()
|
||||
{
|
||||
$col = count(Language::getLanguages(false, false, true)) > 1 ? 9 : 7;
|
||||
|
||||
version_compare(_PS_VERSION_, '1.7.8', '<') or $col--;
|
||||
|
||||
$this->fields_form = [
|
||||
'legend' => [
|
||||
'title' => $this->l('Content'),
|
||||
'icon' => 'icon-edit',
|
||||
],
|
||||
'input' => [
|
||||
[
|
||||
'type' => 'text',
|
||||
'label' => $this->trans('Title', [], 'Admin.Global'),
|
||||
'name' => 'title',
|
||||
'lang' => true,
|
||||
'col' => $col,
|
||||
],
|
||||
[
|
||||
'type' => 'text',
|
||||
'label' => $this->trans('Position', [], 'Admin.Global'),
|
||||
'name' => 'hook',
|
||||
'required' => true,
|
||||
'col' => 3,
|
||||
],
|
||||
[
|
||||
'type' => 'textarea',
|
||||
'label' => $this->l('Content'),
|
||||
'name' => 'content',
|
||||
'lang' => true,
|
||||
'col' => $col,
|
||||
],
|
||||
[
|
||||
'type' => 'switch',
|
||||
'label' => $this->trans('Displayed', [], 'Admin.Global'),
|
||||
'name' => 'active',
|
||||
'required' => false,
|
||||
'is_bool' => true,
|
||||
'values' => [
|
||||
[
|
||||
'id' => 'active_on',
|
||||
'value' => 1,
|
||||
'label' => $this->trans('Enabled', [], 'Admin.Global'),
|
||||
],
|
||||
[
|
||||
'id' => 'active_off',
|
||||
'value' => 0,
|
||||
'label' => $this->trans('Disabled', [], 'Admin.Global'),
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'submit' => [
|
||||
'title' => $this->trans('Save', [], 'Admin.Actions'),
|
||||
],
|
||||
'buttons' => [
|
||||
'save_and_stay' => [
|
||||
'type' => 'submit',
|
||||
'title' => $this->trans('Save and stay', [], 'Admin.Actions'),
|
||||
'icon' => 'process-icon-save',
|
||||
'name' => 'submitAddce_contentAndStay',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
if (Shop::isFeatureActive()) {
|
||||
$this->fields_form['input'][] = [
|
||||
'type' => 'shop',
|
||||
'label' => $this->trans('Shop association', [], 'Admin.Global'),
|
||||
'name' => 'checkBoxShopAsso',
|
||||
];
|
||||
}
|
||||
|
||||
return parent::renderForm();
|
||||
}
|
||||
|
||||
protected function trans($id, array $parameters = [], $domain = null, $locale = null)
|
||||
{
|
||||
return empty($this->translator) ? $this->l($id) : parent::trans($id, $parameters, $domain, $locale);
|
||||
}
|
||||
|
||||
protected function l($string, $module = 'creativeelements', $addslashes = false, $htmlentities = true)
|
||||
{
|
||||
$str = Translate::getModuleTranslation($module, $string, '', null, $addslashes || !$htmlentities);
|
||||
|
||||
return $htmlentities ? $str : call_user_func('stripslashes', $str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,378 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
class AdminCEEditorController extends ModuleAdminController
|
||||
{
|
||||
public $name = 'AdminCEEditor';
|
||||
|
||||
public $display_header = false;
|
||||
|
||||
public $content_only = true;
|
||||
|
||||
/** @var CE\UId */
|
||||
protected $uid;
|
||||
|
||||
public function initShopContext()
|
||||
{
|
||||
require_once _PS_MODULE_DIR_ . 'creativeelements/classes/wrappers/UId.php';
|
||||
|
||||
Tools::getIsset('uid') && $this->uid = CE\UId::parse(Tools::getValue('uid'));
|
||||
|
||||
if (!empty($this->uid->id_shop) && $this->uid->id_type > CE\UId::TEMPLATE && Shop::getContext() > 1) {
|
||||
${'_POST'}['setShopContext'] = 's-' . $this->uid->id_shop;
|
||||
}
|
||||
parent::initShopContext();
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
if (isset($this->context->cookie->last_activity)) {
|
||||
if ($this->context->cookie->last_activity + 900 < time()) {
|
||||
$this->context->employee->logout();
|
||||
} else {
|
||||
$this->context->cookie->last_activity = time();
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($this->context->employee) || !$this->context->employee->isLoggedBack()) {
|
||||
if (isset($this->context->employee)) {
|
||||
$this->context->employee->logout();
|
||||
}
|
||||
Tools::redirectAdmin($this->context->link->getAdminLink('AdminLogin') . '&redirect=' . $this->controller_name);
|
||||
}
|
||||
|
||||
$this->initProcess();
|
||||
}
|
||||
|
||||
public function initCursedPage()
|
||||
{
|
||||
if ($this->ajax) {
|
||||
CE\wp_send_json_error('token_expired');
|
||||
}
|
||||
parent::initCursedPage();
|
||||
}
|
||||
|
||||
public function initProcess()
|
||||
{
|
||||
header('Cache-Control: no-store, no-cache');
|
||||
|
||||
$this->ajax = Tools::getIsset('ajax');
|
||||
$this->action = Tools::getValue('action', '');
|
||||
$this->tabAccess = Profile::getProfileAccess($this->context->employee->id_profile, $this->id);
|
||||
|
||||
if (Shop::isFeatureActive() && $this->uid && !$this->ajax) {
|
||||
$domain = Tools::getShopProtocol() === 'http://' ? 'domain' : 'domain_ssl';
|
||||
|
||||
if ($this->context->shop->$domain != $_SERVER['HTTP_HOST'] && $this->viewAccess()) {
|
||||
CE\update_post_meta(0, 'cookie', $this->context->cookie->getAll());
|
||||
|
||||
$id_shop = $this->uid->id_shop ?: $this->uid->getDefaultShopId();
|
||||
|
||||
Tools::redirectAdmin(
|
||||
$this->context->link->getModuleLink('creativeelements', 'preview', [
|
||||
'id_employee' => $this->context->employee->id,
|
||||
'adtoken' => Tools::getAdminTokenLite('AdminCEEditor'),
|
||||
'redirect' => urlencode($_SERVER['REQUEST_URI']),
|
||||
], true, $this->uid->id_lang, $id_shop)
|
||||
);
|
||||
}
|
||||
}
|
||||
CE\Plugin::instance();
|
||||
}
|
||||
|
||||
public function postProcess()
|
||||
{
|
||||
$process = 'process' . Tools::toCamelCase($this->action, true);
|
||||
|
||||
if ($this->ajax) {
|
||||
method_exists($this, "ajax$process") && $this->{"ajax$process"}();
|
||||
|
||||
if ('elementor_ajax' === $this->action) {
|
||||
CE\add_action('elementor/ajax/register_actions', [$this, 'registerAjaxActions']);
|
||||
}
|
||||
CE\do_action('wp_ajax_' . $this->action);
|
||||
} elseif ($this->action && method_exists($this, $process)) {
|
||||
// Call process
|
||||
return $this->$process();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function initContent()
|
||||
{
|
||||
$this->viewAccess() or die(CE\Helper::transError('You do not have permission to view this.'));
|
||||
|
||||
empty($this->uid) && Tools::redirectAdmin($this->context->link->getAdminLink('AdminCEContent'));
|
||||
|
||||
CE\add_action('elementor/editor/before_enqueue_scripts', [$this, 'beforeEnqueueScripts']);
|
||||
|
||||
CE\Plugin::instance()->editor->init();
|
||||
}
|
||||
|
||||
public function beforeEnqueueScripts()
|
||||
{
|
||||
$suffix = _PS_MODE_DEV_ ? '' : '.min';
|
||||
|
||||
// Enqueue CE assets
|
||||
CE\wp_enqueue_style('ce-editor', _CE_ASSETS_URL_ . 'css/editor-ce.css', [], _CE_VERSION_);
|
||||
CE\wp_register_script('ce-editor', _CE_ASSETS_URL_ . 'js/editor-ce.js', [], _CE_VERSION_, true);
|
||||
CE\wp_localize_script('ce-editor', 'baseDir', __PS_BASE_URI__);
|
||||
CE\wp_enqueue_script('ce-editor');
|
||||
|
||||
// Enqueue TinyMCE assets
|
||||
CE\wp_enqueue_style('material-icons', _CE_ASSETS_URL_ . 'lib/material-icons/material-icons.css', [], '1.012');
|
||||
CE\wp_enqueue_style('tinymce-theme', _CE_ASSETS_URL_ . "lib/tinymce/ps-theme{$suffix}.css", [], _CE_VERSION_);
|
||||
|
||||
CE\wp_register_script('tinymce', _PS_JS_DIR_ . 'tiny_mce/tinymce.min.js', ['jquery'], false, true);
|
||||
CE\wp_register_script('tinymce-inc', _CE_ASSETS_URL_ . 'lib/tinymce/tinymce.inc.js', ['tinymce'], _CE_VERSION_, true);
|
||||
|
||||
CE\wp_localize_script('tinymce', 'baseAdminDir', __PS_BASE_URI__ . basename(_PS_ADMIN_DIR_) . '/');
|
||||
CE\wp_localize_script('tinymce', 'iso_user', CE\get_locale());
|
||||
|
||||
CE\wp_enqueue_script('tinymce-inc');
|
||||
}
|
||||
|
||||
public function processBackToPsEditor()
|
||||
{
|
||||
if (CE\current_user_can('edit', $this->uid)) {
|
||||
CE\Plugin::instance()->db->setIsElementorPage($this->uid, false);
|
||||
}
|
||||
Tools::redirectAdmin($_SERVER['HTTP_REFERER']);
|
||||
}
|
||||
|
||||
public function processAddFooterProduct()
|
||||
{
|
||||
if (!$this->uid->id || $this->uid->id_type != CE\UId::PRODUCT) {
|
||||
Tools::redirectAdmin($_SERVER['HTTP_REFERER']);
|
||||
}
|
||||
|
||||
$content = new CEContent();
|
||||
$content->hook = 'displayFooterProduct';
|
||||
$content->id_product = $this->uid->id;
|
||||
$content->active = true;
|
||||
$content->title = [];
|
||||
$content->content = [];
|
||||
|
||||
foreach (Language::getLanguages(false) as $lang) {
|
||||
$content->title[$lang['id_lang']] = 'Product Footer #' . $this->uid->id;
|
||||
}
|
||||
$content->save();
|
||||
|
||||
$uid = new CE\UId($content->id, CE\UId::CONTENT, $this->uid->id_lang, $this->uid->id_shop);
|
||||
|
||||
Tools::redirectAdmin(
|
||||
$this->context->link->getAdminLink('AdminCEEditor') . "&uid=$uid&footerProduct={$content->id_product}"
|
||||
);
|
||||
}
|
||||
|
||||
public function processAddMaintenance()
|
||||
{
|
||||
if (!$uid = Tools::getValue('uid')) {
|
||||
Tools::redirectAdmin($_SERVER['HTTP_REFERER']);
|
||||
}
|
||||
|
||||
$content = new CEContent();
|
||||
$content->hook = 'displayMaintenance';
|
||||
$content->active = true;
|
||||
$content->title = [];
|
||||
$content->content = [];
|
||||
|
||||
foreach (Language::getLanguages(false) as $lang) {
|
||||
$id_lang = $lang['id_lang'];
|
||||
|
||||
$content->title[$id_lang] = 'Maintenance';
|
||||
$content->content[$id_lang] = (string) Configuration::get('PS_MAINTENANCE_TEXT', $id_lang);
|
||||
}
|
||||
$content->save();
|
||||
|
||||
$id_lang = Tools::substr($uid, -4, 2);
|
||||
$id_shop = Tools::substr($uid, -2);
|
||||
$uid = new CE\UId($content->id, CE\UId::CONTENT, $id_lang, $id_shop);
|
||||
|
||||
Tools::redirectAdmin($this->context->link->getAdminLink('AdminCEEditor') . "&uid=$uid");
|
||||
}
|
||||
|
||||
public function ajaxProcessHeartbeat()
|
||||
{
|
||||
$response = [];
|
||||
$data = isset(${'_POST'}['data']) ? (array) ${'_POST'}['data'] : [];
|
||||
$screen_id = Tools::getValue('screen_id', 'front');
|
||||
|
||||
empty($data) or $response = CE\apply_filters('heartbeat_received', $response, $data, $screen_id);
|
||||
|
||||
$response = CE\apply_filters('heartbeat_send', $response, $screen_id);
|
||||
|
||||
CE\do_action('heartbeat_tick', $response, $screen_id);
|
||||
|
||||
$response['server_time'] = time();
|
||||
|
||||
CE\wp_send_json($response);
|
||||
}
|
||||
|
||||
public function ajaxProcessAutocompleteLink()
|
||||
{
|
||||
$context = Context::getContext();
|
||||
$db = Db::getInstance();
|
||||
$ps = _DB_PREFIX_;
|
||||
$search = $db->escape(Tools::getValue('search'));
|
||||
$id_lang = (int) $context->language->id;
|
||||
$id_shop = (int) $context->shop->id;
|
||||
$limit = 10;
|
||||
|
||||
$rows = $db->executeS("(
|
||||
SELECT m.`id_meta` AS `ID`, ml.`title`, m.`page` AS `permalink`, 'Page' AS `info` FROM `{$ps}meta` AS m
|
||||
LEFT JOIN `{$ps}meta_lang` AS ml ON m.`id_meta` = ml.`id_meta`
|
||||
WHERE ml.`id_lang` = $id_lang AND ml.`id_shop` = $id_shop AND ml.`title` LIKE '%$search%' LIMIT $limit
|
||||
) UNION (
|
||||
SELECT `id_cms` AS `ID`, `meta_title` AS `title`, `link_rewrite` AS `permalink`, 'CMS' AS `info` FROM `{$ps}cms_lang`
|
||||
WHERE `id_lang` = $id_lang AND `id_shop` = $id_shop AND `meta_title` LIKE '%$search%' LIMIT $limit
|
||||
) UNION (
|
||||
SELECT `id_cms_category` AS `ID`, `name` AS `title`, `link_rewrite` AS `permalink`, 'CMS Category' AS `info` FROM `{$ps}cms_category_lang`
|
||||
WHERE `id_lang` = $id_lang AND `id_shop` = $id_shop AND `name` LIKE '%$search%' LIMIT $limit
|
||||
) UNION (
|
||||
SELECT `id_product` AS `ID`, `name` AS `title`, '' AS `permalink`, 'Product' AS `info` FROM `{$ps}product_lang`
|
||||
WHERE `id_lang` = $id_lang AND `id_shop` = $id_shop AND `name` LIKE '%$search%' LIMIT $limit
|
||||
) UNION (
|
||||
SELECT `id_category` AS `ID`, `name` AS `title`, `link_rewrite` AS `permalink`, 'Category' AS `info` FROM `{$ps}category_lang`
|
||||
WHERE `id_lang` = $id_lang AND `id_shop` = $id_shop AND `name` LIKE '%$search%' LIMIT $limit
|
||||
) UNION (
|
||||
SELECT `id_manufacturer` AS `ID`, `name` AS `title`, '' AS `permalink`, 'Brand' AS `info` FROM `{$ps}manufacturer`
|
||||
WHERE `active` = 1 AND `name` LIKE '%$search%' LIMIT $limit
|
||||
) UNION (
|
||||
SELECT `id_supplier` AS `ID`, `name` AS `title`, '' AS `permalink`, 'Supplier' AS `info` FROM `{$ps}supplier`
|
||||
WHERE `active` = 1 AND `name` LIKE '%$search%' LIMIT $limit
|
||||
)");
|
||||
|
||||
if ($rows) {
|
||||
foreach ($rows as &$row) {
|
||||
switch ($row['info']) {
|
||||
case 'CMS':
|
||||
$row['permalink'] = $context->link->getCMSLink($row['ID'], $row['permalink'], null, $id_lang, $id_shop);
|
||||
break;
|
||||
case 'CMS Category':
|
||||
$row['permalink'] = $context->link->getCMSCategoryLink($row['ID'], $row['permalink'], $id_lang, $id_shop);
|
||||
break;
|
||||
case 'Product':
|
||||
$product = new Product($row['ID'], false, $id_lang, $id_shop);
|
||||
$row['permalink'] = $context->link->getProductLink($product);
|
||||
break;
|
||||
case 'Category':
|
||||
$row['permalink'] = $context->link->getCategoryLink($row['ID'], $row['permalink'], $id_lang, null, $id_shop);
|
||||
break;
|
||||
case 'Brand':
|
||||
$row['permalink'] = $context->link->getManufacturerLink($row['ID'], Tools::link_rewrite($row['title']), $id_lang, $id_shop);
|
||||
break;
|
||||
case 'Supplier':
|
||||
$row['permalink'] = $context->link->getSupplierLink($row['ID'], Tools::link_rewrite($row['title']), $id_lang, $id_shop);
|
||||
break;
|
||||
default:
|
||||
$row['permalink'] = $context->link->getPageLink($row['permalink'], null, $id_lang, null, false, $id_shop);
|
||||
break;
|
||||
}
|
||||
$row['info'] = CE\__($row['info']);
|
||||
}
|
||||
}
|
||||
die(json_encode($rows));
|
||||
}
|
||||
|
||||
public function registerAjaxActions($ajax_manager)
|
||||
{
|
||||
$ajax_manager->registerAjaxAction('get_language_content', [$this, 'ajaxGetLanguageContent']);
|
||||
$ajax_manager->registerAjaxAction('get_products_by_id', [$this, 'ajaxGetProductsById']);
|
||||
|
||||
CE\add_filter('elementor/api/get_templates/body_args', [$this, 'filterApiGetTemplateArgs']);
|
||||
CE\add_filter('elementor/api/get_templates/content', [$this, 'filterApiGetTemplateContent']);
|
||||
CE\add_action('elementor/document/after_save', [$this, 'onAfterSaveDocument']);
|
||||
}
|
||||
|
||||
public function ajaxGetLanguageContent($request)
|
||||
{
|
||||
$data = null;
|
||||
|
||||
if (!empty($request['uid']) && $data = CE\get_post_meta($request['uid'], '_elementor_data', true)) {
|
||||
CE\Plugin::$instance->db->iterateData($data, function ($element) {
|
||||
$element['id'] = CE\Utils::generateRandomString();
|
||||
|
||||
return $element;
|
||||
});
|
||||
}
|
||||
return is_array($data) ? $data : [];
|
||||
}
|
||||
|
||||
public function ajaxGetProductsById($request)
|
||||
{
|
||||
if (empty($request['ids'])) {
|
||||
return [];
|
||||
}
|
||||
$context = Context::getContext();
|
||||
$results = [];
|
||||
$ids = implode(',', array_map('intval', $request['ids']));
|
||||
|
||||
$items = Db::getInstance()->executeS('
|
||||
SELECT p.`id_product`, pl.`link_rewrite`, p.`reference`, pl.`name`, image_shop.`id_image` id_image FROM `' . _DB_PREFIX_ . 'product` p
|
||||
' . Shop::addSqlAssociation('product', 'p') . '
|
||||
LEFT JOIN `' . _DB_PREFIX_ . 'product_lang` pl ON (pl.id_product = p.id_product AND pl.id_lang = ' . (int) $context->language->id . Shop::addSqlRestrictionOnLang('pl') . ')
|
||||
LEFT JOIN `' . _DB_PREFIX_ . 'image_shop` image_shop
|
||||
ON (image_shop.`id_product` = p.`id_product` AND image_shop.cover=1 AND image_shop.id_shop=' . (int) $context->shop->id . ')
|
||||
LEFT JOIN `' . _DB_PREFIX_ . 'image_lang` il ON (image_shop.`id_image` = il.`id_image` AND il.`id_lang` = ' . (int) $context->language->id . ')
|
||||
WHERE p.id_product IN (' . $ids . ') GROUP BY p.id_product
|
||||
');
|
||||
|
||||
if ($items) {
|
||||
$protocol = Tools::getShopProtocol();
|
||||
$image_size = ImageType::getFormattedName('home');
|
||||
|
||||
foreach ($items as &$item) {
|
||||
$results[] = [
|
||||
'id' => $item['id_product'],
|
||||
'name' => $item['name'] . (!empty($item['reference']) ? ' (ref: ' . $item['reference'] . ')' : ''),
|
||||
'ref' => (!empty($item['reference']) ? $item['reference'] : ''),
|
||||
'image' => str_replace('http://', $protocol, $context->link->getImageLink($item['link_rewrite'], $item['id_image'], $image_size)),
|
||||
];
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function filterApiGetTemplateArgs($body_args)
|
||||
{
|
||||
$id_shop = Configuration::getGlobalValue('PS_SHOP_DEFAULT');
|
||||
$license_key = Configuration::getGlobalValue('CE_LICENSE');
|
||||
|
||||
if ($license_key) {
|
||||
$body_args['license'] = $license_key;
|
||||
$body_args['domain'] = Tools::getShopProtocol() === 'http://'
|
||||
? ShopUrl::getMainShopDomain($id_shop)
|
||||
: ShopUrl::getMainShopDomainSSL($id_shop)
|
||||
;
|
||||
}
|
||||
|
||||
return $body_args;
|
||||
}
|
||||
|
||||
public function filterApiGetTemplateContent($content)
|
||||
{
|
||||
if (isset($content['error'])) {
|
||||
if (isset($content['code']) && 419 == $content['code']) {
|
||||
Configuration::updateGlobalValue('CE_LICENSE', '');
|
||||
}
|
||||
CE\wp_send_json_error($content['error']);
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function onAfterSaveDocument($document)
|
||||
{
|
||||
// Set edit mode to builder only at save
|
||||
CE\Plugin::$instance->db->setIsElementorPage($document->getPost()->uid);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
require_once _PS_MODULE_DIR_ . 'creativeelements/classes/CEFont.php';
|
||||
|
||||
class AdminCEFontsController extends ModuleAdminController
|
||||
{
|
||||
public $bootstrap = true;
|
||||
|
||||
public $table = 'ce_font';
|
||||
|
||||
public $identifier = 'id_ce_font';
|
||||
|
||||
public $className = 'CEFont';
|
||||
|
||||
protected $ce_font;
|
||||
|
||||
protected $_defaultOrderBy = 'family';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->fields_list = [
|
||||
'id_ce_font' => [
|
||||
'title' => $this->trans('ID', [], 'Admin.Global'),
|
||||
'class' => 'fixed-width-xs',
|
||||
'align' => 'center',
|
||||
],
|
||||
'family' => [
|
||||
'title' => $this->l('Font Name'),
|
||||
],
|
||||
'preview' => [
|
||||
'title' => $this->l('Preview'),
|
||||
'class' => 'ce-font-preview',
|
||||
'orderby' => false,
|
||||
'search' => false,
|
||||
],
|
||||
];
|
||||
|
||||
$this->bulk_actions = [
|
||||
'delete' => [
|
||||
'text' => $this->l('Delete'),
|
||||
'icon' => 'icon-trash text-danger',
|
||||
'confirm' => $this->trans('Delete selected items?', [], 'Admin.Notifications.Info'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function init()
|
||||
{
|
||||
if ($id_ce_font = (int) Tools::getValue('id_ce_font')) {
|
||||
$this->ce_font = new CEFont($id_ce_font);
|
||||
}
|
||||
parent::init();
|
||||
}
|
||||
|
||||
public function initToolBarTitle()
|
||||
{
|
||||
$this->context->smarty->assign('icon', 'icon-list');
|
||||
|
||||
$this->toolbar_title[] = $this->l(
|
||||
'add' === $this->display ? 'Add New Font' : ('edit' === $this->display ? 'Edit Font' : 'Fonts List')
|
||||
);
|
||||
}
|
||||
|
||||
public function initPageHeaderToolbar()
|
||||
{
|
||||
if ('add' !== $this->display && 'edit' !== $this->display) {
|
||||
$this->page_header_toolbar_btn['addce_font'] = [
|
||||
'icon' => 'process-icon-new',
|
||||
'desc' => $this->trans('Add new', [], 'Admin.Actions'),
|
||||
'href' => self::$currentIndex . '&addce_font&token=' . $this->token,
|
||||
];
|
||||
}
|
||||
parent::initPageHeaderToolbar();
|
||||
}
|
||||
|
||||
public function initModal()
|
||||
{
|
||||
// Prevent modals
|
||||
}
|
||||
|
||||
protected function _childValidation()
|
||||
{
|
||||
if (Validate::isImageTypeName($family = Tools::getValue('family')) &&
|
||||
CEFont::familyAlreadyExists($family, Tools::getValue('id_ce_font'))
|
||||
) {
|
||||
$this->errors[] = $this->trans('This name already exists.', [], 'Admin.Design.Notification');
|
||||
}
|
||||
}
|
||||
|
||||
public function validateRules($class_name = false)
|
||||
{
|
||||
parent::validateRules($class_name);
|
||||
|
||||
if (empty($this->errors)) {
|
||||
$font_face = &${'_POST'}['font_face'];
|
||||
|
||||
if (!empty($_FILES['font_face']['name'])) {
|
||||
$upload_error = [];
|
||||
$fonts_url = 'modules/creativeelements/views/fonts/';
|
||||
$fonts_dir = _PS_ROOT_DIR_ . '/' . $fonts_url;
|
||||
|
||||
foreach ($_FILES['font_face']['name'] as $i => &$font_name) {
|
||||
$tmp_name = &$_FILES['font_face']['tmp_name'][$i];
|
||||
$error_code = &$_FILES['font_face']['error'][$i];
|
||||
|
||||
foreach (CEFont::getAllowedExt() as $ext) {
|
||||
if (empty($font_name[$ext]['file']) || empty($tmp_name[$ext]['file'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (empty($error_code[$ext]['file']) &&
|
||||
Tools::strtolower(pathinfo($font_name[$ext]['file'], PATHINFO_EXTENSION)) === $ext &&
|
||||
move_uploaded_file($tmp_name[$ext]['file'], $fonts_dir . $font_name[$ext]['file'])
|
||||
) {
|
||||
$font_face[$i][$ext]['url'] = $fonts_url . $font_name[$ext]['file'];
|
||||
} else {
|
||||
$font_face[$i][$ext]['url'] = '';
|
||||
$upload_error[] = $font_name[$ext]['file'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($upload_error) {
|
||||
$this->errors[] = $this->trans('An error occurred during the file upload process.', [], 'Admin.Notifications.Error') .
|
||||
' (' . implode(', ', $upload_error) . ')';
|
||||
}
|
||||
}
|
||||
${'_POST'}['files'] = json_encode($font_face);
|
||||
}
|
||||
}
|
||||
|
||||
public function setMedia($isNewTheme = false)
|
||||
{
|
||||
parent::setMedia($isNewTheme);
|
||||
|
||||
if ($font_face = (string) $this->ce_font) {
|
||||
$font_face = str_replace('{{BASE}}', $this->context->link->getMediaLink(__PS_BASE_URI__), $font_face);
|
||||
$font_face = str_replace(["\n", "\t"], '', $font_face);
|
||||
|
||||
$this->css_files['data:text/css,' . $font_face] = 'all';
|
||||
}
|
||||
$this->css_files[_MODULE_DIR_ . 'creativeelements/views/css/custom-fonts.css?v=' . _CE_VERSION_] = 'all';
|
||||
$this->js_files[] = _MODULE_DIR_ . 'creativeelements/views/js/custom-fonts.js?v=' . _CE_VERSION_;
|
||||
}
|
||||
|
||||
public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
|
||||
{
|
||||
parent::getList($id_lang, $order_by, $order_way, $start, $limit, $id_lang_shop);
|
||||
|
||||
// Add font previews
|
||||
if (!empty($this->_list)) {
|
||||
foreach ($this->_list as &$row) {
|
||||
$row['id'] = $row['id_ce_font'];
|
||||
$row['preview'] = new CEFont($row['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function renderList()
|
||||
{
|
||||
$this->addRowAction('edit');
|
||||
$this->addRowAction('delete');
|
||||
|
||||
return parent::renderList();
|
||||
}
|
||||
|
||||
public function renderForm()
|
||||
{
|
||||
$this->fields_form = [
|
||||
'legend' => [
|
||||
'title' => $this->l('Font'),
|
||||
'icon' => 'icon-font',
|
||||
],
|
||||
'input' => [
|
||||
[
|
||||
'type' => 'text',
|
||||
'label' => $this->l('Font Name'),
|
||||
'name' => 'family',
|
||||
'placeholder' => $this->l('Enter Font Family'),
|
||||
'required' => true,
|
||||
'col' => 8,
|
||||
],
|
||||
[
|
||||
'type' => 'hidden',
|
||||
'name' => 'files',
|
||||
],
|
||||
[
|
||||
'type' => 'html',
|
||||
'label' => $this->l('Font Files'),
|
||||
'name' => 'add_custom_font',
|
||||
'html_content' => CESmarty::capture(_CE_TEMPLATES_ . 'admin/admin.tpl', 'ce_add_custom_font'),
|
||||
'col' => 8,
|
||||
],
|
||||
],
|
||||
'submit' => [
|
||||
'title' => $this->trans('Save', [], 'Admin.Actions'),
|
||||
],
|
||||
'buttons' => [
|
||||
'save_and_stay' => [
|
||||
'type' => 'submit',
|
||||
'title' => $this->trans('Save and stay', [], 'Admin.Actions'),
|
||||
'icon' => 'process-icon-save',
|
||||
'name' => 'submitAddce_fontAndStay',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
return parent::renderForm();
|
||||
}
|
||||
|
||||
protected function trans($id, array $parameters = [], $domain = null, $locale = null)
|
||||
{
|
||||
return empty($this->translator) ? $this->l($id) : parent::trans($id, $parameters, $domain, $locale);
|
||||
}
|
||||
|
||||
protected function l($string, $module = 'creativeelements', $addslashes = false, $htmlentities = true)
|
||||
{
|
||||
$str = Translate::getModuleTranslation($module, $string, '', null, $addslashes || !$htmlentities);
|
||||
|
||||
return $htmlentities ? $str : call_user_func('stripslashes', $str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,510 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
class AdminCESettingsController extends ModuleAdminController
|
||||
{
|
||||
protected $activate_url = 'https://pagebuilder.webshopworks.com/?connect=activate';
|
||||
|
||||
protected $viewportChanged = false;
|
||||
|
||||
protected $clearCss = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->bootstrap = true;
|
||||
$this->className = 'CESettings';
|
||||
$this->table = 'configuration';
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->fields_options['general_settings'] = [
|
||||
'icon' => 'icon-cog',
|
||||
'title' => $this->l('General Settings'),
|
||||
'fields' => [
|
||||
'elementor_frontend_edit' => [
|
||||
'title' => $this->l('Show Edit Icon on Frontend'),
|
||||
'desc' => $this->l('Displays an edit icon on frontend while employee has active session. By clicking on this icon the live editor will open.'),
|
||||
'validation' => 'isBool',
|
||||
'cast' => 'intval',
|
||||
'type' => 'bool',
|
||||
'default' => '1',
|
||||
],
|
||||
'elementor_max_revisions' => [
|
||||
'title' => $this->l('Limit Revisions'),
|
||||
'desc' => $this->l('Sets the maximum number of revisions per content.'),
|
||||
'validation' => 'isUnsignedInt',
|
||||
'cast' => 'intval',
|
||||
'type' => 'select',
|
||||
'identifier' => 'value',
|
||||
'list' => [
|
||||
['value' => 0, 'name' => $this->l('Disable Revision History')],
|
||||
['value' => 1, 'name' => 1],
|
||||
['value' => 2, 'name' => 2],
|
||||
['value' => 3, 'name' => 3],
|
||||
['value' => 4, 'name' => 4],
|
||||
['value' => 5, 'name' => 5],
|
||||
['value' => 10, 'name' => 10],
|
||||
['value' => 15, 'name' => 15],
|
||||
['value' => 20, 'name' => 20],
|
||||
['value' => 25, 'name' => 25],
|
||||
['value' => 30, 'name' => 30],
|
||||
],
|
||||
],
|
||||
'elementor_disable_color_schemes' => [
|
||||
'title' => $this->l('Disable Default Colors'),
|
||||
'desc' => $this->l('If you prefer to inherit the colors from your theme, you can disable this feature.'),
|
||||
'validation' => 'isBool',
|
||||
'cast' => 'intval',
|
||||
'type' => 'bool',
|
||||
'default' => '0',
|
||||
],
|
||||
'elementor_disable_typography_schemes' => [
|
||||
'title' => $this->l('Disable Default Fonts'),
|
||||
'desc' => $this->l('If you prefer to inherit the fonts from your theme, you can disable this feature here.'),
|
||||
'validation' => 'isBool',
|
||||
'cast' => 'intval',
|
||||
'type' => 'bool',
|
||||
'default' => '0',
|
||||
],
|
||||
],
|
||||
'submit' => [
|
||||
'title' => $this->l('Save'),
|
||||
],
|
||||
];
|
||||
|
||||
$this->fields_options['style_settings'] = [
|
||||
'icon' => 'icon-adjust',
|
||||
'title' => $this->l('Style Settings'),
|
||||
'fields' => [
|
||||
'elementor_default_generic_fonts' => [
|
||||
'title' => $this->l('Default Generic Fonts'),
|
||||
'desc' => $this->l('The list of fonts used if the chosen font is not available.'),
|
||||
'cast' => 'strval',
|
||||
'type' => 'text',
|
||||
'class' => 'fixed-width-xxl',
|
||||
],
|
||||
'elementor_container_width' => [
|
||||
'title' => $this->l('Content Width'),
|
||||
'desc' => $this->l('Sets the default width of the content area (Default: 1140)'),
|
||||
'suffix' => 'px',
|
||||
'validation' => 'isUnsignedInt',
|
||||
'cast' => 'intval',
|
||||
'type' => 'text',
|
||||
'class' => 'fixed-width-sm',
|
||||
],
|
||||
'elementor_space_between_widgets' => [
|
||||
'title' => $this->l('Widgets Space'),
|
||||
'desc' => $this->l('Sets the default space between widgets (Default: 20)'),
|
||||
'suffix' => 'px',
|
||||
'validation' => 'isUnsignedInt',
|
||||
'cast' => 'intval',
|
||||
'type' => 'text',
|
||||
'class' => 'fixed-width-sm',
|
||||
],
|
||||
'elementor_stretched_section_container' => [
|
||||
'title' => $this->l('Stretched Section Fit To'),
|
||||
'desc' => $this->l('Enter parent element selector to which stretched sections will fit to (e.g. #primary / .wrapper / main etc). Leave blank to fit to page width.'),
|
||||
'cast' => 'strval',
|
||||
'type' => 'text',
|
||||
'class' => 'fixed-width-xxl',
|
||||
],
|
||||
'elementor_page_title_selector' => [
|
||||
'title' => $this->l('Page Title Selector'),
|
||||
'desc' => sprintf(
|
||||
$this->l("You can hide the title at document settings. This works for themes that have ”%s” selector. If your theme's selector is different, please enter it above."),
|
||||
'header.page-header'
|
||||
),
|
||||
'cast' => 'strval',
|
||||
'type' => 'text',
|
||||
],
|
||||
'elementor_page_wrapper_selector' => [
|
||||
'title' => $this->l('Content Wrapper Selector'),
|
||||
'desc' => sprintf(
|
||||
$this->l("You can clear margin, padding, max-width from content wrapper at document settings. This works for themes that have ”%s” selector. If your theme's selector is different, please enter it above."),
|
||||
'#content, #wrapper, #wrapper .container'
|
||||
),
|
||||
'cast' => 'strval',
|
||||
'type' => 'text',
|
||||
],
|
||||
'elementor_viewport_lg' => [
|
||||
'title' => $this->l('Tablet Breakpoint'),
|
||||
'desc' => sprintf($this->l('Sets the breakpoint between desktop and tablet devices. Below this breakpoint tablet layout will appear (Default: %dpx).'), 1025),
|
||||
'suffix' => 'px',
|
||||
'validation' => 'isUnsignedInt',
|
||||
'cast' => 'intval',
|
||||
'type' => 'text',
|
||||
'class' => 'fixed-width-sm',
|
||||
],
|
||||
'elementor_viewport_md' => [
|
||||
'title' => $this->l('Mobile Breakpoint'),
|
||||
'desc' => sprintf($this->l('Sets the breakpoint between tablet and mobile devices. Below this breakpoint mobile layout will appear (Default: %dpx).'), 768),
|
||||
'suffix' => 'px',
|
||||
'validation' => 'isUnsignedInt',
|
||||
'cast' => 'intval',
|
||||
'type' => 'text',
|
||||
'class' => 'fixed-width-sm',
|
||||
],
|
||||
'elementor_global_image_lightbox' => [
|
||||
'title' => $this->l('Image Lightbox'),
|
||||
'desc' => $this->l('Open all image links in a lightbox popup window. The lightbox will automatically work on any link that leads to an image file.'),
|
||||
'hint' => $this->l('You can customize the lightbox design by going to: Top-left hamburger icon > Global Settings > Lightbox.'),
|
||||
'validation' => 'isBool',
|
||||
'cast' => 'intval',
|
||||
'type' => 'bool',
|
||||
'default' => '1',
|
||||
],
|
||||
],
|
||||
'submit' => [
|
||||
'title' => $this->l('Save'),
|
||||
],
|
||||
];
|
||||
|
||||
$this->fields_options['advanced_settings'] = [
|
||||
'class' => 'ce-adv-settings',
|
||||
'icon' => 'icon-cogs',
|
||||
'title' => $this->l('Advanced Settings'),
|
||||
'info' => CESmarty::sprintf(_CE_TEMPLATES_ . 'admin/admin.tpl', 'ce_alert', 'warning', $this->l(
|
||||
'Do not change these options without experience, incorrect settings might break your site.'
|
||||
)),
|
||||
'fields' => [
|
||||
'elementor_css_print_method' => [
|
||||
'title' => $this->l('CSS Print Method'),
|
||||
'desc' => $this->l('Use external CSS files for all generated stylesheets. Choose this setting for better performance (recommended).'),
|
||||
'cast' => 'strval',
|
||||
'type' => 'select',
|
||||
'identifier' => 'value',
|
||||
'list' => [
|
||||
['value' => 'external', 'name' => $this->l('External File')],
|
||||
['value' => 'internal', 'name' => $this->l('Internal Embedding')],
|
||||
],
|
||||
],
|
||||
'elementor_edit_buttons' => [
|
||||
'title' => $this->l('Editing Handles'),
|
||||
'desc' => $this->l('Show editing handles when hovering over the element edit button.'),
|
||||
'cast' => 'strval',
|
||||
'type' => 'select',
|
||||
'identifier' => 'value',
|
||||
'list' => [
|
||||
['value' => '', 'name' => $this->l('Hide')],
|
||||
['value' => 'on', 'name' => $this->l('Show')],
|
||||
],
|
||||
],
|
||||
'elementor_exclude_modules' => [
|
||||
'title' => $this->l('Exclude Categories from Module widget'),
|
||||
'type' => 'multiselect',
|
||||
'class' => 'chosen',
|
||||
'cast' => 'json_encode',
|
||||
'auto_value' => false,
|
||||
'identifier' => 'value',
|
||||
'list' => [
|
||||
['value' => 'administration', 'name' => $this->trans('Administration', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'advertising_marketing', 'name' => $this->trans('Advertising & Marketing', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'analytics_stats', 'name' => $this->trans('Analytics & Stats', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'billing_invoicing', 'name' => $this->trans('Taxes & Invoicing', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'checkout', 'name' => $this->trans('Checkout', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'content_management', 'name' => $this->trans('Content Management', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'customer_reviews', 'name' => $this->trans('Customer Reviews', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'export', 'name' => $this->trans('Export', [], 'Admin.Actions')],
|
||||
['value' => 'front_office_features', 'name' => $this->trans('Front office Features', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'i18n_localization', 'name' => $this->trans('Internationalization & Localization', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'merchandizing', 'name' => $this->trans('Merchandising', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'migration_tools', 'name' => $this->trans('Migration Tools', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'payments_gateways', 'name' => $this->trans('Payments & Gateways', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'payment_security', 'name' => $this->trans('Site certification & Fraud prevention', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'pricing_promotion', 'name' => $this->trans('Pricing & Promotion', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'quick_bulk_update', 'name' => $this->trans('Quick / Bulk update', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'seo', 'name' => $this->trans('SEO', [], 'Admin.Catalog.Feature')],
|
||||
['value' => 'shipping_logistics', 'name' => $this->trans('Shipping & Logistics', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'slideshows', 'name' => $this->trans('Slideshows', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'smart_shopping', 'name' => $this->trans('Comparison site & Feed management', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'market_place', 'name' => $this->trans('Marketplace', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'others', 'name' => $this->trans('Other Modules', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'mobile', 'name' => $this->trans('Mobile', [], 'Admin.Global')],
|
||||
['value' => 'dashboard', 'name' => $this->trans('Dashboard', [], 'Admin.Global')],
|
||||
['value' => 'emailing', 'name' => $this->trans('Emailing & SMS', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'social_networks', 'name' => $this->trans('Social Networks', [], 'Admin.Modules.Feature')],
|
||||
['value' => 'social_community', 'name' => $this->trans('Social & Community', [], 'Admin.Modules.Feature')],
|
||||
],
|
||||
],
|
||||
'elementor_load_fontawesome' => [
|
||||
'title' => $this->l('Load FontAwesome Library'),
|
||||
'desc' => $this->l('FontAwesome gives you scalable vector icons that can instantly be customized - size, color, drop shadow, and anything that can be done with the power of CSS.'),
|
||||
'validation' => 'isBool',
|
||||
'cast' => 'intval',
|
||||
'type' => 'bool',
|
||||
'default' => '1',
|
||||
],
|
||||
'elementor_load_waypoints' => [
|
||||
'title' => $this->l('Load Waypoints Library'),
|
||||
'desc' => $this->l('Waypoints library is the easiest way to trigger a function when you scroll to an element.'),
|
||||
'validation' => 'isBool',
|
||||
'cast' => 'intval',
|
||||
'type' => 'bool',
|
||||
'default' => '1',
|
||||
],
|
||||
'elementor_load_slick' => [
|
||||
'title' => $this->l('Load Slick Library'),
|
||||
'desc' => $this->l('Slick is a jQuery plugin for creating fully customizable, responsive and mobile friendly carousels/sliders that work with any html elements.'),
|
||||
'validation' => 'isBool',
|
||||
'cast' => 'intval',
|
||||
'type' => 'bool',
|
||||
'default' => '1',
|
||||
],
|
||||
],
|
||||
'submit' => [
|
||||
'title' => $this->l('Save'),
|
||||
],
|
||||
];
|
||||
|
||||
$this->fields_options['experiments'] = [
|
||||
'class' => 'ce-experiments',
|
||||
'icon' => 'icon-magic',
|
||||
'title' => $this->l('Experiments'),
|
||||
'info' => CESmarty::sprintf(_CE_TEMPLATES_ . 'admin/admin.tpl', 'ce_alert', 'info', $this->l(
|
||||
"Access new and experimental features from Creative Elements before they're officially released. As these features are still in development, they are likely to change, evolve or even be removed altogether."
|
||||
)),
|
||||
'fields' => [
|
||||
'elementor_remove_hidden' => [
|
||||
'title' => $this->l('Remove Hidden Elements'),
|
||||
'desc' => $this->l('When you hide elements on "Advanced tab / Responsive section" their markup will be removed from DOM.'),
|
||||
'validation' => 'isBool',
|
||||
'cast' => 'intval',
|
||||
'type' => 'bool',
|
||||
],
|
||||
'elementor_visibility' => [
|
||||
'title' => $this->l('Visibility Section'),
|
||||
'desc' => $this->l('If you would like to schedule elements or filter them by selected customer groups, then this feature will be handy. It will appear under Advanced tab.'),
|
||||
'validation' => 'isBool',
|
||||
'cast' => 'intval',
|
||||
'type' => 'bool',
|
||||
],
|
||||
],
|
||||
'submit' => [
|
||||
'title' => $this->l('Save'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function initPageHeaderToolbar()
|
||||
{
|
||||
$this->page_header_toolbar_btn['license'] = [
|
||||
'icon' => 'process-icon-file icon-file-text',
|
||||
'desc' => $this->l('License'),
|
||||
'js' => "$('#modal_license').modal()",
|
||||
];
|
||||
$this->page_header_toolbar_btn['regenerate-css'] = [
|
||||
'icon' => 'process-icon-reload icon-rotate-right',
|
||||
'desc' => $this->l('Regenerate CSS'),
|
||||
'js' => '//' . Tools::safeOutput(
|
||||
$this->l('Styles set in Creative Elements are saved in CSS files. Recreate those files, according to the most recent settings.')
|
||||
),
|
||||
];
|
||||
if (Shop::getContext() === Shop::CONTEXT_SHOP) {
|
||||
$this->page_header_toolbar_btn['replace-url'] = [
|
||||
'icon' => 'process-icon-refresh',
|
||||
'desc' => $this->l('Replace URL'),
|
||||
'js' => "$('#modal_replace_url').modal()",
|
||||
];
|
||||
}
|
||||
|
||||
parent::initPageHeaderToolbar();
|
||||
}
|
||||
|
||||
public function initModal()
|
||||
{
|
||||
$ce_license = Configuration::getGlobalValue('CE_LICENSE');
|
||||
|
||||
$this->modals[] = [
|
||||
'modal_id' => 'modal_license',
|
||||
'modal_class' => 'modal-md',
|
||||
'modal_title' => $ce_license
|
||||
? CESmarty::get(_CE_TEMPLATES_ . 'admin/admin.tpl', 'ce_modal_license_status')
|
||||
: $this->l('Activate License')
|
||||
,
|
||||
'modal_content' => CESmarty::sprintf(
|
||||
_CE_TEMPLATES_ . 'admin/admin.tpl',
|
||||
'ce_modal_license',
|
||||
Tools::safeOutput($this->context->link->getAdminLink('AdminCESettings') . '&action=activate'),
|
||||
$this->l(
|
||||
$ce_license
|
||||
? 'Your website is activated. Want to activate this website by a different license?'
|
||||
: 'Please activate your license to get unlimited access to the template library.'
|
||||
),
|
||||
$this->l($ce_license ? 'Switch License' : 'Activate')
|
||||
),
|
||||
];
|
||||
$this->modals[] = [
|
||||
'modal_id' => 'modal_replace_url',
|
||||
'modal_class' => 'modal-md',
|
||||
'modal_title' => $this->l('Update Site Address (URL)'),
|
||||
'modal_content' => CESmarty::sprintf(
|
||||
_CE_TEMPLATES_ . 'admin/admin.tpl',
|
||||
'ce_modal_replace_url',
|
||||
$this->l('It is strongly recommended that you backup your database before using Replace URL.'),
|
||||
$this->l('http://old-url.com'),
|
||||
$this->l('http://new-url.com'),
|
||||
$this->l('Enter your old and new URLs for your PrestaShop installation, to update all Creative Elements data (Relevant for domain transfers or move to \'HTTPS\').'),
|
||||
$this->l('Replace URL')
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
protected function processActivate()
|
||||
{
|
||||
$url = $this->context->link->getAdminLink('AdminCESettings');
|
||||
|
||||
if (Tools::getIsset('license')) {
|
||||
Configuration::updateGlobalValue('CE_LICENSE', Tools::getValue('license'));
|
||||
$url .= '#license';
|
||||
} else {
|
||||
list($p, $r) = explode('://', CE\wp_referer());
|
||||
$encode = 'base64_encode';
|
||||
$url = $this->activate_url . '&' . http_build_query([
|
||||
'response_type' => 'code',
|
||||
'client_id' => Tools::substr($encode(_COOKIE_KEY_), 0, 32),
|
||||
'auth_secret' => rtrim($encode("$r?" . Tools::passwdGen(23 - Tools::strlen($r))), '='),
|
||||
'state' => Tools::substr($encode($this->module->module_key), 0, 12),
|
||||
'redirect_uri' => urlencode($url),
|
||||
]);
|
||||
}
|
||||
Tools::redirectAdmin($url);
|
||||
}
|
||||
|
||||
public function setMedia($isNewTheme = false)
|
||||
{
|
||||
parent::setMedia($isNewTheme);
|
||||
|
||||
$this->css_files[_MODULE_DIR_ . 'creativeelements/views/css/settings.css?v=' . _CE_VERSION_] = 'all';
|
||||
$this->js_files[] = _MODULE_DIR_ . 'creativeelements/views/js/settings.js?v=' . _CE_VERSION_;
|
||||
}
|
||||
|
||||
protected function processUpdateOptions()
|
||||
{
|
||||
parent::processUpdateOptions();
|
||||
|
||||
if ($this->viewportChanged) {
|
||||
CE\Plugin::instance();
|
||||
CE\CoreXResponsiveXResponsive::compileStylesheetTemplates();
|
||||
$this->clearCss = true;
|
||||
}
|
||||
empty($this->clearCss) or CE\Plugin::instance()->files_manager->clearCache();
|
||||
}
|
||||
|
||||
protected function updateOptionElementorContainerWidth($val)
|
||||
{
|
||||
if (Configuration::get('elementor_container_width') != $val) {
|
||||
Configuration::updateValue('elementor_container_width', $val);
|
||||
|
||||
$this->clearCss = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function updateOptionElementorPageTitleSelector($val)
|
||||
{
|
||||
$val = trim($val);
|
||||
|
||||
if (!empty($val) && Validate::isCleanHtml($val)) {
|
||||
Configuration::updateValue('elementor_page_title_selector', $val);
|
||||
} else {
|
||||
$this->errors[] = $this->trans('Required field', [], 'Shop.Forms.Errors') . ': ' . $this->l('Page Title Selector');
|
||||
}
|
||||
}
|
||||
|
||||
protected function updateOptionElementorFullWidthSelector($val)
|
||||
{
|
||||
$val = trim($val);
|
||||
|
||||
if (!empty($val) && Validate::isCleanHtml($val)) {
|
||||
Configuration::updateValue('elementor_full_width_selector', $val);
|
||||
} else {
|
||||
$this->errors[] = $this->trans('Required field', [], 'Shop.Forms.Errors') . ': ' . $this->l('Content Wrapper Selector');
|
||||
}
|
||||
}
|
||||
|
||||
protected function updateOptionElementorViewportLg($val)
|
||||
{
|
||||
if (Configuration::get('elementor_viewport_lg') != $val) {
|
||||
Configuration::updateValue('elementor_viewport_lg', $val);
|
||||
|
||||
$this->viewportChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function updateOptionElementorViewportMd($val)
|
||||
{
|
||||
if (Configuration::get('elementor_viewport_md') != $val) {
|
||||
Configuration::updateValue('elementor_viewport_md', $val);
|
||||
|
||||
$this->viewportChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function updateOptionElementorCssPrintMethod($val)
|
||||
{
|
||||
if (Configuration::get('elementor_css_print_method') != $val) {
|
||||
Configuration::updateValue('elementor_css_print_method', $val);
|
||||
|
||||
$this->clearCss = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function ajaxProcessRegenerateCss()
|
||||
{
|
||||
CE\Plugin::instance()->files_manager->clearCache();
|
||||
|
||||
CE\wp_send_json_success();
|
||||
}
|
||||
|
||||
public function ajaxProcessReplaceUrl()
|
||||
{
|
||||
$from = trim(Tools::getValue('from'));
|
||||
$to = trim(Tools::getValue('to'));
|
||||
|
||||
$is_valid_urls = filter_var($from, FILTER_VALIDATE_URL) && filter_var($to, FILTER_VALIDATE_URL);
|
||||
|
||||
if (!$is_valid_urls) {
|
||||
CE\wp_send_json_error(CE\__("The `from` and `to` URL's must be a valid URL"));
|
||||
}
|
||||
|
||||
if ($from === $to) {
|
||||
CE\wp_send_json_error(CE\__("The `from` and `to` URL's must be different"));
|
||||
}
|
||||
|
||||
$db = Db::getInstance();
|
||||
$table = _DB_PREFIX_ . 'ce_meta';
|
||||
$id = sprintf('%02d', $this->context->shop->id);
|
||||
$old = str_replace('/', '\\\/', $from);
|
||||
$new = str_replace('/', '\\\/', $to);
|
||||
|
||||
$result = $db->execute("
|
||||
UPDATE $table SET `value` = REPLACE(`value`, '$old', '$new')
|
||||
WHERE `name` = '_elementor_data' AND `id` LIKE '%$id' AND `value` <> '[]'
|
||||
");
|
||||
|
||||
if (false === $result) {
|
||||
CE\wp_send_json_error(CE\__('An error occurred'));
|
||||
} else {
|
||||
CE\wp_send_json_success(sprintf(CE\__('%d Rows Affected'), $db->affected_rows()));
|
||||
}
|
||||
}
|
||||
|
||||
protected function trans($id, array $parameters = [], $domain = null, $locale = null)
|
||||
{
|
||||
return empty($this->translator) ? $this->l($id) : parent::trans($id, $parameters, $domain, $locale);
|
||||
}
|
||||
|
||||
protected function l($string, $module = 'creativeelements', $addslashes = false, $htmlentities = true)
|
||||
{
|
||||
$str = Translate::getModuleTranslation($module, $string, '', null, $addslashes || !$htmlentities);
|
||||
|
||||
return $htmlentities ? $str : call_user_func('stripslashes', $str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,415 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
require_once _PS_MODULE_DIR_ . 'creativeelements/classes/CETemplate.php';
|
||||
|
||||
class AdminCETemplatesController extends ModuleAdminController
|
||||
{
|
||||
public $bootstrap = true;
|
||||
|
||||
public $table = 'ce_template';
|
||||
|
||||
public $identifier = 'id_ce_template';
|
||||
|
||||
public $className = 'CETemplate';
|
||||
|
||||
protected $_defaultOrderBy = 'title';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
if ($type = Tools::getValue('type')) {
|
||||
if ('all' == $type) {
|
||||
unset($this->context->cookie->submitFilterce_template);
|
||||
unset($this->context->cookie->cetemplatesce_templateFilter_type);
|
||||
} else {
|
||||
$this->context->cookie->submitFilterce_template = 1;
|
||||
$this->context->cookie->cetemplatesce_templateFilter_type = $type;
|
||||
}
|
||||
}
|
||||
|
||||
$this->fields_options['import-template'] = [
|
||||
'class' => 'ce-import-panel hide',
|
||||
'icon' => 'icon-upload',
|
||||
'title' => $this->l('Import Template'),
|
||||
'description' => $this->l('Choose a JSON template file or a .zip archive of templates, and add them to the list of templates available in your library.'),
|
||||
'fields' => [
|
||||
'action' => [
|
||||
'type' => 'hidden',
|
||||
'value' => 'import_template',
|
||||
'no_multishop_checkbox' => true,
|
||||
],
|
||||
'file' => [
|
||||
'type' => 'file',
|
||||
'title' => $this->l('Template file'),
|
||||
'name' => 'file',
|
||||
'no_multishop_checkbox' => true,
|
||||
],
|
||||
],
|
||||
'submit' => [
|
||||
'imgclass' => 'import',
|
||||
'title' => $this->l('Import Now'),
|
||||
],
|
||||
];
|
||||
|
||||
$this->fields_list = [
|
||||
'id_ce_template' => [
|
||||
'title' => $this->trans('ID', [], 'Admin.Global'),
|
||||
'class' => 'fixed-width-xs',
|
||||
'align' => 'center',
|
||||
],
|
||||
'title' => [
|
||||
'title' => $this->trans('Title', [], 'Admin.Global'),
|
||||
],
|
||||
'type' => [
|
||||
'title' => $this->trans('Type', [], 'Admin.Catalog.Feature'),
|
||||
'class' => 'fixed-width-lg',
|
||||
'type' => 'select',
|
||||
'list' => [
|
||||
'page' => $this->l('Page'),
|
||||
'section' => $this->l('Section'),
|
||||
'header' => $this->l('Header'),
|
||||
'footer' => $this->l('Footer'),
|
||||
'page-index' => $this->l('Home Page'),
|
||||
'page-contact' => $this->l('Contact Page'),
|
||||
'product' => $this->l('Product Page'),
|
||||
'product-quick-view' => $this->l('Quick View'),
|
||||
'product-miniature' => $this->l('Product Miniature'),
|
||||
'page-not-found' => $this->l('404 Page'),
|
||||
],
|
||||
'filter_key' => 'type',
|
||||
],
|
||||
'date_add' => [
|
||||
'title' => $this->trans('Created on', [], 'Modules.Facetedsearch.Admin'),
|
||||
'class' => 'fixed-width-lg',
|
||||
'type' => 'datetime',
|
||||
],
|
||||
'date_upd' => [
|
||||
'title' => $this->l('Modified on'),
|
||||
'class' => 'fixed-width-lg',
|
||||
'type' => 'datetime',
|
||||
],
|
||||
'active' => [
|
||||
'title' => $this->trans('Active', [], 'Admin.Global'),
|
||||
'class' => 'fixed-width-xs',
|
||||
'align' => 'center',
|
||||
'active' => 'status',
|
||||
'type' => 'bool',
|
||||
],
|
||||
'shortcode' => [
|
||||
'title' => $this->l('Shortcode'),
|
||||
'class' => 'ce-shortcode',
|
||||
'type' => 'editable',
|
||||
'orderby' => false,
|
||||
'search' => false,
|
||||
],
|
||||
];
|
||||
|
||||
$this->bulk_actions = [
|
||||
'export' => [
|
||||
'text' => $this->trans('Export', [], 'Admin.Actions'),
|
||||
'icon' => 'icon-mail-forward',
|
||||
],
|
||||
'delete_divider' => [
|
||||
'text' => 'divider',
|
||||
],
|
||||
'delete' => [
|
||||
'text' => $this->l('Delete'),
|
||||
'icon' => 'icon-trash text-danger',
|
||||
'confirm' => $this->trans('Delete selected items?', [], 'Admin.Notifications.Info'),
|
||||
],
|
||||
];
|
||||
|
||||
$this->action_link = CESmarty::get(_CE_TEMPLATES_ . 'admin/admin.tpl', 'ce_action_link');
|
||||
}
|
||||
|
||||
public function processBulkExport()
|
||||
{
|
||||
$uids = [];
|
||||
|
||||
foreach ($this->boxes as $id) {
|
||||
$uids[] = new CE\UId($id, CE\UId::TEMPLATE);
|
||||
}
|
||||
|
||||
CE\Plugin::instance()->templates_manager->getSource('local')->exportMultipleTemplates($uids);
|
||||
}
|
||||
|
||||
protected function processUpdateOptions()
|
||||
{
|
||||
// Process import template
|
||||
CE\UId::$_ID = new CE\UId(0, CE\UId::TEMPLATE);
|
||||
|
||||
$res = CE\Plugin::instance()->templates_manager->directImportTemplate();
|
||||
|
||||
if ($res instanceof CE\WPError) {
|
||||
$this->errors[] = $res->getMessage();
|
||||
} elseif (isset($res[1]['template_id'])) {
|
||||
// More templates
|
||||
Tools::redirectAdmin($this->context->link->getAdminLink('AdminCETemplates') . '&conf=18');
|
||||
} elseif (isset($res[0]['template_id'])) {
|
||||
// Simple template
|
||||
$id = Tools::substr($res[0]['template_id'], 0, -6);
|
||||
|
||||
Tools::redirectAdmin(
|
||||
$this->context->link->getAdminLink('AdminCETemplates') . "&id_ce_template=$id&updatece_template&conf=18"
|
||||
);
|
||||
} else {
|
||||
$this->errors[] = $this->l('Unknown error during import!');
|
||||
}
|
||||
}
|
||||
|
||||
public function ajaxProcessMigrate()
|
||||
{
|
||||
if ($ids = Tools::getValue('ids')) {
|
||||
require_once _CE_PATH_ . 'classes/CEMigrate.php';
|
||||
|
||||
$done = [];
|
||||
|
||||
foreach ($ids as $id) {
|
||||
CEMigrate::moveTemplate($id) && $done[] = (int) $id;
|
||||
}
|
||||
$res = CEMigrate::removeIds('template', $done);
|
||||
|
||||
die(json_encode($res));
|
||||
}
|
||||
}
|
||||
|
||||
public function initHeader()
|
||||
{
|
||||
parent::initHeader();
|
||||
|
||||
$id_lang = $this->context->language->id;
|
||||
$link = $this->context->link;
|
||||
$tabs = &$this->context->smarty->tpl_vars['tabs']->value;
|
||||
$sections = [
|
||||
'section',
|
||||
'header',
|
||||
'footer',
|
||||
'product-quick-view',
|
||||
'product-miniature',
|
||||
];
|
||||
|
||||
foreach ($tabs as &$tab0) {
|
||||
foreach ($tab0['sub_tabs'] as &$tab1) {
|
||||
if ('AdminParentCEContent' === $tab1['class_name']) {
|
||||
foreach ($tab1['sub_tabs'] as &$tab2) {
|
||||
if ('AdminCETemplates' === $tab2['class_name']) {
|
||||
$sub_tabs = &$tab2['sub_tabs'];
|
||||
$tab = Tab::getTab($id_lang, Tab::getIdFromClassName('AdminCETemplates'));
|
||||
$new = Tools::getIsset('addce_template');
|
||||
$href = $link->getAdminLink('AdminCETemplates');
|
||||
$type = $this->context->cookie->cetemplatesce_templateFilter_type;
|
||||
|
||||
$tab['name'] = $this->l('Templates');
|
||||
$tab['current'] = $new || (!in_array($type, ['section', 'page']) || !$type) && !$this->object;
|
||||
$tab['href'] = "$href&type=all";
|
||||
$sub_tabs[] = $tab;
|
||||
|
||||
$tab['name'] = $this->l('Page');
|
||||
$tab['current'] = !$new && ($this->object ? !in_array($this->object->type, $sections) : 'page' === $type);
|
||||
$tab['href'] = "$href&type=page";
|
||||
$sub_tabs[] = $tab;
|
||||
|
||||
$tab['name'] = $this->l('Section');
|
||||
$tab['current'] = !$new && ($this->object ? in_array($this->object->type, $sections) : 'section' === $type);
|
||||
$tab['href'] = "$href&type=section";
|
||||
$sub_tabs[] = $tab;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function initToolBarTitle()
|
||||
{
|
||||
$this->context->smarty->assign('icon', 'icon-list');
|
||||
|
||||
$this->toolbar_title[] = $this->l(
|
||||
'add' === $this->display ? 'Add New Template' : ('edit' === $this->display ? 'Edit Template' : 'Templates List')
|
||||
);
|
||||
}
|
||||
|
||||
public function initPageHeaderToolbar()
|
||||
{
|
||||
if ('add' !== $this->display && 'edit' !== $this->display) {
|
||||
$this->page_header_toolbar_btn['addce_template'] = [
|
||||
'icon' => 'process-icon-new',
|
||||
'desc' => $this->trans('Add new', [], 'Admin.Actions'),
|
||||
'href' => self::$currentIndex . '&addce_template&token=' . $this->token,
|
||||
];
|
||||
$this->page_header_toolbar_btn['importce_template'] = [
|
||||
'icon' => 'process-icon-import',
|
||||
'desc' => $this->trans('Import', [], 'Admin.Actions'),
|
||||
'href' => 'javascript:ceAdmin.onClickImport()',
|
||||
];
|
||||
}
|
||||
parent::initPageHeaderToolbar();
|
||||
}
|
||||
|
||||
public function initModal()
|
||||
{
|
||||
// Prevent modals
|
||||
}
|
||||
|
||||
public function initContent()
|
||||
{
|
||||
$this->context->smarty->assign('current_tab_level', 3);
|
||||
|
||||
return parent::initContent();
|
||||
}
|
||||
|
||||
public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
|
||||
{
|
||||
parent::getList($id_lang, $order_by, $order_way, $start, $limit, $id_lang_shop);
|
||||
|
||||
// Translate template types
|
||||
if (!empty($this->_list)) {
|
||||
$type = &$this->fields_list['type']['list'];
|
||||
|
||||
foreach ($this->_list as &$row) {
|
||||
$row['id'] = $row['id_ce_template'];
|
||||
$row['shortcode'] = '{hook h="CETemplate" id="' . $row['id'] . '"}';
|
||||
empty($type[$row['type']]) or $row['type'] = $type[$row['type']];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function renderList()
|
||||
{
|
||||
$this->addRowAction('edit');
|
||||
$this->addRowAction('preview');
|
||||
$this->addRowAction('export');
|
||||
$this->addRowAction('delete');
|
||||
|
||||
return parent::renderList();
|
||||
}
|
||||
|
||||
public function displayPreviewLink($token, $id, $name = null)
|
||||
{
|
||||
$link = $this->context->link->getModuleLink('creativeelements', 'preview', [
|
||||
'id_employee' => $this->context->employee->id,
|
||||
'adtoken' => Tools::getAdminTokenLite('AdminCETemplates'),
|
||||
'preview_id' => "{$id}010000",
|
||||
], null, null, null, true);
|
||||
|
||||
return sprintf($this->action_link, Tools::safeOutput($link), '_blank', 'eye', $this->trans('Preview', [], 'Admin.Actions'));
|
||||
}
|
||||
|
||||
public function displayExportLink($token, $id, $name = null)
|
||||
{
|
||||
$link = $this->context->link->getAdminLink('AdminCEEditor') . '&' . http_build_query([
|
||||
'ajax' => 1,
|
||||
'action' => 'elementor_library_direct_actions',
|
||||
'library_action' => 'export_template',
|
||||
'source' => 'local',
|
||||
'template_id' => "{$id}010000",
|
||||
]);
|
||||
|
||||
return sprintf($this->action_link, Tools::safeOutput($link), '_self', 'mail-forward', $this->trans('Export', [], 'Admin.Actions'));
|
||||
}
|
||||
|
||||
protected function getTemplateType()
|
||||
{
|
||||
return ($type = $this->object->type) ? [
|
||||
['value' => $type, 'label' => $this->fields_list['type']['list'][$type]],
|
||||
] : [
|
||||
['value' => 'page', 'label' => $this->l('Page')],
|
||||
['value' => 'section', 'label' => $this->l('Section')],
|
||||
];
|
||||
}
|
||||
|
||||
public function renderForm()
|
||||
{
|
||||
$col = version_compare(_PS_VERSION_, '1.7.8', '<') ? 7 : 6;
|
||||
|
||||
$this->fields_form = [
|
||||
'legend' => [
|
||||
'title' => $this->l('Template'),
|
||||
'icon' => 'icon-edit',
|
||||
],
|
||||
'input' => [
|
||||
[
|
||||
'type' => 'text',
|
||||
'label' => $this->trans('Title', [], 'Admin.Global'),
|
||||
'name' => 'title',
|
||||
'col' => $col,
|
||||
],
|
||||
[
|
||||
'type' => 'select',
|
||||
'label' => $this->trans('Type', [], 'Admin.Catalog.Feature'),
|
||||
'name' => 'type',
|
||||
'options' => [
|
||||
'query' => $this->getTemplateType(),
|
||||
'id' => 'value',
|
||||
'name' => 'label',
|
||||
],
|
||||
'col' => 3,
|
||||
],
|
||||
[
|
||||
'type' => 'textarea',
|
||||
'label' => $this->l('Content'),
|
||||
'name' => 'content',
|
||||
'col' => $col,
|
||||
],
|
||||
[
|
||||
'type' => 'switch',
|
||||
'label' => $this->trans('Active', [], 'Admin.Global'),
|
||||
'name' => 'active',
|
||||
'required' => false,
|
||||
'is_bool' => true,
|
||||
'values' => [
|
||||
[
|
||||
'id' => 'active_on',
|
||||
'value' => 1,
|
||||
'label' => $this->trans('Enabled', [], 'Admin.Global'),
|
||||
],
|
||||
[
|
||||
'id' => 'active_off',
|
||||
'value' => 0,
|
||||
'label' => $this->trans('Disabled', [], 'Admin.Global'),
|
||||
],
|
||||
],
|
||||
'default_value' => 1,
|
||||
],
|
||||
],
|
||||
'submit' => [
|
||||
'title' => $this->trans('Save', [], 'Admin.Actions'),
|
||||
],
|
||||
'buttons' => [
|
||||
'save_and_stay' => [
|
||||
'type' => 'submit',
|
||||
'title' => $this->trans('Save and stay', [], 'Admin.Actions'),
|
||||
'icon' => 'process-icon-save',
|
||||
'name' => 'submitAddce_templateAndStay',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
return parent::renderForm();
|
||||
}
|
||||
|
||||
protected function trans($id, array $parameters = [], $domain = null, $locale = null)
|
||||
{
|
||||
return empty($this->translator) ? $this->l($id) : parent::trans($id, $parameters, $domain, $locale);
|
||||
}
|
||||
|
||||
protected function l($string, $module = 'creativeelements', $addslashes = false, $htmlentities = true)
|
||||
{
|
||||
$str = Translate::getModuleTranslation($module, $string, '', null, $addslashes || !$htmlentities);
|
||||
|
||||
return $htmlentities ? $str : call_user_func('stripslashes', $str);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,462 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
require_once _PS_MODULE_DIR_ . 'creativeelements/classes/CETheme.php';
|
||||
|
||||
class AdminCEThemesController extends ModuleAdminController
|
||||
{
|
||||
public $bootstrap = true;
|
||||
|
||||
public $table = 'ce_theme';
|
||||
|
||||
public $identifier = 'id_ce_theme';
|
||||
|
||||
public $className = 'CETheme';
|
||||
|
||||
public $lang = true;
|
||||
|
||||
protected $_defaultOrderBy = 'title';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
if ($type = Tools::getValue('type')) {
|
||||
if ('all' == $type) {
|
||||
unset($this->context->cookie->submitFilterce_template);
|
||||
unset($this->context->cookie->cethemesce_themeFilter_type);
|
||||
} else {
|
||||
$this->context->cookie->submitFilterce_theme = 1;
|
||||
$this->context->cookie->cethemesce_themeFilter_type = $type;
|
||||
}
|
||||
}
|
||||
|
||||
if ((Tools::getIsset('updatece_theme') || Tools::getIsset('addce_theme')) && Shop::getContextShopID() === null) {
|
||||
$this->displayWarning(
|
||||
$this->trans('You are in a multistore context: any modification will impact all your shops, or each shop of the active group.', [], 'Admin.Catalog.Notification')
|
||||
);
|
||||
}
|
||||
|
||||
$table_shop = _DB_PREFIX_ . $this->table . '_shop';
|
||||
$this->_select = 'sa.*';
|
||||
$this->_join = "LEFT JOIN $table_shop sa ON sa.id_ce_theme = a.id_ce_theme AND b.id_shop = sa.id_shop";
|
||||
$this->_where = "AND sa.id_shop = " . (int) $this->context->shop->id;
|
||||
|
||||
$this->fields_list = [
|
||||
'id_ce_theme' => [
|
||||
'title' => $this->trans('ID', [], 'Admin.Global'),
|
||||
'class' => 'fixed-width-xs',
|
||||
'align' => 'center',
|
||||
],
|
||||
'title' => [
|
||||
'title' => $this->trans('Title', [], 'Admin.Global'),
|
||||
],
|
||||
'type' => [
|
||||
'title' => $this->trans('Type', [], 'Admin.Catalog.Feature'),
|
||||
'class' => 'fixed-width-xl',
|
||||
'type' => 'select',
|
||||
'list' => [
|
||||
'header' => $this->l('Header'),
|
||||
'footer' => $this->l('Footer'),
|
||||
'page' => $this->l('Page'),
|
||||
'page-index' => $this->l('Home Page'),
|
||||
'page-contact' => $this->l('Contact Page'),
|
||||
'prod' => $this->l('Product'),
|
||||
'product' => $this->l('Product Page'),
|
||||
'product-quick-view' => $this->l('Quick View'),
|
||||
'product-miniature' => $this->l('Product Miniature'),
|
||||
'page-not-found' => $this->l('404 Page'),
|
||||
],
|
||||
'filter_key' => 'type',
|
||||
],
|
||||
'date_add' => [
|
||||
'title' => $this->trans('Created on', [], 'Modules.Facetedsearch.Admin'),
|
||||
'filter_key' => 'sa!date_add',
|
||||
'class' => 'fixed-width-lg',
|
||||
'type' => 'datetime',
|
||||
],
|
||||
'date_upd' => [
|
||||
'title' => $this->l('Modified on'),
|
||||
'filter_key' => 'sa!date_upd',
|
||||
'class' => 'fixed-width-lg',
|
||||
'type' => 'datetime',
|
||||
],
|
||||
'active' => [
|
||||
'title' => $this->trans('Active', [], 'Admin.Global'),
|
||||
'filter_key' => 'sa!active',
|
||||
'class' => 'fixed-width-xs',
|
||||
'align' => 'center',
|
||||
'active' => 'status',
|
||||
'type' => 'bool',
|
||||
],
|
||||
];
|
||||
|
||||
$this->bulk_actions = [
|
||||
'delete' => [
|
||||
'text' => $this->trans('Delete selected', [], 'Admin.Notifications.Info'),
|
||||
'icon' => 'fa fa-icon-trash',
|
||||
'confirm' => $this->trans('Delete selected items?', [], 'Admin.Notifications.Info'),
|
||||
],
|
||||
];
|
||||
|
||||
$this->fields_options['theme_settings'] = [
|
||||
'class' => 'ce-theme-panel',
|
||||
'icon' => 'icon-cog',
|
||||
'title' => $this->l('Theme Settings'),
|
||||
'fields' => [
|
||||
'CE_HEADER' => [
|
||||
'title' => $this->l('Header'),
|
||||
'cast' => 'strval',
|
||||
'type' => 'select',
|
||||
'identifier' => 'value',
|
||||
'list' => array_merge(
|
||||
[
|
||||
['value' => '', 'name' => $this->l('Default')],
|
||||
],
|
||||
CETheme::getOptions('header', $this->context->language->id, $this->context->shop->id)
|
||||
),
|
||||
],
|
||||
'CE_PAGE_INDEX' => [
|
||||
'title' => $this->l('Home Page'),
|
||||
'cast' => 'strval',
|
||||
'type' => 'select',
|
||||
'identifier' => 'value',
|
||||
'list' => array_merge(
|
||||
[
|
||||
['value' => '', 'name' => $this->l('Default')],
|
||||
],
|
||||
CETheme::getOptions('page-index', $this->context->language->id, $this->context->shop->id)
|
||||
),
|
||||
],
|
||||
'CE_PRODUCT' => [
|
||||
'title' => $this->l('Product Page'),
|
||||
'cast' => 'strval',
|
||||
'type' => 'select',
|
||||
'identifier' => 'value',
|
||||
'list' => array_merge(
|
||||
[
|
||||
['value' => '', 'name' => $this->l('Default')],
|
||||
],
|
||||
CETheme::getOptions('product', $this->context->language->id, $this->context->shop->id)
|
||||
),
|
||||
],
|
||||
'CE_FOOTER' => [
|
||||
'title' => $this->l('Footer'),
|
||||
'cast' => 'strval',
|
||||
'type' => 'select',
|
||||
'identifier' => 'value',
|
||||
'list' => array_merge(
|
||||
[
|
||||
['value' => '', 'name' => $this->l('Default')],
|
||||
],
|
||||
CETheme::getOptions('footer', $this->context->language->id, $this->context->shop->id)
|
||||
),
|
||||
],
|
||||
'CE_PAGE_CONTACT' => [
|
||||
'title' => $this->l('Contact Page'),
|
||||
'cast' => 'strval',
|
||||
'type' => 'select',
|
||||
'identifier' => 'value',
|
||||
'list' => array_merge(
|
||||
[
|
||||
['value' => '', 'name' => $this->l('Default')],
|
||||
],
|
||||
CETheme::getOptions('page-contact', $this->context->language->id, $this->context->shop->id)
|
||||
),
|
||||
],
|
||||
'CE_PRODUCT_QUICK_VIEW' => [
|
||||
'title' => $this->l('Quick View'),
|
||||
'cast' => 'strval',
|
||||
'type' => 'select',
|
||||
'identifier' => 'value',
|
||||
'list' => array_merge(
|
||||
[
|
||||
['value' => '', 'name' => $this->l('Default')],
|
||||
],
|
||||
CETheme::getOptions('product-quick-view', $this->context->language->id, $this->context->shop->id)
|
||||
),
|
||||
],
|
||||
'CE_PAGE_NOT_FOUND' => [
|
||||
'title' => $this->l('404 Page'),
|
||||
'cast' => 'strval',
|
||||
'type' => 'select',
|
||||
'identifier' => 'value',
|
||||
'list' => array_merge(
|
||||
[
|
||||
['value' => '', 'name' => $this->l('Default')],
|
||||
],
|
||||
CETheme::getOptions('page-not-found', $this->context->language->id, $this->context->shop->id)
|
||||
),
|
||||
],
|
||||
'CE_PRODUCT_MINIATURE' => [
|
||||
'title' => $this->l('Product Miniature'),
|
||||
'cast' => 'strval',
|
||||
'type' => 'select',
|
||||
'identifier' => 'value',
|
||||
'list' => array_merge(
|
||||
[
|
||||
['value' => '', 'name' => $this->l('Default')],
|
||||
],
|
||||
CETheme::getOptions('product-miniature', $this->context->language->id, $this->context->shop->id)
|
||||
),
|
||||
],
|
||||
],
|
||||
'submit' => [
|
||||
'title' => $this->l('Save'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function initHeader()
|
||||
{
|
||||
parent::initHeader();
|
||||
|
||||
$id_lang = $this->context->language->id;
|
||||
$link = $this->context->link;
|
||||
$tabs = &$this->context->smarty->tpl_vars['tabs']->value;
|
||||
|
||||
foreach ($tabs as &$tab0) {
|
||||
foreach ($tab0['sub_tabs'] as &$tab1) {
|
||||
if ($tab1['class_name'] == 'AdminParentCEContent') {
|
||||
foreach ($tab1['sub_tabs'] as &$tab2) {
|
||||
if ($tab2['class_name'] == 'AdminCEThemes') {
|
||||
$sub_tabs = &$tab2['sub_tabs'];
|
||||
$tab = Tab::getTab($id_lang, Tab::getIdFromClassName('AdminCEThemes'));
|
||||
$new = Tools::getIsset('addce_theme');
|
||||
$href = $link->getAdminLink('AdminCEThemes');
|
||||
$type = Tools::getValue('type', $this->context->cookie->cethemesce_themeFilter_type);
|
||||
|
||||
$tab['name'] = $this->l('Templates');
|
||||
$tab['current'] = $new || (!$type || 'all' === $type) && !$this->object;
|
||||
$tab['href'] = "$href&type=all";
|
||||
$sub_tabs[] = $tab;
|
||||
|
||||
$type = $this->object ? $this->object->type : $type;
|
||||
|
||||
$tab['name'] = $this->l('Header');
|
||||
$tab['current'] = !$new && 'header' === $type;
|
||||
$tab['href'] = "$href&type=header";
|
||||
$sub_tabs[] = $tab;
|
||||
|
||||
$tab['name'] = $this->l('Footer');
|
||||
$tab['current'] = !$new && 'footer' === $type;
|
||||
$tab['href'] = "$href&type=footer";
|
||||
$sub_tabs[] = $tab;
|
||||
|
||||
$tab['name'] = $this->l('Page');
|
||||
$tab['current'] = !$new && stripos($type, 'page') === 0;
|
||||
$tab['href'] = "$href&type=page";
|
||||
$sub_tabs[] = $tab;
|
||||
|
||||
$tab['name'] = $this->l('Product');
|
||||
$tab['current'] = !$new && 'product-miniature' !== $type && stripos($type, 'prod') === 0;
|
||||
$tab['href'] = "$href&type=prod";
|
||||
$sub_tabs[] = $tab;
|
||||
|
||||
$tab['name'] = $this->l('Miniature');
|
||||
$tab['current'] = !$new && 'product-miniature' === $type;
|
||||
$tab['href'] = "$href&type=product-miniature";
|
||||
$sub_tabs[] = $tab;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function initToolBarTitle()
|
||||
{
|
||||
$this->page_header_toolbar_title = $this->l('Theme Builder');
|
||||
|
||||
$this->context->smarty->assign('icon', 'icon-list');
|
||||
|
||||
$this->toolbar_title[] = $this->l(
|
||||
'add' === $this->display ? 'Add New Template' : ('edit' === $this->display ? 'Edit Template' : 'Templates List')
|
||||
);
|
||||
}
|
||||
|
||||
public function initPageHeaderToolbar()
|
||||
{
|
||||
if (empty($this->display) || 'options' === $this->display) {
|
||||
$this->page_header_toolbar_btn['addce_theme'] = [
|
||||
'href' => self::$currentIndex . '&addce_theme&token=' . $this->token,
|
||||
'desc' => $this->trans('Add new', [], 'Admin.Actions'),
|
||||
'icon' => 'process-icon-new',
|
||||
];
|
||||
}
|
||||
parent::initPageHeaderToolbar();
|
||||
}
|
||||
|
||||
public function initModal()
|
||||
{
|
||||
// Prevent modals
|
||||
}
|
||||
|
||||
public function initContent()
|
||||
{
|
||||
$this->context->smarty->assign('current_tab_level', 3);
|
||||
|
||||
return parent::initContent();
|
||||
}
|
||||
|
||||
public function processFilter()
|
||||
{
|
||||
$type = Tools::getValue('type', $this->context->cookie->cethemesce_themeFilter_type);
|
||||
|
||||
if ('page' === $type || 'prod' === $type) {
|
||||
// Trick for type filtering, use LIKE instead of =
|
||||
$this->fields_list['type']['type'] = 'text';
|
||||
}
|
||||
parent::processFilter();
|
||||
|
||||
$this->fields_list['type']['type'] = 'select';
|
||||
}
|
||||
|
||||
public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
|
||||
{
|
||||
parent::getList($id_lang, $order_by, $order_way, $start, $limit, $id_lang_shop);
|
||||
|
||||
// Translate template types
|
||||
if (!empty($this->_list)) {
|
||||
$type = &$this->fields_list['type']['list'];
|
||||
|
||||
foreach ($this->_list as &$row) {
|
||||
empty($type[$row['type']]) or $row['type'] = $type[$row['type']];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function renderList()
|
||||
{
|
||||
$this->addRowAction('edit');
|
||||
$this->addRowAction('delete');
|
||||
|
||||
return parent::renderList();
|
||||
}
|
||||
|
||||
protected function getThemeType()
|
||||
{
|
||||
$theme_types = [
|
||||
['value' => '', 'label' => $this->l('Select...')],
|
||||
['value' => 'header', 'label' => $this->l('Header')],
|
||||
['value' => 'footer', 'label' => $this->l('Footer')],
|
||||
['value' => 'page-index', 'label' => $this->l('Home Page')],
|
||||
['value' => 'page-contact', 'label' => $this->l('Contact Page')],
|
||||
['value' => 'product', 'label' => $this->l('Product Page')],
|
||||
['value' => 'product-quick-view', 'label' => $this->l('Quick View')],
|
||||
['value' => 'product-miniature', 'label' => $this->l('Product Miniature')],
|
||||
['value' => 'page-not-found', 'label' => $this->l('404 Page')],
|
||||
];
|
||||
if (!empty($this->object->type)) {
|
||||
return array_filter($theme_types, function ($option) {
|
||||
return ${'this'}->object->type === $option['value'];
|
||||
});
|
||||
}
|
||||
return $theme_types;
|
||||
}
|
||||
|
||||
public function renderForm()
|
||||
{
|
||||
$col = count(Language::getLanguages(false, false, true)) > 1 ? 9 : 7;
|
||||
|
||||
version_compare(_PS_VERSION_, '1.7.8', '<') or $col--;
|
||||
|
||||
$this->fields_form = [
|
||||
'legend' => [
|
||||
'title' => $this->l('Template'),
|
||||
'icon' => 'icon-edit',
|
||||
],
|
||||
'input' => [
|
||||
[
|
||||
'type' => 'text',
|
||||
'label' => $this->trans('Title', [], 'Admin.Global'),
|
||||
'name' => 'title',
|
||||
'lang' => true,
|
||||
'col' => $col,
|
||||
],
|
||||
[
|
||||
'type' => 'select',
|
||||
'label' => $this->trans('Type', [], 'Admin.Catalog.Feature'),
|
||||
'name' => 'type',
|
||||
'required' => true,
|
||||
'options' => [
|
||||
'id' => 'value',
|
||||
'name' => 'label',
|
||||
'query' => $this->getThemeType(),
|
||||
],
|
||||
'col' => 3,
|
||||
],
|
||||
[
|
||||
'type' => 'textarea',
|
||||
'label' => $this->l('Content'),
|
||||
'name' => 'content',
|
||||
'lang' => true,
|
||||
'col' => $col,
|
||||
],
|
||||
[
|
||||
'type' => 'switch',
|
||||
'label' => $this->trans('Active', [], 'Admin.Global'),
|
||||
'name' => 'active',
|
||||
'required' => false,
|
||||
'is_bool' => true,
|
||||
'values' => [
|
||||
[
|
||||
'id' => 'active_on',
|
||||
'value' => 1,
|
||||
'label' => $this->trans('Enabled', [], 'Admin.Global'),
|
||||
],
|
||||
[
|
||||
'id' => 'active_off',
|
||||
'value' => 0,
|
||||
'label' => $this->trans('Disabled', [], 'Admin.Global'),
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'submit' => [
|
||||
'title' => $this->trans('Save', [], 'Admin.Actions'),
|
||||
],
|
||||
'buttons' => [
|
||||
'save_and_stay' => [
|
||||
'type' => 'submit',
|
||||
'title' => $this->trans('Save and stay', [], 'Admin.Actions'),
|
||||
'icon' => 'process-icon-save',
|
||||
'name' => 'submitAddce_themeAndStay',
|
||||
'class' => 'btn btn-default pull-right',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
if (Shop::isFeatureActive()) {
|
||||
$this->fields_form['input'][] = [
|
||||
'type' => 'shop',
|
||||
'label' => $this->trans('Shop association', [], 'Admin.Global'),
|
||||
'name' => 'checkBoxShopAsso',
|
||||
];
|
||||
}
|
||||
|
||||
return parent::renderForm();
|
||||
}
|
||||
|
||||
protected function trans($id, array $parameters = [], $domain = null, $locale = null)
|
||||
{
|
||||
return empty($this->translator) ? $this->l($id) : parent::trans($id, $parameters, $domain, $locale);
|
||||
}
|
||||
|
||||
protected function l($string, $module = 'creativeelements', $addslashes = false, $htmlentities = true)
|
||||
{
|
||||
$str = Translate::getModuleTranslation($module, $string, '', null, $addslashes || !$htmlentities);
|
||||
|
||||
return $htmlentities ? $str : call_user_func('stripslashes', $str);
|
||||
}
|
||||
}
|
||||
8
modules/creativeelements/controllers/admin/index.php
Normal file
8
modules/creativeelements/controllers/admin/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../');
|
||||
die;
|
||||
112
modules/creativeelements/controllers/front/ajax.php
Normal file
112
modules/creativeelements/controllers/front/ajax.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or exit;
|
||||
|
||||
class CreativeElementsAjaxModuleFrontController extends ModuleFrontController
|
||||
{
|
||||
protected $content_only = true;
|
||||
|
||||
public function postProcess()
|
||||
{
|
||||
$this->action = Tools::getValue('action');
|
||||
|
||||
Tools::getValue('submitMessage') && $this->ajaxProcessSubmitMessage();
|
||||
Tools::getValue('submitNewsletter') && $this->ajaxProcessSubmitNewsletter();
|
||||
|
||||
method_exists($this, "ajaxProcess{$this->action}") && $this->{"ajaxProcess{$this->action}"}();
|
||||
}
|
||||
|
||||
public function ajaxProcessSubmitMessage()
|
||||
{
|
||||
if ($contact = Module::getInstanceByName('contactform')) {
|
||||
$contact->sendMessage();
|
||||
|
||||
$this->ajaxDie([
|
||||
'success' => implode(nl2br("\n", false), $this->success),
|
||||
'errors' => $this->errors,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->ajaxDie([
|
||||
'errors' => ['Error: Contact Form module should be enabled!'],
|
||||
]);
|
||||
}
|
||||
|
||||
public function ajaxProcessSubmitNewsletter()
|
||||
{
|
||||
$name = 'ps_emailsubscription';
|
||||
$newsletter = Module::getInstanceByName($name);
|
||||
|
||||
if (!$newsletter) {
|
||||
$this->ajaxDie([
|
||||
'errors' => ["Error: $name module should be enabled!"],
|
||||
]);
|
||||
}
|
||||
|
||||
$newsletter->newsletterRegistration(${'_POST'}['blockHookName'] = 'displayCE');
|
||||
|
||||
$this->ajaxDie([
|
||||
'success' => empty($newsletter->valid) ? '' : [$newsletter->valid],
|
||||
'errors' => empty($newsletter->error) ? [] : [$newsletter->error],
|
||||
]);
|
||||
}
|
||||
|
||||
public function ajaxProcessAddToCartModal()
|
||||
{
|
||||
$cart = $this->cart_presenter->present($this->context->cart, true);
|
||||
$product = null;
|
||||
$id_product = (int) Tools::getValue('id_product');
|
||||
$id_product_attribute = (int) Tools::getValue('id_product_attribute');
|
||||
$id_customization = (int) Tools::getValue('id_customization');
|
||||
|
||||
foreach ($cart['products'] as &$p) {
|
||||
if ($id_product === (int) $p['id_product'] &&
|
||||
$id_product_attribute === (int) $p['id_product_attribute'] &&
|
||||
$id_customization === (int) $p['id_customization']
|
||||
) {
|
||||
$product = $p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->context->smarty->assign([
|
||||
'configuration' => $this->getTemplateVarConfiguration(),
|
||||
'product' => $product,
|
||||
'cart' => $cart,
|
||||
'cart_url' => $this->context->link->getPageLink('cart', null, $this->context->language->id, [
|
||||
'action' => 'show',
|
||||
], false, null, true),
|
||||
]);
|
||||
|
||||
$this->ajaxDie([
|
||||
'modal' => $this->context->smarty->fetch('module:ps_shoppingcart/modal.tpl'),
|
||||
]);
|
||||
}
|
||||
|
||||
protected function ajaxDie($value = null, $controller = null, $method = null)
|
||||
{
|
||||
if (null === $controller) {
|
||||
$controller = get_class($this);
|
||||
}
|
||||
if (null === $method) {
|
||||
$bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
|
||||
$method = $bt[1]['function'];
|
||||
}
|
||||
if (version_compare(_PS_VERSION_, '1.6.1.1', '<')) {
|
||||
Hook::exec('actionBeforeAjaxDie', ['controller' => $controller, 'method' => $method, 'value' => $value]);
|
||||
Hook::exec('actionBeforeAjaxDie' . $controller . $method, ['value' => $value]);
|
||||
} else {
|
||||
Hook::exec('actionAjaxDie' . $controller . $method . 'Before', ['value' => $value]);
|
||||
}
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
|
||||
|
||||
die(json_encode($value));
|
||||
}
|
||||
}
|
||||
8
modules/creativeelements/controllers/front/index.php
Normal file
8
modules/creativeelements/controllers/front/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../');
|
||||
die;
|
||||
96
modules/creativeelements/controllers/front/preview.php
Normal file
96
modules/creativeelements/controllers/front/preview.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
class CreativeElementsPreviewModuleFrontController extends ModuleFrontController
|
||||
{
|
||||
protected $uid;
|
||||
|
||||
protected $title;
|
||||
|
||||
public function init()
|
||||
{
|
||||
if (Tools::getIsset('redirect') && CreativeElements::hasAdminToken('AdminCEEditor')) {
|
||||
$cookie = CE\get_post_meta(0, 'cookie', true);
|
||||
CE\delete_post_meta(0, 'cookie');
|
||||
|
||||
if (!empty($cookie)) {
|
||||
$lifetime = max(1, (int) Configuration::get('PS_COOKIE_LIFETIME_BO')) * 3600 + time();
|
||||
$admin = new Cookie('psAdmin', '', $lifetime);
|
||||
|
||||
foreach ($cookie as $key => &$value) {
|
||||
$admin->$key = $value;
|
||||
}
|
||||
unset($admin->remote_addr);
|
||||
|
||||
$admin->write();
|
||||
}
|
||||
Tools::redirectAdmin(urldecode(Tools::getValue('redirect')));
|
||||
}
|
||||
|
||||
$this->uid = CreativeElements::getPreviewUId(false);
|
||||
|
||||
if (!$this->uid) {
|
||||
Tools::redirect('index.php?controller=404');
|
||||
}
|
||||
|
||||
parent::init();
|
||||
}
|
||||
|
||||
public function initContent()
|
||||
{
|
||||
$model = $this->uid->getModel();
|
||||
|
||||
if ('CETemplate' != $model) {
|
||||
$this->warning[] = CESmarty::get(_CE_TEMPLATES_ . 'admin/admin.tpl', 'ce_undefined_position');
|
||||
}
|
||||
$post = CE\get_post($this->uid);
|
||||
|
||||
$this->title = $post->post_title;
|
||||
$this->context->smarty->assign($model::${'definition'}['table'], [
|
||||
'id' => $post->_obj->id,
|
||||
'content' => '',
|
||||
]);
|
||||
|
||||
parent::initContent();
|
||||
|
||||
$this->title = $post->post_title;
|
||||
$this->context->smarty->addTemplateDir(_CE_TEMPLATES_);
|
||||
$this->context->smarty->assign([
|
||||
'HOOK_LEFT_COLUMN' => '',
|
||||
'HOOK_RIGHT_COLUMN' => '',
|
||||
'breadcrumb' => $this->getBreadcrumb(),
|
||||
]);
|
||||
$this->template = 'front/preview.tpl';
|
||||
}
|
||||
|
||||
public function getBreadcrumbLinks()
|
||||
{
|
||||
$breadcrumb = [
|
||||
'links' => [
|
||||
['url' => 'javascript:;', 'title' => 'Creative Elements'],
|
||||
['url' => 'javascript:;', 'title' => CE\__('Preview')],
|
||||
],
|
||||
];
|
||||
if (!empty($this->title)) {
|
||||
$breadcrumb['links'][] = ['url' => 'javascript:;', 'title' => $this->title];
|
||||
}
|
||||
return $breadcrumb;
|
||||
}
|
||||
|
||||
public function getBreadcrumbPath()
|
||||
{
|
||||
$breadcrumb = $this->getBreadcrumbLinks();
|
||||
|
||||
return CESmarty::capture(_CE_TEMPLATES_ . 'admin/admin.tpl', 'ce_preview_breadcrumb', [
|
||||
'links' => $breadcrumb['links'],
|
||||
]);
|
||||
}
|
||||
}
|
||||
16
modules/creativeelements/controllers/index.php
Normal file
16
modules/creativeelements/controllers/index.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../');
|
||||
die;
|
||||
60
modules/creativeelements/core/base/app.php
Normal file
60
modules/creativeelements/core/base/app.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
/**
|
||||
* Base App
|
||||
*
|
||||
* Base app utility class that provides shared functionality of apps.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*/
|
||||
abstract class CoreXBaseXApp extends CoreXBaseXModule
|
||||
{
|
||||
/**
|
||||
* Print config.
|
||||
*
|
||||
* Used to print the app and its components settings as a JavaScript object.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access protected
|
||||
*/
|
||||
final protected function printConfig()
|
||||
{
|
||||
$name = $this->getName();
|
||||
|
||||
$js_var = 'frontend' === $name ? 'ceFrontendConfig' : 'elementor' . call_user_func('ucfirst', $name) . 'Config';
|
||||
$config = $this->getSettings() + $this->getComponentsConfig();
|
||||
wp_localize_script('elementor-' . $name, $js_var, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get components config.
|
||||
*
|
||||
* Retrieves the app components settings.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access private
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getComponentsConfig()
|
||||
{
|
||||
$settings = [];
|
||||
|
||||
foreach ($this->getComponents() as $id => $instance) {
|
||||
$settings[$id] = $instance->getSettings();
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
146
modules/creativeelements/core/base/base-object.php
Normal file
146
modules/creativeelements/core/base/base-object.php
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
/**
|
||||
* Base Object
|
||||
*
|
||||
* Base class that provides basic settings handling functionality.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*/
|
||||
class CoreXBaseXBaseObject
|
||||
{
|
||||
/**
|
||||
* Settings.
|
||||
*
|
||||
* Holds the object settings.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* Get Settings.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $setting Optional. The key of the requested setting. Default is null.
|
||||
*
|
||||
* @return mixed An array of all settings, or a single value if `$setting` was specified.
|
||||
*/
|
||||
final public function getSettings($setting = null)
|
||||
{
|
||||
$this->ensureSettings();
|
||||
|
||||
return self::getItems($this->settings, $setting);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set settings.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access public
|
||||
*
|
||||
* @param array|string $key If key is an array, the settings are overwritten by that array. Otherwise, the
|
||||
* settings of the key will be set to the given `$value` param.
|
||||
*
|
||||
* @param mixed $value Optional. Default is null.
|
||||
*/
|
||||
final public function setSettings($key, $value = null)
|
||||
{
|
||||
$this->ensureSettings();
|
||||
|
||||
if (is_array($key)) {
|
||||
$this->settings = $key;
|
||||
} else {
|
||||
$this->settings[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete setting.
|
||||
*
|
||||
* Deletes the settings array or a specific key of the settings array if `$key` is specified.
|
||||
* @since 2.3.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $key Optional. Default is null.
|
||||
*/
|
||||
public function deleteSetting($key = null)
|
||||
{
|
||||
if ($key) {
|
||||
unset($this->settings[$key]);
|
||||
} else {
|
||||
$this->settings = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get items.
|
||||
*
|
||||
* Utility method that receives an array with a needle and returns all the
|
||||
* items that match the needle. If needle is not defined the entire haystack
|
||||
* will be returned.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access protected
|
||||
* @static
|
||||
*
|
||||
* @param array $haystack An array of items.
|
||||
* @param string $needle Optional. Needle. Default is null.
|
||||
*
|
||||
* @return mixed The whole haystack or the needle from the haystack when requested.
|
||||
*/
|
||||
final protected static function getItems(array $haystack, $needle = null)
|
||||
{
|
||||
if ($needle) {
|
||||
return isset($haystack[$needle]) ? $haystack[$needle] : null;
|
||||
}
|
||||
|
||||
return $haystack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get init settings.
|
||||
*
|
||||
* Used to define the default/initial settings of the object. Inheriting classes may implement this method to define
|
||||
* their own default/initial settings.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getInitSettings()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure settings.
|
||||
*
|
||||
* Ensures that the `$settings` member is initialized
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access private
|
||||
*/
|
||||
private function ensureSettings()
|
||||
{
|
||||
if (null === $this->settings) {
|
||||
$this->settings = $this->getInitSettings();
|
||||
}
|
||||
}
|
||||
}
|
||||
1103
modules/creativeelements/core/base/document.php
Normal file
1103
modules/creativeelements/core/base/document.php
Normal file
File diff suppressed because it is too large
Load Diff
55
modules/creativeelements/core/base/header-footer-base.php
Normal file
55
modules/creativeelements/core/base/header-footer-base.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXDocumentTypesXPost as Post;
|
||||
use CE\CoreXBaseXThemeDocument as ThemeDocument;
|
||||
|
||||
abstract class CoreXBaseXHeaderFooterBase extends ThemeDocument
|
||||
{
|
||||
public function getCssWrapperSelector()
|
||||
{
|
||||
return '#' . $this->getName();
|
||||
}
|
||||
|
||||
public function getElementUniqueSelector(ElementBase $element)
|
||||
{
|
||||
return '#' . $this->getName() . ' .elementor-element' . $element->getUniqueSelector();
|
||||
}
|
||||
|
||||
protected static function getEditorPanelCategories()
|
||||
{
|
||||
// Move to top as active.
|
||||
$categories = [
|
||||
'theme-elements' => [
|
||||
'title' => __('Site'),
|
||||
'active' => true,
|
||||
],
|
||||
];
|
||||
|
||||
return $categories + parent::getEditorPanelCategories();
|
||||
}
|
||||
|
||||
protected function _registerControls()
|
||||
{
|
||||
parent::_registerControls();
|
||||
|
||||
Post::registerStyleControls($this);
|
||||
|
||||
$this->updateControl(
|
||||
'section_page_style',
|
||||
[
|
||||
'label' => __('Style'),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
8
modules/creativeelements/core/base/index.php
Normal file
8
modules/creativeelements/core/base/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../');
|
||||
die;
|
||||
282
modules/creativeelements/core/base/module.php
Normal file
282
modules/creativeelements/core/base/module.php
Normal file
@@ -0,0 +1,282 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
/**
|
||||
* Elementor module.
|
||||
*
|
||||
* An abstract class that provides the needed properties and methods to
|
||||
* manage and handle modules in inheriting classes.
|
||||
*
|
||||
* @since 1.7.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class CoreXBaseXModule extends CoreXBaseXBaseObject
|
||||
{
|
||||
/**
|
||||
* Module components.
|
||||
*
|
||||
* Holds the module components.
|
||||
*
|
||||
* @since 1.7.0
|
||||
* @access private
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $components = [];
|
||||
|
||||
/**
|
||||
* Module instance.
|
||||
*
|
||||
* Holds the module instance.
|
||||
*
|
||||
* @since 1.7.0
|
||||
* @access protected
|
||||
*
|
||||
* @var Module
|
||||
*/
|
||||
protected static $_instances = [];
|
||||
|
||||
/**
|
||||
* Get module name.
|
||||
*
|
||||
* Retrieve the module name.
|
||||
*
|
||||
* @since 1.7.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*
|
||||
* @return string Module name.
|
||||
*/
|
||||
abstract public function getName();
|
||||
|
||||
/**
|
||||
* Instance.
|
||||
*
|
||||
* Ensures only one instance of the module class is loaded or can be loaded.
|
||||
*
|
||||
* @since 1.7.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return Module An instance of the class.
|
||||
*/
|
||||
public static function instance()
|
||||
{
|
||||
$class_name = static::className();
|
||||
|
||||
if (empty(static::$_instances[$class_name])) {
|
||||
static::$_instances[$class_name] = new static();
|
||||
}
|
||||
|
||||
return static::$_instances[$class_name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function isActive()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class name.
|
||||
*
|
||||
* Retrieve the name of the class.
|
||||
*
|
||||
* @since 1.7.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function className()
|
||||
{
|
||||
return get_called_class();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone.
|
||||
*
|
||||
* Disable class cloning and throw an error on object clone.
|
||||
*
|
||||
* The whole idea of the singleton design pattern is that there is a single
|
||||
* object. Therefore, we don't want the object to be cloned.
|
||||
*
|
||||
* @since 1.7.0
|
||||
* @access public
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
// Cloning instances of the class is forbidden
|
||||
_doing_it_wrong(__FUNCTION__, __('Something went wrong.'), '1.0.0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Wakeup.
|
||||
*
|
||||
* Disable unserializing of the class.
|
||||
*
|
||||
* @since 1.7.0
|
||||
* @access public
|
||||
*/
|
||||
public function __wakeup()
|
||||
{
|
||||
// Unserializing instances of the class is forbidden
|
||||
_doing_it_wrong(__FUNCTION__, __('Something went wrong.'), '1.0.0');
|
||||
}
|
||||
|
||||
/**
|
||||
* Add module component.
|
||||
*
|
||||
* Add new component to the current module.
|
||||
*
|
||||
* @since 1.7.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Component ID.
|
||||
* @param mixed $instance An instance of the component.
|
||||
*/
|
||||
public function addComponent($id, $instance)
|
||||
{
|
||||
$this->components[$id] = $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.3.0
|
||||
* @access public
|
||||
* @return Module[]
|
||||
*/
|
||||
public function getComponents()
|
||||
{
|
||||
return $this->components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get module component.
|
||||
*
|
||||
* Retrieve the module component.
|
||||
*
|
||||
* @since 1.7.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Component ID.
|
||||
*
|
||||
* @return mixed An instance of the component, or `false` if the component
|
||||
* doesn't exist.
|
||||
*/
|
||||
public function getComponent($id)
|
||||
{
|
||||
if (isset($this->components[$id])) {
|
||||
return $this->components[$id];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get assets url.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access protected
|
||||
*
|
||||
* @param string $file_name
|
||||
* @param string $file_extension
|
||||
* @param string $relative_url Optional. Default is null.
|
||||
* @param string $add_min_suffix Optional. Default is 'default'.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
final protected function getAssetsUrl($file_name, $file_extension, $relative_url = null, $add_min_suffix = 'default')
|
||||
{
|
||||
static $is_test_mode = null;
|
||||
|
||||
if (null === $is_test_mode) {
|
||||
$is_test_mode = _PS_MODE_DEV_ || defined('ELEMENTOR_TESTS') && ELEMENTOR_TESTS;
|
||||
}
|
||||
|
||||
if (!$relative_url) {
|
||||
$relative_url = $this->getAssetsRelativeUrl() . $file_extension . '/';
|
||||
}
|
||||
|
||||
$url = _CE_URL_ . $relative_url . $file_name;
|
||||
|
||||
if ('default' === $add_min_suffix) {
|
||||
$add_min_suffix = !$is_test_mode;
|
||||
}
|
||||
|
||||
if ($add_min_suffix) {
|
||||
$url .= '.min';
|
||||
}
|
||||
|
||||
return $url . '.' . $file_extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get js assets url
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access protected
|
||||
*
|
||||
* @param string $file_name
|
||||
* @param string $relative_url Optional. Default is null.
|
||||
* @param string $add_min_suffix Optional. Default is 'default'.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
final protected function getJsAssetsUrl($file_name, $relative_url = null, $add_min_suffix = 'default')
|
||||
{
|
||||
return $this->getAssetsUrl($file_name, 'js', $relative_url, $add_min_suffix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get css assets url
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access protected
|
||||
*
|
||||
* @param string $file_name
|
||||
* @param string $relative_url Optional. Default is null.
|
||||
* @param string $add_min_suffix Optional. Default is 'default'.
|
||||
* @param bool $add_direction_suffix Optional. Default is `false`
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
final protected function getCssAssetsUrl($file_name, $relative_url = null, $add_min_suffix = 'default', $add_direction_suffix = false)
|
||||
{
|
||||
static $direction_suffix = null;
|
||||
|
||||
if (!$direction_suffix) {
|
||||
$direction_suffix = is_rtl() ? '-rtl' : '';
|
||||
}
|
||||
|
||||
if ($add_direction_suffix) {
|
||||
$file_name .= $direction_suffix;
|
||||
}
|
||||
|
||||
return $this->getAssetsUrl($file_name, 'css', $relative_url, $add_min_suffix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get assets relative url
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access protected
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getAssetsRelativeUrl()
|
||||
{
|
||||
return 'views/';
|
||||
}
|
||||
}
|
||||
51
modules/creativeelements/core/base/theme-document.php
Normal file
51
modules/creativeelements/core/base/theme-document.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXBaseXDocument as Document;
|
||||
|
||||
abstract class CoreXBaseXThemeDocument extends Document
|
||||
{
|
||||
/*
|
||||
public static function getPreviewAsDefault()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public static function getPreviewAsOptions()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
*/
|
||||
public static function getProperties()
|
||||
{
|
||||
$properties = parent::getProperties();
|
||||
|
||||
$properties['show_in_library'] = true;
|
||||
$properties['register_type'] = true;
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
public function _getInitialConfig()
|
||||
{
|
||||
$config = parent::_getInitialConfig();
|
||||
|
||||
$config['library'] = [
|
||||
'save_as_same_type' => true,
|
||||
];
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
// protected function _registerControls()
|
||||
}
|
||||
35
modules/creativeelements/core/base/theme-page-document.php
Normal file
35
modules/creativeelements/core/base/theme-page-document.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXBaseXThemeDocument as ThemeDocument;
|
||||
use CE\CoreXDocumentTypesXPost as Post;
|
||||
use CE\TemplateLibraryXSourceLocal as SourceLocal;
|
||||
|
||||
abstract class CoreXBaseXThemePageDocument extends ThemeDocument
|
||||
{
|
||||
public function getCssWrapperSelector()
|
||||
{
|
||||
return 'body.ce-theme-' . \Tools::substr($this->getMainId(), 0, -6);
|
||||
}
|
||||
|
||||
protected function _registerControls()
|
||||
{
|
||||
parent::_registerControls();
|
||||
|
||||
if ('product' !== $this->getName()) {
|
||||
Post::registerPostFieldsControl($this);
|
||||
}
|
||||
|
||||
Post::registerStyleControls($this);
|
||||
}
|
||||
}
|
||||
269
modules/creativeelements/core/common/app.php
Normal file
269
modules/creativeelements/core/common/app.php
Normal file
@@ -0,0 +1,269 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
// use CE\CoreXCommonXModulesXFinderXModule as Finder;
|
||||
use CE\CoreXBaseXApp as BaseApp;
|
||||
use CE\CoreXCommonXModulesXAjaxXModule as Ajax;
|
||||
use CE\CoreXCommonXModulesXConnectXModule as Connect;
|
||||
|
||||
/**
|
||||
* App
|
||||
*
|
||||
* Elementor's common app that groups shared functionality, components and configuration
|
||||
*
|
||||
* @since 2.3.0
|
||||
*/
|
||||
class CoreXCommonXApp extends BaseApp
|
||||
{
|
||||
private $templates = [];
|
||||
|
||||
/**
|
||||
* App constructor.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->addDefaultTemplates();
|
||||
|
||||
add_action('elementor/editor/before_enqueue_scripts', [$this, 'register_scripts']);
|
||||
// add_action('admin_enqueue_scripts', [$this, 'register_scripts']);
|
||||
add_action('wp_enqueue_scripts', [$this, 'register_scripts']);
|
||||
|
||||
add_action('elementor/editor/before_enqueue_styles', [$this, 'register_styles']);
|
||||
// add_action('admin_enqueue_scripts', [$this, 'register_styles']);
|
||||
add_action('wp_enqueue_scripts', [$this, 'register_styles'], 9);
|
||||
|
||||
add_action('elementor/editor/footer', [$this, 'print_templates']);
|
||||
// add_action('admin_footer', [$this, 'print_templates']);
|
||||
add_action('wp_footer', [$this, 'print_templates']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Init components
|
||||
*
|
||||
* Initializing common components.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access public
|
||||
*/
|
||||
public function initComponents()
|
||||
{
|
||||
$this->addComponent('ajax', new Ajax());
|
||||
|
||||
// if (current_user_can('manage_options')) {
|
||||
// if (!is_customize_preview()) {
|
||||
// $this->addComponent('finder', new Finder());
|
||||
// }
|
||||
|
||||
// $this->addComponent('connect', new Connect());
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Get name.
|
||||
*
|
||||
* Retrieve the app name.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Common app name.
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'common';
|
||||
}
|
||||
|
||||
/**
|
||||
* Register scripts.
|
||||
*
|
||||
* Register common scripts.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access public
|
||||
*/
|
||||
public function registerScripts()
|
||||
{
|
||||
wp_register_script(
|
||||
'elementor-common-modules',
|
||||
$this->getJsAssetsUrl('common-modules'),
|
||||
[],
|
||||
_CE_VERSION_,
|
||||
true
|
||||
);
|
||||
|
||||
wp_register_script(
|
||||
'backbone-marionette',
|
||||
$this->getJsAssetsUrl('backbone.marionette', 'views/lib/backbone/'),
|
||||
[
|
||||
'backbone',
|
||||
],
|
||||
'2.4.5',
|
||||
true
|
||||
);
|
||||
|
||||
wp_register_script(
|
||||
'backbone-radio',
|
||||
$this->getJsAssetsUrl('backbone.radio', 'views/lib/backbone/'),
|
||||
[
|
||||
'backbone',
|
||||
],
|
||||
'1.0.4',
|
||||
true
|
||||
);
|
||||
|
||||
wp_register_script(
|
||||
'elementor-dialog',
|
||||
$this->getJsAssetsUrl('dialog', 'views/lib/dialog/'),
|
||||
[
|
||||
'jquery-ui-position',
|
||||
],
|
||||
'4.7.1',
|
||||
true
|
||||
);
|
||||
|
||||
wp_register_script(
|
||||
'elementor-common',
|
||||
$this->getJsAssetsUrl('common'),
|
||||
[
|
||||
'jquery',
|
||||
'jquery-ui-draggable',
|
||||
'backbone-marionette',
|
||||
'backbone-radio',
|
||||
'elementor-common-modules',
|
||||
'elementor-dialog',
|
||||
],
|
||||
_CE_VERSION_,
|
||||
true
|
||||
);
|
||||
|
||||
$this->printConfig();
|
||||
|
||||
wp_enqueue_script('elementor-common');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register styles.
|
||||
*
|
||||
* Register common styles.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access public
|
||||
*/
|
||||
public function registerStyles()
|
||||
{
|
||||
wp_register_style(
|
||||
'elementor-icons',
|
||||
$this->getCssAssetsUrl('elementor-icons', 'views/lib/eicons/css/'),
|
||||
[],
|
||||
'4.3.1'
|
||||
);
|
||||
|
||||
wp_register_style(
|
||||
'ce-icons',
|
||||
$this->getCssAssetsUrl('ceicons', 'views/lib/ceicons/'),
|
||||
[],
|
||||
_CE_VERSION_
|
||||
);
|
||||
|
||||
wp_enqueue_style(
|
||||
'elementor-common',
|
||||
$this->getCssAssetsUrl('common', null, 'default', true),
|
||||
[
|
||||
'elementor-icons',
|
||||
],
|
||||
_CE_VERSION_
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add template.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $template Can be either a link to template file or template
|
||||
* HTML content.
|
||||
* @param string $type Optional. Whether to handle the template as path
|
||||
* or text. Default is `path`.
|
||||
*/
|
||||
public function addTemplate($template, $type = 'path')
|
||||
{
|
||||
if ('path' === $type) {
|
||||
ob_start();
|
||||
|
||||
include $template;
|
||||
|
||||
$template = ob_get_clean();
|
||||
}
|
||||
|
||||
$this->templates[] = $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print Templates
|
||||
*
|
||||
* Prints all registered templates.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access public
|
||||
*/
|
||||
public function printTemplates()
|
||||
{
|
||||
foreach ($this->templates as $template) {
|
||||
echo $template;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get init settings.
|
||||
*
|
||||
* Define the default/initial settings of the common app.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getInitSettings()
|
||||
{
|
||||
return [
|
||||
'version' => _CE_VERSION_,
|
||||
'isRTL' => is_rtl(),
|
||||
'activeModules' => array_keys($this->getComponents()),
|
||||
'urls' => [
|
||||
'assets' => _MODULE_DIR_ . 'creativeelements/views/',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add default templates.
|
||||
*
|
||||
* Register common app default templates.
|
||||
* @since 2.3.0
|
||||
* @access private
|
||||
*/
|
||||
private function addDefaultTemplates()
|
||||
{
|
||||
$default_templates = [
|
||||
'includes/editor-templates/library-layout.php',
|
||||
];
|
||||
|
||||
foreach ($default_templates as $template) {
|
||||
$this->addTemplate(_CE_PATH_ . $template);
|
||||
}
|
||||
}
|
||||
}
|
||||
8
modules/creativeelements/core/common/index.php
Normal file
8
modules/creativeelements/core/common/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../');
|
||||
die;
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../../../');
|
||||
die;
|
||||
320
modules/creativeelements/core/common/modules/ajax/module.php
Normal file
320
modules/creativeelements/core/common/modules/ajax/module.php
Normal file
@@ -0,0 +1,320 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXBaseXModule as BaseModule;
|
||||
use CE\CoreXUtilsXExceptions as Exceptions;
|
||||
|
||||
/**
|
||||
* Elementor ajax manager.
|
||||
*
|
||||
* Elementor ajax manager handler class is responsible for handling Elementor
|
||||
* ajax requests, ajax responses and registering actions applied on them.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class CoreXCommonXModulesXAjaxXModule extends BaseModule
|
||||
{
|
||||
const NONCE_KEY = 'elementor_ajax';
|
||||
|
||||
/**
|
||||
* Ajax actions.
|
||||
*
|
||||
* Holds all the register ajax action.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $ajax_actions = [];
|
||||
|
||||
/**
|
||||
* Ajax requests.
|
||||
*
|
||||
* Holds all the register ajax requests.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $requests = [];
|
||||
|
||||
/**
|
||||
* Ajax response data.
|
||||
*
|
||||
* Holds all the response data for all the ajax requests.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $response_data = [];
|
||||
|
||||
/**
|
||||
* Current ajax action ID.
|
||||
*
|
||||
* Holds all the ID for the current ajax action.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
private $current_action_id = null;
|
||||
|
||||
/**
|
||||
* Ajax manager constructor.
|
||||
*
|
||||
* Initializing Elementor ajax manager.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
add_action('wp_ajax_elementor_ajax', [$this, 'handle_ajax_request']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get module name.
|
||||
*
|
||||
* Retrieve the module name.
|
||||
*
|
||||
* @since 1.7.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Module name.
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'ajax';
|
||||
}
|
||||
|
||||
/**
|
||||
* Register ajax action.
|
||||
*
|
||||
* Add new actions for a specific ajax request and the callback function to
|
||||
* be handle the response.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $tag Ajax request name/tag.
|
||||
* @param callable $callback The callback function.
|
||||
*/
|
||||
public function registerAjaxAction($tag, $callback)
|
||||
{
|
||||
if (!did_action('elementor/ajax/register_actions')) {
|
||||
_doing_it_wrong(__METHOD__, esc_html(sprintf('Use `%s` hook to register ajax action.', 'elementor/ajax/register_actions')), '2.0.0');
|
||||
}
|
||||
|
||||
if (is_array($callback) && isset($callback[1]) && strpos($callback[1], '_') !== false) {
|
||||
$callback[1] = \Tools::toCamelCase($callback[1]);
|
||||
}
|
||||
|
||||
$this->ajax_actions[$tag] = compact('tag', 'callback');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle ajax request.
|
||||
*
|
||||
* Verify ajax nonce, and run all the registered actions for this request.
|
||||
*
|
||||
* Fired by `wp_ajax_elementor_ajax` action.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function handleAjaxRequest()
|
||||
{
|
||||
if (!$this->verifyRequestNonce()) {
|
||||
$this->addResponseData(false, __('Token Expired.'))
|
||||
->sendError(Exceptions::UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$editor_post_id = 0;
|
||||
|
||||
if (!empty($_REQUEST['editor_post_id'])) {
|
||||
$editor_post_id = absint($_REQUEST['editor_post_id']);
|
||||
|
||||
Plugin::$instance->db->switchToPost($editor_post_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register ajax actions.
|
||||
*
|
||||
* Fires when an ajax request is received and verified.
|
||||
*
|
||||
* Used to register new ajax action handles.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param self $this An instance of ajax manager.
|
||||
*/
|
||||
do_action('elementor/ajax/register_actions', $this);
|
||||
|
||||
$this->requests = json_decode(${'_POST'}['actions'], true);
|
||||
|
||||
foreach ($this->requests as $id => $action_data) {
|
||||
$this->current_action_id = $id;
|
||||
|
||||
if (!isset($this->ajax_actions[$action_data['action']])) {
|
||||
$this->addResponseData(false, __('Action not found.'), Exceptions::BAD_REQUEST);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($editor_post_id) {
|
||||
$action_data['data']['editor_post_id'] = $editor_post_id;
|
||||
}
|
||||
|
||||
// try {
|
||||
$results = call_user_func($this->ajax_actions[$action_data['action']]['callback'], $action_data['data'], $this);
|
||||
|
||||
if (false === $results) {
|
||||
$this->addResponseData(false);
|
||||
} else {
|
||||
$this->addResponseData(true, $results);
|
||||
}
|
||||
// } catch (\Exception $e) {
|
||||
// $this->addResponseData(false, $e->getMessage(), $e->getCode());
|
||||
// }
|
||||
}
|
||||
|
||||
$this->current_action_id = null;
|
||||
|
||||
$this->sendSuccess();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current action data.
|
||||
*
|
||||
* Retrieve the data for the current ajax request.
|
||||
*
|
||||
* @since 2.0.1
|
||||
* @access public
|
||||
*
|
||||
* @return bool|mixed Ajax request data if action exist, False otherwise.
|
||||
*/
|
||||
public function getCurrentActionData()
|
||||
{
|
||||
if (!$this->current_action_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->requests[$this->current_action_id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create nonce.
|
||||
*
|
||||
* Creates a cryptographic token to
|
||||
* give the user an access to Elementor ajax actions.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access public
|
||||
*
|
||||
* @return string The nonce token.
|
||||
*/
|
||||
public function createNonce()
|
||||
{
|
||||
return wp_create_nonce(self::NONCE_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify request nonce.
|
||||
*
|
||||
* Whether the request nonce verified or not.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access public
|
||||
*
|
||||
* @return bool True if request nonce verified, False otherwise.
|
||||
*/
|
||||
public function verifyRequestNonce()
|
||||
{
|
||||
return !empty($_REQUEST['_nonce']) && wp_verify_nonce($_REQUEST['_nonce'], self::NONCE_KEY);
|
||||
}
|
||||
|
||||
protected function getInitSettings()
|
||||
{
|
||||
return [
|
||||
'url' => Helper::getAjaxLink(),
|
||||
'nonce' => $this->createNonce(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax success response.
|
||||
*
|
||||
* Send a JSON response data back to the ajax request, indicating success.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function sendSuccess()
|
||||
{
|
||||
$response = [
|
||||
'success' => true,
|
||||
'data' => [
|
||||
'responses' => $this->response_data,
|
||||
],
|
||||
];
|
||||
|
||||
die(str_replace('}},"', "}},\n\"", json_encode($response)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax failure response.
|
||||
*
|
||||
* Send a JSON response data back to the ajax request, indicating failure.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*
|
||||
* @param null $code
|
||||
*/
|
||||
private function sendError($code = null)
|
||||
{
|
||||
wp_send_json_error([
|
||||
'responses' => $this->response_data,
|
||||
], $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add response data.
|
||||
*
|
||||
* Add new response data to the array of all the ajax requests.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*
|
||||
* @param bool $success True if the requests returned successfully, False otherwise.
|
||||
* @param mixed $data Optional. Response data. Default is null.
|
||||
* @param int $code Optional. Response code. Default is 200.
|
||||
*
|
||||
* @return Module An instance of ajax manager.
|
||||
*/
|
||||
private function addResponseData($success, $data = null, $code = 200)
|
||||
{
|
||||
$this->response_data[$this->current_action_id] = [
|
||||
'success' => $success,
|
||||
'code' => $code,
|
||||
'data' => $data,
|
||||
];
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
8
modules/creativeelements/core/common/modules/index.php
Normal file
8
modules/creativeelements/core/common/modules/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../../');
|
||||
die;
|
||||
132
modules/creativeelements/core/document-types/content.php
Normal file
132
modules/creativeelements/core/document-types/content.php
Normal file
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXDocumentTypesXPost as Post;
|
||||
use CE\CoreXBaseXDocument as Document;
|
||||
|
||||
class CoreXDocumentTypesXContent extends Document
|
||||
{
|
||||
protected static $maintenance = false;
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'content';
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function getTitle()
|
||||
{
|
||||
return __('Content');
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.2
|
||||
* @access protected
|
||||
* @static
|
||||
*/
|
||||
protected static function getEditorPanelCategories()
|
||||
{
|
||||
$categories = parent::getEditorPanelCategories();
|
||||
|
||||
if (self::$maintenance) {
|
||||
$categories['maintenance-premium'] = $categories['premium'];
|
||||
$categories['maintenance-theme-elements'] = $categories['theme-elements'];
|
||||
|
||||
unset($categories['premium'], $categories['theme-elements']);
|
||||
}
|
||||
|
||||
return $categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function getCssWrapperSelector()
|
||||
{
|
||||
return '.elementor.elementor-' . uidval($this->getMainId())->toDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function _registerControls()
|
||||
{
|
||||
parent::_registerControls();
|
||||
|
||||
$this->startInjection([
|
||||
'of' => 'post_title',
|
||||
]);
|
||||
|
||||
$this->addControl(
|
||||
'full_width',
|
||||
[
|
||||
'label' => __('Clear Content Wrapper'),
|
||||
'type' => ControlsManager::SWITCHER,
|
||||
'description' => sprintf(__(
|
||||
'Not working? You can set a different selector for the content wrapper ' .
|
||||
'in the <a href="%s" target="_blank">Settings page</a>.'
|
||||
), Helper::getSettingsLink()),
|
||||
'selectors' => [
|
||||
\Configuration::get('elementor_page_wrapper_selector') => 'min-width: 100%; margin: 0; padding: 0;',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->endInjection();
|
||||
|
||||
Post::registerStyleControls($this);
|
||||
|
||||
$this->updateControl(
|
||||
'section_page_style',
|
||||
[
|
||||
'label' => __('Style'),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct(array $data = [])
|
||||
{
|
||||
parent::__construct($data);
|
||||
|
||||
if (isset($this->post->_obj->hook) && stripos($this->post->_obj->hook, 'displayMaintenance') === 0) {
|
||||
self::$maintenance = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected function getRemoteLibraryConfig()
|
||||
{
|
||||
$config = parent::getRemoteLibraryConfig();
|
||||
|
||||
$config['type'] = 'page';
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
36
modules/creativeelements/core/document-types/footer.php
Normal file
36
modules/creativeelements/core/document-types/footer.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXBaseXHeaderFooterBase as HeaderFooterBase;
|
||||
|
||||
class CoreXDocumentTypesXFooter extends HeaderFooterBase
|
||||
{
|
||||
public static function getProperties()
|
||||
{
|
||||
$properties = parent::getProperties();
|
||||
|
||||
$properties['location'] = 'footer';
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'footer';
|
||||
}
|
||||
|
||||
public static function getTitle()
|
||||
{
|
||||
return __('Footer');
|
||||
}
|
||||
}
|
||||
36
modules/creativeelements/core/document-types/header.php
Normal file
36
modules/creativeelements/core/document-types/header.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXBaseXHeaderFooterBase as HeaderFooterBase;
|
||||
|
||||
class CoreXDocumentTypesXHeader extends HeaderFooterBase
|
||||
{
|
||||
public static function getProperties()
|
||||
{
|
||||
$properties = parent::getProperties();
|
||||
|
||||
$properties['location'] = 'header';
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return 'header';
|
||||
}
|
||||
|
||||
public static function getTitle()
|
||||
{
|
||||
return __('Header');
|
||||
}
|
||||
}
|
||||
8
modules/creativeelements/core/document-types/index.php
Normal file
8
modules/creativeelements/core/document-types/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../');
|
||||
die;
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXBaseXThemePageDocument as ThemePageDocument;
|
||||
|
||||
class CoreXDocumentTypesXPageContact extends ThemePageDocument
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'page-contact';
|
||||
}
|
||||
|
||||
public static function getTitle()
|
||||
{
|
||||
return __('Contact Page');
|
||||
}
|
||||
|
||||
protected function getRemoteLibraryConfig()
|
||||
{
|
||||
$config = parent::getRemoteLibraryConfig();
|
||||
|
||||
$config['type'] = 'page';
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
36
modules/creativeelements/core/document-types/page-index.php
Normal file
36
modules/creativeelements/core/document-types/page-index.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXBaseXThemePageDocument as ThemePageDocument;
|
||||
|
||||
class CoreXDocumentTypesXPageIndex extends ThemePageDocument
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'page-index';
|
||||
}
|
||||
|
||||
public static function getTitle()
|
||||
{
|
||||
return __('Home Page');
|
||||
}
|
||||
|
||||
protected function getRemoteLibraryConfig()
|
||||
{
|
||||
$config = parent::getRemoteLibraryConfig();
|
||||
|
||||
$config['type'] = 'page';
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXBaseXThemePageDocument as ThemePageDocument;
|
||||
|
||||
class CoreXDocumentTypesXPageNotFound extends ThemePageDocument
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'page-not-found';
|
||||
}
|
||||
|
||||
public static function getTitle()
|
||||
{
|
||||
return __('404 Page');
|
||||
}
|
||||
|
||||
protected function getRemoteLibraryConfig()
|
||||
{
|
||||
$config = parent::getRemoteLibraryConfig();
|
||||
|
||||
$config['category'] = '404 error';
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
264
modules/creativeelements/core/document-types/post.php
Normal file
264
modules/creativeelements/core/document-types/post.php
Normal file
@@ -0,0 +1,264 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXBaseXDocument as Document;
|
||||
use CE\CoreXSettingsXManager as SettingsManager;
|
||||
|
||||
class CoreXDocumentTypesXPost extends Document
|
||||
{
|
||||
/**
|
||||
* @since 2.0.8
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function getProperties()
|
||||
{
|
||||
$properties = parent::getProperties();
|
||||
|
||||
// $properties['admin_tab_group'] = '';
|
||||
$properties['support_wp_page_templates'] = true;
|
||||
|
||||
return $properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.2
|
||||
* @access protected
|
||||
* @static
|
||||
*/
|
||||
protected static function getEditorPanelCategories()
|
||||
{
|
||||
return Utils::arrayInject(
|
||||
parent::getEditorPanelCategories(),
|
||||
'theme-elements',
|
||||
[
|
||||
'theme-elements-single' => [
|
||||
'title' => __('Single'),
|
||||
'active' => false,
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'post';
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function getTitle()
|
||||
{
|
||||
return __('Page');
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function getCssWrapperSelector()
|
||||
{
|
||||
return 'body.elementor-page-' . $this->getMainId();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function _registerControls()
|
||||
{
|
||||
parent::_registerControls();
|
||||
|
||||
self::registerHideTitleControl($this);
|
||||
|
||||
self::registerPostFieldsControl($this);
|
||||
|
||||
self::registerStyleControls($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @static
|
||||
* @param Document $document
|
||||
*/
|
||||
public static function registerHideTitleControl($document)
|
||||
{
|
||||
$page_title_selector = SettingsManager::getSettingsManagers('general')->getModel()->getSettings('elementor_page_title_selector');
|
||||
|
||||
if (!$page_title_selector) {
|
||||
$page_title_selector = 'header.page-header';
|
||||
}
|
||||
|
||||
$page_title_selector .= ', .elementor-page-title';
|
||||
|
||||
$document->startInjection([
|
||||
'of' => 'post_title',
|
||||
]);
|
||||
|
||||
$document->addControl(
|
||||
'hide_title',
|
||||
[
|
||||
'label' => __('Hide Title'),
|
||||
'type' => ControlsManager::SWITCHER,
|
||||
'description' => sprintf(__(
|
||||
'Not working? You can set a different selector for the title ' .
|
||||
'in the <a href="%s" target="_blank">Settings page</a>.'
|
||||
), Helper::getSettingsLink()),
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} ' . $page_title_selector => 'display: none',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$document->endInjection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @static
|
||||
* @param Document $document
|
||||
*/
|
||||
public static function registerStyleControls($document)
|
||||
{
|
||||
$type = $document->getTemplateType();
|
||||
|
||||
if ('product-quick-view' === $type || 'product-miniature' === $type) {
|
||||
return;
|
||||
}
|
||||
|
||||
$document->startControlsSection(
|
||||
'section_page_style',
|
||||
[
|
||||
'label' => __('Body Style'),
|
||||
'tab' => ControlsManager::TAB_STYLE,
|
||||
]
|
||||
);
|
||||
|
||||
$document->addGroupControl(
|
||||
GroupControlBackground::getType(),
|
||||
[
|
||||
'name' => 'background',
|
||||
'fields_options' => [
|
||||
'image' => [
|
||||
// Currently isn't supported.
|
||||
'dynamic' => [
|
||||
'active' => false,
|
||||
],
|
||||
],
|
||||
],
|
||||
'selector' => '{{WRAPPER}}',
|
||||
]
|
||||
);
|
||||
|
||||
$document->addResponsiveControl(
|
||||
'padding',
|
||||
[
|
||||
'label' => __('Padding'),
|
||||
'type' => ControlsManager::DIMENSIONS,
|
||||
'size_units' => ['px', 'em', '%'],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}}' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$document->endControlsSection();
|
||||
|
||||
Plugin::$instance->controls_manager->addCustomCssControls($document);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @static
|
||||
* @param Document $document
|
||||
*/
|
||||
public static function registerPostFieldsControl($document)
|
||||
{
|
||||
$document->startInjection([
|
||||
'of' => 'post_status',
|
||||
]);
|
||||
|
||||
// if (post_type_supports($document->post->post_type, 'excerpt')) {
|
||||
// $document->addControl(
|
||||
// 'post_excerpt',
|
||||
// [
|
||||
// 'label' => __('Excerpt'),
|
||||
// 'type' => ControlsManager::TEXTAREA,
|
||||
// 'default' => $document->post->post_excerpt,
|
||||
// 'label_block' => true,
|
||||
// ]
|
||||
// );
|
||||
// }
|
||||
|
||||
$uid = UId::parse($document->getMainId());
|
||||
|
||||
if (UId::CMS === $uid->id_type ||
|
||||
UId::THEME === $uid->id_type && stripos($document->getTemplateType(), 'page-') === 0
|
||||
) {
|
||||
$document->addControl(
|
||||
'post_featured_image',
|
||||
[
|
||||
'label' => __('Featured Image'),
|
||||
'type' => ControlsManager::MEDIA,
|
||||
'default' => [
|
||||
'url' => $document->getMeta('_og_image'),
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$document->endInjection();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct(array $data = [])
|
||||
{
|
||||
if ($data) {
|
||||
$template = get_post_meta($data['post_id'], '_wp_page_template', true);
|
||||
|
||||
if (empty($template)) {
|
||||
$template = 'default';
|
||||
}
|
||||
|
||||
$data['settings']['template'] = $template;
|
||||
}
|
||||
|
||||
parent::__construct($data);
|
||||
}
|
||||
|
||||
protected function getRemoteLibraryConfig()
|
||||
{
|
||||
$config = parent::getRemoteLibraryConfig();
|
||||
|
||||
$config['type'] = 'page';
|
||||
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,378 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live PageBuilder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXDocumentTypesXProduct as ProductDocument;
|
||||
|
||||
class CoreXDocumentTypesXProductMiniature extends ProductDocument
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'product-miniature';
|
||||
}
|
||||
|
||||
public static function getTitle()
|
||||
{
|
||||
return __('Product Miniature');
|
||||
}
|
||||
|
||||
protected static function getEditorPanelCategories()
|
||||
{
|
||||
$categories = [
|
||||
'product-elements' => [
|
||||
'title' => __('Product Miniature'),
|
||||
],
|
||||
];
|
||||
|
||||
$categories += parent::getEditorPanelCategories();
|
||||
|
||||
return $categories;
|
||||
}
|
||||
|
||||
protected function getRemoteLibraryConfig()
|
||||
{
|
||||
$config = parent::getRemoteLibraryConfig();
|
||||
|
||||
$config['category'] = 'miniature';
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
public function getCssWrapperSelector()
|
||||
{
|
||||
return '.elementor.elementor-' . uidval($this->getMainId())->toDefault();
|
||||
}
|
||||
|
||||
protected function _registerControls()
|
||||
{
|
||||
parent::_registerControls();
|
||||
|
||||
$this->startInjection([
|
||||
'of' => 'preview_id',
|
||||
'at' => 'before',
|
||||
]);
|
||||
|
||||
$this->addResponsiveControl(
|
||||
'preview_width',
|
||||
[
|
||||
'label' => __('Width') . ' (px)',
|
||||
'type' => ControlsManager::NUMBER,
|
||||
'min' => 150,
|
||||
'default' => 360,
|
||||
'tablet_default' => 360,
|
||||
'mobile_default' => 360,
|
||||
]
|
||||
);
|
||||
|
||||
$this->endInjection();
|
||||
|
||||
$this->startControlsSection(
|
||||
'section_style',
|
||||
[
|
||||
'label' => __('Background'),
|
||||
'tab' => ControlsManager::TAB_STYLE,
|
||||
]
|
||||
);
|
||||
|
||||
$this->startControlsTabs('tabs_background');
|
||||
|
||||
$this->startControlsTab(
|
||||
'tab_background_normal',
|
||||
[
|
||||
'label' => __('Normal'),
|
||||
]
|
||||
);
|
||||
|
||||
$this->addGroupControl(
|
||||
GroupControlBackground::getType(),
|
||||
[
|
||||
'name' => 'background',
|
||||
'selector' => '{{WRAPPER}} .elementor-section-wrap',
|
||||
]
|
||||
);
|
||||
|
||||
$this->endControlsTab();
|
||||
|
||||
$this->startControlsTab(
|
||||
'tab_background_hover',
|
||||
[
|
||||
'label' => __('Hover'),
|
||||
]
|
||||
);
|
||||
|
||||
$this->addGroupControl(
|
||||
GroupControlBackground::getType(),
|
||||
[
|
||||
'name' => 'background_hover',
|
||||
'selector' => '{{WRAPPER}} .elementor-section-wrap:hover',
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'background_hover_transition',
|
||||
[
|
||||
'label' => __('Transition Duration'),
|
||||
'type' => ControlsManager::SLIDER,
|
||||
'default' => [
|
||||
'size' => 0.3,
|
||||
],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'max' => 3,
|
||||
'step' => 0.1,
|
||||
],
|
||||
],
|
||||
'separator' => [
|
||||
'{{WRAPPER}} .elementor-section-wrap' => '--e-background-transition-duration: {{SIZE}}s;',
|
||||
],
|
||||
'condition' => [
|
||||
'background_hover_background!' => '',
|
||||
],
|
||||
'separator' => 'before',
|
||||
]
|
||||
);
|
||||
|
||||
$this->endControlsTab();
|
||||
|
||||
$this->endControlsTabs();
|
||||
|
||||
$this->endControlsSection();
|
||||
|
||||
$this->startControlsSection(
|
||||
'section_border',
|
||||
[
|
||||
'label' => __('Border'),
|
||||
'tab' => ControlsManager::TAB_STYLE,
|
||||
]
|
||||
);
|
||||
|
||||
$this->startControlsTabs('tabs_border');
|
||||
|
||||
$this->startControlsTab(
|
||||
'tab_border_normal',
|
||||
[
|
||||
'label' => __('Normal'),
|
||||
]
|
||||
);
|
||||
|
||||
$this->addGroupControl(
|
||||
GroupControlBorder::getType(),
|
||||
[
|
||||
'name' => 'border',
|
||||
'selector' => '{{WRAPPER}} .elementor-section-wrap',
|
||||
]
|
||||
);
|
||||
|
||||
$this->addResponsiveControl(
|
||||
'border_radius',
|
||||
[
|
||||
'label' => __('Border Radius'),
|
||||
'type' => ControlsManager::DIMENSIONS,
|
||||
'size_units' => ['px', '%'],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .elementor-section-wrap' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addGroupControl(
|
||||
GroupControlBoxShadow::getType(),
|
||||
[
|
||||
'name' => 'box_shadow',
|
||||
'selector' => '{{WRAPPER}} .elementor-section-wrap',
|
||||
]
|
||||
);
|
||||
|
||||
$this->endControlsTab();
|
||||
|
||||
$this->startControlsTab(
|
||||
'tab_border_hover',
|
||||
[
|
||||
'label' => __('Hover'),
|
||||
]
|
||||
);
|
||||
|
||||
$this->addGroupControl(
|
||||
GroupControlBorder::getType(),
|
||||
[
|
||||
'name' => 'border_hover',
|
||||
'selector' => '{{WRAPPER}} .elementor-section-wrap:hover',
|
||||
]
|
||||
);
|
||||
|
||||
$this->addResponsiveControl(
|
||||
'border_radius_hover',
|
||||
[
|
||||
'label' => __('Border Radius'),
|
||||
'type' => ControlsManager::DIMENSIONS,
|
||||
'size_units' => ['px', '%'],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .elementor-section-wrap:hover' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addGroupControl(
|
||||
GroupControlBoxShadow::getType(),
|
||||
[
|
||||
'name' => 'box_shadow_hover',
|
||||
'selector' => '{{WRAPPER}} .elementor-section-wrap:hover',
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'border_hover_transition',
|
||||
[
|
||||
'label' => __('Transition Duration'),
|
||||
'type' => ControlsManager::SLIDER,
|
||||
'separator' => 'before',
|
||||
'default' => [
|
||||
'size' => 0.3,
|
||||
],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'max' => 3,
|
||||
'step' => 0.1,
|
||||
],
|
||||
],
|
||||
'conditions' => [
|
||||
'relation' => 'or',
|
||||
'terms' => [
|
||||
[
|
||||
'name' => 'background_hover_background',
|
||||
'operator' => '!==',
|
||||
'value' => '',
|
||||
],
|
||||
[
|
||||
'name' => 'border_hover_border',
|
||||
'operator' => '!==',
|
||||
'value' => '',
|
||||
],
|
||||
],
|
||||
],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .elementor-section-wrap' => '--e-border-transition-duration: {{SIZE}}s;',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->endControlsTab();
|
||||
|
||||
$this->endControlsTabs();
|
||||
|
||||
$this->endControlsSection();
|
||||
|
||||
$this->startControlsSection(
|
||||
'section_advanced',
|
||||
[
|
||||
'label' => __('Advanced'),
|
||||
'tab' => ControlsManager::TAB_ADVANCED,
|
||||
]
|
||||
);
|
||||
|
||||
$this->addResponsiveControl(
|
||||
'margin',
|
||||
[
|
||||
'label' => __('Margin'),
|
||||
'type' => ControlsManager::DIMENSIONS,
|
||||
'size_units' => ['px', '%'],
|
||||
'allowed_dimensions' => 'vertical',
|
||||
'placeholder' => [
|
||||
'top' => '',
|
||||
'right' => 'auto',
|
||||
'bottom' => '',
|
||||
'left' => 'auto',
|
||||
],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}}' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addResponsiveControl(
|
||||
'padding',
|
||||
[
|
||||
'label' => __('Padding'),
|
||||
'type' => ControlsManager::DIMENSIONS,
|
||||
'size_units' => ['px', '%'],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}}' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'css_classes',
|
||||
[
|
||||
'label' => __('CSS Classes'),
|
||||
'type' => ControlsManager::TEXT,
|
||||
'label_block' => false,
|
||||
'title' => __('Add your custom class WITHOUT the dot. e.g: my-class'),
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'overflow',
|
||||
[
|
||||
'label' => __('Overflow'),
|
||||
'type' => ControlsManager::SELECT,
|
||||
'default' => 'hidden',
|
||||
'options' => [
|
||||
'' => __('Default'),
|
||||
'hidden' => __('Hidden'),
|
||||
],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .elementor-section-wrap' => 'overflow: {{VALUE}}',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->endControlsSection();
|
||||
|
||||
Plugin::$instance->controls_manager->addCustomCssControls($this);
|
||||
}
|
||||
|
||||
public function printSmartyElementsWithWrapper(&$elements_data)
|
||||
{
|
||||
$container = $this->getContainerAttributes();
|
||||
$container['class'] .= '{if !empty($productClasses)} {$productClasses}{/if}';
|
||||
|
||||
if ($css_classes = $this->getSettings('css_classes')) {
|
||||
$container['class'] .= " $css_classes";
|
||||
}
|
||||
if (strrpos($container['data-elementor-settings'], '}') !== false) {
|
||||
$container['data-elementor-settings'] = "{literal}{$container['data-elementor-settings']}{/literal}";
|
||||
}
|
||||
$uid = $this->getMainId();
|
||||
$article = [
|
||||
'class' => 'elementor-section-wrap',
|
||||
'data-id-product' => '{$product.id_product}',
|
||||
'data-id-product-attribute' => '{$product.id_product_attribute}',
|
||||
'itemprop' => 'item',
|
||||
];
|
||||
?>
|
||||
{* Generated by Creative Elements, do not modify it *}
|
||||
{ce_enqueue_miniature(<?= $uid ?>)}
|
||||
<div <?= Utils::renderHtmlAttributes($container) ?>>
|
||||
<article <?= Utils::renderHtmlAttributes($article) ?> itemscope itemtype="http://schema.org/Product">
|
||||
<?php
|
||||
foreach ($elements_data as &$element_data) {
|
||||
if ($element = Plugin::$instance->elements_manager->createElementInstance($element_data)) {
|
||||
$element->printElement();
|
||||
}
|
||||
}
|
||||
?>
|
||||
</article>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,597 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXDocumentTypesXProduct as ProductDocument;
|
||||
|
||||
class CoreXDocumentTypesXProductQuickView extends ProductDocument
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'product-quick-view';
|
||||
}
|
||||
|
||||
public static function getTitle()
|
||||
{
|
||||
return __('Quick View');
|
||||
}
|
||||
|
||||
public function getCssWrapperSelector()
|
||||
{
|
||||
return '#ce-product-quick-view';
|
||||
}
|
||||
|
||||
protected static function getEditorPanelCategories()
|
||||
{
|
||||
$categories = [
|
||||
'product-elements' => [
|
||||
'title' => __('Product'),
|
||||
],
|
||||
];
|
||||
|
||||
$categories += parent::getEditorPanelCategories();
|
||||
|
||||
return $categories;
|
||||
}
|
||||
|
||||
protected function getRemoteLibraryConfig()
|
||||
{
|
||||
$config = parent::getRemoteLibraryConfig();
|
||||
|
||||
$config['category'] = 'quick view';
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
protected function _registerControls()
|
||||
{
|
||||
$this->startControlsSection(
|
||||
'popup_layout',
|
||||
[
|
||||
'label' => __('Layout'),
|
||||
'tab' => ControlsManager::TAB_SETTINGS,
|
||||
]
|
||||
);
|
||||
|
||||
$this->addResponsiveControl(
|
||||
'width',
|
||||
[
|
||||
'label' => __('Width'),
|
||||
'type' => ControlsManager::SLIDER,
|
||||
'range' => [
|
||||
'px' => [
|
||||
'min' => 100,
|
||||
'max' => 1600,
|
||||
],
|
||||
'vw' => [
|
||||
'min' => 10,
|
||||
'max' => 100,
|
||||
],
|
||||
],
|
||||
'size_units' => ['px', 'vw'],
|
||||
'default' => [
|
||||
'size' => 1200,
|
||||
],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .dialog-widget-content' => 'width: {{SIZE}}{{UNIT}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'height_type',
|
||||
[
|
||||
'label' => __('Height'),
|
||||
'type' => ControlsManager::SELECT,
|
||||
'default' => 'auto',
|
||||
'options' => [
|
||||
'auto' => __('Fit To Content'),
|
||||
'fit_to_screen' => __('Fit To Screen'),
|
||||
'custom' => __('Custom'),
|
||||
],
|
||||
'selectors_dictionary' => [
|
||||
'fit_to_screen' => '100vh',
|
||||
'custom' => '',
|
||||
],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .dialog-widget-content' => 'height: {{VALUE}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addResponsiveControl(
|
||||
'height',
|
||||
[
|
||||
'label' => __('Custom Height'),
|
||||
'type' => ControlsManager::SLIDER,
|
||||
'range' => [
|
||||
'px' => [
|
||||
'min' => 100,
|
||||
'max' => 1600,
|
||||
],
|
||||
'vh' => [
|
||||
'min' => 10,
|
||||
'max' => 100,
|
||||
],
|
||||
],
|
||||
'size_units' => ['px', 'vh'],
|
||||
'condition' => [
|
||||
'height_type' => 'custom',
|
||||
],
|
||||
'default' => [
|
||||
'size' => 700,
|
||||
],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .dialog-widget-content' => 'height: {{SIZE}}{{UNIT}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'content_position',
|
||||
[
|
||||
'label' => __('Content Position'),
|
||||
'type' => ControlsManager::SELECT,
|
||||
'default' => 'top',
|
||||
'options' => [
|
||||
'top' => __('Top'),
|
||||
'center' => __('Center'),
|
||||
'bottom' => __('Bottom'),
|
||||
],
|
||||
'condition' => [
|
||||
'height_type!' => 'auto',
|
||||
],
|
||||
'selectors_dictionary' => [
|
||||
'top' => 'flex-start',
|
||||
'bottom' => 'flex-end',
|
||||
],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}}' => 'align-items: {{VALUE}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'position_heading',
|
||||
[
|
||||
'label' => __('Position'),
|
||||
'type' => ControlsManager::HEADING,
|
||||
'separator' => 'before',
|
||||
]
|
||||
);
|
||||
|
||||
$this->addResponsiveControl(
|
||||
'horizontal_position',
|
||||
[
|
||||
'label' => __('Horizontal'),
|
||||
'type' => ControlsManager::CHOOSE,
|
||||
'label_block' => false,
|
||||
'toggle' => false,
|
||||
'default' => 'center',
|
||||
'options' => [
|
||||
'left' => [
|
||||
'title' => __('Left'),
|
||||
'icon' => 'eicon-h-align-left',
|
||||
],
|
||||
'center' => [
|
||||
'title' => __('Center'),
|
||||
'icon' => 'eicon-h-align-center',
|
||||
],
|
||||
'right' => [
|
||||
'title' => __('Right'),
|
||||
'icon' => 'eicon-h-align-right',
|
||||
],
|
||||
],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}}' => 'justify-content: {{VALUE}}',
|
||||
],
|
||||
'selectors_dictionary' => [
|
||||
'left' => 'flex-start',
|
||||
'right' => 'flex-end',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addResponsiveControl(
|
||||
'vertical_position',
|
||||
[
|
||||
'label' => __('Vertical'),
|
||||
'type' => ControlsManager::CHOOSE,
|
||||
'label_block' => false,
|
||||
'toggle' => false,
|
||||
'default' => 'center',
|
||||
'options' => [
|
||||
'top' => [
|
||||
'title' => __('Top'),
|
||||
'icon' => 'eicon-v-align-top',
|
||||
],
|
||||
'center' => [
|
||||
'title' => __('Center'),
|
||||
'icon' => 'eicon-v-align-middle',
|
||||
],
|
||||
'bottom' => [
|
||||
'title' => __('Bottom'),
|
||||
'icon' => 'eicon-v-align-bottom',
|
||||
],
|
||||
],
|
||||
'selectors_dictionary' => [
|
||||
'top' => 'flex-start',
|
||||
'bottom' => 'flex-end',
|
||||
],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}}' => 'align-items: {{VALUE}}',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'close_button',
|
||||
[
|
||||
'label' => __('Close Button'),
|
||||
'type' => ControlsManager::SWITCHER,
|
||||
'label_off' => __('Hide'),
|
||||
'label_on' => __('Show'),
|
||||
'default' => 'yes',
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .dialog-close-button' => 'display: block',
|
||||
],
|
||||
'separator' => 'before',
|
||||
]
|
||||
);
|
||||
|
||||
$this->addResponsiveControl(
|
||||
'entrance_animation',
|
||||
[
|
||||
'label' => __('Entrance Animation'),
|
||||
'type' => ControlsManager::ANIMATION,
|
||||
'label_block' => true,
|
||||
'frontend_available' => true,
|
||||
'separator' => 'before',
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'entrance_animation_duration',
|
||||
[
|
||||
'label' => __('Animation Duration') . ' (sec)',
|
||||
'type' => ControlsManager::SLIDER,
|
||||
'range' => [
|
||||
'px' => [
|
||||
'min' => 0.1,
|
||||
'max' => 3,
|
||||
'step' => 0.1,
|
||||
],
|
||||
],
|
||||
'default' => [
|
||||
'size' => 0.5,
|
||||
],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .dialog-message' => 'animation-duration: {{SIZE}}s',
|
||||
],
|
||||
'condition' => [
|
||||
'entrance_animation!' => 'none',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->endControlsSection();
|
||||
|
||||
parent::_registerControls();
|
||||
|
||||
$this->startControlsSection(
|
||||
'section_page_style',
|
||||
[
|
||||
'label' => __('Popup'),
|
||||
'tab' => ControlsManager::TAB_STYLE,
|
||||
]
|
||||
);
|
||||
|
||||
$this->addGroupControl(
|
||||
GroupControlBackground::getType(),
|
||||
[
|
||||
'name' => 'background',
|
||||
'selector' => '{{WRAPPER}} .dialog-message',
|
||||
]
|
||||
);
|
||||
|
||||
$this->addGroupControl(
|
||||
GroupControlBorder::getType(),
|
||||
[
|
||||
'name' => 'border',
|
||||
'selector' => '{{WRAPPER}} .dialog-message',
|
||||
]
|
||||
);
|
||||
|
||||
$this->addResponsiveControl(
|
||||
'border_radius',
|
||||
[
|
||||
'label' => __('Border Radius'),
|
||||
'type' => ControlsManager::DIMENSIONS,
|
||||
'size_units' => ['px', '%'],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .dialog-message' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addGroupControl(
|
||||
GroupControlBoxShadow::getType(),
|
||||
[
|
||||
'name' => 'box_shadow',
|
||||
'selector' => '{{WRAPPER}} .dialog-message',
|
||||
'fields_options' => [
|
||||
'box_shadow_type' => [
|
||||
'default' => 'yes',
|
||||
],
|
||||
'box_shadow' => [
|
||||
'default' => [
|
||||
'horizontal' => 2,
|
||||
'vertical' => 8,
|
||||
'blur' => 23,
|
||||
'spread' => 3,
|
||||
'color' => 'rgba(0,0,0,0.2)',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->endControlsSection();
|
||||
|
||||
$this->startControlsSection(
|
||||
'section_overlay',
|
||||
[
|
||||
'label' => __('Overlay'),
|
||||
'tab' => ControlsManager::TAB_STYLE,
|
||||
]
|
||||
);
|
||||
|
||||
$this->addGroupControl(
|
||||
GroupControlBackground::getType(),
|
||||
[
|
||||
'name' => 'overlay_background',
|
||||
'types' => ['classic', 'gradient'],
|
||||
'selector' => '{{WRAPPER}}',
|
||||
'fields_options' => [
|
||||
'background' => [
|
||||
'default' => 'classic',
|
||||
],
|
||||
'color' => [
|
||||
'default' => 'rgba(0,0,0,.8)',
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->endControlsSection();
|
||||
|
||||
$this->startControlsSection(
|
||||
'section_close_button',
|
||||
[
|
||||
'label' => __('Close Button'),
|
||||
'tab' => ControlsManager::TAB_STYLE,
|
||||
'condition' => [
|
||||
'close_button!' => '',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'close_button_position',
|
||||
[
|
||||
'label' => __('Position'),
|
||||
'type' => ControlsManager::SELECT,
|
||||
'options' => [
|
||||
'inside' => __('Inside'),
|
||||
'outside' => __('Outside'),
|
||||
],
|
||||
'default' => 'outside',
|
||||
'frontend_available' => true,
|
||||
]
|
||||
);
|
||||
|
||||
$this->addResponsiveControl(
|
||||
'close_button_vertical',
|
||||
[
|
||||
'label' => __('Vertical Position'),
|
||||
'type' => ControlsManager::SLIDER,
|
||||
'size_units' => ['%', 'px'],
|
||||
'range' => [
|
||||
'%' => [
|
||||
'max' => 100,
|
||||
'min' => 0,
|
||||
'step' => 0.1,
|
||||
],
|
||||
'px' => [
|
||||
'max' => 500,
|
||||
'min' => -500,
|
||||
],
|
||||
],
|
||||
'default' => [
|
||||
'unit' => '%',
|
||||
],
|
||||
'tablet_default' => [
|
||||
'unit' => '%',
|
||||
],
|
||||
'mobile_default' => [
|
||||
'unit' => '%',
|
||||
],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .dialog-close-button' => 'top: {{SIZE}}{{UNIT}}',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addResponsiveControl(
|
||||
'close_button_horizontal',
|
||||
[
|
||||
'label' => __('Horizontal Position'),
|
||||
'type' => ControlsManager::SLIDER,
|
||||
'size_units' => ['%', 'px'],
|
||||
'range' => [
|
||||
'%' => [
|
||||
'max' => 100,
|
||||
'min' => 0,
|
||||
'step' => 0.1,
|
||||
],
|
||||
'px' => [
|
||||
'max' => 500,
|
||||
'min' => -500,
|
||||
],
|
||||
],
|
||||
'default' => [
|
||||
'unit' => '%',
|
||||
],
|
||||
'tablet_default' => [
|
||||
'unit' => '%',
|
||||
],
|
||||
'mobile_default' => [
|
||||
'unit' => '%',
|
||||
],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .dialog-close-button' => is_rtl() ? 'left: {{SIZE}}{{UNIT}}' : 'right: {{SIZE}}{{UNIT}}',
|
||||
],
|
||||
'separator' => 'after',
|
||||
]
|
||||
);
|
||||
|
||||
$this->startControlsTabs('close_button_style_tabs');
|
||||
|
||||
$this->startControlsTab(
|
||||
'tab_x_button_normal',
|
||||
[
|
||||
'label' => __('Normal'),
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'close_button_color',
|
||||
[
|
||||
'label' => __('Color'),
|
||||
'type' => ControlsManager::COLOR,
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .dialog-close-button i' => 'color: {{VALUE}}',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'close_button_background_color',
|
||||
[
|
||||
'label' => __('Background Color'),
|
||||
'type' => ControlsManager::COLOR,
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .dialog-close-button' => 'background-color: {{VALUE}}',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->endControlsTab();
|
||||
|
||||
$this->startControlsTab(
|
||||
'tab_x_button_hover',
|
||||
[
|
||||
'label' => __('Hover'),
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'close_button_hover_color',
|
||||
[
|
||||
'label' => __('Color'),
|
||||
'type' => ControlsManager::COLOR,
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .dialog-close-button:hover i' => 'color: {{VALUE}}',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'close_button_hover_background_color',
|
||||
[
|
||||
'label' => __('Background Color'),
|
||||
'type' => ControlsManager::COLOR,
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .dialog-close-button:hover' => 'background-color: {{VALUE}}',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->endControlsTab();
|
||||
|
||||
$this->endControlsTabs();
|
||||
|
||||
$this->addResponsiveControl(
|
||||
'icon_size',
|
||||
[
|
||||
'label' => __('Size'),
|
||||
'type' => ControlsManager::SLIDER,
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .dialog-close-button' => 'font-size: {{SIZE}}{{UNIT}}',
|
||||
],
|
||||
'separator' => 'before',
|
||||
]
|
||||
);
|
||||
|
||||
$this->endControlsSection();
|
||||
|
||||
$this->startControlsSection(
|
||||
'section_advanced',
|
||||
[
|
||||
'label' => __('Advanced'),
|
||||
'tab' => ControlsManager::TAB_ADVANCED,
|
||||
]
|
||||
);
|
||||
|
||||
$this->addResponsiveControl(
|
||||
'margin',
|
||||
[
|
||||
'label' => __('Margin'),
|
||||
'type' => ControlsManager::DIMENSIONS,
|
||||
'size_units' => ['px', '%'],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .dialog-message' =>
|
||||
'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}; ' .
|
||||
'max-height: calc(100vh - {{TOP}}{{UNIT}} - {{BOTTOM}}{{UNIT}})',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addResponsiveControl(
|
||||
'padding',
|
||||
[
|
||||
'label' => __('Padding'),
|
||||
'type' => ControlsManager::DIMENSIONS,
|
||||
'size_units' => ['px', '%'],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .dialog-message' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'z_index',
|
||||
[
|
||||
'label' => __('Z-Index'),
|
||||
'type' => ControlsManager::NUMBER,
|
||||
'min' => 0,
|
||||
'selectors' => [
|
||||
'{{WRAPPER}}' => 'z-index: {{VALUE}};',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->endControlsSection();
|
||||
|
||||
Plugin::$instance->controls_manager->addCustomCssControls($this);
|
||||
}
|
||||
}
|
||||
91
modules/creativeelements/core/document-types/product.php
Normal file
91
modules/creativeelements/core/document-types/product.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXBaseXThemePageDocument as ThemePageDocument;
|
||||
|
||||
class CoreXDocumentTypesXProduct extends ThemePageDocument
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'product';
|
||||
}
|
||||
|
||||
public static function getTitle()
|
||||
{
|
||||
return __('Product Page');
|
||||
}
|
||||
|
||||
protected static function getEditorPanelCategories()
|
||||
{
|
||||
$categories = [
|
||||
'product-elements' => [
|
||||
'title' => __('Product'),
|
||||
],
|
||||
];
|
||||
|
||||
$categories += parent::getEditorPanelCategories();
|
||||
|
||||
return $categories;
|
||||
}
|
||||
|
||||
protected function _registerControls()
|
||||
{
|
||||
parent::_registerControls();
|
||||
|
||||
$this->startControlsSection(
|
||||
'preview_settings',
|
||||
[
|
||||
'label' => __('Preview Settings'),
|
||||
'tab' => ControlsManager::TAB_SETTINGS,
|
||||
]
|
||||
);
|
||||
|
||||
if (is_admin()) {
|
||||
$prods = \Product::getProducts(\Context::getContext()->language->id, 0, 1, 'date_upd', 'DESC', false, true);
|
||||
}
|
||||
|
||||
$this->addControl(
|
||||
'preview_id',
|
||||
[
|
||||
'type' => ControlsManager::SELECT2,
|
||||
'label' => __('Product'),
|
||||
'label_block' => true,
|
||||
'select2options' => [
|
||||
'placeholder' => __('Loading') . '...',
|
||||
'allowClear' => false,
|
||||
'product' => true,
|
||||
'ajax' => [
|
||||
'url' => Helper::getAjaxProductsListLink(),
|
||||
],
|
||||
],
|
||||
'default' => !empty($prods[0]['id_product']) ? $prods[0]['id_product'] : 1,
|
||||
'export' => false,
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'apply_preview',
|
||||
[
|
||||
'type' => ControlsManager::BUTTON,
|
||||
'label' => __('Apply & Preview'),
|
||||
'label_block' => true,
|
||||
'show_label' => false,
|
||||
'text' => __('Apply & Preview'),
|
||||
'separator' => 'none',
|
||||
'event' => 'elementorThemeBuilder:ApplyPreview',
|
||||
]
|
||||
);
|
||||
|
||||
$this->endControlsSection();
|
||||
}
|
||||
}
|
||||
627
modules/creativeelements/core/documents-manager.php
Normal file
627
modules/creativeelements/core/documents-manager.php
Normal file
@@ -0,0 +1,627 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXCommonXModulesXAjaxXModule as Ajax;
|
||||
use CE\CoreXDocumentTypesXPost as Post;
|
||||
use CE\CoreXDocumentTypesXContent as Content;
|
||||
use CE\CoreXDocumentTypesXHeader as Header;
|
||||
use CE\CoreXDocumentTypesXFooter as Footer;
|
||||
use CE\CoreXDocumentTypesXProduct as Product;
|
||||
use CE\CoreXDocumentTypesXProductQuickView as ProductQuickView;
|
||||
use CE\CoreXDocumentTypesXProductMiniature as ProductMiniature;
|
||||
use CE\CoreXDocumentTypesXPageIndex as PageIndex;
|
||||
use CE\CoreXDocumentTypesXPageContact as PageContact;
|
||||
use CE\CoreXDocumentTypesXPageNotFound as PageNotFound;
|
||||
use CE\TemplateLibraryXSourceLocal as SourceLocal;
|
||||
|
||||
/**
|
||||
* Elementor documents manager.
|
||||
*
|
||||
* Elementor documents manager handler class is responsible for registering and
|
||||
* managing Elementor documents.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class CoreXDocumentsManager
|
||||
{
|
||||
/**
|
||||
* Registered types.
|
||||
*
|
||||
* Holds the list of all the registered types.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @var Document[]
|
||||
*/
|
||||
protected $types = [];
|
||||
|
||||
/**
|
||||
* Registered documents.
|
||||
*
|
||||
* Holds the list of all the registered documents.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @var Document[]
|
||||
*/
|
||||
protected $documents = [];
|
||||
|
||||
/**
|
||||
* Current document.
|
||||
*
|
||||
* Holds the current document.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @var Document
|
||||
*/
|
||||
protected $current_doc;
|
||||
|
||||
/**
|
||||
* Switched data.
|
||||
*
|
||||
* Holds the current document when changing to the requested post.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $switched_data = [];
|
||||
|
||||
protected $cpt = [];
|
||||
|
||||
/**
|
||||
* Documents manager constructor.
|
||||
*
|
||||
* Initializing the Elementor documents manager.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
add_action('elementor/documents/register', [$this, 'register_default_types'], 0);
|
||||
add_action('elementor/ajax/register_actions', [$this, 'register_ajax_actions']);
|
||||
// add_filter('post_row_actions', [$this, 'filter_post_row_actions'], 11, 2);
|
||||
// add_filter('page_row_actions', [$this, 'filter_post_row_actions'], 11, 2);
|
||||
// add_filter('user_has_cap', [$this, 'remove_user_edit_cap'], 10, 3);
|
||||
add_filter('elementor/editor/localize_settings', [$this, 'localize_settings']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register ajax actions.
|
||||
*
|
||||
* Process ajax action handles when saving data and discarding changes.
|
||||
*
|
||||
* Fired by `elementor/ajax/register_actions` action.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param Ajax $ajax_manager An instance of the ajax manager.
|
||||
*/
|
||||
public function registerAjaxActions($ajax_manager)
|
||||
{
|
||||
$ajax_manager->registerAjaxAction('save_builder', [$this, 'ajax_save']);
|
||||
$ajax_manager->registerAjaxAction('discard_changes', [$this, 'ajax_discard_changes']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register default types.
|
||||
*
|
||||
* Registers the default document types.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function registerDefaultTypes()
|
||||
{
|
||||
$default_types = [
|
||||
'post' => Post::getClassFullName(),
|
||||
'content' => Content::getClassFullName(),
|
||||
'header' => Header::getClassFullName(),
|
||||
'footer' => Footer::getClassFullName(),
|
||||
'product' => Product::getClassFullName(),
|
||||
'product-quick-view' => ProductQuickView::getClassFullName(),
|
||||
'product-miniature' => ProductMiniature::getClassFullName(),
|
||||
'page-index' => PageIndex::getClassFullName(),
|
||||
'page-contact' => PageContact::getClassFullName(),
|
||||
'page-not-found' => PageNotFound::getClassFullName(),
|
||||
];
|
||||
|
||||
foreach ($default_types as $type => $class) {
|
||||
$this->registerDocumentType($type, $class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register document type.
|
||||
*
|
||||
* Registers a single document.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $type Document type name.
|
||||
* @param Document $class The name of the class that registers the document type.
|
||||
* Full name with the namespace.
|
||||
*
|
||||
* @return DocumentsManager The updated document manager instance.
|
||||
*/
|
||||
public function registerDocumentType($type, $class)
|
||||
{
|
||||
$this->types[$type] = $class;
|
||||
|
||||
$cpt = $class::getProperty('cpt');
|
||||
|
||||
if ($cpt) {
|
||||
foreach ($cpt as $post_type) {
|
||||
$this->cpt[$post_type] = $type;
|
||||
}
|
||||
}
|
||||
|
||||
if ($class::getProperty('register_type')) {
|
||||
SourceLocal::addTemplateType($type);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get document.
|
||||
*
|
||||
* Retrieve the document data based on a post ID.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @param bool $from_cache Optional. Whether to retrieve cached data. Default is true.
|
||||
*
|
||||
* @return false|Document Document data or false if post ID was not entered.
|
||||
*/
|
||||
public function get($post_id, $from_cache = true)
|
||||
{
|
||||
$this->registerTypes();
|
||||
|
||||
$post_id = absint($post_id);
|
||||
|
||||
if (!$post_id || !get_post($post_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$post_id = apply_filters('elementor/documents/get/post_id', "$post_id");
|
||||
|
||||
if (!$from_cache || !isset($this->documents[$post_id])) {
|
||||
if ($parent = wp_is_post_autosave($post_id)) {
|
||||
$post_type = get_post_type($parent);
|
||||
} else {
|
||||
$post_type = get_post_type($post_id);
|
||||
}
|
||||
|
||||
$doc_type = 'post';
|
||||
|
||||
if (isset($this->cpt[$post_type])) {
|
||||
$doc_type = $this->cpt[$post_type];
|
||||
}
|
||||
|
||||
// $meta_type = get_post_meta($post_id, Document::TYPE_META_KEY, true);
|
||||
$uid = UId::parse($post_id);
|
||||
$meta_type = get_post($uid)->template_type;
|
||||
|
||||
if ($meta_type && isset($this->types[$meta_type])) {
|
||||
$doc_type = $meta_type;
|
||||
}
|
||||
|
||||
$doc_type_class = $this->getDocumentType($doc_type);
|
||||
$this->documents[$post_id] = new $doc_type_class([
|
||||
'post_id' => $post_id,
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->documents[$post_id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get document or autosave.
|
||||
*
|
||||
* Retrieve either the document or the autosave.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param int $id Post ID.
|
||||
* @param int $user_id User ID. Default is `0`.
|
||||
*
|
||||
* @return false|Document The document if it exist, False otherwise.
|
||||
*/
|
||||
public function getDocOrAutoSave($id, $user_id = 0)
|
||||
{
|
||||
$document = $this->get($id);
|
||||
if ($document && $document->getAutosaveId($user_id)) {
|
||||
$document = $document->getAutosave($user_id);
|
||||
}
|
||||
|
||||
return $document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get document for frontend.
|
||||
*
|
||||
* Retrieve the document for frontend use.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param int $post_id Optional. Post ID. Default is `0`.
|
||||
*
|
||||
* @return false|Document The document if it exist, False otherwise.
|
||||
*/
|
||||
public function getDocForFrontend($post_id)
|
||||
{
|
||||
if (\CreativeElements::getPreviewUId(false)) {
|
||||
$document = $this->getDocOrAutoSave($post_id, get_current_user_id());
|
||||
} else {
|
||||
$document = $this->get($post_id);
|
||||
}
|
||||
|
||||
return $document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get document type.
|
||||
*
|
||||
* Retrieve the type of any given document.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @param string $fallback
|
||||
*
|
||||
* @return Document|bool The type of the document.
|
||||
*/
|
||||
public function getDocumentType($type, $fallback = 'post')
|
||||
{
|
||||
$types = $this->getDocumentTypes();
|
||||
|
||||
if (isset($types[$type])) {
|
||||
return $types[$type];
|
||||
}
|
||||
|
||||
if (isset($types[$fallback])) {
|
||||
return $types[$fallback];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get document types.
|
||||
*
|
||||
* Retrieve the all the registered document types.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $args Optional. An array of key => value arguments to match against
|
||||
* the properties. Default is empty array.
|
||||
* @param string $operator Optional. The logical operation to perform. 'or' means only one
|
||||
* element from the array needs to match; 'and' means all elements
|
||||
* must match; 'not' means no elements may match. Default 'and'.
|
||||
*
|
||||
* @return Document[] All the registered document types.
|
||||
*/
|
||||
public function getDocumentTypes($args = [], $operator = 'and')
|
||||
{
|
||||
$this->registerTypes();
|
||||
|
||||
if (!empty($args)) {
|
||||
// $types_properties = $this->getTypesProperties();
|
||||
|
||||
// $filtered = wp_filter_object_list($types_properties, $args, $operator);
|
||||
|
||||
// return array_intersect_key($this->types, $filtered);
|
||||
throw new \RuntimeException('TODO');
|
||||
}
|
||||
|
||||
return $this->types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get document types with their properties.
|
||||
*
|
||||
* @return array A list of properties arrays indexed by the type.
|
||||
*/
|
||||
public function getTypesProperties()
|
||||
{
|
||||
$types_properties = [];
|
||||
|
||||
foreach ($this->getDocumentTypes() as $type => $class) {
|
||||
$types_properties[$type] = $class::getProperties();
|
||||
}
|
||||
return $types_properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a document.
|
||||
*
|
||||
* Create a new document using any given parameters.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $type Document type.
|
||||
* @param array $post_data An array containing the post data.
|
||||
* @param array $meta_data An array containing the post meta data.
|
||||
*
|
||||
* @return Document The type of the document.
|
||||
*/
|
||||
public function create($type, $post_data = [], $meta_data = [])
|
||||
{
|
||||
$class = $this->getDocumentType($type, false);
|
||||
|
||||
if (!$class) {
|
||||
die(sprintf('Type %s does not exist.', $type));
|
||||
}
|
||||
|
||||
// if (empty($post_data['post_title'])) {
|
||||
// $post_data['post_title'] = __('Elementor');
|
||||
// if ('post' !== $type) {
|
||||
// $post_data['post_title'] = sprintf(
|
||||
// __('Elementor %s'),
|
||||
// call_user_func([$class, 'get_title'])
|
||||
// );
|
||||
// }
|
||||
// $update_title = true;
|
||||
// }
|
||||
|
||||
$meta_data['_elementor_edit_mode'] = 'builder';
|
||||
|
||||
// $meta_data[Document::TYPE_META_KEY] = $type;
|
||||
$post_data['template_type'] = $type;
|
||||
|
||||
$post_data['meta_input'] = $meta_data;
|
||||
|
||||
$post_id = wp_insert_post($post_data);
|
||||
|
||||
// if (!empty($update_title)) {
|
||||
// $post_data['ID'] = $post_id;
|
||||
// $post_data['post_title'] .= ' #' . $post_id;
|
||||
|
||||
// // The meta doesn't need update.
|
||||
// unset($post_data['meta_input']);
|
||||
|
||||
// wp_update_post($post_data);
|
||||
// }
|
||||
|
||||
/** @var Document $document */
|
||||
$document = new $class([
|
||||
'post_id' => $post_id,
|
||||
]);
|
||||
|
||||
// Let the $document to re-save the template type by his way + version.
|
||||
$document->save([]);
|
||||
|
||||
return $document;
|
||||
}
|
||||
|
||||
// public function removeUserEditCap($allcaps, $caps, $args)
|
||||
|
||||
// public function filterPostRowActions($actions, $post)
|
||||
|
||||
/**
|
||||
* Save document data using ajax.
|
||||
*
|
||||
* Save the document on the builder using ajax, when saving the changes, and refresh the editor.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param $request Post ID.
|
||||
*
|
||||
* @throws \Exception If current user don't have permissions to edit the post or the post is not using Elementor.
|
||||
*
|
||||
* @return array The document data after saving.
|
||||
*/
|
||||
public function ajaxSave($request)
|
||||
{
|
||||
$document = $this->get($request['editor_post_id']);
|
||||
|
||||
// if (!$document->isBuiltWithElementor() || !$document->isEditableByCurrentUser()) {
|
||||
if (!$document->isEditableByCurrentUser()) {
|
||||
throw new \Exception('Access denied.');
|
||||
}
|
||||
|
||||
$this->switchToDocument($document);
|
||||
$post = $document->getPost();
|
||||
|
||||
// Set the post as global post.
|
||||
Plugin::$instance->db->switchToPost($post->ID);
|
||||
|
||||
$status = DB::STATUS_DRAFT;
|
||||
|
||||
if (isset($request['status']) && in_array($request['status'], [DB::STATUS_PUBLISH, DB::STATUS_PRIVATE, DB::STATUS_AUTOSAVE], true)) {
|
||||
$status = $request['status'];
|
||||
}
|
||||
|
||||
if (DB::STATUS_AUTOSAVE === $status) {
|
||||
// If the post is a draft - save the `autosave` to the original draft.
|
||||
// Allow a revision only if the original post is already published.
|
||||
if (in_array($post->post_status, [DB::STATUS_PUBLISH, DB::STATUS_PRIVATE], true)) {
|
||||
$document = $document->getAutosave(0, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Set default page template because the footer-saver doesn't send default values,
|
||||
// But if the template was changed from canvas to default - it needed to save.
|
||||
if (Utils::isCptCustomTemplatesSupported($post) && !isset($request['settings']['template'])) {
|
||||
$request['settings']['template'] = 'default';
|
||||
}
|
||||
|
||||
$data = [
|
||||
'elements' => $request['elements'],
|
||||
'settings' => $request['settings'],
|
||||
];
|
||||
|
||||
$document->save($data);
|
||||
|
||||
// Refresh after save.
|
||||
$document = $this->get($post->ID, false);
|
||||
|
||||
$return_data = [
|
||||
'config' => [
|
||||
'document' => [
|
||||
'last_edited' => $document->getLastEdited(),
|
||||
'urls' => [
|
||||
'wp_preview' => $document->getWpPreviewUrl(),
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Returned documents ajax saved data.
|
||||
*
|
||||
* Filters the ajax data returned when saving the post on the builder.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $return_data The returned data.
|
||||
* @param Document $document The document instance.
|
||||
*/
|
||||
$return_data = apply_filters('elementor/documents/ajax_save/return_data', $return_data, $document);
|
||||
|
||||
return $return_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax discard changes.
|
||||
*
|
||||
* Load the document data from an autosave, deleting unsaved changes.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param $request
|
||||
*
|
||||
* @return bool True if changes discarded, False otherwise.
|
||||
*/
|
||||
public function ajaxDiscardChanges($request)
|
||||
{
|
||||
$document = $this->get($request['editor_post_id']);
|
||||
|
||||
$autosave = $document->getAutosave();
|
||||
|
||||
if ($autosave) {
|
||||
$success = $autosave->delete();
|
||||
} else {
|
||||
$success = true;
|
||||
}
|
||||
|
||||
return $success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch to document.
|
||||
*
|
||||
* Change the document to any new given document type.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param Document $document The document to switch to.
|
||||
*/
|
||||
public function switchToDocument($document)
|
||||
{
|
||||
// If is already switched, or is the same post, return.
|
||||
if ($this->current_doc === $document) {
|
||||
$this->switched_data[] = false;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->switched_data[] = [
|
||||
'switched_doc' => $document,
|
||||
'original_doc' => $this->current_doc, // Note, it can be null if the global isn't set
|
||||
];
|
||||
|
||||
$this->current_doc = $document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore document.
|
||||
*
|
||||
* Rollback to the original document.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function restoreDocument()
|
||||
{
|
||||
$data = array_pop($this->switched_data);
|
||||
|
||||
// If not switched, return.
|
||||
if (!$data) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->current_doc = $data['original_doc'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current document.
|
||||
*
|
||||
* Retrieve the current document.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return Document The current document.
|
||||
*/
|
||||
public function getCurrent()
|
||||
{
|
||||
return $this->current_doc;
|
||||
}
|
||||
|
||||
public function localizeSettings($settings)
|
||||
{
|
||||
$translations = [];
|
||||
|
||||
foreach ($this->getDocumentTypes() as $type => $class) {
|
||||
$translations[$type] = $class::getTitle();
|
||||
}
|
||||
|
||||
return array_replace_recursive($settings, [
|
||||
'i18n' => $translations,
|
||||
]);
|
||||
}
|
||||
|
||||
private function registerTypes()
|
||||
{
|
||||
if (!did_action('elementor/documents/register')) {
|
||||
/**
|
||||
* Register Elementor documents.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param DocumentsManager $this The document manager instance.
|
||||
*/
|
||||
do_action('elementor/documents/register', $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
200
modules/creativeelements/core/dynamic-tags/base-tag.php
Normal file
200
modules/creativeelements/core/dynamic-tags/base-tag.php
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
/**
|
||||
* Elementor base tag.
|
||||
*
|
||||
* An abstract class to register new Elementor tags.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class CoreXDynamicTagsXBaseTag extends ControlsStack
|
||||
{
|
||||
const REMOTE_RENDER = false;
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
final public static function getType()
|
||||
{
|
||||
return 'tag';
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function getCategories();
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function getGroup();
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function getTitle();
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*
|
||||
* @param array $options
|
||||
*/
|
||||
abstract public function getContent(array $options = []);
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function getContentType();
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function getPanelTemplateSettingKey()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function isSettingsRequired()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.9
|
||||
* @access public
|
||||
*/
|
||||
public function getEditorConfig()
|
||||
{
|
||||
ob_start();
|
||||
|
||||
$this->printPanelTemplate();
|
||||
|
||||
$panel_template = ob_get_clean();
|
||||
|
||||
return [
|
||||
'name' => $this->getName(),
|
||||
'title' => $this->getTitle(),
|
||||
'panel_template' => &$panel_template,
|
||||
'categories' => $this->getCategories(),
|
||||
'group' => $this->getGroup(),
|
||||
'controls' => $this->getControls(),
|
||||
'content_type' => $this->getContentType(),
|
||||
'settings_required' => $this->isSettingsRequired(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function printPanelTemplate()
|
||||
{
|
||||
$panel_template_setting_key = $this->getPanelTemplateSettingKey();
|
||||
|
||||
if (!$panel_template_setting_key) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<#
|
||||
var key = <?= esc_html($panel_template_setting_key); ?>;
|
||||
if (key) {
|
||||
var settingsKey = "<?= esc_html($panel_template_setting_key); ?>";
|
||||
/*
|
||||
* If the tag has controls,
|
||||
* and key is an existing control (and not an old one),
|
||||
* and the control has options (select/select2/choose),
|
||||
* and the key is an existing option (and not in a group or an old one).
|
||||
*/
|
||||
if (controls && controls[settingsKey]) {
|
||||
var controlSettings = controls[settingsKey];
|
||||
if (controlSettings.options && controlSettings.options[key]) {
|
||||
var label = controlSettings.options[key];
|
||||
key = label.title || label;
|
||||
} else if (controlSettings.groups) {
|
||||
var label = controlSettings.groups[key];
|
||||
if ('string' === typeof label) {
|
||||
key = label;
|
||||
} else {
|
||||
label = _.filter(_.pluck(_.pluck(controlSettings.groups, 'options'), key));
|
||||
if (label[0]) {
|
||||
key = label[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
print('(' + key + ')');
|
||||
}
|
||||
#>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
final public function getUniqueName()
|
||||
{
|
||||
return 'tag-' . $this->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function registerAdvancedSection()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
*/
|
||||
final protected function initControls()
|
||||
{
|
||||
Plugin::$instance->controls_manager->openStack($this);
|
||||
|
||||
$this->startControlsSection('settings', [
|
||||
'label' => __('Settings'),
|
||||
]);
|
||||
|
||||
$this->_registerControls();
|
||||
|
||||
$this->endControlsSection();
|
||||
|
||||
// If in fact no controls were registered, empty the stack
|
||||
if (1 === count(Plugin::$instance->controls_manager->getStacks($this->getUniqueName())['controls'])) {
|
||||
Plugin::$instance->controls_manager->openStack($this);
|
||||
}
|
||||
|
||||
$this->registerAdvancedSection();
|
||||
}
|
||||
}
|
||||
69
modules/creativeelements/core/dynamic-tags/data-tag.php
Normal file
69
modules/creativeelements/core/dynamic-tags/data-tag.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXDynamicTagsXBaseTag as BaseTag;
|
||||
|
||||
/**
|
||||
* Elementor base data tag.
|
||||
*
|
||||
* An abstract class to register new Elementor data tags.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class CoreXDynamicTagsXDataTag extends BaseTag
|
||||
{
|
||||
private static $getter_method = 'getValue';
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
* @abstract
|
||||
*
|
||||
* @param array $options
|
||||
*/
|
||||
abstract protected function getValue(array $options = []);
|
||||
|
||||
/**
|
||||
* @since 2.5.10
|
||||
* @access protected
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getSmartyValue(array $options = [])
|
||||
{
|
||||
return '{literal}' . $this->getValue($options) . '{/literal}';
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
final public function getContentType()
|
||||
{
|
||||
return 'plain';
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $options
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getContent(array $options = [])
|
||||
{
|
||||
return static::REMOTE_RENDER && is_admin() && 'getValue' === self::$getter_method ? null : $this->{self::$getter_method}($options);
|
||||
}
|
||||
}
|
||||
126
modules/creativeelements/core/dynamic-tags/dynamic-css.php
Normal file
126
modules/creativeelements/core/dynamic-tags/dynamic-css.php
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXFilesXCSSXPost as Post;
|
||||
|
||||
class CoreXDynamicTagsXDynamicCSS extends Post
|
||||
{
|
||||
protected $post_id_for_data;
|
||||
|
||||
/**
|
||||
* Dynamic_CSS constructor.
|
||||
*
|
||||
* @since 2.0.13
|
||||
* @access public
|
||||
* @param int $post_id Post ID
|
||||
* @param int $post_id_for_data
|
||||
*/
|
||||
public function __construct($post_id, $post_id_for_data)
|
||||
{
|
||||
$this->post_id_for_data = $post_id_for_data;
|
||||
|
||||
parent::__construct($post_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.13
|
||||
* @access public
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'dynamic';
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.13
|
||||
* @access protected
|
||||
*/
|
||||
protected function useExternalFile()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.13
|
||||
* @access protected
|
||||
*/
|
||||
protected function getFileHandleId()
|
||||
{
|
||||
return 'elementor-post-dynamic-' . $this->post_id_for_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.13
|
||||
* @access protected
|
||||
*/
|
||||
protected function getData()
|
||||
{
|
||||
return Plugin::$instance->db->getPlainEditor($this->post_id_for_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.13
|
||||
* @access public
|
||||
*/
|
||||
public function getMeta($property = null)
|
||||
{
|
||||
// Parse CSS first, to get the fonts list.
|
||||
$css = $this->getContent();
|
||||
|
||||
$meta = [
|
||||
'status' => $css ? self::CSS_STATUS_INLINE : self::CSS_STATUS_EMPTY,
|
||||
'fonts' => $this->getFonts(),
|
||||
'css' => $css,
|
||||
];
|
||||
|
||||
if ($property) {
|
||||
return isset($meta[$property]) ? $meta[$property] : null;
|
||||
}
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.13
|
||||
* @access public
|
||||
*/
|
||||
public function addControlsStackStyleRules(ControlsStack $controls_stack, array $controls, array $values, array $placeholders, array $replacements, array $all_controls = null)
|
||||
{
|
||||
$dynamic_settings = $controls_stack->getSettings('__dynamic__');
|
||||
if (!empty($dynamic_settings)) {
|
||||
$controls = array_intersect_key($controls, $dynamic_settings);
|
||||
|
||||
$all_controls = $controls_stack->getControls();
|
||||
|
||||
$parsed_dynamic_settings = $controls_stack->parseDynamicSettings($values, $controls);
|
||||
|
||||
foreach ($controls as $control) {
|
||||
if (!empty($control['style_fields'])) {
|
||||
$this->addRepeaterControlStyleRules($controls_stack, $control, $values[$control['name']], $placeholders, $replacements);
|
||||
}
|
||||
|
||||
if (empty($control['selectors'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->addControlStyleRules($control, $parsed_dynamic_settings, $all_controls, $placeholders, $replacements);
|
||||
}
|
||||
}
|
||||
|
||||
if ($controls_stack instanceof ElementBase) {
|
||||
foreach ($controls_stack->getChildren() as $child_element) {
|
||||
$this->renderStyles($child_element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
modules/creativeelements/core/dynamic-tags/index.php
Normal file
8
modules/creativeelements/core/dynamic-tags/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../');
|
||||
die;
|
||||
464
modules/creativeelements/core/dynamic-tags/manager.php
Normal file
464
modules/creativeelements/core/dynamic-tags/manager.php
Normal file
@@ -0,0 +1,464 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXCommonXModulesXAjaxXModule as Ajax;
|
||||
use CE\CoreXFilesXCSSXPost as Post;
|
||||
use CE\CoreXFilesXCSSXPostPreview as PostPreview;
|
||||
use CE\CoreXDynamicTagsXBaseTag as BaseTag;
|
||||
use CE\CoreXDynamicTagsXDynamicCSS as DynamicCSS;
|
||||
|
||||
class CoreXDynamicTagsXManager
|
||||
{
|
||||
const TAG_LABEL = 'elementor-tag';
|
||||
|
||||
const MODE_RENDER = 'render';
|
||||
|
||||
const MODE_REMOVE = 'remove';
|
||||
|
||||
const DYNAMIC_SETTING_KEY = '__dynamic__';
|
||||
|
||||
private $tags_groups = [];
|
||||
|
||||
private $tags_info = [];
|
||||
|
||||
private $parsing_mode = self::MODE_RENDER;
|
||||
|
||||
/**
|
||||
* Dynamic tags manager constructor.
|
||||
*
|
||||
* Initializing Elementor dynamic tags manager.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->addActions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse dynamic tags text.
|
||||
*
|
||||
* Receives the dynamic tag text, and returns a single value or multiple values
|
||||
* from the tag callback function.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $text Dynamic tag text.
|
||||
* @param array $settings The dynamic tag settings.
|
||||
* @param callable $parse_callback The functions that renders the dynamic tag.
|
||||
*
|
||||
* @return string|string[]|mixed A single string or an array of strings with
|
||||
* the return values from each tag callback
|
||||
* function.
|
||||
*/
|
||||
public function parseTagsText($text, array $settings, callable $parse_callback)
|
||||
{
|
||||
if (!empty($settings['returnType']) && 'object' === $settings['returnType']) {
|
||||
$value = $this->parseTagText($text, $settings, $parse_callback);
|
||||
} else {
|
||||
$value = preg_replace_callback('/\[' . self::TAG_LABEL . '.+?(?=\])\]/', function ($tag_text_match) use ($settings, $parse_callback) {
|
||||
return $this->parseTagText($tag_text_match[0], $settings, $parse_callback);
|
||||
}, $text);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse dynamic tag text.
|
||||
*
|
||||
* Receives the dynamic tag text, and returns the value from the callback
|
||||
* function.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $tag_text Dynamic tag text.
|
||||
* @param array $settings The dynamic tag settings.
|
||||
* @param callable $parse_callback The functions that renders the dynamic tag.
|
||||
*
|
||||
* @return string|array|mixed If the tag was not found an empty string or an
|
||||
* empty array will be returned, otherwise the
|
||||
* return value from the tag callback function.
|
||||
*/
|
||||
public function parseTagText($tag_text, array $settings, callable $parse_callback)
|
||||
{
|
||||
$tag_data = $this->tagTextToTagData($tag_text);
|
||||
|
||||
if (!$tag_data) {
|
||||
if (!empty($settings['returnType']) && 'object' === $settings['returnType']) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
return call_user_func_array($parse_callback, $tag_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $tag_text
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function tagTextToTagData($tag_text)
|
||||
{
|
||||
preg_match('/id="(.*?(?="))"/', $tag_text, $tag_id_match);
|
||||
preg_match('/name="(.*?(?="))"/', $tag_text, $tag_name_match);
|
||||
preg_match('/settings="(.*?(?="]))/', $tag_text, $tag_settings_match);
|
||||
|
||||
if (!$tag_id_match || !$tag_name_match || !$tag_settings_match) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $tag_id_match[1],
|
||||
'name' => $tag_name_match[1],
|
||||
'settings' => json_decode(urldecode($tag_settings_match[1]), true),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamic tag to text.
|
||||
*
|
||||
* Retrieve the shortcode that represents the dynamic tag.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param BaseTag $tag An instance of the dynamic tag.
|
||||
*
|
||||
* @return string The shortcode that represents the dynamic tag.
|
||||
*/
|
||||
public function tagToText(BaseTag $tag)
|
||||
{
|
||||
return sprintf('[%1$s id="%2$s" name="%3$s" settings="%4$s"]', self::TAG_LABEL, $tag->getId(), $tag->getName(), urlencode(json_encode($tag->getSettings(), JSON_FORCE_OBJECT)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @param string $tag_id
|
||||
* @param string $tag_name
|
||||
* @param array $settings
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function tagDataToTagText($tag_id, $tag_name, array $settings = [])
|
||||
{
|
||||
$tag = $this->createTag($tag_id, $tag_name, $settings);
|
||||
|
||||
if (!$tag) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->tagToText($tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @param string $tag_id
|
||||
* @param string $tag_name
|
||||
* @param array $settings
|
||||
*
|
||||
* @return Tag|null
|
||||
*/
|
||||
public function createTag($tag_id, $tag_name, array $settings = [])
|
||||
{
|
||||
$tag_info = $this->getTagInfo($tag_name);
|
||||
|
||||
if (!$tag_info) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$tag_class = $tag_info['class'];
|
||||
|
||||
return new $tag_class([
|
||||
'settings' => $settings,
|
||||
'id' => $tag_id,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param $tag_id
|
||||
* @param $tag_name
|
||||
* @param array $settings
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getTagDataContent($tag_id, $tag_name, array $settings = [])
|
||||
{
|
||||
if (self::MODE_REMOVE === $this->parsing_mode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$tag = $this->createTag($tag_id, $tag_name, $settings);
|
||||
|
||||
if (!$tag) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $tag->getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param $tag_name
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function getTagInfo($tag_name)
|
||||
{
|
||||
$tags = $this->getTags();
|
||||
|
||||
if (empty($tags[$tag_name])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $tags[$tag_name];
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.9
|
||||
* @access public
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
if (!did_action('elementor/dynamic_tags/register_tags')) {
|
||||
/**
|
||||
* Register dynamic tags.
|
||||
*
|
||||
* Fires when Elementor registers dynamic tags.
|
||||
*
|
||||
* @since 2.0.9
|
||||
*
|
||||
* @param Manager $this Dynamic tags manager.
|
||||
*/
|
||||
do_action('elementor/dynamic_tags/register_tags', $this);
|
||||
}
|
||||
|
||||
return $this->tags_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $class
|
||||
*/
|
||||
public function registerTag($class)
|
||||
{
|
||||
/** @var Tag $tag */
|
||||
$tag = new $class();
|
||||
|
||||
$this->tags_info[$tag->getName()] = [
|
||||
'class' => $class,
|
||||
'instance' => $tag,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.9
|
||||
* @access public
|
||||
*
|
||||
* @param string $tag_name
|
||||
*/
|
||||
public function unregisterTag($tag_name)
|
||||
{
|
||||
unset($this->tags_info[$tag_name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param $group_name
|
||||
* @param array $group_settings
|
||||
*/
|
||||
public function registerGroup($group_name, array $group_settings)
|
||||
{
|
||||
$default_group_settings = [
|
||||
'title' => '',
|
||||
];
|
||||
|
||||
$group_settings = array_merge($default_group_settings, $group_settings);
|
||||
|
||||
$this->tags_groups[$group_name] = $group_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function printTemplates()
|
||||
{
|
||||
foreach ($this->getTags() as $tag_name => $tag_info) {
|
||||
$tag = $tag_info['instance'];
|
||||
|
||||
if (!$tag instanceof Tag) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tag->printTemplate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function getTagsConfig()
|
||||
{
|
||||
$config = [];
|
||||
|
||||
foreach ($this->getTags() as $tag_name => $tag_info) {
|
||||
/** @var Tag $tag */
|
||||
$tag = $tag_info['instance'];
|
||||
|
||||
$config[$tag_name] = $tag->getEditorConfig();
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function getConfig()
|
||||
{
|
||||
return [
|
||||
'tags' => $this->getTagsConfig(),
|
||||
'groups' => $this->tags_groups,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @throws \Exception If post ID is missing.
|
||||
* @throws \Exception If current user don't have permissions to edit the post.
|
||||
*/
|
||||
public function ajaxRenderTags()
|
||||
{
|
||||
$data = json_decode(${'_POST'}['data'], true);
|
||||
|
||||
if (empty($data['post_id'])) {
|
||||
throw new \Exception('Missing post id.');
|
||||
}
|
||||
|
||||
if (!User::isCurrentUserCanEdit($data['post_id'])) {
|
||||
throw new \Exception('Access denied.');
|
||||
}
|
||||
|
||||
Plugin::$instance->db->switchToPost($data['post_id']);
|
||||
|
||||
/**
|
||||
* Before dynamic tags rendered.
|
||||
*
|
||||
* Fires before Elementor renders the dynamic tags.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
do_action('elementor/dynamic_tags/before_render');
|
||||
|
||||
$tags_data = [];
|
||||
|
||||
foreach ($data['tags'] as $tag_key) {
|
||||
$tag_key_parts = explode('-', $tag_key);
|
||||
|
||||
$tag_name = base64_decode($tag_key_parts[0]);
|
||||
|
||||
$tag_settings = json_decode(urldecode(base64_decode($tag_key_parts[1])), true);
|
||||
|
||||
$tag = $this->createTag(null, $tag_name, $tag_settings);
|
||||
|
||||
$tags_data[$tag_key] = $tag->getContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* After dynamic tags rendered.
|
||||
*
|
||||
* Fires after Elementor renders the dynamic tags.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
do_action('elementor/dynamic_tags/after_render');
|
||||
|
||||
return $tags_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param $mode
|
||||
*/
|
||||
public function setParsingMode($mode)
|
||||
{
|
||||
$this->parsing_mode = $mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function getParsingMode()
|
||||
{
|
||||
return $this->parsing_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
* @param Post $css_file
|
||||
*/
|
||||
public function afterEnqueuePostCss($css_file)
|
||||
{
|
||||
$post_id = $css_file->getPostId();
|
||||
|
||||
if ($css_file instanceof PostPreview) {
|
||||
$post_id_for_data = $css_file->getPreviewId();
|
||||
} else {
|
||||
$post_id_for_data = $post_id;
|
||||
}
|
||||
|
||||
$css_file = new DynamicCSS($post_id, $post_id_for_data);
|
||||
|
||||
$css_file->enqueue();
|
||||
}
|
||||
|
||||
// public function registerAjaxActions(Ajax $ajax)
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function addActions()
|
||||
{
|
||||
// add_action('elementor/ajax/register_actions', [$this, 'register_ajax_actions']);
|
||||
add_action('elementor/css-file/post/enqueue', [$this, 'after_enqueue_post_css']);
|
||||
}
|
||||
}
|
||||
149
modules/creativeelements/core/dynamic-tags/tag.php
Normal file
149
modules/creativeelements/core/dynamic-tags/tag.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXDynamicTagsXBaseTag as BaseTag;
|
||||
|
||||
/**
|
||||
* Elementor tag.
|
||||
*
|
||||
* An abstract class to register new Elementor tag.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class CoreXDynamicTagsXTag extends BaseTag
|
||||
{
|
||||
const WRAPPED_TAG = false;
|
||||
|
||||
private static $render_method = 'render';
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getContent(array $options = [])
|
||||
{
|
||||
if (static::REMOTE_RENDER && is_admin() && 'render' === self::$render_method) {
|
||||
return;
|
||||
}
|
||||
|
||||
$settings = $this->getSettings();
|
||||
|
||||
ob_start();
|
||||
|
||||
$this->{self::$render_method}();
|
||||
|
||||
$value = ob_get_clean();
|
||||
|
||||
if ('renderSmarty' === self::$render_method) {
|
||||
if ($settings['before'] || $settings['after'] || $settings['fallback']) {
|
||||
$value = "{capture assign='ce_tag'}$value{/capture}" .
|
||||
'{if strlen($ce_tag)}' .
|
||||
wp_kses_post($settings['before'] . '{$ce_tag nofilter}' . $settings['after']) .
|
||||
'{else}' .
|
||||
$settings['fallback'] .
|
||||
'{/if}';
|
||||
}
|
||||
} elseif ($value) {
|
||||
if (!empty($settings['before'])) {
|
||||
$value = wp_kses_post($settings['before']) . $value;
|
||||
}
|
||||
|
||||
if (!empty($settings['after'])) {
|
||||
$value .= wp_kses_post($settings['after']);
|
||||
}
|
||||
|
||||
if (static::WRAPPED_TAG) {
|
||||
$id = $this->getId();
|
||||
$value = '<span id="elementor-tag-' . esc_attr($id) . '" class="elementor-tag">' . $value . '</span>';
|
||||
}
|
||||
} elseif (!empty($settings['fallback'])) {
|
||||
$value = $settings['fallback'];
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.5.10
|
||||
* @access protected
|
||||
*/
|
||||
protected function renderSmarty()
|
||||
{
|
||||
$this->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
final public function getContentType()
|
||||
{
|
||||
return 'ui';
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.9
|
||||
* @access public
|
||||
*/
|
||||
public function getEditorConfig()
|
||||
{
|
||||
$config = parent::getEditorConfig();
|
||||
|
||||
$config['wrapped_tag'] = $this::WRAPPED_TAG;
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function registerAdvancedSection()
|
||||
{
|
||||
$this->startControlsSection(
|
||||
'advanced',
|
||||
[
|
||||
'label' => __('Advanced'),
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'before',
|
||||
[
|
||||
'label' => __('Before'),
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'after',
|
||||
[
|
||||
'label' => __('After'),
|
||||
]
|
||||
);
|
||||
|
||||
$this->addControl(
|
||||
'fallback',
|
||||
[
|
||||
'label' => __('Fallback'),
|
||||
'separator' => 'before',
|
||||
]
|
||||
);
|
||||
|
||||
$this->endControlsSection();
|
||||
}
|
||||
}
|
||||
314
modules/creativeelements/core/files/base.php
Normal file
314
modules/creativeelements/core/files/base.php
Normal file
@@ -0,0 +1,314 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
abstract class CoreXFilesXBase
|
||||
{
|
||||
const UPLOADS_DIR = 'css/ce/';
|
||||
|
||||
const DEFAULT_FILES_DIR = '';
|
||||
|
||||
const META_KEY = '';
|
||||
|
||||
// private static $wp_uploads_dir = [];
|
||||
|
||||
private $files_dir;
|
||||
|
||||
private $file_name;
|
||||
|
||||
/**
|
||||
* File path.
|
||||
*
|
||||
* Holds the file path.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $path;
|
||||
|
||||
/**
|
||||
* Content.
|
||||
*
|
||||
* Holds the file content.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $content;
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function getBaseUploadsDir()
|
||||
{
|
||||
$wp_upload_dir = wp_upload_dir();
|
||||
|
||||
return $wp_upload_dir['basedir'] . '/' . self::UPLOADS_DIR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function getBaseUploadsUrl()
|
||||
{
|
||||
$wp_upload_dir = wp_upload_dir();
|
||||
|
||||
return $wp_upload_dir['baseurl'] . '/' . self::UPLOADS_DIR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct($file_name)
|
||||
{
|
||||
/**
|
||||
* Elementor File Name
|
||||
*
|
||||
* Filters the File name
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @param string $file_name
|
||||
* @param object $this The file instance, which inherits Elementor\Core\Files
|
||||
*/
|
||||
$file_name = apply_filters('elementor/files/file_name', $file_name, $this);
|
||||
|
||||
$this->setFileName($file_name);
|
||||
|
||||
$this->setFilesDir(static::DEFAULT_FILES_DIR);
|
||||
|
||||
$this->setPath();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*/
|
||||
public function setFilesDir($files_dir)
|
||||
{
|
||||
$this->files_dir = $files_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*/
|
||||
public function setFileName($file_name)
|
||||
{
|
||||
$this->file_name = $file_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*/
|
||||
public function getFileName()
|
||||
{
|
||||
return $this->file_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
$url = self::getBaseUploadsUrl() . $this->files_dir . $this->file_name;
|
||||
|
||||
return add_query_arg(['v' => $this->getMeta('time')], $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
if (!$this->content) {
|
||||
$this->content = $this->parseContent();
|
||||
}
|
||||
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
$this->updateFile();
|
||||
|
||||
$meta = $this->getMeta();
|
||||
|
||||
$meta['time'] = time();
|
||||
|
||||
$this->updateMeta($meta);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*/
|
||||
public function updateFile()
|
||||
{
|
||||
$this->content = $this->parseContent();
|
||||
// CE Fix: global fonts aren't updated
|
||||
$this->delete();
|
||||
|
||||
if ($this->content) {
|
||||
$this->write();
|
||||
} else {
|
||||
// $this->delete();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*/
|
||||
public function write()
|
||||
{
|
||||
return file_put_contents($this->path, $this->content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
if (file_exists($this->path)) {
|
||||
unlink($this->path);
|
||||
}
|
||||
|
||||
$this->deleteMeta();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get meta data.
|
||||
*
|
||||
* Retrieve the CSS file meta data. Returns an array of all the data, or if
|
||||
* custom property is given it will return the property value, or `null` if
|
||||
* the property does not exist.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $property Optional. Custom meta data property. Default is
|
||||
* null.
|
||||
*
|
||||
* @return array|null An array of all the data, or if custom property is
|
||||
* given it will return the property value, or `null` if
|
||||
* the property does not exist.
|
||||
*/
|
||||
public function getMeta($property = null)
|
||||
{
|
||||
$default_meta = $this->getDefaultMeta();
|
||||
|
||||
$meta = array_merge($default_meta, (array) $this->loadMeta());
|
||||
|
||||
if ($property) {
|
||||
return isset($meta[$property]) ? $meta[$property] : null;
|
||||
}
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access protected
|
||||
* @abstract
|
||||
*/
|
||||
abstract protected function parseContent();
|
||||
|
||||
/**
|
||||
* Load meta.
|
||||
*
|
||||
* Retrieve the file meta data.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function loadMeta()
|
||||
{
|
||||
return get_option(static::META_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update meta.
|
||||
*
|
||||
* Update the file meta data.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access protected
|
||||
*
|
||||
* @param array $meta New meta data.
|
||||
*/
|
||||
protected function updateMeta($meta)
|
||||
{
|
||||
update_option(static::META_KEY, $meta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete meta.
|
||||
*
|
||||
* Delete the file meta data.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function deleteMeta()
|
||||
{
|
||||
delete_option(static::META_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function getDefaultMeta()
|
||||
{
|
||||
return [
|
||||
'time' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
// private static function getWpUploadsDir()
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access private
|
||||
*/
|
||||
private function setPath()
|
||||
{
|
||||
$dir_path = self::getBaseUploadsDir() . $this->files_dir;
|
||||
|
||||
if (!is_dir($dir_path)) {
|
||||
@mkdir($dir_path, 0775, true);
|
||||
}
|
||||
|
||||
$this->path = $dir_path . $this->file_name;
|
||||
}
|
||||
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
}
|
||||
718
modules/creativeelements/core/files/css/base.php
Normal file
718
modules/creativeelements/core/files/css/base.php
Normal file
@@ -0,0 +1,718 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
// use CE\CoreXDynamicTagsXManager as Manager;
|
||||
use CE\CoreXDynamicTagsXTag as Tag;
|
||||
use CE\CoreXFilesXBase as BaseFile;
|
||||
use CE\CoreXResponsiveXResponsive as Responsive;
|
||||
|
||||
/**
|
||||
* Elementor CSS file.
|
||||
*
|
||||
* Elementor CSS file handler class is responsible for generating CSS files.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class CoreXFilesXCSSXBase extends BaseFile
|
||||
{
|
||||
/**
|
||||
* Elementor CSS file generated status.
|
||||
*
|
||||
* The parsing result after generating CSS file.
|
||||
*/
|
||||
const CSS_STATUS_FILE = 'file';
|
||||
|
||||
/**
|
||||
* Elementor inline CSS status.
|
||||
*
|
||||
* The parsing result after generating inline CSS.
|
||||
*/
|
||||
const CSS_STATUS_INLINE = 'inline';
|
||||
|
||||
/**
|
||||
* Elementor CSS empty status.
|
||||
*
|
||||
* The parsing result when an empty CSS returned.
|
||||
*/
|
||||
const CSS_STATUS_EMPTY = 'empty';
|
||||
|
||||
/**
|
||||
* Fonts.
|
||||
*
|
||||
* Holds the list of fonts.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $fonts = [];
|
||||
|
||||
/**
|
||||
* Stylesheet object.
|
||||
*
|
||||
* Holds the CSS file stylesheet instance.
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @var Stylesheet
|
||||
*/
|
||||
protected $stylesheet_obj;
|
||||
|
||||
/**
|
||||
* Printed.
|
||||
*
|
||||
* Holds the list of printed files.
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $printed = [];
|
||||
|
||||
/**
|
||||
* Get CSS file name.
|
||||
*
|
||||
* Retrieve the CSS file name.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function getName();
|
||||
|
||||
/**
|
||||
* CSS file constructor.
|
||||
*
|
||||
* Initializing Elementor CSS file.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct($file_name)
|
||||
{
|
||||
parent::__construct($file_name);
|
||||
|
||||
$this->initStylesheet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use external file.
|
||||
*
|
||||
* Whether to use external CSS file of not. When there are new schemes or settings
|
||||
* updates.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access protected
|
||||
*
|
||||
* @return bool True if the CSS requires an update, False otherwise.
|
||||
*/
|
||||
protected function useExternalFile()
|
||||
{
|
||||
return 'internal' !== get_option('elementor_css_print_method');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the CSS file.
|
||||
*
|
||||
* Delete old CSS, parse the CSS, save the new file and update the database.
|
||||
*
|
||||
* This method also sets the CSS status to be used later on in the render posses.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access public
|
||||
*/
|
||||
public function update()
|
||||
{
|
||||
$this->updateFile();
|
||||
|
||||
$meta = $this->getMeta();
|
||||
|
||||
$meta['time'] = time();
|
||||
|
||||
$content = $this->getContent();
|
||||
|
||||
if (empty($content)) {
|
||||
$meta['status'] = self::CSS_STATUS_EMPTY;
|
||||
$meta['css'] = '';
|
||||
} else {
|
||||
$use_external_file = $this->useExternalFile();
|
||||
|
||||
if ($use_external_file) {
|
||||
$meta['status'] = self::CSS_STATUS_FILE;
|
||||
$meta['css'] = '';
|
||||
} else {
|
||||
$meta['status'] = self::CSS_STATUS_INLINE;
|
||||
$meta['css'] = $content;
|
||||
}
|
||||
}
|
||||
|
||||
$this->updateMeta($meta);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*/
|
||||
public function write()
|
||||
{
|
||||
if ($this->useExternalFile()) {
|
||||
parent::write();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue CSS.
|
||||
*
|
||||
* Either enqueue the CSS file in Elementor or add inline style.
|
||||
*
|
||||
* This method is also responsible for loading the fonts.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access public
|
||||
*/
|
||||
public function enqueue()
|
||||
{
|
||||
$handle_id = $this->getFileHandleId();
|
||||
|
||||
if (isset(self::$printed[$handle_id])) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::$printed[$handle_id] = true;
|
||||
|
||||
$meta = $this->getMeta();
|
||||
|
||||
if (self::CSS_STATUS_EMPTY === $meta['status']) {
|
||||
return;
|
||||
}
|
||||
|
||||
// First time after clear cache and etc.
|
||||
if ('' === $meta['status'] || $this->isUpdateRequired()) {
|
||||
$this->update();
|
||||
|
||||
$meta = $this->getMeta();
|
||||
}
|
||||
|
||||
if (self::CSS_STATUS_INLINE === $meta['status']) {
|
||||
$dep = $this->getInlineDependency();
|
||||
|
||||
wp_add_inline_style($dep, $meta['css']);
|
||||
} elseif (self::CSS_STATUS_FILE === $meta['status']) {
|
||||
// Re-check if it's not empty after CSS update.
|
||||
wp_enqueue_style($this->getFileHandleId(), $this->getUrl(), $this->getEnqueueDependencies(), null);
|
||||
}
|
||||
|
||||
// Handle fonts.
|
||||
if (!empty($meta['fonts'])) {
|
||||
foreach ($meta['fonts'] as $font) {
|
||||
Plugin::$instance->frontend->enqueueFont($font);
|
||||
}
|
||||
}
|
||||
|
||||
$name = $this->getName();
|
||||
|
||||
/**
|
||||
* Enqueue CSS file.
|
||||
*
|
||||
* Fires when CSS file is enqueued on Elementor.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$name`, refers to the CSS file name.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param Base $this The current CSS file.
|
||||
*/
|
||||
do_action("elementor/css-file/{$name}/enqueue", $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print CSS.
|
||||
*
|
||||
* Output the final CSS inside the `<style>` tags and all the frontend fonts in
|
||||
* use.
|
||||
*
|
||||
* @since 1.9.4
|
||||
* @access public
|
||||
*/
|
||||
public function printCss()
|
||||
{
|
||||
echo '<style>' . $this->getContent() . '</style>'; // XSS ok.
|
||||
Plugin::$instance->frontend->printFontsLinks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add control rules.
|
||||
*
|
||||
* Parse the CSS for all the elements inside any given control.
|
||||
*
|
||||
* This method recursively renders the CSS for all the selectors in the control.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $control The controls.
|
||||
* @param array $controls_stack The controls stack.
|
||||
* @param callable $value_callback Callback function for the value.
|
||||
* @param array $placeholders Placeholders.
|
||||
* @param array $replacements Replacements.
|
||||
*/
|
||||
public function addControlRules(array $control, array $controls_stack, callable $value_callback, array $placeholders, array $replacements)
|
||||
{
|
||||
$value = call_user_func($value_callback, $control);
|
||||
|
||||
if (null === $value || empty($control['selectors'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($control['selectors'] as $selector => $css_property) {
|
||||
try {
|
||||
$output_css_property = preg_replace_callback(
|
||||
'/\{\{(?:([^.}]+)\.)?([^}| ]*)(?: *\|\| *(?:([^.}]+)\.)?([^}| ]*) *)*}}/',
|
||||
function ($matches) use ($control, $value_callback, $controls_stack, $value, $css_property) {
|
||||
$external_control_missing = $matches[1] && !isset($controls_stack[$matches[1]]);
|
||||
|
||||
$parsed_value = '';
|
||||
|
||||
if (!$external_control_missing) {
|
||||
$parsed_value = $this->parsePropertyPlaceholder($control, $value, $controls_stack, $value_callback, $matches[2], $matches[1]);
|
||||
}
|
||||
|
||||
if ('' === $parsed_value) {
|
||||
if (isset($matches[4])) {
|
||||
$parsed_value = $matches[4];
|
||||
|
||||
$is_string_value = preg_match('/^([\'"])(.*)\1$/', $parsed_value, $string_matches);
|
||||
|
||||
if ($is_string_value) {
|
||||
$parsed_value = $string_matches[2];
|
||||
} elseif (!is_numeric($parsed_value)) {
|
||||
if ($matches[3] && !isset($controls_stack[$matches[3]])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$parsed_value = $this->parsePropertyPlaceholder($control, $value, $controls_stack, $value_callback, $matches[4], $matches[3]);
|
||||
}
|
||||
}
|
||||
|
||||
if ('' === $parsed_value) {
|
||||
if ($external_control_missing) {
|
||||
return '';
|
||||
}
|
||||
|
||||
throw new \Exception();
|
||||
}
|
||||
}
|
||||
|
||||
return $parsed_value;
|
||||
},
|
||||
$css_property
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$output_css_property) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$device_pattern = '/^(?:\([^\)]+\)){1,2}/';
|
||||
|
||||
preg_match($device_pattern, $selector, $device_rules);
|
||||
|
||||
$query = [];
|
||||
|
||||
if ($device_rules) {
|
||||
$selector = preg_replace($device_pattern, '', $selector);
|
||||
|
||||
preg_match_all('/\(([^\)]+)\)/', $device_rules[0], $pure_device_rules);
|
||||
|
||||
$pure_device_rules = $pure_device_rules[1];
|
||||
|
||||
foreach ($pure_device_rules as $device_rule) {
|
||||
if (ElementBase::RESPONSIVE_DESKTOP === $device_rule) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$device = preg_replace('/\+$/', '', $device_rule);
|
||||
|
||||
$endpoint = $device === $device_rule ? 'max' : 'min';
|
||||
|
||||
$query[$endpoint] = $device;
|
||||
}
|
||||
}
|
||||
|
||||
$parsed_selector = str_replace($placeholders, $replacements, $selector);
|
||||
|
||||
if (!$query && !empty($control['responsive'])) {
|
||||
$query = array_intersect_key($control['responsive'], array_flip(['min', 'max']));
|
||||
|
||||
if (!empty($query['max']) && ElementBase::RESPONSIVE_DESKTOP === $query['max']) {
|
||||
unset($query['max']);
|
||||
}
|
||||
}
|
||||
|
||||
$this->stylesheet_obj->addRules($parsed_selector, $output_css_property, $query);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $control
|
||||
* @param mixed $value
|
||||
* @param array $controls_stack
|
||||
* @param callable $value_callback
|
||||
* @param string $placeholder
|
||||
* @param string $parser_control_name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function parsePropertyPlaceholder(array $control, $value, array $controls_stack, $value_callback, $placeholder, $parser_control_name = null)
|
||||
{
|
||||
if ($parser_control_name) {
|
||||
$control = $controls_stack[$parser_control_name];
|
||||
|
||||
$value = call_user_func($value_callback, $control);
|
||||
}
|
||||
|
||||
if (ControlsManager::FONT === $control['type']) {
|
||||
$this->fonts[] = $value;
|
||||
}
|
||||
|
||||
/** @var BaseDataControl $control_obj */
|
||||
$control_obj = Plugin::$instance->controls_manager->getControl($control['type']);
|
||||
|
||||
return (string) $control_obj->getStyleValue($placeholder, $value, $control);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fonts.
|
||||
*
|
||||
* Retrieve the list of fonts.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Fonts.
|
||||
*/
|
||||
public function getFonts()
|
||||
{
|
||||
return $this->fonts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stylesheet.
|
||||
*
|
||||
* Retrieve the CSS file stylesheet instance.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access public
|
||||
*
|
||||
* @return Stylesheet The stylesheet object.
|
||||
*/
|
||||
public function getStylesheet()
|
||||
{
|
||||
return $this->stylesheet_obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add controls stack style rules.
|
||||
*
|
||||
* Parse the CSS for all the elements inside any given controls stack.
|
||||
*
|
||||
* This method recursively renders the CSS for all the child elements in the stack.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @param ControlsStack $controls_stack The controls stack.
|
||||
* @param array $controls Controls array.
|
||||
* @param array $values Values array.
|
||||
* @param array $placeholders Placeholders.
|
||||
* @param array $replacements Replacements.
|
||||
* @param array $all_controls All controls.
|
||||
*/
|
||||
public function addControlsStackStyleRules(ControlsStack $controls_stack, array $controls, array $values, array $placeholders, array $replacements, array $all_controls = null)
|
||||
{
|
||||
if (!$all_controls) {
|
||||
$all_controls = $controls_stack->getControls();
|
||||
}
|
||||
|
||||
$parsed_dynamic_settings = $controls_stack->parseDynamicSettings($values, $controls);
|
||||
|
||||
foreach ($controls as $control) {
|
||||
if (!empty($control['style_fields'])) {
|
||||
$this->addRepeaterControlStyleRules($controls_stack, $control, $values[$control['name']], $placeholders, $replacements);
|
||||
}
|
||||
|
||||
if (!empty($control['__dynamic__'][$control['name']])) {
|
||||
$this->addDynamicControlStyleRules($control, $control['__dynamic__'][$control['name']]);
|
||||
}
|
||||
|
||||
if (!empty($parsed_dynamic_settings['__dynamic__'][$control['name']])) {
|
||||
unset($parsed_dynamic_settings[$control['name']]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (empty($control['selectors'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->addControlStyleRules($control, $parsed_dynamic_settings, $all_controls, $placeholders, $replacements);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file handle ID.
|
||||
*
|
||||
* Retrieve the file handle ID.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
* @abstract
|
||||
*
|
||||
* @return string CSS file handle ID.
|
||||
*/
|
||||
abstract protected function getFileHandleId();
|
||||
|
||||
/**
|
||||
* Render CSS.
|
||||
*
|
||||
* Parse the CSS.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
* @abstract
|
||||
*/
|
||||
abstract protected function renderCss();
|
||||
|
||||
protected function getDefaultMeta()
|
||||
{
|
||||
return array_merge(parent::getDefaultMeta(), [
|
||||
'fonts' => array_unique($this->fonts),
|
||||
'status' => '',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get enqueue dependencies.
|
||||
*
|
||||
* Retrieve the name of the stylesheet used by `wp_enqueue_style()`.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Name of the stylesheet.
|
||||
*/
|
||||
protected function getEnqueueDependencies()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get inline dependency.
|
||||
*
|
||||
* Retrieve the name of the stylesheet used by `wp_add_inline_style()`.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
*
|
||||
* @return string Name of the stylesheet.
|
||||
*/
|
||||
protected function getInlineDependency()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Is update required.
|
||||
*
|
||||
* Whether the CSS requires an update. When there are new schemes or settings
|
||||
* updates.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
*
|
||||
* @return bool True if the CSS requires an update, False otherwise.
|
||||
*/
|
||||
protected function isUpdateRequired()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse CSS.
|
||||
*
|
||||
* Parsing the CSS file.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function parseContent()
|
||||
{
|
||||
$this->renderCss();
|
||||
|
||||
$name = $this->getName();
|
||||
|
||||
/**
|
||||
* Parse CSS file.
|
||||
*
|
||||
* Fires when CSS file is parsed on Elementor.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$name`, refers to the CSS file name.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param Base $this The current CSS file.
|
||||
*/
|
||||
do_action("elementor/css-file/{$name}/parse", $this);
|
||||
|
||||
return $this->stylesheet_obj->__toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add control style rules.
|
||||
*
|
||||
* Register new style rules for the control.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
*
|
||||
* @param array $control The control.
|
||||
* @param array $values Values array.
|
||||
* @param array $controls The controls stack.
|
||||
* @param array $placeholders Placeholders.
|
||||
* @param array $replacements Replacements.
|
||||
*/
|
||||
protected function addControlStyleRules(array $control, array $values, array $controls, array $placeholders, array $replacements)
|
||||
{
|
||||
$this->addControlRules(
|
||||
$control,
|
||||
$controls,
|
||||
function ($control) use ($values) {
|
||||
return $this->getStyleControlValue($control, $values);
|
||||
},
|
||||
$placeholders,
|
||||
$replacements
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get style control value.
|
||||
*
|
||||
* Retrieve the value of the style control for any give control and values.
|
||||
*
|
||||
* It will retrieve the control name and return the style value.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
*
|
||||
* @param array $control The control.
|
||||
* @param array $values Values array.
|
||||
*
|
||||
* @return mixed Style control value.
|
||||
*/
|
||||
private function getStyleControlValue(array $control, array $values)
|
||||
{
|
||||
$value = $values[$control['name']];
|
||||
|
||||
// fix for background image
|
||||
if (!empty($value['url']) && (strrpos($control['name'], '_image') !== false || 'background_video_fallback' === $control['name'])) {
|
||||
$value['url'] = Helper::getMediaLink($value['url']);
|
||||
}
|
||||
|
||||
if (isset($control['selectors_dictionary'][$value])) {
|
||||
$value = $control['selectors_dictionary'][$value];
|
||||
}
|
||||
|
||||
if (!is_numeric($value) && !is_float($value) && empty($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init stylesheet.
|
||||
*
|
||||
* Initialize CSS file stylesheet by creating a new `Stylesheet` object and register new
|
||||
* breakpoints for the stylesheet.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access private
|
||||
*/
|
||||
private function initStylesheet()
|
||||
{
|
||||
$this->stylesheet_obj = new Stylesheet();
|
||||
|
||||
$breakpoints = Responsive::getBreakpoints();
|
||||
|
||||
$this->stylesheet_obj
|
||||
->addDevice('mobile', 0)
|
||||
->addDevice('tablet', $breakpoints['md'])
|
||||
->addDevice('desktop', $breakpoints['lg']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add repeater control style rules.
|
||||
*
|
||||
* Register new style rules for the repeater control.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*
|
||||
* @param ControlsStack $controls_stack The control stack.
|
||||
* @param array $repeater_control The repeater control.
|
||||
* @param array $repeater_values Repeater values array.
|
||||
* @param array $placeholders Placeholders.
|
||||
* @param array $replacements Replacements.
|
||||
*/
|
||||
protected function addRepeaterControlStyleRules(ControlsStack $controls_stack, array $repeater_control, array $repeater_values, array $placeholders, array $replacements)
|
||||
{
|
||||
$placeholders = array_merge($placeholders, ['{{CURRENT_ITEM}}']);
|
||||
|
||||
foreach ($repeater_control['style_fields'] as $index => $item) {
|
||||
$this->addControlsStackStyleRules(
|
||||
$controls_stack,
|
||||
$item,
|
||||
$repeater_values[$index],
|
||||
$placeholders,
|
||||
array_merge($replacements, ['.elementor-repeater-item-' . $repeater_values[$index]['_id']]),
|
||||
$repeater_control['fields']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add dynamic control style rules.
|
||||
*
|
||||
* Register new style rules for the dynamic control.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*
|
||||
* @param array $control The control.
|
||||
* @param string $value The value.
|
||||
*/
|
||||
protected function addDynamicControlStyleRules(array $control, $value)
|
||||
{
|
||||
Plugin::$instance->dynamic_tags->parseTagsText($value, $control, function ($id, $name, $settings) {
|
||||
$tag = Plugin::$instance->dynamic_tags->createTag($id, $name, $settings);
|
||||
|
||||
if (!$tag instanceof Tag) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->addControlsStackStyleRules($tag, $tag->getStyleControls(), $tag->getActiveSettings(), ['{{WRAPPER}}'], ['#elementor-tag-' . $id]);
|
||||
});
|
||||
}
|
||||
}
|
||||
165
modules/creativeelements/core/files/css/global-css.php
Normal file
165
modules/creativeelements/core/files/css/global-css.php
Normal file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXFilesXCSSXBase as Base;
|
||||
|
||||
/**
|
||||
* Elementor global CSS file.
|
||||
*
|
||||
* Elementor CSS file handler class is responsible for generating the global CSS
|
||||
* file.
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
class CoreXFilesXCSSXGlobalCSS extends Base
|
||||
{
|
||||
/**
|
||||
* Elementor global CSS file handler ID.
|
||||
*/
|
||||
const FILE_HANDLER_ID = 'elementor-global';
|
||||
|
||||
const META_KEY = '_elementor_global_css';
|
||||
|
||||
/**
|
||||
* Get CSS file name.
|
||||
*
|
||||
* Retrieve the CSS file name.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return string CSS file name.
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'global';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file handle ID.
|
||||
*
|
||||
* Retrieve the handle ID for the global post CSS file.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
*
|
||||
* @return string CSS file handle ID.
|
||||
*/
|
||||
protected function getFileHandleId()
|
||||
{
|
||||
return self::FILE_HANDLER_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render CSS.
|
||||
*
|
||||
* Parse the CSS for all the widgets and all the scheme controls.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function renderCss()
|
||||
{
|
||||
do_action("ce/css-file/{$this->getName()}/before_render", $this);
|
||||
|
||||
$this->renderSchemesCss();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get inline dependency.
|
||||
*
|
||||
* Retrieve the name of the stylesheet used by `wp_add_inline_style()`.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
*
|
||||
* @return string Name of the stylesheet.
|
||||
*/
|
||||
protected function getInlineDependency()
|
||||
{
|
||||
return 'elementor-frontend';
|
||||
}
|
||||
|
||||
/**
|
||||
* Is update required.
|
||||
*
|
||||
* Whether the CSS requires an update. When there are new schemes or settings
|
||||
* updates.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
*
|
||||
* @return bool True if the CSS requires an update, False otherwise.
|
||||
*/
|
||||
protected function isUpdateRequired()
|
||||
{
|
||||
$file_last_updated = $this->getMeta('time');
|
||||
|
||||
$schemes_last_update = get_option(SchemeBase::LAST_UPDATED_META);
|
||||
|
||||
if ($file_last_updated < $schemes_last_update) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// $elementor_settings_last_updated = get_option(Settings::UPDATE_TIME_FIELD);
|
||||
|
||||
// if ($file_last_updated < $elementor_settings_last_updated) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render schemes CSS.
|
||||
*
|
||||
* Parse the CSS for all the widgets and all the scheme controls.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access private
|
||||
*/
|
||||
private function renderSchemesCss()
|
||||
{
|
||||
$elementor = Plugin::$instance;
|
||||
|
||||
foreach ($elementor->widgets_manager->getWidgetTypes() as $widget) {
|
||||
$scheme_controls = $widget->getSchemeControls();
|
||||
|
||||
foreach ($scheme_controls as $control) {
|
||||
$this->addControlRules(
|
||||
$control,
|
||||
$widget->getControls(),
|
||||
function ($control) use ($elementor) {
|
||||
$scheme_value = $elementor->schemes_manager->getSchemeValue($control['scheme']['type'], $control['scheme']['value']);
|
||||
|
||||
if (empty($scheme_value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!empty($control['scheme']['key'])) {
|
||||
$scheme_value = $scheme_value[$control['scheme']['key']];
|
||||
}
|
||||
|
||||
if (empty($scheme_value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $scheme_value;
|
||||
},
|
||||
['{{WRAPPER}}'],
|
||||
['.elementor-widget-' . $widget->getName()]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
modules/creativeelements/core/files/css/index.php
Normal file
8
modules/creativeelements/core/files/css/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../../');
|
||||
die;
|
||||
124
modules/creativeelements/core/files/css/post-preview.php
Normal file
124
modules/creativeelements/core/files/css/post-preview.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXFilesXCSSXPost as Post;
|
||||
|
||||
/**
|
||||
* Elementor post preview CSS file.
|
||||
*
|
||||
* Elementor CSS file handler class is responsible for generating the post
|
||||
* preview CSS file.
|
||||
*
|
||||
* @since 1.9.0
|
||||
*/
|
||||
class CoreXFilesXCSSXPostPreview extends Post
|
||||
{
|
||||
/**
|
||||
* Preview ID.
|
||||
*
|
||||
* Holds the ID of the current post being previewed.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $preview_id;
|
||||
|
||||
/**
|
||||
* Post preview CSS file constructor.
|
||||
*
|
||||
* Initializing the CSS file of the post preview. Set the post ID and the
|
||||
* parent ID and initiate the stylesheet.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
*/
|
||||
public function __construct($post_id)
|
||||
{
|
||||
$this->preview_id = $post_id;
|
||||
|
||||
$parent_id = wp_get_post_parent_id($post_id);
|
||||
|
||||
parent::__construct($parent_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*/
|
||||
public function getPreviewId()
|
||||
{
|
||||
return $this->preview_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data.
|
||||
*
|
||||
* Retrieve raw post data from the database.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Post data.
|
||||
*/
|
||||
protected function getData()
|
||||
{
|
||||
return Plugin::$instance->db->getPlainEditor($this->preview_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file handle ID.
|
||||
*
|
||||
* Retrieve the handle ID for the previewed post CSS file.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access protected
|
||||
*
|
||||
* @return string CSS file handle ID.
|
||||
*/
|
||||
protected function getFileHandleId()
|
||||
{
|
||||
return 'elementor-preview-' . $this->preview_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get meta data.
|
||||
*
|
||||
* Retrieve the previewed post CSS file meta data.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $property Optional. Custom meta data property. Default is
|
||||
* null.
|
||||
*
|
||||
* @return array Previewed post CSS file meta data.
|
||||
*/
|
||||
public function getMeta($property = null)
|
||||
{
|
||||
// Parse CSS first, to get the fonts list.
|
||||
$css = $this->getContent();
|
||||
|
||||
$meta = [
|
||||
'status' => self::CSS_STATUS_INLINE,
|
||||
'fonts' => $this->getFonts(),
|
||||
'css' => $css,
|
||||
];
|
||||
|
||||
if ($property) {
|
||||
return isset($meta[$property]) ? $meta[$property] : null;
|
||||
}
|
||||
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
347
modules/creativeelements/core/files/css/post.php
Normal file
347
modules/creativeelements/core/files/css/post.php
Normal file
@@ -0,0 +1,347 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXFilesXCSSXBase as Base;
|
||||
|
||||
/**
|
||||
* Elementor post CSS file.
|
||||
*
|
||||
* Elementor CSS file handler class is responsible for generating the single
|
||||
* post CSS file.
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
class CoreXFilesXCSSXPost extends Base
|
||||
{
|
||||
/**
|
||||
* Elementor post CSS file prefix.
|
||||
*/
|
||||
const FILE_PREFIX = '';
|
||||
|
||||
const META_KEY = '_elementor_css';
|
||||
|
||||
/**
|
||||
* Post ID.
|
||||
*
|
||||
* Holds the current post ID.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $post_id;
|
||||
|
||||
/**
|
||||
* Post CSS file constructor.
|
||||
*
|
||||
* Initializing the CSS file of the post. Set the post ID and initiate the stylesheet.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access public
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
*/
|
||||
public function __construct($post_id)
|
||||
{
|
||||
$this->post_id = $post_id;
|
||||
|
||||
parent::__construct(self::FILE_PREFIX . $post_id . '.css');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CSS file name.
|
||||
*
|
||||
* Retrieve the CSS file name.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return string CSS file name.
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'post';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post ID.
|
||||
*
|
||||
* Retrieve the ID of current post.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access public
|
||||
*
|
||||
* @return int Post ID.
|
||||
*/
|
||||
public function getPostId()
|
||||
{
|
||||
return $this->post_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unique element selector.
|
||||
*
|
||||
* Retrieve the unique selector for any given element.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access public
|
||||
*
|
||||
* @param ElementBase $element The element.
|
||||
*
|
||||
* @return string Unique element selector.
|
||||
*/
|
||||
public function getElementUniqueSelector(ElementBase $element)
|
||||
{
|
||||
return '.elementor-' . $this->post_id . ' .elementor-element' . $element->getUniqueSelector();
|
||||
}
|
||||
|
||||
public function getTransformHoverSelector(ElementBase $element)
|
||||
{
|
||||
switch ($element->getSettings('_transform_trigger_hover')) {
|
||||
case 'miniature':
|
||||
$selector = "[data-elementor-type$=miniature] > :hover {$element->getUniqueSelector()} > .elementor-widget-container";
|
||||
break;
|
||||
case 'section':
|
||||
$selector = ".elementor-section:hover > .elementor-container > * > * > .elementor-column-wrap > * > {$element->getUniqueSelector()} > .elementor-widget-container";
|
||||
break;
|
||||
case 'column':
|
||||
$selector = ".elementor-column-wrap:hover > * > {$element->getUniqueSelector()} > .elementor-widget-container";
|
||||
break;
|
||||
default:
|
||||
$selector = "{$element->getUniqueSelector()} > .elementor-widget-container:hover";
|
||||
break;
|
||||
}
|
||||
return $selector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load meta data.
|
||||
*
|
||||
* Retrieve the post CSS file meta data.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Post CSS file meta data.
|
||||
*/
|
||||
protected function loadMeta()
|
||||
{
|
||||
return get_post_meta($this->post_id, static::META_KEY, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update meta data.
|
||||
*
|
||||
* Update the global CSS file meta data.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
*
|
||||
* @param array $meta New meta data.
|
||||
*/
|
||||
protected function updateMeta($meta)
|
||||
{
|
||||
update_post_meta($this->post_id, static::META_KEY, $meta);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete meta.
|
||||
*
|
||||
* Delete the file meta data.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function deleteMeta()
|
||||
{
|
||||
delete_post_meta($this->post_id, static::META_KEY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post data.
|
||||
*
|
||||
* Retrieve raw post data from the database.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Post data.
|
||||
*/
|
||||
protected function getData()
|
||||
{
|
||||
return Plugin::$instance->db->getPlainEditor($this->post_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render CSS.
|
||||
*
|
||||
* Parse the CSS for all the elements.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function renderCss()
|
||||
{
|
||||
$data = $this->getData();
|
||||
|
||||
if (!empty($data)) {
|
||||
foreach ($data as $element_data) {
|
||||
$element = Plugin::$instance->elements_manager->createElementInstance($element_data);
|
||||
|
||||
if (!$element) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->renderStyles($element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue CSS.
|
||||
*
|
||||
* Enqueue the post CSS file in Elementor.
|
||||
*
|
||||
* This method ensures that the post was actually built with elementor before
|
||||
* enqueueing the post CSS file.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access public
|
||||
*/
|
||||
public function enqueue()
|
||||
{
|
||||
if (!Plugin::$instance->db->isBuiltWithElementor($this->post_id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent::enqueue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add controls-stack style rules.
|
||||
*
|
||||
* Parse the CSS for all the elements inside any given controls stack.
|
||||
*
|
||||
* This method recursively renders the CSS for all the child elements in the stack.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @param ControlsStack $controls_stack The controls stack.
|
||||
* @param array $controls Controls array.
|
||||
* @param array $values Values array.
|
||||
* @param array $placeholders Placeholders.
|
||||
* @param array $replacements Replacements.
|
||||
* @param array $all_controls All controls.
|
||||
*/
|
||||
public function addControlsStackStyleRules(ControlsStack $controls_stack, array $controls, array $values, array $placeholders, array $replacements, array $all_controls = null)
|
||||
{
|
||||
parent::addControlsStackStyleRules($controls_stack, $controls, $values, $placeholders, $replacements, $all_controls);
|
||||
|
||||
if ($controls_stack instanceof ElementBase) {
|
||||
foreach ($controls_stack->getChildren() as $child_element) {
|
||||
$this->renderStyles($child_element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get enqueue dependencies.
|
||||
*
|
||||
* Retrieve the name of the stylesheet used by `wp_enqueue_style()`.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Name of the stylesheet.
|
||||
*/
|
||||
protected function getEnqueueDependencies()
|
||||
{
|
||||
return ['elementor-frontend'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get inline dependency.
|
||||
*
|
||||
* Retrieve the name of the stylesheet used by `wp_add_inline_style()`.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
*
|
||||
* @return string Name of the stylesheet.
|
||||
*/
|
||||
protected function getInlineDependency()
|
||||
{
|
||||
return 'elementor-frontend';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get file handle ID.
|
||||
*
|
||||
* Retrieve the handle ID for the post CSS file.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
*
|
||||
* @return string CSS file handle ID.
|
||||
*/
|
||||
protected function getFileHandleId()
|
||||
{
|
||||
return 'elementor-post-' . $this->post_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render styles.
|
||||
*
|
||||
* Parse the CSS for any given element.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access protected
|
||||
*
|
||||
* @param ElementBase $element The element.
|
||||
*/
|
||||
protected function renderStyles(ElementBase $element)
|
||||
{
|
||||
/**
|
||||
* Before element parse CSS.
|
||||
*
|
||||
* Fires before the CSS of the element is parsed.
|
||||
*
|
||||
* @since 1.2.0
|
||||
*
|
||||
* @param Post $this The post CSS file.
|
||||
* @param ElementBase $element The element.
|
||||
*/
|
||||
do_action('elementor/element/before_parse_css', $this, $element);
|
||||
|
||||
$element_settings = $element->getSettings();
|
||||
|
||||
$this->addControlsStackStyleRules(
|
||||
$element,
|
||||
$element->getStyleControls(null, $element->getParsedDynamicSettings()),
|
||||
$element_settings,
|
||||
['{{ID}}', '{{WRAPPER}}', '{{HOVER}}'],
|
||||
[$element->getId(), $this->getElementUniqueSelector($element), $this->getTransformHoverSelector($element)]
|
||||
);
|
||||
|
||||
/**
|
||||
* After element parse CSS.
|
||||
*
|
||||
* Fires after the CSS of the element is parsed.
|
||||
*
|
||||
* @since 1.2.0
|
||||
*
|
||||
* @param Post $this The post CSS file.
|
||||
* @param ElementBase $element The element.
|
||||
*/
|
||||
do_action('elementor/element/parse_css', $this, $element);
|
||||
}
|
||||
}
|
||||
8
modules/creativeelements/core/files/index.php
Normal file
8
modules/creativeelements/core/files/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../');
|
||||
die;
|
||||
129
modules/creativeelements/core/files/manager.php
Normal file
129
modules/creativeelements/core/files/manager.php
Normal file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXFilesXBase as Base;
|
||||
use CE\CoreXFilesXCSSXGlobalCSS as GlobalCSS;
|
||||
use CE\CoreXFilesXCSSXPost as PostCSS;
|
||||
use CE\CoreXResponsiveXFilesXFrontend as Frontend;
|
||||
|
||||
/**
|
||||
* Elementor files manager.
|
||||
*
|
||||
* Elementor files manager handler class is responsible for creating files.
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
class CoreXFilesXManager
|
||||
{
|
||||
/**
|
||||
* Files manager constructor.
|
||||
*
|
||||
* Initializing the Elementor files manager.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->registerActions();
|
||||
}
|
||||
|
||||
/**
|
||||
* On post delete.
|
||||
*
|
||||
* Delete post CSS immediately after a post is deleted from the database.
|
||||
*
|
||||
* Fired by `deleted_post` action.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $post_id Post ID.
|
||||
*/
|
||||
public function onDeletePost($post_id)
|
||||
{
|
||||
if (!Utils::isPostSupport($post_id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$css_file = new PostCSS($post_id);
|
||||
|
||||
$css_file->delete();
|
||||
}
|
||||
|
||||
// public function onExportPostMeta($skip, $meta_key)
|
||||
|
||||
/**
|
||||
* Clear cache.
|
||||
*
|
||||
* Delete all meta containing files data. And delete the actual
|
||||
* files from the upload directory.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access public
|
||||
*/
|
||||
public function clearCache()
|
||||
{
|
||||
if (\Shop::getContext() == \Shop::CONTEXT_ALL) {
|
||||
\Configuration::deleteByName(GlobalCSS::META_KEY);
|
||||
\Configuration::deleteByName(Frontend::META_KEY);
|
||||
} else {
|
||||
\Configuration::deleteFromContext(GlobalCSS::META_KEY);
|
||||
\Configuration::deleteFromContext(Frontend::META_KEY);
|
||||
}
|
||||
|
||||
$db = \Db::getInstance();
|
||||
$table = _DB_PREFIX_ . 'ce_meta';
|
||||
|
||||
foreach (\Shop::getContextListShopID() as $id_shop) {
|
||||
$id_shop = (int) $id_shop;
|
||||
$id = sprintf('%02d', $id_shop);
|
||||
$meta_key = $db->escape(PostCSS::META_KEY);
|
||||
|
||||
$db->execute("DELETE FROM $table WHERE id LIKE '%$id' AND name = '$meta_key'");
|
||||
|
||||
// Delete files.
|
||||
$path = Base::getBaseUploadsDir() . Base::DEFAULT_FILES_DIR;
|
||||
|
||||
foreach (glob("{$path}*$id.css", GLOB_NOSORT) as $file_path) {
|
||||
\Tools::deleteFile($file_path);
|
||||
}
|
||||
foreach (glob("{$path}$id_shop-*.css", GLOB_NOSORT) as $file_path) {
|
||||
\Tools::deleteFile($file_path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor clear files.
|
||||
*
|
||||
* Fires after Elementor clears files
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
do_action('elementor/core/files/clear_cache');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register actions.
|
||||
*
|
||||
* Register filters and actions for the files manager.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access private
|
||||
*/
|
||||
private function registerActions()
|
||||
{
|
||||
add_action('deleted_post', [$this, 'on_delete_post']);
|
||||
// add_filter('wxr_export_skip_postmeta', [$this, 'on_export_post_meta'], 10, 2);
|
||||
}
|
||||
}
|
||||
16
modules/creativeelements/core/index.php
Normal file
16
modules/creativeelements/core/index.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../');
|
||||
die;
|
||||
129
modules/creativeelements/core/modules-manager.php
Normal file
129
modules/creativeelements/core/modules-manager.php
Normal file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXBaseXModule as Module;
|
||||
|
||||
/**
|
||||
* Elementor modules manager.
|
||||
*
|
||||
* Elementor modules manager handler class is responsible for registering and
|
||||
* managing Elementor modules.
|
||||
*
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class CoreXModulesManager
|
||||
{
|
||||
/**
|
||||
* Registered modules.
|
||||
*
|
||||
* Holds the list of all the registered modules.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $modules = [];
|
||||
|
||||
/**
|
||||
* Modules manager constructor.
|
||||
*
|
||||
* Initializing the Elementor modules manager.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$modules_namespace_prefix = $this->getModulesNamespacePrefix();
|
||||
|
||||
foreach ($this->getModulesNames() as $module_name) {
|
||||
$class_name = str_replace('-', ' ', $module_name);
|
||||
|
||||
$class_name = str_replace(' ', '', ucwords($class_name));
|
||||
|
||||
$class_name = $modules_namespace_prefix . '\ModulesX' . $class_name . 'XModule';
|
||||
|
||||
/** @var Module $class_name */
|
||||
if ($class_name::isActive()) {
|
||||
$this->modules[$module_name] = $class_name::instance();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get modules names.
|
||||
*
|
||||
* Retrieve the modules names.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string[] Modules names.
|
||||
*/
|
||||
public function getModulesNames()
|
||||
{
|
||||
return [
|
||||
'history',
|
||||
'library',
|
||||
'dynamic-tags',
|
||||
'page-templates',
|
||||
'catalog',
|
||||
'creative',
|
||||
'fonts-manager',
|
||||
'custom-css',
|
||||
'motion-effects',
|
||||
'visibility',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get modules.
|
||||
*
|
||||
* Retrieve all the registered modules or a specific module.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $module_name Module name.
|
||||
*
|
||||
* @return null|Module|Module[] All the registered modules or a specific module.
|
||||
*/
|
||||
public function getModules($module_name)
|
||||
{
|
||||
if ($module_name) {
|
||||
if (isset($this->modules[$module_name])) {
|
||||
return $this->modules[$module_name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get modules namespace prefix.
|
||||
*
|
||||
* Retrieve the modules namespace prefix.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return string Modules namespace prefix.
|
||||
*/
|
||||
protected function getModulesNamespacePrefix()
|
||||
{
|
||||
return 'CE';
|
||||
}
|
||||
}
|
||||
157
modules/creativeelements/core/responsive/files/frontend.php
Normal file
157
modules/creativeelements/core/responsive/files/frontend.php
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXFilesXBase as Base;
|
||||
use CE\CoreXResponsiveXResponsive as Responsive;
|
||||
|
||||
class CoreXResponsiveXFilesXFrontend extends Base
|
||||
{
|
||||
const META_KEY = 'elementor-custom-breakpoints-files';
|
||||
|
||||
private $template_file;
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct($file_name, $template_file = null)
|
||||
{
|
||||
$this->template_file = $template_file;
|
||||
|
||||
parent::__construct($file_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*/
|
||||
public function parseContent()
|
||||
{
|
||||
$breakpoints = Responsive::getBreakpoints();
|
||||
|
||||
$breakpoints_keys = array_keys($breakpoints);
|
||||
|
||||
$file_content = call_user_func('file_get_contents', $this->template_file);
|
||||
|
||||
$file_content = preg_replace_callback('/-width:\s*(767|768|1024|1025)px\s*\)/', function ($placeholder_data) use ($breakpoints_keys, $breakpoints) {
|
||||
$width = (int) $placeholder_data[1];
|
||||
$size = $width < 768 ? 'sm' : ($width < 1025 ? 'md' : 'lg');
|
||||
$breakpoint_index = array_search($size, $breakpoints_keys);
|
||||
|
||||
$is_max_point = 767 === $width || 1024 === $width;
|
||||
|
||||
if ($is_max_point) {
|
||||
$breakpoint_index++;
|
||||
}
|
||||
|
||||
$value = $breakpoints[$breakpoints_keys[$breakpoint_index]];
|
||||
|
||||
if ($is_max_point) {
|
||||
$value--;
|
||||
}
|
||||
|
||||
return "-width:{$value}px)";
|
||||
}, $file_content);
|
||||
|
||||
return $file_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load meta.
|
||||
*
|
||||
* Retrieve the file meta data.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function loadMeta()
|
||||
{
|
||||
$option = $this->loadMetaOption();
|
||||
|
||||
$file_meta_key = $this->getFileMetaKey();
|
||||
|
||||
if (empty($option[$file_meta_key])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $option[$file_meta_key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update meta.
|
||||
*
|
||||
* Update the file meta data.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access protected
|
||||
*
|
||||
* @param array $meta New meta data.
|
||||
*/
|
||||
protected function updateMeta($meta)
|
||||
{
|
||||
$option = $this->loadMetaOption();
|
||||
|
||||
$option[$this->getFileMetaKey()] = $meta;
|
||||
|
||||
update_option(static::META_KEY, $option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete meta.
|
||||
*
|
||||
* Delete the file meta data.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function deleteMeta()
|
||||
{
|
||||
$option = $this->loadMetaOption();
|
||||
|
||||
$file_meta_key = $this->getFileMetaKey();
|
||||
|
||||
if (isset($option[$file_meta_key])) {
|
||||
unset($option[$file_meta_key]);
|
||||
}
|
||||
|
||||
if ($option) {
|
||||
update_option(static::META_KEY, $option);
|
||||
} else {
|
||||
delete_option(static::META_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access private
|
||||
*/
|
||||
private function getFileMetaKey()
|
||||
{
|
||||
return pathinfo($this->getFileName(), PATHINFO_FILENAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access private
|
||||
*/
|
||||
private function loadMetaOption()
|
||||
{
|
||||
$option = get_option(static::META_KEY);
|
||||
|
||||
if (!$option) {
|
||||
$option = [];
|
||||
}
|
||||
|
||||
return $option;
|
||||
}
|
||||
}
|
||||
8
modules/creativeelements/core/responsive/files/index.php
Normal file
8
modules/creativeelements/core/responsive/files/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../../');
|
||||
die;
|
||||
8
modules/creativeelements/core/responsive/index.php
Normal file
8
modules/creativeelements/core/responsive/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../');
|
||||
die;
|
||||
192
modules/creativeelements/core/responsive/responsive.php
Normal file
192
modules/creativeelements/core/responsive/responsive.php
Normal file
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXResponsiveXFilesXFrontend as FrontendFile;
|
||||
|
||||
/**
|
||||
* Elementor responsive.
|
||||
*
|
||||
* Elementor responsive handler class is responsible for setting up Elementor
|
||||
* responsive breakpoints.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class CoreXResponsiveXResponsive
|
||||
{
|
||||
/**
|
||||
* The Elementor breakpoint prefix.
|
||||
*/
|
||||
const BREAKPOINT_OPTION_PREFIX = 'elementor_viewport_';
|
||||
|
||||
/**
|
||||
* Default breakpoints.
|
||||
*
|
||||
* Holds the default responsive breakpoints.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var array Default breakpoints.
|
||||
*/
|
||||
private static $default_breakpoints = [
|
||||
'xs' => 0,
|
||||
'sm' => 480,
|
||||
'md' => 768,
|
||||
'lg' => 1025,
|
||||
'xl' => 1440,
|
||||
'xxl' => 1600,
|
||||
];
|
||||
|
||||
/**
|
||||
* Editable breakpoint keys.
|
||||
*
|
||||
* Holds the editable breakpoint keys.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var array Editable breakpoint keys.
|
||||
*/
|
||||
private static $editable_breakpoints_keys = [
|
||||
'md',
|
||||
'lg',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get default breakpoints.
|
||||
*
|
||||
* Retrieve the default responsive breakpoints.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array Default breakpoints.
|
||||
*/
|
||||
public static function getDefaultBreakpoints()
|
||||
{
|
||||
return self::$default_breakpoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get editable breakpoints.
|
||||
*
|
||||
* Retrieve the editable breakpoints.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array Editable breakpoints.
|
||||
*/
|
||||
public static function getEditableBreakpoints()
|
||||
{
|
||||
return array_intersect_key(self::getBreakpoints(), array_flip(self::$editable_breakpoints_keys));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get breakpoints.
|
||||
*
|
||||
* Retrieve the responsive breakpoints.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array Responsive breakpoints.
|
||||
*/
|
||||
public static function getBreakpoints()
|
||||
{
|
||||
$self = __CLASS__;
|
||||
|
||||
return array_reduce(
|
||||
array_keys(self::$default_breakpoints),
|
||||
function ($new_array, $breakpoint_key) use ($self) {
|
||||
if (!in_array($breakpoint_key, $self::${'editable_breakpoints_keys'})) {
|
||||
$new_array[$breakpoint_key] = $self::${'default_breakpoints'}[$breakpoint_key];
|
||||
} else {
|
||||
$saved_option = get_option($self::BREAKPOINT_OPTION_PREFIX . $breakpoint_key);
|
||||
|
||||
$new_array[$breakpoint_key] = $saved_option ? (int) $saved_option : $self::${'default_breakpoints'}[$breakpoint_key];
|
||||
}
|
||||
|
||||
return $new_array;
|
||||
},
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function hasCustomBreakpoints()
|
||||
{
|
||||
return !!array_diff(self::$default_breakpoints, self::getBreakpoints());
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function getStylesheetTemplatesPath()
|
||||
{
|
||||
return _CE_PATH_ . 'views/css/';
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function compileStylesheetTemplates()
|
||||
{
|
||||
foreach (self::getStylesheetTemplates() as $file_name => $template_path) {
|
||||
$file = new FrontendFile($file_name, $template_path);
|
||||
|
||||
$file->update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.1.0
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
private static function getStylesheetTemplates()
|
||||
{
|
||||
// $templates_paths = glob(self::getStylesheetTemplatesPath() . '*.css');
|
||||
$stylesheet_path = self::getStylesheetTemplatesPath();
|
||||
$templates_paths = [
|
||||
"{$stylesheet_path}frontend.css",
|
||||
"{$stylesheet_path}frontend.min.css",
|
||||
"{$stylesheet_path}frontend-rtl.css",
|
||||
"{$stylesheet_path}frontend-rtl.min.css",
|
||||
];
|
||||
|
||||
$templates = [];
|
||||
$id_shop = (int) \Context::getContext()->shop->id;
|
||||
|
||||
foreach ($templates_paths as $template_path) {
|
||||
$file_name = "$id_shop-" . basename($template_path);
|
||||
|
||||
$templates[$file_name] = $template_path;
|
||||
}
|
||||
|
||||
return apply_filters('elementor/core/responsive/get_stylesheet_templates', $templates);
|
||||
}
|
||||
}
|
||||
8
modules/creativeelements/core/settings/base/index.php
Normal file
8
modules/creativeelements/core/settings/base/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../../');
|
||||
die;
|
||||
417
modules/creativeelements/core/settings/base/manager.php
Normal file
417
modules/creativeelements/core/settings/base/manager.php
Normal file
@@ -0,0 +1,417 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXCommonXModulesXAjaxXModule as Ajax;
|
||||
use CE\CoreXFilesXCSSXBase as Base;
|
||||
|
||||
/**
|
||||
* Elementor settings base manager.
|
||||
*
|
||||
* Elementor settings base manager handler class is responsible for registering
|
||||
* and managing Elementor settings base managers.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class CoreXSettingsXBaseXManager
|
||||
{
|
||||
/**
|
||||
* Models cache.
|
||||
*
|
||||
* Holds all the models.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
*
|
||||
* @var Model[]
|
||||
*/
|
||||
private $models_cache = [];
|
||||
|
||||
/**
|
||||
* Settings base manager constructor.
|
||||
*
|
||||
* Initializing Elementor settings base manager.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
add_action('elementor/editor/init', [$this, 'on_elementor_editor_init']);
|
||||
|
||||
add_action('elementor/ajax/register_actions', [$this, 'register_ajax_actions']);
|
||||
|
||||
$name = $this->getCssFileName();
|
||||
|
||||
add_action("elementor/css-file/{$name}/parse", [$this, 'add_settings_css_rules']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register ajax actions.
|
||||
*
|
||||
* Add new actions to handle data after an ajax requests returned.
|
||||
*
|
||||
* Fired by `elementor/ajax/register_actions` action.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param Ajax $ajax_manager
|
||||
*/
|
||||
public function registerAjaxActions($ajax_manager)
|
||||
{
|
||||
$name = $this->getName();
|
||||
$ajax_manager->registerAjaxAction("save_{$name}_settings", [$this, 'ajax_save_settings']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get model for config.
|
||||
*
|
||||
* Retrieve the model for settings configuration.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*
|
||||
* @return Model The model object.
|
||||
*/
|
||||
abstract public function getModelForConfig();
|
||||
|
||||
/**
|
||||
* Get manager name.
|
||||
*
|
||||
* Retrieve settings manager name.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function getName();
|
||||
|
||||
/**
|
||||
* Get model.
|
||||
*
|
||||
* Retrieve the model for any given model ID.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @param int $id Optional. Model ID. Default is `0`.
|
||||
*
|
||||
* @return Model The model.
|
||||
*/
|
||||
final public function getModel($id = 0)
|
||||
{
|
||||
$uid = "$id";
|
||||
|
||||
if (!isset($this->models_cache[$uid])) {
|
||||
$this->createModel($uid);
|
||||
}
|
||||
|
||||
return $this->models_cache[$uid];
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax request to save settings.
|
||||
*
|
||||
* Save settings using an ajax request.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $request Ajax request.
|
||||
*
|
||||
* @return array Ajax response data.
|
||||
*/
|
||||
final public function ajaxSaveSettings($request)
|
||||
{
|
||||
$data = $request['data'];
|
||||
|
||||
$id = 0;
|
||||
|
||||
if (!empty($request['id'])) {
|
||||
$id = $request['id'];
|
||||
}
|
||||
|
||||
$this->ajaxBeforeSaveSettings($data, $id);
|
||||
$this->saveSettings($data, $id);
|
||||
|
||||
$settings_name = $this->getName();
|
||||
|
||||
$success_response_data = [];
|
||||
|
||||
/**
|
||||
* Settings success response data.
|
||||
*
|
||||
* Filters the success response data when saving settings using ajax.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$settings_name`, refers to the settings name.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $success_response_data Success response data.
|
||||
* @param int $id Settings ID.
|
||||
* @param array $data Settings data.
|
||||
*/
|
||||
$success_response_data = apply_filters("elementor/settings/{$settings_name}/success_response_data", $success_response_data, $id, $data);
|
||||
|
||||
return $success_response_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save settings.
|
||||
*
|
||||
* Save settings to the database and update the CSS file.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $settings Settings.
|
||||
* @param int $id Optional. Post ID. Default is `0`.
|
||||
*/
|
||||
final public function saveSettings(array $settings, $id = 0)
|
||||
{
|
||||
$special_settings = $this->getSpecialSettingsNames();
|
||||
|
||||
$settings_to_save = $settings;
|
||||
|
||||
foreach ($special_settings as $special_setting) {
|
||||
if (isset($settings_to_save[$special_setting])) {
|
||||
unset($settings_to_save[$special_setting]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->saveSettingsToDb($settings_to_save, $id);
|
||||
|
||||
// Clear cache after save.
|
||||
if (isset($this->models_cache[$id])) {
|
||||
unset($this->models_cache[$id]);
|
||||
}
|
||||
|
||||
$css_file = $this->getCssFileForUpdate($id);
|
||||
|
||||
if ($css_file) {
|
||||
$css_file->update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add settings CSS rules.
|
||||
*
|
||||
* Add new CSS rules to the settings manager.
|
||||
*
|
||||
* Fired by `elementor/css-file/{$name}/parse` action.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @param Base $css_file The requested CSS file.
|
||||
*/
|
||||
public function addSettingsCssRules(Base $css_file)
|
||||
{
|
||||
$model = $this->getModelForCssFile($css_file);
|
||||
|
||||
$css_file->addControlsStackStyleRules(
|
||||
$model,
|
||||
$model->getStyleControls(),
|
||||
$model->getSettings(),
|
||||
['{{WRAPPER}}'],
|
||||
[$model->getCssWrapperSelector()]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* On Elementor init.
|
||||
*
|
||||
* Add editor template for the settings
|
||||
*
|
||||
* Fired by `elementor/init` action.
|
||||
*
|
||||
* @since 2.3.0
|
||||
* @access public
|
||||
*/
|
||||
public function onElementorEditorInit()
|
||||
{
|
||||
Plugin::$instance->common->addTemplate($this->getEditorTemplate(), 'text');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get saved settings.
|
||||
*
|
||||
* Retrieve the saved settings from the database.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
* @abstract
|
||||
*
|
||||
* @param int $id Post ID.
|
||||
*/
|
||||
abstract protected function getSavedSettings($id);
|
||||
|
||||
/**
|
||||
* Get CSS file name.
|
||||
*
|
||||
* Retrieve CSS file name for the settings base manager.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
* @abstract
|
||||
*/
|
||||
abstract protected function getCssFileName();
|
||||
|
||||
/**
|
||||
* Save settings to DB.
|
||||
*
|
||||
* Save settings to the database.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
* @abstract
|
||||
*
|
||||
* @param array $settings Settings.
|
||||
* @param int $id Post ID.
|
||||
*/
|
||||
abstract protected function saveSettingsToDb(array $settings, $id);
|
||||
|
||||
/**
|
||||
* Get model for CSS file.
|
||||
*
|
||||
* Retrieve the model for the CSS file.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
* @abstract
|
||||
*
|
||||
* @param Base $css_file The requested CSS file.
|
||||
*/
|
||||
abstract protected function getModelForCssFile(Base $css_file);
|
||||
|
||||
/**
|
||||
* Get CSS file for update.
|
||||
*
|
||||
* Retrieve the CSS file before updating it.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
* @abstract
|
||||
*
|
||||
* @param int $id Post ID.
|
||||
*/
|
||||
abstract protected function getCssFileForUpdate($id);
|
||||
|
||||
/**
|
||||
* Get special settings names.
|
||||
*
|
||||
* Retrieve the names of the special settings that are not saved as regular
|
||||
* settings. Those settings have a separate saving process.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Special settings names.
|
||||
*/
|
||||
protected function getSpecialSettingsNames()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax before saving settings.
|
||||
*
|
||||
* Validate the data before saving it and updating the data in the database.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $data Post data.
|
||||
* @param int $id Post ID.
|
||||
*/
|
||||
public function ajaxBeforeSaveSettings(array $data, $id)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the setting template content in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @param string $name Settings panel name.
|
||||
*/
|
||||
protected function printEditorTemplateContent($name)
|
||||
{
|
||||
?>
|
||||
<div class="elementor-panel-navigation">
|
||||
<# _.each( elementor.config.settings.<?= esc_html($name) ?>.tabs, function( tabTitle, tabSlug ) { #>
|
||||
<div class="elementor-panel-navigation-tab elementor-tab-control-{{ tabSlug }}" data-tab="{{ tabSlug }}">
|
||||
<a href="#">{{{ tabTitle }}}</a>
|
||||
</div>
|
||||
<# } ); #>
|
||||
</div>
|
||||
<div id="elementor-panel-<?= esc_attr($name) ?>-settings-controls"></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Create model.
|
||||
*
|
||||
* Create a new model object for any given model ID and store the object in
|
||||
* models cache property for later use.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
*
|
||||
* @param int $id Model ID.
|
||||
*/
|
||||
private function createModel($id)
|
||||
{
|
||||
$class_parts = explode('X', get_called_class());
|
||||
|
||||
array_splice($class_parts, count($class_parts) - 1, 1, 'Model');
|
||||
|
||||
$class_name = implode('X', $class_parts);
|
||||
|
||||
$this->models_cache[$id] = new $class_name([
|
||||
'id' => $id,
|
||||
'settings' => $this->getSavedSettings($id),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get editor template.
|
||||
*
|
||||
* Retrieve the final HTML for the editor.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
*
|
||||
* @return string Settings editor template.
|
||||
*/
|
||||
private function getEditorTemplate()
|
||||
{
|
||||
$name = $this->getName();
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
<script type="text/template" id="tmpl-elementor-panel-<?= esc_attr($name) ?>-settings">
|
||||
<?php $this->printEditorTemplateContent($name) ?>
|
||||
</script>
|
||||
<?php
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
}
|
||||
46
modules/creativeelements/core/settings/base/model.php
Normal file
46
modules/creativeelements/core/settings/base/model.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
/**
|
||||
* Elementor settings base model.
|
||||
*
|
||||
* Elementor settings base model handler class is responsible for registering
|
||||
* and managing Elementor settings base models.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class CoreXSettingsXBaseXModel extends ControlsStack
|
||||
{
|
||||
/**
|
||||
* Get CSS wrapper selector.
|
||||
*
|
||||
* Retrieve the wrapper selector for the current panel.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function getCssWrapperSelector();
|
||||
|
||||
/**
|
||||
* Get panel page settings.
|
||||
*
|
||||
* Retrieve the page setting for the current panel.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function getPanelPageSettings();
|
||||
}
|
||||
8
modules/creativeelements/core/settings/general/index.php
Normal file
8
modules/creativeelements/core/settings/general/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../../');
|
||||
die;
|
||||
223
modules/creativeelements/core/settings/general/manager.php
Normal file
223
modules/creativeelements/core/settings/general/manager.php
Normal file
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXFilesXCSSXBase as Base;
|
||||
use CE\CoreXFilesXCSSXGlobalCSS as GlobalCSS;
|
||||
use CE\CoreXSettingsXBaseXManager as BaseManager;
|
||||
use CE\CoreXSettingsXBaseXModel as BaseModel;
|
||||
use CE\CoreXSettingsXGeneralXModel as Model;
|
||||
|
||||
/**
|
||||
* Elementor general settings manager.
|
||||
*
|
||||
* Elementor general settings manager handler class is responsible for registering
|
||||
* and managing Elementor general settings managers.
|
||||
*
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class CoreXSettingsXGeneralXManager extends BaseManager
|
||||
{
|
||||
/**
|
||||
* Lightbox panel tab.
|
||||
*/
|
||||
const PANEL_TAB_LIGHTBOX = 'lightbox';
|
||||
|
||||
/**
|
||||
* Meta key for the general settings.
|
||||
*/
|
||||
const META_KEY = '_elementor_general_settings';
|
||||
|
||||
/**
|
||||
* General settings manager constructor.
|
||||
*
|
||||
* Initializing Elementor general settings manager.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->addPanelTabs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get manager name.
|
||||
*
|
||||
* Retrieve general settings manager name.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Manager name.
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'general';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get model for config.
|
||||
*
|
||||
* Retrieve the model for settings configuration.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return BaseModel The model object.
|
||||
*/
|
||||
public function getModelForConfig()
|
||||
{
|
||||
return $this->getModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get saved settings.
|
||||
*
|
||||
* Retrieve the saved settings from the site options.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @param int $id Post ID.
|
||||
*
|
||||
* @return array Saved settings.
|
||||
*/
|
||||
protected function getSavedSettings($id)
|
||||
{
|
||||
$model_controls = Model::getControlsList();
|
||||
|
||||
$settings = [];
|
||||
|
||||
foreach ($model_controls as $tab_name => $sections) {
|
||||
foreach ($sections as $section_name => $section_data) {
|
||||
foreach ($section_data['controls'] as $control_name => $control_data) {
|
||||
$saved_setting = get_option($control_name, null);
|
||||
|
||||
if (null !== $saved_setting) {
|
||||
$settings[$control_name] = get_option($control_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CSS file name.
|
||||
*
|
||||
* Retrieve CSS file name for the general settings manager.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
* @return string
|
||||
*
|
||||
* @return string CSS file name.
|
||||
*/
|
||||
protected function getCssFileName()
|
||||
{
|
||||
return 'global';
|
||||
}
|
||||
|
||||
/**
|
||||
* Save settings to DB.
|
||||
*
|
||||
* Save general settings to the database, as site options.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @param array $settings Settings.
|
||||
* @param int $id Post ID.
|
||||
*/
|
||||
protected function saveSettingsToDb(array $settings, $id)
|
||||
{
|
||||
$model_controls = Model::getControlsList();
|
||||
|
||||
$one_list_settings = [];
|
||||
|
||||
foreach ($model_controls as $tab_name => $sections) {
|
||||
foreach ($sections as $section_name => $section_data) {
|
||||
foreach ($section_data['controls'] as $control_name => $control_data) {
|
||||
if (isset($settings[$control_name])) {
|
||||
$one_list_control_name = str_replace('elementor_', '', $control_name);
|
||||
|
||||
$one_list_settings[$one_list_control_name] = $settings[$control_name];
|
||||
|
||||
update_option($control_name, $settings[$control_name]);
|
||||
} else {
|
||||
delete_option($control_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save all settings in one list for a future usage
|
||||
if (!empty($one_list_settings)) {
|
||||
update_option(self::META_KEY, $one_list_settings);
|
||||
} else {
|
||||
delete_option(self::META_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get model for CSS file.
|
||||
*
|
||||
* Retrieve the model for the CSS file.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @param Base $css_file The requested CSS file.
|
||||
*
|
||||
* @return BaseModel The model object.
|
||||
*/
|
||||
protected function getModelForCssFile(Base $css_file)
|
||||
{
|
||||
return $this->getModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CSS file for update.
|
||||
*
|
||||
* Retrieve the CSS file before updating the it.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @param int $id Post ID.
|
||||
*
|
||||
* @return GlobalCSS The global CSS file object.
|
||||
*/
|
||||
protected function getCssFileForUpdate($id)
|
||||
{
|
||||
$id_shop = (int) \Context::getContext()->shop->id;
|
||||
|
||||
return new GlobalCSS("$id_shop-global.css");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add panel tabs.
|
||||
*
|
||||
* Register new panel tab for the lightbox settings.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
*/
|
||||
private function addPanelTabs()
|
||||
{
|
||||
ControlsManager::addTab(self::PANEL_TAB_LIGHTBOX, __('Lightbox'));
|
||||
}
|
||||
}
|
||||
337
modules/creativeelements/core/settings/general/model.php
Normal file
337
modules/creativeelements/core/settings/general/model.php
Normal file
@@ -0,0 +1,337 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXSettingsXBaseXModel as BaseModel;
|
||||
use CE\CoreXSettingsXGeneralXManager as Manager;
|
||||
|
||||
/**
|
||||
* Elementor global settings model.
|
||||
*
|
||||
* Elementor global settings model handler class is responsible for registering
|
||||
* and managing Elementor global settings models.
|
||||
*
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class CoreXSettingsXGeneralXModel extends BaseModel
|
||||
{
|
||||
/**
|
||||
* Get model name.
|
||||
*
|
||||
* Retrieve global settings model name.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Model name.
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'global-settings';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CSS wrapper selector.
|
||||
*
|
||||
* Retrieve the wrapper selector for the global settings model.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return string CSS wrapper selector.
|
||||
*/
|
||||
|
||||
public function getCssWrapperSelector()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get panel page settings.
|
||||
*
|
||||
* Retrieve the panel setting for the global settings model.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return array {
|
||||
* Panel settings.
|
||||
*
|
||||
* @type string $title The panel title.
|
||||
* @type array $menu The panel menu.
|
||||
* }
|
||||
*/
|
||||
public function getPanelPageSettings()
|
||||
{
|
||||
return [
|
||||
'title' => __('Global Settings'),
|
||||
'menu' => [
|
||||
'icon' => 'fa fa-cogs',
|
||||
'beforeItem' => 'elementor-settings',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get controls list.
|
||||
*
|
||||
* Retrieve the global settings model controls list.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array Controls list.
|
||||
*/
|
||||
public static function getControlsList()
|
||||
{
|
||||
return [
|
||||
ControlsManager::TAB_STYLE => [
|
||||
'style' => [
|
||||
'label' => __('Style'),
|
||||
'controls' => [
|
||||
'elementor_default_generic_fonts' => [
|
||||
'label' => __('Default Generic Fonts'),
|
||||
'type' => ControlsManager::TEXT,
|
||||
'default' => 'Sans-serif',
|
||||
'description' => __('The list of fonts used if the chosen font is not available.'),
|
||||
'label_block' => true,
|
||||
],
|
||||
'elementor_container_width' => [
|
||||
'label' => __('Content Width') . ' (px)',
|
||||
'type' => ControlsManager::NUMBER,
|
||||
'min' => 300,
|
||||
'description' => __('Sets the default width of the content area (Default: 1140)'),
|
||||
'selectors' => [
|
||||
'.elementor-section.elementor-section-boxed > .elementor-container' => 'max-width: {{VALUE}}px',
|
||||
],
|
||||
],
|
||||
'elementor_space_between_widgets' => [
|
||||
'label' => __('Widgets Space') . ' (px)',
|
||||
'type' => ControlsManager::NUMBER,
|
||||
'min' => 0,
|
||||
'placeholder' => '20',
|
||||
'description' => __('Sets the default space between widgets (Default: 20)'),
|
||||
'selectors' => [
|
||||
'.elementor-widget:not(:last-child)' => 'margin-bottom: {{VALUE}}px',
|
||||
],
|
||||
],
|
||||
'elementor_stretched_section_container' => [
|
||||
'label' => __('Stretched Section Fit To'),
|
||||
'type' => ControlsManager::TEXT,
|
||||
'placeholder' => 'body',
|
||||
'description' => __('Enter parent element selector to which stretched sections will fit to (e.g. #primary / .wrapper / main etc). Leave blank to fit to page width.'),
|
||||
'label_block' => true,
|
||||
'frontend_available' => true,
|
||||
],
|
||||
'elementor_page_title_selector' => [
|
||||
'label' => __('Page Title Selector'),
|
||||
'type' => ControlsManager::TEXTAREA,
|
||||
'rows' => 1,
|
||||
'placeholder' => 'header.page-header',
|
||||
'description' => sprintf(
|
||||
__("You can hide the title at document settings. This works for themes that have ”%s” selector. If your theme's selector is different, please enter it above."),
|
||||
'header.page-header'
|
||||
),
|
||||
'label_block' => true,
|
||||
],
|
||||
'elementor_page_wrapper_selector' => [
|
||||
'label' => __('Content Wrapper Selector'),
|
||||
'type' => ControlsManager::TEXTAREA,
|
||||
'rows' => 3,
|
||||
'placeholder' => '#content, #wrapper, #wrapper .container',
|
||||
'description' => sprintf(
|
||||
__("You can clear margin, padding, max-width from content wrapper at document settings. This works for themes that have ”%s” selector. If your theme's selector is different, please enter it above."),
|
||||
'#content, #wrapper, #wrapper .container'
|
||||
),
|
||||
'label_block' => true,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
Manager::PANEL_TAB_LIGHTBOX => [
|
||||
'lightbox' => [
|
||||
'label' => __('Lightbox'),
|
||||
'controls' => [
|
||||
'elementor_global_image_lightbox' => [
|
||||
'label' => __('Image Lightbox'),
|
||||
'type' => ControlsManager::SWITCHER,
|
||||
'return_value' => '1',
|
||||
'description' => __('Open all image links in a lightbox popup window. The lightbox will automatically work on any link that leads to an image file.'),
|
||||
'frontend_available' => true,
|
||||
],
|
||||
'elementor_enable_lightbox_in_editor' => [
|
||||
'label' => __('Enable In Editor'),
|
||||
'type' => ControlsManager::SWITCHER,
|
||||
'default' => 'yes',
|
||||
'frontend_available' => true,
|
||||
],
|
||||
'elementor_lightbox_enable_counter' => [
|
||||
'label' => __('Counter'),
|
||||
'type' => ControlsManager::SWITCHER,
|
||||
'default' => 'yes',
|
||||
'frontend_available' => true,
|
||||
],
|
||||
'elementor_lightbox_enable_zoom' => [
|
||||
'label' => __('Zoom'),
|
||||
'type' => ControlsManager::SWITCHER,
|
||||
'default' => 'yes',
|
||||
'frontend_available' => true,
|
||||
],
|
||||
'elementor_lightbox_title_src' => [
|
||||
'label' => __('Title'),
|
||||
'type' => ControlsManager::SELECT,
|
||||
'options' => [
|
||||
'' => __('None'),
|
||||
'title' => __('Title'),
|
||||
'caption' => __('Caption'),
|
||||
'alt' => __('Alt'),
|
||||
// 'description' => __('Description'),
|
||||
],
|
||||
'default' => 'title',
|
||||
'frontend_available' => true,
|
||||
],
|
||||
'elementor_lightbox_description_src' => [
|
||||
'label' => __('Description'),
|
||||
'type' => ControlsManager::SELECT,
|
||||
'options' => [
|
||||
'' => __('None'),
|
||||
'title' => __('Title'),
|
||||
'caption' => __('Caption'),
|
||||
'alt' => __('Alt'),
|
||||
// 'description' => __('Description'),
|
||||
],
|
||||
'default' => 'caption',
|
||||
'frontend_available' => true,
|
||||
],
|
||||
'elementor_lightbox_color' => [
|
||||
'label' => __('Background Color'),
|
||||
'type' => ControlsManager::COLOR,
|
||||
'selectors' => [
|
||||
'.elementor-lightbox' => 'background-color: {{VALUE}}',
|
||||
],
|
||||
],
|
||||
'elementor_lightbox_ui_color' => [
|
||||
'label' => __('UI Color'),
|
||||
'type' => ControlsManager::COLOR,
|
||||
'selectors' => [
|
||||
'.elementor-lightbox' => '--lightbox-ui-color: {{VALUE}}',
|
||||
],
|
||||
],
|
||||
'elementor_lightbox_ui_color_hover' => [
|
||||
'label' => __('UI Hover Color'),
|
||||
'type' => ControlsManager::COLOR,
|
||||
'selectors' => [
|
||||
'.elementor-lightbox' => '--lightbox-ui-color-hover: {{VALUE}}',
|
||||
],
|
||||
],
|
||||
'elementor_lightbox_text_color' => [
|
||||
'label' => __('Text Color'),
|
||||
'type' => ControlsManager::COLOR,
|
||||
'selectors' => [
|
||||
'.elementor-lightbox' => '--lightbox-text-color: {{VALUE}}',
|
||||
],
|
||||
],
|
||||
'lightbox_box_shadow_type' => [
|
||||
'label' => _x('Box Shadow', 'Box Shadow Control'),
|
||||
'type' => ControlsManager::POPOVER_TOGGLE,
|
||||
'return_value' => 'yes',
|
||||
'render_type' => 'ui',
|
||||
],
|
||||
'lightbox_box_shadow' => [
|
||||
'label' => _x('Box Shadow', 'Box Shadow Control'),
|
||||
'type' => ControlsManager::BOX_SHADOW,
|
||||
'default' => [
|
||||
'horizontal' => 0,
|
||||
'vertical' => 0,
|
||||
'blur' => 10,
|
||||
'spread' => 0,
|
||||
'color' => 'rgba(0,0,0,0.5)',
|
||||
],
|
||||
'selectors' => [
|
||||
'.elementor-lightbox .elementor-lightbox-image' => 'box-shadow: {{HORIZONTAL}}px {{VERTICAL}}px {{BLUR}}px {{SPREAD}}px {{COLOR}} {{lightbox_box_shadow_position.VALUE}};',
|
||||
],
|
||||
'condition' => [
|
||||
'lightbox_box_shadow_type!' => '',
|
||||
],
|
||||
'popover' => [
|
||||
'start' => true,
|
||||
],
|
||||
],
|
||||
'lightbox_box_shadow_position' => [
|
||||
'label' => 'Position',
|
||||
'type' => ControlsManager::SELECT,
|
||||
'options' => [
|
||||
' ' => 'Outline',
|
||||
'inset' => 'Inset',
|
||||
],
|
||||
'default' => ' ',
|
||||
'render_type' => 'ui',
|
||||
'condition' => [
|
||||
'lightbox_box_shadow_type!' => '',
|
||||
],
|
||||
'popover' => [
|
||||
'end' => true,
|
||||
],
|
||||
],
|
||||
'lightbox_icons_size' => [
|
||||
'label' => __('Toolbar Icons Size'),
|
||||
'type' => ControlsManager::SLIDER,
|
||||
'selectors' => [
|
||||
'.elementor-lightbox' => '--lightbox-header-icons-size: {{SIZE}}{{UNIT}}',
|
||||
],
|
||||
'separator' => 'before',
|
||||
],
|
||||
'lightbox_slider_icons_size' => [
|
||||
'label' => __('Navigation Icons Size'),
|
||||
'type' => ControlsManager::SLIDER,
|
||||
'selectors' => [
|
||||
'.elementor-lightbox' => '--lightbox-navigation-icons-size: {{SIZE}}{{UNIT}}',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Register model controls.
|
||||
*
|
||||
* Used to add new controls to the global settings model.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function _registerControls()
|
||||
{
|
||||
$controls_list = self::getControlsList();
|
||||
|
||||
foreach ($controls_list as $tab_name => $sections) {
|
||||
foreach ($sections as $section_name => $section_data) {
|
||||
$this->startControlsSection(
|
||||
$section_name,
|
||||
[
|
||||
'label' => $section_data['label'],
|
||||
'tab' => $tab_name,
|
||||
]
|
||||
);
|
||||
|
||||
foreach ($section_data['controls'] as $control_name => $control_data) {
|
||||
$this->addControl($control_name, $control_data);
|
||||
}
|
||||
|
||||
$this->endControlsSection();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
modules/creativeelements/core/settings/index.php
Normal file
8
modules/creativeelements/core/settings/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../');
|
||||
die;
|
||||
196
modules/creativeelements/core/settings/manager.php
Normal file
196
modules/creativeelements/core/settings/manager.php
Normal file
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXSettingsXBaseXManager as BaseManager;
|
||||
|
||||
/**
|
||||
* Elementor settings manager.
|
||||
*
|
||||
* Elementor settings manager handler class is responsible for registering and
|
||||
* managing Elementor settings managers.
|
||||
*
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class CoreXSettingsXManager
|
||||
{
|
||||
/**
|
||||
* Settings managers.
|
||||
*
|
||||
* Holds all the registered settings managers.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
*
|
||||
* @var BaseManager[]
|
||||
*/
|
||||
private static $settings_managers = [];
|
||||
|
||||
/**
|
||||
* Builtin settings managers names.
|
||||
*
|
||||
* Holds the names for builtin Elementor settings managers.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $builtin_settings_managers_names = ['page', 'general'];
|
||||
|
||||
/**
|
||||
* Add settings manager.
|
||||
*
|
||||
* Register a single settings manager to the registered settings managers.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param BaseManager $manager Settings manager.
|
||||
*/
|
||||
public static function addSettingsManager(BaseManager $manager)
|
||||
{
|
||||
self::$settings_managers[$manager->getName()] = $manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get settings managers.
|
||||
*
|
||||
* Retrieve registered settings manager(s).
|
||||
*
|
||||
* If no parameter passed, it will retrieve all the settings managers. For
|
||||
* any given parameter it will retrieve a single settings manager if one
|
||||
* exist, or `null` otherwise.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param string $manager_name Optional. Settings manager name. Default is
|
||||
* null.
|
||||
*
|
||||
* @return BaseManager|BaseManager[] Single settings manager, if it exists,
|
||||
* null if it doesn't exists, or the all
|
||||
* the settings managers if no parameter
|
||||
* defined.
|
||||
*/
|
||||
public static function getSettingsManagers($manager_name = null)
|
||||
{
|
||||
if ($manager_name) {
|
||||
if (isset(self::$settings_managers[$manager_name])) {
|
||||
return self::$settings_managers[$manager_name];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return self::$settings_managers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register default settings managers.
|
||||
*
|
||||
* Register builtin Elementor settings managers.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
private static function registerDefaultSettingsManagers()
|
||||
{
|
||||
foreach (self::$builtin_settings_managers_names as $manager_name) {
|
||||
$manager_class = call_user_func('substr', __CLASS__, 0, strrpos(__CLASS__, 'X') + 1) . call_user_func('ucfirst', $manager_name) . 'XManager';
|
||||
|
||||
self::addSettingsManager(new $manager_class());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get settings managers config.
|
||||
*
|
||||
* Retrieve the settings managers configuration.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array The settings managers configuration.
|
||||
*/
|
||||
public static function getSettingsManagersConfig()
|
||||
{
|
||||
$config = [];
|
||||
|
||||
// $user_can = Plugin::instance()->role_manager->userCan('design');
|
||||
|
||||
foreach (self::$settings_managers as $name => $manager) {
|
||||
$settings_model = $manager->getModelForConfig();
|
||||
|
||||
$tabs = $settings_model->getTabsControls();
|
||||
|
||||
// if (!$user_can) {
|
||||
// unset($tabs['style']);
|
||||
// }
|
||||
|
||||
$config[$name] = [
|
||||
'name' => $manager->getName(),
|
||||
'panelPage' => $settings_model->getPanelPageSettings(),
|
||||
'cssWrapperSelector' => $settings_model->getCssWrapperSelector(),
|
||||
'controls' => $settings_model->getControls(),
|
||||
'tabs' => $tabs,
|
||||
'settings' => $settings_model->getSettings(),
|
||||
];
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get settings frontend config.
|
||||
*
|
||||
* Retrieve the settings managers frontend configuration.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array The settings managers frontend configuration.
|
||||
*/
|
||||
public static function getSettingsFrontendConfig()
|
||||
{
|
||||
$config = [];
|
||||
|
||||
foreach (self::$settings_managers as $name => $manager) {
|
||||
$settings_model = $manager->getModelForConfig();
|
||||
|
||||
if ($settings_model) {
|
||||
$config[$name] = $settings_model->getFrontendSettings();
|
||||
}
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run settings managers.
|
||||
*
|
||||
* Register builtin Elementor settings managers.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
self::registerDefaultSettingsManagers();
|
||||
}
|
||||
}
|
||||
8
modules/creativeelements/core/settings/page/index.php
Normal file
8
modules/creativeelements/core/settings/page/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../../');
|
||||
die;
|
||||
310
modules/creativeelements/core/settings/page/manager.php
Normal file
310
modules/creativeelements/core/settings/page/manager.php
Normal file
@@ -0,0 +1,310 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXFilesXCSSXBase as Base;
|
||||
use CE\CoreXFilesXCSSXPost as Post;
|
||||
use CE\CoreXFilesXCSSXPostPreview as PostPreview;
|
||||
use CE\CoreXSettingsXBaseXManager as BaseManager;
|
||||
use CE\CoreXSettingsXBaseXModel as BaseModel;
|
||||
use CE\CoreXSettingsXManager as SettingsManager;
|
||||
use CE\CoreXUtilsXExceptions as Exceptions;
|
||||
|
||||
/**
|
||||
* Elementor page settings manager.
|
||||
*
|
||||
* Elementor page settings manager handler class is responsible for registering
|
||||
* and managing Elementor page settings managers.
|
||||
*
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class CoreXSettingsXPageXManager extends BaseManager
|
||||
{
|
||||
/**
|
||||
* Meta key for the page settings.
|
||||
*/
|
||||
const META_KEY = '_elementor_page_settings';
|
||||
|
||||
/**
|
||||
* Get manager name.
|
||||
*
|
||||
* Retrieve page settings manager name.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Manager name.
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'page';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get model for config.
|
||||
*
|
||||
* Retrieve the model for settings configuration.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return BaseModel The model object.
|
||||
*/
|
||||
public function getModelForConfig()
|
||||
{
|
||||
if (!is_singular() && !Plugin::$instance->editor->isEditMode()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Plugin::$instance->editor->isEditMode()) {
|
||||
$post_id = Plugin::$instance->editor->getPostId();
|
||||
$document = Plugin::$instance->documents->getDocOrAutoSave($post_id);
|
||||
} else {
|
||||
$post_id = get_the_ID();
|
||||
$document = Plugin::$instance->documents->getDocForFrontend($post_id);
|
||||
}
|
||||
|
||||
if (!$document) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$model = $this->getModel($document->getPost()->ID);
|
||||
|
||||
if ($document->isAutosave()) {
|
||||
$model->setSettings('post_status', $document->getMainPost()->post_status);
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax before saving settings.
|
||||
*
|
||||
* Validate the data before saving it and updating the data in the database.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $data Post data.
|
||||
* @param int $id Post ID.
|
||||
*
|
||||
* @throws \Exception If invalid post returned using the `$id`.
|
||||
* @throws \Exception If current user don't have permissions to edit the post.
|
||||
*/
|
||||
public function ajaxBeforeSaveSettings(array $data, $id)
|
||||
{
|
||||
$post = get_post($id);
|
||||
|
||||
if (empty($post)) {
|
||||
throw new \Exception('Invalid post.', Exceptions::NOT_FOUND);
|
||||
}
|
||||
|
||||
if (!current_user_can('edit', $id)) {
|
||||
throw new \Exception('Access denied.', Exceptions::FORBIDDEN);
|
||||
}
|
||||
|
||||
// Avoid save empty post title.
|
||||
if (!empty($data['post_title'])) {
|
||||
$post->post_title = $data['post_title'];
|
||||
}
|
||||
|
||||
// if (isset($data['post_excerpt']) && post_type_supports($post->post_type, 'excerpt')) {
|
||||
// $post->post_excerpt = $data['post_excerpt'];
|
||||
// }
|
||||
|
||||
if (isset($data['post_status'])) {
|
||||
// $this->savePostStatus($id, $data['post_status']);
|
||||
// unset($post->post_status);
|
||||
$post->post_status = $data['post_status'];
|
||||
}
|
||||
|
||||
wp_update_post($post);
|
||||
|
||||
// Check updated status
|
||||
// if (DB::STATUS_PUBLISH === get_post_status($id))
|
||||
$autosave = wp_get_post_autosave($post->ID);
|
||||
|
||||
if ($autosave) {
|
||||
wp_delete_post_revision($autosave->ID);
|
||||
}
|
||||
|
||||
if (isset($data['post_featured_image'])) {
|
||||
if (empty($data['post_featured_image']['url'])) {
|
||||
delete_post_meta($post->ID, '_og_image');
|
||||
} else {
|
||||
update_post_meta($post->ID, '_og_image', $data['post_featured_image']['url']);
|
||||
}
|
||||
}
|
||||
|
||||
if (Utils::isCptCustomTemplatesSupported($post)) {
|
||||
$template = get_post_meta($post->ID, '_wp_page_template', true);
|
||||
|
||||
if (isset($data['template'])) {
|
||||
$template = $data['template'];
|
||||
}
|
||||
|
||||
if (empty($template)) {
|
||||
$template = 'default';
|
||||
}
|
||||
|
||||
update_post_meta($post->ID, '_wp_page_template', $template);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save settings to DB.
|
||||
*
|
||||
* Save page settings to the database, as post meta data.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @param array $settings Settings.
|
||||
* @param int $id Post ID.
|
||||
*/
|
||||
protected function saveSettingsToDb(array $settings, $id)
|
||||
{
|
||||
if (!empty($settings)) {
|
||||
update_post_meta($id, self::META_KEY, $settings);
|
||||
} else {
|
||||
delete_post_meta($id, self::META_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CSS file for update.
|
||||
*
|
||||
* Retrieve the CSS file before updating it.
|
||||
*
|
||||
* This method overrides the parent method to disallow updating CSS files for pages.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @param int $id Post ID.
|
||||
*
|
||||
* @return false Disallow The updating CSS files for pages.
|
||||
*/
|
||||
protected function getCssFileForUpdate($id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get saved settings.
|
||||
*
|
||||
* Retrieve the saved settings from the post meta.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @param int $id Post ID.
|
||||
*
|
||||
* @return array Saved settings.
|
||||
*/
|
||||
protected function getSavedSettings($id)
|
||||
{
|
||||
$settings = get_post_meta($id, self::META_KEY, true);
|
||||
|
||||
if (!$settings) {
|
||||
$settings = [];
|
||||
}
|
||||
|
||||
if (Utils::isCptCustomTemplatesSupported(get_post($id))) {
|
||||
$saved_template = get_post_meta($id, '_wp_page_template', true);
|
||||
|
||||
if ($saved_template) {
|
||||
$settings['template'] = $saved_template;
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CSS file name.
|
||||
*
|
||||
* Retrieve CSS file name for the page settings manager.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @return string CSS file name.
|
||||
*/
|
||||
protected function getCssFileName()
|
||||
{
|
||||
return 'post';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get model for CSS file.
|
||||
*
|
||||
* Retrieve the model for the CSS file.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @param Base $css_file The requested CSS file.
|
||||
*
|
||||
* @return BaseModel The model object.
|
||||
*/
|
||||
protected function getModelForCssFile(Base $css_file)
|
||||
{
|
||||
if (!$css_file instanceof Post) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$post_id = $css_file->getPostId();
|
||||
|
||||
if ($css_file instanceof PostPreview) {
|
||||
$autosave = Utils::getPostAutosave($post_id);
|
||||
if ($autosave) {
|
||||
$post_id = $autosave->ID;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->getModel($post_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get special settings names.
|
||||
*
|
||||
* Retrieve the names of the special settings that are not saved as regular
|
||||
* settings. Those settings have a separate saving process.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Special settings names.
|
||||
*/
|
||||
protected function getSpecialSettingsNames()
|
||||
{
|
||||
return [
|
||||
'id',
|
||||
'post_title',
|
||||
'post_status',
|
||||
'template',
|
||||
'post_excerpt',
|
||||
'post_featured_image',
|
||||
// Do not save:
|
||||
'action',
|
||||
'_nonce',
|
||||
'section_page_settings',
|
||||
'section_page_style',
|
||||
'section_custom_css',
|
||||
'template_default_description',
|
||||
'template_canvas_description',
|
||||
];
|
||||
}
|
||||
|
||||
// public function savePostStatus($post_id, $status)
|
||||
}
|
||||
193
modules/creativeelements/core/settings/page/model.php
Normal file
193
modules/creativeelements/core/settings/page/model.php
Normal file
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
use CE\CoreXSettingsXBaseXModel as BaseModel;
|
||||
|
||||
/**
|
||||
* Elementor page settings model.
|
||||
*
|
||||
* Elementor page settings model handler class is responsible for registering
|
||||
* and managing Elementor page settings models.
|
||||
*
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class CoreXSettingsXPageXModel extends BaseModel
|
||||
{
|
||||
/**
|
||||
* Wrapper post object.
|
||||
*
|
||||
* Holds an instance of `WPPost` containing the post object.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @var WPPost
|
||||
*/
|
||||
private $post;
|
||||
|
||||
/**
|
||||
* @var WPPost
|
||||
*/
|
||||
private $post_parent;
|
||||
|
||||
/**
|
||||
* Model constructor.
|
||||
*
|
||||
* Initializing Elementor page settings model.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $data Optional. Model data. Default is an empty array.
|
||||
*/
|
||||
public function __construct(array $data = [])
|
||||
{
|
||||
$this->post = get_post($data['id']);
|
||||
|
||||
if (!$this->post) {
|
||||
$this->post = new WPPost((object) []);
|
||||
}
|
||||
|
||||
if (wp_is_post_revision($this->post->ID)) {
|
||||
$this->post_parent = get_post($this->post->post_parent);
|
||||
} else {
|
||||
$this->post_parent = $this->post;
|
||||
}
|
||||
|
||||
parent::__construct($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get model name.
|
||||
*
|
||||
* Retrieve page settings model name.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Model name.
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return 'page-settings';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get model unique name.
|
||||
*
|
||||
* Retrieve page settings model unique name.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Model unique name.
|
||||
*/
|
||||
public function getUniqueName()
|
||||
{
|
||||
return $this->getName() . '-' . $this->post->ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get CSS wrapper selector.
|
||||
*
|
||||
* Retrieve the wrapper selector for the page settings model.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return string CSS wrapper selector.
|
||||
*/
|
||||
public function getCssWrapperSelector()
|
||||
{
|
||||
$document = Plugin::$instance->documents->get($this->post_parent->ID);
|
||||
return $document->getCssWrapperSelector();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get panel page settings.
|
||||
*
|
||||
* Retrieve the panel setting for the page settings model.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return array {
|
||||
* Panel settings.
|
||||
*
|
||||
* @type string $title The panel title.
|
||||
* }
|
||||
*/
|
||||
public function getPanelPageSettings()
|
||||
{
|
||||
$document = Plugin::$instance->documents->get($this->post->ID);
|
||||
|
||||
return [
|
||||
/* translators: %s: Document title */
|
||||
'title' => sprintf(__('%s Settings'), $document::getTitle()),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* On export post meta.
|
||||
*
|
||||
* When exporting data, check if the post is not using page template and
|
||||
* exclude it from the exported Elementor data.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $element_data Element data.
|
||||
*
|
||||
* @return array Element data to be exported.
|
||||
*/
|
||||
public function onExport($element_data)
|
||||
{
|
||||
if (!empty($element_data['settings']['template'])) {
|
||||
/**
|
||||
* @var \Elementor\Modules\PageTemplates\Module $page_templates_module
|
||||
*/
|
||||
$page_templates_module = Plugin::$instance->modules_manager->getModules('page-templates');
|
||||
$is_elementor_template = !!$page_templates_module->getTemplatePath($element_data['settings']['template']);
|
||||
|
||||
if (!$is_elementor_template) {
|
||||
unset($element_data['settings']['template']);
|
||||
}
|
||||
}
|
||||
|
||||
return $element_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register model controls.
|
||||
*
|
||||
* Used to add new controls to the page settings model.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function _registerControls()
|
||||
{
|
||||
// Check if it's a real model, or abstract (for example - on import )
|
||||
if ($this->post->ID) {
|
||||
$document = Plugin::$instance->documents->getDocOrAutoSave($this->post->ID);
|
||||
|
||||
if ($document) {
|
||||
$controls = $document->getControls();
|
||||
|
||||
foreach ($controls as $control_id => $args) {
|
||||
$this->addControl($control_id, $args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
47
modules/creativeelements/core/utils/exceptions.php
Normal file
47
modules/creativeelements/core/utils/exceptions.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
/**
|
||||
* Elementor exceptions.
|
||||
*
|
||||
* Elementor exceptions handler class is responsible for handling exceptions.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class CoreXUtilsXExceptions
|
||||
{
|
||||
/**
|
||||
* HTTP status code for bad request error.
|
||||
*/
|
||||
const BAD_REQUEST = 400;
|
||||
|
||||
/**
|
||||
* HTTP status code for unauthorized access error.
|
||||
*/
|
||||
const UNAUTHORIZED = 401;
|
||||
|
||||
/**
|
||||
* HTTP status code for forbidden access error.
|
||||
*/
|
||||
const FORBIDDEN = 403;
|
||||
|
||||
/**
|
||||
* HTTP status code for resource that could not be found.
|
||||
*/
|
||||
const NOT_FOUND = 404;
|
||||
|
||||
/**
|
||||
* HTTP status code for internal server error.
|
||||
*/
|
||||
const INTERNAL_SERVER_ERROR = 500;
|
||||
}
|
||||
8
modules/creativeelements/core/utils/index.php
Normal file
8
modules/creativeelements/core/utils/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../');
|
||||
die;
|
||||
855
modules/creativeelements/creativeelements.php
Normal file
855
modules/creativeelements/creativeelements.php
Normal file
@@ -0,0 +1,855 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks
|
||||
* @copyright 2019-2022 WebshopWorks.com
|
||||
* @license One domain support license
|
||||
*/
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
define('_CE_VERSION_', '2.5.11');
|
||||
define('_CE_PATH_', _PS_MODULE_DIR_ . 'creativeelements/');
|
||||
define('_CE_URL_', defined('_PS_BO_ALL_THEMES_DIR_') ? _MODULE_DIR_ . 'creativeelements/' : 'modules/creativeelements/');
|
||||
define('_CE_ASSETS_URL_', _CE_URL_ . 'views/');
|
||||
define('_CE_TEMPLATES_', _CE_PATH_ . 'views/templates/');
|
||||
/** @deprecated since 2.5.0 - PrestaShop 1.6.x isn't supported */
|
||||
define('_CE_PS16_', false);
|
||||
|
||||
require_once _CE_PATH_ . 'classes/CETheme.php';
|
||||
require_once _CE_PATH_ . 'classes/CEContent.php';
|
||||
require_once _CE_PATH_ . 'classes/CETemplate.php';
|
||||
require_once _CE_PATH_ . 'classes/CEFont.php';
|
||||
require_once _CE_PATH_ . 'classes/CESmarty.php';
|
||||
require_once _CE_PATH_ . 'includes/plugin.php';
|
||||
|
||||
class CreativeElements extends Module
|
||||
{
|
||||
const VIEWED_PRODUCTS_LIMIT = 100;
|
||||
|
||||
protected static $controller;
|
||||
|
||||
protected static $tplOverride;
|
||||
|
||||
protected static $overrides = [
|
||||
'Category',
|
||||
'CmsCategory',
|
||||
'Manufacturer',
|
||||
'Supplier',
|
||||
];
|
||||
|
||||
public $controllers = [
|
||||
'ajax',
|
||||
'preview',
|
||||
];
|
||||
|
||||
public function __construct($name = null, Context $context = null)
|
||||
{
|
||||
$this->name = 'creativeelements';
|
||||
$this->tab = 'content_management';
|
||||
$this->version = '2.5.11';
|
||||
$this->author = 'WebshopWorks';
|
||||
$this->module_key = '7a5ebcc21c1764675f1db5d0f0eacfe5';
|
||||
$this->ps_versions_compliancy = ['min' => '1.7.0', 'max' => '1.7'];
|
||||
$this->bootstrap = true;
|
||||
$this->displayName = $this->l('Creative Elements - live Theme & Page Builder');
|
||||
$this->description = $this->l('The most advanced frontend drag & drop page builder. Create high-end, pixel perfect websites at record speeds. Any theme, any page, any design.');
|
||||
parent::__construct($this->name, null);
|
||||
|
||||
$this->checkThemeChange();
|
||||
|
||||
Shop::addTableAssociation(CETheme::$definition['table'], ['type' => 'shop']);
|
||||
Shop::addTableAssociation(CETheme::$definition['table'] . '_lang', ['type' => 'fk_shop']);
|
||||
Shop::addTableAssociation(CEContent::$definition['table'], ['type' => 'shop']);
|
||||
Shop::addTableAssociation(CEContent::$definition['table'] . '_lang', ['type' => 'fk_shop']);
|
||||
}
|
||||
|
||||
public function install()
|
||||
{
|
||||
require_once _CE_PATH_ . 'classes/CEDatabase.php';
|
||||
|
||||
if (Shop::isFeatureActive()) {
|
||||
Shop::setContext(Shop::CONTEXT_ALL);
|
||||
}
|
||||
CEDatabase::initConfigs();
|
||||
|
||||
if (!CEDatabase::createTables()) {
|
||||
$this->_errors[] = Db::getInstance()->getMsgError();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($res = parent::install() && CEDatabase::updateTabs()) {
|
||||
foreach (CEDatabase::getHooks() as $hook) {
|
||||
$res = $res && $this->registerHook($hook, null, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function uninstall()
|
||||
{
|
||||
foreach (Tab::getCollectionFromModule($this->name) as $tab) {
|
||||
$tab->delete();
|
||||
}
|
||||
|
||||
return parent::uninstall();
|
||||
}
|
||||
|
||||
public function enable($force_all = false)
|
||||
{
|
||||
return parent::enable($force_all) && Db::getInstance()->update(
|
||||
'tab',
|
||||
['active' => 1],
|
||||
"module = 'creativeelements' AND class_name != 'AdminCEEditor'"
|
||||
);
|
||||
}
|
||||
|
||||
public function disable($force_all = false)
|
||||
{
|
||||
return Db::getInstance()->update(
|
||||
'tab',
|
||||
['active' => 0],
|
||||
"module = 'creativeelements'"
|
||||
) && parent::disable($force_all);
|
||||
}
|
||||
|
||||
public function addOverride($classname)
|
||||
{
|
||||
try {
|
||||
return parent::addOverride($classname);
|
||||
} catch (Exception $ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getContent()
|
||||
{
|
||||
Tools::redirectAdmin($this->context->link->getAdminLink('AdminCEThemes'));
|
||||
}
|
||||
|
||||
public function hookDisplayBackOfficeHeader($params = [])
|
||||
{
|
||||
Configuration::get("PS_ALLOW_HTML_\x49FRAME") or Configuration::updateValue("PS_ALLOW_HTML_\x49FRAME", 1);
|
||||
|
||||
// Handle migrate
|
||||
if ((Configuration::getGlobalValue('ce_migrate') || Tools::getIsset('CEMigrate')) &&
|
||||
Db::getInstance()->executeS("SHOW TABLES LIKE '%_ce_meta'")
|
||||
) {
|
||||
require_once _CE_PATH_ . 'classes/CEMigrate.php';
|
||||
CEMigrate::registerJavascripts();
|
||||
}
|
||||
|
||||
$footer_product = '';
|
||||
preg_match('~/([^/]+)/(\d+)/edit\b~', $_SERVER['REQUEST_URI'], $req);
|
||||
$controller = Tools::strtolower(Tools::getValue('controller'));
|
||||
|
||||
switch ($controller) {
|
||||
case 'admincetemplates':
|
||||
$id_type = CE\UId::TEMPLATE;
|
||||
$id = (int) Tools::getValue('id_ce_template');
|
||||
break;
|
||||
case 'admincethemes':
|
||||
$id_type = CE\UId::THEME;
|
||||
$id = (int) Tools::getValue('id_ce_theme');
|
||||
break;
|
||||
case 'admincecontent':
|
||||
$id_type = CE\UId::CONTENT;
|
||||
$id = (int) Tools::getValue('id_ce_content');
|
||||
break;
|
||||
case 'admincmscontent':
|
||||
if ($req && $req[1] == 'category' || Tools::getIsset('addcms_category') || Tools::getIsset('updatecms_category')) {
|
||||
$id_type = CE\UId::CMS_CATEGORY;
|
||||
$id = (int) Tools::getValue('id_cms_category', $req ? $req[2] : 0);
|
||||
break;
|
||||
}
|
||||
$id_type = CE\UId::CMS;
|
||||
$id = (int) Tools::getValue('id_cms', $req ? $req[2] : 0);
|
||||
break;
|
||||
case 'adminproducts':
|
||||
$id_type = CE\UId::PRODUCT;
|
||||
$id = (int) Tools::getValue('id_product', basename(explode('?', $_SERVER['REQUEST_URI'])[0]));
|
||||
$footer_product = new CE\UId(CEContent::getFooterProductId($id), CE\UId::CONTENT, 0, $this->context->shop->id);
|
||||
break;
|
||||
case 'admincategories':
|
||||
$id_type = CE\UId::CATEGORY;
|
||||
$id = (int) Tools::getValue('id_category', $req ? $req[2] : 0);
|
||||
break;
|
||||
case 'adminmanufacturers':
|
||||
$id_type = CE\UId::MANUFACTURER;
|
||||
$id = (int) Tools::getValue('id_manufacturer', $req ? $req[2] : 0);
|
||||
break;
|
||||
case 'adminsuppliers':
|
||||
$id_type = CE\UId::SUPPLIER;
|
||||
$id = (int) Tools::getValue('id_supplier', $req ? $req[2] : 0);
|
||||
break;
|
||||
case 'adminxippost':
|
||||
$id_type = CE\UId::XIPBLOG_POST;
|
||||
$id = (int) Tools::getValue('id_xipposts');
|
||||
break;
|
||||
case 'adminstblog':
|
||||
$id_type = CE\UId::STBLOG_POST;
|
||||
$id = (int) Tools::getValue('id_st_blog');
|
||||
break;
|
||||
case 'adminblogposts':
|
||||
if ('advanceblog' === $this->context->controller->module->name) {
|
||||
$id_type = CE\UId::ADVANCEBLOG_POST;
|
||||
$id = (int) Tools::getValue('id_post');
|
||||
}
|
||||
break;
|
||||
case 'adminpsblogblogs':
|
||||
$id_type = CE\UId::PSBLOG_POST;
|
||||
$id = (int) Tools::getValue('id_psblog_blog');
|
||||
break;
|
||||
case 'admintvcmspost':
|
||||
$id_type = CE\UId::TVCMSBLOG_POST;
|
||||
$id = (int) Tools::getValue('id_tvcmsposts');
|
||||
break;
|
||||
case 'adminmodules':
|
||||
$configure = Tools::strtolower(Tools::getValue('configure'));
|
||||
|
||||
if ('ybc_blog' == $configure && Tools::getValue('control') == 'post') {
|
||||
$id_type = CE\UId::YBC_BLOG_POST;
|
||||
$id = (int) Tools::getValue('id_post');
|
||||
break;
|
||||
}
|
||||
if ('prestablog' == $configure && Tools::getIsset('editNews')) {
|
||||
$id_type = CE\UId::PRESTABLOG_POST;
|
||||
$id = (int) Tools::getValue('idN');
|
||||
break;
|
||||
}
|
||||
if ('hiblog' == $configure) {
|
||||
$id_type = CE\UId::HIBLOG_POST;
|
||||
$id = 0;
|
||||
$hideEditor = [];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'adminmaintenance':
|
||||
$id_type = CE\UId::CONTENT;
|
||||
$id = CEContent::getMaintenanceId();
|
||||
|
||||
$uids = CE\UId::getBuiltList($id, $id_type, $this->context->shop->id);
|
||||
$hideEditor = empty($uids) ? $uids : array_keys($uids[$this->context->shop->id]);
|
||||
break;
|
||||
}
|
||||
|
||||
if (isset($id)) {
|
||||
self::$controller = $this->context->controller;
|
||||
self::$controller->addJQuery();
|
||||
self::$controller->js_files[] = $this->_path . 'views/js/admin.js?v=' . _CE_VERSION_;
|
||||
self::$controller->css_files[$this->_path . 'views/css/admin.css?v=' . _CE_VERSION_] = 'all';
|
||||
|
||||
$uid = new CE\UId($id, $id_type, 0, Shop::getContext() === Shop::CONTEXT_SHOP ? $this->context->shop->id : 0);
|
||||
|
||||
isset($hideEditor) or $hideEditor = $uid->getBuiltLangIdList();
|
||||
|
||||
$display_suppliers = Configuration::get('PS_DISPLAY_SUPPLIERS');
|
||||
$display_manufacturers = version_compare(_PS_VERSION_, '1.7.7', '<')
|
||||
? $display_suppliers
|
||||
: Configuration::get('PS_DISPLAY_MANUFACTURERS');
|
||||
|
||||
Media::addJsDef([
|
||||
'ceAdmin' => [
|
||||
'uid' => "$uid",
|
||||
'hideEditor' => $hideEditor,
|
||||
'footerProduct' => "$footer_product",
|
||||
'i18n' => [
|
||||
'edit' => str_replace("'", "’", $this->l('Edit with Creative Elements')),
|
||||
'save' => str_replace("'", "’", $this->l('Please save the form before editing with Creative Elements')),
|
||||
'error' => str_replace("'", "’", $this->getErrorMsg()),
|
||||
],
|
||||
'editorUrl' => Tools::safeOutput($this->context->link->getAdminLink('AdminCEEditor') . '&uid='),
|
||||
'languages' => Language::getLanguages(true, $uid->id_shop),
|
||||
'editSuppliers' => (int) $display_suppliers,
|
||||
'editManufacturers' => (int) $display_manufacturers,
|
||||
],
|
||||
]);
|
||||
$this->context->smarty->assign('edit_width_ce', $this->context->link->getAdminLink('AdminCEEditor'));
|
||||
}
|
||||
return $this->context->smarty->fetch(_CE_TEMPLATES_ . 'hook/backoffice_header.tpl');
|
||||
}
|
||||
|
||||
protected function getErrorMsg()
|
||||
{
|
||||
if (!Configuration::get('PS_SHOP_ENABLE', null, null, $this->context->shop->id)) {
|
||||
$ips = explode(',', Configuration::get('PS_MAINTENANCE_IP', null, null, $this->context->shop->id));
|
||||
|
||||
if (!in_array(Tools::getRemoteAddr(), $ips)) {
|
||||
return $this->l('The shop is in maintenance mode, please whitelist your IP');
|
||||
}
|
||||
}
|
||||
|
||||
$id_tab = Tab::getIdFromClassName('AdminCEEditor');
|
||||
$access = Profile::getProfileAccess($this->context->employee->id_profile, $id_tab);
|
||||
|
||||
if ('1' !== $access['view']) {
|
||||
return CE\Helper::transError('You do not have permission to view this.');
|
||||
}
|
||||
|
||||
$class = isset(self::$controller->className) ? self::$controller->className : '';
|
||||
|
||||
if (in_array($class, self::$overrides)) {
|
||||
$loadObject = new ReflectionMethod(self::$controller, 'loadObject');
|
||||
$loadObject->setAccessible(true);
|
||||
|
||||
if (empty($loadObject->invoke(self::$controller, true)->active) && !defined("$class::CE_OVERRIDE")) {
|
||||
return $this->l('You can not edit items which are not displayed, because an override file is missing. Please contact us on https://addons.prestashop.com');
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
public function hookActionFrontControllerAfterInit($params = [])
|
||||
{
|
||||
if (version_compare(_PS_VERSION_, '1.7.7', '<')) {
|
||||
// Compatibility fix for PS 1.7.3 - 1.7.6
|
||||
$this->hookActionFrontControllerInitAfter($params);
|
||||
}
|
||||
}
|
||||
|
||||
public function hookActionFrontControllerInitAfter($params = [])
|
||||
{
|
||||
$tpl_dir = $this->context->smarty->getTemplateDir();
|
||||
array_unshift($tpl_dir, _CE_TEMPLATES_ . 'front/theme/');
|
||||
$this->context->smarty->setTemplateDir($tpl_dir);
|
||||
|
||||
if ($id_miniature = (int) Configuration::get('CE_PRODUCT_MINIATURE')) {
|
||||
$this->context->smarty->assign(
|
||||
'CE_PRODUCT_MINIATURE_UID',
|
||||
new CE\UId($id_miniature, CE\UId::THEME, $this->context->language->id, $this->context->shop->id)
|
||||
);
|
||||
CE\Plugin::instance()->frontend->hasElementorInPage(true);
|
||||
}
|
||||
}
|
||||
|
||||
public function hookHeader()
|
||||
{
|
||||
// Compatibility fix for PS 1.7.7.x upgrade
|
||||
return $this->hookDisplayHeader();
|
||||
}
|
||||
|
||||
public function hookDisplayHeader()
|
||||
{
|
||||
self::$controller = $this->context->controller;
|
||||
|
||||
$plugin = CE\Plugin::instance();
|
||||
CE\did_action('template_redirect') or CE\do_action('template_redirect');
|
||||
|
||||
if ($id_quick_view = Configuration::get('CE_PRODUCT_QUICK_VIEW')) {
|
||||
$plugin->frontend->hasElementorInPage(true);
|
||||
}
|
||||
if (self::$controller instanceof ProductController) {
|
||||
$this->addViewedProduct(self::$controller->getProduct()->id);
|
||||
|
||||
if ($id_quick_view && Tools::getValue('action') === 'quickview') {
|
||||
CE\UId::$_ID = new CE\UId($id_quick_view, CE\UId::THEME, $this->context->language->id, $this->context->shop->id);
|
||||
|
||||
self::skipOverrideLayoutTemplate();
|
||||
$this->context->smarty->assign('CE_PRODUCT_QUICK_VIEW_ID', $id_quick_view);
|
||||
}
|
||||
}
|
||||
|
||||
$uid_preview = self::getPreviewUId(false);
|
||||
|
||||
if ($uid_preview && CE\UId::CONTENT === $uid_preview->id_type) {
|
||||
Tools::getIsset('maintenance') && $this->displayMaintenancePage();
|
||||
}
|
||||
|
||||
// PS fix: OverrideLayoutTemplate hook doesn't exec on forbidden page
|
||||
http_response_code() !== 403 or $this->hookOverrideLayoutTemplate();
|
||||
}
|
||||
|
||||
protected function addViewedProduct($id_product)
|
||||
{
|
||||
$products = isset($this->context->cookie->ceViewedProducts)
|
||||
? explode(',', $this->context->cookie->ceViewedProducts)
|
||||
: []
|
||||
;
|
||||
if (in_array($id_product, $products)) {
|
||||
$products = array_diff($products, [$id_product]);
|
||||
}
|
||||
array_unshift($products, (int) $id_product);
|
||||
|
||||
while (count($products) > self::VIEWED_PRODUCTS_LIMIT) {
|
||||
array_pop($products);
|
||||
}
|
||||
$this->context->cookie->ceViewedProducts = implode(',', $products);
|
||||
|
||||
if (Tools::getValue('action') === 'quickview') {
|
||||
$this->context->cookie->write();
|
||||
}
|
||||
}
|
||||
|
||||
public static function skipOverrideLayoutTemplate()
|
||||
{
|
||||
self::$tplOverride = '';
|
||||
}
|
||||
|
||||
public function hookOverrideLayoutTemplate($params = [])
|
||||
{
|
||||
if (null !== self::$tplOverride || !self::$controller) {
|
||||
return self::$tplOverride;
|
||||
}
|
||||
self::$tplOverride = '';
|
||||
|
||||
if (self::isMaintenance()) {
|
||||
return self::$tplOverride;
|
||||
}
|
||||
// Page Content
|
||||
$controller = self::$controller;
|
||||
$tpl_vars = &$this->context->smarty->tpl_vars;
|
||||
$front = Tools::strtolower(preg_replace('/(ModuleFront)?Controller(Override)?$/i', '', get_class($controller)));
|
||||
// PrestaBlog fix for non-default blog URL
|
||||
stripos($front, 'prestablog') === 0 && property_exists($controller, 'news') && $front = 'prestablogblog';
|
||||
|
||||
switch ($front) {
|
||||
case 'creativeelementspreview':
|
||||
$model = self::getPreviewUId(false)->getModel();
|
||||
$key = $model::${'definition'}['table'];
|
||||
|
||||
if (isset($tpl_vars[$key]->value['id'])) {
|
||||
$id = $tpl_vars[$key]->value['id'];
|
||||
$desc = ['description' => &$tpl_vars[$key]->value['content']];
|
||||
}
|
||||
break;
|
||||
case 'cms':
|
||||
$model = class_exists('CMS') ? 'CMS' : 'CMSCategory';
|
||||
$key = $model::${'definition'}['table'];
|
||||
|
||||
if (isset($tpl_vars[$key]->value['id'])) {
|
||||
$id = $tpl_vars[$key]->value['id'];
|
||||
$desc = ['description' => &$tpl_vars[$key]->value['content']];
|
||||
|
||||
CE\add_action('wp_head', 'print_og_image');
|
||||
} elseif (isset($tpl_vars['cms_category']->value['id'])) {
|
||||
$model = 'CMSCategory';
|
||||
$id = $tpl_vars['cms_category']->value['id'];
|
||||
$desc = &$tpl_vars['cms_category']->value;
|
||||
}
|
||||
break;
|
||||
case 'product':
|
||||
case 'category':
|
||||
case 'manufacturer':
|
||||
case 'supplier':
|
||||
$model = $front;
|
||||
|
||||
if (isset($tpl_vars[$model]->value['id'])) {
|
||||
$id = $tpl_vars[$model]->value['id'];
|
||||
$desc = &$tpl_vars[$model]->value;
|
||||
}
|
||||
break;
|
||||
case 'ybc_blogblog':
|
||||
$model = 'Ybc_blog_post_class';
|
||||
|
||||
if (isset($tpl_vars['blog_post']->value['id_post'])) {
|
||||
$id = $tpl_vars['blog_post']->value['id_post'];
|
||||
$desc = &$tpl_vars['blog_post']->value;
|
||||
|
||||
if (Tools::getIsset('adtoken') && self::hasAdminToken('AdminModules')) {
|
||||
// override post status for preview
|
||||
$tpl_vars['blog_post']->value['enabled'] = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'xipblogsingle':
|
||||
$model = 'XipPostsClass';
|
||||
|
||||
if (isset($tpl_vars['xipblogpost']->value['id_xipposts'])) {
|
||||
$id = $tpl_vars['xipblogpost']->value['id_xipposts'];
|
||||
$desc = ['description' => &$tpl_vars['xipblogpost']->value['post_content']];
|
||||
}
|
||||
break;
|
||||
case 'stblogarticle':
|
||||
$model = 'StBlogClass';
|
||||
|
||||
if (isset($tpl_vars['blog']->value['id'])) {
|
||||
$id = $tpl_vars['blog']->value['id'];
|
||||
$desc = ['description' => &$tpl_vars['blog']->value['content']];
|
||||
break;
|
||||
}
|
||||
$blogProp = new ReflectionProperty($controller, 'blog');
|
||||
$blogProp->setAccessible(true);
|
||||
$blog = $blogProp->getValue($controller);
|
||||
|
||||
if (isset($blog->id)) {
|
||||
$id = $blog->id;
|
||||
$desc = ['description' => &$blog->content];
|
||||
}
|
||||
break;
|
||||
case 'advanceblogdetail':
|
||||
$model = 'BlogPosts';
|
||||
|
||||
if (isset($tpl_vars['postData']->value['id_post'])) {
|
||||
$id = $tpl_vars['postData']->value['id_post'];
|
||||
$desc = ['description' => &$tpl_vars['postData']->value['post_content']];
|
||||
}
|
||||
break;
|
||||
case 'prestablogblog':
|
||||
$model = 'NewsClass';
|
||||
$newsProp = new ReflectionProperty($controller, 'news');
|
||||
$newsProp->setAccessible(true);
|
||||
$news = $newsProp->getValue($controller);
|
||||
|
||||
if (isset($news->id)) {
|
||||
$id = $news->id;
|
||||
|
||||
if (isset($tpl_vars['tpl_unique'])) {
|
||||
$desc = ['description' => &$tpl_vars['tpl_unique']->value];
|
||||
} else {
|
||||
$desc = ['description' => &$news->content];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'hiblogpostdetails':
|
||||
$model = 'HiBlogPost';
|
||||
|
||||
if (isset($tpl_vars['post']->value['id_post'])) {
|
||||
$id = $tpl_vars['post']->value['id_post'];
|
||||
$desc = &$tpl_vars['post']->value;
|
||||
|
||||
if (Tools::getIsset('adtoken') && self::hasAdminToken('AdminModules')) {
|
||||
// override post status for preview
|
||||
$tpl_vars['post']->value['enabled'] = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'tvcmsblogsingle':
|
||||
$model = 'TvcmsPostsClass';
|
||||
|
||||
if (isset($tpl_vars['tvcmsblogpost']->value['id_tvcmsposts'])) {
|
||||
$id = $tpl_vars['tvcmsblogpost']->value['id_tvcmsposts'];
|
||||
$desc = ['description' => &$tpl_vars['tvcmsblogpost']->value['post_content']];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (isset($id)) {
|
||||
$uid_preview = self::getPreviewUId();
|
||||
|
||||
if ($uid_preview && $uid_preview->id === (int) $id && $uid_preview->id_type === CE\UId::getTypeId($model)) {
|
||||
CE\UId::$_ID = $uid_preview;
|
||||
} elseif (!CE\UId::$_ID || in_array(CE\UId::$_ID->id_type, [CE\UId::CONTENT, CE\UId::THEME, CE\UId::TEMPLATE])) {
|
||||
CE\UId::$_ID = new CE\UId($id, CE\UId::getTypeId($model), $this->context->language->id, $this->context->shop->id);
|
||||
}
|
||||
|
||||
if (CE\UId::$_ID) {
|
||||
$this->filterBodyClasses();
|
||||
|
||||
$desc['description'] = CE\apply_filters('the_content', $desc['description']);
|
||||
}
|
||||
}
|
||||
|
||||
// Theme Builder
|
||||
$themes = [
|
||||
'header' => Configuration::get('CE_HEADER'),
|
||||
'footer' => Configuration::get('CE_FOOTER'),
|
||||
];
|
||||
$pages = [
|
||||
'index' => 'page-index',
|
||||
'contact' => 'page-contact',
|
||||
'product' => 'product',
|
||||
'pagenotfound' => 'page-not-found',
|
||||
];
|
||||
foreach ($pages as $page_type => $theme_type) {
|
||||
if ($front === $page_type) {
|
||||
$themes[$theme_type] = Configuration::get(self::getThemeVarName($theme_type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
$uid = CE\UId::$_ID;
|
||||
$uid_preview = self::getPreviewUId(false);
|
||||
|
||||
if ($uid_preview && (CE\UId::THEME === $uid_preview->id_type || CE\UId::TEMPLATE === $uid_preview->id_type)) {
|
||||
$preview = self::renderTheme($uid_preview);
|
||||
$document = CE\Plugin::$instance->documents->getDocForFrontend($uid_preview);
|
||||
$type_preview = $document->getTemplateType();
|
||||
$this->context->smarty->assign(self::getThemeVarName($type_preview), $preview);
|
||||
|
||||
if ('product-quick-view' === $type_preview) {
|
||||
unset($desc);
|
||||
$desc = ['description' => &$preview];
|
||||
CE\Plugin::$instance->modules_manager->getModules('catalog')->handleProductQuickView();
|
||||
|
||||
$this->context->smarty->assign('CE_PRODUCT_QUICK_VIEW_ID', $uid_preview->id);
|
||||
} elseif ('product-miniature' === $type_preview) {
|
||||
unset($desc);
|
||||
$desc = ['description' => &$preview];
|
||||
CE\Plugin::$instance->modules_manager->getModules('catalog')->handleProductMiniature();
|
||||
|
||||
$this->context->smarty->assign('CE_PRODUCT_MINIATURE_ID', $uid_preview->id);
|
||||
} elseif ('product' === $type_preview) {
|
||||
$this->context->smarty->assign('CE_PRODUCT_ID', $uid_preview->id);
|
||||
} elseif (stripos($type_preview, 'page-') === 0) {
|
||||
$desc = ['description' => &$preview];
|
||||
CE\add_action('wp_head', 'print_og_image');
|
||||
}
|
||||
array_search($type_preview, $pages) && $this->filterBodyClasses($uid_preview->id);
|
||||
unset($themes[$type_preview]);
|
||||
}
|
||||
if (isset($pages[$front]) && !empty($themes[$pages[$front]])) {
|
||||
$theme_type = $pages[$front];
|
||||
$uid_theme = new CE\UId($themes[$theme_type], CE\UId::THEME, $this->context->language->id, $this->context->shop->id);
|
||||
|
||||
if ('product' === $page_type) {
|
||||
$this->context->smarty->assign([
|
||||
'CE_PRODUCT_ID' => $uid_theme->id,
|
||||
'CE_PRODUCT' => self::renderTheme($uid_theme),
|
||||
]);
|
||||
} else {
|
||||
$desc = ['description' => self::renderTheme($uid_theme)];
|
||||
$this->context->smarty->assign(self::getThemeVarName($theme_type), $desc['description']);
|
||||
CE\add_action('wp_head', 'print_og_image');
|
||||
}
|
||||
$this->filterBodyClasses($uid_theme->id);
|
||||
unset($themes[$theme_type]);
|
||||
}
|
||||
|
||||
self::$tplOverride = CE\apply_filters('template_include', self::$tplOverride);
|
||||
|
||||
if (strrpos(self::$tplOverride, 'layout-canvas') !== false) {
|
||||
empty($desc) or $this->context->smarty->assign('ce_desc', $desc);
|
||||
} else {
|
||||
foreach ($themes as $theme_type => $id_ce_theme) {
|
||||
empty($id_ce_theme) or $this->context->smarty->assign(
|
||||
self::getThemeVarName($theme_type),
|
||||
self::renderTheme(
|
||||
new CE\UId($id_ce_theme, CE\UId::THEME, $this->context->language->id, $this->context->shop->id)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
CE\UId::$_ID = $uid;
|
||||
|
||||
return self::$tplOverride;
|
||||
}
|
||||
|
||||
protected function filterBodyClasses($id_ce_theme = 0)
|
||||
{
|
||||
$body_classes = &$this->context->smarty->tpl_vars['page']->value['body_classes'];
|
||||
|
||||
if ($id_ce_theme) {
|
||||
$body_classes['ce-theme'] = 1;
|
||||
$body_classes["ce-theme-$id_ce_theme"] = 1;
|
||||
} else {
|
||||
$body_classes['elementor-page'] = 1;
|
||||
$body_classes['elementor-page-' . CE\get_the_ID()->toDefault()] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
protected function displayMaintenancePage()
|
||||
{
|
||||
Configuration::set('PS_SHOP_ENABLE', false);
|
||||
Configuration::set('PS_MAINTENANCE_IP', '');
|
||||
|
||||
$displayMaintenancePage = new ReflectionMethod($this->context->controller, 'displayMaintenancePage');
|
||||
$displayMaintenancePage->setAccessible(true);
|
||||
$displayMaintenancePage->invoke($this->context->controller);
|
||||
}
|
||||
|
||||
public function hookDisplayMaintenance($params = [])
|
||||
{
|
||||
if (self::getPreviewUId(false)) {
|
||||
http_response_code(200);
|
||||
header_remove('Retry-After');
|
||||
} else {
|
||||
$this->hookDisplayHeader();
|
||||
}
|
||||
|
||||
CE\add_filter('the_content', function () {
|
||||
$uid = CE\get_the_ID();
|
||||
${'this'}->context->smarty->assign('ce_content', new CEContent($uid->id, $uid->id_lang, $uid->id_shop));
|
||||
|
||||
CE\remove_all_filters('the_content');
|
||||
}, 0);
|
||||
|
||||
if (!$maintenance = $this->renderContent('displayMaintenance', $params)) {
|
||||
return;
|
||||
}
|
||||
self::$controller->registerJavascript('jquery', 'js/jquery/jquery-1.11.0.min.js');
|
||||
|
||||
$this->context->smarty->assign([
|
||||
'iso_code' => $this->context->language->iso_code,
|
||||
'favicon' => Configuration::get('PS_FAVICON'),
|
||||
'favicon_update_time' => Configuration::get('PS_IMG_UPDATE_TIME'),
|
||||
]);
|
||||
return $maintenance;
|
||||
}
|
||||
|
||||
public function hookDisplayFooterProduct($params = [])
|
||||
{
|
||||
return $this->renderContent('displayFooterProduct', $params);
|
||||
}
|
||||
|
||||
public function __call($method, $args)
|
||||
{
|
||||
if (stripos($method, 'hookActionObject') === 0 && stripos($method, 'DeleteAfter') !== false) {
|
||||
call_user_func_array([$this, 'hookActionObjectDeleteAfter'], $args);
|
||||
} elseif (stripos($method, 'hook') === 0) {
|
||||
// render hook only after Header init or if it's Home
|
||||
if (null !== self::$tplOverride || !strcasecmp($method, 'hookDisplayHome')) {
|
||||
return $this->renderContent(Tools::substr($method, 4), $args);
|
||||
}
|
||||
} else {
|
||||
throw new Exception('Can not find method: ' . $method);
|
||||
}
|
||||
}
|
||||
|
||||
public function renderContent($hook_name = null)
|
||||
{
|
||||
if (!$hook_name) {
|
||||
return;
|
||||
}
|
||||
$out = '';
|
||||
$rows = CEContent::getIdsByHook(
|
||||
$hook_name,
|
||||
$id_lang = $this->context->language->id,
|
||||
$id_shop = $this->context->shop->id,
|
||||
Tools::getValue('id_product', 0),
|
||||
self::getPreviewUId()
|
||||
);
|
||||
if ($rows) {
|
||||
$uid = CE\UId::$_ID;
|
||||
|
||||
foreach ($rows as $row) {
|
||||
CE\UId::$_ID = new CE\UId($row['id'], CE\UId::CONTENT, $id_lang, $id_shop);
|
||||
|
||||
$out .= CE\apply_filters('the_content', '');
|
||||
}
|
||||
CE\UId::$_ID = $uid;
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
public static function renderTheme($uid)
|
||||
{
|
||||
CE\UId::$_ID = $uid;
|
||||
|
||||
return CE\apply_filters('the_content', '');
|
||||
}
|
||||
|
||||
public function registerHook($hook_name, $shop_list = null, $position = null)
|
||||
{
|
||||
$res = parent::registerHook($hook_name, $shop_list);
|
||||
|
||||
if ($res && is_numeric($position)) {
|
||||
$this->updatePosition(Hook::getIdByName($hook_name), 0, $position);
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function hookCETemplate($params = [])
|
||||
{
|
||||
if (empty($params['id']) || !Validate::isLoadedObject($tpl = new CETemplate($params['id'])) || !$tpl->active) {
|
||||
return;
|
||||
}
|
||||
$uid = CE\UId::$_ID;
|
||||
CE\UId::$_ID = new CE\UId($params['id'], CE\UId::TEMPLATE);
|
||||
$out = CE\apply_filters('the_content', '');
|
||||
CE\UId::$_ID = $uid;
|
||||
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function hookActionObjectDeleteAfter($params = [])
|
||||
{
|
||||
$model = get_class($params['object']);
|
||||
$id_type = CE\UId::getTypeId($model);
|
||||
$id_start = sprintf('%d%02d', $params['object']->id, $id_type);
|
||||
|
||||
// Delete meta data
|
||||
Db::getInstance()->delete('ce_meta', "id LIKE '{$id_start}____'");
|
||||
|
||||
// Delete CSS files
|
||||
array_map('unlink', glob(_CE_PATH_ . "views/css/ce/$id_start????.css", GLOB_NOSORT));
|
||||
}
|
||||
|
||||
public function hookActionObjectProductDeleteAfter($params = [])
|
||||
{
|
||||
$this->hookActionObjectDeleteAfter($params);
|
||||
|
||||
// Delete displayFooterProduct content
|
||||
if ($id = CEContent::getFooterProductId($params['object']->id)) {
|
||||
$content = new CEContent($id);
|
||||
Validate::isLoadedObject($content) && $content->delete();
|
||||
}
|
||||
}
|
||||
|
||||
public function hookActionProductAdd($params = [])
|
||||
{
|
||||
if (isset($params['request']) && $params['request']->attributes->get('action') === 'duplicate') {
|
||||
$id_product_duplicate = (int) $params['request']->attributes->get('id');
|
||||
} elseif (Tools::getIsset('duplicateproduct')) {
|
||||
$id_product_duplicate = (int) Tools::getValue('id_product');
|
||||
}
|
||||
|
||||
if (isset($id_product_duplicate, $params['id_product']) &&
|
||||
$built_list = CE\UId::getBuiltList($id_product_duplicate, CE\UId::PRODUCT)
|
||||
) {
|
||||
$db = CE\Plugin::instance()->db;
|
||||
$uid = new CE\UId($params['id_product'], CE\UId::PRODUCT, 0);
|
||||
|
||||
foreach ($built_list as $id_shop => &$langs) {
|
||||
foreach ($langs as $id_lang => $uid_from) {
|
||||
$uid->id_lang = $id_lang;
|
||||
$uid->id_shop = $id_shop;
|
||||
|
||||
$db->copyElementorMeta($uid_from, $uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function checkThemeChange()
|
||||
{
|
||||
if (!$theme = Configuration::get('CE_THEME')) {
|
||||
Configuration::updateValue('CE_THEME', _THEME_NAME_);
|
||||
} elseif (_THEME_NAME_ !== $theme) {
|
||||
require_once _CE_PATH_ . 'classes/CEDatabase.php';
|
||||
|
||||
// register missing hooks after changing theme
|
||||
foreach (CEDatabase::getHooks() as $hook) {
|
||||
$this->registerHook($hook, null, 1);
|
||||
}
|
||||
Configuration::updateValue('CE_THEME', _THEME_NAME_);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getPreviewUId($embed = true)
|
||||
{
|
||||
static $res = null;
|
||||
|
||||
if (null === $res && $res = Tools::getIsset('preview_id') &&
|
||||
$uid = CE\UId::parse(Tools::getValue('preview_id'))
|
||||
) {
|
||||
$admin = $uid->getAdminController();
|
||||
$key = 'AdminBlogPosts' === $admin ? 'blogtoken' : 'adtoken';
|
||||
$res = self::hasAdminToken($admin, $key) ? $uid : false;
|
||||
}
|
||||
return !$embed || Tools::getIsset('ver') ? $res : false;
|
||||
}
|
||||
|
||||
public static function hasAdminToken($tab, $key = 'adtoken')
|
||||
{
|
||||
$adtoken = Tools::getAdminToken($tab . (int) Tab::getIdFromClassName($tab) . (int) Tools::getValue('id_employee'));
|
||||
|
||||
return Tools::getValue($key) == $adtoken;
|
||||
}
|
||||
|
||||
public static function getThemeVarName($theme_type)
|
||||
{
|
||||
if ('product' === $theme_type && Tools::getValue('quickview')) {
|
||||
return 'CE_PRODUCT_QUICK_VIEW';
|
||||
} elseif ('product' === $theme_type && Tools::getValue('miniature')) {
|
||||
return 'CE_PRODUCT_MINIATURE';
|
||||
}
|
||||
return 'CE_' . Tools::strtoupper(str_replace('-', '_', $theme_type));
|
||||
}
|
||||
|
||||
public static function isMaintenance()
|
||||
{
|
||||
return !Configuration::get('PS_SHOP_ENABLE') &&
|
||||
!in_array(Tools::getRemoteAddr(), explode(',', Configuration::get('PS_MAINTENANCE_IP')));
|
||||
}
|
||||
}
|
||||
302
modules/creativeelements/includes/api.php
Normal file
302
modules/creativeelements/includes/api.php
Normal file
@@ -0,0 +1,302 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
/**
|
||||
* Elementor API.
|
||||
*
|
||||
* Elementor API handler class is responsible for communicating with Elementor
|
||||
* remote servers retrieving templates data and to send uninstall feedback.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Api
|
||||
{
|
||||
/**
|
||||
* Elementor library option key.
|
||||
*/
|
||||
const LIBRARY_OPTION_KEY = 'elementor_remote_info_library';
|
||||
|
||||
/**
|
||||
* Elementor feed option key.
|
||||
*/
|
||||
const FEED_OPTION_KEY = 'elementor_remote_info_feed_data';
|
||||
|
||||
/**
|
||||
* API info URL.
|
||||
*
|
||||
* Holds the URL of the info API.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @var string API info URL.
|
||||
*/
|
||||
public static $api_info_url = 'http://pagebuilder.webshopworks.com/?api=2&info';
|
||||
|
||||
// private static $api_feedback_url = 'http://pagebuilder.webshopworks.com/?api=2&feedback';
|
||||
|
||||
/**
|
||||
* API get template content URL.
|
||||
*
|
||||
* Holds the URL of the template content API.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var string API get template content URL.
|
||||
*/
|
||||
private static $api_get_template_content_url = 'http://pagebuilder.webshopworks.com/?api=2&template=%d';
|
||||
|
||||
/**
|
||||
* Get info data.
|
||||
*
|
||||
* This function notifies the user of upgrade notices, new templates and contributors.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @param bool $force_update Optional. Whether to force the data retrieval or
|
||||
* not. Default is false.
|
||||
*
|
||||
* @return array|false Info data, or false.
|
||||
*/
|
||||
private static function getInfoData($force_update = false)
|
||||
{
|
||||
$cache_key = 'elementor_remote_info_api_data_' . _CE_VERSION_;
|
||||
|
||||
$info_data = get_transient($cache_key);
|
||||
|
||||
if ($force_update || false === $info_data) {
|
||||
$timeout = ($force_update) ? 25 : 8;
|
||||
|
||||
$response = wp_remote_get(self::$api_info_url, [
|
||||
'timeout' => $timeout,
|
||||
'body' => [
|
||||
// Which API version is used.
|
||||
'api_version' => _CE_VERSION_,
|
||||
// Which language to return.
|
||||
'site_lang' => get_locale(),
|
||||
],
|
||||
]);
|
||||
|
||||
if (empty($response)) {
|
||||
set_transient($cache_key, [], 2 * HOUR_IN_SECONDS);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$info_data = json_decode($response, true);
|
||||
|
||||
if (empty($info_data) || !is_array($info_data)) {
|
||||
set_transient($cache_key, [], 2 * HOUR_IN_SECONDS);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isset($info_data['library'], $info_data['templates'])) {
|
||||
$info_data['library']['templates'] = &$info_data['templates'];
|
||||
update_post_meta(0, self::LIBRARY_OPTION_KEY, $info_data['library']);
|
||||
|
||||
unset($info_data['library'], $info_data['templates']);
|
||||
}
|
||||
|
||||
if (isset($info_data['feed'])) {
|
||||
update_post_meta(0, self::FEED_OPTION_KEY, $info_data['feed']);
|
||||
|
||||
unset($info_data['feed']);
|
||||
}
|
||||
|
||||
set_transient($cache_key, $info_data, 12 * HOUR_IN_SECONDS);
|
||||
}
|
||||
|
||||
return $info_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get upgrade notice.
|
||||
*
|
||||
* Retrieve the upgrade notice if one exists, or false otherwise.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array|false Upgrade notice, or false none exist.
|
||||
*/
|
||||
public static function getUpgradeNotice()
|
||||
{
|
||||
$data = self::getInfoData();
|
||||
|
||||
if (empty($data['upgrade_notice'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $data['upgrade_notice'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get templates data.
|
||||
*
|
||||
* Retrieve the templates data from a remote server.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param bool $force_update Optional. Whether to force the data update or
|
||||
* not. Default is false.
|
||||
*
|
||||
* @return array The templates data.
|
||||
*/
|
||||
public static function getLibraryData($force_update = false)
|
||||
{
|
||||
self::getInfoData($force_update);
|
||||
|
||||
$library_data = get_post_meta(0, self::LIBRARY_OPTION_KEY, true);
|
||||
|
||||
if (empty($library_data)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $library_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get feed data.
|
||||
*
|
||||
* Retrieve the feed info data from remote elementor server.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param bool $force_update Optional. Whether to force the data update or
|
||||
* not. Default is false.
|
||||
*
|
||||
* @return array Feed data.
|
||||
*/
|
||||
public static function getFeedData($force_update = false)
|
||||
{
|
||||
self::getInfoData($force_update);
|
||||
|
||||
$feed = get_post_meta(0, self::FEED_OPTION_KEY, true);
|
||||
|
||||
if (empty($feed)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $feed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get template content.
|
||||
*
|
||||
* Retrieve the templates content received from a remote server.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param int $template_id The template ID.
|
||||
*
|
||||
* @return array The template content.
|
||||
*/
|
||||
public static function getTemplateContent($template_id)
|
||||
{
|
||||
$url = sprintf(self::$api_get_template_content_url, $template_id);
|
||||
|
||||
$body_args = [
|
||||
// Which API version is used.
|
||||
'api_version' => _CE_VERSION_,
|
||||
// Which language to return.
|
||||
'site_lang' => get_locale(),
|
||||
];
|
||||
|
||||
/**
|
||||
* API: Template body args.
|
||||
*
|
||||
* Filters the body arguments send with the GET request when fetching the content.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param array $body_args Body arguments.
|
||||
*/
|
||||
$body_args = apply_filters('elementor/api/get_templates/body_args', $body_args);
|
||||
|
||||
$response = wp_remote_get($url, [
|
||||
'timeout' => 40,
|
||||
'body' => $body_args,
|
||||
]);
|
||||
|
||||
if (empty($response)) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$template_content = json_decode($response, true);
|
||||
/**
|
||||
* API: Template content.
|
||||
*
|
||||
* Filters the remote template content.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param array $template_content Template content.
|
||||
*/
|
||||
$template_content = apply_filters('elementor/api/get_templates/content', $template_content);
|
||||
|
||||
if (isset($template_content['error'])) {
|
||||
return new WPError('response_error', $template_content['error']);
|
||||
}
|
||||
|
||||
if (empty($template_content['data']) && empty($template_content['content'])) {
|
||||
return new WPError('template_data_error', 'An invalid data was returned.');
|
||||
}
|
||||
|
||||
return $template_content;
|
||||
}
|
||||
|
||||
// public static function sendFeedback($feedback_key, $feedback_text)
|
||||
|
||||
/**
|
||||
* Ajax reset API data.
|
||||
*
|
||||
* Reset Elementor library API data using an ajax call.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function ajaxResetApiData()
|
||||
{
|
||||
check_ajax_referer('elementor_reset_library', '_nonce');
|
||||
|
||||
self::getInfoData(true);
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init.
|
||||
*
|
||||
* Initialize Elementor API.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function init()
|
||||
{
|
||||
add_action('wp_ajax_elementor_reset_library', [__CLASS__, 'ajax_reset_api_data']);
|
||||
}
|
||||
}
|
||||
279
modules/creativeelements/includes/autoloader.php
Normal file
279
modules/creativeelements/includes/autoloader.php
Normal file
@@ -0,0 +1,279 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
/**
|
||||
* Elementor autoloader.
|
||||
*
|
||||
* Elementor autoloader handler class is responsible for loading the different
|
||||
* classes needed to run the plugin.
|
||||
*
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class Autoloader
|
||||
{
|
||||
/**
|
||||
* Classes map.
|
||||
*
|
||||
* Maps Elementor classes to file names.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var array Classes used by elementor.
|
||||
*/
|
||||
private static $classes_map;
|
||||
|
||||
/**
|
||||
* Classes aliases.
|
||||
*
|
||||
* Maps Elementor classes to aliases.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var array Classes aliases.
|
||||
*/
|
||||
private static $classes_aliases;
|
||||
|
||||
/**
|
||||
* Run autoloader.
|
||||
*
|
||||
* Register a function as `__autoload()` implementation.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function run()
|
||||
{
|
||||
spl_autoload_register([__CLASS__, 'autoload']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get classes aliases.
|
||||
*
|
||||
* Retrieve the classes aliases names.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array Classes aliases.
|
||||
*/
|
||||
public static function getClassesAliases()
|
||||
{
|
||||
if (!self::$classes_aliases) {
|
||||
self::initClassesAliases();
|
||||
}
|
||||
|
||||
return self::$classes_aliases;
|
||||
}
|
||||
|
||||
public static function getClassesMap()
|
||||
{
|
||||
if (!self::$classes_map) {
|
||||
self::initClassesMap();
|
||||
}
|
||||
|
||||
return self::$classes_map;
|
||||
}
|
||||
|
||||
private static function initClassesMap()
|
||||
{
|
||||
self::$classes_map = [
|
||||
'Api' => 'includes/api.php',
|
||||
'BaseControl' => 'includes/controls/base.php',
|
||||
'BaseDataControl' => 'includes/controls/base-data.php',
|
||||
'BaseUIControl' => 'includes/controls/base-ui.php',
|
||||
'Conditions' => 'includes/conditions.php',
|
||||
'ControlsManager' => 'includes/managers/controls.php',
|
||||
'ControlsStack' => 'includes/base/controls-stack.php',
|
||||
'DB' => 'includes/db.php',
|
||||
'Editor' => 'includes/editor.php',
|
||||
'ElementsManager' => 'includes/managers/elements.php',
|
||||
'Embed' => 'includes/embed.php',
|
||||
'Fonts' => 'includes/fonts.php',
|
||||
'Frontend' => 'includes/frontend.php',
|
||||
'GroupControlBase' => 'includes/controls/groups/base.php',
|
||||
'GroupControlInterface' => 'includes/interfaces/group-control.php',
|
||||
'Heartbeat' => 'includes/heartbeat.php',
|
||||
// 'ImagesManager' => 'includes/managers/image.php',
|
||||
// 'PostsCSSManager' => 'includes/managers/css-files.php',
|
||||
'Preview' => 'includes/preview.php',
|
||||
'SchemeBase' => 'includes/schemes/base.php',
|
||||
'SchemeColor' => 'includes/schemes/color.php',
|
||||
'SchemeColorPicker' => 'includes/schemes/color-picker.php',
|
||||
'SchemeTypography' => 'includes/schemes/typography.php',
|
||||
'SchemeInterface' => 'includes/interfaces/scheme.php',
|
||||
'SchemesManager' => 'includes/managers/schemes.php',
|
||||
'Shapes' => 'includes/shapes.php',
|
||||
'SkinsManager' => 'includes/managers/skins.php',
|
||||
'Stylesheet' => 'includes/stylesheet.php',
|
||||
'TemplateLibraryXClassesXImportImages' => 'includes/template-library/classes/class-import-images.php',
|
||||
'TemplateLibraryXManager' => 'includes/template-library/manager.php',
|
||||
'TemplateLibraryXSourceBase' => 'includes/template-library/sources/base.php',
|
||||
'TemplateLibraryXSourceLocal' => 'includes/template-library/sources/local.php',
|
||||
'TemplateLibraryXSourceRemote' => 'includes/template-library/sources/remote.php',
|
||||
'User' => 'includes/user.php',
|
||||
'Utils' => 'includes/utils.php',
|
||||
'WidgetsManager' => 'includes/managers/widgets.php',
|
||||
];
|
||||
|
||||
$controls_names = ControlsManager::getControlsNames();
|
||||
|
||||
$controls_names = array_merge($controls_names, [
|
||||
'base_multiple',
|
||||
'base_units',
|
||||
]);
|
||||
|
||||
foreach ($controls_names as $control_name) {
|
||||
$class_name = 'Control' . self::normalizeClassName($control_name, '_');
|
||||
|
||||
self::$classes_map[$class_name] = 'includes/controls/' . str_replace('_', '-', $control_name) . '.php';
|
||||
}
|
||||
|
||||
$controls_groups_names = ControlsManager::getGroupsNames();
|
||||
|
||||
foreach ($controls_groups_names as $group_name) {
|
||||
$class_name = 'GroupControl' . self::normalizeClassName(str_replace('-', '_', $group_name), '_');
|
||||
|
||||
self::$classes_map[$class_name] = 'includes/controls/groups/' . $group_name . '.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize Class Name
|
||||
*
|
||||
* Used to convert control names to class name,
|
||||
* a ucwords polyfill for php versions not supporting delimiter parameter
|
||||
* reference : https://github.com/elementor/elementor/issues/7310#issuecomment-469593385
|
||||
*
|
||||
* @param $string
|
||||
* @param string $delimiter
|
||||
*
|
||||
* @todo Remove once we bump minimum php version to 5.6
|
||||
* @return mixed
|
||||
*/
|
||||
private static function normalizeClassName($string, $delimiter = ' ')
|
||||
{
|
||||
return str_replace(' ', '', ucwords(str_replace($delimiter, ' ', $string)));
|
||||
}
|
||||
|
||||
private static function initClassesAliases()
|
||||
{
|
||||
self::$classes_aliases = [
|
||||
'CSSFile' => [
|
||||
'replacement' => 'CoreXFilesXCSSXBase',
|
||||
'version' => '2.1.0',
|
||||
],
|
||||
'GlobalCSSFile' => [
|
||||
'replacement' => 'CoreXFilesXCSSXGlobalCSS',
|
||||
'version' => '2.1.0',
|
||||
],
|
||||
'PostCSSFile' => [
|
||||
'replacement' => 'CoreXFilesXCSSXPost',
|
||||
'version' => '2.1.0',
|
||||
],
|
||||
'PostsCSSManager' => [
|
||||
'replacement' => 'CoreXFilesXManager',
|
||||
'version' => '2.1.0',
|
||||
],
|
||||
'PostPreviewCSS' => [
|
||||
'replacement' => 'CoreXFilesXCSSXPostPreview',
|
||||
'version' => '2.1.0',
|
||||
],
|
||||
'Responsive' => [
|
||||
'replacement' => 'CoreXResponsiveXResponsive',
|
||||
'version' => '2.1.0',
|
||||
],
|
||||
'Ajax' => [
|
||||
'replacement' => 'CoreXCommonXModulesXAjaxXModule',
|
||||
'version' => '2.3.0',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load class.
|
||||
*
|
||||
* For a given class name, require the class file.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @param string $relative_class_name Class name.
|
||||
*/
|
||||
private static function loadClass($relative_class_name)
|
||||
{
|
||||
$classes_map = self::getClassesMap();
|
||||
|
||||
if (isset($classes_map[$relative_class_name])) {
|
||||
$filename = _CE_PATH_ . '/' . $classes_map[$relative_class_name];
|
||||
} else {
|
||||
$filename = call_user_func(
|
||||
'strtolower',
|
||||
preg_replace(
|
||||
['/X/', '/([a-z])([A-Z])/'],
|
||||
['/', '$1-$2'],
|
||||
$relative_class_name
|
||||
)
|
||||
);
|
||||
|
||||
$filename = _CE_PATH_ . $filename . '.php';
|
||||
}
|
||||
|
||||
if (is_readable($filename)) {
|
||||
require $filename;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload.
|
||||
*
|
||||
* For a given class, check if it exist and load it.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @param string $class Class name.
|
||||
*/
|
||||
private static function autoload($class)
|
||||
{
|
||||
if (0 !== strpos($class, __NAMESPACE__ . '\\')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$relative_class_name = preg_replace('/^' . __NAMESPACE__ . '\\\/', '', $class);
|
||||
|
||||
$classes_aliases = self::getClassesAliases();
|
||||
|
||||
$has_class_alias = isset($classes_aliases[$relative_class_name]);
|
||||
|
||||
// Backward Compatibility: Save old class name for set an alias after the new class is loaded
|
||||
if ($has_class_alias) {
|
||||
$alias_data = $classes_aliases[$relative_class_name];
|
||||
|
||||
$relative_class_name = $alias_data['replacement'];
|
||||
}
|
||||
|
||||
$final_class_name = __NAMESPACE__ . '\\' . $relative_class_name;
|
||||
|
||||
if (!class_exists($final_class_name)) {
|
||||
self::loadClass($relative_class_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
2015
modules/creativeelements/includes/base/controls-stack.php
Normal file
2015
modules/creativeelements/includes/base/controls-stack.php
Normal file
File diff suppressed because it is too large
Load Diff
1044
modules/creativeelements/includes/base/element-base.php
Normal file
1044
modules/creativeelements/includes/base/element-base.php
Normal file
File diff suppressed because it is too large
Load Diff
8
modules/creativeelements/includes/base/index.php
Normal file
8
modules/creativeelements/includes/base/index.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
header('Expires: Thu, 28 Feb 2019 00:00:00 GMT');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
|
||||
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||
header('Cache-Control: post-check=0, pre-check=0', false);
|
||||
header('Pragma: no-cache');
|
||||
header('Location: ../../../../');
|
||||
die;
|
||||
370
modules/creativeelements/includes/base/skin-base.php
Normal file
370
modules/creativeelements/includes/base/skin-base.php
Normal file
@@ -0,0 +1,370 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
/**
|
||||
* Elementor skin base.
|
||||
*
|
||||
* An abstract class to register new skins for Elementor widgets. Skins allows
|
||||
* you to add new templates, set custom controls and more.
|
||||
*
|
||||
* To register new skins for your widget use the `add_skin()` method inside the
|
||||
* widget's `_register_skins()` method.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class SkinBase
|
||||
{
|
||||
/**
|
||||
* Parent widget.
|
||||
*
|
||||
* Holds the parent widget of the skin. Default value is null, no parent widget.
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @var WidgetBase|null
|
||||
*/
|
||||
protected $parent = null;
|
||||
|
||||
/**
|
||||
* Skin base constructor.
|
||||
*
|
||||
* Initializing the skin base class by setting parent widget and registering
|
||||
* controls actions.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @param WidgetBase $parent
|
||||
*/
|
||||
public function __construct(WidgetBase $parent)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
|
||||
$this->_registerControlsActions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get skin ID.
|
||||
*
|
||||
* Retrieve the skin ID.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function getId();
|
||||
|
||||
/**
|
||||
* Get skin title.
|
||||
*
|
||||
* Retrieve the skin title.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function getTitle();
|
||||
|
||||
/**
|
||||
* Render skin.
|
||||
*
|
||||
* Generates the final HTML on the frontend.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function render();
|
||||
|
||||
/**
|
||||
* Register skin controls actions.
|
||||
*
|
||||
* Run on init and used to register new skins to be injected to the widget.
|
||||
* This method is used to register new actions that specify the location of
|
||||
* the skin in the widget.
|
||||
*
|
||||
* Example usage:
|
||||
* `add_action( 'elementor/element/{widget_id}/{section_id}/before_section_end', [ $this, 'register_controls' ] );`
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function _registerControlsActions()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get skin control ID.
|
||||
*
|
||||
* Retrieve the skin control ID. Note that skin controls have special prefix
|
||||
* to distinguish them from regular controls, and from controls in other
|
||||
* skins.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @param string $control_base_id Control base ID.
|
||||
*
|
||||
* @return string Control ID.
|
||||
*/
|
||||
protected function getControlId($control_base_id)
|
||||
{
|
||||
$skin_id = str_replace('-', '_', $this->getId());
|
||||
return $skin_id . '_' . $control_base_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get skin settings.
|
||||
*
|
||||
* Retrieve all the skin settings or, when requested, a specific setting.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @TODO: rename to get_setting() and create backward compatibility.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $control_base_id Control base ID.
|
||||
*
|
||||
* @return WidgetBase Widget instance.
|
||||
*/
|
||||
public function getInstanceValue($control_base_id)
|
||||
{
|
||||
$control_id = $this->getControlId($control_base_id);
|
||||
return $this->parent->getSettings($control_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start skin controls section.
|
||||
*
|
||||
* Used to add a new section of controls to the skin.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Section ID.
|
||||
* @param array $args Section arguments.
|
||||
*/
|
||||
public function startControlsSection($id, $args)
|
||||
{
|
||||
$args['condition']['_skin'] = $this->getId();
|
||||
$this->parent->startControlsSection($this->getControlId($id), $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* End skin controls section.
|
||||
*
|
||||
* Used to close an existing open skin controls section.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @access public
|
||||
*/
|
||||
public function endControlsSection()
|
||||
{
|
||||
$this->parent->endControlsSection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new skin control.
|
||||
*
|
||||
* Register a single control to the allow the user to set/update skin data.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Control ID.
|
||||
* @param array $args Control arguments.
|
||||
*
|
||||
* @return bool True if skin added, False otherwise.
|
||||
*/
|
||||
public function addControl($id, $args)
|
||||
{
|
||||
$args['condition']['_skin'] = $this->getId();
|
||||
return $this->parent->addControl($this->getControlId($id), $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update skin control.
|
||||
*
|
||||
* Change the value of an existing skin control.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @since 1.8.1 New `$options` parameter added.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Control ID.
|
||||
* @param array $args Control arguments. Only the new fields you want to update.
|
||||
* @param array $options Optional. Some additional options.
|
||||
*/
|
||||
public function updateControl($id, $args, array $options = [])
|
||||
{
|
||||
$args['condition']['_skin'] = $this->getId();
|
||||
$this->parent->updateControl($this->getControlId($id), $args, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove skin control.
|
||||
*
|
||||
* Unregister an existing skin control.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Control ID.
|
||||
*/
|
||||
public function removeControl($id)
|
||||
{
|
||||
$this->parent->removeControl($this->getControlId($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new responsive skin control.
|
||||
*
|
||||
* Register a set of controls to allow editing based on user screen size.
|
||||
*
|
||||
* @since 1.0.5
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Responsive control ID.
|
||||
* @param array $args Responsive control arguments.
|
||||
*/
|
||||
public function addResponsiveControl($id, $args)
|
||||
{
|
||||
$args['condition']['_skin'] = $this->getId();
|
||||
$this->parent->addResponsiveControl($this->getControlId($id), $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update responsive skin control.
|
||||
*
|
||||
* Change the value of an existing responsive skin control.
|
||||
*
|
||||
* @since 1.3.5
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Responsive control ID.
|
||||
* @param array $args Responsive control arguments.
|
||||
*/
|
||||
public function updateResponsiveControl($id, $args)
|
||||
{
|
||||
$this->parent->updateResponsiveControl($this->getControlId($id), $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove responsive skin control.
|
||||
*
|
||||
* Unregister an existing skin responsive control.
|
||||
*
|
||||
* @since 1.3.5
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Responsive control ID.
|
||||
*/
|
||||
public function removeResponsiveControl($id)
|
||||
{
|
||||
$this->parent->removeResponsiveControl($this->getControlId($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Start skin controls tab.
|
||||
*
|
||||
* Used to add a new tab inside a group of tabs.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Control ID.
|
||||
* @param array $args Control arguments.
|
||||
*/
|
||||
public function startControlsTab($id, $args)
|
||||
{
|
||||
$args['condition']['_skin'] = $this->getId();
|
||||
$this->parent->startControlsTab($this->getControlId($id), $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* End skin controls tab.
|
||||
*
|
||||
* Used to close an existing open controls tab.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*/
|
||||
public function endControlsTab()
|
||||
{
|
||||
$this->parent->endControlsTab();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start skin controls tabs.
|
||||
*
|
||||
* Used to add a new set of tabs inside a section.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Control ID.
|
||||
*/
|
||||
public function startControlsTabs($id)
|
||||
{
|
||||
// $args['condition']['_skin'] = $this->getId();
|
||||
$this->parent->startControlsTabs($this->getControlId($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* End skin controls tabs.
|
||||
*
|
||||
* Used to close an existing open controls tabs.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*/
|
||||
public function endControlsTabs()
|
||||
{
|
||||
$this->parent->endControlsTabs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new group control.
|
||||
*
|
||||
* Register a set of related controls grouped together as a single unified
|
||||
* control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $group_name Group control name.
|
||||
* @param array $args Group control arguments. Default is an empty array.
|
||||
*/
|
||||
final public function addGroupControl($group_name, $args = [])
|
||||
{
|
||||
$args['name'] = $this->getControlId($args['name']);
|
||||
$args['condition']['_skin'] = $this->getId();
|
||||
$this->parent->addGroupControl($group_name, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set parent widget.
|
||||
*
|
||||
* Used to define the parent widget of the skin.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param WidgetBase $parent Parent widget.
|
||||
*/
|
||||
public function setParent($parent)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
}
|
||||
}
|
||||
870
modules/creativeelements/includes/base/widget-base.php
Normal file
870
modules/creativeelements/includes/base/widget-base.php
Normal file
@@ -0,0 +1,870 @@
|
||||
<?php
|
||||
/**
|
||||
* Creative Elements - live Theme & Page Builder
|
||||
*
|
||||
* @author WebshopWorks, Elementor
|
||||
* @copyright 2019-2022 WebshopWorks.com & Elementor.com
|
||||
* @license https://www.gnu.org/licenses/gpl-3.0.html
|
||||
*/
|
||||
|
||||
namespace CE;
|
||||
|
||||
defined('_PS_VERSION_') or die;
|
||||
|
||||
/**
|
||||
* Elementor widget base.
|
||||
*
|
||||
* An abstract class to register new Elementor widgets. It extended the
|
||||
* `ElementBase` class to inherit its properties.
|
||||
*
|
||||
* This abstract class must be extended in order to register new widgets.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class WidgetBase extends ElementBase
|
||||
{
|
||||
const REMOTE_RENDER = false;
|
||||
|
||||
private static $render_method = 'render';
|
||||
|
||||
/**
|
||||
* Whether the widget has content.
|
||||
*
|
||||
* Used in cases where the widget has no content. When widgets uses only
|
||||
* skins to display dynamic content generated on the server.
|
||||
* Default is true, the widget has content template.
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $_has_template_content = true;
|
||||
|
||||
/**
|
||||
* Element edit tools.
|
||||
*
|
||||
* Holds all the edit tools of the element. For example: delete, duplicate etc.
|
||||
*
|
||||
* @access protected
|
||||
* @static
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected static $_edit_tools;
|
||||
|
||||
/**
|
||||
* Get element type.
|
||||
*
|
||||
* Retrieve the element type, in this case `widget`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return string The type.
|
||||
*/
|
||||
public static function getType()
|
||||
{
|
||||
return 'widget';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get widget icon.
|
||||
*
|
||||
* Retrieve the widget icon.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Widget icon.
|
||||
*/
|
||||
public function getIcon()
|
||||
{
|
||||
return 'eicon-apps';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get widget keywords.
|
||||
*
|
||||
* Retrieve the widget keywords.
|
||||
*
|
||||
* @since 1.0.10
|
||||
* @access public
|
||||
*
|
||||
* @return array Widget keywords.
|
||||
*/
|
||||
public function getKeywords()
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get widget categories.
|
||||
*
|
||||
* Retrieve the widget categories.
|
||||
*
|
||||
* @since 1.0.10
|
||||
* @access public
|
||||
*
|
||||
* @return array Widget categories.
|
||||
*/
|
||||
public function getCategories()
|
||||
{
|
||||
return ['general'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget base constructor.
|
||||
*
|
||||
* Initializing the widget base class.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @throws \Exception If arguments are missing when initializing a full widget
|
||||
* instance.
|
||||
*
|
||||
* @param array $data Widget data. Default is an empty array.
|
||||
* @param array|null $args Optional. Widget default arguments. Default is null.
|
||||
*/
|
||||
public function __construct($data = [], $args = null)
|
||||
{
|
||||
parent::__construct($data, $args);
|
||||
|
||||
$is_type_instance = $this->isTypeInstance();
|
||||
|
||||
if (!$is_type_instance && null === $args) {
|
||||
throw new \Exception('`$args` argument is required when initializing a full widget instance.');
|
||||
}
|
||||
|
||||
if ($is_type_instance) {
|
||||
$this->_registerSkins();
|
||||
|
||||
$widget_name = $this->getName();
|
||||
|
||||
/**
|
||||
* Widget skin init.
|
||||
*
|
||||
* Fires when Elementor widget is being initialized.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$widget_name`, refers to the widget name.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param WidgetBase $this The current widget.
|
||||
*/
|
||||
do_action("elementor/widget/{$widget_name}/skins_init", $this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stack.
|
||||
*
|
||||
* Retrieve the widget stack of controls.
|
||||
*
|
||||
* @since 1.9.2
|
||||
* @access public
|
||||
*
|
||||
* @param bool $with_common_controls Optional. Whether to include the common controls. Default is true.
|
||||
*
|
||||
* @return array Widget stack of controls.
|
||||
*/
|
||||
public function getStack($with_common_controls = true)
|
||||
{
|
||||
$stack = parent::getStack();
|
||||
|
||||
if ($with_common_controls && 'common' !== $this->getUniqueName()) {
|
||||
/** @var WidgetCommon $common_widget */
|
||||
$common_widget = Plugin::$instance->widgets_manager->getWidgetTypes('common');
|
||||
|
||||
$stack['controls'] = array_merge($stack['controls'], $common_widget->getControls());
|
||||
|
||||
$stack['tabs'] = array_merge($stack['tabs'], $common_widget->getTabsControls());
|
||||
}
|
||||
|
||||
return $stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get widget controls pointer index.
|
||||
*
|
||||
* Retrieve widget pointer index where the next control should be added.
|
||||
*
|
||||
* While using injection point, it will return the injection point index. Otherwise index of the last control of the
|
||||
* current widget itself without the common controls, plus one.
|
||||
*
|
||||
* @since 1.9.2
|
||||
* @access public
|
||||
*
|
||||
* @return int Widget controls pointer index.
|
||||
*/
|
||||
public function getPointerIndex()
|
||||
{
|
||||
$injection_point = $this->getInjectionPoint();
|
||||
|
||||
if (null !== $injection_point) {
|
||||
return $injection_point['index'];
|
||||
}
|
||||
|
||||
return count($this->getStack(false)['controls']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show in panel.
|
||||
*
|
||||
* Whether to show the widget in the panel or not. By default returns true.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return bool Whether to show the widget in the panel or not.
|
||||
*/
|
||||
public function showInPanel()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start widget controls section.
|
||||
*
|
||||
* Used to add a new section of controls to the widget. Regular controls and
|
||||
* skin controls.
|
||||
*
|
||||
* Note that when you add new controls to widgets they must be wrapped by
|
||||
* `start_controls_section()` and `end_controls_section()`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $section_id Section ID.
|
||||
* @param array $args Section arguments Optional.
|
||||
*/
|
||||
public function startControlsSection($section_id, array $args = [])
|
||||
{
|
||||
parent::startControlsSection($section_id, $args);
|
||||
|
||||
static $is_first_section = true;
|
||||
|
||||
if ($is_first_section) {
|
||||
$this->registerSkinControl();
|
||||
|
||||
$is_first_section = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the Skin Control if the widget has skins.
|
||||
*
|
||||
* An internal method that is used to add a skin control to the widget.
|
||||
* Added at the top of the controls section.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function registerSkinControl()
|
||||
{
|
||||
$skins = $this->getSkins();
|
||||
|
||||
if (!empty($skins)) {
|
||||
$skin_options = [];
|
||||
|
||||
if ($this->_has_template_content) {
|
||||
$skin_options[''] = __('Default');
|
||||
}
|
||||
|
||||
foreach ($skins as $skin_id => $skin) {
|
||||
$skin_options[$skin_id] = $skin->getTitle();
|
||||
}
|
||||
|
||||
// Get the first item for default value
|
||||
$default_value = array_keys($skin_options);
|
||||
$default_value = array_shift($default_value);
|
||||
|
||||
if (1 >= count($skin_options)) {
|
||||
$this->addControl(
|
||||
'_skin',
|
||||
[
|
||||
'label' => __('Skin'),
|
||||
'type' => ControlsManager::HIDDEN,
|
||||
'default' => $default_value,
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$this->addControl(
|
||||
'_skin',
|
||||
[
|
||||
'label' => __('Skin'),
|
||||
'type' => ControlsManager::SELECT,
|
||||
'default' => $default_value,
|
||||
'options' => $skin_options,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default edit tools.
|
||||
*
|
||||
* Retrieve the element default edit tools. Used to set initial tools.
|
||||
* By default the element has no edit tools.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
* @static
|
||||
*
|
||||
* @return array Default edit tools.
|
||||
*/
|
||||
protected static function getDefaultEditTools()
|
||||
{
|
||||
$widget_label = __('Widget');
|
||||
|
||||
$edit_tools = [
|
||||
'edit' => [
|
||||
'title' => __('Edit'),
|
||||
'icon' => 'edit',
|
||||
],
|
||||
];
|
||||
|
||||
if (self::isEditButtonsEnabled()) {
|
||||
$edit_tools += [
|
||||
'duplicate' => [
|
||||
/* translators: %s: Widget label */
|
||||
'title' => sprintf(__('Duplicate %s'), $widget_label),
|
||||
'icon' => 'clone',
|
||||
],
|
||||
'remove' => [
|
||||
/* translators: %s: Widget label */
|
||||
'title' => sprintf(__('Remove %s'), $widget_label),
|
||||
'icon' => 'close',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
return $edit_tools;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register widget skins.
|
||||
*
|
||||
* This method is activated while initializing the widget base class. It is
|
||||
* used to assign skins to widgets with `addSkin()` method.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* protected function _registerSkins() {
|
||||
* $this->addSkin( new SkinClassic( $this ) );
|
||||
* }
|
||||
*
|
||||
* @since 1.7.12
|
||||
* @access protected
|
||||
*/
|
||||
protected function _registerSkins()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Get initial config.
|
||||
*
|
||||
* Retrieve the current widget initial configuration.
|
||||
*
|
||||
* Adds more configuration on top of the controls list, the tabs assigned to
|
||||
* the control, element name, type, icon and more. This method also adds
|
||||
* widget type, keywords and categories.
|
||||
*
|
||||
* @since 1.0.10
|
||||
* @access protected
|
||||
*
|
||||
* @return array The initial widget config.
|
||||
*/
|
||||
protected function _getInitialConfig()
|
||||
{
|
||||
$config = [
|
||||
'widget_type' => $this->getName(),
|
||||
'keywords' => $this->getKeywords(),
|
||||
'categories' => $this->getCategories(),
|
||||
'html_wrapper_class' => $this->getHtmlWrapperClass(),
|
||||
'show_in_panel' => $this->showInPanel(),
|
||||
];
|
||||
|
||||
$stack = Plugin::$instance->controls_manager->getElementStack($this);
|
||||
|
||||
if ($stack) {
|
||||
$config['controls'] = $this->getStack(false)['controls'];
|
||||
$config['tabs_controls'] = $this->getTabsControls();
|
||||
}
|
||||
|
||||
return array_merge(parent::_getInitialConfig(), $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.3.1
|
||||
* @access protected
|
||||
*/
|
||||
protected function shouldPrintEmpty()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print widget content template.
|
||||
*
|
||||
* Used to generate the widget content template on the editor, using a
|
||||
* Backbone JavaScript template.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @param string $template_content Template content.
|
||||
*/
|
||||
protected function printTemplateContent($template_content)
|
||||
{
|
||||
$this->renderEditTools();
|
||||
?>
|
||||
<div class="elementor-widget-container"><?= $template_content ?></div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse text editor.
|
||||
*
|
||||
* Parses the content from rich text editor with shortcodes.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @param string $content Text editor content.
|
||||
*
|
||||
* @return string Parsed content.
|
||||
*/
|
||||
protected function parseTextEditor($content)
|
||||
{
|
||||
/** This filter is documented in wp-includes/widgets/class-wp-widget-text.php */
|
||||
$content = apply_filters('widget_text', $content, $this->getSettings());
|
||||
|
||||
if ('renderSmarty' === self::$render_method) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
// if ($GLOBALS['wp_embed'] instanceof \WP_Embed) {
|
||||
// $content = $GLOBALS['wp_embed']->autoembed($content);
|
||||
// }
|
||||
|
||||
return 'render' === self::$render_method ? do_shortcode($content) : $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML wrapper class.
|
||||
*
|
||||
* Retrieve the widget container class. Can be used to override the
|
||||
* container class for specific widgets.
|
||||
*
|
||||
* @since 2.0.9
|
||||
* @access protected
|
||||
*/
|
||||
protected function getHtmlWrapperClass()
|
||||
{
|
||||
return 'elementor-widget-' . $this->getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add widget render attributes.
|
||||
*
|
||||
* Used to add attributes to the current widget wrapper HTML tag.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function _addRenderAttributes()
|
||||
{
|
||||
parent::_addRenderAttributes();
|
||||
|
||||
$this->addRenderAttribute('_wrapper', 'class', [
|
||||
'elementor-widget',
|
||||
$this->getHtmlWrapperClass(),
|
||||
]);
|
||||
|
||||
$this->addRenderAttribute('_wrapper', 'data-widget_type', $this->getName() . '.' . ($this->getSettings('_skin') ?: 'default'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Render widget output on the frontend.
|
||||
*
|
||||
* Used to generate the final HTML displayed on the frontend.
|
||||
*
|
||||
* Note that if skin is selected, it will be rendered by the skin itself,
|
||||
* not the widget.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function renderContent()
|
||||
{
|
||||
if (static::REMOTE_RENDER && is_admin() && 'render' === self::$render_method) {
|
||||
return print '<div class="ce-remote-render"></div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Before widget render content.
|
||||
*
|
||||
* Fires before Elementor widget is being rendered.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param WidgetBase $this The current widget.
|
||||
*/
|
||||
do_action('elementor/widget/before_render_content', $this);
|
||||
|
||||
ob_start();
|
||||
|
||||
$skin = $this->getCurrentSkin();
|
||||
if ($skin) {
|
||||
$skin->setParent($this);
|
||||
$skin->{self::$render_method}();
|
||||
} else {
|
||||
$this->{self::$render_method}();
|
||||
}
|
||||
|
||||
$widget_content = ob_get_clean();
|
||||
|
||||
if (empty($widget_content)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Plugin::$instance->editor->isEditMode()) {
|
||||
$this->renderEditTools();
|
||||
}
|
||||
|
||||
echo '<div class="elementor-widget-container">';
|
||||
|
||||
/**
|
||||
* Render widget content.
|
||||
*
|
||||
* Filters the widget content before it's rendered.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $widget_content The content of the widget.
|
||||
* @param WidgetBase $this The widget.
|
||||
*/
|
||||
echo apply_filters('elementor/widget/render_content', $widget_content, $this); // XSS ok.
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render widget smarty template.
|
||||
*
|
||||
* @since 2.5.10
|
||||
* @access protected
|
||||
*/
|
||||
protected function renderSmarty()
|
||||
{
|
||||
$this->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render widget plain content.
|
||||
*
|
||||
* Elementor saves the page content in a unique way, but it's not the way
|
||||
* PretaShop saves data. This method is used to save generated HTML to the
|
||||
* database as plain content the PretaShop way.
|
||||
*
|
||||
* When rendering plain content, it allows other PretaShop modules to
|
||||
* interact with the content - to search, check SEO and other purposes. It
|
||||
* also allows the site to keep working even if Elementor is deactivated.
|
||||
*
|
||||
* Note that if the widget uses shortcodes to display the data, the best
|
||||
* practice is to return the shortcode itself.
|
||||
*
|
||||
* Also note that if the widget don't display any content it should return
|
||||
* an empty string.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function renderPlainContent()
|
||||
{
|
||||
$this->renderContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Before widget rendering.
|
||||
*
|
||||
* Used to add stuff before the widget `_wrapper` element.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function beforeRender()
|
||||
{
|
||||
?>
|
||||
<div <?= $this->getRenderAttributeString('_wrapper') ?>>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* After widget rendering.
|
||||
*
|
||||
* Used to add stuff after the widget `_wrapper` element.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function afterRender()
|
||||
{
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element raw data.
|
||||
*
|
||||
* Retrieve the raw element data, including the id, type, settings, child
|
||||
* elements and whether it is an inner element.
|
||||
*
|
||||
* The data with the HTML used always to display the data, but the Elementor
|
||||
* editor uses the raw data without the HTML in order not to render the data
|
||||
* again.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param bool $with_html_content Optional. Whether to return the data with
|
||||
* HTML content or without. Used for caching.
|
||||
* Default is false, without HTML.
|
||||
*
|
||||
* @return array Element raw data.
|
||||
*/
|
||||
public function getRawData($with_html_content = false)
|
||||
{
|
||||
$data = parent::getRawData($with_html_content);
|
||||
|
||||
unset($data['isInner']);
|
||||
|
||||
$data['widgetType'] = $this->getData('widgetType');
|
||||
|
||||
if ($with_html_content) {
|
||||
ob_start();
|
||||
|
||||
$this->renderContent();
|
||||
|
||||
$data['htmlCache'] = ob_get_clean();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print widget content.
|
||||
*
|
||||
* Output the widget final HTML on the frontend.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function _printContent()
|
||||
{
|
||||
$this->renderContent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default data.
|
||||
*
|
||||
* Retrieve the default widget data. Used to reset the data on initialization.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Default data.
|
||||
*/
|
||||
protected function getDefaultData()
|
||||
{
|
||||
$data = parent::getDefaultData();
|
||||
|
||||
$data['widgetType'] = '';
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default child type.
|
||||
*
|
||||
* Retrieve the widget child type based on element data.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @param array $element_data Widget ID.
|
||||
*
|
||||
* @return array|false Child type or false if it's not a valid widget.
|
||||
*/
|
||||
protected function _getDefaultChildType(array $element_data)
|
||||
{
|
||||
return Plugin::$instance->elements_manager->getElementTypes('section');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get repeater setting key.
|
||||
*
|
||||
* Retrieve the unique setting key for the current repeater item. Used to connect the current element in the
|
||||
* repeater to it's settings model and it's control in the panel.
|
||||
*
|
||||
* @since 1.8.0
|
||||
* @access protected
|
||||
*
|
||||
* @param string $setting_key The current setting key inside the repeater item (e.g. `tab_title`).
|
||||
* @param string $repeater_key The repeater key containing the array of all the items in the repeater (e.g. `tabs`).
|
||||
* @param int $repeater_item_index The current item index in the repeater array (e.g. `3`).
|
||||
*
|
||||
* @return string The repeater setting key (e.g. `tabs.3.tab_title`).
|
||||
*/
|
||||
protected function getRepeaterSettingKey($setting_key, $repeater_key, $repeater_item_index)
|
||||
{
|
||||
return implode('.', [$repeater_key, $repeater_item_index, $setting_key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add inline editing attributes.
|
||||
*
|
||||
* Define specific area in the element to be editable inline. The element can have several areas, with this method
|
||||
* you can set the area inside the element that can be edited inline. You can also define the type of toolbar the
|
||||
* user will see, whether it will be a basic toolbar or an advanced one.
|
||||
*
|
||||
* Note: When you use wysiwyg control use the advanced toolbar, with textarea control use the basic toolbar. Text
|
||||
* control should not have toolbar.
|
||||
*
|
||||
* PHP usage (inside `WidgetBase::render()` method):
|
||||
*
|
||||
* $this->addInlineEditingAttributes( 'text', 'advanced' );
|
||||
* echo '<div ' . $this->getRenderAttributeString( 'text' ) . '>' . $this->getSettings( 'text' ) . '</div>';
|
||||
*
|
||||
* @since 1.8.0
|
||||
* @access protected
|
||||
*
|
||||
* @param string $key Element key.
|
||||
* @param string $toolbar Optional. Toolbar type. Accepted values are `advanced`, `basic` or `none`. Default is
|
||||
* `basic`.
|
||||
*/
|
||||
protected function addInlineEditingAttributes($key, $toolbar = 'basic')
|
||||
{
|
||||
if (!Plugin::$instance->editor->isEditMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->addRenderAttribute($key, [
|
||||
'class' => 'elementor-inline-editing',
|
||||
'data-elementor-setting-key' => $key,
|
||||
]);
|
||||
|
||||
if ('basic' !== $toolbar) {
|
||||
$this->addRenderAttribute($key, [
|
||||
'data-elementor-inline-editing-toolbar' => $toolbar,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new skin.
|
||||
*
|
||||
* Register new widget skin to allow the user to set custom designs. Must be
|
||||
* called inside the `_register_skins()` method.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param SkinBase $skin Skin instance.
|
||||
*/
|
||||
public function addSkin(SkinBase $skin)
|
||||
{
|
||||
Plugin::$instance->skins_manager->addSkin($this, $skin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get single skin.
|
||||
*
|
||||
* Retrieve a single skin based on skin ID, from all the skin assigned to
|
||||
* the widget. If the skin does not exist or not assigned to the widget,
|
||||
* return false.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $skin_id Skin ID.
|
||||
*
|
||||
* @return string|false Single skin, or false.
|
||||
*/
|
||||
public function getSkin($skin_id)
|
||||
{
|
||||
$skins = $this->getSkins();
|
||||
if (isset($skins[$skin_id])) {
|
||||
return $skins[$skin_id];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current skin ID.
|
||||
*
|
||||
* Retrieve the ID of the current skin.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Current skin.
|
||||
*/
|
||||
public function getCurrentSkinId()
|
||||
{
|
||||
return $this->getSettings('_skin');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current skin.
|
||||
*
|
||||
* Retrieve the current skin, or if non exist return false.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return SkinBase|false Current skin or false.
|
||||
*/
|
||||
public function getCurrentSkin()
|
||||
{
|
||||
return $this->getSkin($this->getCurrentSkinId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove widget skin.
|
||||
*
|
||||
* Unregister an existing skin and remove it from the widget.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $skin_id Skin ID.
|
||||
*
|
||||
* @return WPError|true Whether the skin was removed successfully from the widget.
|
||||
*/
|
||||
public function removeSkin($skin_id)
|
||||
{
|
||||
return Plugin::$instance->skins_manager->removeSkin($this, $skin_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get widget skins.
|
||||
*
|
||||
* Retrieve all the skin assigned to the widget.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return SkinBase[]
|
||||
*/
|
||||
public function getSkins()
|
||||
{
|
||||
return Plugin::$instance->skins_manager->getSkins($this);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user