Advertisement
Guest User

Untitled

a guest
Aug 27th, 2020
998
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 86.93 KB | None | 0 0
  1. <?php
  2. /**
  3. * Central Template builder class
  4. */
  5.  
  6. // Don't load directly
  7. if ( ! defined('ABSPATH') ) { die('-1'); }
  8.  
  9. if ( ! class_exists( 'AviaBuilder' ) )
  10. {
  11.  
  12. class AviaBuilder
  13. {
  14. const VERSION = '4.7.1.1';
  15.  
  16. /**
  17. * Holds the instance of this class
  18. *
  19. * @since 4.2.1
  20. * @var AviaBuilder
  21. */
  22. static private $_instance = null;
  23.  
  24. /**
  25. *
  26. * @var string 'safe' | 'debug'
  27. */
  28. public static $mode = '';
  29.  
  30. public static $path = array();
  31. public static $resources_to_load = array();
  32. public static $default_iconfont = '';
  33. public static $full_el = array();
  34. public static $full_el_no_section = array();
  35.  
  36. /**
  37. * Define all supported post types
  38. *
  39. * @since 4.3
  40. * @var array
  41. */
  42. protected $supported_post_types;
  43.  
  44. /**
  45. * Define all supported post types
  46. *
  47. * @since 4.4.1
  48. * @var array
  49. */
  50. protected $supported_post_status;
  51.  
  52. /**
  53. *
  54. * @var array
  55. */
  56. public $paths;
  57.  
  58. /**
  59. * [Class name] => class
  60. *
  61. * @var array
  62. */
  63. public $shortcode_class;
  64.  
  65. /**
  66. * Back reference to class name of shortcode
  67. * [shortcode] => ClassName
  68. *
  69. * @since 4.2.1
  70. * @var array
  71. */
  72. public $shortcode;
  73.  
  74. /**
  75. * Back reference to shortcode for children (nested or layout_children)
  76. * The shortcode class must not exist. Needed to identify and repair the element structure
  77. *
  78. * child_shortcode => array( parent_shortcode, .... )
  79. *
  80. * @since 4.2.1
  81. * @var array
  82. */
  83. public $shortcode_parents;
  84.  
  85. /**
  86. *
  87. * @since 4.2.1
  88. * @var ShortcodeParser
  89. */
  90. protected $shortcode_parser;
  91.  
  92. /**
  93. * State of the select box in admin area for the post/page/...
  94. *
  95. * @since 4.2.1
  96. * @var string 'disabled' | 'check_only' | 'auto_repair'
  97. */
  98. protected $posts_shortcode_parser_state;
  99.  
  100. /**
  101. *
  102. * @since 4.3
  103. * @var aviaElementManager
  104. */
  105. protected $element_manager;
  106.  
  107. /**
  108. *
  109. * @since 4.3
  110. * @var aviaAssetManager
  111. */
  112. protected $asset_manager_class;
  113.  
  114.  
  115. /**
  116. * Tabs in backend for categorizing shortcode buttons in ALB
  117. *
  118. * @var array
  119. */
  120. public $tabs;
  121.  
  122.  
  123. /**
  124. * Backend ALB shortcode buttons
  125. *
  126. * @var array
  127. */
  128. public $shortcode_buttons;
  129.  
  130. /**
  131. * Contains usage count for each shortcode in blog
  132. * shortcode => count
  133. *
  134. * @var array
  135. * @since 4.6.4
  136. */
  137. protected $shortcode_usage_blog;
  138.  
  139. /**
  140. *
  141. * @var AviaSaveBuilderTemplate
  142. */
  143. protected $builderTemplate;
  144.  
  145. /**
  146. *
  147. * @var boolean
  148. */
  149. public $disable_drag_drop;
  150.  
  151.  
  152. /**
  153. * Holds the status of the ALB for the current post
  154. *
  155. * @since 4.2.1
  156. * @var string 'active' | ''
  157. */
  158. protected $alb_builder_status;
  159.  
  160. /**
  161. * Stores the balanced post content of a non ALB post to allow building the shortcode tree
  162. *
  163. * @since 4.2.1
  164. * @var string
  165. */
  166. public $post_content;
  167.  
  168. /**
  169. * Revision post id to save our postmeta fields
  170. *
  171. * @since 4.2.1
  172. * @var int
  173. */
  174. protected $revision_id;
  175.  
  176.  
  177. /**
  178. * Flag if the ALB magic wand button had been added to tinyMCE buttons
  179. *
  180. * @since 4.2.4
  181. * @var boolean
  182. */
  183. protected $alb_magic_wand_button;
  184.  
  185. /**
  186. * Flag to add the nonce input field on non alb supported pages that provide the ALB magic wand shortcode button
  187. *
  188. * @since 4.2.4
  189. * @var boolean
  190. */
  191. protected $alb_nonce_added;
  192.  
  193. /**
  194. * Array that contains all the names of shortcodes that can be dissabled automatically
  195. *
  196. * @kriesi
  197. * @since 4.3
  198. * @var array
  199. */
  200. public $may_be_disabled_automatically;
  201.  
  202. /**
  203. * Array that contains all the names of shortcodes with disabled assets that should not be loaded on the frontend
  204. *
  205. * @kriesi
  206. * @since 4.3
  207. * @var array
  208. */
  209. public $disabled_assets;
  210.  
  211. /**
  212. * Flag if we have an ajax callback to prepare modal preview
  213. *
  214. * @since 4.5.4
  215. * @var boolean
  216. */
  217. protected $in_text_to_preview;
  218.  
  219. /**
  220. * Flag if action wp_head has been executed
  221. *
  222. * @since 4.5.5
  223. * @var boolean
  224. */
  225. public $wp_head_done;
  226.  
  227. /**
  228. * Flag if action get_sidebar has been executed
  229. *
  230. * @since 4.5.5
  231. * @var boolean
  232. */
  233. public $wp_sidebar_started;
  234.  
  235. /**
  236. * Flag if action get_footer has been executed
  237. *
  238. * @since 4.5.5
  239. * @var boolean
  240. */
  241. public $wp_footer_started;
  242.  
  243. /**
  244. * Contains registered admin scripts for shortcodes to be enqueued after main admin scripts
  245. *
  246. * @since 4.5.7.1
  247. * @var array
  248. */
  249. protected $registered_admin_scripts;
  250.  
  251. /**
  252. * Contains registered admin CSS for shortcodes to be enqueued after main admin CSS
  253. *
  254. * @since 4.5.7.1
  255. * @var array
  256. */
  257. protected $registered_admin_styles;
  258.  
  259.  
  260. /**
  261. * Return the instance of this class
  262. *
  263. * @since 4.2.1
  264. * @return AviaBuilder
  265. */
  266. static public function instance()
  267. {
  268. if( is_null( AviaBuilder::$_instance ) )
  269. {
  270. AviaBuilder::$_instance = new AviaBuilder();
  271. }
  272.  
  273. return AviaBuilder::$_instance;
  274. }
  275.  
  276.  
  277. /**
  278. * Initializes plugin variables and sets up WordPress hooks/actions.
  279. *
  280. * @return void
  281. */
  282. protected function __construct()
  283. {
  284. $this->paths = array();
  285. $this->shortcode_class = array();
  286. $this->shortcode = array();
  287. $this->shortcode_usage_blog = array();
  288. $this->shortcode_parents = array();
  289. $this->shortcode_parser = null;
  290. $this->posts_shortcode_parser_state = '';
  291. $this->element_manager = null;
  292. $this->asset_manager_class = null;
  293. $this->tabs = array();
  294. $this->shortcode_buttons = array();
  295. $this->builderTemplate = null;
  296. $this->disable_drag_drop = false;
  297. $this->alb_builder_status = 'unknown';
  298. $this->post_content = '';
  299. $this->revision_id = 0;
  300. $this->alb_magic_wand_button = false;
  301. $this->alb_nonce_added = false;
  302. $this->supported_post_types = array( 'post', 'portfolio', 'page', 'product' );
  303. $this->supported_post_status = array( 'publish', 'private', 'future', 'draft', 'pending' );
  304. $this->may_be_disabled_automatically = array();
  305. $this->disabled_assets = array();
  306. $this->in_text_to_preview = false;
  307. $this->wp_head_done = false;
  308. $this->wp_sidebar_started = false;
  309. $this->wp_footer_started = false;
  310. $this->registered_admin_scripts = array();
  311. $this->registered_admin_styles = array();
  312.  
  313. $this->paths['pluginPath'] = trailingslashit( dirname( dirname( __FILE__ ) ) );
  314. $this->paths['pluginDir'] = trailingslashit( basename( $this->paths['pluginPath'] ) );
  315. $this->paths['pluginUrlRoot'] = apply_filters( 'avia_builder_plugins_url', plugins_url() . '/' . $this->paths['pluginDir'] );
  316. $this->paths['pluginUrl'] = $this->paths['pluginUrlRoot'] . 'avia-template-builder/';
  317. $this->paths['assetsURL'] = trailingslashit( $this->paths['pluginUrl'] ) . 'assets/';
  318. $this->paths['assetsPath'] = trailingslashit( $this->paths['pluginPath'] ) . 'assets/';
  319. $this->paths['imagesURL'] = trailingslashit( $this->paths['pluginUrl'] ) . 'images/';
  320. $this->paths['configPath'] = apply_filters( 'avia_builder_config_path', $this->paths['pluginPath'] . 'config/' );
  321. AviaBuilder::$path = $this->paths;
  322.  
  323. AviaBuilder::$default_iconfont = apply_filters( 'avf_default_iconfont',
  324. array( 'entypo-fontello' =>
  325. array(
  326. 'append' => '',
  327. 'include' => $this->paths['assetsPath'] . 'fonts',
  328. 'folder' => $this->paths['assetsURL'] . 'fonts',
  329. 'config' => 'charmap.php',
  330. 'compat' => 'charmap-compat.php', //needed to make the theme compatible with the old version of the font
  331. 'full_path' => 'true' //tells the script to not prepend the wp_upload dir path to these urls
  332. )
  333. )
  334. );
  335.  
  336. add_action( 'load-post.php', array( $this, 'admin_init') , 5 );
  337. add_action( 'load-post-new.php', array( $this, 'admin_init') , 5 );
  338.  
  339. add_action( 'admin_init', array( $this, 'handler_admin_init' ), 1 );
  340. add_action( 'init', array( $this, 'loadLibraries' ), 5 );
  341. add_action( 'init', array( $this, 'init' ), 10 );
  342. add_action( 'wp', array( $this, 'frontend_asset_check' ), 5 );
  343.  
  344. add_action( 'wp_head', array( $this, 'handler_wp_head' ), 99999999 );
  345. add_action( 'get_sidebar', array( $this, 'handler_get_sidebar' ), 1, 1 );
  346. add_action( 'get_footer', array( $this, 'handler_get_footer' ), 1, 1 );
  347.  
  348.  
  349. //save and restore meta information if user restores a revision
  350. add_action( 'wp_creating_autosave', array( $this, 'avia_builder_creating_autosave' ), 10, 1 );
  351. add_action( '_wp_put_post_revision', array( $this, 'avia_builder_put_revision' ), 10, 1 );
  352. add_action( 'wp_restore_post_revision', array( $this, 'avia_builder_restore_revision' ), 10, 2 );
  353.  
  354. add_filter( 'avia_builder_metabox_filter', array( $this, 'handler_alb_metabox_filter' ), 10, 1 );
  355.  
  356. add_action('dbx_post_sidebar', array( $this, 'handler_wp_dbx_post_sidebar' ), 10, 1 );
  357.  
  358. }
  359.  
  360. /**
  361. *
  362. * @since 4.2.1
  363. */
  364. public function __destruct()
  365. {
  366. unset( $this->paths );
  367. unset( $this->shortcode_class );
  368. unset( $this->shortcode );
  369. unset( $this->shortcode_usage_blog );
  370. unset( $this->shortcode_parents );
  371. unset( $this->shortcode_parser );
  372. unset( $this->element_manager );
  373. unset( $this->asset_manager_class );
  374. unset( $this->tabs );
  375. unset( $this->shortcode_buttons );
  376. unset( $this->builderTemplate );
  377. unset( $this->supported_post_types );
  378. unset( $this->supported_post_status );
  379. unset( $this->may_be_disabled_automatically );
  380. unset( $this->disabled_assets );
  381. unset( $this->registered_admin_scripts );
  382. unset( $this->registered_admin_styles );
  383. }
  384.  
  385. /**
  386. * @since 4.6.4
  387. */
  388. public function handler_admin_init()
  389. {
  390. if( isset( $_REQUEST['avia_export'] ) && isset( $_REQUEST['avia_generate_alb_templates_file'] ) )
  391. {
  392. $this->get_AviaSaveBuilderTemplate();
  393. }
  394. }
  395.  
  396.  
  397. /**
  398. * Flag that wp_head has been executed (hooks with very low priority so other plugins may perform a precompile
  399. * and that does not break our shortcode tree count
  400. *
  401. * @since 4.5.5
  402. */
  403. public function handler_wp_head()
  404. {
  405. $this->wp_head_done = true;
  406.  
  407. /**
  408. * WP5.2 reports a problem: Class ‘ShortcodeHelper’ not found
  409. */
  410. if( class_exists( 'ShortcodeHelper' ) )
  411. {
  412. ShortcodeHelper::$shortcode_index = 0;
  413. }
  414. }
  415.  
  416. /**
  417. * Flag that get_sidebar has been executed (hooks with very high priority)
  418. * This allows us to ignore changing of post id's after loop has finished and we can leave the last shortcode tree
  419. *
  420. * @since 4.5.5
  421. * @param string $name
  422. */
  423. public function handler_get_sidebar( $name )
  424. {
  425. $this->wp_sidebar_started = true;
  426. }
  427.  
  428. /**
  429. * Flag that get_footer has been executed (hooks with very high priority)
  430. * This allows us to ignore changing of post id's after loop has finished and we can leave the last shortcode tree
  431. *
  432. * @since 4.5.5
  433. * @param string $name
  434. */
  435. public function handler_get_footer( $name )
  436. {
  437. $this->wp_footer_started = true;
  438. }
  439.  
  440.  
  441. /**
  442. * After all metaboxes have been added we check if hidden input field avia_nonce_loader had been set.
  443. * If not we have to add it. If user adds a shortcode (like tabs) with magic wand that need to call backend
  444. * check_ajax_referrer cannot proceed in backend because this value is missing
  445. *
  446. * @added_by Günter
  447. * @since 4.2.4
  448. * @param WP_Post $post
  449. */
  450. public function handler_wp_dbx_post_sidebar( WP_Post $post )
  451. {
  452. if( ! $this->alb_magic_wand_button )
  453. {
  454. return;
  455. }
  456.  
  457. if( ! $this->alb_nonce_added )
  458. {
  459. $nonce = wp_create_nonce ('avia_nonce_loader');
  460.  
  461. echo '<input type="hidden" name="avia-loader-nonce" id="avia-loader-nonce" value="' . $nonce . '" />';
  462.  
  463. $this->alb_nonce_added = true;
  464. }
  465. }
  466.  
  467.  
  468. /**
  469. *Load all functions that are needed for both front and backend
  470. **/
  471. public function init()
  472. {
  473. if( isset( $_GET['avia_mode'] ) )
  474. {
  475. AviaBuilder::$mode = esc_attr( $_GET['avia_mode'] );
  476. }
  477.  
  478. //activate the element manager
  479. $this->element_manager();
  480.  
  481. $this->createShortcode();
  482.  
  483. $this->addActions();
  484. AviaStoragePost::generate_post_type();
  485.  
  486. //hook into the media uploader. we always need to call this for several hooks to be active
  487. new AviaMedia();
  488.  
  489. //on ajax call load the functions that are usually only loaded on new post and edit post screen
  490. if( AviaHelper::is_ajax() )
  491. {
  492. if( empty( $_POST['avia_request'] ) )
  493. {
  494. return;
  495. }
  496.  
  497. $this->admin_init();
  498. }
  499.  
  500. //activate asset manager
  501. $this->asset_manager();
  502.  
  503.  
  504. }
  505.  
  506.  
  507. /**
  508. *Load functions that are only needed on add/edit post screen
  509. **/
  510. public function admin_init()
  511. {
  512. $this->addAdminFilters();
  513. $this->addAdminActions();
  514. $this->loadTextDomain();
  515. $this->call_classes();
  516. $this->apply_editor_wrap();
  517. }
  518.  
  519. /**
  520. * Load all the required library files.
  521. */
  522. public function loadLibraries()
  523. {
  524. require_once( $this->paths['pluginPath'] . 'php/pointer.class.php' );
  525. require_once( $this->paths['pluginPath'] . 'php/shortcode-helper.class.php' );
  526. require_once( $this->paths['pluginPath'] . 'php/shortcode-parser.class.php' );
  527. require_once( $this->paths['pluginPath'] . 'php/element-manager.class.php' );
  528. require_once( $this->paths['pluginPath'] . 'php/generic-helper.class.php' );
  529. require_once( $this->paths['pluginPath'] . 'php/html-helper.class.php' );
  530. require_once( $this->paths['pluginPath'] . 'php/meta-box.class.php' );
  531. require_once( $this->paths['pluginPath'] . 'php/shortcode-template.class.php' );
  532. require_once( $this->paths['pluginPath'] . 'php/media.class.php' );
  533. require_once( $this->paths['pluginPath'] . 'php/tiny-button.class.php' );
  534. require_once( $this->paths['pluginPath'] . 'php/save-buildertemplate.class.php' );
  535. require_once( $this->paths['pluginPath'] . 'php/storage-post.class.php' );
  536. require_once( $this->paths['pluginPath'] . 'php/font-manager.class.php' );
  537. require_once( $this->paths['pluginPath'] . 'php/asset-manager.class.php' );
  538. require_once( $this->paths['pluginPath'] . 'php/popup-templates.class.php' );
  539.  
  540.  
  541. //autoload files in shortcodes folder and any other folders that were added by filter
  542. $folders = apply_filters( 'avia_load_shortcodes', array( $this->paths['pluginPath'] . 'php/shortcodes/' ) );
  543. $this->autoloadLibraries( $folders );
  544. }
  545.  
  546. /**
  547. * PHP include all files from a number of folders which are passed as an array
  548. * This auoloads all the shortcodes located in php/shortcodes and any other folders that were added by filter
  549. */
  550. protected function autoloadLibraries( $paths )
  551. {
  552. foreach( $paths as $path )
  553. {
  554. //include modules (eg files within folders with the same name)
  555. foreach( glob( $path . '*', GLOB_ONLYDIR ) as $folder )
  556. {
  557. $php_file = trailingslashit( $folder ) . basename( $folder ) . '.php';
  558.  
  559. if( file_exists( $php_file ) )
  560. {
  561. include( $php_file );
  562. }
  563. }
  564.  
  565. //include single files
  566. foreach( glob( $path . '*.php' ) as $file )
  567. {
  568. require_once( $file );
  569. }
  570. }
  571. }
  572.  
  573.  
  574. /**
  575. * Add filters to various wordpress filter hooks
  576. */
  577. protected function addAdminFilters()
  578. {
  579. /**
  580. * lock drag and drop?
  581. *
  582. * @used_by functions-enfold.php avia_disable_alb_drag_drop() 30
  583. * @param boolean
  584. * @return boolean
  585. */
  586. $this->disable_drag_drop = apply_filters( 'avf_allow_drag_drop', false );
  587.  
  588. // add_filter('tiny_mce_before_init', array($this, 'tiny_mce_helper')); // remove span tags from tinymce - currently disabled, doesnt seem to be necessary
  589. add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
  590. }
  591.  
  592. /**
  593. * Add Admin Actions to some wordpress action hooks
  594. */
  595. protected function addAdminActions()
  596. {
  597. add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts_styles' ) );
  598. add_action( 'admin_enqueue_scripts', array( $this, 'handler_admin_dequeue_scripts' ), 99999 );
  599. add_action( 'admin_print_scripts', array( $this,'load_shortcode_assets' ), 2000 );
  600. add_action( 'print_media_templates', array( $this, 'js_template_editor_elements' ) ); //create js templates for AviaBuilder Canvas Elements
  601. add_action( 'avia_save_post_meta_box', array( $this, 'meta_box_save' ) ); //hook into meta box saving and store the status of the template builder and the shortcodes that are used
  602.  
  603. add_filter( 'avf_before_save_alb_post_data', array( $this, 'handler_before_save_alb_post_data' ), 10, 2 ); // hook to balance shortcode for non ALB pages
  604.  
  605. //custom ajax actions
  606. add_action( 'wp_ajax_avia_ajax_text_to_interface', array( $this, 'text_to_interface' ) );
  607. add_action( 'wp_ajax_avia_ajax_text_to_preview', array( $this, 'text_to_preview' ) );
  608. add_action( 'wp_ajax_avia_alb_shortcode_buttons_order', array( $this, 'handler_alb_shortcode_buttons_order' ), 10 );
  609. }
  610.  
  611.  
  612. /**
  613. * Add Actions for the frontend
  614. */
  615. protected function addActions()
  616. {
  617.  
  618. // Enable shortcodes in widget areas
  619. add_filter( 'widget_text', 'do_shortcode' );
  620.  
  621. //default wordpress hooking
  622. add_action( 'wp_head', array( $this, 'load_shortcode_assets' ), 2000 );
  623. add_filter( 'template_include' , array( $this, 'template_include' ), 20000 );
  624. }
  625.  
  626. /**
  627. * Automatically load assests like fonts into your frontend
  628. */
  629. public function load_shortcode_assets()
  630. {
  631. $output = '';
  632. $output .= avia_font_manager::load_font();
  633.  
  634. /* if the builder is decoupled from the theme then make sure to only load iconfonts if they are actually necessary. in enfolds case it is
  635.  
  636. foreach( AviaBuilder::$resources_to_load as $element )
  637. {
  638. if( $element['type'] == 'iconfont' )
  639. {
  640. $output .= avia_font_manager::load_font();
  641. }
  642. }
  643. */
  644.  
  645. echo $output;
  646.  
  647. //output preview css paths
  648. if( is_admin() )
  649. {
  650. echo $this->load_preview_css( $output );
  651. }
  652. }
  653.  
  654. /**
  655. * Adds registered shortcode admin script handles to array. Allows to enqueue them on edit pages only.
  656. * Avoids problems with e.g. WooCommerce that manipulates the enqueue array to preload scripts.
  657. *
  658. * @since 4.7.5.2
  659. * @param string $handle
  660. */
  661. public function add_registered_admin_script( $handle )
  662. {
  663. if( ! in_array( $handle, $this->registered_admin_scripts ) )
  664. {
  665. $this->registered_admin_scripts[] = $handle;
  666. }
  667. }
  668.  
  669. /**
  670. * Adds registered shortcode admin script handles to array. Allows to enqueue them on edit pages only.
  671. * Avoids problems with e.g. WooCommerce that manipulates the enqueue array to preload scripts.
  672. *
  673. * @since 4.7.5.2
  674. * @param string $handle
  675. */
  676. public function add_registered_admin_style( $handle )
  677. {
  678. if( ! in_array( $handle, $this->registered_admin_styles ) )
  679. {
  680. $this->registered_admin_styles[] = $handle;
  681. }
  682. }
  683.  
  684. /**
  685. * load css and js files when in editable mode
  686. */
  687. public function admin_scripts_styles()
  688. {
  689. global $wp_version;
  690. $ver = $wp_version . "-" . AviaBuilder::VERSION;
  691.  
  692. #js
  693. wp_enqueue_script( 'avia_builder_js', $this->paths['assetsURL'] . 'js/avia-builder.js', array( 'jquery', 'jquery-ui-core', 'jquery-ui-sortable', 'jquery-ui-droppable', 'jquery-ui-datepicker', 'wp-color-picker', 'media-editor', 'post' ), $ver, true );
  694. wp_enqueue_script( 'avia_element_js', $this->paths['assetsURL'] . 'js/avia-element-behavior.js' , array( 'avia_builder_js' ), $ver, true );
  695. wp_enqueue_script( 'avia_modal_js', $this->paths['assetsURL'] . 'js/avia-modal.js' , array( 'jquery', 'avia_element_js', 'wp-color-picker' ), $ver, true );
  696. wp_enqueue_script( 'avia_history_js', $this->paths['assetsURL'] . 'js/avia-history.js' , array( 'avia_element_js' ), $ver, true );
  697. wp_enqueue_script( 'avia_tooltip_js', $this->paths['assetsURL'] . 'js/avia-tooltip.js' , array( 'avia_element_js' ), $ver, true );
  698.  
  699. foreach( $this->registered_admin_scripts as $script )
  700. {
  701. wp_enqueue_script( $script );
  702. }
  703.  
  704. #css
  705. wp_enqueue_style( 'avia-modal-style' , $this->paths['assetsURL'].'css/avia-modal.css', false, $ver);
  706. wp_enqueue_style( 'avia-builder-style' , $this->paths['assetsURL'].'css/avia-builder.css', false, $ver);
  707. wp_enqueue_style( 'wp-color-picker' );
  708.  
  709. /**
  710. * @since 4.2.3 we support columns in rtl order (before they were ltr only). To be backward comp. with old sites use this filter.
  711. */
  712. if( is_rtl() && ( 'yes' == apply_filters( 'avf_rtl_column_support', 'yes' ) ) )
  713. {
  714. wp_enqueue_style( 'avia-builder-rtl-style' , $this->paths['assetsURL'].'css/avia-builder-rtl.css');
  715. }
  716.  
  717. foreach( $this->registered_admin_styles as $style )
  718. {
  719. wp_enqueue_style( $style );
  720. }
  721.  
  722. #localize strings for javascript
  723. include_once( $this->paths['configPath'] . 'javascript_strings.php' );
  724.  
  725. if( ! empty( $strings ) )
  726. {
  727. foreach( $strings as $key => $string )
  728. {
  729. wp_localize_script( $key, str_replace( '_js', '_L10n', $key ), $string );
  730. }
  731. }
  732.  
  733. }
  734.  
  735. /**
  736. * @since 4.6.7.4-beta-2
  737. */
  738. public function handler_admin_dequeue_scripts()
  739. {
  740. $screen = get_current_screen();
  741.  
  742. if( ! $screen instanceof WP_Screen )
  743. {
  744. return;
  745. }
  746.  
  747. if( $screen->base == 'post' )
  748. {
  749. /**
  750. * @since WP 5.5 we need to dequeue this script as it blocks space bar
  751. *
  752. * Bug reported with RevSlider - but could be found with every other plugin which enqueues \wp-admin\js\updates.min.js
  753. * https://github.com/KriesiMedia/wp-themes/issues/2949#issuecomment-681851213
  754. */
  755. wp_dequeue_script( 'updates' );
  756. }
  757. }
  758.  
  759. /**
  760. *
  761. * @param string $icon_font
  762. * @param string $css
  763. * @return string
  764. */
  765. public function load_preview_css( $icon_font = '', $css = '' )
  766. {
  767. $output = '';
  768. $template_url = get_template_directory_uri();
  769. $child_theme_url = get_stylesheet_directory_uri();
  770. $avia_dyn_stylesheet_url = false;
  771. $ver = AviaBuilder::VERSION;
  772.  
  773. global $avia;
  774.  
  775. $safe_name = avia_backend_safe_string( $avia->base_data['prefix'] );
  776. $safe_name = apply_filters( 'avf_dynamic_stylesheet_filename', $safe_name );
  777.  
  778. if( get_option( 'avia_stylesheet_exists' . $safe_name ) == 'true' )
  779. {
  780. $avia_upload_dir = wp_upload_dir();
  781.  
  782. /**
  783. * Change the default dynamic upload url
  784. *
  785. * @since 4.4
  786. */
  787. $avia_dyn_upload_path = apply_filters( 'avf_dyn_stylesheet_dir_url', $avia_upload_dir['baseurl'] . '/dynamic_avia' );
  788. $avia_dyn_upload_path = trailingslashit( $avia_dyn_upload_path );
  789.  
  790. if( is_ssl() )
  791. {
  792. $avia_dyn_upload_path = str_replace( 'http://', 'https://', $avia_dyn_upload_path );
  793. }
  794.  
  795. /**
  796. * Change the default dynamic stylesheet name
  797. *
  798. * @since 4.4
  799. */
  800. $avia_dyn_stylesheet_url = apply_filters( 'avf_dyn_stylesheet_file_url', $avia_dyn_upload_path . $safe_name . '.css' );
  801. }
  802.  
  803. $google_fonts = array(
  804. avia_get_option( 'google_webfont' ),
  805. avia_get_option( 'default_font' )
  806. );
  807.  
  808. foreach( $google_fonts as $font )
  809. {
  810. $font_weight = '';
  811.  
  812. if( strpos( $font, ':' ) !== false )
  813. {
  814. $data = explode( ':', $font );
  815. $font = $data[0];
  816. $font_weight = $data[1];
  817. }
  818.  
  819. if( strpos( $font, 'websave' ) === false )
  820. {
  821. $avia->style->add_google_font( $font, $font_weight );
  822. }
  823. }
  824.  
  825. //if no user defined css is available load all the default frontend css
  826. if( empty( $css ) )
  827. {
  828. $css = array(
  829. includes_url('/js/mediaelement/mediaelementplayer-legacy.min.css') => 1,
  830. includes_url('/js/mediaelement/wp-mediaelement.css?ver=4.9.4') => 1,
  831.  
  832. $template_url . '/css/grid.css' => 1,
  833. $template_url . '/css/base.css' => 1,
  834. $template_url . '/css/layout.css' => 1,
  835. $template_url . '/css/shortcodes.css' => 1,
  836. $template_url . '/js/aviapopup/magnific-popup.css' => 1,
  837. $template_url . '/css/rtl.css' => is_rtl(),
  838. $child_theme_url . '/style.css' => $template_url != $child_theme_url,
  839. );
  840.  
  841. // iterate over template builder modules and load the default css in there as well.
  842. // hakish approach that might need refinement if we improve the backend preview
  843. $path = trailingslashit( dirname( $this->paths['pluginPath'] ) ) . 'avia-shortcodes/';
  844.  
  845. foreach( glob( $path . '*', GLOB_ONLYDIR ) as $folder )
  846. {
  847. $css_file = trailingslashit($folder) . basename($folder) . '.css';
  848. $css_url = trailingslashit( $this->paths['pluginUrlRoot'] ) . 'avia-shortcodes/' . basename( $folder ) . '/' . basename( $folder ) . '.css';
  849.  
  850. if( file_exists( $css_file ) )
  851. {
  852. $css[ $css_url ] = 1;
  853. }
  854. }
  855.  
  856. //custom user css, overwriting our styles
  857. $css[ $template_url. '/css/custom.css' ] = 1;
  858. $css[ $avia_dyn_stylesheet_url ] = $avia_dyn_stylesheet_url;
  859. $css[ $template_url . '/css/admin-preview.css' ] = 1;
  860.  
  861. $css = apply_filters( 'avf_preview_window_css_files' , $css );
  862. }
  863.  
  864. //module css
  865. if( is_array( $css ) )
  866. {
  867. foreach( $css as $url => $load )
  868. {
  869. if( $load )
  870. {
  871. $output .= "<link rel='stylesheet' href='{$url}?ver={$ver}' type='text/css' media='all' />";
  872. }
  873. }
  874. }
  875.  
  876. $output .= "<script type='text/javascript' src='" . includes_url( '/js/jquery/jquery.js' ). "?ver={$ver}'></script>";
  877. $output .= "<script type='text/javascript' src='" . $template_url . "/js/avia-admin-preview.js?ver={$ver}'></script>";
  878. $output .= $avia->style->link_google_font();
  879.  
  880. $error = __('It seems you are currently adding some HTML markup or other special characters. Once all HTML tags are closed the preview will be available again. If this message persists please check your input for special characters and try to remove them.', 'avia_framework' );
  881. $html = "<script type='text/javascript'>var avia_preview = " . json_encode( array( 'error' => $error, 'paths' => $output.$icon_font, 'title' => __( 'Element Preview', 'avia_framework' ) , 'background' => __( 'Set preview background:', 'avia_framework' ), 'scale' => __( 'Scaled to:', 'avia_framework' ) ) ) . "; \n";
  882. $html .= '</script>';
  883.  
  884. return $html;
  885. }
  886.  
  887. /**
  888. *multilanguage activation
  889. **/
  890. public function loadTextDomain()
  891. {
  892. load_plugin_textdomain( 'avia_framework', false, $this->paths['pluginDir'] . 'lang/');
  893. }
  894.  
  895. /**
  896. *safe mode or debugging
  897. **/
  898. public function setMode( $status = '' )
  899. {
  900. AviaBuilder::$mode = apply_filters( 'avia_builder_mode', $status );
  901. }
  902.  
  903. /**
  904. * Creates and returns instance of AviaSaveBuilderTemplate
  905. *
  906. * @since 4.6.4
  907. * @return AviaSaveBuilderTemplate
  908. */
  909. public function get_AviaSaveBuilderTemplate()
  910. {
  911. if( ! $this->builderTemplate instanceof AviaSaveBuilderTemplate )
  912. {
  913. $this->builderTemplate = new AviaSaveBuilderTemplate( $this );
  914. }
  915.  
  916. return $this->builderTemplate;
  917. }
  918.  
  919. /**
  920. * Returns the instance of ShortcodeParser
  921. *
  922. * @since 4.2.1
  923. * @return ShortcodeParser
  924. */
  925. public function get_shortcode_parser()
  926. {
  927. if( is_null( $this->shortcode_parser ) )
  928. {
  929. $this->shortcode_parser = new ShortcodeParser( $this->get_posts_shortcode_parser_state() );
  930. }
  931.  
  932. return $this->shortcode_parser;
  933. }
  934.  
  935. /**
  936. * Returns a filtered array of supported post types
  937. *
  938. * @since 4.3
  939. * @return array
  940. */
  941. public function get_supported_post_types()
  942. {
  943. return apply_filters( 'avf_alb_supported_post_types', $this->supported_post_types );
  944. }
  945.  
  946. /**
  947. * Returns a filtered array of supported post status
  948. *
  949. * @since 4.4.1
  950. * @return array
  951. */
  952. public function get_supported_post_status()
  953. {
  954. return apply_filters( 'avf_alb_supported_post_status', $this->supported_post_status );
  955. }
  956.  
  957. /**
  958. * Returns the state for the shortcode parser for the current or given post
  959. *
  960. * @since 4.2.1
  961. * @param int|null $post_id
  962. * @param string $default
  963. * @return string 'disabled' | 'check_only' | 'auto_repair'
  964. */
  965. public function get_posts_shortcode_parser_state( $post_id = null, $default = 'disabled' )
  966. {
  967.  
  968. if( is_null( $post_id ) || ! is_numeric( $post_id ) )
  969. {
  970. if( ! empty( $this->posts_shortcode_parser_state ) )
  971. {
  972. return $this->posts_shortcode_parser_state;
  973. }
  974.  
  975. $post_id = isset( $_POST['post_ID'] ) ? (int)$_POST['post_ID'] : get_the_ID();
  976. }
  977.  
  978. if( ! in_array( $default, array( 'disabled', 'check_only', 'auto_repair' ) ) )
  979. {
  980. $default = 'disabled';
  981. }
  982.  
  983. if( false !== $post_id )
  984. {
  985. $this->posts_shortcode_parser_state = get_post_meta( $post_id, '_avia_sc_parser_state', true );
  986. }
  987.  
  988. if( empty( $this->posts_shortcode_parser_state ) )
  989. {
  990. $this->posts_shortcode_parser_state = $default;
  991. }
  992.  
  993. return $this->posts_shortcode_parser_state;
  994. }
  995.  
  996.  
  997. /**
  998. * Updates the state for the shortcode parser for the current or given post and
  999. * returns the actual value stored in DB
  1000. *
  1001. * @since 4.2.1
  1002. * @param string $state 'disabled' | 'check_only' | 'auto_repair'
  1003. * @param int|null $post_id
  1004. * @param $save_to_revision boolean
  1005. * @return string
  1006. */
  1007. public function set_posts_shortcode_parser_state( $state = '', $post_id = null, $save_to_revision = false )
  1008. {
  1009. if( ! in_array( $state, array( 'disabled', 'check_only', 'auto_repair' ) ) )
  1010. {
  1011. $state = 'check_only';
  1012. }
  1013.  
  1014. $this->posts_shortcode_parser_state = $state;
  1015.  
  1016. if( is_null( $post_id ) || ! is_numeric( $post_id ) )
  1017. {
  1018. $post_id = isset( $_POST['post_ID'] ) ? (int)$_POST['post_ID'] : get_the_ID();
  1019. }
  1020.  
  1021. if( false !== $post_id )
  1022. {
  1023. if( $save_to_revision === false )
  1024. {
  1025. update_post_meta( $post_id, '_avia_sc_parser_state', $this->posts_shortcode_parser_state );
  1026. }
  1027. else
  1028. {
  1029. update_metadata( 'post', $post_id, '_avia_sc_parser_state', $this->posts_shortcode_parser_state );
  1030. }
  1031. }
  1032.  
  1033. return $this->posts_shortcode_parser_state;
  1034. }
  1035.  
  1036. /**
  1037. * Returns option settings
  1038. * Reduced in 4.6.4 to a single option for all developer input fields and only 2 options:
  1039. * - hide input fields but entered input
  1040. * - show input fields
  1041. *
  1042. * @since 4.5.7.2
  1043. * @param string $setting
  1044. * @return string|false depends on which setting
  1045. */
  1046. public function get_developer_settings( $setting = '' )
  1047. {
  1048. $option_value = avia_get_option( 'alb_developer_options', '' );
  1049.  
  1050. if( $option_value == 'alb_developer_options')
  1051. {
  1052. $option_value = 'hide';
  1053. }
  1054. else
  1055. {
  1056. $option_value = 'show';
  1057. }
  1058.  
  1059.  
  1060. $value = '';
  1061.  
  1062. switch( $setting )
  1063. {
  1064. case 'custom_css':
  1065. $value = 'show' == $option_value ? 'developer_options' : $option_value;
  1066. break;
  1067. case 'custom_id':
  1068. $value = 'show' == $option_value ? 'developer_id_attribute' : $option_value;
  1069. break;
  1070. case 'heading_tags':
  1071. $value = 'show' == $option_value ? 'developer_seo_heading_tags' : $option_value;
  1072. break;
  1073. case 'aria_label':
  1074. $value = 'show' == $option_value ? 'developer_aria_label' : $option_value;
  1075. break;
  1076. case 'alb_desc_id':
  1077. $value = 'show' == $option_value ? 'developer_alb_desc_id' : $option_value;
  1078. break;
  1079. default:
  1080. $value = false;
  1081. }
  1082.  
  1083.  
  1084. /**
  1085. * In 4.6.4 option Do not show, ignore ... has been removed
  1086. * You can use this filter to implement a fallback to the old solution.
  1087. * https://github.com/KriesiMedia/enfold-library/blob/master/actions%20and%20filters/ALB%20Elements/Editing%20ALB%20elements/avf_alb_get_developer_settings.php
  1088. *
  1089. * @since 4.5.7.2
  1090. * @param string|false $value
  1091. * @param string $setting
  1092. * @param string $option_value added 4.6.4
  1093. * @return string|false
  1094. */
  1095. return apply_filters( 'avf_alb_get_developer_settings', $value, $setting, $option_value );
  1096. }
  1097.  
  1098. /**
  1099. * Returns the state of the ALB for a given post id.
  1100. * If null, checks for $_POST['aviaLayoutBuilder_active'] or the current post id.
  1101. *
  1102. * @since 4.2.1
  1103. * @param int|null $post_id
  1104. * @param string $default 'active' | ''
  1105. * @return string
  1106. */
  1107. public function get_alb_builder_status( $post_id = null, $default = '' )
  1108. {
  1109. if( is_null( $post_id ) )
  1110. {
  1111. /**
  1112. * Check if we are on an edit page
  1113. */
  1114. if( isset( $_POST['aviaLayoutBuilder_active'] ) )
  1115. {
  1116. $builder_status = $_POST['aviaLayoutBuilder_active'];
  1117. if( ! in_array( $builder_status, array( 'active', '' ) ) )
  1118. {
  1119. $builder_status = $default;
  1120. }
  1121.  
  1122. return $builder_status;
  1123. }
  1124.  
  1125. /**
  1126. * If set, return the saved value
  1127. */
  1128. if( 'unknown' != $this->alb_builder_status )
  1129. {
  1130. return $this->alb_builder_status;
  1131. }
  1132. }
  1133.  
  1134. $id = ! is_null( $post_id ) ? $post_id : get_the_ID();
  1135.  
  1136. if( false === $id )
  1137. {
  1138. return $default;
  1139. }
  1140.  
  1141. $status = get_post_meta( $id, '_aviaLayoutBuilder_active', true );
  1142.  
  1143. /**
  1144. * Allows to filter the status
  1145. *
  1146. * @used_by enfold\config-woocommerce\config.php 10
  1147. */
  1148. $status = apply_filters( 'avf_builder_active', $status, $id );
  1149.  
  1150. return $status;
  1151. }
  1152.  
  1153. /**
  1154. * Set the builder status for the current or a given post id
  1155. *
  1156. * @since 4.2.1
  1157. * @param string $status 'active' | ''
  1158. * @param int|null $post_id
  1159. * @param string $default 'active' | ''
  1160. * @param type $save_to_revision boolean
  1161. * @return boolean
  1162. */
  1163. public function set_alb_builder_status( $status = '', $post_id = null, $default = '', $save_to_revision = false )
  1164. {
  1165. if( ! in_array( $status, array( 'active', '' ) ) )
  1166. {
  1167. $status = $default;
  1168. }
  1169.  
  1170. $id = ! is_null( $post_id ) ? $post_id : get_the_ID();
  1171.  
  1172. if( is_null( $post_id ) )
  1173. {
  1174. $this->alb_builder_status = $status;
  1175. }
  1176.  
  1177. if( false === $id )
  1178. {
  1179. return false;
  1180. }
  1181.  
  1182. if( $save_to_revision === false )
  1183. {
  1184. update_post_meta( $id, '_aviaLayoutBuilder_active', $status );
  1185. }
  1186. else
  1187. {
  1188. update_metadata( 'post', $id, '_aviaLayoutBuilder_active', $status );
  1189. }
  1190.  
  1191. return true;
  1192. }
  1193.  
  1194.  
  1195. /**
  1196. * Returns the ALB shortcodes for the requested post
  1197. *
  1198. * @since 4.2.3
  1199. * @param int $post_id
  1200. * @return string
  1201. */
  1202. public function get_posts_alb_content( $post_id )
  1203. {
  1204. /**
  1205. * @since 4.5.5
  1206. * @return string
  1207. */
  1208. return apply_filters( 'avf_posts_alb_content', get_post_meta( $post_id, '_aviaLayoutBuilderCleanData', true ), $post_id );
  1209. }
  1210.  
  1211. /**
  1212. * Returns the correct content for a page/post/...
  1213. * ALB content, post content (or in future releases any ALB structure)
  1214. *
  1215. * @since 4.3
  1216. * @param int $post_id
  1217. * @param WP_Post $post
  1218. * @return string|false
  1219. */
  1220. public function get_post_content( $post_id, $post = null )
  1221. {
  1222. $builder_stat = $this->get_alb_builder_status( $post_id );
  1223.  
  1224. if( 'active' == $builder_stat )
  1225. {
  1226. return $this->get_posts_alb_content( $post_id );
  1227. }
  1228.  
  1229. if( is_null( $post ) || ( ! $post instanceof WP_Post ) )
  1230. {
  1231. $post = get_post( $post_id );
  1232. }
  1233.  
  1234. if( $post instanceof WP_Post )
  1235. {
  1236. return $post->post_content;
  1237. }
  1238.  
  1239. return false;
  1240. }
  1241.  
  1242. /**
  1243. * Updates the ALB or normal post content depending on ALB status
  1244. *
  1245. * @since 4.3
  1246. * @param int $post_id
  1247. * @param string $content
  1248. */
  1249. public function update_post_content( $post_id, $content )
  1250. {
  1251. $builder_stat = $this->get_alb_builder_status( $post_id );
  1252.  
  1253. if( 'active' == $builder_stat )
  1254. {
  1255. $this->save_posts_alb_content( $post_id, $content );
  1256.  
  1257. /**
  1258. * @used_by currently unused
  1259. * @since 4.5.2
  1260. */
  1261. do_action( 'ava_builder_updated_posts_alb_content', $post_id, $content );
  1262. }
  1263. else
  1264. {
  1265. $new_data = array(
  1266. 'ID' => $post_id,
  1267. 'post_content' => $content
  1268. );
  1269.  
  1270. wp_update_post( $new_data );
  1271. }
  1272. }
  1273.  
  1274. /**
  1275. * Save the ALB shortcodes for the given post in the post meta field
  1276. *
  1277. * @since 4.2.3
  1278. * @param int $post_id
  1279. * @param string $content
  1280. * @param $save_to_revision boolean
  1281. * @return boolean
  1282. */
  1283. public function save_posts_alb_content( $post_id, $content, $save_to_revision = false )
  1284. {
  1285. if( $save_to_revision === false )
  1286. {
  1287. return update_post_meta( $post_id, '_aviaLayoutBuilderCleanData', $content );
  1288. }
  1289. else
  1290. {
  1291. return update_metadata( 'post', $post_id, '_aviaLayoutBuilderCleanData', $content );
  1292. }
  1293. }
  1294.  
  1295. /**
  1296. * Returns the shortcode tree postmeta
  1297. *
  1298. * @since 4.5.1
  1299. * @param int $post_id
  1300. * @return array
  1301. */
  1302. public function get_shortcode_tree( $post_id )
  1303. {
  1304. $tree = get_post_meta( $post_id, '_avia_builder_shortcode_tree', true );
  1305. return is_array( $tree ) ? $tree : array();
  1306. }
  1307.  
  1308. /**
  1309. * Saves the shortcode tree in the postmeta
  1310. *
  1311. * @since 4.5.1
  1312. * @param int $post_id
  1313. * @param array $tree
  1314. * @param $save_to_revision boolean
  1315. * @return boolean
  1316. */
  1317. public function save_shortcode_tree( $post_id, array $tree, $save_to_revision = false )
  1318. {
  1319. if( $save_to_revision === false )
  1320. {
  1321. return update_post_meta( $post_id, '_avia_builder_shortcode_tree', $tree );
  1322. }
  1323.  
  1324. return update_metadata( 'post', $post_id, '_avia_builder_shortcode_tree', $tree );
  1325. }
  1326.  
  1327. /**
  1328. * Allows to set the post revision ID manually
  1329. * (needed when posts are saved via REST API - since WP 5.0 and Gutenberg)
  1330. *
  1331. * @since 4.5.1
  1332. * @param int $post_id
  1333. */
  1334. public function set_revision_id( $post_id )
  1335. {
  1336. $this->revision_id = $post_id;
  1337. }
  1338.  
  1339. /**
  1340. * Store information in user meta data
  1341. *
  1342. * @since 4.6.4
  1343. * @param string $info
  1344. * @param mixed $value
  1345. * @return boolean
  1346. */
  1347. public function set_backend_user_info( $info = '', $value = '' )
  1348. {
  1349. if( ! is_user_logged_in() )
  1350. {
  1351. return false;
  1352. }
  1353.  
  1354. $user_id = get_current_user_id();
  1355.  
  1356. $meta = get_user_meta( $user_id, 'avia_alb_meta', true );
  1357. if( ! is_array( $meta ) )
  1358. {
  1359. $meta = array();
  1360. }
  1361.  
  1362. $result = true;
  1363.  
  1364. switch( $info )
  1365. {
  1366. case 'sc_sort_order':
  1367. $meta[ $info ] = $value;
  1368. break;
  1369. default:
  1370. $result = false;
  1371. break;
  1372. }
  1373.  
  1374. if( $result )
  1375. {
  1376. update_user_meta( $user_id, 'avia_alb_meta', $meta );
  1377. }
  1378.  
  1379. return $result;
  1380. }
  1381.  
  1382. /**
  1383. * Returns user info stored in user meta
  1384. *
  1385. * @since 4.6.4
  1386. * @param string $info 'sc_sort_order'
  1387. * @return mixed|false
  1388. */
  1389. public function get_backend_user_info( $info = '' )
  1390. {
  1391. if( ! is_user_logged_in() )
  1392. {
  1393. return false;
  1394. }
  1395.  
  1396. $user_id = get_current_user_id();
  1397.  
  1398. $meta = get_user_meta( $user_id, 'avia_alb_meta', true );
  1399.  
  1400. $result = false;
  1401. switch( $info )
  1402. {
  1403. case 'sc_sort_order':
  1404. return isset( $meta[ $info ] ) ? $meta[ $info ] : false;
  1405. default:
  1406. break;
  1407. }
  1408.  
  1409. return $result;
  1410. }
  1411.  
  1412. /**
  1413. * Callback to store user selection of sort order for alb shortcodes in editor
  1414. *
  1415. * @since 4.6.4
  1416. */
  1417. public function handler_alb_shortcode_buttons_order()
  1418. {
  1419. header( 'Content-Type: application/json' );
  1420.  
  1421. $return = check_ajax_referer( 'avia_nonce_loader', '_ajax_nonce', false );
  1422. if( ! current_user_can( 'edit_posts' ) )
  1423. {
  1424. $return = false;
  1425. }
  1426.  
  1427. // response output
  1428. $response = array( '_ajax_nonce' => wp_create_nonce( 'avia_nonce_loader' ) );
  1429.  
  1430. /**
  1431. * Return error and allow to resend data
  1432. */
  1433. if( false === $return )
  1434. {
  1435. $response['success'] = false;
  1436. $response['expired_nonce'] = true;
  1437. echo json_encode( $response );
  1438. exit;
  1439. }
  1440.  
  1441. $sorting = isset( $_REQUEST['sorting'] ) ? $_REQUEST['sorting'] : 'order';
  1442. $this->set_backend_user_info( 'sc_sort_order', $sorting );
  1443.  
  1444. $response['success'] = true;
  1445. echo json_encode( $response );
  1446. exit;
  1447. }
  1448.  
  1449. /**
  1450. *set fullwidth elements that need to interact with section shortcode
  1451. */
  1452. public function setFullwidthElements( $elements = array() )
  1453. {
  1454. $elements = apply_filters( 'avf_fwd_elements', $elements );
  1455.  
  1456. AviaBuilder::$full_el_no_section = $elements;
  1457. AviaBuilder::$full_el = array_merge( array( 'av_section' ), $elements );
  1458. }
  1459.  
  1460.  
  1461.  
  1462. /**
  1463. *calls external classes that are needed for the script to operate
  1464. */
  1465. public function call_classes()
  1466. {
  1467. //create the meta boxes
  1468. new MetaBoxBuilder( $this->paths['configPath'] );
  1469.  
  1470. // save button
  1471. $this->get_AviaSaveBuilderTemplate();
  1472.  
  1473. //activate helper function hooks
  1474. AviaHelper::backend();
  1475.  
  1476. /**
  1477. * Create the linebreak button
  1478. */
  1479. $tiny_lb = array(
  1480. 'id' => 'av_builder_linebreak',
  1481. 'title' => __( 'Permanent Line Break', 'avia_framework' ),
  1482. 'access_key' => apply_filters( 'avf_access_key_tinymce', 'ctrl+alt+n', 'av_builder_linebreak' ),
  1483. 'content_open' => '\r\n<br class="avia-permanent-lb" />',
  1484. 'image' => $this->paths['imagesURL'] . 'tiny_line_break.png',
  1485. 'js_plugin_file' => $this->paths['assetsURL'] . 'js/avia-tinymce-linebreak.js',
  1486. 'qtag_content_open' => '\r\n<br class="avia-permanent-lb" />',
  1487. 'qtag_display' => __( 'Line Break', 'avia_framework' ),
  1488. 'shortcodes' => array()
  1489. );
  1490.  
  1491. new avia_tinyMCE_button( $tiny_lb );
  1492.  
  1493. //create tiny mce button
  1494. $tiny = array(
  1495. 'id' => 'avia_builder_button',
  1496. 'title' => __( 'Insert Theme Shortcode', 'avia_framework' ),
  1497. 'image' => $this->paths['imagesURL'] . 'tiny-button.png',
  1498. 'js_plugin_file' => $this->paths['assetsURL'] . 'js/avia-tinymce-buttons.js',
  1499. 'shortcodes' => array_map( array( $this, 'fetch_configs' ), $this->shortcode_class )
  1500. );
  1501.  
  1502. //if we are using tinymce 4 or higher change the javascript file
  1503. global $tinymce_version;
  1504.  
  1505. if( version_compare( $tinymce_version[0], 4, '>=' ) )
  1506. {
  1507. $tiny['js_plugin_file'] = $this->paths['assetsURL'] . 'js/avia-tinymce-buttons-4.js';
  1508. }
  1509.  
  1510. new avia_tinyMCE_button( $tiny );
  1511. $this->alb_magic_wand_button = true;
  1512.  
  1513. //activate iconfont manager
  1514. new avia_font_manager();
  1515.  
  1516. //fetch all Wordpress pointers that help the user to use the builder
  1517. include( $this->paths['configPath'] . 'pointers.php' );
  1518.  
  1519. $myPointers = new AviaPointer( $pointers );
  1520. }
  1521.  
  1522. /**
  1523. *
  1524. * @since 4.2.3
  1525. * @return aviaAssetManager
  1526. */
  1527. public function asset_manager()
  1528. {
  1529. if( empty( $this->asset_manager_class ) )
  1530. {
  1531. //activate asset_manager
  1532. $this->asset_manager_class = new aviaAssetManager( $this );
  1533. }
  1534.  
  1535. return $this->asset_manager_class;
  1536. }
  1537.  
  1538. /**
  1539. * Get instance of the element manager
  1540. *
  1541. * @since 4.3
  1542. * @return aviaElementManager
  1543. */
  1544. public function element_manager()
  1545. {
  1546. if( empty( $this->element_manager ) )
  1547. {
  1548. //activate element_manager
  1549. $this->element_manager = new aviaElementManager();
  1550. }
  1551.  
  1552. return $this->element_manager;
  1553. }
  1554.  
  1555.  
  1556. /**
  1557. * allows to filter which shortcode assets to display in the frontend. waits for the 'wp' hook so the post id is already available
  1558. *
  1559. * @since 4.3
  1560. */
  1561. public function frontend_asset_check()
  1562. {
  1563. //before creating shortcodes allow to filter the assets that are loaded in the frontend
  1564. //pass shortcode names like 'av_video' or 'av_audio' in an array
  1565. $this->disabled_assets = apply_filters( 'avf_disable_frontend_assets', $this->disabled_assets );
  1566.  
  1567. /**
  1568. * Enable additional elements needed for parser info page
  1569. */
  1570. if( isset( $_REQUEST['avia_alb_parser'] ) && ( 'show' == $_REQUEST['avia_alb_parser'] ) && current_user_can( 'edit_post', get_the_ID() ) )
  1571. {
  1572. if( class_exists( 'ShortcodeParser' ) )
  1573. {
  1574. $this->disabled_assets = ShortcodeParser::enable_used_assets( $this->disabled_assets );
  1575. }
  1576. }
  1577. }
  1578.  
  1579.  
  1580. /**
  1581. *array mapping helper that returns the config arrays of a shortcode
  1582. **/
  1583.  
  1584. public function fetch_configs($array)
  1585. {
  1586. return $array->config;
  1587. }
  1588.  
  1589. /**
  1590. * Adds an extra class to the body if the builder is active
  1591. *
  1592. * @param string $classes
  1593. * @return string
  1594. **/
  1595. public function admin_body_class( $classes )
  1596. {
  1597. global $post_ID, $wp_version;
  1598.  
  1599. if( ! empty( $post_ID ) && $this->get_alb_builder_status( $post_ID ) )
  1600. {
  1601. $classes .= ' avia-advanced-editor-enabled ';
  1602. }
  1603.  
  1604. if( version_compare( $wp_version, '5.5', '>=' ) )
  1605. {
  1606. $classes .= ' avia-wp55-fix ';
  1607. }
  1608. else if( version_compare( $wp_version, '5.4', '>=' ) )
  1609. {
  1610. $classes .= ' avia-wp54-fix ';
  1611. }
  1612.  
  1613. if( $this->disable_drag_drop == true )
  1614. {
  1615. $classes .= ' av-no-drag-drop ';
  1616. }
  1617.  
  1618. /**
  1619. * @since 4.2.3 we support columns in rtl order (before they were ltr only). To be backward comp. with old sites use this filter.
  1620. */
  1621. if( is_rtl() && ( 'yes' == apply_filters( 'avf_rtl_column_support', 'yes' ) ) )
  1622. {
  1623. $classes .= ' rtl ';
  1624. }
  1625.  
  1626. return $classes;
  1627. }
  1628.  
  1629.  
  1630.  
  1631. /**
  1632. *automatically load all child classes of the aviaShortcodeTemplate class and create an instance
  1633. **/
  1634. public function createShortcode()
  1635. {
  1636.  
  1637. $children = array();
  1638. foreach( get_declared_classes() as $class )
  1639. {
  1640. if( is_subclass_of( $class, 'aviaShortcodeTemplate' ) )
  1641. {
  1642. $allow = false;
  1643. $children[] = $class;
  1644. $this->shortcode_class[ $class ] = new $class( $this );
  1645. $shortcode = $this->shortcode_class[ $class ]->config['shortcode'];
  1646.  
  1647. //check if the shortcode is allowed. if so init the shortcode, otherwise unset the item
  1648. if( empty( ShortcodeHelper::$manually_allowed_shortcodes ) && empty( ShortcodeHelper::$manually_disallowed_shortcodes ) )
  1649. {
  1650. $allow = true;
  1651. }
  1652.  
  1653. if( ! $allow && ! empty( ShortcodeHelper::$manually_allowed_shortcodes ) && in_array( $shortcode, ShortcodeHelper::$manually_allowed_shortcodes ) )
  1654. {
  1655. $allow = true;
  1656. }
  1657.  
  1658. if( ! $allow && ! empty( ShortcodeHelper::$manually_disallowed_shortcodes ) && ! in_array( $shortcode, ShortcodeHelper::$manually_disallowed_shortcodes ) )
  1659. {
  1660. $allow = true;
  1661. }
  1662.  
  1663. if( $allow )
  1664. {
  1665. $this->shortcode_class[ $class ]->init();
  1666. $this->shortcode[ $this->shortcode_class[ $class ]->config['shortcode'] ] = $class;
  1667.  
  1668. //save if the asset may be disabled automatically
  1669. if( ! empty( $this->shortcode_class[ $class ]->config['disabling_allowed'] ) && $this->shortcode_class[ $class ]->config['disabling_allowed'] !== 'manually' )
  1670. {
  1671. $this->may_be_disabled_automatically[] = $this->shortcode_class[$class]->config['shortcode'] ;
  1672. }
  1673.  
  1674. //save shortcode as allowed by default. if we only want to display the shortcode in tinymce remove it from the list but keep the class instance alive
  1675. if( empty( $this->shortcode_class[ $class ]->config['tinyMCE']['tiny_only'] ) )
  1676. {
  1677. ShortcodeHelper::$allowed_shortcodes[] = $this->shortcode_class[ $class ]->config['shortcode'];
  1678. }
  1679.  
  1680. //save nested shortcodes if they exist
  1681. if( isset( $this->shortcode_class[ $class ]->config['shortcode_nested'] ) )
  1682. {
  1683. ShortcodeHelper::$nested_shortcodes = array_merge( ShortcodeHelper::$nested_shortcodes, $this->shortcode_class[ $class ]->config['shortcode_nested'] );
  1684. }
  1685. }
  1686. else
  1687. {
  1688. unset( $this->shortcode_class[ $class ] );
  1689. }
  1690. }
  1691. }
  1692.  
  1693. /**
  1694. * Initialise reference to parent and children shortcode(s) so we know the default structure of the elements.
  1695. * Nested shortcodes are merged with layout_children.
  1696. */
  1697. foreach( $this->shortcode_class as $class => &$sc )
  1698. {
  1699. $nested = isset( $sc->config['shortcode_nested'] ) && is_array( $sc->config['shortcode_nested'] ) ? $sc->config['shortcode_nested'] : array();
  1700. $sc->config['layout_children'] = array_unique( array_merge( $nested, $sc->config['layout_children'] ) );
  1701.  
  1702. foreach( $sc->config['layout_children'] as $child_sc )
  1703. {
  1704. if( ! isset( $this->shortcode_parents[ $child_sc ] ) )
  1705. {
  1706. $this->shortcode_parents[ $child_sc ] = array();
  1707. }
  1708. $this->shortcode_parents[ $child_sc ][] = $sc->config['shortcode'];
  1709. }
  1710. }
  1711.  
  1712. unset( $sc );
  1713. }
  1714.  
  1715. /**
  1716. * Gets an opening or closing tag or a start fragment and returns the shortcode
  1717. *
  1718. * @since 4.2.1
  1719. * @param type $tag
  1720. * @return false|string
  1721. */
  1722. public function extract_shortcode_from_tag( $tag = '' )
  1723. {
  1724. if( empty( $tag ) || ! is_string( $tag ) )
  1725. {
  1726. return false;
  1727. }
  1728.  
  1729. $match = array();
  1730.  
  1731. $regex = "\[\/?([\w|-]+)"; // gets opening and closing tag till first space after tag
  1732. preg_match_all( "/" . $regex . "/s", $tag, $match, PREG_OFFSET_CAPTURE );
  1733.  
  1734. if( empty( $match ) )
  1735. {
  1736. return false;
  1737. }
  1738.  
  1739. return $match[1][0][0];
  1740. }
  1741.  
  1742.  
  1743. /**
  1744. * Gets an opening or closing shortcode tag (or the beginning part of it, extracts the shortcode and returns the shortcode class
  1745. *
  1746. * @since 4.2.1
  1747. * @param string $tag a valid shortcode tag
  1748. * @return aviaShortcodeTemplate|false
  1749. */
  1750. public function get_sc_class_from_tag( $tag = '' )
  1751. {
  1752. $sc_name = $this->extract_shortcode_from_tag( $tag );
  1753. if( false === $sc_name )
  1754. {
  1755. return false;
  1756. }
  1757.  
  1758. return $this->get_shortcode_class( $sc_name );
  1759. }
  1760.  
  1761.  
  1762. /**
  1763. * Returns the shortcode class
  1764. *
  1765. * @since 4.2.1
  1766. * @param string $sc_name
  1767. * @return aviaShortcodeTemplate|false
  1768. */
  1769. public function get_shortcode_class( $sc_name )
  1770. {
  1771. return ( isset( $this->shortcode[ $sc_name ] ) && isset( $this->shortcode_class[ $this->shortcode[ $sc_name ] ] ) ) ? $this->shortcode_class[ $this->shortcode[ $sc_name ] ] : false;
  1772. }
  1773.  
  1774.  
  1775. /**
  1776. * Returns the array with the parents shortcodes
  1777. *
  1778. * @since 4.2.1
  1779. * @param string $tag
  1780. * @return array
  1781. */
  1782. public function get_sc_parents_from_tag( $tag = '' )
  1783. {
  1784. $sc_name = $this->extract_shortcode_from_tag( $tag );
  1785. if( false === $sc_name )
  1786. {
  1787. return array();
  1788. }
  1789.  
  1790. return ( isset( $this->shortcode_parents[ $sc_name ] ) ) ? $this->shortcode_parents[ $sc_name ] : array();
  1791. }
  1792.  
  1793.  
  1794. /**
  1795. * create JS templates
  1796. */
  1797. public function js_template_editor_elements()
  1798. {
  1799. foreach( $this->shortcode_class as $shortcode )
  1800. {
  1801. $class = $shortcode->config['php_class'];
  1802. $template = $this->shortcode_class[$class]->prepare_editor_element();
  1803.  
  1804. if( is_array( $template ) )
  1805. {
  1806. continue;
  1807. }
  1808.  
  1809. echo "\n<script type='text/html' id='avia-tmpl-{$class}'>\n";
  1810. echo $template;
  1811. echo "\n</script>\n\n";
  1812. }
  1813.  
  1814. }
  1815.  
  1816.  
  1817. /**
  1818. * Balance the shortcode in the post content of a non ALB page.
  1819. * @since 4.3: Also check page content for ALB shortcodes and add a unique id to shortcodes
  1820. *
  1821. * @since 4.2.1
  1822. * @param array $data
  1823. * @param array $postarr
  1824. * @return array
  1825. */
  1826. public function handler_before_save_alb_post_data( array $data, array $postarr )
  1827. {
  1828. /**
  1829. * Get current ALB values and save to post meta
  1830. */
  1831. $builder_stat = $this->get_alb_builder_status();
  1832. $this->set_alb_builder_status( $builder_stat );
  1833.  
  1834. $parser_state = isset( $_POST['_avia_sc_parser_state'] ) ? $_POST['_avia_sc_parser_state'] : '';
  1835. $parser_state = $this->set_posts_shortcode_parser_state( $parser_state );
  1836.  
  1837. $post_id = (int)$postarr['ID'];
  1838.  
  1839. /**
  1840. * Check the hidden container, balance the shortcodes and add missing id's
  1841. */
  1842. if( isset( $_POST['_aviaLayoutBuilderCleanData'] ) )
  1843. {
  1844. $this->get_shortcode_parser()->set_builder_save_location( 'clean_data' );
  1845. $_POST['_aviaLayoutBuilderCleanData'] = ShortcodeHelper::clean_up_shortcode( $_POST['_aviaLayoutBuilderCleanData'], 'balance_only' );
  1846. $_POST['_aviaLayoutBuilderCleanData'] = $this->element_manager->set_element_ids_in_content( $_POST['_aviaLayoutBuilderCleanData'], $post_id );
  1847. }
  1848.  
  1849. if( 'active' == $builder_stat )
  1850. {
  1851. return $data;
  1852. }
  1853.  
  1854. /**
  1855. * Normal pages we only balance the shortcodes but do not modify the otber content to keep all user stylings
  1856. */
  1857. $this->post_content = isset( $data['post_content'] ) ? trim( $data['post_content'] ) : '';
  1858. $this->get_shortcode_parser()->set_builder_save_location( 'content' );
  1859. $this->post_content = ShortcodeHelper::clean_up_shortcode( $this->post_content, 'balance_only' );
  1860.  
  1861. /**
  1862. * Scan content and add missing unique id'S
  1863. */
  1864. $this->post_content = $this->element_manager->set_element_ids_in_content( $this->post_content, $post_id );
  1865.  
  1866. $data['post_content'] = $this->post_content;
  1867.  
  1868. return $data;
  1869. }
  1870.  
  1871. /**
  1872. * Remove Boxes not needed, e.g. Enfold Parser Metabox
  1873. *
  1874. * @since 4.2.1
  1875. * @param array $boxes
  1876. * @return array
  1877. */
  1878. public function handler_alb_metabox_filter( array $boxes )
  1879. {
  1880. if( 'debug' == AviaBuilder::$mode )
  1881. {
  1882. return $boxes;
  1883. }
  1884.  
  1885. foreach ( $boxes as $key => $box )
  1886. {
  1887. if( 'avia_sc_parser' == $box['id'] )
  1888. {
  1889. unset( $boxes[ $key ] );
  1890. }
  1891. }
  1892.  
  1893. $boxes = array_merge( $boxes );
  1894. return $boxes;
  1895. }
  1896.  
  1897. /**
  1898. * Save builder relevant data of the post in backend - $_POST['content'] has already been saved at this point.
  1899. *
  1900. * - Save status of builder (open/closed)
  1901. * - Save and balance shortcodes in _aviaLayoutBuilderCleanData
  1902. * - Create the shortcode tree
  1903. **/
  1904. public function meta_box_save()
  1905. {
  1906.  
  1907. if( isset( $_POST['post_ID'] ) )
  1908. {
  1909. /**
  1910. * New states have been saved already in handler_before_save_alb_post_data
  1911. */
  1912. $builder_stat = $this->get_alb_builder_status();
  1913. $parser_state = $this->get_posts_shortcode_parser_state();
  1914. $post_id = (int) $_POST['post_ID'];
  1915.  
  1916.  
  1917. /**
  1918. * Save the hidden container already checked and updated in handler_before_save_alb_post_data
  1919. */
  1920. if( isset( $_POST['_aviaLayoutBuilderCleanData'] ) )
  1921. {
  1922. $this->save_posts_alb_content( $post_id, $_POST['_aviaLayoutBuilderCleanData'] );
  1923. }
  1924.  
  1925. /**
  1926. * Copy balanced shortcodes to content field so the shortcode tree can be built
  1927. *
  1928. */
  1929. if( 'active' == $builder_stat )
  1930. {
  1931. $this->get_shortcode_parser()->set_builder_save_location( 'content' );
  1932. if( isset( $_POST['_aviaLayoutBuilderCleanData'] ) )
  1933. {
  1934. $_POST['content'] = ShortcodeHelper::clean_up_shortcode( $_POST['_aviaLayoutBuilderCleanData'], 'content' );
  1935. }
  1936. else
  1937. {
  1938. /**
  1939. * _aviaLayoutBuilderCleanData should be set by default, so this is only a fallback
  1940. */
  1941. $_POST['content'] = ShortcodeHelper::clean_up_shortcode( $_POST['content'], 'content' );
  1942. }
  1943. }
  1944. else
  1945. {
  1946. $_POST['content'] = $this->post_content;
  1947. }
  1948.  
  1949.  
  1950. //extract all ALB shortcodes from the post array and store them so we know what we are dealing with when the user opens a page.
  1951. //usesfull for special elements that we might need to render outside of the default loop like fullscreen slideshows
  1952. // $matches = array();
  1953. // preg_match_all("/".ShortcodeHelper::get_fake_pattern()."/s", $_POST['content'], $matches, PREG_OFFSET_CAPTURE );
  1954.  
  1955.  
  1956. /**
  1957. * Extract all ALB shortcodes from the post array and store them so we know what we are dealing with when the user opens a page.
  1958. * Usesfull for special elements that we might need to render outside of the default loop like fullscreen slideshows.
  1959. *
  1960. * We always save this tree so we can be sure to have the correct state of the page when we load this post meta.
  1961. */
  1962. $tree = ShortcodeHelper::build_shortcode_tree( $_POST['content'] );
  1963. $this->save_shortcode_tree( $post_id, $tree);
  1964.  
  1965. $this->element_manager->updated_post_content( $_POST['content'], $post_id );
  1966.  
  1967. /**
  1968. * Now we can save the postmeta data to revision post
  1969. */
  1970. $this->save_alb_revision_data( $post_id );
  1971. }
  1972. }
  1973.  
  1974.  
  1975.  
  1976. /**
  1977. *function that checks if a dynamic template exists and uses that template instead of the default page template
  1978. **/
  1979. public function template_include( $original_template )
  1980. {
  1981. global $avia_config;
  1982.  
  1983. $post_id = @get_the_ID();
  1984.  
  1985. if( is_feed() )
  1986. {
  1987. return;
  1988. }
  1989.  
  1990. if( is_embed() )
  1991. {
  1992. return $original_template;
  1993. }
  1994.  
  1995. if( ( $post_id && is_singular() ) || isset( $avia_config['builder_redirect_id'] ) )
  1996. {
  1997. if( ! empty( $avia_config['builder_redirect_id'] ) )
  1998. {
  1999. $post_id = $avia_config['builder_redirect_id'];
  2000. }
  2001.  
  2002. ShortcodeHelper::$tree = $this->get_shortcode_tree( $post_id );
  2003.  
  2004. $builder_template = locate_template( 'template-builder.php', false );
  2005.  
  2006. /**
  2007. * Redirect to default ALB template if we need to show parser debug info (implemented with default shortcode content)
  2008. */
  2009. if( isset( $_REQUEST['avia_alb_parser'] ) && ( 'show' == $_REQUEST['avia_alb_parser'] ) && ( '' != $builder_template ) )
  2010. {
  2011. $avia_config['conditionals']['is_builder'] = true;
  2012. $avia_config['conditionals']['is_builder_template'] = true;
  2013. return $builder_template;
  2014. }
  2015.  
  2016. if( ( 'active' == $this->get_alb_builder_status( $post_id ) ) && ( '' != $builder_template ) )
  2017. {
  2018. $avia_config['conditionals']['is_builder'] = true;
  2019.  
  2020. //only redirect if no custom template is set
  2021. $template_file = get_post_meta( $post_id, '_wp_page_template', true );
  2022.  
  2023. if( 'default' == $template_file || empty( $template_file ) )
  2024. {
  2025. $avia_config['conditionals']['is_builder_template'] = true;
  2026. return $builder_template;
  2027. }
  2028. }
  2029. else
  2030. {
  2031. /**
  2032. * In case we are in preview mode we have to rebuild the shortcode tree so the user can see the real result of the page
  2033. */
  2034. if( is_preview() )
  2035. {
  2036. global $post;
  2037.  
  2038. /**
  2039. * If user views a preview we must use the content because WordPress doesn't update the post meta field
  2040. */
  2041. setup_postdata( $post );
  2042. $content = apply_filters( 'avia_builder_precompile', get_the_content() );
  2043.  
  2044. /**
  2045. * In preview we must update the shortcode tree to reflect the current page structure.
  2046. * Prior make sure that shortcodes are balanced and save this in post_content so we have
  2047. * the updated content when displaying the page.
  2048. */
  2049. $this->get_shortcode_parser()->set_builder_save_location( 'preview' );
  2050. $post->post_content = ShortcodeHelper::clean_up_shortcode( $content, 'balance_only' );
  2051. ShortcodeHelper::$tree = ShortcodeHelper::build_shortcode_tree( $post->post_content );
  2052. }
  2053. }
  2054.  
  2055. //if a custom page was passed and the template builder is not active redirect to the default page template
  2056. if( isset( $avia_config['builder_redirect_id'] ) )
  2057. {
  2058. if( $template = locate_template( 'page.php', false) )
  2059. {
  2060. return $template;
  2061. }
  2062. }
  2063. }
  2064.  
  2065. return $original_template;
  2066. }
  2067.  
  2068. /**
  2069. *
  2070. *
  2071. */
  2072. public function apply_editor_wrap()
  2073. {
  2074. //fetch the config array
  2075. include( $this->paths['configPath'] . 'meta.php' );
  2076.  
  2077. $slug = '';
  2078. $pages = array();
  2079.  
  2080. //check to which pages the avia builder is applied
  2081. foreach( $elements as $element )
  2082. {
  2083. if( is_array( $element['type'] ) && $element['type'][1] == 'visual_editor' )
  2084. {
  2085. $slug = $element['slug'];
  2086. break;
  2087. }
  2088. }
  2089.  
  2090. foreach( $boxes as $box )
  2091. {
  2092. if( $box['id'] == $slug )
  2093. {
  2094. $pages = $box['page'];
  2095. }
  2096. }
  2097.  
  2098. global $typenow;
  2099.  
  2100. if( ! empty( $pages ) && in_array( $typenow, $pages ) )
  2101. {
  2102. //html modification of the admin area: wrap
  2103. add_action( 'edit_form_after_title', array( $this, 'wrap_default_editor' ), 100000, 2 );
  2104. add_action( 'edit_form_after_editor', array( $this, 'close_default_editor_wrap' ), 1, 1 );
  2105. }
  2106. }
  2107.  
  2108. /**
  2109. * Adds the ALB switch button
  2110. *
  2111. * @param WP_Post|null $post
  2112. * @param string $close_div '' | 'close'
  2113. */
  2114. public function wrap_default_editor( $post = null, $close_div = '' )
  2115. {
  2116. global $post_ID;
  2117.  
  2118. $status = $this->get_alb_builder_status( $post_ID );
  2119.  
  2120. $params = array(
  2121. 'disabled' => false,
  2122. 'note' => '',
  2123. 'noteclass' => '',
  2124. 'button_class' => '',
  2125. 'visual_label' => __( 'Advanced Layout Editor', 'avia_framework' ),
  2126. 'default_label' => __( 'Default Editor', 'avia_framework' )
  2127. );
  2128.  
  2129. /**
  2130. * Filter button layout parameteres
  2131. *
  2132. * @since 4.7.4.1 added params $post, $close_div
  2133. * @param array $params
  2134. * @param WP_Post|null $post
  2135. * @param string $close_div
  2136. */
  2137. $params = apply_filters( 'avf_builder_button_params', $params, $post, $close_div );
  2138.  
  2139.  
  2140. if( $params['disabled'] )
  2141. {
  2142. $status = false;
  2143. }
  2144.  
  2145. $active_builder = $status == 'active' ? $params['default_label'] : $params['visual_label'];
  2146. $editor_class = $status == 'active' ? 'class="avia-hidden-editor"' : '';
  2147. $button_class = $status == 'active' ? 'avia-builder-active' : '';
  2148.  
  2149. echo "<div id='postdivrich_wrap' {$editor_class}>";
  2150.  
  2151. if( $this->disable_drag_drop == false )
  2152. {
  2153. echo '<a id="avia-builder-button" href="#" class="avia-builder-button button-primary ' . $button_class . ' ' . $params['button_class'] . '" data-active-button="' . $params['default_label'] . '" data-inactive-button="' . $params['visual_label'] . '">' . $active_builder . '</a>';
  2154. }
  2155.  
  2156. /**
  2157. * Allow to add additional buttons
  2158. *
  2159. * @since 4.7.4.1
  2160. * @param array $params
  2161. * @param WP_Post|null $post
  2162. * @param string $close_div
  2163. */
  2164. do_action( 'ava_after_layout_builder_button', $params, $post, $close_div );
  2165.  
  2166. if( $params['note'] )
  2167. {
  2168. echo "<div class='av-builder-note {$params['noteclass']}'>{$params['note']}</div>";
  2169. }
  2170.  
  2171. if( 'close' == $close_div )
  2172. {
  2173. echo '</div>';
  2174. }
  2175. }
  2176.  
  2177. /**
  2178. *
  2179. * @param WP_Post $post
  2180. */
  2181. public function close_default_editor_wrap( $post = null )
  2182. {
  2183. echo '</div>';
  2184. }
  2185.  
  2186.  
  2187. /**
  2188. * function called by the metabox class that creates the interface in your wordpress backend
  2189. *
  2190. * @param array $element
  2191. */
  2192. public function visual_editor( $element )
  2193. {
  2194. $output = '';
  2195. $tabs_output = '';
  2196. $title = '';
  2197. $i = 0;
  2198.  
  2199. /**
  2200. * @used_by Avia_Gutenberg 10
  2201. *
  2202. * @since 4.5.1
  2203. * @param string $output
  2204. * @param array $element
  2205. * @return string
  2206. */
  2207. $output = apply_filters( 'avf_builder_metabox_editor_before', $output, $element );
  2208.  
  2209. /**
  2210. * Disable fix for tinyMCE bullet list indent/detent for special pages if it makes problems
  2211. *
  2212. * @since 4.6.0
  2213. * @return boolean
  2214. */
  2215. $fix = apply_filters( 'avf_alb_tinymce_ignore_indent_fix', false );
  2216. $fix_class = false !== $fix ? 'avia-ignore-tiny-indent-fix' : '';
  2217.  
  2218. $output .= '<div class="avia-builder-main-wrap ' . $fix_class . '">';
  2219.  
  2220. /**
  2221. *
  2222. * @used_by aviaShortcodeTemplate::add_backend_button 10
  2223. *
  2224. * @since <4.0
  2225. * @param array
  2226. * @return array
  2227. */
  2228. $this->shortcode_buttons = apply_filters( 'avia_show_shortcode_button', array() );
  2229.  
  2230. if( ! empty( $this->shortcode_buttons ) && $this->disable_drag_drop == false )
  2231. {
  2232. $this->tabs = isset( $element['tab_order'] ) ? array_flip( $element['tab_order'] ) : array();
  2233.  
  2234. foreach( $this->tabs as &$empty_tabs )
  2235. {
  2236. $empty_tabs = array();
  2237. }
  2238.  
  2239. foreach( $this->shortcode_buttons as $shortcode )
  2240. {
  2241. if( empty( $shortcode['tinyMCE']['tiny_only'] ) )
  2242. {
  2243. if( ! isset($shortcode['tab'] ) )
  2244. {
  2245. $shortcode['tab'] = __( 'Custom Elements', 'avia_framework' );
  2246. }
  2247.  
  2248. $this->tabs[ $shortcode['tab'] ][] = $shortcode;
  2249. }
  2250. }
  2251.  
  2252. foreach( $this->tabs as $key => $tab )
  2253. {
  2254. if( empty( $tab ) )
  2255. {
  2256. continue;
  2257. }
  2258.  
  2259. usort( $tab, array( $this, 'sortByOrder' ) );
  2260.  
  2261. $i ++;
  2262. $title .= "<a href='#avia-tab-{$i}'>{$key}</a>";
  2263.  
  2264. $tabs_output .= "<div class='avia-tab avia-tab-{$i}'>";
  2265.  
  2266. $sort_order = 0;
  2267. foreach( $tab as $shortcode )
  2268. {
  2269. if( empty( $shortcode['invisible'] ) )
  2270. {
  2271. $sort_order ++;
  2272. $tabs_output .= $this->create_shortcode_button( $shortcode, $sort_order );
  2273. }
  2274. }
  2275.  
  2276. $tabs_output .= '</div>';
  2277. }
  2278. }
  2279.  
  2280. global $post_ID;
  2281. $active_builder = $this->get_alb_builder_status( $post_ID );
  2282.  
  2283.  
  2284. $extra = AviaBuilder::$mode != true ? '' : 'avia_mode_' . AviaBuilder::$mode;
  2285. $hotekey_info = htmlentities( $element['desc'], ENT_QUOTES, get_bloginfo( 'charset' ) );
  2286.  
  2287. $output .= '<div class="shortcode_button_wrap avia-tab-container"><div class="avia-tab-title-container">'.$title.'</div>' . $tabs_output . '</div>';
  2288. $output .= '<input type="hidden" value="' . $active_builder . '" name="aviaLayoutBuilder_active" id="aviaLayoutBuilder_active" />';
  2289.  
  2290. $params = array(
  2291. 'args' => array( 'icon' => 'ue86e' )
  2292. );
  2293. $icon = av_backend_icon( $params );
  2294.  
  2295. $user_info = $this->get_backend_user_info( 'sc_sort_order' );
  2296. $init_sort = ( ! empty( $user_info ) ) ? $user_info : 'order';
  2297.  
  2298.  
  2299. $sorting_label = array(
  2300. 'order' => __( 'Default', 'avia_framework' ),
  2301. 'name_asc' => __( 'By name (ascending)', 'avia_framework' ),
  2302. 'name_desc' => __( 'By name (descending)', 'avia_framework' ),
  2303. 'usage' => __( 'By usage', 'avia_framework' ),
  2304. );
  2305.  
  2306.  
  2307. $output .= '<div id="avia-sort-list-dropdown" class="avia-sort-list-container" data-init_sort="' . $init_sort . '">';
  2308. $output .= '<ul class="avia-sort-list-select">';
  2309. $output .= '<li class="avia-sort-list-wrap">';
  2310. $output .= '<strong>';
  2311. $output .= '<span class="avia-font-entypo-fontello avia_icon_char">' . $icon['display_char'] . '</span> '. __( 'Sorting', 'avia_framework' ) . ': <span class="avia-sort-list-label">'. $sorting_label[$init_sort] .'</span>';
  2312. $output .= '</strong>';
  2313. $output .= '<ul class="avia-sort-list-main">';
  2314. $output .= '<li class="avia-sort-list-element">';
  2315. $output .= '<a href="#" class="sort_active" data-sorting="order" title="' . esc_attr( __( 'Sort shortcode buttons by theme default sorting', 'avia_framework' ) ) . '">' . __( 'Default', 'avia_framework' ) . '</a>';
  2316. $output .= '</li>';
  2317. $output .= '<li class="avia-sort-list-element">';
  2318. $output .= '<a href="#" class="" data-sorting="name_asc" title="' . esc_attr( __( 'Sort shortcode buttons by name ascending', 'avia_framework' ) ) . '">' . __( 'By name (ascending)', 'avia_framework' ) . '</a>';
  2319. $output .= '</li>';
  2320. $output .= '<li class="avia-sort-list-element">';
  2321. $output .= '<a href="#" class="" data-sorting="name_desc" title="' . esc_attr( __( 'Sort shortcode buttons by name descending', 'avia_framework' ) ) . '">' . __( 'By name (descending)', 'avia_framework' ) . '</a>';
  2322. $output .= '</li>';
  2323. $output .= '<li class="avia-sort-list-element">';
  2324. $output .= '<a href="#" class="" data-sorting="usage" title="' . esc_attr( __( 'Sort shortcode buttons by usage', 'avia_framework' ) ) . '">' . __( 'By usage', 'avia_framework' ) . '</a>';
  2325. $output .= '</li>';
  2326. $output .= '</ul>';
  2327. $output .= '</li>';
  2328. $output .= '</ul>';
  2329. $output .= '</div>';
  2330.  
  2331. if( $this->disable_drag_drop == false )
  2332. {
  2333. $output .= '<a href="#info" class="avia-hotkey-info" data-avia-help-tooltip="' . $hotekey_info . '">' . __( 'Information', 'avia_framework' ) . '</a>';
  2334. $output .= $this->builderTemplate->create_save_button();
  2335. }
  2336.  
  2337. $output .= "<div class='layout-builder-wrap {$extra}'>";
  2338.  
  2339. if( $this->disable_drag_drop == false )
  2340. {
  2341. $output .= "<div class='avia-controll-bar'></div>";
  2342. }
  2343.  
  2344. $output .= " <div id='aviaLayoutBuilder' class='avia-style avia_layout_builder avia_connect_sort preloading av_drop' data-dragdrop-level='0'>";
  2345. $output .= ' </div>';
  2346.  
  2347.  
  2348. $clean_data = $this->get_posts_alb_content( $post_ID );
  2349. // $clean_data = htmlentities($clean_data, ENT_QUOTES, get_bloginfo( 'charset' )); //entity-test: added htmlentities
  2350.  
  2351.  
  2352. $output .= " <textarea id='_aviaLayoutBuilderCleanData' name='_aviaLayoutBuilderCleanData'>".$clean_data."</textarea>";
  2353. $nonce = wp_create_nonce ('avia_nonce_loader');
  2354. $output .= ' <input type="hidden" name="avia-loader-nonce" id="avia-loader-nonce" value="'.$nonce.'" />';
  2355. $output .= '</div>';
  2356.  
  2357. $this->alb_nonce_added = true;
  2358.  
  2359. $output .= '</div> <!-- class="avia-builder-main-wrap" -->';
  2360.  
  2361. return $output;
  2362. }
  2363.  
  2364. /**
  2365. * Function called by the metabox class that creates the interface in your wordpress backend -
  2366. * Output the Shortcode Parser Select and Info Panel below the normal Texteditor and above the ALB Editor
  2367. *
  2368. * @since 4.2.1
  2369. * @param array $element
  2370. * @return string
  2371. */
  2372. public function parser_select_panel( $element )
  2373. {
  2374. global $post_ID;
  2375.  
  2376. $parser_state = $this->get_posts_shortcode_parser_state();
  2377. $link = get_permalink( $post_ID );
  2378.  
  2379. $args = array( 'avia_alb_parser' => 'show' );
  2380. $link = add_query_arg( $args, $link );
  2381.  
  2382.  
  2383. $out = '';
  2384. $out .= '<div class="avia-builder-parser-section">';
  2385. // $out .= '<div class="avia-builder-parser-label">';
  2386. // $out .= '<label for="av_select_sc_parser">';
  2387. // $out .= __( 'Enfold Shortcode Parser:', 'avia_framework' );
  2388. // $out .= '</label>';
  2389. // $out .= '</div>';
  2390. $out .= '<div class="avia-builder-parser-select avia-form-element avia-style">';
  2391. $out .= '<select id="av_select_sc_parser" name="_avia_sc_parser_state" class="avia-style">';
  2392. $out .= '<option value="disabled" ' . selected( 'disabled', $parser_state, false ) . '>' . __( 'Disabled - No checks are done on update', 'avia_framework' ) . '</option>';
  2393. $out .= '<option value="check_only" ' . selected( 'check_only', $parser_state, false ) . '>' . __( 'Check enabled on update - checks the structure only', 'avia_framework' ) . '</option>';
  2394. $out .= '<option value="auto_repair" ' . selected( 'auto_repair', $parser_state, false ) . '>' . __( 'Auto Repair Function enabled - Repairs errors in shortcode structure during update', 'avia_framework' ) . '</option>';
  2395. $out .= '</select>';
  2396. $out .= '</div>';
  2397. $out .= '<div class="avia-builder-parser-info-button">';
  2398. $out .= '<a href="' . $link . '" class="button-primary" target="_blank">' . __( 'Show Parser Info', 'avia_framework') . '</a>';
  2399. $out .= '</div>';
  2400. $out .= '<div class="avia-builder-parser-message">';
  2401. $out .= $this->get_shortcode_parser()->display_dashboard_info();
  2402. $out .= '</div>';
  2403. $out .= '</div>';
  2404.  
  2405. return $out;
  2406. }
  2407.  
  2408. /**
  2409. * Create a shortcode button
  2410. *
  2411. * @since < 4.0
  2412. * @param array $shortcode
  2413. * @param int $sort_order
  2414. * @return string
  2415. */
  2416. protected function create_shortcode_button( $shortcode, $sort_order )
  2417. {
  2418. if( empty( $this->shortcode_usage_blog ) )
  2419. {
  2420. $this->shortcode_usage_blog = Avia_Builder()->element_manager()->get_elements_count( 'blog' );
  2421. }
  2422.  
  2423. $class = '';
  2424. $usage = isset( $this->shortcode_usage_blog[ $shortcode['shortcode'] ] ) ? $this->shortcode_usage_blog[ $shortcode['shortcode'] ] : 0;
  2425.  
  2426.  
  2427. /**
  2428. * @used_by enfold\includes\helper-assets.php:: function av_disable_button_in_backend 10
  2429. *
  2430. * @since 4.3
  2431. * @param array
  2432. * @return array
  2433. */
  2434. $shortcode = apply_filters( 'avf_shortcode_insert_button_backend', $shortcode );
  2435.  
  2436. //disable element based on post type
  2437. if( ! empty( $shortcode['posttype'] ) && $shortcode['posttype'][0] != AviaHelper::backend_post_type() )
  2438. {
  2439. $shortcode['tooltip'] = $shortcode['posttype'][1];
  2440. $class .= 'av-shortcode-disabled ';
  2441. }
  2442.  
  2443. //disable element based on condition
  2444. if( ! empty( $shortcode['disabled'] ) && $shortcode['disabled']['condition'] === true )
  2445. {
  2446. $shortcode['tooltip'] = $shortcode['disabled']['text'];
  2447. $class .= 'av-shortcode-disabled ';
  2448. }
  2449.  
  2450.  
  2451. $icon = isset( $shortcode['icon'] ) ? '<img src="' . $shortcode['icon'] . '" alt="' . esc_attr( $shortcode['name'] ) . '" />' : '';
  2452.  
  2453. $data = ! empty( $shortcode['tooltip'] ) ? " data-avia-tooltip='{$shortcode['tooltip']}' " : '';
  2454. $data .= ! empty( $shortcode['drag-level'] ) ? " data-dragdrop-level='{$shortcode['drag-level']}' " : '';
  2455. $data .= " data-sort_order='{$sort_order}' ";
  2456. $data .= ' data-sort_name="' . esc_attr( $shortcode['name'] ) . '" ';
  2457. $data .= " data-sort_usage='{$usage}' ";
  2458.  
  2459. $class .= isset( $shortcode['class'] ) ? $shortcode['class'] : '';
  2460. $class .= ! empty( $shortcode['target'] ) ? " {$shortcode['target']}" : '';
  2461.  
  2462. $link = '';
  2463. $link .= "<a {$data} href='#{$shortcode['php_class']}' class='shortcode_insert_button {$class}' >{$icon}<span>{$shortcode['name']}</span></a>";
  2464.  
  2465. return $link;
  2466. }
  2467.  
  2468.  
  2469. /**
  2470. * Helper function to sort the shortcode buttons
  2471. *
  2472. * @param array $a
  2473. * @param array $b
  2474. * @return boolean
  2475. */
  2476. protected function sortByOrder( $a, $b )
  2477. {
  2478. if( empty( $a['order'] ) )
  2479. {
  2480. $a['order'] = 10;
  2481. }
  2482.  
  2483. if( empty( $b['order'] ) )
  2484. {
  2485. $b['order'] = 10;
  2486. }
  2487.  
  2488. return $b['order'] >= $a['order'];
  2489. }
  2490.  
  2491.  
  2492.  
  2493. /**
  2494. *
  2495. *
  2496. * @param string|null $text
  2497. * @return string|void
  2498. */
  2499. public function text_to_interface( $text = null )
  2500. {
  2501. if( ! current_user_can( 'edit_posts' ) )
  2502. {
  2503. die();
  2504. }
  2505.  
  2506. if( isset( $_REQUEST['params']['_ajax_nonce'] ) )
  2507. {
  2508. $_REQUEST['_ajax_nonce'] = $_REQUEST['params']['_ajax_nonce'];
  2509. }
  2510.  
  2511. check_ajax_referer('avia_nonce_loader', '_ajax_nonce' );
  2512.  
  2513. global $shortcode_tags;
  2514.  
  2515. $allowed = false;
  2516.  
  2517. //isset when avia_ajax_text_to_interface is executed (avia_builder.js)
  2518. if( isset( $_POST['text'] ) )
  2519. {
  2520. $text = $_POST['text'];
  2521. }
  2522.  
  2523. //only build pattern with a subset of shortcodes
  2524. if( isset( $_POST['params'] ) && isset( $_POST['params']['allowed'] ) )
  2525. {
  2526. $allowed = explode( ',', $_POST['params']['allowed'] );
  2527. }
  2528.  
  2529. //build the shortcode pattern to check if the text that we want to check uses any of the builder shortcodes
  2530. ShortcodeHelper::build_pattern( $allowed );
  2531.  
  2532. $text_nodes = preg_split( "/" . ShortcodeHelper::$pattern . "/s", $text );
  2533.  
  2534. foreach( $text_nodes as $node )
  2535. {
  2536. if( strlen( trim( $node ) ) == 0 || strlen( trim( strip_tags( $node) ) ) == 0)
  2537. {
  2538. //$text = preg_replace("/(".preg_quote($node, '/')."(?!\[\/))/", '', $text);
  2539. }
  2540. else
  2541. {
  2542. $text = preg_replace( "/(" . preg_quote( $node, '/' ) . "(?!\[\/))/", '[av_textblock]$1[/av_textblock]', $text );
  2543. }
  2544. }
  2545.  
  2546. $text = $this->do_shortcode_backend( $text );
  2547.  
  2548. if( isset( $_POST['text'] ) )
  2549. {
  2550. echo $text;
  2551. exit();
  2552. }
  2553. else
  2554. {
  2555. return $text;
  2556. }
  2557. }
  2558.  
  2559. /**
  2560. * Ajax callback to return preview output in modal popup
  2561. *
  2562. * @param string|null $text
  2563. */
  2564. public function text_to_preview( $text = null )
  2565. {
  2566. if( ! current_user_can( 'edit_posts' ) )
  2567. {
  2568. die();
  2569. }
  2570.  
  2571. check_ajax_referer( 'avia_nonce_loader', '_ajax_nonce' );
  2572.  
  2573. $text = '';
  2574. if( isset( $_POST['text'] ) )
  2575. {
  2576. $text = stripslashes( $_POST['text'] );
  2577. }
  2578.  
  2579. $this->in_text_to_preview = true;
  2580.  
  2581. $preview = do_shortcode( $text );
  2582.  
  2583. /**
  2584. * Allow third party to modify content
  2585. *
  2586. * @since 4.3.1
  2587. * @param string $preview
  2588. * @param string $text
  2589. * @return string
  2590. */
  2591. $preview = apply_filters( 'avf_text_to_preview', $preview, $text );
  2592.  
  2593. $this->in_text_to_preview = false;
  2594.  
  2595. echo $preview;
  2596. exit();
  2597. }
  2598.  
  2599. /**
  2600. * Returns if we are in ajax callback for preview
  2601. *
  2602. * @since 4.5.4
  2603. * @return boolean
  2604. */
  2605. public function in_text_to_preview_mode()
  2606. {
  2607. return $this->in_text_to_preview;
  2608. }
  2609.  
  2610. /**
  2611. *
  2612. * @param string $text
  2613. * @return string
  2614. */
  2615. public function do_shortcode_backend( $text )
  2616. {
  2617. return preg_replace_callback( "/" . ShortcodeHelper::$pattern . "/s", array( $this, 'do_shortcode_tag' ), $text );
  2618. }
  2619.  
  2620. /**
  2621. *
  2622. *
  2623. * @param string $m
  2624. * @return string
  2625. */
  2626. public function do_shortcode_tag( $m )
  2627. {
  2628. global $shortcode_tags;
  2629.  
  2630. // allow [[foo]] syntax for escaping a tag
  2631. if ( $m[1] == '[' && $m[6] == ']' )
  2632. {
  2633. return substr( $m[0], 1, -1 );
  2634. }
  2635.  
  2636. //check for enclosing tag or self closing
  2637. $values['closing'] = strpos( $m[0], '[/' . $m[2] . ']' );
  2638. $values['content'] = $values['closing'] !== false ? $m[5] : null;
  2639. $values['tag'] = $m[2];
  2640. $values['attr'] = shortcode_parse_atts( stripslashes( $m[3] ) );
  2641.  
  2642. if( is_array( $values['attr'] ) )
  2643. {
  2644. $charset = get_bloginfo( 'charset' );
  2645. foreach( $values['attr'] as &$attr )
  2646. {
  2647. $attr = htmlentities( $attr, ENT_QUOTES, $charset );
  2648. }
  2649. }
  2650. else
  2651. {
  2652. $values['attr'] = array();
  2653. }
  2654.  
  2655. if( isset( $_POST['params']['extract'] ) )
  2656. {
  2657. //if we open a modal window also check for nested shortcodes
  2658. if( $values['content'] )
  2659. {
  2660. $values['content'] = $this->do_shortcode_backend( $values['content'] );
  2661. }
  2662.  
  2663. $_POST['extracted_shortcode'][] = $values;
  2664.  
  2665. return $m[0];
  2666. }
  2667.  
  2668. if( in_array( $values['tag'], ShortcodeHelper::$allowed_shortcodes ) )
  2669. {
  2670. return $this->shortcode_class[ $this->shortcode[ $values['tag'] ] ]->prepare_editor_element( $values['content'], $values['attr'] );
  2671. }
  2672. else
  2673. {
  2674. return $m[0];
  2675. }
  2676. }
  2677.  
  2678.  
  2679.  
  2680. /**
  2681. * this helper function tells the tiny_mce_editor to remove any span tags that dont have a classname (list insert on ajax tinymce tend do add them)
  2682. * see more: http://martinsikora.com/how-to-make-tinymce-to-output-clean-html
  2683. */
  2684.  
  2685. public function tiny_mce_helper( $mceInit )
  2686. {
  2687. $mceInit['extended_valid_elements'] = empty( $mceInit['extended_valid_elements'] ) ? '' : $mceInit['extended_valid_elements'] . ',';
  2688. $mceInit['extended_valid_elements'] = 'span[!class]';
  2689.  
  2690. return $mceInit;
  2691. }
  2692.  
  2693. /**
  2694. * Return the postmeta metakey names.
  2695. * Can be filtered for specific posts.
  2696. *
  2697. * @since 4.2.1
  2698. * @param int $post_id
  2699. * @param string $context 'save' | 'restore'
  2700. * @return array
  2701. */
  2702. public function get_alb_meta_key_names( $post_id, $context )
  2703. {
  2704. $meta_keys = array(
  2705. '_aviaLayoutBuilder_active',
  2706. '_aviaLayoutBuilderCleanData',
  2707. '_avia_builder_shortcode_tree',
  2708. '_alb_shortcode_status_content',
  2709. '_alb_shortcode_status_clean_data',
  2710. '_alb_shortcode_status_preview',
  2711. '_avia_sc_parser_state',
  2712. '_av_alb_posts_elements_state',
  2713. '_av_el_mgr_version'
  2714. );
  2715.  
  2716. /**
  2717. * @used_by enfold\includes\admin\register-portfolio.php 10
  2718. *
  2719. * @since 4.2.1
  2720. */
  2721. $meta_keys = apply_filters( 'avf_alb_meta_field_names', $meta_keys, $post_id, $context );
  2722.  
  2723. if( ! is_array( $meta_keys) )
  2724. {
  2725. $meta_keys = array();
  2726. }
  2727.  
  2728. return $meta_keys;
  2729. }
  2730.  
  2731.  
  2732. /**
  2733. * Helper function that restores the post meta if user restores a revision
  2734. * see: https://lud.icro.us/post-meta-revisions-wordpress
  2735. */
  2736. public function avia_builder_restore_revision( $post_id, $revision_id )
  2737. {
  2738.  
  2739. $meta_fields = $this->get_alb_meta_key_names( $revision_id, 'restore' );
  2740.  
  2741. foreach( $meta_fields as $meta_field )
  2742. {
  2743. $builder_meta_data = get_metadata( 'post', $revision_id, $meta_field, true );
  2744.  
  2745. if ( ! empty( $builder_meta_data ) )
  2746. {
  2747. update_post_meta( $post_id, $meta_field, $builder_meta_data );
  2748. }
  2749. else
  2750. {
  2751. delete_post_meta( $post_id, $meta_field );
  2752. }
  2753. }
  2754. }
  2755.  
  2756.  
  2757. /**
  2758. * An autosave post is being updated
  2759. *
  2760. * @since 4.2.5
  2761. * @added_by Günter
  2762. * @param array $post
  2763. */
  2764. public function avia_builder_creating_autosave( array $post )
  2765. {
  2766. if( ! isset( $_REQUEST['aviaLayoutBuilder_active'] ) )
  2767. {
  2768. return;
  2769. }
  2770.  
  2771. $this->revision_id = $post['ID'];
  2772.  
  2773. $this->do_alb_autosave( stripslashes( $post['post_content'] ) );
  2774. }
  2775.  
  2776. /**
  2777. * A revision or a new autosave is created
  2778. *
  2779. * @since 4.2.1
  2780. * @added_by Günter
  2781. * @param int $revision_id
  2782. */
  2783. public function avia_builder_put_revision( $revision_id )
  2784. {
  2785. if( ! isset( $_REQUEST['aviaLayoutBuilder_active'] ) )
  2786. {
  2787. return;
  2788. }
  2789.  
  2790. $this->revision_id = $revision_id;
  2791.  
  2792. if( isset( $_POST['content'] ) )
  2793. {
  2794. $this->do_alb_autosave( $_POST['content'] );
  2795. }
  2796. }
  2797.  
  2798. /**
  2799. * Create default revision entries for autosave or preview
  2800. *
  2801. * @since 4.2.5
  2802. * @added_by Günter
  2803. * @param string $content
  2804. */
  2805. protected function do_alb_autosave( $content )
  2806. {
  2807. /**
  2808. * Copy all metadata from original post
  2809. */
  2810. $this->save_alb_revision_data();
  2811.  
  2812.  
  2813. /**
  2814. * Now we need to update the internal data to reflect new situation as we are in an autosave
  2815. * or preview (which saves the content to the only autosave post)
  2816. */
  2817. $tree = ShortcodeHelper::build_shortcode_tree( $content );
  2818.  
  2819. update_metadata( 'post', $this->revision_id, '_aviaLayoutBuilder_active', $_REQUEST['aviaLayoutBuilder_active'] );
  2820. update_metadata( 'post', $this->revision_id, '_aviaLayoutBuilderCleanData', $content );
  2821. update_metadata( 'post', $this->revision_id, '_avia_builder_shortcode_tree', $tree );
  2822. }
  2823.  
  2824.  
  2825.  
  2826. /**
  2827. * A revision had been saved and we have updated our internal data -
  2828. * now save our meta data to restore when user reverts to a revision
  2829. *
  2830. * @since 4.2.1
  2831. * @param int $post_id
  2832. */
  2833. public function save_alb_revision_data( $post_id = 0 )
  2834. {
  2835. if( $this->revision_id <= 0 )
  2836. {
  2837. return;
  2838. }
  2839.  
  2840. if( $post_id <= 0 )
  2841. {
  2842. $post_id = get_the_ID();
  2843. }
  2844.  
  2845. if( false === $post_id )
  2846. {
  2847. return;
  2848. }
  2849.  
  2850. $meta_fields = $this->get_alb_meta_key_names( $post_id, 'save' );
  2851.  
  2852. foreach( $meta_fields as $meta_field )
  2853. {
  2854. $builder_meta_data = get_post_meta( $post_id, $meta_field, true );
  2855.  
  2856. if ( ! empty( $builder_meta_data ) )
  2857. {
  2858. update_metadata( 'post', $this->revision_id, $meta_field, $builder_meta_data );
  2859. }
  2860. }
  2861. }
  2862.  
  2863. /**
  2864. * Gets a post, executes shortcodes and returns the content
  2865. * This function is intended to be called from elements that render post content during output of a page
  2866. * It is important, that this function returns the complete HTML as needed on a blank page
  2867. * e.g. displaying a page as footer
  2868. *
  2869. * The content of this function is based on enfold\template-builder.php
  2870. *
  2871. * @since 4.2.3
  2872. * @param WP_Post $wp_post
  2873. * @return string
  2874. */
  2875. public function compile_post_content( WP_Post $wp_post )
  2876. {
  2877. /**
  2878. * Save values to be able to restore in case we have recursive calls
  2879. */
  2880. $old_tree = ShortcodeHelper::$tree;
  2881. $old_shortcode_index = ShortcodeHelper::$shortcode_index;
  2882.  
  2883.  
  2884. $out = '';
  2885.  
  2886. $builder_stat = $this->get_alb_builder_status( $wp_post->ID );
  2887.  
  2888. if( ( 'active' == $builder_stat ) && ! is_preview() )
  2889. {
  2890. /**
  2891. * Filter the content for content builder elements
  2892. */
  2893. $content = apply_filters( 'avia_builder_precompile', $this->get_posts_alb_content( $wp_post->ID ) );
  2894. ShortcodeHelper::$tree = $this->get_shortcode_tree( $wp_post->ID );
  2895. }
  2896. else
  2897. {
  2898. /**
  2899. * Non ALB page and
  2900. * also if user views a preview we must use the content because WordPress doesn't update the post meta field
  2901. */
  2902. $content = apply_filters( 'avia_builder_precompile', $wp_post->post_content );
  2903.  
  2904.  
  2905. /**
  2906. * Update the shortcode tree to reflect the current page structure.
  2907. * Prior make sure that shortcodes are balanced.
  2908. */
  2909. $this->get_shortcode_parser()->set_builder_save_location( 'none' );
  2910. $content = ShortcodeHelper::clean_up_shortcode( $content, 'balance_only' );
  2911. ShortcodeHelper::$tree = ShortcodeHelper::build_shortcode_tree( $content );
  2912. }
  2913.  
  2914. ShortcodeHelper::$shortcode_index = 0;
  2915.  
  2916. /**
  2917. * check first builder element. if its a section or a fullwidth slider we dont need to create the default opening divs here
  2918. */
  2919. $first_el = isset( ShortcodeHelper::$tree[0] ) ? ShortcodeHelper::$tree[0] : false;
  2920. $last_el = ! empty( ShortcodeHelper::$tree ) ? end( ShortcodeHelper::$tree ) : false;
  2921.  
  2922. if( ! $first_el || ! in_array( $first_el['tag'], AviaBuilder::$full_el ) )
  2923. {
  2924. $out .= avia_new_section( array( 'close' => false, 'main_container' => true, 'class' => 'main_color container_wrap_first' ) );
  2925. }
  2926.  
  2927. $content = apply_filters( 'the_content', $content );
  2928. $content = apply_filters( 'avf_template_builder_content', $content );
  2929.  
  2930. $out .= $content;
  2931.  
  2932. //only close divs if the user didnt add fullwidth slider elements at the end. also skip sidebar if the last element is a slider
  2933. if( ! $last_el || ! in_array( $last_el['tag'], AviaBuilder::$full_el_no_section ) )
  2934. {
  2935. $cm = avia_section_close_markup();
  2936.  
  2937. $out .= '</div>';
  2938. $out .= "</div>{$cm} <!-- section close by builder template -->";
  2939. }
  2940.  
  2941. // global fix for https://kriesi.at/support/topic/footer-disseapearing/#post-427764
  2942. if( in_array( $last_el['tag'], AviaBuilder::$full_el_no_section ) )
  2943. {
  2944. avia_sc_section::$close_overlay = '';
  2945. }
  2946.  
  2947. $out .= avia_sc_section::$close_overlay;
  2948.  
  2949. $out .= ' </div><!--end builder template-->';
  2950. $out .= '</div><!-- close default .container_wrap element -->';
  2951.  
  2952. ShortcodeHelper::$tree = $old_tree;
  2953. ShortcodeHelper::$shortcode_index = $old_shortcode_index;
  2954.  
  2955. return $out;
  2956. }
  2957.  
  2958. } // end class
  2959.  
  2960. /**
  2961. * Returns the main instance of AviaBuilder to prevent the need to use globals
  2962. *
  2963. * @since 4.2.1
  2964. * @return AviaBuilder
  2965. */
  2966. function Avia_Builder()
  2967. {
  2968. return AviaBuilder::instance();
  2969. }
  2970.  
  2971. } // end if !class_exists
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement