pluginBasename = $pluginBasename;
}
function run() {
$upload_dir = wp_upload_dir();
$plugin_url = plugin_dir_url(dirname(__FILE__));
define('VISION_PLUGIN_UPLOAD_DIR', wp_normalize_path($upload_dir['basedir'] . '/vision'));
define('VISION_PLUGIN_UPLOAD_URL', set_url_scheme($upload_dir['baseurl'] . '/vision/'));
define('VISION_PLUGIN_PLAN', 'lite');
$user = wp_get_current_user(); //is_super_admin()
$allowed_roles = $this->getAllowedRoles();
if((array_intersect($allowed_roles, $user->roles) || current_user_can('manage_options')) && is_admin()) {
$this->ajax_action_item_update = 'vision_ajax_item_update';
$this->ajax_action_item_update_status = 'vision_ajax_item_update_status';
$this->ajax_action_settings_update = 'vision_ajax_settings_update';
$this->ajax_action_settings_get = 'vision_ajax_settings_get';
$this->ajax_action_delete_data = 'vision_ajax_delete_data';
$this->ajax_action_modal = 'vision_ajax_modal';
load_plugin_textdomain('vision', false, dirname(dirname(plugin_basename(__FILE__))) . '/languages/');
add_action('admin_menu', [$this, 'admin_menu']);
add_action('admin_footer', [$this, 'admin_footer']);
add_action('admin_notices', [$this, 'admin_notices']);
add_action('in_admin_header', [$this, 'in_admin_header']);
add_action('wp_loaded', [$this, 'page_redirects']);
// important, because ajax has another url
add_action('wp_ajax_' . $this->ajax_action_item_update, [$this, 'ajax_item_update']);
add_action('wp_ajax_' . $this->ajax_action_item_update_status, [$this, 'ajax_item_update_status']);
add_action('wp_ajax_' . $this->ajax_action_settings_update, [$this, 'ajax_settings_update']);
add_action('wp_ajax_' . $this->ajax_action_settings_get, [$this, 'ajax_settings_get']);
add_action('wp_ajax_' . $this->ajax_action_delete_data, [$this, 'ajax_delete_data']);
add_action('wp_ajax_' . $this->ajax_action_modal, [$this, 'ajax_modal']);
} else {
add_shortcode(VISION_SHORTCODE_NAME, [$this, 'shortcode']);
}
// only logged users with right roles can preview a vision map
if(array_intersect($allowed_roles, $user->roles) || current_user_can('manage_options')) {
add_filter('do_parse_request', [$this, 'do_parse_request'], 10, 3);
}
}
function joinPaths() {
$paths = [];
foreach(func_get_args() as $arg) {
if($arg !== '') {
$paths[] = $arg;
}
}
return preg_replace('#/+#','/',join('/', $paths));
}
function joinUrls() {
$urls = [];
foreach(func_get_args() as $arg) {
if($arg !== '') {
$urls[] = $arg;
}
}
return preg_replace('/([^:])(\/{2,})/','$1/',join('/', $urls));
}
function IsNullOrEmptyString($str) {
return(!isset($str) || trim($str)==='');
}
function getAllowedRoles() {
$allowed_roles = ['administrator'];
$settings_key = 'vision_settings';
$settings_value = get_option($settings_key);
if($settings_value) {
$settings = unserialize($settings_value);
if(is_array($settings->roles)) $allowed_roles = array_merge($allowed_roles, $settings->roles);
}
return $allowed_roles;
}
function getLoaderGlobals($timestamp) {
$plugin_url = plugin_dir_url(dirname(__FILE__));
$globals = [
'plan' => VISION_PLUGIN_PLAN,
'version' => $timestamp,
'effects_url' => $plugin_url . 'assets/css/vision-effects.min.css',
'theme_base_url' => $plugin_url . 'assets/themes/',
'plugin_base_url' => $plugin_url . 'assets/js/lib/vision/',
'plugin_upload_base_url' => VISION_PLUGIN_UPLOAD_URL,
'plugin_version' => VISION_PLUGIN_VERSION,
'ssl' => is_ssl()
];
return $globals;
}
function embedLoader($in_footer, $timestamp) {
$plugin_url = plugin_dir_url(dirname(__FILE__));
wp_enqueue_script('vision_loader_js', $plugin_url . 'assets/js/loader.min.js', ['jquery'], VISION_PLUGIN_VERSION, $in_footer);
wp_localize_script('vision_loader_js', 'vision_globals', $this->getLoaderGlobals($timestamp));
}
/**
* generate main css text
*/
function getMainCss($itemData, $itemId) {
$upload_dir = wp_upload_dir();
// create main css
$main_css = '';
$main_css .= '.vision-map-' . $itemId . ' {' . PHP_EOL;
$main_css .= (!$this->IsNullOrEmptyString($itemData->background->color) ? 'background-color:' . $itemData->background->color . ';' . PHP_EOL : '');
if(!$this->IsNullOrEmptyString($itemData->background->image->url)) {
$imageUrl = ($itemData->background->image->relative ? $upload_dir['baseurl'] : '') . $itemData->background->image->url;
$main_css .= 'background-image:url(' . $imageUrl . ');' . PHP_EOL;
}
$main_css .= ($itemData->background->size ? 'background-size:' . $itemData->background->size . ';' . PHP_EOL : '');
$main_css .= ($itemData->background->repeat ? 'background-repeat:' . $itemData->background->repeat . ';' . PHP_EOL : '');
$main_css .= ($itemData->background->position ? 'background-position:' . $itemData->background->position . ';' . PHP_EOL : '');
$main_css .= '}' . PHP_EOL;
$layerId = 0;
foreach($itemData->layers as $layerKey => $layer) {
if(!$layer->visible) {
continue;
}
$layerId++;
$layerSelector = '.vision-map-' . $itemId . ' .vision-layers [data-layer-id="' . $layer->id . '"] .vision-body';
// main
$main_css .= $layerSelector . ' {' . PHP_EOL;
switch($layer->type) {
case 'link': {
$main_css .= ($layer->link->normalColor ? 'background-color:' . $layer->link->normalColor . ';' . PHP_EOL : '');
$main_css .= ($layer->link->radius != NULL ? 'border-radius:' . $layer->link->radius . ';' . PHP_EOL : '');
} break;
case 'image': {
$main_css .= (!$this->IsNullOrEmptyString($layer->image->background->color) ? 'background-color:' . $layer->image->background->color . ';' . PHP_EOL : '');
if(!$this->IsNullOrEmptyString($layer->image->background->file->url)) {
$imageUrl = ($layer->image->background->file->relative ? $upload_dir['baseurl'] : '') . $layer->image->background->file->url;
$main_css .= 'background-image:url(' . $imageUrl . ');' . PHP_EOL;
}
$main_css .= ($layer->image->background->size ? 'background-size:' . $layer->image->background->size . ';' . PHP_EOL : '');
$main_css .= ($layer->image->background->repeat ? 'background-repeat:' . $layer->image->background->repeat . ';' . PHP_EOL : '');
$main_css .= ($layer->image->background->position ? 'background-position:' . $layer->image->background->position . ';' . PHP_EOL : '');
} break;
case 'text': {
$main_css .= (!$this->IsNullOrEmptyString($layer->text->background->color) ? 'background-color:' . $layer->text->background->color . ';' . PHP_EOL : '');
if(!$this->IsNullOrEmptyString($layer->text->background->file->url)) {
$imageUrl = ($layer->text->background->file->relative ? $upload_dir['baseurl'] : '') . $layer->text->background->file->url;
$main_css .= 'background-image:url(' . $imageUrl . ');' . PHP_EOL;
}
$main_css .= ($layer->text->background->size ? 'background-size:' . $layer->text->background->size . ';' . PHP_EOL : '');
$main_css .= ($layer->text->background->repeat ? 'background-repeat:' . $layer->text->background->repeat . ';' . PHP_EOL : '');
$main_css .= ($layer->text->background->position ? 'background-position:' . $layer->text->background->position . ';' . PHP_EOL : '');
$main_css .= ($layer->text->font ? 'font-family:"' . str_replace('+', ' ', $layer->text->font) . '",sans-serif;' . PHP_EOL : '');
$main_css .= ($layer->text->color ? 'color:' . $layer->text->color . ';' . PHP_EOL : '');
$main_css .= ($layer->text->size != NULL ? 'font-size:' . $layer->text->size . 'px;' . PHP_EOL : '');
$main_css .= ($layer->text->lineHeight != NULL ? 'line-height:' . $layer->text->lineHeight . 'px;' . PHP_EOL : '');
$main_css .= ($layer->text->align ? 'text-align:' . $layer->text->align . ';' . PHP_EOL : '');
$main_css .= ($layer->text->letterSpacing != NULL ? 'letter-spacing:' . $layer->text->letterSpacing . 'px;' . PHP_EOL : '');
} break;
}
$main_css .= '}' . PHP_EOL;
if($layer->type == 'link') {
$main_css .= $layerSelector . ':hover {' . PHP_EOL;
$main_css .= ($layer->link->hoverColor ? 'background-color:' . $layer->link->hoverColor . ';' . PHP_EOL : '');
$main_css .= '}' . PHP_EOL;
}
}
return $main_css;
}
/**
* Shortcode output for the plugin
*/
function shortcode($atts) {
$keys_valid = ['id', 'slug', 'class'];
$atts_valid = array_filter($atts, function($key) use ($keys_valid) {
return in_array($key, $keys_valid);
}, ARRAY_FILTER_USE_KEY);
$opt_valid = [
'id' => FILTER_SANITIZE_NUMBER_INT,
'slug' => FILTER_SANITIZE_STRING,
'class' => FILTER_SANITIZE_STRING
];
$atts_valid = filter_var_array($atts_valid, $opt_valid);
extract(shortcode_atts(['id'=>0, 'slug'=>NULL, 'class'=>NULL], $atts_valid));
if(!$id && !$slug) {
return '
' . esc_html__('Error: invalid vision identifier attribute', 'vision') . '
';
}
global $wpdb;
$table = $wpdb->prefix . VISION_PLUGIN_NAME;
$upload_dir = wp_upload_dir();
$sql = ($id ? $wpdb->prepare("SELECT * FROM {$table} WHERE id=%d AND NOT deleted", $id) : $wpdb->prepare("SELECT * FROM {$table} WHERE slug=%s AND NOT deleted LIMIT 0, 1", $slug));
$item = $wpdb->get_row($sql, OBJECT);
$preview = filter_input(INPUT_GET, 'preview', FILTER_SANITIZE_NUMBER_INT);
if($item && ($item->active || (!$item->active && $preview == 1))) {
$version = strtotime(mysql2date('d M Y H:i:s', $item->modified));
$itemData = unserialize($item->data);
$id = $item->id;
$id_postfix = strtolower(wp_generate_password(5, false)); // generate unique postfix for $id to avoid clashes with multiple same shortcode use
$id_element = 'vision-' . $id . '-' . $id_postfix;
array_push($this->shortcodes, ['id' => $item->id, 'version' => $version]);
if(sizeof($this->shortcodes) == 1) {
$this->embedLoader(true, $version);
}
ob_start(); // turn on buffering
echo '' . PHP_EOL;
echo 'containerId ? 'id="' . esc_attr($itemData->containerId) . '" ':'');
echo 'class="vision-map vision-map-' . esc_attr($id . ($class ? ' ' . $class : '')) . '"';
echo 'data-json-src="'. VISION_PLUGIN_UPLOAD_URL . $item->id . '/config.json' . ($version ? '?ver=' . $version : '') . '" ';
echo 'data-item-id="' . esc_attr($item->id) . '" ';
echo 'tabindex="1" ';
echo 'style="display:none;" ';
echo '>' . PHP_EOL;
//=============================================
// STORE BEGIN
echo '
' . PHP_EOL;
echo '
' . PHP_EOL;
foreach($itemData->layers as $layerKey => $layer) {
if(!$layer->visible) {
continue;
}
//=============================================
// LAYER BEGIN
echo '
';
if($layer->contentData) {
echo do_shortcode($layer->contentData);
}
if($layer->type == 'text') {
echo wp_kses_post($layer->text->data);
}
if($layer->type == 'svg') {
if(!$this->IsNullOrEmptyString($layer->svg->file->url)) {
$svgUrl = ($layer->svg->file->url ? ($layer->svg->file->relative ? $upload_dir['baseurl'] : '') . $layer->svg->file->url : '');
echo file_get_contents($svgUrl, FILE_USE_INCLUDE_PATH);
}
}
echo '
' . PHP_EOL;
// LAYER END
//=============================================
}
echo '
' . PHP_EOL;
echo '
' . PHP_EOL;
echo '
' . PHP_EOL;
foreach($itemData->layers as $layerKey => $layer) {
if(!$layer->visible) {
continue;
}
//=============================================
// POPOVER BEGIN
echo '
';
echo do_shortcode($layer->popover->data);
echo '
' . PHP_EOL;
// POPOVER END
//=============================================
}
echo '
' . PHP_EOL;
echo '
' . PHP_EOL;
// STORE END
//=============================================
echo '
' . PHP_EOL;
echo '' . PHP_EOL;
$output = ob_get_contents(); // get the buffered content into a var
ob_end_clean(); // clean buffer
return $output;
}
return '' . esc_html__('Error: the vision item can’t be found', 'vision') . '
';
}
/**
* Run a filter to obtain some custom url settings, compare them to the current url
* and if a match is found the custom callback is fired, the custom view is loaded
* and request is stopped.
*/
function do_parse_request($result) {
if(current_filter() !== 'do_parse_request') {
return $result;
}
if(preg_match('/vision\/map\/([a-z0-9_-]+)/', $_SERVER['REQUEST_URI'], $matches)) {
$preview = filter_input(INPUT_GET, 'preview', FILTER_SANITIZE_NUMBER_INT);
global $wpdb;
$table = $wpdb->prefix . VISION_PLUGIN_NAME;
$shortcode = false;
if(is_numeric($matches[1])) {
$vision_map_id = $matches[1];
if($vision_map_id != null) {
$sql = $wpdb->prepare("SELECT * FROM {$table} WHERE id=%d AND NOT deleted", $vision_map_id);
$item = $wpdb->get_row($sql, OBJECT);
if($item && ($item->active || (!$item->active && $preview == 1))) {
$this->vision_map_id = $item->id;
$this->vision_map_version = strtotime(mysql2date('Y-m-d H:i:s', $item->modified));
$shortcode = true;
}
}
} else {
$vision_map_slug = $matches[1];
if($vision_map_slug != null) {
$sql = $wpdb->prepare("SELECT * FROM {$table} WHERE slug=%s AND NOT deleted", $vision_map_slug);
$item = $wpdb->get_row($sql, OBJECT);
if($item && ($item->active || (!$item->active && $preview == 1))) {
$this->vision_map_id = $item->id;
$this->vision_map_version = strtotime(mysql2date('Y-m-d H:i:s', $item->modified));
$shortcode = true;
}
}
}
if($shortcode) {
require_once(plugin_dir_path(dirname(__FILE__)) . 'includes/page-preview.php');
exit();
}
}
return $result;
}
/**
* Prepare upload directory
*/
function admin_notices() {
$page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_STRING);
if(!($page==='vision' || $page==='vision_item')) {
return;
}
if(!file_exists(VISION_PLUGIN_UPLOAD_DIR)) {
wp_mkdir_p(VISION_PLUGIN_UPLOAD_DIR);
}
if(!file_exists(VISION_PLUGIN_UPLOAD_DIR)) {
echo '';
echo '
' . sprintf(esc_html__('The "%s" directory could not be created', 'vision'), 'vision') . '
';
echo '
' . esc_html__('Please run the following commands in order to make the directory', 'vision') . '
';
echo 'mkdir ' . VISION_PLUGIN_UPLOAD_DIR . '
';
echo 'chmod 777 ' . VISION_PLUGIN_UPLOAD_DIR . '
';
echo '
';
return;
}
if(!wp_is_writable(VISION_PLUGIN_UPLOAD_DIR)) {
echo '';
echo '
' . sprintf(esc_html__('The "%s" directory is not writable, therefore the css and js files cannot be saved.', 'vision'), 'vision') . '
';
echo '
' . esc_html__('Please run the following commands in order to make the directory', 'vision') . '
';
echo 'chmod 777 ' . VISION_PLUGIN_UPLOAD_DIR . '
';
echo '
';
return;
}
if(!file_exists(VISION_PLUGIN_UPLOAD_DIR . '/' . 'index.php')) {
$data = '';
@file_put_contents(VISION_PLUGIN_UPLOAD_DIR . '/' . 'index.php', $data);
}
}
/**
* Fires at the beginning of the content section in an admin page
*/
function in_admin_header() {
$page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_STRING);
if(!(($page==='vision') || ($page==='vision_item') || ($page==='vision_settings'))) {
return;
}
remove_all_actions('admin_notices');
remove_all_actions('all_admin_notices');
add_action('admin_notices', [$this, 'admin_notices']);
}
/**
* Register the administration menu for this plugin into the WordPress Dashboard menu.
*/
function admin_menu() {
// add "edit_posts" if we want to give access to author, editor and contributor roles
add_menu_page(esc_html__('Vision', 'vision'), esc_html__('Vision', 'vision'), 'read', 'vision', [$this, 'admin_menu_page_items'], 'dashicons-format-image');
add_submenu_page('vision', esc_html__('Vision', 'vision'), esc_html__('All Items', 'vision'), 'read', 'vision', [$this, 'admin_menu_page_items']);
add_submenu_page('vision', esc_html__('Vision', 'vision'), esc_html__('Add New', 'vision'), 'read', 'vision_item', [$this, 'admin_menu_page_item']);
add_submenu_page('vision', esc_html__('Vision', 'vision'), esc_html__('Settings', 'vision'), 'manage_options', 'vision_settings', [$this, 'admin_menu_page_settings']);
}
function admin_footer() {
if(get_current_screen() && get_current_screen()->base !== 'plugins') {
return;
}
$globals = [
'token' => $this->get_token(),
'ajax' => [
'url' => VISION_FEEDBACK_URL
]
];
wp_enqueue_style('vision-feedback-css', VISION_PLUGIN_URL . 'assets/css/feedback.min.css', [], VISION_PLUGIN_VERSION);
wp_enqueue_script('vision-feedback-js', VISION_PLUGIN_URL . 'assets/js/feedback.min.js', ['jquery'], VISION_PLUGIN_VERSION, false);
wp_localize_script('vision-feedback-js', 'vision_feedback_globals', $globals);
require_once(plugin_dir_path(dirname(__FILE__)) . 'templates/feedback.php');
}
function get_token() {
global $wp_version;
$current_user = wp_get_current_user();
$data = [
'plugin_name' => VISION_PLUGIN_NAME,
'plugin_version' => VISION_PLUGIN_VERSION,
'wordpress' => $wp_version,
'php' => PHP_VERSION,
'email' => $current_user->user_email,
'site' => trim(str_replace(['http://', 'https://'], '', get_site_url()), '/')
];
return base64_encode(json_encode($data));
}
/**
* Custom redirects
*/
function page_redirects() {
$page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_STRING);
if($page==='vision') {
$action = filter_input(INPUT_GET, 'action', FILTER_SANITIZE_STRING);
if($action) {
$url = remove_query_arg(['action', 'id', '_wpnonce'], $_SERVER['REQUEST_URI']);
header('Refresh:0; url="' . $url . '"', true, 303);
//wp_redirect($url); // does not work delete and dublicate operations on XAMPP
}
}
}
/**
* Show admin menu items page
*/
function admin_menu_page_items() {
$page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_STRING);
if($page==='vision') {
$plugin_url = plugin_dir_url( dirname(__FILE__) );
$upload_dir = wp_upload_dir();
wp_enqueue_style('vision_admin_css', $plugin_url . 'assets/css/admin.min.css', [], VISION_PLUGIN_VERSION, 'all' );
wp_enqueue_style('vision_fontawesome_css', $plugin_url . 'assets/css/font-awesome.min.css', [], VISION_PLUGIN_VERSION, 'all' );
wp_enqueue_script('vision_admin_js', $plugin_url . 'assets/js/admin.min.js', ['jquery'], VISION_PLUGIN_VERSION, false );
// global settings to help ajax work
$globals = [
'plan' => VISION_PLUGIN_PLAN,
'msg_pro_title' => esc_html__('Available only in Pro version', 'vision'),
'upload_url' => $upload_dir['baseurl'],
'ajax_url' => admin_url('admin-ajax.php'),
'ajax_nonce' => wp_create_nonce('vision_ajax' ),
'ajax_msg_error' => esc_html__('Uncaught Error', 'vision') //Look at the console (F12 or Ctrl+Shift+I, Console tab) for more information
];
$globals['ajax_action_update'] = $this->ajax_action_item_update_status;
require_once(plugin_dir_path( dirname(__FILE__) ) . 'includes/list-table-items.php');
require_once(plugin_dir_path( dirname(__FILE__) ) . 'includes/page-items.php');
wp_localize_script('vision_admin_js', 'vision_globals', $globals);
}
}
/**
* Show admin menu item page
*/
function admin_menu_page_item() {
$page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_STRING);
if($page==='vision_item') {
$plugin_url = plugin_dir_url(dirname(__FILE__));
$upload_dir = wp_upload_dir();
wp_enqueue_style('vision_admin_css', $plugin_url . 'assets/css/admin.min.css', [], VISION_PLUGIN_VERSION, 'all' );
wp_enqueue_style('vision_fontawesome_css', $plugin_url . 'assets/css/font-awesome.min.css', [], VISION_PLUGIN_VERSION, 'all' );
wp_enqueue_style('vision_vision_effects_css', $plugin_url . 'assets/css/vision-effects.min.css', [], VISION_PLUGIN_VERSION, 'all' );
wp_enqueue_script('vision_ace_js', $plugin_url . 'assets/js/lib/ace/ace.js', [], VISION_PLUGIN_VERSION, false );
wp_enqueue_script('vision_url_js', $plugin_url . 'assets/js/lib/url/url.min.js', [], VISION_PLUGIN_VERSION, false );
wp_enqueue_script('vision_admin_js', $plugin_url . 'assets/js/admin.min.js', ['jquery'], VISION_PLUGIN_VERSION, false );
wp_enqueue_media();
// global settings to help ajax work
$globals = [
'plan' => VISION_PLUGIN_PLAN,
'msg_pro_title' => esc_html__('Available only in Pro version', 'vision'),
'msg_edit_text' => esc_html__('Edit your text here', 'vision'),
'msg_custom_js_error' => esc_html__('Custom js code error', 'vision'),
'msg_layer_id_error' => esc_html__('The layer ID should be unique', 'vision'),
'wp_base_url' => get_site_url(),
'upload_base_url' => $upload_dir['baseurl'],
'plugin_base_url' => $plugin_url,
'ajax_url' => admin_url('admin-ajax.php'),
'ajax_nonce' => wp_create_nonce('vision_ajax'),
'ajax_msg_error' => esc_html__('Uncaught Error', 'vision') //Look at the console (F12 or Ctrl+Shift+I, Console tab) for more information
];
$id = filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT);
$globals['ajax_action_get'] = $this->ajax_action_settings_get;
$globals['ajax_action_update'] = $this->ajax_action_item_update;
$globals['ajax_action_modal'] = $this->ajax_action_modal;
$globals['ajax_item_id'] = $id;
$globals['settings'] = NULL;
$globals['config'] = NULL;
$settings_key = 'vision_settings';
$settings_value = get_option($settings_key);
if($settings_value) {
$globals['settings'] = unserialize($settings_value); // json_encode(unserialize($settings_value)) problem with double quotes
}
// get item data from DB
if($id) {
global $wpdb;
$table = $wpdb->prefix . VISION_PLUGIN_NAME;
$query = $wpdb->prepare("SELECT * FROM {$table} WHERE id=%s", $id);
$item = $wpdb->get_row($query, OBJECT);
if($item) {
$globals['config'] = unserialize($item->data); // json_encode(unserialize($item->data)) problem with double quotes
}
} else {
// new item
$item = (object) [
'author' => get_current_user_id(),
'editor' => get_current_user_id(),
'created' => current_time('mysql', 1),
'modified' => current_time('mysql', 1)
];
}
require_once( plugin_dir_path( dirname(__FILE__) ) . 'includes/page-item.php' );
// set global settings
wp_localize_script('vision_admin_js', 'vision_globals', $globals);
}
}
/**
* Show admin menu settings page
*/
function admin_menu_page_settings() {
$page = filter_input(INPUT_GET, 'page', FILTER_SANITIZE_STRING);
if($page==='vision_settings') {
$plugin_url = plugin_dir_url(dirname(__FILE__));
wp_enqueue_style('vision_admin_css', $plugin_url . 'assets/css/admin.min.css', [], VISION_PLUGIN_VERSION, 'all' );
wp_enqueue_style('vision_fontawesome_css', $plugin_url . 'assets/css/font-awesome.min.css', [], VISION_PLUGIN_VERSION, 'all' );
wp_enqueue_script('vision_admin_js', $plugin_url . 'assets/js/admin.min.js', ['jquery'], VISION_PLUGIN_VERSION, false );
// global settings to help ajax work
$globals = [
'plan' => VISION_PLUGIN_PLAN,
'msg_pro_title' => esc_html__('Available only in Pro version', 'vision'),
'ajax_url' => admin_url('admin-ajax.php'),
'ajax_nonce' => wp_create_nonce('vision_ajax' ),
'ajax_msg_error' => esc_html__('Uncaught Error', 'vision') //Look at the console (F12 or Ctrl+Shift+I, Console tab) for more information
];
$globals['ajax_action_update'] = $this->ajax_action_settings_update;
$globals['ajax_action_get'] = $this->ajax_action_settings_get;
$globals['ajax_action_modal'] = $this->ajax_action_modal;
$globals['ajax_action_delete_data'] = $this->ajax_action_delete_data;
$globals['config'] = NULL;
// read settings
$settings_key = 'vision_settings';
$settings_value = get_option($settings_key);
if($settings_value) {
$globals['config'] = json_encode(unserialize($settings_value));
}
require_once(plugin_dir_path( dirname(__FILE__) ) . 'includes/page-settings.php' );
wp_localize_script('vision_admin_js', 'vision_globals', $globals);
}
}
/**
* Ajax update item state
*/
function ajax_item_update_status() {
$error = false;
$data = [];
$config = filter_input(INPUT_POST, 'config', FILTER_UNSAFE_RAW);
if(check_ajax_referer('vision_ajax', 'nonce', false)) {
global $wpdb;
$table = $wpdb->prefix . VISION_PLUGIN_NAME;
$config = json_decode($config);
$result = false;
if(isset($config->id) && isset($config->active)) {
$query = $wpdb->prepare("SELECT * FROM {$table} WHERE id=%s", $config->id);
$item = $wpdb->get_row($query, OBJECT );
if($item && (current_user_can('manage_options') || get_current_user_id()==$item->author) ) {
$itemData = unserialize($item->data);
$itemData->active = $config->active;
$result = $wpdb->update(
$table,
['active' => $itemData->active, 'data' => serialize($itemData)],
['id' => $config->id]
);
}
}
if($result) {
$data['id'] = $config->id;
$data['msg'] = esc_html__('The item was successfully updated', 'vision');
} else {
$error = true;
$data['msg'] = esc_html__('The operation failed, can\'t update item', 'vision');
}
} else {
$error = true;
$data['msg'] = esc_html__('The operation failed', 'vision');
}
if($error) {
wp_send_json_error($data);
} else {
wp_send_json_success($data);
}
wp_die(); // this is required to terminate immediately and return a proper response
}
/**
* Ajax update item data
*/
function ajax_item_update() {
$error = false;
$data = [];
if(check_ajax_referer('vision_ajax', 'nonce', false)) {
global $wpdb;
$table = $wpdb->prefix . VISION_PLUGIN_NAME;
$inputId = filter_input(INPUT_POST, 'id', FILTER_UNSAFE_RAW);
$inputData = filter_input(INPUT_POST, 'data', FILTER_UNSAFE_RAW);
$inputConfig = filter_input(INPUT_POST, 'config', FILTER_UNSAFE_RAW);
$itemData = json_decode($inputData);
$itemConfig = json_decode($inputConfig);
$flag = true;
if(VISION_PLUGIN_PLAN == 'lite') {
$rowcount = $wpdb->get_var("SELECT COUNT(*) FROM {$table}");
if(!($rowcount == 0 || ($rowcount == 1 && $inputId))) {
$flag = false;
$error = true;
$data['msg'] = esc_html__('The operation failed, you can work only with one item. To create more, buy the pro version.', 'vision');
}
}
if($flag) {
$itemConfig->modified = current_time('mysql', 1);
if($inputId) {
$result = false;
$query = $wpdb->prepare("SELECT * FROM {$table} WHERE id=%s", $inputId);
$item = $wpdb->get_row($query, OBJECT);
if($item && (current_user_can('manage_options') || get_current_user_id()==$item->author) ) {
$itemData->slug = sanitize_title(($itemData->slug ? $itemData->slug : $itemData->title));
$result = $wpdb->update(
$table,
[
'title' => $itemData->title,
'slug' => $itemData->slug,
'active' => $itemData->active,
'data' => serialize($itemData),
'config' => serialize($itemConfig),
//'author' => get_current_user_id(),
'editor' => get_current_user_id(),
//'date' => NULL,
'modified' => current_time('mysql', 1)
],
['id' => $inputId]
);
}
if($result) {
$data['id'] = $inputId;
$data['msg'] = esc_html__('The item was successfully updated', 'vision');
} else {
$error = true;
$data['msg'] = esc_html__('The operation failed, can\'t update item', 'vision');
}
} else {
$itemData->slug = sanitize_title(($itemData->slug ? $itemData->slug : $itemData->title));
$result = $wpdb->insert(
$table,
[
'title' => $itemData->title,
'slug' => $itemData->slug,
'active' => $itemData->active,
'data' => serialize($itemData),
'config' => serialize($itemConfig),
'author' => get_current_user_id(),
'editor' => get_current_user_id(),
'created' => current_time('mysql', 1),
'modified' => current_time('mysql', 1)
]);
if($result) {
$data['id'] = $inputId = $wpdb->insert_id;
$data['msg'] = esc_html__('The item was successfully created', 'vision');
} else {
$error = true;
$data['msg'] = esc_html__('The operation failed, can\'t create item', 'vision');
}
}
}
// [filemanager] create an external file
if(!$error && wp_is_writable(VISION_PLUGIN_UPLOAD_DIR)) {
$file_json = 'config.json';
$file_main_css = 'main.css';
$file_custom_css = 'custom.css';
$file_root_path = VISION_PLUGIN_UPLOAD_DIR . '/' . $inputId . '/';
if(!is_dir($file_root_path)) {
mkdir($file_root_path);
}
@file_put_contents($file_root_path . $file_json, json_encode($itemConfig));
@file_put_contents($file_root_path . $file_main_css, $this->getMainCss($itemData, $inputId));
@file_put_contents($file_root_path . $file_custom_css, $itemData->customCSS->data);
}
} else {
$error = true;
$data['msg'] = esc_html__('The operation failed', 'vision');
}
if($error) {
wp_send_json_error($data);
} else {
wp_send_json_success($data);
}
wp_die(); // this is required to terminate immediately and return a proper response
}
/**
* Ajax update settings data
*/
function ajax_settings_update() {
$error = false;
$data = [];
$config = filter_input(INPUT_POST, 'config', FILTER_UNSAFE_RAW);
if(check_ajax_referer('vision_ajax', 'nonce', false)) {
$settings_key = 'vision_settings';
$settings_value = serialize(json_decode($config));
$result = false;
if(get_option($settings_key) == false) {
$deprecated = null;
$autoload = 'no';
$result = add_option($settings_key, $settings_value, $deprecated, $autoload);
} else {
$old_settings_value = get_option($settings_key);
if($old_settings_value === $settings_value) {
$result = true;
} else {
$result = update_option($settings_key, $settings_value);
}
}
if($result) {
$data['msg'] = esc_html__('The settings were successfully updated', 'vision');
} else {
$error = true;
$data['msg'] = esc_html__('The operation failed, can\'t update settings', 'vision');
}
}
if($error) {
wp_send_json_error($data);
} else {
wp_send_json_success($data);
}
wp_die(); // this is required to terminate immediately and return a proper response
}
/**
* Ajax settings get data
*/
function ajax_settings_get() {
$error = false;
$data = [];
$type = filter_input(INPUT_POST, 'type', FILTER_SANITIZE_STRING);
if(check_ajax_referer('vision_ajax', 'nonce', false)) {
switch($type) {
case 'roles': {
$data['list'] = [];
$roles = wp_roles()->roles;
foreach($roles as $key => $role) {
if(array_key_exists('read', $role['capabilities'])) {
array_push($data['list'], ['id' => $key, 'name' => translate_user_role($role['name'])]);
}
}
}
break;
case 'themes': {
$data['list'] = [];
$files = glob(plugin_dir_path( dirname(__FILE__) ) . 'assets/themes/*.min.css');
foreach($files as $file) {
$filename = basename($file, '.min.css');
array_push($data['list'], ['id' => $filename, 'title' => str_replace('-', ' ', $filename)]);
}
}
break;
case 'editor-themes': {
$data['list'] = [];
$files = glob(plugin_dir_path( dirname(__FILE__) ) . 'assets/js/lib/ace/theme-*.js');
foreach($files as $file) {
$filename = str_replace('theme-','',basename($file, '.js'));
array_push($data['list'], ['id' => $filename, 'title' => str_replace('_', ' ', $filename)]);
}
}
break;
case 'fonts': {
$data['list'] = array(
array('fontname' => 'none'),
array('fontname' => 'Aclonica'),
array('fontname' => 'Allan'),
array('fontname' => 'Annie+Use+Your+Telescope'),
array('fontname' => 'Anonymous+Pro'),
array('fontname' => 'Allerta+Stencil'),
array('fontname' => 'Allerta'),
array('fontname' => 'Amaranth'),
array('fontname' => 'Anton'),
array('fontname' => 'Architects+Daughter'),
array('fontname' => 'Arimo'),
array('fontname' => 'Artifika'),
array('fontname' => 'Arvo'),
array('fontname' => 'Asset'),
array('fontname' => 'Astloch'),
array('fontname' => 'Bangers'),
array('fontname' => 'Bentham'),
array('fontname' => 'Bevan'),
array('fontname' => 'Bigshot+One'),
array('fontname' => 'Bowlby+One'),
array('fontname' => 'Bowlby+One+SC'),
array('fontname' => 'Brawler'),
array('fontname' => 'Cabin'),
array('fontname' => 'Calligraffitti'),
array('fontname' => 'Candal'),
array('fontname' => 'Cantarell'),
array('fontname' => 'Cardo'),
array('fontname' => 'Carter One'),
array('fontname' => 'Caudex'),
array('fontname' => 'Cedarville+Cursive'),
array('fontname' => 'Cherry+Cream+Soda'),
array('fontname' => 'Chewy'),
array('fontname' => 'Coda'),
array('fontname' => 'Coming+Soon'),
array('fontname' => 'Copse'),
array('fontname' => 'Cousine'),
array('fontname' => 'Covered+By+Your+Grace'),
array('fontname' => 'Crafty+Girls'),
array('fontname' => 'Crimson+Text'),
array('fontname' => 'Crushed'),
array('fontname' => 'Cuprum'),
array('fontname' => 'Damion'),
array('fontname' => 'Dancing+Script'),
array('fontname' => 'Dawning+of+a+New+Day'),
array('fontname' => 'Didact+Gothic'),
array('fontname' => 'Droid+Sans'),
array('fontname' => 'Droid+Sans+Mono'),
array('fontname' => 'Droid+Serif'),
array('fontname' => 'EB+Garamond'),
array('fontname' => 'Expletus+Sans'),
array('fontname' => 'Fontdiner+Swanky'),
array('fontname' => 'Forum'),
array('fontname' => 'Francois+One'),
array('fontname' => 'Geo'),
array('fontname' => 'Give+You+Glory'),
array('fontname' => 'Goblin+One'),
array('fontname' => 'Goudy+Bookletter+1911'),
array('fontname' => 'Gravitas+One'),
array('fontname' => 'Gruppo'),
array('fontname' => 'Hammersmith+One'),
array('fontname' => 'Holtwood+One+SC'),
array('fontname' => 'Homemade+Apple'),
array('fontname' => 'Inconsolata'),
array('fontname' => 'Indie+Flower'),
array('fontname' => 'IM+Fell+DW+Pica'),
array('fontname' => 'IM+Fell+DW+Pica+SC'),
array('fontname' => 'IM+Fell+Double+Pica'),
array('fontname' => 'IM+Fell+Double+Pica+SC'),
array('fontname' => 'IM+Fell+English'),
array('fontname' => 'IM+Fell+English+SC'),
array('fontname' => 'IM+Fell+French+Canon'),
array('fontname' => 'IM+Fell+French+Canon+SC'),
array('fontname' => 'IM+Fell+Great+Primer'),
array('fontname' => 'IM+Fell+Great+Primer+SC'),
array('fontname' => 'Irish+Grover'),
array('fontname' => 'Irish+Growler'),
array('fontname' => 'Istok+Web'),
array('fontname' => 'Josefin+Sans'),
array('fontname' => 'Josefin+Slab'),
array('fontname' => 'Judson'),
array('fontname' => 'Jura'),
array('fontname' => 'Just+Another+Hand'),
array('fontname' => 'Just+Me+Again+Down+Here'),
array('fontname' => 'Kameron'),
array('fontname' => 'Kenia'),
array('fontname' => 'Kranky'),
array('fontname' => 'Kreon'),
array('fontname' => 'Kristi'),
array('fontname' => 'La+Belle+Aurore'),
array('fontname' => 'Lato'),
array('fontname' => 'League+Script'),
array('fontname' => 'Lekton'),
array('fontname' => 'Limelight'),
array('fontname' => 'Lobster'),
array('fontname' => 'Lobster Two'),
array('fontname' => 'Lora'),
array('fontname' => 'Love+Ya+Like+A+Sister'),
array('fontname' => 'Loved+by+the+King'),
array('fontname' => 'Luckiest+Guy'),
array('fontname' => 'Maiden+Orange'),
array('fontname' => 'Mako'),
array('fontname' => 'Maven+Pro'),
array('fontname' => 'Meddon'),
array('fontname' => 'MedievalSharp'),
array('fontname' => 'Megrim'),
array('fontname' => 'Merriweather'),
array('fontname' => 'Metrophobic'),
array('fontname' => 'Michroma'),
array('fontname' => 'Miltonian+Tattoo'),
array('fontname' => 'Miltonian'),
array('fontname' => 'Modern Antiqua'),
array('fontname' => 'Monofett'),
array('fontname' => 'Molengo'),
array('fontname' => 'Mountains of Christmas'),
array('fontname' => 'Muli'),
array('fontname' => 'Neucha'),
array('fontname' => 'Neuton'),
array('fontname' => 'News+Cycle'),
array('fontname' => 'Nixie+One'),
array('fontname' => 'Nobile'),
array('fontname' => 'Nova+Cut'),
array('fontname' => 'Nova+Flat'),
array('fontname' => 'Nova+Mono'),
array('fontname' => 'Nova+Oval'),
array('fontname' => 'Nova+Round'),
array('fontname' => 'Nova+Script'),
array('fontname' => 'Nova+Slim'),
array('fontname' => 'Nova+Square'),
array('fontname' => 'Nunito'),
array('fontname' => 'OFL+Sorts+Mill+Goudy+TT'),
array('fontname' => 'Old+Standard+TT'),
array('fontname' => 'Open+Sans'),
array('fontname' => 'Orbitron'),
array('fontname' => 'Oswald'),
array('fontname' => 'Over+the+Rainbow'),
array('fontname' => 'Reenie+Beanie'),
array('fontname' => 'Pacifico'),
array('fontname' => 'Patrick+Hand'),
array('fontname' => 'Paytone+One'),
array('fontname' => 'Permanent+Marker'),
array('fontname' => 'Philosopher'),
array('fontname' => 'Play'),
array('fontname' => 'Playfair+Display'),
array('fontname' => 'Podkova'),
array('fontname' => 'PT+Sans'),
array('fontname' => 'PT+Sans+Narrow'),
array('fontname' => 'PT+Serif'),
array('fontname' => 'PT+Serif Caption'),
array('fontname' => 'Puritan'),
array('fontname' => 'Quattrocento'),
array('fontname' => 'Quattrocento+Sans'),
array('fontname' => 'Radley'),
array('fontname' => 'Redressed'),
array('fontname' => 'Rock+Salt'),
array('fontname' => 'Rokkitt'),
array('fontname' => 'Ruslan+Display'),
array('fontname' => 'Schoolbell'),
array('fontname' => 'Shadows+Into+Light'),
array('fontname' => 'Shanti'),
array('fontname' => 'Sigmar+One'),
array('fontname' => 'Six+Caps'),
array('fontname' => 'Slackey'),
array('fontname' => 'Smythe'),
array('fontname' => 'Special+Elite'),
array('fontname' => 'Stardos+Stencil'),
array('fontname' => 'Sue+Ellen+Francisco'),
array('fontname' => 'Sunshiney'),
array('fontname' => 'Swanky+and+Moo+Moo'),
array('fontname' => 'Syncopate'),
array('fontname' => 'Tangerine'),
array('fontname' => 'Tenor+Sans'),
array('fontname' => 'Terminal+Dosis+Light'),
array('fontname' => 'The+Girl+Next+Door'),
array('fontname' => 'Tinos'),
array('fontname' => 'Ubuntu'),
array('fontname' => 'Ultra'),
array('fontname' => 'Unkempt'),
array('fontname' => 'UnifrakturMaguntia'),
array('fontname' => 'Varela'),
array('fontname' => 'Varela Round'),
array('fontname' => 'Vibur'),
array('fontname' => 'Vollkorn'),
array('fontname' => 'VT323'),
array('fontname' => 'Waiting+for+the+Sunrise'),
array('fontname' => 'Wallpoet'),
array('fontname' => 'Walter+Turncoat'),
array('fontname' => 'Wire+One'),
array('fontname' => 'Yanone+Kaffeesatz'),
array('fontname' => 'Yeseva+One'),
array('fontname' => 'Zeyada')
);
}
break;
default: {
$error = true;
$data['msg'] = esc_html__('The operation failed', 'vision');
}
break;
}
} else {
$error = true;
$data['msg'] = esc_html__('The operation failed', 'vision');
}
if($error) {
wp_send_json_error($data);
} else {
wp_send_json_success($data);
}
wp_die(); // this is required to terminate immediately and return a proper response
}
/**
* Ajax delete all data from tables
*/
function ajax_delete_data() {
$error = true;
$data = [];
$data['msg'] = esc_html__('The operation failed, can\'t delete data', 'vision');
if(check_ajax_referer('vision_ajax', 'nonce', false)) {
global $wpdb;
$table = $wpdb->prefix . VISION_PLUGIN_NAME;
foreach($wpdb->get_results("SELECT id FROM {$table}") as $key => $item) {
// [filemanager] delete file
if(wp_is_writable(VISION_PLUGIN_UPLOAD_DIR)) {
$file_json = 'config.json';
$file_main_css = 'main.css';
$file_custom_css = 'custom.css';
$file_root_path = VISION_PLUGIN_UPLOAD_DIR . '/' . $item->id . '/';
wp_delete_file($file_root_path . $file_json);
wp_delete_file($file_root_path . $file_main_css);
wp_delete_file($file_root_path . $file_custom_css);
if(is_dir($file_root_path)) {
rmdir($file_root_path);
}
}
}
$query = "TRUNCATE TABLE {$table}";
$result = $wpdb->query($query);
if($result) {
$error = false;
$data['msg'] = esc_html__('All data deleted', 'vision');
}
}
if($error) {
wp_send_json_error($data);
} else {
wp_send_json_success($data);
}
wp_die(); // this is required to terminate immediately and return a proper response
}
/**
* Ajax settings get data
*/
function ajax_modal() {
if(check_ajax_referer('vision_ajax', 'nonce', false)) {
$modalName = filter_input(INPUT_GET, 'name', FILTER_SANITIZE_STRING);
$modalPath = plugin_dir_path( dirname(__FILE__) ) . 'includes/modal-' . $modalName . '.php';
if(file_exists($modalPath)) {
require_once( $modalPath );
}
}
wp_die(); // this is required to terminate immediately and return a proper response
}
}
?>