khaihihi
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
// Part BC: Post types
|
||||
// =========================
|
||||
|
||||
/**
|
||||
* @param $state
|
||||
* @return bool|string
|
||||
*/
|
||||
function vc_bc_access_rule_48_post_type_get_state( $state ) {
|
||||
if ( null === $state ) {
|
||||
$content_types = vc_settings()->get( 'content_types' );
|
||||
if ( empty( $content_types ) ) {
|
||||
$state = true;
|
||||
} else {
|
||||
$state = 'custom';
|
||||
}
|
||||
}
|
||||
|
||||
return $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param $role
|
||||
* @param $rule
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
function vc_bc_access_rule_48_post_type_rule( $value, $role, $rule ) {
|
||||
if ( ! $role ) {
|
||||
return $value;
|
||||
}
|
||||
global $vc_bc_access_rule_48_editor_post_types;
|
||||
$part = vc_role_access()->who( $role->name )->part( 'post_types' );
|
||||
if ( ! isset( $part->getRole()->capabilities[ $part->getStateKey() ] ) ) {
|
||||
if ( is_null( $vc_bc_access_rule_48_editor_post_types ) ) {
|
||||
$pt_array = vc_settings()->get( 'content_types' );
|
||||
$vc_bc_access_rule_48_editor_post_types = $pt_array ? $pt_array : vc_default_editor_post_types();
|
||||
}
|
||||
|
||||
return in_array( $rule, $vc_bc_access_rule_48_editor_post_types, true );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
// Part BC: shortcodes
|
||||
// =========================
|
||||
|
||||
/**
|
||||
* @param $state
|
||||
* @param $role
|
||||
* @return bool|string
|
||||
*/
|
||||
function vc_bc_access_rule_48_shortcodes_get_state( $state, $role ) {
|
||||
if ( ! $role ) {
|
||||
return $state;
|
||||
}
|
||||
if ( null === $state ) {
|
||||
$group_access_settings = vc_settings()->get( 'groups_access_rules' );
|
||||
if ( ! isset( $group_access_settings[ $role->name ]['shortcodes'] ) ) {
|
||||
$state = true;
|
||||
} else {
|
||||
$state = 'custom';
|
||||
}
|
||||
}
|
||||
|
||||
return $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param $role
|
||||
* @param $rule
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
function vc_bc_access_rule_48_shortcodes_rule( $value, $role, $rule ) {
|
||||
if ( ! $role ) {
|
||||
return $value;
|
||||
}
|
||||
if ( ! vc_bc_access_get_shortcodes_state_is_set( $role ) ) {
|
||||
if ( preg_match( '/_edit$/', $rule ) ) {
|
||||
return false;
|
||||
}
|
||||
$group_access_settings = vc_settings()->get( 'groups_access_rules' );
|
||||
if ( isset( $group_access_settings[ $role->name ]['shortcodes'] ) && ! empty( $group_access_settings[ $role->name ]['shortcodes'] ) ) {
|
||||
$rule = preg_replace( '/_all$/', '', $rule );
|
||||
|
||||
return 'vc_row' === $rule || ( isset( $group_access_settings[ $role->name ]['shortcodes'][ $rule ] ) && 1 === (int) $group_access_settings[ $role->name ]['shortcodes'][ $rule ] );
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is state set
|
||||
*
|
||||
* @param $role
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
function vc_bc_access_get_shortcodes_state_is_set( $role ) {
|
||||
if ( ! $role ) {
|
||||
return false;
|
||||
}
|
||||
$part = vc_role_access()->who( $role->name )->part( 'shortcodes' );
|
||||
|
||||
return isset( $part->getRole()->capabilities[ $part->getStateKey() ] );
|
||||
}
|
||||
|
||||
// Part BC: backened editor
|
||||
// ===========================
|
||||
/**
|
||||
* @param $state
|
||||
* @param $role
|
||||
* @return bool|string
|
||||
*/
|
||||
function vc_bc_access_rule_48_backend_editor_get_state( $state, $role ) {
|
||||
if ( ! $role ) {
|
||||
return $state;
|
||||
}
|
||||
if ( null === $state ) {
|
||||
$group_access_settings = vc_settings()->get( 'groups_access_rules' );
|
||||
if ( ! isset( $group_access_settings[ $role->name ]['show'] ) || 'all' === $group_access_settings[ $role->name ]['show'] ) {
|
||||
$state = true;
|
||||
} elseif ( 'no' === $group_access_settings[ $role->name ]['show'] ) {
|
||||
$state = false;
|
||||
} else {
|
||||
$state = 'default';
|
||||
}
|
||||
}
|
||||
|
||||
return $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $state
|
||||
* @param $role
|
||||
* @return bool
|
||||
*/
|
||||
function vc_bc_access_rule_48_frontend_editor_get_state( $state, $role ) {
|
||||
if ( ! $role ) {
|
||||
return $state;
|
||||
}
|
||||
if ( null === $state ) {
|
||||
$group_access_settings = vc_settings()->get( 'groups_access_rules' );
|
||||
|
||||
if ( isset( $group_access_settings[ $role->name ]['show'] ) && 'no' === $group_access_settings[ $role->name ]['show'] ) {
|
||||
$state = false;
|
||||
} else {
|
||||
$state = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $state;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param $role
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
function vc_bc_access_rule_48_backend_editor_can_disabled_ce_editor_rule( $value, $role ) {
|
||||
if ( ! $role ) {
|
||||
return $value;
|
||||
}
|
||||
$part = vc_role_access()->who( $role->name )->part( 'backend_editor' );
|
||||
if ( ! isset( $part->getRole()->capabilities[ $part->getStateKey() ] ) ) {
|
||||
$group_access_settings = vc_settings()->get( 'groups_access_rules' );
|
||||
|
||||
return isset( $group_access_settings[ $role->name ]['show'] ) && 'only' === $group_access_settings[ $role->name ]['show'];
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $role
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
function vc_bc_access_rule_48_backend_editor_add_cap_disabled_ce_editor( $role ) {
|
||||
if ( ! $role ) {
|
||||
return $role;
|
||||
}
|
||||
$part = vc_role_access()->who( $role->name )->part( 'backend_editor' );
|
||||
if ( ! isset( $part->getRole()->capabilities[ $part->getStateKey() ] ) ) {
|
||||
$group_access_settings = vc_settings()->get( 'groups_access_rules' );
|
||||
if ( isset( $group_access_settings[ $role->name ]['show'] ) && 'only' === $group_access_settings[ $role->name ]['show'] ) {
|
||||
$role->capabilities[ $part->getStateKey() . '/disabled_ce_editor' ] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $role;
|
||||
}
|
||||
|
||||
function vc_bc_access_rule_48() {
|
||||
add_filter( 'vc_role_access_with_post_types_get_state', 'vc_bc_access_rule_48_post_type_get_state' );
|
||||
add_filter( 'vc_role_access_with_post_types_can', 'vc_bc_access_rule_48_post_type_rule', 10, 3 );
|
||||
|
||||
add_filter( 'vc_role_access_with_shortcodes_get_state', 'vc_bc_access_rule_48_shortcodes_get_state', 10, 3 );
|
||||
add_filter( 'vc_role_access_with_shortcodes_can', 'vc_bc_access_rule_48_shortcodes_rule', 10, 3 );
|
||||
|
||||
add_filter( 'vc_role_access_with_backend_editor_get_state', 'vc_bc_access_rule_48_backend_editor_get_state', 10, 3 );
|
||||
add_filter( 'vc_role_access_with_backend_editor_can_disabled_ce_editor', 'vc_bc_access_rule_48_backend_editor_can_disabled_ce_editor_rule', 10, 2 );
|
||||
|
||||
add_filter( 'vc_role_access_with_frontend_editor_get_state', 'vc_bc_access_rule_48_frontend_editor_get_state', 10, 3 );
|
||||
|
||||
add_filter( 'vc_role_access_all_caps_role', 'vc_bc_access_rule_48_backend_editor_add_cap_disabled_ce_editor' );
|
||||
}
|
||||
|
||||
// BC function for shortcode
|
||||
add_action( 'vc_before_init', 'vc_bc_access_rule_48' );
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
add_action( 'vc_activation_hook', 'vc_bc_multisite_options', 9 );
|
||||
|
||||
/**
|
||||
* @param $networkWide
|
||||
*/
|
||||
function vc_bc_multisite_options( $networkWide ) {
|
||||
global $current_site;
|
||||
if ( ! is_multisite() || empty( $current_site ) || ! $networkWide || get_site_option( 'vc_bc_options_called', false ) || get_site_option( 'wpb_js_js_composer_purchase_code', false ) ) {
|
||||
return;
|
||||
}
|
||||
// Now we need to check BC with license keys
|
||||
$is_main_blog_activated = get_blog_option( (int) $current_site->id, 'wpb_js_js_composer_purchase_code' );
|
||||
if ( $is_main_blog_activated ) {
|
||||
update_site_option( 'wpb_js_js_composer_purchase_code', $is_main_blog_activated );
|
||||
}
|
||||
update_site_option( 'vc_bc_options_called', true );
|
||||
}
|
||||
@@ -0,0 +1,424 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Collection of static methods for work with settings presets
|
||||
*
|
||||
* @since 4.8
|
||||
*/
|
||||
class Vc_Settings_Preset {
|
||||
|
||||
/**
|
||||
* Get default preset id for specific shortcode
|
||||
*
|
||||
* @since 4.7
|
||||
*
|
||||
* @param string $shortcode_name
|
||||
*
|
||||
* @return mixed int|null
|
||||
*/
|
||||
public static function getDefaultSettingsPresetId( $shortcode_name = null ) {
|
||||
if ( ! $shortcode_name ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'post_type' => 'vc_settings_preset',
|
||||
'post_mime_type' => self::constructShortcodeMimeType( $shortcode_name ),
|
||||
'posts_per_page' => - 1,
|
||||
'meta_key' => '_vc_default',
|
||||
'meta_value' => true,
|
||||
);
|
||||
|
||||
$posts = get_posts( $args );
|
||||
|
||||
if ( $posts ) {
|
||||
$default_id = $posts[0]->ID;
|
||||
} else {
|
||||
// check for vendor presets
|
||||
$default_id = vc_vendor_preset()->getDefaultId( $shortcode_name );
|
||||
}
|
||||
|
||||
return $default_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set existing preset as default
|
||||
*
|
||||
* If this is vendor preset, clone it and set new one as default
|
||||
*
|
||||
* @param int $id If falsy, no default will be set
|
||||
* @param string $shortcode_name
|
||||
*
|
||||
* @return boolean
|
||||
*
|
||||
* @since 4.7
|
||||
*/
|
||||
public static function setAsDefaultSettingsPreset( $id, $shortcode_name ) {
|
||||
$post_id = self::getDefaultSettingsPresetId( $shortcode_name );
|
||||
if ( $post_id ) {
|
||||
delete_post_meta( $post_id, '_vc_default' );
|
||||
}
|
||||
|
||||
if ( $id ) {
|
||||
if ( is_numeric( $id ) ) {
|
||||
// user preset
|
||||
|
||||
update_post_meta( $id, '_vc_default', true );
|
||||
} else {
|
||||
// vendor preset
|
||||
|
||||
$preset = vc_vendor_preset()->get( $id );
|
||||
|
||||
if ( ! $preset || $shortcode_name !== $preset['shortcode'] ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
self::saveSettingsPreset( $preset['shortcode'], $preset['title'], wp_json_encode( $preset['params'] ), true );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mime type for specific shortcode
|
||||
*
|
||||
* @since 4.7
|
||||
*
|
||||
* @param $shortcode_name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function constructShortcodeMimeType( $shortcode_name ) {
|
||||
return 'vc-settings-preset/' . str_replace( '_', '-', $shortcode_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shortcode name from post's mime type
|
||||
*
|
||||
* @since 4.7
|
||||
*
|
||||
* @param string $post_mime_type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function extractShortcodeMimeType( $post_mime_type ) {
|
||||
$chunks = explode( '/', $post_mime_type );
|
||||
|
||||
if ( 2 !== count( $chunks ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return str_replace( '-', '_', $chunks[1] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all presets
|
||||
*
|
||||
* @since 5.2
|
||||
*
|
||||
* @return array E.g. array(preset_id => value, preset_id => value, ...)
|
||||
*/
|
||||
public static function listAllPresets() {
|
||||
$list = array();
|
||||
|
||||
$args = array(
|
||||
'post_type' => 'vc_settings_preset',
|
||||
'posts_per_page' => - 1,
|
||||
);
|
||||
|
||||
// user presets
|
||||
$posts = get_posts( $args );
|
||||
foreach ( $posts as $post ) {
|
||||
$shortcode_name = self::extractShortcodeMimeType( $post->post_mime_type );
|
||||
$list[ $post->ID ] = (array) json_decode( $post->post_content );
|
||||
}
|
||||
|
||||
// vendor presets
|
||||
$presets = self::listDefaultVendorSettingsPresets();
|
||||
foreach ( $presets as $shortcode => $params ) {
|
||||
if ( ! isset( $list[ $shortcode ] ) ) {
|
||||
$list[ $shortcode ] = $params;
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all default presets
|
||||
*
|
||||
* @since 4.7
|
||||
*
|
||||
* @return array E.g. array(shortcode_name => value, shortcode_name => value, ...)
|
||||
*/
|
||||
public static function listDefaultSettingsPresets() {
|
||||
$list = array();
|
||||
|
||||
$args = array(
|
||||
'post_type' => 'vc_settings_preset',
|
||||
'posts_per_page' => - 1,
|
||||
'meta_key' => '_vc_default',
|
||||
'meta_value' => true,
|
||||
);
|
||||
|
||||
// user presets
|
||||
$posts = get_posts( $args );
|
||||
foreach ( $posts as $post ) {
|
||||
$shortcode_name = self::extractShortcodeMimeType( $post->post_mime_type );
|
||||
$list[ $shortcode_name ] = (array) json_decode( $post->post_content );
|
||||
}
|
||||
|
||||
// vendor presets
|
||||
$presets = self::listDefaultVendorSettingsPresets();
|
||||
foreach ( $presets as $shortcode => $params ) {
|
||||
if ( ! isset( $list[ $shortcode ] ) ) {
|
||||
$list[ $shortcode ] = $params;
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all default vendor presets
|
||||
*
|
||||
* @since 4.8
|
||||
*
|
||||
* @return array E.g. array(shortcode_name => value, shortcode_name => value, ...)
|
||||
*/
|
||||
public static function listDefaultVendorSettingsPresets() {
|
||||
$list = array();
|
||||
|
||||
$presets = vc_vendor_preset()->getDefaults();
|
||||
foreach ( $presets as $id => $preset ) {
|
||||
$list[ $preset['shortcode'] ] = $preset['params'];
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save shortcode preset
|
||||
*
|
||||
* @since 4.7
|
||||
*
|
||||
* @param string $shortcode_name
|
||||
* @param string $title
|
||||
* @param string $content
|
||||
* @param boolean $is_default
|
||||
*
|
||||
* @return mixed int|false Post ID
|
||||
*/
|
||||
public static function saveSettingsPreset( $shortcode_name, $title, $content, $is_default = false ) {
|
||||
$post_id = wp_insert_post( array(
|
||||
'post_title' => $title,
|
||||
'post_content' => $content,
|
||||
'post_status' => 'publish',
|
||||
'post_type' => 'vc_settings_preset',
|
||||
'post_mime_type' => self::constructShortcodeMimeType( $shortcode_name ),
|
||||
), false );
|
||||
|
||||
if ( $post_id && $is_default ) {
|
||||
self::setAsDefaultSettingsPreset( $post_id, $shortcode_name );
|
||||
}
|
||||
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of all presets for specific shortcode
|
||||
*
|
||||
* @since 4.7
|
||||
*
|
||||
* @param string $shortcode_name
|
||||
*
|
||||
* @return array E.g. array(id1 => title1, id2 => title2, ...)
|
||||
*/
|
||||
public static function listSettingsPresets( $shortcode_name = null ) {
|
||||
$list = array();
|
||||
|
||||
if ( ! $shortcode_name ) {
|
||||
return $list;
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'post_type' => 'vc_settings_preset',
|
||||
'orderby' => array( 'post_date' => 'DESC' ),
|
||||
'posts_per_page' => - 1,
|
||||
'post_mime_type' => self::constructShortcodeMimeType( $shortcode_name ),
|
||||
);
|
||||
|
||||
$posts = get_posts( $args );
|
||||
foreach ( $posts as $post ) {
|
||||
$list[ $post->ID ] = $post->post_title;
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of all vendor presets for specific shortcode
|
||||
*
|
||||
* @since 4.8
|
||||
*
|
||||
* @param string $shortcode_name
|
||||
*
|
||||
* @return array E.g. array(id1 => title1, id2 => title2, ...)
|
||||
*/
|
||||
public static function listVendorSettingsPresets( $shortcode_name = null ) {
|
||||
$list = array();
|
||||
|
||||
if ( ! $shortcode_name ) {
|
||||
return $list;
|
||||
}
|
||||
|
||||
$presets = vc_vendor_preset()->getAll( $shortcode_name );
|
||||
|
||||
foreach ( $presets as $id => $preset ) {
|
||||
$list[ $id ] = $preset['title'];
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get specific shortcode preset
|
||||
*
|
||||
* @since 4.7
|
||||
*
|
||||
* @param mixed $id Can be int (user preset) or string (vendor preset)
|
||||
* @param bool $array If true, return array instead of string
|
||||
*
|
||||
* @return mixed string?array Post content
|
||||
*/
|
||||
public static function getSettingsPreset( $id, $array = false ) {
|
||||
if ( is_numeric( $id ) ) {
|
||||
// user preset
|
||||
|
||||
$post = get_post( $id );
|
||||
|
||||
if ( ! $post ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$params = $array ? (array) json_decode( $post->post_content ) : $post->post_content;
|
||||
} else {
|
||||
// vendor preset
|
||||
|
||||
$preset = vc_vendor_preset()->get( $id );
|
||||
|
||||
if ( ! $preset ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$params = $preset['params'];
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete shortcode preset
|
||||
*
|
||||
* @since 4.7
|
||||
*
|
||||
* @param int $post_id Post must be of type 'vc_settings_preset'
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function deleteSettingsPreset( $post_id ) {
|
||||
$post = get_post( $post_id );
|
||||
|
||||
if ( ! $post || 'vc_settings_preset' !== $post->post_type ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) wp_delete_post( $post_id, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return rendered popup menu
|
||||
*
|
||||
* @since 4.7
|
||||
*
|
||||
* @param string $shortcode_name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getRenderedSettingsPresetPopup( $shortcode_name ) {
|
||||
$list_vendor_presets = self::listVendorSettingsPresets( $shortcode_name );
|
||||
$list_presets = self::listSettingsPresets( $shortcode_name );
|
||||
|
||||
$default_id = self::getDefaultSettingsPresetId( $shortcode_name );
|
||||
|
||||
if ( ! $default_id ) {
|
||||
$default_id = vc_vendor_preset()->getDefaultId( $shortcode_name );
|
||||
}
|
||||
|
||||
ob_start();
|
||||
vc_include_template( apply_filters( 'vc_render_settings_preset_popup', 'editors/partials/settings_presets_popup.tpl.php' ), array(
|
||||
'list_presets' => array(
|
||||
$list_presets,
|
||||
$list_vendor_presets,
|
||||
),
|
||||
'default_id' => $default_id,
|
||||
'shortcode_name' => $shortcode_name,
|
||||
) );
|
||||
|
||||
$html = ob_get_clean();
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $shortcodes
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function addVcPresetsToShortcodes( $shortcodes ) {
|
||||
if ( vc_user_access()->part( 'presets' )->can()->get() ) {
|
||||
$shortcodesAndPresets = array();
|
||||
|
||||
foreach ( $shortcodes as $shortcode ) {
|
||||
$presets = self::listSettingsPresets( $shortcode['base'] );
|
||||
$shortcodesAndPresets[ $shortcode['base'] ] = $shortcode;
|
||||
if ( ! empty( $presets ) ) {
|
||||
foreach ( $presets as $presetId => $preset ) {
|
||||
$shortcodesAndPresets[ $presetId ] = array(
|
||||
'name' => $preset,
|
||||
'base' => $shortcode['base'],
|
||||
'description' => $shortcode['description'],
|
||||
'presetId' => $presetId,
|
||||
'_category_ids' => array( '_my_elements_' ),
|
||||
);
|
||||
|
||||
if ( isset( $shortcode['icon'] ) ) {
|
||||
$shortcodesAndPresets[ $presetId ]['icon'] = $shortcode['icon'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $shortcodesAndPresets;
|
||||
}
|
||||
|
||||
return $shortcodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $category
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function addPresetCategory( $category ) {
|
||||
$presetCategory = (array) '_my_elements_';
|
||||
$category = array_merge( $presetCategory, $category );
|
||||
|
||||
return $category;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Singleton to hold all vendor presets
|
||||
*
|
||||
* @since 4.8
|
||||
*/
|
||||
class Vc_Vendor_Preset {
|
||||
|
||||
private static $instance;
|
||||
private static $presets = array();
|
||||
|
||||
/**
|
||||
* @return \Vc_Vendor_Preset
|
||||
*/
|
||||
public static function getInstance() {
|
||||
if ( ! self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
protected function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add vendor preset to collection
|
||||
*
|
||||
* @param string $title
|
||||
* @param string $shortcode
|
||||
* @param array $params
|
||||
* @param bool $default
|
||||
*
|
||||
* @return bool
|
||||
* @since 4.8
|
||||
*
|
||||
*/
|
||||
public function add( $title, $shortcode, $params, $default = false ) {
|
||||
if ( ! $title || ! is_string( $title ) || ! $shortcode || ! is_string( $shortcode ) || ! $params || ! is_array( $params ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$preset = array(
|
||||
'shortcode' => $shortcode,
|
||||
'default' => $default,
|
||||
'params' => $params,
|
||||
'title' => $title,
|
||||
);
|
||||
|
||||
// @codingStandardsIgnoreLine
|
||||
$id = md5( serialize( $preset ) );
|
||||
|
||||
self::$presets[ $id ] = $preset;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get specific vendor preset
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return mixed array|false
|
||||
* @since 4.8
|
||||
*
|
||||
*/
|
||||
public function get( $id ) {
|
||||
if ( isset( self::$presets[ $id ] ) ) {
|
||||
return self::$presets[ $id ];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all vendor presets for specific shortcode
|
||||
*
|
||||
* @param string $shortcode
|
||||
*
|
||||
* @return array
|
||||
* @since 4.8
|
||||
*
|
||||
*/
|
||||
public function getAll( $shortcode ) {
|
||||
$list = array();
|
||||
|
||||
foreach ( self::$presets as $id => $preset ) {
|
||||
if ( $shortcode === $preset['shortcode'] ) {
|
||||
$list[ $id ] = $preset;
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all default vendor presets
|
||||
*
|
||||
* Include only one default preset per shortcode
|
||||
*
|
||||
* @return array
|
||||
* @since 4.8
|
||||
*
|
||||
*/
|
||||
public function getDefaults() {
|
||||
$list = array();
|
||||
|
||||
$added = array();
|
||||
|
||||
foreach ( self::$presets as $id => $preset ) {
|
||||
if ( $preset['default'] && ! in_array( $preset['shortcode'], $added, true ) ) {
|
||||
$added[] = $preset['shortcode'];
|
||||
$list[ $id ] = $preset;
|
||||
}
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ID of default preset for specific shortcode
|
||||
*
|
||||
* If multiple presets are default, return first
|
||||
*
|
||||
* @param string $shortcode
|
||||
*
|
||||
* @return string|null
|
||||
* @since 4.8
|
||||
*
|
||||
*/
|
||||
public function getDefaultId( $shortcode ) {
|
||||
foreach ( self::$presets as $id => $preset ) {
|
||||
if ( $shortcode === $preset['shortcode'] && $preset['default'] ) {
|
||||
return $id;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"params/hidden.php": "",
|
||||
"params/vc_grid_item.php": "",
|
||||
"vendors/acf.php": "",
|
||||
"vendors/cf7.php": "",
|
||||
"vendors/gravity_forms.php": "",
|
||||
"vendors/jwplayer.php": "",
|
||||
"vendors/layerslider.php": "",
|
||||
"vendors/mqtranslate.php": "",
|
||||
"vendors/ninja_forms.php": "",
|
||||
"vendors/qtranslate.php": "",
|
||||
"vendors/qtranslate-x.php": "",
|
||||
"vendors/revslider.php": "",
|
||||
"vendors/woocommerce.php": "",
|
||||
"vendors/yoast_seo.php": "",
|
||||
"vendors/wpml.php": "",
|
||||
"vendors/gutenberg.php": "",
|
||||
"hook-vc-grid.php": "Logic for shortcode vc_grid",
|
||||
"hook-vc-iconpicker-param.php": "Logic for shortcode param iconpicker",
|
||||
"hook-vc-message.php": "Logic for shortcode vc_message",
|
||||
"hook-vc-progress-bar.php": "Logic for shortcode vc_progress_bar",
|
||||
"hook-vc-wp-text.php": "Logic for shortcode vc_wp_text fix",
|
||||
"hook-vc-pie.php": "Logic for shortcode vc_pie",
|
||||
"vc-grid-item-editor.php": "Create new post type vc_grid_item or Grid item",
|
||||
"ui-vc-pointers.php": "Integrating With WordPress’ UI: Admin Pointers",
|
||||
"vc-pages/automapper.php": "",
|
||||
"vc-pages/page-custom-css.php": "Vc Special pages.",
|
||||
"vc-pages/page-design-options.php": "Vc Special pages.",
|
||||
"vc-pages/page-role-manager.php": "Vc Special pages.",
|
||||
"vc-pages/pages.php": "Vc Special pages.",
|
||||
"vc-pages/settings-tabs.php": "Vc Special pages.",
|
||||
"vc-pages/welcome-screen.php": "Vc Special pages.",
|
||||
"vc-pointers-backend-editor.php": "Backend editor VC Pointers",
|
||||
"vc-pointers-frontend-editor.php": "Frontend editor VC Pointers",
|
||||
"vc-image-filters.php": "PHP class for photo effects like Instagram",
|
||||
"vc-settings-presets.php": "Logic for settings presets",
|
||||
"vc-single-image.php": "add bc for single image",
|
||||
"params-to-init.php": "add required init params",
|
||||
"bc-access-rules-4.8.php": "BC for roles via filters >= VC 4.8",
|
||||
"post-type-default-template.php": "Load default templates",
|
||||
"bc-multisite-options.php": "BC for multisite options",
|
||||
"vc-undoredo.php": "Undo Redo logic"
|
||||
}
|
||||
182
wp-content/plugins/js_composer/include/autoload/hook-vc-grid.php
Normal file
182
wp-content/plugins/js_composer/include/autoload/hook-vc-grid.php
Normal file
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Vc_Hooks_Vc_Grid
|
||||
* @since 4.4
|
||||
*/
|
||||
class Vc_Hooks_Vc_Grid {
|
||||
protected $grid_id_unique_name = 'vc_gid'; // if you change this also change in vc-basic-grid.php
|
||||
|
||||
/**
|
||||
* Initializing hooks for grid element,
|
||||
* Add actions to save appended shortcodes to post meta (for rendering in preview with shortcode id)
|
||||
* And add action to hook request for grid data, to output it.
|
||||
* @since 4.4
|
||||
*/
|
||||
public function load() {
|
||||
|
||||
// Hook for set post settings meta with shortcodes data
|
||||
/**
|
||||
* @since 4.4.3
|
||||
*/
|
||||
add_filter( 'vc_hooks_vc_post_settings', array(
|
||||
$this,
|
||||
'gridSavePostSettingsId',
|
||||
), 10, 3 );
|
||||
/**
|
||||
* Used to output shortcode data for ajax request. called on any page request.
|
||||
*/
|
||||
add_action( 'wp_ajax_vc_get_vc_grid_data', array(
|
||||
$this,
|
||||
'getGridDataForAjax',
|
||||
) );
|
||||
add_action( 'wp_ajax_nopriv_vc_get_vc_grid_data', array(
|
||||
$this,
|
||||
'getGridDataForAjax',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @since 4.4.3
|
||||
*/
|
||||
private function getShortcodeRegexForId() {
|
||||
return '\\[' // Opening bracket
|
||||
. '(\\[?)' // 1: Optional second opening bracket for escaping shortcodes: [[tag]]
|
||||
. '([\\w\-_]+)' // 2: Shortcode name
|
||||
. '(?![\\w\-])' // Not followed by word character or hyphen
|
||||
. '(' // 3: Unroll the loop: Inside the opening shortcode tag
|
||||
. '[^\\]\\/]*' // Not a closing bracket or forward slash
|
||||
. '(?:' . '\\/(?!\\])' // A forward slash not followed by a closing bracket
|
||||
. '[^\\]\\/]*' // Not a closing bracket or forward slash
|
||||
. ')*?'
|
||||
|
||||
. '(?:' . '(' . $this->grid_id_unique_name // 4: GridId must exist
|
||||
. '[^\\]\\/]*' // Not a closing bracket or forward slash
|
||||
. ')+' . ')'
|
||||
|
||||
. ')' . '(?:' . '(\\/)' // 5: Self closing tag ...
|
||||
. '\\]' // ... and closing bracket
|
||||
. '|' . '\\]' // Closing bracket
|
||||
. '(?:' . '(' // 6: Unroll the loop: Optionally, anything between the opening and closing shortcode tags
|
||||
. '[^\\[]*+' // Not an opening bracket
|
||||
. '(?:' . '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag
|
||||
. '[^\\[]*+' // Not an opening bracket
|
||||
. ')*+' . ')' . '\\[\\/\\2\\]' // Closing shortcode tag
|
||||
. ')?' . ')' . '(\\]?)'; // 7: Optional second closing brocket for escaping shortcodes: [[tag]]
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $settings
|
||||
* @param $post_id
|
||||
* @param $post
|
||||
*
|
||||
* @return array
|
||||
* @since 4.4.3
|
||||
*
|
||||
*/
|
||||
public function gridSavePostSettingsId( array $settings, $post_id, $post ) {
|
||||
$pattern = $this->getShortcodeRegexForId();
|
||||
$content = stripslashes( $post->post_content );
|
||||
preg_match_all( "/$pattern/", $content, $found ); // fetch only needed shortcodes
|
||||
if ( is_array( $found ) && ! empty( $found[0] ) ) {
|
||||
$to_save = array();
|
||||
if ( isset( $found[1] ) && is_array( $found[1] ) ) {
|
||||
foreach ( $found[1] as $key => $parse_able ) {
|
||||
if ( empty( $parse_able ) || '[' !== $parse_able ) {
|
||||
$id_pattern = '/' . $this->grid_id_unique_name . '\:([\w\-_]+)/';
|
||||
$id_value = $found[4][ $key ];
|
||||
|
||||
preg_match( $id_pattern, $id_value, $id_matches );
|
||||
|
||||
if ( ! empty( $id_matches ) ) {
|
||||
$id_to_save = $id_matches[1];
|
||||
|
||||
// why we need to check if shortcode is parse able?
|
||||
// 1: if it is escaped it must not be displayed (parsed)
|
||||
// 2: so if 1 is true it must not be saved in database meta
|
||||
$shortcode_tag = $found[2][ $key ];
|
||||
$shortcode_atts_string = $found[3][ $key ];
|
||||
/** @var array $atts */
|
||||
$atts = shortcode_parse_atts( $shortcode_atts_string );
|
||||
$content = $found[6][ $key ];
|
||||
$data = array(
|
||||
'tag' => $shortcode_tag,
|
||||
'atts' => $atts,
|
||||
'content' => $content,
|
||||
);
|
||||
|
||||
$to_save[ $id_to_save ] = $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! empty( $to_save ) ) {
|
||||
$settings['vc_grid_id'] = array( 'shortcodes' => $to_save );
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
* @since 4.4
|
||||
*
|
||||
* @output/@return string - grid data for ajax request.
|
||||
*/
|
||||
public function getGridDataForAjax() {
|
||||
$tag = str_replace( '.', '', vc_request_param( 'tag' ) );
|
||||
$allowed = apply_filters( 'vc_grid_get_grid_data_access', vc_verify_public_nonce() && $tag, $tag );
|
||||
if ( $allowed ) {
|
||||
$shortcode_fishbone = visual_composer()->getShortCode( $tag );
|
||||
if ( is_object( $shortcode_fishbone ) && vc_get_shortcode( $tag ) ) {
|
||||
/** @var WPBakeryShortcode_Vc_Basic_Grid $vc_grid */
|
||||
$vc_grid = $shortcode_fishbone->shortcodeClass();
|
||||
if ( method_exists( $vc_grid, 'isObjectPageable' ) && $vc_grid->isObjectPageable() && method_exists( $vc_grid, 'renderAjax' ) ) {
|
||||
// @codingStandardsIgnoreLine
|
||||
wp_die( $vc_grid->renderAjax( vc_request_param( 'data' ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
* @var Vc_Hooks_Vc_Grid $hook
|
||||
*/
|
||||
$hook = new Vc_Hooks_Vc_Grid();
|
||||
|
||||
// when WPBakery Page Builder initialized let's trigger Vc_Grid hooks.
|
||||
add_action( 'vc_after_init', array(
|
||||
$hook,
|
||||
'load',
|
||||
) );
|
||||
|
||||
if ( 'vc_edit_form' === vc_post_param( 'action' ) ) {
|
||||
VcShortcodeAutoloader::getInstance()->includeClass( 'WPBakeryShortCode_Vc_Basic_Grid' );
|
||||
|
||||
add_filter( 'vc_edit_form_fields_attributes_vc_basic_grid', array(
|
||||
'WPBakeryShortCode_Vc_Basic_Grid',
|
||||
'convertButton2ToButton3',
|
||||
) );
|
||||
|
||||
add_filter( 'vc_edit_form_fields_attributes_vc_media_grid', array(
|
||||
'WPBakeryShortCode_Vc_Basic_Grid',
|
||||
'convertButton2ToButton3',
|
||||
) );
|
||||
|
||||
add_filter( 'vc_edit_form_fields_attributes_vc_masonry_grid', array(
|
||||
'WPBakeryShortCode_Vc_Basic_Grid',
|
||||
'convertButton2ToButton3',
|
||||
) );
|
||||
|
||||
add_filter( 'vc_edit_form_fields_attributes_vc_masonry_media_grid', array(
|
||||
'WPBakeryShortCode_Vc_Basic_Grid',
|
||||
'convertButton2ToButton3',
|
||||
) );
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/***
|
||||
* @since 4.4
|
||||
* Hook Vc-Iconpicker-Param.php
|
||||
*
|
||||
* Adds actions and filters for iconpicker param.
|
||||
* Used to:
|
||||
* - register/enqueue icons fonts for admin pages
|
||||
* - register/enqueue js for iconpicker param
|
||||
* - register/enqueue css for iconpicker param
|
||||
*/
|
||||
|
||||
// @see Vc_Base::frontCss, used to append actions when frontCss(frontend editor/and real view mode) method called
|
||||
// This action registers all styles(fonts) to be enqueue later
|
||||
add_action( 'vc_base_register_front_css', 'vc_iconpicker_base_register_css' );
|
||||
|
||||
// @see Vc_Base::registerAdminCss, used to append action when registerAdminCss(backend editor) method called
|
||||
// This action registers all styles(fonts) to be enqueue later
|
||||
add_action( 'vc_base_register_admin_css', 'vc_iconpicker_base_register_css' );
|
||||
|
||||
// @see Vc_Base::registerAdminJavascript, used to append action when registerAdminJavascript(backend/frontend editor) method called
|
||||
// This action will register needed js file, and also you can use it for localizing js.
|
||||
add_action( 'vc_base_register_admin_js', 'vc_iconpicker_base_register_js' );
|
||||
|
||||
// @see Vc_Backend_Editor::printScriptsMessages (wp-content/plugins/js_composer/include/classes/editors/class-vc-backend-editor.php),
|
||||
// used to enqueue needed js/css files when backend editor is rendering
|
||||
add_action( 'vc_backend_editor_enqueue_js_css', 'vc_iconpicker_editor_jscss' );
|
||||
// @see Vc_Frontend_Editor::enqueueAdmin (wp-content/plugins/js_composer/include/classes/editors/class-vc-frontend-editor.php),
|
||||
// used to enqueue needed js/css files when frontend editor is rendering
|
||||
add_action( 'vc_frontend_editor_enqueue_js_css', 'vc_iconpicker_editor_jscss' );
|
||||
|
||||
/**
|
||||
* This action registers all styles(fonts) to be enqueue later
|
||||
* @see filter 'vc_base_register_front_css' - preview/frontend-editor
|
||||
* filter 'vc_base_register_admin_css' - backend editor
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
function vc_iconpicker_base_register_css() {
|
||||
// Vc Icon picker fonts:
|
||||
wp_register_style( 'vc_font_awesome_5_shims', vc_asset_url( 'lib/bower/font-awesome/css/v4-shims.min.css' ), array(), WPB_VC_VERSION );
|
||||
wp_register_style( 'vc_font_awesome_5', vc_asset_url( 'lib/bower/font-awesome/css/all.min.css' ), array( 'vc_font_awesome_5_shims' ), WPB_VC_VERSION );
|
||||
wp_register_style( 'vc_typicons', vc_asset_url( 'css/lib/typicons/src/font/typicons.min.css' ), false, WPB_VC_VERSION );
|
||||
wp_register_style( 'vc_openiconic', vc_asset_url( 'css/lib/vc-open-iconic/vc_openiconic.min.css' ), false, WPB_VC_VERSION );
|
||||
wp_register_style( 'vc_linecons', vc_asset_url( 'css/lib/vc-linecons/vc_linecons_icons.min.css' ), false, WPB_VC_VERSION );
|
||||
wp_register_style( 'vc_entypo', vc_asset_url( 'css/lib/vc-entypo/vc_entypo.min.css' ), false, WPB_VC_VERSION );
|
||||
wp_register_style( 'vc_monosocialiconsfont', vc_asset_url( 'css/lib/monosocialiconsfont/monosocialiconsfont.min.css' ), false, WPB_VC_VERSION );
|
||||
wp_register_style( 'vc_material', vc_asset_url( 'css/lib/vc-material/vc_material.min.css' ), false, WPB_VC_VERSION );
|
||||
// Theme
|
||||
wp_register_style( 'vc-icon-picker-main-css', vc_asset_url( 'lib/bower/vcIconPicker/css/jquery.fonticonpicker.min.css' ), false, WPB_VC_VERSION );
|
||||
wp_register_style( 'vc-icon-picker-main-css-theme', vc_asset_url( 'lib/bower/vcIconPicker/themes/grey-theme/jquery.fonticonpicker.vcgrey.min.css' ), false, WPB_VC_VERSION );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register admin js for iconpicker functionality
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
function vc_iconpicker_base_register_js() {
|
||||
wp_register_script( 'vc-icon-picker', vc_asset_url( 'lib/bower/vcIconPicker/jquery.fonticonpicker.min.js' ), array( 'jquery' ), WPB_VC_VERSION, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue ALL fonts/styles for Editor(admin) mode. (to allow easy change icons)
|
||||
* - To append your icons fonts add action:
|
||||
* vc_backend_editor_enqueue_jscss and vc_frontend_editor_enqueue_jscss
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
function vc_iconpicker_editor_jscss() {
|
||||
// Enqueue js and theme css files
|
||||
wp_enqueue_script( 'vc-icon-picker' );
|
||||
wp_enqueue_style( 'vc-icon-picker-main-css' );
|
||||
wp_enqueue_style( 'vc-icon-picker-main-css-theme' );
|
||||
|
||||
// Fonts
|
||||
wp_enqueue_style( 'vc_font_awesome_5' );
|
||||
wp_enqueue_style( 'vc_openiconic' );
|
||||
wp_enqueue_style( 'vc_typicons' );
|
||||
wp_enqueue_style( 'vc_entypo' );
|
||||
wp_enqueue_style( 'vc_linecons' );
|
||||
wp_enqueue_style( 'vc_monosocialiconsfont' );
|
||||
wp_enqueue_style( 'vc_material' );
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
if ( 'vc_edit_form' === vc_post_param( 'action' ) ) {
|
||||
VcShortcodeAutoloader::getInstance()->includeClass( 'WPBakeryShortCode_Vc_Message' );
|
||||
|
||||
add_filter( 'vc_edit_form_fields_attributes_vc_message', array(
|
||||
'WPBakeryShortCode_Vc_Message',
|
||||
'convertAttributesToMessageBox2',
|
||||
) );
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
if ( 'vc_edit_form' === vc_post_param( 'action' ) ) {
|
||||
VcShortcodeAutoloader::getInstance()->includeClass( 'WPBakeryShortCode_Vc_Pie' );
|
||||
|
||||
add_filter( 'vc_edit_form_fields_attributes_vc_pie', array(
|
||||
'WPBakeryShortCode_Vc_Pie',
|
||||
'convertOldColorsToNew',
|
||||
) );
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
if ( 'vc_edit_form' === vc_post_param( 'action' ) ) {
|
||||
VcShortcodeAutoloader::getInstance()->includeClass( 'WPBakeryShortCode_Vc_Progress_Bar' );
|
||||
|
||||
add_filter( 'vc_edit_form_fields_attributes_vc_progress_bar', array(
|
||||
'WPBakeryShortCode_Vc_Progress_Bar',
|
||||
'convertAttributesToNewProgressBar',
|
||||
) );
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
if ( 'vc_edit_form' === vc_post_param( 'action' ) ) {
|
||||
VcShortcodeAutoloader::getInstance()->includeClass( 'WPBakeryShortCode_Vc_Wp_Text' );
|
||||
|
||||
add_filter( 'vc_edit_form_fields_attributes_vc_wp_text', array(
|
||||
'WPBakeryShortCode_Vc_Wp_Text',
|
||||
'convertTextAttributeToContent',
|
||||
) );
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
add_filter( 'vc_edit_form_fields_optional_params', 'vc_edit_for_fields_add_optional_params' );
|
||||
|
||||
if ( 'vc_edit_form' === vc_post_param( 'action' ) ) {
|
||||
add_action( 'vc_edit_form_fields_after_render', 'vc_output_required_params_to_init' );
|
||||
add_filter( 'vc_edit_form_fields_optional_params', 'vc_edit_for_fields_add_optional_params' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $params
|
||||
* @return array
|
||||
*/
|
||||
function vc_edit_for_fields_add_optional_params( $params ) {
|
||||
$arr = array(
|
||||
'hidden',
|
||||
'textfield',
|
||||
'dropdown',
|
||||
'checkbox',
|
||||
'posttypes',
|
||||
'taxonomies',
|
||||
'taxomonies',
|
||||
'exploded_textarea',
|
||||
'textarea_raw_html',
|
||||
'textarea_safe',
|
||||
'textarea',
|
||||
'attach_images',
|
||||
'attach_image',
|
||||
'widgetised_sidebars',
|
||||
'colorpicker',
|
||||
'loop',
|
||||
'vc_link',
|
||||
'sorted_list',
|
||||
'tab_id',
|
||||
'href',
|
||||
'custom_markup',
|
||||
'animation_style',
|
||||
'iconpicker',
|
||||
'el_id',
|
||||
'vc_grid_item',
|
||||
'google_fonts',
|
||||
);
|
||||
$params = array_values( array_unique( array_merge( $params, $arr ) ) );
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
function vc_output_required_params_to_init() {
|
||||
$params = WpbakeryShortcodeParams::getRequiredInitParams();
|
||||
|
||||
$js_array = array();
|
||||
foreach ( $params as $param ) {
|
||||
$js_array[] = '"' . $param . '"';
|
||||
}
|
||||
|
||||
$data = '
|
||||
if ( window.vc ) {
|
||||
window.vc.required_params_to_init = [' . implode( ',', $js_array ) . '];
|
||||
}';
|
||||
$custom_tag = 'script';
|
||||
$output = '<' . $custom_tag . '>' . $data . '</' . $custom_tag . '>';
|
||||
|
||||
echo $output;
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_wpb_gallery_html', 'vc_gallery_html' );
|
||||
|
||||
function vc_gallery_html() {
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'edit_posts', 'edit_pages' )->validateDie();
|
||||
|
||||
$images = vc_post_param( 'content' );
|
||||
if ( ! empty( $images ) ) {
|
||||
wp_send_json_success( vc_field_attached_images( explode( ',', $images ) ) );
|
||||
}
|
||||
die();
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* required hooks for hidden field.
|
||||
* @since 4.5
|
||||
*/
|
||||
require_once vc_path_dir( 'PARAMS_DIR', 'hidden/hidden.php' );
|
||||
|
||||
vc_add_shortcode_param( 'hidden', 'vc_hidden_form_field' );
|
||||
add_filter( 'vc_edit_form_fields_render_field_hidden_before', 'vc_edit_form_fields_render_field_hidden_before' );
|
||||
add_filter( 'vc_edit_form_fields_render_field_hidden_after', 'vc_edit_form_fields_render_field_hidden_after' );
|
||||
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $settings
|
||||
* @param $value
|
||||
* @return string
|
||||
*/
|
||||
function vc_vc_grid_item_form_field( $settings, $value ) {
|
||||
require_once vc_path_dir( 'PARAMS_DIR', 'vc_grid_item/editor/class-vc-grid-item-editor.php' );
|
||||
require_once vc_path_dir( 'PARAMS_DIR', 'vc_grid_item/class-vc-grid-item.php' );
|
||||
$output = '<div data-vc-grid-element="container">' . '<select data-vc-grid-element="value" type="hidden" name="' . esc_attr( $settings['param_name'] ) . '" class="wpb_vc_param_value wpb-select ' . esc_attr( $settings['param_name'] ) . ' ' . esc_attr( $settings['type'] ) . '_field" ' . '>';
|
||||
$vc_grid_item_templates = Vc_Grid_Item::predefinedTemplates();
|
||||
if ( is_array( $vc_grid_item_templates ) ) {
|
||||
foreach ( $vc_grid_item_templates as $key => $data ) {
|
||||
$output .= '<option data-vc-link="' . esc_url( admin_url( 'post-new.php?post_type=vc_grid_item&vc_gitem_template=' . $key ) ) . '" value="' . esc_attr( $key ) . '"' . ( $key === $value ? ' selected="true"' : '' ) . '>' . esc_html( $data['name'] ) . '</option>';
|
||||
}
|
||||
}
|
||||
|
||||
$grid_item_posts = get_posts( array(
|
||||
'posts_per_page' => '-1',
|
||||
'orderby' => 'post_title',
|
||||
'post_type' => Vc_Grid_Item_Editor::postType(),
|
||||
) );
|
||||
foreach ( $grid_item_posts as $post ) {
|
||||
$output .= '<option data-vc-link="' . esc_url( get_edit_post_link( $post->ID ) ) . '"value="' . esc_attr( $post->ID ) . '"' . ( (string) $post->ID === $value ? ' selected="true"' : '' ) . '>' . esc_html( $post->post_title ) . '</option>';
|
||||
}
|
||||
$output .= '</select></div>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
function vc_load_vc_grid_item_param() {
|
||||
vc_add_shortcode_param( 'vc_grid_item', 'vc_vc_grid_item_form_field' );
|
||||
}
|
||||
|
||||
add_action( 'vc_load_default_params', 'vc_load_vc_grid_item_param' );
|
||||
/**
|
||||
* @param $target
|
||||
* @return string
|
||||
*/
|
||||
function vc_gitem_post_data_get_link_target_frontend_editor( $target ) {
|
||||
return ' target="_blank"';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $rel
|
||||
* @return string
|
||||
*/
|
||||
function vc_gitem_post_data_get_link_rel_frontend_editor( $rel ) {
|
||||
return ' rel="' . esc_attr( $rel ) . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $atts
|
||||
* @param string $default_class
|
||||
* @param string $title
|
||||
* @return string
|
||||
*/
|
||||
function vc_gitem_create_link( $atts, $default_class = '', $title = '' ) {
|
||||
$link = '';
|
||||
$target = '';
|
||||
$rel = '';
|
||||
$title_attr = '';
|
||||
$css_class = 'vc_gitem-link' . ( strlen( $default_class ) > 0 ? ' ' . $default_class : '' );
|
||||
if ( isset( $atts['link'] ) ) {
|
||||
if ( 'custom' === $atts['link'] && ! empty( $atts['url'] ) ) {
|
||||
$link = vc_build_link( $atts['url'] );
|
||||
if ( strlen( $link['target'] ) ) {
|
||||
$target = ' target="' . esc_attr( $link['target'] ) . '"';
|
||||
}
|
||||
if ( strlen( $link['rel'] ) ) {
|
||||
$rel = ' rel="' . esc_attr( $link['rel'] ) . '"';
|
||||
}
|
||||
if ( strlen( $link['title'] ) ) {
|
||||
$title = $link['title'];
|
||||
}
|
||||
$link = 'a href="' . esc_url( $link['url'] ) . '" class="' . esc_attr( $css_class ) . '"';
|
||||
} elseif ( 'post_link' === $atts['link'] ) {
|
||||
$link = 'a href="{{ post_link_url }}" class="' . esc_attr( $css_class ) . '"';
|
||||
if ( ! strlen( $title ) ) {
|
||||
$title = '{{ post_title }}';
|
||||
}
|
||||
} elseif ( 'post_author' === $atts['link'] ) {
|
||||
$link = 'a href="{{ post_author_href }}" class="' . esc_attr( $css_class ) . '"';
|
||||
if ( ! strlen( $title ) ) {
|
||||
$title = '{{ post_author }}';
|
||||
}
|
||||
} elseif ( 'image' === $atts['link'] ) {
|
||||
$link = 'a{{ post_image_url_href }} class="' . esc_attr( $css_class ) . '"';
|
||||
} elseif ( 'image_lightbox' === $atts['link'] ) {
|
||||
$link = 'a{{ post_image_url_attr_prettyphoto:' . $css_class . ' }}';
|
||||
}
|
||||
}
|
||||
if ( strlen( $title ) > 0 ) {
|
||||
$title_attr = ' title="' . esc_attr( $title ) . '"';
|
||||
}
|
||||
|
||||
return apply_filters( 'vc_gitem_post_data_get_link_link', $link, $atts, $css_class ) . apply_filters( 'vc_gitem_post_data_get_link_target', $target, $atts ) . apply_filters( 'vc_gitem_post_data_get_link_rel', $rel, $atts ) . apply_filters( 'vc_gitem_post_data_get_link_title', $title_attr, $atts );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $atts
|
||||
* @param $post
|
||||
* @param string $default_class
|
||||
* @param string $title
|
||||
* @return string
|
||||
*/
|
||||
function vc_gitem_create_link_real( $atts, $post, $default_class = '', $title = '' ) {
|
||||
$link = '';
|
||||
$target = '';
|
||||
$rel = '';
|
||||
$title_attr = '';
|
||||
$link_css_class = 'vc_gitem-link';
|
||||
if ( isset( $atts['link'] ) ) {
|
||||
$link_css_class = 'vc_gitem-link' . ( strlen( $default_class ) > 0 ? ' ' . $default_class : '' );
|
||||
if ( strlen( $atts['el_class'] ) > 0 ) {
|
||||
$link_css_class .= ' ' . $atts['el_class'];
|
||||
}
|
||||
$link_css_class = trim( preg_replace( '/\s+/', ' ', $link_css_class ) );
|
||||
if ( 'custom' === $atts['link'] && ! empty( $atts['url'] ) ) {
|
||||
$link = vc_build_link( $atts['url'] );
|
||||
if ( strlen( $link['target'] ) ) {
|
||||
$target = ' target="' . esc_attr( $link['target'] ) . '"';
|
||||
}
|
||||
if ( strlen( $link['rel'] ) ) {
|
||||
$rel = ' rel="' . esc_attr( $link['rel'] ) . '"';
|
||||
}
|
||||
if ( strlen( $link['title'] ) ) {
|
||||
$title = $link['title'];
|
||||
}
|
||||
$link = 'a href="' . esc_url( $link['url'] ) . '" class="' . esc_attr( $link_css_class ) . '"';
|
||||
} elseif ( 'post_link' === $atts['link'] ) {
|
||||
$link = 'a href="' . esc_url( get_permalink( $post->ID ) ) . '" class="' . esc_attr( $link_css_class ) . '"';
|
||||
if ( ! strlen( $title ) ) {
|
||||
$title = the_title( '', '', false );
|
||||
}
|
||||
} elseif ( 'image' === $atts['link'] ) {
|
||||
$href_link = vc_gitem_template_attribute_post_image_url( '', array(
|
||||
'post' => $post,
|
||||
'data' => '',
|
||||
) );
|
||||
$link = 'a href="' . esc_url( $href_link ) . '" class="' . esc_attr( $link_css_class ) . '"';
|
||||
} elseif ( 'image_lightbox' === $atts['link'] ) {
|
||||
$link = 'a' . vc_gitem_template_attribute_post_image_url_attr_prettyphoto( '', array(
|
||||
'post' => $post,
|
||||
'data' => esc_attr( $link_css_class ),
|
||||
) );
|
||||
}
|
||||
}
|
||||
if ( strlen( $title ) > 0 ) {
|
||||
$title_attr = ' title="' . esc_attr( $title ) . '"';
|
||||
}
|
||||
|
||||
return apply_filters( 'vc_gitem_post_data_get_link_real_link', $link, $atts, $post, $link_css_class ) . apply_filters( 'vc_gitem_post_data_get_link_real_target', $target, $atts, $post ) . apply_filters( 'vc_gitem_post_data_get_link_real_rel', $rel, $atts, $post ) . apply_filters( 'vc_gitem_post_data_get_link_real_title', $title_attr, $atts );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $link
|
||||
* @return string
|
||||
*/
|
||||
function vc_gitem_post_data_get_link_link_frontend_editor( $link ) {
|
||||
return empty( $link ) ? 'a' : $link;
|
||||
}
|
||||
|
||||
if ( vc_is_page_editable() ) {
|
||||
add_filter( 'vc_gitem_post_data_get_link_link', 'vc_gitem_post_data_get_link_link_frontend_editor' );
|
||||
add_filter( 'vc_gitem_post_data_get_link_real_link', 'vc_gitem_post_data_get_link_link_frontend_editor' );
|
||||
add_filter( 'vc_gitem_post_data_get_link_target', 'vc_gitem_post_data_get_link_target_frontend_editor' );
|
||||
add_filter( 'vc_gitem_post_data_get_link_rel', 'vc_gitem_post_data_get_link_rel_frontend_editor' );
|
||||
add_filter( 'vc_gitem_post_data_get_link_real_target', 'vc_gitem_post_data_get_link_target_frontend_editor' );
|
||||
add_filter( 'vc_gitem_post_data_get_link_real_rel', 'vc_gitem_post_data_get_link_rel_frontend_editor' );
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true value for filter 'wpb_vc_js_status_filter'.
|
||||
* It allows to start backend editor on load.
|
||||
* @return string
|
||||
* @since 4.12
|
||||
*
|
||||
*/
|
||||
function vc_set_default_content_for_post_type_wpb_vc_js_status_filter() {
|
||||
return 'true';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default content by post type in editor.
|
||||
*
|
||||
* Data for post type templates stored in settings.
|
||||
*
|
||||
* @param $post_content
|
||||
* @param $post
|
||||
* @return null
|
||||
* @throws \Exception
|
||||
* @since 4.12
|
||||
*
|
||||
*/
|
||||
function vc_set_default_content_for_post_type( $post_content, $post ) {
|
||||
if ( ! empty( $post_content ) || ! vc_backend_editor()->isValidPostType( $post->post_type ) ) {
|
||||
return $post_content;
|
||||
}
|
||||
$template_settings = new Vc_Setting_Post_Type_Default_Template_Field( 'general', 'default_template_post_type' );
|
||||
$new_post_content = $template_settings->getTemplateByPostType( $post->post_type );
|
||||
if ( null !== $new_post_content ) {
|
||||
add_filter( 'wpb_vc_js_status_filter', 'vc_set_default_content_for_post_type_wpb_vc_js_status_filter' );
|
||||
|
||||
return $new_post_content;
|
||||
}
|
||||
|
||||
return $post_content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default template for post types manager
|
||||
*
|
||||
* Class Vc_Setting_Post_Type_Default_Template_Field
|
||||
*
|
||||
* @since 4.12
|
||||
*/
|
||||
class Vc_Setting_Post_Type_Default_Template_Field {
|
||||
protected $tab;
|
||||
protected $key;
|
||||
protected $post_types = false;
|
||||
|
||||
/**
|
||||
* Vc_Setting_Post_Type_Default_Template_Field constructor.
|
||||
* @param $tab
|
||||
* @param $key
|
||||
*/
|
||||
public function __construct( $tab, $key ) {
|
||||
$this->tab = $tab;
|
||||
$this->key = $key;
|
||||
add_action( 'vc_settings_tab-general', array(
|
||||
$this,
|
||||
'addField',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getFieldName() {
|
||||
return esc_html__( 'Default template for post types', 'js_composer' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getFieldKey() {
|
||||
require_once vc_path_dir( 'SETTINGS_DIR', 'class-vc-settings.php' );
|
||||
|
||||
return Vc_Settings::getFieldPrefix() . $this->key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @return bool
|
||||
*/
|
||||
protected function isValidPostType( $type ) {
|
||||
return post_type_exists( $type );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|bool
|
||||
*/
|
||||
protected function getPostTypes() {
|
||||
if ( false === $this->post_types ) {
|
||||
require_once vc_path_dir( 'SETTINGS_DIR', 'class-vc-roles.php' );
|
||||
$vc_roles = new Vc_Roles();
|
||||
$this->post_types = $vc_roles->getPostTypes();
|
||||
}
|
||||
|
||||
return $this->post_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function getTemplates() {
|
||||
return $this->getTemplatesEditor()->getAllTemplates();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool|\Vc_Templates_Panel_Editor
|
||||
*/
|
||||
protected function getTemplatesEditor() {
|
||||
return visual_composer()->templatesPanelEditor();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get settings data for default templates
|
||||
*
|
||||
* @return array|mixed
|
||||
*/
|
||||
protected function get() {
|
||||
require_once vc_path_dir( 'SETTINGS_DIR', 'class-vc-settings.php' );
|
||||
|
||||
$value = Vc_Settings::get( $this->key );
|
||||
|
||||
return $value ? $value : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get template's shortcodes string
|
||||
*
|
||||
* @param $template_data
|
||||
* @return string|null
|
||||
*/
|
||||
protected function getTemplate( $template_data ) {
|
||||
$template = null;
|
||||
$template_settings = preg_split( '/\:\:/', $template_data );
|
||||
|
||||
$template_id = $template_settings[1];
|
||||
$template_type = $template_settings[0];
|
||||
|
||||
if ( ! isset( $template_id, $template_type ) || '' === $template_id || '' === $template_type ) {
|
||||
return $template;
|
||||
}
|
||||
WPBMap::addAllMappedShortcodes();
|
||||
if ( 'my_templates' === $template_type ) {
|
||||
$saved_templates = get_option( $this->getTemplatesEditor()->getOptionName() );
|
||||
|
||||
$content = trim( $saved_templates[ $template_id ]['template'] );
|
||||
$content = str_replace( '\"', '"', $content );
|
||||
$pattern = get_shortcode_regex();
|
||||
$template = preg_replace_callback( "/{$pattern}/s", 'vc_convert_shortcode', $content );
|
||||
} else {
|
||||
if ( 'default_templates' === $template_type ) {
|
||||
$template_data = $this->getTemplatesEditor()->getDefaultTemplate( (int) $template_id );
|
||||
if ( isset( $template_data['content'] ) ) {
|
||||
$template = $template_data['content'];
|
||||
}
|
||||
} else {
|
||||
$template_preview = apply_filters( 'vc_templates_render_backend_template_preview', $template_id, $template_type );
|
||||
if ( (string) $template_preview !== (string) $template_id ) {
|
||||
$template = $template_preview;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $type
|
||||
* @return string|null
|
||||
*/
|
||||
public function getTemplateByPostType( $type ) {
|
||||
$value = $this->get();
|
||||
|
||||
return isset( $value[ $type ] ) ? $this->getTemplate( $value[ $type ] ) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $settings
|
||||
* @return mixed
|
||||
*/
|
||||
public function sanitize( $settings ) {
|
||||
foreach ( $settings as $type => $template ) {
|
||||
if ( empty( $template ) ) {
|
||||
unset( $settings[ $type ] );
|
||||
} elseif ( ! $this->isValidPostType( $type ) || ! $this->getTemplate( $template ) ) {
|
||||
add_settings_error( $this->getFieldKey(), 1, esc_html__( 'Invalid template or post type.', 'js_composer' ), 'error' );
|
||||
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
vc_include_template( 'pages/vc-settings/default-template-post-type.tpl.php', array(
|
||||
'post_types' => $this->getPostTypes(),
|
||||
'templates' => $this->getTemplates(),
|
||||
'title' => $this->getFieldName(),
|
||||
'value' => $this->get(),
|
||||
'field_key' => $this->getFieldKey(),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add field settings page
|
||||
*
|
||||
* Method called by vc hook vc_settings_tab-general.
|
||||
*/
|
||||
public function addField() {
|
||||
vc_settings()->addField( $this->tab, $this->getFieldName(), $this->key, array(
|
||||
$this,
|
||||
'sanitize',
|
||||
), array(
|
||||
$this,
|
||||
'render',
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start only for admin part with hooks
|
||||
*/
|
||||
if ( is_admin() ) {
|
||||
/**
|
||||
* Initialize Vc_Setting_Post_Type_Default_Template_Field
|
||||
* Called by admin_init hook
|
||||
*/
|
||||
function vc_settings_post_type_default_template_field_init() {
|
||||
new Vc_Setting_Post_Type_Default_Template_Field( 'general', 'default_template_post_type' );
|
||||
}
|
||||
|
||||
add_filter( 'default_content', 'vc_set_default_content_for_post_type', 100, 2 );
|
||||
add_action( 'admin_init', 'vc_settings_post_type_default_template_field_init', 8 );
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
global $vc_default_pointers, $vc_pointers;
|
||||
$vc_default_pointers = (array) apply_filters( 'vc_pointers_list', array(
|
||||
'vc_grid_item',
|
||||
'vc_pointers_backend_editor',
|
||||
'vc_pointers_frontend_editor',
|
||||
) );
|
||||
if ( is_admin() ) {
|
||||
add_action( 'admin_enqueue_scripts', 'vc_pointer_load', 1000 );
|
||||
}
|
||||
|
||||
function vc_pointer_load() {
|
||||
global $vc_pointers;
|
||||
// Don't run on WP < 3.3
|
||||
if ( get_bloginfo( 'version' ) < '3.3' ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$screen = get_current_screen();
|
||||
$screen_id = $screen->id;
|
||||
|
||||
// Get pointers for this screen
|
||||
$pointers = apply_filters( 'vc-ui-pointers', array() );
|
||||
$pointers = apply_filters( 'vc_ui-pointers-' . $screen_id, $pointers );
|
||||
|
||||
if ( ! $pointers || ! is_array( $pointers ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get dismissed pointers
|
||||
$dismissed = explode( ',', (string) get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true ) );
|
||||
$vc_pointers = array( 'pointers' => array() );
|
||||
|
||||
// Check pointers and remove dismissed ones.
|
||||
foreach ( $pointers as $pointer_id => $pointer ) {
|
||||
|
||||
// Sanity check
|
||||
if ( in_array( $pointer_id, $dismissed, true ) || empty( $pointer ) || empty( $pointer_id ) || empty( $pointer['name'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$pointer['pointer_id'] = $pointer_id;
|
||||
|
||||
// Add the pointer to $valid_pointers array
|
||||
|
||||
$vc_pointers['pointers'][] = $pointer;
|
||||
}
|
||||
|
||||
// No valid pointers? Stop here.
|
||||
if ( empty( $vc_pointers['pointers'] ) ) {
|
||||
return;
|
||||
}
|
||||
wp_enqueue_style( 'wp-pointer' );
|
||||
wp_enqueue_script( 'wp-pointer' );
|
||||
// messages
|
||||
$vc_pointers['texts'] = array(
|
||||
'finish' => esc_html__( 'Finish', 'js_composer' ),
|
||||
'next' => esc_html__( 'Next', 'js_composer' ),
|
||||
'prev' => esc_html__( 'Prev', 'js_composer' ),
|
||||
);
|
||||
|
||||
// Add pointer options to script.
|
||||
wp_localize_script( 'wp-pointer', 'vcPointer', $vc_pointers );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove Vc pointers keys to show Tour markers again.
|
||||
* @sine 4.5
|
||||
*/
|
||||
function vc_pointer_reset() {
|
||||
global $vc_default_pointers;
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'manage_options' )->validateDie()->part( 'settings' )->can( 'vc-general-tab' )->validateDie();
|
||||
|
||||
$pointers = (array) apply_filters( 'vc_pointers_list', $vc_default_pointers );
|
||||
$prev_meta_value = get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true );
|
||||
$dismissed = explode( ',', (string) $prev_meta_value );
|
||||
if ( count( $dismissed ) > 0 && count( $pointers ) ) {
|
||||
$meta_value = implode( ',', array_diff( $dismissed, $pointers ) );
|
||||
update_user_meta( get_current_user_id(), 'dismissed_wp_pointers', $meta_value, $prev_meta_value );
|
||||
}
|
||||
|
||||
wp_send_json( array( 'success' => true ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset tour guid
|
||||
* @return bool
|
||||
*/
|
||||
function vc_pointers_is_dismissed() {
|
||||
global $vc_default_pointers;
|
||||
$pointers = (array) apply_filters( 'vc_pointers_list', $vc_default_pointers );
|
||||
$prev_meta_value = get_user_meta( get_current_user_id(), 'dismissed_wp_pointers', true );
|
||||
$dismissed = explode( ',', (string) $prev_meta_value );
|
||||
|
||||
return count( array_diff( $dismissed, $pointers ) ) < count( $dismissed );
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_vc_pointer_reset', 'vc_pointer_reset' );
|
||||
@@ -0,0 +1,298 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
global $vc_grid_item_editor;
|
||||
/**
|
||||
* Creates new post type for grid_editor.
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
function vc_grid_item_editor_create_post_type() {
|
||||
if ( is_admin() ) {
|
||||
require_once vc_path_dir( 'PARAMS_DIR', 'vc_grid_item/editor/class-vc-grid-item-editor.php' );
|
||||
Vc_Grid_Item_Editor::createPostType();
|
||||
add_action( 'vc_menu_page_build', 'vc_gitem_add_submenu_page' );
|
||||
// TODO: add check vendor is active
|
||||
add_filter( 'vc_vendor_qtranslate_enqueue_js_backend', 'vc_vendor_qtranslate_enqueue_js_backend_grid_editor' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.5
|
||||
*/
|
||||
function vc_vendor_qtranslate_enqueue_js_backend_grid_editor() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set required objects to render editor for grid item
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
function vc_grid_item_editor_init() {
|
||||
global $vc_grid_item_editor;
|
||||
require_once vc_path_dir( 'PARAMS_DIR', 'vc_grid_item/editor/class-vc-grid-item-editor.php' );
|
||||
require_once vc_path_dir( 'PARAMS_DIR', 'vc_grid_item/class-wpb-map-grid-item.php' );
|
||||
$vc_grid_item_editor = new Vc_Grid_Item_Editor();
|
||||
$vc_grid_item_editor->addMetaBox();
|
||||
add_action( 'wp_ajax_vc_grid_item_editor_load_template_preview', array(
|
||||
&$vc_grid_item_editor,
|
||||
'renderTemplatePreview',
|
||||
) );
|
||||
$vc_grid_item_editor->addHooksSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render preview for grid item
|
||||
* @since 4.4
|
||||
*/
|
||||
function vc_grid_item_render_preview() {
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( array(
|
||||
'edit_post',
|
||||
(int) vc_request_param( 'post_id' ),
|
||||
) )->validateDie()->part( 'grid_builder' )->can()->validateDie();
|
||||
|
||||
require_once vc_path_dir( 'PARAMS_DIR', 'vc_grid_item/class-vc-grid-item.php' );
|
||||
$grid_item = new Vc_Grid_Item();
|
||||
$grid_item->mapShortcodes();
|
||||
require_once vc_path_dir( 'PARAMS_DIR', 'vc_grid_item/editor/class-vc-grid-item-preview.php' );
|
||||
$vcGridPreview = new Vc_Grid_Item_Preview();
|
||||
add_filter( 'vc_gitem_template_attribute_post_image_background_image_css_value', array(
|
||||
$vcGridPreview,
|
||||
'addCssBackgroundImage',
|
||||
) );
|
||||
add_filter( 'vc_gitem_template_attribute_post_image_url_value', array(
|
||||
$vcGridPreview,
|
||||
'addImageUrl',
|
||||
) );
|
||||
add_filter( 'vc_gitem_template_attribute_post_image_html', array(
|
||||
$vcGridPreview,
|
||||
'addImage',
|
||||
) );
|
||||
add_filter( 'vc_gitem_attribute_featured_image_img', array(
|
||||
$vcGridPreview,
|
||||
'addPlaceholderImage',
|
||||
) );
|
||||
add_filter( 'vc_gitem_post_data_get_link_real_link', array(
|
||||
$vcGridPreview,
|
||||
'disableRealContentLink',
|
||||
), 10, 4 );
|
||||
add_filter( 'vc_gitem_post_data_get_link_link', array(
|
||||
$vcGridPreview,
|
||||
'disableContentLink',
|
||||
), 10, 3 );
|
||||
add_filter( 'vc_gitem_zone_image_block_link', array(
|
||||
$vcGridPreview,
|
||||
'disableGitemZoneLink',
|
||||
) );
|
||||
$vcGridPreview->render();
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Map grid element shortcodes.
|
||||
*
|
||||
* @since 4.5
|
||||
*/
|
||||
function vc_grid_item_map_shortcodes() {
|
||||
require_once vc_path_dir( 'PARAMS_DIR', 'vc_grid_item/class-vc-grid-item.php' );
|
||||
$grid_item = new Vc_Grid_Item();
|
||||
$grid_item->mapShortcodes();
|
||||
vc_mapper()->setCheckForAccess( false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current post type
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
function vc_grid_item_get_post_type() {
|
||||
$post_type = null;
|
||||
if ( vc_request_param( 'post_type' ) ) {
|
||||
$post_type = vc_request_param( 'post_type' );
|
||||
} elseif ( vc_request_param( 'post' ) ) {
|
||||
$post = get_post( vc_request_param( 'post' ) );
|
||||
$post_type = $post instanceof WP_Post && $post->post_type ? $post->post_type : null;
|
||||
}
|
||||
|
||||
return $post_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check and Map grid element shortcodes if required.
|
||||
* @since 4.5
|
||||
*/
|
||||
function vc_grid_item_editor_shortcodes() {
|
||||
require_once vc_path_dir( 'PARAMS_DIR', 'vc_grid_item/editor/class-vc-grid-item-editor.php' );
|
||||
// TODO: remove this because mapping can be based on post_type
|
||||
if ( ( 'true' === vc_request_param( 'vc_grid_item_editor' ) || ( is_admin() && vc_grid_item_get_post_type() === Vc_Grid_Item_Editor::postType() ) && vc_user_access()
|
||||
->wpAny( 'edit_posts', 'edit_pages' )->part( 'grid_builder' )->can()->get() ) ) {
|
||||
|
||||
global $vc_grid_item_editor;
|
||||
add_action( 'vc_user_access_check-shortcode_edit', array(
|
||||
&$vc_grid_item_editor,
|
||||
'accessCheckShortcodeEdit',
|
||||
), 10, 2 );
|
||||
add_action( 'vc_user_access_check-shortcode_all', array(
|
||||
&$vc_grid_item_editor,
|
||||
'accessCheckShortcodeAll',
|
||||
), 10, 2 );
|
||||
|
||||
vc_grid_item_map_shortcodes();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* add action in admin for vc grid item editor manager
|
||||
*/
|
||||
add_action( 'init', 'vc_grid_item_editor_create_post_type' );
|
||||
add_action( 'admin_init', 'vc_grid_item_editor_init' );
|
||||
add_action( 'vc_after_init', 'vc_grid_item_editor_shortcodes' );
|
||||
/**
|
||||
* Call preview as ajax request is called.
|
||||
*/
|
||||
add_action( 'wp_ajax_vc_gitem_preview', 'vc_grid_item_render_preview', 5 );
|
||||
|
||||
/**
|
||||
* Add WP ui pointers in grid element editor.
|
||||
*/
|
||||
if ( is_admin() ) {
|
||||
add_filter( 'vc_ui-pointers-vc_grid_item', 'vc_grid_item_register_pointer' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $pointers
|
||||
* @return mixed
|
||||
*/
|
||||
function vc_grid_item_register_pointer( $pointers ) {
|
||||
$screen = get_current_screen();
|
||||
if ( 'add' === $screen->action ) {
|
||||
$pointers['vc_grid_item'] = array(
|
||||
'name' => 'vcPointersController',
|
||||
'messages' => array(
|
||||
array(
|
||||
'target' => '#vc_templates-editor-button',
|
||||
'options' => array(
|
||||
'content' => sprintf( '<h3> %s </h3> <p> %s </p>', esc_html__( 'Start Here!', 'js_composer' ), esc_html__( 'Start easy - use predefined template as a starting point and modify it.', 'js_composer' ) ),
|
||||
'position' => array(
|
||||
'edge' => 'left',
|
||||
'align' => 'center',
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'target' => '[data-vc-navbar-control="animation"]',
|
||||
'options' => array(
|
||||
'content' => sprintf( '<h3> %s </h3> <p> %s </p>', esc_html__( 'Use Animations', 'js_composer' ), esc_html__( 'Select animation preset for grid element. "Hover" state will be added next to the "Normal" state tab.', 'js_composer' ) ),
|
||||
'position' => array(
|
||||
'edge' => 'right',
|
||||
'align' => 'center',
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'target' => '.vc_gitem_animated_block-shortcode',
|
||||
'options' => array(
|
||||
'content' => sprintf( '<h3> %s </h3> <p> %s </p>', esc_html__( 'Style Design Options', 'js_composer' ), esc_html__( 'Edit "Normal" state to set "Featured image" as a background, control zone sizing proportions and other design options (Height mode: Select "Original" to scale image without cropping).', 'js_composer' ) ),
|
||||
'position' => array(
|
||||
'edge' => 'bottom',
|
||||
'align' => 'center',
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'target' => '[data-vc-gitem="add-c"][data-vc-position="top"]',
|
||||
'options' => array(
|
||||
'content' => sprintf( '<h3> %s </h3> <p> %s </p>', esc_html__( 'Extend Element', 'js_composer' ), esc_html__( 'Additional content zone can be added to grid element edges (Note: This zone can not be animated).', 'js_composer' ) ) . '<p><img src="' . esc_url( vc_asset_url( 'vc/gb_additional_content.png' ) ) . '" alt="" /></p>',
|
||||
'position' => array(
|
||||
'edge' => 'right',
|
||||
'align' => 'center',
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'target' => '#wpadminbar',
|
||||
'options' => array(
|
||||
'content' => sprintf( '<h3> %s </h3> %s', esc_html__( 'Watch Video Tutorial', 'js_composer' ), '<p>' . esc_html__( 'Have a look how easy it is to work with grid element builder.', 'js_composer' ) . '</p>' . '<iframe width="500" height="281" src="https://www.youtube.com/embed/sBvEiIL6Blo" frameborder="0" allowfullscreen></iframe>' ),
|
||||
'position' => array(
|
||||
'edge' => 'top',
|
||||
'align' => 'center',
|
||||
),
|
||||
'pointerClass' => 'vc_gitem-animated-block-pointer-video',
|
||||
'pointerWidth' => '530',
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return $pointers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|mixed|void
|
||||
*/
|
||||
function vc_gitem_content_shortcodes() {
|
||||
require_once vc_path_dir( 'PARAMS_DIR', 'vc_grid_item/class-vc-grid-item.php' );
|
||||
$grid_item = new Vc_Grid_Item();
|
||||
$invalid_shortcodes = apply_filters( 'vc_gitem_zone_grid_item_not_content_shortcodes', array(
|
||||
'vc_gitem',
|
||||
'vc_gitem_animated_block',
|
||||
'vc_gitem_zone',
|
||||
'vc_gitem_zone_a',
|
||||
'vc_gitem_zone_b',
|
||||
'vc_gitem_zone_c',
|
||||
'vc_gitem_row',
|
||||
'vc_gitem_col',
|
||||
) );
|
||||
|
||||
return array_diff( array_keys( $grid_item->shortcodes() ), $invalid_shortcodes );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $content
|
||||
* @return false|int
|
||||
*/
|
||||
function vc_gitem_has_content( $content ) {
|
||||
$tags = vc_gitem_content_shortcodes();
|
||||
$regexp = vc_get_shortcode_regex( implode( '|', $tags ) );
|
||||
|
||||
return preg_match( '/' . $regexp . '/', $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add sub page to WPBakery Page Builder pages
|
||||
*
|
||||
* @since 4.5
|
||||
*/
|
||||
function vc_gitem_add_submenu_page() {
|
||||
if ( vc_user_access()->part( 'grid_builder' )->can()->get() ) {
|
||||
$labels = Vc_Grid_Item_Editor::getPostTypesLabels();
|
||||
add_submenu_page( VC_PAGE_MAIN_SLUG, $labels['name'], $labels['name'], 'edit_posts', 'edit.php?post_type=' . rawurlencode( Vc_Grid_Item_Editor::postType() ), '' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Highlight Vc submenu.
|
||||
* @since 4.5
|
||||
*/
|
||||
function vc_gitem_menu_highlight() {
|
||||
global $parent_file, $submenu_file, $post_type;
|
||||
require_once vc_path_dir( 'PARAMS_DIR', 'vc_grid_item/editor/class-vc-grid-item-editor.php' );
|
||||
if ( Vc_Grid_Item_Editor::postType() === $post_type && defined( 'VC_PAGE_MAIN_SLUG' ) ) {
|
||||
$parent_file = VC_PAGE_MAIN_SLUG;
|
||||
$submenu_file = 'edit.php?post_type=' . rawurlencode( Vc_Grid_Item_Editor::postType() );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
add_action( 'admin_head', 'vc_gitem_menu_highlight' );
|
||||
|
||||
function vc_gitem_set_mapper_check_access() {
|
||||
if ( vc_user_access()->checkAdminNonce()->wpAny( 'edit_posts', 'edit_pages' )->part( 'grid_builder' )->can()->get() && 'true' === vc_post_param( 'vc_grid_item_editor' ) ) {
|
||||
vc_mapper()->setCheckForAccess( false );
|
||||
}
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_vc_edit_form', 'vc_gitem_set_mapper_check_access' );
|
||||
@@ -0,0 +1,358 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
add_filter( 'attachment_fields_to_edit', 'vc_attachment_filter_field', 10, 2 );
|
||||
add_filter( 'media_meta', 'vc_attachment_filter_media_meta', 10, 2 );
|
||||
add_action( 'wp_ajax_vc_media_editor_add_image', 'vc_media_editor_add_image' );
|
||||
add_action( 'wp_ajax_vc_media_editor_preview_image', 'vc_media_editor_preview_image' );
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
function vc_get_filters() {
|
||||
return array(
|
||||
'antique' => esc_html__( 'Antique', 'js_composer' ),
|
||||
'blackwhite' => esc_html__( 'Black & White', 'js_composer' ),
|
||||
'boost' => esc_html__( 'Boost', 'js_composer' ),
|
||||
'concentrate' => esc_html__( 'Concentrate', 'js_composer' ),
|
||||
'country' => esc_html__( 'Country', 'js_composer' ),
|
||||
'darken' => esc_html__( 'Darken', 'js_composer' ),
|
||||
'dream' => esc_html__( 'Dream', 'js_composer' ),
|
||||
'everglow' => esc_html__( 'Everglow', 'js_composer' ),
|
||||
'forest' => esc_html__( 'Forest', 'js_composer' ),
|
||||
'freshblue' => esc_html__( 'Fresh Blue', 'js_composer' ),
|
||||
'frozen' => esc_html__( 'Frozen', 'js_composer' ),
|
||||
'hermajesty' => esc_html__( 'Her Majesty', 'js_composer' ),
|
||||
'light' => esc_html__( 'Light', 'js_composer' ),
|
||||
'orangepeel' => esc_html__( 'Orange Peel', 'js_composer' ),
|
||||
'rain' => esc_html__( 'Rain', 'js_composer' ),
|
||||
'retro' => esc_html__( 'Retro', 'js_composer' ),
|
||||
'sepia' => esc_html__( 'Sepia', 'js_composer' ),
|
||||
'summer' => esc_html__( 'Summer', 'js_composer' ),
|
||||
'tender' => esc_html__( 'Tender', 'js_composer' ),
|
||||
'vintage' => esc_html__( 'Vintage', 'js_composer' ),
|
||||
'washed' => esc_html__( 'Washed', 'js_composer' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Image Filter field to media uploader
|
||||
*
|
||||
* @param array $form_fields , fields to include in attachment form
|
||||
* @param object $post , attachment record in database
|
||||
*
|
||||
* @return array $form_fields, modified form fields
|
||||
*/
|
||||
function vc_attachment_filter_field( $form_fields, $post ) {
|
||||
// don't add filter field, if image already has filter applied
|
||||
if ( get_post_meta( $post->ID, 'vc-applied-image-filter', true ) ) {
|
||||
return $form_fields;
|
||||
}
|
||||
|
||||
$options = vc_get_filters();
|
||||
|
||||
$html_options = '<option value="">' . esc_html__( 'None', 'js_composer' ) . '</option>';
|
||||
foreach ( $options as $value => $title ) {
|
||||
$html_options .= '<option value="' . esc_attr( $value ) . '">' . esc_html( $title ) . '</option>';
|
||||
}
|
||||
|
||||
$form_fields['vc-image-filter'] = array(
|
||||
'label' => '',
|
||||
'input' => 'html',
|
||||
'html' => '
|
||||
<div style="display:none">
|
||||
<span class="vc-filter-label">' . esc_html__( 'Image filter', 'js_composer' ) . '</span>
|
||||
<select name="attachments[' . esc_attr( $post->ID ) . '][vc-image-filter]" id="attachments-' . esc_attr( $post->ID ) . '-vc-image-filter" data-vc-preview-image-filter="' . esc_attr( $post->ID ) . '">
|
||||
' . $html_options . '
|
||||
</select>
|
||||
</div>',
|
||||
'value' => get_post_meta( $post->ID, 'vc_image_filter', true ),
|
||||
'helps' => '',
|
||||
);
|
||||
|
||||
return $form_fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply filters to specified images
|
||||
*
|
||||
* If image(s) has filter specified via filters _POST param:
|
||||
* 1) copy it
|
||||
* 2) apply specified filter
|
||||
* 3) return new image id
|
||||
*
|
||||
* Required _POST params:
|
||||
* - array ids: array of attachment ids
|
||||
*
|
||||
* Optional _POST params:
|
||||
* - array filters: mapped array of ids and filters to apply
|
||||
*
|
||||
*/
|
||||
function vc_media_editor_add_image() {
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'upload_files' )->validateDie();
|
||||
|
||||
require_once vc_path_dir( 'HELPERS_DIR', 'class-vc-image-filter.php' );
|
||||
$response = array(
|
||||
'success' => true,
|
||||
'data' => array(
|
||||
'ids' => array(),
|
||||
),
|
||||
);
|
||||
|
||||
$filters = (array) vc_post_param( 'filters', array() );
|
||||
|
||||
$ids = (array) vc_post_param( 'ids', array() );
|
||||
if ( ! $ids ) {
|
||||
wp_send_json( $response );
|
||||
}
|
||||
|
||||
// default action is wp_handle_upload, which forces wp to check upload with is_uploaded_file()
|
||||
// override action to anything else to skip security checks
|
||||
$action = 'vc_handle_upload_imitation';
|
||||
|
||||
$file_key = 0;
|
||||
$post_id = 0;
|
||||
$post_data = array();
|
||||
$overrides = array( 'action' => $action );
|
||||
$_POST = array( 'action' => $action );
|
||||
|
||||
foreach ( $ids as $key => $attachment_id ) {
|
||||
if ( ! empty( $filters[ $attachment_id ] ) ) {
|
||||
$filter_name = $filters[ $attachment_id ];
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
$source_path = get_attached_file( $attachment_id );
|
||||
|
||||
if ( empty( $source_path ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$temp_path = sys_get_temp_dir() . DIRECTORY_SEPARATOR . basename( $source_path );
|
||||
|
||||
if ( ! copy( $source_path, $temp_path ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$extension = strtolower( pathinfo( $temp_path, PATHINFO_EXTENSION ) );
|
||||
$mime_type = '';
|
||||
switch ( $extension ) {
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
$image = imagecreatefromjpeg( $temp_path );
|
||||
$mime_type = 'image/jpeg';
|
||||
break;
|
||||
|
||||
case 'png':
|
||||
$image = imagecreatefrompng( $temp_path );
|
||||
$mime_type = 'image/png';
|
||||
break;
|
||||
|
||||
case 'gif':
|
||||
$image = imagecreatefromgif( $temp_path );
|
||||
$mime_type = 'image/gif';
|
||||
break;
|
||||
|
||||
default:
|
||||
$image = false;
|
||||
}
|
||||
|
||||
if ( ! $image ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$Filter = new vcImageFilter( $image );
|
||||
$Filter->$filter_name();
|
||||
|
||||
if ( ! vc_save_gd_resource( $Filter->getImage(), $temp_path ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$new_filename = basename( $temp_path, '.' . $extension ) . '-' . $filter_name . '.' . $extension;
|
||||
|
||||
$_FILES = array(
|
||||
array(
|
||||
'name' => $new_filename,
|
||||
'type' => $mime_type,
|
||||
'tmp_name' => $temp_path,
|
||||
'error' => UPLOAD_ERR_OK,
|
||||
'size' => filesize( $temp_path ),
|
||||
),
|
||||
);
|
||||
|
||||
$new_attachment_id = media_handle_upload( $file_key, $post_id, $post_data, $overrides );
|
||||
|
||||
if ( ! $new_attachment_id || is_wp_error( $new_attachment_id ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
update_post_meta( $new_attachment_id, 'vc-applied-image-filter', $filter_name );
|
||||
|
||||
$ids[ $key ] = $new_attachment_id;
|
||||
}
|
||||
|
||||
$response['data']['ids'] = $ids;
|
||||
|
||||
wp_send_json( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate filter preview
|
||||
*
|
||||
* Preview url is generated as data uri (base64)
|
||||
*
|
||||
* Required _POST params:
|
||||
* - string filter: filter name
|
||||
* - int attachment_id: attachment id
|
||||
*
|
||||
* @return void Results are sent out as json
|
||||
* @throws \Exception
|
||||
*/
|
||||
function vc_media_editor_preview_image() {
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'upload_files' )->validateDie();
|
||||
|
||||
require_once vc_path_dir( 'HELPERS_DIR', 'class-vc-image-filter.php' );
|
||||
|
||||
$response = array(
|
||||
'success' => true,
|
||||
'data' => array(
|
||||
'src' => '',
|
||||
),
|
||||
);
|
||||
|
||||
$filter_name = vc_post_param( 'filter', '' );
|
||||
$attachment_id = vc_post_param( 'attachment_id', false );
|
||||
$preferred_size = vc_post_param( 'preferred_size', 'medium' );
|
||||
|
||||
if ( ! $filter_name || ! $attachment_id ) {
|
||||
wp_send_json( $response );
|
||||
}
|
||||
|
||||
$attachment_path = get_attached_file( $attachment_id );
|
||||
|
||||
$attachment_details = wp_prepare_attachment_for_js( $attachment_id );
|
||||
|
||||
if ( ! isset( $attachment_details['sizes'][ $preferred_size ] ) ) {
|
||||
$preferred_size = 'thumbnail';
|
||||
}
|
||||
|
||||
$attachment_url = wp_get_attachment_image_src( $attachment_id, $preferred_size );
|
||||
|
||||
if ( empty( $attachment_path ) || empty( $attachment_url[0] ) ) {
|
||||
wp_send_json( $response );
|
||||
}
|
||||
|
||||
$source_path = dirname( $attachment_path ) . '/' . basename( $attachment_url[0] );
|
||||
|
||||
$image = vc_get_gd_resource( $source_path );
|
||||
|
||||
if ( ! $image ) {
|
||||
wp_send_json( $response );
|
||||
}
|
||||
|
||||
$Filter = new vcImageFilter( $image );
|
||||
$Filter->$filter_name();
|
||||
|
||||
$extension = strtolower( pathinfo( $source_path, PATHINFO_EXTENSION ) );
|
||||
|
||||
ob_start();
|
||||
switch ( $extension ) {
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
imagejpeg( $Filter->getImage() );
|
||||
break;
|
||||
|
||||
case 'png':
|
||||
imagepng( $Filter->getImage() );
|
||||
break;
|
||||
|
||||
case 'gif':
|
||||
imagegif( $Filter->getImage() );
|
||||
break;
|
||||
}
|
||||
|
||||
$data = ob_get_clean();
|
||||
|
||||
// @codingStandardsIgnoreLine
|
||||
$response['data']['src'] = 'data:image/' . $extension . ';base64,' . base64_encode( $data );
|
||||
|
||||
wp_send_json( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Read file from disk as GD resource
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return bool|resource
|
||||
*/
|
||||
function vc_get_gd_resource( $file ) {
|
||||
$extension = strtolower( pathinfo( $file, PATHINFO_EXTENSION ) );
|
||||
|
||||
switch ( $extension ) {
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
return imagecreatefromjpeg( $file );
|
||||
|
||||
case 'png':
|
||||
return imagecreatefrompng( $file );
|
||||
|
||||
case 'gif':
|
||||
return imagecreatefromgif( $file );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save GD resource to file
|
||||
*
|
||||
* @param resource $resource
|
||||
* @param string $file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
function vc_save_gd_resource( $resource, $file ) {
|
||||
$extension = strtolower( pathinfo( $file, PATHINFO_EXTENSION ) );
|
||||
|
||||
switch ( $extension ) {
|
||||
case 'jpeg':
|
||||
case 'jpg':
|
||||
return imagejpeg( $resource, $file );
|
||||
|
||||
case 'png':
|
||||
return imagepng( $resource, $file );
|
||||
|
||||
case 'gif':
|
||||
return imagegif( $resource, $file );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add "Filter: ..." meta field to attachment details box
|
||||
*
|
||||
* @param array $media_meta , meta to include in attachment form
|
||||
* @param object $post , attachment record in database
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
function vc_attachment_filter_media_meta( $media_meta, $post ) {
|
||||
$filter_name = get_post_meta( $post->ID, 'vc-applied-image-filter', true );
|
||||
if ( ! $filter_name ) {
|
||||
return $media_meta;
|
||||
}
|
||||
|
||||
$filters = vc_get_filters();
|
||||
if ( ! isset( $filters[ $filter_name ] ) ) {
|
||||
return $media_meta;
|
||||
}
|
||||
|
||||
$media_meta .= esc_html__( 'Filter:', 'js_composer' ) . ' ' . $filters[ $filter_name ];
|
||||
|
||||
return $media_meta;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and enqueue js/css for automapper settings tab.
|
||||
* @since 4.5
|
||||
*/
|
||||
function vc_automapper_init() {
|
||||
if ( vc_user_access()->wpAny( 'manage_options' )->part( 'settings' )->can( 'vc-automapper-tab' )->get() ) {
|
||||
vc_automapper()->addAjaxActions();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns automapper template.
|
||||
*
|
||||
* @return string
|
||||
* @since 4.5
|
||||
*/
|
||||
function vc_page_automapper_build() {
|
||||
return 'pages/vc-settings/vc-automapper.php';
|
||||
}
|
||||
|
||||
// TODO: move to separate file in autoload
|
||||
add_filter( 'vc_settings-render-tab-vc-automapper', 'vc_page_automapper_build' );
|
||||
is_admin() && ( strpos( vc_request_param( 'action' ), 'vc_automapper' ) !== false || 'vc-automapper' === vc_get_param( 'page' ) ) && add_action( 'admin_init', 'vc_automapper_init' );
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
function vc_page_settings_custom_css_load() {
|
||||
wp_enqueue_script( 'ace-editor', vc_asset_url( 'lib/bower/ace-builds/src-min-noconflict/ace.js' ), array( 'jquery' ), WPB_VC_VERSION, true );
|
||||
}
|
||||
|
||||
add_action( 'vc-settings-render-tab-vc-custom_css', 'vc_page_settings_custom_css_load' );
|
||||
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to check for current less version during page open
|
||||
*
|
||||
* @since 4.5
|
||||
*/
|
||||
add_action( 'vc_before_init', 'vc_check_for_custom_css_build' );
|
||||
|
||||
/**
|
||||
* Function check is system has custom build of css
|
||||
* and check it version in comparison with current VC version
|
||||
*
|
||||
* @since 4.5
|
||||
*/
|
||||
function vc_check_for_custom_css_build() {
|
||||
$version = vc_settings()->getCustomCssVersion();
|
||||
if ( vc_user_access()->wpAny( 'manage_options' )->part( 'settings' )->can( 'vc-color-tab' )
|
||||
->get() && vc_settings()->useCustomCss() && ( ! $version || version_compare( WPB_VC_VERSION, $version, '<>' ) ) ) {
|
||||
add_action( 'admin_notices', 'vc_custom_css_admin_notice' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display admin notice depending on current page
|
||||
*
|
||||
* @since 4.5
|
||||
*/
|
||||
function vc_custom_css_admin_notice() {
|
||||
global $current_screen;
|
||||
vc_settings()->set( 'compiled_js_composer_less', '' );
|
||||
$class = 'notice notice-warning vc_settings-custom-design-notice';
|
||||
$message_important = esc_html__( 'Important notice', 'js_composer' );
|
||||
if ( is_object( $current_screen ) && isset( $current_screen->id ) && 'visual-composer_page_vc-color' === $current_screen->id ) {
|
||||
$message = esc_html__( 'You have an outdated version of WPBakery Page Builder Design Options. It is required to review and save it.', 'js_composer' );
|
||||
echo '<div class="' . esc_attr( $class ) . '"><p><strong>' . esc_html( $message_important ) . '</strong>: ' . esc_html( $message ) . '</p></div>';
|
||||
} else {
|
||||
$message = esc_html__( 'You have an outdated version of WPBakery Page Builder Design Options. It is required to review and save it.', 'js_composer' );
|
||||
$btnClass = 'button button-primary button-large vc_button-settings-less';
|
||||
echo '<div class="' . esc_attr( $class ) . '"><p><strong>' . esc_html( $message_important ) . '</strong>: ' . esc_html( $message ) . '</p>' . '<p>';
|
||||
echo '<a ' . implode( ' ', array(
|
||||
'href="' . esc_url( admin_url( 'admin.php?page=vc-color' ) ) . '"',
|
||||
'class="' . esc_attr( $btnClass ) . '"',
|
||||
'id="vc_less-save-button"',
|
||||
'style="vertical-align: baseline;"',
|
||||
// needed to fix ":active bug"
|
||||
) ) . '>';
|
||||
echo esc_html__( 'Open Design Options', 'js_composer' ) . '</a>';
|
||||
echo '</p></div>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $submitButtonAttributes
|
||||
* @return mixed
|
||||
*/
|
||||
function vc_page_settings_tab_color_submit_attributes( $submitButtonAttributes ) {
|
||||
$submitButtonAttributes['data-vc-less-path'] = vc_str_remove_protocol( vc_asset_url( 'less/js_composer.less' ) );
|
||||
$submitButtonAttributes['data-vc-less-root'] = vc_str_remove_protocol( vc_asset_url( 'less' ) );
|
||||
$submitButtonAttributes['data-vc-less-variables'] = wp_json_encode( apply_filters( 'vc_settings-less-variables', array(
|
||||
// Main accent color:
|
||||
'vc_grey' => array(
|
||||
'key' => 'wpb_js_vc_color',
|
||||
'default' => vc_settings()->getDefault( 'vc_color' ),
|
||||
),
|
||||
// Hover color
|
||||
'vc_grey_hover' => array(
|
||||
'key' => 'wpb_js_vc_color_hover',
|
||||
'default' => vc_settings()->getDefault( 'vc_color_hover' ),
|
||||
),
|
||||
'vc_image_slider_link_active' => 'wpb_js_vc_color_hover',
|
||||
// Call to action background color
|
||||
'vc_call_to_action_bg' => 'wpb_js_vc_color_call_to_action_bg',
|
||||
'vc_call_to_action_2_bg' => 'wpb_js_vc_color_call_to_action_bg',
|
||||
'vc_call_to_action_border' => array(
|
||||
'key' => 'wpb_js_vc_color_call_to_action_border',
|
||||
// darken 5%
|
||||
'default_key' => 'wpb_js_vc_color',
|
||||
'modify_output' => array(
|
||||
array(
|
||||
'plain' => array(
|
||||
'darken({{ value }}, 5%)',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// Google maps background color
|
||||
'vc_google_maps_bg' => 'wpb_js_vc_color_google_maps_bg',
|
||||
// Post slider caption background color
|
||||
'vc_post_slider_caption_bg' => 'wpb_js_vc_color_post_slider_caption_bg',
|
||||
// Progress bar background color
|
||||
'vc_progress_bar_bg' => 'wpb_js_vc_color_progress_bar_bg',
|
||||
// Separator border color
|
||||
'vc_separator_border' => 'wpb_js_vc_color_separator_border',
|
||||
// Tabs navigation background color
|
||||
'vc_tab_bg' => 'wpb_js_vc_color_tab_bg',
|
||||
// Active tab background color
|
||||
'vc_tab_bg_active' => 'wpb_js_vc_color_tab_bg_active',
|
||||
// Elements bottom margin
|
||||
'vc_element_margin_bottom' => array(
|
||||
'key' => 'wpb_js_margin',
|
||||
'default' => vc_settings()->getDefault( 'margin' ),
|
||||
),
|
||||
// Grid gutter width
|
||||
'grid-gutter-width' => array(
|
||||
'key' => 'wpb_js_gutter',
|
||||
'default' => vc_settings()->getDefault( 'gutter' ),
|
||||
'modify_output' => array(
|
||||
array(
|
||||
'plain' => array(
|
||||
'{{ value }}px',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
'screen-sm-min' => array(
|
||||
'key' => 'wpb_js_responsive_max',
|
||||
'default' => vc_settings()->getDefault( 'responsive_max' ),
|
||||
'modify_output' => array(
|
||||
array(
|
||||
'plain' => array(
|
||||
'{{ value }}px',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
) ) );
|
||||
|
||||
return $submitButtonAttributes;
|
||||
}
|
||||
|
||||
function vc_page_settings_desing_options_load() {
|
||||
add_filter( 'vc_settings-tab-submit-button-attributes-color', 'vc_page_settings_tab_color_submit_attributes' );
|
||||
wp_enqueue_script( 'vc_less_js', vc_asset_url( 'lib/bower/lessjs/dist/less.min.js' ), array(), WPB_VC_VERSION, true );
|
||||
}
|
||||
|
||||
add_action( 'vc-settings-render-tab-vc-color', 'vc_page_settings_desing_options_load' );
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
/**
|
||||
* @param $tabs
|
||||
* @return array
|
||||
*/
|
||||
function vc_settings_tabs_vc_roles( $tabs ) {
|
||||
// inster after vc-general tab
|
||||
if ( array_key_exists( 'vc-general', $tabs ) ) {
|
||||
$new = array();
|
||||
foreach ( $tabs as $key => $value ) {
|
||||
$new[ $key ] = $value;
|
||||
if ( 'vc-general' === $key ) {
|
||||
$new['vc-roles'] = esc_html__( 'Role Manager', 'js_composer' );
|
||||
}
|
||||
}
|
||||
$tabs = $new;
|
||||
} else {
|
||||
$tabs['vc-roles'] = esc_html__( 'Roles Manager', 'js_composer' );
|
||||
}
|
||||
|
||||
return $tabs;
|
||||
}
|
||||
|
||||
if ( ! is_network_admin() ) {
|
||||
add_filter( 'vc_settings_tabs', 'vc_settings_tabs_vc_roles' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
function vc_settings_render_tab_vc_roles() {
|
||||
return 'pages/vc-settings/tab-vc-roles.php';
|
||||
}
|
||||
|
||||
add_filter( 'vc_settings-render-tab-vc-roles', 'vc_settings_render_tab_vc_roles' );
|
||||
|
||||
function vc_roles_settings_save() {
|
||||
if ( check_admin_referer( 'vc_settings-roles-action', 'vc_nonce_field' ) && current_user_can( 'manage_options' ) ) {
|
||||
require_once vc_path_dir( 'SETTINGS_DIR', 'class-vc-roles.php' );
|
||||
$vc_roles = new Vc_Roles();
|
||||
$data = $vc_roles->save( vc_request_param( 'vc_roles', array() ) );
|
||||
echo wp_json_encode( $data );
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_vc_roles_settings_save', 'vc_roles_settings_save' );
|
||||
if ( 'vc-roles' === vc_get_param( 'page' ) ) {
|
||||
function vc_settings_render_tab_vc_roles_scripts() {
|
||||
wp_register_script( 'vc_accordion_script', vc_asset_url( 'lib/vc_accordion/vc-accordion.min.js' ), array( 'jquery' ), WPB_VC_VERSION, true );
|
||||
}
|
||||
|
||||
add_action( 'admin_init', 'vc_settings_render_tab_vc_roles_scripts' );
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.5
|
||||
*/
|
||||
function vc_page_css_enqueue() {
|
||||
wp_enqueue_style( 'vc_page-css', vc_asset_url( 'css/js_composer_settings.min.css' ), array(), WPB_VC_VERSION );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build group page objects.
|
||||
*
|
||||
* @param $slug
|
||||
* @param $title
|
||||
* @param $tab
|
||||
*
|
||||
* @return Vc_Pages_Group
|
||||
* @since 4.5
|
||||
*
|
||||
*/
|
||||
function vc_pages_group_build( $slug, $title, $tab = '' ) {
|
||||
$vc_page_welcome_tabs = vc_get_page_welcome_tabs();
|
||||
require_once vc_path_dir( 'CORE_DIR', 'class-vc-page.php' );
|
||||
require_once vc_path_dir( 'CORE_DIR', 'class-vc-pages-group.php' );
|
||||
// Create page.
|
||||
if ( ! strlen( $tab ) ) {
|
||||
$tab = $slug;
|
||||
}
|
||||
$page = new Vc_Page();
|
||||
$page->setSlug( $tab )->setTitle( $title )->setTemplatePath( 'pages/' . $slug . '/' . $tab . '.php' );
|
||||
// Create page group to stick with other in template.
|
||||
$pages_group = new Vc_Pages_Group();
|
||||
$pages_group->setSlug( $slug )->setPages( $vc_page_welcome_tabs )->setActivePage( $page )->setTemplatePath( 'pages/vc-welcome/index.php' );
|
||||
|
||||
return $pages_group;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.5
|
||||
*/
|
||||
function vc_menu_page_build() {
|
||||
if ( vc_user_access()->wpAny( 'manage_options' )->part( 'settings' )->can( 'vc-general-tab' )->get() ) {
|
||||
define( 'VC_PAGE_MAIN_SLUG', 'vc-general' );
|
||||
} else {
|
||||
define( 'VC_PAGE_MAIN_SLUG', 'vc-welcome' );
|
||||
}
|
||||
add_menu_page( esc_html__( 'WPBakery Page Builder', 'js_composer' ), esc_html__( 'WPBakery Page Builder', 'js_composer' ), 'edit_posts', VC_PAGE_MAIN_SLUG, null, vc_asset_url( 'vc/logo/wpb-logo-white_32.svg' ), 76 );
|
||||
do_action( 'vc_menu_page_build' );
|
||||
}
|
||||
|
||||
function vc_network_menu_page_build() {
|
||||
if ( ! vc_is_network_plugin() ) {
|
||||
return;
|
||||
}
|
||||
if ( vc_user_access()->wpAny( 'manage_options' )->part( 'settings' )->can( 'vc-general-tab' )->get() && ! is_main_site() ) {
|
||||
define( 'VC_PAGE_MAIN_SLUG', 'vc-general' );
|
||||
} else {
|
||||
define( 'VC_PAGE_MAIN_SLUG', 'vc-welcome' );
|
||||
}
|
||||
add_menu_page( esc_html__( 'WPBakery Page Builder', 'js_composer' ), esc_html__( 'WPBakery Page Builder', 'js_composer' ), 'exist', VC_PAGE_MAIN_SLUG, null, vc_asset_url( 'vc/logo/wpb-logo-white_32.svg' ), 76 );
|
||||
do_action( 'vc_network_menu_page_build' );
|
||||
}
|
||||
|
||||
add_action( 'admin_menu', 'vc_menu_page_build' );
|
||||
add_action( 'network_admin_menu', 'vc_network_menu_page_build' );
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
function vc_page_settings_render() {
|
||||
$page = vc_get_param( 'page' );
|
||||
do_action( 'vc_page_settings_render-' . $page );
|
||||
vc_settings()->renderTab( $page );
|
||||
}
|
||||
|
||||
function vc_page_settings_build() {
|
||||
if ( ! vc_user_access()->wpAny( 'manage_options' )->get() ) {
|
||||
return;
|
||||
}
|
||||
$tabs = vc_settings()->getTabs();
|
||||
foreach ( $tabs as $slug => $title ) {
|
||||
$has_access = vc_user_access()->part( 'settings' )->can( $slug . '-tab' )->get();
|
||||
|
||||
if ( $has_access ) {
|
||||
$page = add_submenu_page( VC_PAGE_MAIN_SLUG, $title, $title, 'manage_options', $slug, 'vc_page_settings_render' );
|
||||
add_action( 'load-' . $page, array(
|
||||
vc_settings(),
|
||||
'adminLoad',
|
||||
) );
|
||||
}
|
||||
}
|
||||
do_action( 'vc_page_settings_build' );
|
||||
}
|
||||
|
||||
function vc_page_settings_admin_init() {
|
||||
vc_settings()->initAdmin();
|
||||
}
|
||||
|
||||
add_action( 'vc_menu_page_build', 'vc_page_settings_build' );
|
||||
add_action( 'vc_network_menu_page_build', 'vc_page_settings_build' );
|
||||
add_action( 'admin_init', 'vc_page_settings_admin_init' );
|
||||
add_action( 'vc-settings-render-tab-vc-roles', 'vc_settings_enqueue_js' );
|
||||
|
||||
function vc_settings_enqueue_js() {
|
||||
// enqueue accordion in vc-roles page only
|
||||
wp_enqueue_script( 'vc_accordion_script' );
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get welcome pages main slug.
|
||||
*
|
||||
* @return mixed|string
|
||||
* @since 4.5
|
||||
*/
|
||||
function vc_page_welcome_slug() {
|
||||
$vc_page_welcome_tabs = vc_get_page_welcome_tabs();
|
||||
|
||||
return isset( $vc_page_welcome_tabs ) ? key( $vc_page_welcome_tabs ) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Build vc-welcome page block which will be shown after Vc installation.
|
||||
*
|
||||
* vc_filter: vc_page_welcome_render_capabilities
|
||||
*
|
||||
* @since 4.5
|
||||
*/
|
||||
function vc_page_welcome_render() {
|
||||
$vc_page_welcome_tabs = vc_get_page_welcome_tabs();
|
||||
$slug = vc_page_welcome_slug();
|
||||
$tab_slug = vc_get_param( 'tab', $slug );
|
||||
// If tab slug in the list please render;
|
||||
if ( ! empty( $tab_slug ) && isset( $vc_page_welcome_tabs[ $tab_slug ] ) ) {
|
||||
$pages_group = vc_pages_group_build( $slug, $vc_page_welcome_tabs[ $tab_slug ], $tab_slug );
|
||||
$pages_group->render();
|
||||
}
|
||||
}
|
||||
|
||||
function vc_page_welcome_add_sub_page() {
|
||||
// Add submenu page
|
||||
$page = add_submenu_page( VC_PAGE_MAIN_SLUG, esc_html__( 'About', 'js_composer' ), esc_html__( 'About', 'js_composer' ), 'edit_posts', vc_page_welcome_slug(), 'vc_page_welcome_render' );
|
||||
// Css for perfect styling.
|
||||
add_action( 'admin_print_styles-' . $page, 'vc_page_css_enqueue' );
|
||||
|
||||
}
|
||||
|
||||
function vc_welcome_menu_hooks() {
|
||||
$settings_tab_enabled = vc_user_access()->wpAny( 'manage_options' )->part( 'settings' )->can( 'vc-general-tab' )->get();
|
||||
add_action( 'vc_menu_page_build', 'vc_page_welcome_add_sub_page', $settings_tab_enabled ? 11 : 1 );
|
||||
}
|
||||
|
||||
function vc_welcome_menu_hooks_network() {
|
||||
if ( ! vc_is_network_plugin() ) {
|
||||
return;
|
||||
}
|
||||
$settings_tab_enabled = vc_user_access()->wpAny( 'manage_options' )->part( 'settings' )->can( 'vc-general-tab' )->get();
|
||||
add_action( 'vc_network_menu_page_build', 'vc_page_welcome_add_sub_page', $settings_tab_enabled && ! is_main_site() ? 11 : 1 );
|
||||
}
|
||||
|
||||
add_action( 'admin_menu', 'vc_welcome_menu_hooks', 9 );
|
||||
add_action( 'network_admin_menu', 'vc_welcome_menu_hooks_network', 9 );
|
||||
/**
|
||||
* ====================
|
||||
* Redirect to welcome page on plugin activation.
|
||||
* ====================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set redirect transition on update or activation
|
||||
* @since 4.5
|
||||
*/
|
||||
function vc_page_welcome_set_redirect() {
|
||||
if ( ! is_network_admin() && ! vc_get_param( 'activate-multi' ) ) {
|
||||
set_transient( '_vc_page_welcome_redirect', 1, 30 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do redirect if required on welcome page
|
||||
* @since 4.5
|
||||
*/
|
||||
function vc_page_welcome_redirect() {
|
||||
$redirect = get_transient( '_vc_page_welcome_redirect' );
|
||||
delete_transient( '_vc_page_welcome_redirect' );
|
||||
if ( $redirect ) {
|
||||
wp_safe_redirect( admin_url( 'admin.php?page=' . rawurlencode( vc_page_welcome_slug() ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Enables redirect on activation.
|
||||
add_action( 'vc_activation_hook', 'vc_page_welcome_set_redirect' );
|
||||
add_action( 'admin_init', 'vc_page_welcome_redirect' );
|
||||
|
||||
/**
|
||||
* @return mixed|void
|
||||
*/
|
||||
function vc_get_page_welcome_tabs() {
|
||||
global $vc_page_welcome_tabs;
|
||||
$vc_page_welcome_tabs = apply_filters( 'vc_page-welcome-slugs-list', array(
|
||||
'vc-welcome' => esc_html__( 'What\'s New', 'js_composer' ),
|
||||
'vc-faq' => esc_html__( 'FAQ', 'js_composer' ),
|
||||
'vc-resources' => esc_html__( 'Resources', 'js_composer' ),
|
||||
) );
|
||||
|
||||
return $vc_page_welcome_tabs;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add WP ui pointers to backend editor.
|
||||
*/
|
||||
function vc_add_admin_pointer() {
|
||||
if ( is_admin() ) {
|
||||
foreach ( vc_editor_post_types() as $post_type ) {
|
||||
add_filter( 'vc_ui-pointers-' . $post_type, 'vc_backend_editor_register_pointer' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
add_action( 'admin_init', 'vc_add_admin_pointer' );
|
||||
|
||||
/**
|
||||
* @param $pointers
|
||||
* @return mixed
|
||||
*/
|
||||
function vc_backend_editor_register_pointer( $pointers ) {
|
||||
$screen = get_current_screen();
|
||||
$block = false;
|
||||
if ( method_exists( $screen, 'is_block_editor' ) ) {
|
||||
if ( $screen->is_block_editor() ) {
|
||||
$block = true;
|
||||
}
|
||||
}
|
||||
if ( ! $block || 'add' === $screen->action ) {
|
||||
$pointers['vc_pointers_backend_editor'] = array(
|
||||
'name' => 'vcPointerController',
|
||||
'messages' => array(
|
||||
array(
|
||||
'target' => '.composer-switch',
|
||||
'options' => array(
|
||||
'content' => sprintf( '<h3> %s </h3> <p> %s </p>', esc_html__( 'Welcome to WPBakery Page Builder', 'js_composer' ), esc_html__( 'Choose Backend or Frontend editor.', 'js_composer' ) ),
|
||||
'position' => array(
|
||||
'edge' => 'left',
|
||||
'align' => 'center',
|
||||
),
|
||||
'buttonsEvent' => 'vcPointersEditorsTourEvents',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'target' => '#vc_templates-editor-button, #vc-templatera-editor-button',
|
||||
'options' => array(
|
||||
'content' => sprintf( '<h3> %s </h3> <p> %s </p>', esc_html__( 'Add Elements', 'js_composer' ), esc_html__( 'Add new element or start with a template.', 'js_composer' ) ),
|
||||
'position' => array(
|
||||
'edge' => 'left',
|
||||
'align' => 'center',
|
||||
),
|
||||
'buttonsEvent' => 'vcPointersEditorsTourEvents',
|
||||
),
|
||||
'closeEvent' => 'shortcodes:vc_row:add',
|
||||
'showEvent' => 'backendEditor.show',
|
||||
),
|
||||
array(
|
||||
'target' => '[data-vc-control="add"]:first',
|
||||
'options' => array(
|
||||
'content' => sprintf( '<h3> %s </h3> <p> %s </p>', esc_html__( 'Rows and Columns', 'js_composer' ), esc_html__( 'This is a row container. Divide it into columns and style it. You can add elements into columns.', 'js_composer' ) ),
|
||||
'position' => array(
|
||||
'edge' => 'left',
|
||||
'align' => 'center',
|
||||
),
|
||||
'buttonsEvent' => 'vcPointersEditorsTourEvents',
|
||||
),
|
||||
'closeEvent' => 'click #wpb_visual_composer',
|
||||
'showEvent' => 'shortcodeView:ready',
|
||||
),
|
||||
array(
|
||||
'target' => '.wpb_column_container:first .wpb_content_element:first .vc_controls-cc',
|
||||
'options' => array(
|
||||
'content' => sprintf( '<h3> %s </h3> <p> %s <br/><br/> %s</p>', esc_html__( 'Control Elements', 'js_composer' ), esc_html__( 'You can edit your element at any time and drag it around your layout.', 'js_composer' ), sprintf( esc_html__( 'P.S. Learn more at our %sKnowledge Base%s.', 'js_composer' ), '<a href="https://kb.wpbakery.com" target="_blank">', '</a>' ) ),
|
||||
'position' => array(
|
||||
'edge' => 'left',
|
||||
'align' => 'center',
|
||||
),
|
||||
'buttonsEvent' => 'vcPointersEditorsTourEvents',
|
||||
),
|
||||
'showCallback' => 'vcPointersShowOnContentElementControls',
|
||||
'closeEvent' => 'click #wpb_visual_composer',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
return $pointers;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add WP ui pointers to backend editor.
|
||||
*/
|
||||
function vc_frontend_editor_pointer() {
|
||||
vc_is_frontend_editor() && add_filter( 'vc-ui-pointers', 'vc_frontend_editor_register_pointer' );
|
||||
}
|
||||
|
||||
add_action( 'admin_init', 'vc_frontend_editor_pointer' );
|
||||
|
||||
/**
|
||||
* @param $pointers
|
||||
* @return mixed
|
||||
*/
|
||||
function vc_frontend_editor_register_pointer( $pointers ) {
|
||||
global $post;
|
||||
if ( is_object( $post ) && ! strlen( $post->post_content ) ) {
|
||||
$pointers['vc_pointers_frontend_editor'] = array(
|
||||
'name' => 'vcPointerController',
|
||||
'messages' => array(
|
||||
array(
|
||||
'target' => '#vc_add-new-element',
|
||||
'options' => array(
|
||||
'content' => sprintf( '<h3> %s </h3> <p> %s </p>', esc_html__( 'Add Elements', 'js_composer' ), esc_html__( 'Add new element or start with a template.', 'js_composer' ) ),
|
||||
'position' => array(
|
||||
'edge' => 'top',
|
||||
'align' => 'left',
|
||||
),
|
||||
'buttonsEvent' => 'vcPointersEditorsTourEvents',
|
||||
),
|
||||
'closeEvent' => 'shortcodes:add',
|
||||
),
|
||||
array(
|
||||
'target' => '.vc_controls-out-tl:first',
|
||||
'options' => array(
|
||||
'content' => sprintf( '<h3> %s </h3> <p> %s </p>', esc_html__( 'Rows and Columns', 'js_composer' ), esc_html__( 'This is a row container. Divide it into columns and style it. You can add elements into columns.', 'js_composer' ) ),
|
||||
'position' => array(
|
||||
'edge' => 'left',
|
||||
'align' => 'center',
|
||||
),
|
||||
'buttonsEvent' => 'vcPointersEditorsTourEvents',
|
||||
),
|
||||
'closeCallback' => 'vcPointersCloseInIFrame',
|
||||
'showCallback' => 'vcPointersSetInIFrame',
|
||||
),
|
||||
array(
|
||||
'target' => '.vc_controls-cc:first',
|
||||
'options' => array(
|
||||
'content' => sprintf( '<h3> %s </h3> <p> %s <br/><br/> %s</p>', esc_html__( 'Control Elements', 'js_composer' ), esc_html__( 'You can edit your element at any time and drag it around your layout.', 'js_composer' ), sprintf( esc_html__( 'P.S. Learn more at our %sKnowledge Base%s.', 'js_composer' ), '<a href="https://kb.wpbakery.com" target="_blank">', '</a>' ) ),
|
||||
'position' => array(
|
||||
'edge' => 'left',
|
||||
'align' => 'center',
|
||||
),
|
||||
'buttonsEvent' => 'vcPointersEditorsTourEvents',
|
||||
),
|
||||
'closeCallback' => 'vcPointersCloseInIFrame',
|
||||
'showCallback' => 'vcPointersSetInIFrame',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return $pointers;
|
||||
}
|
||||
|
||||
function vc_page_editable_enqueue_pointer_scripts() {
|
||||
if ( vc_is_page_editable() ) {
|
||||
wp_enqueue_style( 'wp-pointer' );
|
||||
wp_enqueue_script( 'wp-pointer' );
|
||||
}
|
||||
}
|
||||
|
||||
add_action( 'wp_enqueue_scripts', 'vc_page_editable_enqueue_pointer_scripts' );
|
||||
@@ -0,0 +1,261 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_vc_action_save_settings_preset', 'vc_action_save_settings_preset' );
|
||||
add_action( 'wp_ajax_vc_action_set_as_default_settings_preset', 'vc_action_set_as_default_settings_preset' );
|
||||
add_action( 'wp_ajax_vc_action_delete_settings_preset', 'vc_action_delete_settings_preset' );
|
||||
add_action( 'wp_ajax_vc_action_restore_default_settings_preset', 'vc_action_restore_default_settings_preset' );
|
||||
add_action( 'wp_ajax_vc_action_get_settings_preset', 'vc_action_get_settings_preset' );
|
||||
add_action( 'wp_ajax_vc_action_render_settings_preset_popup', 'vc_action_render_settings_preset_popup' );
|
||||
add_action( 'wp_ajax_vc_action_render_settings_preset_title_prompt', 'vc_action_render_settings_preset_title_prompt' );
|
||||
add_action( 'wp_ajax_vc_action_render_settings_templates_prompt', 'vc_action_render_settings_templates_prompt' );
|
||||
add_action( 'vc_restore_default_settings_preset', 'vc_action_set_as_default_settings_preset', 10, 2 );
|
||||
add_action( 'vc_register_settings_preset', 'vc_register_settings_preset', 10, 4 );
|
||||
add_filter( 'vc_add_new_elements_to_box', 'vc_add_new_elements_to_box' );
|
||||
add_filter( 'vc_add_new_category_filter', 'vc_add_new_category_filter' );
|
||||
|
||||
function vc_include_settings_preset_class() {
|
||||
require_once vc_path_dir( 'AUTOLOAD_DIR', 'class-vc-settings-presets.php' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Vc_Vendor_Preset
|
||||
*/
|
||||
function vc_vendor_preset() {
|
||||
require_once vc_path_dir( 'AUTOLOAD_DIR', 'class-vc-vendor-presets.php' );
|
||||
|
||||
return Vc_Vendor_Preset::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save settings preset for specific shortcode
|
||||
*
|
||||
* Include freshly rendered html in response
|
||||
*
|
||||
* Required _POST params:
|
||||
* - shortcode_name string
|
||||
* - title string
|
||||
* - data string params in json
|
||||
* - is_default
|
||||
*
|
||||
* @since 4.7
|
||||
*/
|
||||
function vc_action_save_settings_preset() {
|
||||
vc_include_settings_preset_class();
|
||||
vc_user_access()->part( 'presets' )->checkStateAny( true, null )->validateDie(); // user must have permission to save presets
|
||||
|
||||
$id = Vc_Settings_Preset::saveSettingsPreset( vc_post_param( 'shortcode_name' ), vc_post_param( 'title' ), vc_post_param( 'data' ), vc_post_param( 'is_default' ) );
|
||||
|
||||
$response = array(
|
||||
'success' => (bool) $id,
|
||||
'html' => Vc_Settings_Preset::getRenderedSettingsPresetPopup( vc_post_param( 'shortcode_name' ) ),
|
||||
'id' => $id,
|
||||
);
|
||||
|
||||
wp_send_json( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set existing preset as default
|
||||
*
|
||||
* Include freshly rendered html in response
|
||||
*
|
||||
* Required _POST params:
|
||||
* - id int
|
||||
* - shortcode_name string
|
||||
*
|
||||
* @since 4.7
|
||||
*/
|
||||
function vc_action_set_as_default_settings_preset() {
|
||||
vc_include_settings_preset_class();
|
||||
vc_user_access()->part( 'presets' )->checkStateAny( true, null )->validateDie(); // user must have permission to set as default presets
|
||||
|
||||
$id = vc_post_param( 'id' );
|
||||
$shortcode_name = vc_post_param( 'shortcode_name' );
|
||||
|
||||
$status = Vc_Settings_Preset::setAsDefaultSettingsPreset( $id, $shortcode_name );
|
||||
|
||||
$response = array(
|
||||
'success' => $status,
|
||||
'html' => Vc_Settings_Preset::getRenderedSettingsPresetPopup( $shortcode_name ),
|
||||
);
|
||||
|
||||
wp_send_json( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmark current default preset as default
|
||||
*
|
||||
* Include freshly rendered html in response
|
||||
*
|
||||
* Required _POST params:
|
||||
* - shortcode_name string
|
||||
*
|
||||
* @since 4.7
|
||||
*/
|
||||
function vc_action_restore_default_settings_preset() {
|
||||
vc_include_settings_preset_class();
|
||||
vc_user_access()->part( 'presets' )->checkStateAny( true, null )->validateDie(); // user must have permission to restore presets
|
||||
|
||||
$shortcode_name = vc_post_param( 'shortcode_name' );
|
||||
|
||||
$status = Vc_Settings_Preset::setAsDefaultSettingsPreset( null, $shortcode_name );
|
||||
|
||||
$response = array(
|
||||
'success' => $status,
|
||||
'html' => Vc_Settings_Preset::getRenderedSettingsPresetPopup( $shortcode_name ),
|
||||
);
|
||||
|
||||
wp_send_json( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete specific settings preset
|
||||
*
|
||||
* Include freshly rendered html in response
|
||||
*
|
||||
* Required _POST params:
|
||||
* - shortcode_name string
|
||||
* - id int
|
||||
*
|
||||
* @since 4.7
|
||||
*/
|
||||
function vc_action_delete_settings_preset() {
|
||||
vc_include_settings_preset_class();
|
||||
vc_user_access()->part( 'presets' )->checkStateAny( true, null )->validateDie(); // user must have permission to delete presets
|
||||
|
||||
$default = get_post_meta( vc_post_param( 'id' ), '_vc_default', true );
|
||||
|
||||
$status = Vc_Settings_Preset::deleteSettingsPreset( vc_post_param( 'id' ) );
|
||||
|
||||
$response = array(
|
||||
'success' => $status,
|
||||
'default' => $default,
|
||||
'html' => Vc_Settings_Preset::getRenderedSettingsPresetPopup( vc_post_param( 'shortcode_name' ) ),
|
||||
);
|
||||
|
||||
wp_send_json( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data for specific settings preset
|
||||
*
|
||||
* Required _POST params:
|
||||
* - id int
|
||||
*
|
||||
* @since 4.7
|
||||
*/
|
||||
function vc_action_get_settings_preset() {
|
||||
vc_include_settings_preset_class();
|
||||
|
||||
$data = Vc_Settings_Preset::getSettingsPreset( vc_post_param( 'id' ), true );
|
||||
|
||||
if ( false !== $data ) {
|
||||
$response = array(
|
||||
'success' => true,
|
||||
'data' => $data,
|
||||
);
|
||||
} else {
|
||||
$response = array(
|
||||
'success' => false,
|
||||
);
|
||||
}
|
||||
|
||||
wp_send_json( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Respond with rendered popup menu
|
||||
*
|
||||
* Required _POST params:
|
||||
* - shortcode_name string
|
||||
*
|
||||
* @since 4.7
|
||||
*/
|
||||
function vc_action_render_settings_preset_popup() {
|
||||
vc_include_settings_preset_class();
|
||||
$html = Vc_Settings_Preset::getRenderedSettingsPresetPopup( vc_post_param( 'shortcode_name' ) );
|
||||
|
||||
$response = array(
|
||||
'success' => true,
|
||||
'html' => $html,
|
||||
);
|
||||
|
||||
wp_send_json( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return rendered title prompt
|
||||
*
|
||||
* @since 4.7
|
||||
*
|
||||
*/
|
||||
function vc_action_render_settings_preset_title_prompt() {
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'edit_posts', 'edit_pages' )->validateDie()->part( 'presets' )->can()->validateDie();
|
||||
|
||||
ob_start();
|
||||
vc_include_template( apply_filters( 'vc_render_settings_preset_title_prompt', 'editors/partials/prompt-presets.tpl.php' ) );
|
||||
$html = ob_get_clean();
|
||||
|
||||
$response = array(
|
||||
'success' => true,
|
||||
'html' => $html,
|
||||
);
|
||||
|
||||
wp_send_json( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return rendered template prompt
|
||||
*/
|
||||
function vc_action_render_settings_templates_prompt() {
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'edit_posts', 'edit_pages' )->validateDie()->part( 'templates' )->can()->validateDie();
|
||||
|
||||
ob_start();
|
||||
vc_include_template( apply_filters( 'vc_render_settings_preset_title_prompt', 'editors/partials/prompt-templates.tpl.php' ) );
|
||||
$html = ob_get_clean();
|
||||
|
||||
$response = array(
|
||||
'success' => true,
|
||||
'html' => $html,
|
||||
);
|
||||
|
||||
wp_send_json( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register (add) new vendor preset
|
||||
*
|
||||
* @since 4.8
|
||||
*
|
||||
* @param string $title
|
||||
* @param string $shortcode
|
||||
* @param array $params
|
||||
* @param bool $default
|
||||
*/
|
||||
function vc_register_settings_preset( $title, $shortcode, $params, $default = false ) {
|
||||
vc_vendor_preset()->add( $title, $shortcode, $params, $default );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $shortcodes
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
function vc_add_new_elements_to_box( $shortcodes ) {
|
||||
require_once vc_path_dir( 'AUTOLOAD_DIR', 'class-vc-settings-presets.php' );
|
||||
|
||||
return Vc_Settings_Preset::addVcPresetsToShortcodes( $shortcodes );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $cat
|
||||
* @return array
|
||||
*/
|
||||
function vc_add_new_category_filter( $cat ) {
|
||||
require_once vc_path_dir( 'AUTOLOAD_DIR', 'class-vc-settings-presets.php' );
|
||||
|
||||
return Vc_Settings_Preset::addPresetCategory( $cat );
|
||||
}
|
||||
@@ -0,0 +1,280 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class VcShortcodeAutoloader
|
||||
*/
|
||||
class VcShortcodeAutoloader {
|
||||
|
||||
private static $instance = null;
|
||||
private static $config = null;
|
||||
private static $cached = null;
|
||||
|
||||
/**
|
||||
* @param bool $load_config
|
||||
* @return \VcShortcodeAutoloader|null
|
||||
*/
|
||||
public static function getInstance( $load_config = true ) {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new VcShortcodeAutoloader( $load_config );
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* VcShortcodeAutoloader constructor.
|
||||
* @param bool $load_config
|
||||
*/
|
||||
private function __construct( $load_config = true ) {
|
||||
if ( ! $load_config ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$config = array(
|
||||
'classmap_file' => vc_path_dir( 'APP_ROOT', 'vc_classmap.json.php' ),
|
||||
'shortcodes_dir' => vc_path_dir( 'SHORTCODES_DIR' ),
|
||||
'root_dir' => vc_path_dir( 'APP_ROOT' ),
|
||||
);
|
||||
|
||||
if ( is_file( $config['classmap_file'] ) ) {
|
||||
$config['classmap'] = require $config['classmap_file'];
|
||||
self::$cached = true;
|
||||
} else {
|
||||
$config['classmap'] = self::generateClassMap( $config['shortcodes_dir'] );
|
||||
self::$cached = false;
|
||||
}
|
||||
|
||||
self::$config = $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include class dependencies
|
||||
*
|
||||
* @param string $class Class name
|
||||
*
|
||||
* @return string[] Included (if any) files
|
||||
*/
|
||||
public static function includeClass( $class ) {
|
||||
// call the constructor (php 7.4 compat)
|
||||
self::getInstance();
|
||||
$class = strtolower( $class );
|
||||
$files = array();
|
||||
|
||||
if ( self::$config['classmap'] ) {
|
||||
$files = isset( self::$config['classmap'][ $class ] ) ? self::$config['classmap'][ $class ] : array();
|
||||
}
|
||||
|
||||
if ( $files ) {
|
||||
foreach ( $files as $k => $file ) {
|
||||
if ( self::$cached ) {
|
||||
$files[ $k ] = $file = self::$config['root_dir'] . DIRECTORY_SEPARATOR . $file;
|
||||
}
|
||||
|
||||
if ( is_file( $file ) ) {
|
||||
require_once $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all classes defined in file
|
||||
*
|
||||
* @param string $file Full path to file
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public static function extractClassNames( $file ) {
|
||||
$classes = array();
|
||||
|
||||
// @codingStandardsIgnoreLine
|
||||
$contents = file_get_contents( $file );
|
||||
if ( ! $contents ) {
|
||||
return $classes;
|
||||
}
|
||||
|
||||
$tokens = token_get_all( $contents );
|
||||
$class_token = false;
|
||||
foreach ( $tokens as $token ) {
|
||||
if ( is_array( $token ) ) {
|
||||
if ( T_CLASS === $token[0] ) {
|
||||
$class_token = true;
|
||||
} elseif ( $class_token && T_STRING === $token[0] ) {
|
||||
$classes[] = $token[1];
|
||||
$class_token = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract all classes from file with their extends
|
||||
*
|
||||
* @param $file
|
||||
*
|
||||
* @return array Associative array where key is class name and value is parent class name (if any))
|
||||
*/
|
||||
public static function extractClassesAndExtends( $file ) {
|
||||
$classes = array();
|
||||
|
||||
// @codingStandardsIgnoreLine
|
||||
$contents = file_get_contents( $file );
|
||||
if ( ! $contents ) {
|
||||
return $classes;
|
||||
}
|
||||
|
||||
// class Foo extends Bar {
|
||||
preg_match_all( '/class\s+(\w+)\s+extends\s(\w+)\s+\{/i', $contents, $matches, PREG_SET_ORDER );
|
||||
foreach ( $matches as $v ) {
|
||||
$classes[ $v[1] ] = $v[2];
|
||||
}
|
||||
|
||||
// class Foo {
|
||||
preg_match_all( '/class\s+(\w+)\s+\{/i', $contents, $matches, PREG_SET_ORDER );
|
||||
foreach ( $matches as $v ) {
|
||||
$classes[ $v[1] ] = null;
|
||||
}
|
||||
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find file by class name
|
||||
*
|
||||
* Search is case-insensitive
|
||||
*
|
||||
* @param string $class
|
||||
* @param string[]|string $dirs One or more directories where to look (recursive)
|
||||
*
|
||||
* @return string|false Full path to class file
|
||||
*/
|
||||
public static function findClassFile( $class, $dirs ) {
|
||||
foreach ( (array) $dirs as $dir ) {
|
||||
$Directory = new RecursiveDirectoryIterator( $dir );
|
||||
$Iterator = new RecursiveIteratorIterator( $Directory );
|
||||
$Regex = new RegexIterator( $Iterator, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH );
|
||||
$class = strtolower( $class );
|
||||
|
||||
foreach ( $Regex as $file => $object ) {
|
||||
$classes = self::extractClassNames( $file );
|
||||
|
||||
if ( $classes && in_array( $class, array_map( 'strtolower', $classes ), true ) ) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct full dependency list of classes for each class in right order (including class itself)
|
||||
*
|
||||
* @param string[]|string $dirs Directories where to look (recursive)
|
||||
*
|
||||
* @return array Associative array where key is lowercase class name and value is array of files to include for
|
||||
* that class to work
|
||||
*/
|
||||
public static function generateClassMap( $dirs ) {
|
||||
$flat_map = array();
|
||||
foreach ( (array) $dirs as $dir ) {
|
||||
$Directory = new RecursiveDirectoryIterator( $dir );
|
||||
$Iterator = new RecursiveIteratorIterator( $Directory );
|
||||
$Regex = new RegexIterator( $Iterator, '/^.+\.php$/i', RecursiveRegexIterator::GET_MATCH );
|
||||
|
||||
foreach ( $Regex as $file => $object ) {
|
||||
$classes = self::extractClassesAndExtends( $file );
|
||||
|
||||
foreach ( $classes as $class => $extends ) {
|
||||
$class = strtolower( $class );
|
||||
$extends = strtolower( $extends );
|
||||
if ( in_array( $extends, array(
|
||||
'wpbakeryshortcodescontainer',
|
||||
'wpbakeryvisualcomposer',
|
||||
'wpbakeryshortcode',
|
||||
'wpbmap',
|
||||
), true ) ) {
|
||||
$extends = null;
|
||||
}
|
||||
$flat_map[ $class ] = array(
|
||||
'class' => $class,
|
||||
'file' => $file,
|
||||
'extends' => $extends,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$map = array();
|
||||
foreach ( $flat_map as $params ) {
|
||||
$dependencies = array(
|
||||
array(
|
||||
'class' => $params['class'],
|
||||
'file' => $params['file'],
|
||||
),
|
||||
);
|
||||
|
||||
if ( $params['extends'] ) {
|
||||
$queue = array( $params['extends'] );
|
||||
|
||||
while ( $queue ) {
|
||||
$current_class = array_pop( $queue );
|
||||
$current_class = $flat_map[ $current_class ];
|
||||
|
||||
$dependencies[] = array(
|
||||
'class' => $current_class['class'],
|
||||
'file' => $current_class['file'],
|
||||
);
|
||||
|
||||
if ( ! empty( $current_class['extends'] ) ) {
|
||||
$queue[] = $current_class['extends'];
|
||||
}
|
||||
}
|
||||
|
||||
$map[ $params['class'] ] = array_reverse( $dependencies );
|
||||
} else {
|
||||
$map[ $params['class'] ] = $dependencies;
|
||||
}
|
||||
}
|
||||
|
||||
// simplify array
|
||||
$classmap = array();
|
||||
foreach ( $map as $class => $dependencies ) {
|
||||
$classmap[ $class ] = array();
|
||||
foreach ( $dependencies as $v ) {
|
||||
$classmap[ $class ][] = str_replace( '\\', '/', $v['file'] );
|
||||
}
|
||||
}
|
||||
|
||||
return $classmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerate and save class map file
|
||||
*
|
||||
* @param string[]|string $dirs Directories where to look (recursive)
|
||||
* @param string $target Output file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function saveClassMap( $dirs, $target ) {
|
||||
if ( ! $target ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$classmap = self::generateClassMap( $dirs );
|
||||
|
||||
// @codingStandardsIgnoreLine
|
||||
$code = '<?php return (array) json_decode(\'' . json_encode( $classmap ) . '\') ?>';
|
||||
|
||||
// @codingStandardsIgnoreLine
|
||||
return (bool) file_put_contents( $target, $code );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
if ( 'vc_edit_form' === vc_post_param( 'action' ) ) {
|
||||
add_filter( 'vc_edit_form_fields_attributes_vc_single_image', 'vc_single_image_convert_old_link_to_new' );
|
||||
}
|
||||
/**
|
||||
* Backward compatibility
|
||||
*
|
||||
* @param $atts
|
||||
* @return mixed
|
||||
* @since 4.6
|
||||
*/
|
||||
function vc_single_image_convert_old_link_to_new( $atts ) {
|
||||
if ( empty( $atts['onclick'] ) && isset( $atts['img_link_large'] ) && 'yes' === $atts['img_link_large'] ) {
|
||||
$atts['onclick'] = 'img_link_large';
|
||||
unset( $atts['img_link_large'] );
|
||||
} elseif ( empty( $atts['onclick'] ) && ( ! isset( $atts['img_link_large'] ) || 'yes' !== $atts['img_link_large'] ) ) {
|
||||
unset( $atts['img_link_large'] );
|
||||
}
|
||||
|
||||
if ( empty( $atts['onclick'] ) && ! empty( $atts['link'] ) ) {
|
||||
$atts['onclick'] = 'custom_link';
|
||||
}
|
||||
|
||||
return $atts;
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_wpb_single_image_src', 'vc_single_image_src' );
|
||||
|
||||
function vc_single_image_src() {
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'edit_posts', 'edit_pages' )->validateDie();
|
||||
|
||||
$image_id = (int) vc_post_param( 'content' );
|
||||
$params = vc_post_param( 'params' );
|
||||
$post_id = (int) vc_post_param( 'post_id' );
|
||||
$img_size = vc_post_param( 'size' );
|
||||
$img = '';
|
||||
|
||||
if ( ! empty( $params['source'] ) ) {
|
||||
$source = $params['source'];
|
||||
} else {
|
||||
$source = 'media_library';
|
||||
}
|
||||
|
||||
switch ( $source ) {
|
||||
case 'media_library':
|
||||
case 'featured_image':
|
||||
if ( 'featured_image' === $source ) {
|
||||
if ( $post_id && has_post_thumbnail( $post_id ) ) {
|
||||
$img_id = get_post_thumbnail_id( $post_id );
|
||||
} else {
|
||||
$img_id = 0;
|
||||
}
|
||||
} else {
|
||||
$img_id = preg_replace( '/[^\d]/', '', $image_id );
|
||||
}
|
||||
|
||||
if ( ! $img_size ) {
|
||||
$img_size = 'thumbnail';
|
||||
}
|
||||
|
||||
if ( $img_id ) {
|
||||
$img = wp_get_attachment_image_src( $img_id, $img_size );
|
||||
if ( $img ) {
|
||||
$img = $img[0];
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'external_link':
|
||||
if ( ! empty( $params['custom_src'] ) ) {
|
||||
$img = $params['custom_src'];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
echo esc_url( $img );
|
||||
die();
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
function vc_navbar_undoredo() {
|
||||
if ( vc_is_frontend_editor() || is_admin() ) {
|
||||
require_once vc_path_dir( 'EDITORS_DIR', 'navbar/class-vc-navbar-undoredo.php' );
|
||||
new Vc_Navbar_Undoredo();
|
||||
}
|
||||
}
|
||||
|
||||
add_action( 'admin_init', 'vc_navbar_undoredo' );
|
||||
28
wp-content/plugins/js_composer/include/autoload/vendors/acf.php
vendored
Normal file
28
wp-content/plugins/js_composer/include/autoload/vendors/acf.php
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4 vendors initialization moved to hooks in autoload/vendors.
|
||||
*
|
||||
* Used to initialize advanced custom fields vendor.
|
||||
*/
|
||||
add_action( 'acf/init', 'vc_init_vendor_acf' ); // pro version
|
||||
add_action( 'acf/register_fields', 'vc_init_vendor_acf' ); // free version
|
||||
add_action( 'plugins_loaded', 'vc_init_vendor_acf' );
|
||||
add_action( 'after_setup_theme', 'vc_init_vendor_acf' ); // for themes
|
||||
function vc_init_vendor_acf() {
|
||||
if ( did_action( 'vc-vendor-acf-load' ) ) {
|
||||
return;
|
||||
}
|
||||
include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); // Require class-vc-wxr-parser-plugin.php to use is_plugin_active() below
|
||||
if ( class_exists( 'acf' ) || is_plugin_active( 'advanced-custom-fields/acf.php' ) || is_plugin_active( 'advanced-custom-fields-pro/acf.php' ) ) {
|
||||
require_once vc_path_dir( 'VENDORS_DIR', 'plugins/class-vc-vendor-advanced-custom-fields.php' );
|
||||
$vendor = new Vc_Vendor_AdvancedCustomFields();
|
||||
add_action( 'vc_after_set_mode', array(
|
||||
$vendor,
|
||||
'load',
|
||||
) );
|
||||
}
|
||||
}
|
||||
22
wp-content/plugins/js_composer/include/autoload/vendors/cf7.php
vendored
Normal file
22
wp-content/plugins/js_composer/include/autoload/vendors/cf7.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4 vendors initialization moved to hooks in autoload/vendors.
|
||||
*
|
||||
* Used to initialize plugin contact form 7 vendor - fix load cf7 shortcode when in editor (frontend)
|
||||
*/
|
||||
add_action( 'plugins_loaded', 'vc_init_vendor_cf7' );
|
||||
function vc_init_vendor_cf7() {
|
||||
include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); // Require class-vc-wxr-parser-plugin.php to use is_plugin_active() below
|
||||
if ( is_plugin_active( 'contact-form-7/wp-contact-form-7.php' ) || defined( 'WPCF7_PLUGIN' ) ) {
|
||||
require_once vc_path_dir( 'VENDORS_DIR', 'plugins/class-vc-vendor-contact-form7.php' );
|
||||
$vendor = new Vc_Vendor_ContactForm7();
|
||||
add_action( 'vc_after_set_mode', array(
|
||||
$vendor,
|
||||
'load',
|
||||
) );
|
||||
} // if contact form7 plugin active
|
||||
}
|
||||
106
wp-content/plugins/js_composer/include/autoload/vendors/gravity_forms.php
vendored
Normal file
106
wp-content/plugins/js_composer/include/autoload/vendors/gravity_forms.php
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4 vendors initialization moved to hooks in autoload/vendors.
|
||||
*
|
||||
* Used to add gravity forms shortcode into WPBakery Page Builder
|
||||
*/
|
||||
add_action( 'plugins_loaded', 'vc_init_vendor_gravity_forms' );
|
||||
function vc_init_vendor_gravity_forms() {
|
||||
include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); // Require class-vc-wxr-parser-plugin.php to use is_plugin_active() below
|
||||
if ( is_plugin_active( 'gravityforms/gravityforms.php' ) || class_exists( 'RGForms' ) || class_exists( 'RGFormsModel' ) ) {
|
||||
// Call on map
|
||||
add_action( 'vc_after_init', 'vc_vendor_gravityforms_load' );
|
||||
} // if gravityforms active
|
||||
}
|
||||
|
||||
function vc_vendor_gravityforms_load() {
|
||||
$gravity_forms_array[ esc_html__( 'No Gravity forms found.', 'js_composer' ) ] = '';
|
||||
if ( class_exists( 'RGFormsModel' ) ) {
|
||||
/** @noinspection PhpUndefinedClassInspection */
|
||||
$gravity_forms = RGFormsModel::get_forms( 1, 'title' );
|
||||
if ( $gravity_forms ) {
|
||||
$gravity_forms_array = array( esc_html__( 'Select a form to display.', 'js_composer' ) => '' );
|
||||
foreach ( $gravity_forms as $gravity_form ) {
|
||||
$gravity_forms_array[ $gravity_form->title ] = $gravity_form->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
vc_map( array(
|
||||
'name' => esc_html__( 'Gravity Form', 'js_composer' ),
|
||||
'base' => 'gravityform',
|
||||
'icon' => 'icon-wpb-vc_gravityform',
|
||||
'category' => esc_html__( 'Content', 'js_composer' ),
|
||||
'description' => esc_html__( 'Place Gravity form', 'js_composer' ),
|
||||
'params' => array(
|
||||
array(
|
||||
'type' => 'dropdown',
|
||||
'heading' => esc_html__( 'Form', 'js_composer' ),
|
||||
'param_name' => 'id',
|
||||
'value' => $gravity_forms_array,
|
||||
'save_always' => true,
|
||||
'description' => esc_html__( 'Select a form to add it to your post or page.', 'js_composer' ),
|
||||
'admin_label' => true,
|
||||
),
|
||||
array(
|
||||
'type' => 'dropdown',
|
||||
'heading' => esc_html__( 'Display Form Title', 'js_composer' ),
|
||||
'param_name' => 'title',
|
||||
'value' => array(
|
||||
esc_html__( 'No', 'js_composer' ) => 'false',
|
||||
esc_html__( 'Yes', 'js_composer' ) => 'true',
|
||||
),
|
||||
'save_always' => true,
|
||||
'description' => esc_html__( 'Would you like to display the forms title?', 'js_composer' ),
|
||||
'dependency' => array(
|
||||
'element' => 'id',
|
||||
'not_empty' => true,
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'dropdown',
|
||||
'heading' => esc_html__( 'Display Form Description', 'js_composer' ),
|
||||
'param_name' => 'description',
|
||||
'value' => array(
|
||||
esc_html__( 'No', 'js_composer' ) => 'false',
|
||||
esc_html__( 'Yes', 'js_composer' ) => 'true',
|
||||
),
|
||||
'save_always' => true,
|
||||
'description' => esc_html__( 'Would you like to display the forms description?', 'js_composer' ),
|
||||
'dependency' => array(
|
||||
'element' => 'id',
|
||||
'not_empty' => true,
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'dropdown',
|
||||
'heading' => esc_html__( 'Enable AJAX?', 'js_composer' ),
|
||||
'param_name' => 'ajax',
|
||||
'value' => array(
|
||||
esc_html__( 'No', 'js_composer' ) => 'false',
|
||||
esc_html__( 'Yes', 'js_composer' ) => 'true',
|
||||
),
|
||||
'save_always' => true,
|
||||
'description' => esc_html__( 'Enable AJAX submission?', 'js_composer' ),
|
||||
'dependency' => array(
|
||||
'element' => 'id',
|
||||
'not_empty' => true,
|
||||
),
|
||||
),
|
||||
array(
|
||||
'type' => 'textfield',
|
||||
'heading' => esc_html__( 'Tab Index', 'js_composer' ),
|
||||
'param_name' => 'tabindex',
|
||||
'description' => esc_html__( '(Optional) Specify the starting tab index for the fields of this form. Leave blank if you\'re not sure what this is.',
|
||||
'js_composer' ),
|
||||
'dependency' => array(
|
||||
'element' => 'id',
|
||||
'not_empty' => true,
|
||||
),
|
||||
),
|
||||
),
|
||||
) );
|
||||
}
|
||||
89
wp-content/plugins/js_composer/include/autoload/vendors/gutenberg.php
vendored
Normal file
89
wp-content/plugins/js_composer/include/autoload/vendors/gutenberg.php
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
/**
|
||||
* @param $post
|
||||
* @return bool
|
||||
*/
|
||||
function vcv_disable_gutenberg_for_classic_editor( $post ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Vc_Settings $settings
|
||||
*/
|
||||
function vc_gutenberg_add_settings( $settings ) {
|
||||
global $wp_version;
|
||||
if ( function_exists( 'the_gutenberg_project' ) || version_compare( $wp_version, '4.9.8', '>' ) ) {
|
||||
$settings->addField( 'general', esc_html__( 'Disable Gutenberg Editor', 'js_composer' ), 'gutenberg_disable', 'vc_gutenberg_sanitize_disable_callback', 'vc_gutenberg_disable_render_callback' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $rules
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function vc_gutenberg_sanitize_disable_callback( $rules ) {
|
||||
return (bool) $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not responsive checkbox callback function
|
||||
*/
|
||||
function vc_gutenberg_disable_render_callback() {
|
||||
$checked = ( $checked = get_option( 'wpb_js_gutenberg_disable' ) ) ? $checked : false;
|
||||
?>
|
||||
<label>
|
||||
<input type="checkbox"<?php echo esc_attr( $checked ) ? ' checked' : ''; ?> value="1"
|
||||
name="<?php echo 'wpb_js_gutenberg_disable' ?>">
|
||||
<?php esc_html_e( 'Disable', 'js_composer' ) ?>
|
||||
</label><br/>
|
||||
<p
|
||||
class="description indicator-hint"><?php esc_html_e( 'Disable Gutenberg Editor.', 'js_composer' ); ?></p>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $result
|
||||
* @param $postType
|
||||
* @return bool
|
||||
*/
|
||||
function vc_gutenberg_check_disabled( $result, $postType ) {
|
||||
if ( 'wpb_gutenberg_param' === $postType ) {
|
||||
return true;
|
||||
}
|
||||
if ( ! isset( $_GET['vcv-gutenberg-editor'] ) && ( get_option( 'wpb_js_gutenberg_disable' ) || vc_is_wpb_content() || isset( $_GET['classic-editor'] ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
function vc_is_wpb_content() {
|
||||
$post = get_post();
|
||||
if ( ! empty( $post ) && isset( $post->post_content ) && preg_match( '/\[vc_row/', $post->post_content ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function vc_gutenberg_map() {
|
||||
global $wp_version;
|
||||
if ( function_exists( 'the_gutenberg_project' ) || version_compare( $wp_version, '4.9.8', '>' ) ) {
|
||||
vc_lean_map( 'vc_gutenberg', null, dirname( __FILE__ ) . '/shortcode-vc-gutenberg.php' );
|
||||
}
|
||||
}
|
||||
|
||||
add_filter( 'use_block_editor_for_post_type', 'vc_gutenberg_check_disabled', 10, 2 );
|
||||
add_action( 'vc_settings_tab-general', 'vc_gutenberg_add_settings' );
|
||||
add_action( 'init', 'vc_gutenberg_map' );
|
||||
|
||||
/** @see include/params/gutenberg/class-vc-gutenberg-param.php */
|
||||
require_once vc_path_dir( 'PARAMS_DIR', 'gutenberg/class-vc-gutenberg-param.php' );
|
||||
new Vc_Gutenberg_Param();
|
||||
18
wp-content/plugins/js_composer/include/autoload/vendors/jwplayer.php
vendored
Normal file
18
wp-content/plugins/js_composer/include/autoload/vendors/jwplayer.php
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4 vendors initialization moved to hooks in autoload/vendors.
|
||||
*
|
||||
* Used to initialize plugin jwplayer vendor for frontend editor.
|
||||
*/
|
||||
add_action( 'plugins_loaded', 'vc_init_vendor_jwplayer' );
|
||||
function vc_init_vendor_jwplayer() {
|
||||
if ( is_plugin_active( 'jw-player-plugin-for-wordpress/jwplayermodule.php' ) || defined( 'JWP6' ) || class_exists( 'JWP6_Plugin' ) ) {
|
||||
require_once vc_path_dir( 'VENDORS_DIR', 'plugins/class-vc-vendor-jwplayer.php' );
|
||||
$vendor = new Vc_Vendor_Jwplayer();
|
||||
$vendor->load();
|
||||
}
|
||||
}
|
||||
19
wp-content/plugins/js_composer/include/autoload/vendors/layerslider.php
vendored
Normal file
19
wp-content/plugins/js_composer/include/autoload/vendors/layerslider.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4 vendors initialization moved to hooks in autoload/vendors.
|
||||
*
|
||||
* Used to initialize plugin layerslider vendor.
|
||||
*/
|
||||
add_action( 'plugins_loaded', 'vc_init_vendor_layerslider' );
|
||||
function vc_init_vendor_layerslider() {
|
||||
include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); // Require class-vc-wxr-parser-plugin.php to use is_plugin_active() below
|
||||
if ( is_plugin_active( 'LayerSlider/layerslider.php' ) || class_exists( 'LS_Sliders' ) || defined( 'LS_ROOT_PATH' ) ) {
|
||||
require_once vc_path_dir( 'VENDORS_DIR', 'plugins/class-vc-vendor-layerslider.php' );
|
||||
$vendor = new Vc_Vendor_Layerslider();
|
||||
$vendor->load();
|
||||
}
|
||||
}
|
||||
22
wp-content/plugins/js_composer/include/autoload/vendors/mqtranslate.php
vendored
Normal file
22
wp-content/plugins/js_composer/include/autoload/vendors/mqtranslate.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4 vendors initialization moved to hooks in autoload/vendors.
|
||||
*
|
||||
* Used to initialize plugin mqtranslate vendor
|
||||
*/
|
||||
add_action( 'plugins_loaded', 'vc_init_vendor_mqtranslate' );
|
||||
function vc_init_vendor_mqtranslate() {
|
||||
include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); // Require class-vc-wxr-parser-plugin.php to use is_plugin_active() below
|
||||
if ( is_plugin_active( 'mqtranslate/mqtranslate.php' ) || function_exists( 'mqtranslate_activation_check' ) ) {
|
||||
require_once vc_path_dir( 'VENDORS_DIR', 'plugins/class-vc-vendor-mqtranslate.php' );
|
||||
$vendor = new Vc_Vendor_Mqtranslate();
|
||||
add_action( 'vc_after_set_mode', array(
|
||||
$vendor,
|
||||
'load',
|
||||
) );
|
||||
}
|
||||
}
|
||||
22
wp-content/plugins/js_composer/include/autoload/vendors/ninja_forms.php
vendored
Normal file
22
wp-content/plugins/js_composer/include/autoload/vendors/ninja_forms.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4 vendors initialization moved to hooks in autoload/vendors.
|
||||
*
|
||||
* Used to initialize plugin ninja forms vendor
|
||||
*/
|
||||
add_action( 'plugins_loaded', 'vc_init_vendor_ninja_forms' );
|
||||
function vc_init_vendor_ninja_forms() {
|
||||
include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); // Require class-vc-wxr-parser-plugin.php to use is_plugin_active() below
|
||||
if ( is_plugin_active( 'ninja-forms/ninja-forms.php' ) || defined( 'NINJA_FORMS_DIR' ) || function_exists( 'ninja_forms_get_all_forms' ) ) {
|
||||
require_once vc_path_dir( 'VENDORS_DIR', 'plugins/class-vc-vendor-ninja-forms.php' );
|
||||
$vendor = new Vc_Vendor_NinjaForms();
|
||||
add_action( 'vc_after_set_mode', array(
|
||||
$vendor,
|
||||
'load',
|
||||
) );
|
||||
}
|
||||
}
|
||||
21
wp-content/plugins/js_composer/include/autoload/vendors/qtranslate-x.php
vendored
Normal file
21
wp-content/plugins/js_composer/include/autoload/vendors/qtranslate-x.php
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4 vendors initialization moved to hooks in autoload/vendors.
|
||||
*
|
||||
* Used to initialize plugin qtranslate vendor.
|
||||
*/
|
||||
add_action( 'plugins_loaded', 'vc_init_vendor_qtranslatex' );
|
||||
function vc_init_vendor_qtranslatex() {
|
||||
if ( defined( 'QTX_VERSION' ) ) {
|
||||
require_once vc_path_dir( 'VENDORS_DIR', 'plugins/class-vc-vendor-qtranslate-x.php' );
|
||||
$vendor = new Vc_Vendor_QtranslateX();
|
||||
add_action( 'vc_after_set_mode', array(
|
||||
$vendor,
|
||||
'load',
|
||||
) );
|
||||
}
|
||||
}
|
||||
22
wp-content/plugins/js_composer/include/autoload/vendors/qtranslate.php
vendored
Normal file
22
wp-content/plugins/js_composer/include/autoload/vendors/qtranslate.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4 vendors initialization moved to hooks in autoload/vendors.
|
||||
*
|
||||
* Used to initialize plugin qtranslate vendor.
|
||||
*/
|
||||
add_action( 'plugins_loaded', 'vc_init_vendor_qtranslate' );
|
||||
function vc_init_vendor_qtranslate() {
|
||||
include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); // Require class-vc-wxr-parser-plugin.php to use is_plugin_active() below
|
||||
if ( is_plugin_active( 'qtranslate/qtranslate.php' ) || defined( 'QT_SUPPORTED_WP_VERSION' ) ) {
|
||||
require_once vc_path_dir( 'VENDORS_DIR', 'plugins/class-vc-vendor-qtranslate.php' );
|
||||
$vendor = new Vc_Vendor_Qtranslate();
|
||||
add_action( 'vc_after_set_mode', array(
|
||||
$vendor,
|
||||
'load',
|
||||
) );
|
||||
}
|
||||
}
|
||||
19
wp-content/plugins/js_composer/include/autoload/vendors/revslider.php
vendored
Normal file
19
wp-content/plugins/js_composer/include/autoload/vendors/revslider.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4 vendors initialization moved to hooks in autoload/vendors.
|
||||
*
|
||||
* Used to initialize plugin revslider vendor.
|
||||
*/
|
||||
add_action( 'plugins_loaded', 'vc_init_vendor_revslider' );
|
||||
function vc_init_vendor_revslider() {
|
||||
include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); // Require class-vc-wxr-parser-plugin.php to use is_plugin_active() below
|
||||
if ( is_plugin_active( 'revslider/revslider.php' ) || class_exists( 'RevSlider' ) ) {
|
||||
require_once vc_path_dir( 'VENDORS_DIR', 'plugins/class-vc-vendor-revslider.php' );
|
||||
$vendor = new Vc_Vendor_Revslider();
|
||||
$vendor->load();
|
||||
}
|
||||
}
|
||||
41
wp-content/plugins/js_composer/include/autoload/vendors/shortcode-vc-gutenberg.php
vendored
Normal file
41
wp-content/plugins/js_composer/include/autoload/vendors/shortcode-vc-gutenberg.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
return array(
|
||||
'name' => esc_html__( 'Gutenberg Editor', 'js_composer' ),
|
||||
'icon' => 'vc_icon-vc-gutenberg',
|
||||
'wrapper_class' => 'clearfix',
|
||||
'category' => esc_html__( 'Content', 'js_composer' ),
|
||||
'description' => esc_html__( 'Insert Gutenberg editor in your layout', 'js_composer' ),
|
||||
'weight' => - 10,
|
||||
'params' => array(
|
||||
array(
|
||||
'type' => 'gutenberg',
|
||||
'holder' => 'div',
|
||||
'heading' => esc_html__( 'Text', 'js_composer' ),
|
||||
'param_name' => 'content',
|
||||
'value' => '<!-- wp:paragraph --><p>Hello! This is the Gutenberg block you can edit directly from the WPBakery Page Builder.</p><!-- /wp:paragraph -->',
|
||||
),
|
||||
vc_map_add_css_animation(),
|
||||
array(
|
||||
'type' => 'el_id',
|
||||
'heading' => esc_html__( 'Element ID', 'js_composer' ),
|
||||
'param_name' => 'el_id',
|
||||
'description' => sprintf( esc_html__( 'Enter element ID (Note: make sure it is unique and valid according to %sw3c specification%s).', 'js_composer' ), '<a href="https://www.w3schools.com/tags/att_global_id.asp" target="_blank">', '</a>' ),
|
||||
),
|
||||
array(
|
||||
'type' => 'textfield',
|
||||
'heading' => esc_html__( 'Extra class name', 'js_composer' ),
|
||||
'param_name' => 'el_class',
|
||||
'description' => esc_html__( 'Style particular content element differently - add a class name and refer to it in custom CSS.', 'js_composer' ),
|
||||
),
|
||||
array(
|
||||
'type' => 'css_editor',
|
||||
'heading' => esc_html__( 'CSS box', 'js_composer' ),
|
||||
'param_name' => 'css',
|
||||
'group' => esc_html__( 'Design Options', 'js_composer' ),
|
||||
),
|
||||
),
|
||||
);
|
||||
41
wp-content/plugins/js_composer/include/autoload/vendors/woocommerce.php
vendored
Normal file
41
wp-content/plugins/js_composer/include/autoload/vendors/woocommerce.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add script for grid item add to card link
|
||||
*
|
||||
* @since 4.5
|
||||
*/
|
||||
function vc_woocommerce_add_to_cart_script() {
|
||||
wp_enqueue_script( 'vc_woocommerce-add-to-cart-js', vc_asset_url( 'js/vendors/woocommerce-add-to-cart.js' ), array( 'wc-add-to-cart' ), WPB_VC_VERSION );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4 vendors initialization moved to hooks in autoload/vendors.
|
||||
*
|
||||
* Used to initialize plugin WooCommerce vendor. (adds tons of WooCommerce shortcodes and some fixes)
|
||||
*/
|
||||
add_action( 'plugins_loaded', 'vc_init_vendor_woocommerce' );
|
||||
function vc_init_vendor_woocommerce() {
|
||||
include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); // Require class-vc-wxr-parser-plugin.php to use is_plugin_active() below
|
||||
if ( is_plugin_active( 'woocommerce/woocommerce.php' ) || class_exists( 'WooCommerce' ) ) {
|
||||
require_once vc_path_dir( 'VENDORS_DIR', 'plugins/class-vc-vendor-woocommerce.php' );
|
||||
$vendor = new Vc_Vendor_Woocommerce();
|
||||
add_action( 'vc_after_set_mode', array(
|
||||
$vendor,
|
||||
'load',
|
||||
) );
|
||||
require_once vc_path_dir( 'VENDORS_DIR', 'plugins/woocommerce/grid-item-filters.php' );
|
||||
// Add 'add to card' link to the list of Add link.
|
||||
add_filter( 'vc_gitem_add_link_param', 'vc_gitem_add_link_param_woocommerce' );
|
||||
// Filter to add link attributes for grid element shortcode.
|
||||
add_filter( 'vc_gitem_post_data_get_link_link', 'vc_gitem_post_data_get_link_link_woocommerce', 10, 3 );
|
||||
add_filter( 'vc_gitem_post_data_get_link_target', 'vc_gitem_post_data_get_link_target_woocommerce', 12, 2 );
|
||||
add_filter( 'vc_gitem_post_data_get_link_real_link', 'vc_gitem_post_data_get_link_real_link_woocommerce', 10, 4 );
|
||||
add_filter( 'vc_gitem_post_data_get_link_real_target', 'vc_gitem_post_data_get_link_real_target_woocommerce', 12, 3 );
|
||||
add_filter( 'vc_gitem_zone_image_block_link', 'vc_gitem_zone_image_block_link_woocommerce', 10, 3 );
|
||||
add_action( 'wp_enqueue_scripts', 'vc_woocommerce_add_to_cart_script' );
|
||||
}
|
||||
}
|
||||
16
wp-content/plugins/js_composer/include/autoload/vendors/wpml.php
vendored
Normal file
16
wp-content/plugins/js_composer/include/autoload/vendors/wpml.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
add_action( 'plugins_loaded', 'vc_init_vendor_wpml' );
|
||||
function vc_init_vendor_wpml() {
|
||||
if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
|
||||
require_once vc_path_dir( 'VENDORS_DIR', 'plugins/class-vc-vendor-wpml.php' );
|
||||
$vendor = new Vc_Vendor_WPML();
|
||||
add_action( 'vc_after_set_mode', array(
|
||||
$vendor,
|
||||
'load',
|
||||
) );
|
||||
}
|
||||
}
|
||||
27
wp-content/plugins/js_composer/include/autoload/vendors/yoast_seo.php
vendored
Normal file
27
wp-content/plugins/js_composer/include/autoload/vendors/yoast_seo.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4 vendors initialization moved to hooks in autoload/vendors.
|
||||
*
|
||||
* Used to initialize plugin yoast vendor.
|
||||
*/
|
||||
// 16 is required to be called after WPSEO_Admin_Init constructor. @since 4.9
|
||||
add_action( 'plugins_loaded', 'vc_init_vendor_yoast', 16 );
|
||||
function vc_init_vendor_yoast() {
|
||||
include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); // Require class-vc-wxr-parser-plugin.php to use is_plugin_active() below
|
||||
if ( is_plugin_active( 'wordpress-seo/wp-seo.php' ) || class_exists( 'WPSEO_Metabox' ) ) {
|
||||
require_once vc_path_dir( 'VENDORS_DIR', 'plugins/class-vc-vendor-yoast_seo.php' );
|
||||
$vendor = new Vc_Vendor_YoastSeo();
|
||||
if ( defined( 'WPSEO_VERSION' ) && version_compare( WPSEO_VERSION, '3.0.0' ) === - 1 ) {
|
||||
add_action( 'vc_after_set_mode', array(
|
||||
$vendor,
|
||||
'load',
|
||||
) );
|
||||
} elseif ( is_admin() && 'vc_inline' === vc_action() ) {
|
||||
$vendor->frontendEditorBuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Vc_Access
|
||||
*
|
||||
* @package WPBakeryPageBuilder
|
||||
* @since 4.8
|
||||
*/
|
||||
abstract class Vc_Access {
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $validAccess = true;
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function getValidAccess() {
|
||||
return $this->validAccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $validAccess
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setValidAccess( $validAccess ) {
|
||||
$this->validAccess = $validAccess;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check multi access settings by method inside class object.
|
||||
*
|
||||
* @param $method
|
||||
* @param $valid
|
||||
* @param $argsList
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function checkMulti( $method, $valid, $argsList ) {
|
||||
if ( $this->getValidAccess() ) {
|
||||
$access = ! $valid;
|
||||
foreach ( $argsList as $args ) {
|
||||
if ( ! is_array( $args ) ) {
|
||||
$args = array( $args );
|
||||
}
|
||||
$this->setValidAccess( true );
|
||||
call_user_func_array( array(
|
||||
$this,
|
||||
$method,
|
||||
), $args );
|
||||
if ( $valid === $this->getValidAccess() ) {
|
||||
$access = $valid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->setValidAccess( $access );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current validation state and reset it to true. ( should be never called twice )
|
||||
* @return bool
|
||||
*/
|
||||
public function get() {
|
||||
$result = $this->getValidAccess();
|
||||
$this->setValidAccess( true );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call die() function with message if access is invalid.
|
||||
*
|
||||
* @param string $message
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function validateDie( $message = '' ) {
|
||||
$result = $this->getValidAccess();
|
||||
$this->setValidAccess( true );
|
||||
if ( ! $result ) {
|
||||
if ( defined( 'VC_DIE_EXCEPTION' ) && VC_DIE_EXCEPTION ) {
|
||||
throw new Exception( $message );
|
||||
} else {
|
||||
die( esc_html( $message ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $func
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function check( $func ) {
|
||||
if ( $this->getValidAccess() ) {
|
||||
$args = func_get_args();
|
||||
$args = array_slice( $args, 1 );
|
||||
if ( ! empty( $func ) ) {
|
||||
$this->setValidAccess( call_user_func_array( $func, $args ) );
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Any of provided rules should be valid.
|
||||
* Usage: checkAny(
|
||||
* 'vc_verify_admin_nonce',
|
||||
* array( 'current_user_can', 'edit_post', 12 ),
|
||||
* array( 'current_user_can', 'edit_posts' ),
|
||||
* )
|
||||
* @return $this
|
||||
*/
|
||||
public function checkAny() {
|
||||
if ( $this->getValidAccess() ) {
|
||||
$args = func_get_args();
|
||||
$this->checkMulti( 'check', true, $args );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* All provided rules should be valid.
|
||||
* Usage: checkAll(
|
||||
* 'vc_verify_admin_nonce',
|
||||
* array( 'current_user_can', 'edit_post', 12 ),
|
||||
* array( 'current_user_can', 'edit_posts' ),
|
||||
* )
|
||||
* @return $this
|
||||
*/
|
||||
public function checkAll() {
|
||||
if ( $this->getValidAccess() ) {
|
||||
$args = func_get_args();
|
||||
$this->checkMulti( 'check', false, $args );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $nonce
|
||||
*
|
||||
* @return Vc_Access
|
||||
*/
|
||||
public function checkAdminNonce( $nonce = '' ) {
|
||||
return $this->check( 'vc_verify_admin_nonce', $nonce );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $nonce
|
||||
*
|
||||
* @return Vc_Access
|
||||
*/
|
||||
public function checkPublicNonce( $nonce = '' ) {
|
||||
return $this->check( 'vc_verify_public_nonce', $nonce );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
require_once vc_path_dir( 'CORE_DIR', 'access/class-vc-role-access-controller.php' );
|
||||
|
||||
/**
|
||||
* Class Vc_Current_User_Access_Controller
|
||||
*/
|
||||
class Vc_Current_User_Access_Controller extends Vc_Role_Access_Controller {
|
||||
/**
|
||||
* Get capability for current user
|
||||
*
|
||||
* @param $rule
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getCapRule( $rule ) {
|
||||
$role_rule = $this->getStateKey() . '/' . $rule;
|
||||
|
||||
return current_user_can( $role_rule );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add capability to role.
|
||||
*
|
||||
* @param $rule
|
||||
* @param bool $value
|
||||
*/
|
||||
public function setCapRule( $rule, $value = true ) {
|
||||
$role_rule = $this->getStateKey() . '/' . $rule;
|
||||
|
||||
wp_get_current_user()->add_cap( $role_rule, $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool|\WP_Role|null
|
||||
*/
|
||||
public function getRole() {
|
||||
if ( ! $this->roleName && function_exists( 'wp_get_current_user' ) ) {
|
||||
$user = wp_get_current_user();
|
||||
$user_roles = array_intersect( array_values( (array) $user->roles ), array_keys( (array) get_editable_roles() ) );
|
||||
$this->roleName = reset( $user_roles );
|
||||
$this->role = get_role( $this->roleName );
|
||||
}
|
||||
|
||||
return $this->role;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
require_once vc_path_dir( 'CORE_DIR', 'access/class-vc-role-access.php' );
|
||||
|
||||
/**
|
||||
* Class Vc_User_Access
|
||||
*/
|
||||
class Vc_Current_User_Access extends Vc_Role_Access {
|
||||
/**
|
||||
* @param $part
|
||||
*
|
||||
* @return Vc_Current_User_Access_Controller;
|
||||
*/
|
||||
public function part( $part ) {
|
||||
if ( ! isset( $this->parts[ $part ] ) ) {
|
||||
require_once vc_path_dir( 'CORE_DIR', 'access/class-vc-current-user-access-controller.php' );
|
||||
/** @var Vc_Current_User_Access_Controller $user_access_controller */
|
||||
$this->parts[ $part ] = new Vc_Current_User_Access_Controller( $part );
|
||||
}
|
||||
/** @var Vc_Current_User_Access_Controller $user_access_controller */
|
||||
$user_access_controller = $this->parts[ $part ];
|
||||
// we also check for user "logged_in" status
|
||||
$is_user_logged_in = function_exists( 'is_user_logged_in' ) && is_user_logged_in();
|
||||
$user_access_controller->setValidAccess( $is_user_logged_in && $this->getValidAccess() ); // send current status to upper level
|
||||
$this->setValidAccess( true ); // reset
|
||||
|
||||
return $user_access_controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $method
|
||||
* @param $valid
|
||||
* @param $argsList
|
||||
* @return $this
|
||||
*/
|
||||
public function wpMulti( $method, $valid, $argsList ) {
|
||||
if ( $this->getValidAccess() ) {
|
||||
$access = ! $valid;
|
||||
foreach ( $argsList as &$args ) {
|
||||
if ( ! is_array( $args ) ) {
|
||||
$args = array( $args );
|
||||
}
|
||||
array_unshift( $args, 'current_user_can' );
|
||||
$this->setValidAccess( true );
|
||||
call_user_func_array( array(
|
||||
$this,
|
||||
$method,
|
||||
), $args );
|
||||
if ( $valid === $this->getValidAccess() ) {
|
||||
$access = $valid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->setValidAccess( $access );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check WordPress capability. Should be valid one cap at least.
|
||||
*
|
||||
* @return Vc_Current_User_Access
|
||||
*/
|
||||
public function wpAny() {
|
||||
if ( $this->getValidAccess() ) {
|
||||
$args = func_get_args();
|
||||
$this->wpMulti( 'check', true, $args );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check WordPress capability. Should be valid all caps.
|
||||
*
|
||||
* @return Vc_Current_User_Access
|
||||
*/
|
||||
public function wpAll() {
|
||||
if ( $this->getValidAccess() ) {
|
||||
$args = func_get_args();
|
||||
$this->wpMulti( 'check', false, $args );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
require_once vc_path_dir( 'CORE_DIR', 'access/abstract-class-vc-access.php' );
|
||||
|
||||
/**
|
||||
* Class Vc_Role_Access_Controller
|
||||
*
|
||||
* @since 4.8
|
||||
*/
|
||||
class Vc_Role_Access_Controller extends Vc_Access {
|
||||
protected static $part_name_prefix = 'vc_access_rules_';
|
||||
protected $part = false;
|
||||
protected $roleName = false;
|
||||
protected $role = false;
|
||||
protected $validAccess = true;
|
||||
protected $mergedCaps = array(
|
||||
'vc_row_inner_all' => 'vc_row_all',
|
||||
'vc_column_all' => 'vc_row_all',
|
||||
'vc_column_inner_all' => 'vc_row_all',
|
||||
'vc_row_inner_edit' => 'vc_row_edit',
|
||||
'vc_column_edit' => 'vc_row_edit',
|
||||
'vc_column_inner_edit' => 'vc_row_edit',
|
||||
);
|
||||
|
||||
/**
|
||||
* Vc_Role_Access_Controller constructor.
|
||||
* @param $part
|
||||
*/
|
||||
public function __construct( $part ) {
|
||||
$this->part = $part;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set role name.
|
||||
*
|
||||
* @param $role_name
|
||||
*/
|
||||
public function setRoleName( $role_name ) {
|
||||
$this->roleName = $role_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get part for role.
|
||||
* @return bool
|
||||
*/
|
||||
public function getPart() {
|
||||
return $this->part;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get state of the Vc access rules part.
|
||||
*
|
||||
* @return mixed;
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getState() {
|
||||
$role = $this->getRole();
|
||||
$state = null;
|
||||
if ( $role && isset( $role->capabilities, $role->capabilities[ $this->getStateKey() ] ) ) {
|
||||
$state = $role->capabilities[ $this->getStateKey() ];
|
||||
}
|
||||
|
||||
return apply_filters( 'vc_role_access_with_' . $this->getPart() . '_get_state', $state, $this->getRole() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set state for full part.
|
||||
*
|
||||
* State can have 3 values:
|
||||
* true - all allowed under this part;
|
||||
* false - all disabled under this part;
|
||||
* string|'custom' - custom settings. It means that need to check exact capability.
|
||||
*
|
||||
* @param bool $value
|
||||
*
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setState( $value = true ) {
|
||||
$this->getRole() && $this->getRole()->add_cap( $this->getStateKey(), $value );
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can user do what he doo.
|
||||
* Any rule has three types of state: true, false, string.
|
||||
*
|
||||
* @param string $rule
|
||||
* @param bool|true $check_state
|
||||
*
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function can( $rule = '', $check_state = true ) {
|
||||
if ( null === $this->getRole() ) {
|
||||
$this->setValidAccess( is_super_admin() );
|
||||
} elseif ( $this->getValidAccess() ) {
|
||||
// YES it is hard coded :)
|
||||
if ( 'administrator' === $this->getRole()->name && 'settings' === $this->getPart() && ( 'vc-roles-tab' === $rule || 'vc-updater-tab' === $rule ) ) {
|
||||
$this->setValidAccess( true );
|
||||
|
||||
return $this;
|
||||
}
|
||||
$rule = $this->updateMergedCaps( $rule );
|
||||
|
||||
if ( true === $check_state ) {
|
||||
$state = $this->getState();
|
||||
$return = false !== $state;
|
||||
if ( null === $state ) {
|
||||
$return = true;
|
||||
} elseif ( is_bool( $state ) ) {
|
||||
$return = $state;
|
||||
} elseif ( '' !== $rule ) {
|
||||
$return = $this->getCapRule( $rule );
|
||||
}
|
||||
} else {
|
||||
$return = $this->getCapRule( $rule );
|
||||
}
|
||||
$return = apply_filters( 'vc_role_access_with_' . $this->getPart() . '_can', $return, $this->getRole(), $rule );
|
||||
$return = apply_filters( 'vc_role_access_with_' . $this->getPart() . '_can_' . $rule, $return, $this->getRole() );
|
||||
$this->setValidAccess( $return );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can user do what he doo.
|
||||
* Any rule has three types of state: true,false, string.
|
||||
*/
|
||||
public function canAny() {
|
||||
if ( $this->getValidAccess() ) {
|
||||
$args = func_get_args();
|
||||
$this->checkMulti( 'can', true, $args );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can user do what he doo.
|
||||
* Any rule has three types of state: true,false, string.
|
||||
*/
|
||||
public function canAll() {
|
||||
if ( $this->getValidAccess() ) {
|
||||
$args = func_get_args();
|
||||
$this->checkMulti( 'can', false, $args );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get capability for role
|
||||
*
|
||||
* @param $rule
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getCapRule( $rule ) {
|
||||
$rule = $this->getStateKey() . '/' . $rule;
|
||||
|
||||
return $this->getRole() ? $this->getRole()->has_cap( $rule ) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add capability to role.
|
||||
*
|
||||
* @param $rule
|
||||
* @param bool $value
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function setCapRule( $rule, $value = true ) {
|
||||
$role_rule = $this->getStateKey() . '/' . $rule;
|
||||
$this->getRole() && $this->getRole()->add_cap( $role_rule, $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all capability for this part.
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getAllCaps() {
|
||||
$role = $this->getRole();
|
||||
$caps = array();
|
||||
if ( $role ) {
|
||||
$role = apply_filters( 'vc_role_access_all_caps_role', $role );
|
||||
if ( isset( $role->capabilities ) && is_array( $role->capabilities ) ) {
|
||||
foreach ( $role->capabilities as $key => $value ) {
|
||||
if ( preg_match( '/^' . $this->getStateKey() . '\//', $key ) ) {
|
||||
$rule = preg_replace( '/^' . $this->getStateKey() . '\//', '', $key );
|
||||
$caps[ $rule ] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $caps;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|\WP_Role
|
||||
* @throws Exception
|
||||
*/
|
||||
public function getRole() {
|
||||
if ( ! $this->role ) {
|
||||
if ( ! $this->getRoleName() ) {
|
||||
throw new Exception( 'roleName for role_manager is not set, please use ->who(roleName) method to set!' );
|
||||
}
|
||||
$this->role = get_role( $this->getRoleName() );
|
||||
}
|
||||
|
||||
return $this->role;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function getRoleName() {
|
||||
return $this->roleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getStateKey() {
|
||||
return self::$part_name_prefix . $this->getPart();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @return $this
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function checkState( $data ) {
|
||||
if ( $this->getValidAccess() ) {
|
||||
$this->setValidAccess( $this->getState() === $data );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function checkStateAny() {
|
||||
if ( $this->getValidAccess() ) {
|
||||
$args = func_get_args();
|
||||
$this->checkMulti( 'checkState', true, $args );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return access value.
|
||||
* @return string
|
||||
*/
|
||||
public function __toString() {
|
||||
return (string) $this->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $rule
|
||||
* @return mixed
|
||||
*/
|
||||
public function updateMergedCaps( $rule ) {
|
||||
if ( isset( $this->mergedCaps[ $rule ] ) ) {
|
||||
return $this->mergedCaps[ $rule ];
|
||||
}
|
||||
|
||||
return $rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getMergedCaps() {
|
||||
return $this->mergedCaps;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
require_once vc_path_dir( 'CORE_DIR', 'access/abstract-class-vc-access.php' );
|
||||
|
||||
/**
|
||||
* Class Vc_Role_Access
|
||||
*/
|
||||
class Vc_Role_Access extends Vc_Access {
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $roleName = false;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $parts = array();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
require_once ABSPATH . 'wp-admin/includes/user.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $part
|
||||
* @return \Vc_Role_Access_Controller
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function part( $part ) {
|
||||
$role_name = $this->getRoleName();
|
||||
if ( ! $role_name ) {
|
||||
throw new Exception( 'roleName for vc_role_access is not set, please use ->who(roleName) method to set!' );
|
||||
}
|
||||
$key = $part . '_' . $role_name;
|
||||
if ( ! isset( $this->parts[ $key ] ) ) {
|
||||
require_once vc_path_dir( 'CORE_DIR', 'access/class-vc-role-access-controller.php' );
|
||||
/** @var Vc_Role_Access_Controller $role_access_controller */
|
||||
$this->parts[ $key ] = new Vc_Role_Access_Controller( $part );
|
||||
$role_access_controller = $this->parts[ $key ];
|
||||
$role_access_controller->setRoleName( $this->getRoleName() );
|
||||
}
|
||||
/** @var Vc_Role_Access_Controller $role_access_controller */
|
||||
$role_access_controller = $this->parts[ $key ];
|
||||
$role_access_controller->setValidAccess( $this->getValidAccess() ); // send current status to upper level
|
||||
$this->setValidAccess( true ); // reset
|
||||
|
||||
return $role_access_controller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set role to get access to data.
|
||||
*
|
||||
* @param $roleName
|
||||
* @return $this
|
||||
* @internal param $role
|
||||
*
|
||||
*/
|
||||
public function who( $roleName ) {
|
||||
$this->roleName = $roleName;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function getRoleName() {
|
||||
return $this->roleName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,749 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* WPBakery Page Builder basic class.
|
||||
* @since 4.2
|
||||
*/
|
||||
class Vc_Base {
|
||||
/**
|
||||
* Shortcode's edit form.
|
||||
*
|
||||
* @since 4.2
|
||||
* @access protected
|
||||
* @var bool|Vc_Shortcode_Edit_Form
|
||||
*/
|
||||
protected $shortcode_edit_form = false;
|
||||
|
||||
/**
|
||||
* Templates management panel editor.
|
||||
* @since 4.4
|
||||
* @access protected
|
||||
* @var bool|Vc_Templates_Panel_Editor
|
||||
*/
|
||||
protected $templates_panel_editor = false;
|
||||
/**
|
||||
* Presets management panel editor.
|
||||
* @since 5.2
|
||||
* @access protected
|
||||
* @var bool|Vc_Preset_Panel_Editor
|
||||
*/
|
||||
protected $preset_panel_editor = false;
|
||||
/**
|
||||
* Post object for VC in Admin.
|
||||
*
|
||||
* @since 4.4
|
||||
* @access protected
|
||||
* @var bool|Vc_Post_Admin
|
||||
*/
|
||||
protected $post_admin = false;
|
||||
/**
|
||||
* Post object for VC.
|
||||
*
|
||||
* @since 4.4.3
|
||||
* @access protected
|
||||
* @var bool|Vc_Post_Admin
|
||||
*/
|
||||
protected $post = false;
|
||||
/**
|
||||
* List of shortcodes map to VC.
|
||||
*
|
||||
* @since 4.2
|
||||
* @access public
|
||||
* @var array WPBakeryShortCodeFishBones
|
||||
*/
|
||||
protected $shortcodes = array();
|
||||
|
||||
/** @var Vc_Shared_Templates */
|
||||
public $shared_templates;
|
||||
|
||||
/**
|
||||
* Load default object like shortcode parsing.
|
||||
*
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*/
|
||||
public function init() {
|
||||
do_action( 'vc_before_init_base' );
|
||||
if ( is_admin() ) {
|
||||
$this->postAdmin()->init();
|
||||
}
|
||||
add_filter( 'body_class', array(
|
||||
$this,
|
||||
'bodyClass',
|
||||
) );
|
||||
add_filter( 'the_excerpt', array(
|
||||
$this,
|
||||
'excerptFilter',
|
||||
) );
|
||||
add_action( 'wp_head', array(
|
||||
$this,
|
||||
'addMetaData',
|
||||
) );
|
||||
if ( is_admin() ) {
|
||||
$this->initAdmin();
|
||||
} else {
|
||||
$this->initPage();
|
||||
}
|
||||
do_action( 'vc_after_init_base' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Post object for interacting with Current post data.
|
||||
* @return Vc_Post_Admin
|
||||
* @since 4.4
|
||||
*/
|
||||
public function postAdmin() {
|
||||
if ( false === $this->post_admin ) {
|
||||
require_once vc_path_dir( 'CORE_DIR', 'class-vc-post-admin.php' );
|
||||
$this->post_admin = new Vc_Post_Admin();
|
||||
}
|
||||
|
||||
return $this->post_admin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build VC for frontend pages.
|
||||
*
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*/
|
||||
public function initPage() {
|
||||
do_action( 'vc_build_page' );
|
||||
add_action( 'template_redirect', array(
|
||||
$this,
|
||||
'frontCss',
|
||||
) );
|
||||
add_action( 'template_redirect', array(
|
||||
'WPBMap',
|
||||
'addAllMappedShortcodes',
|
||||
) );
|
||||
add_action( 'wp_head', array(
|
||||
$this,
|
||||
'addFrontCss',
|
||||
), 1000 );
|
||||
add_action( 'wp_head', array(
|
||||
$this,
|
||||
'addNoScript',
|
||||
), 1000 );
|
||||
add_action( 'template_redirect', array(
|
||||
$this,
|
||||
'frontJsRegister',
|
||||
) );
|
||||
add_filter( 'the_content', array(
|
||||
$this,
|
||||
'fixPContent',
|
||||
), 11 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load admin required modules and elements
|
||||
*
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*/
|
||||
public function initAdmin() {
|
||||
do_action( 'vc_build_admin_page' );
|
||||
// editors actions:
|
||||
$this->editForm()->init();
|
||||
$this->templatesPanelEditor()->init();
|
||||
$this->shared_templates->init();
|
||||
|
||||
// plugins list page actions links
|
||||
add_filter( 'plugin_action_links', array(
|
||||
$this,
|
||||
'pluginActionLinks',
|
||||
), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for edit form.
|
||||
* @param Vc_Shortcode_Edit_Form $form
|
||||
* @since 4.2
|
||||
*
|
||||
*/
|
||||
public function setEditForm( Vc_Shortcode_Edit_Form $form ) {
|
||||
$this->shortcode_edit_form = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Shortcodes Edit form object.
|
||||
*
|
||||
* @return Vc_Shortcode_Edit_Form
|
||||
* @since 4.2
|
||||
* @access public
|
||||
* @see Vc_Shortcode_Edit_Form::__construct
|
||||
*/
|
||||
public function editForm() {
|
||||
return $this->shortcode_edit_form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for Templates editor.
|
||||
* @param Vc_Templates_Panel_Editor $editor
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function setTemplatesPanelEditor( Vc_Templates_Panel_Editor $editor ) {
|
||||
$this->templates_panel_editor = $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for Preset editor.
|
||||
* @param Vc_Preset_Panel_Editor $editor
|
||||
* @since 5.2
|
||||
*
|
||||
*/
|
||||
public function setPresetPanelEditor( Vc_Preset_Panel_Editor $editor ) {
|
||||
$this->preset_panel_editor = $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get templates manager.
|
||||
* @return bool|Vc_Templates_Panel_Editor
|
||||
* @since 4.4
|
||||
* @access public
|
||||
* @see Vc_Templates_Panel_Editor::__construct
|
||||
*/
|
||||
public function templatesPanelEditor() {
|
||||
return $this->templates_panel_editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get preset manager.
|
||||
* @return bool|Vc_Preset_Panel_Editor
|
||||
* @since 5.2
|
||||
* @access public
|
||||
* @see Vc_Preset_Panel_Editor::__construct
|
||||
*/
|
||||
public function presetPanelEditor() {
|
||||
return $this->preset_panel_editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shortcode class instance.
|
||||
*
|
||||
* @param string $tag
|
||||
*
|
||||
* @return Vc_Shortcodes_Manager|null
|
||||
* @see WPBakeryShortCodeFishBones
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function getShortCode( $tag ) {
|
||||
return Vc_Shortcodes_Manager::getInstance()->setTag( $tag );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove shortcode from shortcodes list of VC.
|
||||
*
|
||||
* @param $tag - shortcode tag
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function removeShortCode( $tag ) {
|
||||
remove_shortcode( $tag );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set or modify new settings for shortcode.
|
||||
*
|
||||
* This function widely used by WPBMap class methods to modify shortcodes mapping
|
||||
*
|
||||
* @param $tag
|
||||
* @param $name
|
||||
* @param $value
|
||||
* @throws \Exception
|
||||
* @since 4.3
|
||||
*/
|
||||
public function updateShortcodeSetting( $tag, $name, $value ) {
|
||||
Vc_Shortcodes_Manager::getInstance()->getElementClass( $tag )->setSettings( $name, $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build custom css styles for page from shortcodes attributes created by VC editors.
|
||||
*
|
||||
* Called by save method, which is hooked by edit_post action.
|
||||
* Function creates meta data for post with the key '_wpb_shortcodes_custom_css'
|
||||
* and value as css string, which will be added to the footer of the page.
|
||||
*
|
||||
* @param $post_id
|
||||
* @throws \Exception
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*/
|
||||
public function buildShortcodesCustomCss( $post_id ) {
|
||||
$post = get_post( $post_id );
|
||||
/**
|
||||
* vc_filter: vc_base_build_shortcodes_custom_css
|
||||
* @since 4.4
|
||||
*/
|
||||
$css = apply_filters( 'vc_base_build_shortcodes_custom_css', $this->parseShortcodesCustomCss( $post->post_content ), $post_id );
|
||||
if ( empty( $css ) ) {
|
||||
delete_metadata( 'post', $post_id, '_wpb_shortcodes_custom_css' );
|
||||
} else {
|
||||
update_metadata( 'post', $post_id, '_wpb_shortcodes_custom_css', $css );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse shortcodes custom css string.
|
||||
*
|
||||
* This function is used by self::buildShortcodesCustomCss and creates css string from shortcodes attributes
|
||||
* like 'css_editor'.
|
||||
*
|
||||
* @param $content
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
* @see WPBakeryVisualComposerCssEditor
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*/
|
||||
public function parseShortcodesCustomCss( $content ) {
|
||||
$css = '';
|
||||
if ( ! preg_match( '/\s*(\.[^\{]+)\s*\{\s*([^\}]+)\s*\}\s*/', $content ) ) {
|
||||
return $css;
|
||||
}
|
||||
WPBMap::addAllMappedShortcodes();
|
||||
preg_match_all( '/' . get_shortcode_regex() . '/', $content, $shortcodes );
|
||||
foreach ( $shortcodes[2] as $index => $tag ) {
|
||||
$shortcode = WPBMap::getShortCode( $tag );
|
||||
$attr_array = shortcode_parse_atts( trim( $shortcodes[3][ $index ] ) );
|
||||
if ( isset( $shortcode['params'] ) && ! empty( $shortcode['params'] ) ) {
|
||||
foreach ( $shortcode['params'] as $param ) {
|
||||
if ( isset( $param['type'] ) && 'css_editor' === $param['type'] && isset( $attr_array[ $param['param_name'] ] ) ) {
|
||||
$css .= $attr_array[ $param['param_name'] ];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach ( $shortcodes[5] as $shortcode_content ) {
|
||||
$css .= $this->parseShortcodesCustomCss( $shortcode_content );
|
||||
}
|
||||
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooked class method by wp_head WP action to output post custom css.
|
||||
*
|
||||
* Method gets post meta value for page by key '_wpb_post_custom_css' and if it is not empty
|
||||
* outputs css string wrapped into style tag.
|
||||
*
|
||||
* @param int $id
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function addPageCustomCss( $id = null ) {
|
||||
if ( is_front_page() || is_home() ) {
|
||||
$id = get_queried_object_id();
|
||||
} elseif ( is_singular() ) {
|
||||
if ( ! $id ) {
|
||||
$id = get_the_ID();
|
||||
}
|
||||
}
|
||||
|
||||
if ( $id ) {
|
||||
if ( 'true' === vc_get_param( 'preview' ) && wp_revisions_enabled( get_post( $id ) ) ) {
|
||||
$latest_revision = wp_get_post_revisions( $id );
|
||||
if ( ! empty( $latest_revision ) ) {
|
||||
$array_values = array_values( $latest_revision );
|
||||
$id = $array_values[0]->ID;
|
||||
}
|
||||
}
|
||||
$post_custom_css = get_metadata( 'post', $id, '_wpb_post_custom_css', true );
|
||||
if ( ! empty( $post_custom_css ) ) {
|
||||
$post_custom_css = wp_strip_all_tags( $post_custom_css );
|
||||
echo '<style type="text/css" data-type="vc_custom-css">';
|
||||
echo $post_custom_css;
|
||||
echo '</style>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooked class method by wp_footer WP action to output shortcodes css editor settings from page meta data.
|
||||
*
|
||||
* Method gets post meta value for page by key '_wpb_shortcodes_custom_css' and if it is not empty
|
||||
* outputs css string wrapped into style tag.
|
||||
*
|
||||
* @param int $id
|
||||
*
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function addShortcodesCustomCss( $id = null ) {
|
||||
if ( ! is_singular() ) {
|
||||
return;
|
||||
}
|
||||
if ( ! $id ) {
|
||||
$id = get_the_ID();
|
||||
}
|
||||
|
||||
if ( $id ) {
|
||||
if ( 'true' === vc_get_param( 'preview' ) && wp_revisions_enabled( get_post( $id ) ) ) {
|
||||
$latest_revision = wp_get_post_revisions( $id );
|
||||
if ( ! empty( $latest_revision ) ) {
|
||||
$array_values = array_values( $latest_revision );
|
||||
$id = $array_values[0]->ID;
|
||||
}
|
||||
}
|
||||
$shortcodes_custom_css = get_metadata( 'post', $id, '_wpb_shortcodes_custom_css', true );
|
||||
if ( ! empty( $shortcodes_custom_css ) ) {
|
||||
$shortcodes_custom_css = wp_strip_all_tags( $shortcodes_custom_css );
|
||||
echo '<style type="text/css" data-type="vc_shortcodes-custom-css">';
|
||||
echo $shortcodes_custom_css;
|
||||
echo '</style>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add css styles for current page and elements design options added w\ editor.
|
||||
*/
|
||||
public function addFrontCss() {
|
||||
$this->addPageCustomCss();
|
||||
$this->addShortcodesCustomCss();
|
||||
}
|
||||
|
||||
public function addNoScript() {
|
||||
$custom_tag = 'style';
|
||||
$second_tag = 'noscript';
|
||||
echo '<' . esc_attr( $second_tag ) . '>';
|
||||
echo '<' . esc_attr( $custom_tag ) . '>';
|
||||
echo ' .wpb_animate_when_almost_visible { opacity: 1; }';
|
||||
echo '</' . esc_attr( $custom_tag ) . '>';
|
||||
echo '</' . esc_attr( $second_tag ) . '>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Register front css styles.
|
||||
*
|
||||
* Calls wp_register_style for required css libraries files.
|
||||
*
|
||||
* @since 3.1
|
||||
* @access public
|
||||
*/
|
||||
public function frontCss() {
|
||||
wp_register_style( 'flexslider', vc_asset_url( 'lib/bower/flexslider/flexslider.min.css' ), array(), WPB_VC_VERSION );
|
||||
wp_register_style( 'nivo-slider-css', vc_asset_url( 'lib/bower/nivoslider/nivo-slider.min.css' ), array(), WPB_VC_VERSION );
|
||||
wp_register_style( 'nivo-slider-theme', vc_asset_url( 'lib/bower/nivoslider/themes/default/default.min.css' ), array( 'nivo-slider-css' ), WPB_VC_VERSION );
|
||||
wp_register_style( 'prettyphoto', vc_asset_url( 'lib/prettyphoto/css/prettyPhoto.min.css' ), array(), WPB_VC_VERSION );
|
||||
wp_register_style( 'isotope-css', vc_asset_url( 'css/lib/isotope.min.css' ), array(), WPB_VC_VERSION );
|
||||
wp_register_style( 'vc_font_awesome_5_shims', vc_asset_url( 'lib/bower/font-awesome/css/v4-shims.min.css' ), array(), WPB_VC_VERSION );
|
||||
wp_register_style( 'vc_font_awesome_5', vc_asset_url( 'lib/bower/font-awesome/css/all.min.css' ), array( 'vc_font_awesome_5_shims' ), WPB_VC_VERSION );
|
||||
wp_register_style( 'vc_animate-css', vc_asset_url( 'lib/bower/animate-css/animate.min.css' ), array(), WPB_VC_VERSION );
|
||||
|
||||
$front_css_file = vc_asset_url( 'css/js_composer.min.css' );
|
||||
$upload_dir = wp_upload_dir();
|
||||
$vc_upload_dir = vc_upload_dir();
|
||||
if ( '1' === vc_settings()->get( 'use_custom' ) && is_file( $upload_dir['basedir'] . '/' . $vc_upload_dir . '/js_composer_front_custom.css' ) ) {
|
||||
$front_css_file = $upload_dir['baseurl'] . '/' . $vc_upload_dir . '/js_composer_front_custom.css';
|
||||
$front_css_file = vc_str_remove_protocol( $front_css_file );
|
||||
}
|
||||
wp_register_style( 'js_composer_front', $front_css_file, array(), WPB_VC_VERSION );
|
||||
|
||||
$custom_css_path = $upload_dir['basedir'] . '/' . $vc_upload_dir . '/custom.css';
|
||||
if ( is_file( $upload_dir['basedir'] . '/' . $vc_upload_dir . '/custom.css' ) && filesize( $custom_css_path ) > 0 ) {
|
||||
$custom_css_url = $upload_dir['baseurl'] . '/' . $vc_upload_dir . '/custom.css';
|
||||
$custom_css_url = vc_str_remove_protocol( $custom_css_url );
|
||||
wp_register_style( 'js_composer_custom_css', $custom_css_url, array(), WPB_VC_VERSION );
|
||||
}
|
||||
|
||||
add_action( 'wp_enqueue_scripts', array(
|
||||
$this,
|
||||
'enqueueStyle',
|
||||
) );
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
do_action( 'vc_base_register_front_css' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue base css class for VC elements and enqueue custom css if exists.
|
||||
*/
|
||||
public function enqueueStyle() {
|
||||
$post = get_post();
|
||||
if ( $post && strpos( $post->post_content, '[vc_row' ) !== false ) {
|
||||
wp_enqueue_style( 'js_composer_front' );
|
||||
}
|
||||
wp_enqueue_style( 'js_composer_custom_css' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register front javascript libs.
|
||||
*
|
||||
* Calls wp_register_script for required css libraries files.
|
||||
*
|
||||
* @since 3.1
|
||||
* @access public
|
||||
*/
|
||||
public function frontJsRegister() {
|
||||
wp_register_script( 'prettyphoto', vc_asset_url( 'lib/prettyphoto/js/jquery.prettyPhoto.min.js' ), array( 'jquery' ), WPB_VC_VERSION, true );
|
||||
wp_register_script( 'vc_waypoints', vc_asset_url( 'lib/vc_waypoints/vc-waypoints.min.js' ), array( 'jquery' ), WPB_VC_VERSION, true );
|
||||
|
||||
// @deprecated used in old tabs
|
||||
wp_register_script( 'jquery_ui_tabs_rotate', vc_asset_url( 'lib/bower/jquery-ui-tabs-rotate/jquery-ui-tabs-rotate.min.js' ), array(
|
||||
'jquery',
|
||||
'jquery-ui-tabs',
|
||||
), WPB_VC_VERSION, true );
|
||||
|
||||
// used in vc_gallery, old grid
|
||||
wp_register_script( 'isotope', vc_asset_url( 'lib/bower/isotope/dist/isotope.pkgd.min.js' ), array( 'jquery' ), WPB_VC_VERSION, true );
|
||||
|
||||
wp_register_script( 'twbs-pagination', vc_asset_url( 'lib/bower/twbs-pagination/jquery.twbsPagination.min.js' ), array( 'jquery' ), WPB_VC_VERSION, true );
|
||||
wp_register_script( 'nivo-slider', vc_asset_url( 'lib/bower/nivoslider/jquery.nivo.slider.pack.js' ), array( 'jquery' ), WPB_VC_VERSION, true );
|
||||
wp_register_script( 'flexslider', vc_asset_url( 'lib/bower/flexslider/jquery.flexslider-min.js' ), array( 'jquery' ), WPB_VC_VERSION, true );
|
||||
wp_register_script( 'wpb_composer_front_js', vc_asset_url( 'js/dist/js_composer_front.min.js' ), array( 'jquery' ), WPB_VC_VERSION, true );
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
do_action( 'vc_base_register_front_js' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register admin javascript libs.
|
||||
*
|
||||
* Calls wp_register_script for required css libraries files for Admin dashboard.
|
||||
*
|
||||
* @since 3.1
|
||||
* vc_filter: vc_i18n_locale_composer_js_view, since 4.4 - override localization for js
|
||||
* @access public
|
||||
*/
|
||||
public function registerAdminJavascript() {
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
do_action( 'vc_base_register_admin_js' );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Register admin css styles.
|
||||
*
|
||||
* Calls wp_register_style for required css libraries files for admin dashboard.
|
||||
*
|
||||
* @since 3.1
|
||||
* @access public
|
||||
*/
|
||||
public function registerAdminCss() {
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
do_action( 'vc_base_register_admin_css' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Settings link in plugin's page
|
||||
* @param $links
|
||||
* @param $file
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
* @since 4.2
|
||||
*/
|
||||
public function pluginActionLinks( $links, $file ) {
|
||||
if ( plugin_basename( vc_path_dir( 'APP_DIR', '/js_composer.php' ) ) === $file ) {
|
||||
$title = esc_html__( 'WPBakery Page Builder Settings', 'js_composer' );
|
||||
$html = esc_html__( 'Settings', 'js_composer' );
|
||||
if ( ! vc_user_access()->part( 'settings' )->can( 'vc-general-tab' )->get() ) {
|
||||
$title = esc_html__( 'About WPBakery Page Builder', 'js_composer' );
|
||||
$html = esc_html__( 'About', 'js_composer' );
|
||||
}
|
||||
$link = '<a title="' . esc_attr( $title ) . '" href="' . esc_url( $this->getSettingsPageLink() ) . '">' . $html . '</a>';
|
||||
array_unshift( $links, $link ); // Add to top
|
||||
}
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get settings page link
|
||||
* @return string url to settings page
|
||||
* @throws \Exception
|
||||
* @since 4.2
|
||||
*/
|
||||
public function getSettingsPageLink() {
|
||||
$page = 'vc-general';
|
||||
if ( ! vc_user_access()->part( 'settings' )->can( 'vc-general-tab' )->get() ) {
|
||||
$page = 'vc-welcome';
|
||||
}
|
||||
|
||||
return add_query_arg( array( 'page' => $page ), admin_url( 'admin.php' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooked class method by wp_head WP action.
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*/
|
||||
public function addMetaData() {
|
||||
echo '<meta name="generator" content="Powered by WPBakery Page Builder - drag and drop page builder for WordPress."/>' . "\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Method adds css class to body tag.
|
||||
*
|
||||
* Hooked class method by body_class WP filter. Method adds custom css class to body tag of the page to help
|
||||
* identify and build design specially for VC shortcodes.
|
||||
*
|
||||
* @param $classes
|
||||
*
|
||||
* @return array
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function bodyClass( $classes ) {
|
||||
return js_composer_body_class( $classes );
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds excerpt for post from content.
|
||||
*
|
||||
* Hooked class method by the_excerpt WP filter. When user creates content with VC all content is always wrapped by
|
||||
* shortcodes. This methods calls do_shortcode for post's content and then creates a new excerpt.
|
||||
*
|
||||
* @param $output
|
||||
*
|
||||
* @return string
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function excerptFilter( $output ) {
|
||||
global $post;
|
||||
if ( empty( $output ) && ! empty( $post->post_content ) ) {
|
||||
$text = wp_strip_all_tags( do_shortcode( $post->post_content ) );
|
||||
$excerpt_length = apply_filters( 'excerpt_length', 55 );
|
||||
$excerpt_more = apply_filters( 'excerpt_more', ' [...]' );
|
||||
$text = wp_trim_words( $text, $excerpt_length, $excerpt_more );
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove unwanted wraping with p for content.
|
||||
*
|
||||
* Hooked by 'the_content' filter.
|
||||
* @param null $content
|
||||
*
|
||||
* @return string|null
|
||||
* @since 4.2
|
||||
*
|
||||
*/
|
||||
public function fixPContent( $content = null ) {
|
||||
if ( $content ) {
|
||||
$s = array(
|
||||
'/' . preg_quote( '</div>', '/' ) . '[\s\n\f]*' . preg_quote( '</p>', '/' ) . '/i',
|
||||
'/' . preg_quote( '<p>', '/' ) . '[\s\n\f]*' . preg_quote( '<div ', '/' ) . '/i',
|
||||
'/' . preg_quote( '<p>', '/' ) . '[\s\n\f]*' . preg_quote( '<section ', '/' ) . '/i',
|
||||
'/' . preg_quote( '</section>', '/' ) . '[\s\n\f]*' . preg_quote( '</p>', '/' ) . '/i',
|
||||
);
|
||||
$r = array(
|
||||
'</div>',
|
||||
'<div ',
|
||||
'<section ',
|
||||
'</section>',
|
||||
);
|
||||
$content = preg_replace( $s, $r, $content );
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of string for locale.
|
||||
*
|
||||
* @return array
|
||||
* @since 4.7
|
||||
*
|
||||
*/
|
||||
public function getEditorsLocale() {
|
||||
return array(
|
||||
'add_remove_picture' => esc_html__( 'Add/remove picture', 'js_composer' ),
|
||||
'finish_adding_text' => esc_html__( 'Finish Adding Images', 'js_composer' ),
|
||||
'add_image' => esc_html__( 'Add Image', 'js_composer' ),
|
||||
'add_images' => esc_html__( 'Add Images', 'js_composer' ),
|
||||
'settings' => esc_html__( 'Settings', 'js_composer' ),
|
||||
'main_button_title' => esc_html__( 'WPBakery Page Builder', 'js_composer' ),
|
||||
'main_button_title_backend_editor' => esc_html__( 'Backend Editor', 'js_composer' ),
|
||||
'main_button_title_frontend_editor' => esc_html__( 'Frontend Editor', 'js_composer' ),
|
||||
'main_button_title_revert' => esc_html__( 'Classic Mode', 'js_composer' ),
|
||||
'main_button_title_gutenberg' => esc_html__( 'Gutenberg Editor', 'js_composer' ),
|
||||
'please_enter_templates_name' => esc_html__( 'Enter template name you want to save.', 'js_composer' ),
|
||||
'confirm_deleting_template' => esc_html__( 'Confirm deleting "{template_name}" template, press Cancel to leave. This action cannot be undone.', 'js_composer' ),
|
||||
'press_ok_to_delete_section' => esc_html__( 'Press OK to delete section, Cancel to leave', 'js_composer' ),
|
||||
'drag_drop_me_in_column' => esc_html__( 'Drag and drop me in the column', 'js_composer' ),
|
||||
'press_ok_to_delete_tab' => esc_html__( 'Press OK to delete "{tab_name}" tab, Cancel to leave', 'js_composer' ),
|
||||
'slide' => esc_html__( 'Slide', 'js_composer' ),
|
||||
'tab' => esc_html__( 'Tab', 'js_composer' ),
|
||||
'section' => esc_html__( 'Section', 'js_composer' ),
|
||||
'please_enter_new_tab_title' => esc_html__( 'Please enter new tab title', 'js_composer' ),
|
||||
'press_ok_delete_section' => esc_html__( 'Press OK to delete "{tab_name}" section, Cancel to leave', 'js_composer' ),
|
||||
'section_default_title' => esc_html__( 'Section', 'js_composer' ),
|
||||
'please_enter_section_title' => esc_html__( 'Please enter new section title', 'js_composer' ),
|
||||
'error_please_try_again' => esc_html__( 'Error. Please try again.', 'js_composer' ),
|
||||
'if_close_data_lost' => esc_html__( 'If you close this window all shortcode settings will be lost. Close this window?', 'js_composer' ),
|
||||
'header_select_element_type' => esc_html__( 'Select element type', 'js_composer' ),
|
||||
'header_media_gallery' => esc_html__( 'Media gallery', 'js_composer' ),
|
||||
'header_element_settings' => esc_html__( 'Element settings', 'js_composer' ),
|
||||
'add_tab' => esc_html__( 'Add tab', 'js_composer' ),
|
||||
'are_you_sure_convert_to_new_version' => esc_html__( 'Are you sure you want to convert to new version?', 'js_composer' ),
|
||||
'loading' => esc_html__( 'Loading...', 'js_composer' ),
|
||||
// Media editor
|
||||
'set_image' => esc_html__( 'Set Image', 'js_composer' ),
|
||||
'are_you_sure_reset_css_classes' => esc_html__( 'Are you sure that you want to remove all your data?', 'js_composer' ),
|
||||
'loop_frame_title' => esc_html__( 'Loop settings', 'js_composer' ),
|
||||
'enter_custom_layout' => esc_html__( 'Custom row layout', 'js_composer' ),
|
||||
'wrong_cells_layout' => esc_html__( 'Wrong row layout format! Example: 1/2 + 1/2 or span6 + span6.', 'js_composer' ),
|
||||
'row_background_color' => esc_html__( 'Row background color', 'js_composer' ),
|
||||
'row_background_image' => esc_html__( 'Row background image', 'js_composer' ),
|
||||
'column_background_color' => esc_html__( 'Column background color', 'js_composer' ),
|
||||
'column_background_image' => esc_html__( 'Column background image', 'js_composer' ),
|
||||
'guides_on' => esc_html__( 'Guides ON', 'js_composer' ),
|
||||
'guides_off' => esc_html__( 'Guides OFF', 'js_composer' ),
|
||||
'template_save' => esc_html__( 'New template successfully saved.', 'js_composer' ),
|
||||
'template_added' => esc_html__( 'Template added to the page.', 'js_composer' ),
|
||||
'template_added_with_id' => esc_html__( 'Template added to the page. Template has ID attributes, make sure that they are not used more than once on the same page.', 'js_composer' ),
|
||||
'template_removed' => esc_html__( 'Template successfully removed.', 'js_composer' ),
|
||||
'template_is_empty' => esc_html__( 'Template is empty: There is no content to be saved as a template.', 'js_composer' ),
|
||||
'template_save_error' => esc_html__( 'Error while saving template.', 'js_composer' ),
|
||||
'css_updated' => esc_html__( 'Page settings updated!', 'js_composer' ),
|
||||
'update_all' => esc_html__( 'Update all', 'js_composer' ),
|
||||
'confirm_to_leave' => esc_html__( 'The changes you made will be lost if you navigate away from this page.', 'js_composer' ),
|
||||
'inline_element_saved' => esc_html__( '%s saved!', 'js_composer' ),
|
||||
'inline_element_deleted' => esc_html__( '%s deleted!', 'js_composer' ),
|
||||
'inline_element_cloned' => sprintf( __( '%%s cloned. %sEdit now?%s', 'js_composer' ), '<a href="#" class="vc_edit-cloned" data-model-id="%s">', '</a>' ),
|
||||
'gfonts_loading_google_font_failed' => esc_html__( 'Loading Google Font failed', 'js_composer' ),
|
||||
'gfonts_loading_google_font' => esc_html__( 'Loading Font...', 'js_composer' ),
|
||||
'gfonts_unable_to_load_google_fonts' => esc_html__( 'Unable to load Google Fonts', 'js_composer' ),
|
||||
'no_title_parenthesis' => sprintf( '(%s)', esc_html__( 'no title', 'js_composer' ) ),
|
||||
'error_while_saving_image_filtered' => esc_html__( 'Error while applying filter to the image. Check your server and memory settings.', 'js_composer' ),
|
||||
'ui_saved' => sprintf( '<i class="vc-composer-icon vc-c-icon-check"></i> %s', esc_html__( 'Saved!', 'js_composer' ) ),
|
||||
'ui_danger' => sprintf( '<i class="vc-composer-icon vc-c-icon-close"></i> %s', esc_html__( 'Failed to Save!', 'js_composer' ) ),
|
||||
'delete_preset_confirmation' => esc_html__( 'You are about to delete this preset. This action can not be undone.', 'js_composer' ),
|
||||
'ui_template_downloaded' => esc_html__( 'Downloaded', 'js_composer' ),
|
||||
'ui_template_update' => esc_html__( 'Update', 'js_composer' ),
|
||||
'ui_templates_failed_to_download' => esc_html__( 'Failed to download template', 'js_composer' ),
|
||||
'preset_removed' => esc_html__( 'Element successfully removed.', 'js_composer' ),
|
||||
'vc_successfully_updated' => esc_html__( 'Successfully updated!', 'js_composer' ),
|
||||
'gutenbergDoesntWorkProperly' => esc_html__( 'Gutenberg plugin doesn\'t work properly. Please check Gutenberg plugin.', 'js_composer' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,870 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Vc starts here. Manager sets mode, adds required wp hooks and loads required object of structure
|
||||
*
|
||||
* Manager controls and access to all modules and classes of VC.
|
||||
*
|
||||
* @package WPBakeryVisualComposer
|
||||
* @since 4.2
|
||||
*/
|
||||
class Vc_Manager {
|
||||
/**
|
||||
* Set status/mode for VC.
|
||||
*
|
||||
* It depends on what functionality is required from vc to work with current page/part of WP.
|
||||
*
|
||||
* Possible values:
|
||||
* none - current status is unknown, default mode;
|
||||
* page - simple wp page;
|
||||
* admin_page - wp dashboard;
|
||||
* admin_frontend_editor - WPBakery Page Builder front end editor version;
|
||||
* admin_settings_page - settings page
|
||||
* page_editable - inline version for iframe in front end editor;
|
||||
*
|
||||
* @since 4.2
|
||||
* @var string
|
||||
*/
|
||||
private $mode = 'none';
|
||||
/**
|
||||
* Enables WPBakery Page Builder to act as the theme plugin.
|
||||
*
|
||||
* @since 4.2
|
||||
* @var bool
|
||||
*/
|
||||
private $is_as_theme = false;
|
||||
/**
|
||||
* Vc is network plugin or not.
|
||||
* @since 4.2
|
||||
* @var bool
|
||||
*/
|
||||
private $is_network_plugin = null;
|
||||
/**
|
||||
* List of paths.
|
||||
*
|
||||
* @since 4.2
|
||||
* @var array
|
||||
*/
|
||||
private $paths = array();
|
||||
/**
|
||||
* Default post types where to activate WPBakery Page Builder meta box settings
|
||||
* @since 4.2
|
||||
* @var array
|
||||
*/
|
||||
private $editor_default_post_types = array( 'page' ); // TODO: move to Vc settings
|
||||
/**
|
||||
* Directory name in theme folder where composer should search for alternative templates of the shortcode.
|
||||
* @since 4.2
|
||||
* @var string
|
||||
*/
|
||||
private $custom_user_templates_dir = false;
|
||||
|
||||
/**
|
||||
* Set updater mode
|
||||
* @since 4.2
|
||||
* @var bool
|
||||
*/
|
||||
private $disable_updater = false;
|
||||
/**
|
||||
* Modules and objects instances list
|
||||
* @since 4.2
|
||||
* @var array
|
||||
*/
|
||||
private $factory = array();
|
||||
/**
|
||||
* File name for components manifest file.
|
||||
*
|
||||
* @since 4.4
|
||||
* @var string
|
||||
*/
|
||||
private $components_manifest = 'components.json';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $plugin_name = 'js_composer/js_composer.php';
|
||||
|
||||
/**
|
||||
* Core singleton class
|
||||
* @var self - pattern realization
|
||||
*/
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* @var Vc_Current_User_Access|false
|
||||
* @since 4.8
|
||||
*/
|
||||
private $current_user_access = false;
|
||||
/**
|
||||
* @var Vc_Role_Access|false
|
||||
* @since 4.8
|
||||
*/
|
||||
private $role_access = false;
|
||||
|
||||
public $editor_post_types;
|
||||
|
||||
/**
|
||||
* Constructor loads API functions, defines paths and adds required wp actions
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
private function __construct() {
|
||||
$dir = WPB_PLUGIN_DIR;
|
||||
/**
|
||||
* Define path settings for WPBakery Page Builder.
|
||||
*
|
||||
* APP_ROOT - plugin directory.
|
||||
* WP_ROOT - WP application root directory.
|
||||
* APP_DIR - plugin directory name.
|
||||
* CONFIG_DIR - configuration directory.
|
||||
* ASSETS_DIR - asset directory full path.
|
||||
* ASSETS_DIR_NAME - directory name for assets. Used from urls creating.
|
||||
* CORE_DIR - classes directory for core vc files.
|
||||
* HELPERS_DIR - directory with helpers functions files.
|
||||
* SHORTCODES_DIR - shortcodes classes.
|
||||
* SETTINGS_DIR - main dashboard settings classes.
|
||||
* TEMPLATES_DIR - directory where all html templates are hold.
|
||||
* EDITORS_DIR - editors for the post contents
|
||||
* PARAMS_DIR - complex params for shortcodes editor form.
|
||||
* UPDATERS_DIR - automatic notifications and updating classes.
|
||||
*/
|
||||
$this->setPaths( array(
|
||||
'APP_ROOT' => $dir,
|
||||
'WP_ROOT' => preg_replace( '/$\//', '', ABSPATH ),
|
||||
'APP_DIR' => basename( plugin_basename( $dir ) ),
|
||||
'CONFIG_DIR' => $dir . '/config',
|
||||
'ASSETS_DIR' => $dir . '/assets',
|
||||
'ASSETS_DIR_NAME' => 'assets',
|
||||
'AUTOLOAD_DIR' => $dir . '/include/autoload',
|
||||
'CORE_DIR' => $dir . '/include/classes/core',
|
||||
'HELPERS_DIR' => $dir . '/include/helpers',
|
||||
'SHORTCODES_DIR' => $dir . '/include/classes/shortcodes',
|
||||
'SETTINGS_DIR' => $dir . '/include/classes/settings',
|
||||
'TEMPLATES_DIR' => $dir . '/include/templates',
|
||||
'EDITORS_DIR' => $dir . '/include/classes/editors',
|
||||
'PARAMS_DIR' => $dir . '/include/params',
|
||||
'UPDATERS_DIR' => $dir . '/include/classes/updaters',
|
||||
'VENDORS_DIR' => $dir . '/include/classes/vendors',
|
||||
'DEPRECATED_DIR' => $dir . '/include/classes/deprecated',
|
||||
) );
|
||||
// Load API
|
||||
require_once $this->path( 'HELPERS_DIR', 'helpers_factory.php' );
|
||||
require_once $this->path( 'HELPERS_DIR', 'helpers.php' );
|
||||
require_once $this->path( 'DEPRECATED_DIR', 'interfaces.php' );
|
||||
require_once $this->path( 'CORE_DIR', 'class-vc-sort.php' ); // used by wpb-map
|
||||
require_once $this->path( 'CORE_DIR', 'class-wpb-map.php' );
|
||||
require_once $this->path( 'CORE_DIR', 'class-vc-shared-library.php' );
|
||||
require_once $this->path( 'HELPERS_DIR', 'helpers_api.php' );
|
||||
require_once $this->path( 'DEPRECATED_DIR', 'helpers_deprecated.php' );
|
||||
require_once $this->path( 'PARAMS_DIR', 'params.php' );
|
||||
require_once $this->path( 'AUTOLOAD_DIR', 'vc-shortcode-autoloader.php' );
|
||||
require_once $this->path( 'SHORTCODES_DIR', 'core/class-vc-shortcodes-manager.php' );
|
||||
require_once $this->path( 'CORE_DIR', 'class-vc-modifications.php' );
|
||||
// Add hooks
|
||||
add_action( 'plugins_loaded', array(
|
||||
$this,
|
||||
'pluginsLoaded',
|
||||
), 9 );
|
||||
add_action( 'init', array(
|
||||
$this,
|
||||
'init',
|
||||
), 11 );
|
||||
$this->setPluginName( $this->path( 'APP_DIR', 'js_composer.php' ) );
|
||||
register_activation_hook( WPB_PLUGIN_FILE, array(
|
||||
$this,
|
||||
'activationHook',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instane of VC_Manager
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function getInstance() {
|
||||
if ( ! ( self::$instance instanceof self ) ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* prevent the instance from being cloned (which would create a second instance of it)
|
||||
*/
|
||||
private function __clone() {
|
||||
}
|
||||
|
||||
/**
|
||||
* prevent from being unserialized (which would create a second instance of it)
|
||||
*/
|
||||
private function __wakeup() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function WP plugin_loaded action hook. Loads locale
|
||||
*
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*/
|
||||
public function pluginsLoaded() {
|
||||
// Setup locale
|
||||
do_action( 'vc_plugins_loaded' );
|
||||
load_plugin_textdomain( 'js_composer', false, $this->path( 'APP_DIR', 'locale' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function for WP init action hook. Sets Vc mode and loads required objects.
|
||||
*
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*/
|
||||
public function init() {
|
||||
ob_start();
|
||||
do_action( 'vc_before_init' );
|
||||
ob_end_clean(); // FIX for whitespace issues (#76147)
|
||||
$this->setMode();
|
||||
do_action( 'vc_after_set_mode' );
|
||||
/**
|
||||
* Set version of VC if required.
|
||||
*/
|
||||
$this->setVersion();
|
||||
// Load required
|
||||
! vc_is_updater_disabled() && vc_updater()->init();
|
||||
/**
|
||||
* Init default hooks and options to load.
|
||||
*/
|
||||
$this->vc()->init();
|
||||
/**
|
||||
* if is admin and not front end editor.
|
||||
*/
|
||||
is_admin() && ! vc_is_frontend_editor() && $this->asAdmin();
|
||||
/**
|
||||
* if frontend editor is enabled init editor.
|
||||
*/
|
||||
vc_enabled_frontend() && vc_frontend_editor()->init();
|
||||
do_action( 'vc_before_mapping' ); // VC ACTION
|
||||
// Include default shortcodes.
|
||||
$this->mapper()->init(); // execute all required
|
||||
do_action( 'vc_after_mapping' ); // VC ACTION
|
||||
// Load && Map shortcodes from Automapper.
|
||||
vc_automapper()->map();
|
||||
new Vc_Modifications();
|
||||
if ( vc_user_access()->wpAny( 'manage_options' )->part( 'settings' )->can( 'vc-updater-tab' )->get() ) {
|
||||
vc_license()->setupReminder();
|
||||
}
|
||||
do_action( 'vc_after_init' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Vc_Current_User_Access
|
||||
* @since 4.8
|
||||
*/
|
||||
public function getCurrentUserAccess() {
|
||||
if ( ! $this->current_user_access ) {
|
||||
require_once vc_path_dir( 'CORE_DIR', 'access/class-vc-current-user-access.php' );
|
||||
$this->current_user_access = new Vc_Current_User_Access();
|
||||
}
|
||||
|
||||
return $this->current_user_access;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param false|Vc_Current_User_Access $current_user_access
|
||||
*/
|
||||
public function setCurrentUserAccess( $current_user_access ) {
|
||||
$this->current_user_access = $current_user_access;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Vc_Role_Access
|
||||
* @since 4.8
|
||||
*/
|
||||
public function getRoleAccess() {
|
||||
if ( ! $this->role_access ) {
|
||||
require_once vc_path_dir( 'CORE_DIR', 'access/class-vc-role-access.php' );
|
||||
$this->role_access = new Vc_Role_Access();
|
||||
}
|
||||
|
||||
return $this->role_access;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param false|Vc_Role_Access $role_access
|
||||
*/
|
||||
public function setRoleAccess( $role_access ) {
|
||||
$this->role_access = $role_access;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables to add hooks in activation process.
|
||||
* @param $networkWide
|
||||
* @since 4.5
|
||||
*
|
||||
*/
|
||||
public function activationHook( $networkWide = false ) {
|
||||
do_action( 'vc_activation_hook', $networkWide );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load required components to enable useful functionality.
|
||||
*
|
||||
* @access public
|
||||
* @since 4.4
|
||||
*/
|
||||
public function loadComponents() {
|
||||
$manifest_file = apply_filters( 'vc_autoload_components_manifest_file', vc_path_dir( 'AUTOLOAD_DIR', $this->components_manifest ) );
|
||||
if ( is_file( $manifest_file ) ) {
|
||||
ob_start();
|
||||
require_once $manifest_file;
|
||||
$data = ob_get_clean();
|
||||
if ( $data ) {
|
||||
$components = (array) json_decode( $data );
|
||||
$components = apply_filters( 'vc_autoload_components_list', $components );
|
||||
$dir = vc_path_dir( 'AUTOLOAD_DIR' );
|
||||
foreach ( $components as $component => $description ) {
|
||||
$component_path = $dir . '/' . $component;
|
||||
if ( false === strpos( $component_path, '*' ) ) {
|
||||
require_once $component_path;
|
||||
} else {
|
||||
$components_paths = glob( $component_path );
|
||||
if ( is_array( $components_paths ) ) {
|
||||
foreach ( $components_paths as $path ) {
|
||||
if ( false === strpos( $path, '*' ) ) {
|
||||
require_once $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load required logic for operating in Wp Admin dashboard.
|
||||
*
|
||||
* @return void
|
||||
* @since 4.2
|
||||
* @access protected
|
||||
*
|
||||
*/
|
||||
protected function asAdmin() {
|
||||
vc_license()->init();
|
||||
vc_backend_editor()->addHooksSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set VC mode.
|
||||
*
|
||||
* Mode depends on which page is requested by client from server and request parameters like vc_action.
|
||||
*
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
* @since 4.2
|
||||
* @access protected
|
||||
*/
|
||||
protected function setMode() {
|
||||
/**
|
||||
* TODO: Create another system (When ajax rebuild).
|
||||
* Use vc_action param to define mode.
|
||||
* 1. admin_frontend_editor - set by editor or request param
|
||||
* 2. admin_backend_editor - set by editor or request param
|
||||
* 3. admin_frontend_editor_ajax - set by request param
|
||||
* 4. admin_backend_editor_ajax - set by request param
|
||||
* 5. admin_updater - by vc_action
|
||||
* 6. page_editable - by vc_action
|
||||
*/
|
||||
if ( is_admin() ) {
|
||||
if ( 'vc_inline' === vc_action() ) {
|
||||
vc_user_access()->wpAny( array(
|
||||
'edit_post',
|
||||
(int) vc_request_param( 'post_id' ),
|
||||
) )->validateDie()->part( 'frontend_editor' )->can()->validateDie();
|
||||
$this->mode = 'admin_frontend_editor';
|
||||
} elseif ( ( vc_user_access()->wpAny( 'edit_posts', 'edit_pages' )
|
||||
->get() ) && ( 'vc_upgrade' === vc_action() || ( 'update-selected' === vc_get_param( 'action' ) && $this->pluginName() === vc_get_param( 'plugins' ) ) ) ) {
|
||||
$this->mode = 'admin_updater';
|
||||
} elseif ( vc_user_access()->wpAny( 'manage_options' )->get() && array_key_exists( vc_get_param( 'page' ), vc_settings()->getTabs() ) ) {
|
||||
$this->mode = 'admin_settings_page';
|
||||
} else {
|
||||
$this->mode = 'admin_page';
|
||||
}
|
||||
} else {
|
||||
if ( 'true' === vc_get_param( 'vc_editable' ) ) {
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( array(
|
||||
'edit_post',
|
||||
(int) vc_request_param( 'vc_post_id' ),
|
||||
) )->validateDie()->part( 'frontend_editor' )->can()->validateDie();
|
||||
$this->mode = 'page_editable';
|
||||
} else {
|
||||
$this->mode = 'page';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets version of the VC in DB as option `vc_version`
|
||||
*
|
||||
* @return void
|
||||
* @since 4.3.2
|
||||
* @access protected
|
||||
*
|
||||
*/
|
||||
protected function setVersion() {
|
||||
$version = get_option( 'vc_version' );
|
||||
if ( ! is_string( $version ) || version_compare( $version, WPB_VC_VERSION ) !== 0 ) {
|
||||
add_action( 'vc_after_init', array(
|
||||
vc_settings(),
|
||||
'rebuild',
|
||||
) );
|
||||
update_option( 'vc_version', WPB_VC_VERSION );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current mode for VC.
|
||||
*
|
||||
* @return string
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function mode() {
|
||||
return $this->mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for paths
|
||||
*
|
||||
* @param $paths
|
||||
* @since 4.2
|
||||
* @access protected
|
||||
*
|
||||
*/
|
||||
protected function setPaths( $paths ) {
|
||||
$this->paths = $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets absolute path for file/directory in filesystem.
|
||||
*
|
||||
* @param $name - name of path dir
|
||||
* @param string $file - file name or directory inside path
|
||||
*
|
||||
* @return string
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function path( $name, $file = '' ) {
|
||||
$path = $this->paths[ $name ] . ( strlen( $file ) > 0 ? '/' . preg_replace( '/^\//', '', $file ) : '' );
|
||||
|
||||
return apply_filters( 'vc_path_filter', $path );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default post types. Vc editors are enabled for such kind of posts.
|
||||
*
|
||||
* @param array $type - list of default post types.
|
||||
*/
|
||||
public function setEditorDefaultPostTypes( array $type ) {
|
||||
$this->editor_default_post_types = $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of default post types where user can use WPBakery Page Builder editors.
|
||||
*
|
||||
* @return array
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function editorDefaultPostTypes() {
|
||||
return $this->editor_default_post_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post types where VC editors are enabled.
|
||||
*
|
||||
* @return array
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function editorPostTypes() {
|
||||
if ( is_null( $this->editor_post_types ) ) {
|
||||
$post_types = array_keys( vc_user_access()->part( 'post_types' )->getAllCaps() );
|
||||
$this->editor_post_types = $post_types ? $post_types : $this->editorDefaultPostTypes();
|
||||
}
|
||||
|
||||
return $this->editor_post_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set post types where VC editors are enabled.
|
||||
*
|
||||
* @param array $post_types
|
||||
* @throws \Exception
|
||||
* @since 4.4
|
||||
* @access public
|
||||
*/
|
||||
public function setEditorPostTypes( array $post_types ) {
|
||||
$this->editor_post_types = ! empty( $post_types ) ? $post_types : $this->editorDefaultPostTypes();
|
||||
|
||||
require_once ABSPATH . 'wp-admin/includes/user.php';
|
||||
|
||||
$editable_roles = get_editable_roles();
|
||||
foreach ( $editable_roles as $role => $settings ) {
|
||||
$part = vc_role_access()->who( $role )->part( 'post_types' );
|
||||
$all_post_types = $part->getAllCaps();
|
||||
|
||||
foreach ( $all_post_types as $post_type => $value ) {
|
||||
$part->getRole()->remove_cap( $part->getStateKey() . '/' . $post_type );
|
||||
}
|
||||
$part->setState( 'custom' );
|
||||
|
||||
foreach ( $this->editor_post_types as $post_type ) {
|
||||
$part->setCapRule( $post_type );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for as-theme-plugin status for VC.
|
||||
*
|
||||
* @param bool $value
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function setIsAsTheme( $value = true ) {
|
||||
$this->is_as_theme = (bool) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get as-theme-plugin status
|
||||
*
|
||||
* As theme plugin status used by theme developers. It disables settings
|
||||
*
|
||||
* @return bool
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function isAsTheme() {
|
||||
return (bool) $this->is_as_theme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for as network plugin for MultiWP.
|
||||
*
|
||||
* @param bool $value
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function setAsNetworkPlugin( $value = true ) {
|
||||
$this->is_network_plugin = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets VC is activated as network plugin.
|
||||
*
|
||||
* @return bool
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function isNetworkPlugin() {
|
||||
if ( is_null( $this->is_network_plugin ) ) {
|
||||
// Check is VC as network plugin
|
||||
if ( is_multisite() && ( is_plugin_active_for_network( $this->pluginName() ) || is_network_only_plugin( $this->pluginName() ) ) ) {
|
||||
$this->setAsNetworkPlugin( true );
|
||||
}
|
||||
}
|
||||
|
||||
return $this->is_network_plugin ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for disable updater variable.
|
||||
* @param bool $value
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public function disableUpdater( $value = true ) {
|
||||
$this->disable_updater = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get is vc updater is disabled;
|
||||
*
|
||||
* @return bool
|
||||
* @see to where updater will be
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public function isUpdaterDisabled() {
|
||||
return is_admin() && $this->disable_updater;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user directory name.
|
||||
*
|
||||
* Directory name is the directory name vc should scan for custom shortcodes template.
|
||||
*
|
||||
* @param $dir - path to shortcodes templates inside developers theme
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function setCustomUserShortcodesTemplateDir( $dir ) {
|
||||
preg_replace( '/\/$/', '', $dir );
|
||||
$this->custom_user_templates_dir = $dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default directory where shortcodes templates area placed.
|
||||
*
|
||||
* @return string - path to default shortcodes
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function getDefaultShortcodesTemplatesDir() {
|
||||
return vc_path_dir( 'TEMPLATES_DIR', 'shortcodes' );
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get shortcodes template dir.
|
||||
*
|
||||
* @param $template
|
||||
*
|
||||
* @return string
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function getShortcodesTemplateDir( $template ) {
|
||||
return false !== $this->custom_user_templates_dir ? $this->custom_user_templates_dir . '/' . $template : locate_template( 'vc_templates/' . $template );
|
||||
}
|
||||
|
||||
/**
|
||||
* Directory name where template files will be stored.
|
||||
*
|
||||
* @return string
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function uploadDir() {
|
||||
return 'js_composer';
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for VC_Mapper instance
|
||||
*
|
||||
* @return Vc_Mapper
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function mapper() {
|
||||
if ( ! isset( $this->factory['mapper'] ) ) {
|
||||
require_once $this->path( 'CORE_DIR', 'class-vc-mapper.php' );
|
||||
$this->factory['mapper'] = new Vc_Mapper();
|
||||
}
|
||||
|
||||
return $this->factory['mapper'];
|
||||
}
|
||||
|
||||
/**
|
||||
* WPBakery Page Builder.
|
||||
*
|
||||
* @return Vc_Base
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function vc() {
|
||||
if ( ! isset( $this->factory['vc'] ) ) {
|
||||
do_action( 'vc_before_init_vc' );
|
||||
require_once $this->path( 'CORE_DIR', 'class-vc-base.php' );
|
||||
$vc = new Vc_Base();
|
||||
// DI Set template new modal editor.
|
||||
require_once $this->path( 'EDITORS_DIR', 'popups/class-vc-templates-panel-editor.php' );
|
||||
require_once $this->path( 'CORE_DIR', 'shared-templates/class-vc-shared-templates.php' );
|
||||
$vc->setTemplatesPanelEditor( new Vc_Templates_Panel_Editor() );
|
||||
// Create shared templates
|
||||
$vc->shared_templates = new Vc_Shared_Templates();
|
||||
|
||||
// DI Set edit form
|
||||
require_once $this->path( 'EDITORS_DIR', 'popups/class-vc-shortcode-edit-form.php' );
|
||||
$vc->setEditForm( new Vc_Shortcode_Edit_Form() );
|
||||
|
||||
// DI Set preset new modal editor.
|
||||
require_once $this->path( 'EDITORS_DIR', 'popups/class-vc-preset-panel-editor.php' );
|
||||
$vc->setPresetPanelEditor( new Vc_Preset_Panel_Editor() );
|
||||
|
||||
$this->factory['vc'] = $vc;
|
||||
do_action( 'vc_after_init_vc' );
|
||||
}
|
||||
|
||||
return $this->factory['vc'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Vc options.
|
||||
*
|
||||
* @return Vc_Settings
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function settings() {
|
||||
if ( ! isset( $this->factory['settings'] ) ) {
|
||||
do_action( 'vc_before_init_settings' );
|
||||
require_once $this->path( 'SETTINGS_DIR', 'class-vc-settings.php' );
|
||||
$this->factory['settings'] = new Vc_Settings();
|
||||
do_action( 'vc_after_init_settings' );
|
||||
}
|
||||
|
||||
return $this->factory['settings'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Vc license settings.
|
||||
*
|
||||
* @return Vc_License
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function license() {
|
||||
if ( ! isset( $this->factory['license'] ) ) {
|
||||
do_action( 'vc_before_init_license' );
|
||||
require_once $this->path( 'SETTINGS_DIR', 'class-vc-license.php' );
|
||||
$this->factory['license'] = new Vc_License();
|
||||
do_action( 'vc_after_init_license' );
|
||||
}
|
||||
|
||||
return $this->factory['license'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get frontend VC editor.
|
||||
*
|
||||
* @return Vc_Frontend_Editor
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function frontendEditor() {
|
||||
if ( ! isset( $this->factory['frontend_editor'] ) ) {
|
||||
do_action( 'vc_before_init_frontend_editor' );
|
||||
require_once $this->path( 'EDITORS_DIR', 'class-vc-frontend-editor.php' );
|
||||
$this->factory['frontend_editor'] = new Vc_Frontend_Editor();
|
||||
}
|
||||
|
||||
return $this->factory['frontend_editor'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get backend VC editor. Edit page version.
|
||||
*
|
||||
* @return Vc_Backend_Editor
|
||||
* @since 4.2
|
||||
*
|
||||
*/
|
||||
public function backendEditor() {
|
||||
if ( ! isset( $this->factory['backend_editor'] ) ) {
|
||||
do_action( 'vc_before_init_backend_editor' );
|
||||
require_once $this->path( 'EDITORS_DIR', 'class-vc-backend-editor.php' );
|
||||
$this->factory['backend_editor'] = new Vc_Backend_Editor();
|
||||
}
|
||||
|
||||
return $this->factory['backend_editor'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets automapper instance.
|
||||
*
|
||||
* @return Vc_Automapper
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function automapper() {
|
||||
if ( ! isset( $this->factory['automapper'] ) ) {
|
||||
do_action( 'vc_before_init_automapper' );
|
||||
require_once $this->path( 'SETTINGS_DIR', 'automapper/automapper.php' );
|
||||
require_once $this->path( 'SETTINGS_DIR', 'automapper/class-vc-automap-model.php' );
|
||||
require_once $this->path( 'SETTINGS_DIR', 'automapper/class-vc-automapper.php' );
|
||||
$this->factory['automapper'] = new Vc_Automapper();
|
||||
do_action( 'vc_after_init_automapper' );
|
||||
}
|
||||
|
||||
return $this->factory['automapper'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets updater instance.
|
||||
* @return Vc_Updater
|
||||
* @since 4.2
|
||||
*
|
||||
*/
|
||||
public function updater() {
|
||||
|
||||
if ( ! isset( $this->factory['updater'] ) ) {
|
||||
do_action( 'vc_before_init_updater' );
|
||||
require_once $this->path( 'UPDATERS_DIR', 'class-vc-updater.php' );
|
||||
$updater = new Vc_Updater();
|
||||
require_once vc_path_dir( 'UPDATERS_DIR', 'class-vc-updating-manager.php' );
|
||||
$updater->setUpdateManager( new Vc_Updating_Manager( WPB_VC_VERSION, $updater->versionUrl(), $this->pluginName() ) );
|
||||
$this->factory['updater'] = $updater;
|
||||
do_action( 'vc_after_init_updater' );
|
||||
}
|
||||
|
||||
return $this->factory['updater'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for plugin name variable.
|
||||
* @return string
|
||||
* @since 4.2
|
||||
*
|
||||
*/
|
||||
public function pluginName() {
|
||||
return $this->plugin_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @since 4.8.1
|
||||
*/
|
||||
public function setPluginName( $name ) {
|
||||
$this->plugin_name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get absolute url for VC asset file.
|
||||
*
|
||||
* Assets are css, javascript, less files and images.
|
||||
*
|
||||
* @param $file
|
||||
*
|
||||
* @return string
|
||||
* @since 4.2
|
||||
*
|
||||
*/
|
||||
public function assetUrl( $file ) {
|
||||
return preg_replace( '/\s/', '%20', plugins_url( $this->path( 'ASSETS_DIR_NAME', $file ), WPB_PLUGIN_FILE ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* WPBakery WPBakery Page Builder Main manager.
|
||||
*
|
||||
* @package WPBakeryPageBuilder
|
||||
* @since 4.2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Vc mapper new class. On maintenance
|
||||
* Allows to bind hooks for shortcodes.
|
||||
* @since 4.2
|
||||
*/
|
||||
class Vc_Mapper {
|
||||
/**
|
||||
* @since 4.2
|
||||
* Stores mapping activities list which where called before initialization
|
||||
* @var array
|
||||
*/
|
||||
protected $init_activity = array();
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @since 4.9
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $element_activities = array();
|
||||
|
||||
protected $hasAccess = array();
|
||||
|
||||
protected $checkForAccess = true;
|
||||
|
||||
/**
|
||||
* @since 4.2
|
||||
*/
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Include params list objects and calls all stored activity methods.
|
||||
*
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*/
|
||||
public function init() {
|
||||
do_action( 'vc_mapper_init_before' );
|
||||
require_once vc_path_dir( 'PARAMS_DIR', 'load.php' );
|
||||
WPBMap::setInit();
|
||||
require_once vc_path_dir( 'CONFIG_DIR', 'lean-map.php' );
|
||||
$this->callActivities();
|
||||
do_action( 'vc_mapper_init_after' );
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by VC objects methods if it is called before VC initialization.
|
||||
*
|
||||
* @param $object - mame of class object
|
||||
* @param $method - method name
|
||||
* @param array $params - list of attributes for object method
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
* @see WPBMAP
|
||||
*/
|
||||
public function addActivity( $object, $method, $params = array() ) {
|
||||
$this->init_activity[] = array(
|
||||
$object,
|
||||
$method,
|
||||
$params,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by VC objects methods if it is called before VC initialization.
|
||||
*
|
||||
* @param $tag - shortcode tag of element
|
||||
* @param $method - method name
|
||||
* @param array $params - list of attributes for object method
|
||||
* @since 4.9
|
||||
* @access public
|
||||
*
|
||||
* @see WPBMAP
|
||||
*/
|
||||
public function addElementActivity( $tag, $method, $params = array() ) {
|
||||
if ( ! isset( $this->element_activities[ $tag ] ) ) {
|
||||
$this->element_activities[ $tag ] = array();
|
||||
}
|
||||
$this->element_activities[ $tag ][] = array(
|
||||
$method,
|
||||
$params,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call all stored activities.
|
||||
*
|
||||
* Called by init method. List of activities stored by $init_activity are created by other objects called after
|
||||
* initialization.
|
||||
*
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*/
|
||||
protected function callActivities() {
|
||||
do_action( 'vc_mapper_call_activities_before' );
|
||||
foreach ( $this->init_activity as $activity ) {
|
||||
list( $object, $method, $params ) = $activity;
|
||||
if ( 'mapper' === $object ) {
|
||||
switch ( $method ) {
|
||||
case 'map':
|
||||
$currentScope = WPBMap::getScope();
|
||||
if ( isset( $params['scope'] ) ) {
|
||||
WPBMap::setScope( $params['scope'] );
|
||||
}
|
||||
WPBMap::map( $params['tag'], $params['attributes'] );
|
||||
WPBMap::setScope( $currentScope );
|
||||
break;
|
||||
case 'drop_param':
|
||||
WPBMap::dropParam( $params['name'], $params['attribute_name'] );
|
||||
break;
|
||||
case 'add_param':
|
||||
WPBMap::addParam( $params['name'], $params['attribute'] );
|
||||
break;
|
||||
case 'mutate_param':
|
||||
WPBMap::mutateParam( $params['name'], $params['attribute'] );
|
||||
break;
|
||||
case 'drop_all_shortcodes':
|
||||
WPBMap::dropAllShortcodes();
|
||||
break;
|
||||
case 'drop_shortcode':
|
||||
WPBMap::dropShortcode( $params['name'] );
|
||||
break;
|
||||
case 'modify':
|
||||
WPBMap::modify( $params['name'], $params['setting_name'], $params['value'] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does user has access to modify/clone/delete/add shortcode
|
||||
*
|
||||
* @param $shortcode
|
||||
*
|
||||
* @return bool
|
||||
* @since 4.5
|
||||
* @todo fix_roles and maybe remove/@deprecate this
|
||||
*/
|
||||
public function userHasAccess( $shortcode ) {
|
||||
if ( $this->isCheckForAccess() ) {
|
||||
if ( isset( $this->hasAccess[ $shortcode ] ) ) {
|
||||
return $this->hasAccess[ $shortcode ];
|
||||
} else {
|
||||
$this->hasAccess[ $shortcode ] = vc_user_access_check_shortcode_edit( $shortcode );
|
||||
}
|
||||
|
||||
return $this->hasAccess[ $shortcode ];
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @since 4.5
|
||||
* @todo fix_roles and maybe remove/@deprecate this
|
||||
*/
|
||||
public function isCheckForAccess() {
|
||||
return $this->checkForAccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $checkForAccess
|
||||
* @since 4.5
|
||||
*
|
||||
* @todo fix_roles and maybe remove/@deprecate this
|
||||
*/
|
||||
public function setCheckForAccess( $checkForAccess ) {
|
||||
$this->checkForAccess = $checkForAccess;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tag
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function callElementActivities( $tag ) {
|
||||
do_action( 'vc_mapper_call_activities_before' );
|
||||
if ( isset( $this->element_activities[ $tag ] ) ) {
|
||||
foreach ( $this->element_activities[ $tag ] as $activity ) {
|
||||
list( $method, $params ) = $activity;
|
||||
switch ( $method ) {
|
||||
case 'drop_param':
|
||||
WPBMap::dropParam( $params['name'], $params['attribute_name'] );
|
||||
break;
|
||||
case 'add_param':
|
||||
WPBMap::addParam( $params['name'], $params['attribute'] );
|
||||
break;
|
||||
case 'mutate_param':
|
||||
WPBMap::mutateParam( $params['name'], $params['attribute'] );
|
||||
break;
|
||||
case 'drop_shortcode':
|
||||
WPBMap::dropShortcode( $params['name'] );
|
||||
break;
|
||||
case 'modify':
|
||||
WPBMap::modify( $params['name'], $params['setting_name'], $params['value'] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
class Vc_Modifications {
|
||||
public static $modified = false;
|
||||
|
||||
public function __construct() {
|
||||
add_action( 'wp_footer', array(
|
||||
$this,
|
||||
'renderScript',
|
||||
) );
|
||||
}
|
||||
|
||||
public function renderScript() {
|
||||
if ( self::$modified ) {
|
||||
// output script
|
||||
$tag = 'script';
|
||||
echo '<' . $tag . ' type="text/html" id="wpb-modifications"></' . $tag . '>';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Vc_Page
|
||||
*/
|
||||
class Vc_Page {
|
||||
protected $slug;
|
||||
protected $title;
|
||||
protected $templatePath;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public function getSlug() {
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $slug
|
||||
*
|
||||
* @return $this;
|
||||
*/
|
||||
public function setSlug( $slug ) {
|
||||
$this->slug = (string) $slug;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTitle() {
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setTitle( $title ) {
|
||||
$this->title = (string) $title;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTemplatePath() {
|
||||
return $this->templatePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $templatePath
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setTemplatePath( $templatePath ) {
|
||||
$this->templatePath = $templatePath;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
vc_include_template( $this->getTemplatePath(), array(
|
||||
'page' => $this,
|
||||
) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Vs_Pages_Group Show the groups of the pages likes pages with tabs.
|
||||
*
|
||||
* @since 4.5
|
||||
*/
|
||||
class Vc_Pages_Group extends Vc_Page {
|
||||
protected $activePage;
|
||||
protected $pages;
|
||||
protected $templatePath;
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getActivePage() {
|
||||
return $this->activePage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Vc_Page $activePage
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setActivePage( Vc_Page $activePage ) {
|
||||
$this->activePage = $activePage;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getPages() {
|
||||
return $this->pages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $pages
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPages( $pages ) {
|
||||
$this->pages = $pages;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getTemplatePath() {
|
||||
return $this->templatePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $templatePath
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setTemplatePath( $templatePath ) {
|
||||
$this->templatePath = $templatePath;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render html output for current page.
|
||||
*/
|
||||
public function render() {
|
||||
vc_include_template( $this->getTemplatePath(), array(
|
||||
'pages' => $this->getPages(),
|
||||
'active_page' => $this->activePage,
|
||||
'page' => $this,
|
||||
) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Ability to interact with post data.
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
class Vc_Post_Admin {
|
||||
/**
|
||||
* Add hooks required to save, update and manipulate post
|
||||
*/
|
||||
public function init() {
|
||||
// Called in BE
|
||||
add_action( 'save_post', array(
|
||||
$this,
|
||||
'save',
|
||||
) );
|
||||
|
||||
// Called in FE
|
||||
add_action( 'wp_ajax_vc_save', array(
|
||||
$this,
|
||||
'saveAjaxFe',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function saveAjaxFe() {
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'edit_posts', 'edit_pages' )->validateDie();
|
||||
|
||||
$post_id = intval( vc_post_param( 'post_id' ) );
|
||||
if ( $post_id > 0 ) {
|
||||
ob_start();
|
||||
|
||||
// Update post_content, title and etc.
|
||||
// post_title
|
||||
// content
|
||||
// post_status
|
||||
if ( vc_post_param( 'content' ) ) {
|
||||
$post = get_post( $post_id );
|
||||
$post->post_content = stripslashes( vc_post_param( 'content' ) );
|
||||
$post_status = vc_post_param( 'post_status' );
|
||||
$post_title = vc_post_param( 'post_title' );
|
||||
if ( null !== $post_title ) {
|
||||
$post->post_title = $post_title;
|
||||
}
|
||||
kses_remove_filters();
|
||||
remove_filter( 'content_save_pre', 'balanceTags', 50 );
|
||||
if ( $post_status && 'publish' === $post_status ) {
|
||||
if ( vc_user_access()->wpAll( array(
|
||||
get_post_type_object( $post->post_type )->cap->publish_posts,
|
||||
$post_id,
|
||||
) )->get() ) {
|
||||
if ( 'private' !== $post->post_status && 'future' !== $post->post_status ) {
|
||||
$post->post_status = 'publish';
|
||||
}
|
||||
} else {
|
||||
$post->post_status = 'pending';
|
||||
}
|
||||
}
|
||||
|
||||
wp_update_post( $post );
|
||||
$this->setPostMeta( $post_id );
|
||||
}
|
||||
|
||||
visual_composer()->buildShortcodesCustomCss( $post_id );
|
||||
wp_cache_flush();
|
||||
ob_clean();
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
wp_send_json_error();
|
||||
}/** @noinspection PhpDocMissingThrowsInspection */
|
||||
|
||||
/**
|
||||
* Save generated shortcodes, html and WPBakery Page Builder status in posts meta.
|
||||
*
|
||||
* @access public
|
||||
* @param $post_id - current post id
|
||||
*
|
||||
* @return void
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function save( $post_id ) {
|
||||
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE || vc_is_inline() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->setPostMeta( $post_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves VC Backend editor meta box visibility status.
|
||||
*
|
||||
* If post param 'wpb_vc_js_status' set to true, then methods adds/updated post
|
||||
* meta option with tag '_wpb_vc_js_status'.
|
||||
* @param $post_id
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function setJsStatus( $post_id ) {
|
||||
$value = vc_post_param( 'wpb_vc_js_status' );
|
||||
if ( null !== $value ) {
|
||||
if ( '' === get_post_meta( $post_id, '_wpb_vc_js_status' ) ) {
|
||||
add_post_meta( $post_id, '_wpb_vc_js_status', $value, true );
|
||||
} elseif ( get_post_meta( $post_id, '_wpb_vc_js_status', true ) !== $value ) {
|
||||
update_post_meta( $post_id, '_wpb_vc_js_status', $value );
|
||||
} elseif ( '' === $value ) {
|
||||
delete_post_meta( $post_id, '_wpb_vc_js_status', get_post_meta( $post_id, '_wpb_vc_js_status', true ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves VC interface version which is used for building post content.
|
||||
* @param $post_id
|
||||
* @since 4.4
|
||||
* @todo check is it used everywhere and is it needed?!
|
||||
* @deprecated not needed anywhere
|
||||
*/
|
||||
public function setInterfaceVersion( $post_id ) {
|
||||
_deprecated_function( '\Vc_Post_Admin::setInterfaceVersion', '4.4', '' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Post Settings for VC.
|
||||
*
|
||||
* It is possible to add any data to post settings by adding filter with tag 'vc_hooks_vc_post_settings'.
|
||||
* @param $post_id
|
||||
* @since 4.4
|
||||
* vc_filter: vc_hooks_vc_post_settings - hook to override post meta settings for WPBakery Page Builder (used in grid for
|
||||
* example)
|
||||
*
|
||||
*/
|
||||
public function setSettings( $post_id ) {
|
||||
$settings = array();
|
||||
$settings = apply_filters( 'vc_hooks_vc_post_settings', $settings, $post_id, get_post( $post_id ) );
|
||||
if ( is_array( $settings ) && ! empty( $settings ) ) {
|
||||
update_post_meta( $post_id, '_vc_post_settings', $settings );
|
||||
} else {
|
||||
delete_post_meta( $post_id, '_vc_post_settings' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $post_id
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function setPostMeta( $post_id ) {
|
||||
if ( ! vc_user_access()->wpAny( array(
|
||||
'edit_post',
|
||||
$post_id,
|
||||
) )->get() ) {
|
||||
return;
|
||||
}
|
||||
$this->setJsStatus( $post_id );
|
||||
if ( 'dopreview' !== vc_post_param( 'wp-preview' ) ) {
|
||||
$this->setSettings( $post_id );
|
||||
}
|
||||
/**
|
||||
* vc_filter: vc_base_save_post_custom_css
|
||||
* @since 4.4
|
||||
*/
|
||||
$post_custom_css = apply_filters( 'vc_base_save_post_custom_css', vc_post_param( 'vc_post_custom_css' ), $post_id );
|
||||
if ( null !== $post_custom_css && empty( $post_custom_css ) ) {
|
||||
delete_metadata( 'post', $post_id, '_wpb_post_custom_css' );
|
||||
} elseif ( null !== $post_custom_css ) {
|
||||
$post_custom_css = wp_strip_all_tags( $post_custom_css );
|
||||
update_metadata( 'post', $post_id, '_wpb_post_custom_css', $post_custom_css );
|
||||
}
|
||||
visual_composer()->buildShortcodesCustomCss( $post_id );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/*** WPBakery Page Builder Content elements refresh ***/
|
||||
class VcSharedLibrary {
|
||||
// Here we will store plugin wise (shared) settings. Colors, Locations, Sizes, etc...
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $colors = array(
|
||||
'Blue' => 'blue',
|
||||
'Turquoise' => 'turquoise',
|
||||
'Pink' => 'pink',
|
||||
'Violet' => 'violet',
|
||||
'Peacoc' => 'peacoc',
|
||||
'Chino' => 'chino',
|
||||
'Mulled Wine' => 'mulled_wine',
|
||||
'Vista Blue' => 'vista_blue',
|
||||
'Black' => 'black',
|
||||
'Grey' => 'grey',
|
||||
'Orange' => 'orange',
|
||||
'Sky' => 'sky',
|
||||
'Green' => 'green',
|
||||
'Juicy pink' => 'juicy_pink',
|
||||
'Sandy brown' => 'sandy_brown',
|
||||
'Purple' => 'purple',
|
||||
'White' => 'white',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $icons = array(
|
||||
'Glass' => 'glass',
|
||||
'Music' => 'music',
|
||||
'Search' => 'search',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $sizes = array(
|
||||
'Mini' => 'xs',
|
||||
'Small' => 'sm',
|
||||
'Normal' => 'md',
|
||||
'Large' => 'lg',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $button_styles = array(
|
||||
'Rounded' => 'rounded',
|
||||
'Square' => 'square',
|
||||
'Round' => 'round',
|
||||
'Outlined' => 'outlined',
|
||||
'3D' => '3d',
|
||||
'Square Outlined' => 'square_outlined',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $message_box_styles = array(
|
||||
'Standard' => 'standard',
|
||||
'Solid' => 'solid',
|
||||
'Solid icon' => 'solid-icon',
|
||||
'Outline' => 'outline',
|
||||
'3D' => '3d',
|
||||
);
|
||||
|
||||
/**
|
||||
* Toggle styles
|
||||
* @var array
|
||||
*/
|
||||
public static $toggle_styles = array(
|
||||
'Default' => 'default',
|
||||
'Simple' => 'simple',
|
||||
'Round' => 'round',
|
||||
'Round Outline' => 'round_outline',
|
||||
'Rounded' => 'rounded',
|
||||
'Rounded Outline' => 'rounded_outline',
|
||||
'Square' => 'square',
|
||||
'Square Outline' => 'square_outline',
|
||||
'Arrow' => 'arrow',
|
||||
'Text Only' => 'text_only',
|
||||
);
|
||||
|
||||
/**
|
||||
* Animation styles
|
||||
* @var array
|
||||
*/
|
||||
public static $animation_styles = array(
|
||||
'Bounce' => 'easeOutBounce',
|
||||
'Elastic' => 'easeOutElastic',
|
||||
'Back' => 'easeOutBack',
|
||||
'Cubic' => 'easeInOutCubic',
|
||||
'Quint' => 'easeInOutQuint',
|
||||
'Quart' => 'easeOutQuart',
|
||||
'Quad' => 'easeInQuad',
|
||||
'Sine' => 'easeOutSine',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $cta_styles = array(
|
||||
'Rounded' => 'rounded',
|
||||
'Square' => 'square',
|
||||
'Round' => 'round',
|
||||
'Outlined' => 'outlined',
|
||||
'Square Outlined' => 'square_outlined',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $txt_align = array(
|
||||
'Left' => 'left',
|
||||
'Right' => 'right',
|
||||
'Center' => 'center',
|
||||
'Justify' => 'justify',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $el_widths = array(
|
||||
'100%' => '',
|
||||
'90%' => '90',
|
||||
'80%' => '80',
|
||||
'70%' => '70',
|
||||
'60%' => '60',
|
||||
'50%' => '50',
|
||||
'40%' => '40',
|
||||
'30%' => '30',
|
||||
'20%' => '20',
|
||||
'10%' => '10',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $sep_widths = array(
|
||||
'1px' => '',
|
||||
'2px' => '2',
|
||||
'3px' => '3',
|
||||
'4px' => '4',
|
||||
'5px' => '5',
|
||||
'6px' => '6',
|
||||
'7px' => '7',
|
||||
'8px' => '8',
|
||||
'9px' => '9',
|
||||
'10px' => '10',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $sep_styles = array(
|
||||
'Border' => '',
|
||||
'Dashed' => 'dashed',
|
||||
'Dotted' => 'dotted',
|
||||
'Double' => 'double',
|
||||
'Shadow' => 'shadow',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $box_styles = array(
|
||||
'Default' => '',
|
||||
'Rounded' => 'vc_box_rounded',
|
||||
'Border' => 'vc_box_border',
|
||||
'Outline' => 'vc_box_outline',
|
||||
'Shadow' => 'vc_box_shadow',
|
||||
'Bordered shadow' => 'vc_box_shadow_border',
|
||||
'3D Shadow' => 'vc_box_shadow_3d',
|
||||
);
|
||||
|
||||
/**
|
||||
* Round box styles
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $round_box_styles = array(
|
||||
'Round' => 'vc_box_circle',
|
||||
'Round Border' => 'vc_box_border_circle',
|
||||
'Round Outline' => 'vc_box_outline_circle',
|
||||
'Round Shadow' => 'vc_box_shadow_circle',
|
||||
'Round Border Shadow' => 'vc_box_shadow_border_circle',
|
||||
);
|
||||
|
||||
/**
|
||||
* Circle box styles
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $circle_box_styles = array(
|
||||
'Circle' => 'vc_box_circle_2',
|
||||
'Circle Border' => 'vc_box_border_circle_2',
|
||||
'Circle Outline' => 'vc_box_outline_circle_2',
|
||||
'Circle Shadow' => 'vc_box_shadow_circle_2',
|
||||
'Circle Border Shadow' => 'vc_box_shadow_border_circle_2',
|
||||
);
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getColors() {
|
||||
return self::$colors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getIcons() {
|
||||
return self::$icons;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getSizes() {
|
||||
return self::$sizes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getButtonStyles() {
|
||||
return self::$button_styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getMessageBoxStyles() {
|
||||
return self::$message_box_styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getToggleStyles() {
|
||||
return self::$toggle_styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getAnimationStyles() {
|
||||
return self::$animation_styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getCtaStyles() {
|
||||
return self::$cta_styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getTextAlign() {
|
||||
return self::$txt_align;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getBorderWidths() {
|
||||
return self::$sep_widths;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getElementWidths() {
|
||||
return self::$el_widths;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getSeparatorStyles() {
|
||||
return self::$sep_styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of box styles
|
||||
*
|
||||
* Possible $groups values:
|
||||
* - default
|
||||
* - round
|
||||
* - circle
|
||||
*
|
||||
* @param array $groups Array of groups to include. If not specified, return all
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getBoxStyles( $groups = array() ) {
|
||||
$list = array();
|
||||
$groups = (array) $groups;
|
||||
|
||||
if ( ! $groups || in_array( 'default', $groups, true ) ) {
|
||||
$list += self::$box_styles;
|
||||
}
|
||||
|
||||
if ( ! $groups || in_array( 'round', $groups, true ) ) {
|
||||
$list += self::$round_box_styles;
|
||||
}
|
||||
|
||||
if ( ! $groups || in_array( 'cirlce', $groups, true ) ) {
|
||||
$list += self::$circle_box_styles;
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getColorsDashed() {
|
||||
$colors = array(
|
||||
esc_html__( 'Blue', 'js_composer' ) => 'blue',
|
||||
esc_html__( 'Turquoise', 'js_composer' ) => 'turquoise',
|
||||
esc_html__( 'Pink', 'js_composer' ) => 'pink',
|
||||
esc_html__( 'Violet', 'js_composer' ) => 'violet',
|
||||
esc_html__( 'Peacoc', 'js_composer' ) => 'peacoc',
|
||||
esc_html__( 'Chino', 'js_composer' ) => 'chino',
|
||||
esc_html__( 'Mulled Wine', 'js_composer' ) => 'mulled-wine',
|
||||
esc_html__( 'Vista Blue', 'js_composer' ) => 'vista-blue',
|
||||
esc_html__( 'Black', 'js_composer' ) => 'black',
|
||||
esc_html__( 'Grey', 'js_composer' ) => 'grey',
|
||||
esc_html__( 'Orange', 'js_composer' ) => 'orange',
|
||||
esc_html__( 'Sky', 'js_composer' ) => 'sky',
|
||||
esc_html__( 'Green', 'js_composer' ) => 'green',
|
||||
esc_html__( 'Juicy pink', 'js_composer' ) => 'juicy-pink',
|
||||
esc_html__( 'Sandy brown', 'js_composer' ) => 'sandy-brown',
|
||||
esc_html__( 'Purple', 'js_composer' ) => 'purple',
|
||||
esc_html__( 'White', 'js_composer' ) => 'white',
|
||||
);
|
||||
|
||||
return $colors;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort array values by key, default key is 'weight'
|
||||
* Used in uasort() function.
|
||||
* For fix equal weight problem used $this->data array_search
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Vc_Sort
|
||||
* @since 4.4
|
||||
*/
|
||||
class Vc_Sort {
|
||||
/**
|
||||
* @since 4.4
|
||||
* @var array $data - sorting data
|
||||
*/
|
||||
protected $data = array();
|
||||
/**
|
||||
* @since 4.4
|
||||
* @var string $key - key for search
|
||||
*/
|
||||
protected $key = 'weight';
|
||||
|
||||
/**
|
||||
* @param $data - array to sort
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function __construct( $data ) {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to change/set data to sort
|
||||
*
|
||||
* @param $data
|
||||
* @since 4.5
|
||||
*
|
||||
*/
|
||||
public function setData( $data ) {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort $this->data by user key, used in class-vc-mapper.
|
||||
* If keys are equals it SAVES a position in array (index).
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return array - sorted array
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function sortByKey( $key = 'weight' ) {
|
||||
$this->key = $key;
|
||||
uasort( $this->data, array(
|
||||
$this,
|
||||
'key',
|
||||
) );
|
||||
|
||||
return array_merge( $this->data ); // reset array keys to 0..N
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorting by key callable for usort function
|
||||
* @param $a - compare value
|
||||
* @param $b - compare value
|
||||
*
|
||||
* @return int
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
private function key( $a, $b ) {
|
||||
$a_weight = isset( $a[ $this->key ] ) ? (int) $a[ $this->key ] : 0;
|
||||
$b_weight = isset( $b[ $this->key ] ) ? (int) $b[ $this->key ] : 0;
|
||||
// To save real-ordering
|
||||
if ( $a_weight === $b_weight ) {
|
||||
// @codingStandardsIgnoreLine
|
||||
$cmp_a = array_search( $a, $this->data );
|
||||
// @codingStandardsIgnoreLine
|
||||
$cmp_b = array_search( $b, $this->data );
|
||||
|
||||
return $cmp_a - $cmp_b;
|
||||
}
|
||||
|
||||
return $b_weight - $a_weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array - sorting data
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function getData() {
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,974 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* WPBakery WPBakery Page Builder Main manager.
|
||||
*
|
||||
* @package WPBakeryPageBuilder
|
||||
* @since 4.2
|
||||
*/
|
||||
class WPBMap {
|
||||
protected static $scope = 'default';
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $sc = array();
|
||||
protected static $scopes = array(
|
||||
'default' => array(),
|
||||
);
|
||||
protected static $removedElements = array();
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected static $sorted_sc = false;
|
||||
|
||||
/**
|
||||
* @var array|false
|
||||
*/
|
||||
protected static $categories = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected static $user_sc = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected static $user_sorted_sc = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected static $user_categories = false;
|
||||
|
||||
/**
|
||||
* @var Vc_Settings $settings
|
||||
*/
|
||||
protected static $settings;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected static $user_role;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected static $tags_regexp;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected static $is_init = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected static $init_elements = array();
|
||||
protected static $init_elements_scoped = array(
|
||||
'default' => array(),
|
||||
);
|
||||
|
||||
/**
|
||||
* Set init status fro WPMap.
|
||||
*
|
||||
* if $is_init is FALSE, then all activity like add, update and delete for shortcodes attributes will be hold in
|
||||
* the list of activity and will be executed after initialization.
|
||||
*
|
||||
* @param bool $value
|
||||
* @see Vc_Mapper::iniy.
|
||||
* @static
|
||||
*
|
||||
*/
|
||||
public static function setInit( $value = true ) {
|
||||
self::$is_init = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets user role and access rules for current user.
|
||||
*
|
||||
* @static
|
||||
* @return mixed
|
||||
*/
|
||||
protected static function getSettings() {
|
||||
global $current_user;
|
||||
|
||||
// @todo fix_roles? what is this and why it is inside class-wpb-map?
|
||||
if ( null !== self::$settings ) {
|
||||
if ( function_exists( 'wp_get_current_user' ) ) {
|
||||
wp_get_current_user();
|
||||
/** @var Vc_Settings $settings - get use group access rules */
|
||||
if ( ! empty( $current_user->roles ) ) {
|
||||
self::$user_role = $current_user->roles[0];
|
||||
} else {
|
||||
self::$user_role = 'author';
|
||||
}
|
||||
} else {
|
||||
self::$user_role = 'author';
|
||||
}
|
||||
self::$settings = vc_settings()->get( 'groups_access_rules' );
|
||||
}
|
||||
|
||||
return self::$settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is shortcode with a tag mapped to VC.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @param $tag - shortcode tag.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function exists( $tag ) {
|
||||
$currentScope = self::getScope();
|
||||
if ( 'default' !== $currentScope ) {
|
||||
if ( isset( self::$scopes[ $currentScope ], self::$scopes[ $currentScope ][ $tag ] ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return (bool) isset( self::$sc[ $tag ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Map shortcode to VC.
|
||||
*
|
||||
* This method maps shortcode to VC.
|
||||
* You need to shortcode's tag and settings to map correctly.
|
||||
* Default shortcodes are mapped in config/map.php file.
|
||||
* The best way is to call this method with "init" action callback function of WP.
|
||||
*
|
||||
* vc_filter: vc_mapper_tag - to change shortcode tag, arguments 2 ( $tag, $attributes )
|
||||
* vc_filter: vc_mapper_attributes - to change shortcode attributes (like params array), arguments 2 ( $attributes,
|
||||
* $tag ) vc_filter: vc_mapper_attribute - to change singe shortcode param data, arguments 2 ( $attribute, $tag )
|
||||
* vc_filter: vc_mapper_attribute_{PARAM_TYPE} - to change singe shortcode param data by param type, arguments 2 (
|
||||
* $attribute, $tag )
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @param $tag
|
||||
* @param $attributes
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function map( $tag, $attributes ) {
|
||||
if ( in_array( $tag, self::$removedElements, true ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( ! self::$is_init ) {
|
||||
if ( empty( $attributes['name'] ) ) {
|
||||
throw new Exception( sprintf( esc_html__( 'Wrong name for shortcode:%s. Name required', 'js_composer' ), $tag ) );
|
||||
} elseif ( empty( $attributes['base'] ) ) {
|
||||
throw new Exception( sprintf( esc_html__( 'Wrong base for shortcode:%s. Base required', 'js_composer' ), $tag ) );
|
||||
} else {
|
||||
vc_mapper()->addActivity( 'mapper', 'map', array(
|
||||
'tag' => $tag,
|
||||
'attributes' => $attributes,
|
||||
'scope' => self::getScope(),
|
||||
) );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
if ( empty( $attributes['name'] ) ) {
|
||||
throw new Exception( sprintf( esc_html__( 'Wrong name for shortcode:%s. Name required', 'js_composer' ), $tag ) );
|
||||
} elseif ( empty( $attributes['base'] ) ) {
|
||||
throw new Exception( sprintf( esc_html__( 'Wrong base for shortcode:%s. Base required', 'js_composer' ), $tag ) );
|
||||
} else {
|
||||
if ( self::getScope() !== 'default' ) {
|
||||
if ( ! isset( self::$scopes[ self::getScope() ] ) ) {
|
||||
self::$scopes[ self::getScope() ] = array();
|
||||
}
|
||||
self::$scopes[ self::getScope() ][ $tag ] = $attributes;
|
||||
} else {
|
||||
self::$sc[ $tag ] = $attributes;
|
||||
}
|
||||
// Unset cache class object in case if re-map called
|
||||
if ( Vc_Shortcodes_Manager::getInstance()->isShortcodeClassInitialized( $tag ) ) {
|
||||
Vc_Shortcodes_Manager::getInstance()->unsetElementClass( $tag );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy method to map shortcode to VC.
|
||||
*
|
||||
* This method maps shortcode to VC.
|
||||
* You can shortcode settings as you do in self::map method. Bu also you
|
||||
* can pass function name or file, which will be used to add settings for
|
||||
* element. But this will be done only when element data is really required.
|
||||
*
|
||||
* @static
|
||||
* @param $tag
|
||||
* @param $settings_file
|
||||
* @param $settings_function
|
||||
* @param $attributes
|
||||
*
|
||||
* @return bool
|
||||
* @since 4.9
|
||||
*
|
||||
*/
|
||||
public static function leanMap( $tag, $settings_function = null, $settings_file = null, $attributes = array() ) {
|
||||
if ( in_array( $tag, self::$removedElements, true ) ) {
|
||||
return false;
|
||||
}
|
||||
$currentScope = self::getScope();
|
||||
if ( 'default' !== $currentScope ) {
|
||||
if ( ! isset( self::$scopes[ $currentScope ] ) ) {
|
||||
self::$scopes[ $currentScope ] = array();
|
||||
}
|
||||
self::$scopes[ $currentScope ][ $tag ] = $attributes;
|
||||
self::$scopes[ $currentScope ][ $tag ]['base'] = $tag;
|
||||
if ( is_string( $settings_file ) ) {
|
||||
self::$scopes[ $currentScope ][ $tag ]['__vc_settings_file'] = $settings_file;
|
||||
}
|
||||
if ( ! is_null( $settings_function ) ) {
|
||||
self::$scopes[ $currentScope ][ $tag ]['__vc_settings_function'] = $settings_function;
|
||||
}
|
||||
} else {
|
||||
self::$sc[ $tag ] = $attributes;
|
||||
self::$sc[ $tag ]['base'] = $tag;
|
||||
if ( is_string( $settings_file ) ) {
|
||||
self::$sc[ $tag ]['__vc_settings_file'] = $settings_file;
|
||||
}
|
||||
if ( ! is_null( $settings_function ) ) {
|
||||
self::$sc[ $tag ]['__vc_settings_function'] = $settings_function;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates list of shortcodes taking into account the access rules for shortcodes from VC Settings page.
|
||||
*
|
||||
* This method parses the list of mapped shortcodes and creates categories list for users.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @param bool $force - force data generation even data already generated.
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected static function generateUserData( $force = false ) {
|
||||
if ( ! $force && false !== self::$user_sc && false !== self::$user_categories ) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::$user_sc = array();
|
||||
self::$user_categories = array();
|
||||
self::$user_sorted_sc = array();
|
||||
$deprecated = 'deprecated';
|
||||
$add_deprecated = false;
|
||||
if ( is_array( self::$sc ) && ! empty( self::$sc ) ) {
|
||||
foreach ( array_keys( self::$sc ) as $name ) {
|
||||
self::setElementSettings( $name );
|
||||
if ( ! isset( self::$sc[ $name ] ) ) {
|
||||
continue;
|
||||
}
|
||||
$values = self::$sc[ $name ];
|
||||
if ( vc_user_access_check_shortcode_all( $name ) ) {
|
||||
if ( ! isset( $values['content_element'] ) || true === $values['content_element'] ) {
|
||||
$categories = isset( $values['category'] ) ? $values['category'] : '_other_category_';
|
||||
$values['_category_ids'] = array();
|
||||
if ( isset( $values['deprecated'] ) && false !== $values['deprecated'] ) {
|
||||
$add_deprecated = true;
|
||||
$values['_category_ids'][] = 'deprecated';
|
||||
} else {
|
||||
if ( is_array( $categories ) && ! empty( $categories ) ) {
|
||||
foreach ( $categories as $c ) {
|
||||
if ( false === array_search( $c, self::$user_categories, true ) ) {
|
||||
self::$user_categories[] = $c;
|
||||
}
|
||||
$values['_category_ids'][] = md5( $c );
|
||||
}
|
||||
} else {
|
||||
if ( false === array_search( $categories, self::$user_categories, true ) ) {
|
||||
self::$user_categories[] = $categories;
|
||||
}
|
||||
$values['_category_ids'][] = md5( $categories );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $values['params'] ) ) {
|
||||
$params = $values['params'];
|
||||
$values['params'] = array();
|
||||
foreach ( $params as $attribute ) {
|
||||
$attribute = apply_filters( 'vc_mapper_attribute', $attribute, $name );
|
||||
$attribute = apply_filters( 'vc_mapper_attribute_' . $attribute['type'], $attribute, $name );
|
||||
$values['params'][] = $attribute;
|
||||
}
|
||||
$sort = new Vc_Sort( $values['params'] );
|
||||
$values['params'] = $sort->sortByKey();
|
||||
}
|
||||
|
||||
self::$user_sc[ $name ] = $values;
|
||||
self::$user_sorted_sc[] = $values;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $add_deprecated ) {
|
||||
self::$user_categories[] = $deprecated;
|
||||
}
|
||||
|
||||
$sort = new Vc_Sort( self::$user_sorted_sc );
|
||||
self::$user_sorted_sc = $sort->sortByKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates list of shortcodes.
|
||||
*
|
||||
* This method parses the list of mapped shortcodes and creates categories list.
|
||||
*
|
||||
* @static_other_category_
|
||||
*
|
||||
* @param bool $force - force data generation even data already generated.
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected static function generateData( $force = false ) {
|
||||
if ( ! $force && false !== self::$categories ) {
|
||||
return;
|
||||
}
|
||||
foreach ( self::$sc as $tag => $settings ) {
|
||||
self::setElementSettings( $tag );
|
||||
}
|
||||
self::$categories = self::collectCategories( self::$sc );
|
||||
$sort = new Vc_Sort( array_values( self::$sc ) );
|
||||
self::$sorted_sc = $sort->sortByKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mapped shortcode settings.
|
||||
*
|
||||
* @static
|
||||
* @return array
|
||||
*/
|
||||
public static function getShortCodes() {
|
||||
return self::$sc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mapped shortcode settings.
|
||||
*
|
||||
* @static
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getAllShortCodes() {
|
||||
self::generateData();
|
||||
|
||||
return self::$sc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mapped shortcode settings.
|
||||
*
|
||||
* @static
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getSortedAllShortCodes() {
|
||||
self::generateData();
|
||||
|
||||
return self::$sorted_sc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sorted list of mapped shortcode settings for current user.
|
||||
*
|
||||
* Sorting depends on the weight attribute and mapping order.
|
||||
*
|
||||
* @static
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getSortedUserShortCodes() {
|
||||
self::generateUserData();
|
||||
|
||||
return self::$user_sorted_sc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of mapped shortcode settings for current user.
|
||||
* @static
|
||||
* @return bool - associated array of shortcodes settings with tag as the key.
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getUserShortCodes() {
|
||||
self::generateUserData();
|
||||
|
||||
return self::$user_sc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mapped shortcode settings by tag.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @param $tag - shortcode tag.
|
||||
*
|
||||
* @return array|null null @since 4.4.3
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getShortCode( $tag ) {
|
||||
return self::setElementSettings( $tag );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mapped shortcode settings by tag.
|
||||
*
|
||||
* @param $tag - shortcode tag.
|
||||
*
|
||||
* @return array|null
|
||||
* @throws \Exception
|
||||
* @since 4.5.2
|
||||
* @static
|
||||
*/
|
||||
public static function getUserShortCode( $tag ) {
|
||||
self::generateUserData();
|
||||
if ( isset( self::$user_sc[ $tag ] ) && is_array( self::$user_sc[ $tag ] ) ) {
|
||||
$shortcode = self::$user_sc[ $tag ];
|
||||
if ( ! empty( $shortcode['params'] ) ) {
|
||||
$params = $shortcode['params'];
|
||||
$shortcode['params'] = array();
|
||||
foreach ( $params as $attribute ) {
|
||||
$attribute = apply_filters( 'vc_mapper_attribute', $attribute, $tag );
|
||||
$attribute = apply_filters( 'vc_mapper_attribute_' . $attribute['type'], $attribute, $tag );
|
||||
$shortcode['params'][] = $attribute;
|
||||
}
|
||||
$sort = new Vc_Sort( $shortcode['params'] );
|
||||
$shortcode['params'] = $sort->sortByKey();
|
||||
}
|
||||
|
||||
return $shortcode;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all categories for mapped shortcodes.
|
||||
*
|
||||
* @static
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getCategories() {
|
||||
self::generateData();
|
||||
|
||||
return self::$categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all categories for current user.
|
||||
*
|
||||
* Category is added to the list when at least one shortcode of this category is allowed for current user
|
||||
* by Vc access rules.
|
||||
*
|
||||
* @static
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getUserCategories() {
|
||||
self::generateUserData();
|
||||
|
||||
return self::$user_categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop shortcode param.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @param $name
|
||||
* @param $attribute_name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function dropParam( $name, $attribute_name ) {
|
||||
$currentScope = self::getScope();
|
||||
if ( 'default' !== $currentScope ) {
|
||||
self::setScope( 'default' );
|
||||
$res = self::dropParam( $name, $attribute_name );
|
||||
self::setScope( $currentScope );
|
||||
|
||||
return $res;
|
||||
}
|
||||
if ( ! isset( self::$init_elements[ $name ] ) ) {
|
||||
vc_mapper()->addElementActivity( $name, 'drop_param', array(
|
||||
'name' => $name,
|
||||
'attribute_name' => $attribute_name,
|
||||
) );
|
||||
|
||||
return true;
|
||||
}
|
||||
if ( isset( self::$sc[ $name ], self::$sc[ $name ]['params'] ) && is_array( self::$sc[ $name ]['params'] ) ) {
|
||||
foreach ( self::$sc[ $name ]['params'] as $index => $param ) {
|
||||
if ( $param['param_name'] === $attribute_name ) {
|
||||
unset( self::$sc[ $name ]['params'][ $index ] );
|
||||
// fix indexes
|
||||
self::$sc[ $name ]['params'] = array_merge( self::$sc[ $name ]['params'] );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns param settings for mapped shortcodes.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @param $tag
|
||||
* @param $param_name
|
||||
*
|
||||
* @return bool| array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function getParam( $tag, $param_name ) {
|
||||
$currentScope = self::getScope();
|
||||
$element = false;
|
||||
if ( 'default' !== $currentScope ) {
|
||||
if ( isset( self::$scopes[ $currentScope ][ $tag ], self::$scopes[ $currentScope ][ $tag ] ) ) {
|
||||
$element = self::$scopes[ $currentScope ][ $tag ];
|
||||
}
|
||||
}
|
||||
if ( ! $element && isset( self::$sc[ $tag ] ) ) {
|
||||
$element = self::$sc[ $tag ];
|
||||
}
|
||||
if ( ! $element ) {
|
||||
// No element found
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( isset( $element['__vc_settings_function'] ) || isset( $element['__vc_settings_file'] ) ) {
|
||||
$element = self::setElementSettings( $tag );
|
||||
}
|
||||
|
||||
if ( ! isset( $element['params'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ( $element['params'] as $index => $param ) {
|
||||
if ( $param['param_name'] === $param_name ) {
|
||||
return $element['params'][ $index ];
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new param to shortcode params list.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @param $name
|
||||
* @param array $attribute
|
||||
*
|
||||
* @return bool - true if added, false if scheduled/rejected
|
||||
*/
|
||||
public static function addParam( $name, $attribute = array() ) {
|
||||
$currentScope = self::getScope();
|
||||
if ( 'default' !== $currentScope ) {
|
||||
self::setScope( 'default' );
|
||||
$res = self::addParam( $name, $attribute );
|
||||
self::setScope( $currentScope );
|
||||
|
||||
return $res;
|
||||
}
|
||||
if ( ! isset( self::$init_elements[ $name ] ) ) {
|
||||
vc_mapper()->addElementActivity( $name, 'add_param', array(
|
||||
'name' => $name,
|
||||
'attribute' => $attribute,
|
||||
) );
|
||||
|
||||
return false;
|
||||
}
|
||||
if ( ! isset( self::$sc[ $name ] ) ) {
|
||||
// No shortcode found
|
||||
return false;
|
||||
} elseif ( ! isset( $attribute['param_name'] ) ) {
|
||||
throw new Exception( sprintf( esc_html__( "Wrong attribute for '%s' shortcode. Attribute 'param_name' required", 'js_composer' ), $name ) );
|
||||
} else {
|
||||
|
||||
$replaced = false;
|
||||
|
||||
if ( is_array( self::$sc[ $name ]['params'] ) ) {
|
||||
foreach ( self::$sc[ $name ]['params'] as $index => $param ) {
|
||||
if ( $param['param_name'] === $attribute['param_name'] ) {
|
||||
$replaced = true;
|
||||
self::$sc[ $name ]['params'][ $index ] = $attribute;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self::$sc[ $name ]['params'] = array();
|
||||
}
|
||||
if ( false === $replaced ) {
|
||||
self::$sc[ $name ]['params'][] = $attribute;
|
||||
}
|
||||
|
||||
$sort = new Vc_Sort( self::$sc[ $name ]['params'] );
|
||||
self::$sc[ $name ]['params'] = $sort->sortByKey();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change param attributes of mapped shortcode.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @param $name
|
||||
* @param array $attribute
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function mutateParam( $name, $attribute = array() ) {
|
||||
$currentScope = self::getScope();
|
||||
if ( 'default' !== $currentScope ) {
|
||||
self::setScope( 'default' );
|
||||
$res = self::mutateParam( $name, $attribute );
|
||||
self::setScope( $currentScope );
|
||||
|
||||
return $res;
|
||||
}
|
||||
if ( ! isset( self::$init_elements[ $name ] ) ) {
|
||||
vc_mapper()->addElementActivity( $name, 'mutate_param', array(
|
||||
'name' => $name,
|
||||
'attribute' => $attribute,
|
||||
) );
|
||||
|
||||
return false;
|
||||
}
|
||||
if ( ! isset( self::$sc[ $name ] ) ) {
|
||||
// No shortcode found
|
||||
return false;
|
||||
} elseif ( ! isset( $attribute['param_name'] ) ) {
|
||||
throw new Exception( sprintf( esc_html__( "Wrong attribute for '%s' shortcode. Attribute 'param_name' required", 'js_composer' ), $name ) );
|
||||
} else {
|
||||
|
||||
$replaced = false;
|
||||
|
||||
foreach ( self::$sc[ $name ]['params'] as $index => $param ) {
|
||||
if ( $param['param_name'] === $attribute['param_name'] ) {
|
||||
$replaced = true;
|
||||
self::$sc[ $name ]['params'][ $index ] = array_merge( $param, $attribute );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( false === $replaced ) {
|
||||
self::$sc[ $name ]['params'][] = $attribute;
|
||||
}
|
||||
$sort = new Vc_Sort( self::$sc[ $name ]['params'] );
|
||||
self::$sc[ $name ]['params'] = $sort->sortByKey();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes shortcode from mapping list.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @param $name
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function dropShortcode( $name ) {
|
||||
$currentScope = self::getScope();
|
||||
if ( 'default' !== $currentScope ) {
|
||||
self::setScope( 'default' );
|
||||
$res = self::dropShortcode( $name );
|
||||
self::setScope( $currentScope );
|
||||
|
||||
return $res;
|
||||
}
|
||||
self::$removedElements[] = $name;
|
||||
if ( ! isset( self::$init_elements[ $name ] ) ) {
|
||||
vc_mapper()->addElementActivity( $name, 'drop_shortcode', array(
|
||||
'name' => $name,
|
||||
) );
|
||||
}
|
||||
unset( self::$sc[ $name ] );
|
||||
visual_composer()->removeShortCode( $name );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function dropAllShortcodes() {
|
||||
$currentScope = self::getScope();
|
||||
if ( 'default' !== $currentScope ) {
|
||||
self::setScope( 'default' );
|
||||
$res = self::dropAllShortcodes();
|
||||
self::setScope( $currentScope );
|
||||
|
||||
return $res;
|
||||
}
|
||||
if ( ! self::$is_init ) {
|
||||
vc_mapper()->addActivity( '*', 'drop_all_shortcodes', array() );
|
||||
|
||||
return false;
|
||||
}
|
||||
foreach ( self::$sc as $name => $data ) {
|
||||
visual_composer()->removeShortCode( $name );
|
||||
}
|
||||
self::$sc = array();
|
||||
self::$user_sc = false;
|
||||
self::$user_categories = false;
|
||||
self::$user_sorted_sc = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify shortcode's mapped settings.
|
||||
* You can modify only one option of the group options.
|
||||
* Call this method with $settings_name param as associated array to mass modifications.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @param $name - shortcode' name.
|
||||
* @param $setting_name - option key name or the array of options.
|
||||
* @param string $value - value of settings if $setting_name is option key.
|
||||
*
|
||||
* @return array|bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function modify( $name, $setting_name, $value = '' ) {
|
||||
$currentScope = self::getScope();
|
||||
if ( 'default' !== $currentScope ) {
|
||||
self::setScope( 'default' );
|
||||
$res = self::modify( $name, $setting_name, $value );
|
||||
self::setScope( $currentScope );
|
||||
|
||||
return $res;
|
||||
}
|
||||
if ( ! isset( self::$init_elements[ $name ] ) ) {
|
||||
vc_mapper()->addElementActivity( $name, 'modify', array(
|
||||
'name' => $name,
|
||||
'setting_name' => $setting_name,
|
||||
'value' => $value,
|
||||
) );
|
||||
|
||||
return false;
|
||||
}
|
||||
if ( ! isset( self::$sc[ $name ] ) ) {
|
||||
// No shortcode found
|
||||
return false;
|
||||
} elseif ( 'base' === $setting_name ) {
|
||||
throw new Exception( sprintf( esc_html__( "Wrong setting_name for shortcode:%s. Base can't be modified.", 'js_composer' ), $name ) );
|
||||
}
|
||||
if ( is_array( $setting_name ) ) {
|
||||
foreach ( $setting_name as $key => $value ) {
|
||||
self::modify( $name, $key, $value );
|
||||
}
|
||||
} else {
|
||||
if ( is_array( $value ) ) {
|
||||
// fix indexes
|
||||
$value = array_merge( $value );
|
||||
}
|
||||
self::$sc[ $name ][ $setting_name ] = $value;
|
||||
visual_composer()->updateShortcodeSetting( $name, $setting_name, $value );
|
||||
}
|
||||
|
||||
return self::$sc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns "|" separated list of mapped shortcode tags.
|
||||
*
|
||||
* @static
|
||||
* @return string
|
||||
*/
|
||||
public static function getTagsRegexp() {
|
||||
if ( empty( self::$tags_regexp ) ) {
|
||||
self::$tags_regexp = implode( '|', array_keys( self::$sc ) );
|
||||
}
|
||||
|
||||
return self::$tags_regexp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorting method for WPBMap::generateUserData method. Called by uasort php function.
|
||||
* @param $a
|
||||
* @param $b
|
||||
*
|
||||
* @return int
|
||||
* @deprecated - use Vc_Sort::sortByKey since 4.4
|
||||
* @static
|
||||
*
|
||||
*/
|
||||
public static function sort( $a, $b ) {
|
||||
$a_weight = isset( $a['weight'] ) ? (int) $a['weight'] : 0;
|
||||
$b_weight = isset( $b['weight'] ) ? (int) $b['weight'] : 0;
|
||||
if ( $a_weight === $b_weight ) {
|
||||
// @codingStandardsIgnoreLine
|
||||
$cmpa = array_search( $a, (array) self::$user_sorted_sc, true );
|
||||
// @codingStandardsIgnoreLine
|
||||
$cmpb = array_search( $b, (array) self::$user_sorted_sc, true );
|
||||
|
||||
return ( $cmpa > $cmpb ) ? 1 : - 1;
|
||||
}
|
||||
|
||||
return ( $a_weight < $b_weight ) ? 1 : - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $shortcodes
|
||||
* @return array
|
||||
*/
|
||||
public static function collectCategories( &$shortcodes ) {
|
||||
$categories_list = array();
|
||||
$deprecated = 'deprecated';
|
||||
$add_deprecated = false;
|
||||
if ( is_array( $shortcodes ) && ! empty( $shortcodes ) ) {
|
||||
foreach ( $shortcodes as $name => $values ) {
|
||||
$values['_category_ids'] = array();
|
||||
if ( isset( $values['deprecated'] ) && false !== $values['deprecated'] ) {
|
||||
$add_deprecated = true;
|
||||
$values['_category_ids'][] = 'deprecated';
|
||||
} elseif ( isset( $values['category'] ) ) {
|
||||
$categories = $values['category'];
|
||||
if ( is_array( $categories ) && ! empty( $categories ) ) {
|
||||
foreach ( $categories as $c ) {
|
||||
if ( false === array_search( $c, $categories_list, true ) ) {
|
||||
$categories[] = $c;
|
||||
}
|
||||
$values['_category_ids'][] = md5( $c );
|
||||
}
|
||||
} else {
|
||||
if ( false === array_search( $categories, $categories_list, true ) ) {
|
||||
$categories_list[] = $categories;
|
||||
}
|
||||
/** @var string $categories */
|
||||
$values['_category_ids'][] = md5( $categories );
|
||||
}
|
||||
}
|
||||
$shortcodes[ $name ] = $values;
|
||||
}
|
||||
}
|
||||
if ( $add_deprecated ) {
|
||||
$categories_list[] = $deprecated;
|
||||
}
|
||||
|
||||
return $categories_list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process files/functions for lean mapping settings
|
||||
*
|
||||
* @param $tag
|
||||
*
|
||||
* @return array|null
|
||||
* @throws \Exception
|
||||
* @since 4.9
|
||||
*/
|
||||
public static function setElementSettings( $tag ) {
|
||||
$currentScope = self::getScope();
|
||||
if ( 'default' !== $currentScope ) {
|
||||
if ( isset( self::$scopes[ $currentScope ], self::$scopes[ $currentScope ][ $tag ] ) && ! in_array( $tag, self::$removedElements, true ) ) {
|
||||
if ( isset( self::$init_elements_scoped[ $currentScope ], self::$init_elements_scoped[ $currentScope ][ $tag ] ) && ! empty( self::$init_elements_scoped[ $currentScope ][ $tag ] ) ) {
|
||||
return self::$scopes[ $currentScope ][ $tag ];
|
||||
}
|
||||
|
||||
$settings = self::$scopes[ $currentScope ][ $tag ];
|
||||
if ( isset( $settings['__vc_settings_function'] ) ) {
|
||||
self::$scopes[ $currentScope ][ $tag ] = call_user_func( $settings['__vc_settings_function'], $tag );
|
||||
} elseif ( isset( $settings['__vc_settings_file'] ) ) {
|
||||
self::$scopes[ $currentScope ][ $tag ] = include $settings['__vc_settings_file'];
|
||||
}
|
||||
self::$scopes[ $currentScope ][ $tag ]['base'] = $tag;
|
||||
self::$init_elements_scoped[ $currentScope ][ $tag ] = true;
|
||||
vc_mapper()->callElementActivities( $tag );
|
||||
|
||||
return self::$scopes[ $currentScope ][ $tag ];
|
||||
}
|
||||
}
|
||||
if ( ! isset( self::$sc[ $tag ] ) || in_array( $tag, self::$removedElements, true ) ) {
|
||||
return null;
|
||||
}
|
||||
if ( isset( self::$init_elements[ $tag ] ) && self::$init_elements[ $tag ] ) {
|
||||
return self::$sc[ $tag ];
|
||||
}
|
||||
$settings = self::$sc[ $tag ];
|
||||
if ( isset( $settings['__vc_settings_function'] ) ) {
|
||||
self::$sc[ $tag ] = call_user_func( $settings['__vc_settings_function'], $tag );
|
||||
} elseif ( isset( $settings['__vc_settings_file'] ) ) {
|
||||
self::$sc[ $tag ] = include $settings['__vc_settings_file'];
|
||||
}
|
||||
self::$sc[ $tag ]['base'] = $tag;
|
||||
self::$init_elements[ $tag ] = true;
|
||||
vc_mapper()->callElementActivities( $tag );
|
||||
|
||||
return self::$sc[ $tag ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add elements as shortcodes
|
||||
*
|
||||
* @since 4.9
|
||||
*/
|
||||
public static function addAllMappedShortcodes() {
|
||||
foreach ( self::$sc as $tag => $settings ) {
|
||||
if ( ! in_array( $tag, self::$removedElements, true ) && ! shortcode_exists( $tag ) ) {
|
||||
add_shortcode( $tag, 'vc_do_shortcode' );
|
||||
}
|
||||
}
|
||||
|
||||
// Map also custom scopes
|
||||
foreach ( self::$scopes as $scopeName => $scopeElements ) {
|
||||
foreach ( $scopeElements as $tag => $settings ) {
|
||||
if ( ! in_array( $tag, self::$removedElements, true ) && ! shortcode_exists( $tag ) ) {
|
||||
add_shortcode( $tag, 'vc_do_shortcode' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $scope
|
||||
*/
|
||||
public static function setScope( $scope = 'default' ) {
|
||||
if ( ! isset( self::$scopes[ $scope ] ) ) {
|
||||
self::$scopes[ $scope ] = array();
|
||||
self::$init_elements_scoped[ $scope ] = array();
|
||||
}
|
||||
self::$scope = $scope;
|
||||
}
|
||||
|
||||
public static function resetScope() {
|
||||
self::$scope = 'default';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function getScope() {
|
||||
return self::$scope;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
require_once dirname( __FILE__ ) . '/importer/class-vc-wp-import.php';
|
||||
require_once dirname( __FILE__ ) . '/importer/class-vc-wxr-parser-plugin.php';
|
||||
|
||||
/**
|
||||
* Class Vc_Shared_Templates
|
||||
*/
|
||||
class Vc_Shared_Templates {
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $initialized = false;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $download_link_url = 'https://support.wpbakery.com/templates/download-link';
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function init() {
|
||||
if ( $this->initialized ) {
|
||||
return;
|
||||
}
|
||||
$this->initialized = true;
|
||||
|
||||
add_filter( 'vc_templates_render_category', array(
|
||||
$this,
|
||||
'renderTemplateBlock',
|
||||
), 10 );
|
||||
|
||||
add_filter( 'vc_templates_render_frontend_template', array(
|
||||
$this,
|
||||
'renderFrontendTemplate',
|
||||
), 10, 2 );
|
||||
|
||||
add_filter( 'vc_templates_render_backend_template', array(
|
||||
$this,
|
||||
'renderBackendTemplate',
|
||||
), 10, 2 );
|
||||
add_filter( 'vc_templates_render_backend_template_preview', array(
|
||||
$this,
|
||||
'renderBackendTemplate',
|
||||
), 10, 2 );
|
||||
add_action( 'vc_templates_delete_templates', array(
|
||||
$this,
|
||||
'delete',
|
||||
), 10, 2 );
|
||||
add_filter( 'wp_ajax_vc_shared_templates_download', array(
|
||||
$this,
|
||||
'ajaxDownloadTemplate',
|
||||
) );
|
||||
add_filter( 'vc_get_all_templates', array(
|
||||
$this,
|
||||
'addTemplatesTab',
|
||||
) );
|
||||
|
||||
$this->registerPostType();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $templateId
|
||||
* @param $templateType
|
||||
* @return string
|
||||
*/
|
||||
public function renderBackendTemplate( $templateId, $templateType ) {
|
||||
if ( 'shared_templates' === $templateType ) {
|
||||
$templates = get_posts( array(
|
||||
'post_type' => 'vc4_templates',
|
||||
'include' => intval( $templateId ),
|
||||
'numberposts' => 1,
|
||||
) );
|
||||
if ( ! empty( $templates ) ) {
|
||||
$template = $templates[0];
|
||||
|
||||
return $template->post_content;
|
||||
}
|
||||
wp_send_json_error( array(
|
||||
'code' => 'Wrong ID or no Template found',
|
||||
) );
|
||||
}
|
||||
|
||||
return $templateId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $templateId
|
||||
* @param $templateType
|
||||
* @return mixed
|
||||
*/
|
||||
public function renderFrontendTemplate( $templateId, $templateType ) {
|
||||
if ( 'shared_templates' === $templateType ) {
|
||||
$templates = get_posts( array(
|
||||
'post_type' => 'vc4_templates',
|
||||
'include' => intval( $templateId ),
|
||||
'numberposts' => 1,
|
||||
) );
|
||||
if ( ! empty( $templates ) ) {
|
||||
$template = $templates[0];
|
||||
|
||||
vc_frontend_editor()->setTemplateContent( $template->post_content );
|
||||
vc_frontend_editor()->enqueueRequired();
|
||||
vc_include_template( 'editors/frontend_template.tpl.php', array(
|
||||
'editor' => vc_frontend_editor(),
|
||||
) );
|
||||
die();
|
||||
}
|
||||
wp_send_json_error( array(
|
||||
'code' => 'Wrong ID or no Template found #3',
|
||||
) );
|
||||
}
|
||||
|
||||
return $templateId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $templateId
|
||||
* @param $templateType
|
||||
* @return mixed
|
||||
*/
|
||||
public function delete( $templateId, $templateType ) {
|
||||
if ( 'shared_templates' === $templateType ) {
|
||||
$templates = get_posts( array(
|
||||
'post_type' => 'vc4_templates',
|
||||
'include' => intval( $templateId ),
|
||||
'numberposts' => 1,
|
||||
) );
|
||||
if ( ! empty( $templates ) ) {
|
||||
$template = $templates[0];
|
||||
if ( wp_delete_post( $template->ID ) ) {
|
||||
wp_send_json_success();
|
||||
}
|
||||
}
|
||||
wp_send_json_error( array(
|
||||
'code' => 'Wrong ID or no Template found #2',
|
||||
) );
|
||||
}
|
||||
|
||||
return $templateId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Post type from templates registration in WordPress
|
||||
*/
|
||||
private function registerPostType() {
|
||||
register_post_type( 'vc4_templates', array(
|
||||
'label' => 'Vc Templates',
|
||||
'public' => false,
|
||||
'publicly_queryable' => false,
|
||||
'exclude_from_search' => false,
|
||||
'show_ui' => false,
|
||||
'show_in_menu' => false,
|
||||
'menu_position' => 10,
|
||||
'menu_icon' => 'dashicons-admin-page',
|
||||
'hierarchical' => false,
|
||||
'taxonomies' => array(),
|
||||
'has_archive' => false,
|
||||
'rewrite' => false,
|
||||
'query_var' => false,
|
||||
'show_in_nav_menus' => false,
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax request processing from templates panel
|
||||
*/
|
||||
public function ajaxDownloadTemplate() {
|
||||
/** @var Vc_Current_User_Access $access */
|
||||
$access = vc_user_access()->checkAdminNonce()->validateDie( wp_json_encode( array(
|
||||
'success' => false,
|
||||
'message' => 'access denied',
|
||||
) ) )->part( 'templates' )->checkStateAny( true, null )->validateDie( wp_json_encode( array(
|
||||
'success' => false,
|
||||
'message' => 'part access denied',
|
||||
) ) )->check( array(
|
||||
vc_license(),
|
||||
'isActivated',
|
||||
) );
|
||||
$access->validateDie( wp_json_encode( array(
|
||||
'success' => false,
|
||||
'message' => 'license is not activated',
|
||||
) ) );
|
||||
|
||||
$templateId = vc_request_param( 'id' );
|
||||
$requestUrl = $this->getTemplateDownloadLink( $templateId );
|
||||
$status = false;
|
||||
$file = $this->downloadTemplate( $requestUrl );
|
||||
$data = array();
|
||||
if ( $file ) {
|
||||
new Vc_WXR_Parser_Plugin();
|
||||
$importer = new Vc_WP_Import();
|
||||
ob_start();
|
||||
$importer->import( $file );
|
||||
if ( ! empty( $importer->processed_posts ) ) {
|
||||
$status = true;
|
||||
$postId = reset( $importer->processed_posts );
|
||||
$data['post_id'] = $postId;
|
||||
}
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
if ( $status ) {
|
||||
wp_send_json_success( $data );
|
||||
} else {
|
||||
wp_send_json_error();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $requestUrl
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
private function downloadTemplate( $requestUrl ) {
|
||||
// FIX SSL SNI
|
||||
$filter_add = true;
|
||||
if ( function_exists( 'curl_version' ) ) {
|
||||
$version = curl_version();
|
||||
if ( version_compare( $version['version'], '7.18', '>=' ) ) {
|
||||
$filter_add = false;
|
||||
}
|
||||
}
|
||||
if ( $filter_add ) {
|
||||
add_filter( 'https_ssl_verify', '__return_false' );
|
||||
}
|
||||
$downloadUrlRequest = wp_remote_get( $requestUrl, array(
|
||||
'timeout' => 30,
|
||||
) );
|
||||
|
||||
if ( $filter_add ) {
|
||||
remove_filter( 'https_ssl_verify', '__return_false' );
|
||||
}
|
||||
if ( is_array( $downloadUrlRequest ) && 200 === $downloadUrlRequest['response']['code'] ) {
|
||||
return $this->parseRequest( $downloadUrlRequest );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $request
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
private function parseRequest( $request ) {
|
||||
$body = json_decode( $request['body'], true );
|
||||
if ( isset( $body['status'], $body['url'] ) && 1 === $body['status'] ) {
|
||||
$downloadUrl = $body['url'];
|
||||
$downloadedTemplateFile = download_url( $downloadUrl );
|
||||
if ( is_wp_error( $downloadedTemplateFile ) || ! $downloadedTemplateFile ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $downloadedTemplateFile;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function addTemplatesTab( $data ) {
|
||||
if ( vc_user_access()->part( 'templates' )->checkStateAny( true, null, 'add' )->get() ) {
|
||||
$templates = $this->getTemplates();
|
||||
if ( ! empty( $templates ) || vc_user_access()->part( 'templates' )->checkStateAny( true, null )->get() ) {
|
||||
$newCategory = array(
|
||||
'category' => 'shared_templates',
|
||||
'category_name' => esc_html__( 'Template library', 'js_composer' ),
|
||||
'category_weight' => 10,
|
||||
'templates' => $this->getTemplates(),
|
||||
);
|
||||
$data[] = $newCategory;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $category
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function renderTemplateBlock( $category ) {
|
||||
if ( 'shared_templates' === $category['category'] ) {
|
||||
$category['output'] = $this->getTemplateBlockTemplate();
|
||||
}
|
||||
|
||||
return $category;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getTemplateBlockTemplate() {
|
||||
ob_start();
|
||||
vc_include_template( 'editors/popups/shared-templates/category.tpl.php', array(
|
||||
'controller' => $this,
|
||||
'templates' => $this->getTemplates(),
|
||||
) );
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getTemplates() {
|
||||
$posts = get_posts( 'post_type=vc4_templates&numberposts=-1' );
|
||||
$templates = array();
|
||||
if ( ! empty( $posts ) ) {
|
||||
foreach ( $posts as $post ) {
|
||||
/** @var WP_Post $post */
|
||||
$id = get_post_meta( $post->ID, '_vc4_templates-id', true );
|
||||
$template = array();
|
||||
$template['title'] = $post->post_title;
|
||||
$template['version'] = get_post_meta( $post->ID, '_vc4_templates-version', true );
|
||||
$template['id'] = $id;
|
||||
$template['post_id'] = $post->ID;
|
||||
$template['name'] = $post->post_title; // For Settings
|
||||
$template['type'] = 'shared_templates'; // For Settings
|
||||
$template['unique_id'] = $id; // For Settings
|
||||
$templates[] = $template;
|
||||
}
|
||||
}
|
||||
|
||||
return $templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create url for request to download
|
||||
* It requires a license key, product and version
|
||||
*
|
||||
* @param $id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getTemplateDownloadLink( $id ) {
|
||||
$url = esc_url( vc_license()->getSiteUrl() );
|
||||
$key = rawurlencode( vc_license()->getLicenseKey() );
|
||||
|
||||
$url = $this->download_link_url . '?product=vc&url=' . $url . '&key=' . $key . '&version=' . WPB_VC_VERSION . '&id=' . esc_attr( $id );
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,664 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/*
|
||||
* Modified by WPBakery Page Builder team
|
||||
WordPress Importer
|
||||
http://wordpress.org/extend/plugins/wordpress-importer/
|
||||
Description: Import posts, pages, comments, custom fields, categories, tags and more from a WordPress export file.
|
||||
Author: wordpressdotorg
|
||||
Author URI: http://wordpress.org/
|
||||
Version: 0.6.3 with fixes and enchancements from WPBakery Page Builder
|
||||
Text Domain: js_composer
|
||||
License: GPL version 2 or later - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*/
|
||||
|
||||
// Load Importer API
|
||||
require_once ABSPATH . 'wp-admin/includes/import.php';
|
||||
|
||||
if ( ! class_exists( 'WP_Importer' ) ) {
|
||||
$class_wp_importer = ABSPATH . 'wp-admin/includes/class-wp-importer.php';
|
||||
if ( file_exists( $class_wp_importer ) ) {
|
||||
require $class_wp_importer;
|
||||
}
|
||||
}
|
||||
|
||||
// include WXR file parsers
|
||||
require_once dirname( __FILE__ ) . '/class-vc-wxr-parser.php';
|
||||
|
||||
/**
|
||||
* WordPress Importer class for managing the import process of a WXR file
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Importer
|
||||
*/
|
||||
if ( class_exists( 'WP_Importer' ) ) {
|
||||
/**
|
||||
* Class Vc_WP_Import
|
||||
*/
|
||||
class Vc_WP_Import extends WP_Importer {
|
||||
/**
|
||||
* @var float
|
||||
*/
|
||||
public $max_wxr_version = 1.2; // max. supported WXR version
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $id;
|
||||
|
||||
/**
|
||||
* @var information to import from WXR file
|
||||
*/
|
||||
public $version;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $posts = array();
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $base_url = '';
|
||||
|
||||
// mappings from old information to new
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $processed_posts = array();
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $processed_attachments = array();
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $post_orphans = array();
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public $fetch_attachments = true;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $url_remap = array();
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $featured_images = array();
|
||||
|
||||
/**
|
||||
* The main controller for the actual import stage.
|
||||
*
|
||||
* @param string $file Path to the WXR file for importing
|
||||
*/
|
||||
public function import( $file ) {
|
||||
add_filter( 'vc_import_post_meta_key', array(
|
||||
$this,
|
||||
'is_valid_meta_key',
|
||||
) );
|
||||
add_filter( 'http_request_timeout', array(
|
||||
$this,
|
||||
'bump_request_timeout',
|
||||
) );
|
||||
|
||||
$this->import_start( $file );
|
||||
|
||||
wp_suspend_cache_invalidation( true );
|
||||
$this->process_posts();
|
||||
wp_suspend_cache_invalidation( false );
|
||||
|
||||
// update incorrect/missing information in the DB
|
||||
$this->backfill_parents();
|
||||
$this->backfill_attachment_urls();
|
||||
$this->remap_featured_images();
|
||||
do_action( 'vc_import_pre_end', $this );
|
||||
$this->import_end();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the WXR file and prepares us for the task of processing parsed data
|
||||
*
|
||||
* @param string $file Path to the WXR file for importing
|
||||
*/
|
||||
public function import_start( $file ) {
|
||||
if ( ! is_file( $file ) ) {
|
||||
echo '<p><strong>' . esc_html__( 'Sorry, there has been an error.', 'js_composer' ) . '</strong><br />';
|
||||
echo esc_html__( 'The file does not exist, please try again.', 'js_composer' ) . '</p>';
|
||||
die();
|
||||
}
|
||||
|
||||
$import_data = $this->parse( $file );
|
||||
|
||||
if ( is_wp_error( $import_data ) ) {
|
||||
echo '<p><strong>' . esc_html__( 'Sorry, there has been an error.', 'js_composer' ) . '</strong><br />';
|
||||
/** @var \WP_Error $import_data */
|
||||
echo esc_html( $import_data->get_error_message() ) . '</p>';
|
||||
die();
|
||||
}
|
||||
|
||||
$this->version = $import_data['version'];
|
||||
$this->posts = $import_data['posts'];
|
||||
$this->base_url = esc_url( $import_data['base_url'] );
|
||||
|
||||
wp_defer_term_counting( true );
|
||||
wp_defer_comment_counting( true );
|
||||
|
||||
do_action( 'vc_import_start' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs post-import cleanup of files and the cache
|
||||
*/
|
||||
public function import_end() {
|
||||
wp_import_cleanup( $this->id );
|
||||
|
||||
wp_cache_flush();
|
||||
foreach ( get_taxonomies() as $tax ) {
|
||||
delete_option( "{$tax}_children" );
|
||||
_get_term_hierarchy( $tax );
|
||||
}
|
||||
|
||||
wp_defer_term_counting( false );
|
||||
wp_defer_comment_counting( false );
|
||||
|
||||
do_action( 'vc_import_end' );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the WXR upload and initial parsing of the file to prepare for
|
||||
* displaying author import options
|
||||
*
|
||||
* @return bool False if error uploading or invalid file, true otherwise
|
||||
*/
|
||||
public function handle_upload() {
|
||||
$file = wp_import_handle_upload();
|
||||
|
||||
if ( isset( $file['error'] ) ) {
|
||||
echo '<p><strong>' . esc_html__( 'Sorry, there has been an error.', 'js_composer' ) . '</strong><br />';
|
||||
echo esc_html( $file['error'] ) . '</p>';
|
||||
|
||||
return false;
|
||||
} elseif ( ! file_exists( $file['file'] ) ) {
|
||||
echo '<p><strong>' . esc_html__( 'Sorry, there has been an error.', 'js_composer' ) . '</strong><br />';
|
||||
printf( esc_html__( 'The export file could not be found at %s. It is likely that this was caused by a permissions problem.', 'js_composer' ), '<code>' . esc_html( $file['file'] ) . '</code>' );
|
||||
echo '</p>';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->id = (int) $file['id'];
|
||||
$import_data = $this->parse( $file['file'] );
|
||||
if ( is_wp_error( $import_data ) ) {
|
||||
echo '<p><strong>' . esc_html__( 'Sorry, there has been an error.', 'js_composer' ) . '</strong><br />';
|
||||
/** @var \WP_Error $import_data */
|
||||
echo esc_html( $import_data->get_error_message() ) . '</p>';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->version = $import_data['version'];
|
||||
if ( $this->version > $this->max_wxr_version ) {
|
||||
echo '<div class="error"><p><strong>';
|
||||
printf( esc_html__( 'This WXR file (version %s) may not be supported by this version of the importer. Please consider updating.', 'js_composer' ), esc_html( $import_data['version'] ) );
|
||||
echo '</strong></p></div>';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new posts based on import information
|
||||
*
|
||||
* Posts marked as having a parent which doesn't exist will become top level items.
|
||||
* Doesn't create a new post if: the post type doesn't exist, the given post ID
|
||||
* is already noted as imported or a post with the same title and date already exists.
|
||||
* Note that new/updated terms, comments and meta are imported for the last of the above.
|
||||
*/
|
||||
public function process_posts() {
|
||||
$status = array();
|
||||
$this->posts = apply_filters( 'vc_import_posts', $this->posts );
|
||||
if ( is_array( $this->posts ) && ! empty( $this->posts ) ) {
|
||||
foreach ( $this->posts as $post ) {
|
||||
$post = apply_filters( 'vc_import_post_data_raw', $post );
|
||||
|
||||
if ( ! post_type_exists( $post['post_type'] ) ) {
|
||||
$status[] = array(
|
||||
'success' => false,
|
||||
'code' => 'invalid_post_type',
|
||||
'post' => $post,
|
||||
);
|
||||
do_action( 'vc_import_post_exists', $post );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isset( $this->processed_posts[ $post['post_id'] ] ) && ! empty( $post['post_id'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( 'auto-draft' === $post['status'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$post_parent = (int) $post['post_parent'];
|
||||
if ( $post_parent ) {
|
||||
// if we already know the parent, map it to the new local ID
|
||||
if ( isset( $this->processed_posts[ $post_parent ] ) ) {
|
||||
$post_parent = $this->processed_posts[ $post_parent ];
|
||||
// otherwise record the parent for later
|
||||
} else {
|
||||
$this->post_orphans[ intval( $post['post_id'] ) ] = $post_parent;
|
||||
$post_parent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// map the post author
|
||||
$author = (int) get_current_user_id();
|
||||
|
||||
$postdata = array(
|
||||
'post_author' => $author,
|
||||
'post_date' => $post['post_date'],
|
||||
'post_date_gmt' => $post['post_date_gmt'],
|
||||
'post_content' => $post['post_content'],
|
||||
'post_excerpt' => $post['post_excerpt'],
|
||||
'post_title' => $post['post_title'],
|
||||
'post_status' => $post['status'],
|
||||
'post_name' => $post['post_name'],
|
||||
'comment_status' => $post['comment_status'],
|
||||
'ping_status' => $post['ping_status'],
|
||||
'guid' => $post['guid'],
|
||||
'post_parent' => $post_parent,
|
||||
'menu_order' => $post['menu_order'],
|
||||
'post_type' => $post['post_type'],
|
||||
'post_password' => $post['post_password'],
|
||||
);
|
||||
|
||||
$original_post_ID = $post['post_id'];
|
||||
$postdata = apply_filters( 'vc_import_post_data_processed', $postdata, $post, $this );
|
||||
|
||||
$postdata = wp_slash( $postdata );
|
||||
|
||||
if ( 'attachment' === $postdata['post_type'] ) {
|
||||
$remote_url = ! empty( $post['attachment_url'] ) ? $post['attachment_url'] : $post['guid'];
|
||||
|
||||
// try to use _wp_attached file for upload folder placement to ensure the same location as the export site
|
||||
// e.g. location is 2003/05/image.jpg but the attachment post_date is 2010/09, see media_handle_upload()
|
||||
$postdata['upload_date'] = $post['post_date'];
|
||||
if ( isset( $post['postmeta'] ) ) {
|
||||
foreach ( $post['postmeta'] as $meta ) {
|
||||
if ( '_wp_attached_file' === $meta['key'] ) {
|
||||
if ( preg_match( '%^[0-9]{4}/[0-9]{2}%', $meta['value'], $matches ) ) {
|
||||
$postdata['upload_date'] = $matches[0];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$post_id = $this->process_attachment( $postdata, $remote_url, $original_post_ID );
|
||||
} else {
|
||||
$post_id = wp_insert_post( $postdata, true );
|
||||
do_action( 'vc_import_insert_post', $post_id, $original_post_ID, $postdata, $post );
|
||||
// map pre-import ID to local ID
|
||||
$this->processed_posts[ intval( $post['post_id'] ) ] = (int) $post_id;
|
||||
}
|
||||
|
||||
if ( is_wp_error( $post_id ) ) {
|
||||
$status[] = array(
|
||||
'success' => false,
|
||||
'code' => 'wp_error',
|
||||
'post' => $post_id,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( true === $post['is_sticky'] ) {
|
||||
stick_post( $post_id );
|
||||
}
|
||||
|
||||
if ( ! isset( $post['postmeta'] ) ) {
|
||||
$post['postmeta'] = array();
|
||||
}
|
||||
|
||||
$post['postmeta'] = apply_filters( 'vc_import_post_meta', $post['postmeta'], $post_id, $post );
|
||||
|
||||
// add/update post meta
|
||||
if ( ! empty( $post['postmeta'] ) ) {
|
||||
foreach ( $post['postmeta'] as $meta ) {
|
||||
$key = apply_filters( 'vc_import_post_meta_key', $meta['key'], $post_id, $post );
|
||||
$value = false;
|
||||
|
||||
if ( '_edit_last' === $key ) {
|
||||
$key = false;
|
||||
}
|
||||
|
||||
if ( $key ) {
|
||||
// export gets meta straight from the DB so could have a serialized string
|
||||
if ( ! $value ) {
|
||||
$value = maybe_unserialize( $meta['value'] );
|
||||
}
|
||||
|
||||
add_post_meta( $post_id, $key, $value );
|
||||
do_action( 'vc_import_post_meta', $post_id, $key, $value );
|
||||
|
||||
// if the post has a featured image, take note of this in case of remap
|
||||
if ( '_thumbnail_id' === $key ) {
|
||||
$this->featured_images[ $post_id ] = (int) $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
unset( $this->posts );
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* If fetching attachments is enabled then attempt to create a new attachment
|
||||
*
|
||||
* @param array $post Attachment post details from WXR
|
||||
* @param string $url URL to fetch attachment from
|
||||
* @param $original_post_ID
|
||||
* @return int|\WP_Error Post ID on success, WP_Error otherwise
|
||||
*/
|
||||
public function process_attachment( $post, $url, $original_post_ID ) {
|
||||
if ( ! $this->fetch_attachments ) {
|
||||
return new WP_Error( 'attachment_processing_error', esc_html__( 'Fetching attachments is not enabled', 'js_composer' ) );
|
||||
}
|
||||
|
||||
// if the URL is absolute, but does not contain address, then upload it assuming base_site_url
|
||||
if ( preg_match( '|^/[\w\W]+$|', $url ) ) {
|
||||
$url = rtrim( $this->base_url, '/' ) . $url;
|
||||
}
|
||||
|
||||
$upload = $this->fetch_remote_file( $url, $post );
|
||||
if ( is_wp_error( $upload ) ) {
|
||||
return $upload;
|
||||
}
|
||||
|
||||
$info = wp_check_filetype( $upload['file'] );
|
||||
if ( $info ) {
|
||||
$post['post_mime_type'] = $info['type'];
|
||||
} else {
|
||||
return new WP_Error( 'attachment_processing_error', esc_html__( 'Invalid file type', 'js_composer' ) );
|
||||
}
|
||||
|
||||
$post['guid'] = $upload['url'];
|
||||
|
||||
// as per wp-admin/includes/upload.php
|
||||
$post_id = wp_insert_attachment( $post, $upload['file'] );
|
||||
wp_update_attachment_metadata( $post_id, wp_generate_attachment_metadata( $post_id, $upload['file'] ) );
|
||||
|
||||
// remap resized image URLs, works by stripping the extension and remapping the URL stub.
|
||||
if ( preg_match( '!^image/!', $info['type'] ) ) {
|
||||
$parts = pathinfo( $url );
|
||||
$name = basename( $parts['basename'], ".{$parts['extension']}" ); // PATHINFO_FILENAME in PHP 5.2
|
||||
|
||||
$parts_new = pathinfo( $upload['url'] );
|
||||
$name_new = basename( $parts_new['basename'], ".{$parts_new['extension']}" );
|
||||
|
||||
$this->url_remap[ $parts['dirname'] . '/' . $name ] = $parts_new['dirname'] . '/' . $name_new;
|
||||
}
|
||||
$this->processed_attachments[ intval( $original_post_ID ) ] = (int) $post_id;
|
||||
|
||||
return $post_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $url
|
||||
* @param bool $file_path
|
||||
* @return array|bool|\Requests_Utility_CaseInsensitiveDictionary
|
||||
*/
|
||||
private function wp_get_http( $url, $file_path = false ) {
|
||||
set_time_limit( 60 );
|
||||
|
||||
$options = array();
|
||||
$options['redirection'] = 5;
|
||||
|
||||
$options['method'] = 'GET';
|
||||
|
||||
$response = wp_safe_remote_request( $url, $options );
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$headers = wp_remote_retrieve_headers( $response );
|
||||
$headers['response'] = wp_remote_retrieve_response_code( $response );
|
||||
|
||||
if ( ! $file_path ) {
|
||||
return $headers;
|
||||
}
|
||||
|
||||
// GET request - write it to the supplied filename
|
||||
// @codingStandardsIgnoreLine
|
||||
$out_fp = fopen( $file_path, 'w' );
|
||||
if ( ! $out_fp ) {
|
||||
return $headers;
|
||||
}
|
||||
|
||||
// @codingStandardsIgnoreLine
|
||||
fwrite( $out_fp, wp_remote_retrieve_body( $response ) );
|
||||
// @codingStandardsIgnoreLine
|
||||
fclose( $out_fp );
|
||||
clearstatcache();
|
||||
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to download a remote file attachment
|
||||
*
|
||||
* @param string $url URL of item to fetch
|
||||
* @param array $post Attachment details
|
||||
* @return array|WP_Error Local file location details on success, WP_Error otherwise
|
||||
*/
|
||||
public function fetch_remote_file( $url, $post ) {
|
||||
// extract the file name and extension from the url
|
||||
$file_name = basename( $url );
|
||||
|
||||
// get placeholder file in the upload dir with a unique, sanitized filename
|
||||
$upload = wp_upload_bits( $file_name, null, '', $post['upload_date'] );
|
||||
if ( $upload['error'] ) {
|
||||
return new WP_Error( 'upload_dir_error', $upload['error'] );
|
||||
}
|
||||
|
||||
// fetch the remote url and write it to the placeholder file
|
||||
$headers = $this->wp_get_http( $url, $upload['file'] );
|
||||
|
||||
// request failed
|
||||
if ( ! $headers ) {
|
||||
// @codingStandardsIgnoreLine
|
||||
@unlink( $upload['file'] );
|
||||
|
||||
return new WP_Error( 'import_file_error', esc_html__( 'Remote server did not respond', 'js_composer' ) );
|
||||
}
|
||||
|
||||
// make sure the fetch was successful
|
||||
if ( intval( $headers['response'] ) !== 200 ) {
|
||||
// @codingStandardsIgnoreLine
|
||||
@unlink( $upload['file'] );
|
||||
|
||||
return new WP_Error( 'import_file_error', sprintf( esc_html__( 'Remote server returned error response %1$d %2$s', 'js_composer' ), esc_html( $headers['response'] ), get_status_header_desc( $headers['response'] ) ) );
|
||||
}
|
||||
|
||||
$filesize = filesize( $upload['file'] );
|
||||
|
||||
if ( isset( $headers['content-length'] ) && intval( $headers['content-length'] ) !== $filesize ) {
|
||||
// @codingStandardsIgnoreLine
|
||||
@unlink( $upload['file'] );
|
||||
|
||||
return new WP_Error( 'import_file_error', esc_html__( 'Remote file is incorrect size', 'js_composer' ) );
|
||||
}
|
||||
|
||||
if ( ! $filesize ) {
|
||||
// @codingStandardsIgnoreLine
|
||||
@unlink( $upload['file'] );
|
||||
|
||||
return new WP_Error( 'import_file_error', esc_html__( 'Zero size file downloaded', 'js_composer' ) );
|
||||
}
|
||||
|
||||
$max_size = (int) $this->max_attachment_size();
|
||||
if ( ! empty( $max_size ) && $filesize > $max_size ) {
|
||||
// @codingStandardsIgnoreLine
|
||||
@unlink( $upload['file'] );
|
||||
|
||||
return new WP_Error( 'import_file_error', sprintf( esc_html__( 'Remote file is too large, limit is %s', 'js_composer' ), size_format( $max_size ) ) );
|
||||
}
|
||||
|
||||
// keep track of the old and new urls so we can substitute them later
|
||||
$this->url_remap[ $url ] = $upload['url'];
|
||||
$this->url_remap[ $post['guid'] ] = $upload['url']; // r13735, really needed?
|
||||
// keep track of the destination if the remote url is redirected somewhere else
|
||||
if ( isset( $headers['x-final-location'] ) && $headers['x-final-location'] !== $url ) {
|
||||
$this->url_remap[ $headers['x-final-location'] ] = $upload['url'];
|
||||
}
|
||||
|
||||
return $upload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to associate posts and menu items with previously missing parents
|
||||
*
|
||||
* An imported post's parent may not have been imported when it was first created
|
||||
* so try again. Similarly for child menu items and menu items which were missing
|
||||
* the object (e.g. post) they represent in the menu
|
||||
*/
|
||||
public function backfill_parents() {
|
||||
global $wpdb;
|
||||
|
||||
// find parents for post orphans
|
||||
foreach ( $this->post_orphans as $child_id => $parent_id ) {
|
||||
$local_child_id = false;
|
||||
$local_parent_id = false;
|
||||
if ( isset( $this->processed_posts[ $child_id ] ) ) {
|
||||
$local_child_id = $this->processed_posts[ $child_id ];
|
||||
}
|
||||
if ( isset( $this->processed_posts[ $parent_id ] ) ) {
|
||||
$local_parent_id = $this->processed_posts[ $parent_id ];
|
||||
}
|
||||
|
||||
if ( $local_child_id && $local_parent_id ) {
|
||||
// @codingStandardsIgnoreLine
|
||||
$wpdb->update( $wpdb->posts, array( 'post_parent' => $local_parent_id ), array( 'ID' => $local_child_id ), '%d', '%d' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use stored mapping information to update old attachment URLs
|
||||
*/
|
||||
public function backfill_attachment_urls() {
|
||||
global $wpdb;
|
||||
// make sure we do the longest urls first, in case one is a substring of another
|
||||
uksort( $this->url_remap, array(
|
||||
$this,
|
||||
'cmpr_strlen',
|
||||
) );
|
||||
|
||||
foreach ( $this->url_remap as $from_url => $to_url ) {
|
||||
// remap urls in post_content
|
||||
// @codingStandardsIgnoreLine
|
||||
$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s)", $from_url, $to_url ) );
|
||||
// remap enclosure urls
|
||||
// @codingStandardsIgnoreLine
|
||||
$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_value = REPLACE(meta_value, %s, %s) WHERE meta_key='enclosure'", $from_url, $to_url ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update _thumbnail_id meta to new, imported attachment IDs
|
||||
*/
|
||||
public function remap_featured_images() {
|
||||
// cycle through posts that have a featured image
|
||||
foreach ( $this->featured_images as $post_id => $value ) {
|
||||
if ( isset( $this->processed_posts[ $value ] ) ) {
|
||||
$new_id = $this->processed_posts[ $value ];
|
||||
// only update if there's a difference
|
||||
if ( $new_id !== $value ) {
|
||||
update_post_meta( $post_id, '_thumbnail_id', $new_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a WXR file
|
||||
*
|
||||
* @param string $file Path to WXR file for parsing
|
||||
* @return array Information gathered from the WXR file
|
||||
*/
|
||||
public function parse( $file ) {
|
||||
$parser = new Vc_WXR_Parser();
|
||||
|
||||
return $parser->parse( $file );
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide if the given meta key maps to information we will want to import
|
||||
*
|
||||
* @param string $key The meta key to check
|
||||
* @return string|bool The key if we do want to import, false if not
|
||||
*/
|
||||
public function is_valid_meta_key( $key ) {
|
||||
// skip attachment metadata since we'll regenerate it from scratch
|
||||
// skip _edit_lock as not relevant for import
|
||||
if ( in_array( $key, array(
|
||||
'_wp_attached_file',
|
||||
'_wp_attachment_metadata',
|
||||
'_edit_lock',
|
||||
), true ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide whether or not the importer is allowed to create users.
|
||||
* Default is true, can be filtered via import_allow_create_users
|
||||
*
|
||||
* @return bool True if creating users is allowed
|
||||
*/
|
||||
public function allow_create_users() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide whether or not the importer should attempt to download attachment files.
|
||||
* Default is true, can be filtered via import_allow_fetch_attachments. The choice
|
||||
* made at the import options screen must also be true, false here hides that checkbox.
|
||||
*
|
||||
* @return bool True if downloading attachments is allowed
|
||||
*/
|
||||
public function allow_fetch_attachments() {
|
||||
return apply_filters( 'vc_import_allow_fetch_attachments', true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Decide what the maximum file size for downloaded attachments is.
|
||||
* Default is 0 (unlimited), can be filtered via import_attachment_size_limit
|
||||
*
|
||||
* @return int Maximum attachment file size to import
|
||||
*/
|
||||
public function max_attachment_size() {
|
||||
return apply_filters( 'vc_import_attachment_size_limit', 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* return the difference in length between two strings
|
||||
* @param string $a
|
||||
* @param string $b
|
||||
* @return int
|
||||
*/
|
||||
public function cmpr_strlen( $a, $b ) {
|
||||
return strlen( $b ) - strlen( $a );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Vc_WXR_Parser_Plugin
|
||||
*/
|
||||
class Vc_WXR_Parser_Plugin {
|
||||
public $shortcodes = array(
|
||||
'gallery' => array(
|
||||
'ids',
|
||||
),
|
||||
'vc_single_image' => array(
|
||||
'image',
|
||||
),
|
||||
'vc_gallery' => array(
|
||||
'images',
|
||||
),
|
||||
'vc_images_carousel' => array(
|
||||
'images',
|
||||
),
|
||||
'vc_media_grid' => array(
|
||||
'include',
|
||||
),
|
||||
'vc_masonry_media_grid' => array(
|
||||
'include',
|
||||
),
|
||||
);
|
||||
protected $remaps = 0;
|
||||
|
||||
public function __construct() {
|
||||
$this->shortcodes = apply_filters( 'vc_shared_templates_import_shortcodes', $this->shortcodes );
|
||||
add_filter( 'vc_import_post_data_processed', array(
|
||||
$this,
|
||||
'processPostContent',
|
||||
) );
|
||||
|
||||
add_action( 'vc_import_pre_end', array(
|
||||
$this,
|
||||
'remapIdsInPosts',
|
||||
) );
|
||||
}
|
||||
|
||||
private $idsRemap = array();
|
||||
|
||||
/**
|
||||
* @param array $postdata
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function processPostContent( $postdata ) {
|
||||
if ( ! empty( $postdata['post_content'] ) && 'vc4_templates' === $postdata['post_type'] ) {
|
||||
$this->parseShortcodes( $postdata['post_content'] );
|
||||
}
|
||||
|
||||
return $postdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Vc_WP_Import $importer
|
||||
*/
|
||||
public function remapIdsInPosts( $importer ) {
|
||||
$currentPost = reset( $importer->processed_posts );
|
||||
// Nothing to remap or something wrong
|
||||
if ( ! $currentPost ) {
|
||||
return;
|
||||
}
|
||||
$post = get_post( $currentPost );
|
||||
if ( empty( $post ) || ! is_object( $post ) || 'vc4_templates' !== $post->post_type ) {
|
||||
return;
|
||||
}
|
||||
// We ready to remap attributes in processed attachments
|
||||
$attachments = $importer->processed_attachments;
|
||||
$this->remaps = 0;
|
||||
$newContent = $this->processAttachments( $attachments, $post->post_content );
|
||||
|
||||
if ( $this->remaps ) {
|
||||
$post->post_content = $newContent;
|
||||
wp_update_post( $post );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attachments
|
||||
* @param $content
|
||||
* @return mixed
|
||||
*/
|
||||
protected function processAttachments( $attachments, $content ) {
|
||||
if ( ! empty( $this->idsRemap ) ) {
|
||||
foreach ( $this->idsRemap as $shortcode ) {
|
||||
$tag = $shortcode['tag'];
|
||||
$attributes = $this->shortcodes[ $tag ];
|
||||
$rawQuery = $shortcode['attrs_query'];
|
||||
$newQuery = $this->shortcodeAttributes( $shortcode, $attributes, $rawQuery, $attachments );
|
||||
|
||||
if ( $newQuery ) {
|
||||
$content = str_replace( $rawQuery, $newQuery, $content );
|
||||
$this->remaps ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
$urlRegex = '#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|(?:[^[:punct:]\s]|/))#';
|
||||
$urlMatches = array();
|
||||
preg_match_all( $urlRegex, $content, $urlMatches );
|
||||
if ( ! empty( $urlMatches[0] ) ) {
|
||||
foreach ( $urlMatches[0] as $url ) {
|
||||
$idsMatches = array();
|
||||
preg_match_all( '/id\=(?P<id>\d+)/', $url, $idsMatches );
|
||||
if ( ! empty( $idsMatches['id'] ) ) {
|
||||
$this->remaps = true;
|
||||
$vals = array_map( 'intval', $idsMatches['id'] );
|
||||
$content = $this->remapAttachmentUrls( $attachments, $content, $url, $vals );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attachments
|
||||
* @param $content
|
||||
* @param $url
|
||||
* @param $vals
|
||||
* @return mixed
|
||||
*/
|
||||
protected function remapAttachmentUrls( $attachments, $content, $url, $vals ) {
|
||||
foreach ( $vals as $oldAttachmentId ) {
|
||||
if ( isset( $attachments[ $oldAttachmentId ] ) ) {
|
||||
$newUrl = wp_get_attachment_url( $attachments[ $oldAttachmentId ] );
|
||||
$content = str_replace( $url, $newUrl . '?id=' . $attachments[ $oldAttachmentId ], $content );
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $shortcode
|
||||
* @param $attributes
|
||||
* @param $newQuery
|
||||
* @param $attachments
|
||||
* @return bool|mixed
|
||||
*/
|
||||
protected function shortcodeAttributes( $shortcode, $attributes, $newQuery, $attachments ) {
|
||||
$replacements = 0;
|
||||
foreach ( $attributes as $attribute ) {
|
||||
// for example in vc_single_image 'image' attribute
|
||||
if ( isset( $shortcode['attrs'][ $attribute ] ) ) {
|
||||
$attributeValue = $shortcode['attrs'][ $attribute ];
|
||||
$attributeValues = explode( ',', $attributeValue );
|
||||
$newValues = $attributeValues;
|
||||
array_walk( $newValues, array(
|
||||
$this,
|
||||
'attributesWalker',
|
||||
), array(
|
||||
'attachments' => $attachments,
|
||||
) );
|
||||
$newAttributeValue = implode( ',', $newValues );
|
||||
$newQuery = str_replace( sprintf( '%s="%s"', $attribute, $attributeValue ), sprintf( '%s="%s"', $attribute, $newAttributeValue ), $newQuery );
|
||||
$replacements ++;
|
||||
}
|
||||
}
|
||||
if ( $replacements ) {
|
||||
return $newQuery;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attributeValue
|
||||
* @param $key
|
||||
* @param $data
|
||||
*/
|
||||
public function attributesWalker( &$attributeValue, $key, $data ) {
|
||||
$intValue = intval( $attributeValue );
|
||||
if ( array_key_exists( $intValue, $data['attachments'] ) ) {
|
||||
$attributeValue = $data['attachments'][ $intValue ];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $content
|
||||
* @return array
|
||||
*/
|
||||
private function parseShortcodes( $content ) {
|
||||
WPBMap::addAllMappedShortcodes();
|
||||
preg_match_all( '/' . get_shortcode_regex() . '/', trim( $content ), $found );
|
||||
|
||||
if ( count( $found[2] ) === 0 ) {
|
||||
return $this->idsRemap;
|
||||
}
|
||||
foreach ( $found[2] as $index => $tag ) {
|
||||
$content = $found[5][ $index ];
|
||||
$shortcode = array(
|
||||
'tag' => $tag,
|
||||
'attrs_query' => $found[3][ $index ],
|
||||
'attrs' => shortcode_parse_atts( $found[3][ $index ] ),
|
||||
);
|
||||
if ( array_key_exists( $tag, $this->shortcodes ) ) {
|
||||
$this->idsRemap[] = $shortcode;
|
||||
}
|
||||
$this->idsRemap = $this->parseShortcodes( $content );
|
||||
}
|
||||
|
||||
return $this->idsRemap;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,375 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* WXR Parser that uses regular expressions. Fallback for installs without an XML parser.
|
||||
*/
|
||||
class Vc_WXR_Parser_Regex {
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $authors = array();
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $posts = array();
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $categories = array();
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $tags = array();
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $terms = array();
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $base_url = '';
|
||||
|
||||
/**
|
||||
* Vc_WXR_Parser_Regex constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->has_gzip = is_callable( 'gzopen' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $file
|
||||
* @return array|\WP_Error
|
||||
*/
|
||||
public function parse( $file ) {
|
||||
$wxr_version = false;
|
||||
$in_post = false;
|
||||
|
||||
$fp = $this->fopen( $file, 'r' );
|
||||
if ( $fp ) {
|
||||
while ( ! $this->feof( $fp ) ) {
|
||||
$importline = rtrim( $this->fgets( $fp ) );
|
||||
|
||||
if ( ! $wxr_version && preg_match( '|<wp:wxr_version>(\d+\.\d+)</wp:wxr_version>|', $importline, $version ) ) {
|
||||
$wxr_version = $version[1];
|
||||
}
|
||||
|
||||
if ( false !== strpos( $importline, '<wp:base_site_url>' ) ) {
|
||||
preg_match( '|<wp:base_site_url>(.*?)</wp:base_site_url>|is', $importline, $url );
|
||||
$this->base_url = $url[1];
|
||||
continue;
|
||||
}
|
||||
if ( false !== strpos( $importline, '<wp:category>' ) ) {
|
||||
preg_match( '|<wp:category>(.*?)</wp:category>|is', $importline, $category );
|
||||
$this->categories[] = $this->process_category( $category[1] );
|
||||
continue;
|
||||
}
|
||||
if ( false !== strpos( $importline, '<wp:tag>' ) ) {
|
||||
preg_match( '|<wp:tag>(.*?)</wp:tag>|is', $importline, $tag );
|
||||
$this->tags[] = $this->process_tag( $tag[1] );
|
||||
continue;
|
||||
}
|
||||
if ( false !== strpos( $importline, '<wp:term>' ) ) {
|
||||
preg_match( '|<wp:term>(.*?)</wp:term>|is', $importline, $term );
|
||||
$this->terms[] = $this->process_term( $term[1] );
|
||||
continue;
|
||||
}
|
||||
if ( false !== strpos( $importline, '<wp:author>' ) ) {
|
||||
preg_match( '|<wp:author>(.*?)</wp:author>|is', $importline, $author );
|
||||
$a = $this->process_author( $author[1] );
|
||||
$this->authors[ $a['author_login'] ] = $a;
|
||||
continue;
|
||||
}
|
||||
if ( false !== strpos( $importline, '<item>' ) ) {
|
||||
$post = '';
|
||||
$in_post = true;
|
||||
continue;
|
||||
}
|
||||
if ( false !== strpos( $importline, '</item>' ) ) {
|
||||
$in_post = false;
|
||||
$this->posts[] = $this->process_post( $post );
|
||||
continue;
|
||||
}
|
||||
if ( $in_post ) {
|
||||
$post .= $importline . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
$this->fclose( $fp );
|
||||
}
|
||||
|
||||
if ( ! $wxr_version ) {
|
||||
return new WP_Error( 'WXR_parse_error', esc_html__( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'js_composer' ) );
|
||||
}
|
||||
|
||||
return array(
|
||||
'authors' => $this->authors,
|
||||
'posts' => $this->posts,
|
||||
'categories' => $this->categories,
|
||||
'tags' => $this->tags,
|
||||
'terms' => $this->terms,
|
||||
'base_url' => $this->base_url,
|
||||
'version' => $wxr_version,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $string
|
||||
* @param $tag
|
||||
* @return mixed|string|string[]|null
|
||||
*/
|
||||
public function get_tag( $string, $tag ) {
|
||||
preg_match( "|<$tag.*?>(.*?)</$tag>|is", $string, $return );
|
||||
if ( isset( $return[1] ) ) {
|
||||
if ( substr( $return[1], 0, 9 ) === '<![CDATA[' ) {
|
||||
if ( strpos( $return[1], ']]]]><![CDATA[>' ) !== false ) {
|
||||
preg_match_all( '|<!\[CDATA\[(.*?)\]\]>|s', $return[1], $matches );
|
||||
$return = '';
|
||||
foreach ( $matches[1] as $match ) {
|
||||
$return .= $match;
|
||||
}
|
||||
} else {
|
||||
$return = preg_replace( '|^<!\[CDATA\[(.*)\]\]>$|s', '$1', $return[1] );
|
||||
}
|
||||
} else {
|
||||
$return = $return[1];
|
||||
}
|
||||
} else {
|
||||
$return = '';
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $c
|
||||
* @return array
|
||||
*/
|
||||
public function process_category( $c ) {
|
||||
return array(
|
||||
'term_id' => $this->get_tag( $c, 'wp:term_id' ),
|
||||
'cat_name' => $this->get_tag( $c, 'wp:cat_name' ),
|
||||
'category_nicename' => $this->get_tag( $c, 'wp:category_nicename' ),
|
||||
'category_parent' => $this->get_tag( $c, 'wp:category_parent' ),
|
||||
'category_description' => $this->get_tag( $c, 'wp:category_description' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $t
|
||||
* @return array
|
||||
*/
|
||||
public function process_tag( $t ) {
|
||||
return array(
|
||||
'term_id' => $this->get_tag( $t, 'wp:term_id' ),
|
||||
'tag_name' => $this->get_tag( $t, 'wp:tag_name' ),
|
||||
'tag_slug' => $this->get_tag( $t, 'wp:tag_slug' ),
|
||||
'tag_description' => $this->get_tag( $t, 'wp:tag_description' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $t
|
||||
* @return array
|
||||
*/
|
||||
public function process_term( $t ) {
|
||||
return array(
|
||||
'term_id' => $this->get_tag( $t, 'wp:term_id' ),
|
||||
'term_taxonomy' => $this->get_tag( $t, 'wp:term_taxonomy' ),
|
||||
'slug' => $this->get_tag( $t, 'wp:term_slug' ),
|
||||
'term_parent' => $this->get_tag( $t, 'wp:term_parent' ),
|
||||
'term_name' => $this->get_tag( $t, 'wp:term_name' ),
|
||||
'term_description' => $this->get_tag( $t, 'wp:term_description' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $a
|
||||
* @return array
|
||||
*/
|
||||
public function process_author( $a ) {
|
||||
return array(
|
||||
'author_id' => $this->get_tag( $a, 'wp:author_id' ),
|
||||
'author_login' => $this->get_tag( $a, 'wp:author_login' ),
|
||||
'author_email' => $this->get_tag( $a, 'wp:author_email' ),
|
||||
'author_display_name' => $this->get_tag( $a, 'wp:author_display_name' ),
|
||||
'author_first_name' => $this->get_tag( $a, 'wp:author_first_name' ),
|
||||
'author_last_name' => $this->get_tag( $a, 'wp:author_last_name' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $post
|
||||
* @return array
|
||||
*/
|
||||
public function process_post( $post ) {
|
||||
$post_id = $this->get_tag( $post, 'wp:post_id' );
|
||||
$post_title = $this->get_tag( $post, 'title' );
|
||||
$post_date = $this->get_tag( $post, 'wp:post_date' );
|
||||
$post_date_gmt = $this->get_tag( $post, 'wp:post_date_gmt' );
|
||||
$comment_status = $this->get_tag( $post, 'wp:comment_status' );
|
||||
$ping_status = $this->get_tag( $post, 'wp:ping_status' );
|
||||
$status = $this->get_tag( $post, 'wp:status' );
|
||||
$post_name = $this->get_tag( $post, 'wp:post_name' );
|
||||
$post_parent = $this->get_tag( $post, 'wp:post_parent' );
|
||||
$menu_order = $this->get_tag( $post, 'wp:menu_order' );
|
||||
$post_type = $this->get_tag( $post, 'wp:post_type' );
|
||||
$post_password = $this->get_tag( $post, 'wp:post_password' );
|
||||
$is_sticky = $this->get_tag( $post, 'wp:is_sticky' );
|
||||
$guid = $this->get_tag( $post, 'guid' );
|
||||
$post_author = $this->get_tag( $post, 'dc:creator' );
|
||||
|
||||
$post_excerpt = $this->get_tag( $post, 'excerpt:encoded' );
|
||||
$post_excerpt = preg_replace_callback( '|<(/?[A-Z]+)|', array(
|
||||
$this,
|
||||
'normalize_tag',
|
||||
), $post_excerpt );
|
||||
$post_excerpt = str_replace( '<br>', '<br />', $post_excerpt );
|
||||
$post_excerpt = str_replace( '<hr>', '<hr />', $post_excerpt );
|
||||
|
||||
$post_content = $this->get_tag( $post, 'content:encoded' );
|
||||
$post_content = preg_replace_callback( '|<(/?[A-Z]+)|', array(
|
||||
$this,
|
||||
'normalize_tag',
|
||||
), $post_content );
|
||||
$post_content = str_replace( '<br>', '<br />', $post_content );
|
||||
$post_content = str_replace( '<hr>', '<hr />', $post_content );
|
||||
|
||||
$postdata = compact( 'post_id', 'post_author', 'post_date', 'post_date_gmt', 'post_content', 'post_excerpt', 'post_title', 'status', 'post_name', 'comment_status', 'ping_status', 'guid', 'post_parent', 'menu_order', 'post_type', 'post_password', 'is_sticky' );
|
||||
|
||||
$attachment_url = $this->get_tag( $post, 'wp:attachment_url' );
|
||||
if ( $attachment_url ) {
|
||||
$postdata['attachment_url'] = $attachment_url;
|
||||
}
|
||||
|
||||
preg_match_all( '|<category domain="([^"]+?)" nicename="([^"]+?)">(.+?)</category>|is', $post, $terms, PREG_SET_ORDER );
|
||||
foreach ( $terms as $t ) {
|
||||
$post_terms[] = array(
|
||||
'slug' => $t[2],
|
||||
'domain' => $t[1],
|
||||
'name' => str_replace( array(
|
||||
'<![CDATA[',
|
||||
']]>',
|
||||
), '', $t[3] ),
|
||||
);
|
||||
}
|
||||
if ( ! empty( $post_terms ) ) {
|
||||
$postdata['terms'] = $post_terms;
|
||||
}
|
||||
|
||||
preg_match_all( '|<wp:comment>(.+?)</wp:comment>|is', $post, $comments );
|
||||
$comments = $comments[1];
|
||||
if ( $comments ) {
|
||||
foreach ( $comments as $comment ) {
|
||||
preg_match_all( '|<wp:commentmeta>(.+?)</wp:commentmeta>|is', $comment, $commentmeta );
|
||||
$commentmeta = $commentmeta[1];
|
||||
$c_meta = array();
|
||||
foreach ( $commentmeta as $m ) {
|
||||
$c_meta[] = array(
|
||||
'key' => $this->get_tag( $m, 'wp:meta_key' ),
|
||||
'value' => $this->get_tag( $m, 'wp:meta_value' ),
|
||||
);
|
||||
}
|
||||
|
||||
$post_comments[] = array(
|
||||
'comment_id' => $this->get_tag( $comment, 'wp:comment_id' ),
|
||||
'comment_author' => $this->get_tag( $comment, 'wp:comment_author' ),
|
||||
'comment_author_email' => $this->get_tag( $comment, 'wp:comment_author_email' ),
|
||||
'comment_author_IP' => $this->get_tag( $comment, 'wp:comment_author_IP' ),
|
||||
'comment_author_url' => $this->get_tag( $comment, 'wp:comment_author_url' ),
|
||||
'comment_date' => $this->get_tag( $comment, 'wp:comment_date' ),
|
||||
'comment_date_gmt' => $this->get_tag( $comment, 'wp:comment_date_gmt' ),
|
||||
'comment_content' => $this->get_tag( $comment, 'wp:comment_content' ),
|
||||
'comment_approved' => $this->get_tag( $comment, 'wp:comment_approved' ),
|
||||
'comment_type' => $this->get_tag( $comment, 'wp:comment_type' ),
|
||||
'comment_parent' => $this->get_tag( $comment, 'wp:comment_parent' ),
|
||||
'comment_user_id' => $this->get_tag( $comment, 'wp:comment_user_id' ),
|
||||
'commentmeta' => $c_meta,
|
||||
);
|
||||
}
|
||||
}
|
||||
if ( ! empty( $post_comments ) ) {
|
||||
$postdata['comments'] = $post_comments;
|
||||
}
|
||||
|
||||
preg_match_all( '|<wp:postmeta>(.+?)</wp:postmeta>|is', $post, $postmeta );
|
||||
$postmeta = $postmeta[1];
|
||||
if ( $postmeta ) {
|
||||
foreach ( $postmeta as $p ) {
|
||||
$post_postmeta[] = array(
|
||||
'key' => $this->get_tag( $p, 'wp:meta_key' ),
|
||||
'value' => $this->get_tag( $p, 'wp:meta_value' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
if ( ! empty( $post_postmeta ) ) {
|
||||
$postdata['postmeta'] = $post_postmeta;
|
||||
}
|
||||
|
||||
return $postdata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $matches
|
||||
* @return string
|
||||
*/
|
||||
public function normalize_tag( $matches ) {
|
||||
return '<' . strtolower( $matches[1] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $filename
|
||||
* @param string $mode
|
||||
* @return bool|resource
|
||||
*/
|
||||
public function fopen( $filename, $mode = 'r' ) {
|
||||
if ( $this->has_gzip ) {
|
||||
return gzopen( $filename, $mode );
|
||||
}
|
||||
|
||||
// @codingStandardsIgnoreLine
|
||||
return fopen( $filename, $mode );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fp
|
||||
* @return bool|int
|
||||
*/
|
||||
public function feof( $fp ) {
|
||||
if ( $this->has_gzip ) {
|
||||
return gzeof( $fp );
|
||||
}
|
||||
|
||||
// @codingStandardsIgnoreLine
|
||||
return feof( $fp );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fp
|
||||
* @param int $len
|
||||
* @return bool|string
|
||||
*/
|
||||
public function fgets( $fp, $len = 8192 ) {
|
||||
if ( $this->has_gzip ) {
|
||||
return gzgets( $fp, $len );
|
||||
}
|
||||
|
||||
// @codingStandardsIgnoreLine
|
||||
return fgets( $fp, $len );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $fp
|
||||
* @return bool
|
||||
*/
|
||||
public function fclose( $fp ) {
|
||||
if ( $this->has_gzip ) {
|
||||
return gzclose( $fp );
|
||||
}
|
||||
|
||||
// @codingStandardsIgnoreLine
|
||||
return fclose( $fp );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* WXR Parser that makes use of the SimpleXML PHP extension.
|
||||
*/
|
||||
class Vc_WXR_Parser_SimpleXML {
|
||||
/**
|
||||
* @param $file
|
||||
* @return array|\WP_Error
|
||||
*/
|
||||
public function parse( $file ) {
|
||||
$authors = array();
|
||||
$posts = array();
|
||||
$categories = array();
|
||||
$tags = array();
|
||||
$terms = array();
|
||||
|
||||
$internal_errors = libxml_use_internal_errors( true );
|
||||
|
||||
$dom = new DOMDocument();
|
||||
$old_value = null;
|
||||
if ( function_exists( 'libxml_disable_entity_loader' ) ) {
|
||||
$old_value = libxml_disable_entity_loader( true );
|
||||
}
|
||||
/** @var \WP_Filesystem_Direct $wp_filesystem */
|
||||
global $wp_filesystem;
|
||||
if ( empty( $wp_filesystem ) ) {
|
||||
require_once ABSPATH . '/wp-admin/includes/file.php';
|
||||
WP_Filesystem( false, false, true );
|
||||
}
|
||||
$success = $dom->loadXML( $wp_filesystem->get_contents( $file ) );
|
||||
if ( ! is_null( $old_value ) ) {
|
||||
libxml_disable_entity_loader( $old_value );
|
||||
}
|
||||
|
||||
if ( ! $success || isset( $dom->doctype ) ) {
|
||||
return new WP_Error( 'SimpleXML_parse_error', esc_html__( 'There was an error when reading this WXR file', 'js_composer' ), libxml_get_errors() );
|
||||
}
|
||||
|
||||
$xml = simplexml_import_dom( $dom );
|
||||
unset( $dom );
|
||||
|
||||
// halt if loading produces an error
|
||||
if ( ! $xml ) {
|
||||
return new WP_Error( 'SimpleXML_parse_error', esc_html__( 'There was an error when reading this WXR file', 'js_composer' ), libxml_get_errors() );
|
||||
}
|
||||
|
||||
$wxr_version = $xml->xpath( '/rss/channel/wp:wxr_version' );
|
||||
if ( ! $wxr_version ) {
|
||||
return new WP_Error( 'WXR_parse_error', esc_html__( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'js_composer' ) );
|
||||
}
|
||||
|
||||
$wxr_version = (string) trim( $wxr_version[0] );
|
||||
// confirm that we are dealing with the correct file format
|
||||
if ( ! preg_match( '/^\d+\.\d+$/', $wxr_version ) ) {
|
||||
return new WP_Error( 'WXR_parse_error', esc_html__( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'js_composer' ) );
|
||||
}
|
||||
|
||||
$base_url = $xml->xpath( '/rss/channel/wp:base_site_url' );
|
||||
$base_url = (string) trim( $base_url[0] );
|
||||
|
||||
$namespaces = $xml->getDocNamespaces();
|
||||
if ( ! isset( $namespaces['wp'] ) ) {
|
||||
$namespaces['wp'] = 'http://wordpress.org/export/1.1/';
|
||||
}
|
||||
if ( ! isset( $namespaces['excerpt'] ) ) {
|
||||
$namespaces['excerpt'] = 'http://wordpress.org/export/1.1/excerpt/';
|
||||
}
|
||||
|
||||
// grab authors
|
||||
foreach ( $xml->xpath( '/rss/channel/wp:author' ) as $author_arr ) {
|
||||
$a = $author_arr->children( $namespaces['wp'] );
|
||||
$login = (string) $a->author_login;
|
||||
$authors[ $login ] = array(
|
||||
'author_id' => (int) $a->author_id,
|
||||
'author_login' => $login,
|
||||
'author_email' => (string) $a->author_email,
|
||||
'author_display_name' => (string) $a->author_display_name,
|
||||
'author_first_name' => (string) $a->author_first_name,
|
||||
'author_last_name' => (string) $a->author_last_name,
|
||||
);
|
||||
}
|
||||
|
||||
// grab cats, tags and terms
|
||||
foreach ( $xml->xpath( '/rss/channel/wp:category' ) as $term_arr ) {
|
||||
$t = $term_arr->children( $namespaces['wp'] );
|
||||
$category = array(
|
||||
'term_id' => (int) $t->term_id,
|
||||
'category_nicename' => (string) $t->category_nicename,
|
||||
'category_parent' => (string) $t->category_parent,
|
||||
'cat_name' => (string) $t->cat_name,
|
||||
'category_description' => (string) $t->category_description,
|
||||
);
|
||||
|
||||
foreach ( $t->termmeta as $meta ) {
|
||||
$category['termmeta'][] = array(
|
||||
'key' => (string) $meta->meta_key,
|
||||
'value' => (string) $meta->meta_value,
|
||||
);
|
||||
}
|
||||
|
||||
$categories[] = $category;
|
||||
}
|
||||
|
||||
foreach ( $xml->xpath( '/rss/channel/wp:tag' ) as $term_arr ) {
|
||||
$t = $term_arr->children( $namespaces['wp'] );
|
||||
$tag = array(
|
||||
'term_id' => (int) $t->term_id,
|
||||
'tag_slug' => (string) $t->tag_slug,
|
||||
'tag_name' => (string) $t->tag_name,
|
||||
'tag_description' => (string) $t->tag_description,
|
||||
);
|
||||
|
||||
foreach ( $t->termmeta as $meta ) {
|
||||
$tag['termmeta'][] = array(
|
||||
'key' => (string) $meta->meta_key,
|
||||
'value' => (string) $meta->meta_value,
|
||||
);
|
||||
}
|
||||
|
||||
$tags[] = $tag;
|
||||
}
|
||||
|
||||
foreach ( $xml->xpath( '/rss/channel/wp:term' ) as $term_arr ) {
|
||||
$t = $term_arr->children( $namespaces['wp'] );
|
||||
$term = array(
|
||||
'term_id' => (int) $t->term_id,
|
||||
'term_taxonomy' => (string) $t->term_taxonomy,
|
||||
'slug' => (string) $t->term_slug,
|
||||
'term_parent' => (string) $t->term_parent,
|
||||
'term_name' => (string) $t->term_name,
|
||||
'term_description' => (string) $t->term_description,
|
||||
);
|
||||
|
||||
foreach ( $t->termmeta as $meta ) {
|
||||
$term['termmeta'][] = array(
|
||||
'key' => (string) $meta->meta_key,
|
||||
'value' => (string) $meta->meta_value,
|
||||
);
|
||||
}
|
||||
|
||||
$terms[] = $term;
|
||||
}
|
||||
|
||||
// grab posts
|
||||
foreach ( $xml->channel->item as $item ) {
|
||||
$post = array(
|
||||
'post_title' => (string) $item->title,
|
||||
'guid' => (string) $item->guid,
|
||||
);
|
||||
|
||||
$dc = $item->children( 'http://purl.org/dc/elements/1.1/' );
|
||||
$post['post_author'] = (string) $dc->creator;
|
||||
|
||||
$content = $item->children( 'http://purl.org/rss/1.0/modules/content/' );
|
||||
$excerpt = $item->children( $namespaces['excerpt'] );
|
||||
$post['post_content'] = (string) $content->encoded;
|
||||
$post['post_excerpt'] = (string) $excerpt->encoded;
|
||||
|
||||
$wp = $item->children( $namespaces['wp'] );
|
||||
$post['post_id'] = (int) $wp->post_id;
|
||||
$post['post_date'] = (string) $wp->post_date;
|
||||
$post['post_date_gmt'] = (string) $wp->post_date_gmt;
|
||||
$post['comment_status'] = (string) $wp->comment_status;
|
||||
$post['ping_status'] = (string) $wp->ping_status;
|
||||
$post['post_name'] = (string) $wp->post_name;
|
||||
$post['status'] = (string) $wp->status;
|
||||
$post['post_parent'] = (int) $wp->post_parent;
|
||||
$post['menu_order'] = (int) $wp->menu_order;
|
||||
$post['post_type'] = (string) $wp->post_type;
|
||||
$post['post_password'] = (string) $wp->post_password;
|
||||
$post['is_sticky'] = (int) $wp->is_sticky;
|
||||
|
||||
if ( isset( $wp->attachment_url ) ) {
|
||||
$post['attachment_url'] = (string) $wp->attachment_url;
|
||||
}
|
||||
|
||||
foreach ( $item->category as $c ) {
|
||||
$att = $c->attributes();
|
||||
if ( isset( $att['nicename'] ) ) {
|
||||
$post['terms'][] = array(
|
||||
'name' => (string) $c,
|
||||
'slug' => (string) $att['nicename'],
|
||||
'domain' => (string) $att['domain'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $wp->postmeta as $meta ) {
|
||||
$post['postmeta'][] = array(
|
||||
'key' => (string) $meta->meta_key,
|
||||
'value' => (string) $meta->meta_value,
|
||||
);
|
||||
}
|
||||
|
||||
foreach ( $wp->comment as $comment ) {
|
||||
$meta = array();
|
||||
if ( isset( $comment->commentmeta ) ) {
|
||||
foreach ( $comment->commentmeta as $m ) {
|
||||
$meta[] = array(
|
||||
'key' => (string) $m->meta_key,
|
||||
'value' => (string) $m->meta_value,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$post['comments'][] = array(
|
||||
'comment_id' => (int) $comment->comment_id,
|
||||
'comment_author' => (string) $comment->comment_author,
|
||||
'comment_author_email' => (string) $comment->comment_author_email,
|
||||
'comment_author_IP' => (string) $comment->comment_author_IP,
|
||||
'comment_author_url' => (string) $comment->comment_author_url,
|
||||
'comment_date' => (string) $comment->comment_date,
|
||||
'comment_date_gmt' => (string) $comment->comment_date_gmt,
|
||||
'comment_content' => (string) $comment->comment_content,
|
||||
'comment_approved' => (string) $comment->comment_approved,
|
||||
'comment_type' => (string) $comment->comment_type,
|
||||
'comment_parent' => (string) $comment->comment_parent,
|
||||
'comment_user_id' => (int) $comment->comment_user_id,
|
||||
'commentmeta' => $meta,
|
||||
);
|
||||
}
|
||||
|
||||
$posts[] = $post;
|
||||
}
|
||||
|
||||
return array(
|
||||
'authors' => $authors,
|
||||
'posts' => $posts,
|
||||
'categories' => $categories,
|
||||
'tags' => $tags,
|
||||
'terms' => $terms,
|
||||
'base_url' => $base_url,
|
||||
'version' => $wxr_version,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* WXR Parser that makes use of the XML Parser PHP extension.
|
||||
*/
|
||||
class Vc_WXR_Parser_XML {
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $wp_tags = array(
|
||||
'wp:post_id',
|
||||
'wp:post_date',
|
||||
'wp:post_date_gmt',
|
||||
'wp:comment_status',
|
||||
'wp:ping_status',
|
||||
'wp:attachment_url',
|
||||
'wp:status',
|
||||
'wp:post_name',
|
||||
'wp:post_parent',
|
||||
'wp:menu_order',
|
||||
'wp:post_type',
|
||||
'wp:post_password',
|
||||
'wp:is_sticky',
|
||||
'wp:term_id',
|
||||
'wp:category_nicename',
|
||||
'wp:category_parent',
|
||||
'wp:cat_name',
|
||||
'wp:category_description',
|
||||
'wp:tag_slug',
|
||||
'wp:tag_name',
|
||||
'wp:tag_description',
|
||||
'wp:term_taxonomy',
|
||||
'wp:term_parent',
|
||||
'wp:term_name',
|
||||
'wp:term_description',
|
||||
'wp:author_id',
|
||||
'wp:author_login',
|
||||
'wp:author_email',
|
||||
'wp:author_display_name',
|
||||
'wp:author_first_name',
|
||||
'wp:author_last_name',
|
||||
);
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $wp_sub_tags = array(
|
||||
'wp:comment_id',
|
||||
'wp:comment_author',
|
||||
'wp:comment_author_email',
|
||||
'wp:comment_author_url',
|
||||
'wp:comment_author_IP',
|
||||
'wp:comment_date',
|
||||
'wp:comment_date_gmt',
|
||||
'wp:comment_content',
|
||||
'wp:comment_approved',
|
||||
'wp:comment_type',
|
||||
'wp:comment_parent',
|
||||
'wp:comment_user_id',
|
||||
);
|
||||
|
||||
/**
|
||||
* @param $file
|
||||
* @return array|\WP_Error
|
||||
*/
|
||||
public function parse( $file ) {
|
||||
$this->wxr_version = false;
|
||||
$this->in_post = false;
|
||||
$this->cdata = false;
|
||||
$this->data = false;
|
||||
$this->sub_data = false;
|
||||
$this->in_tag = false;
|
||||
$this->in_sub_tag = false;
|
||||
|
||||
$this->authors = array();
|
||||
$this->posts = array();
|
||||
$this->term = array();
|
||||
$this->category = array();
|
||||
$this->tag = array();
|
||||
|
||||
$xml = xml_parser_create( 'UTF-8' );
|
||||
xml_parser_set_option( $xml, XML_OPTION_SKIP_WHITE, 1 );
|
||||
xml_parser_set_option( $xml, XML_OPTION_CASE_FOLDING, 0 );
|
||||
xml_set_object( $xml, $this );
|
||||
xml_set_character_data_handler( $xml, 'cdata' );
|
||||
xml_set_element_handler( $xml, 'tag_open', 'tag_close' );
|
||||
|
||||
/** @var \WP_Filesystem_Direct $wp_filesystem */ global $wp_filesystem;
|
||||
if ( empty( $wp_filesystem ) ) {
|
||||
require_once ABSPATH . '/wp-admin/includes/file.php';
|
||||
WP_Filesystem( false, false, true );
|
||||
}
|
||||
if ( ! xml_parse( $xml, $wp_filesystem->get_contents( $file ), true ) ) {
|
||||
$current_line = xml_get_current_line_number( $xml );
|
||||
$current_column = xml_get_current_column_number( $xml );
|
||||
$error_code = xml_get_error_code( $xml );
|
||||
$error_string = xml_error_string( $error_code );
|
||||
|
||||
return new WP_Error( 'XML_parse_error', 'There was an error when reading this WXR file', array(
|
||||
$current_line,
|
||||
$current_column,
|
||||
$error_string,
|
||||
) );
|
||||
}
|
||||
xml_parser_free( $xml );
|
||||
|
||||
if ( ! preg_match( '/^\d+\.\d+$/', $this->wxr_version ) ) {
|
||||
return new WP_Error( 'WXR_parse_error', esc_html__( 'This does not appear to be a WXR file, missing/invalid WXR version number', 'js_composer' ) );
|
||||
}
|
||||
|
||||
return array(
|
||||
'authors' => $this->authors,
|
||||
'posts' => $this->posts,
|
||||
'categories' => $this->category,
|
||||
'tags' => $this->tag,
|
||||
'terms' => $this->term,
|
||||
'base_url' => $this->base_url,
|
||||
'version' => $this->wxr_version,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $parse
|
||||
* @param $tag
|
||||
* @param $attr
|
||||
*/
|
||||
public function tag_open( $parse, $tag, $attr ) {
|
||||
if ( in_array( $tag, $this->wp_tags, true ) ) {
|
||||
$this->in_tag = substr( $tag, 3 );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( in_array( $tag, $this->wp_sub_tags, true ) ) {
|
||||
$this->in_sub_tag = substr( $tag, 3 );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( $tag ) {
|
||||
case 'category':
|
||||
if ( isset( $attr['domain'], $attr['nicename'] ) ) {
|
||||
$this->sub_data['domain'] = $attr['domain'];
|
||||
$this->sub_data['slug'] = $attr['nicename'];
|
||||
}
|
||||
break;
|
||||
case 'item':
|
||||
$this->in_post = true;
|
||||
if ( $this->in_post ) {
|
||||
$this->in_tag = 'post_title';
|
||||
}
|
||||
break;
|
||||
case 'title':
|
||||
if ( $this->in_post ) {
|
||||
$this->in_tag = 'post_title';
|
||||
}
|
||||
break;
|
||||
case 'guid':
|
||||
$this->in_tag = 'guid';
|
||||
break;
|
||||
case 'dc:creator':
|
||||
$this->in_tag = 'post_author';
|
||||
break;
|
||||
case 'content:encoded':
|
||||
$this->in_tag = 'post_content';
|
||||
break;
|
||||
case 'excerpt:encoded':
|
||||
$this->in_tag = 'post_excerpt';
|
||||
break;
|
||||
|
||||
case 'wp:term_slug':
|
||||
$this->in_tag = 'slug';
|
||||
break;
|
||||
case 'wp:meta_key':
|
||||
$this->in_sub_tag = 'key';
|
||||
break;
|
||||
case 'wp:meta_value':
|
||||
$this->in_sub_tag = 'value';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $parser
|
||||
* @param $cdata
|
||||
*/
|
||||
public function cdata( $parser, $cdata ) {
|
||||
if ( ! trim( $cdata ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( false !== $this->in_tag || false !== $this->in_sub_tag ) {
|
||||
$this->cdata .= $cdata;
|
||||
} else {
|
||||
$this->cdata .= trim( $cdata );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $parser
|
||||
* @param $tag
|
||||
*/
|
||||
public function tag_close( $parser, $tag ) {
|
||||
switch ( $tag ) {
|
||||
case 'wp:comment':
|
||||
unset( $this->sub_data['key'], $this->sub_data['value'] ); // remove meta sub_data
|
||||
if ( ! empty( $this->sub_data ) ) {
|
||||
$this->data['comments'][] = $this->sub_data;
|
||||
}
|
||||
$this->sub_data = false;
|
||||
break;
|
||||
case 'wp:commentmeta':
|
||||
$this->sub_data['commentmeta'][] = array(
|
||||
'key' => $this->sub_data['key'],
|
||||
'value' => $this->sub_data['value'],
|
||||
);
|
||||
break;
|
||||
case 'category':
|
||||
if ( ! empty( $this->sub_data ) ) {
|
||||
$this->sub_data['name'] = $this->cdata;
|
||||
$this->data['terms'][] = $this->sub_data;
|
||||
}
|
||||
$this->sub_data = false;
|
||||
break;
|
||||
case 'wp:postmeta':
|
||||
if ( ! empty( $this->sub_data ) ) {
|
||||
$this->data['postmeta'][] = $this->sub_data;
|
||||
}
|
||||
$this->sub_data = false;
|
||||
break;
|
||||
case 'item':
|
||||
$this->posts[] = $this->data;
|
||||
$this->data = false;
|
||||
break;
|
||||
case 'wp:category':
|
||||
case 'wp:tag':
|
||||
case 'wp:term':
|
||||
$n = substr( $tag, 3 );
|
||||
array_push( $this->$n, $this->data );
|
||||
$this->data = false;
|
||||
break;
|
||||
case 'wp:author':
|
||||
if ( ! empty( $this->data['author_login'] ) ) {
|
||||
$this->authors[ $this->data['author_login'] ] = $this->data;
|
||||
}
|
||||
$this->data = false;
|
||||
break;
|
||||
case 'wp:base_site_url':
|
||||
$this->base_url = $this->cdata;
|
||||
break;
|
||||
case 'wp:wxr_version':
|
||||
$this->wxr_version = $this->cdata;
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( $this->in_sub_tag ) {
|
||||
$this->sub_data[ $this->in_sub_tag ] = ! empty( $this->cdata ) ? $this->cdata : '';
|
||||
$this->in_sub_tag = false;
|
||||
} elseif ( $this->in_tag ) {
|
||||
$this->data[ $this->in_tag ] = ! empty( $this->cdata ) ? $this->cdata : '';
|
||||
$this->in_tag = false;
|
||||
}
|
||||
}
|
||||
|
||||
$this->cdata = false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
require_once dirname( __FILE__ ) . '/class-vc-wxr-parser-regex.php';
|
||||
require_once dirname( __FILE__ ) . '/class-vc-wxr-parser-simplexml.php';
|
||||
require_once dirname( __FILE__ ) . '/class-vc-wxr-parser-xml.php';
|
||||
/**
|
||||
* WordPress eXtended RSS file parser implementations
|
||||
*
|
||||
* @package WordPress
|
||||
* @subpackage Importer
|
||||
*/
|
||||
|
||||
/**
|
||||
* WordPress Importer class for managing parsing of WXR files.
|
||||
*/
|
||||
class Vc_WXR_Parser {
|
||||
/**
|
||||
* @param $file
|
||||
* @return array|\WP_Error
|
||||
*/
|
||||
public function parse( $file ) {
|
||||
// Attempt to use proper XML parsers first
|
||||
if ( extension_loaded( 'simplexml' ) ) {
|
||||
$parser = new Vc_WXR_Parser_SimpleXML();
|
||||
$result = $parser->parse( $file );
|
||||
|
||||
// If SimpleXML succeeds or this is an invalid WXR file then return the results
|
||||
if ( ! is_wp_error( $result ) || 'SimpleXML_parse_error' !== $result->get_error_code() ) {
|
||||
return $result;
|
||||
}
|
||||
} elseif ( extension_loaded( 'xml' ) ) {
|
||||
$parser = new Vc_WXR_Parser_XML();
|
||||
$result = $parser->parse( $file );
|
||||
|
||||
// If XMLParser succeeds or this is an invalid WXR file then return the results
|
||||
if ( ! is_wp_error( $result ) || 'XML_parse_error' !== $result->get_error_code() ) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
// We have a malformed XML file, so display the error and fallthrough to regex
|
||||
if ( isset( $result ) && defined( 'IMPORT_DEBUG' ) && IMPORT_DEBUG ) {
|
||||
echo '<pre>';
|
||||
if ( 'SimpleXML_parse_error' === $result->get_error_code() ) {
|
||||
foreach ( $result->get_error_data() as $error ) {
|
||||
echo esc_html( $error->line . ':' . $error->column ) . ' ' . esc_html( $error->message ) . "\n";
|
||||
}
|
||||
} elseif ( 'XML_parse_error' === $result->get_error_code() ) {
|
||||
$error = $result->get_error_data();
|
||||
echo esc_html( $error[0] . ':' . $error[1] ) . ' ' . esc_html( $error[2] );
|
||||
}
|
||||
echo '</pre>';
|
||||
echo '<p><strong>' . esc_html__( 'There was an error when reading this WXR file', 'js_composer' ) . '</strong><br />';
|
||||
echo esc_html__( 'Details are shown above. The importer will now try again with a different parser...', 'js_composer' ) . '</p>';
|
||||
}
|
||||
|
||||
// use regular expressions if nothing else available or this is bad XML
|
||||
$parser = new Vc_WXR_Parser_Regex();
|
||||
|
||||
return $parser->parse( $file );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to register new shortcode attribute hook.
|
||||
*
|
||||
* @param $name - attribute name
|
||||
* @param $form_field_callback - hook, will be called when settings form is shown and attribute added to shortcode
|
||||
* param list
|
||||
* @param $script_url - javascript file url which will be attached at the end of settings form.
|
||||
*
|
||||
* @return bool
|
||||
* @deprecated due to without prefix name 4.4
|
||||
* @since 4.2
|
||||
*/
|
||||
function add_shortcode_param( $name, $form_field_callback, $script_url = null ) {
|
||||
_deprecated_function( 'add_shortcode_param', '4.4 (will be removed in 6.0)', 'vc_add_shortcode_param' );
|
||||
|
||||
return vc_add_shortcode_param( $name, $form_field_callback, $script_url );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|string
|
||||
* @since 4.2
|
||||
* @deprecated 4.2
|
||||
*/
|
||||
function get_row_css_class() {
|
||||
_deprecated_function( 'get_row_css_class', '4.2 (will be removed in 6.0)' );
|
||||
$custom = vc_settings()->get( 'row_css_class' );
|
||||
|
||||
return ! empty( $custom ) ? $custom : 'vc_row-fluid';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @deprecated 5.2
|
||||
*/
|
||||
function vc_generate_dependencies_attributes() {
|
||||
_deprecated_function( 'vc_generate_dependencies_attributes', '5.1', '' );
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract width/height from string
|
||||
*
|
||||
* @param string $dimensions WxH
|
||||
* @return mixed array(width, height) or false
|
||||
* @since 4.7
|
||||
*
|
||||
* @deprecated since 5.8
|
||||
*/
|
||||
function vcExtractDimensions( $dimensions ) {
|
||||
_deprecated_function( 'vcExtractDimensions', '5.8', 'vc_extract_dimensions' );
|
||||
|
||||
return vc_extract_dimensions( $dimensions );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $images IDs or srcs of images
|
||||
* @return string
|
||||
* @since 4.2
|
||||
* @deprecated since 2019, 5.8
|
||||
*/
|
||||
function fieldAttachedImages( $images = array() ) {
|
||||
_deprecated_function( 'fieldAttachedImages', '5.8', 'vc_field_attached_images' );
|
||||
|
||||
return vc_field_attached_images( $images );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $asset
|
||||
*
|
||||
* @return array|string
|
||||
* @deprecated
|
||||
*/
|
||||
function getVcShared( $asset = '' ) {
|
||||
|
||||
return vc_get_shared( $asset );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a action param for ajax
|
||||
* @return bool
|
||||
* @since 4.8
|
||||
* @deprecated 6.1
|
||||
*/
|
||||
function vc_wp_action() {
|
||||
_deprecated_function( 'vc_wp_action', '6.1', 'vc_request_param' );
|
||||
|
||||
return vc_request_param( 'action' );
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
* @deprecated since 5.8
|
||||
* Interface for editors
|
||||
*/
|
||||
interface Vc_Editor_Interface {
|
||||
/**
|
||||
* @return mixed
|
||||
* @deprecated 5.8
|
||||
* @since 4.3
|
||||
*/
|
||||
public function renderEditor();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
* @deprecated 5.8
|
||||
* Default render interface
|
||||
*/
|
||||
interface Vc_Render {
|
||||
/**
|
||||
* @return mixed
|
||||
* @deprecated 5.8
|
||||
* @since 4.3
|
||||
*/
|
||||
public function render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.3
|
||||
* @deprecated 5.8
|
||||
* Interface for third-party plugins classes loader.
|
||||
*/
|
||||
interface Vc_Vendor_Interface {
|
||||
/**
|
||||
* @return mixed
|
||||
* @deprecated 5.8
|
||||
* @since 4.3
|
||||
*/
|
||||
public function load();
|
||||
}
|
||||
@@ -0,0 +1,304 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* WPBakery WPBakery Page Builder admin editor
|
||||
*
|
||||
* @package WPBakeryPageBuilder
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* VC backend editor.
|
||||
*
|
||||
* This editor is available on default Wp post/page admin edit page. ON admin_init callback adds meta box to
|
||||
* edit page.
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
class Vc_Backend_Editor {
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $layout;
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public $post_custom_css;
|
||||
/**
|
||||
* @var bool|string $post - stores data about post.
|
||||
*/
|
||||
public $post = false;
|
||||
|
||||
/**
|
||||
* This method is called by Vc_Manager to register required action hooks for VC backend editor.
|
||||
*
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*/
|
||||
public function addHooksSettings() {
|
||||
// @todo - fix_roles do this only if be editor is enabled.
|
||||
// load backend editor
|
||||
if ( function_exists( 'add_theme_support' ) ) {
|
||||
add_theme_support( 'post-thumbnails' ); // @todo check is it needed?
|
||||
}
|
||||
add_action( 'add_meta_boxes', array(
|
||||
$this,
|
||||
'render',
|
||||
), 5 );
|
||||
add_action( 'admin_print_scripts-post.php', array(
|
||||
$this,
|
||||
'registerScripts',
|
||||
) );
|
||||
add_action( 'admin_print_scripts-post-new.php', array(
|
||||
$this,
|
||||
'registerScripts',
|
||||
) );
|
||||
add_action( 'admin_print_scripts-post.php', array(
|
||||
$this,
|
||||
'printScriptsMessages',
|
||||
) );
|
||||
add_action( 'admin_print_scripts-post-new.php', array(
|
||||
$this,
|
||||
'printScriptsMessages',
|
||||
) );
|
||||
|
||||
}
|
||||
|
||||
public function registerScripts() {
|
||||
$this->registerBackendJavascript();
|
||||
$this->registerBackendCss();
|
||||
// B.C:
|
||||
visual_composer()->registerAdminCss();
|
||||
visual_composer()->registerAdminJavascript();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls add_meta_box to create Editor block. Block is rendered by WPBakeryVisualComposerLayout.
|
||||
*
|
||||
* @param $post_type
|
||||
* @throws \Exception
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*
|
||||
* @see WPBakeryVisualComposerLayout
|
||||
*/
|
||||
public function render( $post_type ) {
|
||||
if ( $this->isValidPostType( $post_type ) ) {
|
||||
// meta box to render
|
||||
add_meta_box( 'wpb_visual_composer', esc_html__( 'WPBakery Page Builder', 'js_composer' ), array(
|
||||
$this,
|
||||
'renderEditor',
|
||||
), $post_type, 'normal', 'high' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output html for backend editor meta box.
|
||||
*
|
||||
* @param null|Wp_Post $post
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function renderEditor( $post = null ) {
|
||||
/**
|
||||
* TODO: setter/getter for $post
|
||||
*/
|
||||
if ( ! is_object( $post ) || 'WP_Post' !== get_class( $post ) || ! isset( $post->ID ) ) {
|
||||
return false;
|
||||
}
|
||||
$this->post = $post;
|
||||
$post_custom_css = wp_strip_all_tags( get_post_meta( $post->ID, '_wpb_post_custom_css', true ) );
|
||||
$this->post_custom_css = $post_custom_css;
|
||||
vc_include_template( 'editors/backend_editor.tpl.php', array(
|
||||
'editor' => $this,
|
||||
'post' => $this->post,
|
||||
) );
|
||||
add_action( 'admin_footer', array(
|
||||
$this,
|
||||
'renderEditorFooter',
|
||||
) );
|
||||
do_action( 'vc_backend_editor_render' );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output required html and js content for VC editor.
|
||||
*
|
||||
* Here comes panels, modals and js objects with data for mapped shortcodes.
|
||||
*/
|
||||
public function renderEditorFooter() {
|
||||
vc_include_template( 'editors/partials/backend_editor_footer.tpl.php', array(
|
||||
'editor' => $this,
|
||||
'post' => $this->post,
|
||||
) );
|
||||
do_action( 'vc_backend_editor_footer_render' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is post type is valid for rendering VC backend editor.
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function isValidPostType( $type = '' ) {
|
||||
$type = ! empty( $type ) ? $type : get_post_type();
|
||||
if ( 'vc_grid_item' === $type ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return apply_filters( 'vc_is_valid_post_type_be', vc_check_post_type( $type ), $type );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue required javascript libraries and css files.
|
||||
*
|
||||
* This method also setups reminder about license activation.
|
||||
*
|
||||
* @since 4.2
|
||||
* @access public
|
||||
*/
|
||||
public function printScriptsMessages() {
|
||||
if ( ! vc_is_frontend_editor() && $this->isValidPostType( get_post_type() ) ) {
|
||||
$this->enqueueEditorScripts();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue required javascript libraries and css files.
|
||||
*
|
||||
* @since 4.8
|
||||
* @access public
|
||||
*/
|
||||
public function enqueueEditorScripts() {
|
||||
if ( $this->editorEnabled() ) {
|
||||
$this->enqueueJs();
|
||||
$this->enqueueCss();
|
||||
WPBakeryShortCodeFishBones::enqueueCss();
|
||||
WPBakeryShortCodeFishBones::enqueueJs();
|
||||
} else {
|
||||
wp_enqueue_script( 'vc-backend-actions-js' );
|
||||
$this->enqueueCss(); // needed for navbar @todo split
|
||||
}
|
||||
do_action( 'vc_backend_editor_enqueue_js_css' );
|
||||
}
|
||||
|
||||
public function registerBackendJavascript() {
|
||||
// editor can be disabled but fe can be enabled. so we currently need this file. @todo maybe make backend-disabled.min.js
|
||||
wp_register_script( 'vc-backend-actions-js', vc_asset_url( 'js/dist/backend-actions.min.js' ), array(
|
||||
'jquery',
|
||||
'backbone',
|
||||
'underscore',
|
||||
), WPB_VC_VERSION, true );
|
||||
wp_register_script( 'vc-backend-min-js', vc_asset_url( 'js/dist/backend.min.js' ), array( 'vc-backend-actions-js' ), WPB_VC_VERSION, true );
|
||||
// used in tta shortcodes, and panels.
|
||||
wp_register_script( 'vc_accordion_script', vc_asset_url( 'lib/vc_accordion/vc-accordion.min.js' ), array( 'jquery' ), WPB_VC_VERSION, true );
|
||||
wp_register_script( 'wpb_php_js', vc_asset_url( 'lib/php.default/php.default.min.js' ), array( 'jquery' ), WPB_VC_VERSION, true );
|
||||
// used as polyfill for JSON.stringify and etc
|
||||
wp_register_script( 'wpb_json-js', vc_asset_url( 'lib/bower/json-js/json2.min.js' ), array(), WPB_VC_VERSION, true );
|
||||
// used in post settings editor
|
||||
wp_register_script( 'ace-editor', vc_asset_url( 'lib/bower/ace-builds/src-min-noconflict/ace.js' ), array( 'jquery' ), WPB_VC_VERSION, true );
|
||||
wp_register_script( 'webfont', 'https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js', array(), WPB_VC_VERSION, true ); // Google Web Font CDN
|
||||
|
||||
wp_localize_script( 'vc-backend-actions-js', 'i18nLocale', visual_composer()->getEditorsLocale() );
|
||||
}
|
||||
|
||||
public function registerBackendCss() {
|
||||
wp_register_style( 'js_composer', vc_asset_url( 'css/js_composer_backend_editor.min.css' ), array(), WPB_VC_VERSION, false );
|
||||
|
||||
if ( $this->editorEnabled() ) {
|
||||
/**
|
||||
* @deprecated, used for accordions/tabs/tours
|
||||
*/
|
||||
wp_register_style( 'ui-custom-theme', vc_asset_url( 'css/ui-custom-theme/jquery-ui-less.custom.min.css' ), array(), WPB_VC_VERSION );
|
||||
|
||||
/**
|
||||
* @todo check vc_add-element-deprecated-warning for fa icon usage ( set to our font )
|
||||
* also used in vc_icon shortcode
|
||||
*/
|
||||
wp_register_style( 'vc_font_awesome_5_shims', vc_asset_url( 'lib/bower/font-awesome/css/v4-shims.min.css' ), array(), WPB_VC_VERSION );
|
||||
wp_register_style( 'vc_font_awesome_5', vc_asset_url( 'lib/bower/font-awesome/css/all.min.css' ), array( 'vc_font_awesome_5_shims' ), WPB_VC_VERSION );
|
||||
/**
|
||||
* @todo check for usages
|
||||
* definetelly used in edit form param: css_animation, but curreny vc_add_shortcode_param doesn't accept css [ @todo refactor that ]
|
||||
*/
|
||||
wp_register_style( 'vc_animate-css', vc_asset_url( 'lib/bower/animate-css/animate.min.css' ), array(), WPB_VC_VERSION );
|
||||
}
|
||||
}
|
||||
|
||||
public function enqueueJs() {
|
||||
$wp_dependencies = array(
|
||||
'jquery',
|
||||
'underscore',
|
||||
'backbone',
|
||||
'media-views',
|
||||
'media-editor',
|
||||
'wp-pointer',
|
||||
'mce-view',
|
||||
'wp-color-picker',
|
||||
'jquery-ui-sortable',
|
||||
'jquery-ui-droppable',
|
||||
'jquery-ui-draggable',
|
||||
'jquery-ui-autocomplete',
|
||||
'jquery-ui-resizable',
|
||||
// used in @deprecated tabs
|
||||
'jquery-ui-tabs',
|
||||
'jquery-ui-accordion',
|
||||
);
|
||||
$dependencies = array(
|
||||
'vc_accordion_script',
|
||||
'wpb_php_js',
|
||||
// used in our files [e.g. edit form saving sprintf]
|
||||
'wpb_json-js',
|
||||
'ace-editor',
|
||||
'webfont',
|
||||
'vc-backend-min-js',
|
||||
);
|
||||
|
||||
// This workaround will allow to disable any of dependency on-the-fly
|
||||
foreach ( $wp_dependencies as $dependency ) {
|
||||
wp_enqueue_script( $dependency );
|
||||
}
|
||||
foreach ( $dependencies as $dependency ) {
|
||||
wp_enqueue_script( $dependency );
|
||||
}
|
||||
}
|
||||
|
||||
public function enqueueCss() {
|
||||
$wp_dependencies = array(
|
||||
'wp-color-picker',
|
||||
'farbtastic',
|
||||
// deprecated for tabs/accordion
|
||||
'ui-custom-theme',
|
||||
// used in deprecated message and also in vc-icon shortcode
|
||||
'vc_font_awesome_5',
|
||||
// used in css_animation edit form param
|
||||
'vc_animate-css',
|
||||
);
|
||||
$dependencies = array(
|
||||
'js_composer',
|
||||
);
|
||||
|
||||
// This workaround will allow to disable any of dependency on-the-fly
|
||||
foreach ( $wp_dependencies as $dependency ) {
|
||||
wp_enqueue_style( $dependency );
|
||||
}
|
||||
foreach ( $dependencies as $dependency ) {
|
||||
wp_enqueue_style( $dependency );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function editorEnabled() {
|
||||
return vc_user_access()->part( 'backend_editor' )->can()->get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,315 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* WPBakery WPBakery Page Builder shortcode attributes fields
|
||||
*
|
||||
* @package WPBakeryPageBuilder
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Edit form fields builder for shortcode attributes.
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
class Vc_Edit_Form_Fields {
|
||||
/**
|
||||
* @since 4.4
|
||||
* @var bool
|
||||
*/
|
||||
protected $tag = false;
|
||||
/**
|
||||
* @since 4.4
|
||||
* @var array
|
||||
*/
|
||||
protected $atts = array();
|
||||
/**
|
||||
* @since 4.4
|
||||
* @var array
|
||||
*/
|
||||
protected $settings = array();
|
||||
/**
|
||||
* @since 4.4
|
||||
* @var bool
|
||||
*/
|
||||
protected $post_id = false;
|
||||
|
||||
/**
|
||||
* Construct Form fields.
|
||||
*
|
||||
* @param $tag - shortcode tag
|
||||
* @param $atts - list of attribute assign to the shortcode.
|
||||
* @throws \Exception
|
||||
* @since 4.4
|
||||
*/
|
||||
public function __construct( $tag, $atts ) {
|
||||
$this->tag = $tag;
|
||||
$this->atts = apply_filters( 'vc_edit_form_fields_attributes_' . $this->tag, $atts );
|
||||
$this->setSettings( WPBMap::getShortCode( $this->tag ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get settings
|
||||
* @param $key
|
||||
*
|
||||
* @return null
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function setting( $key ) {
|
||||
return isset( $this->settings[ $key ] ) ? $this->settings[ $key ] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set settings data
|
||||
* @param array $settings
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function setSettings( array $settings ) {
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcode Post ID getter.
|
||||
* If post id isn't set try to get from get_the_ID function.
|
||||
* @return int|bool;
|
||||
* @since 4.4
|
||||
*/
|
||||
public function postId() {
|
||||
if ( ! $this->post_id ) {
|
||||
$this->post_id = get_the_ID();
|
||||
}
|
||||
|
||||
return $this->post_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcode Post ID setter.
|
||||
* @param $post_id - integer value in post_id
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function setPostId( $post_id ) {
|
||||
$this->post_id = (int) $post_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shortcode attribute value.
|
||||
*
|
||||
* This function checks if value isn't set then it uses std or value fields in param settings.
|
||||
* @param $param_settings
|
||||
* @param $value
|
||||
*
|
||||
* @return null
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
protected function parseShortcodeAttributeValue( $param_settings, $value ) {
|
||||
if ( is_null( $value ) ) { // If value doesn't exists
|
||||
if ( isset( $param_settings['std'] ) ) {
|
||||
$value = $param_settings['std'];
|
||||
} elseif ( isset( $param_settings['value'] ) && is_array( $param_settings['value'] ) && ! empty( $param_settings['type'] ) && 'checkbox' !== $param_settings['type'] ) {
|
||||
$first_key = key( $param_settings['value'] );
|
||||
$value = $first_key ? $param_settings['value'][ $first_key ] : '';
|
||||
} elseif ( isset( $param_settings['value'] ) && ! is_array( $param_settings['value'] ) ) {
|
||||
$value = $param_settings['value'];
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue js scripts for attributes types.
|
||||
* @return string
|
||||
* @since 4.4
|
||||
*/
|
||||
public function enqueueScripts() {
|
||||
$output = '';
|
||||
$scripts = apply_filters( 'vc_edit_form_enqueue_script', WpbakeryShortcodeParams::getScripts() );
|
||||
if ( is_array( $scripts ) ) {
|
||||
foreach ( $scripts as $script ) {
|
||||
$custom_tag = 'script';
|
||||
// @todo Check posibility to use wp_add_inline_script
|
||||
// @codingStandardsIgnoreLine
|
||||
$output .= '<' . $custom_tag . ' src="' . esc_url( $script ) . '"></' . $custom_tag . '>';
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render grouped fields.
|
||||
* @param $groups
|
||||
* @param $groups_content
|
||||
*
|
||||
* @return string
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
protected function renderGroupedFields( $groups, $groups_content ) {
|
||||
$output = '';
|
||||
if ( count( $groups ) > 1 || ( count( $groups ) >= 1 && empty( $groups_content['_general'] ) ) ) {
|
||||
$output .= '<div class="vc_panel-tabs" id="vc_edit-form-tabs">';
|
||||
$output .= '<ul class="vc_general vc_ui-tabs-line" data-vc-ui-element="panel-tabs-controls">';
|
||||
$key = 0;
|
||||
foreach ( $groups as $g ) {
|
||||
$output .= '<li class="vc_edit-form-tab-control" data-tab-index="' . esc_attr( $key ) . '"><button data-vc-ui-element-target="#vc_edit-form-tab-' . ( $key ++ ) . '" class="vc_ui-tabs-line-trigger" data-vc-ui-element="panel-tab-control">' . ( '_general' === $g ? esc_html__( 'General', 'js_composer' ) : $g ) . '</button></li>';
|
||||
}
|
||||
$output .= '<li class="vc_ui-tabs-line-dropdown-toggle" data-vc-action="dropdown"
|
||||
data-vc-content=".vc_ui-tabs-line-dropdown" data-vc-ui-element="panel-tabs-line-toggle">
|
||||
<span class="vc_ui-tabs-line-trigger" data-vc-accordion
|
||||
data-vc-container=".vc_ui-tabs-line-dropdown-toggle"
|
||||
data-vc-target=".vc_ui-tabs-line-dropdown"> </span>
|
||||
<ul class="vc_ui-tabs-line-dropdown" data-vc-ui-element="panel-tabs-line-dropdown">
|
||||
</ul>
|
||||
</ul>';
|
||||
|
||||
$key = 0;
|
||||
foreach ( $groups as $g ) {
|
||||
$output .= '<div id="vc_edit-form-tab-' . ( $key ++ ) . '" class="vc_edit-form-tab vc_row vc_ui-flex-row" data-vc-ui-element="panel-edit-element-tab">';
|
||||
$output .= $groups_content[ $g ];
|
||||
$output .= '</div>';
|
||||
}
|
||||
$output .= '</div>';
|
||||
} elseif ( ! empty( $groups_content['_general'] ) ) {
|
||||
$output .= '<div class="vc_edit-form-tab vc_row vc_ui-flex-row vc_active" data-vc-ui-element="panel-edit-element-tab">' . $groups_content['_general'] . '</div>';
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render fields html and output it.
|
||||
* @since 4.4
|
||||
* vc_filter: vc_edit_form_class - filter to override editor_css_classes array
|
||||
*/
|
||||
public function render() {
|
||||
$this->loadDefaultParams();
|
||||
$output = $el_position = '';
|
||||
$groups_content = $groups = array();
|
||||
$params = $this->setting( 'params' );
|
||||
$editor_css_classes = apply_filters( 'vc_edit_form_class', array(
|
||||
'wpb_edit_form_elements',
|
||||
'vc_edit_form_elements',
|
||||
), $this->atts, $params );
|
||||
$deprecated = $this->setting( 'deprecated' );
|
||||
require_once vc_path_dir( 'AUTOLOAD_DIR', 'class-vc-settings-presets.php' );
|
||||
// TODO: check presets 6.0
|
||||
// $list_vendor_presets = Vc_Settings_Preset::listVendorSettingsPresets( $this->tag );
|
||||
// $list_presets = Vc_Settings_Preset::listSettingsPresets( $this->tag );
|
||||
$show_settings = false;
|
||||
|
||||
$saveAsTemplateElements = apply_filters( 'vc_popup_save_as_template_elements', array(
|
||||
'vc_row',
|
||||
'vc_section',
|
||||
) );
|
||||
|
||||
$show_presets = ! in_array( $this->tag, $saveAsTemplateElements, true ) && vc_user_access()->part( 'presets' )->checkStateAny( true, null )->get();
|
||||
|
||||
if ( in_array( $this->tag, $saveAsTemplateElements, true ) && vc_user_access()->part( 'templates' )->checkStateAny( true, null )->get() ) {
|
||||
$show_settings = true;
|
||||
}
|
||||
$custom_tag = 'script';
|
||||
$output .= sprintf( '<' . $custom_tag . '>window.vc_presets_show=%s;</' . $custom_tag . '>', $show_presets ? 'true' : 'false' );
|
||||
$output .= sprintf( '<' . $custom_tag . '>window.vc_settings_show=%s;</' . $custom_tag . '>', $show_presets || $show_settings ? 'true' : 'false' );
|
||||
|
||||
if ( ! empty( $deprecated ) ) {
|
||||
$output .= '<div class="vc_row vc_ui-flex-row vc_shortcode-edit-form-deprecated-message"><div class="vc_col-sm-12 wpb_element_wrapper">' . vc_message_warning( sprintf( esc_html__( 'You are using outdated element, it is deprecated since version %s.', 'js_composer' ), $this->setting( 'deprecated' ) ) ) . '</div></div>';
|
||||
}
|
||||
$output .= '<div class="' . implode( ' ', $editor_css_classes ) . '" data-title="' . esc_attr__( 'Edit', 'js_composer' ) . ' ' . esc_attr( $this->setting( 'name' ) ) . '">';
|
||||
if ( is_array( $params ) ) {
|
||||
foreach ( $params as $param ) {
|
||||
$name = isset( $param['param_name'] ) ? $param['param_name'] : null;
|
||||
if ( ! is_null( $name ) ) {
|
||||
$value = isset( $this->atts[ $name ] ) ? $this->atts[ $name ] : null;
|
||||
$value = $this->parseShortcodeAttributeValue( $param, $value );
|
||||
$group = isset( $param['group'] ) && '' !== $param['group'] ? $param['group'] : '_general';
|
||||
if ( ! isset( $groups_content[ $group ] ) ) {
|
||||
$groups[] = $group;
|
||||
$groups_content[ $group ] = '';
|
||||
}
|
||||
$groups_content[ $group ] .= $this->renderField( $param, $value );
|
||||
}
|
||||
}
|
||||
}
|
||||
$output .= $this->renderGroupedFields( $groups, $groups_content );
|
||||
$output .= '</div>';
|
||||
$output .= $this->enqueueScripts();
|
||||
|
||||
// @codingStandardsIgnoreLine
|
||||
echo $output;
|
||||
do_action( 'vc_edit_form_fields_after_render' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate html for shortcode attribute.
|
||||
*
|
||||
* Method
|
||||
* @param $param
|
||||
* @param $value
|
||||
*
|
||||
* vc_filter: vc_single_param_edit - hook to edit any shortode param
|
||||
* vc_filter: vc_form_fields_render_field_{shortcode_name}_{param_name}_param_value - hook to edit shortcode param
|
||||
* value vc_filter: vc_form_fields_render_field_{shortcode_name}_{param_name}_param - hook to edit shortcode
|
||||
* param attributes vc_filter: vc_single_param_edit_holder_output - hook to edit output of this method
|
||||
*
|
||||
* @return mixed
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function renderField( $param, $value ) {
|
||||
$param['vc_single_param_edit_holder_class'] = array(
|
||||
'wpb_el_type_' . $param['type'],
|
||||
'vc_wrapper-param-type-' . $param['type'],
|
||||
'vc_shortcode-param',
|
||||
'vc_column',
|
||||
);
|
||||
if ( ! empty( $param['param_holder_class'] ) ) {
|
||||
$param['vc_single_param_edit_holder_class'][] = $param['param_holder_class'];
|
||||
}
|
||||
$param = apply_filters( 'vc_single_param_edit', $param, $value );
|
||||
$output = '<div class="' . implode( ' ', $param['vc_single_param_edit_holder_class'] ) . '" data-vc-ui-element="panel-shortcode-param" data-vc-shortcode-param-name="' . esc_attr( $param['param_name'] ) . '" data-param_type="' . esc_attr( $param['type'] ) . '" data-param_settings="' . esc_attr( htmlentities( wp_json_encode( $param ) ) ) . '">';
|
||||
$output .= ( isset( $param['heading'] ) ) ? '<div class="wpb_element_label">' . $param['heading'] . '</div>' : '';
|
||||
$output .= '<div class="edit_form_line">';
|
||||
$value = apply_filters( 'vc_form_fields_render_field_' . $this->setting( 'base' ) . '_' . $param['param_name'] . '_param_value', $value, $param, $this->settings, $this->atts );
|
||||
$param = apply_filters( 'vc_form_fields_render_field_' . $this->setting( 'base' ) . '_' . $param['param_name'] . '_param', $param, $value, $this->settings, $this->atts );
|
||||
$output = apply_filters( 'vc_edit_form_fields_render_field_' . $param['type'] . '_before', $output );
|
||||
$output .= vc_do_shortcode_param_settings_field( $param['type'], $param, $value, $this->setting( 'base' ) );
|
||||
$output_after = '';
|
||||
if ( isset( $param['description'] ) ) {
|
||||
$output_after .= '<span class="vc_description vc_clearfix">' . $param['description'] . '</span>';
|
||||
}
|
||||
$output_after .= '</div></div>';
|
||||
$output .= apply_filters( 'vc_edit_form_fields_render_field_' . $param['type'] . '_after', $output_after );
|
||||
|
||||
return apply_filters( 'vc_single_param_edit_holder_output', $output, $param, $value, $this->settings, $this->atts );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create default shortcode params
|
||||
*
|
||||
* List of params stored in global variable $vc_params_list.
|
||||
* Please check include/params/load.php for default params list.
|
||||
* @return bool
|
||||
* @since 4.4
|
||||
*/
|
||||
public function loadDefaultParams() {
|
||||
global $vc_params_list;
|
||||
if ( empty( $vc_params_list ) ) {
|
||||
return false;
|
||||
}
|
||||
$script_url = vc_asset_url( 'js/dist/edit-form.min.js' );
|
||||
foreach ( $vc_params_list as $param ) {
|
||||
vc_add_shortcode_param( $param, 'vc_' . $param . '_form_field', $script_url );
|
||||
}
|
||||
do_action( 'vc_load_default_params' );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
require_once vc_path_dir( 'EDITORS_DIR', 'navbar/class-vc-navbar.php' );
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Vc_Navbar_Frontend extends Vc_Navbar {
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $controls = array(
|
||||
'add_element',
|
||||
'templates',
|
||||
'view_post',
|
||||
'save_update',
|
||||
'screen_size',
|
||||
'custom_css',
|
||||
);
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $controls_filter_name = 'vc_nav_front_controls';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $brand_url = 'https://wpbakery.com/?utm_campaign=VCplugin&utm_source=vc_user&utm_medium=frontend_editor';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $css_class = 'vc_navbar vc_navbar-frontend';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getControlScreenSize() {
|
||||
$disable_responsive = vc_settings()->get( 'not_responsive_css' );
|
||||
if ( '1' !== $disable_responsive ) {
|
||||
$screen_sizes = array(
|
||||
array(
|
||||
'title' => esc_html__( 'Desktop', 'js_composer' ),
|
||||
'size' => '100%',
|
||||
'key' => 'default',
|
||||
'active' => true,
|
||||
),
|
||||
array(
|
||||
'title' => esc_html__( 'Tablet landscape mode', 'js_composer' ),
|
||||
'size' => '1024px',
|
||||
'key' => 'landscape-tablets',
|
||||
),
|
||||
array(
|
||||
'title' => esc_html__( 'Tablet portrait mode', 'js_composer' ),
|
||||
'size' => '768px',
|
||||
'key' => 'portrait-tablets',
|
||||
),
|
||||
array(
|
||||
'title' => esc_html__( 'Smartphone landscape mode', 'js_composer' ),
|
||||
'size' => '480px',
|
||||
'key' => 'landscape-smartphones',
|
||||
),
|
||||
array(
|
||||
'title' => esc_html__( 'Smartphone portrait mode', 'js_composer' ),
|
||||
'size' => '320px',
|
||||
'key' => 'portrait-smartphones',
|
||||
),
|
||||
);
|
||||
$output = '<li class="vc_pull-right">' . '<div class="vc_dropdown" id="vc_screen-size-control">' . '<a href="#" class="vc_dropdown-toggle"' . ' title="' . esc_attr__( 'Responsive preview', 'js_composer' ) . '"><i class="vc-composer-icon vc_current-layout-icon vc-c-icon-layout_default"' . ' id="vc_screen-size-current"></i><i class="vc-composer-icon vc-c-icon-arrow_drop_down"></i></a>' . '<ul class="vc_dropdown-list">';
|
||||
$screen = current( $screen_sizes );
|
||||
while ( $screen ) {
|
||||
$output .= '<li><a href="#" title="' . esc_attr( $screen['title'] ) . '"' . ' class="vc_screen-width vc-composer-icon vc-c-icon-layout_' . esc_attr( $screen['key'] ) . ( isset( $screen['active'] ) && $screen['active'] ? ' active' : '' ) . '" data-size="' . esc_attr( $screen['size'] ) . '"></a></li>';
|
||||
next( $screen_sizes );
|
||||
$screen = current( $screen_sizes );
|
||||
}
|
||||
$output .= '</ul></div></li>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getControlSaveUpdate() {
|
||||
$post = $this->post();
|
||||
$post_type = get_post_type_object( $this->post->post_type );
|
||||
$can_publish = current_user_can( $post_type->cap->publish_posts );
|
||||
ob_start();
|
||||
?>
|
||||
<li class="vc_show-mobile vc_pull-right">
|
||||
<button data-url="<?php echo esc_attr( get_edit_post_link( $post->ID ) . '&wpb_vc_js_status=true&classic-editor' ); ?>"
|
||||
class="vc_btn vc_btn-default vc_btn-sm vc_navbar-btn vc_btn-backend-editor" id="vc_button-cancel"
|
||||
title="<?php esc_attr_e( 'Cancel all changes and return to WP dashboard', 'js_composer' ); ?>">
|
||||
<?php
|
||||
echo vc_user_access()->part( 'backend_editor' )->can()->get() ? esc_html__( 'Backend Editor', 'js_composer' ) : esc_html__( 'Edit', 'js_composer' );
|
||||
?>
|
||||
</button>
|
||||
<?php
|
||||
if ( ! in_array( $post->post_status, array(
|
||||
'publish',
|
||||
'future',
|
||||
'private',
|
||||
), true ) ) :
|
||||
?>
|
||||
<?php if ( 'draft' === $post->post_status ) : ?>
|
||||
<button type="button" class="vc_btn vc_btn-default vc_btn-sm vc_navbar-btn vc_btn-save-draft"
|
||||
id="vc_button-save-draft"
|
||||
title="<?php esc_attr_e( 'Save Draft', 'js_composer' ); ?>"><?php esc_html_e( 'Save Draft', 'js_composer' ); ?></button>
|
||||
<?php elseif ( 'pending' === $post->post_status && $can_publish ) : ?>
|
||||
<button type="button" class="vc_btn vc_btn-primary vc_btn-sm vc_navbar-btn vc_btn-save"
|
||||
id="vc_button-save-as-pending"
|
||||
title="<?php esc_attr_e( 'Save as Pending', 'js_composer' ); ?>"><?php esc_html_e( 'Save as Pending', 'js_composer' ); ?></button>
|
||||
<?php endif ?>
|
||||
<?php if ( $can_publish ) : ?>
|
||||
<button type="button" class="vc_btn vc_btn-primary vc_btn-sm vc_navbar-btn vc_btn-save"
|
||||
id="vc_button-update" title="<?php esc_attr_e( 'Publish', 'js_composer' ); ?>"
|
||||
data-change-status="publish"><?php esc_html_e( 'Publish', 'js_composer' ); ?></button>
|
||||
<?php else : ?>
|
||||
<button type="button" class="vc_btn vc_btn-primary vc_btn-sm vc_navbar-btn vc_btn-save"
|
||||
id="vc_button-update" title="<?php esc_attr_e( 'Submit for Review', 'js_composer' ); ?>"
|
||||
data-change-status="pending"><?php esc_html_e( 'Submit for Review', 'js_composer' ); ?></button>
|
||||
<?php endif ?>
|
||||
<?php else : ?>
|
||||
<button type="button" class="vc_btn vc_btn-primary vc_btn-sm vc_navbar-btn vc_btn-save"
|
||||
id="vc_button-update"
|
||||
title="<?php esc_attr_e( 'Update', 'js_composer' ); ?>"><?php esc_html_e( 'Update', 'js_composer' ); ?></button>
|
||||
<?php endif ?>
|
||||
</li>
|
||||
<?php
|
||||
$output = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getControlViewPost() {
|
||||
return '<li class="vc_pull-right">' . '<a href="' . esc_url( get_permalink( $this->post() ) ) . '" class="vc_icon-btn vc_back-button"' . ' title="' . esc_attr__( 'Exit WPBakery Page Builder edit mode', 'js_composer' ) . '"><i class="vc-composer-icon vc-c-icon-close"></i></a>' . '</li>';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Vc_Navbar_Undoredo
|
||||
*/
|
||||
class Vc_Navbar_Undoredo {
|
||||
public function __construct() {
|
||||
// Backend
|
||||
add_filter( 'vc_nav_controls', array(
|
||||
$this,
|
||||
'addControls',
|
||||
) );
|
||||
|
||||
// Frontend
|
||||
add_filter( 'vc_nav_front_controls', array(
|
||||
$this,
|
||||
'addControls',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $controls
|
||||
* @return array
|
||||
*/
|
||||
public function addControls( $controls ) {
|
||||
$controls[] = array(
|
||||
'redo',
|
||||
'<li class="vc_pull-right"><a id="vc_navbar-redo" href="javascript:;" class="vc_icon-btn" disabled title="' . esc_attr__( 'Redo', 'js_composer' ) . '"><i class="vc_navbar-icon fa fa-repeat"></i></a></li>',
|
||||
);
|
||||
$controls[] = array(
|
||||
'undo',
|
||||
'<li class="vc_pull-right"><a id="vc_navbar-undo" href="javascript:;" class="vc_icon-btn" disabled title="' . esc_attr__( 'Undo', 'js_composer' ) . '"><i class="vc_navbar-icon fa fa-undo"></i></a></li>',
|
||||
);
|
||||
|
||||
return $controls;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders navigation bar for Editors.
|
||||
*/
|
||||
class Vc_Navbar {
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $controls = array(
|
||||
'add_element',
|
||||
'templates',
|
||||
'save_backend',
|
||||
'preview',
|
||||
'frontend',
|
||||
'custom_css',
|
||||
'fullscreen',
|
||||
'windowed',
|
||||
);
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $brand_url = 'https://wpbakery.com/?utm_campaign=VCplugin&utm_source=vc_user&utm_medium=backend_editor';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $css_class = 'vc_navbar';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $controls_filter_name = 'vc_nav_controls';
|
||||
/**
|
||||
* @var bool|WP_Post
|
||||
*/
|
||||
protected $post = false;
|
||||
|
||||
/**
|
||||
* @param WP_Post $post
|
||||
*/
|
||||
public function __construct( WP_Post $post ) {
|
||||
$this->post = $post;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate array of controls by iterating property $controls list.
|
||||
* vc_filter: vc_nav_controls - hook to override list of controls
|
||||
* @return array - list of arrays witch contains key name and html output for button.
|
||||
*/
|
||||
public function getControls() {
|
||||
$control_list = array();
|
||||
foreach ( $this->controls as $control ) {
|
||||
$method = vc_camel_case( 'get_control_' . $control );
|
||||
if ( method_exists( $this, $method ) ) {
|
||||
$control_list[] = array(
|
||||
$control,
|
||||
$this->$method(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return apply_filters( $this->controls_filter_name, $control_list );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current post.
|
||||
* @return null|WP_Post
|
||||
*/
|
||||
public function post() {
|
||||
if ( $this->post ) {
|
||||
return $this->post;
|
||||
} else {
|
||||
$this->post = get_post();
|
||||
}
|
||||
|
||||
return $this->post;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render template.
|
||||
*/
|
||||
public function render() {
|
||||
vc_include_template( 'editors/navbar/navbar.tpl.php', array(
|
||||
'css_class' => $this->css_class,
|
||||
'controls' => $this->getControls(),
|
||||
'nav_bar' => $this,
|
||||
'post' => $this->post(),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* vc_filter: vc_nav_front_logo - hook to override WPBakery Page Builder logo
|
||||
* @return string
|
||||
*/
|
||||
public function getLogo() {
|
||||
$output = '<a id="vc_logo" class="vc_navbar-brand" title="' . esc_attr__( 'WPBakery Page Builder', 'js_composer' ) . '" href="' . esc_url( $this->brand_url ) . '" target="_blank">' . esc_attr__( 'WPBakery Page Builder', 'js_composer' ) . '</a>';
|
||||
|
||||
return apply_filters( 'vc_nav_front_logo', $output );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getControlCustomCss() {
|
||||
if ( ! vc_user_access()->part( 'post_settings' )->can()->get() ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '<li class="vc_pull-right"><a id="vc_post-settings-button" href="javascript:;" class="vc_icon-btn vc_post-settings" title="' . esc_attr__( 'Page settings', 'js_composer' ) . '">' . '<span id="vc_post-css-badge" class="vc_badge vc_badge-custom-css" style="display: none;">' . esc_attr__( 'CSS', 'js_composer' ) . '</span><i class="vc-composer-icon vc-c-icon-cog"></i></a>' . '</li>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getControlFullscreen() {
|
||||
return '<li class="vc_show-mobile vc_pull-right">' . '<a id="vc_fullscreen-button" class="vc_icon-btn vc_fullscreen-button" title="' . esc_attr__( 'Full screen', 'js_composer' ) . '"><i class="vc-composer-icon vc-c-icon-fullscreen"></i></a>' . '</li>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getControlWindowed() {
|
||||
return '<li class="vc_show-mobile vc_pull-right">' . '<a id="vc_windowed-button" class="vc_icon-btn vc_windowed-button" title="' . esc_attr__( 'Exit full screen', 'js_composer' ) . '"><i class="vc-composer-icon vc-c-icon-fullscreen_exit"></i></a>' . '</li>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getControlAddElement() {
|
||||
if ( vc_user_access()->part( 'shortcodes' )->checkStateAny( true, 'custom', null )
|
||||
->get() && vc_user_access_check_shortcode_all( 'vc_row' ) && vc_user_access_check_shortcode_all( 'vc_column' ) ) {
|
||||
return '<li class="vc_show-mobile">' . ' <a href="javascript:;" class="vc_icon-btn vc_element-button" data-model-id="vc_element" id="vc_add-new-element" title="' . '' . esc_attr__( 'Add new element', 'js_composer' ) . '">' . ' <i class="vc-composer-icon vc-c-icon-add_element"></i>' . ' </a>' . '</li>';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getControlTemplates() {
|
||||
if ( ! vc_user_access()->part( 'templates' )->can()->get() ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '<li><a href="javascript:;" class="vc_icon-btn vc_templates-button" id="vc_templates-editor-button" title="' . esc_attr__( 'Templates', 'js_composer' ) . '"><i class="vc-composer-icon vc-c-icon-add_template"></i></a></li>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getControlFrontend() {
|
||||
if ( ! vc_enabled_frontend() ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '<li class="vc_pull-right" style="display: none;">' . '<a href="' . esc_url( vc_frontend_editor()->getInlineUrl() ) . '" class="vc_btn vc_btn-primary vc_btn-sm vc_navbar-btn" id="wpb-edit-inline">' . esc_html__( 'Frontend', 'js_composer' ) . '</a>' . '</li>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getControlPreview() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getControlSaveBackend() {
|
||||
return '<li class="vc_pull-right vc_save-backend">' . '<a href="javascript:;" class="vc_btn vc_btn-grey vc_btn-sm vc_navbar-btn vc_control-preview">' . esc_attr__( 'Preview', 'js_composer' ) . '</a>' . '<a class="vc_btn vc_btn-sm vc_navbar-btn vc_btn-primary vc_control-save" id="wpb-save-post">' . esc_attr__( 'Update', 'js_composer' ) . '</a>' . '</li>';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add element for VC editors with a list of mapped shortcodes.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
class Vc_Add_Element_Box {
|
||||
/**
|
||||
* Enable show empty message
|
||||
*
|
||||
* @since 4.8
|
||||
* @var bool
|
||||
*/
|
||||
protected $show_empty_message = false;
|
||||
|
||||
/**
|
||||
* @param $params
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getIcon( $params ) {
|
||||
$data = '';
|
||||
if ( isset( $params['is_container'] ) && true === $params['is_container'] ) {
|
||||
$data = ' data-is-container="true"';
|
||||
}
|
||||
|
||||
return '<i class="vc_general vc_element-icon' . ( ! empty( $params['icon'] ) ? ' ' . esc_attr( sanitize_text_field( $params['icon'] ) ) : '' ) . '" ' . $data . '></i> ';
|
||||
}
|
||||
|
||||
/**
|
||||
* Single button html template
|
||||
*
|
||||
* @param $params
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderButton( $params ) {
|
||||
if ( ! is_array( $params ) || empty( $params ) ) {
|
||||
return '';
|
||||
}
|
||||
$output = $class = $class_out = $data = $category_css_classes = '';
|
||||
if ( ! empty( $params['class'] ) ) {
|
||||
$class_ar = $class_at_out = explode( ' ', $params['class'] );
|
||||
$count = count( $class_ar );
|
||||
for ( $n = 0; $n < $count; $n ++ ) {
|
||||
$class_ar[ $n ] .= '_nav';
|
||||
$class_at_out[ $n ] .= '_o';
|
||||
}
|
||||
$class = ' ' . implode( ' ', $class_ar );
|
||||
$class_out = ' ' . implode( ' ', $class_at_out );
|
||||
}
|
||||
if ( isset( $params['_category_ids'] ) ) {
|
||||
foreach ( $params['_category_ids'] as $id ) {
|
||||
$category_css_classes .= ' js-category-' . $id;
|
||||
}
|
||||
}
|
||||
if ( isset( $params['is_container'] ) && true === $params['is_container'] ) {
|
||||
$data .= ' data-is-container="true"';
|
||||
}
|
||||
$data .= ' data-vc-ui-element="add-element-button"';
|
||||
$description = ! empty( $params['description'] ) ? '<span class="vc_element-description">' . htmlspecialchars( esc_html( $params['description'] ), ENT_QUOTES, 'UTF-8' ) . '</span>' : '';
|
||||
$name = '<span data-vc-shortcode-name>' . htmlspecialchars( esc_html( stripslashes( $params['name'] ) ), ENT_QUOTES, 'UTF-8' ) . '</span>';
|
||||
$output .= '<li data-element="' . esc_attr( $params['base'] ) . '" ' . ( isset( $params['presetId'] ) ? 'data-preset="' . esc_attr( $params['presetId'] ) . '"' : '' ) . ' class="wpb-layout-element-button vc_col-xs-12 vc_col-sm-4 vc_col-md-3 vc_col-lg-2' . ( isset( $params['deprecated'] ) ? ' vc_element-deprecated' : '' ) . esc_attr( $category_css_classes ) . esc_attr( $class_out ) . '" ' . $data . '><div class="vc_el-container"><a id="' . esc_attr( $params['base'] ) . '" data-tag="' . esc_attr( $params['base'] ) . '" class="dropable_el vc_shortcode-link' . esc_attr( $class ) . '" href="javascript:;" data-vc-clickable>' . $this->getIcon( $params ) . $name . $description . '</a></div></li>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mapped shortcodes list.
|
||||
*
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
* @since 4.4
|
||||
*/
|
||||
public function shortcodes() {
|
||||
return apply_filters( 'vc_add_new_elements_to_box', WPBMap::getSortedUserShortCodes() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render list of buttons for each mapped and allowed VC shortcodes.
|
||||
* vc_filter: vc_add_element_box_buttons - hook to override output of getControls method
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
* @see WPBMap::getSortedUserShortCodes
|
||||
*/
|
||||
public function getControls() {
|
||||
$output = '<ul class="wpb-content-layouts">';
|
||||
/** @var array $element */
|
||||
$buttons_count = 0;
|
||||
$shortcodes = $this->shortcodes();
|
||||
foreach ( $shortcodes as $element ) {
|
||||
if ( isset( $element['content_element'] ) && false === $element['content_element'] ) {
|
||||
continue;
|
||||
}
|
||||
$button = $this->renderButton( $element );
|
||||
if ( ! empty( $button ) ) {
|
||||
$buttons_count ++;
|
||||
}
|
||||
$output .= $button;
|
||||
}
|
||||
$output .= '</ul>';
|
||||
if ( 0 === $buttons_count ) {
|
||||
$this->show_empty_message = true;
|
||||
}
|
||||
|
||||
return apply_filters( 'vc_add_element_box_buttons', $output );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get categories list from mapping data.
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
* @since 4.5
|
||||
*/
|
||||
public function getCategories() {
|
||||
return apply_filters( 'vc_add_new_category_filter', WPBMap::getUserCategories() );
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function render() {
|
||||
vc_include_template( 'editors/popups/vc_ui-panel-add-element.tpl.php', array(
|
||||
'box' => $this,
|
||||
'template_variables' => array(
|
||||
'categories' => $this->getCategories(),
|
||||
),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render icon for shortcode
|
||||
*
|
||||
* @param $params
|
||||
*
|
||||
* @return string
|
||||
* @since 4.8
|
||||
*/
|
||||
public function renderIcon( $params ) {
|
||||
return $this->getIcon( $params );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isShowEmptyMessage() {
|
||||
return $this->show_empty_message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getPartState() {
|
||||
return vc_user_access()->part( 'shortcodes' )->getState();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit row layout
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
class Vc_Edit_Layout {
|
||||
public function renderUITemplate() {
|
||||
global $vc_row_layouts;
|
||||
vc_include_template( 'editors/popups/vc_ui-panel-row-layout.tpl.php', array(
|
||||
'vc_row_layouts' => $vc_row_layouts,
|
||||
) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Post settings like custom css for page are displayed here.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
class Vc_Post_Settings {
|
||||
protected $editor;
|
||||
|
||||
/**
|
||||
* @param $editor
|
||||
*/
|
||||
public function __construct( $editor ) {
|
||||
$this->editor = $editor;
|
||||
}
|
||||
|
||||
public function editor() {
|
||||
return $this->editor;
|
||||
}
|
||||
|
||||
public function renderUITemplate() {
|
||||
vc_include_template( 'editors/popups/vc_ui-panel-post-settings.tpl.php', array(
|
||||
'box' => $this,
|
||||
) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Vc_Preset_Panel_Editor
|
||||
* @since 5.2
|
||||
*/
|
||||
class Vc_Preset_Panel_Editor {
|
||||
/**
|
||||
* @since 5.2
|
||||
* @var bool
|
||||
*/
|
||||
protected $initialized = false;
|
||||
|
||||
/**
|
||||
* @since 5.2
|
||||
* Add ajax hooks, filters.
|
||||
*/
|
||||
public function init() {
|
||||
if ( $this->initialized ) {
|
||||
return;
|
||||
}
|
||||
$this->initialized = true;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.2
|
||||
*/
|
||||
public function renderUIPreset() {
|
||||
vc_include_template( 'editors/popups/vc_ui-panel-preset.tpl.php', array(
|
||||
'box' => $this,
|
||||
) );
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of all presets for specific shortcode
|
||||
*
|
||||
* @return array E.g. array(id1 => title1, id2 => title2, ...)
|
||||
* @since 5.2
|
||||
*
|
||||
*
|
||||
*/
|
||||
public function listPresets() {
|
||||
$list = array();
|
||||
|
||||
$args = array(
|
||||
'post_type' => 'vc_settings_preset',
|
||||
'orderby' => array( 'post_date' => 'DESC' ),
|
||||
'posts_per_page' => - 1,
|
||||
);
|
||||
|
||||
$posts = get_posts( $args );
|
||||
foreach ( $posts as $post ) {
|
||||
|
||||
$presetParentName = self::constructPresetParent( $post->post_mime_type );
|
||||
|
||||
$list[ $post->ID ] = array(
|
||||
'title' => $post->post_title,
|
||||
'parent' => $presetParentName,
|
||||
);
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Single preset html
|
||||
*
|
||||
* @return string
|
||||
* @since 5.2
|
||||
*
|
||||
*
|
||||
*/
|
||||
public function getPresets() {
|
||||
$listPresets = $this->listPresets();
|
||||
$output = '';
|
||||
|
||||
foreach ( $listPresets as $presetId => $preset ) {
|
||||
$output .= '<div class="vc_ui-template">';
|
||||
$output .= '<div class="vc_ui-list-bar-item">';
|
||||
$output .= '<button type="button" class="vc_ui-list-bar-item-trigger" title="' . esc_attr( $preset['title'] ) . '"
|
||||
data-vc-ui-element="template-title">' . esc_html( $preset['title'] ) . '</button>';
|
||||
$output .= '<div class="vc_ui-list-bar-item-actions">';
|
||||
|
||||
$output .= '<button id="' . esc_attr( $preset['parent'] ) . '" type="button" class="vc_general vc_ui-control-button" title="' . esc_attr( 'Add element', 'js_composer' ) . '" data-template-handler="" data-preset="' . esc_attr( $presetId ) . '" data-tag="' . esc_attr( $preset['parent'] ) . '" data-vc-ui-add-preset>';
|
||||
$output .= '<i class="vc-composer-icon vc-c-icon-add"></i>';
|
||||
$output .= '</button>';
|
||||
|
||||
$output .= '<button type="button" class="vc_general vc_ui-control-button" data-vc-ui-delete="preset-title" data-preset="' . esc_attr( $presetId ) . '" data-preset-parent="' . esc_attr( $preset['parent'] ) . '" title="' . esc_attr( 'Delete element', 'js_composer' ) . '">';
|
||||
$output .= '<i class="vc-composer-icon vc-c-icon-delete_empty"></i>';
|
||||
$output .= '</button>';
|
||||
|
||||
$output .= '</div>';
|
||||
$output .= '</div>';
|
||||
$output .= '</div>';
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get preset parent shortcode name from post mime type
|
||||
*
|
||||
* @param $presetMimeType
|
||||
*
|
||||
* @return string
|
||||
* @since 5.2
|
||||
*
|
||||
*/
|
||||
public static function constructPresetParent( $presetMimeType ) {
|
||||
return str_replace( '-', '_', str_replace( 'vc-settings-preset/', '', $presetMimeType ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* WPBakery WPBakery Page Builder main class.
|
||||
*
|
||||
* @package WPBakeryPageBuilder
|
||||
* @since 4.2
|
||||
*/
|
||||
|
||||
/**
|
||||
* Edit form for shortcodes with ability to manage shortcode attributes in more convenient way.
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
class Vc_Shortcode_Edit_Form {
|
||||
protected $initialized;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function init() {
|
||||
if ( $this->initialized ) {
|
||||
return;
|
||||
}
|
||||
$this->initialized = true;
|
||||
|
||||
add_action( 'wp_ajax_vc_edit_form', array(
|
||||
$this,
|
||||
'renderFields',
|
||||
) );
|
||||
|
||||
add_filter( 'vc_single_param_edit', array(
|
||||
$this,
|
||||
'changeEditFormFieldParams',
|
||||
) );
|
||||
add_filter( 'vc_edit_form_class', array(
|
||||
$this,
|
||||
'changeEditFormParams',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function render() {
|
||||
vc_include_template( 'editors/popups/vc_ui-panel-edit-element.tpl.php', array(
|
||||
'box' => $this,
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Build edit form fields.
|
||||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
public function renderFields() {
|
||||
$tag = vc_post_param( 'tag' );
|
||||
vc_user_access()->checkAdminNonce()->validateDie( esc_html__( 'Access denied', 'js_composer' ) )->wpAny( array(
|
||||
'edit_post',
|
||||
(int) vc_request_param( 'post_id' ),
|
||||
) )->validateDie( esc_html__( 'Access denied', 'js_composer' ) )->check( 'vc_user_access_check_shortcode_edit', $tag )->validateDie( esc_html__( 'Access denied', 'js_composer' ) );
|
||||
|
||||
$params = (array) stripslashes_deep( vc_post_param( 'params' ) );
|
||||
$params = array_map( 'vc_htmlspecialchars_decode_deep', $params );
|
||||
|
||||
require_once vc_path_dir( 'EDITORS_DIR', 'class-vc-edit-form-fields.php' );
|
||||
$fields = new Vc_Edit_Form_Fields( $tag, $params );
|
||||
$output = $fields->render();
|
||||
// @codingStandardsIgnoreLine
|
||||
wp_die( $output );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $param
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function changeEditFormFieldParams( $param ) {
|
||||
$css = $param['vc_single_param_edit_holder_class'];
|
||||
if ( isset( $param['edit_field_class'] ) ) {
|
||||
$new_css = $param['edit_field_class'];
|
||||
} else {
|
||||
$new_css = 'vc_col-xs-12';
|
||||
}
|
||||
array_unshift( $css, $new_css );
|
||||
$param['vc_single_param_edit_holder_class'] = $css;
|
||||
|
||||
return $param;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $css_classes
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function changeEditFormParams( $css_classes ) {
|
||||
$css = '';
|
||||
array_unshift( $css_classes, $css );
|
||||
|
||||
return $css_classes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,870 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Vc_Templates_Panel_Editor
|
||||
* @since 4.4
|
||||
*/
|
||||
class Vc_Templates_Panel_Editor {
|
||||
/**
|
||||
* @since 4.4
|
||||
* @var string
|
||||
*/
|
||||
protected $option_name = 'wpb_js_templates';
|
||||
/**
|
||||
* @since 4.4
|
||||
* @var bool
|
||||
*/
|
||||
protected $default_templates = false;
|
||||
/**
|
||||
* @since 4.4
|
||||
* @var bool
|
||||
*/
|
||||
protected $initialized = false;
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
* Add ajax hooks, filters.
|
||||
*/
|
||||
public function init() {
|
||||
if ( $this->initialized ) {
|
||||
return;
|
||||
}
|
||||
$this->initialized = true;
|
||||
add_filter( 'vc_load_default_templates_welcome_block', array(
|
||||
$this,
|
||||
'loadDefaultTemplatesLimit',
|
||||
) );
|
||||
|
||||
add_filter( 'vc_templates_render_category', array(
|
||||
$this,
|
||||
'renderTemplateBlock',
|
||||
), 10 );
|
||||
add_filter( 'vc_templates_render_template', array(
|
||||
$this,
|
||||
'renderTemplateWindow',
|
||||
), 10, 2 );
|
||||
|
||||
/**
|
||||
* Ajax methods
|
||||
* 'vc_save_template' -> saving content as template
|
||||
* 'vc_backend_load_template' -> loading template content for backend
|
||||
* 'vc_frontend_load_template' -> loading template content for frontend
|
||||
* 'vc_delete_template' -> deleting template by index
|
||||
*/
|
||||
add_action( 'wp_ajax_vc_save_template', array(
|
||||
$this,
|
||||
'save',
|
||||
) );
|
||||
add_action( 'wp_ajax_vc_backend_load_template', array(
|
||||
$this,
|
||||
'renderBackendTemplate',
|
||||
) );
|
||||
add_action( 'wp_ajax_vc_frontend_load_template', array(
|
||||
$this,
|
||||
'renderFrontendTemplate',
|
||||
) );
|
||||
add_action( 'wp_ajax_vc_load_template_preview', array(
|
||||
$this,
|
||||
'renderTemplatePreview',
|
||||
) );
|
||||
add_action( 'wp_ajax_vc_delete_template', array(
|
||||
$this,
|
||||
'delete',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function addBodyClassTemplatePreview() {
|
||||
return 'vc_general-template-preview';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $category
|
||||
* @return mixed
|
||||
*/
|
||||
public function renderTemplateBlock( $category ) {
|
||||
if ( 'my_templates' === $category['category'] ) {
|
||||
$category['output'] = '';
|
||||
|
||||
if ( vc_user_access()->part( 'templates' )->checkStateAny( true, null )->get() ) {
|
||||
$category['output'] .= '
|
||||
<div class="vc_column vc_col-sm-12" data-vc-hide-on-search="true">
|
||||
<div class="vc_element_label">' . esc_html__( 'Save current layout as a template', 'js_composer' ) . '</div>
|
||||
<div class="vc_input-group">
|
||||
<input name="padding" data-js-element="vc-templates-input" class="vc_form-control wpb-textinput vc_panel-templates-name" type="text" value="" placeholder="' . esc_attr__( 'Template name', 'js_composer' ) . '" data-vc-disable-empty="#vc_ui-save-template-btn">
|
||||
<span class="vc_input-group-btn">
|
||||
<button class="vc_general vc_ui-button vc_ui-button-size-sm vc_ui-button-action vc_ui-button-shape-rounded vc_template-save-btn" id="vc_ui-save-template-btn" disabled data-vc-ui-element="button-save">' . esc_html__( 'Save Template', 'js_composer' ) . '</button>
|
||||
</span>
|
||||
</div>
|
||||
<span class="vc_description">' . esc_html__( 'Save layout and reuse it on different sections of this site.', 'js_composer' ) . '</span>
|
||||
</div>';
|
||||
}
|
||||
|
||||
$category['output'] .= '<div class="vc_column vc_col-sm-12">';
|
||||
if ( isset( $category['category_name'] ) ) {
|
||||
$category['output'] .= '<h3>' . esc_html( $category['category_name'] ) . '</h3>';
|
||||
}
|
||||
if ( isset( $category['category_description'] ) ) {
|
||||
$category['output'] .= '<p class="vc_description">' . esc_html( $category['category_description'] ) . '</p>';
|
||||
}
|
||||
|
||||
$category['output'] .= '</div>';
|
||||
$category['output'] .= '
|
||||
<div class="vc_column vc_col-sm-12">
|
||||
<div class="vc_ui-template-list vc_templates-list-my_templates vc_ui-list-bar" data-vc-action="collapseAll">';
|
||||
if ( ! empty( $category['templates'] ) ) {
|
||||
foreach ( $category['templates'] as $template ) {
|
||||
$category['output'] .= $this->renderTemplateListItem( $template );
|
||||
}
|
||||
}
|
||||
$category['output'] .= '
|
||||
</div>
|
||||
</div>';
|
||||
} else {
|
||||
if ( 'default_templates' === $category['category'] ) {
|
||||
$category['output'] = '<div class="vc_col-md-12">';
|
||||
if ( isset( $category['category_name'] ) ) {
|
||||
$category['output'] .= '<h3>' . esc_html( $category['category_name'] ) . '</h3>';
|
||||
}
|
||||
if ( isset( $category['category_description'] ) ) {
|
||||
$category['output'] .= '<p class="vc_description">' . esc_html( $category['category_description'] ) . '</p>';
|
||||
}
|
||||
$category['output'] .= '</div>';
|
||||
$category['output'] .= '
|
||||
<div class="vc_column vc_col-sm-12">
|
||||
<div class="vc_ui-template-list vc_templates-list-default_templates vc_ui-list-bar" data-vc-action="collapseAll">';
|
||||
if ( ! empty( $category['templates'] ) ) {
|
||||
foreach ( $category['templates'] as $template ) {
|
||||
$category['output'] .= $this->renderTemplateListItem( $template );
|
||||
}
|
||||
}
|
||||
$category['output'] .= '
|
||||
</div>
|
||||
</div>';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $category;
|
||||
}
|
||||
|
||||
/** Output rendered template in new panel dialog
|
||||
* @param $template_name
|
||||
* @param $template_data
|
||||
*
|
||||
* @return string
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function renderTemplateWindow( $template_name, $template_data ) {
|
||||
if ( 'my_templates' === $template_data['type'] ) {
|
||||
return $this->renderTemplateWindowMyTemplates( $template_name, $template_data );
|
||||
} else {
|
||||
if ( 'default_templates' === $template_data['type'] ) {
|
||||
return $this->renderTemplateWindowDefaultTemplates( $template_name, $template_data );
|
||||
}
|
||||
}
|
||||
|
||||
return $template_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $template_name
|
||||
* @param $template_data
|
||||
*
|
||||
* @return string
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function renderTemplateWindowMyTemplates( $template_name, $template_data ) {
|
||||
ob_start();
|
||||
$template_id = esc_attr( $template_data['unique_id'] );
|
||||
$template_id_hash = md5( $template_id ); // needed for jquery target for TTA
|
||||
$template_name = esc_html( $template_name );
|
||||
$preview_template_title = esc_attr__( 'Preview template', 'js_composer' );
|
||||
$add_template_title = esc_attr__( 'Add template', 'js_composer' );
|
||||
echo '<button type="button" class="vc_ui-list-bar-item-trigger" title="' . esc_attr( $add_template_title ) . '" data-template-handler="" data-vc-ui-element="template-title">' . esc_html( $template_name ) . '</button><div class="vc_ui-list-bar-item-actions"><button type="button" class="vc_general vc_ui-control-button" title="' . esc_attr( $add_template_title ) . '" data-template-handler=""><i class="vc-composer-icon vc-c-icon-add"></i></button>';
|
||||
|
||||
if ( vc_user_access()->part( 'templates' )->checkStateAny( true, null )->get() ) {
|
||||
$delete_template_title = esc_attr__( 'Delete template', 'js_composer' );
|
||||
echo '<button type="button" class="vc_general vc_ui-control-button" data-vc-ui-delete="template-title" title="' . esc_attr( $delete_template_title ) . '"><i class="vc-composer-icon vc-c-icon-delete_empty"></i></button>';
|
||||
}
|
||||
|
||||
echo '<button type="button" class="vc_general vc_ui-control-button" title="' . esc_attr( $preview_template_title ) . '" data-vc-container=".vc_ui-list-bar" data-vc-preview-handler data-vc-target="[data-template_id_hash=' . esc_attr( $template_id_hash ) . ']"><i class="vc-composer-icon vc-c-icon-arrow_drop_down"></i></button></div>';
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $template_name
|
||||
* @param $template_data
|
||||
*
|
||||
* @return string
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function renderTemplateWindowDefaultTemplates( $template_name, $template_data ) {
|
||||
ob_start();
|
||||
$template_id = esc_attr( $template_data['unique_id'] );
|
||||
$template_id_hash = md5( $template_id ); // needed for jquery target for TTA
|
||||
$template_name = esc_html( $template_name );
|
||||
$preview_template_title = esc_attr__( 'Preview template', 'js_composer' );
|
||||
$add_template_title = esc_attr__( 'Add template', 'js_composer' );
|
||||
|
||||
echo sprintf( '<button type="button" class="vc_ui-list-bar-item-trigger" title="%s"
|
||||
data-template-handler=""
|
||||
data-vc-ui-element="template-title">%s</button>
|
||||
<div class="vc_ui-list-bar-item-actions">
|
||||
<button type="button" class="vc_general vc_ui-control-button" title="%s"
|
||||
data-template-handler="">
|
||||
<i class="vc-composer-icon vc-c-icon-add"></i>
|
||||
</button>
|
||||
<button type="button" class="vc_general vc_ui-control-button" title="%s"
|
||||
data-vc-container=".vc_ui-list-bar" data-vc-preview-handler data-vc-target="[data-template_id_hash=%s]">
|
||||
<i class="vc-composer-icon vc-c-icon-arrow_drop_down"></i>
|
||||
</button>
|
||||
</div>', esc_attr( $add_template_title ), esc_html( $template_name ), esc_attr( $add_template_title ), esc_attr( $preview_template_title ), esc_attr( $template_id_hash ) );
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
* vc_filter: vc_templates_render_frontend_template - called when unknown template received to render in frontend.
|
||||
*/
|
||||
public function renderFrontendTemplate() {
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'edit_posts', 'edit_pages' )->validateDie()->part( 'templates' )->can()->validateDie();
|
||||
|
||||
add_filter( 'vc_frontend_template_the_content', array(
|
||||
$this,
|
||||
'frontendDoTemplatesShortcodes',
|
||||
) );
|
||||
$template_id = vc_post_param( 'template_unique_id' );
|
||||
$template_type = vc_post_param( 'template_type' );
|
||||
add_action( 'wp_print_scripts', array(
|
||||
$this,
|
||||
'addFrontendTemplatesShortcodesCustomCss',
|
||||
) );
|
||||
|
||||
if ( '' === $template_id ) {
|
||||
die( 'Error: Vc_Templates_Panel_Editor::renderFrontendTemplate:1' );
|
||||
}
|
||||
WPBMap::addAllMappedShortcodes();
|
||||
if ( 'my_templates' === $template_type ) {
|
||||
$saved_templates = get_option( $this->option_name );
|
||||
vc_frontend_editor()->setTemplateContent( $saved_templates[ $template_id ]['template'] );
|
||||
vc_frontend_editor()->enqueueRequired();
|
||||
vc_include_template( 'editors/frontend_template.tpl.php', array(
|
||||
'editor' => vc_frontend_editor(),
|
||||
) );
|
||||
die();
|
||||
} else {
|
||||
if ( 'default_templates' === $template_type ) {
|
||||
$this->renderFrontendDefaultTemplate();
|
||||
} else {
|
||||
// @codingStandardsIgnoreLine
|
||||
print apply_filters( 'vc_templates_render_frontend_template', $template_id, $template_type );
|
||||
}
|
||||
}
|
||||
die; // no needs to do anything more. optimization.
|
||||
}
|
||||
|
||||
/**
|
||||
* Load frontend default template content by index
|
||||
* @since 4.4
|
||||
*/
|
||||
public function renderFrontendDefaultTemplate() {
|
||||
$template_index = (int) vc_post_param( 'template_unique_id' );
|
||||
$data = $this->getDefaultTemplate( $template_index );
|
||||
if ( ! $data ) {
|
||||
die( 'Error: Vc_Templates_Panel_Editor::renderFrontendDefaultTemplate:1' );
|
||||
}
|
||||
vc_frontend_editor()->setTemplateContent( trim( $data['content'] ) );
|
||||
vc_frontend_editor()->enqueueRequired();
|
||||
vc_include_template( 'editors/frontend_template.tpl.php', array(
|
||||
'editor' => vc_frontend_editor(),
|
||||
) );
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.7
|
||||
*/
|
||||
public function renderUITemplate() {
|
||||
vc_include_template( 'editors/popups/vc_ui-panel-templates.tpl.php', array(
|
||||
'box' => $this,
|
||||
) );
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public function save() {
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'edit_posts', 'edit_pages' )->validateDie()->part( 'templates' )->checkStateAny( true, null )->validateDie();
|
||||
|
||||
$template_name = vc_post_param( 'template_name' );
|
||||
$template = vc_post_param( 'template' );
|
||||
if ( ! isset( $template_name ) || '' === trim( $template_name ) || ! isset( $template ) || '' === trim( $template ) ) {
|
||||
header( ':', true, 500 );
|
||||
throw new Exception( 'Error: Vc_Templates_Panel_Editor::save:1' );
|
||||
}
|
||||
|
||||
$template_arr = array(
|
||||
'name' => stripslashes( $template_name ),
|
||||
'template' => stripslashes( $template ),
|
||||
);
|
||||
|
||||
$saved_templates = get_option( $this->option_name );
|
||||
|
||||
$template_id = sanitize_title( $template_name ) . '_' . wp_rand();
|
||||
if ( false === $saved_templates ) {
|
||||
$autoload = 'no';
|
||||
$new_template = array();
|
||||
$new_template[ $template_id ] = $template_arr;
|
||||
add_option( $this->option_name, $new_template, '', $autoload );
|
||||
} else {
|
||||
$saved_templates[ $template_id ] = $template_arr;
|
||||
update_option( $this->option_name, $saved_templates );
|
||||
}
|
||||
$template = array(
|
||||
'name' => $template_arr['name'],
|
||||
'type' => 'my_templates',
|
||||
'unique_id' => $template_id,
|
||||
);
|
||||
// @codingStandardsIgnoreLine
|
||||
print $this->renderTemplateListItem( $template );
|
||||
die;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loading Any templates Shortcodes for backend by string $template_id from AJAX
|
||||
* @since 4.4
|
||||
* vc_filter: vc_templates_render_backend_template - called when unknown template requested to render in backend
|
||||
*/
|
||||
public function renderBackendTemplate() {
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'edit_posts', 'edit_pages' )->validateDie()->part( 'templates' )->can()->validateDie();
|
||||
|
||||
$template_id = vc_post_param( 'template_unique_id' );
|
||||
$template_type = vc_post_param( 'template_type' );
|
||||
|
||||
if ( ! isset( $template_id, $template_type ) || '' === $template_id || '' === $template_type ) {
|
||||
die( 'Error: Vc_Templates_Panel_Editor::renderBackendTemplate:1' );
|
||||
}
|
||||
WPBMap::addAllMappedShortcodes();
|
||||
if ( 'my_templates' === $template_type ) {
|
||||
$saved_templates = get_option( $this->option_name );
|
||||
|
||||
$content = trim( $saved_templates[ $template_id ]['template'] );
|
||||
$content = str_replace( '\"', '"', $content );
|
||||
$pattern = get_shortcode_regex();
|
||||
$content = preg_replace_callback( "/{$pattern}/s", 'vc_convert_shortcode', $content );
|
||||
// @codingStandardsIgnoreLine
|
||||
print $content;
|
||||
die();
|
||||
} else {
|
||||
if ( 'default_templates' === $template_type ) {
|
||||
$this->getBackendDefaultTemplate();
|
||||
die();
|
||||
} else {
|
||||
// @codingStandardsIgnoreLine
|
||||
print apply_filters( 'vc_templates_render_backend_template', $template_id, $template_type );
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render new template view as backened editor content.
|
||||
*
|
||||
* @since 4.8
|
||||
*/
|
||||
public function renderTemplatePreview() {
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( array(
|
||||
'edit_post',
|
||||
(int) vc_request_param( 'post_id' ),
|
||||
) )->validateDie()->part( 'templates' )->can()->validateDie();
|
||||
|
||||
$template_id = vc_request_param( 'template_unique_id' );
|
||||
$template_type = vc_request_param( 'template_type' );
|
||||
global $current_user;
|
||||
wp_get_current_user();
|
||||
|
||||
if ( ! isset( $template_id, $template_type ) || '' === $template_id || '' === $template_type ) {
|
||||
die( esc_html__( 'Error: wrong template id.', 'js_composer' ) );
|
||||
}
|
||||
WPBMap::addAllMappedShortcodes();
|
||||
if ( 'my_templates' === $template_type ) {
|
||||
$saved_templates = get_option( $this->option_name );
|
||||
|
||||
$content = trim( $saved_templates[ $template_id ]['template'] );
|
||||
$content = str_replace( '\"', '"', $content );
|
||||
$pattern = get_shortcode_regex();
|
||||
$content = preg_replace_callback( "/{$pattern}/s", 'vc_convert_shortcode', $content );
|
||||
} else {
|
||||
if ( 'default_templates' === $template_type ) {
|
||||
$content = $this->getBackendDefaultTemplate( true );
|
||||
} else {
|
||||
$content = apply_filters( 'vc_templates_render_backend_template_preview', $template_id, $template_type );
|
||||
}
|
||||
}
|
||||
|
||||
vc_include_template( apply_filters( 'vc_render_template_preview_include_template', 'editors/vc_ui-template-preview.tpl.php' ), array(
|
||||
'content' => $content,
|
||||
'editorPost' => get_post( vc_request_param( 'post_id' ) ),
|
||||
'current_user' => $current_user,
|
||||
) );
|
||||
die();
|
||||
|
||||
}
|
||||
|
||||
public function registerPreviewScripts() {
|
||||
visual_composer()->registerAdminJavascript();
|
||||
visual_composer()->registerAdminCss();
|
||||
vc_backend_editor()->registerBackendJavascript();
|
||||
vc_backend_editor()->registerBackendCss();
|
||||
wp_register_script( 'vc_editors-templates-preview-js', vc_asset_url( 'js/editors/templates-preview.js' ), array(
|
||||
'vc-backend-min-js',
|
||||
), WPB_VC_VERSION, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue required scripts for template preview
|
||||
* @since 4.8
|
||||
*/
|
||||
public function enqueuePreviewScripts() {
|
||||
vc_backend_editor()->enqueueCss();
|
||||
vc_backend_editor()->enqueueJs();
|
||||
wp_enqueue_script( 'vc_editors-templates-preview-js' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public function delete() {
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'edit_posts', 'edit_pages' )->validateDie()->part( 'templates' )->checkStateAny( true, null )->validateDie();
|
||||
|
||||
$template_id = vc_post_param( 'template_id' );
|
||||
$template_type = vc_post_param( 'template_type' );
|
||||
|
||||
if ( ! isset( $template_id ) || '' === $template_id ) {
|
||||
die( 'Error: Vc_Templates_Panel_Editor::delete:1' );
|
||||
}
|
||||
if ( 'my_templates' === $template_type ) {
|
||||
|
||||
$saved_templates = get_option( $this->option_name );
|
||||
unset( $saved_templates[ $template_id ] );
|
||||
if ( count( $saved_templates ) > 0 ) {
|
||||
update_option( $this->option_name, $saved_templates );
|
||||
} else {
|
||||
delete_option( $this->option_name );
|
||||
}
|
||||
wp_send_json_success();
|
||||
} else {
|
||||
do_action( 'vc_templates_delete_templates', $template_id, $template_type );
|
||||
}
|
||||
wp_send_json_error();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $templates
|
||||
*
|
||||
* vc_filter: vc_load_default_templates_limit_total - total items to show
|
||||
*
|
||||
* @return array
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function loadDefaultTemplatesLimit( $templates ) {
|
||||
$start_index = 0;
|
||||
$total_templates_to_show = apply_filters( 'vc_load_default_templates_limit_total', 6 );
|
||||
|
||||
return array_slice( $templates, $start_index, $total_templates_to_show );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user templates
|
||||
*
|
||||
* @return mixed
|
||||
* @since 4.12
|
||||
*/
|
||||
public function getUserTemplates() {
|
||||
return apply_filters( 'vc_get_user_templates', get_option( $this->option_name ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get all templates for display
|
||||
* - with image (optional preview image)
|
||||
* - with unique_id (required for do something for rendering.. )
|
||||
* - with name (required for display? )
|
||||
* - with type (required for requesting data in server)
|
||||
* - with category key (optional/required for filtering), if no category provided it will be displayed only in
|
||||
* "All" category type vc_filter: vc_get_user_templates - hook to override "user My Templates" vc_filter:
|
||||
* vc_get_all_templates - hook for override return array(all templates), hook to add/modify/remove more templates,
|
||||
* - this depends only to displaying in panel window (more layouts)
|
||||
* @return array - all templates with name/unique_id/category_key(optional)/image
|
||||
* @since 4.4
|
||||
*/
|
||||
public function getAllTemplates() {
|
||||
$data = array();
|
||||
// Here we go..
|
||||
if ( apply_filters( 'vc_show_user_templates', true ) ) {
|
||||
// We need to get all "My Templates"
|
||||
$user_templates = $this->getUserTemplates();
|
||||
// this has only 'name' and 'template' key and index 'key' is template id.
|
||||
$arr_category = array(
|
||||
'category' => 'my_templates',
|
||||
'category_name' => esc_html__( 'My Templates', 'js_composer' ),
|
||||
'category_description' => esc_html__( 'Append previously saved template to the current layout.', 'js_composer' ),
|
||||
'category_weight' => 10,
|
||||
);
|
||||
$category_templates = array();
|
||||
if ( ! empty( $user_templates ) ) {
|
||||
foreach ( $user_templates as $template_id => $template_data ) {
|
||||
$category_templates[] = array(
|
||||
'unique_id' => $template_id,
|
||||
'name' => $template_data['name'],
|
||||
'type' => 'my_templates',
|
||||
// for rendering in backend/frontend with ajax
|
||||
);
|
||||
}
|
||||
}
|
||||
$arr_category['templates'] = $category_templates;
|
||||
$data[] = $arr_category;
|
||||
}
|
||||
|
||||
// To get all "Default Templates"
|
||||
$default_templates = $this->getDefaultTemplates();
|
||||
if ( ! empty( $default_templates ) ) {
|
||||
$arr_category = array(
|
||||
'category' => 'default_templates',
|
||||
'category_name' => esc_html__( 'Default Templates', 'js_composer' ),
|
||||
'category_description' => esc_html__( 'Append default template to the current layout.', 'js_composer' ),
|
||||
'category_weight' => 11,
|
||||
);
|
||||
$category_templates = array();
|
||||
foreach ( $default_templates as $template_id => $template_data ) {
|
||||
if ( isset( $template_data['disabled'] ) && $template_data['disabled'] ) {
|
||||
continue;
|
||||
}
|
||||
$category_templates[] = array(
|
||||
'unique_id' => $template_id,
|
||||
'name' => $template_data['name'],
|
||||
'type' => 'default_templates',
|
||||
// for rendering in backend/frontend with ajax
|
||||
'image' => isset( $template_data['image_path'] ) ? $template_data['image_path'] : false,
|
||||
// preview image
|
||||
'custom_class' => isset( $template_data['custom_class'] ) ? $template_data['custom_class'] : false,
|
||||
);
|
||||
}
|
||||
if ( ! empty( $category_templates ) ) {
|
||||
$arr_category['templates'] = $category_templates;
|
||||
$data[] = $arr_category;
|
||||
}
|
||||
}
|
||||
|
||||
// To get any other 3rd "Custom template" - do this by hook filter 'vc_get_all_templates'
|
||||
return apply_filters( 'vc_get_all_templates', $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Load default templates list and initialize variable
|
||||
* To modify you should use add_filter('vc_load_default_templates','your_custom_function');
|
||||
* Argument is array of templates data like:
|
||||
* array(
|
||||
* array(
|
||||
* 'name'=>esc_html__('My custom template','my_plugin'),
|
||||
* 'image_path'=> preg_replace( '/\s/', '%20', plugins_url( 'images/my_image.png', __FILE__ ) ), //
|
||||
* always use preg replace to be sure that "space" will not break logic
|
||||
* 'custom_class'=>'my_custom_class', // if needed
|
||||
* 'content'=>'[my_shortcode]yeah[/my_shortcode]', // Use HEREDoc better to escape all single-quotes
|
||||
* and double quotes
|
||||
* ),
|
||||
* ...
|
||||
* );
|
||||
* Also see filters 'vc_load_default_templates_panels' and 'vc_load_default_templates_welcome_block' to modify
|
||||
* templates in panels tab and/or in welcome block. vc_filter: vc_load_default_templates - filter to override
|
||||
* default templates array
|
||||
* @return array
|
||||
* @since 4.4
|
||||
*/
|
||||
public function loadDefaultTemplates() {
|
||||
if ( ! $this->initialized ) {
|
||||
$this->init(); // add hooks if not added already (fix for in frontend)
|
||||
}
|
||||
|
||||
if ( ! is_array( $this->default_templates ) ) {
|
||||
require_once vc_path_dir( 'CONFIG_DIR', 'templates.php' );
|
||||
$templates = apply_filters( 'vc_load_default_templates', $this->default_templates );
|
||||
$this->default_templates = $templates;
|
||||
do_action( 'vc_load_default_templates_action' );
|
||||
}
|
||||
|
||||
return $this->default_templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for loadDefaultTemplates
|
||||
* @return array - list of default templates
|
||||
* @since 4.4
|
||||
*/
|
||||
public function getDefaultTemplates() {
|
||||
return $this->loadDefaultTemplates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default template data by template index in array.
|
||||
* @param number $template_index
|
||||
*
|
||||
* @return array|bool
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function getDefaultTemplate( $template_index ) {
|
||||
$this->loadDefaultTemplates();
|
||||
if ( ! is_numeric( $template_index ) || ! is_array( $this->default_templates ) || ! isset( $this->default_templates[ $template_index ] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->default_templates[ $template_index ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom template to default templates list ( at end of list )
|
||||
* $data = array( 'name'=>'', 'image'=>'', 'content'=>'' )
|
||||
* @param $data
|
||||
*
|
||||
* @return bool true if added, false if failed
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function addDefaultTemplates( $data ) {
|
||||
if ( is_array( $data ) && ! empty( $data ) && isset( $data['name'], $data['content'] ) ) {
|
||||
if ( ! is_array( $this->default_templates ) ) {
|
||||
$this->default_templates = array();
|
||||
}
|
||||
$this->default_templates[] = $data;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load default template content by index from ajax
|
||||
* @param bool $return | should function return data or not
|
||||
*
|
||||
* @return string
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function getBackendDefaultTemplate( $return = false ) {
|
||||
$template_index = (int) vc_request_param( 'template_unique_id' );
|
||||
$data = $this->getDefaultTemplate( $template_index );
|
||||
if ( ! $data ) {
|
||||
die( 'Error: Vc_Templates_Panel_Editor::getBackendDefaultTemplate:1' );
|
||||
}
|
||||
if ( $return ) {
|
||||
return trim( $data['content'] );
|
||||
} else {
|
||||
print trim( $data['content'] );
|
||||
die;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function sortTemplatesByCategories( array $data ) {
|
||||
$buffer = $data;
|
||||
uasort( $buffer, array(
|
||||
$this,
|
||||
'cmpCategory',
|
||||
) );
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function sortTemplatesByNameWeight( array $data ) {
|
||||
$buffer = $data;
|
||||
uasort( $buffer, array(
|
||||
$this,
|
||||
'cmpNameWeight',
|
||||
) );
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function should return array of templates categories
|
||||
* @param array $categories
|
||||
*
|
||||
* @return array - associative array of category key => and visible Name
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
public function getAllCategoriesNames( array $categories ) {
|
||||
$categories_names = array();
|
||||
|
||||
foreach ( $categories as $category ) {
|
||||
if ( isset( $category['category'] ) ) {
|
||||
$categories_names[ $category['category'] ] = isset( $category['category_name'] ) ? $category['category_name'] : $category['category'];
|
||||
}
|
||||
}
|
||||
|
||||
return $categories_names;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
* @since 4.4
|
||||
*/
|
||||
public function getAllTemplatesSorted() {
|
||||
$data = $this->getAllTemplates();
|
||||
// firstly we need to sort by categories
|
||||
$data = $this->sortTemplatesByCategories( $data );
|
||||
// secondly we need to sort templates by their weight or name
|
||||
foreach ( $data as $key => $category ) {
|
||||
$data[ $key ]['templates'] = $this->sortTemplatesByNameWeight( $category['templates'] );
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to compare two templates by category, category_weight
|
||||
* If category weight is less template will appear in first positions
|
||||
* @param array $a - template one
|
||||
* @param array $b - second template to compare
|
||||
*
|
||||
* @return int
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
protected function cmpCategory( $a, $b ) {
|
||||
$a_k = isset( $a['category'] ) ? $a['category'] : '*';
|
||||
$b_k = isset( $b['category'] ) ? $b['category'] : '*';
|
||||
$a_category_weight = isset( $a['category_weight'] ) ? $a['category_weight'] : 0;
|
||||
$b_category_weight = isset( $b['category_weight'] ) ? $b['category_weight'] : 0;
|
||||
|
||||
return $a_category_weight === $b_category_weight ? strcmp( $a_k, $b_k ) : $a_category_weight - $b_category_weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $a
|
||||
* @param $b
|
||||
*
|
||||
* @return int
|
||||
* @since 4.4
|
||||
*
|
||||
*/
|
||||
protected function cmpNameWeight( $a, $b ) {
|
||||
$a_k = isset( $a['name'] ) ? $a['name'] : '*';
|
||||
$b_k = isset( $b['name'] ) ? $b['name'] : '*';
|
||||
$a_weight = isset( $a['weight'] ) ? $a['weight'] : 0;
|
||||
$b_weight = isset( $b['weight'] ) ? $b['weight'] : 0;
|
||||
|
||||
return $a_weight === $b_weight ? strcmp( $a_k, $b_k ) : $a_weight - $b_weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls do_shortcode for templates.
|
||||
*
|
||||
* @param $content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function frontendDoTemplatesShortcodes( $content ) {
|
||||
return do_shortcode( $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom css from shortcodes from template for template editor.
|
||||
*
|
||||
* Used by action 'wp_print_scripts'.
|
||||
*
|
||||
* @todo move to autoload or else some where.
|
||||
* @since 4.4.3
|
||||
*
|
||||
*/
|
||||
public function addFrontendTemplatesShortcodesCustomCss() {
|
||||
$output = $shortcodes_custom_css = '';
|
||||
$shortcodes_custom_css = visual_composer()->parseShortcodesCustomCss( vc_frontend_editor()->getTemplateContent() );
|
||||
if ( ! empty( $shortcodes_custom_css ) ) {
|
||||
$shortcodes_custom_css = wp_strip_all_tags( $shortcodes_custom_css );
|
||||
$first_tag = 'style';
|
||||
$output .= '<' . $first_tag . ' data-type="vc_shortcodes-custom-css">';
|
||||
$output .= $shortcodes_custom_css;
|
||||
$output .= '</' . $first_tag . '>';
|
||||
}
|
||||
// @todo Check for wp_add_inline_style posibility
|
||||
// @codingStandardsIgnoreLine
|
||||
print $output;
|
||||
}
|
||||
|
||||
public function addScriptsToTemplatePreview() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $template
|
||||
* @return string
|
||||
*/
|
||||
public function renderTemplateListItem( $template ) {
|
||||
$name = isset( $template['name'] ) ? esc_html( $template['name'] ) : esc_html__( 'No title', 'js_composer' );
|
||||
$template_id = esc_attr( $template['unique_id'] );
|
||||
$template_id_hash = md5( $template_id ); // needed for jquery target for TTA
|
||||
$template_name = esc_html( $name );
|
||||
$template_name_lower = esc_attr( vc_slugify( $template_name ) );
|
||||
$template_type = esc_attr( isset( $template['type'] ) ? $template['type'] : 'custom' );
|
||||
$custom_class = esc_attr( isset( $template['custom_class'] ) ? $template['custom_class'] : '' );
|
||||
|
||||
$output = <<<HTML
|
||||
<div class="vc_ui-template vc_templates-template-type-$template_type $custom_class"
|
||||
data-template_id="$template_id"
|
||||
data-template_id_hash="$template_id_hash"
|
||||
data-category="$template_type"
|
||||
data-template_unique_id="$template_id"
|
||||
data-template_name="$template_name_lower"
|
||||
data-template_type="$template_type"
|
||||
data-vc-content=".vc_ui-template-content">
|
||||
<div class="vc_ui-list-bar-item">
|
||||
HTML;
|
||||
$output .= apply_filters( 'vc_templates_render_template', $name, $template );
|
||||
$output .= <<<HTML
|
||||
</div>
|
||||
<div class="vc_ui-template-content" data-js-content>
|
||||
</div>
|
||||
</div>
|
||||
HTML;
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getOptionName() {
|
||||
return $this->option_name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
// Helpers
|
||||
if ( ! function_exists( 'vc_atm_build_categories_array' ) ) {
|
||||
/**
|
||||
* @param $string
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function vc_atm_build_categories_array( $string ) {
|
||||
return explode( ',', preg_replace( '/\,\s+/', ',', trim( $string ) ) );
|
||||
}
|
||||
}
|
||||
if ( ! function_exists( 'vc_atm_build_params_array' ) ) {
|
||||
/**
|
||||
* @param $array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function vc_atm_build_params_array( $array ) {
|
||||
$params = array();
|
||||
if ( is_array( $array ) ) {
|
||||
foreach ( $array as $param ) {
|
||||
if ( 'dropdown' === $param['type'] ) {
|
||||
$param['value'] = explode( ',', preg_replace( '/\,\s+/', ',', trim( $param['value'] ) ) );
|
||||
}
|
||||
$param['save_always'] = true;
|
||||
$params[] = $param;
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Vc_Automap_Model' ) ) {
|
||||
/**
|
||||
* Shortcode as model for automapper. Provides crud functionality for storing data for shortcodes that mapped by ATM
|
||||
*
|
||||
* @see Vc_Automapper
|
||||
* @since 4.1
|
||||
*/
|
||||
class Vc_Automap_Model {
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected static $option_name = 'vc_automapped_shortcodes';
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected static $option_data;
|
||||
/**
|
||||
* @var array|bool
|
||||
*/
|
||||
public $id = false;
|
||||
public $tag;
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $data;
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $vars = array(
|
||||
'tag',
|
||||
'name',
|
||||
'category',
|
||||
'description',
|
||||
'params',
|
||||
);
|
||||
public $name;
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
*/
|
||||
public function __construct( $data ) {
|
||||
$this->loadOptionData();
|
||||
$this->id = is_array( $data ) && isset( $data['id'] ) ? esc_attr( $data['id'] ) : $data;
|
||||
if ( is_array( $data ) ) {
|
||||
$this->data = stripslashes_deep( $data );
|
||||
}
|
||||
foreach ( $this->vars as $var ) {
|
||||
$this->{$var} = $this->get( $var );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function findAll() {
|
||||
self::loadOptionData();
|
||||
$records = array();
|
||||
foreach ( self::$option_data as $id => $record ) {
|
||||
$record['id'] = $id;
|
||||
$model = new self( $record );
|
||||
if ( $model ) {
|
||||
$records[] = $model;
|
||||
}
|
||||
}
|
||||
|
||||
return $records;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|mixed
|
||||
*/
|
||||
final protected static function loadOptionData() {
|
||||
if ( is_null( self::$option_data ) ) {
|
||||
self::$option_data = get_option( self::$option_name );
|
||||
}
|
||||
if ( ! self::$option_data ) {
|
||||
self::$option_data = array();
|
||||
}
|
||||
|
||||
return self::$option_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function get( $key ) {
|
||||
if ( is_null( $this->data ) ) {
|
||||
$this->data = isset( self::$option_data[ $this->id ] ) ? self::$option_data[ $this->id ] : array();
|
||||
}
|
||||
|
||||
return isset( $this->data[ $key ] ) ? $this->data[ $key ] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attr
|
||||
* @param null $value
|
||||
*/
|
||||
public function set( $attr, $value = null ) {
|
||||
if ( is_array( $attr ) ) {
|
||||
foreach ( $attr as $key => $value ) {
|
||||
$this->set( $key, $value );
|
||||
}
|
||||
} elseif ( ! is_null( $value ) ) {
|
||||
$this->{$attr} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function save() {
|
||||
if ( ! $this->isValid() ) {
|
||||
return false;
|
||||
}
|
||||
foreach ( $this->vars as $var ) {
|
||||
$this->data[ $var ] = $this->{$var};
|
||||
}
|
||||
|
||||
return $this->saveOption();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function delete() {
|
||||
return $this->deleteOption();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid() {
|
||||
if ( ! is_string( $this->name ) || empty( $this->name ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( ! preg_match( '/^\S+$/', $this->tag ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function saveOption() {
|
||||
self::$option_data[ $this->id ] = $this->data;
|
||||
|
||||
return update_option( self::$option_name, self::$option_data );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function deleteOption() {
|
||||
unset( self::$option_data[ $this->id ] );
|
||||
|
||||
return delete_option( self::$option_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,392 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
if ( ! class_exists( 'Vc_Automapper' ) ) {
|
||||
/**
|
||||
* Automated shortcode mapping
|
||||
*
|
||||
* Automapper adds settings tab for VC settings tabs with ability to map custom shortcodes to VC editors,
|
||||
* if shortcode is not mapped by default or developers haven't done this yet.
|
||||
* No more shortcode copy/paste. Add any third party shortcode to the list of VC menu elements for reuse.
|
||||
* Edit params, values and description.
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
class Vc_Automapper {
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected static $disabled = false;
|
||||
protected $title;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->title = esc_attr__( 'Shortcode Mapper', 'js_composer' );
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function addAjaxActions() {
|
||||
add_action( 'wp_ajax_vc_automapper_create', array(
|
||||
$this,
|
||||
'create',
|
||||
) );
|
||||
add_action( 'wp_ajax_vc_automapper_read', array(
|
||||
$this,
|
||||
'read',
|
||||
) );
|
||||
add_action( 'wp_ajax_vc_automapper_update', array(
|
||||
$this,
|
||||
'update',
|
||||
) );
|
||||
add_action( 'wp_ajax_vc_automapper_delete', array(
|
||||
$this,
|
||||
'delete',
|
||||
) );
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds html for Automapper CRUD like administration block
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function renderHtml() {
|
||||
if ( $this->disabled() ) {
|
||||
return false;
|
||||
}
|
||||
?>
|
||||
<div class="tab_intro">
|
||||
<p><?php esc_html_e( 'WPBakery Page Builder Shortcode Mapper adds custom 3rd party vendors shortcodes to the list of WPBakery Page Builder content elements menu (Note: to map shortcode it needs to be installed on site).', 'js_composer' ); ?></p>
|
||||
</div>
|
||||
<div class="vc_automapper-toolbar">
|
||||
<a href=javascript:;" class="button button-primary"
|
||||
id="vc_automapper-add-btn"><?php esc_html_e( 'Map Shortcode', 'js_composer' ); ?></a>
|
||||
</div>
|
||||
<ul class="vc_automapper-list">
|
||||
</ul>
|
||||
<?php $this->renderTemplates(); ?>
|
||||
<?php
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $shortcode
|
||||
*/
|
||||
public function renderListItem( $shortcode ) {
|
||||
echo sprintf( '<li class="vc_automapper-item" data-item-id=""><label>%s</label><span class="vc_automapper-item-controls"><a href="javascript:;" class="vc_automapper-edit-btn" data-id="%s" data-tag="%s"></a><a href="javascript:;" class="vc_automapper-delete-btn" data-id="%s" data-tag="%s"></a></span></li>', esc_html( $shortcode->name ), esc_attr( $shortcode->id ), esc_attr( $shortcode->tag ), esc_attr( $shortcode->id ), esc_attr( $shortcode->tag ) );
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderMapFormTpl() {
|
||||
$custom_tag = 'script'; // Maybe use html shadow dom or ajax response for templates
|
||||
?>
|
||||
<<?php echo esc_attr( $custom_tag ); ?> type="text/html" id="vc_automapper-add-form-tpl">
|
||||
<label for="vc_atm-shortcode-string"
|
||||
class="vc_info"><?php esc_html_e( 'Shortcode string', 'js_composer' ); ?></label>
|
||||
|
||||
<div class="vc_wrapper">
|
||||
<div class="vc_string">
|
||||
<input id="vc_atm-shortcode-string"
|
||||
placeholder="<?php esc_attr_e( 'Please enter valid shortcode', 'js_composer' ); ?>"
|
||||
type="text" class="vc_atm-string">
|
||||
</div>
|
||||
<div class="vc_buttons">
|
||||
<a href="#" id="vc_atm-parse-string"
|
||||
class="button button-primary vc_parse-btn"><?php esc_attr_e( 'Parse Shortcode', 'js_composer' ); ?></a>
|
||||
<a href="#" class="button vc_atm-cancel"><?php esc_attr_e( 'Cancel', 'js_composer' ); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
<span
|
||||
class="description"><?php esc_html_e( 'Enter valid shortcode (Example: [my_shortcode first_param="first_param_value"]My shortcode content[/my_shortcode]).', 'js_composer' ); ?></span>
|
||||
</<?php echo esc_attr( $custom_tag ); ?>>
|
||||
<<?php echo esc_attr( $custom_tag ); ?> type="text/html" id="vc_automapper-item-complex-tpl">
|
||||
<div class="widget-top">
|
||||
<div class="widget-title-action">
|
||||
<button type="button" class="widget-action hide-if-no-js" aria-expanded="true">
|
||||
<span class="screen-reader-text"><?php esc_html_e( 'Edit widget: Search', 'js_composer' ); ?></span>
|
||||
<span class="toggle-indicator" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="widget-title"><h4>{{ name }}<span class="in-widget-title"></span></h4></div>
|
||||
</div>
|
||||
<div class="widget-inside">
|
||||
</div>
|
||||
</<?php echo esc_attr( $custom_tag ); ?>>
|
||||
<<?php echo esc_attr( $custom_tag ); ?> type="text/html" id="vc_automapper-form-tpl">
|
||||
<input type="hidden" name="name" id="vc_atm-name" value="{{ name }}">
|
||||
|
||||
<div class="vc_shortcode-preview" id="vc_shortcode-preview">
|
||||
{{{ shortcode_preview }}}
|
||||
</div>
|
||||
<div class="vc_line"></div>
|
||||
<div class="vc_wrapper">
|
||||
<h4 class="vc_h"><?php esc_html_e( 'General Information', 'js_composer' ); ?></h4>
|
||||
|
||||
<div class="vc_field vc_tag">
|
||||
<label for="vc_atm-tag"><?php esc_html_e( 'Tag:', 'js_composer' ); ?></label>
|
||||
<input type="text" name="tag" id="vc_atm-tag" value="{{ tag }}">
|
||||
</div>
|
||||
<div class="vc_field vc_description">
|
||||
<label for="vc_atm-description"><?php esc_html_e( 'Description:', 'js_composer' ); ?></label>
|
||||
<textarea name="description" id="vc_atm-description">{{ description }}</textarea>
|
||||
</div>
|
||||
<div class="vc_field vc_category">
|
||||
<label for="vc_atm-category"><?php esc_html_e( 'Category:', 'js_composer' ); ?></label>
|
||||
<input type="text" name="category" id="vc_atm-category" value="{{ category }}">
|
||||
<span
|
||||
class="description"><?php esc_html_e( 'Comma separated categories names', 'js_composer' ); ?></span>
|
||||
</div>
|
||||
<div class="vc_field vc_is-container">
|
||||
<label for="vc_atm-is-container"><input type="checkbox" name="is_container"
|
||||
id="vc_atm-is-container"
|
||||
value=""> <?php esc_html_e( 'Include content param into shortcode', 'js_composer' ); ?>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="vc_line"></div>
|
||||
<div class="vc_wrapper">
|
||||
<h4 class="vc_h"><?php esc_html_e( 'Shortcode Parameters', 'js_composer' ); ?></h4>
|
||||
<a href="#" id="vc_atm-add-param"
|
||||
class="button vc_add-param">+ <?php esc_html_e( 'Add Param', 'js_composer' ); ?></a>
|
||||
|
||||
<div class="vc_params" id="vc_atm-params-list"></div>
|
||||
</div>
|
||||
<div class="vc_buttons">
|
||||
<a href="#" id="vc_atm-save"
|
||||
class="button button-primary"><?php esc_html_e( 'Save Changes', 'js_composer' ); ?></a>
|
||||
<a href="#" class="button vc_atm-cancel"><?php esc_html_e( 'Cancel', 'js_composer' ); ?></a>
|
||||
<a href="#" class="button vc_atm-delete"><?php esc_html_e( 'Delete', 'js_composer' ); ?></a>
|
||||
</div>
|
||||
</<?php echo esc_attr( $custom_tag ); ?>>
|
||||
<<?php echo esc_attr( $custom_tag ); ?> type="text/html" id="vc_atm-form-param-tpl">
|
||||
<div class="vc_controls vc_controls-row vc_clearfix"><a
|
||||
class="vc_control column_move vc_column-move vc_move-param" href="#"
|
||||
title="<?php esc_html_e( 'Drag row to reorder', 'js_composer' ); ?>" data-vc-control="move"><i
|
||||
class="vc-composer-icon vc-c-icon-dragndrop"></i></a><span class="vc_row_edit_clone_delete"><a
|
||||
class="vc_control column_delete vc_delete-param" href="#"
|
||||
title="<?php esc_html_e( 'Delete this param', 'js_composer' ); ?>"><i class="vc-composer-icon vc-c-icon-delete_empty"></i></a></span>
|
||||
</div>
|
||||
<div class="wpb_element_wrapper">
|
||||
<div class="vc_row vc_row-fluid wpb_row_container">
|
||||
<div class="wpb_vc_column wpb_sortable vc_col-sm-12 wpb_content_holder vc_empty-column">
|
||||
<div class="wpb_element_wrapper">
|
||||
<div class="vc_fields vc_clearfix">
|
||||
<div class="vc_param_name vc_param-field">
|
||||
<label><?php esc_html_e( 'Param name', 'js_composer' ); ?></label>
|
||||
<# if ( 'content' === param_name) { #>
|
||||
<span class="vc_content"><?php esc_html_e( 'Content', 'js_composer' ); ?></span>
|
||||
<input type="text" style="display: none;" name="param_name"
|
||||
value="{{ param_name }}"
|
||||
placeholder="<?php esc_attr_e( 'Required value', 'js_composer' ); ?>"
|
||||
class="vc_param-name"
|
||||
data-system="true">
|
||||
<span class="description"
|
||||
style="display: none;"><?php esc_html_e( 'Use only letters, numbers and underscore.', 'js_composer' ); ?></span>
|
||||
<# } else { #>
|
||||
<input type="text" name="param_name" value="{{ param_name }}"
|
||||
placeholder="<?php esc_attr_e( 'Required value', 'js_composer' ); ?>"
|
||||
class="vc_param-name">
|
||||
<span
|
||||
class="description"><?php esc_html_e( 'Please use only letters, numbers and underscore.', 'js_composer' ); ?></span>
|
||||
<# } #>
|
||||
</div>
|
||||
<div class="vc_heading vc_param-field">
|
||||
<label><?php esc_html_e( 'Heading', 'js_composer' ); ?></label>
|
||||
<input type="text" name="heading" value="{{ heading }}"
|
||||
placeholder="<?php esc_attr_e( 'Input heading', 'js_composer' ); ?>"
|
||||
<# if ( 'hidden' === type) { #>
|
||||
disabled="disabled"
|
||||
<# } #>>
|
||||
<span
|
||||
class="description"><?php esc_html_e( 'Heading for field in shortcode edit form.', 'js_composer' ); ?></span>
|
||||
</div>
|
||||
<div class="vc_type vc_param-field">
|
||||
<label><?php esc_html_e( 'Field type', 'js_composer' ); ?></label>
|
||||
<select name="type">
|
||||
<option value=""><?php esc_html_e( 'Select field type', 'js_composer' ); ?></option>
|
||||
<option
|
||||
value="textfield"<?php echo '<# if (type === "textfield") { #> selected<# } #>'; ?>><?php esc_html_e( 'Textfield', 'js_composer' ); ?></option>
|
||||
<option
|
||||
value="dropdown"<?php echo '<# if (type === "dropdown") { #> selected<# } #>'; ?>><?php esc_html_e( 'Dropdown', 'js_composer' ); ?></option>
|
||||
<option
|
||||
value="textarea"<?php echo '<# if(type==="textarea") { #> selected="selected"<# } #>'; ?>><?php esc_html_e( 'Textarea', 'js_composer' ); ?></option>
|
||||
<# if ( 'content' === param_name ) { #>
|
||||
<option
|
||||
value="textarea_html"<?php echo '<# if (type === "textarea_html") { #> selected<# } #>'; ?>><?php esc_html_e( 'Textarea HTML', 'js_composer' ); ?></option>
|
||||
<# } #>
|
||||
<option
|
||||
value="hidden"<?php echo '<# if (type === "hidden") { #> selected<# } #>'; ?>><?php esc_html_e( 'Hidden', 'js_composer' ); ?></option>
|
||||
|
||||
</select>
|
||||
<span
|
||||
class="description"><?php esc_html_e( 'Field type for shortcode edit form.', 'js_composer' ); ?></span>
|
||||
</div>
|
||||
<div class="vc_value vc_param-field">
|
||||
<label><?php esc_html_e( 'Default value', 'js_composer' ); ?></label>
|
||||
<input type="text" name="value" value="{{ value }}" class="vc_param-value">
|
||||
<span
|
||||
class="description"><?php esc_html_e( 'Default value or list of values for dropdown type (Note: separate by comma).', 'js_composer' ); ?></span>
|
||||
</div>
|
||||
<div class="description vc_param-field">
|
||||
<label><?php esc_html_e( 'Description', 'js_composer' ); ?></label>
|
||||
<textarea name="description" placeholder=""
|
||||
<# if ( 'hidden' === type ) { #>
|
||||
disabled="disabled"
|
||||
<# } #> >{{ description
|
||||
}}</textarea>
|
||||
<span
|
||||
class="description"><?php esc_html_e( 'Enter description for parameter.', 'js_composer' ); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</<?php echo esc_attr( $custom_tag ); ?>>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function renderTemplates() {
|
||||
$custom_tag = 'script'; // Maybe use ajax resonse for template
|
||||
?>
|
||||
<<?php echo esc_attr( $custom_tag ); ?> type="text/html" id="vc_automapper-item-tpl">
|
||||
<label class="vc_automapper-edit-btn">{{ name }}</label>
|
||||
<span class="vc_automapper-item-controls">
|
||||
<a href="#" class="vc_automapper-delete-btn" title="<?php esc_html_e( 'Delete', 'js_composer' ); ?>"></a>
|
||||
<a href="#" class="vc_automapper-edit-btn" title="<?php esc_html_e( 'Edit', 'js_composer' ); ?>"></a>
|
||||
</span>
|
||||
</<?php echo esc_attr( $custom_tag ); ?>>
|
||||
<?php
|
||||
$this->renderMapFormTpl();
|
||||
}
|
||||
|
||||
public function create() {
|
||||
if ( ! vc_request_param( '_vcnonce' ) ) {
|
||||
return;
|
||||
}
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'manage_options' )->validateDie()->part( 'settings' )->can( 'vc-automapper-tab' )->validateDie();
|
||||
|
||||
$data = vc_post_param( 'data' );
|
||||
$shortcode = new Vc_Automap_Model( $data );
|
||||
|
||||
$this->result( $shortcode->save() );
|
||||
}
|
||||
|
||||
public function update() {
|
||||
if ( ! vc_request_param( '_vcnonce' ) ) {
|
||||
return;
|
||||
}
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'manage_options' )->validateDie()->part( 'settings' )->can( 'vc-automapper-tab' )->validateDie();
|
||||
|
||||
$id = (int) vc_post_param( 'id' );
|
||||
$data = vc_post_param( 'data' );
|
||||
$shortcode = new Vc_Automap_Model( $id );
|
||||
if ( ! isset( $data['params'] ) ) {
|
||||
$data['params'] = array();
|
||||
}
|
||||
$shortcode->set( $data );
|
||||
|
||||
$this->result( $shortcode->save() );
|
||||
}
|
||||
|
||||
public function delete() {
|
||||
if ( ! vc_request_param( '_vcnonce' ) ) {
|
||||
return;
|
||||
}
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'manage_options' )->validateDie()->part( 'settings' )->can( 'vc-automapper-tab' )->validateDie();
|
||||
|
||||
$id = vc_post_param( 'id' );
|
||||
$shortcode = new Vc_Automap_Model( $id );
|
||||
|
||||
$this->result( $shortcode->delete() );
|
||||
}
|
||||
|
||||
public function read() {
|
||||
if ( ! vc_request_param( '_vcnonce' ) ) {
|
||||
return;
|
||||
}
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'manage_options' )->validateDie()->part( 'settings' )->can( 'vc-automapper-tab' )->validateDie();
|
||||
|
||||
$this->result( Vc_Automap_Model::findAll() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax result output
|
||||
*
|
||||
* @param $data
|
||||
*/
|
||||
public function result( $data ) {
|
||||
if ( false !== $data ) {
|
||||
wp_send_json_success( $data );
|
||||
} else {
|
||||
wp_send_json_error( $data );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter/Getter for Disabling Automapper
|
||||
* @static
|
||||
*
|
||||
* @param bool $disable
|
||||
*/
|
||||
public static function setDisabled( $disable = true ) {
|
||||
self::$disabled = $disable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public static function disabled() {
|
||||
return self::$disabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter/Getter for Automapper title
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @param string $title
|
||||
*/
|
||||
public function setTitle( $title ) {
|
||||
$this->title = $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|void
|
||||
*/
|
||||
public function title() {
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static function map() {
|
||||
$shortcodes = Vc_Automap_Model::findAll();
|
||||
foreach ( $shortcodes as $shortcode ) {
|
||||
vc_map( array(
|
||||
'name' => $shortcode->name,
|
||||
'base' => $shortcode->tag,
|
||||
'category' => vc_atm_build_categories_array( $shortcode->category ),
|
||||
'description' => $shortcode->description,
|
||||
'params' => vc_atm_build_params_array( $shortcode->params ),
|
||||
'show_settings_on_create' => ! empty( $shortcode->params ),
|
||||
'atm' => true,
|
||||
'icon' => 'icon-wpb-atm',
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,555 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* WPBakery WPBakery Page Builder Plugin
|
||||
*
|
||||
* @package WPBakeryPageBuilder
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manage license
|
||||
*
|
||||
* Activation/deactivation is done via support portal and does not use Envato username and
|
||||
* api_key anymore
|
||||
*/
|
||||
class Vc_License {
|
||||
|
||||
/**
|
||||
* Option name where license key is stored
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $license_key_option = 'js_composer_purchase_code';
|
||||
|
||||
/**
|
||||
* Option name where license key token is stored
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $license_key_token_option = 'license_key_token';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected static $support_host = 'https://support.wpbakery.com';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $error = null;
|
||||
|
||||
public function init() {
|
||||
|
||||
if ( 'vc-updater' === vc_get_param( 'page' ) ) {
|
||||
$activate = vc_get_param( 'activate' );
|
||||
$deactivate = vc_get_param( 'deactivate' );
|
||||
if ( $activate ) {
|
||||
$this->finishActivationDeactivation( true, $activate );
|
||||
} elseif ( $deactivate ) {
|
||||
$this->finishActivationDeactivation( false, $deactivate );
|
||||
}
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_vc_get_activation_url', array(
|
||||
$this,
|
||||
'startActivationResponse',
|
||||
) );
|
||||
add_action( 'wp_ajax_vc_get_deactivation_url', array(
|
||||
$this,
|
||||
'startDeactivationResponse',
|
||||
) );
|
||||
|
||||
add_action( 'wp_ajax_nopriv_vc_check_license_key', array(
|
||||
vc_license(),
|
||||
'checkLicenseKeyFromRemote',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Output notice
|
||||
*
|
||||
* @param string $message
|
||||
* @param bool $success
|
||||
*/
|
||||
public function outputNotice( $message, $success = true ) {
|
||||
echo sprintf( '<div class="%s"><p>%s</p></div>', (bool) $success ? 'updated' : 'error', esc_html( $message ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Show error
|
||||
*
|
||||
* @param string $error
|
||||
*/
|
||||
public function showError( $error ) {
|
||||
$this->error = $error;
|
||||
add_action( 'admin_notices', array(
|
||||
$this,
|
||||
'outputLastError',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Output last error
|
||||
*/
|
||||
public function outputLastError() {
|
||||
$this->outputNotice( $this->error, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Output successful activation message
|
||||
*/
|
||||
public function outputActivatedSuccess() {
|
||||
$this->outputNotice( esc_html__( 'WPBakery Page Builder successfully activated.', 'js_composer' ), true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Output successful deactivation message
|
||||
*/
|
||||
public function outputDeactivatedSuccess() {
|
||||
$this->outputNotice( esc_html__( 'WPBakery Page Builder successfully deactivated.', 'js_composer' ), true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish pending activation/deactivation
|
||||
*
|
||||
* 1) Make API call to support portal
|
||||
* 2) Receive success status and license key
|
||||
* 3) Set new license key
|
||||
*
|
||||
* @param bool $activation
|
||||
* @param string $user_token
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function finishActivationDeactivation( $activation, $user_token ) {
|
||||
if ( ! $this->isValidToken( $user_token ) ) {
|
||||
$this->showError( esc_html__( 'Token is not valid or has expired', 'js_composer' ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $activation ) {
|
||||
$url = self::$support_host . '/finish-license-activation';
|
||||
} else {
|
||||
$url = self::$support_host . '/finish-license-deactivation';
|
||||
}
|
||||
|
||||
$params = array(
|
||||
'body' => array( 'token' => $user_token ),
|
||||
'timeout' => 30,
|
||||
);
|
||||
// FIX SSL SNI
|
||||
$filter_add = true;
|
||||
if ( function_exists( 'curl_version' ) ) {
|
||||
$version = curl_version();
|
||||
if ( version_compare( $version['version'], '7.18', '>=' ) ) {
|
||||
$filter_add = false;
|
||||
}
|
||||
}
|
||||
if ( $filter_add ) {
|
||||
add_filter( 'https_ssl_verify', '__return_false' );
|
||||
}
|
||||
$response = wp_remote_post( $url, $params );
|
||||
|
||||
if ( $filter_add ) {
|
||||
remove_filter( 'https_ssl_verify', '__return_false' );
|
||||
}
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
$this->showError( sprintf( esc_html__( '%s. Please try again.', 'js_composer' ), $response->get_error_message() ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( 200 !== $response['response']['code'] ) {
|
||||
$this->showError( sprintf( esc_html__( 'Server did not respond with OK: %s', 'js_composer' ), $response['response']['code'] ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$json = json_decode( $response['body'], true );
|
||||
|
||||
if ( ! $json || ! isset( $json['status'] ) ) {
|
||||
$this->showError( esc_html__( 'Invalid response structure. Please contact us for support.', 'js_composer' ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $json['status'] ) {
|
||||
$this->showError( esc_html__( 'Something went wrong. Please contact us for support.', 'js_composer' ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $activation ) {
|
||||
if ( ! isset( $json['license_key'] ) || ! $this->isValidFormat( $json['license_key'] ) ) {
|
||||
$this->showError( esc_html__( 'Invalid response structure. Please contact us for support.', 'js_composer' ) );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->setLicenseKey( $json['license_key'] );
|
||||
|
||||
add_action( 'admin_notices', array(
|
||||
$this,
|
||||
'outputActivatedSuccess',
|
||||
) );
|
||||
} else {
|
||||
$this->setLicenseKey( '' );
|
||||
|
||||
add_action( 'admin_notices', array(
|
||||
$this,
|
||||
'outputDeactivatedSuccess',
|
||||
) );
|
||||
}
|
||||
|
||||
$this->setLicenseKeyToken( '' );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isActivated() {
|
||||
return (bool) $this->getLicenseKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check license key from remote
|
||||
*
|
||||
* Function is used by support portal to check if VC w/ specific license is still installed
|
||||
*/
|
||||
public function checkLicenseKeyFromRemote() {
|
||||
$license_key = vc_request_param( 'license_key' );
|
||||
|
||||
if ( ! $this->isValid( $license_key ) ) {
|
||||
$response = array(
|
||||
'status' => false,
|
||||
'error' => esc_html__( 'Invalid license key', 'js_composer' ),
|
||||
);
|
||||
} else {
|
||||
$response = array( 'status' => true );
|
||||
}
|
||||
|
||||
die( wp_json_encode( $response ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate action URL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generateActivationUrl() {
|
||||
$token = sha1( $this->newLicenseKeyToken() );
|
||||
$url = esc_url( self::getSiteUrl() );
|
||||
$redirect = esc_url( vc_updater()->getUpdaterUrl() );
|
||||
|
||||
return sprintf( '%s/activate-license?token=%s&url=%s&redirect=%s', self::$support_host, $token, $url, $redirect );
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate action URL
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generateDeactivationUrl() {
|
||||
$license_key = $this->getLicenseKey();
|
||||
$token = sha1( $this->newLicenseKeyToken() );
|
||||
$url = esc_url( self::getSiteUrl() );
|
||||
$redirect = esc_url( vc_updater()->getUpdaterUrl() );
|
||||
|
||||
return sprintf( '%s/deactivate-license?license_key=%s&token=%s&url=%s&redirect=%s', self::$support_host, $license_key, $token, $url, $redirect );
|
||||
}
|
||||
|
||||
/**
|
||||
* Start activation process and output redirect URL as JSON
|
||||
*/
|
||||
public function startActivationResponse() {
|
||||
vc_user_access()->checkAdminNonce()->validateDie()->wpAny( 'manage_options' )->validateDie()->part( 'settings' )->can( 'vc-updater-tab' )->validateDie();
|
||||
|
||||
$response = array(
|
||||
'status' => true,
|
||||
'url' => $this->generateActivationUrl(),
|
||||
);
|
||||
|
||||
die( wp_json_encode( $response ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Start deactivation process and output redirect URL as JSON
|
||||
*/
|
||||
public function startDeactivationResponse() {
|
||||
vc_user_access()->checkAdminNonce()->validateDie( 'Failed nonce check' )->wpAny( 'manage_options' )->validateDie( 'Failed access check' )->part( 'settings' )->can( 'vc-updater-tab' )
|
||||
->validateDie( 'Failed access check #2' );
|
||||
|
||||
$response = array(
|
||||
'status' => true,
|
||||
'url' => $this->generateDeactivationUrl(),
|
||||
);
|
||||
|
||||
die( wp_json_encode( $response ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set license key
|
||||
*
|
||||
* @param string $license_key
|
||||
*/
|
||||
public function setLicenseKey( $license_key ) {
|
||||
if ( vc_is_network_plugin() ) {
|
||||
update_site_option( 'wpb_js_' . self::$license_key_option, $license_key );
|
||||
} else {
|
||||
vc_settings()->set( self::$license_key_option, $license_key );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get license key
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLicenseKey() {
|
||||
if ( vc_is_network_plugin() ) {
|
||||
$value = get_site_option( 'wpb_js_' . self::$license_key_option );
|
||||
} else {
|
||||
$value = vc_settings()->get( self::$license_key_option );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if specified license key is valid
|
||||
*
|
||||
* @param string $license_key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid( $license_key ) {
|
||||
return $license_key === $this->getLicenseKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up license activation notice if needed
|
||||
*
|
||||
* Don't show notice on dev environment
|
||||
*/
|
||||
public function setupReminder() {
|
||||
if ( self::isDevEnvironment() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$version1 = isset( $_COOKIE['vchideactivationmsg_vc11'] ) ? sanitize_text_field( wp_unslash( $_COOKIE['vchideactivationmsg_vc11'] ) ) : '';
|
||||
|
||||
if ( ! $this->isActivated() && ( empty( $version1 ) || version_compare( $version1, WPB_VC_VERSION, '<' ) ) && ! ( vc_is_network_plugin() && is_network_admin() ) ) {
|
||||
add_action( 'admin_notices', array(
|
||||
$this,
|
||||
'adminNoticeLicenseActivation',
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if current enviroment is dev
|
||||
*
|
||||
* Environment is considered dev if host is:
|
||||
* - ip address
|
||||
* - tld is local, dev, wp, test, example, localhost or invalid
|
||||
* - no tld (localhost, custom hosts)
|
||||
*
|
||||
* @param string $host Hostname to check. If null, use HTTP_HOST
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isDevEnvironment( $host = null ) {
|
||||
if ( ! $host ) {
|
||||
$host = self::getSiteUrl();
|
||||
}
|
||||
|
||||
$chunks = explode( '.', $host );
|
||||
|
||||
if ( 1 === count( $chunks ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( in_array( end( $chunks ), array(
|
||||
'local',
|
||||
'dev',
|
||||
'wp',
|
||||
'test',
|
||||
'example',
|
||||
'localhost',
|
||||
'invalid',
|
||||
), true ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( preg_match( '/^[0-9\.]+$/', $host ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function adminNoticeLicenseActivation() {
|
||||
if ( vc_is_network_plugin() ) {
|
||||
update_site_option( 'wpb_js_composer_license_activation_notified', 'yes' );
|
||||
} else {
|
||||
vc_settings()->set( 'composer_license_activation_notified', 'yes' );
|
||||
}
|
||||
$redirect = esc_url( vc_updater()->getUpdaterUrl() );
|
||||
$first_tag = 'style';
|
||||
$second_tag = 'script';
|
||||
// @codingStandardsIgnoreStart
|
||||
?>
|
||||
<<?php echo esc_attr( $first_tag ); ?>>
|
||||
.vc_license-activation-notice {
|
||||
position: relative;
|
||||
}
|
||||
</<?php echo esc_attr( $first_tag ); ?>>
|
||||
<<?php echo esc_attr( $second_tag ); ?>>
|
||||
(function ( $ ) {
|
||||
var setCookie = function ( c_name, value, exdays ) {
|
||||
var exdate = new Date();
|
||||
exdate.setDate( exdate.getDate() + exdays );
|
||||
var c_value = encodeURIComponent( value ) + ((null === exdays) ? "" : "; expires=" + exdate.toUTCString());
|
||||
document.cookie = c_name + "=" + c_value;
|
||||
};
|
||||
$( document ).off( 'click.vc-notice-dismiss' ).on( 'click.vc-notice-dismiss',
|
||||
'.vc-notice-dismiss',
|
||||
function ( e ) {
|
||||
e.preventDefault();
|
||||
var $el = $( this ).closest(
|
||||
'#vc_license-activation-notice' );
|
||||
$el.fadeTo( 100, 0, function () {
|
||||
$el.slideUp( 100, function () {
|
||||
$el.remove();
|
||||
} );
|
||||
} );
|
||||
setCookie( 'vchideactivationmsg_vc11',
|
||||
'<?php echo esc_attr( WPB_VC_VERSION ); ?>',
|
||||
30 );
|
||||
} );
|
||||
})( window.jQuery );
|
||||
</<?php echo esc_attr( $second_tag ); ?>>
|
||||
<?php
|
||||
echo '<div class="updated vc_license-activation-notice" id="vc_license-activation-notice"><p>' . sprintf( esc_html__( 'Hola! Would you like to receive automatic updates and unlock premium support? Please %sactivate your copy%s of WPBakery Page Builder.', 'js_composer' ), '<a href="' . esc_url( wp_nonce_url( $redirect ) ) . '">', '</a>' ) . '</p>' . '<button type="button" class="notice-dismiss vc-notice-dismiss"><span class="screen-reader-text">' . esc_html__( 'Dismiss this notice.', 'js_composer' ) . '</span></button></div>';
|
||||
|
||||
// @codingStandardsIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* Get license key token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getLicenseKeyToken() {
|
||||
$value = vc_is_network_plugin() ? get_site_option( self::$license_key_token_option ) : get_option( self::$license_key_token_option );
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set license key token
|
||||
*
|
||||
* @param string $token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function setLicenseKeyToken( $token ) {
|
||||
if ( vc_is_network_plugin() ) {
|
||||
$value = update_site_option( self::$license_key_token_option, $token );
|
||||
} else {
|
||||
$value = update_option( self::$license_key_token_option, $token );
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return new license key token
|
||||
*
|
||||
* Token is used to change license key from remote location
|
||||
*
|
||||
* Format is: timestamp|20-random-characters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generateLicenseKeyToken() {
|
||||
$token = current_time( 'timestamp' ) . '|' . vc_random_string( 20 );
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and set new license key token
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function newLicenseKeyToken() {
|
||||
$token = $this->generateLicenseKeyToken();
|
||||
|
||||
$this->setLicenseKeyToken( $token );
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if specified license key token is valid
|
||||
*
|
||||
* @param string $token_to_check SHA1 hashed token
|
||||
* @param int $ttl_in_seconds Time to live in seconds. Default = 20min
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValidToken( $token_to_check, $ttl_in_seconds = 1200 ) {
|
||||
$token = $this->getLicenseKeyToken();
|
||||
|
||||
if ( ! $token_to_check || sha1( $token ) !== $token_to_check ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$chunks = explode( '|', $token );
|
||||
|
||||
if ( intval( $chunks[0] ) < ( current_time( 'timestamp' ) - $ttl_in_seconds ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if license key format is valid
|
||||
*
|
||||
* license key is version 4 UUID, that have form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
|
||||
* where x is any hexadecimal digit and y is one of 8, 9, A, or B.
|
||||
*
|
||||
* @param string $license_key
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValidFormat( $license_key ) {
|
||||
$pattern = '/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i';
|
||||
|
||||
return (bool) preg_match( $pattern, $license_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|void
|
||||
*/
|
||||
/**
|
||||
* @return string|void
|
||||
*/
|
||||
public static function getSiteUrl() {
|
||||
if ( vc_is_network_plugin() ) {
|
||||
return network_site_url();
|
||||
} else {
|
||||
return site_url();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage role.
|
||||
* @since 4.8
|
||||
*
|
||||
* Class Vc_Roles
|
||||
*/
|
||||
class Vc_Roles {
|
||||
protected $post_types = false;
|
||||
protected $vc_excluded_post_types = false;
|
||||
protected $parts = array(
|
||||
'post_types',
|
||||
'backend_editor',
|
||||
'frontend_editor',
|
||||
'post_settings',
|
||||
'settings',
|
||||
'templates',
|
||||
'shortcodes',
|
||||
'grid_builder',
|
||||
'presets',
|
||||
'dragndrop',
|
||||
);
|
||||
|
||||
/**
|
||||
* Get list of parts
|
||||
* @return mixed
|
||||
*/
|
||||
public function getParts() {
|
||||
return apply_filters( 'vc_roles_parts_list', $this->parts );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check required capability for this role to have user access.
|
||||
*
|
||||
* @param $part
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
public function getPartCapability( $part ) {
|
||||
return 'settings' !== $part ? array(
|
||||
'edit_posts',
|
||||
'edit_pages',
|
||||
) : 'manage_options';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $role
|
||||
* @param $caps
|
||||
* @return bool
|
||||
*/
|
||||
public function hasRoleCapability( $role, $caps ) {
|
||||
$has = false;
|
||||
$wp_role = get_role( $role );
|
||||
if ( is_string( $caps ) ) {
|
||||
$has = $wp_role->has_cap( $caps );
|
||||
} elseif ( is_array( $caps ) ) {
|
||||
$i = 0;
|
||||
$count = count( $caps );
|
||||
while ( false === $has && $i < $count ) {
|
||||
$has = $this->hasRoleCapability( $role, $caps[ $i ++ ] );
|
||||
}
|
||||
}
|
||||
|
||||
return $has;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \WP_Roles
|
||||
*/
|
||||
public function getWpRoles() {
|
||||
global $wp_roles;
|
||||
if ( function_exists( 'wp_roles' ) ) {
|
||||
return $wp_roles;
|
||||
} else {
|
||||
if ( ! isset( $wp_roles ) ) {
|
||||
// @codingStandardsIgnoreLine
|
||||
$wp_roles = new WP_Roles();
|
||||
}
|
||||
}
|
||||
|
||||
return $wp_roles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $params
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function save( $params = array() ) {
|
||||
$data = array( 'message' => '' );
|
||||
$roles = $this->getWpRoles();
|
||||
$editable_roles = get_editable_roles();
|
||||
foreach ( $params as $role => $parts ) {
|
||||
if ( is_string( $parts ) ) {
|
||||
$parts = json_decode( stripslashes( $parts ), true );
|
||||
}
|
||||
if ( isset( $editable_roles[ $role ] ) ) {
|
||||
foreach ( $parts as $part => $settings ) {
|
||||
$part_key = vc_role_access()->who( $role )->part( $part )->getStateKey();
|
||||
$stateValue = '0';
|
||||
$roles->use_db = false; // Disable saving in DB on every cap change
|
||||
foreach ( $settings as $key => $value ) {
|
||||
if ( '_state' === $key ) {
|
||||
$stateValue = in_array( $value, array(
|
||||
'0',
|
||||
'1',
|
||||
), true ) ? (bool) $value : $value;
|
||||
} else {
|
||||
if ( empty( $value ) ) {
|
||||
$roles->remove_cap( $role, $part_key . '/' . $key );
|
||||
} else {
|
||||
$roles->add_cap( $role, $part_key . '/' . $key, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
$roles->use_db = true; // Enable for the lat change in cap of role to store data in DB
|
||||
$roles->add_cap( $role, $part_key, $stateValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
$data['message'] = esc_html__( 'Roles settings successfully saved.', 'js_composer' );
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|bool
|
||||
*/
|
||||
public function getPostTypes() {
|
||||
if ( false === $this->post_types ) {
|
||||
$this->post_types = array();
|
||||
$exclude = $this->getExcludePostTypes();
|
||||
foreach ( get_post_types( array( 'public' => true ) ) as $post_type ) {
|
||||
if ( ! in_array( $post_type, $exclude, true ) ) {
|
||||
$this->post_types[] = array(
|
||||
$post_type,
|
||||
$post_type,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->post_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool|mixed|void
|
||||
*/
|
||||
public function getExcludePostTypes() {
|
||||
if ( false === $this->vc_excluded_post_types ) {
|
||||
$this->vc_excluded_post_types = apply_filters( 'vc_settings_exclude_post_type', array(
|
||||
'attachment',
|
||||
'revision',
|
||||
'nav_menu_item',
|
||||
'mediapage',
|
||||
) );
|
||||
}
|
||||
|
||||
return $this->vc_excluded_post_types;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,217 @@
|
||||
<?php
|
||||
/**
|
||||
* @package WPBakery
|
||||
* @noinspection PhpIncludeInspection
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
define( 'VC_SHORTCODE_CUSTOMIZE_PREFIX', 'vc_theme_' );
|
||||
/**
|
||||
*
|
||||
*/
|
||||
define( 'VC_SHORTCODE_BEFORE_CUSTOMIZE_PREFIX', 'vc_theme_before_' );
|
||||
/**
|
||||
*
|
||||
*/
|
||||
define( 'VC_SHORTCODE_AFTER_CUSTOMIZE_PREFIX', 'vc_theme_after_' );
|
||||
/**
|
||||
*
|
||||
*/
|
||||
define( 'VC_SHORTCODE_CUSTOM_CSS_FILTER_TAG', 'vc_shortcodes_css_class' );
|
||||
|
||||
require_once $this->path( 'SHORTCODES_DIR', 'core/class-wpbakery-visualcomposer-abstract.php' );
|
||||
require_once $this->path( 'SHORTCODES_DIR', 'core/class-wpbakeryshortcode.php' );
|
||||
require_once $this->path( 'SHORTCODES_DIR', 'core/class-wbpakeryshortcodefishbones.php' );
|
||||
require_once $this->path( 'SHORTCODES_DIR', 'core/class-wpbakeryshortcodescontainer.php' );
|
||||
|
||||
/**
|
||||
* @since 4.9
|
||||
*
|
||||
* Class Vc_Shortcodes_Manager
|
||||
*/
|
||||
class Vc_Shortcodes_Manager {
|
||||
private $shortcode_classes = array(
|
||||
'default' => array(),
|
||||
);
|
||||
|
||||
private $tag;
|
||||
/**
|
||||
* Core singleton class
|
||||
* @var self - pattern realization
|
||||
*/
|
||||
private static $instance;
|
||||
|
||||
/**
|
||||
* Get the instance of Vc_Shortcodes_Manager
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function getInstance() {
|
||||
if ( ! ( self::$instance instanceof self ) ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function getTag() {
|
||||
return $this->tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tag
|
||||
* @return $this
|
||||
*/
|
||||
/**
|
||||
* @param $tag
|
||||
* @return $this
|
||||
*/
|
||||
public function setTag( $tag ) {
|
||||
$this->tag = $tag;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tag
|
||||
* @return \WPBakeryShortCodeFishBones
|
||||
* @throws \Exception
|
||||
*/
|
||||
/**
|
||||
* @param $tag
|
||||
* @return \WPBakeryShortCodeFishBones
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getElementClass( $tag ) {
|
||||
$currentScope = WPBMap::getScope();
|
||||
if ( isset( $this->shortcode_classes[ $currentScope ], $this->shortcode_classes[ $currentScope ][ $tag ] ) ) {
|
||||
return $this->shortcode_classes[ $currentScope ][ $tag ];
|
||||
}
|
||||
if ( ! isset( $this->shortcode_classes[ $currentScope ] ) ) {
|
||||
$this->shortcode_classes[ $currentScope ] = array();
|
||||
}
|
||||
$settings = WPBMap::getShortCode( $tag );
|
||||
if ( empty( $settings ) ) {
|
||||
throw new Exception( 'Element must be mapped in system' );
|
||||
}
|
||||
require_once vc_path_dir( 'SHORTCODES_DIR', 'wordpress-widgets.php' );
|
||||
|
||||
$class_name = ! empty( $settings['php_class_name'] ) ? $settings['php_class_name'] : 'WPBakeryShortCode_' . $settings['base'];
|
||||
|
||||
$autoloaded_dependencies = VcShortcodeAutoloader::includeClass( $class_name );
|
||||
|
||||
if ( ! $autoloaded_dependencies ) {
|
||||
$file = vc_path_dir( 'SHORTCODES_DIR', str_replace( '_', '-', $settings['base'] ) . '.php' );
|
||||
if ( is_file( $file ) ) {
|
||||
require_once $file;
|
||||
}
|
||||
}
|
||||
|
||||
if ( class_exists( $class_name ) && is_subclass_of( $class_name, 'WPBakeryShortCode' ) ) {
|
||||
$shortcode_class = new $class_name( $settings );
|
||||
} else {
|
||||
$shortcode_class = new WPBakeryShortCodeFishBones( $settings );
|
||||
}
|
||||
$this->shortcode_classes[ $currentScope ][ $tag ] = $shortcode_class;
|
||||
|
||||
return $shortcode_class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \WPBakeryShortCodeFishBones
|
||||
* @throws \Exception
|
||||
*/
|
||||
/**
|
||||
* @return \WPBakeryShortCodeFishBones
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function shortcodeClass() {
|
||||
return $this->getElementClass( $this->tag );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function template( $content = '' ) {
|
||||
return $this->getElementClass( $this->tag )->contentAdmin( array(), $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
*
|
||||
* @return null
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function settings( $name ) {
|
||||
$settings = WPBMap::getShortCode( $this->tag );
|
||||
|
||||
return isset( $settings[ $name ] ) ? $settings[ $name ] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $atts
|
||||
* @param null $content
|
||||
* @param null $tag
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function render( $atts, $content = null, $tag = null ) {
|
||||
return $this->getElementClass( $this->tag )->output( $atts, $content );
|
||||
}
|
||||
|
||||
public function buildShortcodesAssets() {
|
||||
$elements = WPBMap::getAllShortCodes();
|
||||
foreach ( $elements as $tag => $settings ) {
|
||||
$element_class = $this->getElementClass( $tag );
|
||||
$element_class->enqueueAssets();
|
||||
$element_class->printIconStyles();
|
||||
}
|
||||
}
|
||||
|
||||
public function buildShortcodesAssetsForEditable() {
|
||||
$elements = WPBMap::getAllShortCodes(); // @todo create pull to use only where it is set inside function. BC problem
|
||||
foreach ( $elements as $tag => $settings ) {
|
||||
$element_class = $this->getElementClass( $tag );
|
||||
$element_class->printIconStyles();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tag
|
||||
* @return bool
|
||||
*/
|
||||
/**
|
||||
* @param $tag
|
||||
* @return bool
|
||||
*/
|
||||
public function isShortcodeClassInitialized( $tag ) {
|
||||
$currentScope = WPBMap::getScope();
|
||||
|
||||
return isset( $this->shortcode_classes[ $currentScope ], $this->shortcode_classes[ $currentScope ][ $tag ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tag
|
||||
* @return bool
|
||||
*/
|
||||
/**
|
||||
* @param $tag
|
||||
* @return bool
|
||||
*/
|
||||
public function unsetElementClass( $tag ) {
|
||||
$currentScope = WPBMap::getScope();
|
||||
unset( $this->shortcode_classes[ $currentScope ][ $tag ] );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class WPBakeryShortCodeFishBones
|
||||
*/
|
||||
class WPBakeryShortCodeFishBones extends WPBakeryShortCode {
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $shortcode_class = false;
|
||||
|
||||
/**
|
||||
* @param $settings
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function __construct( $settings ) {
|
||||
if ( ! $settings ) {
|
||||
throw new Exception( 'Element must have settings to register' );
|
||||
}
|
||||
$this->settings = $settings;
|
||||
$this->shortcode = $this->settings['base'];
|
||||
add_action( 'admin_init', array(
|
||||
$this,
|
||||
'hookAdmin',
|
||||
) );
|
||||
if ( ! shortcode_exists( $this->shortcode ) ) {
|
||||
add_shortcode( $this->shortcode, array(
|
||||
$this,
|
||||
'render',
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
public function hookAdmin() {
|
||||
$this->enqueueAssets();
|
||||
add_action( 'admin_init', array(
|
||||
$this,
|
||||
'enqueueAssets',
|
||||
) );
|
||||
if ( vc_is_page_editable() ) {
|
||||
// fix for page editable
|
||||
add_action( 'wp_head', array(
|
||||
$this,
|
||||
'printIconStyles',
|
||||
) );
|
||||
}
|
||||
|
||||
add_action( 'admin_head', array(
|
||||
$this,
|
||||
'printIconStyles',
|
||||
) ); // fe+be
|
||||
add_action( 'admin_print_scripts-post.php', array(
|
||||
$this,
|
||||
'enqueueAssets',
|
||||
) );
|
||||
add_action( 'admin_print_scripts-post-new.php', array(
|
||||
$this,
|
||||
'enqueueAssets',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPBakeryShortCodeFishBones
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function shortcodeClass() {
|
||||
if ( false !== $this->shortcode_class ) {
|
||||
return $this->shortcode_class;
|
||||
}
|
||||
|
||||
require_once vc_path_dir( 'SHORTCODES_DIR', 'wordpress-widgets.php' );
|
||||
|
||||
$class_name = $this->settings( 'php_class_name' ) ? $this->settings( 'php_class_name' ) : 'WPBakeryShortCode_' . $this->settings( 'base' );
|
||||
|
||||
$autoloaded_dependencies = VcShortcodeAutoloader::includeClass( $class_name );
|
||||
|
||||
if ( ! $autoloaded_dependencies ) {
|
||||
$file = vc_path_dir( 'SHORTCODES_DIR', str_replace( '_', '-', $this->settings( 'base' ) ) . '.php' );
|
||||
if ( is_file( $file ) ) {
|
||||
require_once $file;
|
||||
}
|
||||
}
|
||||
|
||||
if ( class_exists( $class_name ) && is_subclass_of( $class_name, 'WPBakeryShortCode' ) ) {
|
||||
$this->shortcode_class = new $class_name( $this->settings );
|
||||
} else {
|
||||
$this->shortcode_class = new WPBakeryShortCodeFishBones( $this->settings );
|
||||
}
|
||||
|
||||
return $this->shortcode_class;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param $tag
|
||||
*
|
||||
* @return \WPBakeryShortCodeFishBones
|
||||
* @throws \Exception
|
||||
* @since 4.9
|
||||
*
|
||||
*/
|
||||
public static function getElementClass( $tag ) {
|
||||
$settings = WPBMap::getShortCode( $tag );
|
||||
if ( empty( $settings ) ) {
|
||||
throw new Exception( 'Element must be mapped in system' );
|
||||
}
|
||||
require_once vc_path_dir( 'SHORTCODES_DIR', 'wordpress-widgets.php' );
|
||||
|
||||
$class_name = ! empty( $settings['php_class_name'] ) ? $settings['php_class_name'] : 'WPBakeryShortCode_' . $settings['base'];
|
||||
|
||||
$autoloaded_dependencies = VcShortcodeAutoloader::includeClass( $class_name );
|
||||
|
||||
if ( ! $autoloaded_dependencies ) {
|
||||
$file = vc_path_dir( 'SHORTCODES_DIR', str_replace( '_', '-', $settings['base'] ) . '.php' );
|
||||
if ( is_file( $file ) ) {
|
||||
require_once $file;
|
||||
}
|
||||
}
|
||||
|
||||
if ( class_exists( $class_name ) && is_subclass_of( $class_name, 'WPBakeryShortCode' ) ) {
|
||||
$shortcode_class = new $class_name( $settings );
|
||||
} else {
|
||||
$shortcode_class = new WPBakeryShortCodeFishBones( $settings );
|
||||
}
|
||||
|
||||
return $shortcode_class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $atts
|
||||
* @param null $content
|
||||
* @param null $tag
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function render( $atts, $content = null, $tag = null ) {
|
||||
return self::getElementClass( $tag )->output( $atts, $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function template( $content = '' ) {
|
||||
return $this->shortcodeClass()->contentAdmin( array(), $content );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/* abstract VisualComposer class to create structural object of any type */
|
||||
|
||||
/**
|
||||
* Class WPBakeryVisualComposerAbstract
|
||||
*/
|
||||
abstract class WPBakeryVisualComposerAbstract {
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
public static $config;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $controls_css_settings = 'cc';
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $controls_list = array(
|
||||
'edit',
|
||||
'clone',
|
||||
'delete',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $shortcode_content = '';
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $settings
|
||||
* @deprecated not used
|
||||
*/
|
||||
public function init( $settings ) {
|
||||
self::$config = (array) $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $action
|
||||
* @param $method
|
||||
* @param int $priority
|
||||
* @return true|void
|
||||
* @deprecated 6.0 use native WordPress actions
|
||||
*/
|
||||
public function addAction( $action, $method, $priority = 10 ) {
|
||||
return add_action( $action, array(
|
||||
$this,
|
||||
$method,
|
||||
), $priority );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $action
|
||||
* @param $method
|
||||
* @param int $priority
|
||||
*
|
||||
* @return bool
|
||||
* @deprecated 6.0 use native WordPress actions
|
||||
*
|
||||
*/
|
||||
public function removeAction( $action, $method, $priority = 10 ) {
|
||||
return remove_action( $action, array(
|
||||
$this,
|
||||
$method,
|
||||
), $priority );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $filter
|
||||
* @param $method
|
||||
* @param int $priority
|
||||
*
|
||||
* @return bool|void
|
||||
* @deprecated 6.0 use native WordPress actions
|
||||
*
|
||||
*/
|
||||
public function addFilter( $filter, $method, $priority = 10 ) {
|
||||
return add_filter( $filter, array(
|
||||
$this,
|
||||
$method,
|
||||
), $priority );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $filter
|
||||
* @param $method
|
||||
* @param int $priority
|
||||
* @return bool
|
||||
* @deprecated 6.0 use native WordPress
|
||||
*
|
||||
*/
|
||||
public function removeFilter( $filter, $method, $priority = 10 ) {
|
||||
return remove_filter( $filter, array(
|
||||
$this,
|
||||
$method,
|
||||
), $priority );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tag
|
||||
* @param $func
|
||||
* @deprecated 6.0 not used
|
||||
*
|
||||
*/
|
||||
public function addShortCode( $tag, $func ) {
|
||||
// this function is deprecated since 6.0
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $content
|
||||
* @deprecated 6.0 not used
|
||||
*
|
||||
*/
|
||||
public function doShortCode( $content ) {
|
||||
// this function is deprecated since 6.0
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $tag
|
||||
* @deprecated 6.0 not used
|
||||
*
|
||||
*/
|
||||
public function removeShortCode( $tag ) {
|
||||
// this function is deprecated since 6.0
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $param
|
||||
*
|
||||
* @return null
|
||||
* @deprecated 6.0 not used, use vc_post_param
|
||||
*
|
||||
*/
|
||||
public function post( $param ) {
|
||||
// this function is deprecated since 6.0
|
||||
|
||||
return vc_post_param( $param );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $param
|
||||
*
|
||||
* @return null
|
||||
* @deprecated 6.0 not used, use vc_get_param
|
||||
*
|
||||
*/
|
||||
public function get( $param ) {
|
||||
// this function is deprecated since 6.0
|
||||
|
||||
return vc_get_param( $param );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $asset
|
||||
*
|
||||
* @return string
|
||||
* @deprecated 4.5 use vc_asset_url
|
||||
*
|
||||
*/
|
||||
public function assetURL( $asset ) {
|
||||
// this function is deprecated since 4.5
|
||||
|
||||
return vc_asset_url( $asset );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $asset
|
||||
*
|
||||
* @return string
|
||||
* @deprecated 6.0 not used
|
||||
*/
|
||||
public function assetPath( $asset ) {
|
||||
// this function is deprecated since 6.0
|
||||
|
||||
return self::$config['APP_ROOT'] . self::$config['ASSETS_DIR'] . $asset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
*
|
||||
* @return null
|
||||
* @deprecated 6.0 not used
|
||||
*/
|
||||
public static function config( $name ) {
|
||||
return isset( self::$config[ $name ] ) ? self::$config[ $name ] : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,867 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class WPBakeryShortCode
|
||||
*/
|
||||
abstract class WPBakeryShortCode extends WPBakeryVisualComposerAbstract {
|
||||
/**
|
||||
* @var string - shortcode tag
|
||||
*/
|
||||
protected $shortcode;
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $html_template;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $atts;
|
||||
|
||||
/**
|
||||
* @var
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $js_scripts = array();
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $css_scripts = array();
|
||||
/**
|
||||
* default scripts like scripts
|
||||
* @var bool
|
||||
* @since 4.4.3
|
||||
*/
|
||||
protected static $default_scripts_enqueued = false;
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $shortcode_string = '';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $controls_template_file = 'editors/partials/backend_controls.tpl.php';
|
||||
|
||||
public $nonDraggableClass = 'vc-non-draggable';
|
||||
/** @noinspection PhpMissingParentConstructorInspection */
|
||||
|
||||
/**
|
||||
* @param $settings
|
||||
*/
|
||||
public function __construct( $settings ) {
|
||||
$this->settings = $settings;
|
||||
$this->shortcode = $this->settings['base'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function addInlineAnchors( $content ) {
|
||||
return ( $this->isInline() || $this->isEditor() && true === $this->settings( 'is_container' ) ? '<span class="vc_container-anchor"></span>' : '' ) . $content;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function enqueueAssets() {
|
||||
if ( ! empty( $this->settings['admin_enqueue_js'] ) ) {
|
||||
$this->registerJs( $this->settings['admin_enqueue_js'] );
|
||||
}
|
||||
if ( ! empty( $this->settings['admin_enqueue_css'] ) ) {
|
||||
$this->registerCss( $this->settings['admin_enqueue_css'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out the styles needed to render the element icon for the back end interface.
|
||||
* Only performed if the 'icon' setting is a valid URL.
|
||||
*
|
||||
* @return void
|
||||
* @since 4.2
|
||||
* @modified 4.4
|
||||
* @author Benjamin Intal
|
||||
*/
|
||||
public function printIconStyles() {
|
||||
if ( ! filter_var( $this->settings( 'icon' ), FILTER_VALIDATE_URL ) ) {
|
||||
return;
|
||||
}
|
||||
$first_tag = 'style';
|
||||
echo '
|
||||
<' . esc_attr( $first_tag ) . '>
|
||||
.vc_el-container #' . esc_attr( $this->settings['base'] ) . ' .vc_element-icon,
|
||||
.wpb_' . esc_attr( $this->settings['base'] ) . ' > .wpb_element_wrapper > .wpb_element_title > .vc_element-icon,
|
||||
.vc_el-container > #' . esc_attr( $this->settings['base'] ) . ' > .vc_element-icon,
|
||||
.vc_el-container > #' . esc_attr( $this->settings['base'] ) . ' > .vc_element-icon[data-is-container="true"],
|
||||
.compose_mode .vc_helper.vc_helper-' . esc_attr( $this->settings['base'] ) . ' > .vc_element-icon,
|
||||
.vc_helper.vc_helper-' . esc_attr( $this->settings['base'] ) . ' > .vc_element-icon,
|
||||
.compose_mode .vc_helper.vc_helper-' . esc_attr( $this->settings['base'] ) . ' > .vc_element-icon[data-is-container="true"],
|
||||
.vc_helper.vc_helper-' . esc_attr( $this->settings['base'] ) . ' > .vc_element-icon[data-is-container="true"],
|
||||
.wpb_' . esc_attr( $this->settings['base'] ) . ' > .wpb_element_wrapper > .wpb_element_title > .vc_element-icon,
|
||||
.wpb_' . esc_attr( $this->settings['base'] ) . ' > .wpb_element_wrapper > .wpb_element_title > .vc_element-icon[data-is-container="true"] {
|
||||
background-position: 0 0;
|
||||
background-image: url(' . esc_url( $this->settings['icon'] ) . ');
|
||||
-webkit-background-size: contain;
|
||||
-moz-background-size: contain;
|
||||
-ms-background-size: contain;
|
||||
-o-background-size: contain;
|
||||
background-size: contain;
|
||||
}
|
||||
</' . esc_attr( $first_tag ) . '>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $param
|
||||
*/
|
||||
protected function registerJs( $param ) {
|
||||
if ( is_array( $param ) && ! empty( $param ) ) {
|
||||
foreach ( $param as $value ) {
|
||||
$this->registerJs( $value );
|
||||
}
|
||||
} elseif ( is_string( $param ) && ! empty( $param ) ) {
|
||||
$name = 'admin_enqueue_js_' . md5( $param );
|
||||
self::$js_scripts[] = $name;
|
||||
wp_register_script( $name, $param, array( 'jquery' ), WPB_VC_VERSION, true );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $param
|
||||
*/
|
||||
protected function registerCss( $param ) {
|
||||
if ( is_array( $param ) && ! empty( $param ) ) {
|
||||
foreach ( $param as $value ) {
|
||||
$this->registerCss( $value );
|
||||
}
|
||||
} elseif ( is_string( $param ) && ! empty( $param ) ) {
|
||||
$name = 'admin_enqueue_css_' . md5( $param );
|
||||
self::$css_scripts[] = $name;
|
||||
wp_register_style( $name, $param, array( 'js_composer' ), WPB_VC_VERSION );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static function enqueueCss() {
|
||||
if ( ! empty( self::$css_scripts ) ) {
|
||||
foreach ( self::$css_scripts as $stylesheet ) {
|
||||
wp_enqueue_style( $stylesheet );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static function enqueueJs() {
|
||||
if ( ! empty( self::$js_scripts ) ) {
|
||||
foreach ( self::$js_scripts as $script ) {
|
||||
wp_enqueue_script( $script );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $shortcode
|
||||
*/
|
||||
public function shortcode( $shortcode ) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $template
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function setTemplate( $template ) {
|
||||
return $this->html_template = apply_filters( 'vc_shortcode_set_template_' . $this->shortcode, $template );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
protected function getTemplate() {
|
||||
if ( isset( $this->html_template ) ) {
|
||||
return $this->html_template;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getFileName() {
|
||||
return $this->shortcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find html template for shortcode output.
|
||||
*/
|
||||
protected function findShortcodeTemplate() {
|
||||
// Check template path in shortcode's mapping settings
|
||||
if ( ! empty( $this->settings['html_template'] ) && is_file( $this->settings( 'html_template' ) ) ) {
|
||||
return $this->setTemplate( $this->settings['html_template'] );
|
||||
}
|
||||
|
||||
// Check template in theme directory
|
||||
$user_template = vc_shortcodes_theme_templates_dir( $this->getFileName() . '.php' );
|
||||
if ( is_file( $user_template ) ) {
|
||||
return $this->setTemplate( $user_template );
|
||||
}
|
||||
|
||||
// Check default place
|
||||
$default_dir = vc_manager()->getDefaultShortcodesTemplatesDir() . '/';
|
||||
if ( is_file( $default_dir . $this->getFileName() . '.php' ) ) {
|
||||
return $this->setTemplate( $default_dir . $this->getFileName() . '.php' );
|
||||
}
|
||||
$template = apply_filters( 'vc_shortcode_set_template_' . $this->shortcode, '' );
|
||||
|
||||
if ( ! empty( $template ) ? $template : '' ) {
|
||||
return $this->setTemplate( $template );
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $atts
|
||||
* @param null $content
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function content( $atts, $content = null ) {
|
||||
return $this->loadTemplate( $atts, $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $atts
|
||||
* @param null $content
|
||||
*
|
||||
* vc_filter: vc_shortcode_content_filter - hook to edit template content
|
||||
* vc_filter: vc_shortcode_content_filter_after - hook after template is loaded to override output
|
||||
*
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function loadTemplate( $atts, $content = null ) {
|
||||
$output = '';
|
||||
if ( ! is_null( $content ) ) {
|
||||
/** @var string $content */
|
||||
$content = apply_filters( 'vc_shortcode_content_filter', $content, $this->shortcode );
|
||||
}
|
||||
$this->findShortcodeTemplate();
|
||||
if ( $this->html_template && file_exists( $this->html_template ) ) {
|
||||
if ( strpos( $this->html_template, WPB_PLUGIN_DIR ) === false ) {
|
||||
// Modified or new
|
||||
Vc_Modifications::$modified = true;
|
||||
}
|
||||
ob_start();
|
||||
/** @var string $content - used inside template */
|
||||
$output = require $this->html_template;
|
||||
// Allow return in template files
|
||||
if ( 1 === $output ) {
|
||||
$output = ob_get_contents();
|
||||
}
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
return apply_filters( 'vc_shortcode_content_filter_after', $output, $this->shortcode, $atts, $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $atts
|
||||
* @param $content
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function contentAdmin( $atts, $content = null ) {
|
||||
$output = $custom_markup = $width = $el_position = '';
|
||||
if ( null !== $content ) {
|
||||
$content = wpautop( stripslashes( $content ) );
|
||||
}
|
||||
$shortcode_attributes = array( 'width' => '1/1' );
|
||||
$atts = vc_map_get_attributes( $this->getShortcode(), $atts ) + $shortcode_attributes;
|
||||
$this->atts = $atts;
|
||||
$elem = $this->getElementHolder( $width );
|
||||
if ( isset( $this->settings['custom_markup'] ) && '' !== $this->settings['custom_markup'] ) {
|
||||
$markup = $this->settings['custom_markup'];
|
||||
$elem = str_ireplace( '%wpb_element_content%', $this->customMarkup( $markup, $content ), $elem );
|
||||
$output .= $elem;
|
||||
} else {
|
||||
$inner = $this->outputTitle( $this->settings['name'] );
|
||||
$inner .= $this->paramsHtmlHolders( $atts );
|
||||
$elem = str_ireplace( '%wpb_element_content%', $inner, $elem );
|
||||
$output .= $elem;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isAdmin() {
|
||||
return apply_filters( 'vc_shortcodes_is_admin', is_admin() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isInline() {
|
||||
return vc_is_inline();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isEditor() {
|
||||
return vc_is_editor();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $atts
|
||||
* @param null $content
|
||||
* @param string $base
|
||||
*
|
||||
* vc_filter: vc_shortcode_output - hook to override output of shortcode
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function output( $atts, $content = null, $base = '' ) {
|
||||
$this->atts = $prepared_atts = $this->prepareAtts( $atts );
|
||||
$this->shortcode_content = $content;
|
||||
$output = '';
|
||||
$content = empty( $content ) && ! empty( $atts['content'] ) ? $atts['content'] : $content;
|
||||
if ( ( $this->isInline() || vc_is_page_editable() ) && method_exists( $this, 'contentInline' ) ) {
|
||||
$output .= $this->contentInline( $this->atts, $content );
|
||||
} else {
|
||||
$this->enqueueDefaultScripts();
|
||||
$custom_output = VC_SHORTCODE_CUSTOMIZE_PREFIX . $this->shortcode;
|
||||
$custom_output_before = VC_SHORTCODE_BEFORE_CUSTOMIZE_PREFIX . $this->shortcode; // before shortcode function hook
|
||||
$custom_output_after = VC_SHORTCODE_AFTER_CUSTOMIZE_PREFIX . $this->shortcode; // after shortcode function hook
|
||||
|
||||
// Before shortcode
|
||||
if ( function_exists( $custom_output_before ) ) {
|
||||
$output .= $custom_output_before( $this->atts, $content );
|
||||
} else {
|
||||
$output .= $this->beforeShortcode( $this->atts, $content );
|
||||
}
|
||||
// Shortcode content
|
||||
if ( function_exists( $custom_output ) ) {
|
||||
$output .= $custom_output( $this->atts, $content );
|
||||
} else {
|
||||
$output .= $this->content( $this->atts, $content );
|
||||
}
|
||||
// After shortcode
|
||||
if ( function_exists( $custom_output_after ) ) {
|
||||
$output .= $custom_output_after( $this->atts, $content );
|
||||
} else {
|
||||
$output .= $this->afterShortcode( $this->atts, $content );
|
||||
}
|
||||
}
|
||||
// Filter for overriding outputs
|
||||
$output = apply_filters( 'vc_shortcode_output', $output, $this, $prepared_atts, $this->shortcode );
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function enqueueDefaultScripts() {
|
||||
if ( false === self::$default_scripts_enqueued ) {
|
||||
wp_enqueue_script( 'wpb_composer_front_js' );
|
||||
wp_enqueue_style( 'js_composer_front' );
|
||||
self::$default_scripts_enqueued = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return shortcode attributes, see \WPBakeryShortCode::output
|
||||
* @return array
|
||||
* @since 4.4
|
||||
*/
|
||||
public function getAtts() {
|
||||
return $this->atts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates html before shortcode html.
|
||||
*
|
||||
* @param $atts - shortcode attributes list
|
||||
* @param $content - shortcode content
|
||||
*
|
||||
* @return string - html which will be displayed before shortcode html.
|
||||
*/
|
||||
public function beforeShortcode( $atts, $content ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates html before shortcode html.
|
||||
*
|
||||
* @param $atts - shortcode attributes list
|
||||
* @param $content - shortcode content
|
||||
*
|
||||
* @return string - html which will be displayed after shortcode html.
|
||||
*/
|
||||
public function afterShortcode( $atts, $content ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $el_class
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getExtraClass( $el_class ) {
|
||||
$output = '';
|
||||
if ( '' !== $el_class ) {
|
||||
$output = ' ' . str_replace( '.', '', $el_class );
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $css_animation
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCSSAnimation( $css_animation ) {
|
||||
$output = '';
|
||||
if ( '' !== $css_animation && 'none' !== $css_animation ) {
|
||||
wp_enqueue_script( 'vc_waypoints' );
|
||||
wp_enqueue_style( 'vc_animate-css' );
|
||||
$output = ' wpb_animate_when_almost_visible wpb_' . $css_animation . ' ' . $css_animation;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create HTML comment for blocks only if wpb_debug=true
|
||||
*
|
||||
* @param $string
|
||||
*
|
||||
* @return string
|
||||
* @deprecated 4.7 For debug type html comments use more generic debugComment function.
|
||||
*
|
||||
*/
|
||||
public function endBlockComment( $string ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* if wpb_debug=true return HTML comment
|
||||
*
|
||||
* @param string $comment
|
||||
*
|
||||
* @return string
|
||||
* @since 4.7
|
||||
* @deprecated 5.5 no need for extra info in output, use xdebug
|
||||
*/
|
||||
public function debugComment( $comment ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function settings( $name ) {
|
||||
return isset( $this->settings[ $name ] ) ? $this->settings[ $name ] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param $value
|
||||
*/
|
||||
public function setSettings( $name, $value ) {
|
||||
$this->settings[ $name ] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @since 5.5
|
||||
*/
|
||||
public function getSettings() {
|
||||
return $this->settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $width
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getElementHolder( $width ) {
|
||||
$output = '';
|
||||
$column_controls = $this->getColumnControlsModular();
|
||||
$sortable = ( vc_user_access_check_shortcode_all( $this->shortcode ) ? 'wpb_sortable' : $this->nonDraggableClass );
|
||||
$css_class = 'wpb_' . $this->settings['base'] . ' wpb_content_element ' . $sortable . '' . ( ! empty( $this->settings['class'] ) ? ' ' . $this->settings['class'] : '' );
|
||||
$output .= '<div data-element_type="' . $this->settings['base'] . '" class="' . $css_class . '">';
|
||||
$output .= str_replace( '%column_size%', wpb_translateColumnWidthToFractional( $width ), $column_controls );
|
||||
$output .= $this->getCallbacks( $this->shortcode );
|
||||
$output .= '<div class="wpb_element_wrapper ' . $this->settings( 'wrapper_class' ) . '">';
|
||||
$output .= '%wpb_element_content%';
|
||||
$output .= '</div>';
|
||||
$output .= '</div>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
// Return block controls
|
||||
|
||||
/**
|
||||
* @param $controls
|
||||
* @param string $extended_css
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getColumnControls( $controls, $extended_css = '' ) {
|
||||
$controls_start = '<div class="vc_controls controls_element' . ( ! empty( $extended_css ) ? " {$extended_css}" : '' ) . '">';
|
||||
|
||||
$controls_end = '</div>';
|
||||
|
||||
$controls_add = '';
|
||||
$controls_edit = ' <a class="vc_control column_edit" href="javascript:;" title="' . sprintf( esc_attr__( 'Edit %s', 'js_composer' ), strtolower( $this->settings( 'name' ) ) ) . '"><span class="vc_icon"></span></a>';
|
||||
$controls_delete = ' <a class="vc_control column_clone" href="javascript:;" title="' . sprintf( esc_attr__( 'Clone %s', 'js_composer' ), strtolower( $this->settings( 'name' ) ) ) . '"><span class="vc_icon"></span></a> <a class="column_delete" href="javascript:;" title="' . sprintf( esc_attr__( 'Delete %s', 'js_composer' ), strtolower( $this->settings( 'name' ) ) ) . '"><span class="vc_icon"></span></a>';
|
||||
|
||||
$column_controls_full = $controls_start . $controls_add . $controls_edit . $controls_delete . $controls_end;
|
||||
$column_controls_size_delete = $controls_start . $controls_delete . $controls_end;
|
||||
$column_controls_popup_delete = $controls_start . $controls_delete . $controls_end;
|
||||
$column_controls_edit_popup_delete = $controls_start . $controls_edit . $controls_delete . $controls_end;
|
||||
$column_controls_edit = $controls_start . $controls_edit . $controls_end;
|
||||
|
||||
$editAccess = vc_user_access_check_shortcode_edit( $this->shortcode );
|
||||
$allAccess = vc_user_access_check_shortcode_all( $this->shortcode );
|
||||
|
||||
if ( 'popup_delete' === $controls ) {
|
||||
return $allAccess ? $column_controls_popup_delete : '';
|
||||
} elseif ( 'edit_popup_delete' === $controls ) {
|
||||
return $allAccess ? $column_controls_edit_popup_delete : ( $editAccess ? $column_controls_edit : '' );
|
||||
} elseif ( 'size_delete' === $controls ) {
|
||||
return $allAccess ? $column_controls_size_delete : '';
|
||||
} elseif ( 'add' === $controls ) {
|
||||
return $allAccess ? ( $controls_start . $controls_add . $controls_end ) : '';
|
||||
} else {
|
||||
return $allAccess ? $column_controls_full : ( $editAccess ? $column_controls_edit : '' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return list of controls
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getControlsList() {
|
||||
$editAccess = vc_user_access_check_shortcode_edit( $this->shortcode );
|
||||
$allAccess = vc_user_access_check_shortcode_all( $this->shortcode );
|
||||
if ( $allAccess ) {
|
||||
return apply_filters( 'vc_wpbakery_shortcode_get_controls_list', $this->controls_list, $this->shortcode );
|
||||
} else {
|
||||
$controls = apply_filters( 'vc_wpbakery_shortcode_get_controls_list', $this->controls_list, $this->shortcode );
|
||||
if ( $editAccess ) {
|
||||
foreach ( $controls as $key => $value ) {
|
||||
if ( 'edit' !== $value && 'add' !== $value ) {
|
||||
unset( $controls[ $key ] );
|
||||
}
|
||||
}
|
||||
|
||||
return $controls;
|
||||
} else {
|
||||
return in_array( 'add', $controls, true ) ? array( 'add' ) : array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build new modern controls for shortcode.
|
||||
*
|
||||
* @param string $extended_css
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getColumnControlsModular( $extended_css = '' ) {
|
||||
ob_start();
|
||||
vc_include_template( apply_filters( 'vc_wpbakery_shortcode_get_column_controls_modular_template', $this->controls_template_file ), array(
|
||||
'shortcode' => $this->shortcode,
|
||||
'position' => $this->controls_css_settings,
|
||||
'extended_css' => $extended_css,
|
||||
'name' => $this->settings( 'name' ),
|
||||
'controls' => $this->getControlsList(),
|
||||
'name_css_class' => $this->getBackendEditorControlsElementCssClass(),
|
||||
'add_allowed' => $this->getAddAllowed(),
|
||||
) );
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getBackendEditorControlsElementCssClass() {
|
||||
$moveAccess = vc_user_access()->part( 'dragndrop' )->checkStateAny( true, null )->get();
|
||||
|
||||
$sortable = ( vc_user_access_check_shortcode_all( $this->shortcode ) && $moveAccess ? ' vc_element-move' : ' ' . $this->nonDraggableClass );
|
||||
|
||||
return 'vc_control-btn vc_element-name' . $sortable;
|
||||
}
|
||||
|
||||
/**
|
||||
* This will fire callbacks if they are defined in map.php
|
||||
*
|
||||
* @param $id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCallbacks( $id ) {
|
||||
$output = '';
|
||||
|
||||
if ( isset( $this->settings['js_callback'] ) ) {
|
||||
foreach ( $this->settings['js_callback'] as $text_val => $val ) {
|
||||
// TODO: name explain
|
||||
$output .= '<input type="hidden" class="wpb_vc_callback wpb_vc_' . esc_attr( $text_val ) . '_callback " name="' . esc_attr( $text_val ) . '" value="' . $val . '" />';
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $param
|
||||
* @param $value
|
||||
*
|
||||
* vc_filter: vc_wpbakeryshortcode_single_param_html_holder_value - hook to override param value (param type and etc is available in args)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function singleParamHtmlHolder( $param, $value ) {
|
||||
$value = apply_filters( 'vc_wpbakeryshortcode_single_param_html_holder_value', $value, $param, $this->settings, $this->atts );
|
||||
$output = '';
|
||||
// Compatibility fixes
|
||||
$old_names = array(
|
||||
'yellow_message',
|
||||
'blue_message',
|
||||
'green_message',
|
||||
'button_green',
|
||||
'button_grey',
|
||||
'button_yellow',
|
||||
'button_blue',
|
||||
'button_red',
|
||||
'button_orange',
|
||||
);
|
||||
$new_names = array(
|
||||
'alert-block',
|
||||
'alert-info',
|
||||
'alert-success',
|
||||
'btn-success',
|
||||
'btn',
|
||||
'btn-info',
|
||||
'btn-primary',
|
||||
'btn-danger',
|
||||
'btn-warning',
|
||||
);
|
||||
$value = str_ireplace( $old_names, $new_names, $value );
|
||||
$param_name = isset( $param['param_name'] ) ? $param['param_name'] : '';
|
||||
$type = isset( $param['type'] ) ? $param['type'] : '';
|
||||
$class = isset( $param['class'] ) ? $param['class'] : '';
|
||||
if ( ! empty( $param['holder'] ) ) {
|
||||
if ( 'input' === $param['holder'] ) {
|
||||
$output .= '<' . $param['holder'] . ' readonly="true" class="wpb_vc_param_value ' . $param_name . ' ' . $type . ' ' . $class . '" name="' . $param_name . '" value="' . $value . '">';
|
||||
} elseif ( in_array( $param['holder'], array(
|
||||
'img',
|
||||
'iframe',
|
||||
), true ) ) {
|
||||
$output .= '<' . $param['holder'] . ' class="wpb_vc_param_value ' . $param_name . ' ' . $type . ' ' . $class . '" name="' . $param_name . '" src="' . esc_url( $value ) . '">';
|
||||
} elseif ( 'hidden' !== $param['holder'] ) {
|
||||
$output .= '<' . $param['holder'] . ' class="wpb_vc_param_value ' . $param_name . ' ' . $type . ' ' . $class . '" name="' . $param_name . '">' . $value . '</' . $param['holder'] . '>';
|
||||
}
|
||||
}
|
||||
if ( ! empty( $param['admin_label'] ) && true === $param['admin_label'] ) {
|
||||
$output .= '<span class="vc_admin_label admin_label_' . $param['param_name'] . ( empty( $value ) ? ' hidden-label' : '' ) . '"><label>' . $param['heading'] . '</label>: ' . $value . '</span>';
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $params
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getIcon( $params ) {
|
||||
$data = '';
|
||||
if ( isset( $params['is_container'] ) && true === $params['is_container'] ) {
|
||||
$data = ' data-is-container="true"';
|
||||
}
|
||||
$title = '';
|
||||
if ( isset( $params['title'] ) ) {
|
||||
$title = 'title="' . esc_attr( $params['title'] ) . '" ';
|
||||
}
|
||||
|
||||
return '<i ' . $title . 'class="vc_general vc_element-icon' . ( ! empty( $params['icon'] ) ? ' ' . sanitize_text_field( $params['icon'] ) : '' ) . '"' . $data . '></i> ';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function outputTitle( $title ) {
|
||||
$icon = $this->settings( 'icon' );
|
||||
if ( filter_var( $icon, FILTER_VALIDATE_URL ) ) {
|
||||
$icon = '';
|
||||
}
|
||||
$params = array(
|
||||
'icon' => $icon,
|
||||
'is_container' => $this->settings( 'is_container' ),
|
||||
);
|
||||
|
||||
return '<h4 class="wpb_element_title"> ' . $this->getIcon( $params ) . esc_attr( $title ) . '</h4>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function template( $content = '' ) {
|
||||
return $this->contentAdmin( $this->atts, $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* This functions prepares attributes to use in template
|
||||
* Converts back escaped characters
|
||||
*
|
||||
* @param $atts
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function prepareAtts( $atts ) {
|
||||
$returnAttributes = array();
|
||||
if ( is_array( $atts ) ) {
|
||||
foreach ( $atts as $key => $val ) {
|
||||
$returnAttributes[ $key ] = str_replace( array(
|
||||
'`{`',
|
||||
'`}`',
|
||||
'``',
|
||||
), array(
|
||||
'[',
|
||||
']',
|
||||
'"',
|
||||
), $val );
|
||||
}
|
||||
}
|
||||
|
||||
return apply_filters( 'vc_shortcode_prepare_atts', $returnAttributes, $this->shortcode, $this->settings );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getShortcode() {
|
||||
return $this->shortcode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Since 4.5
|
||||
* Possible placeholders:
|
||||
* {{ content }}
|
||||
* {{ title }}
|
||||
* {{ container-class }}
|
||||
*
|
||||
* Possible keys:
|
||||
* {{
|
||||
* <%
|
||||
* %
|
||||
* @param $markup
|
||||
* @param string $content
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
* @since 4.5
|
||||
*/
|
||||
protected function customMarkup( $markup, $content = '' ) {
|
||||
$pattern = '/\{\{([\s\S][^\n]+?)\}\}|<%([\s\S][^\n]+?)%>|%([\s\S][^\n]+?)%/';
|
||||
preg_match_all( $pattern, $markup, $matches, PREG_SET_ORDER );
|
||||
if ( is_array( $matches ) && ! empty( $matches ) ) {
|
||||
foreach ( $matches as $match ) {
|
||||
switch ( strtolower( trim( $match[1] ) ) ) {
|
||||
case 'content':
|
||||
if ( '' !== $content ) {
|
||||
$markup = str_replace( $match[0], $content, $markup );
|
||||
} elseif ( isset( $this->settings['default_content_in_template'] ) && '' !== $this->settings['default_content_in_template'] ) {
|
||||
$markup = str_replace( $match[0], $this->settings['default_content_in_template'], $markup );
|
||||
} else {
|
||||
$markup = str_replace( $match[0], '', $markup );
|
||||
}
|
||||
break;
|
||||
case 'title':
|
||||
$markup = str_replace( $match[0], $this->outputTitle( $this->settings['name'] ), $markup );
|
||||
break;
|
||||
case 'container-class':
|
||||
if ( method_exists( $this, 'containerContentClass' ) ) {
|
||||
$markup = str_replace( $match[0], $this->containerContentClass(), $markup );
|
||||
} else {
|
||||
$markup = str_replace( $match[0], '', $markup );
|
||||
}
|
||||
break;
|
||||
case 'editor_controls':
|
||||
$markup = str_replace( $match[0], $this->getColumnControls( $this->settings( 'controls' ) ), $markup );
|
||||
break;
|
||||
case 'editor_controls_bottom_add':
|
||||
$markup = str_replace( $match[0], $this->getColumnControls( 'add', 'bottom-controls' ), $markup );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return do_shortcode( $markup );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $atts
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function paramsHtmlHolders( $atts ) {
|
||||
$inner = '';
|
||||
if ( isset( $this->settings['params'] ) && is_array( $this->settings['params'] ) ) {
|
||||
foreach ( $this->settings['params'] as $param ) {
|
||||
$param_value = isset( $atts[ $param['param_name'] ] ) ? $atts[ $param['param_name'] ] : '';
|
||||
$inner .= $this->singleParamHtmlHolder( $param, $param_value );
|
||||
}
|
||||
}
|
||||
|
||||
return $inner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is allowed to add another element inside current element.
|
||||
*
|
||||
* @return bool
|
||||
* @since 4.8
|
||||
*
|
||||
*/
|
||||
public function getAddAllowed() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class WPBakeryShortCodesContainer
|
||||
*/
|
||||
abstract class WPBakeryShortCodesContainer extends WPBakeryShortCode {
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $predefined_atts = array();
|
||||
protected $backened_editor_prepend_controls = true;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function customAdminBlockParams() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $width
|
||||
* @param $i
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function mainHtmlBlockParams( $width, $i ) {
|
||||
$sortable = ( vc_user_access_check_shortcode_all( $this->shortcode ) ? 'wpb_sortable' : $this->nonDraggableClass );
|
||||
|
||||
return 'data-element_type="' . esc_attr( $this->settings['base'] ) . '" class="wpb_' . esc_attr( $this->settings['base'] ) . ' ' . esc_attr( $sortable ) . '' . ( ! empty( $this->settings['class'] ) ? ' ' . esc_attr( $this->settings['class'] ) : '' ) . ' wpb_content_holder vc_shortcodes_container"' . $this->customAdminBlockParams();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $width
|
||||
* @param $i
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function containerHtmlBlockParams( $width, $i ) {
|
||||
return 'class="' . $this->containerContentClass() . '"';
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function containerContentClass() {
|
||||
return 'wpb_column_container vc_container_for_children vc_clearfix';
|
||||
}/** @noinspection PhpMissingParentCallCommonInspection */
|
||||
|
||||
/**
|
||||
* @param string $controls
|
||||
* @param string $extended_css
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getColumnControls( $controls = 'full', $extended_css = '' ) {
|
||||
$controls_html = array();
|
||||
|
||||
$controls_html['start'] = '<div class="vc_controls vc_controls-visible controls_column' . ( ! empty( $extended_css ) ? " {$extended_css}" : '' ) . '">';
|
||||
$controls_html['end'] = '</div>';
|
||||
|
||||
if ( 'bottom-controls' === $extended_css ) {
|
||||
$controls_html['title'] = sprintf( esc_attr__( 'Append to this %s', 'js_composer' ), strtolower( $this->settings( 'name' ) ) );
|
||||
} else {
|
||||
$controls_html['title'] = sprintf( esc_attr__( 'Prepend to this %s', 'js_composer' ), strtolower( $this->settings( 'name' ) ) );
|
||||
}
|
||||
|
||||
$controls_html['move'] = '<a class="vc_control column_move vc_column-move" data-vc-control="move" href="#" title="' . sprintf( esc_attr__( 'Move this %s', 'js_composer' ), strtolower( $this->settings( 'name' ) ) ) . '"><i class="vc-composer-icon vc-c-icon-dragndrop"></i></a>';
|
||||
$moveAccess = vc_user_access()->part( 'dragndrop' )->checkStateAny( true, null )->get();
|
||||
if ( ! $moveAccess ) {
|
||||
$controls_html['move'] = '';
|
||||
}
|
||||
$controls_html['add'] = '<a class="vc_control column_add" data-vc-control="add" href="#" title="' . $controls_html['title'] . '"><i class="vc-composer-icon vc-c-icon-add"></i></a>';
|
||||
$controls_html['edit'] = '<a class="vc_control column_edit" data-vc-control="edit" href="#" title="' . sprintf( esc_html__( 'Edit this %s', 'js_composer' ), strtolower( $this->settings( 'name' ) ) ) . '"><i class="vc-composer-icon vc-c-icon-mode_edit"></i></a>';
|
||||
$controls_html['clone'] = '<a class="vc_control column_clone" data-vc-control="clone" href="#" title="' . sprintf( esc_html__( 'Clone this %s', 'js_composer' ), strtolower( $this->settings( 'name' ) ) ) . '"><i class="vc-composer-icon vc-c-icon-content_copy"></i></a>';
|
||||
$controls_html['delete'] = '<a class="vc_control column_delete" data-vc-control="delete" href="#" title="' . sprintf( esc_html__( 'Delete this %s', 'js_composer' ), strtolower( $this->settings( 'name' ) ) ) . '"><i class="vc-composer-icon vc-c-icon-delete_empty"></i></a>';
|
||||
$controls_html['full'] = $controls_html['move'] . $controls_html['add'] . $controls_html['edit'] . $controls_html['clone'] . $controls_html['delete'];
|
||||
|
||||
$editAccess = vc_user_access_check_shortcode_edit( $this->shortcode );
|
||||
$allAccess = vc_user_access_check_shortcode_all( $this->shortcode );
|
||||
|
||||
if ( ! empty( $controls ) ) {
|
||||
if ( is_string( $controls ) ) {
|
||||
$controls = array( $controls );
|
||||
}
|
||||
$controls_string = $controls_html['start'];
|
||||
foreach ( $controls as $control ) {
|
||||
if ( ( $editAccess && 'edit' === $control ) || $allAccess ) {
|
||||
if ( isset( $controls_html[ $control ] ) ) {
|
||||
$controls_string .= $controls_html[ $control ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $controls_string . $controls_html['end'];
|
||||
}
|
||||
|
||||
if ( $allAccess ) {
|
||||
return $controls_html['start'] . $controls_html['full'] . $controls_html['end'];
|
||||
} elseif ( $editAccess ) {
|
||||
return $controls_html['start'] . $controls_html['edit'] . $controls_html['end'];
|
||||
}
|
||||
|
||||
return $controls_html['start'] . $controls_html['end'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $atts
|
||||
* @param null $content
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function contentAdmin( $atts, $content = null ) {
|
||||
$width = '';
|
||||
|
||||
$atts = shortcode_atts( $this->predefined_atts, $atts );
|
||||
extract( $atts );
|
||||
$this->atts = $atts;
|
||||
$output = '';
|
||||
|
||||
$output .= '<div ' . $this->mainHtmlBlockParams( $width, 1 ) . '>';
|
||||
if ( $this->backened_editor_prepend_controls ) {
|
||||
$output .= $this->getColumnControls( $this->settings( 'controls' ) );
|
||||
}
|
||||
$output .= '<div class="wpb_element_wrapper">';
|
||||
|
||||
if ( isset( $this->settings['custom_markup'] ) && '' !== $this->settings['custom_markup'] ) {
|
||||
$markup = $this->settings['custom_markup'];
|
||||
$output .= $this->customMarkup( $markup );
|
||||
} else {
|
||||
$output .= $this->outputTitle( $this->settings['name'] );
|
||||
$output .= '<div ' . $this->containerHtmlBlockParams( $width, 1 ) . '>';
|
||||
$output .= do_shortcode( shortcode_unautop( $content ) );
|
||||
$output .= '</div>';
|
||||
$output .= $this->paramsHtmlHolders( $atts );
|
||||
}
|
||||
|
||||
$output .= '</div>';
|
||||
if ( $this->backened_editor_prepend_controls ) {
|
||||
$output .= $this->getColumnControls( 'add', 'bottom-controls' );
|
||||
|
||||
}
|
||||
$output .= '</div>';
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function outputTitle( $title ) {
|
||||
$icon = $this->settings( 'icon' );
|
||||
if ( filter_var( $icon, FILTER_VALIDATE_URL ) ) {
|
||||
$icon = '';
|
||||
}
|
||||
$params = array(
|
||||
'icon' => $icon,
|
||||
'is_container' => $this->settings( 'is_container' ),
|
||||
'title' => $title,
|
||||
);
|
||||
|
||||
return '<h4 class="wpb_element_title"> ' . $this->getIcon( $params ) . '</h4>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getBackendEditorChildControlsElementCssClass() {
|
||||
return 'vc_element-name';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class WPBakeryShortCode_Layerslider_Vc
|
||||
*/
|
||||
class WPBakeryShortCode_Layerslider_Vc extends WPBakeryShortCode {
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class Vc_Pageable
|
||||
*/
|
||||
class WPBakeryShortCode_Vc_Pageable extends WPBakeryShortCode {
|
||||
/**
|
||||
* @param $settings
|
||||
*/
|
||||
public function __construct( $settings ) {
|
||||
parent::__construct( $settings );
|
||||
$this->shortcodeScripts();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register scripts and styles for pager
|
||||
*/
|
||||
public function shortcodeScripts() {
|
||||
wp_register_script( 'vc_pageable_owl-carousel', vc_asset_url( 'lib/owl-carousel2-dist/owl.carousel.min.js' ), array(
|
||||
'jquery',
|
||||
), WPB_VC_VERSION, true );
|
||||
wp_register_script( 'vc_waypoints', vc_asset_url( 'lib/vc_waypoints/vc-waypoints.min.js' ), array( 'jquery' ), WPB_VC_VERSION, true );
|
||||
|
||||
wp_register_style( 'vc_pageable_owl-carousel-css', vc_asset_url( 'lib/owl-carousel2-dist/assets/owl.min.css' ), array(), WPB_VC_VERSION );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $grid_style
|
||||
* @param $settings
|
||||
* @param $content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function contentAll( $grid_style, $settings, $content ) {
|
||||
return '<div class="vc_pageable-slide-wrapper vc_clearfix" data-vc-grid-content="true">' . $content . '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $grid_style
|
||||
* @param $settings
|
||||
* @param $content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function contentLoadMore( $grid_style, $settings, $content ) {
|
||||
if ( ! isset( $settings['btn_data'] ) && isset( $settings['button_style'] ) && isset( $settings['button_size'] ) && isset( $settings['button_color'] ) ) {
|
||||
// BC: for those who overrided
|
||||
$output = sprintf( '<div class="vc_pageable-slide-wrapper vc_clearfix" data-vc-grid-content="true">%s</div><div class="vc_pageable-load-more-btn" data-vc-grid-load-more-btn="true">%s</div>', $content, do_shortcode( '[vc_button2 size="' . $settings['button_size'] . '" title="' . esc_attr__( 'Load more', 'js_composer' ) . '" style="' . $settings['button_style'] . '" color="' . $settings['button_color'] . '" el_class="vc_grid-btn-load_more"]' ) );
|
||||
|
||||
return $output;
|
||||
} elseif ( isset( $settings['btn_data'] ) ) {
|
||||
$data = $settings['btn_data'];
|
||||
$data['el_class'] = 'vc_grid-btn-load_more';
|
||||
$data['link'] = 'load-more-grid';
|
||||
$button3 = new WPBakeryShortCode_Vc_Btn( array( 'base' => 'vc_btn' ) );
|
||||
|
||||
$output = sprintf( '<div class="vc_pageable-slide-wrapper vc_clearfix" data-vc-grid-content="true">%s</div><div class="vc_pageable-load-more-btn" data-vc-grid-load-more-btn="true">%s</div>', $content, apply_filters( 'vc_gitem_template_attribute_vc_btn', '', array(
|
||||
'post' => new stdClass(),
|
||||
'data' => str_replace( array(
|
||||
'{{ vc_btn:',
|
||||
'}}',
|
||||
), '', $button3->output( $data ) ),
|
||||
) ) );
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $grid_style
|
||||
* @param $settings
|
||||
* @param $content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function contentLazy( $grid_style, $settings, $content ) {
|
||||
return '<div class="vc_pageable-slide-wrapper vc_clearfix" data-vc-grid-content="true">' . $content . '</div><div data-lazy-loading-btn="true" style="display: none;"><a href="' . esc_url( get_permalink( $settings['page_id'] ) ) . '"></a></div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $grid_style
|
||||
* @param $settings
|
||||
* @param string $content
|
||||
*
|
||||
* @param string $css_class
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function renderPagination( $grid_style, $settings, $content = '', $css_class = '' ) {
|
||||
$css_class .= empty( $css_class ) ? '' : ' vc_pageable-wrapper vc_hook_hover';
|
||||
$content_method = vc_camel_case( 'content-' . $grid_style );
|
||||
$content = method_exists( $this, $content_method ) ? $this->$content_method( $grid_style, $settings, $content ) : $content;
|
||||
|
||||
$output = '<div class="' . esc_attr( $css_class ) . '" data-vc-pageable-content="true">' . $content . '</div>';
|
||||
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
public function enqueueScripts() {
|
||||
wp_enqueue_script( 'vc_pageable_owl-carousel' );
|
||||
wp_enqueue_style( 'vc_pageable_owl-carousel-css' );
|
||||
wp_enqueue_style( 'vc_animate-css' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is pageable
|
||||
* @return bool
|
||||
* @since 4.7.4
|
||||
*/
|
||||
public function isObjectPageable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check can user manage post.
|
||||
*
|
||||
* @param int $page_id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function currentUserCanManage( $page_id ) {
|
||||
return vc_user_access()->wpAny( array(
|
||||
'edit_post',
|
||||
(int) $page_id,
|
||||
) )->get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Class WPBakeryShortCode_Rev_Slider_Vc
|
||||
*/
|
||||
class WPBakeryShortCode_Rev_Slider_Vc extends WPBakeryShortCode {
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
require_once vc_path_dir( 'SHORTCODES_DIR', 'vc-tab.php' );
|
||||
|
||||
/**
|
||||
* Class WPBakeryShortCode_VC_Accordion_tab
|
||||
*/
|
||||
class WPBakeryShortCode_VC_Accordion_Tab extends WPBakeryShortCode_VC_Tab {
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $controls_css_settings = 'tc vc_control-container';
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $controls_list = array(
|
||||
'add',
|
||||
'edit',
|
||||
'clone',
|
||||
'delete',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $nonDraggableClass = 'vc-non-draggable-container';
|
||||
|
||||
/**
|
||||
* @param $atts
|
||||
* @param null $content
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function contentAdmin( $atts, $content = null ) {
|
||||
$width = '';
|
||||
// @codingStandardsIgnoreLine
|
||||
extract( vc_map_get_attributes( $this->getShortcode(), $atts ) );
|
||||
$output = '';
|
||||
|
||||
$column_controls = $this->getColumnControls( $this->settings( 'controls' ) );
|
||||
$column_controls_bottom = $this->getColumnControls( 'add', 'bottom-controls' );
|
||||
|
||||
if ( 'column_14' === $width || '1/4' === $width ) {
|
||||
$width = array( 'vc_col-sm-3' );
|
||||
} elseif ( 'column_14-14-14-14' === $width ) {
|
||||
$width = array(
|
||||
'vc_col-sm-3',
|
||||
'vc_col-sm-3',
|
||||
'vc_col-sm-3',
|
||||
'vc_col-sm-3',
|
||||
);
|
||||
} elseif ( 'column_13' === $width || '1/3' === $width ) {
|
||||
$width = array( 'vc_col-sm-4' );
|
||||
} elseif ( 'column_13-23' === $width ) {
|
||||
$width = array(
|
||||
'vc_col-sm-4',
|
||||
'vc_col-sm-8',
|
||||
);
|
||||
} elseif ( 'column_13-13-13' === $width ) {
|
||||
$width = array(
|
||||
'vc_col-sm-4',
|
||||
'vc_col-sm-4',
|
||||
'vc_col-sm-4',
|
||||
);
|
||||
} elseif ( 'column_12' === $width || '1/2' === $width ) {
|
||||
$width = array( 'vc_col-sm-6' );
|
||||
} elseif ( 'column_12-12' === $width ) {
|
||||
$width = array(
|
||||
'vc_col-sm-6',
|
||||
'vc_col-sm-6',
|
||||
);
|
||||
} elseif ( 'column_23' === $width || '2/3' === $width ) {
|
||||
$width = array( 'vc_col-sm-8' );
|
||||
} elseif ( 'column_34' === $width || '3/4' === $width ) {
|
||||
$width = array( 'vc_col-sm-9' );
|
||||
} elseif ( 'column_16' === $width || '1/6' === $width ) {
|
||||
$width = array( 'vc_col-sm-2' );
|
||||
} else {
|
||||
$width = array( '' );
|
||||
}
|
||||
$sortable = ( vc_user_access_check_shortcode_all( $this->shortcode ) ? 'wpb_sortable' : $this->nonDraggableClass );
|
||||
|
||||
$count = count( $width );
|
||||
for ( $i = 0; $i < $count; $i ++ ) {
|
||||
$output .= '<div class="group ' . $sortable . '">';
|
||||
$output .= '<h3><span class="tab-label"><%= params.title %></span></h3>';
|
||||
$output .= '<div ' . $this->mainHtmlBlockParams( $width, $i ) . '>';
|
||||
$output .= str_replace( '%column_size%', wpb_translateColumnWidthToFractional( $width[ $i ] ), $column_controls );
|
||||
$output .= '<div class="wpb_element_wrapper">';
|
||||
$output .= '<div ' . $this->containerHtmlBlockParams( $width, $i ) . '>';
|
||||
$output .= do_shortcode( shortcode_unautop( $content ) );
|
||||
$output .= '</div>';
|
||||
if ( isset( $this->settings['params'] ) ) {
|
||||
$inner = '';
|
||||
foreach ( $this->settings['params'] as $param ) {
|
||||
$param_value = isset( ${$param['param_name']} ) ? ${$param['param_name']} : '';
|
||||
if ( is_array( $param_value ) ) {
|
||||
// Get first element from the array
|
||||
reset( $param_value );
|
||||
$first_key = key( $param_value );
|
||||
$param_value = $param_value[ $first_key ];
|
||||
}
|
||||
$inner .= $this->singleParamHtmlHolder( $param, $param_value );
|
||||
}
|
||||
$output .= $inner;
|
||||
}
|
||||
$output .= '</div>';
|
||||
$output .= str_replace( '%column_size%', wpb_translateColumnWidthToFractional( $width[ $i ] ), $column_controls_bottom );
|
||||
$output .= '</div>';
|
||||
$output .= '</div>';
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $width
|
||||
* @param $i
|
||||
* @return string
|
||||
*/
|
||||
public function mainHtmlBlockParams( $width, $i ) {
|
||||
return 'data-element_type="' . esc_attr( $this->settings['base'] ) . '" class=" wpb_' . esc_attr( $this->settings['base'] ) . '"' . $this->customAdminBlockParams();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $width
|
||||
* @param $i
|
||||
* @return string
|
||||
*/
|
||||
public function containerHtmlBlockParams( $width, $i ) {
|
||||
return 'class="wpb_column_container vc_container_for_children"';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $title
|
||||
* @return string
|
||||
*/
|
||||
protected function outputTitle( $title ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function customAdminBlockParams() {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* WPBakery WPBakery Page Builder shortcodes
|
||||
*
|
||||
* @package WPBakeryPageBuilder
|
||||
*
|
||||
*/
|
||||
class WPBakeryShortCode_Vc_Accordion extends WPBakeryShortCode {
|
||||
protected $controls_css_settings = 'out-tc vc_controls-content-widget';
|
||||
|
||||
/**
|
||||
* @param $atts
|
||||
* @param null $content
|
||||
* @return mixed|string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function contentAdmin( $atts, $content = null ) {
|
||||
$width = $custom_markup = '';
|
||||
$shortcode_attributes = array( 'width' => '1/1' );
|
||||
foreach ( $this->settings['params'] as $param ) {
|
||||
if ( 'content' !== $param['param_name'] ) {
|
||||
$shortcode_attributes[ $param['param_name'] ] = isset( $param['value'] ) ? $param['value'] : null;
|
||||
} elseif ( 'content' === $param['param_name'] && null === $content ) {
|
||||
$content = $param['value'];
|
||||
}
|
||||
}
|
||||
extract( shortcode_atts( $shortcode_attributes, $atts ) );
|
||||
|
||||
$elem = $this->getElementHolder( $width );
|
||||
|
||||
$inner = '';
|
||||
foreach ( $this->settings['params'] as $param ) {
|
||||
$param_value = isset( ${$param['param_name']} ) ? ${$param['param_name']} : '';
|
||||
if ( is_array( $param_value ) ) {
|
||||
// Get first element from the array
|
||||
reset( $param_value );
|
||||
$first_key = key( $param_value );
|
||||
$param_value = $param_value[ $first_key ];
|
||||
}
|
||||
$inner .= $this->singleParamHtmlHolder( $param, $param_value );
|
||||
}
|
||||
|
||||
$tmp = '';
|
||||
|
||||
if ( isset( $this->settings['custom_markup'] ) && '' !== $this->settings['custom_markup'] ) {
|
||||
if ( '' !== $content ) {
|
||||
$custom_markup = str_ireplace( '%content%', $tmp . $content, $this->settings['custom_markup'] );
|
||||
} elseif ( '' === $content && isset( $this->settings['default_content_in_template'] ) && '' !== $this->settings['default_content_in_template'] ) {
|
||||
$custom_markup = str_ireplace( '%content%', $this->settings['default_content_in_template'], $this->settings['custom_markup'] );
|
||||
} else {
|
||||
$custom_markup = str_ireplace( '%content%', '', $this->settings['custom_markup'] );
|
||||
}
|
||||
$inner .= do_shortcode( $custom_markup );
|
||||
}
|
||||
$output = str_ireplace( '%wpb_element_content%', $inner, $elem );
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,588 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
require_once vc_path_dir( 'SHORTCODES_DIR', 'paginator/class-vc-pageable.php' );
|
||||
require_once vc_path_dir( 'SHORTCODES_DIR', 'vc-btn.php' );
|
||||
|
||||
/**
|
||||
* Class WPBakeryShortCode_Vc_Basic_Grid
|
||||
*/
|
||||
class WPBakeryShortCode_Vc_Basic_Grid extends WPBakeryShortCode_Vc_Pageable {
|
||||
public $pagable_type = 'grid';
|
||||
public $items = array();
|
||||
public static $excluded_ids = array();
|
||||
protected $element_template = '';
|
||||
protected static $default_max_items = 1000;
|
||||
public $post_id = false;
|
||||
/** @var \Vc_Grid_Item $grid_item */
|
||||
public $grid_item = false;
|
||||
protected $filter_terms;
|
||||
public $attributes_defaults = array(
|
||||
'initial_loading_animation' => 'zoomIn',
|
||||
'full_width' => '',
|
||||
'layout' => '',
|
||||
'element_width' => '4',
|
||||
'items_per_page' => '5',
|
||||
'gap' => '',
|
||||
'style' => 'all',
|
||||
'show_filter' => '',
|
||||
'filter_default_title' => 'all',
|
||||
'exclude_filter' => '',
|
||||
'filter_style' => '',
|
||||
'filter_size' => 'md',
|
||||
'filter_align' => '',
|
||||
'filter_color' => '',
|
||||
'arrows_design' => '',
|
||||
'arrows_position' => '',
|
||||
'arrows_color' => '',
|
||||
'paging_design' => '',
|
||||
'paging_color' => '',
|
||||
'paging_animation_in' => '',
|
||||
'paging_animation_out' => '',
|
||||
'loop' => '',
|
||||
'autoplay' => '',
|
||||
'post_type' => 'post',
|
||||
'filter_source' => 'category',
|
||||
'orderby' => '',
|
||||
'order' => 'DESC',
|
||||
// @codingStandardsIgnoreLine
|
||||
'meta_key' => '',
|
||||
'max_items' => '10',
|
||||
'offset' => '0',
|
||||
'taxonomies' => '',
|
||||
'custom_query' => '',
|
||||
'data_type' => 'query',
|
||||
'include' => '',
|
||||
'exclude' => '',
|
||||
'item' => 'none',
|
||||
'grid_id' => '',
|
||||
// disabled, needed for-BC:
|
||||
'button_style' => '',
|
||||
'button_color' => '',
|
||||
'button_size' => '',
|
||||
// New button3:
|
||||
'btn_title' => '',
|
||||
'btn_style' => 'modern',
|
||||
'btn_el_id' => '',
|
||||
'btn_custom_background' => '#ededed',
|
||||
'btn_custom_text' => '#666',
|
||||
'btn_outline_custom_color' => '#666',
|
||||
'btn_outline_custom_hover_background' => '#666',
|
||||
'btn_outline_custom_hover_text' => '#fff',
|
||||
'btn_shape' => 'rounded',
|
||||
'btn_color' => 'blue',
|
||||
'btn_size' => 'md',
|
||||
'btn_align' => 'inline',
|
||||
'btn_button_block' => '',
|
||||
'btn_add_icon' => '',
|
||||
'btn_i_align' => 'left',
|
||||
'btn_i_type' => 'fontawesome',
|
||||
'btn_i_icon_fontawesome' => 'fa fa-adjust',
|
||||
'btn_i_icon_openiconic' => 'vc-oi vc-oi-dial',
|
||||
'btn_i_icon_typicons' => 'typcn typcn-adjust-brightness',
|
||||
'btn_i_icon_entypo' => 'entypo-icon entypo-icon-note',
|
||||
'btn_i_icon_linecons' => 'vc_li vc_li-heart',
|
||||
'btn_i_icon_pixelicons' => 'vc_pixel_icon vc_pixel_icon-alert',
|
||||
'btn_custom_onclick' => '',
|
||||
'btn_custom_onclick_code' => '',
|
||||
// fix template
|
||||
'page_id' => '',
|
||||
);
|
||||
protected $grid_settings = array();
|
||||
protected $grid_id_unique_name = 'vc_gid'; // if you change this also change in hook-vc-grid.php
|
||||
|
||||
/**
|
||||
* @var \WP_Query
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* WPBakeryShortCode_Vc_Basic_Grid constructor.
|
||||
* @param $settings
|
||||
*/
|
||||
public function __construct( $settings ) {
|
||||
parent::__construct( $settings );
|
||||
$this->attributes_defaults['btn_title'] = esc_html__( 'Load more', 'js_composer' );
|
||||
$this->shortcodeScripts();
|
||||
}
|
||||
|
||||
public function shortcodeScripts() {
|
||||
parent::shortcodeScripts();
|
||||
|
||||
wp_register_script( 'vc_grid-js-imagesloaded', vc_asset_url( 'lib/bower/imagesloaded/imagesloaded.pkgd.min.js' ), array( 'jquery' ), WPB_VC_VERSION, true );
|
||||
wp_register_script( 'vc_grid', vc_asset_url( 'js/dist/vc_grid.min.js' ), array(
|
||||
'jquery',
|
||||
'underscore',
|
||||
'vc_pageable_owl-carousel',
|
||||
'vc_waypoints',
|
||||
// 'isotope',
|
||||
'vc_grid-js-imagesloaded',
|
||||
), WPB_VC_VERSION, true );
|
||||
}
|
||||
|
||||
public function enqueueScripts() {
|
||||
parent::enqueueScripts();
|
||||
wp_enqueue_script( 'vc_grid-js-imagesloaded' );
|
||||
wp_enqueue_script( 'vc_grid' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
*/
|
||||
public static function addExcludedId( $id ) {
|
||||
self::$excluded_ids[] = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function excludedIds() {
|
||||
return self::$excluded_ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $atts
|
||||
* @param $content
|
||||
* @return false|mixed|string|void
|
||||
*/
|
||||
public function getId( $atts, $content ) {
|
||||
if ( vc_is_page_editable() || is_preview() ) {
|
||||
/*
|
||||
* We are in Frontend editor
|
||||
* We need to send RAW shortcode data, so hash is just json_encode of atts and content
|
||||
*/
|
||||
return rawurlencode( wp_json_encode( array(
|
||||
'tag' => $this->shortcode,
|
||||
'atts' => $atts,
|
||||
'content' => $content,
|
||||
) ) );
|
||||
}
|
||||
|
||||
$id_pattern = '/' . $this->grid_id_unique_name . '\:([\w\-_]+)/';
|
||||
|
||||
$id_value = isset( $atts['grid_id'] ) ? $atts['grid_id'] : '';
|
||||
|
||||
preg_match( $id_pattern, $id_value, $id_matches );
|
||||
$id_to_save = wp_json_encode( array( 'failed_to_get_id' => esc_attr( $id_value ) ) );
|
||||
|
||||
if ( ! empty( $id_matches ) ) {
|
||||
$id_to_save = $id_matches[1];
|
||||
}
|
||||
|
||||
return $id_to_save;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $page_id
|
||||
* @param $grid_id
|
||||
* @return array|mixed|object|void
|
||||
*/
|
||||
public function findPostShortcodeById( $page_id, $grid_id ) {
|
||||
if ( $this->currentUserCanManage( $page_id ) && preg_match( '/\"tag\"\:/', urldecode( $grid_id ) ) ) {
|
||||
return json_decode( urldecode( $grid_id ), true ); // if frontend, no hash exists - just RAW data
|
||||
}
|
||||
$post_meta = get_post_meta( (int) $page_id, '_vc_post_settings' );
|
||||
$shortcode = false;
|
||||
if ( is_array( $post_meta ) ) {
|
||||
foreach ( $post_meta as $meta ) {
|
||||
if ( isset( $meta['vc_grid_id'] ) && ! empty( $meta['vc_grid_id']['shortcodes'] ) && isset( $meta['vc_grid_id']['shortcodes'][ $grid_id ] ) ) {
|
||||
$shortcode = $meta['vc_grid_id']['shortcodes'][ $grid_id ];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return apply_filters( 'vc_basic_grid_find_post_shortcode', $shortcode, $page_id, $grid_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function renderItems() {
|
||||
$output = '';
|
||||
$items = '';
|
||||
$this->buildGridSettings();
|
||||
$atts = $this->atts;
|
||||
$settings = $this->grid_settings;
|
||||
$filter_terms = $this->filter_terms;
|
||||
$is_end = isset( $this->is_end ) && $this->is_end;
|
||||
$css_classes = 'vc_grid vc_row' . esc_attr( $atts['gap'] > 0 ? ' vc_grid-gutter-' . (int) $atts['gap'] . 'px' : '' );
|
||||
$currentScope = WPBMap::getScope();
|
||||
if ( is_array( $this->items ) && ! empty( $this->items ) ) {
|
||||
// Adding before vc_map
|
||||
WPBMap::setScope( Vc_Grid_Item_Editor::postType() );
|
||||
require_once vc_path_dir( 'PARAMS_DIR', 'vc_grid_item/class-vc-grid-item.php' );
|
||||
$this->grid_item = new Vc_Grid_Item();
|
||||
$this->grid_item->setGridAttributes( $atts );
|
||||
$this->grid_item->setIsEnd( $is_end );
|
||||
$this->grid_item->setTemplateById( $atts['item'] );
|
||||
$output .= $this->grid_item->addShortcodesCustomCss();
|
||||
ob_start();
|
||||
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
||||
wp_print_styles();
|
||||
}
|
||||
$output .= ob_get_clean();
|
||||
$attributes = array(
|
||||
'filter_terms' => $filter_terms,
|
||||
'atts' => $atts,
|
||||
'grid_item',
|
||||
$this->grid_item,
|
||||
);
|
||||
$output .= apply_filters( 'vc_basic_grid_template_filter', vc_get_template( 'shortcodes/vc_basic_grid_filter.php', $attributes ), $attributes );
|
||||
global $post;
|
||||
$backup = $post;
|
||||
foreach ( $this->items as $postItem ) {
|
||||
$this->query->setup_postdata( $postItem );
|
||||
// @codingStandardsIgnoreLine
|
||||
$post = $postItem;
|
||||
$items .= $this->grid_item->renderItem( $postItem );
|
||||
}
|
||||
wp_reset_postdata();
|
||||
$post = $backup;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
$items = apply_filters( $this->shortcode . '_items_list', $items );
|
||||
$output .= $this->renderPagination( $atts['style'], $settings, $items, $css_classes );
|
||||
WPBMap::setScope( $currentScope );
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function setContentLimits() {
|
||||
$atts = $this->atts;
|
||||
if ( 'ids' === $this->atts['post_type'] ) {
|
||||
$this->atts['max_items'] = 0;
|
||||
$this->atts['offset'] = 0;
|
||||
$this->atts['items_per_page'] = apply_filters( 'vc_basic_grid_max_items', self::$default_max_items );
|
||||
} else {
|
||||
$offset = isset( $atts['offset'] ) ? (int) $atts['offset'] : $this->attributes_defaults['offset'];
|
||||
$this->atts['offset'] = $offset;
|
||||
$this->atts['max_items'] = isset( $atts['max_items'] ) ? (int) $atts['max_items'] : (int) $this->attributes_defaults['max_items'];
|
||||
$this->atts['items_per_page'] = ! isset( $atts['items_per_page'] ) ? (int) $this->attributes_defaults['items_per_page'] : (int) $atts['items_per_page'];
|
||||
if ( $this->atts['max_items'] < 1 ) {
|
||||
$this->atts['max_items'] = apply_filters( 'vc_basic_grid_max_items', self::$default_max_items );
|
||||
}
|
||||
}
|
||||
$this->setPagingAll( $this->atts['max_items'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $max_items
|
||||
*/
|
||||
protected function setPagingAll( $max_items ) {
|
||||
$atts = $this->atts;
|
||||
$this->atts['query_items_per_page'] = $max_items > 0 ? $max_items : apply_filters( 'vc_basic_grid_items_per_page_all_max_items', self::$default_max_items );
|
||||
$this->atts['items_per_page'] = $this->atts['query_items_per_page'];
|
||||
$this->atts['query_offset'] = isset( $atts['offset'] ) ? (int) $atts['offset'] : $this->attributes_defaults['offset'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $vc_request_param
|
||||
* @return false|mixed|string|void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function renderAjax( $vc_request_param ) {
|
||||
$this->items = array(); // clear this items array (if used more than once);
|
||||
$id = isset( $vc_request_param['shortcode_id'] ) ? $vc_request_param['shortcode_id'] : false;
|
||||
$shortcode = false;
|
||||
if ( ! isset( $vc_request_param['page_id'] ) ) {
|
||||
return wp_json_encode( array( 'status' => 'Nothing found' ) );
|
||||
}
|
||||
if ( $id ) {
|
||||
$shortcode = $this->findPostShortcodeById( $vc_request_param['page_id'], $id );
|
||||
}
|
||||
if ( ! is_array( $shortcode ) ) {
|
||||
return wp_json_encode( array( 'status' => 'Nothing found' ) );
|
||||
}
|
||||
visual_composer()->registerAdminCss();
|
||||
visual_composer()->registerAdminJavascript();
|
||||
// Set post id
|
||||
$this->post_id = (int) $vc_request_param['page_id'];
|
||||
|
||||
$shortcode_atts = $shortcode['atts'];
|
||||
$this->shortcode_content = $shortcode['content'];
|
||||
$this->buildAtts( $shortcode_atts, $shortcode['content'] );
|
||||
|
||||
$this->buildItems();
|
||||
|
||||
return $this->renderItems();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool|false|int
|
||||
*/
|
||||
public function postID() {
|
||||
if ( ! $this->post_id ) {
|
||||
$this->post_id = get_the_ID();
|
||||
}
|
||||
|
||||
return $this->post_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $atts
|
||||
* @param $content
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function buildAtts( $atts, $content ) {
|
||||
$this->post_id = false;
|
||||
$this->grid_settings = array();
|
||||
$this->filter_terms = null;
|
||||
$this->items = array();
|
||||
$arr_keys = array_keys( $atts );
|
||||
$count = count( $atts );
|
||||
for ( $i = 0; $i < $count; $i ++ ) {
|
||||
$atts[ $arr_keys[ $i ] ] = html_entity_decode( $atts[ $arr_keys[ $i ] ], ENT_QUOTES, 'utf-8' );
|
||||
}
|
||||
if ( isset( $atts['grid_id'] ) && ! empty( $atts['grid_id'] ) ) {
|
||||
$id_to_save = $this->getId( $atts, $content );
|
||||
}
|
||||
|
||||
$atts = $this->convertButton2ToButton3( $atts );
|
||||
$atts = shortcode_atts( $this->attributes_defaults, vc_map_get_attributes( $this->getShortcode(), $atts ) );
|
||||
$this->atts = $atts;
|
||||
if ( isset( $id_to_save ) ) {
|
||||
$this->atts['shortcode_id'] = $id_to_save;
|
||||
}
|
||||
|
||||
$this->atts['page_id'] = $this->postID();
|
||||
|
||||
$this->element_template = $content;
|
||||
// @since 4.4.3
|
||||
if ( 'custom' === $this->attr( 'post_type' ) ) {
|
||||
$this->atts['style'] = 'all';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter attribute.
|
||||
*
|
||||
* @param $key
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function attr( $key ) {
|
||||
return isset( $this->atts[ $key ] ) ? $this->atts[ $key ] : null;
|
||||
}
|
||||
|
||||
public function buildGridSettings() {
|
||||
$this->grid_settings = array(
|
||||
'page_id' => $this->atts['page_id'],
|
||||
// used in basic grid for initialization
|
||||
'style' => $this->atts['style'],
|
||||
'action' => 'vc_get_vc_grid_data',
|
||||
);
|
||||
// used in ajax request for items
|
||||
if ( isset( $this->atts['shortcode_id'] ) && ! empty( $this->atts['shortcode_id'] ) ) {
|
||||
$this->grid_settings['shortcode_id'] = $this->atts['shortcode_id'];
|
||||
} elseif ( isset( $this->atts['shortcode_hash'] ) && ! empty( $this->atts['shortcode_hash'] ) ) {
|
||||
// @deprecated since 4.4.3
|
||||
$this->grid_settings['shortcode_hash'] = $this->atts['shortcode_hash'];
|
||||
}
|
||||
if ( 'load-more' === $this->atts['style'] ) {
|
||||
$this->grid_settings = array_merge( $this->grid_settings, array(
|
||||
// used in dispaly style load more button, lazy, pagination
|
||||
'items_per_page' => $this->atts['items_per_page'],
|
||||
'btn_data' => vc_map_integrate_parse_atts( $this->shortcode, 'vc_btn', $this->atts, 'btn_' ),
|
||||
) );
|
||||
} elseif ( 'lazy' === $this->atts['style'] ) {
|
||||
$this->grid_settings = array_merge( $this->grid_settings, array(
|
||||
'items_per_page' => $this->atts['items_per_page'],
|
||||
) );
|
||||
} elseif ( 'pagination' === $this->atts['style'] ) {
|
||||
$this->grid_settings = array_merge( $this->grid_settings, array(
|
||||
'items_per_page' => $this->atts['items_per_page'],
|
||||
// used in pagination style
|
||||
'auto_play' => $this->atts['autoplay'] > 0 ? true : false,
|
||||
'gap' => (int) $this->atts['gap'],
|
||||
// not used yet, but can be used in isotope..
|
||||
'speed' => (int) $this->atts['autoplay'] * 1000,
|
||||
'loop' => $this->atts['loop'],
|
||||
'animation_in' => $this->atts['paging_animation_in'],
|
||||
'animation_out' => $this->atts['paging_animation_out'],
|
||||
'arrows_design' => $this->atts['arrows_design'],
|
||||
'arrows_color' => $this->atts['arrows_color'],
|
||||
'arrows_position' => $this->atts['arrows_position'],
|
||||
'paging_design' => $this->atts['paging_design'],
|
||||
'paging_color' => $this->atts['paging_color'],
|
||||
) );
|
||||
}
|
||||
$this->grid_settings['tag'] = $this->shortcode;
|
||||
}
|
||||
|
||||
// TODO: setter & getter to attributes
|
||||
|
||||
/**
|
||||
* @param $atts
|
||||
* @return array
|
||||
*/
|
||||
public function buildQuery( $atts ) {
|
||||
// Set include & exclude
|
||||
if ( 'ids' !== $atts['post_type'] && ! empty( $atts['exclude'] ) ) {
|
||||
$atts['exclude'] .= ',' . implode( ',', $this->excludedIds() );
|
||||
} else {
|
||||
$atts['exclude'] = implode( ',', $this->excludedIds() );
|
||||
}
|
||||
if ( 'ids' !== $atts['post_type'] ) {
|
||||
$settings = array(
|
||||
'posts_per_page' => $atts['query_items_per_page'],
|
||||
'offset' => $atts['query_offset'],
|
||||
'orderby' => $atts['orderby'],
|
||||
'order' => $atts['order'],
|
||||
'meta_key' => in_array( $atts['orderby'], array(
|
||||
'meta_value',
|
||||
'meta_value_num',
|
||||
), true ) ? $atts['meta_key'] : '',
|
||||
'post_type' => $atts['post_type'],
|
||||
'exclude' => $atts['exclude'],
|
||||
);
|
||||
if ( ! empty( $atts['taxonomies'] ) ) {
|
||||
$vc_taxonomies_types = get_taxonomies( array( 'public' => true ) );
|
||||
$terms = get_terms( array_keys( $vc_taxonomies_types ), array(
|
||||
'hide_empty' => false,
|
||||
'include' => $atts['taxonomies'],
|
||||
) );
|
||||
$settings['tax_query'] = array();
|
||||
$tax_queries = array(); // List of taxnonimes
|
||||
foreach ( $terms as $term ) {
|
||||
if ( ! isset( $tax_queries[ $term->taxonomy ] ) ) {
|
||||
$tax_queries[ $term->taxonomy ] = array(
|
||||
'taxonomy' => $term->taxonomy,
|
||||
'field' => 'id',
|
||||
'terms' => array( $term->term_id ),
|
||||
'relation' => 'IN',
|
||||
);
|
||||
} else {
|
||||
$tax_queries[ $term->taxonomy ]['terms'][] = $term->term_id;
|
||||
}
|
||||
}
|
||||
$settings['tax_query'] = array_values( $tax_queries );
|
||||
$settings['tax_query']['relation'] = 'OR';
|
||||
}
|
||||
} else {
|
||||
if ( empty( $atts['include'] ) ) {
|
||||
$atts['include'] = - 1;
|
||||
} elseif ( ! empty( $atts['exclude'] ) ) {
|
||||
$include = array_map( 'trim', explode( ',', $atts['include'] ) );
|
||||
$exclude = array_map( 'trim', explode( ',', $atts['exclude'] ) );
|
||||
$diff = array_diff( $include, $exclude );
|
||||
$atts['include'] = implode( ', ', $diff );
|
||||
}
|
||||
$settings = array(
|
||||
'include' => $atts['include'],
|
||||
'posts_per_page' => $atts['query_items_per_page'],
|
||||
'offset' => $atts['query_offset'],
|
||||
'post_type' => 'any',
|
||||
'orderby' => 'post__in',
|
||||
);
|
||||
$this->atts['items_per_page'] = - 1;
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
public function buildItems() {
|
||||
$this->filter_terms = $this->items = array();
|
||||
|
||||
$this->query = new WP_Query();
|
||||
|
||||
$this->setContentLimits();
|
||||
|
||||
$this->addExcludedId( $this->postID() );
|
||||
if ( 'custom' === $this->atts['post_type'] && ! empty( $this->atts['custom_query'] ) ) {
|
||||
$query = html_entity_decode( vc_value_from_safe( $this->atts['custom_query'] ), ENT_QUOTES, 'utf-8' );
|
||||
$query = apply_filters( 'vc_basic_grid_filter_query_filters', $query, $this->atts, $this->shortcode );
|
||||
$post_data = $this->query->query( $query );
|
||||
$this->atts['items_per_page'] = - 1;
|
||||
} elseif ( false !== $this->atts['query_items_per_page'] ) {
|
||||
$settings = $this->filterQuerySettings( $this->buildQuery( $this->atts ) );
|
||||
$post_data = $this->query->query( $settings );
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if ( $this->atts['items_per_page'] > 0 && count( $post_data ) > $this->atts['items_per_page'] ) {
|
||||
$post_data = array_slice( $post_data, 0, $this->atts['items_per_page'] );
|
||||
}
|
||||
foreach ( $post_data as $post ) {
|
||||
$post->filter_terms = wp_get_object_terms( $post->ID, $this->atts['filter_source'], array( 'fields' => 'ids' ) );
|
||||
$this->filter_terms = wp_parse_args( $this->filter_terms, $post->filter_terms );
|
||||
$this->items[] = $post;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $args
|
||||
* @return array
|
||||
*/
|
||||
public function filterQuerySettings( $args ) {
|
||||
$defaults = array(
|
||||
'numberposts' => 5,
|
||||
'offset' => 0,
|
||||
'category' => 0,
|
||||
'orderby' => 'date',
|
||||
'order' => 'DESC',
|
||||
'include' => array(),
|
||||
'exclude' => array(),
|
||||
'meta_key' => '',
|
||||
'meta_value' => '',
|
||||
'post_type' => 'post',
|
||||
'suppress_filters' => apply_filters( 'vc_basic_grid_filter_query_suppress_filters', true ),
|
||||
'public' => true,
|
||||
);
|
||||
|
||||
$r = wp_parse_args( $args, $defaults );
|
||||
if ( empty( $r['post_status'] ) ) {
|
||||
$r['post_status'] = ( 'attachment' === $r['post_type'] ) ? 'inherit' : 'publish';
|
||||
}
|
||||
if ( ! empty( $r['numberposts'] ) && empty( $r['posts_per_page'] ) ) {
|
||||
$r['posts_per_page'] = $r['numberposts'];
|
||||
}
|
||||
if ( ! empty( $r['category'] ) ) {
|
||||
$r['cat'] = $r['category'];
|
||||
}
|
||||
if ( ! empty( $r['include'] ) ) {
|
||||
$incposts = wp_parse_id_list( $r['include'] );
|
||||
$r['posts_per_page'] = count( $incposts ); // only the number of posts included
|
||||
$r['post__in'] = $incposts;
|
||||
} elseif ( ! empty( $r['exclude'] ) ) {
|
||||
$r['post__not_in'] = wp_parse_id_list( $r['exclude'] );
|
||||
}
|
||||
|
||||
$r['ignore_sticky_posts'] = true;
|
||||
$r['no_found_rows'] = true;
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $atts
|
||||
* @return mixed
|
||||
*/
|
||||
public static function convertButton2ToButton3( $atts ) {
|
||||
if ( isset( $atts['button_style'] ) || isset( $atts['button_size'] ) || isset( $atts['button_color'] ) ) {
|
||||
// we use old button 2 attributes:
|
||||
$style = isset( $atts['button_style'] ) ? $atts['button_style'] : 'rounded';
|
||||
$size = isset( $atts['button_size'] ) ? $atts['button_size'] : 'md';
|
||||
$color = isset( $atts['button_color'] ) ? $atts['button_color'] : 'blue';
|
||||
$oldData = array(
|
||||
'style' => $style,
|
||||
'size' => $size,
|
||||
'color' => str_replace( '_', '-', $color ),
|
||||
);
|
||||
// remove attributes on save
|
||||
$atts['button_style'] = '';
|
||||
$atts['button_size'] = '';
|
||||
$atts['button_color'] = '';
|
||||
$newData = WPBakeryShortCode_Vc_Btn::convertAttributesToButton3( $oldData );
|
||||
foreach ( $newData as $key => $value ) {
|
||||
$atts[ 'btn_' . $key ] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $atts;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
die( '-1' );
|
||||
}
|
||||
|
||||
/**
|
||||
* WPBakery WPBakery Page Builder shortcodes
|
||||
*
|
||||
* @package WPBakeryPageBuilder
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class WPBakeryShortCode_Vc_Btn
|
||||
* @since 4.5
|
||||
*/
|
||||
class WPBakeryShortCode_Vc_Btn extends WPBakeryShortCode {
|
||||
/**
|
||||
* @param $atts
|
||||
* @return mixed
|
||||
*/
|
||||
public static function convertAttributesToButton3( $atts ) {
|
||||
// size btn1 to size btn2
|
||||
$btn1_sizes = array(
|
||||
'wpb_regularsize',
|
||||
'btn-large',
|
||||
'btn-small',
|
||||
'btn-mini',
|
||||
);
|
||||
if ( isset( $atts['size'] ) && in_array( $atts['size'], $btn1_sizes, true ) ) {
|
||||
$atts['size'] = str_replace( $btn1_sizes, array(
|
||||
'md',
|
||||
'lg',
|
||||
'sm',
|
||||
'xs',
|
||||
), $atts['size'] );
|
||||
}
|
||||
|
||||
// Convert Btn1 href+target attributes to Btn2 `link` attribute
|
||||
if ( ! isset( $atts['link'] ) && isset( $atts['href'] ) && strlen( $atts['href'] ) > 0 ) {
|
||||
$link = $atts['href'];
|
||||
$target = isset( $atts['target'] ) ? $atts['target'] : '';
|
||||
$title = isset( $atts['title'] ) ? $atts['title'] : $link;
|
||||
$atts['link'] = 'url:' . rawurlencode( $link ) . '|title:' . $title . ( strlen( $target ) > 0 ? '|target:' . rawurlencode( $target ) : '' );
|
||||
}
|
||||
|
||||
if ( ( ! isset( $atts['add_icon'] ) || 'true' !== $atts['add_icon'] ) && isset( $atts['icon'] ) && strlen( $atts['icon'] ) > 0 && 'none' !== $atts['icon'] ) {
|
||||
// old icon from btn1 is set, let's convert it to new btn
|
||||
$atts['add_icon'] = 'true';
|
||||
$atts['icon_type'] = 'pixelicons';
|
||||
$atts['icon_align'] = 'right';
|
||||
$atts['icon_pixelicons'] = 'vc_pixel_icon vc_pixel_icon-' . str_replace( 'wpb_', '', $atts['icon'] );
|
||||
}
|
||||
$haystack = array(
|
||||
'rounded',
|
||||
'square',
|
||||
'round',
|
||||
'outlined',
|
||||
'square_outlined',
|
||||
);
|
||||
if ( isset( $atts['style'] ) && in_array( $atts['style'], $haystack, true ) ) {
|
||||
switch ( $atts['style'] ) {
|
||||
case 'rounded':
|
||||
$atts['style'] = 'flat';
|
||||
$atts['shape'] = 'rounded';
|
||||
break;
|
||||
case 'square':
|
||||
$atts['style'] = 'flat';
|
||||
$atts['shape'] = 'square';
|
||||
break;
|
||||
case 'round':
|
||||
$atts['style'] = 'flat';
|
||||
$atts['shape'] = 'round';
|
||||
break;
|
||||
case 'outlined':
|
||||
$atts['style'] = 'outline';
|
||||
break;
|
||||
case 'square_outlined':
|
||||
$atts['style'] = 'outline';
|
||||
$atts['shape'] = 'square';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $atts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $title
|
||||
*
|
||||
* @return string
|
||||
* @since 4.5
|
||||
*/
|
||||
protected function outputTitle( $title ) {
|
||||
$icon = $this->settings( 'icon' );
|
||||
|
||||
return '<h4 class="wpb_element_title"><span class="vc_general vc_element-icon vc_btn3-icon' . ( ! empty( $icon ) ? ' ' . $icon : '' ) . '"></span></h4>';
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user