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 baf46fa4b7..aa466d8ad0 100644 --- a/admin/abstract-api.php +++ b/admin/abstract-api.php @@ -40,6 +40,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 * @@ -67,4 +75,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 767c7ad2e1..726b01d045 100644 --- a/admin/blocks/api.php +++ b/admin/blocks/api.php @@ -105,8 +105,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( @@ -235,18 +235,15 @@ public function actionCreateGlobalBlock() { if ( $status == 'publish' && is_null( $compiledData ) ) { $this->error( 400, "The compiled data is missing" ); - } - - $bockManager = new Brizy_Admin_Blocks_Manager( Brizy_Admin_Blocks_Main::CP_GLOBAL ); + }$bockManager = new Brizy_Admin_Blocks_Manager(Brizy_Admin_Blocks_Main::CP_GLOBAL); /** - * @var Brizy_Editor_Block $block ; - */ - $block = $bockManager->createEntity( $this->param( 'uid' ), $status ); - $block->setMeta( stripslashes( $this->param( 'meta' ) ) ); - $block->set_editor_data( $editorData ); - $block->set_needs_compile( true ); - $block->setHtml( $html ); + * @var Brizy_Editor_Block $block; + */ + $block = $bockManager->createEntity($this->param('uid'), $status); + $block->setMeta(stripslashes($this->param('meta'))); + $block->set_editor_data($editorData); + $block->set_needs_compile(true);$block->setHtml( $html ); if ( $status == 'publish' && $compiledData ) { @@ -256,7 +253,7 @@ public function actionCreateGlobalBlock() { $this->error( 400, "The compiled data is invalid" ); } - $block->set_encoded_compiled_html( $compiled['html'] ); + $block->set_encoded_compiled_html( $compiled['html'] ); $block->set_compiled_scripts( [ 'free' => $compiled['assets']['freeScripts'], 'pro' => ( isset( $compiled['assets']['proScripts'] ) ? $compiled['assets']['proScripts'] : [] ), @@ -272,14 +269,15 @@ public function actionCreateGlobalBlock() { } if ( $this->param( 'tags' ) ) { - $block->setTags( stripslashes( $this->param( 'tags' ) ) ); - } - if ( $position ) { - $block->setPosition( - Brizy_Editor_BlockPosition::createFromSerializedData( get_object_vars( json_decode( $position ) ) ) - ); - } + $block->setTags(stripslashes($this->param('tags'))); + } + + if ($position) { + $block->setPosition( + Brizy_Editor_BlockPosition::createFromSerializedData(get_object_vars(json_decode($position))) + ); + } // rules if ( $rulesData ) { @@ -428,8 +426,8 @@ public function actionUpdateGlobalBlocks() { } } - $bockManager = new Brizy_Admin_Blocks_Manager( Brizy_Admin_Blocks_Main::CP_GLOBAL ); - $blocks = $bockManager->getEntity( (array) $this->param( 'uid' ) ); + $bockManager = new Brizy_Admin_Blocks_Manager(Brizy_Admin_Blocks_Main::CP_GLOBAL); + $blocks = $bockManager->getEntity((array)$this->param('uid')); foreach ( (array) $this->param( 'uid' ) as $i => $uid ) { @@ -519,13 +517,15 @@ public function actionUpdateGlobalBlocks() { $block->save(); - do_action( 'brizy_global_block_updated', $block ); - } - } + do_action('brizy_global_block_updated', $block); + + } +} do_action( 'brizy_global_data_updated' ); - $this->success( [] ); + + $this->success([]); } catch ( Exception $exception ) { $this->error( 400, $exception->getMessage() ); @@ -554,24 +554,25 @@ public function actionDeleteGlobalBlock() { public function actionGetSavedBlocks() { $this->verifyNonce( self::nonce ); - try { - $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 ), - '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', - $bockManager->createResponseForEntities( $blocks, $fields ), - $fields, - $bockManager ); - $this->success( $blocks ); - } catch ( Exception $exception ) { - $this->error( 400, $exception->getMessage() ); - } - } + try { + $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), + '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', + $bockManager->createResponseForEntities($blocks, $fields), + $fields, + $bockManager + ); + $this->success($blocks); + } catch (Exception $exception) { + $this->error(400, $exception->getMessage()); + } + } public function actionGetSavedBlockByUid() { $this->verifyNonce( self::nonce ); @@ -618,20 +619,20 @@ public function actionCreateSavedBlock() { $this->error( 400, 'Invalid media data provided' ); } - try { - $bockManager = new Brizy_Admin_Blocks_Manager( Brizy_Admin_Blocks_Main::CP_SAVED ); - $block = $bockManager->createEntity( $this->param( 'uid' ) ); - $block->setMedia( stripslashes( $this->param( 'media' ) ) ); - $block->setMeta( stripslashes( $this->param( 'meta' ) ) ); + try { + $bockManager = new Brizy_Admin_Blocks_Manager(Brizy_Admin_Blocks_Main::CP_SAVED); + $block = $bockManager->createEntity($this->param('uid')); + $block->setMedia(stripslashes($this->param('media'))); + $block->setMeta(stripslashes($this->param('meta'))); - if ( $this->param( 'title' ) ) { + if($this->param('title')){ $block->setTitle( stripslashes( $this->param( 'title' ) ) ); } if ( $this->param( 'tags' ) ) { - $block->setTags( stripslashes( $this->param( 'tags' ) ) ); - } + $block->setTags(stripslashes($this->param('tags'))); + } - $block->set_editor_data( $this->sanitizeJson(stripslashes( $this->param( 'data' ) ) )); + $block->set_editor_data( $this->sanitizeJson(stripslashes( $this->param( 'data' ) ) )); $block->set_needs_compile( true ); //$block->setCloudUpdateRequired( true ); $block->save(); @@ -688,13 +689,13 @@ public function actionUpdateSavedBlock() { } - if ( (int) $this->param( 'is_autosave' ) ) { - $block->save( 1 ); - } else { - $block->save(); - do_action( 'brizy_saved_block_updated', $block ); - do_action( 'brizy_global_data_updated' ); - } + if ((int)$this->param('is_autosave')) { + $block->save(1); + } else { + $block->save(); + do_action('brizy_saved_block_updated', $block); + do_action('brizy_global_data_updated'); + } Brizy_Editor_Block::cleanClassCache(); diff --git a/admin/blocks/main.php b/admin/blocks/main.php index b648c71f50..1518b7a486 100644 --- a/admin/blocks/main.php +++ b/admin/blocks/main.php @@ -372,7 +372,7 @@ private function findReferencedInPage($wpPost) return []; } - $context = Brizy_Content_ContextFactory::createContext(Brizy_Editor_Project::get(), $wpPost); + $context = Brizy_Content_ContextFactory::createContext(Brizy_Editor_Project::get(), $wpPost->getWpPost()); $placeholderProvider = new Brizy_Content_Providers_GlobalBlockProvider($context); $extractor = new \BrizyPlaceholders\Extractor($placeholderProvider); diff --git a/admin/layouts/api.php b/admin/layouts/api.php index 7dbf5c7593..3110c8d821 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) { @@ -201,16 +202,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 74b4254efa..706d578cd3 100755 --- a/brizy.php +++ b/brizy.php @@ -134,4 +134,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/polylang.php b/compatibilities/polylang.php index 994286e533..345b7863a9 100644 --- a/compatibilities/polylang.php +++ b/compatibilities/polylang.php @@ -5,7 +5,7 @@ class Brizy_Compatibilities_Polylang { public function __construct() { - add_action( 'brizy_post_loop_args', [ $this, 'post_loop_args' ] ); + add_filter( 'brizy_post_loop_args', [ $this, 'post_loop_args' ] ); add_filter( 'pll_home_url_white_list', [ $this, 'home_url_white_list' ] ); } diff --git a/config.dev.php b/config.dev.php index 3d989b063c..d56a1b256e 100755 --- a/config.dev.php +++ b/config.dev.php @@ -48,7 +48,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; diff --git a/config.php b/config.php index ec55fd4402..b5ffad9a52 100755 --- a/config.php +++ b/config.php @@ -107,3 +107,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 a8070924bf..d4e33aa854 100644 --- a/content/context-factory.php +++ b/content/context-factory.php @@ -17,12 +17,12 @@ class Brizy_Content_ContextFactory * * @return Brizy_Content_Context */ - static public function createContext($project = null, $wp_post = null, $isLoop = false) + static public function createContext($project = null, $wp_post = null, $parentContext = false) { - $context = self::getContext($project, $wp_post); + $context = new Brizy_Content_Context($project, null, $wp_post, null, $parentContext); - if ($isLoop) { - return apply_filters('brizy_loop_context_create', $context, $wp_post); + if ($wp_post) { + $context->setAuthor($wp_post->post_author); } return apply_filters('brizy_context_create', $context, $wp_post); diff --git a/content/context.php b/content/context.php index 9295d24529..a04492a246 100644 --- a/content/context.php +++ b/content/context.php @@ -1,11 +1,18 @@ setPlaceholders($contentPlaceholders); + $this->setPlaceholders(array_merge($this->getPlaceholders(), $contentPlaceholders)); } @@ -75,10 +82,122 @@ protected function set($key, $value) * @param $project * @param $wp_post */ - public function __construct($project = null, $wp_post = null) + 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); } -} \ No newline at end of file + + /** + * @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 309d7e4e83..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 1329b15215..6b12bf5721 100644 --- a/content/main-processor.php +++ b/content/main-processor.php @@ -31,6 +31,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 43d0fb8916..7e58bdc0f1 100644 --- a/content/placeholder-provider.php +++ b/content/placeholder-provider.php @@ -35,12 +35,12 @@ public function __construct($context = null) */ public function getPlaceholders() { - $out = array(); + if (self::$cache_all_placeholders) { return self::$cache_all_placeholders; } - + $out = []; foreach ($this->providers as $provider) { $out = array_merge($out, $provider->getPlaceholders()); } 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/placeholder-wrapper-processor.php b/content/placeholder-wrapper-processor.php new file mode 100644 index 0000000000..916295acc7 --- /dev/null +++ b/content/placeholder-wrapper-processor.php @@ -0,0 +1,50 @@ +context = $context; + $this->processors[] = new Brizy_Content_ReferencedGlobalBlockProcessor(); // collect all referenced blocks + $this->processors[] = new Brizy_Content_BlocksProcessor(); // inserts the global blocks and popups referenced + $this->processors[] = new Brizy_Content_WrapperToPlaceholderProcessor(); + } + + /** + * @param $content + * + * @return string + */ + public function process($content) + { + foreach ($this->processors as $processor) { + $content = $processor->process($content, $this->context); + } + + return $content; + } + + /** + * @param Brizy_Content_Context $context + */ + public function setContext($context) + { + $this->context = $context; + } +} diff --git a/content/placeholders/abstract.php b/content/placeholders/abstract.php index b17c2bdba6..e835975a7b 100644 --- a/content/placeholders/abstract.php +++ b/content/placeholders/abstract.php @@ -69,7 +69,7 @@ public function support($placeholderName) public function shouldFallbackValue($value, ContextInterface $context, ContentPlaceholder $placeholder) { - return empty($value); + return is_null($value) || $value===""; } public function getFallbackValue(ContextInterface $context, ContentPlaceholder $placeholder) 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/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/providers/free-provider.php b/content/providers/free-provider.php index 5dada2446a..e54adf4763 100644 --- a/content/providers/free-provider.php +++ b/content/providers/free-provider.php @@ -6,250 +6,213 @@ class Brizy_Content_Providers_FreeProvider extends Brizy_Content_Providers_Abstr 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(); + new Brizy_Content_Placeholders_Simple( 'Internal Display Block By User Role', 'display_by_roles', function( Brizy_Content_Context $context, ContentPlaceholder $contentPlaceholder ) { - if ( ! empty( $attrs['roles'] ) ) { - $roles = explode( ',', $attrs['roles'] ); - $userRoles = (array) wp_get_current_user()->roles; + $attrs = $contentPlaceholder->getAttributes(); - if ( in_array( 'logged', $roles ) && is_user_logged_in() ) { - $userRoles[] = 'logged'; - } + 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 ( Brizy_Editor_User::is_user_allowed() ) { - if ( ! empty( $_GET['role'] ) ) { + if ( ! empty( $_GET['role'] ) ) { + + if ( $_GET['role'] === 'default' ) { + $roles[] = 'default'; + $userRoles[] = 'default'; + } else { + $userRoles = []; - if ( $_GET['role'] === 'default' ) { + if ( $_GET['role'] == 'not_logged' ) { + + if ( in_array( 'not_logged', $roles ) ) { $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']; - } } + } else { + $userRoles[] = $_GET['role']; } } + } + } - if ( in_array( 'not_logged', $roles ) ) { + if ( in_array( 'not_logged', $roles ) ) { - $roles = array_diff( $roles, [ 'not_logged' ] ); + $roles = array_diff( $roles, [ 'not_logged' ] ); - if ( is_user_logged_in() ) { - if ( ! array_intersect( $roles, $userRoles ) ) { - return ''; - } - } - } else { - if ( ! array_intersect( $roles, $userRoles ) ) { - return ''; - } + if ( is_user_logged_in() ) { + if ( ! array_intersect( $roles, $userRoles ) ) { + return ''; } } + } else { + if ( ! array_intersect( $roles, $userRoles ) ) { + return ''; + } + } + } - $replacer = new \BrizyPlaceholders\Replacer( $context->getProvider() ); + $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' ), 'brizy_dc_image_alt' ) - ); - $this->registerPlaceholder( - new Brizy_Content_Placeholders_UniquePageUrl( __( 'Uniquer page url', 'brizy' ), 'brizy_dc_current_page_unique_url' ) - ); - $this->registerPlaceholder( - new Brizy_Content_Placeholders_Simple( __( 'WP Language', 'brizy' ), '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 ) { + 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' ), 'brizy_dc_image_alt' ) + );$this->registerPlaceholder( new Brizy_Content_Placeholders_UniquePageUrl( __( 'Uniquer page url', 'brizy' ), 'brizy_dc_current_page_unique_url' ) + );$this->registerPlaceholder( new Brizy_Content_Placeholders_Simple( __( 'WP Language', 'brizy' ), '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 ) { - $attrs = $contentPlaceholder->getAttributes(); + $attrs = $contentPlaceholder->getAttributes(); - $id = isset( $attrs['sidebarId'] ) ? $attrs['sidebarId'] : null; + $id = isset( $attrs['sidebarId'] ) ? $attrs['sidebarId'] : null; - if ( $id ) { - ob_start(); + if ( $id ) { + ob_start(); - dynamic_sidebar( $id ); + dynamic_sidebar( $id ); - return ob_get_clean(); - } + return ob_get_clean(); + } - return ''; - } ) - ); - $this->registerPlaceholder( - new Brizy_Content_Placeholders_Simple( '', 'editor_navigation', function ( $context, $contentPlaceholder ) { + return ''; + } ) + );$this->registerPlaceholder(new Brizy_Content_Placeholders_Simple( '', 'editor_navigation', function ( $context, $contentPlaceholder ) { + + $attrs = $contentPlaceholder->getAttributes(); - $attrs = $contentPlaceholder->getAttributes(); + return $attrs['menuId'] ? wp_nav_menu( array( 'menu' => $attrs['menuId'], 'echo' => false ) ) : ''; + } ) - return $attrs['menuId'] ? wp_nav_menu( array( 'menu' => $attrs['menuId'], 'echo' => false ) ) : ''; - } ) ); $this->registerPlaceholder( - new Brizy_Content_Placeholders_Simple( '', 'editor_post_field', function ( $context, $contentPlaceholder ) { + new Brizy_Content_Placeholders_SimplePostAware( '', 'editor_post_field', function ( $context, $contentPlaceholder ) { - $attrs = $contentPlaceholder->getAttributes(); + $attrs = $contentPlaceholder->getAttributes(); - $post = ( $context = Brizy_Content_ContextFactory::getGlobalContext() ) ? $context->getWpPost() : get_post(); + $post = $context->getWpPost(); - if ( ! $post || ! isset( $attrs['property'] ) ) { - return ''; - } + if ( ! $post || ! isset( $attrs['property'] ) ) { + return ''; + } - return $this->filterData( $attrs['property'], $post ); - } ) - ); - $this->registerPlaceholder( - new Brizy_Content_Placeholders_Simple( '', 'editor_post_info', function () { - - $post = ( $context = Brizy_Content_ContextFactory::getGlobalContext() ) ? $context->getWpPost() : get_post(); - - 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 $this->filterData( $attrs['property'], $post ); + } ) + );$this->registerPlaceholder(new Brizy_Content_Placeholders_Simple( '', 'editor_post_info', function ( $context, $contentPlaceholder ) { - return ''; - } ) - ); - $this->registerPlaceholder( - new Brizy_Content_Placeholders_Simple( '', 'editor_posts', function ( $context, $contentPlaceholder ) { + $post = $context->getWpPost(); - $atts = $contentPlaceholder->getAttributes(); + if ( $post ) { + $commentsCount = get_approved_comments( $post->ID, [ 'count' => true ] ); + $params = []; - // 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"}} + $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 ) ); - // this array is used as default values for displayPosts - $extra_atts = array( - "columns" => 1, - "display_date" => 1, - "display_author" => 1, - ); + return Brizy_Editor_View::get(BRIZY_PLUGIN_PATH . '/public/views/post-info', $params); + } - $extra_atts = array_merge( $extra_atts, $atts ); + return ''; + } ) - $posts = $this->getPosts( $atts ); + );$this->registerPlaceholder(new Brizy_Content_Placeholders_Simple( '', 'editor_posts', function ( $context, $contentPlaceholder ) { - return $this->displayPosts( $posts, $extra_atts ); - } ) - ); - $this->registerPlaceholder( - new Brizy_Content_Placeholders_Simple( - __( 'Product Page', 'brizy' ), - 'editor_product_page', - function ( $context, $contentPlaceholder ) { + $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"}} - $atts = $contentPlaceholder->getAttributes(); + // 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 ); + + $posts = $this->getPosts( $atts ); + + return $this->displayPosts( $posts, $extra_atts ); + } ) + );$this->registerPlaceholder(new Brizy_Content_Placeholders_Simple( __( 'Product Page', 'brizy' ), + 'editor_product_page', function ( $context, $contentPlaceholder ) { + + $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['itemId'] ) && current_user_can( 'manage_options' ) ) { - return __( 'Please set a valid product', 'brizy' ); - } + if ( empty( $atts['itemId'] ) && current_user_can( 'manage_options' ) ) { + return __( 'Please set a valid product', 'brizy' ); + } - $this->setScriptDependency( - 'brizy-preview', - [ 'zoom', 'photoswipe', 'flexslider', 'wc-single-product' ] - ); + $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 ); + // 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['itemId'] . '"]' ); + $html = do_shortcode( '[product_page id="' . $atts['itemId'] . '"]' ); - add_filter( 'the_content', [ Brizy_Admin_Templates::instance(), 'filterPageContent' ], - 12000 ); + 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 ) { + return $html; + } - $atts = $contentPlaceholder->getAttributes(); + ) + );$this->registerPlaceholder(new Brizy_Content_Placeholders_Simple( 'Products Page', 'editor_product_products', function ( $context, $contentPlaceholder ) { - $shortcodeAttributes = []; + $atts = $contentPlaceholder->getAttributes(); - 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 = []; - $shortcodeAttributes = implode( ' ', $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'] ); + } - 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]' ); - } ) + $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_order_tracking', function () { - return do_shortcode( '[woocommerce_order_tracking]' ); - } ) + $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' ), @@ -260,14 +223,12 @@ function () { return wc_print_notices( true ); } - return ""; + return ""; }, self::CONFIG_KEY_TEXT ) ); - } - - private function filterData( $property, $post ) { + }private function filterData( $property, $post ) { switch ( $property ) { case 'post_title': return get_the_title( $post ); @@ -387,10 +348,7 @@ private function displayPosts( $posts, $extra_atts ) { @@ -412,10 +370,7 @@ private function getPostExcerpt( $post ) { 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 + $the_excerpt = implode( ' ', $words ); // put in excerpt only the number of word that is set in $excerpt_length } return $the_excerpt; diff --git a/editor.php b/editor.php index 0d3c64c3f2..806f74f625 100755 --- a/editor.php +++ b/editor.php @@ -328,6 +328,8 @@ public function registerCustomPostTemplates() { */ private function loadEditorApi( $post, $user ) { try { + new Brizy_Editor_Filters_Api( ); + if ( Brizy_Editor_User::is_user_allowed() ) { new Brizy_Editor_RestExtend(); new Brizy_Editor_API( $post ); @@ -417,7 +419,7 @@ function currentPostId() { $pid = (int) $_REQUEST['page_id']; } elseif ( isset( $_REQUEST['post_ID'] ) ) { - $pid = (int) $_POST['post_ID']; + $pid = (int) $_REQUEST['post_ID']; } elseif ( isset( $_REQUEST['id'] ) ) { $pid = (int) $_REQUEST['id']; diff --git a/editor/api.php b/editor/api.php index 841c5287f2..21156451a2 100755 --- a/editor/api.php +++ b/editor/api.php @@ -21,6 +21,7 @@ class Brizy_Editor_API extends Brizy_Admin_AbstractApi { 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'; @@ -69,35 +70,36 @@ protected function initializeApiActions() { 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 . self::AJAX_GET_DYNAMIC_CONTENT, array( $this, 'addDynamicContent' ) ); - add_action( $p . 'nopriv_' . Brizy_Editor::prefix( self::AJAX_TIMESTAMP ), array( $this, 'timestamp' ) ); + $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_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_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->addAjaxAction( self::AJAX_GET_DYNAMIC_CONTENT, array( $this, 'addDynamicContent' ) ); + $this->addAjaxAction( self::AJAX_DOWNLOAD_MEDIA, array( $this, 'download_media' ) ); + $this->addNoPrivAjaxAction( Brizy_Editor::prefix( self::AJAX_TIMESTAMP ), array($this, 'timestamp')); } @@ -134,10 +136,8 @@ public function addDynamicContent() { $provider = new Brizy_Content_PlaceholderProvider( $context ); $placeholders = $provider->getGroupedPlaceholdersForApiResponse(); - return $this->success( $placeholders ); - } - - public function lock_project() { + return $this->success($placeholders); + }public function lock_project() { $this->verifyNonce( self::nonce ); if ( Brizy_Editor::get()->checkIfProjectIsLocked() === false ) { @@ -321,12 +321,10 @@ public function set_project() { throw new Exception( '', 400 ); } - if (!$compiledStyles) { + if (!$compiledStyles) { Brizy_Logger::instance()->error('Invalid project styles provided', ['compiled' => $compiledStyles]); throw new Exception('', 400); - } - - if ( ! $dataVersion ) { + }if (!$dataVersion ) { Brizy_Logger::instance()->error( 'No data version provided', [ 'data' => $dataVersion ] ); throw new Exception( '', 400 ); } @@ -335,10 +333,10 @@ public function set_project() { $project->setDataAsJson( $meta ); $project->setDataVersion( $dataVersion ); + if ( (int) $this->param( 'is_autosave' ) === 1 ) { $project->save( 1 ); - } else { - $project->setCompiledStyles( $compiledStyles ); + } else {$project->setCompiledStyles( $compiledStyles ); $project->set_compiler(Brizy_Editor_Entity::COMPILER_BROWSER ); $project->save(); $project->savePost(); @@ -452,15 +450,14 @@ public function update_item() { // there is no need to make it true as we already receive the compiled html from editor $this->post->set_needs_compile( false ); $this->post->set_compiler( Brizy_Editor_Entity::COMPILER_BROWSER ); - } - - if ( $atemplate ) { + }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->getWpPost()->post_status = $status; @@ -470,7 +467,6 @@ public function update_item() { } else { $this->post->setDataVersion( $dataVersion ); $this->post->setLastUserEdited( get_current_user_id() ); - $this->post->save( 0 ); $this->post->savePost( true ); } @@ -541,11 +537,7 @@ public function placeholder_content() { $contents[] = apply_filters( 'brizy_content', $placeholder, Brizy_Editor_Project::get(), $post ); } - $this->success( - array( - 'placeholders' => $contents, - ) - ); + $this->success( array( 'placeholders' => $contents ) ); } catch ( Exception $exception ) { Brizy_Logger::instance()->exception( $exception ); $this->error( $exception->getCode(), $exception->getMessage() ); @@ -554,19 +546,21 @@ public function placeholder_content() { 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 ) { + $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', @@ -574,13 +568,19 @@ public function placeholders_content() { Brizy_Editor_Project::get(), $post ); + } catch ( Exception $exception ) { + Brizy_Logger::instance()->exception( $exception ); + continue; } } - $this->success( array( 'placeholders' => $contents ) ); - } catch ( Exception $exception ) { - Brizy_Logger::instance()->exception( $exception ); - $this->error( $exception->getCode(), $exception->getMessage() ); + + } + $this->success( + array( + 'placeholders' => $contents) + ); + } private function getPostSample( $templateId ) { @@ -621,7 +621,7 @@ private function getPostSample( $templateId ) { ]; $values = $rule->getEntityValues(); - $posts = []; + $posts = []; if ( empty( $values[0] ) ) { // For All condition $posts = get_posts( $args ); @@ -684,6 +684,7 @@ private function getPostSample( $templateId ) { $wp_query->is_tax = true; } + return array_pop( $terms ); case Brizy_Admin_Rule::WOO_SHOP_PAGE : diff --git a/editor/editor/editor.php b/editor/editor/editor.php index 443398e9ad..9af12a6c02 100755 --- a/editor/editor/editor.php +++ b/editor/editor/editor.php @@ -96,12 +96,13 @@ public function getClientConfig($context) ]; $config = $this->getApiConfigFields($config, $context); - $config = $this->addLoopSourcesClientConfig( + $config = $this->addLoopSourcesClientConfig( $config, $mode === 'template', $this->post->getWpPostId(), $context ); + $config = apply_filters('brizy_client_config', $config, $context); return $config; } @@ -168,6 +169,7 @@ public function config($context = self::COMPILE_CONTEXT) '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( @@ -211,10 +213,9 @@ public function config($context = self::COMPILE_CONTEXT) 'editorVersion' => BRIZY_EDITOR_VERSION, 'imageSizes' => $this->getImgSizes(), 'moduleGroups' => [], - 'l10n' => $this->getTexts(), + 'l10n' => $this->getTexts(), 'membership' => true, - 'elements' => [ 'image' => [ 'zoom' => true ], 'video'=>[ 'types'=>['youtube','vimeo','url'] ] ], - ); + 'elements' => [ 'image' => [ 'zoom' => true ], 'video'=>[ 'types'=>['youtube','vimeo','url'] ] ],); $manager = new Brizy_Editor_Accounts_ServiceAccountManager(Brizy_Editor_Project::get()); if (!$this->isPopup($config) && !$this->isStory($config)) { @@ -575,7 +576,7 @@ private function addContentDefaults($config, $context) ], ], ], - 'AssetsPosts' => [ + 'AssetsPosts' => [ '_version' => 3, 'type' => 'posts', 'source' => 'post', @@ -917,8 +918,7 @@ private function getPostLoopSources($isTemplate, $wp_post_id, $context) if ($template_type == Brizy_Admin_Templates::TYPE_ARCHIVE || $template_type == Brizy_Admin_Templates::TYPE_PRODUCT_ARCHIVE) { $templateTypeArchive = true; } - - $rule_manager = new Brizy_Admin_Rules_Manager(); + $rule_manager = new Brizy_Admin_Rules_Manager(); $template_rules = $rule_manager->getRules($wp_post_id); $isSearchTemplate = $this->isSearchTemplate($template_rules); } @@ -951,7 +951,6 @@ private function getPostLoopSources($isTemplate, $wp_post_id, $context) foreach ($types as $type) { $typeObj = get_post_type_object($type); - $typeDto = [ 'name' => $typeObj->name, 'label' => $typeObj->label, @@ -963,7 +962,7 @@ private function getPostLoopSources($isTemplate, $wp_post_id, $context) return $result; } - private function addLoopSourcesConfig($config, $isTemplate, $wp_post_id, $context) + private function addLoopSourcesConfig($config, $isTemplate, $wp_post_id, $context) { $sources = $this->getPostLoopSources($isTemplate, $wp_post_id, $context); @@ -979,14 +978,6 @@ private function addLoopSourcesConfig($config, $isTemplate, $wp_post_id, $contex return $config; } - private function addLoopSourcesClientConfig($config, $isTemplate, $wp_post_id, $context) - { - $sources = $this->getPostLoopSources($isTemplate, $wp_post_id, $context); - $config['collectionTypes'] = $sources; - - return $config; - } - private function addGlobalBlocksData($config) { @@ -1001,41 +992,22 @@ private function addGlobalBlocksData($config) $postTermsByKeys[$term->term_id] = $term; } - $config['wp']['postTerms'] = $postTerms; - $config['wp']['postTermParents'] = array_values( - array_diff_key($this->getAllParents($postTermsByKeys), $postTermsByKeys) - ); - $config['wp']['postAuthor'] = (int)$this->post->getWpPost()->post_author; - + $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; - } + private function addLoopSourcesClientConfig($config, $isTemplate, $wp_post_id, $context) + { + $sources = $this->getPostLoopSources($isTemplate, $wp_post_id, $context); + $config['collectionTypes'] = $sources; - return (object)$attachment_data; + return $config; } + /** * @return array|null */ @@ -1482,7 +1454,8 @@ private function parseSize($size) private function getOneArchiveLink($args = '') - { + + { global $wpdb, $wp_locale; $defaults = array( @@ -1721,7 +1694,6 @@ private function getTemplateType($template_rules) return ''; } - private function isSearchTemplate($template_rules) { foreach ($template_rules as $rule) { @@ -1741,9 +1713,7 @@ private function isSearchTemplate($template_rules) } return false; - } - - /** + }/** * @return array */ public function getProjectStatus() @@ -1766,7 +1736,6 @@ public function getProjectStatus() */ public function getApiActions($config = [], $context = null) { - $pref = Brizy_Editor::prefix(); $actions = array( @@ -1859,6 +1828,7 @@ public function getApiActions($config = [], $context = null) 'symbolDelete' => $pref.Brizy_Admin_Symbols_Api::DELETE_ACTION, 'symbolList' => $pref.Brizy_Admin_Symbols_Api::LIST_ACTION, 'getDynamicContentPlaceholders' => $pref.Brizy_Editor_API::AJAX_GET_DYNAMIC_CONTENT, + 'filterPlaceholderContents' => $pref . Brizy_Editor_Filters_Api::AJAX_FILTER_PLACEHOLDERS_CONTENT, ); return $actions; diff --git a/editor/editor/module-groups/essential-provider.php b/editor/editor/module-groups/essential-provider.php index 53db677b0f..8682eab3bb 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 8ee0b94fc3..a90fe0e28c 100644 --- a/editor/entity.php +++ b/editor/entity.php @@ -200,7 +200,7 @@ abstract protected function loadInstanceData(); /** * @return mixed */ - abstract public function createResponse( $fields = array(), $context=Brizy_Editor_Editor_Editor::EDITOR_CONTEXT ); + abstract public function createResponse( $fields = array() , $context=Brizy_Editor_Editor_Editor::EDITOR_CONTEXT ); /** * Save post data and and trigger post update @@ -360,7 +360,7 @@ public function getUid() { } public function getTitle() { - return $this->getWpPost()->post_title; + return html_entity_decode($this->getWpPost()->post_title); } public function setTitle( $title ) { diff --git a/editor/filters/api.php b/editor/filters/api.php new file mode 100644 index 0000000000..3ed7a58371 --- /dev/null +++ b/editor/filters/api.php @@ -0,0 +1,105 @@ +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); + +// $postContent = apply_filters( +// 'brizy_content', +// $postContent, +// Brizy_Editor_Project::get(), +// $brizyPost->getWpPost() +// ); + + $context = Brizy_Content_ContextFactory::createContext(Brizy_Editor_Project::get(), $brizyPost->getWpPost()); + $mainProcessor = new Brizy_Content_PlaceholderWrapperProcessor($context); + $postContent = $mainProcessor->process($postContent); + + + $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) + { + return $post->get_compiled_html(); + + $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 9a0823c827..1615b81136 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 9d9a7e39e3..1a33ac40fc 100755 --- a/editor/post.php +++ b/editor/post.php @@ -7,14 +7,14 @@ class Brizy_Editor_Post extends Brizy_Editor_Entity use Brizy_Editor_AutoSaveAware; - const BRIZY_POST = 'brizy-post'; - const BRIZY_POST_NEEDS_COMPILE_KEY = 'brizy-need-compile'; - const BRIZY_POST_SIGNATURE_KEY = 'brizy-post-signature'; - const BRIZY_POST_HASH_KEY = 'brizy-post-hash'; - const BRIZY_POST_EDITOR_VERSION = 'brizy-post-editor-version'; - const BRIZY_POST_COMPILER_VERSION = 'brizy-post-compiler-version'; - const BRIZY_POST_PLUGIN_VERSION = 'brizy-post-plugin-version'; - const BRIZY_TAGS = 'brizy-tags'; + const BRIZY_POST = 'brizy-post'; + const BRIZY_POST_NEEDS_COMPILE_KEY = 'brizy-need-compile'; + const BRIZY_POST_SIGNATURE_KEY = 'brizy-post-signature'; + const BRIZY_POST_HASH_KEY = 'brizy-post-hash'; + const BRIZY_POST_EDITOR_VERSION = 'brizy-post-editor-version'; + const BRIZY_POST_COMPILER_VERSION = 'brizy-post-compiler-version'; + const BRIZY_POST_PLUGIN_VERSION = 'brizy-post-plugin-version'; + const BRIZY_TAGS = 'brizy-tags'; static protected $instance = null; static protected $compiled_page = []; @@ -277,8 +277,8 @@ public function savePost($createRevision = false) { $postarr = [ 'ID' => $this->getWpPostId(), - 'post_title' => $this->getTitle(), - 'post_content' => $this->getPostContent($createRevision), + 'post_title' => $this->getTitle(), + 'post_content' => $this->getPostContent($createRevision), ]; $this->deleteOldAutosaves($this->getWpPostId()); @@ -329,7 +329,9 @@ private function getPostContent($noFilters) $this->get_compiled_html() ); - $replacer = new \BrizyPlaceholders\Replacer($placeholderProvider); + $context->setPlaceholders($placeholders); + + $replacer = new \BrizyPlaceholders\Replacer($placeholderProvider); $content = $replacer->replaceWithExtractedData($placeholders, $placeholderInstances, $content, $context); $content = $extractor->stripPlaceholders($content); @@ -805,15 +807,15 @@ protected function loadInstanceData() //$storageData = $storage->get_storage(); $storage_post = $storage->get($this->getObjectKey(), false); - $this->setTitle(get_the_title($this->getWpPostId())); + $this->setTitle( get_the_title( $this->getWpPostId() ) ); - // check for deprecated forms of posts - if ($storage_post instanceof self) { - $this->set_editor_data($storage_post->editor_data); - $this->set_needs_compile(true); - $this->save(); - } else { - if (is_array($storage_post)) { + // check for deprecated forms of posts + if ( $storage_post instanceof self ) { + $this->set_editor_data( $storage_post->editor_data ); + $this->set_needs_compile( true ); + $this->save(); + } else { + if ( is_array( $storage_post ) ) { if (isset($storage_post['compiled_html'])) { $this->set_encoded_compiled_html($storage_post['compiled_html']); @@ -864,7 +866,8 @@ protected function loadInstanceData() protected function populateAutoSavedData($autosave) { $autosave->setTitle($this->getTitle()); - $autosave->set_template($this->get_template()); + $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); diff --git a/editor/zip/archiver.php b/editor/zip/archiver.php index c480abe3b8..94ac58a30a 100644 --- a/editor/zip/archiver.php +++ b/editor/zip/archiver.php @@ -88,7 +88,8 @@ public function addEntityToZip(ZipArchive $z, Brizy_Editor_Zip_ArchiveItem $item $block = $item->getPost(); $data = array( 'class' => get_class($block), - 'title' => $block->getTitle(), + 'title' => $block->getTitle(), + 'title' => $block->getTitle(), 'meta' => $block->getMeta(), 'media' => $block->getMedia(), 'data' => $block->get_editor_data(true), 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..310303ea3e --- /dev/null +++ b/public/editor-client/src/Elements/Filters/index.ts @@ -0,0 +1,37 @@ +import { getFields } from "../../api"; +import { Filters } from "../../types/Filters"; +import { t } from "../../utils/i18n"; +import { converter, parseFields } from "./utils"; + +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")); + } +}; diff --git a/public/editor-client/src/Elements/Filters/utils.ts b/public/editor-client/src/Elements/Filters/utils.ts new file mode 100644 index 0000000000..985c4c3b57 --- /dev/null +++ b/public/editor-client/src/Elements/Filters/utils.ts @@ -0,0 +1,105 @@ +import { + Choice, + FilterFieldsData, + fromStringQueryTypeSource, + isChoiceArray, + isPossibleValueArray, + PossibleValue, + QueryTypeSource +} from "../../types/Filters"; +import { isAllValuesValid } from "../../utils/reader/array"; + +export const createQueryTypeSource = ( + query: string, + type: string, + source: string, + filterBy: string +): QueryTypeSource | undefined => + fromStringQueryTypeSource(`${query}|||${type}|||${source}|||${filterBy}`); + +export const converter = (data: FilterFieldsData): Choice[] => { + const arr = Object.values(data).reduce((acc: Choice[], cur) => { + const field = cur.map((item) => { + return { + value: + createQueryTypeSource( + getQuery(item.filterQuery, item.optionQuery, item.optionSource), + item.type, + item.optionSource, + item.filterBy + ) ?? "", + title: item.label + }; + }); + return [...acc, ...field]; + }, []); + + return arr ?? []; +}; + +export const getQuery = ( + filterQuery: string, + optionQuery: string, + optionSource: string +): string => filterQuery || optionQuery || `metaKey=${optionSource}`; + +export 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 parsedValues: PossibleValue[] = isPossibleValueArray( + selectedItem.possibleValues + ) + ? selectedItem.possibleValues + : []; + const items: Choice[] = parsedValues.map((it) => ({ + value: it.term_id, + title: it.name + })); + + if (search) { + return [ + allItem, + ...items.filter((it) => + it.title.toLocaleLowerCase().includes(search.toLocaleLowerCase()) + ) + ]; + } + + if (isAllValuesValid(items)) { + return [allItem, ...items]; + } + } + + if (selectedItem.optionSource === "meta") { + const items = isChoiceArray(selectedItem.possibleValues) + ? selectedItem.possibleValues + : []; + + if (search) { + return [ + allItem, + ...items.filter((it) => + it.title.toLocaleLowerCase().includes(search.toLocaleLowerCase()) + ) + ]; + } + + if (isAllValuesValid(items)) { + return [allItem, ...items]; + } + } + + return [allItem]; +}; diff --git a/public/editor-client/src/api/index.ts b/public/editor-client/src/api/index.ts index b53628f339..661f32bd21 100644 --- a/public/editor-client/src/api/index.ts +++ b/public/editor-client/src/api/index.ts @@ -1262,3 +1262,40 @@ export const updateGlobalBlocks = async ( }; //#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, + version: editorVersion, + action: actions.filterFields ?? "brizy_filter_fields", + ...data + }); + + const result = await request(url, { + method: "POST", + 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/config.ts b/public/editor-client/src/config.ts index 9176f937e6..56b9635fd0 100644 --- a/public/editor-client/src/config.ts +++ b/public/editor-client/src/config.ts @@ -52,6 +52,8 @@ interface Actions { heartBeat: string; takeOver: string; getFonts: string; + + filterFields: string; } interface ProjectStatus { @@ -282,6 +284,10 @@ const actionsReader = parseStrict({ getFonts: pipe( mPipe(Obj.readKey("getFonts"), Str.read), throwOnNullish("Invalid actions: getFonts") + ), + filterFields: pipe( + mPipe(Obj.readKey("filterFields"), Str.read), + throwOnNullish("Invalid actions: filterFields") ) }); diff --git a/public/editor-client/src/index.ts b/public/editor-client/src/index.ts index acb8f5ed65..660a710099 100644 --- a/public/editor-client/src/index.ts +++ b/public/editor-client/src/index.ts @@ -13,11 +13,12 @@ import { defaultStories } from "./defaultTemplates"; import { placeholderData, placeholders } from "./dynamicContent"; +import { handler as filters, possibleValues } from "./Elements/Filters"; import { handler as posts } from "./Elements/Posts"; import { uploadedFonts } from "./fonts"; -import { heartBeat } from "./heartBeat"; -import {globalBlocks } from "./globalBlocks/blocks"; +import { globalBlocks } from "./globalBlocks/blocks"; import { globalPopups } from "./globalBlocks/popups"; +import { heartBeat } from "./heartBeat"; import { addMedia } from "./media/addMedia"; import { addMediaGallery } from "./media/addMediaGallery"; import { onChange } from "./onChange"; @@ -90,8 +91,20 @@ if (window.__VISUAL_CONFIG__) { // Elements if (window.__VISUAL_CONFIG__.elements) { set(window.__VISUAL_CONFIG__.elements, ["posts", "handler"], posts); + set(window.__VISUAL_CONFIG__.elements, ["filters", "handler"], filters); + set( + window.__VISUAL_CONFIG__.elements, + ["filters", "possibleValues"], + possibleValues + ); } else { set(window.__VISUAL_CONFIG__, ["elements", "posts", "handler"], posts); + set(window.__VISUAL_CONFIG__, ["elements", "filters", "handler"], filters); + set( + window.__VISUAL_CONFIG__, + ["elements", "filters", "possibleValues"], + possibleValues + ); } // Dynamic Content diff --git a/public/editor-client/src/types/Filters.ts b/public/editor-client/src/types/Filters.ts new file mode 100644 index 0000000000..3a4102e21f --- /dev/null +++ b/public/editor-client/src/types/Filters.ts @@ -0,0 +1,112 @@ +import { pass } from "fp-utilities"; +import { Literal } from "../utils/types"; +import { NewType } from "./NewType"; +import { Response } from "./Response"; + +export type Choice = { title: string; value: Literal }; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const isChoice = (values: any): values is Choice => { + return typeof values === "object" && "title" in values && "value" in values; +}; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const isChoiceArray = (arr: any): arr is Choice[] => { + if (!Array.isArray(arr)) return false; + for (const item of arr) { + if (!isChoice(item)) return false; + } + return true; +}; + +export type QueryTypeSource = NewType; + +export const isQueryTypeSource = (s: string): s is QueryTypeSource => + s.split("|||").length === 4; + +export const fromStringQueryTypeSource = pass(isQueryTypeSource); + +interface FieldsCommon { + filterQuery: string; + label: string; + optionQuery: string; + optionSource: string; + filterBy: string; + type: string; +} + +export interface FilterField extends FieldsCommon { + possibleValues: PossibleValue[] | Choice[]; +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const isPossibleValue = (values: any): values is PossibleValue => { + return ( + typeof values === "object" && + "count" in values && + "description" in values && + "filter" in values && + "name" in values && + "parent" in values && + "slug" in values && + "taxonomy" in values && + "term_group" in values && + "term_id" in values && + "term_taxonomy_id" in values + ); +}; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const isPossibleValueArray = (arr: any): arr is PossibleValue[] => { + if (!Array.isArray(arr)) return false; + for (const item of arr) { + if (!isPossibleValue(item)) return false; + } + return true; +}; + +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 FiltersHandlerArgs { + postId: string; + loopAttributes: string; +} + +export interface FiltersValuesArgs { + postId: string; + loopAttributes: string; + optionSource: string; + type: string; + search?: string; +} + +export interface Filters { + handler: ( + res: Response, + rej: Response, + args: FiltersHandlerArgs + ) => void; + possibleValues: ( + res: Response, + rej: Response, + data: FiltersValuesArgs + ) => void; +} diff --git a/public/editor-client/src/types/global.d.ts b/public/editor-client/src/types/global.d.ts index 65d1c87534..7bfa81fee2 100644 --- a/public/editor-client/src/types/global.d.ts +++ b/public/editor-client/src/types/global.d.ts @@ -21,6 +21,7 @@ import { AddMediaData, AddMediaGallery } from "./Media"; import { OnChange } from "./OnChange"; import { PopupConditions } from "./PopupConditions"; import { Posts } from "./Posts"; +import { Filters } from "./Filters"; import { Data } from "./Publish"; import { SavedBlocks, SavedLayouts, SavedPopups } from "./SavedBlocks"; import { Screenshots } from "./Screenshots"; @@ -185,6 +186,7 @@ export interface VISUAL_CONFIG { elements?: { posts: Posts; + filters: Filters; }; //#endregion 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..86786f4894 --- /dev/null +++ b/public/editor-client/src/utils/reader/array.ts @@ -0,0 +1,12 @@ +import { isT } from "fp-utilities"; +import { Reader } from "./types"; + +export const read: Reader> = (v) => { + if (Array.isArray(v)) { + return v; + } + + return undefined; +}; + +export const isAllValuesValid = (arr: Array) => arr.every(isT); diff --git a/public/main.php b/public/main.php index 941b079194..bf89d35661 100755 --- a/public/main.php +++ b/public/main.php @@ -1,5 +1,6 @@ - +