diff --git a/.github/.build-env b/.github/.build-env index 8226cbc437..a5e67b68d3 100644 --- a/.github/.build-env +++ b/.github/.build-env @@ -1,4 +1,4 @@ -BUILD_ENVIRONMENT=develop -FREE_BRANCH=develop -PRO_BRANCH=develop -EDITOR_BRANCH=dev \ No newline at end of file +BUILD_ENVIRONMENT=master +FREE_BRANCH=master +PRO_BRANCH=master +EDITOR_BRANCH=master diff --git a/admin/abstract-api.php b/admin/abstract-api.php index 76499875ec..952f007e69 100644 --- a/admin/abstract-api.php +++ b/admin/abstract-api.php @@ -38,6 +38,14 @@ protected function verifyNonce( $action ) { } } + protected function addAjaxAction($action,$callable) { + add_action( 'wp_ajax_' . Brizy_Editor::prefix($action), $callable ); + } + + protected function addNoPrivAjaxAction($action,$callable) { + add_action( 'wp_ajax_nopriv_' . Brizy_Editor::prefix($action), $callable ); + } + /** * @param int|string $name * @@ -65,4 +73,4 @@ protected function error( $code, $message ) { protected function success( $data ) { wp_send_json_success( $data ); } -} \ No newline at end of file +} diff --git a/admin/blocks/api.php b/admin/blocks/api.php index 07304d1c1a..cc3a35f2c6 100644 --- a/admin/blocks/api.php +++ b/admin/blocks/api.php @@ -111,8 +111,8 @@ public function actionDownloadBlocks() $items = array_filter($items); if (count($items) == 0) { - $this->error(404, __('There are no blocks to be archived', 'brizy' ) ); - } + $this->error(404, __('There are no blocks to be archived', 'brizy')); + } $fontManager = new Brizy_Admin_Fonts_Manager(); $zip = new Brizy_Editor_Zip_Archiver( @@ -240,7 +240,7 @@ public function actionCreateGlobalBlock() /** * @var Brizy_Editor_Post $block; */ - $block = $bockManager->createEntity($this->param('uid'), $status); + $block = $bockManager->createEntity($this->param('uid'), $status); $block->setMeta(stripslashes($this->param('meta'))); $block->set_editor_data($editorData); $block->set_needs_compile(true); @@ -380,7 +380,7 @@ public function actionUpdateGlobalBlocks() } $bockManager = new Brizy_Admin_Blocks_Manager(Brizy_Admin_Blocks_Main::CP_GLOBAL); - $blocks = $bockManager->getEntity((array)$this->param('uid')); + $blocks = $bockManager->getEntity((array)$this->param('uid')); foreach ((array)$this->param('uid') as $i => $uid) { @@ -442,11 +442,13 @@ public function actionUpdateGlobalBlocks() $block->save(); do_action('brizy_global_block_updated', $block); + } - } +} do_action('brizy_global_data_updated'); + $this->success([]); } catch (Exception $exception) { @@ -479,18 +481,19 @@ public function actionGetSavedBlocks() $this->verifyNonce(self::nonce); try { - $fields = $this->param('fields') ? $this->param('fields') : []; + $fields = $this->param('fields') ? $this->param('fields') : []; $bockManager = new Brizy_Admin_Blocks_Manager(Brizy_Admin_Blocks_Main::CP_SAVED); - $blocks = $bockManager->getEntities([ - 'paged' => (int)($this->param('page') ?: 1), + $blocks = $bockManager->getEntities([ + 'paged' => (int)($this->param('page') ?: 1), 'posts_per_page' => (int)($this->param('count') ?: -1), 'order' => $this->param('order') ?: 'ASC', 'orderby' => $this->param('orderby') ?: 'ID' - ]); - $blocks = apply_filters('brizy_get_saved_blocks', + ]);$blocks = apply_filters( + 'brizy_get_saved_blocks', $bockManager->createResponseForEntities($blocks, $fields), $fields, - $bockManager); + $bockManager + ); $this->success($blocks); } catch (Exception $exception) { $this->error(400, $exception->getMessage()); @@ -546,7 +549,7 @@ public function actionCreateSavedBlock() try { $bockManager = new Brizy_Admin_Blocks_Manager(Brizy_Admin_Blocks_Main::CP_SAVED); - $block = $bockManager->createEntity($this->param('uid')); + $block = $bockManager->createEntity($this->param('uid')); $block->setMedia(stripslashes($this->param('media'))); $block->setMeta(stripslashes($this->param('meta'))); diff --git a/admin/layouts/api.php b/admin/layouts/api.php index 8eab29d543..7a2ef8b705 100644 --- a/admin/layouts/api.php +++ b/admin/layouts/api.php @@ -41,13 +41,13 @@ protected function getRequestNonce() protected function initializeApiActions() { - $pref = 'wp_ajax_' . Brizy_Editor::prefix(); - add_action($pref . self::DOWNLOAD_LAYOUTS, array($this, 'actionDownloadLayouts')); - add_action($pref . self::GET_LAYOUT_BY_UID_ACTION, array($this, 'actionGetLayoutByUid')); - add_action($pref . self::GET_LAYOUTS_ACTION, array($this, 'actionGetLayouts')); - add_action($pref . self::CREATE_LAYOUT_ACTION, array($this, 'actionCreateLayout')); - add_action($pref . self::UPDATE_LAYOUT_ACTION, array($this, 'actionUpdateLayout')); - add_action($pref . self::DELETE_LAYOUT_ACTION, array($this, 'actionDeleteLayout')); + $pref = 'wp_ajax_'.Brizy_Editor::prefix(); + add_action($pref.self::DOWNLOAD_LAYOUTS, array($this, 'actionDownloadLayouts')); + add_action($pref.self::GET_LAYOUT_BY_UID_ACTION, array($this, 'actionGetLayoutByUid')); + add_action($pref.self::GET_LAYOUTS_ACTION, array($this, 'actionGetLayouts')); + add_action($pref.self::CREATE_LAYOUT_ACTION, array($this, 'actionCreateLayout')); + add_action($pref.self::UPDATE_LAYOUT_ACTION, array($this, 'actionUpdateLayout')); + add_action($pref.self::DELETE_LAYOUT_ACTION, array($this, 'actionDeleteLayout')); } public function actionDownloadLayouts() @@ -77,26 +77,26 @@ public function actionDownloadLayouts() return null; }, $explode); - $items = array_filter($items); + $items = array_filter($items); if (count($items) == 0) { $this->error(404, __('There are no layouts to be archived')); } - $zipPath = "Layout-" . date(DATE_ATOM) . ".zip"; + $zipPath = "Layout-".date(DATE_ATOM).".zip"; $fontManager = new Brizy_Admin_Fonts_Manager(); - $zip = new Brizy_Editor_Zip_Archiver( + $zip = new Brizy_Editor_Zip_Archiver( Brizy_Editor_Project::get(), $fontManager, BRIZY_SYNC_VERSION ); - $zipPath = $zip->createZip($items, $zipPath); + $zipPath = $zip->createZip($items, $zipPath); header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: private", false); header("Content-Type: application/octet-stream"); - header("Content-Disposition: attachment; filename=\"" . basename($zipPath) . "\";"); + header("Content-Disposition: attachment; filename=\"".basename($zipPath)."\";"); header("Content-Transfer-Encoding: binary"); echo file_get_contents($zipPath); @@ -143,18 +143,19 @@ public function actionGetLayouts() $layoutManager = new Brizy_Admin_Layouts_Manager(); $fields = $this->param('fields') ? $this->param('fields') : []; - $layouts = $layoutManager->getEntities( - [ + + $layouts = $layoutManager->getEntities([ 'paged' => (int)($this->param('page') ?: 1), 'posts_per_page' => (int)($this->param('count') ?: -1), 'order' => $this->param('order') ?: 'ASC', 'orderby' => $this->param('orderby') ?: 'ID' - ] - ); - $layouts = apply_filters('brizy_get_layouts', + ]); + $layouts = apply_filters( + 'brizy_get_layouts', $layoutManager->createResponseForEntities($layouts, $fields), $fields, - $layoutManager); + $layoutManager + ); $this->success($layouts); } catch (Exception $exception) { @@ -192,16 +193,18 @@ public function actionCreateLayout() $layout->set_editor_data($editorData); $layout->set_needs_compile(true); - if ($this->param('title')) { - $layout->setTitle(stripslashes($this->param('title'))); - } + if($this->param('title')) + { + $layout->setTitle(stripslashes($this->param('title'))); + } - if ($this->param('tags')) { - $layout->setTags(stripslashes($this->param('tags'))); - } + if($this->param('tags')) + { + $layout->setTags(stripslashes($this->param('tags'))); + } - //$layout->setCloudUpdateRequired( true ); + //$layout->setCloudUpdateRequired( true ); $layout->setDataVersion(1); $layout->save(); diff --git a/admin/main.php b/admin/main.php index 6ac2f4ac90..d92fe018d0 100755 --- a/admin/main.php +++ b/admin/main.php @@ -490,7 +490,6 @@ private function enable_brizy_for_post( $p ) { wp_update_post( $p ); } do_action( 'brizy_before_enabled_for_post', $p ); - $post->enable_editor(); $post->set_template( Brizy_Config::BRIZY_BLANK_TEMPLATE_FILE_NAME ); $post->set_plugin_version( BRIZY_VERSION ); diff --git a/admin/rules/api.php b/admin/rules/api.php index bc9f2cd528..da4529362c 100644 --- a/admin/rules/api.php +++ b/admin/rules/api.php @@ -342,7 +342,7 @@ public function getGroupList() { $groups = []; - if ( $templateType == 'single' || $templateType == 'single_product' || $context == 'popup-rules' || $context == 'global-block-rules' ) { + if ($templateType == 'single' || $templateType == 'single_product' || $context == 'popup-rules' || $context == 'global-block-rules' ) { $groups[] = array( 'title' => 'Main Content', 'value' => Brizy_Admin_Rule::POSTS, @@ -360,7 +360,7 @@ public function getGroupList() { ) : null; } - if ( $templateType == 'archive' || $templateType == 'product_archive' || $context == 'popup-rules' || $context == 'global-block-rules' ) { + if ($templateType == 'archive' || $templateType == 'product_archive' || $context == 'popup-rules' || $context == 'global-block-rules' ) { $archiveItems = array_map( $closure, $this->getArchivesList( Brizy_Admin_Rule::ARCHIVE, $templateType ) ); $taxonomyItems = array_map( $closure, $this->getTaxonomyList( Brizy_Admin_Rule::TAXONOMY, $templateType ) ); diff --git a/admin/stories/main.php b/admin/stories/main.php index fdc9aa0929..db67a9bb1b 100644 --- a/admin/stories/main.php +++ b/admin/stories/main.php @@ -59,7 +59,7 @@ static public function registerCustomPosts() 'public' => true, 'description' => __bt( 'brizy', 'Brizy' ) . ' ' . __( 'stories', 'brizy' ) . '.', 'show_in_menu' => Brizy_Admin_Settings::menu_slug(), - 'rewrite' => [ 'slug' => self::CP_STORY ], + 'rewrite' => [ 'slug' => apply_filters('brizy_story_rewrite_slug',self::CP_STORY) ], 'capability_type' => 'page', 'exclude_from_search' => true, 'supports' => [ 'title', 'post_content', 'revisions' ], diff --git a/brizy.php b/brizy.php index 3770c1393c..eb83766bd0 100755 --- a/brizy.php +++ b/brizy.php @@ -132,4 +132,4 @@ function brizy_load_text_domain() load_plugin_textdomain('brizy', false, dirname(plugin_basename(__FILE__)) . '/languages'); } -new Brizy_Compatibilities_Init(); +new Brizy_Compatibilities_Init(); \ No newline at end of file diff --git a/compatibilities/init.php b/compatibilities/init.php index 3de8ea8956..4b4273c63e 100644 --- a/compatibilities/init.php +++ b/compatibilities/init.php @@ -134,6 +134,10 @@ public function action_plugins_loaded() { if ( class_exists( 'WP_Optimize' ) ) { new Brizy_Compatibilities_WpOptimize(); } + + if ( defined( 'JETPACK__PLUGIN_FILE' ) ) { + new Brizy_Compatibilities_Jetpack(); + } } public function after_setup_theme() { diff --git a/compatibilities/jetpack.php b/compatibilities/jetpack.php new file mode 100644 index 0000000000..f06636acf2 --- /dev/null +++ b/compatibilities/jetpack.php @@ -0,0 +1,17 @@ +process( $img_url, $context ); - $url = $media_processor->process( $url, $context ); + try { + $project = Brizy_Editor_Project::get(); + $context = Brizy_Content_ContextFactory::createContext($project); + $media_processor = new Brizy_Editor_Asset_ImgProcessor(); + $domain_processor = new Brizy_Editor_Asset_DomainProcessor(); + $url = $domain_processor->process($img_url, $context); + $url = $media_processor->process($url, $context); - return $url; - } catch ( Exception $e ) { - // do nothing... :) :) - } + return $url; + } catch (Exception $e) { + // do nothing... :) :) + } - return $img_url; - } + return $img_url; + } } diff --git a/composer.json b/composer.json index a3def2d31a..3692959410 100755 --- a/composer.json +++ b/composer.json @@ -13,7 +13,7 @@ "knplabs/gaufrette": "0.7", "bagrinsergiu/brizy-migration-utils": "^1.4", "bagrinsergiu/brizy-merge-page-assets": "dev-master", - "bagrinsergiu/content-placeholder": "2.0.6", + "bagrinsergiu/content-placeholder": "^2.0.9", "enshrined/svg-sanitize": "^0.13", "select2/select2": "^4.0", "symfony/dotenv": "^3", diff --git a/composer.lock b/composer.lock index 68f813c6f4..8f2f7c3c1f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bdcbe172c58a2c591f0dfd20b08210f9", + "content-hash": "396f55004f56c13112b3cc191037766b", "packages": [ { "name": "bagrinsergiu/brizy-merge-page-assets", @@ -89,24 +89,25 @@ }, { "name": "bagrinsergiu/content-placeholder", - "version": "2.0.6", + "version": "2.0.9", "source": { "type": "git", "url": "https://github.com/bagrinsergiu/brizy-content-placeholder.git", - "reference": "ba8b64a6055615b2294f2b575e303fb3b0331d7e" + "reference": "b83a386223b21c2e38c4f38798c6426e45fdd3c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bagrinsergiu/brizy-content-placeholder/zipball/ba8b64a6055615b2294f2b575e303fb3b0331d7e", - "reference": "ba8b64a6055615b2294f2b575e303fb3b0331d7e", + "url": "https://api.github.com/repos/bagrinsergiu/brizy-content-placeholder/zipball/b83a386223b21c2e38c4f38798c6426e45fdd3c0", + "reference": "b83a386223b21c2e38c4f38798c6426e45fdd3c0", "shasum": "" }, "require": { "php": ">=5.4.0" }, "require-dev": { - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.4" + "php": ">=7.1.0", + "phpspec/prophecy-phpunit": "^2", + "phpunit/phpunit": "^9.5.9" }, "type": "library", "autoload": { @@ -122,10 +123,10 @@ "placeholders" ], "support": { - "source": "https://github.com/bagrinsergiu/brizy-content-placeholder/tree/2.0.6", + "source": "https://github.com/bagrinsergiu/brizy-content-placeholder/tree/2.0.9", "issues": "https://github.com/bagrinsergiu/brizy-content-placeholder/issues" }, - "time": "2021-12-22T12:23:25+00:00" + "time": "2023-07-05T10:53:28+00:00" }, { "name": "enshrined/svg-sanitize", @@ -443,5 +444,5 @@ "php": ">=5.6" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.2.0" } diff --git a/config.dev.php b/config.dev.php index 9bed970c51..0063b3115f 100755 --- a/config.dev.php +++ b/config.dev.php @@ -47,7 +47,7 @@ class Brizy_Config { const CLOUD_LAYOUTS = '/api/layouts'; const CLOUD_SCREENSHOT = '/screenshot/%s'; const CLOUD_SCREENSHOTS = '/api/screenshots'; - const CLOUD_CUSTOM_FILES = '/api/custom_files'; + const CLOUD_CUSTOM_FILES = '/api/custom_files'; const WP_HTTP_TIMEOUT = 600; static public function getCompilerUrls() { diff --git a/config.php b/config.php index 61237a7c7e..5fc8c84884 100755 --- a/config.php +++ b/config.php @@ -104,3 +104,39 @@ static public function getTermsOfServiceUrl() { return apply_filters( 'brizy_config_terms_of_service_url', self::TERMS_OF_SERVICE_URL ); } } + + +/* + * // input +{{ filter_option + type="input" + dataSource="manual" +}} + +// range +{{ filter_option + type="range" + dataSource="manual" +}} + +// radio +{{ filter_option + type="radio" + dataSource="manual|query" + matchQuery="entity=taxonomy&entityName=category&valueMatch[property]=name&valueMatch[value]=string&valueMatch[operation]=in|like|<|>|<=|>=|<>|=" +}} + +// checkboxes posts by property match +{{ filter_option + type="checkbox" + dataSource="manual|query" + matchQuery="entity=post&entityName=page&orderBy=name&order=ASC&valueMatch[property]=post_title&valueMatch[value]=Page&valueMatch[operation]=in|like|<|>|<=|>=|<>|=" +}} + +// checkboxes posts by meta match +{{ filter_option + type="checkbox" + dataSource="manual|query" + matchQuery="entity=post&entityName=page&valueMatch[meta]=metaName&valueMatch[value]=Page&valueMatch[operation]=in|like|<|>|<=|>=|<>|=" +}} +*/ diff --git a/content/context-factory.php b/content/context-factory.php index e45fda5803..d4e33aa854 100644 --- a/content/context-factory.php +++ b/content/context-factory.php @@ -1,60 +1,67 @@ setAuthor( $wp_post->post_author ); - } - - return $context; - } +class Brizy_Content_ContextFactory +{ + + /** + * @var Brizy_Content_Context + */ + static $globalContext = null; + + /** + * @param $project + * @param $brizy_post + * @param $wp_post + * @param $contentHtml + * + * @return Brizy_Content_Context + */ + static public function createContext($project = null, $wp_post = null, $parentContext = false) + { + $context = new Brizy_Content_Context($project, null, $wp_post, null, $parentContext); + + if ($wp_post) { + $context->setAuthor($wp_post->post_author); + } + + return apply_filters('brizy_context_create', $context, $wp_post); + } + + static public function createEmptyContext() + { + return new Brizy_Content_Context(); + } + + static public function getGlobalContext() + { + return self::$globalContext; + } + + static public function makeContextGlobal(Brizy_Content_Context $context) + { + return self::$globalContext = $context; + } + + static public function clearGlobalContext() + { + self::$globalContext = null; + } + + /** + * @param $project + * @param $wp_post + * + * @return Brizy_Content_Context + */ + private static function getContext($project, $wp_post) + { + $context = new Brizy_Content_Context($project, $wp_post); + + if ($wp_post instanceof WP_Post) { + $context->setAuthor($wp_post->post_author); + } + + return $context; + } } diff --git a/content/context.php b/content/context.php index 4e45d542b3..a04492a246 100644 --- a/content/context.php +++ b/content/context.php @@ -1,77 +1,203 @@ set( $key, $arguments[0] ); - break; - case 'get': - return $this->get( $key ); - break; - } - } - - - /** - * @param $name - * - * @return null|mixed - */ - protected function get( $name ) { - - if ( is_null( $name ) ) { - return; - } - - if ( isset( $this->data[ $name ] ) ) { - return $this->data[ $name ]; - } - - return null; - } - - public function afterExtract($contentPlaceholders, $instancePlaceholders, $contentAfterExtractor) { - $this->setPlaceholders($contentPlaceholders); +class Brizy_Content_Context implements ContextInterface +{ + + protected $data = array(); + + /** + * @var ContentPlaceholder[] + */ + protected $placeholders = []; + + + /** + * @param $name + * @param $arguments + * + * @return mixed|null + */ + public function __call($name, $arguments) + { + $method = substr($name, 0, 3); + $key = substr($name, 3); + + switch ($method) { + case 'set': + return $this->set($key, $arguments[0]); + break; + case 'get': + return $this->get($key); + break; + } + } + + + /** + * @param $name + * + * @return null|mixed + */ + protected function get($name) + { + + if (is_null($name)) { + return; + } + + if (isset($this->data[$name])) { + return $this->data[$name]; + } + + return null; + } + + public function afterExtract($contentPlaceholders, $instancePlaceholders, $contentAfterExtractor) + { + $this->setPlaceholders(array_merge($this->getPlaceholders(), $contentPlaceholders)); } /** - * @param $key - * @param $value - * - * @return null|mixed - */ - protected function set( $key, $value ) { - if ( is_null( $value ) ) { - return null; - } - - return $this->data[ $key ] = $value; - } - - /** - * BrizyPro_Content_Context constructor. - * - * @param $project - * @param $wp_post - */ - public function __construct( $project, $brizy_post, $wp_post, $contentHtml ) { - $this->setProject( $project ); - $this->setWpPost( $wp_post ); - } -} \ No newline at end of file + * @param $key + * @param $value + * + * @return null|mixed + */ + protected function set($key, $value) + { + if (is_null($value)) { + return null; + } + + return $this->data[$key] = $value; + } + + /** + * BrizyPro_Content_Context constructor. + * + * @param $project + * @param $wp_post + */ + public function __construct($project, $brizy_post, $wp_post, $contentHtml, $parentContext = null) + { + $this->setProject($project); + $this->setWpPost($wp_post); + $this->setParentContext($parentContext); + $this->setEntity($wp_post); + } + + /** + * @return array + */ + public function getPlaceholders() + { + return $this->placeholders; + } + + /** + * @param array $placeholders + * + * @return Brizy_Content_Context + */ + public function setPlaceholders(array $placeholders) + { + $this->placeholders = $placeholders; + + return $this; + } + + /** + * @param $id + * + * @return mixed|null + */ + public function getPlaceholderById($id) + { + $results = $this->getPlaceholdersByAttrValue('id', $id); + + return isset($results[0]) ? $results[0] : null; + } + + public function getPlaceholderByNameAndId($name, $id) + { + if (isset($this->placeholders)) { + foreach ($this->placeholders as $placeholder) { + if ($placeholder->getName() == $name && $placeholder->getAttribute('id') == $id) { + return $placeholder; + } + } + } + return null; + } + + /** + * @param $key + * @param $value + * + * @return array|null + */ + public function getPlaceholdersByAttrValue($key, $value) + { + if (is_null($value)) { + return null; + } + + $results = []; + if (isset($this->placeholders)) { + foreach ($this->placeholders as $placeholder) { + if ($placeholder->getAttribute($key) == $value) { + $results[] = $placeholder; + } + } + } + + if ($context = $this->getParentContext()) { + $results = array_merge($results, $context->getPlaceholdersByAttrValue($key, $value)); + } + + return $results; + } + + /** + * @return array + */ + public function getProvider() + { + if ($provider = $this->get('Provider')) { + return $provider; + } + + if ($parentContext = $this->getParentContext()) { + return $parentContext->getProvider(); + } + + return null; + } + + /** + * @param $attributes + * + * @return Brizy_Content_ContentPlaceholder|null + */ + public function getPlaceholderByAttrValues($attributes) + { + + if (isset($this->placeholders)) { + foreach ($this->placeholders as $placeholder) { + if (count(array_intersect($placeholder->getAttributes(), $attributes)) == count($attributes)) { + return $placeholder; + } + } + } + + if ($context = $this->getParentContext()) { + return $context->getPlaceholderByAttrValues($attributes); + } + + return null; + } +} diff --git a/content/dynamic-content-processor.php b/content/dynamic-content-processor.php index 3b24270cf6..8062e16792 100644 --- a/content/dynamic-content-processor.php +++ b/content/dynamic-content-processor.php @@ -3,27 +3,71 @@ use BrizyPlaceholders\Extractor; use BrizyPlaceholders\Replacer; -class Brizy_Content_DynamicContentProcessor implements Brizy_Editor_Content_ProcessorInterface { +class Brizy_Content_DynamicContentProcessor implements Brizy_Editor_Content_ProcessorInterface +{ - /** - * @param string $content - * @param Brizy_Content_Context $context - * - * @return mixed - */ - public function process( $content, Brizy_Content_Context $context ) { + /** + * @param string $content + * @param Brizy_Content_Context $context + * + * @return mixed + */ + public function process($targetContent, Brizy_Content_Context $context) + { - $placeholderProvider = new Brizy_Content_PlaceholderProvider( $context ); - $extractor = new Extractor( $placeholderProvider ); + $placeholderProvider = new Brizy_Content_PlaceholderProvider($context); + $extractor = new Extractor($placeholderProvider); - $context->setProvider( $placeholderProvider ); + $context->setProvider($placeholderProvider); - list( $contentPlaceholders, $placeholderInstances, $content ) = $extractor->extract( $content ); + list($contentPlaceholders, $placeholderInstances, $content) = $extractor->extract($targetContent); - $replacer = new Replacer( $placeholderProvider ); + if (count($contentPlaceholders) > 0) { + $context->setPlaceholders($contentPlaceholders); - $content = $replacer->replaceWithExtractedData( $contentPlaceholders, $placeholderInstances, $content ,$context); + // load all page placeholders + $postContent = $this->getBrizyPostContent( + $context->getProject(), + Brizy_Editor_Post::get($context->getWpPost()) + ); + if ($targetContent != $postContent) { + /** + * @var \BrizyPlaceholders\ContentPlaceholder[] $contentPlaceholders ; + */ + list($newContentPlaceholders, $newPlaceholderInstances, $newPostContent) = $extractor->extract($postContent); - return $content; - } + $context->afterExtract($newContentPlaceholders, $newPlaceholderInstances, $newPostContent); + } + + $replacer = new Replacer($placeholderProvider); + $content = $replacer->replaceWithExtractedData( + $contentPlaceholders, + $placeholderInstances, + $content, + $context + ); + } + + return $content; + } + + + private function getBrizyPostContent(Brizy_Editor_Project $project, Brizy_Editor_Post $post) + { + if($post->get_needs_compile()) + { + $post->compile_page(); + } + + if ( ! $post->get_compiled_html()) { + $compiled_html_body = $post->get_compiled_html_body(); + $content = Brizy_SiteUrlReplacer::restoreSiteUrl($compiled_html_body); + $post->set_needs_compile(true)->saveStorage(); + } else { + $compiled_page = $post->get_compiled_page(); + $content = $compiled_page->getBody(); + } + + return $content; + } } diff --git a/content/main-processor.php b/content/main-processor.php index 1e2a04850c..25ef2d6ac7 100644 --- a/content/main-processor.php +++ b/content/main-processor.php @@ -28,6 +28,24 @@ public function __construct( Brizy_Content_Context $context ) { $this->processors[] = new Brizy_Editor_Asset_MediaProcessor(); $this->processors = apply_filters( 'brizy_content_processors', $this->processors, $context ); + + /* CODE BEFORE REBASE. + $urlBuilder = new Brizy_Editor_UrlBuilder( $context->getProject(), $context->getWpPost() ? $context->getWpPost()->ID : null ); + $asset_storage = new Brizy_Editor_Asset_AssetProxyStorage( $urlBuilder ); + $media_storage = new Brizy_Editor_Asset_MediaProxyStorage( $urlBuilder ); + + $this->processors[] = new Brizy_Editor_Asset_AssetProxyProcessor( $asset_storage ); + $this->processors[] = new Brizy_Editor_Asset_MediaAssetProcessor( $media_storage ); + $this->processors[] = new Brizy_Editor_Asset_SvgAssetProcessor( ); + + $this->processors = apply_filters( 'brizy_content_processors', $this->processors, $context ); + + array_unshift( $this->processors, + new Brizy_Editor_Asset_DomainProcessor(), + new Brizy_Content_ShortcodeToPlaceholderProcessor(), + new Brizy_Content_DynamicContentProcessor() + ); + */ } /** diff --git a/content/placeholder-extractor.php b/content/placeholder-extractor.php index 3528a6adf6..62c7d0fafb 100644 --- a/content/placeholder-extractor.php +++ b/content/placeholder-extractor.php @@ -27,7 +27,7 @@ public function __construct($provider) private static function getPlaceholderRegexExpression() { - return "/(?{{\s*(?.+?)(?(?:\s+)((?:\w+\s*=\s*(?:'|\"|\"|\')(?:.[^\"']*|)(?:'|\"|\"|\')\s*)*))?}}(?:(?.*?){{\s*end_(\g{placeholderName})\s*}})?)/ims";; + return "/(?{{\s*(?.+?)\s*(?(?:\s+)((?:\w+(?:\[(?:\w+)?\])?\s*=\s*(?:'|\"|\"|\')(?:.[^\"']*|)(?:'|\"|\"|\')\s*)*))?}}(?:(?.*?){{\s*end_(\g{placeholderName})\s*}})?)/ims"; } public static function stripPlaceholders($content) @@ -96,11 +96,24 @@ private function getPlaceholderAttributes($attributeString) $attrString = trim($attributeString); $attrMatches = array(); $attributes = array(); - preg_match_all("/(\w+)\s*=\s*(?'|\"|\"|\')(.*?)(\g{quote})/mi", $attrString, $attrMatches); + preg_match_all("/((?\w+)(?\[(?\w+)?\])?)\s*=\s*(?'|\"|\"|\')(?.*?)(\g{quote})/mi", $attrString, $attrMatches); if (isset($attrMatches[0]) && is_array($attrMatches[0])) { - foreach ($attrMatches[1] as $i => $name) { - $attributes[$name] = $attrMatches[3][$i]; + foreach ($attrMatches[0] as $i => $attStr) { + $attrName = $attrMatches['attr_name'][$i]; + $attrValue = urldecode($attrMatches['attr_value'][$i]); + $isArray = $attrMatches['array'][$i]!=''; + $arrayKey = $attrMatches['array_key'][$i]; + // check if the attribute is an array + if($isArray) + { + if($arrayKey) + $attributes[$attrName][$arrayKey] = $attrValue; + else + $attributes[$attrName][] = $attrValue; + } else { + $attributes[$attrName] = $attrValue; + } } } diff --git a/content/placeholder-provider.php b/content/placeholder-provider.php index 89935d0217..7e58bdc0f1 100644 --- a/content/placeholder-provider.php +++ b/content/placeholder-provider.php @@ -3,107 +3,104 @@ use BrizyPlaceholders\PlaceholderInterface; use BrizyPlaceholders\RegistryInterface; -class Brizy_Content_PlaceholderProvider implements RegistryInterface { - - /** - * @var array of implements Brizy_Editor_Content_PlaceholdersProviderInterface - */ - protected $providers = array(); - - /** - * @var array - */ - static private $cache_grouped_placeholders = null; - static private $cache_all_placeholders = null; - - /** - * BrizyPro_Content_ProviderPlaceholders constructor. - * - * $context: for back compatibility - * - * @param Brizy_Content_Context $context - */ - public function __construct( $context = null ) { - $this->providers[] = new Brizy_Content_Providers_FreeProvider(); - $this->providers = apply_filters( 'brizy_providers', $this->providers, null ); - } - - /** - * @return array - */ - public function getPlaceholders() { - $out = array(); - - if ( self::$cache_all_placeholders ) { - return self::$cache_all_placeholders; - } - - foreach ( $this->providers as $provider ) { - $out = array_merge( $out, $provider->getPlaceholders() ); - } - - self::$cache_all_placeholders = $out; - - return $out; - } - - - /** - * @return array - */ - public function getGroupedPlaceholders() { - if ( self::$cache_grouped_placeholders ) { - return self::$cache_grouped_placeholders; - } - - $result = array(); - - foreach ( $this->providers as $provider ) { - - foreach ( $provider->getPlaceholders() as $placeholder ) { - - if ( $placeholder->getGroup() ) { - $result[ $placeholder->getGroup() ][] = $placeholder; - } - } - } - - return apply_filters( 'brizy_placeholders', self::$cache_grouped_placeholders = $result ); - } - - public function getGroupedPlaceholdersForApiResponse() { - $groups = $this->getGroupedPlaceholders(); - $result = []; - foreach ( $groups as $group => $entries ) { - - $result[ $group ] = array_map( function ( $entry ) { - - $placeholder = [ - 'placeholder' => '{{' . $entry->getPlaceholder() . '}}', - 'label' => $entry->getLabel(), - 'display' => $entry->getDisplay() - ]; - - return apply_filters( 'editor_placeholder_data', $placeholder, $entry ); - }, $entries ); - } - - return $result; - } - - /** - * @param $name - * - * @return \BrizyPlaceholders\PlaceholderInterface - */ +class Brizy_Content_PlaceholderProvider implements RegistryInterface +{ + + /** + * @var array of implements Brizy_Editor_Content_PlaceholdersProviderInterface + */ + protected $providers = array(); + + /** + * @var array + */ + static private $cache_grouped_placeholders = null; + static private $cache_all_placeholders = null; + + /** + * BrizyPro_Content_ProviderPlaceholders constructor. + * + * $context: for back compatibility + * + * @param Brizy_Content_Context $context + */ + public function __construct($context = null) + { + $this->providers[] = new Brizy_Content_Providers_FreeProvider(); + $this->providers = apply_filters('brizy_providers', $this->providers, null); + } + + /** + * @return array + */ + public function getPlaceholders() + { + + + if (self::$cache_all_placeholders) { + return self::$cache_all_placeholders; + } + $out = []; + foreach ($this->providers as $provider) { + $out = array_merge($out, $provider->getPlaceholders()); + } + + self::$cache_all_placeholders = $out; + + return $out; + } + + + /** + * @return array + */ + public function getGroupedPlaceholders() + { + if (self::$cache_grouped_placeholders) { + return self::$cache_grouped_placeholders; + } + + $result = array(); + + foreach ($this->providers as $provider) { + + foreach ($provider->getPlaceholders() as $placeholder) { + + if ($placeholder->getGroup()) { + $result[$placeholder->getGroup()][] = $placeholder; + } + } + } + + return apply_filters('brizy_placeholders', self::$cache_grouped_placeholders = $result); + } + + public function getGroupedPlaceholdersForApiResponse() + { + $groups = $this->getGroupedPlaceholders(); + $result = []; + foreach ($groups as $group => $entries) { + $result[$group] = array_map(function (PlaceholderInterface $entry) { + return apply_filters('editor_placeholder_data', $entry->getConfigStructure(), $entry); + }, $entries); + } + + return $result; + } + + /** + * @param $name + * + * @return \BrizyPlaceholders\PlaceholderInterface + */ // public function getPlaceholder($name) // { // return $this->getPlaceholderSupportingName($name); // } - /** - * @inheritDoc - */ + /** + * @inheritDoc + */ // public function getPlaceholdersByGroup($groupName) // { // $getGroupedPlaceholders = $this->getGroupedPlaceholders(); @@ -113,18 +110,20 @@ public function getGroupedPlaceholdersForApiResponse() { // } // } - /** - * @inheritDoc - */ - public function getPlaceholderSupportingName( $name ) { - foreach ( $this->providers as $provider ) { - if ( $instance = $provider->getPlaceholderSupportingName( $name ) ) { - return $instance; - } - } - } - - public function registerPlaceholder( PlaceholderInterface $instance ) { - throw new Exception( 'Try to use a specific registry to register the placeholder' ); - } + /** + * @inheritDoc + */ + public function getPlaceholderSupportingName($name) + { + foreach ($this->providers as $provider) { + if ($instance = $provider->getPlaceholderSupportingName($name)) { + return $instance; + } + } + } + + public function registerPlaceholder(PlaceholderInterface $instance) + { + throw new Exception('Try to use a specific registry to register the placeholder'); + } } diff --git a/content/placeholder-replacer.php b/content/placeholder-replacer.php index 063f123f36..a30aa448d7 100644 --- a/content/placeholder-replacer.php +++ b/content/placeholder-replacer.php @@ -19,9 +19,12 @@ class Brizy_Content_PlaceholderReplacer { * * @param $context * @param $placeholderProvider + * @param $extractor */ - public function __construct( $context, $placeholderProvider ) { + public function __construct( $context, $placeholderProvider, $extractor ) { + $this->context = $context; $this->placeholderProvider = $placeholderProvider; + $this->placeholderExtractor = $extractor; } /** @@ -31,37 +34,46 @@ public function __construct( $context, $placeholderProvider ) { * * @return string|string[] */ - public function getContent( $placeholders, $content, $context= null) { + public function getContent( $content) { $toReplace = array(); $toReplaceWithValues = array(); + list( $placeholders, $acontent ) = $this->placeholderExtractor->extract( $content ); - if(!$context) + if(!$this->context) { - $context = Brizy_Content_ContextFactory::createEmptyContext(); + $this->context = Brizy_Content_ContextFactory::createEmptyContext(); } + // set the placeholders found at this level + $this->context->setPlaceholders($placeholders); + if ( $placeholders ) { foreach ( $placeholders as $contentPlaceholder ) { try { $placeholder = $this->placeholderProvider->getPlaceholder( $contentPlaceholder->getName() ); if ( $placeholder ) { $toReplace[] = $contentPlaceholder->getUid(); - $toReplaceWithValues[] = $placeholder->getValue( $context , $contentPlaceholder ); + $toReplaceWithValues[] = $placeholder->getValue( $this->context , $contentPlaceholder ); } else { $toReplace[] = $contentPlaceholder->getPlaceholder(); $toReplaceWithValues[] = ''; } } catch ( Exception $e ) { + + if (defined('WP_DEBUG') && true === WP_DEBUG) { + var_dump($e); + } + continue; } } } - $content = str_replace( $toReplace, $toReplaceWithValues, $content ); + $acontent = str_replace( $toReplace, $toReplaceWithValues, $acontent ); - return $content; + return $acontent; } } diff --git a/content/placeholders/abstract.php b/content/placeholders/abstract.php index a9ef478087..4f159381bc 100644 --- a/content/placeholders/abstract.php +++ b/content/placeholders/abstract.php @@ -1,34 +1,40 @@ getPlaceholder()==$placeholderName; + public function getUniqueId() + { + return md5(get_class($this)); + } + + public function getConfigStructure() + { + return [ + 'id' => $this->getUniqueId(), + 'label' => $this->getLabel(), + 'name' => $this->getPlaceholder(), + 'placeholder' => $this->buildPlaceholder(), + 'display' => $this->getDisplay(), + 'attr' => (object)$this->getAttributes() + ]; + } + + public function support($placeholderName) + { + return $this->getPlaceholder() == $placeholderName; } public function shouldFallbackValue($value, ContextInterface $context, ContentPlaceholder $placeholder) { - return empty($value); + return is_null($value) || $value===""; } public function getFallbackValue(ContextInterface $context, ContentPlaceholder $placeholder) { $attributes = $placeholder->getAttributes(); + return isset($attributes[PlaceholderInterface::FALLBACK_KEY]) ? $attributes[PlaceholderInterface::FALLBACK_KEY] : ''; } /** - * @return mixed - */ - public function getLabel() { - return $this->label; - } - - /** - * @param mixed $label - * - * @return Brizy_Content_Placeholders_Abstract - */ - public function setLabel( $label ) { - $this->label = $label; - - return $this; - } - - /** - * @return string - */ - public function getDisplay() { - return $this->display; - } - - /** - * @param string $display - * - * @return Brizy_Content_Placeholders_Abstract - */ - public function setDisplay( $display ) { - $this->display = $display; - - return $this; - } + * @return mixed + */ + public function getLabel() + { + return $this->label; + } + + /** + * @param mixed $label + * + * @return Brizy_Content_Placeholders_Abstract + */ + public function setLabel($label) + { + $this->label = $label; + + return $this; + } + + /** + * @return string + */ + public function getDisplay() + { + return $this->display; + } + + /** + * @param string $display + * + * @return Brizy_Content_Placeholders_Abstract + */ + public function setDisplay($display) + { + $this->display = $display; + + return $this; + } /** * @return string @@ -98,62 +127,106 @@ public function getGroup() /** * @param string $group + * * @return Brizy_Content_Placeholders_Abstract */ public function setGroup($group) { $this->group = $group; + + return $this; + } + + /** + * @return mixed + */ + public function getPlaceholder() + { + return $this->placeholder; + } + + /** + * @param mixed $placeholder + * + * @return Brizy_Content_Placeholders_Abstract + */ + public function setPlaceholder($placeholder) + { + $this->placeholder = $placeholder; + return $this; } - /** - * @return mixed - */ - public function getPlaceholder() { - return $this->placeholder; - } - - /** - * @param mixed $placeholder - * - * @return Brizy_Content_Placeholders_Abstract - */ - public function setPlaceholder( $placeholder ) { - $this->placeholder = $placeholder; - - return $this; - } - - /** - * @return array - */ - public function convertToOptionValue() { - return array( - 'label' => $this->getLabel(), - 'placeholder' => $this->getPlaceholder(), - 'display' => $this->getDisplay(), - ); - } - - public function jsonSerialize() { - return array( - 'label' => $this->getLabel(), - 'placeholder' => $this->getReplacePlaceholder(), - 'display' => $this->getDisplay(), - ); - } - - /** - * @return string - */ - public function getReplacePlaceholder() { - $placeholder = $this->getPlaceholder(); - - if ( ! empty( $placeholder ) ) { - return "{{" . $placeholder . "}}"; - } - - return ""; - } + public function getAttributes() + { + return $this->attributes; + } + + public function setAttributes($attributes) + { + return $this->attributes = (array)$attributes; + } + + public function getEntity(ContentPlaceholder $placeholder) + { + if (($entityType = $placeholder->getAttribute('type')) && ($entityId = $placeholder->getAttribute('id'))) { + + if ($this->is_post_type($entityType)) { + return get_post((int)$entityId); + } + if ($entityType == "WP_User") { + return get_user_by('ID', $entityId); + } + + if ($entityType == "WP_Term") { + return get_term((int)$entityId); + } + } + + return null; + } + + /** + * @return array + */ + public function convertToOptionValue() + { + return array( + 'label' => $this->getLabel(), + 'placeholder' => $this->getPlaceholder(), + 'display' => $this->getDisplay(), + ); + } + + public function jsonSerialize() + { + return array( + 'label' => $this->getLabel(), + 'placeholder' => $this->getReplacePlaceholder(), + 'display' => $this->getDisplay(), + ); + } + + /** + * @return string + */ + public function getReplacePlaceholder($attributes = []) + { + return $this->buildPlaceholder($attributes); + } + + private function is_post_type($post = null) + { + $all_custom_post_types = get_post_types(); + + // there are no custom post types + if (empty ($all_custom_post_types)) { + return false; + } + + $custom_types = array_keys($all_custom_post_types); + + return in_array($post, $custom_types); + } } diff --git a/content/placeholders/ignore-dc.php b/content/placeholders/ignore-dc.php new file mode 100644 index 0000000000..64a1da7c31 --- /dev/null +++ b/content/placeholders/ignore-dc.php @@ -0,0 +1,40 @@ +setLabel($label); + $this->setPlaceholder('brizy_dc_ignore_dc'); + $this->setDisplay($display); + $this->setGroup($group); + } + + /** + * @param ContextInterface $context + * @param ContentPlaceholder $placeholder + * + * @return mixed + */ + public function getValue(ContextInterface $context, ContentPlaceholder $placeholder) + { + return $placeholder->getContent(); + } +} \ No newline at end of file diff --git a/content/placeholders/permalink.php b/content/placeholders/permalink.php index 0d669d034e..3fa415e9d8 100644 --- a/content/placeholders/permalink.php +++ b/content/placeholders/permalink.php @@ -2,33 +2,42 @@ use BrizyPlaceholders\ContentPlaceholder; -class Brizy_Content_Placeholders_Permalink extends Brizy_Content_Placeholders_Simple { - - - /** - * Brizy_Content_Placeholders_Simple constructor. - * - * @param $label - * @param $placeholder - * @param $value - * @param string $display - */ - public function __construct() { - parent::__construct( 'Permalink', 'brizy_dc_permalink', null ); - } - - /** - * @param ContentPlaceholder $contentPlaceholder - * @param Brizy_Content_Context $context - * - * @return mixed|string - */ - public function getValue(\BrizyPlaceholders\ContextInterface $context, ContentPlaceholder $contentPlaceholder) { - $attributes = $contentPlaceholder->getAttributes(); - if ( isset( $attributes['post_id'] ) && (int) $attributes['post_id'] > 0 ) { - return get_permalink( (int) $attributes['post_id'] ); - } - - return ''; - } +class Brizy_Content_Placeholders_Permalink extends Brizy_Content_Placeholders_Simple +{ + + + /** + * Brizy_Content_Placeholders_Simple constructor. + * + * @param $label + * @param $placeholder + * @param $value + * @param string $display + */ + public function __construct() + { + parent::__construct('Permalink', 'brizy_dc_permalink', null); + } + + /** + * @param ContentPlaceholder $contentPlaceholder + * @param Brizy_Content_Context $context + * + * @return mixed|string + */ + public function getValue(\BrizyPlaceholders\ContextInterface $context, ContentPlaceholder $contentPlaceholder) + { + $attributes = $contentPlaceholder->getAttributes(); + + if ($entity = $this->getEntity($contentPlaceholder)) { + return get_permalink($entity->post_id); + } + + + if (isset($attributes['post_id']) && (int)$attributes['post_id'] > 0) { + return get_permalink((int)$attributes['post_id']); + } + + return ''; + } } \ No newline at end of file diff --git a/content/placeholders/simple-post-aware.php b/content/placeholders/simple-post-aware.php new file mode 100644 index 0000000000..0a4b38417a --- /dev/null +++ b/content/placeholders/simple-post-aware.php @@ -0,0 +1,45 @@ +getAttribute('post_id'); + + if ($postId) { + $newContext = Brizy_Content_ContextFactory::createContext( + $context->getProject(), + null, + get_post($postId), + null, + false + ); + + return parent::getValue($newContext, $contentPlaceholder); + } + + if ( ! $context->getWpPost()) { + return; + } + + return parent::getValue($context, $contentPlaceholder); + } + + /** + * @return mixed|string + */ + protected function getOptionValue() + { + return $this->getReplacePlaceholder(); + } +} \ No newline at end of file diff --git a/content/placeholders/simple.php b/content/placeholders/simple.php index 4c19469256..3a00fbb529 100644 --- a/content/placeholders/simple.php +++ b/content/placeholders/simple.php @@ -5,7 +5,6 @@ class Brizy_Content_Placeholders_Simple extends Brizy_Content_Placeholders_Abstract { - /** * @return string|callable */ @@ -19,13 +18,13 @@ class Brizy_Content_Placeholders_Simple extends Brizy_Content_Placeholders_Abstr * @param $value * @param string $display */ - public function __construct($label, $placeholder, $value, $group = null, $display = Brizy_Content_Placeholders_Abstract::DISPLAY_INLINE) + public function __construct($label, $placeholder, $value, $group = null, $display = Brizy_Content_Placeholders_Abstract::DISPLAY_INLINE, $attrs = []) { $this->setLabel($label); $this->setPlaceholder($placeholder); $this->setDisplay($display); $this->setGroup($group); - + $this->setAttributes($attrs); $this->value = $value; } @@ -40,7 +39,7 @@ public function getValue(ContextInterface $context, ContentPlaceholder $placehol $method = $this->value; if (is_object($method) && ($method instanceof Closure)) { - return call_user_func($method, $context, $placeholder); + return call_user_func($method, $context, $placeholder, $this->getEntity($placeholder)); } return $this->value; diff --git a/content/placeholders/unique-page-url.php b/content/placeholders/unique-page-url.php index 28b3f89988..4d1b730d5a 100644 --- a/content/placeholders/unique-page-url.php +++ b/content/placeholders/unique-page-url.php @@ -39,7 +39,10 @@ public function getValue(\BrizyPlaceholders\ContextInterface $context, ContentPl add_filter( 'pre_term_link', $closure ); - $object = get_queried_object(); + if(!($object = $this->getEntity($contentPlaceholder))) + { + $object = get_queried_object(); + } if(is_archive()) { $url = add_query_arg($wp->query_vars, home_url() ); diff --git a/content/providers/free-provider.php b/content/providers/free-provider.php index b4772096ec..1e00a8005c 100644 --- a/content/providers/free-provider.php +++ b/content/providers/free-provider.php @@ -3,358 +3,294 @@ use BrizyPlaceholders\ContentPlaceholder; use \BrizyPlaceholders\Registry; -class Brizy_Content_Providers_FreeProvider extends Brizy_Content_Providers_AbstractProvider -{ - public function __construct() { - - $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple( 'Internal Display Block By User Role', 'display_by_roles', function ( Brizy_Content_Context $context, ContentPlaceholder $contentPlaceholder ) { - - $attrs = $contentPlaceholder->getAttributes(); - - if ( ! empty( $attrs['roles'] ) ) { - $roles = explode( ',', $attrs['roles'] ); - $userRoles = (array) wp_get_current_user()->roles; - - if ( in_array( 'logged', $roles ) && is_user_logged_in() ) { - $userRoles[] = 'logged'; - } - - if ( Brizy_Editor_User::is_user_allowed() ) { - - if ( ! empty( $_GET['role'] ) ) { - - if ( $_GET['role'] === 'default' ) { - $roles[] = 'default'; - $userRoles[] = 'default'; - } else { - $userRoles = []; - - if ( $_GET['role'] == 'not_logged' ) { - - if ( in_array( 'not_logged', $roles ) ) { - $roles[] = 'default'; - $userRoles[] = 'default'; - } - } else { - $userRoles[] = $_GET['role']; - } - } - } - } - - if ( in_array( 'not_logged', $roles ) ) { +class Brizy_Content_Providers_FreeProvider extends Brizy_Content_Providers_AbstractProvider { + public function __construct() { + + $this->registerPlaceholder( + + new Brizy_Content_Placeholders_Simple( 'Internal Display Block By User Role', 'display_by_roles', function( Brizy_Content_Context $context, ContentPlaceholder $contentPlaceholder ) { + + $attrs = $contentPlaceholder->getAttributes(); + + if ( ! empty( $attrs['roles'] ) ) { + $roles = explode( ',', $attrs['roles'] ); + $userRoles = (array) wp_get_current_user()->roles; + + if ( in_array( 'logged', $roles ) && is_user_logged_in() ) { + $userRoles[] = 'logged'; + } + + if ( Brizy_Editor_User::is_user_allowed() ) { + + if ( ! empty( $_GET['role'] ) ) { + + if ( $_GET['role'] === 'default' ) { + $roles[] = 'default'; + $userRoles[] = 'default'; + } else { + $userRoles = []; + + if ( $_GET['role'] == 'not_logged' ) { + + if ( in_array( 'not_logged', $roles ) ) { + $roles[] = 'default'; + $userRoles[] = 'default'; + } + } else { + $userRoles[] = $_GET['role']; + } + } + } + } + + if ( in_array( 'not_logged', $roles ) ) { + + $roles = array_diff( $roles, [ 'not_logged' ] ); + + if ( is_user_logged_in() ) { + if ( ! array_intersect( $roles, $userRoles ) ) { + return ''; + } + } + } else { + if ( ! array_intersect( $roles, $userRoles ) ) { + return ''; + } + } + } + + $replacer = new \BrizyPlaceholders\Replacer( $context->getProvider() ); + + return $replacer->replacePlaceholders( $contentPlaceholder->getContent(), $context ); + } ) ); + $this->registerPlaceholder( new Brizy_Content_Placeholders_ImageTitleAttribute( 'Internal Title Attributes', 'brizy_dc_image_title' ) ); + $this->registerPlaceholder( new Brizy_Content_Placeholders_ImageAltAttribute( 'Internal Alt Attributes', 'brizy_dc_image_alt' ) ); + $this->registerPlaceholder( new Brizy_Content_Placeholders_UniquePageUrl( 'Uniquer page url', 'brizy_dc_current_page_unique_url' ) ); + $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple( 'WP Language', 'brizy_dc_page_language', get_locale() ) ); + $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple( 'Ajax Url', 'brizy_dc_ajax_url', admin_url( 'admin-ajax.php' ) ) ); + $this->registerPlaceholder( new Brizy_Content_Placeholders_SimplePostAware('Permalink', 'brizy_dc_permalink',function ( $context, $contentPlaceholder ) { + return get_permalink( (int)$context->getWpPost()->ID ); + }) ); + $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple( '', 'editor_sidebar', function ( $context, $contentPlaceholder ) { - $roles = array_diff( $roles, [ 'not_logged' ] ); + $attrs = $contentPlaceholder->getAttributes(); - if ( is_user_logged_in() ) { - if ( ! array_intersect( $roles, $userRoles ) ) { - return ''; - } - } - } else { - if ( ! array_intersect( $roles, $userRoles ) ) { - return ''; - } - } - } + $id = isset( $attrs['id'] ) ? $attrs['id'] : null; - $replacer = new \BrizyPlaceholders\Replacer( $context->getProvider() ); + if ( $id ) { + ob_start(); - return $replacer->replacePlaceholders( $contentPlaceholder->getContent(), $context ); - } ) ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_ImageTitleAttribute('Internal Title Attributes', 'brizy_dc_image_title') ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_ImageAltAttribute('Internal Alt Attributes', 'brizy_dc_image_alt') ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_UniquePageUrl('Uniquer page url', 'brizy_dc_current_page_unique_url') ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple('WP Language', 'brizy_dc_page_language', get_locale()) ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple('Ajax Url', 'brizy_dc_ajax_url', admin_url('admin-ajax.php')) ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_Permalink() ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple('', 'editor_sidebar', function ($context, $contentPlaceholder) { + dynamic_sidebar( $id ); - $attrs = $contentPlaceholder->getAttributes(); + return ob_get_clean(); + } - $id = isset($attrs['id']) ? $attrs['id'] : null; + return ''; + } ) ); + $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple( '', 'editor_navigation', function ( $context, $contentPlaceholder ) { - if ($id) { - ob_start(); + $attrs = $contentPlaceholder->getAttributes(); - dynamic_sidebar($id); + return $attrs['name'] ? wp_nav_menu( array( 'menu' => $attrs['name'], 'echo' => false ) ) : ''; + } ) ); - return ob_get_clean(); - } + $this->registerPlaceholder( new Brizy_Content_Placeholders_SimplePostAware( '', 'editor_post_field', function ( $context, $contentPlaceholder ) { - return ''; - }) ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple('', 'editor_navigation', function ($context, $contentPlaceholder) { + $attrs = $contentPlaceholder->getAttributes(); - $attrs = $contentPlaceholder->getAttributes(); + $post = $context->getWpPost(); - return $attrs['name'] ? wp_nav_menu(array('menu' => $attrs['name'], 'echo' => false)) : ''; - }) ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple('', 'editor_post_field', function ($context, $contentPlaceholder) { + if ( ! $post || ! isset( $attrs['property'] ) ) { + return ''; + } - $attrs = $contentPlaceholder->getAttributes(); + return $this->filterData( $attrs['property'], $post ); + } ) ); + $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple( '', 'editor_post_info', function ( $context, $contentPlaceholder ) { - $post = ($context = Brizy_Content_ContextFactory::getGlobalContext()) ? $context->getWpPost() : get_post(); + $post = $context->getWpPost(); - if (!$post || !isset($attrs['property'])) { - return ''; - } - - return $this->filterData($attrs['property'], $post); - }) ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple('', 'editor_post_info', function () { + if ( $post ) { + $commentsCount = get_approved_comments( $post->ID, [ 'count' => true ] ); + $params = []; - $post = ($context = Brizy_Content_ContextFactory::getGlobalContext()) ? $context->getWpPost() : get_post(); + $params['author'] = get_the_author_meta( 'display_name', $post->post_author ); + $params['date'] = get_the_date( '', $post ); + $params['time'] = get_the_time( '', $post ); + $params['comments'] = sprintf( _n( '%s comment', '%s comments', $commentsCount, 'brizy' ), number_format_i18n( $commentsCount ) ); - if ( $post ) { - $commentsCount = get_approved_comments( $post->ID, [ 'count' => true ] ); - $params = []; - $params['author'] = get_the_author_meta( 'display_name', $post->post_author ); - $params['date'] = get_the_date( '', $post ); - $params['time'] = get_the_time( '', $post ); - $params['comments'] = sprintf( _n( '%s comment', '%s comments', $commentsCount, 'brizy' ), number_format_i18n( $commentsCount ) ); + return Brizy_Editor_View::get( BRIZY_PLUGIN_PATH . '/public/views/post-info', $params ); + } - return Brizy_Editor_View::get( BRIZY_PLUGIN_PATH . '/public/views/post-info', $params ); - } + return ''; + } ) ); - return ''; - }) ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple('', 'editor_posts', function ($context, $contentPlaceholder) { + $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple( '', 'editor_posts', function ( $context, $contentPlaceholder ) { - $atts = $contentPlaceholder->getAttributes(); + $atts = $contentPlaceholder->getAttributes(); - // shortcode to use in page: {{editor_posts posts_per_page="5" category="1,2" orderby="date" order="DESC" columns="1" display_date="1" display_author="1"}} + // shortcode to use in page: {{editor_posts posts_per_page="5" category="1,2" orderby="date" order="DESC" columns="1" display_date="1" display_author="1"}} - // this array is used as default values for displayPosts - $extra_atts = array( - "columns" => 1, - "display_date" => 1, - "display_author" => 1, - ); + // this array is used as default values for displayPosts + $extra_atts = array( + "columns" => 1, + "display_date" => 1, + "display_author" => 1, + ); - $extra_atts = array_merge($extra_atts, $atts); + $extra_atts = array_merge( $extra_atts, $atts ); - $posts = $this->getPosts($atts); + $posts = $this->getPosts( $atts ); - return $this->displayPosts($posts, $extra_atts); - }) ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple('Product Page', 'editor_product_page', function ($context, $contentPlaceholder) { + return $this->displayPosts( $posts, $extra_atts ); + } ) ); + $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple( 'Product Page', 'editor_product_page', function ( $context, $contentPlaceholder ) { - $atts = $contentPlaceholder->getAttributes(); + $atts = $contentPlaceholder->getAttributes(); // if ( ! empty( $atts['id'] ) ) { // $product_data = get_post( $atts['id'] ); // $product = ! empty( $product_data ) && in_array( $product_data->post_type, [ 'product', 'product_variation' ] ) ? wc_setup_product_data( $product_data ) : false; // } - if (empty($atts['id']) && current_user_can('manage_options')) { - return __('Please set a valid product', 'brizy'); - } - - $this->setScriptDependency('brizy-preview', ['zoom', 'photoswipe', 'flexslider', 'wc-single-product']); - - // Avoid infinite loop. There's a call of the function the_content() in the woocommerce/single-product/tabs/description.php - remove_filter('the_content', [Brizy_Admin_Templates::instance(), 'filterPageContent'], -12000); - - $html = do_shortcode('[product_page id="' . $atts['id'] . '"]'); - - add_filter('the_content', [Brizy_Admin_Templates::instance(), 'filterPageContent'], -12000); - - return $html; - }) ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple('Products Page', 'editor_product_products', function ($context, $contentPlaceholder) { - - $atts = $contentPlaceholder->getAttributes(); - - $shortcodeAttributes = []; - - if (isset($atts['limit'])) { - $shortcodeAttributes[] = sprintf("limit=\"%d\"", (int)$atts['limit']); - } - if (isset($atts['columns'])) { - $shortcodeAttributes[] = sprintf("columns=\"%d\"", (int)$atts['columns']); - } - if (isset($atts['category'])) { - $shortcodeAttributes[] = sprintf("category=\"%s\"", $atts['category']); - } - if (isset($atts['orderby'])) { - $shortcodeAttributes[] = sprintf("orderby=\"%s\"", $atts['orderby']); - } - if (isset($atts['order'])) { - $shortcodeAttributes[] = sprintf("order=\"%s\"", $atts['order']); - } - - $shortcodeAttributes = implode(' ', $shortcodeAttributes); - - return do_shortcode('[products ' . $shortcodeAttributes . ' ]'); - }) ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple('', 'editor_product_default_cart', function () { - return do_shortcode('[woocommerce_cart]'); - }) ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple('', 'editor_product_checkout', function () { - return do_shortcode('[woocommerce_checkout]'); - }) ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple('', 'editor_product_my_account', function () { - return do_shortcode('[woocommerce_my_account]'); - }) ); - $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple('', 'editor_product_order_tracking', function () { - return do_shortcode('[woocommerce_order_tracking]'); - }) ); + if ( empty( $atts['id'] ) && current_user_can( 'manage_options' ) ) { + return __( 'Please set a valid product', 'brizy' ); + } + + $this->setScriptDependency( 'brizy-preview', [ 'zoom', 'photoswipe', 'flexslider', 'wc-single-product' ] ); + + // Avoid infinite loop. There's a call of the function the_content() in the woocommerce/single-product/tabs/description.php + remove_filter( 'the_content', [ Brizy_Admin_Templates::instance(), 'filterPageContent' ], - 12000 ); + + $html = do_shortcode( '[product_page id="' . $atts['id'] . '"]' ); + + add_filter( 'the_content', [ Brizy_Admin_Templates::instance(), 'filterPageContent' ], - 12000 ); + + return $html; + } ) ); + + $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple( 'Products Page', 'editor_product_products', function ( $context, $contentPlaceholder ) { + + $atts = $contentPlaceholder->getAttributes(); + + $shortcodeAttributes = []; + + if ( isset( $atts['limit'] ) ) { + $shortcodeAttributes[] = sprintf( "limit=\"%d\"", (int) $atts['limit'] ); + } + if ( isset( $atts['columns'] ) ) { + $shortcodeAttributes[] = sprintf( "columns=\"%d\"", (int) $atts['columns'] ); + } + if ( isset( $atts['category'] ) ) { + $shortcodeAttributes[] = sprintf( "category=\"%s\"", $atts['category'] ); + } + if ( isset( $atts['orderby'] ) ) { + $shortcodeAttributes[] = sprintf( "orderby=\"%s\"", $atts['orderby'] ); + } + if ( isset( $atts['order'] ) ) { + $shortcodeAttributes[] = sprintf( "order=\"%s\"", $atts['order'] ); + } + + $shortcodeAttributes = implode( ' ', $shortcodeAttributes ); + + return do_shortcode( '[products ' . $shortcodeAttributes . ' ]' ); + } ) ); + $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple( '', 'editor_product_default_cart', function () { + return do_shortcode( '[woocommerce_cart]' ); + } ) ); + $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple( '', 'editor_product_checkout', function () { + return do_shortcode( '[woocommerce_checkout]' ); + } ) ); + $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple( '', 'editor_product_my_account', function () { + return do_shortcode( '[woocommerce_my_account]' ); + } ) ); + $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple( '', 'editor_product_order_tracking', function () { + return do_shortcode( '[woocommerce_order_tracking]' ); + } ) ); + $this->registerPlaceholder( new Brizy_Content_Placeholders_IgnoreDc('') ); $this->registerPlaceholder( new Brizy_Content_Placeholders_Simple(__( 'WooCommerce Notices', 'brizy' ), 'editor_woo_notice', function () { return wc_print_notices( true ); }, self::CONFIG_KEY_TEXT ) ); } - private function filterData($property, $post) - { - switch ($property) { - case 'post_title': - return get_the_title($post); - case 'post_excerpt': - return get_the_excerpt($post); - case 'post_content': - return get_the_content($post); - case 'post_password': - return ''; - default: - return $post->{$property}; - } - } - - /** - * It rewrite the wodpress function wp_trim_excerpt. - * The only thing we do is exclude the appling of the hook the_content. - * Further information read the description of the function getValue of this class. - * - * @param string $text - * @param null $post - * - * @return string - */ - public static function wp_trim_excerpt($text = '', $post = null) - { - global $pages; - - // not sure why this is null (this happens on author pages.. maybe there are more) - // - if (is_null($pages)) - $pages = []; - - $raw_excerpt = $text; - if ('' == $text) { - - $post = get_post($post); - $text = get_the_content('', false, $post); - - - $text = strip_shortcodes($text); - $text = excerpt_remove_blocks($text); - - /** This filter is documented in wp-includes/post-template.php */ - $text = apply_filters('the_content', $text); - $text = str_replace(']]>', ']]>', $text); - - - /** - * Filters the number of words in an excerpt. - * - * @param int $number The number of words. Default 55. - * - * @since 2.7.0 - * - */ - $excerpt_length = apply_filters('excerpt_length', 55); - - /** - * Filters the string in the "more" link displayed after a trimmed excerpt. - * - * @param string $more_string The string shown within the more link. - * - * @since 2.9.0 - * - */ - $excerpt_more = apply_filters('excerpt_more', ' ' . '[…]'); - $text = wp_trim_words($text, $excerpt_length, $excerpt_more); - } - - /** - * Filters the trimmed excerpt string. - * - * @param string $text The trimmed text. - * @param string $raw_excerpt The text prior to trimming. - * - * @since 2.8.0 - * - */ - return apply_filters('wp_trim_excerpt', $text, $raw_excerpt); - } - - private function getPosts($atts) - { - // here are default posts arguments: https://codex.wordpress.org/Template_Tags/get_posts - // maybe here we need to change some attributes, unset or add something before make query - $posts = get_posts($atts); - - return $posts; - } - - private function displayPosts($posts, $extra_atts) - { - ob_start(); - - $thumbnail_size = ''; // possible sizes: thumbnail, medium, medium_large, large - if ((int)$extra_atts['columns'] > 1) { - $thumbnail_size = 'large'; - } - - foreach ($posts as $post) { ?> + private function filterData( $property, $post ) { + switch ( $property ) { + case 'post_title': + return get_the_title( $post ); + case 'post_excerpt': + return get_the_excerpt( $post ); + case 'post_content': + return get_the_content( $post ); + case 'post_password': + return ''; + default: + return $post->{$property}; + } + } + + private function getPosts( $atts ) { + // here are default posts arguments: https://codex.wordpress.org/Template_Tags/get_posts + // maybe here we need to change some attributes, unset or add something before make query + $posts = get_posts( $atts ); + + return $posts; + } + + private function displayPosts( $posts, $extra_atts ) { + ob_start(); + + $thumbnail_size = ''; // possible sizes: thumbnail, medium, medium_large, large + if ( (int) $extra_atts['columns'] > 1 ) { + $thumbnail_size = 'large'; + } + + foreach ( $posts as $post ) { ?> - post_excerpt)) { - // if !empty excerpt - return $post->post_excerpt; - } + private function getPostExcerpt( $post ) { + if ( ! empty( $post->post_excerpt ) ) { + // if !empty excerpt + return $post->post_excerpt; + } - $the_excerpt = strip_tags(strip_shortcodes($post->post_content)); // Strips tags and shortcodes - $excerpt_length = 50; // Sets excerpt length by word count, default in WP is 55 - $words = explode(' ', $the_excerpt, $excerpt_length + 1); + $the_excerpt = strip_tags( strip_shortcodes( $post->post_content ) ); // Strips tags and shortcodes + $excerpt_length = 50; // Sets excerpt length by word count, default in WP is 55 + $words = explode( ' ', $the_excerpt, $excerpt_length + 1 ); - if (count($words) > $excerpt_length) { - array_pop($words); - $the_excerpt = implode(' ', $words); // put in excerpt only the number of word that is set in $excerpt_length - } + if ( count( $words ) > $excerpt_length ) { + array_pop( $words ); + $the_excerpt = implode( ' ', $words ); // put in excerpt only the number of word that is set in $excerpt_length + } - return $the_excerpt; - } + return $the_excerpt; + } } diff --git a/editor.php b/editor.php index 1dd07acc9b..608a6e1149 100755 --- a/editor.php +++ b/editor.php @@ -3,322 +3,340 @@ /** * Class Brizy_Editor */ -class Brizy_Editor { +class Brizy_Editor +{ - private static $settings_key = 'post-types'; + private static $settings_key = 'post-types'; - private static $instance; + private static $instance; - private static $is_allowed_for_current_user = null; - /** - * All plugin ajax actions and enpoints are going to be prefixed with this string. - * This will not affect the database prefix tables or option keys and post meta keys * - * - * @var string - */ - private static $prefix = null; + private static $is_allowed_for_current_user = null; + /** + * All plugin ajax actions and enpoints are going to be prefixed with this string. + * This will not affect the database prefix tables or option keys and post meta keys * + * + * @var string + */ + private static $prefix = null; - public static function get() { + public static function get() + { - if ( self::$instance ) { - return self::$instance; - } + if (self::$instance) { + return self::$instance; + } - self::$instance = new self(); + self::$instance = new self(); - return self::$instance; - } + return self::$instance; + } - /** - * Return the prefix - * - * @param string $string - * - * @return string - */ - public static function prefix( $string = null ) { + /** + * Return the prefix + * + * @param string $string + * + * @return string + */ + public static function prefix($string = null) + { + + $string = $string ? trim($string) : ''; + + if (!self::$prefix) { - $string = $string ? trim( $string ) : ''; - - if ( ! self::$prefix ) { - - $prefix = 'brizy'; - - if ( class_exists( 'BrizyPro_Admin_WhiteLabel' ) && BrizyPro_Admin_WhiteLabel::_init()->getEnabled() ) { - $prefix = method_exists( 'BrizyPro_Admin_WhiteLabel', 'getPrefix' ) ? BrizyPro_Admin_WhiteLabel::_init()->getPrefix() : get_option( 'brizy_prefix', 'brizy' ); - } - - self::$prefix = $prefix; - } - - return self::$prefix . $string; - } - - /** - * @param string $string - * - * @return string - * @deprecated - * Return the prefix - * - */ - public static function setPrefix( $string ) { - - if ( $string == '' ) { - throw new Exception( 'The prefix cannot be empty' ); - } - - update_option( 'brizy_prefix', $string ); - - return self::$prefix = $string; - } - - - /** - * Brizy_Editor constructor. - */ - private function __construct() { - - if ( is_admin() ) { - Brizy_SystemChecks::run(); - } - - // make sure the project is created - // do not remove this! we force the project creation here. - $project = Brizy_Editor_Project::get(); - - Brizy_Admin_Flash::instance()->initialize(); // initialize flash - - add_action( 'init', array( $this, 'registerCustomPostTemplates' ), - 4000 ); - add_action( 'init', array( $this, 'runMigrations' ), - 3000 ); - - add_action( 'init', array( 'Brizy_MaintenanceMode', 'init' ), - 4000 ); - add_action( 'init', array( $this, 'resetPermalinks' ), - 2000 ); - add_action( 'init', array( $this, 'initialize' ), - 2000 ); - add_action( 'init', [ $this, 'handleEditorEditMode' ], 0 ); - add_action( 'wp', [ $this, 'handleEditorPreviewMode' ] ); - } - - public function initialize() { - - add_action( 'init', array( $this, 'wordpressInit' ), 1000 ); - add_action( 'wp_loaded', array( $this, 'wordpressLoaded' ) ); - add_action( 'wp_print_scripts', array( $this, 'forceJqueryQueue' ), 99999 ); - - if ( current_user_can( Brizy_Admin_Capabilities::CAP_EDIT_WHOLE_PAGE ) || Brizy_Editor_User::is_administrator() ) { - Brizy_Admin_Rules_Api::_init(); - } - - if ( ! defined( 'WP_POST_REVISIONS' ) || ( defined( 'WP_POST_REVISIONS' ) && WP_POST_REVISIONS !== false ) ) { - add_filter( "wp_revisions_to_keep", array( $this, 'revisionsToKeep' ), 10, 2 ); - } - - } - - public function runMigrations() { - - try { - if ( ! Brizy_Editor_Project::get()->getWpPost() ) { - return; - } - } catch ( Exception $e ) { - Brizy_Admin_Flash::instance()->add_error( 'On run migrations, get project throw the message: ' . $e->getMessage() ); - } - - try { - $migrationManager = new Brizy_Admin_Migrations(); - $migrationManager->runMigrations( BRIZY_VERSION ); - } catch ( Brizy_Admin_Migrations_UpgradeRequiredException $e ) { - Brizy_Admin_Flash::instance()->add_error( 'Please upgrade Brizy to the latest version.' ); - Brizy_Logger::instance()->critical( 'Unknown migration found. The plugin must be downgraded to the previous version' ); - //throw new Exception( 'Halt plugin execution!' ); - } - } - - public function wordpressInit() { - - // watch all supported posts and create meta revisions - $metaManager = new Brizy_Admin_Post_RevisionManager(); - $metaManager->addMonitor( new Brizy_Admin_Post_BrizyPostsMonitor() ); - $metaManager->addMonitor( new Brizy_Admin_Post_ProjectPostMonitor() ); - - //Brizy_Editor_Asset_Cleaner::_init(); - Brizy_Admin_PanelPostContent::_init(); - Brizy_Admin_Templates::instance(); - Brizy_Admin_Popups_Main::_init(); - Brizy_Admin_FormEntries::_init(); - Brizy_Admin_Fonts_Main::_init(); - Brizy_Admin_Blocks_Main::_init(); - Brizy_Admin_Stories_Main::_init(); + $prefix = 'brizy'; + + if (class_exists('BrizyPro_Admin_WhiteLabel') && BrizyPro_Admin_WhiteLabel::_init()->getEnabled()) { + $prefix = method_exists('BrizyPro_Admin_WhiteLabel', 'getPrefix') ? BrizyPro_Admin_WhiteLabel::_init()->getPrefix() : get_option('brizy_prefix', 'brizy'); + } + + self::$prefix = $prefix; + } + + return self::$prefix . $string; + } + + /** + * @param string $string + * + * @return string + * @deprecated + * Return the prefix + * + */ + public static function setPrefix($string) + { + + if ($string == '') { + throw new Exception('The prefix cannot be empty'); + } + + update_option('brizy_prefix', $string); + + return self::$prefix = $string; + } + + + /** + * Brizy_Editor constructor. + */ + private function __construct() + { + + if (is_admin()) { + Brizy_SystemChecks::run(); + } + + // make sure the project is created + // do not remove this! we force the project creation here. + $project = Brizy_Editor_Project::get(); + + Brizy_Admin_Flash::instance()->initialize(); // initialize flash + + add_action('init', array($this, 'registerCustomPostTemplates'), -4000); + add_action('init', array($this, 'runMigrations'), -3000); + + add_action('init', array('Brizy_MaintenanceMode', 'init'), -4000); + add_action('init', array($this, 'resetPermalinks'), -2000); + add_action('init', array($this, 'initialize'), -2000); + add_action('init', [$this, 'handleEditorEditMode'], 0); + add_action('wp', [$this, 'handleEditorPreviewMode']); + } + + public function initialize() + { + + add_action('init', array($this, 'wordpressInit'), 1000); + add_action('wp_loaded', array($this, 'wordpressLoaded')); + add_action('wp_print_scripts', array($this, 'forceJqueryQueue'), 99999); + + if (current_user_can(Brizy_Admin_Capabilities::CAP_EDIT_WHOLE_PAGE) || Brizy_Editor_User::is_administrator()) { + Brizy_Admin_Rules_Api::_init(); + } + + if (!defined('WP_POST_REVISIONS') || (defined('WP_POST_REVISIONS') && WP_POST_REVISIONS !== false)) { + add_filter("wp_revisions_to_keep", array($this, 'revisionsToKeep'), 10, 2); + } + + } + + public function runMigrations() + { + + try { + if (!Brizy_Editor_Project::get()->getWpPost()) { + return; + } + } catch (Exception $e) { + Brizy_Admin_Flash::instance()->add_error('On run migrations, get project throw the message: ' . $e->getMessage()); + } + + try { + $migrationManager = new Brizy_Admin_Migrations(); + $migrationManager->runMigrations(BRIZY_VERSION); + } catch (Brizy_Admin_Migrations_UpgradeRequiredException $e) { + Brizy_Admin_Flash::instance()->add_error('Please upgrade Brizy to the latest version.'); + Brizy_Logger::instance()->critical('Unknown migration found. The plugin must be downgraded to the previous version'); + //throw new Exception( 'Halt plugin execution!' ); + } + } + + public function wordpressInit() + { + + // watch all supported posts and create meta revisions + $metaManager = new Brizy_Admin_Post_RevisionManager(); + $metaManager->addMonitor(new Brizy_Admin_Post_BrizyPostsMonitor()); + $metaManager->addMonitor(new Brizy_Admin_Post_ProjectPostMonitor()); + + //Brizy_Editor_Asset_Cleaner::_init(); + Brizy_Admin_PanelPostContent::_init(); + Brizy_Admin_Templates::instance(); + Brizy_Admin_Popups_Main::_init(); + Brizy_Admin_FormEntries::_init(); + Brizy_Admin_Fonts_Main::_init(); + Brizy_Admin_Blocks_Main::_init(); + Brizy_Admin_Stories_Main::_init(); Brizy_Admin_Symbols_Main::_init(); - if ( Brizy_Editor_User::is_user_allowed() ) { - Brizy_Admin_Svg_Main::_init(); - Brizy_Admin_Json_Main::_init(); - Brizy_Admin_Layouts_Main::_init(); - Brizy_Admin_Membership_Membership::_init(); - - // the cloud will be always initialized with the exception when the white label is enabled - if ( ! ( class_exists( 'BrizyPro_Admin_WhiteLabel' ) && BrizyPro_Admin_WhiteLabel::_init()->getEnabled() ) ) { - Brizy_Admin_Cloud::_init(); - } - } - - $this->initializeAssetLoaders(); - - $supported_post_types = $this->supported_post_types(); - $supported_post_types[] = Brizy_Admin_Templates::CP_TEMPLATE; - - foreach ( $supported_post_types as $type ) { - add_filter( "theme_{$type}_templates", array( $this, 'registerPageTemplates' ) ); - } - } - - public function wordpressLoaded() { - - $pid = Brizy_Editor::get()->currentPostId(); - $post = null; - - try { - // do not delete this line - $user = Brizy_Editor_User::get(); - - if ( $pid ) { - $post = Brizy_Editor_Post::get( $pid ); - } - } catch ( Exception $e ) { - } - - $this->loadEditorApi( $post, $user ); - $this->loadEditorAdminSettings(); + if (Brizy_Editor_User::is_user_allowed()) { + Brizy_Admin_Svg_Main::_init(); + Brizy_Admin_Json_Main::_init(); + Brizy_Admin_Layouts_Main::_init(); + Brizy_Admin_Membership_Membership::_init(); + + // the cloud will be always initialized with the exception when the white label is enabled + if (!(class_exists('BrizyPro_Admin_WhiteLabel') && BrizyPro_Admin_WhiteLabel::_init()->getEnabled())) { + Brizy_Admin_Cloud::_init(); + } + } + + $this->initializeAssetLoaders(); + + $supported_post_types = $this->supported_post_types(); + $supported_post_types[] = Brizy_Admin_Templates::CP_TEMPLATE; + + foreach ($supported_post_types as $type) { + add_filter("theme_{$type}_templates", array($this, 'registerPageTemplates')); + } + } + + public function wordpressLoaded() + { + + $pid = Brizy_Editor::get()->currentPostId(); + $post = null; + + try { + // do not delete this line + $user = Brizy_Editor_User::get(); + + if ($pid) { + $post = Brizy_Editor_Post::get($pid); + } + } catch (Exception $e) { + } + + $this->loadEditorApi($post, $user); + $this->loadEditorAdminSettings(); + + if (!class_exists('BrizyPro_Admin_WhiteLabel') || !BrizyPro_Admin_WhiteLabel::_init()->getEnabled()) { + if (current_user_can('manage_options')) { + add_action('wp_dashboard_setup', 'Brizy_Admin_DashboardWidget::_init'); + } + } + + if ((current_user_can('manage_options') && is_admin()) || (defined('WP_CLI') && WP_CLI)) { + new Brizy_Import_Main(); + } + + add_filter('brizy_content', array($this, 'brizy_content'), 10, 3); + } + + public function handleEditorEditMode() + { + $pid = Brizy_Editor::get()->currentPostId(); + + if (!$pid || !Brizy_Editor_Entity::isBrizyEnabled($pid) || !Brizy_Editor_User::is_user_allowed()) { + return; + } + + try { + $post = Brizy_Editor_Post::get($pid); + } catch (Exception $e) { + return; + } + + try { + $main = Brizy_Public_Main::get($post); + + $main->editMode(); + } catch (Exception $e) { + Brizy_Logger::instance()->exception($e); + } + } + + public function handleEditorPreviewMode() + { + $pid = Brizy_Editor::get()->currentPostId(); + + if (!$pid || !Brizy_Editor_Entity::isBrizyEnabled($pid)) { + return; + } + + try { + $post = Brizy_Editor_Post::get($pid); + } catch (Exception $e) { + return; + } + + try { + $main = Brizy_Public_Main::get($post); + $main->previewMode(); + } catch (Exception $e) { + Brizy_Logger::instance()->exception($e); + } + } + + public function revisionsToKeep($num, $post) + { + try { + $revisionCount = apply_filters('brizy_revisions_max_count', BRIZY_MAX_REVISIONS_TO_KEEP); + + // $num can be -1 + if ($revisionCount > $num && $num >= 0) { + return $num; + } + + if (in_array($post->post_type, array(Brizy_Editor_Project::BRIZY_PROJECT))) { + return $revisionCount; + } + + if (Brizy_Editor_Entity::isBrizyEnabled($post->ID)) { + $num = $revisionCount; + } + } catch (Exception $e) { + Brizy_Logger::instance()->debug($e->getMessage(), array($e)); + } + + return $num; + } + + /** + * Reset permalinks after plugin upgrade or enable + */ + public function resetPermalinks() + { + + $this->registerCustomPostTemplates(); + + if (defined('BRIZY_PRO_VERSION') && class_exists('BrizyPro_Main')) { + $mainInstance = new BrizyPro_Main(); + $mainInstance->registerCustomPosts(); + } + + if (get_option('brizy-regenerate-permalinks', false)) { + flush_rewrite_rules(); + delete_option('brizy-regenerate-permalinks'); + } + } + + /** + * @param $templates + * + * @return array + */ + function registerPageTemplates($templates) + { + return array_merge($templates, + array( + Brizy_Config::BRIZY_BLANK_TEMPLATE_FILE_NAME => __bt('brizy', 'Brizy') . __(' Template', 'brizy') + )); + } + + public function registerCustomPostTemplates() + { + Brizy_Editor_Project::registerCustomPostType(); + Brizy_Admin_Layouts_Main::registerCustomPosts(); + Brizy_Admin_Fonts_Main::registerCustomPosts(); + Brizy_Admin_FormEntries::registerCustomPost(); + Brizy_Admin_Stories_Main::registerCustomPosts(); + Brizy_Admin_Popups_Main::registerCustomPosts(); + Brizy_Admin_Blocks_Main::registerCustomPosts(); + Brizy_Admin_Templates::registerCustomPostTemplate(); + } + + /** + * @param $project + * @param $post + * @param $user + */ + private function loadEditorApi($post, $user) + { + try { + new Brizy_Editor_Filters_Api( ); - if ( ! class_exists( 'BrizyPro_Admin_WhiteLabel' ) || ! BrizyPro_Admin_WhiteLabel::_init()->getEnabled() ) { - if ( current_user_can( 'manage_options' ) ) { - add_action( 'wp_dashboard_setup', 'Brizy_Admin_DashboardWidget::_init' ); - } - } - - if ( ( current_user_can( 'manage_options' ) && is_admin() ) || ( defined( 'WP_CLI' ) && WP_CLI ) ) { - new Brizy_Import_Main(); - } - - add_filter( 'brizy_content', array( $this, 'brizy_content' ), 10, 3 ); - } - - public function handleEditorEditMode() { - $pid = Brizy_Editor::get()->currentPostId(); - - if ( ! $pid || ! Brizy_Editor_Entity::isBrizyEnabled( $pid ) || ! Brizy_Editor_User::is_user_allowed() ) { - return; - } - - try { - $post = Brizy_Editor_Post::get( $pid ); - } catch ( Exception $e ) { - return; - } - - try { - $main = Brizy_Public_Main::get( $post ); - - $main->editMode(); - } catch ( Exception $e ) { - Brizy_Logger::instance()->exception( $e ); - } - } - - public function handleEditorPreviewMode() { - $pid = Brizy_Editor::get()->currentPostId(); - - if ( ! $pid || ! Brizy_Editor_Entity::isBrizyEnabled( $pid ) ) { - return; - } - - try { - $post = Brizy_Editor_Post::get( $pid ); - } catch ( Exception $e ) { - return; - } - - try { - $main = Brizy_Public_Main::get( $post ); - $main->previewMode(); - } catch ( Exception $e ) { - Brizy_Logger::instance()->exception( $e ); - } - } - - public function revisionsToKeep( $num, $post ) { - try { - $revisionCount = apply_filters( 'brizy_revisions_max_count', BRIZY_MAX_REVISIONS_TO_KEEP ); - - // $num can be -1 - if ( $revisionCount > $num && $num >= 0 ) { - return $num; - } - - if ( in_array( $post->post_type, array( Brizy_Editor_Project::BRIZY_PROJECT ) ) ) { - return $revisionCount; - } - - if ( Brizy_Editor_Entity::isBrizyEnabled( $post->ID ) ) { - $num = $revisionCount; - } - } catch ( Exception $e ) { - Brizy_Logger::instance()->debug( $e->getMessage(), array( $e ) ); - } - - return $num; - } - - /** - * Reset permalinks after plugin upgrade or enable - */ - public function resetPermalinks() { - - $this->registerCustomPostTemplates(); - - if ( defined( 'BRIZY_PRO_VERSION' ) && class_exists( 'BrizyPro_Main' ) ) { - $mainInstance = new BrizyPro_Main(); - $mainInstance->registerCustomPosts(); - } - - if ( get_option( 'brizy-regenerate-permalinks', false ) ) { - flush_rewrite_rules(); - delete_option( 'brizy-regenerate-permalinks' ); - } - } - - /** - * @param $templates - * - * @return array - */ - function registerPageTemplates( $templates ) { - return array_merge( $templates, - array( - Brizy_Config::BRIZY_BLANK_TEMPLATE_FILE_NAME => __bt( 'brizy', 'Brizy' ) . __( ' Template', 'brizy' ) - ) ); - } - - public function registerCustomPostTemplates() { - Brizy_Editor_Project::registerCustomPostType(); - Brizy_Admin_Layouts_Main::registerCustomPosts(); - Brizy_Admin_Fonts_Main::registerCustomPosts(); - Brizy_Admin_FormEntries::registerCustomPost(); - Brizy_Admin_Stories_Main::registerCustomPosts(); - Brizy_Admin_Popups_Main::registerCustomPosts(); - Brizy_Admin_Blocks_Main::registerCustomPosts(); - Brizy_Admin_Templates::registerCustomPostTemplate(); - } - - /** - * @param $project - * @param $post - * @param $user - */ - private function loadEditorApi( $post, $user ) { - try { if ( Brizy_Editor_User::is_user_allowed() ) { new Brizy_Editor_RestExtend(); new Brizy_Editor_API( $post ); @@ -326,278 +344,298 @@ private function loadEditorApi( $post, $user ) { Brizy_Editor_Accounts_Api::_init(); } - new Brizy_Editor_Forms_Api( $post ); - - // for other apis - do_action( 'brizy_register_api_methods', $user, $post ); - } catch ( Exception $e ) { - Brizy_Logger::instance()->exception( $e ); - } - } - - private function loadEditorAdminSettings() { - try { - new Brizy_Admin_Capabilities( Brizy_Editor_Storage_Common::instance() ); - - if ( is_admin() ) { - Brizy_Admin_Main::instance(); - new Brizy_Admin_GettingStarted(); - $this->initFeedback(); - } - - if ( is_network_admin() ) { - Brizy_Admin_NetworkSettings::_init(); - } elseif ( is_admin() ) { - Brizy_Admin_Settings::_init(); - } - } catch ( Exception $exception ) { - Brizy_Admin_Flash::instance()->add_error( 'Unable to empty the trash. Please try again later.' ); - wp_safe_redirect( $_SERVER['HTTP_REFERER'] ); - exit; - } - } - - public function brizy_content( $content, $project, $wpPost, $contentType = 'document' ) { - - $context = Brizy_Content_ContextFactory::createContext( $project, null, $wpPost, null ); - $mainProcessor = new Brizy_Content_MainProcessor( $context ); - - return $mainProcessor->process( $content ); - } - - public function forceJqueryQueue() { - if ( ! wp_script_is( 'jquery', 'enqueued' ) ) { - wp_enqueue_script( 'jquery' ); - } - } - - private function initializeAssetLoaders() { - try { - $url_builder = new Brizy_Editor_UrlBuilder( null ); - - $config = null; - $proxy = new Brizy_Public_AssetProxy( $url_builder, $config ); - $crop_proxy = new Brizy_Public_CropProxy( $url_builder, $config ); - $attachment_proxy = new Brizy_Public_AttachmentProxy( $url_builder, $config ); - $screenshot_roxy = new Brizy_Public_BlockScreenshotProxy( new Brizy_Editor_UrlBuilder( null ), $config ); - } catch ( Exception $e ) { - Brizy_Logger::instance()->exception( $e ); - } - } - - /* - * ==================================================================================================== - * ===================================================================================================== - * ===================================================================================================== - * ===================================================================================================== - * ===================================================================================================== - */ - function currentPostId() { - $pid = null; - global $wp_query; - - if ( isset( $_REQUEST['post'] ) ) { - $pid = (int) $_REQUEST['post']; - } elseif - ( isset( $_REQUEST['page_id'] ) ) { - $pid = (int) $_REQUEST['page_id']; - } elseif - ( isset( $_REQUEST['post_ID'] ) ) { - $pid = (int) $_POST['post_ID']; - } elseif - ( isset( $_REQUEST['id'] ) ) { - $pid = (int) $_REQUEST['id']; - } elseif - ( isset( $_REQUEST[ Brizy_Editor::prefix( '_post' ) ] ) ) { - $pid = (int) $_REQUEST[ Brizy_Editor::prefix( '_post' ) ]; - } elseif ( $wp_query && $wp_query->is_posts_page ) { - $pid = (int) get_queried_object_id(); - } elseif - ( $wp_query && ( $apid = get_queried_object_id() ) && ( is_single() || is_page() ) && $wp_query->queried_object instanceof WP_Post ) { - $pid = (int) $apid; - } elseif ( function_exists( 'is_shop' ) && is_shop() ) { - $pid = wc_get_page_id( 'shop' ); - } - - return $pid; - } - - static public function get_slug() { - return apply_filters( 'brizy-slug', 'brizy' ); - } - - public function get_path( $rel = '/' ) { - return BRIZY_PLUGIN_PATH . DIRECTORY_SEPARATOR . ltrim( $rel, DIRECTORY_SEPARATOR ); - } - - public function get_url( $rel = '' ) { - return BRIZY_PLUGIN_URL . "/" . ltrim( $rel, "/" ); - } - - public function get_version() { - return BRIZY_VERSION; - } - - /** - * @param $wp_post_id - * @param bool $throw - * - * @return bool - * @throws Brizy_Editor_Exceptions_UnsupportedPostType - */ - public static function checkIfPostTypeIsSupported( $wp_post_id, $throw = true ) { - $type = get_post_type( $wp_post_id ); - - $supported_post_types = self::get()->supported_post_types(); - $supported_post_types[] = 'revision'; - - if ( ! in_array( $type, $supported_post_types ) ) { - - if ( $throw ) { - throw new Brizy_Editor_Exceptions_UnsupportedPostType( - "Brizy editor doesn't support '{$type}' post type" - ); - } else { - return false; - } - } - - return true; - } - - public function supported_post_types() { - $types = $this->get_post_types(); - - return apply_filters( 'brizy_supported_post_types', apply_filters( 'brizy:post_types', $types ) ); - } - - public function default_supported_post_types() { - return array( 'page', 'post' ); - } - - public function get_name() { - return __bt( 'brizy', 'Brizy' ); - } - - protected function get_post_types() { - try { - return Brizy_Editor_Storage_Common::instance()->get( self::$settings_key ); - } catch ( Brizy_Editor_Exceptions_NotFound $exception ) { - Brizy_Editor_Storage_Common::instance()->set( self::$settings_key, $this->default_supported_post_types() ); - - return $this->default_supported_post_types(); - } - } - - public function lockProject() { - if ( ! function_exists( 'wp_set_post_lock' ) ) { - require_once ABSPATH . 'wp-admin/includes/post.php'; - } - wp_set_post_lock( Brizy_Editor_Project::get()->getWpPostId() ); - } - - public function removeProjectLock() { - delete_post_meta( Brizy_Editor_Project::get()->getWpPostId(), '_edit_lock' ); - } - - public function checkIfProjectIsLocked() { - if ( ! function_exists( 'wp_check_post_lock' ) ) { - require_once ABSPATH . 'wp-admin/includes/post.php'; - } - - return wp_check_post_lock( Brizy_Editor_Project::get()->getWpPostId() ); - } - - - private function initFeedback() { - - $feedback = true; - - if ( class_exists( 'BrizyPro_Admin_WhiteLabel' ) ) { - - $whiteLabel = BrizyPro_Admin_WhiteLabel::_init(); - $callable = is_callable( [ $whiteLabel, 'getEnabled' ] ); - - if ( ( $callable && $whiteLabel->getEnabled() ) || ! $callable ) { - $feedback = false; - } - } - - if ( $feedback && current_user_can( 'manage_options' ) ) { - new Brizy_Admin_Feedback(); - } - } - - /** - * @deprecated Use Brizy_Editor_User::is_user_allowed() - */ - public static function is_user_allowed() { - - if ( ! is_user_logged_in() ) { - return false; - } - - if ( current_user_can( 'manage_options' ) ) { - return true; - } - - if ( is_null( self::$is_allowed_for_current_user ) ) { - self::$is_allowed_for_current_user = ( - current_user_can( Brizy_Admin_Capabilities::CAP_EDIT_WHOLE_PAGE ) - || - current_user_can( Brizy_Admin_Capabilities::CAP_EDIT_CONTENT_ONLY ) - ); - } - - return self::$is_allowed_for_current_user; - } - - /** - * Get all image sizes. - * - * Retrieve available image sizes with data like `width`, `height` and `crop`. - * - * @return array An array of available image sizes. - */ - static public function get_all_image_sizes() { - global $_wp_additional_image_sizes; - - static $image_sizes = []; - - if ( $image_sizes ) { - return $image_sizes; - } - - foreach ( [ 'thumbnail', 'medium', 'medium_large', 'large' ] as $size ) { - $image_sizes[ $size ] = [ - 'width' => (int) get_option( $size . '_size_w' ), - 'height' => (int) get_option( $size . '_size_h' ), - 'crop' => (bool) get_option( $size . '_crop' ), - ]; - } - - if ( $_wp_additional_image_sizes ) { - $image_sizes = array_merge( $image_sizes, $_wp_additional_image_sizes ); - } - - /** The filter image_size_names_choose is documented in wp-admin/includes/media.php */ - $image_sizes = array_filter( apply_filters( 'image_size_names_choose', $image_sizes ), function ( $size ) { - return ! empty( $size['width'] ) && ! empty( $size['height'] ); - } ); - - foreach ( $image_sizes as $sizeName => $sizeAttrs ) { - $label = ucwords( str_replace( '_', ' ', $sizeName ) ); - if ( is_array( $sizeAttrs ) ) { - $label .= sprintf( ' - %d x %d', $sizeAttrs['width'], $sizeAttrs['height'] ); - } - - $image_sizes[ $sizeName ]['label'] = $label; - } - - if ( ! array_key_exists( 'original', $image_sizes ) ) { - $image_sizes = [ 'original' => [ 'label' => __( 'Original', 'brizy' ) ] ] + $image_sizes; - } - - return $image_sizes; - } + new Brizy_Editor_Forms_Api($post); + + // for other apis + do_action('brizy_register_api_methods', $user, $post); + } catch (Exception $e) { + Brizy_Logger::instance()->exception($e); + } + } + + private function loadEditorAdminSettings() + { + try { + new Brizy_Admin_Capabilities(Brizy_Editor_Storage_Common::instance()); + + if (is_admin()) { + Brizy_Admin_Main::instance(); + new Brizy_Admin_GettingStarted(); + $this->initFeedback(); + } + + if (is_network_admin()) { + Brizy_Admin_NetworkSettings::_init(); + } elseif (is_admin()) { + Brizy_Admin_Settings::_init(); + } + } catch (Exception $exception) { + Brizy_Admin_Flash::instance()->add_error('Unable to empty the trash. Please try again later.'); + wp_safe_redirect($_SERVER['HTTP_REFERER']); + exit; + } + } + + public function brizy_content($content, $project, $wpPost, $contentType = 'document') + { + + $context = Brizy_Content_ContextFactory::createContext($project, $wpPost); + $mainProcessor = new Brizy_Content_MainProcessor($context); + + return $mainProcessor->process($content); + } + + public function forceJqueryQueue() + { + if (!wp_script_is('jquery', 'enqueued')) { + wp_enqueue_script('jquery'); + } + } + + private function initializeAssetLoaders() + { + try { + $url_builder = new Brizy_Editor_UrlBuilder(null); + + $config = null; + $proxy = new Brizy_Public_AssetProxy($url_builder, $config); + $crop_proxy = new Brizy_Public_CropProxy($url_builder, $config); + $attachment_proxy = new Brizy_Public_AttachmentProxy($url_builder, $config); + $screenshot_roxy = new Brizy_Public_BlockScreenshotProxy(new Brizy_Editor_UrlBuilder(null), $config); + } catch (Exception $e) { + Brizy_Logger::instance()->exception($e); + } + } + + /* + * ==================================================================================================== + * ===================================================================================================== + * ===================================================================================================== + * ===================================================================================================== + * ===================================================================================================== + */ + function currentPostId() + { + $pid = null; + global $wp_query; + + if (isset($_REQUEST['post'])) { + $pid = (int)$_REQUEST['post']; + } elseif + (isset($_REQUEST['page_id'])) { + $pid = (int)$_REQUEST['page_id']; + } elseif + (isset($_REQUEST['post_ID'])) { + $pid = (int)$_REQUEST['post_ID']; + } elseif + (isset($_REQUEST['id'])) { + $pid = (int)$_REQUEST['id']; + } elseif + (isset($_REQUEST[Brizy_Editor::prefix('_post')])) { + $pid = (int)$_REQUEST[Brizy_Editor::prefix('_post')]; + } elseif ($wp_query && $wp_query->is_posts_page) { + $pid = (int)get_queried_object_id(); + } elseif + ($wp_query && ($apid = get_queried_object_id()) && (is_single() || is_page()) && $wp_query->queried_object instanceof WP_Post) { + $pid = (int)$apid; + } elseif (function_exists('is_shop') && is_shop()) { + $pid = wc_get_page_id('shop'); + } + + return $pid; + } + + static public function get_slug() + { + return apply_filters('brizy-slug', 'brizy'); + } + + public function get_path($rel = '/') + { + return BRIZY_PLUGIN_PATH . DIRECTORY_SEPARATOR . ltrim($rel, DIRECTORY_SEPARATOR); + } + + public function get_url($rel = '') + { + return BRIZY_PLUGIN_URL . "/" . ltrim($rel, "/"); + } + + public function get_version() + { + return BRIZY_VERSION; + } + + /** + * @param $wp_post_id + * @param bool $throw + * + * @return bool + * @throws Brizy_Editor_Exceptions_UnsupportedPostType + */ + public static function checkIfPostTypeIsSupported($wp_post_id, $throw = true) + { + $type = get_post_type($wp_post_id); + + $supported_post_types = self::get()->supported_post_types(); + $supported_post_types[] = 'revision'; + + if (!in_array($type, $supported_post_types)) { + + if ($throw) { + throw new Brizy_Editor_Exceptions_UnsupportedPostType( + "Brizy editor doesn't support '{$type}' post type" + ); + } else { + return false; + } + } + + return true; + } + + public function supported_post_types() + { + $types = $this->get_post_types(); + + return apply_filters('brizy_supported_post_types', apply_filters('brizy:post_types', $types)); + } + + public function default_supported_post_types() + { + return array('page', 'post'); + } + + public function get_name() + { + return __bt('brizy', 'Brizy'); + } + + protected function get_post_types() + { + try { + return Brizy_Editor_Storage_Common::instance()->get(self::$settings_key); + } catch (Brizy_Editor_Exceptions_NotFound $exception) { + Brizy_Editor_Storage_Common::instance()->set(self::$settings_key, $this->default_supported_post_types()); + + return $this->default_supported_post_types(); + } + } + + public function lockProject() + { + if (!function_exists('wp_set_post_lock')) { + require_once ABSPATH . 'wp-admin/includes/post.php'; + } + wp_set_post_lock(Brizy_Editor_Project::get()->getWpPostId()); + } + + public function removeProjectLock() + { + delete_post_meta(Brizy_Editor_Project::get()->getWpPostId(), '_edit_lock'); + } + + public function checkIfProjectIsLocked() + { + if (!function_exists('wp_check_post_lock')) { + require_once ABSPATH . 'wp-admin/includes/post.php'; + } + + return wp_check_post_lock(Brizy_Editor_Project::get()->getWpPostId()); + } + + + private function initFeedback() + { + + $feedback = true; + + if (class_exists('BrizyPro_Admin_WhiteLabel')) { + + $whiteLabel = BrizyPro_Admin_WhiteLabel::_init(); + $callable = is_callable([$whiteLabel, 'getEnabled']); + + if (($callable && $whiteLabel->getEnabled()) || !$callable) { + $feedback = false; + } + } + + if ($feedback && current_user_can('manage_options')) { + new Brizy_Admin_Feedback(); + } + } + + /** + * @deprecated Use Brizy_Editor_User::is_user_allowed() + */ + public static function is_user_allowed() + { + + if (!is_user_logged_in()) { + return false; + } + + if (current_user_can('manage_options')) { + return true; + } + + if (is_null(self::$is_allowed_for_current_user)) { + self::$is_allowed_for_current_user = ( + current_user_can(Brizy_Admin_Capabilities::CAP_EDIT_WHOLE_PAGE) + || + current_user_can(Brizy_Admin_Capabilities::CAP_EDIT_CONTENT_ONLY) + ); + } + + return self::$is_allowed_for_current_user; + } + + /** + * Get all image sizes. + * + * Retrieve available image sizes with data like `width`, `height` and `crop`. + * + * @return array An array of available image sizes. + */ + static public function get_all_image_sizes() + { + global $_wp_additional_image_sizes; + + static $image_sizes = []; + + if ($image_sizes) { + return $image_sizes; + } + + foreach (['thumbnail', 'medium', 'medium_large', 'large'] as $size) { + $image_sizes[$size] = [ + 'width' => (int)get_option($size . '_size_w'), + 'height' => (int)get_option($size . '_size_h'), + 'crop' => (bool)get_option($size . '_crop'), + ]; + } + + if ($_wp_additional_image_sizes) { + $image_sizes = array_merge($image_sizes, $_wp_additional_image_sizes); + } + + /** The filter image_size_names_choose is documented in wp-admin/includes/media.php */ + $image_sizes = array_filter(apply_filters('image_size_names_choose', $image_sizes), function ($size) { + return !empty($size['width']) && !empty($size['height']); + }); + + foreach ($image_sizes as $sizeName => $sizeAttrs) { + $label = ucwords(str_replace('_', ' ', $sizeName)); + if (is_array($sizeAttrs)) { + $label .= sprintf(' - %d x %d', $sizeAttrs['width'], $sizeAttrs['height']); + } + + $image_sizes[$sizeName]['label'] = $label; + } + + if (!array_key_exists('original', $image_sizes)) { + $image_sizes = ['original' => ['label' => __('Original', 'brizy')]] + $image_sizes; + } + + return $image_sizes; + } } diff --git a/editor/api.php b/editor/api.php index 58c99b4e02..16acf083d8 100755 --- a/editor/api.php +++ b/editor/api.php @@ -1,242 +1,231 @@ post; - } - - /** - * Brizy_Editor_API constructor. - * - * @param Brizy_Editor_Project $project - * @param Brizy_Editor_Post $post - */ - public function __construct($post) - { - - $this->post = $post; - - parent::__construct(); - } - - protected function initializeApiActions() - { - if ( ! Brizy_Editor_User::is_user_allowed()) { - return; - } - - $p = 'wp_ajax_'.Brizy_Editor::prefix(); - add_action($p.self::AJAX_REMOVE_LOCK, array($this, 'removeProjectLock')); - add_action($p.self::AJAX_HEARTBEAT, array($this, 'heartbeat')); - add_action($p.self::AJAX_TAKE_OVER, array($this, 'takeOver')); - add_action($p.self::AJAX_GET, array($this, 'get_item')); - add_action($p.self::AJAX_GET_POST_INFO, array($this, 'get_post_info')); - add_action($p.self::AJAX_UPDATE, array($this, 'update_item')); - add_action($p.self::AJAX_GET_PROJECT, array($this, 'get_project')); - add_action($p.self::AJAX_SET_PROJECT, array($this, 'set_project')); - add_action($p.self::AJAX_LOCK_PROJECT, array($this, 'lock_project')); - add_action($p.self::AJAX_SIDEBARS, array($this, 'get_sidebars')); - add_action($p.self::AJAX_SHORTCODE_CONTENT, array($this, 'shortcode_content')); - add_action($p.self::AJAX_PLACEHOLDER_CONTENT, array($this, 'placeholder_content')); - add_action($p.self::AJAX_PLACEHOLDERS_CONTENT, array($this, 'placeholders_content')); - add_action($p.self::AJAX_GET_POST_OBJECTS, array($this, 'get_post_objects')); - add_action($p.self::AJAX_SEARCH_POST, array($this, 'search_post')); - add_action($p.self::AJAX_GET_MENU_LIST, array($this, 'get_menu_list')); - add_action($p.self::AJAX_GET_TERMS, array($this, 'get_terms')); - add_action($p.self::AJAX_GET_USERS, array($this, 'get_users')); - add_action($p.self::AJAX_GET_TERMS_BY, array($this, 'get_terms_by')); - add_action($p.self::AJAX_MEDIA_METAKEY, array($this, 'get_media_key')); - add_action($p.self::AJAX_CREATE_ATTACHMENT_UID, array($this, 'get_attachment_key')); - add_action($p.self::AJAX_SET_FEATURED_IMAGE, array($this, 'set_featured_image')); - add_action($p.self::AJAX_SET_IMAGE_FOCAL_PT, array($this, 'set_featured_image_focal_point')); - add_action($p.self::AJAX_TIMESTAMP, array($this, 'timestamp')); - add_action($p.self::AJAX_SET_TEMPLATE_TYPE, array($this, 'setTemplateType')); - add_action($p.self::AJAX_GET_POST_TAXONOMIES, array($this, 'addPostTaxonomies')); - add_action($p.'nopriv_'.Brizy_Editor::prefix(self::AJAX_TIMESTAMP), array($this, 'timestamp')); - - } - - protected function getRequestNonce() - { - return $this->param('hash'); - } - - public function addPostTaxonomies() - { - - $this->verifyNonce(self::nonce); - - if (empty($postType = $this->param('post_type'))) { - $this->error(400, 'Bad request'); - } - - $taxonomies = get_object_taxonomies($postType, 'objects'); - $post_taxonomies = array_map(function (WP_Taxonomy $taxonomy) { - return [ - 'name' => $taxonomy->name, - 'label' => $taxonomy->label, - 'labels' => $taxonomy->labels, - 'public' => $taxonomy->public, - 'hierarchical' => $taxonomy->hierarchical, - ]; - }, array_values($taxonomies)); - - $this->success($post_taxonomies); - } - - public function lock_project() - { - $this->verifyNonce(self::nonce); - - if (Brizy_Editor::get()->checkIfProjectIsLocked() === false) { - Brizy_Editor::get()->lockProject(); - } - - $editor = new Brizy_Editor_Editor_Editor(Brizy_Editor_Project::get(), null); - $this->success($editor->getProjectStatus()); - } - - public function removeProjectLock() - { - $this->verifyNonce(self::nonce); - - if (Brizy_Editor::get()->checkIfProjectIsLocked() === false) { - Brizy_Editor::get()->removeProjectLock(); - } - - $editor = new Brizy_Editor_Editor_Editor(Brizy_Editor_Project::get(), null); - $this->success($editor->getProjectStatus()); - } - - public function heartbeat() - { - $this->verifyNonce(self::nonce); - - if (Brizy_Editor::get()->checkIfProjectIsLocked() === false) { - Brizy_Editor::get()->lockProject(); - } - $editor = new Brizy_Editor_Editor_Editor(Brizy_Editor_Project::get(), null); - $this->success($editor->getProjectStatus()); - } - - public function takeOver() - { - $this->verifyNonce(self::nonce); - - Brizy_Editor::get()->lockProject(); - - $editor = new Brizy_Editor_Editor_Editor(Brizy_Editor_Project::get(), null); - $this->success($editor->getProjectStatus()); - } - - public function timestamp() - { - $this->success(array('timestamp' => time())); - } - - - public function set_featured_image() - { - $this->verifyNonce(self::nonce); - - if ( ! isset($_REQUEST['attachmentId'])) { - $this->error(400, 'Bad request'); - } +class Brizy_Editor_API extends Brizy_Admin_AbstractApi { + + const nonce = 'brizy-api'; + const AJAX_GET_POST_INFO = '_get_post_info'; + const AJAX_GET = '_editor_get_items'; + const AJAX_UPDATE = '_update_item'; + const AJAX_GET_PROJECT = '_get_project'; + const AJAX_SET_PROJECT = '_set_project'; + const AJAX_LOCK_PROJECT = '_lock_project'; + const AJAX_MEDIA = '_media'; + const AJAX_SIDEBARS = '_sidebars'; + const AJAX_SIDEBAR_CONTENT = '_sidebar_content'; + const AJAX_SHORTCODE_CONTENT = '_shortcode_content'; + const AJAX_PLACEHOLDER_CONTENT = '_placeholder_content'; + const AJAX_PLACEHOLDERS_CONTENT = '_placeholders_content'; + const AJAX_GET_POST_OBJECTS = '_get_posts'; + const AJAX_SEARCH_POST = '_search_posts'; + const AJAX_GET_MENU_LIST = '_get_menu_list'; + const AJAX_REMOVE_LOCK = '_remove_lock'; + const AJAX_HEARTBEAT = '_heartbeat'; + const AJAX_TAKE_OVER = '_take_over'; + const AJAX_DOWNLOAD_MEDIA = '_download_media'; + const AJAX_JWT_TOKEN = '_multipass_create'; + const AJAX_UPDATE_MENU_DATA = '_update_menu_data'; + const AJAX_UPDATE_EDITOR_META_DATA = '_update_editor_meta_data'; + const AJAX_UPDATE_MENU_ITEM_DATA = '_update_menu_item_data'; + const AJAX_MEDIA_METAKEY = '_get_media_key'; + const AJAX_CREATE_ATTACHMENT_UID = '_create_attachment_uid'; + const AJAX_SET_FEATURED_IMAGE = '_set_featured_image'; + const AJAX_SET_IMAGE_FOCAL_PT = '_set_featured_image_focal_point'; + const AJAX_REMOVE_FEATURED_IMAGE = '_remove_featured_image'; + const AJAX_TIMESTAMP = '_timestamp'; + const AJAX_SET_TEMPLATE_TYPE = '_set_template_type'; + const AJAX_GET_USERS = '_get_users'; + const AJAX_GET_TERMS = '_get_terms'; + const AJAX_GET_TERMS_BY = '_get_terms_by'; + const AJAX_GET_POST_TAXONOMIES = '_get_post_taxonomies'; + + + /** + * @var Brizy_Editor_Post + */ + private $post; + + /** + * @return Brizy_Editor_Post + */ + public function get_post() { + return $this->post; + } + + /** + * Brizy_Editor_API constructor. + * + * @param Brizy_Editor_Project $project + * @param Brizy_Editor_Post $post + */ + public function __construct( $post ) { + + $this->post = $post; + + parent::__construct(); + } + + protected function initializeApiActions() { + if ( ! Brizy_Editor_User::is_user_allowed() ) { + return; + } + + + $this->addAjaxAction( self::AJAX_REMOVE_LOCK, array( $this, 'removeProjectLock' ) ); + $this->addAjaxAction( self::AJAX_HEARTBEAT, array( $this, 'heartbeat' ) ); + $this->addAjaxAction( self::AJAX_TAKE_OVER, array( $this, 'takeOver' ) ); + $this->addAjaxAction( self::AJAX_GET, array( $this, 'get_item' ) ); + $this->addAjaxAction( self::AJAX_GET_POST_INFO, array( $this, 'get_post_info' ) ); + $this->addAjaxAction( self::AJAX_UPDATE, array( $this, 'update_item' ) ); + $this->addAjaxAction( self::AJAX_GET_PROJECT, array( $this, 'get_project' ) ); + $this->addAjaxAction( self::AJAX_SET_PROJECT, array( $this, 'set_project' ) ); + $this->addAjaxAction( self::AJAX_LOCK_PROJECT, array( $this, 'lock_project' ) ); + $this->addAjaxAction( self::AJAX_SIDEBARS, array( $this, 'get_sidebars' ) ); + $this->addAjaxAction( self::AJAX_SHORTCODE_CONTENT, array( $this, 'shortcode_content' ) ); + $this->addAjaxAction( self::AJAX_PLACEHOLDER_CONTENT, array( $this, 'placeholder_content' ) ); + $this->addAjaxAction( self::AJAX_PLACEHOLDERS_CONTENT, array( $this, 'placeholders_content' ) ); + $this->addAjaxAction( self::AJAX_GET_POST_OBJECTS, array( $this, 'get_post_objects' ) ); + $this->addAjaxAction( self::AJAX_SEARCH_POST, array( $this, 'search_post' ) ); + $this->addAjaxAction( self::AJAX_GET_MENU_LIST, array( $this, 'get_menu_list' ) ); + $this->addAjaxAction( self::AJAX_GET_TERMS, array( $this, 'get_terms' ) ); + $this->addAjaxAction( self::AJAX_GET_USERS, array( $this, 'get_users' ) ); + $this->addAjaxAction( self::AJAX_GET_TERMS_BY, array( $this, 'get_terms_by' ) ); + $this->addAjaxAction( self::AJAX_DOWNLOAD_MEDIA, array( $this, 'download_media' ) ); + $this->addAjaxAction( self::AJAX_MEDIA_METAKEY, array( $this, 'get_media_key' ) ); + $this->addAjaxAction( self::AJAX_CREATE_ATTACHMENT_UID, array( $this, 'get_attachment_key' ) ); + $this->addAjaxAction( self::AJAX_SET_FEATURED_IMAGE, array( $this, 'set_featured_image' ) ); + $this->addAjaxAction( self::AJAX_SET_IMAGE_FOCAL_PT, array( $this, 'set_featured_image_focal_point' ) ); + $this->addAjaxAction( self::AJAX_TIMESTAMP, array( $this, 'timestamp' ) ); + $this->addAjaxAction( self::AJAX_SET_TEMPLATE_TYPE, array( $this, 'setTemplateType' ) ); + $this->addAjaxAction( self::AJAX_GET_POST_TAXONOMIES, array( $this, 'addPostTaxonomies' ) ); + $this->addNoPrivAjaxAction( Brizy_Editor::prefix( self::AJAX_TIMESTAMP ), array( $this, 'timestamp' ) ); + + } + + protected function getRequestNonce() { + return $this->param( 'hash' ); + } + + public function addPostTaxonomies() { + + $this->verifyNonce( self::nonce ); + + if ( empty( $postType = $this->param( 'post_type' ) ) ) { + $this->error( 400, 'Bad request' ); + } + + $taxonomies = get_object_taxonomies( $postType, 'objects' ); + $post_taxonomies = array_map( function ( WP_Taxonomy $taxonomy ) { + return [ + 'name' => $taxonomy->name, + 'label' => $taxonomy->label, + 'labels' => $taxonomy->labels, + 'public' => $taxonomy->public, + 'hierarchical' => $taxonomy->hierarchical, + ]; + }, array_values( $taxonomies ) ); + + $this->success( $post_taxonomies ); + } + + public function lock_project() { + $this->verifyNonce( self::nonce ); + + if ( Brizy_Editor::get()->checkIfProjectIsLocked() === false ) { + Brizy_Editor::get()->lockProject(); + } + + $editor = new Brizy_Editor_Editor_Editor( Brizy_Editor_Project::get(), null ); + $this->success( $editor->getProjectStatus() ); + } + + public function removeProjectLock() { + $this->verifyNonce( self::nonce ); + + if ( Brizy_Editor::get()->checkIfProjectIsLocked() === false ) { + Brizy_Editor::get()->removeProjectLock(); + } + + $editor = new Brizy_Editor_Editor_Editor( Brizy_Editor_Project::get(), null ); + $this->success( $editor->getProjectStatus() ); + } + + public function heartbeat() { + $this->verifyNonce( self::nonce ); + + if ( Brizy_Editor::get()->checkIfProjectIsLocked() === false ) { + Brizy_Editor::get()->lockProject(); + } + $editor = new Brizy_Editor_Editor_Editor( Brizy_Editor_Project::get(), null ); + $this->success( $editor->getProjectStatus() ); + } - if ($this->post && $this->post->uses_editor()) { - set_post_thumbnail($this->post->getWpPostId(), (int)$_REQUEST['attachmentId']); + public function takeOver() { + $this->verifyNonce( self::nonce ); + + Brizy_Editor::get()->lockProject(); + + $editor = new Brizy_Editor_Editor_Editor( Brizy_Editor_Project::get(), null ); + $this->success( $editor->getProjectStatus() ); + } + + public function timestamp() { + $this->success( array( 'timestamp' => time() ) ); + } + + + public function set_featured_image() { + $this->verifyNonce( self::nonce ); + + if ( ! isset( $_REQUEST['attachmentId'] ) ) { + $this->error( 400, 'Bad request' ); + } - $uid = $this->createMediaKey($this->post->getWpPostId(), (int)$_REQUEST['attachmentId']); + if ( $this->post && $this->post->uses_editor() ) { + set_post_thumbnail( $this->post->getWpPostId(), (int) $_REQUEST['attachmentId'] ); - $this->success(array('uid' => $uid)); - } + $uid = $this->createMediaKey( $this->post->getWpPostId(), (int) $_REQUEST['attachmentId'] ); - $this->error(400, 'Invalid post'); - } + $this->success( array( 'uid' => $uid ) ); + } - public function set_featured_image_focal_point() - { - $this->verifyNonce(self::nonce); + $this->error( 400, 'Invalid post' ); + } - if ( ! isset($_REQUEST['attachmentId']) || ! isset($_REQUEST['pointX']) || ! isset($_REQUEST['pointY'])) { - $this->error(400, 'Bad request'); - } + public function set_featured_image_focal_point() { + $this->verifyNonce( self::nonce ); - if ($this->post && $this->post->uses_editor()) { + if ( ! isset( $_REQUEST['attachmentId'] ) || ! isset( $_REQUEST['pointX'] ) || ! isset( $_REQUEST['pointY'] ) ) { + $this->error( 400, 'Bad request' ); + } - update_post_meta( - $this->post->getWpPostId(), - 'brizy_attachment_focal_point', - array( - 'x' => $_REQUEST['pointX'], - 'y' => $_REQUEST['pointY'], - ) - ); + if ( $this->post && $this->post->uses_editor() ) { - $this->success(array()); - } + update_post_meta( + $this->post->getWpPostId(), + 'brizy_attachment_focal_point', + array( + 'x' => $_REQUEST['pointX'], + 'y' => $_REQUEST['pointY'], + ) + ); - $this->error(400, 'Invalid post'); - } + $this->success( array() ); + } - public function remove_featured_image() - { - $this->verifyNonce(self::nonce); + $this->error( 400, 'Invalid post' ); + } - if ($this->post && $this->post->uses_editor()) { - delete_post_thumbnail($this->post->getWpPostId()); - delete_post_meta($this->post->getWpPostId(), 'brizy_attachment_focal_point'); - $this->success(null); - } + public function remove_featured_image() { + $this->verifyNonce( self::nonce ); - $this->error(400, 'Invalid post'); - } + if ( $this->post && $this->post->uses_editor() ) { + delete_post_thumbnail( $this->post->getWpPostId() ); + delete_post_meta( $this->post->getWpPostId(), 'brizy_attachment_focal_point' ); + $this->success( null ); + } + + $this->error( 400, 'Invalid post' ); + } // public function multipass_create() { @@ -291,808 +280,790 @@ public function remove_featured_image() // } // } - /** - * @internal - **/ - public function get_project() - { - try { - $this->verifyNonce(self::nonce); - $data = Brizy_Editor_Project::get()->createResponse(); - $this->success($data); - } catch (Exception $exception) { - Brizy_Logger::instance()->exception($exception); - $this->error($exception->getCode(), $exception->getMessage()); - } - } - - /** - * @internal - */ - public function set_project() - { - try { - $this->verifyNonce(self::nonce); - - // update project globas - $meta = stripslashes($this->param('data')); - $dataVersion = (int)stripslashes($this->param('dataVersion')); - - if ( ! $meta) { - Brizy_Logger::instance()->error('Invalid project meta provided', ['data' => $meta]); - throw new Exception('', 400); - } - - if ( ! $dataVersion) { - Brizy_Logger::instance()->error('No data version provided', ['data' => $dataVersion]); - throw new Exception('', 400); - } - - $project = Brizy_Editor_Project::get(); - $project->setDataAsJson($meta); - $project->setDataVersion($dataVersion); - - - if ((int)$this->param('is_autosave') === 1) { - $project->save(1); - } else { - $project->save(); - $project->savePost(); - Brizy_Editor::get()->lockProject(); - do_action('brizy_global_data_updated'); - } - - $this->success($project->createResponse()); - } catch (Exception $exception) { - Brizy_Logger::instance()->exception($exception); - $this->error(400, $exception->getMessage()); - exit; - } - } - - /** - * @internal - **/ - public function get_item() - { - try { - $this->verifyNonce(self::nonce); - - if ( ! $this->post) { - throw new Exception('Invalid post provided'); - } - - $data = $this->post->createResponse(); - $data['is_index'] = true; - - $this->success(array($data)); - } catch (Exception $exception) { - Brizy_Logger::instance()->exception($exception); - $this->error(500, $exception->getMessage()); - exit; - } - } - - /** - * @internal - **/ - public function get_post_info() - { - try { - $this->verifyNonce(self::nonce); - - $postId = (int)$this->param('post_id'); - $defaultFields = ['ID', 'post_title', 'post_content']; - $post_fields = array_intersect((array)$this->param('fields'), $defaultFields); - - if (count($post_fields) == 0) { - $post_fields = $defaultFields; - } - - if ( ! $postId) { - $this->error(400, 'Invalid post id'); - } - - $post = get_post($postId, ARRAY_A); - - if ( ! $post) { - $this->error(404, 'Invalid post id'); - } - - $data = array_intersect_key($post, array_flip($defaultFields)); - - $this->success($data); - } catch (Exception $exception) { - Brizy_Logger::instance()->exception($exception); - $this->error(500, $exception->getMessage()); - exit; - } - } - - /** - * @internal - **/ - public function update_item() - { - try { - $this->verifyNonce(self::nonce); - - $data = stripslashes($this->param('data')); - $atemplate = $this->param('template'); - $dataVersion = (int)stripslashes($this->param('dataVersion')); - $status = stripslashes($this->param('status')); - - if ( ! in_array($status, ['publish', 'draft', 'pending', 'private', 'future'])) { - $this->error(400, "Invalid post type"); - } - - if ($atemplate) { - $this->post->set_template($atemplate); - } - - if ($data) { - $this->post->set_editor_data($data); - $this->post->set_editor_version(BRIZY_EDITOR_VERSION); - $this->post->set_needs_compile(true); - } - - $this->post->getWpPost()->post_status = $status; - - if ((int)$this->param('is_autosave') == 1) { - $this->post->save(1); - } else { - $this->post->setDataVersion($dataVersion); - $this->post->setLastUserEdited(get_current_user_id()); - $this->post->save(0); - $this->post->savePost(true); - } - - $this->success($this->post->createResponse()); - } catch (Exception $exception) { - Brizy_Logger::instance()->exception($exception); - $this->error(500, $exception->getMessage()); - } - } - - /* - * Used for elements like Woocommerce pages. - */ - public function shortcode_content() - { - try { - - $this->verifyNonce(self::nonce); - - if (isset($_REQUEST['shortcode'])) { - $shortcode = stripslashes($_REQUEST['shortcode']); - } else { - throw new Exception('Shortcode string not provided.', 500); - } - - $shortcode_content = do_shortcode($shortcode); - - $this->success( - array( - 'shortcode' => $shortcode_content, - ) - ); - - } catch (Exception $exception) { - Brizy_Logger::instance()->exception($exception); - $this->error($exception->getCode(), $exception->getMessage()); - } - } - - public function placeholder_content() - { - try { - $this->verifyNonce(self::nonce); - $postId = $this->param('post_id'); - $placeholders = $this->param('placeholders'); - - if ( ! $placeholders) { - throw new Exception('Placeholder string not provided.', 400); - } - - global $post, $wp_query; - - $post = $this->getPostSample($postId); - - if ($post instanceof WP_Post) { - setup_postdata($post); - $wp_query->is_single = true; - - if (function_exists('wc_get_product')) { - global $product; - - $product = wc_get_product($post->ID); - } - } - - $contents = []; - foreach ($placeholders as $placeholder) { - $placeholder = stripslashes($placeholder); - $contents[] = apply_filters('brizy_content', $placeholder, Brizy_Editor_Project::get(), $post); - } - - $this->success( - array( - 'placeholders' => $contents, - ) - ); - } catch (Exception $exception) { - Brizy_Logger::instance()->exception($exception); - $this->error($exception->getCode(), $exception->getMessage()); - } - } - - public function placeholders_content() - { - global $post, $wp_query; - try { - $this->verifyNonce(self::nonce); - $posts = $this->param('p'); - $contents = []; - foreach ($posts as $postId => $placeholders) { - $post = $this->getPostSample($postId); - $contents[$postId] = []; - - if ($post instanceof WP_Post) { - setup_postdata($post); - $wp_query->is_single = true; - } - foreach ($placeholders as $placeholder) { - $placeholder = stripslashes($placeholder); - $contents[$postId][] = apply_filters( - 'brizy_content', - $placeholder, - Brizy_Editor_Project::get(), - $post - ); - } - } - $this->success( - array( - 'placeholders' => $contents, - ) - ); - } catch (Exception $exception) { - Brizy_Logger::instance()->exception($exception); - $this->error($exception->getCode(), $exception->getMessage()); - } - } - - private function getPostSample($templateId) - { - global $wp_query; - $wp_post = get_post($templateId); - if ($wp_post->post_type !== Brizy_Admin_Templates::CP_TEMPLATE) { - return $wp_post; - } - - - $ruleManager = new Brizy_Admin_Rules_Manager(); - $rules = $ruleManager->getRules($wp_post->ID); - $rule = null; - - // find first include rule - foreach ($rules as $rule) { - /** - * @var Brizy_Admin_Rule $rule ; - */ - if ($rule->getType() == Brizy_Admin_Rule::TYPE_INCLUDE) { - break; - } - } - - if ($rule) { - switch ($rule->getAppliedFor()) { - case Brizy_Admin_Rule::POSTS : - $args = [ - 'fields' => 'ids', - 'post_type' => $rule->getEntityType(), - 'posts_per_page' => -1, - 'meta_query' => [ - [ - 'key' => Brizy_Editor_Constants::BRIZY_ENABLED, - 'compare' => 'NOT EXISTS', - ], - ], - ]; - - $values = $rule->getEntityValues(); - $posts = []; - if (empty($values[0])) { - // For All condition - $posts = get_posts($args); - } else { - $filter = $values[0]; - - if (is_numeric($filter)) { - $args['post__in'] = [$filter]; - } else { - // $filter = in|category|12 OR in|genre|48 OR in|category|45 OR author|2 - $explode = explode('|', $filter); - - if ($explode[0] === 'in') { - $args['tax_query'] = [ - [ - 'taxonomy' => $explode[1], - 'terms' => $explode[2], - ], - ]; - } else { - $args['author'] = $explode[1]; - } - } - - $posts = get_posts($args); - } - - if ($post = array_pop($posts)) { - return get_post($post); - } else { - return $wp_post; - } - - case Brizy_Admin_Rule::TAXONOMY : - $args = array( - 'taxonomy' => $rule->getEntityType(), - 'hide_empty' => true, - ); - - if (count($rule->getEntityValues())) { - $args['term_taxonomy_id'] = $rule->getEntityValues(); - } - - $terms = get_terms($args); - $term = array_pop($terms); - - if ($term) { - $wp_query = new WP_Query( - [ - 'tax_query' => [ - [ - 'taxonomy' => $rule->getEntityType(), - 'field' => 'term_id', - 'terms' => $term->term_id, - ], - ], - ] - ); - - $wp_query->is_tax = true; - } - - return array_pop($terms); - - case Brizy_Admin_Rule::WOO_SHOP_PAGE : - $wp_query = new WP_Query(['post_type' => 'product', 'fields' => 'ids']); - if (function_exists('wc_get_page_id') && wc_get_page_id('shop')) { - return get_post(wc_get_page_id('shop')); - } - break; - case Brizy_Admin_Rule::ARCHIVE : - if ($rule->getEntityType() == 'product') { - $wp_query = new WP_Query(['post_type' => 'product', 'fields' => 'ids']); - $posts = $wp_query->get_posts(); - - return get_post(array_pop($posts)); - } - $posts = $wp_query->get_posts(); - - return get_post(array_pop($posts));; - case Brizy_Admin_Rule::TEMPLATE : - - switch ($rule->getEntityType()) { - case 'author': - $authors = get_users(); - $wp_query = new WP_Query( - ['author_name' => get_userdata(get_current_user_id())->data->user_nicename] - ); - $wp_query->is_author = true; - - return array_pop($authors); - - - case '404': - $wp_query->is_404 = true; - - return null; - case 'search': - $wp_query->is_search = true; - - return null; - - case 'home_page': - $get_option = get_option('page_for_posts'); - - if ($get_option) { - return get_post($get_option); - } - break; - case 'front_page': - $get_option = get_option('page_on_front'); - - if ($get_option) { - return get_post($get_option); - } - break; - } - - break; - case Brizy_Admin_Rule::YEAR_ARCHIVE: - - $wp_query = new WP_Query('year='.date('Y')); - $wp_query->is_year = true; + /** + * @internal + **/ + public function get_project() { + try { + $this->verifyNonce( self::nonce ); + $data = Brizy_Editor_Project::get()->createResponse(); + $this->success( $data ); + } catch ( Exception $exception ) { + Brizy_Logger::instance()->exception( $exception ); + $this->error( $exception->getCode(), $exception->getMessage() ); + } + } + + /** + * @internal + */ + public function set_project() { + try { + $this->verifyNonce( self::nonce ); + + // update project globas + $meta = stripslashes( $this->param( 'data' ) ); + $dataVersion = (int) stripslashes( $this->param( 'dataVersion' ) ); + + if ( ! $meta ) { + Brizy_Logger::instance()->error( 'Invalid project meta provided', [ 'data' => $meta ] ); + throw new Exception( '', 400 ); + } + + if ( ! $dataVersion ) { + Brizy_Logger::instance()->error( 'No data version provided', [ 'data' => $dataVersion ] ); + throw new Exception( '', 400 ); + } + + $project = Brizy_Editor_Project::get(); + $project->setDataAsJson( $meta ); + $project->setDataVersion( $dataVersion ); + + + if ( (int) $this->param( 'is_autosave' ) === 1 ) { + $project->save( 1 ); + } else { + $project->save(); + $project->savePost(); + Brizy_Editor::get()->lockProject(); + do_action( 'brizy_global_data_updated' ); + } + + $this->success( $project->createResponse() ); + } catch ( Exception $exception ) { + Brizy_Logger::instance()->exception( $exception ); + $this->error( 400, $exception->getMessage() ); + exit; + } + } + + /** + * @internal + **/ + public function get_item() { + try { + $this->verifyNonce( self::nonce ); + + if ( ! $this->post ) { + throw new Exception( 'Invalid post provided' ); + } + + $data = $this->post->createResponse(); + $data['is_index'] = true; + + $this->success( array( $data ) ); + } catch ( Exception $exception ) { + Brizy_Logger::instance()->exception( $exception ); + $this->error( 500, $exception->getMessage() ); + exit; + } + } + + /** + * @internal + **/ + public function get_post_info() { + try { + $this->verifyNonce( self::nonce ); + + $postId = (int) $this->param( 'post_id' ); + $defaultFields = [ 'ID', 'post_title', 'post_content' ]; + $post_fields = array_intersect( (array) $this->param( 'fields' ), $defaultFields ); + + if ( count( $post_fields ) == 0 ) { + $post_fields = $defaultFields; + } + + if ( ! $postId ) { + $this->error( 400, 'Invalid post id' ); + } + + $post = get_post( $postId, ARRAY_A ); + + if ( ! $post ) { + $this->error( 404, 'Invalid post id' ); + } + + $data = array_intersect_key( $post, array_flip( $defaultFields ) ); + + $this->success( $data ); + } catch ( Exception $exception ) { + Brizy_Logger::instance()->exception( $exception ); + $this->error( 500, $exception->getMessage() ); + exit; + } + } + + /** + * @internal + **/ + public function update_item() { + try { + $this->verifyNonce( self::nonce ); + + $data = stripslashes( $this->param( 'data' ) ); + $atemplate = $this->param( 'template' ); + $dataVersion = (int) stripslashes( $this->param( 'dataVersion' ) ); + $status = stripslashes( $this->param( 'status' ) ); + + if ( ! in_array( $status, [ 'publish', 'draft', 'pending', 'private', 'future' ] ) ) { + $this->error( 400, "Invalid post type" ); + } + + if ( $atemplate ) { + $this->post->set_template( $atemplate ); + } + + if ( $data ) { + $this->post->set_editor_data( $data ); + $this->post->set_editor_version( BRIZY_EDITOR_VERSION ); + $this->post->set_needs_compile( true ); + } + + $this->post->getWpPost()->post_status = $status; + + if ( (int) $this->param( 'is_autosave' ) == 1 ) { + $this->post->save( 1 ); + } else { + $this->post->setDataVersion( $dataVersion ); + $this->post->setLastUserEdited( get_current_user_id() ); + $this->post->save( 0 ); + $this->post->savePost( true ); + } + + $this->success( $this->post->createResponse() ); + } catch ( Exception $exception ) { + Brizy_Logger::instance()->exception( $exception ); + $this->error( 500, $exception->getMessage() ); + } + } + + /* + * Used for elements like Woocommerce pages. + */ + public function shortcode_content() { + try { + + $this->verifyNonce( self::nonce ); + + if ( isset( $_REQUEST['shortcode'] ) ) { + $shortcode = stripslashes( $_REQUEST['shortcode'] ); + } else { + throw new Exception( 'Shortcode string not provided.', 500 ); + } + + $shortcode_content = do_shortcode( $shortcode ); + + $this->success( + array( + 'shortcode' => $shortcode_content, + ) + ); + + } catch ( Exception $exception ) { + Brizy_Logger::instance()->exception( $exception ); + $this->error( $exception->getCode(), $exception->getMessage() ); + } + } + + public function placeholder_content() { + try { + $this->verifyNonce( self::nonce ); + $postId = $this->param( 'post_id' ); + $placeholders = $this->param( 'placeholders' ); + + if ( ! $placeholders ) { + throw new Exception( 'Placeholder string not provided.', 400 ); + } + + global $post, $wp_query; + + $post = $this->getPostSample( $postId ); + + if ( $post instanceof WP_Post ) { + setup_postdata( $post ); + $wp_query->is_single = true; + + if ( function_exists( 'wc_get_product' ) ) { + global $product; + + $product = wc_get_product( $post->ID ); + } + } + + $contents = []; + foreach ( $placeholders as $placeholder ) { + $placeholder = stripslashes( $placeholder ); + $contents[] = apply_filters( 'brizy_content', $placeholder, Brizy_Editor_Project::get(), $post ); + } + + $this->success( array( 'placeholders' => $contents ) ); + } catch ( Exception $exception ) { + Brizy_Logger::instance()->exception( $exception ); + $this->error( $exception->getCode(), $exception->getMessage() ); + } + } + + public function placeholders_content() { + global $post, $wp_query; + + $this->verifyNonce( self::nonce ); + $posts = $this->param( 'p' ); + $contents = []; + foreach ( $posts as $postId => $placeholders ) { + + $post = $this->getPostSample( $postId ); + $contents[ $postId ] = []; + + if ( $post instanceof WP_Post ) { + setup_postdata( $post ); + $wp_query->is_single = true; + } + foreach ( $placeholders as $placeholder ) { + try { + $placeholder = stripslashes( $placeholder ); + $contents[ $postId ][] = apply_filters( + 'brizy_content', + $placeholder, + Brizy_Editor_Project::get(), + $post + ); + } catch ( Exception $exception ) { + Brizy_Logger::instance()->exception( $exception ); + continue; + } + } + + + } + $this->success( + array( + 'placeholders' => $contents, + ) + ); + + } + + private function getPostSample( $templateId ) { + global $wp_query; + $wp_post = get_post( $templateId ); + if ( $wp_post->post_type !== Brizy_Admin_Templates::CP_TEMPLATE ) { + return $wp_post; + } + + + $ruleManager = new Brizy_Admin_Rules_Manager(); + $rules = $ruleManager->getRules( $wp_post->ID ); + $rule = null; + + // find first include rule + foreach ( $rules as $rule ) { + /** + * @var Brizy_Admin_Rule $rule ; + */ + if ( $rule->getType() == Brizy_Admin_Rule::TYPE_INCLUDE ) { + break; + } + } + + if ( $rule ) { + switch ( $rule->getAppliedFor() ) { + case Brizy_Admin_Rule::POSTS : + $args = [ + 'fields' => 'ids', + 'post_type' => $rule->getEntityType(), + 'posts_per_page' => - 1, + 'meta_query' => [ + [ + 'key' => Brizy_Editor_Constants::BRIZY_ENABLED, + 'compare' => 'NOT EXISTS', + ], + ], + ]; + + $values = $rule->getEntityValues(); + $posts = []; + if ( empty( $values[0] ) ) { + // For All condition + $posts = get_posts( $args ); + } else { + $filter = $values[0]; + + if ( is_numeric( $filter ) ) { + $args['post__in'] = [ $filter ]; + } else { + // $filter = in|category|12 OR in|genre|48 OR in|category|45 OR author|2 + $explode = explode( '|', $filter ); + + if ( $explode[0] === 'in' ) { + $args['tax_query'] = [ + [ + 'taxonomy' => $explode[1], + 'terms' => $explode[2], + ], + ]; + } else { + $args['author'] = $explode[1]; + } + } + + $posts = get_posts( $args ); + } + + if ( $post = array_pop( $posts ) ) { + return get_post( $post ); + } else { + return $wp_post; + } + + case Brizy_Admin_Rule::TAXONOMY : + $args = array( + 'taxonomy' => $rule->getEntityType(), + 'hide_empty' => true, + ); + + if ( count( $rule->getEntityValues() ) ) { + $args['term_taxonomy_id'] = $rule->getEntityValues(); + } + + $terms = get_terms( $args ); + $term = array_pop( $terms ); + + if ( $term ) { + $wp_query = new WP_Query( + [ + 'tax_query' => [ + [ + 'taxonomy' => $rule->getEntityType(), + 'field' => 'term_id', + 'terms' => $term->term_id, + ], + ], + ] + ); + + $wp_query->is_tax = true; + } + + + return array_pop( $terms ); + + case Brizy_Admin_Rule::WOO_SHOP_PAGE : + $wp_query = new WP_Query( [ 'post_type' => 'product', 'fields' => 'ids' ] ); + if ( function_exists( 'wc_get_page_id' ) && wc_get_page_id( 'shop' ) ) { + return get_post( wc_get_page_id( 'shop' ) ); + } + break; + case Brizy_Admin_Rule::ARCHIVE : + if ( $rule->getEntityType() == 'product' ) { + $wp_query = new WP_Query( [ 'post_type' => 'product', 'fields' => 'ids' ] ); + $posts = $wp_query->get_posts(); + + return get_post( array_pop( $posts ) ); + } + $posts = $wp_query->get_posts(); + + return get_post( array_pop( $posts ) );; + case Brizy_Admin_Rule::TEMPLATE : + + switch ( $rule->getEntityType() ) { + case 'author': + $authors = get_users(); + $wp_query = new WP_Query( + [ 'author_name' => get_userdata( get_current_user_id() )->data->user_nicename ] + ); + $wp_query->is_author = true; + + return array_pop( $authors ); + + + case '404': + $wp_query->is_404 = true; + + return null; + case 'search': + $wp_query->is_search = true; + + return null; + + case 'home_page': + $get_option = get_option( 'page_for_posts' ); + + if ( $get_option ) { + return get_post( $get_option ); + } + break; + case 'front_page': + $get_option = get_option( 'page_on_front' ); + + if ( $get_option ) { + return get_post( $get_option ); + } + break; + } + + break; + case Brizy_Admin_Rule::YEAR_ARCHIVE: + + $wp_query = new WP_Query( 'year=' . date( 'Y' ) ); + $wp_query->is_year = true; + + return null; + case Brizy_Admin_Rule::MONTH_ARCHIVE: + + $wp_query = new WP_Query( 'year=' . date( 'Y' ) . '&monthnum=' . date( 'm' ) ); + $wp_query->is_month = true; + + return null; + case Brizy_Admin_Rule::DAY_ARCHIVE: + + $wp_query = new WP_Query( 'year=' . date( 'Y' ) . '&monthnum=' . date( 'm' ) . '&day=' . date( 'd' ) ); + $wp_query->is_day = true; - return null; - case Brizy_Admin_Rule::MONTH_ARCHIVE: + return null; + } + } + } - $wp_query = new WP_Query('year='.date('Y').'&monthnum='.date('m')); - $wp_query->is_month = true; + public function get_post_objects() { - return null; - case Brizy_Admin_Rule::DAY_ARCHIVE: + global $wp_post_types; + $this->verifyNonce( self::nonce ); - $wp_query = new WP_Query('year='.date('Y').'&monthnum='.date('m').'&day='.date('d')); - $wp_query->is_day = true; + $searchTerm = $this->param( 'filterTerm' ); + $postType = $this->param( 'postType' ) ? $this->param( 'postType' ) : null; + $excludePostType = $this->param( 'excludePostTypes' ) ? $this->param( 'excludePostTypes' ) : array(); - return null; - } - } - } + if ( ! $postType ) { + $postType = array_keys( + array_filter( + $wp_post_types, + function ( $type ) { + return ! in_array( $type->name, array( 'brizy_template' ) ) && $type->show_ui; + } + ) + ); + } - public function get_post_objects() - { + add_filter( 'posts_where', array( $this, 'brizy_post_title_filter' ), 10, 2 ); + $posts = Brizy_Editor_Post::get_post_list( $searchTerm, $postType, $excludePostType, 0, 10000 ); + remove_filter( 'posts_where', array( $this, 'brizy_post_title_filter' ), 10 ); - global $wp_post_types; - $this->verifyNonce(self::nonce); + $this->success( array( 'filter_term' => $searchTerm, 'posts' => $posts ) ); + } - $searchTerm = $this->param('filterTerm'); - $postType = $this->param('postType') ? $this->param('postType') : null; - $excludePostType = $this->param('excludePostTypes') ? $this->param('excludePostTypes') : array(); + public function get_sidebars() { + global $wp_registered_sidebars; - if ( ! $postType) { - $postType = array_keys( - array_filter( - $wp_post_types, - function ($type) { - return ! in_array($type->name, array('brizy_template')) && $type->show_ui; - } - ) - ); - } + $this->verifyNonce( self::nonce ); - add_filter('posts_where', array($this, 'brizy_post_title_filter'), 10, 2); - $posts = Brizy_Editor_Post::get_post_list($searchTerm, $postType, $excludePostType, 0, 10000); - remove_filter('posts_where', array($this, 'brizy_post_title_filter'), 10); + $items = array(); - $this->success(array('filter_term' => $searchTerm, 'posts' => $posts)); - } + foreach ( $wp_registered_sidebars as $sidebar ) { + $item = array( + 'id' => $sidebar['id'], + 'title' => $sidebar['name'], + ); + $items[] = $item; + } - public function get_sidebars() - { - global $wp_registered_sidebars; + $this->success( $items ); + } - $this->verifyNonce(self::nonce); + public function brizy_post_title_filter( $where, $wp_query = null ) { - $items = array(); + global $wpdb; - foreach ($wp_registered_sidebars as $sidebar) { - $item = array( - 'id' => $sidebar['id'], - 'title' => $sidebar['name'], - ); - $items[] = $item; - } - $this->success($items); - } + if ( $wp_query instanceof WP_Query && $term = $wp_query->get( 'post_title_term' ) ) { + $search_term = $wpdb->esc_like( $term ); + $search_term = ' \'%' . $search_term . '%\''; - public function brizy_post_title_filter($where, $wp_query = null) - { + $where .= ' AND ' . $wpdb->posts . '.post_title LIKE ' . $search_term; + } + + return $where; + } + + public function get_menu_list() { + $this->success( wp_get_nav_menus( array( 'hide_empty' => true ) ), 200 ); + } + + /** + * Used in woocomerce producs, block conditions + */ + public function get_terms() { + + try { + $this->verifyNonce( self::nonce ); + + $taxonomy = $this->param( 'taxonomy' ); + + $terms = (array) get_terms( array( 'taxonomy' => $taxonomy, 'hide_empty' => false ) ); + + $this->success( array_values( $terms ) ); + + } catch ( Exception $e ) { + Brizy_Logger::instance()->error( $e->getMessage(), [ $e ] ); + $this->error( 500, $e->getMessage() ); + } + } + + /** + * Used in posts filter element + */ + public function get_terms_by() { + + $this->verifyNonce( self::nonce ); + + $args = []; + + foreach ( [ 'taxonomy', 'search', 'include' ] as $field ) { + $value = $this->param( $field ); + if ( ! empty( $value ) ) { + $args[ $field ] = $value; + } + } + + $terms = get_terms( $args ); + + if ( is_wp_error( $terms ) ) { + $this->error( 200, $terms ); + } + + + $out = []; + foreach ( $terms as $term ) { + $out[] = [ + 'term_id' => $term->term_id, + 'name' => $term->name, + 'taxonomy' => $term->taxonomy, + 'taxonomy_name' => get_taxonomy( $term->taxonomy )->labels->singular_name, + ]; + } + + $this->success( $out ); + } + + /** + * Used in posts filter element + */ + public function search_post() { + $this->verifyNonce( self::nonce ); + $args = [ 'numberposts' => - 1 ]; + $args['post_type'] = array_values( get_post_types( [ 'public' => true ] ) ); + + // exclude attachments + if ( ( $key = array_search( 'attachment', $args['post_type'] ) ) !== false ) { + unset( $args['post_type'][ $key ] ); + } + + // se post types + if ( $requiredTypes = $this->param( 'post_type' ) ) { + if ( is_string( $requiredTypes ) ) { + $args['post_type'] = [ $requiredTypes ]; + } else { + $args['post_type'] = $requiredTypes; + } + } + + // exclude post types + if ( $excludeTypes = $this->param( 'exclude_post_type' ) ) { + if ( is_string( $excludeTypes ) ) { + if ( ( $key = array_search( $excludeTypes, $args['post_type'] ) ) !== false ) { + unset( $args['post_type'][ $key ] ); + } + } else { + $args['post_type'] = array_diff( $args['post_type'], $excludeTypes ); + } + } + + // include posts by id + if ( $this->param( 'include' ) ) { + $args['post__in'] = $this->param( 'include' ); + } elseif ( $this->param( 'search' ) /*&& strlen($this->param('search')) >= 3*/ ) { + $args['s'] = $this->param( 'search' ); + } else { + $this->success( [] ); + } + + $posts = get_posts( $args ); + + if ( is_wp_error( $posts ) ) { + $this->error( 200, $posts ); + } + + $out = []; + foreach ( $posts as $post ) { + $pt = get_post_type_object( $post->post_type ); + $out[] = [ + 'ID' => $post->ID, + 'title' => $post->post_title, + 'permalink' => "{{brizy_dc_permalink post_id=\"{$post->ID}\"}}", + 'postType' => [ + 'type' => $post->post_type, + 'singular_name' => $pt->labels->singular_name, + 'name' => $pt->labels->name + ] + ]; + } + + $this->success( $out ); + } + + public function get_users() { + $this->verifyNonce( self::nonce ); + + $args = []; + $search = $this->param( 'search' ); + $include = $this->param( 'include' ); + + $args['fields'] = $this->param( 'fields' ) ? $this->param( 'fields' ) : [ 'ID', 'display_name' ]; + + if ( $this->param( 'roles' ) && is_array( $this->param( 'roles' ) ) ) { + $args['role__in'] = $this->param( 'roles' ); + } + + if ( ! empty( $search ) ) { + $args['search'] = '*' . $search . '*'; + $args['search_columns'] = [ 'display_name' ]; + } + + if ( is_array( $include ) && ! empty( $include ) ) { + $args['include'] = $include; + } + + $users = get_users( $args ); + + $users = array_map( + function ( $user ) { + $user->ID = (int) $user->ID; + + return $user; + }, + $users + ); + + $this->success( $users ); + } + + public function get_media_key() { + try { + session_write_close(); + $this->verifyNonce( self::nonce ); + $apost = (int) $_REQUEST['post_id']; + $attachment_id = (int) $_REQUEST['attachment_id']; + + if ( ! $attachment_id || get_post_status( $attachment_id ) === false ) { + $this->error( 400, 'Invalid attachment id' ); + } + $uid = $this->createMediaKey( $apost, $attachment_id ); + + $this->success( array( 'uid' => $uid ) ); + + } catch ( Exception $e ) { + Brizy_Logger::instance()->error( $e->getMessage(), [ $e ] ); + + return; + } + } + + /** + * @see Brizy_Admin_Migrations_AttachmentUidMigration + */ + public function get_attachment_key() { + try { + session_write_close(); + + $this->verifyNonce( self::nonce ); + $attachmentId = isset( $_REQUEST['attachment_id'] ) ? (int) $_REQUEST['attachment_id'] : null; + + if ( ! $attachmentId || get_post_status( $attachmentId ) === false ) { + $this->error( 400, 'Invalid attachment id' ); + } + + $uid = get_post_meta( $attachmentId, 'brizy_post_uid', true ); - global $wpdb; + if ( ! $uid ) { + $file = get_attached_file( $attachmentId ); + $path_parts = pathinfo( $file ); + $uid = "wp-" . md5( $attachmentId . time() ) . '.' . $path_parts['extension']; + // this is a bit wrong as the attachment is attached to itself + // (we used brizy_post_uid to mark the attachments as attached to the post with uid in this key) + // we also migrated the attachment that does not have brizy_attachment_uid meta and + // does have only brizy_post_uid meta: see the Brizy_Admin_Migrations_AttachmentUidMigration class + update_post_meta( $attachmentId, 'brizy_post_uid', $uid ); + + // we added this here as the correct way to create a brizy_attachment_uid key + update_post_meta( $attachmentId, 'brizy_attachment_uid', $uid ); + } - if ($wp_query instanceof WP_Query && $term = $wp_query->get('post_title_term')) { - $search_term = $wpdb->esc_like($term); - $search_term = ' \'%'.$search_term.'%\''; - - $where .= ' AND '.$wpdb->posts.'.post_title LIKE '.$search_term; - } - - return $where; - } - - public function get_menu_list() - { - $this->success(wp_get_nav_menus(array('hide_empty' => true)), 200); - } - - /** - * Used in woocomerce producs, block conditions - */ - public function get_terms() - { - - try { - $this->verifyNonce(self::nonce); - - $taxonomy = $this->param('taxonomy'); - - $terms = (array)get_terms(array('taxonomy' => $taxonomy, 'hide_empty' => false)); - - $this->success(array_values($terms)); - - } catch (Exception $e) { - Brizy_Logger::instance()->error($e->getMessage(), [$e]); - $this->error(500, $e->getMessage()); - } - } - - /** - * Used in posts filter element - */ - public function get_terms_by() - { - - $this->verifyNonce(self::nonce); - - $args = []; - - foreach (['taxonomy', 'search', 'include'] as $field) { - $value = $this->param($field); - if ( ! empty($value)) { - $args[$field] = $value; - } - } - - $terms = get_terms($args); - - if (is_wp_error($terms)) { - $this->error(200, $terms); - } - - - $out = []; - foreach ($terms as $term) { - $out[] = [ - 'term_id' => $term->term_id, - 'name' => $term->name, - 'taxonomy' => $term->taxonomy, - 'taxonomy_name' => get_taxonomy($term->taxonomy)->labels->singular_name, - ]; - } - - $this->success($out); - } - - /** - * Used in posts filter element - */ - public function search_post() - { - $this->verifyNonce(self::nonce); - $args = ['numberposts' => -1]; - $args['post_type'] = array_values(get_post_types(['public' => true])); - - // exclude attachments - if (($key = array_search('attachment', $args['post_type'])) !== false) { - unset($args['post_type'][$key]); - } - - // se post types - if ($requiredTypes = $this->param('post_type')) { - if (is_string($requiredTypes)) { - $args['post_type'] = [$requiredTypes]; - } else { - $args['post_type'] = $requiredTypes; - } - } - - // exclude post types - if ($excludeTypes = $this->param('exclude_post_type')) { - if (is_string($excludeTypes)) { - if (($key = array_search($excludeTypes, $args['post_type'])) !== false) { - unset($args['post_type'][$key]); - } - } else { - $args['post_type'] = array_diff($args['post_type'], $excludeTypes); - } - } - - // include posts by id - if ($this->param('include')) { - $args['post__in'] = $this->param('include'); - } elseif ($this->param('search') /*&& strlen($this->param('search')) >= 3*/) { - $args['s'] = $this->param('search'); - } else { - $this->success([]); - } - - $posts = get_posts($args); - - if (is_wp_error($posts)) { - $this->error(200, $posts); - } - - $out = []; - foreach ($posts as $post) { - $pt = get_post_type_object( $post->post_type ); - $out[] = [ - 'ID' => $post->ID, - 'title' => $post->post_title, - 'permalink'=>"{{brizy_dc_permalink post_id=\"{$post->ID}\"}}", - 'postType' => [ 'type' => $post->post_type, - 'singular_name' => $pt->labels->singular_name, - 'name' => $pt->labels->name - ] - ]; - } - - $this->success($out); - } - - public function get_users() - { - $this->verifyNonce(self::nonce); - - $args = []; - $search = $this->param('search'); - $include = $this->param('include'); - - $args['fields'] = $this->param('fields') ? $this->param('fields') : ['ID', 'display_name']; - - if ($this->param('roles') && is_array($this->param('roles'))) { - $args['role__in'] = $this->param('roles'); - } - - if ( ! empty($search)) { - $args['search'] = '*'.$search.'*'; - $args['search_columns'] = ['display_name']; - } - - if (is_array($include) && ! empty($include)) { - $args['include'] = $include; - } - - $users = get_users($args); - - $users = array_map( - function ($user) { - $user->ID = (int)$user->ID; - - return $user; - }, - $users - ); - - $this->success($users); - } - - public function get_media_key() - { - try { - session_write_close(); - $this->verifyNonce(self::nonce); - $apost = (int)$_REQUEST['post_id']; - $attachment_id = (int)$_REQUEST['attachment_id']; - - if ( ! $attachment_id || get_post_status($attachment_id) === false) { - $this->error(400, 'Invalid attachment id'); - } - $uid = $this->createMediaKey($apost, $attachment_id); - - $this->success(array('uid' => $uid)); - - } catch (Exception $e) { - Brizy_Logger::instance()->error($e->getMessage(), [$e]); - - return; - } - } - - /** - * @see Brizy_Admin_Migrations_AttachmentUidMigration - */ - public function get_attachment_key() - { - try { - session_write_close(); - - $this->verifyNonce(self::nonce); - $attachmentId = isset($_REQUEST['attachment_id']) ? (int)$_REQUEST['attachment_id'] : null; - - if ( ! $attachmentId || get_post_status($attachmentId) === false) { - $this->error(400, 'Invalid attachment id'); - } - - $uid = get_post_meta($attachmentId, 'brizy_post_uid', true); - - if ( ! $uid) { - $file = get_attached_file($attachmentId); - $path_parts = pathinfo($file); - $uid = "wp-".md5($attachmentId.time()).'.'.$path_parts['extension']; - - // this is a bit wrong as the attachment is attached to itself - // (we used brizy_post_uid to mark the attachments as attached to the post with uid in this key) - // we also migrated the attachment that does not have brizy_attachment_uid meta and - // does have only brizy_post_uid meta: see the Brizy_Admin_Migrations_AttachmentUidMigration class - update_post_meta($attachmentId, 'brizy_post_uid', $uid); - - // we added this here as the correct way to create a brizy_attachment_uid key - update_post_meta($attachmentId, 'brizy_attachment_uid', $uid); - } - - $this->success(array('uid' => $uid)); + $this->success( array( 'uid' => $uid ) ); - } catch (Exception $e) { - Brizy_Logger::instance()->error($e->getMessage(), [$e]); + } catch ( Exception $e ) { + Brizy_Logger::instance()->error( $e->getMessage(), [ $e ] ); - return; - } - } + return; + } + } - public function setTemplateType() - { - try { + public function setTemplateType() { + try { - $this->verifyNonce(self::nonce); - $templateId = $this->param('template_id'); - $templateType = $this->param('template_type'); + $this->verifyNonce( self::nonce ); + $templateId = $this->param( 'template_id' ); + $templateType = $this->param( 'template_type' ); - if (get_post_type($templateId) != Brizy_Admin_Templates::CP_TEMPLATE) { - $this->error(400, 'Invalid template'); - } + if ( get_post_type( $templateId ) != Brizy_Admin_Templates::CP_TEMPLATE ) { + $this->error( 400, 'Invalid template' ); + } - $allowedTypes = [ - Brizy_Admin_Templates::TYPE_SINGLE, - Brizy_Admin_Templates::TYPE_ARCHIVE, - Brizy_Admin_Templates::TYPE_SINGLE_PRODUCT, - Brizy_Admin_Templates::TYPE_PRODUCT_ARCHIVE, - ]; + $allowedTypes = [ + Brizy_Admin_Templates::TYPE_SINGLE, + Brizy_Admin_Templates::TYPE_ARCHIVE, + Brizy_Admin_Templates::TYPE_SINGLE_PRODUCT, + Brizy_Admin_Templates::TYPE_PRODUCT_ARCHIVE, + ]; - if ( ! in_array($templateType, $allowedTypes, true)) { - $this->error(400, 'Invalid template type'); - } + if ( ! in_array( $templateType, $allowedTypes, true ) ) { + $this->error( 400, 'Invalid template type' ); + } - update_post_meta($templateId, Brizy_Admin_Templates::TEMPLATE_TYPE_KEY, $templateType); + update_post_meta( $templateId, Brizy_Admin_Templates::TEMPLATE_TYPE_KEY, $templateType ); - $this->success([]); + $this->success( [] ); - } catch (Exception $e) { - Brizy_Logger::instance()->error($e->getMessage(), [$e]); - $this->error(500, $e->getMessage()); + } catch ( Exception $e ) { + Brizy_Logger::instance()->error( $e->getMessage(), [ $e ] ); + $this->error( 500, $e->getMessage() ); - return; - } - } + return; + } + } - private function createMediaKey($postId, $attachmentId) - { - $uid = get_post_meta($attachmentId, 'brizy_attachment_uid', true); + private function createMediaKey( $postId, $attachmentId ) { + $uid = get_post_meta( $attachmentId, 'brizy_attachment_uid', true ); - if ( ! $uid) { - $file = get_attached_file($attachmentId); - $path_parts = pathinfo($file); - $uid = "wp-".md5($attachmentId.time()).'.'.$path_parts['extension']; - update_post_meta($attachmentId, 'brizy_attachment_uid', $uid); - } + if ( ! $uid ) { + $file = get_attached_file( $attachmentId ); + $path_parts = pathinfo( $file ); + $uid = "wp-" . md5( $attachmentId . time() ) . '.' . $path_parts['extension']; + update_post_meta( $attachmentId, 'brizy_attachment_uid', $uid ); + } - if ($postId) { - $post = Brizy_Editor_Post::get($postId); - $post_ui = $post->getUid(); + if ( $postId ) { + $post = Brizy_Editor_Post::get( $postId ); + $post_ui = $post->getUid(); - $post_uids = get_post_meta($attachmentId, 'brizy_post_uid'); + $post_uids = get_post_meta( $attachmentId, 'brizy_post_uid' ); - if ( ! in_array($post_ui, $post_uids)) { - add_post_meta($attachmentId, 'brizy_post_uid', $post_ui); - } - } + if ( ! in_array( $post_ui, $post_uids ) ) { + add_post_meta( $attachmentId, 'brizy_post_uid', $post_ui ); + } + } - return $uid; - } + return $uid; + } } diff --git a/editor/editor/editor.php b/editor/editor/editor.php index 1279b3d22a..a5aeb6e581 100755 --- a/editor/editor/editor.php +++ b/editor/editor/editor.php @@ -1,522 +1,537 @@ getWpPostId() ? $post->getWpPostId() : 0; - if ( isset( self::$insance[ $postId ] ) ) { - return self::$insance[ $postId ]; - } - - return self::$insance[ $postId ] = new self( $project, $post ); - } - - /** - * Brizy_Editor_Editor_Editor constructor. - * - * @param Brizy_Editor_Project $project - * @param Brizy_Editor_Post $post - */ - public function __construct( Brizy_Editor_Project $project, Brizy_Editor_Post $post = null ) { - $this->post = $post; - $this->project = $project; - $this->urlBuilder = new Brizy_Editor_UrlBuilder( $project, $post ? $post->getWpPostId() : null ); - } - - private function getMode( $postType ) { - switch ( $postType ) { - case Brizy_Admin_Stories_Main::CP_STORY: - return 'internal_story'; - case Brizy_Admin_Templates::CP_TEMPLATE: - return 'template'; - case Brizy_Admin_Popups_Main::CP_POPUP: - return 'internal_popup'; - case 'product': - case 'product_variation': - return 'product'; - default: - return 'page'; - } - } - - public function getClientConfig( $editorConfig, $context ) { - if ( !isset($editorConfig['wp']['postLoopSources']) ) { + * @param Brizy_Editor_Project $project + * @param Brizy_Editor_Post $post + * + * @return Brizy_Editor_Editor_Editor + */ + public static function get(Brizy_Editor_Project $project, Brizy_Editor_Post $post) + { + + $postId = $post && $post->getWpPostId() ? $post->getWpPostId() : 0; + if (isset(self::$insance[$postId])) { + return self::$insance[$postId]; + } + + return self::$insance[$postId] = new self($project, $post); + } + + /** + * Brizy_Editor_Editor_Editor constructor. + * + * @param Brizy_Editor_Project $project + * @param Brizy_Editor_Post $post + */ + public function __construct(Brizy_Editor_Project $project, Brizy_Editor_Post $post = null) + { + $this->post = $post; + $this->project = $project; + $this->urlBuilder = new Brizy_Editor_UrlBuilder($project, $post ? $post->getWpPostId() : null); + } + + private function getMode($postType) + { + switch ($postType) { + case Brizy_Admin_Stories_Main::CP_STORY: + return 'internal_story'; + case Brizy_Admin_Templates::CP_TEMPLATE: + return 'template'; + case Brizy_Admin_Popups_Main::CP_POPUP: + return 'internal_popup'; + case 'product': + case 'product_variation': + return 'product'; + default: + return 'page'; + } + } + + public function getClientConfig($editorConfig, $context) + { + if (!isset($editorConfig['wp']['postLoopSources'])) { throw new \Exception("Unable to locate the \$config['wp']['postLoopSources']"); } - $config = [ - 'hash' => wp_create_nonce( Brizy_Editor_API::nonce ), - 'editorVersion' => BRIZY_EDITOR_VERSION, - 'url' => set_url_scheme( admin_url( 'admin-ajax.php' ) ), - 'actions' => $this->getApiActions(), - 'pageId' => $this->post->getWpPostId(), + $config = [ + 'hash' => wp_create_nonce(Brizy_Editor_API::nonce), + 'editorVersion' => BRIZY_EDITOR_VERSION, + 'url' => set_url_scheme(admin_url('admin-ajax.php')), + 'actions' => $this->getApiActions(), + 'pageId' => $this->post->getWpPostId(), 'collectionTypes' => $editorConfig['wp']['postLoopSources'] ]; - $config = $this->getApiConfigFields( $config, $context ); - - return $config; - } - - /** - * @throws Exception - */ - public function config( $context = self::COMPILE_CONTEXT ) { - do_action( 'brizy_create_editor_config_before' ); - - $cachePostId = ( $this->post ? $this->post->getWpPostId() : 0 ) . '_' . $context; - if ( isset( self::$config[ $cachePostId ] ) ) { - return self::$config[ $cachePostId ]; - } - - global $wp_registered_sidebars; - - $parent_post_type = get_post_type( $this->post->getWpPostId() ); - $wp_post_id = $this->post->getWpPostId(); - $preview_post_link = $this->getPreviewUrl( $this->post->getWpPost() ); - - $change_template_url = set_url_scheme( - admin_url( 'admin-post.php?post=' . $this->post->getWpPostId() . '&action=_brizy_change_template' ) - ); - $mode = $this->getMode( $parent_post_type ); - - $heartBeatInterval = (int) apply_filters( 'wp_check_post_lock_window', 150 ); - $config = array( - 'user' => array( - 'role' => 'admin', - 'isAuthorized' => $this->project->getMetaValue( 'brizy-cloud-token' ) !== null, - 'allowScripts' => $this->isUserAllowedToAddScripts( $context ), - ), - 'project' => array( - 'id' => $this->project->getId(), - 'status' => $this->getProjectStatus(), - 'heartBeatInterval' => ( $heartBeatInterval > 10 && $heartBeatInterval < 30 ? $heartBeatInterval : 30 ) * 1000, - ), - 'urls' => array( - 'site' => home_url(), - 'api' => home_url( '/wp-json/v1' ), - 'assets' => $context == self::COMPILE_CONTEXT ? Brizy_Config::EDITOR_BUILD_RELATIVE_PATH : $this->urlBuilder->editor_build_url(), - 'image' => $this->urlBuilder->external_media_url() . "", - 'blockThumbnails' => $this->urlBuilder->external_asset_url( 'thumbs' ) . "", - 'templateThumbnails' => $this->urlBuilder->external_asset_url( 'thumbs' ) . "", - 'templateIcons' => $this->urlBuilder->proxy_url( 'editor/icons' ), - 'templateFonts' => $this->urlBuilder->external_fonts_url(), - 'editorFonts' => home_url( '/' ), - 'pagePreview' => $preview_post_link, - 'about' => __bt( 'about-url', apply_filters( 'brizy_about_url', Brizy_Config::ABOUT_URL ) ), - 'backToDashboard' => get_edit_post_link( $wp_post_id, null ), - 'assetsExternal' => $this->urlBuilder->external_asset_url() . "", - 'termsOfService' => Brizy_Config::getTermsOfServiceUrl(), - - // wp specific - 'changeTemplate' => $change_template_url, - 'upgradeToPro' => Brizy_Config::getUpgradeUrl(), - - 'support' => Brizy_Config::getSupportUrl(), - 'pluginSettings' => admin_url( 'admin.php?page=' . Brizy_Admin_Settings::menu_slug() ), - 'dashboardNavMenu' => admin_url( 'nav-menus.php' ), - 'customFile' => home_url( '?' . Brizy_Editor::prefix( '_attachment' ) . '=' ), - ), - 'form' => array( - 'submitUrl' => '{{brizy_dc_ajax_url}}?action=' . Brizy_Editor::prefix( - Brizy_Editor_Forms_Api::AJAX_SUBMIT_FORM - ), - ), - 'serverTimestamp' => time(), - 'menuData' => $this->get_menu_data(), - 'wp' => array( - 'pluginPrefix' => Brizy_Editor::prefix(), - 'permalink' => get_permalink( $wp_post_id ), - 'page' => $wp_post_id, - 'postType' => get_post_type( $wp_post_id ), - 'featuredImage' => $this->getThumbnailData( $wp_post_id ), - 'templates' => $this->post->get_templates(), - - 'plugins' => array( - 'dummy' => true, - 'woocommerce' => self::get_woocomerce_plugin_info(), - ), - 'hasSidebars' => count( $wp_registered_sidebars ) > 0, - 'l10n' => $this->getTexts(), - 'pageData' => apply_filters( 'brizy_page_data', array() ), - 'availableRoles' => Brizy_Admin_Membership_Membership::roleList(), - 'usersCanRegister' => get_option( 'users_can_register' ), - ), - 'mode' => $mode, - 'applications' => array( - 'form' => array( - 'submitUrl' => '{{brizy_dc_ajax_url}}?action=' . Brizy_Editor::prefix( - Brizy_Editor_Forms_Api::AJAX_SUBMIT_FORM - ), - ), - ), - 'ui' => [], - 'server' => array( - 'maxUploadFileSize' => $this->fileUploadMaxSize(), - ), - 'branding' => array( 'name' => __bt( 'brizy', 'Brizy' ) ), - 'prefix' => Brizy_Editor::prefix(), - 'cloud' => $this->getCloudInfo(), - 'editorVersion' => BRIZY_EDITOR_VERSION, - 'imageSizes' => $this->getImgSizes(), - 'moduleGroups' => [] - ); - $manager = new Brizy_Editor_Accounts_ServiceAccountManager( Brizy_Editor_Project::get() ); - - $config = $this->addRecaptchaAccounts( $manager, $config, $context ); - $config = $this->addSocialAccounts( $manager, $config, $context ); - $config = $this->addWpPostTypes( $config, $context ); - $config = $this->addTemplateFields( $config, $mode === 'template', $wp_post_id, $context ); - $config['wp']['api'] = $this->getApiActions( $config, $context ); - $config = $this->addGlobalBlocksData( $config ); - $config = $this->addGlobalBlocksData( $config ); - $config = $this->getPostLoopSources( $config, $mode === 'template', $wp_post_id, $context ); - $config = $this->getApiConfigFields( $config, $context ); - $config = $this->addContentDefaults( $config, $context ); - $config = $this->addUIConfig( $config, $context ); - $config = $this->addProjectData( $config, $context ); - $config = $this->addModuleGroups( $config, $context ); - $config = $this->addPageData( $config, $context ); - - self::$config[ $cachePostId ] = apply_filters( 'brizy_editor_config', $config, $context ); - - do_action( 'brizy_create_editor_config_after' ); - - return self::$config[ $cachePostId ]; - } - - private function addUIConfig( $config, $context ) { - - $is_popup = $this->isPopup( $config ); - $is_story = $this->isStory( $config ); - $is_template = $this->isTemplate( $config ); - - $options = [ - ! Brizy_Compatibilities_BrizyProCompatibility::isPro() ? - [ - "type" => "link", - "icon" => "nc-unlock", - "label" => __bt( "Upgrade to Pro", "Upgrade to Pro", 'brizy' ), - "link" => $config['urls']['upgradeToPro'], - "linkTarget" => "_blank", - ] : null, - [ - "type" => "link", - "icon" => "nc-info", - "label" => __bt( "About us", "About us", 'brizy' ), - "link" => $config['urls']['about'], - "linkTarget" => "_blank" - ], - [ - "type" => "link", - "icon" => "nc-help-docs", - "label" => __bt( "Support", "Support", 'brizy' ), - "link" => $config['urls']['support'], - "linkTarget" => "_blank", - "roles" => [ "admin" ] - ], - [ - "type" => "shortcuts", - "icon" => "nc-alert-circle-que", - "label" => __bt( "Shortcuts", "Shortcuts", 'brizy' ), - "link" => "#" - ], - [ - "type" => "link", - "icon" => "nc-cog", - "label" => __bt( "Plugin Settings", "Plugin Settings", 'brizy' ), - "link" => $config['urls']['pluginSettings'], - "linkTarget" => "_blank", - "roles" => [ "admin" ] - ], - [ - "type" => "link", - "icon" => "nc-back", - "label" => __bt( "Go to Dashboard", "Go to Dashboard", 'brizy' ), - "link" => $config['urls']['backToDashboard'] - ] - ]; - $config['ui']['leftSidebar'] = [ - "topTabsOrder" => [ "addElements", "reorderBlock", "globalStyle" ], - "bottomTabsOrder" => [ "deviceMode", "pageSettings", "more" ], - "pageSettings" => [ - "options" => [ - "template" => ! ( $is_popup || $is_story ), - "membership" => ! ( $is_popup || $is_story ), - "featuredImage" => ! ( $is_popup || $is_story ) && ! $is_template - ] - ], - "more" => [ - "options" => array_values( array_filter( $options ) ) - ] - ]; - - $config['ui']['popupSettings'] = [ - "horizontalAlign" => true, - "verticalAlign" => true, - "embedded" => false, - "displayCondition" => $is_popup, - "scrollPageBehind" => true, - "clickOutsideToClose" => true, - "deletePopup" => $is_popup, - "backgroundPreviewUrl" => $config['urls']['pagePreview'] - ]; - - return $config; - } - - /** - * @param $config - * - * @return string[]|WP_Post_Type[] - */ - private function addWpPostTypes( $config, $context ) { - $excludePostTypes = [ 'attachment' ]; - - $types = get_post_types( [ 'public' => true ] ); - $result = []; - foreach ( $types as $type ) { - if ( in_array( $type, $excludePostTypes ) ) { - continue; - } - $typeObj = get_post_type_object( $type ); - $typeDto = [ - 'name' => $typeObj->name, - 'label' => $typeObj->label, - ]; - $result[] = $typeDto; - - } - - $config['wp']['postTypes'] = $result; - - return $config; - } - - private function addPageData( $config, $context ) { - - $config['pageData'] = $this->post->createConfigData(); - - return $config; - } - - private function addModuleGroups( $config, $context ) { - - $moduleGroupCollector = new Brizy_Editor_Editor_ModuleGroups_Manager(); - - $config['ui']['leftSidebar'] = array_merge( $config['ui']['leftSidebar'], [ 'moduleGroups' => $moduleGroupCollector->getAll( $config ) ] ); - - return $config; - } - - - private function addProjectData( $config, $context ) { - - $response = Brizy_Editor_Project::get()->createResponse(); - $response['data'] = json_decode( $response['data'] ); - $config['projectData'] = $response; - - return $config; - } - - - private function getApiConfigFields( $config, $context ) { - $config['api'] = [ - 'media' => [ - 'mediaResizeUrl' => home_url() - ], - 'customFile' => [ - 'customFileUrl' => home_url() - ], - 'templates' => [ - 'kitsUrl' => Brizy_Config::getEditorTemplatesUrl('kits'), + $config = $this->getApiConfigFields($config, $context); + $config = apply_filters('brizy_client_config', $config, $context); + return $config; + } + + /** + * @throws Exception + */ + public function config($context = self::COMPILE_CONTEXT) + { + do_action('brizy_create_editor_config_before'); + + $cachePostId = ($this->post ? $this->post->getWpPostId() : 0) . '_' . $context; + if (isset(self::$config[$cachePostId])) { + return self::$config[$cachePostId]; + } + + global $wp_registered_sidebars; + + $parent_post_type = get_post_type($this->post->getWpPostId()); + $wp_post_id = $this->post->getWpPostId(); + $preview_post_link = $this->getPreviewUrl($this->post->getWpPost()); + + $change_template_url = set_url_scheme( + admin_url('admin-post.php?post=' . $this->post->getWpPostId() . '&action=_brizy_change_template') + ); + $mode = $this->getMode($parent_post_type); + + $heartBeatInterval = (int)apply_filters('wp_check_post_lock_window', 150); + $config = array( + 'user' => array( + 'role' => 'admin', + 'isAuthorized' => $this->project->getMetaValue('brizy-cloud-token') !== null, + 'allowScripts' => $this->isUserAllowedToAddScripts($context), + ), + 'project' => array( + 'id' => $this->project->getId(), + 'status' => $this->getProjectStatus(), + 'heartBeatInterval' => ($heartBeatInterval > 10 && $heartBeatInterval < 30 ? $heartBeatInterval : 30) * 1000, + ), + 'urls' => array( + 'site' => home_url(), + 'api' => home_url('/wp-json/v1'), + 'assets' => $context == self::COMPILE_CONTEXT ? Brizy_Config::EDITOR_BUILD_RELATIVE_PATH : $this->urlBuilder->editor_build_url(), + 'image' => $this->urlBuilder->external_media_url() . "", + 'blockThumbnails' => $this->urlBuilder->external_asset_url('thumbs') . "", + 'templateThumbnails' => $this->urlBuilder->external_asset_url('thumbs') . "", + 'templateIcons' => $this->urlBuilder->proxy_url('editor/icons'), + 'templateFonts' => $this->urlBuilder->external_fonts_url(), + 'editorFonts' => home_url('/'), + 'pagePreview' => $preview_post_link, + 'about' => __bt('about-url', apply_filters('brizy_about_url', Brizy_Config::ABOUT_URL)), + 'backToDashboard' => get_edit_post_link($wp_post_id, null), + 'assetsExternal' => $this->urlBuilder->external_asset_url() . "", + 'termsOfService' => Brizy_Config::getTermsOfServiceUrl(), + + // wp specific + 'changeTemplate' => $change_template_url, + 'upgradeToPro' => Brizy_Config::getUpgradeUrl(), + + 'support' => Brizy_Config::getSupportUrl(), + 'pluginSettings' => admin_url('admin.php?page=' . Brizy_Admin_Settings::menu_slug()), + 'dashboardNavMenu' => admin_url('nav-menus.php'), + 'customFile' => home_url('?' . Brizy_Editor::prefix('_attachment') . '='), + 'filterPlaceholders'=> home_url("/wp-admin/admin-ajax.php?action=".Brizy_Editor::prefix('_filter_placeholders_content')) + ), + 'form' => array( + 'submitUrl' => '{{brizy_dc_ajax_url}}?action=' . Brizy_Editor::prefix( + Brizy_Editor_Forms_Api::AJAX_SUBMIT_FORM + ), + ), + 'serverTimestamp' => time(), + 'menuData' => $this->get_menu_data(), + 'wp' => array( + 'pluginPrefix' => Brizy_Editor::prefix(), + 'permalink' => get_permalink($wp_post_id), + 'page' => $wp_post_id, + 'postType' => get_post_type($wp_post_id), + 'featuredImage' => $this->getThumbnailData($wp_post_id), + 'templates' => $this->post->get_templates(), + + 'plugins' => array( + 'dummy' => true, + 'woocommerce' => self::get_woocomerce_plugin_info(), + ), + 'hasSidebars' => count($wp_registered_sidebars) > 0, + 'l10n' => $this->getTexts(), + 'pageData' => apply_filters('brizy_page_data', array()), + 'availableRoles' => Brizy_Admin_Membership_Membership::roleList(), + 'usersCanRegister' => get_option('users_can_register'), + ), + 'mode' => $mode, + 'applications' => array( + 'form' => array( + 'submitUrl' => '{{brizy_dc_ajax_url}}?action=' . Brizy_Editor::prefix( + Brizy_Editor_Forms_Api::AJAX_SUBMIT_FORM + ), + ), + ), + 'ui' => [], + 'server' => array( + 'maxUploadFileSize' => $this->fileUploadMaxSize(), + ), + 'branding' => array('name' => __bt('brizy', 'Brizy')), + 'prefix' => Brizy_Editor::prefix(), + 'cloud' => $this->getCloudInfo(), + 'editorVersion' => BRIZY_EDITOR_VERSION, + 'imageSizes' => $this->getImgSizes(), + 'moduleGroups' => [] + ); + $manager = new Brizy_Editor_Accounts_ServiceAccountManager(Brizy_Editor_Project::get()); + + $config = $this->addRecaptchaAccounts($manager, $config, $context); + $config = $this->addSocialAccounts($manager, $config, $context); + $config = $this->addWpPostTypes($config, $context); + $config = $this->addTemplateFields($config, $mode === 'template', $wp_post_id, $context); + $config['wp']['api'] = $this->getApiActions($config, $context); + $config = $this->addGlobalBlocksData($config); + $config = $this->addGlobalBlocksData($config); + $config = $this->getPostLoopSources($config, $mode === 'template', $wp_post_id, $context); + $config = $this->getApiConfigFields($config, $context); + $config = $this->addContentDefaults($config, $context); + $config = $this->addUIConfig($config, $context); + $config = $this->addProjectData($config, $context); + $config = $this->addModuleGroups($config, $context); + $config = $this->addPageData($config, $context); + + self::$config[$cachePostId] = apply_filters('brizy_editor_config', $config, $context); + + do_action('brizy_create_editor_config_after'); + + return self::$config[$cachePostId]; + } + + private function addUIConfig($config, $context) + { + + $is_popup = $this->isPopup($config); + $is_story = $this->isStory($config); + $is_template = $this->isTemplate($config); + + $options = [ + !Brizy_Compatibilities_BrizyProCompatibility::isPro() ? + [ + "type" => "link", + "icon" => "nc-unlock", + "label" => __bt("Upgrade to Pro", "Upgrade to Pro", 'brizy'), + "link" => $config['urls']['upgradeToPro'], + "linkTarget" => "_blank", + ] : null, + [ + "type" => "link", + "icon" => "nc-info", + "label" => __bt("About us", "About us", 'brizy'), + "link" => $config['urls']['about'], + "linkTarget" => "_blank" + ], + [ + "type" => "link", + "icon" => "nc-help-docs", + "label" => __bt("Support", "Support", 'brizy'), + "link" => $config['urls']['support'], + "linkTarget" => "_blank", + "roles" => ["admin"] + ], + [ + "type" => "shortcuts", + "icon" => "nc-alert-circle-que", + "label" => __bt("Shortcuts", "Shortcuts", 'brizy'), + "link" => "#" + ], + [ + "type" => "link", + "icon" => "nc-cog", + "label" => __bt("Plugin Settings", "Plugin Settings", 'brizy'), + "link" => $config['urls']['pluginSettings'], + "linkTarget" => "_blank", + "roles" => ["admin"] + ], + [ + "type" => "link", + "icon" => "nc-back", + "label" => __bt("Go to Dashboard", "Go to Dashboard", 'brizy'), + "link" => $config['urls']['backToDashboard'] + ] + ]; + $config['ui']['leftSidebar'] = [ + "topTabsOrder" => ["addElements", "reorderBlock", "globalStyle"], + "bottomTabsOrder" => ["deviceMode", "pageSettings", "more"], + "pageSettings" => [ + "options" => [ + "template" => !($is_popup || $is_story), + "membership" => !($is_popup || $is_story), + "featuredImage" => !($is_popup || $is_story) && !$is_template + ] + ], + "more" => [ + "options" => array_values(array_filter($options)) + ] + ]; + + $config['ui']['popupSettings'] = [ + "horizontalAlign" => true, + "verticalAlign" => true, + "embedded" => false, + "displayCondition" => $is_popup, + "scrollPageBehind" => true, + "clickOutsideToClose" => true, + "deletePopup" => $is_popup, + "backgroundPreviewUrl" => $config['urls']['pagePreview'] + ]; + + return $config; + } + + /** + * @param $config + * + * @return string[]|WP_Post_Type[] + */ + private function addWpPostTypes($config, $context) + { + $excludePostTypes = ['attachment']; + + $types = get_post_types(['public' => true]); + $result = []; + foreach ($types as $type) { + if (in_array($type, $excludePostTypes)) { + continue; + } + $typeObj = get_post_type_object($type); + $typeDto = [ + 'name' => $typeObj->name, + 'label' => $typeObj->label, + ]; + $result[] = $typeDto; + + } + + $config['wp']['postTypes'] = $result; + + return $config; + } + + private function addPageData($config, $context) + { + + $config['pageData'] = $this->post->createConfigData(); + + return $config; + } + + private function addModuleGroups($config, $context) + { + + $moduleGroupCollector = new Brizy_Editor_Editor_ModuleGroups_Manager(); + + $config['ui']['leftSidebar'] = array_merge($config['ui']['leftSidebar'], ['moduleGroups' => $moduleGroupCollector->getAll($config)]); + + return $config; + } + + + private function addProjectData($config, $context) + { + + $response = Brizy_Editor_Project::get()->createResponse(); + $response['data'] = json_decode($response['data']); + $config['projectData'] = $response; + + return $config; + } + + + private function getApiConfigFields($config, $context) + { + $config['api'] = [ + 'media' => [ + 'mediaResizeUrl' => home_url() + ], + 'customFile' => [ + 'customFileUrl' => home_url() + ], + 'templates' => [ + 'kitsUrl' => Brizy_Config::getEditorTemplatesUrl('kits'), 'layoutsUrl' => Brizy_Config::getEditorTemplatesUrl('layouts'), - 'popupsUrl' => Brizy_Config::getEditorTemplatesUrl('popups'), + 'popupsUrl' => Brizy_Config::getEditorTemplatesUrl('popups'), 'storiesUrl' => Brizy_Config::getEditorTemplatesUrl('stories') ] - ]; - - return $config; - } - - private function addContentDefaults( $config, $context ) { - $config['contentDefaults'] = [ - 'ProductMetafield' => ['linkSource' => 'page'], - 'Row' => [ - 'linkSource' => 'page', - 'linkType' => 'page', - 'items' => [ - [ - 'type' => 'Column', - 'value' => [ - '_styles' => ['column'], - 'linkSource' => 'page', - 'linkType' => 'page', - 'items' => [] - ] - ], - [ - 'type' => 'Column', - 'value' => [ - '_styles' => ['column'], - 'linkSource' => 'page', - 'linkType' => 'page', - 'items' => [] - ] - ] - ] + ]; + + return $config; + } + + private function addContentDefaults($config, $context) + { + $config['contentDefaults'] = [ + 'ProductMetafield' => ['linkSource' => 'page'], + 'Row' => [ + 'linkSource' => 'page', + 'linkType' => 'page', + 'items' => [ + [ + 'type' => 'Column', + 'value' => [ + '_styles' => ['column'], + 'linkSource' => 'page', + 'linkType' => 'page', + 'items' => [] + ] + ], + [ + 'type' => 'Column', + 'value' => [ + '_styles' => ['column'], + 'linkSource' => 'page', + 'linkType' => 'page', + 'items' => [] + ] + ] + ] ], - 'Button' => ['linkSource' => 'page', 'linkType' => 'page'], - 'RichText' => ['linkSource' => 'page', 'linkType' => 'page'], - 'Icon' => ['linkSource' => 'page', 'linkType' => 'page'], - 'Image' => ['linkSource' => 'page', 'linkType' => 'page'], - 'Lottie' => ['linkSource' => 'page', 'linkType' => 'page'], - 'FeaturedImage' => ['linkSource' => 'page', 'linkType' => 'page'], - 'PostExcerpt' => ['linkSource' => 'page', 'linkType' => 'page', 'textPopulation' => '{{brizy_dc_post_excerpt}}', 'textPopulationEntityType' => '', 'textPopulationEntityId' => '', '_population' => [ + 'Button' => ['linkSource' => 'page', 'linkType' => 'page'], + 'RichText' => ['linkSource' => 'page', 'linkType' => 'page'], + 'Icon' => ['linkSource' => 'page', 'linkType' => 'page'], + 'Image' => ['linkSource' => 'page', 'linkType' => 'page'], + 'Lottie' => ['linkSource' => 'page', 'linkType' => 'page'], + 'FeaturedImage' => ['linkSource' => 'page', 'linkType' => 'page'], + 'PostExcerpt' => ['linkSource' => 'page', 'linkType' => 'page', 'textPopulation' => '{{brizy_dc_post_excerpt}}', 'textPopulationEntityType' => '', 'textPopulationEntityId' => '', '_population' => [ 'name' => 'brizy_dc_post_excerpt', 'placeholder' => '{{brizy_dc_post_excerpt}}'] ], - 'Column' => [ - [ 'type' => 'Column', 'value' => [ 'linkSource' => 'page', 'linkType' => 'page', 'items' => []]], - [ 'type' => 'Column', 'value' => [ 'linkSource' => 'page', 'linkType' => 'page', 'items' => []]] - ], - 'PostContent' => ['linkSource' => 'page', 'textPopulation' => '{{brizy_dc_post_content}}', 'textPopulationEntityType' => '', 'textPopulationEntityId' => '', '_population' => ['name' => 'brizy_dc_post_content', 'placeholder' => '{{brizy_dc_post_content}}']], - 'PostTitle' => ['linkSource' => 'page', 'linkType' => 'page', 'textPopulation' => '{{brizy_dc_post_title}}', 'textPopulationEntityType' => '', 'textPopulationEntityId' => '', '_population' => ['name' => 'brizy_dc_post_title', 'placeholder' => '{{brizy_dc_post_title}}']], - 'Posts' => [ - '_styles' => [ 'posts', 'posts-posts' ], - '_version' => 3, - 'order' => 'ASC', - 'orderBy' => 'ID', - 'source' => 'post', - 'type' => 'posts', - 'items' => [ - [ - 'type' => 'Column', - 'value' => [ - '_styles' => [ 'posts--column' ], - 'items' => [ - [ - 'type' => 'Wrapper', - 'value' => [ - '_styles' => [ 'wrapper', 'wrapper--image' ], - 'items' => [ - [ - 'type' => 'Image', - 'value' => [ - '_styles' => [ 'image', 'image--dynamic' ], - 'imagePopulation' => '{{brizy_dc_img_featured_image}}', - ], - ], - ], - ], - ], - [ - 'type' => 'Wrapper', - 'value' => [ - '_styles' => [ - 'wrapper', - 'wrapper-postTitle', - 'wrapper-postTitle-posts', - 'wrapper-postTitle-posts-posts' - ], - 'items' => [ - [ - 'type' => 'WPPostsTitle', - 'value' => [ - '_styles' => [ - 'postTitle', - 'postTitle-posts', - 'postTitle-posts-posts' - ], - ], - ], - ], - ], - ], - [ - 'type' => 'Wrapper', - 'value' => [ - '_styles' => [ - 'wrapper', - 'wrapper-postExcerpt', - 'wrapper-postExcerpt-posts', - 'wrapper-postExcerpt-posts-posts' - ], - 'items' => [ - [ - 'type' => 'WPPostExcerpt', - 'value' => [ - '_styles' => [ - 'postExcerpt', - 'postExcerpt-posts', - 'postExcerpt-posts-posts' - ], - ], - ], - ], - ], - ], - [ - 'type' => 'Cloneable', - 'value' => [ - '_styles' => [ 'wrapper-clone', 'wrapper-clone--button' ], - 'items' => [ - [ - 'type' => 'Button', - 'value' => [ - '_styles' => [ 'button', 'button--dynamic' ], - ], - ], - ], - ], - ], - ], - ], - ], - ], - ], - ]; - - return $config; - } - - private function getPostLoopSources( $config, $isTemplate, $wp_post_id, $context ) { + 'Column' => [ + ['type' => 'Column', 'value' => ['linkSource' => 'page', 'linkType' => 'page', 'items' => []]], + ['type' => 'Column', 'value' => ['linkSource' => 'page', 'linkType' => 'page', 'items' => []]] + ], + 'PostContent' => ['linkSource' => 'page', 'textPopulation' => '{{brizy_dc_post_content}}', 'textPopulationEntityType' => '', 'textPopulationEntityId' => '', '_population' => ['name' => 'brizy_dc_post_content', 'placeholder' => '{{brizy_dc_post_content}}']], + 'PostTitle' => ['linkSource' => 'page', 'linkType' => 'page', 'textPopulation' => '{{brizy_dc_post_title}}', 'textPopulationEntityType' => '', 'textPopulationEntityId' => '', '_population' => ['name' => 'brizy_dc_post_title', 'placeholder' => '{{brizy_dc_post_title}}']], + 'Posts' => [ + '_styles' => ['posts', 'posts-posts'], + '_version' => 3, + 'order' => 'ASC', + 'orderBy' => 'ID', + 'source' => 'post', + 'type' => 'posts', + 'items' => [ + [ + 'type' => 'Column', + 'value' => [ + '_styles' => ['posts--column'], + 'items' => [ + [ + 'type' => 'Wrapper', + 'value' => [ + '_styles' => ['wrapper', 'wrapper--image'], + 'items' => [ + [ + 'type' => 'Image', + 'value' => [ + '_styles' => ['image', 'image--dynamic'], + 'imagePopulation' => '{{brizy_dc_img_featured_image}}', + ], + ], + ], + ], + ], + [ + 'type' => 'Wrapper', + 'value' => [ + '_styles' => [ + 'wrapper', + 'wrapper-postTitle', + 'wrapper-postTitle-posts', + 'wrapper-postTitle-posts-posts' + ], + 'items' => [ + [ + 'type' => 'WPPostsTitle', + 'value' => [ + '_styles' => [ + 'postTitle', + 'postTitle-posts', + 'postTitle-posts-posts' + ], + ], + ], + ], + ], + ], + [ + 'type' => 'Wrapper', + 'value' => [ + '_styles' => [ + 'wrapper', + 'wrapper-postExcerpt', + 'wrapper-postExcerpt-posts', + 'wrapper-postExcerpt-posts-posts' + ], + 'items' => [ + [ + 'type' => 'WPPostExcerpt', + 'value' => [ + '_styles' => [ + 'postExcerpt', + 'postExcerpt-posts', + 'postExcerpt-posts-posts' + ], + ], + ], + ], + ], + ], + [ + 'type' => 'Cloneable', + 'value' => [ + '_styles' => ['wrapper-clone', 'wrapper-clone--button'], + 'items' => [ + [ + 'type' => 'Button', + 'value' => [ + '_styles' => ['button', 'button--dynamic'], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ], + ]; + + return $config; + } + + private function getPostLoopSources($config, $isTemplate, $wp_post_id, $context) + { $types = get_post_types(['public' => true]); $typesSort = ['page', 'post', 'editor-story']; @@ -528,952 +543,977 @@ private function getPostLoopSources( $config, $isTemplate, $wp_post_id, $context $result = []; - $templateTypeArchive = false; - if ( $isTemplate ) { - $template_type = Brizy_Admin_Templates::getTemplateType( $wp_post_id ); - if ( $template_type == Brizy_Admin_Templates::TYPE_ARCHIVE || $template_type == Brizy_Admin_Templates::TYPE_PRODUCT_ARCHIVE ) { - $templateTypeArchive = true; - } - } - - if ( $templateTypeArchive ) { - $result[] = [ - "name" => "brz_current_context", - "label" => "Current Query", - ]; - } - - foreach ( $types as $type ) { - $typeObj = get_post_type_object( $type ); - $typeDto = [ - 'name' => $typeObj->name, - 'label' => $typeObj->label, - ]; - $result[] = $typeDto; - - } - - $config['wp']['postLoopSources'] = $result; - - # as stated in this issue: https://github.com/bagrinsergiu/blox-editor/issues/21795 - # we have to add in config the post sources - $config['posts']['sources'] = array_map( function ( $source ) { - return [ - 'value' => $source['name'], - 'title' => $source['label'] - ]; - }, $result ); + $templateTypeArchive = false; + if ($isTemplate) { + $template_type = Brizy_Admin_Templates::getTemplateType($wp_post_id); + if ($template_type == Brizy_Admin_Templates::TYPE_ARCHIVE || $template_type == Brizy_Admin_Templates::TYPE_PRODUCT_ARCHIVE) { + $templateTypeArchive = true; + } + } + + if ($templateTypeArchive) { + $result[] = [ + "name" => "brz_current_context", + "label" => "Current Query", + ]; + } + + foreach ($types as $type) { + $typeObj = get_post_type_object($type); + $typeDto = [ + 'name' => $typeObj->name, + 'label' => $typeObj->label, + ]; + $result[] = $typeDto; + + } + + $config['wp']['postLoopSources'] = $result; + + # as stated in this issue: https://github.com/bagrinsergiu/blox-editor/issues/21795 + # we have to add in config the post sources + $config['posts']['sources'] = array_map(function ($source) { + return [ + 'value' => $source['name'], + 'title' => $source['label'] + ]; + }, $result); return $config; - } - - private function addGlobalBlocksData( $config ) { - - $postTaxonomies = get_post_taxonomies( $wp_post_id = (int) $config['wp']['page'] ); - $postTerms = []; - foreach ( $postTaxonomies as $tax ) { - $postTerms = array_merge( $postTerms, wp_get_post_terms( $wp_post_id, $tax ) ); - } - - $postTermsByKeys = []; - foreach ( $postTerms as $term ) { - $postTermsByKeys[ $term->term_id ] = $term; - } - - $config['wp']['postTerms'] = $postTerms; - $config['wp']['postTermParents'] = array_diff_key( $this->getAllParents( $postTermsByKeys ), $postTermsByKeys ); - $config['wp']['postAuthor'] = (int) $this->post->getWpPost()->post_author; - - return $config; - } - - /** - * @return object - */ - private function get_page_attachments() { - global $wpdb; - $query = $wpdb->prepare( - "SELECT + } + + private function addGlobalBlocksData($config) + { + + $postTaxonomies = get_post_taxonomies($wp_post_id = (int)$config['wp']['page']); + $postTerms = []; + foreach ($postTaxonomies as $tax) { + $postTerms = array_merge($postTerms, wp_get_post_terms($wp_post_id, $tax)); + } + + $postTermsByKeys = []; + foreach ($postTerms as $term) { + $postTermsByKeys[$term->term_id] = $term; + } + + $config['wp']['post_terms'] = $postTerms; + $config['wp']['post_term_parents'] = array_diff_key($this->getAllParents($postTermsByKeys), $postTermsByKeys); + $config['wp']['post_author'] = (int)$this->post->getWpPost()->post_author; + return $config; + } + + + /** + * @return object + */ + private function get_page_attachments() + { + global $wpdb; + $query = $wpdb->prepare( + "SELECT pm.* FROM {$wpdb->prefix}postmeta pm JOIN {$wpdb->prefix}postmeta pm2 ON pm2.post_id=pm.post_id AND pm2.meta_key='brizy_post_uid' AND pm2.meta_value=%s WHERE pm.meta_key='brizy_attachment_uid' GROUP BY pm.post_id", - $this->post->getUid() - ); - - $results = $wpdb->get_results( $query ); - $attachment_data = array(); - foreach ( $results as $row ) { - $attachment_data[ $row->meta_value ] = true; - } - - return (object) $attachment_data; - } - - /** - * @return array|null - */ - public static function get_woocomerce_plugin_info() { - if ( function_exists( 'wc' ) && defined( 'WC_PLUGIN_FILE' ) ) { - return array( 'version' => WooCommerce::instance()->version ); - } - - return null; - } - - /** - * @param $wp_post_id - * - * @return array|null - */ - private function getThumbnailData( $wp_post_id ) { - $post_thumbnail_id = get_post_thumbnail_id( $wp_post_id ); - $post_thumbnail = ""; - - if ( $post_thumbnail_id ) { - $post_thumbnail_focal_point = get_post_meta( $wp_post_id, 'brizy_attachment_focal_point', true ); - - if ( ! is_array( $post_thumbnail_focal_point ) ) { - $post_thumbnail_focal_point = array( 'x' => "", 'y' => "" ); - } - - $post_thumbnail = array( - 'id' => $post_thumbnail_id, - 'url' => get_the_post_thumbnail_url( $wp_post_id ), - 'pointX' => isset( $post_thumbnail_focal_point['x'] ) ? $post_thumbnail_focal_point['x'] : "", - 'pointY' => isset( $post_thumbnail_focal_point['y'] ) ? $post_thumbnail_focal_point['y'] : "", - ); - } - - return $post_thumbnail; - } - - private function getAllParents( $terms ) { - $result = []; - foreach ( $terms as $i => $term ) { - foreach ( $this->getTermParents( $term ) as $aTerm ) { - if ( ! isset( $result[ $aTerm->term_id ] ) ) { - $result[ $aTerm->term_id ] = $aTerm; - } - } - } - - return $result; - } - - private function getTermParents( $term ) { - $parents = []; - if ( $term->parent ) { - $parent = get_term_by( 'id', $term->parent, $term->taxonomy ); - - if ( $parent ) { - $parents[ $parent->term_id ] = $parent; - if ( $parent->parent > 0 ) { - $parents = array_merge( $parents, $this->getTermParents( $parent ) ); - } - } - } - - return $parents; - } - - /** - * @param $wp_post - * - * @return null|string - * @throws Brizy_Editor_Exceptions_NotFound - * @throws Brizy_Editor_Exceptions_UnsupportedPostType - */ - private function getPreviewUrl( $wp_post ) { - - if ( $wp_post->post_type == Brizy_Admin_Templates::CP_TEMPLATE ) { - - $ruleManager = new Brizy_Admin_Rules_Manager(); - $rules = $ruleManager->getRules( $wp_post->ID ); - $rule = null; - - - if ( ! function_exists( 'addQueryStringToUrl' ) ) { - function addQueryStringToUrl( $link, $query ) { - $parsedUrl = parse_url( $link ); - $separator = ( ! isset( $parsedUrl['query'] ) || $parsedUrl['query'] == null ) ? '?' : '&'; - $link .= $separator . $query; - - return $link; - } - } - - - // find first include rule - foreach ( $rules as $rule ) { - /** - * @var Brizy_Admin_Rule $rule ; - */ - if ( $rule->getType() == Brizy_Admin_Rule::TYPE_INCLUDE ) { - break; - } - } - - if ( $rule ) { - - switch ( $rule->getAppliedFor() ) { - case Brizy_Admin_Rule::WOO_SHOP_PAGE: - if ( function_exists( 'wc_get_page_id' ) && wc_get_page_id( 'shop' ) ) { - $wp_post = get_post( wc_get_page_id( 'shop' ) ); - } - break; - case Brizy_Admin_Rule::POSTS : - $args = array( - 'post_type' => $rule->getEntityType(), - ); - - if ( count( $rule->getEntityValues() ) ) { - $args['post__in'] = $rule->getEntityValues(); - } - - $array = get_posts( $args ); - - foreach ( $array as $p ) { - - if ( $p->post_type == 'attachment' ) { - return addQueryStringToUrl( get_attachment_link( $p->ID ), 'preview=1' ); - } - - if ( ! Brizy_Editor::checkIfPostTypeIsSupported( $p->ID, false ) || - ! Brizy_Editor_Entity::isBrizyEnabled( $p->ID ) ) { - $wp_post = $p; - break; - } - - } - break; - case Brizy_Admin_Rule::TAXONOMY : - $args = array( - 'taxonomy' => $rule->getEntityType(), - 'hide_empty' => true, - ); - if ( count( $rule->getEntityValues() ) ) { - $args['term_taxonomy_id'] = $rule->getEntityValues(); - } - - $array = get_terms( $args ); - - if ( count( $array ) == 0 ) { - break; - } - $term = array_pop( $array ); - $link = get_term_link( $term ); - - return addQueryStringToUrl( $link, 'preview=1' ); - break; - case Brizy_Admin_Rule::ARCHIVE : - if ( $rule->getEntityType() ) { - $link = get_post_type_archive_link( $rule->getEntityType() ); - - return addQueryStringToUrl( $link, 'preview=1' ); - } - - $link = $this->getOneArchiveLink(); - - return addQueryStringToUrl( $link, 'preview=1' ); - break; - case Brizy_Admin_Rule::TEMPLATE : - - // array( 'title' => 'Author page', 'value' => 'author', 'groupValue' => Brizy_Admin_Rule::TEMPLATE ), - // array( 'title' => 'Search page', 'value' => 'search', 'groupValue' => Brizy_Admin_Rule::TEMPLATE ), - // array( 'title' => 'Home page', 'value' => 'front_page', 'groupValue' => Brizy_Admin_Rule::TEMPLATE ), - // array( 'title' => '404 page', 'value' => '404', 'groupValue' => Brizy_Admin_Rule::TEMPLATE ), - // array( 'title' => 'Archive page', 'value' => '', 'groupValue' => Brizy_Admin_Rule::ARCHIVE ), - switch ( $rule->getEntityType() ) { - case 'author': - $authors = get_users(); - $author = array_pop( $authors ); - $link = get_author_posts_url( $author->ID ); - - return addQueryStringToUrl( $link, 'preview=1' ); - break; - - case 'search': - return addQueryStringToUrl( get_search_link( 'find-me' ), 'preview=1' ); - break; - case '404': - return addQueryStringToUrl( get_home_url( null, (string) time() ), 'preview=1' ); - break; - case 'home_page': - $get_option = get_option( 'page_for_posts' ); - - if ( $get_option ) { - return addQueryStringToUrl( get_permalink( $get_option ), 'preview=1' ); - } - break; - case 'front_page': - return addQueryStringToUrl( home_url(), 'preview=1' ); - break; - } - - break; - } - - } - } - - return get_preview_post_link( - $wp_post, - array( - 'preview_id' => $wp_post->ID, - 'preview_nonce' => wp_create_nonce( 'post_preview_' . $wp_post->ID ), - ) - ); - } - - /** - * @return array - */ - private function get_menu_data() { - $menus = wp_get_nav_menus(); - $menu_data = array(); - - foreach ( $menus as $menu ) { - - $custom_menu_data = get_term_meta( $menu->term_id, 'brizy_data', true ); - - $menu_uid = get_term_meta( $menu->term_id, 'brizy_uid', true ); - if ( ! $menu_uid ) { - $menu_uid = md5( $menu->term_id . time() ); - update_term_meta( $menu->term_id, 'brizy_uid', $menu_uid ); - } - - $amenu = array( - 'id' => $menu_uid, - 'name' => $menu->name, - 'items' => array(), - ); - - $amenu = (object) array_merge( - $amenu, - get_object_vars( is_object( $custom_menu_data ) ? $custom_menu_data : (object) array() ) - ); - - $menuItems = []; - - add_action( 'wp_get_nav_menu_items', function ( $items ) use ( &$menuItems ) { - foreach ( $items as $item ) { - $menuItems[ $item->ID ] = $item; - } - - return $items; - }, - 1000 ); - - $currentItems = wp_get_nav_menu_items( $menu->term_id ); - - _wp_menu_item_classes_by_context( $menuItems ); - - $currentItemsAssociative = []; - foreach ( $currentItems as $currentItem ) { - $currentItemsAssociative[ $currentItem->ID ] = $currentItem; - } - - $menuItems = $currentItemsAssociative + $menuItems; - - $menu_items = $this->get_menu_tree( $menuItems ); - - if ( count( $menu_items ) > 0 ) { - $amenu->items = $menu_items; - } - - $menu_data[] = $amenu; - } - - return apply_filters( 'brizy_menu_data', $menu_data ); - } - - /** - * @param $items - * @param int $parent - * - * @return array - */ - private function get_menu_tree( $items, $parent = 0 ) { - $result_items = array(); - - foreach ( $items as $item ) { - if ( (string) $item->menu_item_parent !== (string) $parent ) { - continue; - } - - $menu_uid = get_post_meta( $item->ID, 'brizy_post_uid', true ); - - if ( ! $menu_uid ) { - $menu_uid = md5( $item->ID . time() ); - $update = update_post_meta( $item->ID, 'brizy_post_uid', $menu_uid ); - - if ( ! $update ) { - $menu_uid = $item->ID; - } - } - - $megaMenuItems = $this->getMegaMenuItems(); - - $menu_data = get_post_meta( $item->ID, 'brizy_data', true ); - - $item_value = array( - 'id' => $menu_uid, - 'title' => $item->title, - 'url' => $item->url, - 'megaMenuItems' => $megaMenuItems, - 'description' => $item->post_content, - 'position' => $item->menu_order, - 'attrTitle' => $item->post_excerpt, - 'current' => count( - array_intersect( - [ - 'current-menu-parent', - 'current-menu-item', - ], - $item->classes - ) - ) > 0, - 'target' => get_post_meta( $item->ID, '_menu_item_target', true ), - 'classes' => array_values( array_filter( $item->classes ) ), - 'xfn' => get_post_meta( $item->ID, '_menu_item_xfn', true ), - ); - - $an_item = (object) array( - 'type' => 'MenuItem', - ); - - $an_item->value = (object) array_merge( - $item_value, - get_object_vars( is_object( $menu_data ) ? $menu_data : (object) array() ) - ); - - $child_items = $this->get_menu_tree( $items, $item->ID ); - - $an_item->value->items = array(); - - if ( count( $child_items ) > 0 ) { - $an_item->value->items = $child_items; - } - - $result_items[] = $an_item; - } - - return $result_items; - } - - /** - * @return array - */ - private function getMegaMenuItems() { - - return array( - (object) ( array( - 'type' => "SectionMegaMenu", - 'value' => (object) array( 'items' => array() ), - ) ), - ); - } - - /** - * @param Brizy_Editor_Accounts_ServiceAccountManager $manager - * @param array $config - * - * @return array - */ - private function addRecaptchaAccounts( Brizy_Editor_Accounts_ServiceAccountManager $manager, array $config, $context ) { - $accounts = $manager->getAccountsByGroup( Brizy_Editor_Accounts_AbstractAccount::RECAPTCHA_GROUP ); - - if ( isset( $accounts[0] ) && $accounts[0] instanceof Brizy_Editor_Accounts_RecaptchaAccount ) { - $config['applications']['form']['recaptcha']['siteKey'] = $accounts[0]->getSiteKey(); - } - - return $config; - } - - /** - * @param Brizy_Editor_Accounts_ServiceAccountManager $manager - * @param array $config - * - * @return array - */ - private function addSocialAccounts( Brizy_Editor_Accounts_ServiceAccountManager $manager, array $config, $context ) { - $accounts = $manager->getAccountsByGroup( Brizy_Editor_Accounts_AbstractAccount::SOCIAL_GROUP ); - - foreach ( $accounts as $account ) { - if ( isset( $account ) && $account instanceof Brizy_Editor_Accounts_SocialAccount ) { - $config['applications'][ $account->getGroup() ][] = $account->convertToOptionValue(); - } - } - - return $config; - } - - - private function fileUploadMaxSize() { - static $max_size = - 1; - - if ( $max_size < 0 ) { - // Start with post_max_size. - $post_max_size = $this->parseSize( ini_get( 'post_max_size' ) ); - if ( $post_max_size > 0 ) { - $max_size = number_format( $post_max_size / 1048576, 2, '.', '' ); - } - - // If upload_max_size is less, then reduce. Except if upload_max_size is - // zero, which indicates no limit. - $upload_max = $this->parseSize( ini_get( 'upload_max_filesize' ) ); - if ( $upload_max > 0 && $upload_max < $max_size ) { - $max_size = number_format( $upload_max / 1048576, 2, '.', '' ); - } - } - - return $max_size; - } - - private function parseSize( $size ) { - $unit = preg_replace( '/[^bkmgtpezy]/i', '', $size ); // Remove the non-unit characters from the size. - $size = preg_replace( '/[^0-9\.]/', '', $size ); // Remove the non-numeric characters from the size. - if ( $unit ) { - // Find the position of the unit in the ordered string which is the power of magnitude to multiply a kilobyte by. - return round( $size * pow( 1024, stripos( 'bkmgtpezy', $unit[0] ) ) ); - } else { - return round( $size ); - } - } - - - private function getOneArchiveLink( $args = '' ) { - global $wpdb, $wp_locale; - - $defaults = array( - 'type' => 'monthly', - 'limit' => '', - 'order' => 'DESC', - 'post_type' => 'post', - 'year' => get_query_var( 'year' ), - 'monthnum' => get_query_var( 'monthnum' ), - 'day' => get_query_var( 'day' ), - 'w' => get_query_var( 'w' ), - ); - - $r = wp_parse_args( $args, $defaults ); - - $post_type_object = get_post_type_object( $r['post_type'] ); - if ( ! is_post_type_viewable( $post_type_object ) ) { - return; - } - $r['post_type'] = $post_type_object->name; - - if ( '' == $r['type'] ) { - $r['type'] = 'monthly'; - } - - if ( ! empty( $r['limit'] ) ) { - $r['limit'] = absint( $r['limit'] ); - $r['limit'] = ' LIMIT ' . $r['limit']; - } - - $order = strtoupper( $r['order'] ); - if ( $order !== 'ASC' ) { - $order = 'DESC'; - } - - // this is what will separate dates on weekly archive links - $archive_week_separator = '–'; - - $sql_where = $wpdb->prepare( "WHERE post_type = %s AND post_status = 'publish'", $r['post_type'] ); - - /** - * Filters the SQL WHERE clause for retrieving archives. - * - * @param string $sql_where Portion of SQL query containing the WHERE clause. - * @param array $r An array of default arguments. - * - * @since 2.2.0 - * - */ - $where = apply_filters( 'getarchives_where', $sql_where, $r ); - - /** - * Filters the SQL JOIN clause for retrieving archives. - * - * @param string $sql_join Portion of SQL query containing JOIN clause. - * @param array $r An array of default arguments. - * - * @since 2.2.0 - * - */ - $join = apply_filters( 'getarchives_join', '', $r ); - - $output = ''; - - $last_changed = wp_cache_get_last_changed( 'posts' ); - - $limit = $r['limit']; - - if ( 'monthly' == $r['type'] ) { - $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date $order $limit"; - $key = md5( $query ); - $key = "wp_get_archives:$key:$last_changed"; - if ( ! $results = wp_cache_get( $key, 'posts' ) ) { - $results = $wpdb->get_results( $query ); - wp_cache_set( $key, $results, 'posts' ); - } - if ( $results ) { - foreach ( (array) $results as $result ) { - $url = get_month_link( $result->year, $result->month ); - if ( 'post' !== $r['post_type'] ) { - $url = add_query_arg( 'post_type', $r['post_type'], $url ); - } - - return $url; - } - } - } - } - - /** - * @return string - * @throws Exception - */ - private function getTexts() { - if ( BRIZY_DEVELOPMENT ) { - $brizy_public_editor_build_texts = '\Brizy_Public_EditorBuild_Dev_Texts'; - } else { - $version = ''; - foreach ( explode( '-', BRIZY_EDITOR_VERSION ) as $tmp ) { - $version .= ucfirst( $tmp ); - } - $brizy_public_editor_build_texts = '\Brizy_Public_EditorBuild_' . $version . '_Texts'; - } - - if ( ! class_exists( $brizy_public_editor_build_texts ) ) { - if ( BRIZY_DEVELOPMENT ) { - throw new \Exception( 'You must build the editor first.' ); - } else { - throw new \Exception( 'Unable to find class ' . $brizy_public_editor_build_texts ); - } - } - - return (object) $brizy_public_editor_build_texts::get_editor_texts(); - } - - private function addTemplateFields( $config, $is_template, $wp_post_id, $context ) { - - $template_rules = []; - if ( $is_template ) { - $rule_manager = new Brizy_Admin_Rules_Manager(); - $template_rules = $rule_manager->getRules( $wp_post_id ); - $config['template_type'] = $this->getTemplateType( $template_rules ); - } - - $config['wp']['ruleMatches'] = $this->getTemplateRuleMatches( $is_template, $wp_post_id, $template_rules ); - - return $config; - } - - /** - * @param $isTemplate - * @param $wpPostId - * @param $templateRules - * - * @return array - */ - private function getTemplateRuleMatches( $isTemplate, $wpPostId, $templateRules ) { - - $ruleMatches = array(); - - if ( $isTemplate ) { - - foreach ( $templateRules as $rule ) { - /** - * @var Brizy_Admin_Rule $rule ; - */ - $ruleMatches[] = array( - 'type' => $rule->getType(), - 'group' => $rule->getAppliedFor(), - 'entityType' => $rule->getEntityType(), - 'values' => $rule->getEntityValues(), - ); - } - $ruleMatches[] = array( - 'type' => Brizy_Admin_Rule::TYPE_INCLUDE, - 'group' => Brizy_Admin_Rule::BRIZY_TEMPLATE, - 'entityType' => $this->post->getWpPost()->post_type, - 'values' => array( $wpPostId ), - ); - } else { - $ruleMatches[] = array( - 'type' => Brizy_Admin_Rule::TYPE_INCLUDE, - 'group' => Brizy_Admin_Rule::POSTS, - 'entityType' => $this->post->getWpPost()->post_type, - 'values' => array( $wpPostId ), - ); - } - - return $ruleMatches; - } - - - /** - * - * @param $template_rules - */ - private function getTemplateType( $template_rules ) { - foreach ( $template_rules as $rule ) { - - if ( $rule->getType() != Brizy_Admin_Rule::TYPE_INCLUDE ) { - continue; - } - - // single mode - if ( $rule->getAppliedFor() == Brizy_Admin_Rule::POSTS ) { - if ( $rule->getEntityType() == 'product' ) { - return 'product'; - } else { - return 'single'; - } - } - - - // single mode - if ( $rule->getAppliedFor() == Brizy_Admin_Rule::TEMPLATE ) { - if ( in_array( $rule->getEntityType(), [ '404', 'front_page' ] ) ) { - return 'single'; - } - - if ( in_array( $rule->getEntityType(), [ 'search', 'author', 'home_page' ] ) ) { - return 'archive'; - } - } - - // archive mode - if ( $rule->getAppliedFor() == Brizy_Admin_Rule::TAXONOMY ) { - if ( in_array( $rule->getEntityType(), [ 'product_cat', 'product_tag' ] ) ) { - return 'product_archive'; - } - if ( in_array( $rule->getEntityType(), [ 'category', 'post_tag', ] ) ) { - return 'archive'; - } - } - - // product archive mode - if ( in_array( $rule->getAppliedFor(), [ - Brizy_Admin_Rule::ARCHIVE, - Brizy_Admin_Rule::DATE_ARCHIVE, - Brizy_Admin_Rule::DAY_ARCHIVE, - Brizy_Admin_Rule::MONTH_ARCHIVE, - Brizy_Admin_Rule::YEAR_ARCHIVE, - Brizy_Admin_Rule::TAXONOMY, - Brizy_Admin_Rule::WOO_SHOP_PAGE, - ] ) ) { - if ( $rule->getAppliedFor() == Brizy_Admin_Rule::WOO_SHOP_PAGE && in_array( $rule->getEntityType(), [ - 'product', - 'shop_page', - ] ) ) { - return 'product_archive'; - } else { - return 'archive'; - } - } - } - - return ''; - } - - /** - * @return array - */ - public function getProjectStatus() { - $projectLockedBy = Brizy_Editor::get()->checkIfProjectIsLocked(); - $userData = WP_User::get_data_by( 'id', $projectLockedBy ); - unset( $userData->user_pass ); - unset( $userData->user_registered ); - unset( $userData->user_status ); - unset( $userData->user_activation_key ); - - return [ - 'locked' => $projectLockedBy !== false, - 'lockedBy' => $userData, - ]; - } - - /** - * @return array - */ - public function getApiActions( $config = [], $context = null ) { - - $pref = Brizy_Editor::prefix(); - - $actions = array( - 'hash' => wp_create_nonce( Brizy_Editor_API::nonce ), - 'url' => set_url_scheme( admin_url( 'admin-ajax.php' ) ), - 'heartBeat' => $pref . Brizy_Editor_API::AJAX_HEARTBEAT, - 'takeOver' => $pref . Brizy_Editor_API::AJAX_TAKE_OVER, - 'lockProject' => $pref . Brizy_Editor_API::AJAX_LOCK_PROJECT, - 'removeLock' => $pref . Brizy_Editor_API::AJAX_REMOVE_LOCK, - 'getPage' => $pref . Brizy_Editor_API::AJAX_GET, - 'getPostInfo' => $pref . Brizy_Editor_API::AJAX_GET_POST_INFO, - 'updatePage' => $pref . Brizy_Editor_API::AJAX_UPDATE, - 'getProject' => $pref . Brizy_Editor_API::AJAX_GET_PROJECT, - 'setProject' => $pref . Brizy_Editor_API::AJAX_SET_PROJECT, - 'setProjectMeta' => $pref . Brizy_Editor_API::AJAX_UPDATE_EDITOR_META_DATA, - 'getGlobalBlockList' => $pref . Brizy_Admin_Blocks_Api::GET_GLOBAL_BLOCKS_ACTION, - 'createGlobalBlock' => $pref . Brizy_Admin_Blocks_Api::CREATE_GLOBAL_BLOCK_ACTION, - 'updateGlobalBlock' => $pref . Brizy_Admin_Blocks_Api::UPDATE_GLOBAL_BLOCK_ACTION, - 'updateGlobalBlocks' => $pref . Brizy_Admin_Blocks_Api::UPDATE_GLOBAL_BLOCKS_ACTION, - 'deleteGlobalBlock' => $pref . Brizy_Admin_Blocks_Api::DELETE_GLOBAL_BLOCK_ACTION, - 'getRuleGroupList' => $pref . Brizy_Admin_Rules_Api::RULE_GROUP_LIST, - 'getLayoutByUid' => $pref . Brizy_Admin_Layouts_Api::GET_LAYOUT_BY_UID_ACTION, - 'getLayoutList' => $pref . Brizy_Admin_Layouts_Api::GET_LAYOUTS_ACTION, - 'createLayout' => $pref . Brizy_Admin_Layouts_Api::CREATE_LAYOUT_ACTION, - 'updateLayout' => $pref . Brizy_Admin_Layouts_Api::UPDATE_LAYOUT_ACTION, - 'deleteLayout' => $pref . Brizy_Admin_Layouts_Api::DELETE_LAYOUT_ACTION, - 'cloudSignIn' => $pref . Brizy_Admin_Cloud_Api::AJAX_SIGNIN_ACTION, - 'cloudSignUp' => $pref . Brizy_Admin_Cloud_Api::AJAX_SIGNUP_ACTION, - 'cloudSignOut' => $pref . Brizy_Admin_Cloud_Api::AJAX_SIGNOUT_ACTION, - 'cloudSyncAllowed' => $pref . Brizy_Admin_Cloud_Api::AJAX_SYNC_ALLOWED, - 'cloudResetPassword' => $pref . Brizy_Admin_Cloud_Api::AJAX_RESET_PASSWORD_ACTION, - 'cloudSync' => $pref . Brizy_Admin_Cloud_Api::AJAX_TRIGGER_SYNC_ACTION, - 'createRule' => $pref . Brizy_Admin_Rules_Api::CREATE_RULE_ACTION, - 'createRules' => $pref . Brizy_Admin_Rules_Api::CREATE_RULES_ACTION, - 'updateRules' => $pref . Brizy_Admin_Rules_Api::UPDATE_RULES_ACTION, - 'deleteRule' => $pref . Brizy_Admin_Rules_Api::DELETE_RULE_ACTION, - 'getRuleList' => $pref . Brizy_Admin_Rules_Api::LIST_RULE_ACTION, - 'updateBlockPositions' => $pref . Brizy_Admin_Blocks_Api::UPDATE_POSITIONS_ACTION, - 'getSavedBlockByUid' => $pref . Brizy_Admin_Blocks_Api::GET_SAVED_BLOCK_ACTION, - 'getSavedBlockList' => $pref . Brizy_Admin_Blocks_Api::GET_SAVED_BLOCKS_ACTION, - 'createSavedBlock' => $pref . Brizy_Admin_Blocks_Api::CREATE_SAVED_BLOCK_ACTION, - 'updateSavedBlock' => $pref . Brizy_Admin_Blocks_Api::UPDATE_SAVED_BLOCK_ACTION, - 'deleteSavedBlock' => $pref . Brizy_Admin_Blocks_Api::DELETE_SAVED_BLOCK_ACTION, - 'downloadBlocks' => $pref . Brizy_Admin_Blocks_Api::DOWNLOAD_BLOCKS, - 'uploadBlocks' => $pref . Brizy_Admin_Blocks_Api::UPLOAD_BLOCKS, - 'downloadLayouts' => $pref . Brizy_Admin_Layouts_Api::DOWNLOAD_LAYOUTS, - 'uploadLayouts' => $pref . Brizy_Admin_Layouts_Api::UPLOAD_LAYOUTS, - 'media' => $pref . Brizy_Editor_API::AJAX_MEDIA, - 'getMediaUid' => $pref . Brizy_Editor_API::AJAX_MEDIA_METAKEY, - 'getAttachmentUid' => $pref . Brizy_Editor_API::AJAX_CREATE_ATTACHMENT_UID, - 'getServerTimeStamp' => $pref . Brizy_Editor_API::AJAX_TIMESTAMP, - 'createBlockScreenshot' => $pref . Brizy_Editor_BlockScreenshotApi::AJAX_CREATE_BLOCK_SCREENSHOT, - 'updateBlockScreenshot' => $pref . Brizy_Editor_BlockScreenshotApi::AJAX_UPDATE_BLOCK_SCREENSHOT, - 'getSidebars' => $pref . Brizy_Editor_API::AJAX_SIDEBARS, - 'shortcodeContent' => $pref . Brizy_Editor_API::AJAX_SHORTCODE_CONTENT, - 'placeholderContent' => $pref . Brizy_Editor_API::AJAX_PLACEHOLDER_CONTENT, - 'placeholdersContent' => $pref . Brizy_Editor_API::AJAX_PLACEHOLDERS_CONTENT, - 'getPostTaxonomies' => $pref . Brizy_Editor_API::AJAX_GET_POST_TAXONOMIES, - 'getMenus' => $pref . Brizy_Editor_API::AJAX_GET_MENU_LIST, - 'getTerms' => $pref . Brizy_Editor_API::AJAX_GET_TERMS, - 'getTermsBy' => $pref . Brizy_Editor_API::AJAX_GET_TERMS_BY, - 'getUsers' => $pref . Brizy_Editor_API::AJAX_GET_USERS, - 'getPostObjects' => $pref . Brizy_Editor_API::AJAX_GET_POST_OBJECTS, // ??? - 'searchPosts' => $pref . Brizy_Editor_API::AJAX_SEARCH_POST, - 'setFeaturedImage' => $pref . Brizy_Editor_API::AJAX_SET_FEATURED_IMAGE, - 'setFeaturedImageFocalPoint' => $pref . Brizy_Editor_API::AJAX_SET_IMAGE_FOCAL_PT, - 'removeFeaturedImage' => $pref . Brizy_Editor_API::AJAX_REMOVE_FEATURED_IMAGE, - 'getForm' => $pref . Brizy_Editor_Forms_Api::AJAX_GET_FORM, - 'createForm' => $pref . Brizy_Editor_Forms_Api::AJAX_CREATE_FORM, - 'updateForm' => $pref . Brizy_Editor_Forms_Api::AJAX_UPDATE_FORM, - 'deleteForm' => $pref . Brizy_Editor_Forms_Api::AJAX_DELETE_FORM, - 'getIntegration' => $pref . Brizy_Editor_Forms_Api::AJAX_GET_INTEGRATION, - 'createIntegration' => $pref . Brizy_Editor_Forms_Api::AJAX_CREATE_INTEGRATION, - 'updateIntegration' => $pref . Brizy_Editor_Forms_Api::AJAX_UPDATE_INTEGRATION, - 'deleteIntegration' => $pref . Brizy_Editor_Forms_Api::AJAX_DELETE_INTEGRATION, - 'createFont' => $pref . Brizy_Admin_Fonts_Api::AJAX_CREATE_FONT_ACTION, - 'deleteFont' => $pref . Brizy_Admin_Fonts_Api::AJAX_DELETE_FONT_ACTION, - 'getFonts' => $pref . Brizy_Admin_Fonts_Api::AJAX_GET_FONTS_ACTION, - 'getAccount' => $pref . Brizy_Editor_Accounts_Api::BRIZY_GET_ACCOUNT, - 'getAccounts' => $pref . Brizy_Editor_Accounts_Api::BRIZY_GET_ACCOUNTS, - 'addAccount' => $pref . Brizy_Editor_Accounts_Api::BRIZY_ADD_ACCOUNT, - 'updateAccount' => $pref . Brizy_Editor_Accounts_Api::BRIZY_UPDATE_ACCOUNT, - 'deleteAccount' => $pref . Brizy_Editor_Accounts_Api::BRIZY_DELETE_ACCOUNT, - 'validateRecaptchaAccount' => $pref . Brizy_Editor_Forms_Api::AJAX_VALIDATE_RECAPTCHA_ACCOUNT, - 'rulePostsGroupList' => $pref . Brizy_Admin_Rules_Api::RULE_POSTS_GROUP_LIST, - 'ruleArchiveGroupList' => $pref . Brizy_Admin_Rules_Api::RULE_ARCHIVE_GROUP_LIST, - 'ruleTemplateGroupList' => $pref . Brizy_Admin_Rules_Api::RULE_TEMPLATE_GROUP_LIST, - 'symbolCreate' => $pref . Brizy_Admin_Symbols_Api::CREATE_ACTION, - 'symbolUpdate' => $pref . Brizy_Admin_Symbols_Api::UPDATE_ACTION, - 'symbolDelete' => $pref . Brizy_Admin_Symbols_Api::DELETE_ACTION, - 'symbolList' => $pref . Brizy_Admin_Symbols_Api::LIST_ACTION, - ); - - return $actions; - } - - /** - * @return array - * @throws Exception - */ - public function getCloudInfo() { - // the cloud will be always initialized with the exception when the white label is enabled - // we wil return isSyncAllowed = false just in case - if ( class_exists( 'BrizyPro_Admin_WhiteLabel' ) && BrizyPro_Admin_WhiteLabel::_init()->getEnabled() ) { - return array( - 'isSyncAllowed' => false, - ); - } - - $response = array( - 'isSyncAllowed' => true, - ); - - if ( $this->project->getMetaValue( 'brizy-cloud-token' ) !== null ) { - try { - $cloudClient = Brizy_Admin_Cloud_Client::instance( - Brizy_Editor_Project::get(), - new WP_Http() - ); - $versions = $cloudClient->getCloudEditorVersions(); - $response['isSyncAllowed'] = $versions['sync'] == BRIZY_SYNC_VERSION; - } catch ( Exception $e ) { - return [ 'isSyncAllowed' => false ]; - } - } - - return $response; - } - - /** - * Do not use: $userId = get_post_meta( $this->post->getWpPostId(), '_edit_last', true ); - * This meta _edit_last is often deleted by plugins dealing with optimize database - * - * @param $context - * - * @return bool - */ - private function isUserAllowedToAddScripts( $context ) { - - if ( $context == self::COMPILE_CONTEXT ) { - - $userId = $this->post->getLastUserEdited(); - - if ( $userId === null ) { - return true; - } - - } else { - $userId = get_current_user_id(); - } - - $userCan = user_can( $userId, 'unfiltered_html' ); - - return $userCan; - } - - private function getImgSizes() { - - $sizes = []; - - foreach ( Brizy_Editor::get_all_image_sizes() as $name => $size ) { - if ( isset( $size['crop'] ) ) { - unset( $size['crop'] ); - } - $size['name'] = $name; - $sizes[] = $size; - } - - return $sizes; - } + $this->post->getUid() + ); + + $results = $wpdb->get_results($query); + $attachment_data = array(); + foreach ($results as $row) { + $attachment_data[$row->meta_value] = true; + } + + return (object)$attachment_data; + } + + /** + * @return array|null + */ + public static function get_woocomerce_plugin_info() + { + if (function_exists('wc') && defined('WC_PLUGIN_FILE')) { + return array('version' => WooCommerce::instance()->version); + } + + return null; + } + + /** + * @param $wp_post_id + * + * @return array|null + */ + private function getThumbnailData($wp_post_id) + { + $post_thumbnail_id = get_post_thumbnail_id($wp_post_id); + $post_thumbnail = ""; + + if ($post_thumbnail_id) { + $post_thumbnail_focal_point = get_post_meta($wp_post_id, 'brizy_attachment_focal_point', true); + + if (!is_array($post_thumbnail_focal_point)) { + $post_thumbnail_focal_point = array('x' => "", 'y' => ""); + } + + $post_thumbnail = array( + 'id' => $post_thumbnail_id, + 'url' => get_the_post_thumbnail_url($wp_post_id), + 'pointX' => isset($post_thumbnail_focal_point['x']) ? $post_thumbnail_focal_point['x'] : "", + 'pointY' => isset($post_thumbnail_focal_point['y']) ? $post_thumbnail_focal_point['y'] : "", + ); + } + + return $post_thumbnail; + } + + private function getAllParents($terms) + { + $result = []; + foreach ($terms as $i => $term) { + foreach ($this->getTermParents($term) as $aTerm) { + if (!isset($result[$aTerm->term_id])) { + $result[$aTerm->term_id] = $aTerm; + } + } + } + + return $result; + } + + private function getTermParents($term) + { + $parents = []; + if ($term->parent) { + $parent = get_term_by('id', $term->parent, $term->taxonomy); + + if ($parent) { + $parents[$parent->term_id] = $parent; + if ($parent->parent > 0) { + $parents = array_merge($parents, $this->getTermParents($parent)); + } + } + } + + return $parents; + } + + /** + * @param $wp_post + * + * @return null|string + * @throws Brizy_Editor_Exceptions_NotFound + * @throws Brizy_Editor_Exceptions_UnsupportedPostType + */ + private function getPreviewUrl($wp_post) + { + + if ($wp_post->post_type == Brizy_Admin_Templates::CP_TEMPLATE) { + + $ruleManager = new Brizy_Admin_Rules_Manager(); + $rules = $ruleManager->getRules($wp_post->ID); + $rule = null; + + + if (!function_exists('addQueryStringToUrl')) { + function addQueryStringToUrl($link, $query) + { + $parsedUrl = parse_url($link); + $separator = (!isset($parsedUrl['query']) || $parsedUrl['query'] == null) ? '?' : '&'; + $link .= $separator . $query; + + return $link; + } + } + + + // find first include rule + foreach ($rules as $rule) { + /** + * @var Brizy_Admin_Rule $rule ; + */ + if ($rule->getType() == Brizy_Admin_Rule::TYPE_INCLUDE) { + break; + } + } + + if ($rule) { + + switch ($rule->getAppliedFor()) { + case Brizy_Admin_Rule::WOO_SHOP_PAGE: + if (function_exists('wc_get_page_id') && wc_get_page_id('shop')) { + $wp_post = get_post(wc_get_page_id('shop')); + } + break; + case Brizy_Admin_Rule::POSTS : + $args = array( + 'post_type' => $rule->getEntityType(), + ); + + if (count($rule->getEntityValues())) { + $args['post__in'] = $rule->getEntityValues(); + } + + $array = get_posts($args); + + foreach ($array as $p) { + + if ($p->post_type == 'attachment') { + return addQueryStringToUrl(get_attachment_link($p->ID), 'preview=1'); + } + + if (!Brizy_Editor::checkIfPostTypeIsSupported($p->ID, false) || + !Brizy_Editor_Entity::isBrizyEnabled($p->ID)) { + $wp_post = $p; + break; + } + + } + break; + case Brizy_Admin_Rule::TAXONOMY : + $args = array( + 'taxonomy' => $rule->getEntityType(), + 'hide_empty' => true, + ); + if (count($rule->getEntityValues())) { + $args['term_taxonomy_id'] = $rule->getEntityValues(); + } + + $array = get_terms($args); + + if (count($array) == 0) { + break; + } + $term = array_pop($array); + $link = get_term_link($term); + + return addQueryStringToUrl($link, 'preview=1'); + break; + case Brizy_Admin_Rule::ARCHIVE : + if ($rule->getEntityType()) { + $link = get_post_type_archive_link($rule->getEntityType()); + + return addQueryStringToUrl($link, 'preview=1'); + } + + $link = $this->getOneArchiveLink(); + + return addQueryStringToUrl($link, 'preview=1'); + break; + case Brizy_Admin_Rule::TEMPLATE : + + // array( 'title' => 'Author page', 'value' => 'author', 'groupValue' => Brizy_Admin_Rule::TEMPLATE ), + // array( 'title' => 'Search page', 'value' => 'search', 'groupValue' => Brizy_Admin_Rule::TEMPLATE ), + // array( 'title' => 'Home page', 'value' => 'front_page', 'groupValue' => Brizy_Admin_Rule::TEMPLATE ), + // array( 'title' => '404 page', 'value' => '404', 'groupValue' => Brizy_Admin_Rule::TEMPLATE ), + // array( 'title' => 'Archive page', 'value' => '', 'groupValue' => Brizy_Admin_Rule::ARCHIVE ), + switch ($rule->getEntityType()) { + case 'author': + $authors = get_users(); + $author = array_pop($authors); + $link = get_author_posts_url($author->ID); + + return addQueryStringToUrl($link, 'preview=1'); + break; + + case 'search': + return addQueryStringToUrl(get_search_link('find-me'), 'preview=1'); + break; + case '404': + return addQueryStringToUrl(get_home_url(null, (string)time()), 'preview=1'); + break; + case 'home_page': + $get_option = get_option('page_for_posts'); + + if ($get_option) { + return addQueryStringToUrl(get_permalink($get_option), 'preview=1'); + } + break; + case 'front_page': + return addQueryStringToUrl(home_url(), 'preview=1'); + break; + } + + break; + } + + } + } + + return get_preview_post_link( + $wp_post, + array( + 'preview_id' => $wp_post->ID, + 'preview_nonce' => wp_create_nonce('post_preview_' . $wp_post->ID), + ) + ); + } + + /** + * @return array + */ + private function get_menu_data() + { + $menus = wp_get_nav_menus(); + $menu_data = array(); + + foreach ($menus as $menu) { + + $custom_menu_data = get_term_meta($menu->term_id, 'brizy_data', true); + + $menu_uid = get_term_meta($menu->term_id, 'brizy_uid', true); + if (!$menu_uid) { + $menu_uid = md5($menu->term_id . time()); + update_term_meta($menu->term_id, 'brizy_uid', $menu_uid); + } + + $amenu = array( + 'id' => $menu_uid, + 'name' => $menu->name, + 'items' => array(), + ); + + $amenu = (object)array_merge( + $amenu, + get_object_vars(is_object($custom_menu_data) ? $custom_menu_data : (object)array()) + ); + + $menuItems = []; + + add_action('wp_get_nav_menu_items', function ($items) use (&$menuItems) { + foreach ($items as $item) { + $menuItems[$item->ID] = $item; + } + + return $items; + }, -1000); + + $currentItems = wp_get_nav_menu_items($menu->term_id); + + _wp_menu_item_classes_by_context($menuItems); + + $currentItemsAssociative = []; + foreach ($currentItems as $currentItem) { + $currentItemsAssociative[$currentItem->ID] = $currentItem; + } + + $menuItems = $currentItemsAssociative + $menuItems; + + $menu_items = $this->get_menu_tree($menuItems); + + if (count($menu_items) > 0) { + $amenu->items = $menu_items; + } + + $menu_data[] = $amenu; + } + + return apply_filters('brizy_menu_data', $menu_data); + } + + /** + * @param $items + * @param int $parent + * + * @return array + */ + private function get_menu_tree($items, $parent = 0) + { + $result_items = array(); + + foreach ($items as $item) { + if ((string)$item->menu_item_parent !== (string)$parent) { + continue; + } + + $menu_uid = get_post_meta($item->ID, 'brizy_post_uid', true); + + if (!$menu_uid) { + $menu_uid = md5($item->ID . time()); + $update = update_post_meta($item->ID, 'brizy_post_uid', $menu_uid); + + if (!$update) { + $menu_uid = $item->ID; + } + } + + $megaMenuItems = $this->getMegaMenuItems(); + + $menu_data = get_post_meta($item->ID, 'brizy_data', true); + + $item_value = array( + 'id' => $menu_uid, + 'title' => $item->title, + 'url' => $item->url, + 'megaMenuItems' => $megaMenuItems, + 'description' => $item->post_content, + 'position' => $item->menu_order, + 'attrTitle' => $item->post_excerpt, + 'current' => count( + array_intersect( + [ + 'current-menu-parent', + 'current-menu-item', + ], + $item->classes + ) + ) > 0, + 'target' => get_post_meta($item->ID, '_menu_item_target', true), + 'classes' => array_values(array_filter($item->classes)), + 'xfn' => get_post_meta($item->ID, '_menu_item_xfn', true), + ); + + $an_item = (object)array( + 'type' => 'MenuItem', + ); + + $an_item->value = (object)array_merge( + $item_value, + get_object_vars(is_object($menu_data) ? $menu_data : (object)array()) + ); + + $child_items = $this->get_menu_tree($items, $item->ID); + + $an_item->value->items = array(); + + if (count($child_items) > 0) { + $an_item->value->items = $child_items; + } + + $result_items[] = $an_item; + } + + return $result_items; + } + + /** + * @return array + */ + private function getMegaMenuItems() + { + + return array( + (object)(array( + 'type' => "SectionMegaMenu", + 'value' => (object)array('items' => array()), + )), + ); + } + + /** + * @param Brizy_Editor_Accounts_ServiceAccountManager $manager + * @param array $config + * + * @return array + */ + private function addRecaptchaAccounts(Brizy_Editor_Accounts_ServiceAccountManager $manager, array $config, $context) + { + $accounts = $manager->getAccountsByGroup(Brizy_Editor_Accounts_AbstractAccount::RECAPTCHA_GROUP); + + if (isset($accounts[0]) && $accounts[0] instanceof Brizy_Editor_Accounts_RecaptchaAccount) { + $config['applications']['form']['recaptcha']['siteKey'] = $accounts[0]->getSiteKey(); + } + + return $config; + } + + /** + * @param Brizy_Editor_Accounts_ServiceAccountManager $manager + * @param array $config + * + * @return array + */ + private function addSocialAccounts(Brizy_Editor_Accounts_ServiceAccountManager $manager, array $config, $context) + { + $accounts = $manager->getAccountsByGroup(Brizy_Editor_Accounts_AbstractAccount::SOCIAL_GROUP); + + foreach ($accounts as $account) { + if (isset($account) && $account instanceof Brizy_Editor_Accounts_SocialAccount) { + $config['applications'][$account->getGroup()][] = $account->convertToOptionValue(); + } + } + + return $config; + } + + + private function fileUploadMaxSize() + { + static $max_size = -1; + + if ($max_size < 0) { + // Start with post_max_size. + $post_max_size = $this->parseSize(ini_get('post_max_size')); + if ($post_max_size > 0) { + $max_size = number_format($post_max_size / 1048576, 2, '.', ''); + } + + // If upload_max_size is less, then reduce. Except if upload_max_size is + // zero, which indicates no limit. + $upload_max = $this->parseSize(ini_get('upload_max_filesize')); + if ($upload_max > 0 && $upload_max < $max_size) { + $max_size = number_format($upload_max / 1048576, 2, '.', ''); + } + } + + return $max_size; + } + + private function parseSize($size) + { + $unit = preg_replace('/[^bkmgtpezy]/i', '', $size); // Remove the non-unit characters from the size. + $size = preg_replace('/[^0-9\.]/', '', $size); // Remove the non-numeric characters from the size. + if ($unit) { + // Find the position of the unit in the ordered string which is the power of magnitude to multiply a kilobyte by. + return round($size * pow(1024, stripos('bkmgtpezy', $unit[0]))); + } else { + return round($size); + } + } + + + private function getOneArchiveLink($args = '') + { + global $wpdb, $wp_locale; + + $defaults = array( + 'type' => 'monthly', + 'limit' => '', + 'order' => 'DESC', + 'post_type' => 'post', + 'year' => get_query_var('year'), + 'monthnum' => get_query_var('monthnum'), + 'day' => get_query_var('day'), + 'w' => get_query_var('w'), + ); + + $r = wp_parse_args($args, $defaults); + + $post_type_object = get_post_type_object($r['post_type']); + if (!is_post_type_viewable($post_type_object)) { + return; + } + $r['post_type'] = $post_type_object->name; + + if ('' == $r['type']) { + $r['type'] = 'monthly'; + } + + if (!empty($r['limit'])) { + $r['limit'] = absint($r['limit']); + $r['limit'] = ' LIMIT ' . $r['limit']; + } + + $order = strtoupper($r['order']); + if ($order !== 'ASC') { + $order = 'DESC'; + } + + // this is what will separate dates on weekly archive links + $archive_week_separator = '–'; + + $sql_where = $wpdb->prepare("WHERE post_type = %s AND post_status = 'publish'", $r['post_type']); + + /** + * Filters the SQL WHERE clause for retrieving archives. + * + * @param string $sql_where Portion of SQL query containing the WHERE clause. + * @param array $r An array of default arguments. + * + * @since 2.2.0 + * + */ + $where = apply_filters('getarchives_where', $sql_where, $r); + + /** + * Filters the SQL JOIN clause for retrieving archives. + * + * @param string $sql_join Portion of SQL query containing JOIN clause. + * @param array $r An array of default arguments. + * + * @since 2.2.0 + * + */ + $join = apply_filters('getarchives_join', '', $r); + + $output = ''; + + $last_changed = wp_cache_get_last_changed('posts'); + + $limit = $r['limit']; + + if ('monthly' == $r['type']) { + $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date $order $limit"; + $key = md5($query); + $key = "wp_get_archives:$key:$last_changed"; + if (!$results = wp_cache_get($key, 'posts')) { + $results = $wpdb->get_results($query); + wp_cache_set($key, $results, 'posts'); + } + if ($results) { + foreach ((array)$results as $result) { + $url = get_month_link($result->year, $result->month); + if ('post' !== $r['post_type']) { + $url = add_query_arg('post_type', $r['post_type'], $url); + } + + return $url; + } + } + } + } + + /** + * @return string + * @throws Exception + */ + private function getTexts() + { + if (BRIZY_DEVELOPMENT) { + $brizy_public_editor_build_texts = '\Brizy_Public_EditorBuild_Dev_Texts'; + } else { + $version = ''; + foreach (explode('-', BRIZY_EDITOR_VERSION) as $tmp) { + $version .= ucfirst($tmp); + } + $brizy_public_editor_build_texts = '\Brizy_Public_EditorBuild_' . $version . '_Texts'; + } + + if (!class_exists($brizy_public_editor_build_texts)) { + if (BRIZY_DEVELOPMENT) { + throw new \Exception('You must build the editor first.'); + } else { + throw new \Exception('Unable to find class ' . $brizy_public_editor_build_texts); + } + } + + return (object)$brizy_public_editor_build_texts::get_editor_texts(); + } + + private function addTemplateFields($config, $is_template, $wp_post_id, $context) + { + + $template_rules = []; + if ($is_template) { + $rule_manager = new Brizy_Admin_Rules_Manager(); + $template_rules = $rule_manager->getRules($wp_post_id); + $config['template_type'] = $this->getTemplateType($template_rules); + } + + $config['wp']['ruleMatches'] = $this->getTemplateRuleMatches($is_template, $wp_post_id, $template_rules); + + return $config; + } + + /** + * @param $isTemplate + * @param $wpPostId + * @param $templateRules + * + * @return array + */ + private function getTemplateRuleMatches($isTemplate, $wpPostId, $templateRules) + { + + $ruleMatches = array(); + + if ($isTemplate) { + + foreach ($templateRules as $rule) { + /** + * @var Brizy_Admin_Rule $rule ; + */ + $ruleMatches[] = array( + 'type' => $rule->getType(), + 'group' => $rule->getAppliedFor(), + 'entityType' => $rule->getEntityType(), + 'values' => $rule->getEntityValues(), + ); + } + $ruleMatches[] = array( + 'type' => Brizy_Admin_Rule::TYPE_INCLUDE, + 'group' => Brizy_Admin_Rule::BRIZY_TEMPLATE, + 'entityType' => $this->post->getWpPost()->post_type, + 'values' => array($wpPostId), + ); + } else { + $ruleMatches[] = array( + 'type' => Brizy_Admin_Rule::TYPE_INCLUDE, + 'group' => Brizy_Admin_Rule::POSTS, + 'entityType' => $this->post->getWpPost()->post_type, + 'values' => array($wpPostId), + ); + } + + return $ruleMatches; + } + + + /** + * + * @param $template_rules + */ + private function getTemplateType($template_rules) + { + foreach ($template_rules as $rule) { + + if ($rule->getType() != Brizy_Admin_Rule::TYPE_INCLUDE) { + continue; + } + + // single mode + if ($rule->getAppliedFor() == Brizy_Admin_Rule::POSTS) { + if ($rule->getEntityType() == 'product') { + return 'product'; + } else { + return 'single'; + } + } + + + // single mode + if ($rule->getAppliedFor() == Brizy_Admin_Rule::TEMPLATE) { + if (in_array($rule->getEntityType(), ['404', 'front_page'])) { + return 'single'; + } + + if (in_array($rule->getEntityType(), ['search', 'author', 'home_page'])) { + return 'archive'; + } + } + + // archive mode + if ($rule->getAppliedFor() == Brizy_Admin_Rule::TAXONOMY) { + if (in_array($rule->getEntityType(), ['product_cat', 'product_tag'])) { + return 'product_archive'; + } + if (in_array($rule->getEntityType(), ['category', 'post_tag',])) { + return 'archive'; + } + } + + // product archive mode + if (in_array($rule->getAppliedFor(), [ + Brizy_Admin_Rule::ARCHIVE, + Brizy_Admin_Rule::DATE_ARCHIVE, + Brizy_Admin_Rule::DAY_ARCHIVE, + Brizy_Admin_Rule::MONTH_ARCHIVE, + Brizy_Admin_Rule::YEAR_ARCHIVE, + Brizy_Admin_Rule::TAXONOMY, + Brizy_Admin_Rule::WOO_SHOP_PAGE, + ])) { + if ($rule->getAppliedFor() == Brizy_Admin_Rule::WOO_SHOP_PAGE && in_array($rule->getEntityType(), [ + 'product', + 'shop_page', + ])) { + return 'product_archive'; + } else { + return 'archive'; + } + } + } + + return ''; + } + + /** + * @return array + */ + public function getProjectStatus() + { + $projectLockedBy = Brizy_Editor::get()->checkIfProjectIsLocked(); + $userData = WP_User::get_data_by('id', $projectLockedBy); + unset($userData->user_pass); + unset($userData->user_registered); + unset($userData->user_status); + unset($userData->user_activation_key); + + return [ + 'locked' => $projectLockedBy !== false, + 'lockedBy' => $userData, + ]; + } + + /** + * @return array + */ + public function getApiActions($config = [], $context = null) + { + $pref = Brizy_Editor::prefix(); + + $actions = array( + 'hash' => wp_create_nonce(Brizy_Editor_API::nonce), + 'url' => set_url_scheme(admin_url('admin-ajax.php')), + 'heartBeat' => $pref . Brizy_Editor_API::AJAX_HEARTBEAT, + 'takeOver' => $pref . Brizy_Editor_API::AJAX_TAKE_OVER, + 'lockProject' => $pref . Brizy_Editor_API::AJAX_LOCK_PROJECT, + 'removeLock' => $pref . Brizy_Editor_API::AJAX_REMOVE_LOCK, + 'getPage' => $pref . Brizy_Editor_API::AJAX_GET, + 'getPostInfo' => $pref . Brizy_Editor_API::AJAX_GET_POST_INFO, + 'updatePage' => $pref . Brizy_Editor_API::AJAX_UPDATE, + 'getProject' => $pref . Brizy_Editor_API::AJAX_GET_PROJECT, + 'setProject' => $pref . Brizy_Editor_API::AJAX_SET_PROJECT, + 'setProjectMeta' => $pref . Brizy_Editor_API::AJAX_UPDATE_EDITOR_META_DATA, + 'getGlobalBlockList' => $pref . Brizy_Admin_Blocks_Api::GET_GLOBAL_BLOCKS_ACTION, + 'createGlobalBlock' => $pref . Brizy_Admin_Blocks_Api::CREATE_GLOBAL_BLOCK_ACTION, + 'updateGlobalBlock' => $pref . Brizy_Admin_Blocks_Api::UPDATE_GLOBAL_BLOCK_ACTION, + 'updateGlobalBlocks' => $pref . Brizy_Admin_Blocks_Api::UPDATE_GLOBAL_BLOCKS_ACTION, + 'deleteGlobalBlock' => $pref . Brizy_Admin_Blocks_Api::DELETE_GLOBAL_BLOCK_ACTION, + 'getRuleGroupList' => $pref . Brizy_Admin_Rules_Api::RULE_GROUP_LIST, + 'getLayoutByUid' => $pref . Brizy_Admin_Layouts_Api::GET_LAYOUT_BY_UID_ACTION, + 'getLayoutList' => $pref . Brizy_Admin_Layouts_Api::GET_LAYOUTS_ACTION, + 'createLayout' => $pref . Brizy_Admin_Layouts_Api::CREATE_LAYOUT_ACTION, + 'updateLayout' => $pref . Brizy_Admin_Layouts_Api::UPDATE_LAYOUT_ACTION, + 'deleteLayout' => $pref . Brizy_Admin_Layouts_Api::DELETE_LAYOUT_ACTION, + 'cloudSignIn' => $pref . Brizy_Admin_Cloud_Api::AJAX_SIGNIN_ACTION, + 'cloudSignUp' => $pref . Brizy_Admin_Cloud_Api::AJAX_SIGNUP_ACTION, + 'cloudSignOut' => $pref . Brizy_Admin_Cloud_Api::AJAX_SIGNOUT_ACTION, + 'cloudSyncAllowed' => $pref . Brizy_Admin_Cloud_Api::AJAX_SYNC_ALLOWED, + 'cloudResetPassword' => $pref . Brizy_Admin_Cloud_Api::AJAX_RESET_PASSWORD_ACTION, + 'cloudSync' => $pref . Brizy_Admin_Cloud_Api::AJAX_TRIGGER_SYNC_ACTION, + 'createRule' => $pref . Brizy_Admin_Rules_Api::CREATE_RULE_ACTION, + 'createRules' => $pref . Brizy_Admin_Rules_Api::CREATE_RULES_ACTION, + 'updateRules' => $pref . Brizy_Admin_Rules_Api::UPDATE_RULES_ACTION, + 'deleteRule' => $pref . Brizy_Admin_Rules_Api::DELETE_RULE_ACTION, + 'getRuleList' => $pref . Brizy_Admin_Rules_Api::LIST_RULE_ACTION, + 'updateBlockPositions' => $pref . Brizy_Admin_Blocks_Api::UPDATE_POSITIONS_ACTION, + 'getSavedBlockByUid' => $pref . Brizy_Admin_Blocks_Api::GET_SAVED_BLOCK_ACTION, + 'getSavedBlockList' => $pref . Brizy_Admin_Blocks_Api::GET_SAVED_BLOCKS_ACTION, + 'createSavedBlock' => $pref . Brizy_Admin_Blocks_Api::CREATE_SAVED_BLOCK_ACTION, + 'updateSavedBlock' => $pref . Brizy_Admin_Blocks_Api::UPDATE_SAVED_BLOCK_ACTION, + 'deleteSavedBlock' => $pref . Brizy_Admin_Blocks_Api::DELETE_SAVED_BLOCK_ACTION, + 'downloadBlocks' => $pref . Brizy_Admin_Blocks_Api::DOWNLOAD_BLOCKS, + 'uploadBlocks' => $pref . Brizy_Admin_Blocks_Api::UPLOAD_BLOCKS, + 'downloadLayouts' => $pref . Brizy_Admin_Layouts_Api::DOWNLOAD_LAYOUTS, + 'uploadLayouts' => $pref . Brizy_Admin_Layouts_Api::UPLOAD_LAYOUTS, + 'media' => $pref . Brizy_Editor_API::AJAX_MEDIA, + 'getMediaUid' => $pref . Brizy_Editor_API::AJAX_MEDIA_METAKEY, + 'getAttachmentUid' => $pref . Brizy_Editor_API::AJAX_CREATE_ATTACHMENT_UID, + 'getServerTimeStamp' => $pref . Brizy_Editor_API::AJAX_TIMESTAMP, + 'createBlockScreenshot' => $pref . Brizy_Editor_BlockScreenshotApi::AJAX_CREATE_BLOCK_SCREENSHOT, + 'updateBlockScreenshot' => $pref . Brizy_Editor_BlockScreenshotApi::AJAX_UPDATE_BLOCK_SCREENSHOT, + 'getSidebars' => $pref . Brizy_Editor_API::AJAX_SIDEBARS, + 'shortcodeContent' => $pref . Brizy_Editor_API::AJAX_SHORTCODE_CONTENT, + 'placeholderContent' => $pref . Brizy_Editor_API::AJAX_PLACEHOLDER_CONTENT, + 'placeholdersContent' => $pref . Brizy_Editor_API::AJAX_PLACEHOLDERS_CONTENT, + 'getPostTaxonomies' => $pref . Brizy_Editor_API::AJAX_GET_POST_TAXONOMIES, + 'getMenus' => $pref . Brizy_Editor_API::AJAX_GET_MENU_LIST, + 'getTerms' => $pref . Brizy_Editor_API::AJAX_GET_TERMS, + 'getTermsBy' => $pref . Brizy_Editor_API::AJAX_GET_TERMS_BY, + 'getUsers' => $pref . Brizy_Editor_API::AJAX_GET_USERS, + 'getPostObjects' => $pref . Brizy_Editor_API::AJAX_GET_POST_OBJECTS, // ??? + 'searchPosts' => $pref . Brizy_Editor_API::AJAX_SEARCH_POST, + 'setFeaturedImage' => $pref . Brizy_Editor_API::AJAX_SET_FEATURED_IMAGE, + 'setFeaturedImageFocalPoint' => $pref . Brizy_Editor_API::AJAX_SET_IMAGE_FOCAL_PT, + 'removeFeaturedImage' => $pref . Brizy_Editor_API::AJAX_REMOVE_FEATURED_IMAGE, + 'getForm' => $pref . Brizy_Editor_Forms_Api::AJAX_GET_FORM, + 'createForm' => $pref . Brizy_Editor_Forms_Api::AJAX_CREATE_FORM, + 'updateForm' => $pref . Brizy_Editor_Forms_Api::AJAX_UPDATE_FORM, + 'deleteForm' => $pref . Brizy_Editor_Forms_Api::AJAX_DELETE_FORM, + 'getIntegration' => $pref . Brizy_Editor_Forms_Api::AJAX_GET_INTEGRATION, + 'createIntegration' => $pref . Brizy_Editor_Forms_Api::AJAX_CREATE_INTEGRATION, + 'updateIntegration' => $pref . Brizy_Editor_Forms_Api::AJAX_UPDATE_INTEGRATION, + 'deleteIntegration' => $pref . Brizy_Editor_Forms_Api::AJAX_DELETE_INTEGRATION, + 'createFont' => $pref . Brizy_Admin_Fonts_Api::AJAX_CREATE_FONT_ACTION, + 'deleteFont' => $pref . Brizy_Admin_Fonts_Api::AJAX_DELETE_FONT_ACTION, + 'getFonts' => $pref . Brizy_Admin_Fonts_Api::AJAX_GET_FONTS_ACTION, + 'getAccount' => $pref . Brizy_Editor_Accounts_Api::BRIZY_GET_ACCOUNT, + 'getAccounts' => $pref . Brizy_Editor_Accounts_Api::BRIZY_GET_ACCOUNTS, + 'addAccount' => $pref . Brizy_Editor_Accounts_Api::BRIZY_ADD_ACCOUNT, + 'updateAccount' => $pref . Brizy_Editor_Accounts_Api::BRIZY_UPDATE_ACCOUNT, + 'deleteAccount' => $pref . Brizy_Editor_Accounts_Api::BRIZY_DELETE_ACCOUNT, + 'validateRecaptchaAccount' => $pref . Brizy_Editor_Forms_Api::AJAX_VALIDATE_RECAPTCHA_ACCOUNT, + 'rulePostsGroupList' => $pref . Brizy_Admin_Rules_Api::RULE_POSTS_GROUP_LIST, + 'ruleArchiveGroupList' => $pref . Brizy_Admin_Rules_Api::RULE_ARCHIVE_GROUP_LIST, + 'ruleTemplateGroupList' => $pref . Brizy_Admin_Rules_Api::RULE_TEMPLATE_GROUP_LIST, + 'symbolCreate' => $pref . Brizy_Admin_Symbols_Api::CREATE_ACTION, + 'symbolUpdate' => $pref . Brizy_Admin_Symbols_Api::UPDATE_ACTION, + 'symbolDelete' => $pref . Brizy_Admin_Symbols_Api::DELETE_ACTION, + 'symbolList' => $pref . Brizy_Admin_Symbols_Api::LIST_ACTION, + 'filterPlaceholderContents' => $pref . Brizy_Editor_Filters_Api::AJAX_FILTER_PLACEHOLDERS_CONTENT, + ); + + return $actions; + } + + /** + * @return array + * @throws Exception + */ + public function getCloudInfo() + { + // the cloud will be always initialized with the exception when the white label is enabled + // we wil return isSyncAllowed = false just in case + if (class_exists('BrizyPro_Admin_WhiteLabel') && BrizyPro_Admin_WhiteLabel::_init()->getEnabled()) { + return array( + 'isSyncAllowed' => false, + ); + } + + $response = array( + 'isSyncAllowed' => true, + ); + + if ($this->project->getMetaValue('brizy-cloud-token') !== null) { + try { + $cloudClient = Brizy_Admin_Cloud_Client::instance( + Brizy_Editor_Project::get(), + new WP_Http() + ); + $versions = $cloudClient->getCloudEditorVersions(); + $response['isSyncAllowed'] = $versions['sync'] == BRIZY_SYNC_VERSION; + } catch (Exception $e) { + return ['isSyncAllowed' => false]; + } + } + + return $response; + } + + /** + * Do not use: $userId = get_post_meta( $this->post->getWpPostId(), '_edit_last', true ); + * This meta _edit_last is often deleted by plugins dealing with optimize database + * + * @param $context + * + * @return bool + */ + private function isUserAllowedToAddScripts($context) + { + + if ($context == self::COMPILE_CONTEXT) { + + $userId = $this->post->getLastUserEdited(); + + if ($userId === null) { + return true; + } + + } else { + $userId = get_current_user_id(); + } + + $userCan = user_can($userId, 'unfiltered_html'); + + return $userCan; + } + + private function getImgSizes() + { + + $sizes = []; + + foreach (Brizy_Editor::get_all_image_sizes() as $name => $size) { + if (isset($size['crop'])) { + unset($size['crop']); + } + $size['name'] = $name; + $sizes[] = $size; + } + + return $sizes; + } } diff --git a/editor/editor/module-groups/essential-provider.php b/editor/editor/module-groups/essential-provider.php index 7605089c1c..9a58cd287c 100644 --- a/editor/editor/module-groups/essential-provider.php +++ b/editor/editor/module-groups/essential-provider.php @@ -21,7 +21,8 @@ public function collect( $context ) { "Line", "MenuSimple", "Menu", - "Search" + "Search", + "Filters" ], 300 ), ]; } diff --git a/editor/entity.php b/editor/entity.php index 3ab01fe3a4..726ddfe320 100644 --- a/editor/entity.php +++ b/editor/entity.php @@ -1,85 +1,80 @@ setWpPostId($postId); + $this->setWpPostId( $postId ); - $this->loadInstanceData(); - } + $this->loadInstanceData(); + } /** * @return bool */ public function can_edit_posts() - { - return current_user_can('edit_posts'); - } + {return current_user_can( 'edit_posts' ); + } /** - * @return bool - */ - static public function canEditPosts() - { - return current_user_can('edit_posts'); - } + * @return bool + */ + static public function canEditPosts() { + return current_user_can( 'edit_posts' ); + } - static public function get($postId, $uid = null) - { - $type = get_post_type($postId); + static public function get( $postId, $uid = null ) { + $type = get_post_type( $postId ); - switch ($type) { + switch ( $type ) { - case Brizy_Admin_Blocks_Main::CP_GLOBAL: - case Brizy_Admin_Blocks_Main::CP_SAVED: - return Brizy_Editor_Block::get($postId, $uid); + case Brizy_Admin_Blocks_Main::CP_GLOBAL: + case Brizy_Admin_Blocks_Main::CP_SAVED: + return Brizy_Editor_Block::get( $postId, $uid ); - default: - case 'page': - case 'post': - case Brizy_Admin_Popups_Main::CP_POPUP: - return Brizy_Editor_Post::get($postId, $uid); - } - } + default: + case 'page': + case 'post': + case Brizy_Admin_Popups_Main::CP_POPUP: + return Brizy_Editor_Post::get( $postId, $uid ); + } + } /** @@ -87,20 +82,20 @@ static public function get($postId, $uid = null) */ public function uses_editor() { - return self::isBrizyEnabled($this->getWpPostId()); + return self::isBrizyEnabled( $this->getWpPostId() ); } /** * @return bool */ - static public function isBrizyEnabled($post) + static public function isBrizyEnabled( $post ) { - if ($post instanceof WP_Post) { - $post = $post->ID; - } + if ( $post instanceof WP_Post ) { + $post = $post->ID; + } - return (bool)get_post_meta($post, Brizy_Editor_Constants::BRIZY_ENABLED, true); + return (bool) get_post_meta( $post, Brizy_Editor_Constants::BRIZY_ENABLED, true ); } /** @@ -110,33 +105,32 @@ static public function isBrizyEnabled($post) * @throws Brizy_Editor_Exceptions_AccessDenied */ public function set_uses_editor($value) - { - self::setBrizyEnabled($this->getWpPostId(), $value); + {self::setBrizyEnabled( $this->getWpPostId(), $value ); - return $this; - } + return $this; + } /** * @return bool */ - static public function setBrizyEnabled($post, $value) + static public function setBrizyEnabled( $post, $value ) { if (!self::canEditPosts()) { throw new Brizy_Editor_Exceptions_AccessDenied('Current user cannot edit page'); } - if ($post instanceof WP_Post) { - $post = $post->ID; - } + if ( $post instanceof WP_Post ) { + $post = $post->ID; + } - update_post_meta($post, Brizy_Editor_Constants::BRIZY_ENABLED, (int)$value); + update_post_meta( $post, Brizy_Editor_Constants::BRIZY_ENABLED, (int) $value ); } /** * @return string */ - static public function getEditUrl($post) + static public function getEditUrl( $post ) { if ($post instanceof WP_Post) { @@ -156,250 +150,234 @@ static public function getEditUrl($post) ); } - /** - * @param $postId - * - * @return Brizy_Editor_Block|Brizy_Editor_Post|mixed - * @throws Exception - */ - public function duplicateTo($postId) - { - // check post types - if (get_post_type($postId) !== $this->getWpPost()->post_type) { - throw new Exception('Cannot duplicate post. Invalid target post type'); - } - - if (!$this->uses_editor()) { - throw new Exception('The source post is not using Brizy.'); - } - - // copy current date the the new post - $newPost = self::get($postId); - - if ($newPost->uses_editor()) { - throw new Exception('Target post is using Brizy.'); - } - - $newPost->set_needs_compile(true); - $newPost->set_uses_editor(true); - $newPost->setDataVersion(1); - $newPost->createUid(); - - return $newPost; - } - - - /** - * Will return the key on witch the object data will be saved in storage - * - * @return mixed - */ - abstract protected function getObjectKey(); - - /** - * Load all object data - */ - abstract protected function loadInstanceData(); - - /** - * @return mixed - */ - abstract public function createResponse($fields = array()); - - /** - * Save post data and and trigger post update - * - * @return mixed - */ - abstract public function savePost(); - - /** - * This will save ro create an autosave object the the data from entity - * Also before saving the data version will be checked - * - * @return $this - * @throws Exception - */ - public function save($autosave = 0) - { - - // check entity versions before saving. - if ((int)$autosave === 0) { - $this->saveDataVersion(); - } - - $this->createUid(); - - return $this; - } - - /** - * This will take all values from entity and save them to database - */ - public function saveStorage() - { - $value = $this->convertToOptionValue(); - $this->getStorage()->set($this->getObjectKey(), $value); - } - - - /** - * @return Brizy_Editor_Post[] - * @throws Brizy_Editor_Exceptions_NotFound - * @throws Brizy_Editor_Exceptions_UnsupportedPostType - */ - public static function get_all_brizy_post_ids() - { - global $wpdb; - $posts = $wpdb->get_results( - $wpdb->prepare( - "SELECT p.ID FROM {$wpdb->postmeta} pm + /** + * @param $postId + * + * @return Brizy_Editor_Block|Brizy_Editor_Post|mixed + * @throws Exception + */ + public function duplicateTo( $postId ) { + // check post types + if ( get_post_type( $postId ) !== $this->getWpPost()->post_type ) { + throw new Exception( 'Cannot duplicate post. Invalid target post type' ); + } + + if (!$this->uses_editor() ) { + throw new Exception( 'The source post is not using Brizy.' ); + } + + // copy current date the the new post + $newPost = self::get( $postId ); + + if ( $newPost->uses_editor() ) { + throw new Exception( 'Target post is using Brizy.' ); + } + + $newPost->set_needs_compile( true ); + $newPost->set_uses_editor( true ); + $newPost->setDataVersion( 1 ); + $newPost->createUid(); + + return $newPost; + } + + + /** + * Will return the key on witch the object data will be saved in storage + * + * @return mixed + */ + abstract protected function getObjectKey(); + + /** + * Load all object data + */ + abstract protected function loadInstanceData(); + + /** + * @return mixed + */ + abstract public function createResponse( $fields = array() ); + + /** + * Save post data and and trigger post update + * + * @return mixed + */ + abstract public function savePost(); + + /** + * This will save ro create an autosave object the the data from entity + * Also before saving the data version will be checked + * + * @return $this + * @throws Exception + */ + public function save( $autosave = 0 ) { + + // check entity versions before saving. + if ( (int) $autosave === 0 ) { + $this->saveDataVersion(); + } + + $this->createUid(); + + return $this; + } + + /** + * This will take all values from entity and save them to database + */ + public function saveStorage() { + $value = $this->convertToOptionValue(); + $this->getStorage()->set( $this->getObjectKey(), $value ); + } + + + /** + * @return Brizy_Editor_Post[] + * @throws Brizy_Editor_Exceptions_NotFound + * @throws Brizy_Editor_Exceptions_UnsupportedPostType + */ + public static function get_all_brizy_post_ids() { + global $wpdb; + $posts = $wpdb->get_results( + $wpdb->prepare( + "SELECT p.ID FROM {$wpdb->postmeta} pm JOIN {$wpdb->posts} p ON p.ID=pm.post_id and p.post_type <> 'revision' and p.post_type<>'attachment' and p.post_status='publish' WHERE pm.meta_key = %s ", - Brizy_Editor_Storage_Post::META_KEY - ), ARRAY_A - ); - - return array_column($posts, 'ID'); - } - - /** - * @return int - */ - public function getWpPostId() - { - return $this->wp_post_id; - } - - /** - * @param int $wp_post_id - * - * @return Brizy_Editor_Entity - */ - public function setWpPostId($wp_post_id) - { - $this->wp_post_id = $wp_post_id; - - return $this; - } - - /** - * Return the post parent id - * - * @return int - */ - public function getWpPostParentId() - { - return $this->getWpPost()->post_parent ?: $this->getWpPostId(); - } - - /** - * @return WP_Post - */ - public function getWpPost() - { - return $this->wp_post ?: ($this->wp_post = get_post($this->getWpPostId())); - } - - /** - * @return $this - */ - protected function saveDataVersion() - { - $version = $this->getCurrentDataVersion(); - - if ($this->dataVersion !== $version + 1) { - Brizy_Logger::instance()->critical( - 'Unable to save entity. The data version is wrong.', - [ - 'post_id' => $this->getWpPostId(), - 'currentVersion' => $version, - 'newVersion' => $this->dataVersion, - ] - ); - throw new Brizy_Editor_Exceptions_DataVersionMismatch('Unable to save entity. The data version is wrong.'); - } - - update_post_meta($this->getWpPostId(), self::BRIZY_DATA_VERSION_KEY, $this->dataVersion); - - return $this; - } - - /** - * @return int - */ - public function getCurrentDataVersion() - { - return (int)(get_post_meta($this->getWpPostId(), self::BRIZY_DATA_VERSION_KEY, true) ?: 0); - } - - - /** - * @param $dataVersion - * - * @return $this - */ - public function setDataVersion($dataVersion) - { - $this->dataVersion = (int)$dataVersion; - - return $this; - } - - /** - * @return string - */ - public function getUid() - { - return $this->uid; - } - - public function getTitle() - { - return $this->getWpPost()->post_title; - } - - public function setTitle($title) - { - $this->getWpPost()->post_title = $title; - - return $this; - } - - /** - * Return an instance of Brizy_Editor_Storage_Abstract that will store the object data - * - * @return Brizy_Editor_Storage_Post - */ - protected function getStorage() - { - return Brizy_Editor_Storage_Post::instance($this->wp_post_id); - } - - /** - * @return mixed|string - */ - protected function createUid() - { - $WPPost = $this->getWpPost(); - $post_id = $WPPost->post_type != 'revision' ? $this->getWpPostId() : $WPPost->post_parent; - - if ($uid = $this->getUid()) { - $uid = get_post_meta($post_id, 'brizy_post_uid', true); - if (!$uid) { - update_post_meta($post_id, 'brizy_post_uid', $this->getUid()); - } - - return $uid; - } - - $uid = get_post_meta($post_id, 'brizy_post_uid', true); - - if (!$uid) { - $uid = md5($post_id . time()); - update_post_meta($post_id, 'brizy_post_uid', $uid); - } - - return $this->uid = $uid; - } + Brizy_Editor_Storage_Post::META_KEY + ), ARRAY_A + ); + + return array_column( $posts, 'ID' ); + } + + /** + * @return int + */ + public function getWpPostId() { + return $this->wp_post_id; + } + + /** + * @param int $wp_post_id + * + * @return Brizy_Editor_Entity + */ + public function setWpPostId( $wp_post_id ) { + $this->wp_post_id = $wp_post_id; + + return $this; + } + + /** + * Return the post parent id + * + * @return int + */ + public function getWpPostParentId() { + return $this->getWpPost()->post_parent ?: $this->getWpPostId(); + } + + /** + * @return WP_Post + */ + public function getWpPost() { + return $this->wp_post ?: ( $this->wp_post = get_post( $this->getWpPostId() ) ); + } + + /** + * @return $this + */ + protected function saveDataVersion() { + $version = $this->getCurrentDataVersion(); + + if ( $this->dataVersion !== $version + 1 ) { + Brizy_Logger::instance()->critical( + 'Unable to save entity. The data version is wrong.', + [ + 'post_id' => $this->getWpPostId(), + 'currentVersion' => $version, + 'newVersion' => $this->dataVersion, + ] + ); + throw new Brizy_Editor_Exceptions_DataVersionMismatch( 'Unable to save entity. The data version is wrong.' ); + } + + update_post_meta( $this->getWpPostId(), self::BRIZY_DATA_VERSION_KEY, $this->dataVersion ); + + return $this; + } + + /** + * @return int + */ + public function getCurrentDataVersion() { + return (int) ( get_post_meta( $this->getWpPostId(), self::BRIZY_DATA_VERSION_KEY, true ) ?: 0 ); + } + + + /** + * @param $dataVersion + * + * @return $this + */ + public function setDataVersion( $dataVersion ) { + $this->dataVersion = (int) $dataVersion; + + return $this; + } + + /** + * @return string + */ + public function getUid() { + return $this->uid; + } + + public function getTitle() { + return html_entity_decode($this->getWpPost()->post_title); + } + + public function setTitle( $title ) { + $this->getWpPost()->post_title = $title; + + return $this; + } + + /** + * Return an instance of Brizy_Editor_Storage_Abstract that will store the object data + * + * @return Brizy_Editor_Storage_Post + */ + protected function getStorage() { + return Brizy_Editor_Storage_Post::instance( $this->wp_post_id ); + } + + /** + * @return mixed|string + */ + protected function createUid() { + $WPPost = $this->getWpPost(); + $post_id = $WPPost->post_type != 'revision' ? $this->getWpPostId() : $WPPost->post_parent; + + if ( $uid = $this->getUid() ) { + $uid = get_post_meta( $post_id, 'brizy_post_uid', true ); + if (!$uid ) { + update_post_meta( $post_id, 'brizy_post_uid', $this->getUid() ); + } + + return $uid; + } + + $uid = get_post_meta( $post_id, 'brizy_post_uid', true ); + + if (!$uid ) { + $uid = md5( $post_id . time() ); + update_post_meta( $post_id, 'brizy_post_uid', $uid ); + } + + return $this->uid = $uid; + } } diff --git a/editor/filters/api.php b/editor/filters/api.php new file mode 100644 index 0000000000..004be87e04 --- /dev/null +++ b/editor/filters/api.php @@ -0,0 +1,87 @@ +addNoPrivAjaxAction(self::AJAX_FILTER_PLACEHOLDERS_CONTENT, array($this, 'filterPlaceholdersContent')); + $this->addAjaxAction(self::AJAX_FILTER_PLACEHOLDERS_CONTENT, array($this, 'filterPlaceholdersContent')); + } + + protected function getRequestNonce() + { + return $this->param('hash'); + } + + public function filterPlaceholdersContent() + { + + if (empty($postId = $this->param('post_id'))) { + $this->error(400, 'Please provide the post id'); + } + + if (empty($placeholders = $this->param('placeholders'))) { + $this->error(400, 'Please provide the placeholders param'); + } + + $placeholderContents = []; + $brizyPost = Brizy_Editor_Post::get($postId); + $postContent = $this->getBrizyPostContent(Brizy_Editor_Project::get(), $brizyPost); + + $placeholderProvider = new Brizy_Content_PlaceholderProvider(); + $context = new Brizy_Content_Context(Brizy_Editor_Project::get(), $brizyPost, $brizyPost->getWpPost(), ''); + $context->setProvider($placeholderProvider); + $extractor = new \BrizyPlaceholders\Extractor($placeholderProvider); + + /** + * @var \BrizyPlaceholders\ContentPlaceholder[] $contentPlaceholders ; + */ + list($contentPlaceholders, $placeholderInstances, $newPostContent) = $extractor->extract($postContent); + $context->setPlaceholders($contentPlaceholders); + + foreach ($placeholders as $placeholderId) { + try { + /** + * @var \BrizyPlaceholders\ContentPlaceholder $placeholder ; + */ + $placeholder = $context->getPlaceholderById($placeholderId); + + if (!$placeholder) { + $placeholderContents[$placeholderId] = ''; + continue; + } + + /** + * @var Brizy_Content_Placeholders_Abstract $placeholderInstance ; + */ + $placeholderInstance = $placeholderProvider->getPlaceholderSupportingName($placeholder->getName()); + $placeholderContents[$placeholderId] = $placeholderInstance->getValue($context, $placeholder); + } catch (\Exception $e) { + $placeholderContents[$placeholderId] = null; + } + } + + + $this->success(['placeholders' => $placeholderContents]); + } + + private function getBrizyPostContent(Brizy_Editor_Project $project, Brizy_Editor_Post $post) + { + $project = Brizy_Editor_Project::get(); + + if (!$post->get_compiled_html()) { + $compiled_html_body = $post->get_compiled_html_body(); + $content = Brizy_SiteUrlReplacer::restoreSiteUrl($compiled_html_body); + $post->set_needs_compile(true)->saveStorage(); + } else { + $compiled_page = $post->get_compiled_page(); + $content = $compiled_page->get_body(); + } + + return $content; + } +} diff --git a/editor/popup.php b/editor/popup.php index a4c8af387d..c49ea1aaa9 100644 --- a/editor/popup.php +++ b/editor/popup.php @@ -1,4 +1,4 @@ -tags; + return html_entity_decode($this->tags); } /** diff --git a/editor/post.php b/editor/post.php index d633d61d97..1efaaa3e7f 100755 --- a/editor/post.php +++ b/editor/post.php @@ -1,10 +1,11 @@ -uid = $uid; - } - - parent::__construct( $postId ); - - // create the uid if the editor is enabled for this post - if ( $this->uses_editor() ) { - $this->createUid(); - } - } - - /** - * @param $apost - * - * @return Brizy_Editor_Post|mixed - * @throws Exception - */ - public static function get( $apost, $uid = null ) { - - $wp_post_id = $apost; - if ( $apost instanceof WP_Post ) { - $wp_post_id = $apost->ID; - } - - if ( isset( self::$instance[ $wp_post_id ] ) ) { - return self::$instance[ $wp_post_id ]; - } - - return self::$instance[ $wp_post_id ] = new self( $wp_post_id, $uid ); - } - - /** - * @param $postId - * - * @return Brizy_Editor_Block|Brizy_Editor_Post|mixed - * @throws Exception - */ - public function duplicateTo( $postId ) { - $newPost = parent::duplicateTo( $postId ); - - // copy current data to new post - $newPost->set_template( $this->get_template() ); - - $storage = $this->getStorage(); - - $newStorage = $newPost->getStorage(); - $newStorage->loadStorage( $storage->get_storage() ); - $newPost->loadInstanceData(); - $newPost->saveStorage(); - - return $newPost; - - } - - - /** - * Clear all cached instances; - */ - public static function cleanClassCache() { - self::$instance = array(); - } - - /** - * @return string - */ - public function serialize() { - $get_object_vars = get_object_vars( $this ); - - unset( $get_object_vars['wp_post_id'] ); - unset( $get_object_vars['wp_post'] ); - unset( $get_object_vars['api_page'] ); - unset( $get_object_vars['store_assets'] ); - unset( $get_object_vars['assets'] ); - - return serialize( $get_object_vars ); - } - - - /** - * @param $data - */ - public function unserialize( $data ) { - parent::unserialize( $data ); // TODO: Change the autogenerated stub - } - - public function createResponse( $fields = array() ) { - - $p_id = (int) $this->getWpPostId(); - - $global = array( - 'title' => $the_title = $this->getTitle(), - 'slug' => sanitize_title( $the_title ), - 'data' => $this->get_editor_data(), - 'id' => $p_id, - 'is_index' => false, - 'template' => get_page_template_slug( $p_id ), - 'status' => get_post_status( $p_id ), - 'url' => get_the_permalink( $p_id ), - 'dataVersion' => $this->getCurrentDataVersion(), - 'author' => $this->getWpPost()->post_author - ); - - return $global; - } - - public function createConfigData() { - - $p_id = (int) $this->getWpPostId(); - - $json_decode = json_decode( $this->get_editor_data() ); - $data = array( - '_kind' => "wp", - 'id' => $p_id, - 'data' => $json_decode?:"", - 'dataVersion' => $this->getCurrentDataVersion(), - 'title' => $the_title = $this->getTitle(), - 'slug' => sanitize_title( $the_title ), - 'status' => get_post_status( $p_id ), - 'is_index' => false, - 'template' => get_page_template_slug( $p_id ), - 'url' => esc_url( apply_filters( 'the_permalink', get_permalink( $p_id ), $this->getWpPost() ) ) - ); - - return $data; - } - - - public function convertToOptionValue() { - - return array( - 'compiled_html' => $this->get_encoded_compiled_html(), - 'compiled_scripts' => $this->getCompiledScripts(), - 'compiled_styles' => $this->getCompiledStyles(), - 'compiled_html_body' => $this->get_compiled_html_body(), - 'compiled_html_head' => $this->get_compiled_html_head(), - 'editor_version' => $this->editor_version, - 'compiler_version' => $this->compiler_version, - 'plugin_version' => $this->plugin_version, - 'pro_plugin_version' => $this->pro_plugin_version, - 'editor_data' => $this->editor_data, - Brizy_Editor_Constants::USES_BRIZY => $this->uses_editor(), - 'lastUserEdited' => $this->lastUserEdited - ); - } - - - /** - * Mark all brizy post that needs compile - */ - public static function mark_all_for_compilation() { - global $wpdb; - $wpdb->update( $wpdb->postmeta, array( 'meta_value' => 1 ), array( 'meta_key' => self::BRIZY_POST_NEEDS_COMPILE_KEY ) ); - } - - - public function savePost( $createRevision = false ) { - - $postarr = [ - 'ID' => $this->getWpPostId(), - 'post_title' => $this->getTitle(), - 'post_content' => $this->getPostContent( $createRevision ) - ]; - - $this->deleteOldAutosaves( $this->getWpPostId() ); - - if ( $createRevision ) { - - $post_type_object = get_post_type_object( $this->getWpPost()->post_type ); - - if ( current_user_can( $post_type_object->cap->publish_posts ) ) { - $postarr['post_status'] = $this->getWpPost()->post_status; - } - - } else { - remove_action( 'post_updated', 'wp_save_post_revision' ); - } - - wp_update_post( $postarr ); - - $this->createUid(); - } - - private function getPostContent( $noFilters ) { - - $post = $this->getWpPost(); - $emptyContent = '
'; - $versionTime = ''; - - $excluded = [ - Brizy_Admin_Blocks_Main::CP_GLOBAL, - Brizy_Admin_Blocks_Main::CP_SAVED, - Brizy_Admin_Templates::CP_TEMPLATE, - Brizy_Admin_Popups_Main::CP_POPUP - ]; - - if ( in_array( $post->post_type, $excluded ) ) { - return $emptyContent . $versionTime; - } - - if ( $noFilters ) { - $content = $post->post_content; - } else { - $context = Brizy_Content_ContextFactory::createContext( Brizy_Editor_Project::get(), null, $post, null ); - $placeholderProvider = new Brizy_Content_PlaceholderWpProvider( $context ); - $context->setProvider( $placeholderProvider ); - $extractor = new \BrizyPlaceholders\Extractor( $placeholderProvider ); - - list( $placeholders, $placeholderInstances, $content ) = $extractor->extract( $this->get_compiled_page()->getPageContent() ); - - $replacer = new \BrizyPlaceholders\Replacer( $placeholderProvider ); - $content = $replacer->replaceWithExtractedData( $placeholders, $placeholderInstances, $content, $context ); - - $content = $extractor->stripPlaceholders( $content ); - $content = apply_filters( 'brizy_content', $content, Brizy_Editor_Project::get(), $post ); - } - - $content = strpos( $content, 'brz-root__container' ) ? preg_replace( '//', '', $content ) : $emptyContent; - - return $content . $versionTime; - } - - /** - * @param int $autosave - * - * @return bool|Brizy_Editor_Entity - */ - public function save( $autosave = 0 ) { - - parent::save( $autosave ); - - if ( $autosave == 0 ) { - $this->saveStorage(); - } else { - $this->auto_save_post( $this->getWpPost(), function ( $autosaveObject ) { - $autosavePost = $this->populateAutoSavedData( $autosaveObject ); - $autosavePost->saveStorage(); - } ); - } - - return true; - } - - /** - * @return bool - * @throws Brizy_Editor_Exceptions_ServiceUnavailable - * @throws Exception - */ - public function compile_page() { - - Brizy_Logger::instance()->notice( 'Compile page', array( $this ) ); - $compiledData = Brizy_Editor_User::get()->compile_page( Brizy_Editor_Project::get(), $this ); - $compiledData['pageHtml'] = Brizy_SiteUrlReplacer::hideSiteUrl( $compiledData['pageHtml'] ); - - $this->set_compiled_html( $compiledData['pageHtml'] ); - $this->set_compiled_html_head( null ); - $this->set_compiled_html_body( null ); - $this->set_needs_compile( false ); - $this->set_compiler_version( BRIZY_EDITOR_VERSION ); - $this->set_plugin_version( BRIZY_VERSION ); - $this->set_pro_plugin_version( defined( 'BRIZY_PRO_VERSION' ) ? BRIZY_PRO_VERSION : null ); - $this->setCompiledScripts( $compiledData['pageScripts'] ); - $this->setCompiledStyles( $compiledData['pageStyles'] ); - - return true; - } - - - /** - * @return string - */ - public function get_compiled_html() { - return $this->compiled_html; - } - - /** - * @param string $compiled_html - * - * @return Brizy_Editor_Post - */ - public function set_compiled_html( $compiled_html ) { - $this->compiled_html = $compiled_html; - - return $this; - } - - /** - * @return array - */ - public function getCompiledScripts() { - return $this->compiled_scripts; - } - - /** - * @param array $compiled_scripts - * - * @return Brizy_Editor_Post - */ - public function setCompiledScripts( $compiled_scripts ) { - $this->compiled_scripts = $compiled_scripts; - - return $this; - } - - /** - * @return array - */ - public function getCompiledStyles() { - return $this->compiled_styles; - } - - /** - * @param array $compiled_styles - * - * @return Brizy_Editor_Post - */ - public function setCompiledStyles( $compiled_styles ) { - $this->compiled_styles = $compiled_styles; - - return $this; - } - - - /** - * @param $compiled_html - * - * @return $this - */ - public function set_encoded_compiled_html( $compiled_html ) { - - if ( ( $decodedData = base64_decode( $compiled_html, true ) ) !== false ) { - $this->set_compiled_html( $decodedData ); - } else { - $this->set_compiled_html( $compiled_html ); - } - - return $this; - } - - /** - * @return string - */ - public function get_encoded_compiled_html() { - - return base64_encode( $this->get_compiled_html() ); - } - - /** - * @return string - * @deprecated use get_compiled_html - */ - public function get_compiled_html_body() { - return $this->compiled_html_body; - } - - /** - * @return string - * @deprecated use get_compiled_html - */ - public function get_compiled_html_head() { - return $this->compiled_html_head; - } - - /** - * @param $html - * - * @return $this - * @deprecated use set_compiled_html - * - */ - public function set_compiled_html_body( $html ) { - $this->compiled_html_body = $html; - - return $this; - } - - /** - * @param $html - * - * @return $this - * @deprecated use set_compiled_html - * - */ - public function set_compiled_html_head( $html ) { - // remove all title and meta tags. - $this->compiled_html_head = $html; - - return $this; - } - - /** - * @return string - */ - public function get_editor_data() { - - if ( ( $decodedData = base64_decode( $this->editor_data, true ) ) !== false ) { - return $decodedData; - } - - return $this->editor_data; - } - - /** - * @param $content - * - * @return $this - */ - public function set_editor_data( $content ) { - - if ( is_null( $content ) ) { - $content = ''; - } - - if ( base64_decode( $content, true ) !== false ) { - $this->editor_data = $content; - } else { - $this->editor_data = base64_encode( $content ); - } - - return $this; - } - - /** - * @return $this - * @throws Brizy_Editor_Exceptions_AccessDenied - */ - public function enable_editor() { - - if ( ! $this->can_edit_posts() ) { - throw new Brizy_Editor_Exceptions_AccessDenied( 'Current user cannot edit page' ); - } - - $this->set_uses_editor( true ); - - return $this; - } - - /** - * @return $this - * @throws Brizy_Editor_Exceptions_AccessDenied - */ - public function disable_editor() { - if ( ! $this->can_edit_posts() ) { - throw new Brizy_Editor_Exceptions_AccessDenied( 'Current user cannot edit page' ); - } - - $this->set_uses_editor( false ); - - return $this; - } - - /** - * @param string $editor_version - */ - public function set_editor_version( $editor_version ) { - $this->editor_version = $editor_version; - update_metadata( 'post', $this->getWpPostId(), self::BRIZY_POST_EDITOR_VERSION, $editor_version ); - } - - /** - * @param string $compiler_version - */ - public function set_compiler_version( $compiler_version ) { - $this->compiler_version = $compiler_version; - update_metadata( 'post', $this->getWpPostId(), self::BRIZY_POST_COMPILER_VERSION, $compiler_version ); - } - - /** - * @param string $plugin_version - */ - public function set_plugin_version( $plugin_version ) { - $this->plugin_version = $plugin_version; - update_metadata( 'post', $this->getWpPostId(), self::BRIZY_POST_PLUGIN_VERSION, $plugin_version ); - } - - - /** - * @param $v - * - * @return $this - */ - public function set_needs_compile( $v ) { - $this->needs_compile = (bool) $v; - update_metadata( 'post', $this->getWpPostId(), self::BRIZY_POST_NEEDS_COMPILE_KEY, (bool) $v ); - - return $this; - } - - /** - * @return bool - */ - public function get_needs_compile() { - return $this->needs_compile; - } - - /** - * @return Brizy_Editor_CompiledHtml - */ - public function get_compiled_page() { - - if ( isset( self::$compiled_page[ $this->getWpPostId() ] ) ) { - return self::$compiled_page[ $this->getWpPostId() ]; - } - - return self::$compiled_page[ $this->getWpPostId() ] = new Brizy_Editor_CompiledHtml( $this->get_compiled_html() ); - } - - public function isCompiledWithCurrentVersion() { - $proVersion = defined( 'BRIZY_PRO_VERSION' ) ? BRIZY_PRO_VERSION : null; - - return $this->get_compiler_version() === BRIZY_EDITOR_VERSION && $this->get_pro_plugin_version() === $proVersion && $this->plugin_version === BRIZY_VERSION; - } - - /** - * @return array - */ - public function get_templates() { - - $type = get_post_type( $this->getWpPostId() ); - $templates = array( - array( - 'id' => '', - 'title' => __( 'Default', 'brizy' ) - ) - ); - - foreach ( wp_get_theme()->get_page_templates( null, $type ) as $key => $title ) { - $templates[] = [ - 'id' => $key, - 'title' => $title - ]; - } - - return apply_filters( "brizy:$type:templates", $templates ); - } - - /** - * @param string $aTemplate - * - * @return $this - */ - public function set_template( $aTemplate ) { - - $aTemplate = apply_filters( 'brizy_post_template', $aTemplate ); - - if ( $aTemplate == '' ) { - delete_post_meta( $this->getWpPostId(), '_wp_page_template' ); - } else { - update_post_meta( $this->getWpPostId(), '_wp_page_template', $aTemplate ); - } - - return $this; - } - - /** - * @return mixed - */ - public function get_template() { - return get_post_meta( $this->getWpPostId(), '_wp_page_template', true ); - } - - - /** - * @return string - */ - public function get_compiler_version() { - return $this->compiler_version; - } - - /** - * @return string - */ - public function get_pro_plugin_version() { - return $this->pro_plugin_version; - } - - /** - * @param string $pro_plugin_version - * - * @return Brizy_Editor_Post - */ - public function set_pro_plugin_version( $pro_plugin_version ) { - $this->pro_plugin_version = $pro_plugin_version; - - return $this; - } - - /** - * @return string - */ - public function get_editor_version() { - return $this->editor_version; - } - - /** - * @return string - * @deprecated Use getEditUrl() - */ - public function edit_url() { - return self::getEditUrl( $this->getWpPostId() ); - } - - /** - * Will return the key on witch the object data will be saved in storage - * - * @return mixed - */ - protected function getObjectKey() { - return self::BRIZY_POST; - } - - /** - * Load all object data - */ - protected function loadInstanceData() { - // get the storage values - $storage = $this->getStorage(); - //$storageData = $storage->get_storage(); - $storage_post = $storage->get( $this->getObjectKey(), false ); - - $this->setTitle( get_the_title( $this->getWpPostId() ) ); + static protected $instance = null; + static protected $compiled_page = []; + + /** + * @var string + */ + protected $compiled_html; + + /** + * @var array + */ + protected $compiled_scripts; + + /** + * @var array + */ + protected $compiled_styles; + + /** + * @var string + */ + protected $compiled_html_body; + + /** + * @var string + */ + protected $compiled_html_head; + + /** + * @var bool + */ + protected $needs_compile; + + /** + * Json for the editor. + * + * @var string + */ + protected $editor_data; + + /** + * @var bool + */ + protected $uses_editor; + + /** + * @var string + */ + protected $editor_version; + + /** + * @var string + */ + protected $compiler_version; + + /** + * @var string + */ + protected $pro_plugin_version; + + /** + * @var string + */ + protected $plugin_version; + + /** + * @var int + */ + protected $lastUserEdited; + + /** + * Brizy_Editor_Post2 constructor. + * + * @param $postId + * + * @throws Exception + */ + public function __construct($postId, $uid = null) + { + + if ($uid) { + $this->uid = $uid; + } + + parent::__construct($postId); + + // create the uid if the editor is enabled for this post + if ($this->uses_editor()) { + $this->createUid(); + } + } + + /** + * @param $apost + * + * @return Brizy_Editor_Post|mixed + * @throws Exception + */ + public static function get($apost, $uid = null) + { + + $wp_post_id = $apost; + if ($apost instanceof WP_Post) { + $wp_post_id = $apost->ID; + } + + if (isset(self::$instance[$wp_post_id])) { + return self::$instance[$wp_post_id]; + } + + return self::$instance[$wp_post_id] = new self($wp_post_id, $uid); + } + + /** + * @param $postId + * + * @return Brizy_Editor_Block|Brizy_Editor_Post|mixed + * @throws Exception + */ + public function duplicateTo($postId) + { + $newPost = parent::duplicateTo($postId); + + // copy current data to new post + $newPost->set_template($this->get_template()); + + $storage = $this->getStorage(); + + $newStorage = $newPost->getStorage(); + $newStorage->loadStorage($storage->get_storage()); + $newPost->loadInstanceData(); + $newPost->saveStorage(); + + return $newPost; + + } + + + /** + * Clear all cached instances; + */ + public static function cleanClassCache() + { + self::$instance = array(); + } + + /** + * @return string + */ + public function serialize() + { + $get_object_vars = get_object_vars($this); + + unset($get_object_vars['wp_post_id']); + unset($get_object_vars['wp_post']); + unset($get_object_vars['api_page']); + unset($get_object_vars['store_assets']); + unset($get_object_vars['assets']); + + return serialize($get_object_vars); + } + + + /** + * @param $data + */ + public function unserialize($data) + { + parent::unserialize($data); // TODO: Change the autogenerated stub + } + + public function createResponse($fields = array()) + { + + $p_id = (int)$this->getWpPostId(); + + $global = array( + 'title' => $the_title = $this->getTitle(), + 'slug' => sanitize_title($the_title), + 'data' => $this->get_editor_data(), + 'id' => $p_id, + 'is_index' => false, + 'template' => get_page_template_slug($p_id), + 'status' => get_post_status($p_id), + 'url' => get_the_permalink($p_id), + 'dataVersion' => $this->getCurrentDataVersion(), + 'author' => $this->getWpPost()->post_author + ); + + return $global; + } + + public function createConfigData() + { + + $p_id = (int)$this->getWpPostId(); + + $json_decode = json_decode($this->get_editor_data()); + $data = array( + '_kind' => "wp", + 'id' => $p_id, + 'data' => $json_decode ?: "", + 'dataVersion' => $this->getCurrentDataVersion(), + 'title' => $the_title = $this->getTitle(), + 'slug' => sanitize_title($the_title), + 'status' => get_post_status($p_id), + 'is_index' => false, + 'template' => get_page_template_slug($p_id), + 'url' => esc_url(apply_filters('the_permalink', get_permalink($p_id), $this->getWpPost())) + ); + + return $data; + } + + + public function convertToOptionValue() + { + + return array( + 'compiled_html' => $this->get_encoded_compiled_html(), + 'compiled_scripts' => $this->getCompiledScripts(), + 'compiled_styles' => $this->getCompiledStyles(), + 'compiled_html_body' => $this->get_compiled_html_body(), + 'compiled_html_head' => $this->get_compiled_html_head(), + 'editor_version' => $this->editor_version, + 'compiler_version' => $this->compiler_version, + 'plugin_version' => $this->plugin_version, + 'pro_plugin_version' => $this->pro_plugin_version, + 'editor_data' => $this->editor_data, + Brizy_Editor_Constants::USES_BRIZY => $this->uses_editor(), + 'lastUserEdited' => $this->lastUserEdited + ); + } + + + /** + * Mark all brizy post that needs compile + */ + public static function mark_all_for_compilation() + { + global $wpdb; + $wpdb->update($wpdb->postmeta, array('meta_value' => 1), array('meta_key' => self::BRIZY_POST_NEEDS_COMPILE_KEY)); + } + + + public function savePost($createRevision = false) + { + + $postarr = [ + 'ID' => $this->getWpPostId(), + 'post_title' => $this->getTitle(), + 'post_content' => $this->getPostContent($createRevision) + ]; + + $this->deleteOldAutosaves($this->getWpPostId()); + + if ($createRevision) { + + $post_type_object = get_post_type_object($this->getWpPost()->post_type); + + if (current_user_can($post_type_object->cap->publish_posts)) { + $postarr['post_status'] = $this->getWpPost()->post_status; + } + + } else { + remove_action('post_updated', 'wp_save_post_revision'); + } + + wp_update_post($postarr); + + $this->createUid(); + } + + private function getPostContent($noFilters) + { + + $post = $this->getWpPost(); + $emptyContent = '
'; + $versionTime = ''; + + $excluded = [ + Brizy_Admin_Blocks_Main::CP_GLOBAL, + Brizy_Admin_Blocks_Main::CP_SAVED, + Brizy_Admin_Templates::CP_TEMPLATE, + Brizy_Admin_Popups_Main::CP_POPUP + ]; + + if (in_array($post->post_type, $excluded)) { + return $emptyContent . $versionTime; + } + + if ($noFilters) { + $content = $post->post_content; + } else { + $context = Brizy_Content_ContextFactory::createContext(Brizy_Editor_Project::get()); + $placeholderProvider = new Brizy_Content_PlaceholderWpProvider($context); + $context->setProvider($placeholderProvider); + $extractor = new \BrizyPlaceholders\Extractor($placeholderProvider); + + list($placeholders, $placeholderInstances, $content) = $extractor->extract($this->get_compiled_page()->getPageContent()); + + $context->setPlaceholders($placeholders); + + $replacer = new \BrizyPlaceholders\Replacer($placeholderProvider); + $content = $replacer->replaceWithExtractedData($placeholders, $placeholderInstances, $content, $context); + + $content = $extractor->stripPlaceholders($content); + $content = apply_filters('brizy_content', $content, Brizy_Editor_Project::get(), $post); + } + + $content = strpos($content, 'brz-root__container') ? preg_replace('//', '', $content) : $emptyContent; + + return $content . $versionTime; + } + + /** + * @param int $autosave + * + * @return bool|Brizy_Editor_Entity + */ + public function save($autosave = 0) + { + + parent::save($autosave); + + if ($autosave == 0) { + $this->saveStorage(); + } else { + $this->auto_save_post($this->getWpPost(), function ($autosaveObject) { + $autosavePost = $this->populateAutoSavedData($autosaveObject); + $autosavePost->saveStorage(); + }); + } + + return true; + } + + /** + * @return bool + * @throws Brizy_Editor_Exceptions_ServiceUnavailable + * @throws Exception + */ + public function compile_page() + { + + Brizy_Logger::instance()->notice('Compile page', array($this)); + $compiledData = Brizy_Editor_User::get()->compile_page(Brizy_Editor_Project::get(), $this); + $compiledData['pageHtml'] = Brizy_SiteUrlReplacer::hideSiteUrl($compiledData['pageHtml']); + + $this->set_compiled_html($compiledData['pageHtml']); + $this->set_compiled_html_head(null); + $this->set_compiled_html_body(null); + $this->set_needs_compile(false); + $this->set_compiler_version(BRIZY_EDITOR_VERSION); + $this->set_plugin_version(BRIZY_VERSION); + $this->set_pro_plugin_version(defined('BRIZY_PRO_VERSION') ? BRIZY_PRO_VERSION : null); + $this->setCompiledScripts($compiledData['pageScripts']); + $this->setCompiledStyles($compiledData['pageStyles']); + + return true; + } + + + /** + * @return string + */ + public function get_compiled_html() + { + return $this->compiled_html; + } + + /** + * @param string $compiled_html + * + * @return Brizy_Editor_Post + */ + public function set_compiled_html($compiled_html) + { + $this->compiled_html = $compiled_html; + + return $this; + } + + /** + * @return array + */ + public function getCompiledScripts() + { + return $this->compiled_scripts; + } + + /** + * @param array $compiled_scripts + * + * @return Brizy_Editor_Post + */ + public function setCompiledScripts($compiled_scripts) + { + $this->compiled_scripts = $compiled_scripts; + + return $this; + } + + /** + * @return array + */ + public function getCompiledStyles() + { + return $this->compiled_styles; + } + + /** + * @param array $compiled_styles + * + * @return Brizy_Editor_Post + */ + public function setCompiledStyles($compiled_styles) + { + $this->compiled_styles = $compiled_styles; + + return $this; + } + + + /** + * @param $compiled_html + * + * @return $this + */ + public function set_encoded_compiled_html($compiled_html) + { + + if (($decodedData = base64_decode($compiled_html, true)) !== false) { + $this->set_compiled_html($decodedData); + } else { + $this->set_compiled_html($compiled_html); + } + + return $this; + } + + /** + * @return string + */ + public function get_encoded_compiled_html() + { + + return base64_encode($this->get_compiled_html()); + } + + /** + * @return string + * @deprecated use get_compiled_html + */ + public function get_compiled_html_body() + { + return $this->compiled_html_body; + } + + /** + * @return string + * @deprecated use get_compiled_html + */ + public function get_compiled_html_head() + { + return $this->compiled_html_head; + } + + /** + * @param $html + * + * @return $this + * @deprecated use set_compiled_html + * + */ + public function set_compiled_html_body($html) + { + $this->compiled_html_body = $html; + + return $this; + } + + /** + * @param $html + * + * @return $this + * @deprecated use set_compiled_html + * + */ + public function set_compiled_html_head($html) + { + // remove all title and meta tags. + $this->compiled_html_head = $html; + + return $this; + } + + /** + * @return string + */ + public function get_editor_data() + { + + if (($decodedData = base64_decode($this->editor_data, true)) !== false) { + return $decodedData; + } + + return $this->editor_data; + } + + /** + * @param $content + * + * @return $this + */ + public function set_editor_data($content) + { + + if (is_null($content)) { + $content = ''; + } + + if (base64_decode($content, true) !== false) { + $this->editor_data = $content; + } else { + $this->editor_data = base64_encode($content); + } + + return $this; + } + + /** + * @return $this + * @throws Brizy_Editor_Exceptions_AccessDenied + */ + public function enable_editor() + { + + if (!$this->can_edit_posts()) { + throw new Brizy_Editor_Exceptions_AccessDenied('Current user cannot edit page'); + } + + $this->set_uses_editor(true); + + return $this; + } + + /** + * @return $this + * @throws Brizy_Editor_Exceptions_AccessDenied + */ + public function disable_editor() + { + if (!$this->can_edit_posts()) { + throw new Brizy_Editor_Exceptions_AccessDenied('Current user cannot edit page'); + } + + $this->set_uses_editor(false); + + return $this; + } + + /** + * @param string $editor_version + */ + public function set_editor_version($editor_version) + { + $this->editor_version = $editor_version; + update_metadata('post', $this->getWpPostId(), self::BRIZY_POST_EDITOR_VERSION, $editor_version); + } + + /** + * @param string $compiler_version + */ + public function set_compiler_version($compiler_version) + { + $this->compiler_version = $compiler_version; + update_metadata('post', $this->getWpPostId(), self::BRIZY_POST_COMPILER_VERSION, $compiler_version); + } + + /** + * @param string $plugin_version + */ + public function set_plugin_version($plugin_version) + { + $this->plugin_version = $plugin_version; + update_metadata('post', $this->getWpPostId(), self::BRIZY_POST_PLUGIN_VERSION, $plugin_version); + } + + + /** + * @param $v + * + * @return $this + */ + public function set_needs_compile($v) + { + $this->needs_compile = (bool)$v; + update_metadata('post', $this->getWpPostId(), self::BRIZY_POST_NEEDS_COMPILE_KEY, (bool)$v); + + return $this; + } + + /** + * @return bool + */ + public function get_needs_compile() + { + return $this->needs_compile; + } + + /** + * @return Brizy_Editor_CompiledHtml + */ + public function get_compiled_page() + { + + if (isset(self::$compiled_page[$this->getWpPostId()])) { + return self::$compiled_page[$this->getWpPostId()]; + } + + return self::$compiled_page[$this->getWpPostId()] = new Brizy_Editor_CompiledHtml($this->get_compiled_html()); + } + + public function isCompiledWithCurrentVersion() + { + $proVersion = defined('BRIZY_PRO_VERSION') ? BRIZY_PRO_VERSION : null; + + return $this->get_compiler_version() === BRIZY_EDITOR_VERSION && $this->get_pro_plugin_version() === $proVersion && $this->plugin_version === BRIZY_VERSION; + } + + /** + * @return array + */ + public function get_templates() + { + + $type = get_post_type($this->getWpPostId()); + $templates = array( + array( + 'id' => '', + 'title' => __('Default', 'brizy') + ) + ); + + foreach (wp_get_theme()->get_page_templates(null, $type) as $key => $title) { + $templates[] = [ + 'id' => $key, + 'title' => $title + ]; + } + + return apply_filters("brizy:$type:templates", $templates); + } + + /** + * @param string $aTemplate + * + * @return $this + */ + public function set_template($aTemplate) + { + + $aTemplate = apply_filters('brizy_post_template', $aTemplate); + + if ($aTemplate == '') { + delete_post_meta($this->getWpPostId(), '_wp_page_template'); + } else { + update_post_meta($this->getWpPostId(), '_wp_page_template', $aTemplate); + } + + return $this; + } + + /** + * @return mixed + */ + public function get_template() + { + return get_post_meta($this->getWpPostId(), '_wp_page_template', true); + } + + + /** + * @return string + */ + public function get_compiler_version() + { + return $this->compiler_version; + } + + /** + * @return string + */ + public function get_pro_plugin_version() + { + return $this->pro_plugin_version; + } + + /** + * @param string $pro_plugin_version + * + * @return Brizy_Editor_Post + */ + public function set_pro_plugin_version($pro_plugin_version) + { + $this->pro_plugin_version = $pro_plugin_version; + + return $this; + } + + /** + * @return string + */ + public function get_editor_version() + { + return $this->editor_version; + } + + /** + * @return string + * @deprecated Use getEditUrl() + */ + public function edit_url() + { + return self::getEditUrl($this->getWpPostId()); + } + + /** + * Will return the key on witch the object data will be saved in storage + * + * @return mixed + */ + protected function getObjectKey() + { + return self::BRIZY_POST; + } + + /** + * Load all object data + */ + protected function loadInstanceData() + { + // get the storage values + $storage = $this->getStorage(); + //$storageData = $storage->get_storage(); + $storage_post = $storage->get($this->getObjectKey(), false); + + $this->setTitle( get_the_title( $this->getWpPostId() ) ); // check for deprecated forms of posts if ( $storage_post instanceof self ) { @@ -723,64 +773,67 @@ protected function loadInstanceData() { $this->save(); } else if ( is_array( $storage_post ) ) { - if ( isset( $storage_post['compiled_html'] ) ) { - $this->set_encoded_compiled_html( $storage_post['compiled_html'] ); - } - if ( isset( $storage_post['compiled_scripts'] ) ) { - $this->setCompiledScripts( $storage_post['compiled_scripts'] ); - } - if ( isset( $storage_post['compiled_styles'] ) ) { - $this->setCompiledStyles( $storage_post['compiled_styles'] ); - } - - $data_needs_compile = isset( $storage_post['needs_compile'] ) ? $storage_post['needs_compile'] : true; - $this->set_editor_data( $storage_post['editor_data'] ); - $this->set_needs_compile( metadata_exists( 'post', $this->getWpPostId(), self::BRIZY_POST_NEEDS_COMPILE_KEY ) ? (bool) get_post_meta( $this->getWpPostId(), self::BRIZY_POST_NEEDS_COMPILE_KEY, true ) : $data_needs_compile ); - $this->set_editor_version( isset( $storage_post['editor_version'] ) ? $storage_post['editor_version'] : BRIZY_EDITOR_VERSION ); - $this->set_compiler_version( isset( $storage_post['compiler_version'] ) ? $storage_post['compiler_version'] : BRIZY_EDITOR_VERSION ); - $this->set_plugin_version( isset( $storage_post['plugin_version'] ) ? $storage_post['plugin_version'] : null ); - $this->set_pro_plugin_version( isset( $storage_post['pro_plugin_version'] ) ? $storage_post['pro_plugin_version'] : null ); - $this->compiled_html_head = isset( $storage_post['compiled_html_head'] ) ? $storage_post['compiled_html_head'] : null; - $this->compiled_html_body = isset( $storage_post['compiled_html_body'] ) ? $storage_post['compiled_html_body'] : null; - $this->lastUserEdited = isset( $storage_post['lastUserEdited'] ) ? $storage_post['lastUserEdited'] : null; - } - } - - /** - * @param self $autosave - * - * @return mixed - */ - protected function populateAutoSavedData( $autosave ) { - $autosave->setTitle( $this->getTitle() ); - $autosave->set_template( $this->get_template() ); - $autosave->set_editor_data( $this->get_editor_data() ); - $autosave->set_editor_version( $this->get_editor_version() ); - $autosave->set_needs_compile( true ); - $autosave->setLastUserEdited( get_current_user_id() ); - - return $autosave; - } - - - public static function get_post_list( $searchTerm, $postType, $excludePostType = array(), $offset = 0, $limit = 20 ) { - - global $wp_post_types, $wpdb; - $searchQuery = ''; - $postLabel = $wp_post_types[ $postType ]->label; - - // not sure iw we will have this case :D - if ( is_array( $excludePostType ) && in_array( $postType, $excludePostType ) ) { - return []; - } - - if ( $searchTerm ) { - $searchQuery = " AND post_title LIKE %s"; - } - - $postStatus = $postType == 'attachment' ? "'inherit'" : "'publish','pending','draft','future','private'"; - - $query = <<set_encoded_compiled_html($storage_post['compiled_html']); + } + if (isset($storage_post['compiled_scripts'])) { + $this->setCompiledScripts($storage_post['compiled_scripts']); + } + if (isset($storage_post['compiled_styles'])) { + $this->setCompiledStyles($storage_post['compiled_styles']); + } + + $data_needs_compile = isset($storage_post['needs_compile']) ? $storage_post['needs_compile'] : true; + $this->set_editor_data($storage_post['editor_data']); + $this->set_needs_compile(metadata_exists('post', $this->getWpPostId(), self::BRIZY_POST_NEEDS_COMPILE_KEY) ? (bool)get_post_meta($this->getWpPostId(), self::BRIZY_POST_NEEDS_COMPILE_KEY, true) : $data_needs_compile); + $this->set_editor_version(isset($storage_post['editor_version']) ? $storage_post['editor_version'] : BRIZY_EDITOR_VERSION); + $this->set_compiler_version(isset($storage_post['compiler_version']) ? $storage_post['compiler_version'] : BRIZY_EDITOR_VERSION); + $this->set_plugin_version(isset($storage_post['plugin_version']) ? $storage_post['plugin_version'] : null); + $this->set_pro_plugin_version(isset($storage_post['pro_plugin_version']) ? $storage_post['pro_plugin_version'] : null); + $this->compiled_html_head = isset($storage_post['compiled_html_head']) ? $storage_post['compiled_html_head'] : null; + $this->compiled_html_body = isset($storage_post['compiled_html_body']) ? $storage_post['compiled_html_body'] : null; + $this->lastUserEdited = isset($storage_post['lastUserEdited']) ? $storage_post['lastUserEdited'] : null; + } + } + + /** + * @param self $autosave + * + * @return mixed + */ + protected function populateAutoSavedData($autosave) + { + $autosave->setTitle($this->getTitle()); + $autosave->setTitle( $this->getTitle() ); + $autosave->set_template($this->get_template()); + $autosave->set_editor_data($this->get_editor_data()); + $autosave->set_editor_version($this->get_editor_version()); + $autosave->set_needs_compile(true); + $autosave->setLastUserEdited(get_current_user_id()); + + return $autosave; + } + + + public static function get_post_list($searchTerm, $postType, $excludePostType = array(), $offset = 0, $limit = 20) + { + + global $wp_post_types, $wpdb; + $searchQuery = ''; + $postLabel = $wp_post_types[$postType]->label; + + // not sure iw we will have this case :D + if (is_array($excludePostType) && in_array($postType, $excludePostType)) { + return []; + } + + if ($searchTerm) { + $searchQuery = " AND post_title LIKE %s"; + } + + $postStatus = $postType == 'attachment' ? "'inherit'" : "'publish','pending','draft','future','private'"; + + $query = <<get_results( $wpdb->prepare( $query, $postType, $postLabel, $postType, $offset, $limit ) ); - - foreach ( $posts as $i => $p ) { - $postTitle = apply_filters( 'the_title', $p->post_title ); - $p->post_title = $postTitle; - $p->title = $postTitle; - $p->uid = self::create_uid( $p->ID, $p->uid ); - $p->ID = (int) $p->ID; - } - - return $posts; - } - - private static function create_uid( $postId, $uid ) { - - if ( ! $uid ) { - $uid = md5( $postId . time() ); - update_post_meta( $postId, 'brizy_post_uid', $uid ); - } - - return $uid; - } - - /** - * @return WP_Post - * @deprecated Use getWpPost(); - * - */ - public function get_wp_post() { - return $this->getWpPost(); - } - - /** - * @return int|null - */ - public function getLastUserEdited() { - return $this->lastUserEdited; - } - - /** - * @param int $userId - */ - public function setLastUserEdited( $userId ) { - $this->lastUserEdited = $userId; - } + $posts = $wpdb->get_results($wpdb->prepare($query, $postType, $postLabel, $postType, $offset, $limit)); + + foreach ($posts as $i => $p) { + $postTitle = apply_filters('the_title', $p->post_title); + $p->post_title = $postTitle; + $p->title = $postTitle; + $p->uid = self::create_uid($p->ID, $p->uid); + $p->ID = (int)$p->ID; + } + + return $posts; + } + + private static function create_uid($postId, $uid) + { + + if (!$uid) { + $uid = md5($postId . time()); + update_post_meta($postId, 'brizy_post_uid', $uid); + } + + return $uid; + } + + /** + * @return WP_Post + * @deprecated Use getWpPost(); + * + */ + public function get_wp_post() + { + return $this->getWpPost(); + } + + /** + * @return int|null + */ + public function getLastUserEdited() + { + return $this->lastUserEdited; + } + + /** + * @param int $userId + */ + public function setLastUserEdited($userId) + { + $this->lastUserEdited = $userId; + } } diff --git a/editor/zip/archiver.php b/editor/zip/archiver.php index 992376bbe3..0ff17fe9ad 100644 --- a/editor/zip/archiver.php +++ b/editor/zip/archiver.php @@ -84,6 +84,7 @@ public function addEntityToZip(ZipArchive $z, Brizy_Editor_Zip_ArchiveItem $item $data = array( 'class' => get_class($block), 'title' => $block->getTitle(), + 'title' => $block->getTitle(), 'meta' => $block->getMeta(), 'media' => $block->getMedia(), 'data' => $block->get_editor_data(), diff --git a/public/crop-proxy.php b/public/crop-proxy.php index 6d1dd786e8..d642bef5f6 100644 --- a/public/crop-proxy.php +++ b/public/crop-proxy.php @@ -30,6 +30,8 @@ public function process_query() { return; } + do_action( 'brizy_before_extract_img' ); + session_write_close(); try { diff --git a/public/editor-client/README.md b/public/editor-client/README.md index 41be80139c..d6b397fde6 100644 --- a/public/editor-client/README.md +++ b/public/editor-client/README.md @@ -49,6 +49,8 @@ export interface __BRZ_PLUGIN_ENV__ { getMediaUid: string; getAttachmentUid: string; setProject: string; + updatePage: string; + updateRules: string; getSavedBlockList: string; getSavedBlockByUid: string; diff --git a/public/editor-client/src/Elements/filters/index.ts b/public/editor-client/src/Elements/filters/index.ts new file mode 100644 index 0000000000..554333b32c --- /dev/null +++ b/public/editor-client/src/Elements/filters/index.ts @@ -0,0 +1,134 @@ +import { getFields } from "../../api"; +import { + Choice, + FilterFieldsData, + Filters, + PossibleValue, + QueryTypeSource +} from "../../types/Filters"; +import { t } from "../../utils/i18n"; + +export const handler: Filters["handler"] = async (res, rej, data) => { + try { + const result = await getFields(data); + + const convertedValue = converter(result); + + res(convertedValue ?? []); + } catch (e) { + rej(t("Failed to load sources")); + } +}; + +export const possibleValues: Filters["possibleValues"] = async ( + res, + rej, + { type, search, optionSource, postId, loopAttributes } +) => { + try { + const result = await getFields({ postId, loopAttributes }); + + const convertPossibleValues = parseFields( + result, + optionSource, + type, + search + ); + + res(convertPossibleValues ?? []); + } catch (e) { + rej(t("Failed to load sources")); + } +}; + +const createQueryTypeSource = ( + query: string, + type: string, + source: string, + filterBy: string +): QueryTypeSource => { + return `${query}|||${type}|||${source}|||${filterBy}` as QueryTypeSource; +}; + +const converter = (data: FilterFieldsData): Choice[] => { + const arr = Object.values(data).reduce((acc: Choice[], cur) => { + const field = cur.map((item) => { + return { + value: createQueryTypeSource( + item.filterQuery + ? item.filterQuery + : item.optionQuery + ? item.optionQuery + : `metaKey=${item.optionSource}`, + item.type, + item.optionSource, + item.filterBy + ), + title: item.label + }; + }); + return [...acc, ...field]; + }, []); + + return arr ?? []; +}; + +const parseFields = ( + data: FilterFieldsData, + optionSource: string, + type: string, + search?: string +): Choice[] => { + const allItem = { value: "all", title: type === "inc" ? "All" : "None" }; + + const selectedItem = Object.values(data).reduce((acc, cur) => { + const field = cur.filter((item) => item.optionQuery === optionSource); + + return [...acc, ...field]; + }, [])[0]; + + if (selectedItem.optionSource === "tax") { + const items: Choice[] = ( + selectedItem.possibleValues as PossibleValue[] + ).map((it: PossibleValue) => ({ + value: it.term_id, + title: it.name + })); + + if (search) { + return [ + allItem, + ...items.filter((it) => + it.title.toLocaleLowerCase().includes(search.toLocaleLowerCase()) + ) + ]; + } + + if (checkNotNullOrUndefinedValues(items)) { + return [allItem, ...items]; + } + } + + if (selectedItem.optionSource === "meta") { + const items = selectedItem.possibleValues as Choice[]; + + if (search) { + return [ + allItem, + ...items.filter((it) => + it.title.toLocaleLowerCase().includes(search.toLocaleLowerCase()) + ) + ]; + } + + if (checkNotNullOrUndefinedValues(items)) { + return [allItem, ...items]; + } + } + + return [allItem]; +}; + +function checkNotNullOrUndefinedValues(arr: unknown[]) { + return arr.every((value) => value !== null && value !== undefined); +} diff --git a/public/editor-client/src/api/adapter.ts b/public/editor-client/src/api/adapter.ts index aef8c995a7..6fa124424c 100644 --- a/public/editor-client/src/api/adapter.ts +++ b/public/editor-client/src/api/adapter.ts @@ -1,3 +1,5 @@ +import { Config } from "../config"; +import { Page } from "../types/Page"; import { Project } from "../types/Project"; import { CreatedSavedBlock, @@ -175,3 +177,31 @@ export const stringifyProject = (project: Project): APIProject => ({ }); //#endregion + +//#region Collections + +export type GetCollections = ( + data: { + search?: string; + postType?: string[]; + abortSignal?: AbortSignal; + }, + config: Config +) => Promise<{ ID: number; title: string; permalink: string }[]>; + +//#endregion + +//#region Page + +type APIPage = Omit & { + data: string; + dataVersion: string; +}; + +export const stringifyPage = (page: Page): APIPage => ({ + ...page, + data: JSON.stringify(page.data), + dataVersion: `${page.dataVersion}` +}); + +//#endregion diff --git a/public/editor-client/src/api/index.ts b/public/editor-client/src/api/index.ts index f6cf26425b..86679bd973 100644 --- a/public/editor-client/src/api/index.ts +++ b/public/editor-client/src/api/index.ts @@ -1,4 +1,6 @@ import { getConfig } from "../config"; +import { Page } from "../types/Page"; +import { Rule } from "../types/PopupConditions"; import { Project } from "../types/Project"; import { ResponseWithBody } from "../types/Response"; import { @@ -11,13 +13,15 @@ import { } from "../types/SavedBlocks"; import { t } from "../utils/i18n"; import { + GetCollections, parseMetaSavedBlock, parseSavedBlock, parseSavedLayout, + stringifyPage, + stringifyProject, stringifySavedBlock } from "./adapter"; -import { makeFormEncode } from "./utils"; -import { stringifyProject } from "./adapter"; +import { makeFormEncode, makeUrl } from "./utils"; //#region Common Utils Request & PersistentRequest @@ -46,19 +50,6 @@ export function request( return fetch(url, config); } -export const makeUrl = ( - baseUrl: string, - params: Record = {} -): string => { - const url = new URL(baseUrl); - - Object.entries(params).forEach(([key, value]) => { - url.searchParams.append(key, value); - }); - - return url.toString(); -}; - export function persistentRequest( url: string, config: RequestInit = {} @@ -598,6 +589,7 @@ export const uploadSaveLayouts = async ( formData.append("version", editorVersion); formData.append("hash", hash); + formData.append("action", actions.uploadBlocks); const r = await request(url, { method: "POST", body: formData }); @@ -614,3 +606,198 @@ export const uploadSaveLayouts = async ( }; //#endregion + +//#region Collections + +export const getCollections: GetCollections = async ( + { search = "", postType, abortSignal }, + config +) => { + const { + url, + hash, + actions: { searchPosts } + } = config; + + const version = config.editorVersion; + const body = new URLSearchParams({ + hash, + version, + action: searchPosts + }); + + if (search !== "") { + body.append("search", search); + } + if (postType !== undefined) { + for (const p of postType) { + body.append("post_type[]", p); + } + } + + const r = await request(url, { + method: "POST", + body, + signal: abortSignal + }); + const rj = await r.json(); + + if (rj.success) { + return rj.data; + } else { + throw rj; + } +}; + +export const getCollectionSourceItems = async (id: string) => { + const config = getConfig(); + + if (!config) { + throw new Error(t("Invalid __BRZ_PLUGIN_ENV__")); + } + + const { editorVersion, url: _url, hash, actions } = config; + + return request(_url, { + method: "POST", + body: new URLSearchParams({ + hash, + version: editorVersion, + postType: id, + action: actions.getPostObjects + }) + }) + .then((r) => r.json()) + .then((result) => { + if (!result?.data) { + throw t("Something went wrong"); + } + + return result.data; + }) + .catch((e) => { + if (process.env.NODE_ENV === "development") { + console.error(e); + } + return []; + }); +}; + +//#endregion + +//#region Page + +export const updatePage = ( + page: Page, + meta: { is_autosave?: 0 | 1 } = {} +): Promise => { + const config = getConfig(); + + if (!config) { + throw new Error(t("Invalid __BRZ_PLUGIN_ENV__")); + } + + const { editorVersion, url: _url, hash, actions } = config; + const url = makeUrl(_url, { + action: actions.updatePage, + version: editorVersion, + hash + }); + const { is_autosave = 1 } = meta; + const { id, status, data, dataVersion } = stringifyPage(page); + const body = new URLSearchParams({ + id, + status, + data, + dataVersion: `${dataVersion}`, + is_autosave: `${is_autosave}` + }); + + return persistentRequest(url, { method: "POST", body }).then((d) => { + if (!d.ok) { + throw new Error(t("Fail to update page")); + } + + return d.data; + }); +}; + +//#endregion + +//#region PopupRules + +interface PopupData { + dataVersion: number; + rules: Array; +} + +export const updatePopupRules = async ( + data: PopupData +): Promise> => { + const config = getConfig(); + + if (!config) { + throw new Error(t("Invalid __BRZ_PLUGIN_ENV__")); + } + const { pageId, url, hash, editorVersion, actions } = config; + const { rules, dataVersion } = data; + + const _url = makeUrl(url, { + action: actions.updateRules, + hash, + post: pageId, + version: editorVersion, + dataVersion: `${dataVersion}` + }); + + try { + const r = await request(_url, { + method: "POST", + body: JSON.stringify(rules) + }); + const data = await r.json(); + + return data.data; + } catch (e) { + throw new Error(t("Fail to update popup rules")); + } +}; + +//#endregion + +//#region FiltersFields + +export const getFields = async (data: { + postId: string; + loopAttributes: string; +}) => { + try { + const config = getConfig(); + + if (!config) { + throw new Error(t("Invalid __BRZ_PLUGIN_ENV__")); + } + + const { editorVersion, url, hash, actions } = config; + + const body = new URLSearchParams({ + hash: hash, + version: editorVersion, + action: actions.filterFields ?? "brizy_filter_fields", + ...data + }); + + const result = await request(url, { + method: "POST", + body: body + }); + + const r = await result.json(); + + return r.data; + } catch (e) { + throw new Error(t("Fail to load fields!")); + } +}; + +//#endregion diff --git a/public/editor-client/src/autoSave/index.ts b/public/editor-client/src/autoSave/index.ts index c791a78327..03a8097b0a 100644 --- a/public/editor-client/src/autoSave/index.ts +++ b/public/editor-client/src/autoSave/index.ts @@ -1,8 +1,12 @@ -import { updateProject } from "../api"; +import { updatePage, updateProject } from "../api"; import { AutoSave } from "../types/AutoSave"; export const autoSave = (data: AutoSave) => { if (data.projectData) { updateProject(data.projectData); } + + if (data.pageData) { + updatePage(data.pageData); + } }; diff --git a/public/editor-client/src/collectionItems/getCollectionItemsIds.ts b/public/editor-client/src/collectionItems/getCollectionItemsIds.ts new file mode 100644 index 0000000000..a3cb03a7db --- /dev/null +++ b/public/editor-client/src/collectionItems/getCollectionItemsIds.ts @@ -0,0 +1,32 @@ +import { getCollectionSourceItems } from "../api"; +import { ChoicesSync } from "../types/Choices"; +import { Response } from "../types/Response"; +import { t } from "../utils/i18n"; + +export const getCollectionItemsIds = { + async handler( + res: Response, + rej: Response, + extra: { id: string } + ) { + try { + const data = await getCollectionSourceItems(extra.id); + + const items = [ + { title: t("None"), value: "" }, + ...data.posts.map(({ ID, title }: { ID: string; title: string }) => ({ + value: ID, + title + })) + ]; + + res(items); + } catch (e) { + if (process.env.NODE_ENV === "development") { + console.error(e); + } + + rej(t("Something went wrong")); + } + } +}; diff --git a/public/editor-client/src/collectionItems/searchCollectionItems.ts b/public/editor-client/src/collectionItems/searchCollectionItems.ts new file mode 100644 index 0000000000..be412fdb81 --- /dev/null +++ b/public/editor-client/src/collectionItems/searchCollectionItems.ts @@ -0,0 +1,46 @@ +import { getCollections } from "../api"; +import { getConfig } from "../config"; +import { Response } from "../types/Response"; +import { t } from "../utils/i18n"; +import { read } from "../utils/reader/string"; + +interface ChoiceWithPermalink { + id: string; + title: string; + permalink?: string; +} + +export const searchCollectionItems = { + async handler( + res: Response, + rej: Response, + { collectionId, search }: { collectionId: string; search: string } + ) { + try { + const config = getConfig(); + + if (!config) { + throw new Error(t("Invalid __BRZ_PLUGIN_ENV__")); + } + + const items = await getCollections( + { search, postType: [collectionId] }, + config + ); + + const _items = items + .filter((item) => read(item.ID)) + .map(({ title, permalink, ID }) => { + return { + title, + permalink, + id: String(ID) + }; + }); + + res(_items); + } catch (e) { + rej(t("Something went wrong")); + } + } +}; diff --git a/public/editor-client/src/collectionItems/utils.ts b/public/editor-client/src/collectionItems/utils.ts new file mode 100644 index 0000000000..5b87fc08e8 --- /dev/null +++ b/public/editor-client/src/collectionItems/utils.ts @@ -0,0 +1,37 @@ +import { request } from "src/api"; +import { t } from "src/utils/i18n"; +import { getConfig } from "../config"; + +export const getCollectionSourceItems = async (id: string) => { + const config = getConfig(); + + if (!config) { + throw new Error(t("Invalid __BRZ_PLUGIN_ENV__")); + } + + const { editorVersion, url: _url, hash, actions } = config; + + return await request(_url, { + method: "POST", + body: new URLSearchParams({ + hash, + version: editorVersion, + postType: id, + action: actions.getPostObjects + }) + }) + .then((r) => r.json()) + .then((result) => { + if (!result?.data) { + throw "Something went wrong"; + } + + return result.data; + }) + .catch((e) => { + if (process.env.NODE_ENV === "development") { + console.error(e); + } + return []; + }); +}; diff --git a/public/editor-client/src/collectionTypes/loadCollectionTypes.ts b/public/editor-client/src/collectionTypes/loadCollectionTypes.ts new file mode 100644 index 0000000000..4cb2005072 --- /dev/null +++ b/public/editor-client/src/collectionTypes/loadCollectionTypes.ts @@ -0,0 +1,22 @@ +import { ChoicesSync } from "../types/Choices"; +import { Response } from "../types/Response"; +import { t } from "../utils/i18n"; +import { getCollectionTypes } from "./utils"; + +export const loadCollectionTypes = { + async handler(res: Response, rej: Response) { + try { + const collectionTypes = getCollectionTypes(); + + if (!collectionTypes) { + return rej(t("Missing collectionTypes in config")); + } + + const items = [{ title: "None", value: "" }, ...collectionTypes]; + + res(items); + } catch (e) { + rej(t("Failed to load collection types")); + } + } +}; diff --git a/public/editor-client/src/collectionTypes/utils.ts b/public/editor-client/src/collectionTypes/utils.ts new file mode 100644 index 0000000000..c542d04339 --- /dev/null +++ b/public/editor-client/src/collectionTypes/utils.ts @@ -0,0 +1,18 @@ +import { getConfig } from "src/config"; +import { ChoicesSync } from "src/types/Choices"; +import { MValue } from "src/utils/types"; + +export const getCollectionTypes = (): MValue => { + const config = getConfig(); + + const collectionTypes = config?.collectionTypes; + + if (collectionTypes && Array.isArray(collectionTypes)) { + return collectionTypes.map(({ label, name }) => ({ + title: label, + value: name + })); + } + + return undefined; +}; diff --git a/public/editor-client/src/config.ts b/public/editor-client/src/config.ts index b1ccf7df72..92af087f59 100644 --- a/public/editor-client/src/config.ts +++ b/public/editor-client/src/config.ts @@ -1,7 +1,9 @@ import { mPipe, optional, parseStrict } from "fp-utilities"; +import { CollectionType } from "./types/Collections"; import { PLUGIN_ENV } from "./types/global"; import { pipe } from "./utils/fp/pipe"; import { onNullish } from "./utils/onNullish"; +import * as Arr from "./utils/reader/array"; import * as Obj from "./utils/reader/object"; import * as Str from "./utils/reader/string"; import { throwOnNullish } from "./utils/throwOnNullish"; @@ -18,6 +20,8 @@ interface Actions { getMediaUid: string; getAttachmentUid: string; setProject: string; + updatePage: string; + updateRules: string; getSavedBlockList: string; getSavedBlockByUid: string; @@ -31,6 +35,12 @@ interface Actions { getLayoutByUid: string; updateLayout: string; deleteLayout: string; + + getPostObjects: string; + + searchPosts: string; + + filterFields: string; } interface API { @@ -46,6 +56,7 @@ export interface Config { actions: Actions; api: API; l10n?: Record; + collectionTypes: CollectionType[]; } const templatesReader = parseStrict, DefaultTemplates>({ @@ -67,6 +78,12 @@ const templatesReader = parseStrict, DefaultTemplates>({ ) }); +const collectionTypesReader = (arr: Array): Array => { + return arr.filter( + (o): o is CollectionType => Obj.isObject(o) && !!o.label && !!o.name + ); +}; + const apiReader = parseStrict({ mediaResizeUrl: pipe( mPipe( @@ -105,6 +122,14 @@ const actionsReader = parseStrict({ mPipe(Obj.readKey("setProject"), Str.read), throwOnNullish("Invalid actions: setProject") ), + updatePage: pipe( + mPipe(Obj.readKey("updatePage"), Str.read), + throwOnNullish("Invalid actions: updatePage") + ), + updateRules: pipe( + mPipe(Obj.readKey("updateRules"), Str.read), + throwOnNullish("Invalid actions: updateRules") + ), createSavedBlock: pipe( mPipe(Obj.readKey("createSavedBlock"), Str.read), throwOnNullish("Invalid actions: createSavedBlock") @@ -148,6 +173,18 @@ const actionsReader = parseStrict({ deleteLayout: pipe( mPipe(Obj.readKey("deleteLayout"), Str.read), throwOnNullish("Invalid actions: deleteLayout") + ), + getPostObjects: pipe( + mPipe(Obj.readKey("getPostObjects"), Str.read), + throwOnNullish("Invalid actions: getPostObjects") + ), + searchPosts: pipe( + mPipe(Obj.readKey("searchPosts"), Str.read), + throwOnNullish("Invalid actions: searchPosts") + ), + filterFields: pipe( + mPipe(Obj.readKey("filterFields"), Str.read), + throwOnNullish("Invalid actions: filterFields") ) }); @@ -176,7 +213,11 @@ const reader = parseStrict({ mPipe(Obj.readKey("api"), Obj.read, apiReader), throwOnNullish("Invalid: api") ), - l10n: optional(pipe(Obj.readKey("l10n"), Obj.read, onNullish({}))) + l10n: optional(pipe(Obj.readKey("l10n"), Obj.read, onNullish({}))), + collectionTypes: pipe( + mPipe(Obj.readKey("collectionTypes"), Arr.read, collectionTypesReader), + throwOnNullish("Invalid: collectionTypes") + ) }); export const getConfig = (): MValue => { diff --git a/public/editor-client/src/dynamicContent/__tests__/getPlaceholder.ts b/public/editor-client/src/dynamicContent/__tests__/getPlaceholder.ts new file mode 100644 index 0000000000..ee5b19f774 --- /dev/null +++ b/public/editor-client/src/dynamicContent/__tests__/getPlaceholder.ts @@ -0,0 +1,45 @@ +import { DCPlaceholderObj } from "../../types/DynamicContent"; +import { getPlaceholder } from "../utils"; + +describe("Testing 'getPlaceholder' function", () => { + test.each<[DCPlaceholderObj, string]>([ + [{ name: "a" }, "{{a}}"], + [{ name: "b", attr: {} }, "{{b}}"], + [ + { + name: "c", + attr: { + a: undefined, + b: null, + c: [1, 2, 3], + d: () => { + return {}; + }, + }, + }, + "{{c}}", + ], + [{ name: "d", attr: { a: "", b: undefined } }, "{{d a=''}}"], + [{ name: "efg", attr: { a: "abc", b: 123 } }, "{{efg a='abc' b='123'}}"], + [ + { + name: "h_i_j", + attr: { x: 777, c: "xxx", b: "abc", a: 123, _fallback: "fb" }, + }, + + "{{h_i_j _fallback='fb' a='123' b='abc' c='xxx' x='777'}}", + ], + [ + { name: "test", attr: { placeholder: "This is O'reilly book" } }, + + "{{test placeholder='This%20is%20O'reilly%20book'}}", + ], + [{ name: "UserAttribute['test']" }, "{{UserAttribute['test']}}"], + [ + { name: "UserAttribute['test']", attr: { a: "", b: undefined } }, + "{{UserAttribute['test'] a=''}}", + ], + ])("no. %#", (placeholderObj, expected) => { + expect(getPlaceholder(placeholderObj)).toStrictEqual(expected); + }); +}); diff --git a/public/editor-client/src/dynamicContent/__tests__/getPlaceholderObj.ts b/public/editor-client/src/dynamicContent/__tests__/getPlaceholderObj.ts new file mode 100644 index 0000000000..8b63ea6876 --- /dev/null +++ b/public/editor-client/src/dynamicContent/__tests__/getPlaceholderObj.ts @@ -0,0 +1,60 @@ +import { DCPlaceholderObj } from "../../types/DynamicContent"; +import { MValue } from "../../utils/types"; +import { getPlaceholderObj } from "../utils"; + +describe("Testing 'getPlaceholderObj' function", () => { + test.each<[string, MValue]>([ + ["", undefined], + ["invalid string", undefined], + ["{", undefined], + ["}", undefined], + ["{ test", undefined], + ["test }", undefined], + ["{ test }", undefined], + ["{{", undefined], + ["}}", undefined], + ["{{ test", undefined], + ["test }}", undefined], + ["{{ test }", undefined], + ["{ test }}", undefined], + ["a='123' b='456'", undefined], + ["{ a='123' b='456' }", undefined], + ["{{", undefined], + ["}}", undefined], + ["a='123' b='456'", undefined], + ["{ a='123' b='456' }", undefined], + ["[[ asdasd asd ]]", undefined] + ])("Invalid str %#", (str, expected) => { + expect(getPlaceholderObj(str)).toStrictEqual(expected); + }); + + test.each<[string, DCPlaceholderObj]>([ + ["{{test}}", { name: "test" }], + ["{{ test }}", { name: "test" }], + ["{{ test }}", { name: "test" }], + ["{{test_abc123}}", { name: "test_abc123" }], + ["{{ test_abc123}}", { name: "test_abc123" }], + ["{{ test_abc123-23324}}", { name: "test_abc123-23324" }], + ["{{test_abc123-23324 }}", { name: "test_abc123-23324" }], + [ + "{{ test_abc123-23324 a='123' b='344'}}", + { name: "test_abc123-23324", attr: { a: "123", b: "344" } } + ], + [ + "{{ test a='123' b=\"abc-111__xyz\" }}", + { name: "test", attr: { a: "123", b: "abc-111__xyz" } } + ], + [ + "{{ test dasdasdas ac='1' 12121212121 DC=\"z\" }}", + { name: "test", attr: { ac: "1", DC: "z" } } + ], + ["{{ a-b-c }}", { name: "a-b-c" }], + ["{{ a='123' b='456' }}", { name: "a", attr: { b: "456" } }], + [ + "{{ a='123' _fallback='test' }}", + { name: "a", attr: { _fallback: "test" } } + ] + ])("Valid str %#", (str, expected) => { + expect(getPlaceholderObj(str)).toStrictEqual(expected); + }); +}); diff --git a/public/editor-client/src/dynamicContent/explodePlaceholder.ts b/public/editor-client/src/dynamicContent/explodePlaceholder.ts new file mode 100644 index 0000000000..3874649459 --- /dev/null +++ b/public/editor-client/src/dynamicContent/explodePlaceholder.ts @@ -0,0 +1,12 @@ +import { ExplodePlaceholder } from "../types/DynamicContent"; +import { getPlaceholderObj } from "./utils"; + +export const explodePlaceholder: ExplodePlaceholder = (placeholder) => { + try { + const placeholderObj = getPlaceholderObj(placeholder); + + return placeholderObj; + } catch (e) { + return undefined; + } +}; diff --git a/public/editor-client/src/dynamicContent/makePlaceholder.ts b/public/editor-client/src/dynamicContent/makePlaceholder.ts new file mode 100644 index 0000000000..404fbf3494 --- /dev/null +++ b/public/editor-client/src/dynamicContent/makePlaceholder.ts @@ -0,0 +1,12 @@ +import { MakePlaceholder } from "../types/DynamicContent"; +import { getPlaceholder } from "./utils"; + +export const makePlaceholder: MakePlaceholder = (placeholderObj) => { + try { + const placeholder = getPlaceholder(placeholderObj); + + return placeholder; + } catch (e) { + return undefined; + } +}; diff --git a/public/editor-client/src/dynamicContent/utils.ts b/public/editor-client/src/dynamicContent/utils.ts new file mode 100644 index 0000000000..f99d999f6d --- /dev/null +++ b/public/editor-client/src/dynamicContent/utils.ts @@ -0,0 +1,50 @@ +import { mPipe } from "fp-utilities"; +import { DCPlaceholderObj, Dictionary } from "../types/DynamicContent"; +import * as Str from "../utils/reader/string"; +import { MValue } from "../utils/types"; + +const _escape = mPipe(Str.read, encodeURI); +export const getPlaceholder = (placeholderObj: DCPlaceholderObj): string => { + const { name, attr } = placeholderObj; + + const attrStr = attr + ? Object.keys(attr) + .sort() + .flatMap((k: string) => { + const v = _escape(attr[k] as string); + return v !== undefined ? `${k}='${v}'` : []; + }) + .join(" ") + : ""; + + return attrStr.length > 0 ? `{{${name} ${attrStr}}}` : `{{${name}}}`; +}; + +const _unescape = mPipe(Str.read, decodeURI); +export const getPlaceholderObj = ( + placeholder: string +): MValue => { + const r1 = /^{{\s*([\w-]+)(.*?)\s*}}$/; + const nameAndAttr = r1.exec(placeholder); + + if (!nameAndAttr) { + return undefined; + } + + const [, name, attrStr] = nameAndAttr; + + if (attrStr === "") { + return { name }; + } + + const r2 = /(\w+)=("|'|"|')(.*?)\2/g; + let attr: Dictionary | undefined = undefined; + let match; + + while ((match = r2.exec(attrStr.trim()))) { + attr = attr ?? {}; + attr[match[1]] = _unescape(match[3]); + } + + return attr ? { name, attr } : { name }; +}; diff --git a/public/editor-client/src/index.ts b/public/editor-client/src/index.ts index 73db392de3..fe016183a0 100644 --- a/public/editor-client/src/index.ts +++ b/public/editor-client/src/index.ts @@ -1,4 +1,7 @@ import { autoSave } from "./autoSave"; +import { getCollectionItemsIds } from "./collectionItems/getCollectionItemsIds"; +import { searchCollectionItems } from "./collectionItems/searchCollectionItems"; +import { loadCollectionTypes } from "./collectionTypes/loadCollectionTypes"; import { getConfig } from "./config"; import { addFile } from "./customFile/addFile"; import { @@ -7,9 +10,13 @@ import { defaultPopups, defaultStories } from "./defaultTemplates"; +import { explodePlaceholder } from "./dynamicContent/explodePlaceholder"; +import { makePlaceholder } from "./dynamicContent/makePlaceholder"; +import { handler as filters, possibleValues } from "./Elements/filters"; import { addMedia } from "./media/addMedia"; import { addMediaGallery } from "./media/addMediaGallery"; import { onChange } from "./onChange"; +import { popupConditions } from "./popupConditions"; import { publish } from "./publish"; import { savedBlocks } from "./savedBlocks/savedBlocks"; import { savedLayouts } from "./savedBlocks/savedLayouts"; @@ -34,10 +41,18 @@ const api = { savedBlocks, savedPopups, savedLayouts, + popupConditions, defaultKits: defaultKits(config), defaultPopups: defaultPopups(config), defaultStories: defaultStories(config), - defaultLayouts: defaultLayouts(config) + defaultLayouts: defaultLayouts(config), + collectionItems: { + searchCollectionItems, + getCollectionItemsIds + }, + collectionTypes: { + loadCollectionTypes + } }; if (window.__VISUAL_CONFIG__) { @@ -54,4 +69,24 @@ if (window.__VISUAL_CONFIG__) { if (window.__VISUAL_CONFIG__.ui) { window.__VISUAL_CONFIG__.ui.publish = publish; } + + // Dynamic Content + if (window.__VISUAL_CONFIG__.dynamicContent) { + window.__VISUAL_CONFIG__.dynamicContent.makePlaceholder = makePlaceholder; + window.__VISUAL_CONFIG__.dynamicContent.explodePlaceholder = + explodePlaceholder; + } + + // Elements + if ( + window.__VISUAL_CONFIG__.elements && + window.__VISUAL_CONFIG__.elements.filters + ) { + window.__VISUAL_CONFIG__.elements.filters.handler = filters; + window.__VISUAL_CONFIG__.elements.filters.possibleValues = possibleValues; + } else { + window.__VISUAL_CONFIG__.elements = { + filters: { handler: filters, possibleValues: possibleValues } + }; + } } diff --git a/public/editor-client/src/onChange/index.ts b/public/editor-client/src/onChange/index.ts index 089580a4a0..2238ea28a6 100644 --- a/public/editor-client/src/onChange/index.ts +++ b/public/editor-client/src/onChange/index.ts @@ -1,8 +1,12 @@ -import { updateProject } from "../api"; +import { updatePage, updateProject } from "../api"; import { OnChange } from "../types/OnChange"; export const onChange = (data: OnChange) => { if (data.projectData) { updateProject(data.projectData, { is_autosave: 0 }); } + + if (data.pageData) { + updatePage(data.pageData, { is_autosave: 0 }); + } }; diff --git a/public/editor-client/src/popupConditions/index.ts b/public/editor-client/src/popupConditions/index.ts new file mode 100644 index 0000000000..e26599af1f --- /dev/null +++ b/public/editor-client/src/popupConditions/index.ts @@ -0,0 +1,16 @@ +import { updatePopupRules } from "../api"; +import { PopupConditions } from "../types/PopupConditions"; +import { t } from "../utils/i18n"; + +export const popupConditions: PopupConditions = { + conditions: { + async save(res, rej, data) { + try { + const rules = await updatePopupRules(data); + res(rules); + } catch (e) { + rej(t("Fail to update popup rules")); + } + } + } +}; diff --git a/public/editor-client/src/publish/index.ts b/public/editor-client/src/publish/index.ts index 8558d1f4e3..cb7e15eb78 100644 --- a/public/editor-client/src/publish/index.ts +++ b/public/editor-client/src/publish/index.ts @@ -1,16 +1,26 @@ -import { updateProject } from "../api"; +import { updatePage, updateProject } from "../api"; import { Publish } from "../types/Publish"; +import { t } from "../utils/i18n"; export const publish: Publish = { async handler(res, rej, args) { - const { projectData } = args; + const { projectData, pageData } = args; if (projectData) { try { await updateProject(projectData, { is_autosave: 0 }); res(args); } catch (e) { - rej("Failed to update project"); + rej(t("Failed to update project")); + } + } + + if (pageData) { + try { + await updatePage(pageData, { is_autosave: 0 }); + res(args); + } catch (e) { + rej(t("Failed to update page")); } } } diff --git a/public/editor-client/src/types/AutoSave.ts b/public/editor-client/src/types/AutoSave.ts index ccb1c0907b..f7f90c6545 100644 --- a/public/editor-client/src/types/AutoSave.ts +++ b/public/editor-client/src/types/AutoSave.ts @@ -1,9 +1,10 @@ +import { Page } from "./Page"; import { Project } from "./Project"; export interface AutoSave { - // TODO Currently only projectData is used - // Need to add pageData and globalBlocks + // TODO Currently only projectData and pageData is used + // Need to add globalBlocks projectData: Project; - // pageData: PageCommon; + pageData: Page; // globalBlocks: Array; } diff --git a/public/editor-client/src/types/Choices.ts b/public/editor-client/src/types/Choices.ts new file mode 100644 index 0000000000..43d4038202 --- /dev/null +++ b/public/editor-client/src/types/Choices.ts @@ -0,0 +1,19 @@ +import { Literal } from "../utils/types"; + +interface Choice { + icon?: { + name?: string; + className?: string; + }; + title: string; + value: Literal; +} + +export type ChoicesSync = Choice[]; + +export interface ChoicesAsync { + load: (abortSignal?: AbortSignal) => Promise; + emptyLoad?: { + title?: string; + }; +} diff --git a/public/editor-client/src/types/Collections.ts b/public/editor-client/src/types/Collections.ts new file mode 100644 index 0000000000..f666ef13e7 --- /dev/null +++ b/public/editor-client/src/types/Collections.ts @@ -0,0 +1,9 @@ +export interface CollectionExtra { + collectionId: string; + search: string; +} + +export interface CollectionType { + name: string; + label: string; +} diff --git a/public/editor-client/src/types/DynamicContent.ts b/public/editor-client/src/types/DynamicContent.ts new file mode 100644 index 0000000000..aa1465a220 --- /dev/null +++ b/public/editor-client/src/types/DynamicContent.ts @@ -0,0 +1,18 @@ +import { MValue } from "../utils/types"; + +export type Dictionary = { + [k: string]: T | undefined; +}; + +export interface DCPlaceholderObj { + name: string; + attr?: Dictionary; +} + +export type MakePlaceholder = ( + placeholderObj: DCPlaceholderObj +) => MValue; + +export type ExplodePlaceholder = ( + placeholder: string +) => MValue; diff --git a/public/editor-client/src/types/Filters.ts b/public/editor-client/src/types/Filters.ts new file mode 100644 index 0000000000..edcd71598c --- /dev/null +++ b/public/editor-client/src/types/Filters.ts @@ -0,0 +1,61 @@ +import { NewType } from "./NewType"; +import { Response } from "./Response"; + +export type Choice = { title: string; value: string | number }; + +export type QueryTypeSource = NewType; + +interface FieldsCommon { + filterQuery: string; + label: string; + optionQuery: string; + optionSource: string; + filterBy: string; + type: string; +} + +export interface FilterField extends FieldsCommon { + possibleValues: PossibleValue[] | Choice[]; +} + +export type PossibleValue = { + count: number; + description: string; + filter: string; + name: string; + parent: number; + slug: string; + taxonomy: string; + term_group: number; + term_id: number; + term_taxonomy_id: number; +}; + +export type FilterFieldsData = { + fields: FilterField[]; + taxonomies: FilterField[]; + metaFields: FilterField[]; + authors: FilterField[]; +}; + +export interface Filters { + handler: ( + res: Response, + rej: Response, + args: { + postId: string; + loopAttributes: string; + } + ) => void; + possibleValues: ( + res: Response, + rej: Response, + data: { + postId: string; + loopAttributes: string; + optionSource: string; + type: string; + search?: string; + } + ) => void; +} diff --git a/public/editor-client/src/types/OnChange.ts b/public/editor-client/src/types/OnChange.ts index 3a48ea488a..4ee08043f9 100644 --- a/public/editor-client/src/types/OnChange.ts +++ b/public/editor-client/src/types/OnChange.ts @@ -1,9 +1,10 @@ +import { Page } from "./Page"; import { Project } from "./Project"; export interface OnChange { - // TODO Currently only projectData is used - // Need to add pageData and globalBlocks + // TODO Currently only projectData and pageData is used + // Need to add globalBlocks projectData: Project; - // pageData: PageCommon; + pageData: Page; // globalBlocks: Array; } diff --git a/public/editor-client/src/types/Page.ts b/public/editor-client/src/types/Page.ts new file mode 100644 index 0000000000..3fc0de076f --- /dev/null +++ b/public/editor-client/src/types/Page.ts @@ -0,0 +1,6 @@ +export interface Page { + id: string; + data: Record; + dataVersion: number; + status: "draft" | "publish"; +} diff --git a/public/editor-client/src/types/PopupConditions.ts b/public/editor-client/src/types/PopupConditions.ts new file mode 100644 index 0000000000..99f86f5b68 --- /dev/null +++ b/public/editor-client/src/types/PopupConditions.ts @@ -0,0 +1,24 @@ +import { Response } from "./Response"; + +export interface Rule { + type: string; + appliedFor: number; + entityType: string; + mode: "reference" | "specific"; + entityValues: Array; +} + +export interface Extra { + rules: Array; + dataVersion: number; +} + +export interface PopupConditions { + conditions?: { + save: ( + res: Response>, + rej: Response, + extra: Extra + ) => void; + }; +} diff --git a/public/editor-client/src/types/Project.ts b/public/editor-client/src/types/Project.ts index 275d2db58b..c87630ccd7 100644 --- a/public/editor-client/src/types/Project.ts +++ b/public/editor-client/src/types/Project.ts @@ -6,13 +6,4 @@ export interface Project { dataVersion: number; } -export interface PublishData { - // TODO Currently only projectData is used - // Need to add pageData and globalBlocks - projectData?: Project; - is_autosave: 1 | 0; - // pageData: PageCommon; - // globalBlocks: Array; -} - //#endregion diff --git a/public/editor-client/src/types/Publish.ts b/public/editor-client/src/types/Publish.ts index fd5e2bc564..addd6abf2f 100644 --- a/public/editor-client/src/types/Publish.ts +++ b/public/editor-client/src/types/Publish.ts @@ -1,10 +1,15 @@ -import { PublishData } from "./Project"; +import { Page } from "./Page"; +import { Project } from "./Project"; import { Response } from "./Response"; +export interface Data { + // TODO Currently only projectData and pageData is used + // Need to add globalBlocks + projectData?: Project; + pageData?: Page; + // globalBlocks: Array; +} + export interface Publish { - handler: ( - res: Response, - rej: Response, - args: PublishData - ) => void; + handler: (res: Response, rej: Response, args: Data) => void; } diff --git a/public/editor-client/src/types/global.d.ts b/public/editor-client/src/types/global.d.ts index 9b7f7a2c47..6df8dddfd1 100644 --- a/public/editor-client/src/types/global.d.ts +++ b/public/editor-client/src/types/global.d.ts @@ -1,4 +1,5 @@ import { AutoSave } from "./AutoSave"; +import { CollectionExtra, CollectionType } from "./Collections"; import { BlocksArray, DefaultBlock, @@ -9,9 +10,14 @@ import { PopupsWithThumbs, StoriesWithThumbs } from "./DefaultTemplate"; -import { AddMediaData, AddMediaExtra } from "./Media"; +import { ExplodePlaceholder, MakePlaceholder } from "./DynamicContent"; +import { AddFileData } from "./File"; +import { AddMediaData, AddMediaGallery } from "./Media"; import { OnChange } from "./OnChange"; +import { PopupConditions } from "./PopupConditions"; import { PublishData } from "./Project"; +import { SavedBlocks, SavedLayouts, SavedPopups } from "./SavedBlocks"; +import { Filters } from "./Filters"; declare class WPMediaLibrary { get: (selector: string) => import("backbone").Collection; @@ -30,6 +36,7 @@ export interface PLUGIN_ENV { customFileUrl?: string; }; l10n?: Record; + collectionTypes?: CollectionType[]; } export interface VISUAL_CONFIG { @@ -69,38 +76,30 @@ export interface VISUAL_CONFIG { media?: { mediaResizeUrl?: string; - addMedia?: { - label?: string; - handler: ( - res: Response, - rej: Response, - extra: AddMediaExtra - ) => void; - }; + addMedia?: AddMediaData; - addMediaGallery?: { - label?: string; - handler: ( - res: Response>, - rej: Response, - extra: AddMediaExtra - ) => void; - }; + addMediaGallery?: AddMediaGallery; }; + // File customFile?: { customFileUrl?: string; - addFile?: { - label?: string; - handler: ( - res: Response, - rej: Response, - extra: AddFileExtra - ) => void; - }; + addFile?: AddFileData; }; + // SavedBlocks + savedBlocks?: SavedBlocks; + + // SavedLayouts + savedLayouts?: SavedLayouts; + + // SavedPopups + savedPopups?: SavedPopups; + + // PopupConditions + popupConditions?: PopupConditions; + defaultKits?: DefaultTemplate, DefaultBlock>; defaultPopups?: DefaultTemplate; defaultLayouts?: DefaultTemplate< @@ -111,6 +110,48 @@ export interface VISUAL_CONFIG { StoriesWithThumbs, BlocksArray | DefaultBlock >; + + //Collection Items + collectionItems?: { + searchCollectionItems: { + handler: ( + res: Response, + rej: Response, + extra: CollectionExtra + ) => void; + }; + getCollectionItemsIds: { + handler: ( + res: Response, + rej: Response, + extra: { id: string } + ) => void; + }; + }; + + //Collection Types + collectionTypes?: { + loadCollectionTypes: { + handler: (res: Response, rej: Response) => void; + }; + }; + }; + + //#endregion + + //#region Dynamic Content + + dynamicContent?: { + makePlaceholder: MakePlaceholder; + explodePlaceholder: ExplodePlaceholder; + }; + + //#endregion + + // #region Elements + + elements?: { + filters: Filters; }; //#endregion @@ -139,7 +180,7 @@ declare global { }; }; query: (query: { - type: "image, audio, video, application, text, pdf"; + type: "image, audio, video, application, text, pdf" | "image"; }) => WPMediaLibrary; state: () => WPMediaLibrary; } diff --git a/public/editor-client/src/utils/reader/array.ts b/public/editor-client/src/utils/reader/array.ts new file mode 100644 index 0000000000..11f8dabd71 --- /dev/null +++ b/public/editor-client/src/utils/reader/array.ts @@ -0,0 +1,9 @@ +import { Reader } from "./types"; + +export const read: Reader> = (v) => { + if (Array.isArray(v)) { + return v; + } + + return undefined; +}; diff --git a/public/editor-client/src/utils/types.ts b/public/editor-client/src/utils/types.ts index 3b289238a1..0da661ff86 100644 --- a/public/editor-client/src/utils/types.ts +++ b/public/editor-client/src/utils/types.ts @@ -1,2 +1,3 @@ export type MValue = A | undefined; export type Nullish = undefined | null; +export type Literal = string | number; diff --git a/public/editor-src/editor/js/bootstraps/initConfig/default/api/getSourceChoices.ts b/public/editor-src/editor/js/bootstraps/initConfig/default/api/getSourceChoices.ts index 1b589f08f9..d00ccf6d36 100644 --- a/public/editor-src/editor/js/bootstraps/initConfig/default/api/getSourceChoices.ts +++ b/public/editor-src/editor/js/bootstraps/initConfig/default/api/getSourceChoices.ts @@ -11,7 +11,7 @@ export const getSourceChoices = (config: C): C => { const loadSourceTypes = async () => { const sourceTypes = await getCollectionSourceTypes(config); return [ - { title: "Not Selected", value: "" }, + { title: "None", value: "" }, ...sourceTypes.map((item) => ({ title: item.title, value: item.id })) ]; }; diff --git a/public/main.php b/public/main.php index f6c0d8bdb4..dd79c7a023 100755 --- a/public/main.php +++ b/public/main.php @@ -1,5 +1,6 @@ - +
@@ -18,7 +18,11 @@

Your theme must use the the_content filter in order for Brizy to work

- +
+ +
+
+ diff --git a/readme.txt b/readme.txt index 2188258a4e..ac0a9a3e9c 100644 --- a/readme.txt +++ b/readme.txt @@ -162,7 +162,7 @@ Don't worry if you make a mistake or delete something that you shouldn't have. W * Fixed: Section Parallax * Fixed: Section containers -= 2.4.26 - 2023-06-21 = += 2.4.22 - 2023-06-21 = * New: Added option to sort tags alphabetically in the Accordion element * New: Added vertical space option for Accordion element * New: Add width in px for the boxed option on Blocks