| 1 |
<?php |
| 2 |
|
| 3 |
////////////////////////////////////////////////////////////// |
| 4 |
//=========================================================== |
| 5 |
// ajax.php |
| 6 |
//=========================================================== |
| 7 |
// PAGELAYER |
| 8 |
// Inspired by the DESIRE to be the BEST OF ALL |
| 9 |
// ---------------------------------------------------------- |
| 10 |
// Started by: Pulkit Gupta |
| 11 |
// Date: 23rd Jan 2017 |
| 12 |
// Time: 23:00 hrs |
| 13 |
// Site: http://pagelayer.com/wordpress (PAGELAYER) |
| 14 |
// ---------------------------------------------------------- |
| 15 |
// Please Read the Terms of use at http://pagelayer.com/tos |
| 16 |
// ---------------------------------------------------------- |
| 17 |
//=========================================================== |
| 18 |
// (c)Pagelayer Team |
| 19 |
//=========================================================== |
| 20 |
////////////////////////////////////////////////////////////// |
| 21 |
|
| 22 |
// Are we being accessed directly ? |
| 23 |
if(!defined('PAGELAYER_VERSION')) { |
| 24 |
exit('Hacking Attempt !'); |
| 25 |
} |
| 26 |
|
| 27 |
// Recommended Plugins Installation and Activation Action Handlers |
| 28 |
// NOTE: These must be registered BEFORE the pagelayer_nonce gate below, |
| 29 |
// because install/activate requests do NOT send pagelayer_nonce. |
| 30 |
add_action('wp_ajax_pagelayer_install_plugin', 'pagelayer_install_recommended_plugin'); |
| 31 |
function pagelayer_install_recommended_plugin(){ |
| 32 |
check_ajax_referer('pagelayer_recommended_plugins', 'security'); |
| 33 |
|
| 34 |
if(!current_user_can('install_plugins')){ |
| 35 |
wp_send_json_error(array('message' => __('You do not have permission to install plugins.', 'pagelayer'))); |
| 36 |
} |
| 37 |
|
| 38 |
$slug = !empty($_REQUEST['plugin']) ? sanitize_text_field(wp_unslash($_REQUEST['plugin'])) : ''; |
| 39 |
if(empty($slug)){ |
| 40 |
wp_send_json_error(array('message' => __('Plugin slug is required.', 'pagelayer'))); |
| 41 |
} |
| 42 |
|
| 43 |
require_once ABSPATH . 'wp-admin/includes/plugin-install.php'; |
| 44 |
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; |
| 45 |
require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
| 46 |
require_once ABSPATH . 'wp-admin/includes/file.php'; |
| 47 |
|
| 48 |
// Initialize WP_Filesystem - required before Plugin_Upgrader can write files |
| 49 |
$creds = request_filesystem_credentials(site_url() . '/wp-admin/', '', false, false, null); |
| 50 |
if(!WP_Filesystem($creds)){ |
| 51 |
wp_send_json_error(array('message' => __('Could not initialize filesystem. Please check file permissions.', 'pagelayer'))); |
| 52 |
} |
| 53 |
|
| 54 |
$api = plugins_api('plugin_information', array('slug' => $slug, 'fields' => array('sections' => false))); |
| 55 |
|
| 56 |
if(is_wp_error($api)){ |
| 57 |
wp_send_json_error(array('message' => $api->get_error_message())); |
| 58 |
} |
| 59 |
|
| 60 |
// Use Automatic_Upgrader_Skin (silent); buffer any stray output to keep response clean JSON |
| 61 |
$skin = new \Automatic_Upgrader_Skin(); |
| 62 |
$upgrader = new \Plugin_Upgrader($skin); |
| 63 |
|
| 64 |
ob_start(); |
| 65 |
$result = $upgrader->install($api->download_link); |
| 66 |
ob_end_clean(); |
| 67 |
|
| 68 |
if(is_wp_error($result)){ |
| 69 |
wp_send_json_error(array('message' => $result->get_error_message())); |
| 70 |
} |
| 71 |
if($result === false || $result === null){ |
| 72 |
$error_msgs = $skin->get_upgrade_messages(); |
| 73 |
$msg = !empty($error_msgs) ? implode(' ', $error_msgs) : __('Plugin installation failed. Please check file permissions.', 'pagelayer'); |
| 74 |
wp_send_json_error(array('message' => $msg)); |
| 75 |
} |
| 76 |
|
| 77 |
$all_plugins = get_plugins(); |
| 78 |
$installed_plugin = ''; |
| 79 |
foreach($all_plugins as $path => $data){ |
| 80 |
if(strpos($path, $slug . '/') === 0){ |
| 81 |
$installed_plugin = $path; |
| 82 |
break; |
| 83 |
} |
| 84 |
} |
| 85 |
|
| 86 |
if(empty($installed_plugin)){ |
| 87 |
wp_send_json_error(array('message' => __('Plugin installed but could not be located for activation.', 'pagelayer'))); |
| 88 |
} |
| 89 |
|
| 90 |
$result = activate_plugin($installed_plugin); |
| 91 |
if(is_wp_error($result)){ |
| 92 |
wp_send_json_error(array('message' => $result->get_error_message())); |
| 93 |
} |
| 94 |
|
| 95 |
wp_send_json_success(array('message' => __('Plugin installed and activated successfully.', 'pagelayer'))); |
| 96 |
} |
| 97 |
|
| 98 |
add_action('wp_ajax_pagelayer_activate_plugin', 'pagelayer_activate_recommended_plugin'); |
| 99 |
function pagelayer_activate_recommended_plugin(){ |
| 100 |
check_ajax_referer('pagelayer_recommended_plugins', 'security'); |
| 101 |
|
| 102 |
if(!current_user_can('activate_plugins')){ |
| 103 |
wp_send_json_error(array('message' => __('You do not have permission to activate plugins.', 'pagelayer'))); |
| 104 |
} |
| 105 |
|
| 106 |
$slug = !empty($_REQUEST['plugin']) ? sanitize_text_field(wp_unslash($_REQUEST['plugin'])) : ''; |
| 107 |
if(empty($slug)){ |
| 108 |
wp_send_json_error(array('message' => __('Plugin slug is required.', 'pagelayer'))); |
| 109 |
} |
| 110 |
|
| 111 |
if(!function_exists('get_plugins')){ |
| 112 |
require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
| 113 |
} |
| 114 |
|
| 115 |
$all_plugins = get_plugins(); |
| 116 |
$plugin_path = ''; |
| 117 |
foreach($all_plugins as $path => $data){ |
| 118 |
if(strpos($path, $slug . '/') === 0){ |
| 119 |
$plugin_path = $path; |
| 120 |
break; |
| 121 |
} |
| 122 |
} |
| 123 |
|
| 124 |
if(empty($plugin_path)){ |
| 125 |
wp_send_json_error(array('message' => __('Plugin not found.', 'pagelayer'))); |
| 126 |
} |
| 127 |
|
| 128 |
$result = activate_plugin($plugin_path); |
| 129 |
if(is_wp_error($result)){ |
| 130 |
wp_send_json_error(array('message' => $result->get_error_message())); |
| 131 |
} |
| 132 |
|
| 133 |
wp_send_json_success(array('message' => __('Plugin activated successfully.', 'pagelayer'))); |
| 134 |
} |
| 135 |
|
| 136 |
// AI Agents Connection AJAX handlers |
| 137 |
// NOTE: These must be registered BEFORE the pagelayer_nonce gate below, |
| 138 |
// because they use their own nonce (pagelayer_mcp_nonce) or basic auth. |
| 139 |
add_action('wp_ajax_pagelayer_mcp_generate_app_password', 'pagelayer_mcp_generate_app_password'); |
| 140 |
add_action('wp_ajax_pagelayer_mcp_adapter_action', 'pagelayer_mcp_adapter_action'); |
| 141 |
add_action('wp_ajax_pagelayer_mcp_test_connection', 'pagelayer_mcp_test_connection'); |
| 142 |
add_action('wp_ajax_pagelayer_mcp_save_test_status', 'pagelayer_mcp_save_test_status'); |
| 143 |
add_action('wp_ajax_pagelayer_mcp_save_image_api_key', 'pagelayer_mcp_save_image_api_key'); |
| 144 |
|
| 145 |
// Verifies, without any HTTP round trip, the two things a loopback request would |
| 146 |
// have proved: that the supplied Application Password authenticates this user, |
| 147 |
// and that the Pagelayer abilities are registered. Used when the loopback itself |
| 148 |
// fails (cURL timeout etc.) so the panel can still tell the user where they stand. |
| 149 |
function pagelayer_mcp_verify_locally($username, $password) { |
| 150 |
$result = array('password_ok' => false, 'abilities' => 0, 'message' => ''); |
| 151 |
|
| 152 |
if(!class_exists('WP_Application_Passwords')){ |
| 153 |
$result['message'] = __('Application Passwords are not supported on this WordPress version.', 'pagelayer'); |
| 154 |
return $result; |
| 155 |
} |
| 156 |
|
| 157 |
$user = get_user_by('login', $username); |
| 158 |
if(!$user && is_email($username)){ |
| 159 |
$user = get_user_by('email', $username); |
| 160 |
} |
| 161 |
|
| 162 |
if(!$user){ |
| 163 |
$result['message'] = sprintf(__('No user named "%s" exists on this site.', 'pagelayer'), $username); |
| 164 |
return $result; |
| 165 |
} |
| 166 |
|
| 167 |
// Core strips non-alphanumerics before comparing, so the password works with |
| 168 |
// or without the readability spaces (see wp_authenticate_application_password). |
| 169 |
$stripped = preg_replace('/[^a-z\d]/i', '', $password); |
| 170 |
|
| 171 |
foreach(\WP_Application_Passwords::get_user_application_passwords($user->ID) as $item){ |
| 172 |
if(\WP_Application_Passwords::check_password($stripped, $item['password'])){ |
| 173 |
$result['password_ok'] = true; |
| 174 |
break; |
| 175 |
} |
| 176 |
} |
| 177 |
|
| 178 |
if(function_exists('wp_get_abilities')){ |
| 179 |
foreach(wp_get_abilities() as $name => $ability){ |
| 180 |
$name = is_string($name) ? $name : ''; |
| 181 |
if(strpos($name, 'pagelayer-') === 0){ |
| 182 |
$result['abilities']++; |
| 183 |
} |
| 184 |
} |
| 185 |
} |
| 186 |
|
| 187 |
if($result['password_ok']){ |
| 188 |
$result['message'] = sprintf( |
| 189 |
__('Checked locally instead: your Application Password IS valid for "%1$s", and %2$d Pagelayer abilities are registered.', 'pagelayer'), |
| 190 |
$username, |
| 191 |
$result['abilities'] |
| 192 |
); |
| 193 |
}else{ |
| 194 |
$result['message'] = sprintf( |
| 195 |
__('Checked locally instead: the supplied Application Password does NOT match any password stored for "%s" — generate a new one below.', 'pagelayer'), |
| 196 |
$username |
| 197 |
); |
| 198 |
} |
| 199 |
|
| 200 |
return $result; |
| 201 |
} |
| 202 |
|
| 203 |
function pagelayer_mcp_test_connection() { |
| 204 |
include_once(PAGELAYER_DIR.'/main/abilities.php'); |
| 205 |
check_ajax_referer('pagelayer_mcp_nonce', 'nonce'); |
| 206 |
|
| 207 |
if(!current_user_can('manage_options')){ |
| 208 |
wp_send_json_error(__('You do not have permission to test the connection.', 'pagelayer')); |
| 209 |
} |
| 210 |
|
| 211 |
$start = microtime(true); |
| 212 |
$url = trailingslashit(home_url()) . ltrim(Pagelayer_Abilities::$ABILITIES_ENDPOINT, '/'); |
| 213 |
|
| 214 |
$username = isset($_POST['username']) ? sanitize_text_field(wp_unslash($_POST['username'])) : ''; |
| 215 |
$password = isset($_POST['password']) ? sanitize_text_field(wp_unslash($_POST['password'])) : ''; |
| 216 |
|
| 217 |
// Application Passwords are silently inert unless the site is on HTTPS or the |
| 218 |
// environment type is "local" (wp_is_application_passwords_supported()). WP |
| 219 |
// still hands out a password string in that state, so the only symptom is a |
| 220 |
// 401 on every request — check it up front instead of blaming the password. |
| 221 |
if(function_exists('wp_is_application_passwords_available') && !wp_is_application_passwords_available()){ |
| 222 |
$message = sprintf( |
| 223 |
__('Application Passwords are disabled on this site, so every request is treated as anonymous (HTTP 401). WordPress only enables them over HTTPS or when the environment type is "local". This site reports %1$s and environment type "%2$s". Either serve the site over HTTPS, or add define(\'WP_ENVIRONMENT_TYPE\', \'local\'); to wp-config.php for a development site.', 'pagelayer'), |
| 224 |
is_ssl() ? 'HTTPS' : 'HTTP', |
| 225 |
function_exists('wp_get_environment_type') ? wp_get_environment_type() : 'unknown' |
| 226 |
); |
| 227 |
Pagelayer_Abilities::save_test_connection_status(false, $message); |
| 228 |
wp_send_json_error(['message' => $message]); |
| 229 |
} |
| 230 |
|
| 231 |
$response = wp_remote_get($url, [ |
| 232 |
// wp_remote_get() defaults to a 5s timeout, which a local dev stack will |
| 233 |
// blow through on a loopback request (TLS handshake plus a full second |
| 234 |
// WordPress bootstrap, often with WP_DEBUG on). |
| 235 |
'timeout' => 20, |
| 236 |
'headers' => [ |
| 237 |
'Accept' => 'application/json', |
| 238 |
'Authorization' => 'Basic ' . base64_encode($username . ':' . $password), |
| 239 |
], |
| 240 |
'sslverify' => false, |
| 241 |
]); |
| 242 |
|
| 243 |
$elapsed = round((microtime(true) - $start) * 1000); |
| 244 |
|
| 245 |
if(is_wp_error($response)){ |
| 246 |
// The loopback never completed, so it told us nothing about the HTTP path. |
| 247 |
// Verify in-process what we actually can — that the Application Password |
| 248 |
// is valid and the abilities are registered — and say plainly which part |
| 249 |
// is still unverified, instead of reporting a flat failure. |
| 250 |
$local = pagelayer_mcp_verify_locally($username, $password); |
| 251 |
|
| 252 |
$message = sprintf( |
| 253 |
__('Could not complete the loopback request to %1$s (%2$s). %3$s %4$s', 'pagelayer'), |
| 254 |
$url, |
| 255 |
$response->get_error_message(), |
| 256 |
$local['message'], |
| 257 |
__('A loopback failure is usually the local server itself, not your setup: many dev stacks run too few PHP workers to serve a second request while this one is still open, so the site cannot call itself. Your AI client connects from outside and is not affected. Confirm from a terminal with: curl -ik -u "USERNAME:APP PASSWORD" ', 'pagelayer') . $url |
| 258 |
); |
| 259 |
|
| 260 |
Pagelayer_Abilities::save_test_connection_status(false, $message); |
| 261 |
wp_send_json_error([ |
| 262 |
'message' => $message, |
| 263 |
'local_check' => $local, |
| 264 |
'loopback_failed' => true, |
| 265 |
]); |
| 266 |
} |
| 267 |
|
| 268 |
$code = wp_remote_retrieve_response_code($response); |
| 269 |
$body = json_decode(wp_remote_retrieve_body($response), true); |
| 270 |
|
| 271 |
if($code >= 200 && $code < 300 && is_array($body)){ |
| 272 |
$pagelayer_abilities = 0; |
| 273 |
foreach($body as $ability){ |
| 274 |
$name = isset($ability['name']) ? $ability['name'] : (isset($ability['id']) ? $ability['id'] : ''); |
| 275 |
if(is_string($name) && strpos($name, 'pagelayer-') === 0){ |
| 276 |
$pagelayer_abilities++; |
| 277 |
} |
| 278 |
} |
| 279 |
|
| 280 |
$message = sprintf(__('Authenticated with your Application Password and discovered %1$d Pagelayer abilities in %2$dms. Your site is ready to connect.', 'pagelayer'), $pagelayer_abilities, $elapsed); |
| 281 |
|
| 282 |
Pagelayer_Abilities::save_test_connection_status(true, $message); |
| 283 |
|
| 284 |
wp_send_json_success([ |
| 285 |
'message' => $message, |
| 286 |
'abilities' => $pagelayer_abilities, |
| 287 |
'elapsed_ms' => $elapsed, |
| 288 |
]); |
| 289 |
} |
| 290 |
|
| 291 |
// A 401 means the request arrived with no authenticated user at all; a 403 |
| 292 |
// means it authenticated but lacked the capability. Those need different fixes. |
| 293 |
if($code === 401){ |
| 294 |
$auth_header_seen = (bool) (function_exists('wp_get_authorization_header') ? wp_get_authorization_header() : (!empty($_SERVER['HTTP_AUTHORIZATION']) || !empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION']))); |
| 295 |
|
| 296 |
$message = __('The abilities endpoint treated the request as anonymous (HTTP 401), so the Application Password never authenticated. The two usual causes are: (1) the password was revoked or mistyped — generate a new one below; or (2) your web server is stripping the Authorization header before PHP sees it. For Apache, ensure the "RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]" line is present in .htaccess and that AllowOverride permits it. For nginx/FastCGI, ensure the Authorization header is forwarded to PHP-FPM.', 'pagelayer'); |
| 297 |
|
| 298 |
if(!$auth_header_seen){ |
| 299 |
$message .= ' ' . __('Note: this admin request itself arrived without an Authorization header, which is normal here but means the stripping check is inconclusive — test with curl -u user:app-password against the endpoint to confirm.', 'pagelayer'); |
| 300 |
} |
| 301 |
|
| 302 |
Pagelayer_Abilities::save_test_connection_status(false, $message); |
| 303 |
wp_send_json_error([ |
| 304 |
'message' => $message, |
| 305 |
]); |
| 306 |
} |
| 307 |
|
| 308 |
if($code === 403){ |
| 309 |
$message = __('The Application Password authenticated, but the account was refused (HTTP 403). Check that this user still has the required capabilities, and that no security plugin is blocking REST API requests.', 'pagelayer'); |
| 310 |
Pagelayer_Abilities::save_test_connection_status(false, $message); |
| 311 |
wp_send_json_error([ |
| 312 |
'message' => $message, |
| 313 |
]); |
| 314 |
} |
| 315 |
|
| 316 |
$message = sprintf(__('The abilities endpoint responded with status %1$d. Check the MCP Adapter is active and try again.', 'pagelayer'), $code); |
| 317 |
Pagelayer_Abilities::save_test_connection_status(false, $message); |
| 318 |
wp_send_json_error([ |
| 319 |
'message' => $message, |
| 320 |
]); |
| 321 |
} |
| 322 |
|
| 323 |
function pagelayer_mcp_save_test_status() { |
| 324 |
include_once(PAGELAYER_DIR.'/main/abilities.php'); |
| 325 |
check_ajax_referer('pagelayer_mcp_nonce', 'nonce'); |
| 326 |
|
| 327 |
if(!current_user_can('manage_options')){ |
| 328 |
wp_send_json_error(__('You do not have permission to do that.', 'pagelayer')); |
| 329 |
} |
| 330 |
|
| 331 |
$ok = !empty($_POST['ok']); |
| 332 |
$message = !empty($_POST['message']) ? sanitize_text_field(wp_unslash($_POST['message'])) : ''; |
| 333 |
|
| 334 |
Pagelayer_Abilities::save_test_connection_status($ok, $message); |
| 335 |
|
| 336 |
wp_send_json_success(); |
| 337 |
} |
| 338 |
|
| 339 |
function pagelayer_mcp_save_image_api_key() { |
| 340 |
check_ajax_referer('pagelayer_mcp_nonce', 'nonce'); |
| 341 |
|
| 342 |
if(!current_user_can('manage_options')){ |
| 343 |
wp_send_json_error(array('message' => __('You do not have permission to do that.', 'pagelayer'))); |
| 344 |
} |
| 345 |
|
| 346 |
$provider = !empty($_POST['provider']) ? sanitize_key(wp_unslash($_POST['provider'])) : ''; |
| 347 |
$api_key = !empty($_POST['api_key']) ? sanitize_text_field(wp_unslash($_POST['api_key'])) : ''; |
| 348 |
|
| 349 |
if(empty($api_key)){ |
| 350 |
wp_send_json_error(array('message' => __('An API key is required.', 'pagelayer'))); |
| 351 |
} |
| 352 |
|
| 353 |
if($provider !== 'pexels'){ |
| 354 |
wp_send_json_error(array('message' => __('Unsupported image provider.', 'pagelayer'))); |
| 355 |
} |
| 356 |
|
| 357 |
update_option('pagelayer_pexels_api_key', $api_key, false); |
| 358 |
|
| 359 |
wp_send_json_success(array('message' => __('Image search API key saved.', 'pagelayer'))); |
| 360 |
} |
| 361 |
|
| 362 |
function pagelayer_mcp_generate_app_password() { |
| 363 |
include_once(PAGELAYER_DIR.'/main/abilities.php'); |
| 364 |
check_ajax_referer('pagelayer_mcp_nonce', 'nonce'); |
| 365 |
|
| 366 |
if(!current_user_can('manage_options')){ |
| 367 |
wp_send_json_error('Unauthorized'); |
| 368 |
} |
| 369 |
|
| 370 |
$user_id = get_current_user_id(); |
| 371 |
if(!class_exists('WP_Application_Passwords')){ |
| 372 |
wp_send_json_error('Application Passwords not supported in this WP version.'); |
| 373 |
} |
| 374 |
|
| 375 |
// WP_Application_Passwords::create_new_application_password() does NOT check |
| 376 |
// availability, so without this the UI happily issues a password that |
| 377 |
// wp_authenticate_application_password() will always reject — a "Generated" |
| 378 |
// checkmark followed by a permanent 401. |
| 379 |
if(function_exists('wp_is_application_passwords_available') && !wp_is_application_passwords_available()){ |
| 380 |
wp_send_json_error(sprintf( |
| 381 |
__('Application Passwords are disabled on this site, so a generated password could never authenticate. WordPress enables them only over HTTPS or when the environment type is "local". This site reports %1$s and environment type "%2$s". Serve the site over HTTPS, or add define(\'WP_ENVIRONMENT_TYPE\', \'local\'); to wp-config.php for a development site.', 'pagelayer'), |
| 382 |
is_ssl() ? 'HTTPS' : 'HTTP', |
| 383 |
function_exists('wp_get_environment_type') ? wp_get_environment_type() : 'unknown' |
| 384 |
)); |
| 385 |
} |
| 386 |
|
| 387 |
$passwords = \WP_Application_Passwords::get_user_application_passwords($user_id); |
| 388 |
foreach($passwords as $app){ |
| 389 |
if(!empty($app['app_id']) && $app['app_id'] === Pagelayer_Abilities::$APP_PASSWORD_APP_ID){ |
| 390 |
\WP_Application_Passwords::delete_application_password($user_id, $app['uuid']); |
| 391 |
} |
| 392 |
} |
| 393 |
|
| 394 |
$new_password = \WP_Application_Passwords::create_new_application_password($user_id, array( |
| 395 |
'name' => Pagelayer_Abilities::$APP_PASSWORD_NAME, |
| 396 |
'app_id' => Pagelayer_Abilities::$APP_PASSWORD_APP_ID, |
| 397 |
)); |
| 398 |
|
| 399 |
if(is_wp_error($new_password)){ |
| 400 |
wp_send_json_error($new_password->get_error_message()); |
| 401 |
} |
| 402 |
|
| 403 |
wp_send_json_success(array('password' => $new_password[0])); |
| 404 |
} |
| 405 |
|
| 406 |
function pagelayer_mcp_adapter_action() { |
| 407 |
include_once(PAGELAYER_DIR.'/main/abilities.php'); |
| 408 |
check_ajax_referer('pagelayer_mcp_nonce', 'nonce'); |
| 409 |
|
| 410 |
if(!current_user_can('manage_options')){ |
| 411 |
wp_send_json_error('Unauthorized'); |
| 412 |
} |
| 413 |
|
| 414 |
$type = isset($_POST['type']) ? sanitize_text_field($_POST['type']) : ''; |
| 415 |
|
| 416 |
if(!function_exists('get_plugins')){ |
| 417 |
require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
| 418 |
} |
| 419 |
|
| 420 |
if ($type === 'install') { |
| 421 |
include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; |
| 422 |
include_once ABSPATH . 'wp-admin/includes/file.php'; |
| 423 |
|
| 424 |
// The MCP Adapter is hosted on GitHub, not WordPress.org, so fetch the download URL from the GitHub API |
| 425 |
$download_url = Pagelayer_Abilities::get_mcp_adapter_download_url(); |
| 426 |
|
| 427 |
$upgrader = new \Plugin_Upgrader(new \Automatic_Upgrader_Skin()); |
| 428 |
$installed = $upgrader->install($download_url); |
| 429 |
|
| 430 |
if(is_wp_error($installed)){ |
| 431 |
wp_send_json_error($installed->get_error_message()); |
| 432 |
}elseif(!$installed){ |
| 433 |
wp_send_json_error('Installation failed. The MCP Adapter plugin is downloaded from GitHub. Please check your server can reach github.com.'); |
| 434 |
} |
| 435 |
|
| 436 |
$plugin_file = Pagelayer_Abilities::get_installed_mcp_adapter_file(); |
| 437 |
if($plugin_file){ |
| 438 |
activate_plugin($plugin_file); |
| 439 |
wp_send_json_success('Installed and activated'); |
| 440 |
} |
| 441 |
wp_send_json_success('Installed but not activated'); |
| 442 |
|
| 443 |
} elseif ($type === 'activate') { |
| 444 |
$plugin_file = Pagelayer_Abilities::get_installed_mcp_adapter_file(); |
| 445 |
if($plugin_file){ |
| 446 |
$result = activate_plugin($plugin_file); |
| 447 |
if(is_wp_error($result)){ |
| 448 |
wp_send_json_error($result->get_error_message()); |
| 449 |
} |
| 450 |
wp_send_json_success('Activated'); |
| 451 |
} |
| 452 |
wp_send_json_error('Plugin not found'); |
| 453 |
} |
| 454 |
|
| 455 |
wp_send_json_error('Invalid action'); |
| 456 |
} |
| 457 |
|
| 458 |
// Is the nonce there ? |
| 459 |
if(empty($_REQUEST['pagelayer_nonce'])){ |
| 460 |
return; |
| 461 |
} |
| 462 |
|
| 463 |
pagelayer_memory_limit(128); |
| 464 |
|
| 465 |
// The ajax handler |
| 466 |
add_action('wp_ajax_pagelayer_wp_widget', 'pagelayer_wp_widget_ajax'); |
| 467 |
function pagelayer_wp_widget_ajax(){ |
| 468 |
|
| 469 |
global $pagelayer; |
| 470 |
|
| 471 |
// Some AJAX security |
| 472 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 473 |
|
| 474 |
if(!current_user_can('edit_theme_options')){ |
| 475 |
$ret['error'][] = __pl('no_permission'); |
| 476 |
pagelayer_json_output($ret); |
| 477 |
} |
| 478 |
|
| 479 |
pagelayer_load_shortcodes(); |
| 480 |
|
| 481 |
header('Content-Type: application/json'); |
| 482 |
|
| 483 |
$ret = []; |
| 484 |
$tag = @$_POST['tag']; |
| 485 |
//pagelayer_print($pagelayer->shortcodes[$tag]); |
| 486 |
|
| 487 |
// No tag ? |
| 488 |
if(empty($pagelayer->shortcodes[$tag])){ |
| 489 |
$ret['error'][] = __pl('no_tag'); |
| 490 |
pagelayer_json_output($ret); |
| 491 |
} |
| 492 |
|
| 493 |
// Include the widgets |
| 494 |
$widgets = ABSPATH . 'site-admin/includes/widgets.php'; |
| 495 |
$widgets = file_exists($widgets) ? $widgets : ABSPATH . 'wp-admin/includes/widgets.php'; |
| 496 |
require_once($widgets); |
| 497 |
|
| 498 |
$class = $pagelayer->shortcodes[$tag]['widget']; |
| 499 |
|
| 500 |
// Check the widget class exists ? |
| 501 |
if(empty($class) || !class_exists($class)){ |
| 502 |
$ret['error'][] = __pl('no_widget_class'); |
| 503 |
pagelayer_json_output($ret); |
| 504 |
} |
| 505 |
|
| 506 |
$instance = []; |
| 507 |
$widget = new $class(); |
| 508 |
$widget->_set('pagelayer-widget-1234567890'); |
| 509 |
|
| 510 |
// Is there any existing data ? |
| 511 |
if(!empty($_POST['widget_data'])){ |
| 512 |
$json = json_decode(stripslashes($_POST['widget_data']), true); |
| 513 |
//pagelayer_print($json);die(); |
| 514 |
if(!empty($json)){ |
| 515 |
$instance = $json; |
| 516 |
} |
| 517 |
} |
| 518 |
|
| 519 |
// Are there any form values ? |
| 520 |
if(!empty($_POST['values'])){ |
| 521 |
parse_str(stripslashes($_POST['values']), $data); |
| 522 |
//pagelayer_print($data);die(); |
| 523 |
|
| 524 |
// Any data ? |
| 525 |
if(!empty($data)){ |
| 526 |
|
| 527 |
// Rss widget checkboxes fix |
| 528 |
if(!empty($data['widget-rss'])){ |
| 529 |
$data['widget-rss']['pagelayer-widget-1234567890']['show_summary'] = empty($data['widget-rss']['pagelayer-widget-1234567890']['show_summary'])? 0 : 1; |
| 530 |
$data['widget-rss']['pagelayer-widget-1234567890']['show_author'] = empty($data['widget-rss']['pagelayer-widget-1234567890']['show_author'])? 0 : 1; |
| 531 |
$data['widget-rss']['pagelayer-widget-1234567890']['show_date'] = empty($data['widget-rss']['pagelayer-widget-1234567890']['show_date'])? 0 : 1; |
| 532 |
} |
| 533 |
|
| 534 |
// First key is useless |
| 535 |
$data = current($data); |
| 536 |
|
| 537 |
// Do we still have valid data ? |
| 538 |
if(!empty($data)){ |
| 539 |
|
| 540 |
// 2nd key is useless and just over-ride instance |
| 541 |
$instance = current($data); |
| 542 |
|
| 543 |
} |
| 544 |
} |
| 545 |
} |
| 546 |
|
| 547 |
// Settings instance For Text widget |
| 548 |
if($widget->id_base == 'text'){ |
| 549 |
$instance['visual'] = false; |
| 550 |
$instance['legacy'] = false; |
| 551 |
} |
| 552 |
|
| 553 |
// Get the form |
| 554 |
ob_start(); |
| 555 |
$widget->form($instance); |
| 556 |
$ret['form'] = ob_get_contents(); |
| 557 |
ob_end_clean(); |
| 558 |
|
| 559 |
// Get the html |
| 560 |
ob_start(); |
| 561 |
$widget->widget([], $instance); |
| 562 |
$ret['html'] = ob_get_contents(); |
| 563 |
ob_end_clean(); |
| 564 |
|
| 565 |
// Widget data to set |
| 566 |
if(!empty($instance)){ |
| 567 |
$ret['widget_data'] = $instance; |
| 568 |
} |
| 569 |
|
| 570 |
// Custom html widget form elements |
| 571 |
if(!empty($widget) && $widget->name=='Custom HTML'){ |
| 572 |
$custom_html = explode('>', $ret['form']); |
| 573 |
|
| 574 |
$custom_html[0] = '<label for="widget-custom_html-pagelayer-widget-1234567890-title">Title:</label>'.$custom_html[0]; |
| 575 |
$custom_html[0] = str_replace('type="hidden"', 'type="text"',$custom_html[0]); |
| 576 |
|
| 577 |
$custom_html[1] = '<label for="widget-custom_html-pagelayer-widget-1234567890-content">Content:</label>'.$custom_html[1]; |
| 578 |
$custom_html[1] = str_replace('hidden', '', $custom_html[1]); |
| 579 |
|
| 580 |
$ret['form'] = implode('>', $custom_html); |
| 581 |
} |
| 582 |
|
| 583 |
pagelayer_json_output($ret); |
| 584 |
|
| 585 |
} |
| 586 |
|
| 587 |
// Build with AI — wrappers; generation/settings logic lives in Pagelayer_AI_Controller |
| 588 |
add_action('wp_ajax_pagelayer_ai_generate', 'pagelayer_ai_generate'); |
| 589 |
function pagelayer_ai_generate(){ |
| 590 |
|
| 591 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 592 |
|
| 593 |
$done = []; |
| 594 |
|
| 595 |
if(!current_user_can('edit_posts')){ |
| 596 |
$done['error'][] = __pl('no_permission'); |
| 597 |
pagelayer_json_output($done); |
| 598 |
} |
| 599 |
|
| 600 |
$ctrl = Pagelayer_AI_Controller::get_instance(); |
| 601 |
$res = $ctrl->process_generate(); |
| 602 |
|
| 603 |
if(is_wp_error($res)){ |
| 604 |
$done['error'] = $res->get_error_message(); |
| 605 |
pagelayer_json_output($done); |
| 606 |
} |
| 607 |
|
| 608 |
$done = is_array($res) ? $res : []; |
| 609 |
if(!isset($done['success'])){ |
| 610 |
$done['success'] = true; |
| 611 |
} |
| 612 |
pagelayer_json_output($done); |
| 613 |
} |
| 614 |
|
| 615 |
add_action('wp_ajax_pagelayer_ai_settings', 'pagelayer_ai_settings'); |
| 616 |
function pagelayer_ai_settings(){ |
| 617 |
|
| 618 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 619 |
|
| 620 |
$done = []; |
| 621 |
|
| 622 |
if(!current_user_can('edit_posts')){ |
| 623 |
$done['error'][] = __pl('no_permission'); |
| 624 |
pagelayer_json_output($done); |
| 625 |
} |
| 626 |
|
| 627 |
$ctrl = Pagelayer_AI_Controller::get_instance(); |
| 628 |
$res = $ctrl->process_get_settings(); |
| 629 |
|
| 630 |
if(is_wp_error($res)){ |
| 631 |
$done['error'] = $res->get_error_message(); |
| 632 |
pagelayer_json_output($done); |
| 633 |
} |
| 634 |
|
| 635 |
$done = is_array($res) ? $res : []; |
| 636 |
if(!isset($done['success'])){ |
| 637 |
$done['success'] = true; |
| 638 |
} |
| 639 |
pagelayer_json_output($done); |
| 640 |
} |
| 641 |
|
| 642 |
add_action('wp_ajax_pagelayer_ai_save_settings', 'pagelayer_ai_save_settings'); |
| 643 |
function pagelayer_ai_save_settings(){ |
| 644 |
|
| 645 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 646 |
|
| 647 |
$done = []; |
| 648 |
|
| 649 |
if(!current_user_can('edit_posts')){ |
| 650 |
$done['error'][] = __pl('no_permission'); |
| 651 |
pagelayer_json_output($done); |
| 652 |
} |
| 653 |
|
| 654 |
$ctrl = Pagelayer_AI_Controller::get_instance(); |
| 655 |
$res = $ctrl->process_save_settings(); |
| 656 |
|
| 657 |
if(is_wp_error($res)){ |
| 658 |
$done['error'] = $res->get_error_message(); |
| 659 |
pagelayer_json_output($done); |
| 660 |
} |
| 661 |
|
| 662 |
$done = is_array($res) ? $res : []; |
| 663 |
if(!isset($done['success'])){ |
| 664 |
$done['success'] = true; |
| 665 |
} |
| 666 |
pagelayer_json_output($done); |
| 667 |
} |
| 668 |
|
| 669 |
// Update Post content |
| 670 |
add_action('wp_ajax_pagelayer_save_content', 'pagelayer_save_content'); |
| 671 |
function pagelayer_save_content(){ |
| 672 |
|
| 673 |
// Some AJAX security |
| 674 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 675 |
|
| 676 |
$content = $_POST['pagelayer_update_content']; |
| 677 |
|
| 678 |
$postID = (int) $_GET['postID']; |
| 679 |
|
| 680 |
if(empty($postID)){ |
| 681 |
$msg['error'] = __pl('invalid_post_id'); |
| 682 |
pagelayer_json_output($msg); |
| 683 |
} |
| 684 |
|
| 685 |
$_post = get_post($postID); |
| 686 |
|
| 687 |
// Post found ? |
| 688 |
if(empty($_post)){ |
| 689 |
$msg['error'] = __pl('invalid_post_id'); |
| 690 |
pagelayer_json_output($msg); |
| 691 |
} |
| 692 |
|
| 693 |
// Get the post type and its capabilities |
| 694 |
$post_type = $_post->post_type; |
| 695 |
$post_type_obj = get_post_type_object($post_type); |
| 696 |
|
| 697 |
// Are you allowed to edit ? |
| 698 |
if(!pagelayer_user_can_edit($postID)){ |
| 699 |
$msg['error'][] = __pl('no_permission'); |
| 700 |
pagelayer_json_output($msg); |
| 701 |
} |
| 702 |
|
| 703 |
// Check if the post exists |
| 704 |
if(!empty($postID)){ |
| 705 |
|
| 706 |
$content = base64_decode($content); |
| 707 |
|
| 708 |
/*if(!pagelayer_is_utf8($content)){ |
| 709 |
$content = utf8_encode($content); |
| 710 |
}*/ |
| 711 |
|
| 712 |
$is_xss = pagelayer_xss_content($content); |
| 713 |
|
| 714 |
if(!pagelayer_user_can_add_js_content() && strlen($is_xss) > 0){ |
| 715 |
$msg['error'][] = __pl('xss_found').' - '.$is_xss; |
| 716 |
pagelayer_json_output($msg); |
| 717 |
} |
| 718 |
|
| 719 |
// Is comment mode? |
| 720 |
if(pagelayer_is_comment_mode()){ |
| 721 |
global $pagelayer_comment_errors, $pagelayer_comment_alerts; |
| 722 |
$content = pagelayer_extract_comment_atts($postID, $content); |
| 723 |
} |
| 724 |
|
| 725 |
// Add slash to save data in post |
| 726 |
$content = wp_slash($content); |
| 727 |
|
| 728 |
$post = array( |
| 729 |
'ID' => $postID, |
| 730 |
'post_content' => $content, |
| 731 |
); |
| 732 |
|
| 733 |
// Any properties ? |
| 734 |
$allowed = ['post_title', 'post_name', 'post_excerpt', 'post_status', 'post_password', 'post_date', 'post_parent', 'menu_order']; |
| 735 |
|
| 736 |
foreach($allowed as $k){ |
| 737 |
if(isset($_REQUEST[$k])){ |
| 738 |
$post[$k] = sanitize_text_field($_REQUEST[$k]); |
| 739 |
} |
| 740 |
} |
| 741 |
|
| 742 |
// Restrict contributors from setting 'publish' or modifying unauthorized fields |
| 743 |
$current_user_can_publish = current_user_can($post_type_obj->cap->publish_posts); |
| 744 |
if(!$current_user_can_publish){ |
| 745 |
if(!in_array($post['post_status'], ['draft', 'pending'])){ |
| 746 |
$post['post_status'] = 'pending'; // Force pending status |
| 747 |
} |
| 748 |
} |
| 749 |
|
| 750 |
if(!empty($post['post_password'])){ |
| 751 |
if($_REQUEST['post_sticky'] == true){ |
| 752 |
$msg['error'] = __pl('post_pass_with_sticky_err'); |
| 753 |
pagelayer_json_output($msg); |
| 754 |
} |
| 755 |
|
| 756 |
// Prevent unauthorized password protection |
| 757 |
$can_protect = current_user_can($post_type_obj->cap->edit_private_posts); |
| 758 |
if(!$can_protect){ |
| 759 |
$msg['error'][] = __pl('no_permission_to_set_password'); |
| 760 |
pagelayer_json_output($msg); |
| 761 |
} |
| 762 |
} |
| 763 |
|
| 764 |
// Prevent unauthorized modification of `post_author` |
| 765 |
if(isset($_REQUEST['post_author']) && $_REQUEST['post_author'] != $_post->post_author){ |
| 766 |
|
| 767 |
$edit_others_posts = current_user_can($post_type_obj->cap->edit_others_posts); |
| 768 |
|
| 769 |
if($edit_others_posts){ |
| 770 |
$post['post_author'] = (int) $_REQUEST['post_author']; |
| 771 |
}else{ |
| 772 |
$msg['error'][] = __pl('no_permission_to_change_author'); |
| 773 |
pagelayer_json_output($msg); |
| 774 |
} |
| 775 |
} |
| 776 |
|
| 777 |
$post['comment_status'] = !empty($_REQUEST['comment_status']) ? 'open' : 'closed'; |
| 778 |
$post['ping_status'] = !empty($_REQUEST['ping_status']) ? 'open' : 'closed'; |
| 779 |
$post['post_status'] = empty($post['post_status']) ? $_post->post_status : $post['post_status']; |
| 780 |
|
| 781 |
if(!empty($post['post_status']) && $post['post_status'] == 'publish'){ |
| 782 |
|
| 783 |
// Allowed to publish pages ? |
| 784 |
if($_post->post_type == 'page' && !current_user_can('publish_pages')){ |
| 785 |
$msg['error'][] = __pl('no_publish_permission'); |
| 786 |
pagelayer_json_output($msg); |
| 787 |
} |
| 788 |
|
| 789 |
// Allowed to publish posts ? |
| 790 |
if($_post->post_type == 'post' && !current_user_can('publish_posts')){ |
| 791 |
$post['post_status'] = 'pending'; |
| 792 |
} |
| 793 |
} |
| 794 |
|
| 795 |
if(!empty($post['post_password'])){ |
| 796 |
$post['post_password'] = (in_array($post['post_status'], array('pass_protected', 'publish')) ? $post['post_password'] : ''); |
| 797 |
$post['post_status'] = 'publish'; |
| 798 |
}else{ |
| 799 |
$post['post_status'] = ($post['post_status'] == 'pass_protected') ? 'publish' : $post['post_status']; |
| 800 |
$post['post_password'] = ''; |
| 801 |
} |
| 802 |
|
| 803 |
// Set post GMT time |
| 804 |
if(!empty($post['post_date']) && '0000-00-00 00:00:00' !== $post['post_date']){ |
| 805 |
$post['post_date_gmt'] = get_gmt_from_date( $post['post_date'] ); |
| 806 |
|
| 807 |
if( in_array($post['post_status'], array('future', 'publish')) && $_post->post_date_gmt === '0000-00-00 00:00:00' ){ |
| 808 |
$post['edit_date'] = true; |
| 809 |
} |
| 810 |
} |
| 811 |
|
| 812 |
$_REQUEST['featured_image'] = (int) $_REQUEST['featured_image']; |
| 813 |
if(!empty($_REQUEST['featured_image'])){ |
| 814 |
set_post_thumbnail($postID, $_REQUEST['featured_image']); |
| 815 |
}else{ |
| 816 |
delete_post_thumbnail($postID); |
| 817 |
} |
| 818 |
|
| 819 |
if(!isset($_REQUEST['post_category'])){ |
| 820 |
$_REQUEST['post_category'] = ''; |
| 821 |
} |
| 822 |
|
| 823 |
if(!isset($_REQUEST['post_tags'])){ |
| 824 |
$_REQUEST['post_tags'] = ''; |
| 825 |
} |
| 826 |
|
| 827 |
if($_post->post_type == 'post'){ |
| 828 |
$post['post_category'] = pagelayer_sanitize_text_field($_REQUEST['post_category']); |
| 829 |
|
| 830 |
$post['tags_input'] = pagelayer_sanitize_text_field($_REQUEST['post_tags']); |
| 831 |
}else{ |
| 832 |
$cat_name = pagelayer_post_type_category($_post->post_type); |
| 833 |
if($cat_name){ |
| 834 |
$post['tax_input'][$cat_name] = pagelayer_sanitize_text_field($_REQUEST['post_category']); |
| 835 |
} |
| 836 |
|
| 837 |
$tag_name = pagelayer_post_type_tag($_post->post_type); |
| 838 |
if($tag_name){ |
| 839 |
$post['tax_input'][$tag_name] = pagelayer_sanitize_text_field($_REQUEST['post_tags']); |
| 840 |
} |
| 841 |
} |
| 842 |
|
| 843 |
if(isset($_REQUEST['post_sticky']) && !empty($_REQUEST['post_sticky'])){ |
| 844 |
stick_post( $postID ); |
| 845 |
}else{ |
| 846 |
if(is_sticky($postID)){ |
| 847 |
unstick_post( $postID ); |
| 848 |
} |
| 849 |
} |
| 850 |
|
| 851 |
// Any contact templates ? |
| 852 |
if(!empty($_REQUEST['contacts']) && current_user_can('activate_plugins')){ |
| 853 |
update_post_meta($postID, 'pagelayer_contact_templates', $_REQUEST['contacts']); |
| 854 |
}else{ |
| 855 |
delete_post_meta($postID, 'pagelayer_contact_templates'); |
| 856 |
} |
| 857 |
|
| 858 |
// Save copyright |
| 859 |
if(isset($_REQUEST['copyright']) && current_user_can('manage_options')){ |
| 860 |
update_option('pagelayer-copyright', wp_unslash($_REQUEST['copyright'])); |
| 861 |
} |
| 862 |
|
| 863 |
// Apply a filter |
| 864 |
$post = apply_filters('pagelayer_save_content', $post); |
| 865 |
|
| 866 |
// Update the post into the database |
| 867 |
$ret = wp_update_post($post, true); |
| 868 |
|
| 869 |
// Render the post |
| 870 |
//update_post_meta($postID, 'pagelayer_rendered_post', pagelayer_get_post_content($postID)); |
| 871 |
|
| 872 |
if (is_wp_error($ret)) { |
| 873 |
$errors = $ret->get_error_messages(); |
| 874 |
$msg['error'] = __pl('post_update_err').' : '.implode('', $errors); |
| 875 |
}else{ |
| 876 |
|
| 877 |
// Get the updated post |
| 878 |
$_post = get_post($postID); |
| 879 |
|
| 880 |
// Is this a Pagelayer post |
| 881 |
$data = get_post_meta($postID, 'pagelayer-data', true); |
| 882 |
|
| 883 |
if(empty($data)){ |
| 884 |
|
| 885 |
// Convert to pagelayer accessed post |
| 886 |
if(!add_post_meta($postID, 'pagelayer-data', time(), true)){ |
| 887 |
update_post_meta($postID, 'pagelayer-data', time()); |
| 888 |
} |
| 889 |
} |
| 890 |
|
| 891 |
if(!empty($pagelayer_comment_alerts)){ |
| 892 |
$msg['comment_alerts'] = $pagelayer_comment_alerts; |
| 893 |
} |
| 894 |
|
| 895 |
if(!empty($pagelayer_comment_errors)){ |
| 896 |
$msg['error'][] = 'Comment Mode errrors found !'; |
| 897 |
$msg['comment_errors'] = $pagelayer_comment_errors; |
| 898 |
} |
| 899 |
|
| 900 |
$msg['success'] = __pl('post_update_success'); |
| 901 |
} |
| 902 |
|
| 903 |
}else{ |
| 904 |
$msg['error'] = __pl('post_update_err'); |
| 905 |
} |
| 906 |
|
| 907 |
$msg['post_status'] = (empty($_post->post_password)) ? $_post->post_status : 'pass_protected'; |
| 908 |
|
| 909 |
// Save global widgets data |
| 910 |
if(!empty($_REQUEST['global_widgets'])){ |
| 911 |
pagelayer_save_templ_content(true); |
| 912 |
} |
| 913 |
|
| 914 |
// Save nav menu data |
| 915 |
if(!empty($_REQUEST['pagelayer_nav_items']) && current_user_can('edit_theme_options')){ |
| 916 |
$menu_items = (array) $_REQUEST['pagelayer_nav_items']; |
| 917 |
foreach($menu_items as $items){ |
| 918 |
pagelayer_save_nav_menu_items($items); |
| 919 |
} |
| 920 |
} |
| 921 |
|
| 922 |
// Save Customizer data |
| 923 |
if(!empty($_REQUEST['pagelayer_customizer_options']) && current_user_can('edit_theme_options')){ |
| 924 |
|
| 925 |
$customizer_options = wp_unslash($_REQUEST['pagelayer_customizer_options']); |
| 926 |
$customizer_options = json_decode($customizer_options, true); |
| 927 |
|
| 928 |
// Add current post type |
| 929 |
$customizer_options['pagelayer_current_post_type'] = $_post->post_type; |
| 930 |
|
| 931 |
pagelayer_save_customizer_options($customizer_options); |
| 932 |
} |
| 933 |
|
| 934 |
pagelayer_json_output($msg); |
| 935 |
|
| 936 |
} |
| 937 |
|
| 938 |
// Save sections and global sections |
| 939 |
add_action('wp_ajax_pagelayer_save_templ_content', 'pagelayer_save_templ_content'); |
| 940 |
function pagelayer_save_templ_content($echo = false){ |
| 941 |
|
| 942 |
// Some AJAX security |
| 943 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 944 |
|
| 945 |
if ( ! current_user_can( get_post_type_object( 'pagelayer-template' )->cap->create_posts ) ) { |
| 946 |
$ret['error'][$g_post_id] = __pl('no_permission'); |
| 947 |
pagelayer_json_output($ret); |
| 948 |
return false; |
| 949 |
} |
| 950 |
|
| 951 |
// Are you allowed to edit ? |
| 952 |
if(!pagelayer_user_can_edit($_REQUEST['postID'])){ |
| 953 |
$msg['error'][] = __pl('no_permission'); |
| 954 |
pagelayer_json_output($msg); |
| 955 |
} |
| 956 |
|
| 957 |
$ret = array(); |
| 958 |
|
| 959 |
// Save global widgets data |
| 960 |
if(empty($_REQUEST['global_widgets'])){ |
| 961 |
$ret['error'][] = 'No widgets given'; |
| 962 |
pagelayer_json_output($ret); |
| 963 |
return false; |
| 964 |
} |
| 965 |
|
| 966 |
$global_widgets = $_REQUEST['global_widgets']; |
| 967 |
|
| 968 |
foreach($global_widgets as $key => $value){ |
| 969 |
|
| 970 |
$g_post_id = (int) $value['post_id']; |
| 971 |
|
| 972 |
// Are you allowed to edit ? |
| 973 |
if(!empty($g_post_id) && !pagelayer_user_can_edit($g_post_id)){ |
| 974 |
$ret['error'][$g_post_id] = __pl('no_permission').' : '.$g_post_id; |
| 975 |
continue; |
| 976 |
} |
| 977 |
|
| 978 |
// Decode base64 data |
| 979 |
$value['content'] = base64_decode($value['content']); |
| 980 |
|
| 981 |
$is_xss = pagelayer_xss_content($value['content']); |
| 982 |
|
| 983 |
if(!current_user_can('manage_options') && strlen($is_xss) > 0){ |
| 984 |
$ret['error'][$g_post_id] = __pl('xss_found').' - '.$is_xss; |
| 985 |
pagelayer_json_output($ret); |
| 986 |
} |
| 987 |
|
| 988 |
// Add slash to save data in post |
| 989 |
$value['content'] = wp_slash($value['content']); |
| 990 |
|
| 991 |
// We need to create the post |
| 992 |
if(empty($value['post_id'])){ |
| 993 |
|
| 994 |
$g_ret = wp_insert_post([ |
| 995 |
'post_type' => 'pagelayer-template', |
| 996 |
'post_title' => $value['title'], |
| 997 |
'post_content' => $value['content'], |
| 998 |
'post_status' => 'publish', |
| 999 |
'comment_status' => 'closed', |
| 1000 |
'ping_status' => 'closed' |
| 1001 |
]); |
| 1002 |
|
| 1003 |
$g_post_id = $g_ret; |
| 1004 |
|
| 1005 |
// Save our template metas |
| 1006 |
update_post_meta($g_post_id, 'pagelayer_template_type', $value['type']); |
| 1007 |
update_post_meta($g_post_id, 'pagelayer-data', time()); |
| 1008 |
|
| 1009 |
}else if(!empty($value['content'])){ |
| 1010 |
|
| 1011 |
// Save global widget content |
| 1012 |
$post = array( |
| 1013 |
'ID' => $g_post_id, |
| 1014 |
'post_title' => $value['title'], |
| 1015 |
'post_content' => $value['content'], |
| 1016 |
); |
| 1017 |
|
| 1018 |
wp_update_post($post); |
| 1019 |
} |
| 1020 |
|
| 1021 |
if(is_wp_error($g_post_id)){ |
| 1022 |
$ret['error'][$g_post_id] = __pl('template_update_err'); |
| 1023 |
}else{ |
| 1024 |
$ret['success'][$g_post_id] = __pl('template_update_success'); |
| 1025 |
} |
| 1026 |
} |
| 1027 |
|
| 1028 |
if(!$echo){ |
| 1029 |
pagelayer_json_output($ret); |
| 1030 |
}else{ |
| 1031 |
return $ret; |
| 1032 |
} |
| 1033 |
} |
| 1034 |
|
| 1035 |
// Update the Site Title |
| 1036 |
add_action('wp_ajax_pagelayer_set_jscss_giver', 'pagelayer_set_jscss_giver'); |
| 1037 |
function pagelayer_set_jscss_giver(){ |
| 1038 |
global $wpdb; |
| 1039 |
|
| 1040 |
// Some AJAX security |
| 1041 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1042 |
|
| 1043 |
if( !current_user_can('manage_options') ){ |
| 1044 |
$ret['error'] = __pl('no_permission'); |
| 1045 |
pagelayer_json_output($ret); |
| 1046 |
} |
| 1047 |
|
| 1048 |
$val = (int) @$_REQUEST['set']; |
| 1049 |
|
| 1050 |
if(in_array($val, [1, -1])){ |
| 1051 |
update_option('pagelayer_enable_giver', $val); |
| 1052 |
} |
| 1053 |
|
| 1054 |
$ret['success'] = 1; |
| 1055 |
pagelayer_json_output($ret); |
| 1056 |
} |
| 1057 |
|
| 1058 |
// Shortcodes Widget Handler |
| 1059 |
add_action('wp_ajax_pagelayer_do_shortcodes', 'pagelayer_do_shortcodes'); |
| 1060 |
function pagelayer_do_shortcodes(){ |
| 1061 |
|
| 1062 |
// Some AJAX security |
| 1063 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1064 |
|
| 1065 |
if(!current_user_can('edit_posts')){// TODO : WooCommerce |
| 1066 |
$ret['error'][] = __pl('no_permission'); |
| 1067 |
pagelayer_json_output($ret); |
| 1068 |
} |
| 1069 |
|
| 1070 |
$data = ''; |
| 1071 |
if(isset($_REQUEST['shortcode_data'])){ |
| 1072 |
$data = stripslashes($_REQUEST['shortcode_data']); |
| 1073 |
} |
| 1074 |
|
| 1075 |
// Load shortcodes |
| 1076 |
pagelayer_load_shortcodes(); |
| 1077 |
|
| 1078 |
$data = pagelayer_the_content($data); |
| 1079 |
|
| 1080 |
// Create the HTML object |
| 1081 |
$node = pagelayerQuery::parseStr($data); |
| 1082 |
$node->query('.pagelayer-ele')->removeClass('pagelayer-ele'); |
| 1083 |
echo $node->html(); |
| 1084 |
|
| 1085 |
wp_die(); |
| 1086 |
|
| 1087 |
} |
| 1088 |
|
| 1089 |
// Give the JS |
| 1090 |
add_action('wp_ajax_pagelayer_givejs', 'pagelayer_givejs'); |
| 1091 |
function pagelayer_givejs(){ |
| 1092 |
|
| 1093 |
global $pagelayer; |
| 1094 |
|
| 1095 |
// WordPress adds the Expires header in all AJAX calls. We need to remove it for cache to work |
| 1096 |
header_remove("Expires"); |
| 1097 |
header_remove("Cache-Control"); |
| 1098 |
|
| 1099 |
// Load shortcodes |
| 1100 |
pagelayer_load_shortcodes(); |
| 1101 |
|
| 1102 |
// Load font options |
| 1103 |
pagelayer_load_font_options(); |
| 1104 |
|
| 1105 |
// Pagelayer Template Loading Mechanism |
| 1106 |
include_once(PAGELAYER_DIR.'/js/givejs.php'); |
| 1107 |
|
| 1108 |
exit(); |
| 1109 |
|
| 1110 |
} |
| 1111 |
|
| 1112 |
add_action('wp_ajax_pagelayer_givecss', 'pagelayer_givecss'); |
| 1113 |
add_action('wp_ajax_nopriv_pagelayer_givecss', 'pagelayer_givecss'); |
| 1114 |
function pagelayer_givecss(){ |
| 1115 |
|
| 1116 |
global $pagelayer; |
| 1117 |
|
| 1118 |
// WordPress adds the Expires header in all AJAX calls. We need to remove it for cache to work |
| 1119 |
header_remove("Expires"); |
| 1120 |
header_remove("Cache-Control"); |
| 1121 |
|
| 1122 |
// Pagelayer Template Loading Mechanism |
| 1123 |
include_once(PAGELAYER_DIR.'/css/givecss.php'); |
| 1124 |
|
| 1125 |
exit(); |
| 1126 |
|
| 1127 |
} |
| 1128 |
|
| 1129 |
// Shortcodes Widget Handler |
| 1130 |
add_action('wp_ajax_pagelayer_get_section_shortcodes', 'pagelayer_get_section_shortcodes'); |
| 1131 |
function pagelayer_get_section_shortcodes(){ |
| 1132 |
|
| 1133 |
global $pagelayer; |
| 1134 |
|
| 1135 |
// Some AJAX security |
| 1136 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1137 |
|
| 1138 |
if(!current_user_can('edit_posts')){ |
| 1139 |
$ret['error'][] = __pl('no_permission'); |
| 1140 |
pagelayer_json_output($ret); |
| 1141 |
} |
| 1142 |
|
| 1143 |
$data = ''; |
| 1144 |
if(isset($_REQUEST['pagelayer_section_id'])){ |
| 1145 |
|
| 1146 |
$get_url = PAGELAYER_API.'/library.php?give_id='.sanitize_text_field($_REQUEST['pagelayer_section_id']).(!empty($pagelayer->license['license']) ? '&license='.$pagelayer->license['license'] : '').'&url='.rawurlencode(site_url()); |
| 1147 |
|
| 1148 |
// For SitePad users |
| 1149 |
if(function_exists('get_softaculous_file')){ |
| 1150 |
$get_url = get_softaculous_file($get_url, 1); |
| 1151 |
} |
| 1152 |
|
| 1153 |
$fetch = wp_remote_get($get_url, array('timeout' => 60)); |
| 1154 |
|
| 1155 |
if ( is_array( $fetch ) && ! is_wp_error( $fetch ) && isset( $fetch['body'] ) ) { |
| 1156 |
$data = json_decode( $fetch['body'], true ); // use the content |
| 1157 |
}else{ |
| 1158 |
$data['error'] = __pl('The response was malformed'); |
| 1159 |
pagelayer_json_output($data); |
| 1160 |
} |
| 1161 |
} |
| 1162 |
|
| 1163 |
if(isset($_REQUEST['postID'])){ |
| 1164 |
$post_id = (int) $_REQUEST['postID']; |
| 1165 |
|
| 1166 |
if(!empty($post_id)){ |
| 1167 |
$post = get_post( $post_id ); |
| 1168 |
// Need to make the reviews post global |
| 1169 |
if ( !empty( $post ) ) { |
| 1170 |
$GLOBALS['post'] = $post; |
| 1171 |
|
| 1172 |
$GLOBALS['wp_query'] = new WP_Query([ |
| 1173 |
'post_type' => $GLOBALS['post']->post_type, |
| 1174 |
'post__in' => array($post_id), |
| 1175 |
]); |
| 1176 |
} |
| 1177 |
} |
| 1178 |
} |
| 1179 |
|
| 1180 |
// Upload the images if any in the shortcode |
| 1181 |
preg_match_all('/"'.preg_quote('{{pl_lib_images}}', '/').'([^"]*)"/is', $data['code'], $matches); |
| 1182 |
|
| 1183 |
foreach($matches[0] as $k => $v){ |
| 1184 |
$image_url = trim($v, '"\''); |
| 1185 |
$urls[$image_url] = $image_url; |
| 1186 |
} |
| 1187 |
|
| 1188 |
foreach($urls as $k => $image_url){ |
| 1189 |
|
| 1190 |
$file = basename($image_url); |
| 1191 |
$id = 0; |
| 1192 |
|
| 1193 |
// Upload this |
| 1194 |
if(!empty($data[$file])){ |
| 1195 |
|
| 1196 |
$id = pagelayer_upload_media($file, base64_decode($data[$file])); |
| 1197 |
|
| 1198 |
if(!empty($id)){ |
| 1199 |
$data['code'] = str_replace('"'.$image_url.'"', '"'.$id.'"', $data['code']); |
| 1200 |
} |
| 1201 |
} |
| 1202 |
|
| 1203 |
} |
| 1204 |
|
| 1205 |
// Load shortcodes |
| 1206 |
pagelayer_load_shortcodes(); |
| 1207 |
|
| 1208 |
if(!empty($data['code'])){ |
| 1209 |
$data['code'] = pagelayer_the_content($data['code'], true); |
| 1210 |
} |
| 1211 |
|
| 1212 |
pagelayer_json_output($data); |
| 1213 |
|
| 1214 |
} |
| 1215 |
|
| 1216 |
// Shortcodes Widget Handler |
| 1217 |
add_action('wp_ajax_pagelayer_get_section_blocks', 'pagelayer_get_section_blocks'); |
| 1218 |
function pagelayer_get_section_blocks(){ |
| 1219 |
|
| 1220 |
global $pagelayer; |
| 1221 |
|
| 1222 |
// Some AJAX security |
| 1223 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1224 |
|
| 1225 |
if(!current_user_can('edit_posts')){ |
| 1226 |
$ret['error'][] = __pl('no_permission'); |
| 1227 |
pagelayer_json_output($ret); |
| 1228 |
} |
| 1229 |
|
| 1230 |
$data = ''; |
| 1231 |
if(isset($_REQUEST['pagelayer_section_id'])){ |
| 1232 |
|
| 1233 |
$get_url = PAGELAYER_API.'/library.php?give_id='.sanitize_text_field($_REQUEST['pagelayer_section_id']).(!empty($pagelayer->license['license']) ? '&license='.$pagelayer->license['license'] : '').'&url='.rawurlencode(site_url()); |
| 1234 |
|
| 1235 |
// For SitePad users |
| 1236 |
if(function_exists('get_softaculous_file')){ |
| 1237 |
$get_url = get_softaculous_file($get_url, 1); |
| 1238 |
} |
| 1239 |
|
| 1240 |
$fetch = wp_remote_get($get_url, array('timeout' => 60)); |
| 1241 |
|
| 1242 |
if ( is_array( $fetch ) && ! is_wp_error( $fetch ) && isset( $fetch['body'] ) ) { |
| 1243 |
$data = json_decode( $fetch['body'], true ); // use the content |
| 1244 |
}else{ |
| 1245 |
$data['error'] = __pl('The response was malformed'); |
| 1246 |
pagelayer_json_output($data); |
| 1247 |
} |
| 1248 |
} |
| 1249 |
|
| 1250 |
// Upload the images if any in the shortcode |
| 1251 |
preg_match_all('/"'.preg_quote('{{pl_lib_images}}', '/').'([^"]*)"/is', $data['code'], $matches); |
| 1252 |
|
| 1253 |
foreach($matches[0] as $k => $v){ |
| 1254 |
$image_url = trim($v, '"\''); |
| 1255 |
$urls[$image_url] = $image_url; |
| 1256 |
} |
| 1257 |
|
| 1258 |
foreach($urls as $k => $image_url){ |
| 1259 |
|
| 1260 |
$file = basename($image_url); |
| 1261 |
$id = 0; |
| 1262 |
|
| 1263 |
// Upload this |
| 1264 |
if(!empty($data[$file])){ |
| 1265 |
|
| 1266 |
$id = pagelayer_upload_media($file, base64_decode($data[$file])); |
| 1267 |
|
| 1268 |
if(!empty($id)){ |
| 1269 |
$data['code'] = str_replace('"'.$image_url.'"', '"'.$id.'"', $data['code']); |
| 1270 |
} |
| 1271 |
} |
| 1272 |
|
| 1273 |
} |
| 1274 |
|
| 1275 |
if ( false !== strpos( $data['code'], '[pl_' ) ) { |
| 1276 |
// Load shortcodes |
| 1277 |
pagelayer_load_shortcodes(); |
| 1278 |
|
| 1279 |
// Load Parse Shortcodes |
| 1280 |
include_once(PAGELAYER_DIR.'/main/parse-shortcodes.php'); |
| 1281 |
|
| 1282 |
$data['code'] = pagelayer_do_shortcode_to_block($data['code']); |
| 1283 |
} |
| 1284 |
|
| 1285 |
$data['code'] = pagelayer_add_tmp_atts($data['code']); |
| 1286 |
|
| 1287 |
pagelayer_json_output($data); |
| 1288 |
|
| 1289 |
} |
| 1290 |
|
| 1291 |
// Get the Site Title |
| 1292 |
add_action('wp_ajax_pagelayer_fetch_site_title', 'pagelayer_fetch_site_title'); |
| 1293 |
function pagelayer_fetch_site_title(){ |
| 1294 |
|
| 1295 |
// Some AJAX security |
| 1296 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1297 |
|
| 1298 |
echo get_bloginfo('name'); |
| 1299 |
wp_die(); |
| 1300 |
} |
| 1301 |
|
| 1302 |
// Update the Site Title |
| 1303 |
add_action('wp_ajax_pagelayer_update_site_title', 'pagelayer_update_site_title'); |
| 1304 |
function pagelayer_update_site_title(){ |
| 1305 |
global $wpdb; |
| 1306 |
|
| 1307 |
// Some AJAX security |
| 1308 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1309 |
|
| 1310 |
$site_title = $_POST['site_title']; |
| 1311 |
|
| 1312 |
if(!current_user_can('manage_options')){ |
| 1313 |
$ret['error'][] = __pl('no_permission'); |
| 1314 |
pagelayer_json_output($ret); |
| 1315 |
} |
| 1316 |
|
| 1317 |
update_option('blogname', $site_title); |
| 1318 |
|
| 1319 |
wp_die(); |
| 1320 |
} |
| 1321 |
|
| 1322 |
// Show the SideBars |
| 1323 |
add_action('wp_ajax_pagelayer_fetch_sidebar', 'pagelayer_fetch_sidebar'); |
| 1324 |
function pagelayer_fetch_sidebar(){ |
| 1325 |
|
| 1326 |
global $wp_registered_sidebars; |
| 1327 |
|
| 1328 |
// Some AJAX security |
| 1329 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1330 |
|
| 1331 |
// Create a list |
| 1332 |
$pagelayer_wp_widgets = array(); |
| 1333 |
|
| 1334 |
foreach($wp_registered_sidebars as $v){ |
| 1335 |
$pagelayer_wp_widgets[$v['id']] = $v['name']; |
| 1336 |
} |
| 1337 |
|
| 1338 |
$id = @$_REQUEST['sidebar']; |
| 1339 |
|
| 1340 |
if(function_exists('dynamic_sidebar') && !empty($pagelayer_wp_widgets[$id])) { |
| 1341 |
ob_start(); |
| 1342 |
dynamic_sidebar($id); |
| 1343 |
$result = ob_get_clean(); |
| 1344 |
}else{ |
| 1345 |
$result = __pl('no_widget_area'); |
| 1346 |
} |
| 1347 |
|
| 1348 |
echo $result; |
| 1349 |
wp_die(); |
| 1350 |
|
| 1351 |
} |
| 1352 |
|
| 1353 |
// Show the primary menu ! |
| 1354 |
add_action('wp_ajax_pagelayer_fetch_primary_menu', 'pagelayer_fetch_primary_menu'); |
| 1355 |
function pagelayer_fetch_primary_menu(){ |
| 1356 |
|
| 1357 |
// Some AJAX security |
| 1358 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1359 |
|
| 1360 |
if(isset($_POST['nav_list'])){ |
| 1361 |
$_POST['nav_list'] = (int) $_POST['nav_list']; |
| 1362 |
|
| 1363 |
// Load Pagelayer nav menu walker |
| 1364 |
include_once(PAGELAYER_DIR.'/main/nav_walker.php'); |
| 1365 |
|
| 1366 |
$postID = (int) $_REQUEST['postID']; |
| 1367 |
|
| 1368 |
// To on live mode |
| 1369 |
$GLOBALS['post'] = get_post($postID); |
| 1370 |
$GLOBALS['wp_query'] = new WP_Query([ |
| 1371 |
'post_type' => $GLOBALS['post']->post_type, |
| 1372 |
'post__in' => array($postID), |
| 1373 |
]); |
| 1374 |
|
| 1375 |
// Load short |
| 1376 |
pagelayer_load_shortcodes(); |
| 1377 |
|
| 1378 |
wp_nav_menu([ |
| 1379 |
'menu' => wp_get_nav_menu_object($_POST['nav_list']), |
| 1380 |
'menu_id' => $_POST["nav_list"], |
| 1381 |
'menu_class' => 'pagelayer-wp_menu-ul', |
| 1382 |
'walker' => new Pagelayer_Walker_Nav_Menu(), |
| 1383 |
//'theme_location' => 'primary', |
| 1384 |
'echo' => true, |
| 1385 |
]); |
| 1386 |
} |
| 1387 |
|
| 1388 |
wp_die(); |
| 1389 |
} |
| 1390 |
|
| 1391 |
// Save post revision |
| 1392 |
add_action('wp_ajax_pagelayer_create_post_autosave', 'pagelayer_create_post_autosave'); |
| 1393 |
function pagelayer_create_post_autosave(){ |
| 1394 |
|
| 1395 |
// Some AJAX security |
| 1396 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1397 |
|
| 1398 |
$ret = array(); |
| 1399 |
$postID = (int) $_GET['postID']; |
| 1400 |
$content = $_REQUEST['pagelayer_post_content']; |
| 1401 |
|
| 1402 |
// Decode base64 data |
| 1403 |
$content = base64_decode($content); |
| 1404 |
$content = wp_slash($content); |
| 1405 |
|
| 1406 |
// Are you allowed to edit ? |
| 1407 |
if(!pagelayer_user_can_edit($postID)){ |
| 1408 |
$ret['error'][] = __pl('no_permission'); |
| 1409 |
pagelayer_json_output($ret); |
| 1410 |
} |
| 1411 |
|
| 1412 |
if(empty($postID)){ |
| 1413 |
$ret['error'] = __pl('invalid_post_id'); |
| 1414 |
}else{ |
| 1415 |
|
| 1416 |
$post = array( |
| 1417 |
'post_ID' => $postID, |
| 1418 |
'post_content' => $content, |
| 1419 |
); |
| 1420 |
|
| 1421 |
$ret['id'] = wp_create_post_autosave($post); |
| 1422 |
} |
| 1423 |
|
| 1424 |
$ret['url'] = get_preview_post_link($postID); |
| 1425 |
|
| 1426 |
pagelayer_json_output($ret); |
| 1427 |
|
| 1428 |
} |
| 1429 |
|
| 1430 |
// Get post revision |
| 1431 |
add_action('wp_ajax_pagelayer_get_revision', 'pagelayer_get_revision'); |
| 1432 |
function pagelayer_get_revision(){ |
| 1433 |
|
| 1434 |
// Some AJAX security |
| 1435 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1436 |
|
| 1437 |
$ret = array(); |
| 1438 |
$postID = (int) $_GET['postID']; |
| 1439 |
|
| 1440 |
// Are you allowed to edit ? |
| 1441 |
if(!pagelayer_user_can_edit($postID)){ |
| 1442 |
$ret['error'][] = __pl('no_permission'); |
| 1443 |
pagelayer_json_output($ret); |
| 1444 |
} |
| 1445 |
|
| 1446 |
if(empty($postID)){ |
| 1447 |
$ret['error'] = __pl('invalid_post_id'); |
| 1448 |
}else{ |
| 1449 |
$ret = pagelayer_get_post_revision_by_id($postID); |
| 1450 |
} |
| 1451 |
|
| 1452 |
pagelayer_json_output($ret); |
| 1453 |
|
| 1454 |
} |
| 1455 |
|
| 1456 |
// Apply post revision |
| 1457 |
add_action('wp_ajax_pagelayer_apply_revision', 'pagelayer_apply_revision'); |
| 1458 |
function pagelayer_apply_revision(){ |
| 1459 |
|
| 1460 |
// Some AJAX security |
| 1461 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1462 |
|
| 1463 |
$revisionID = (int) $_REQUEST['revisionID']; |
| 1464 |
$parID = wp_get_post_parent_id($revisionID); |
| 1465 |
$ret = array(); |
| 1466 |
|
| 1467 |
if(empty($parID)){ |
| 1468 |
$parID = $revisionID; |
| 1469 |
} |
| 1470 |
|
| 1471 |
// Are you allowed to edit ? |
| 1472 |
if(!pagelayer_user_can_edit($parID)){ |
| 1473 |
$ret['error'][] = __pl('no_permission'); |
| 1474 |
pagelayer_json_output($ret); |
| 1475 |
} |
| 1476 |
|
| 1477 |
if(empty($revisionID)){ |
| 1478 |
$ret['error'] = __pl('invalid_post_id'); |
| 1479 |
}else{ |
| 1480 |
|
| 1481 |
$post = get_post( $revisionID ); |
| 1482 |
|
| 1483 |
if ( empty( $post ) ) { |
| 1484 |
$ret['error'] = __pl('invalid_revision'); |
| 1485 |
pagelayer_json_output($ret); |
| 1486 |
} |
| 1487 |
|
| 1488 |
// Need to make the reviews post global |
| 1489 |
$GLOBALS['post'] = $post; |
| 1490 |
$GLOBALS['wp_query'] = new WP_Query([ |
| 1491 |
'post_type' => $GLOBALS['post']->post_type, |
| 1492 |
'post__in' => array($parID), |
| 1493 |
]); |
| 1494 |
|
| 1495 |
// Need to reload the shortcodes |
| 1496 |
pagelayer_load_shortcodes(); |
| 1497 |
|
| 1498 |
$ret['id'] = $revisionID; |
| 1499 |
$ret['content'] = pagelayer_the_content($post->post_content, true); |
| 1500 |
|
| 1501 |
if(is_wp_error($post)) { |
| 1502 |
$ret['error'] = __pl('rev_load_error'); |
| 1503 |
}else{ |
| 1504 |
$ret['success'] = __pl('rev_load_success'); |
| 1505 |
} |
| 1506 |
|
| 1507 |
wp_reset_postdata(); |
| 1508 |
} |
| 1509 |
|
| 1510 |
pagelayer_json_output($ret); |
| 1511 |
|
| 1512 |
} |
| 1513 |
|
| 1514 |
// Get post revision |
| 1515 |
add_action('wp_ajax_pagelayer_delete_revision', 'pagelayer_delete_revision'); |
| 1516 |
function pagelayer_delete_revision() { |
| 1517 |
|
| 1518 |
// Some AJAX security |
| 1519 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1520 |
|
| 1521 |
$revisionID = (int) $_REQUEST['revisionID']; |
| 1522 |
$parID = wp_get_post_parent_id($revisionID); |
| 1523 |
$ret = array(); |
| 1524 |
|
| 1525 |
// Are you allowed to edit ? |
| 1526 |
if(!pagelayer_user_can_edit($parID)){ |
| 1527 |
$ret['error'][] = __pl('no_permission'); |
| 1528 |
pagelayer_json_output($ret); |
| 1529 |
} |
| 1530 |
|
| 1531 |
if(empty($revisionID)){ |
| 1532 |
$ret['error'] = __pl('invalid_post_id'); |
| 1533 |
}else{ |
| 1534 |
|
| 1535 |
$revision = get_post( $revisionID ); |
| 1536 |
|
| 1537 |
if ( empty( $revision ) ) { |
| 1538 |
$ret['error'] = __pl('invalid_revision'); |
| 1539 |
}else{ |
| 1540 |
|
| 1541 |
if ( ! current_user_can( 'delete_post', $parID ) ) { |
| 1542 |
$ret['error'] = __pl('access_denied'); |
| 1543 |
pagelayer_json_output($ret); |
| 1544 |
} |
| 1545 |
|
| 1546 |
$deleted = wp_delete_post_revision( $revision->ID ); |
| 1547 |
|
| 1548 |
if ( ! $deleted || is_wp_error( $deleted ) ) { |
| 1549 |
$ret['error'] = __pl('delete_rev_error'); |
| 1550 |
}else{ |
| 1551 |
$ret['success'] = __pl('delete_rev_success'); |
| 1552 |
} |
| 1553 |
} |
| 1554 |
} |
| 1555 |
|
| 1556 |
pagelayer_json_output($ret); |
| 1557 |
|
| 1558 |
} |
| 1559 |
|
| 1560 |
// Get post navigation |
| 1561 |
add_action('wp_ajax_pagelayer_post_nav', 'pagelayer_post_nav'); |
| 1562 |
function pagelayer_post_nav() { |
| 1563 |
|
| 1564 |
// Some AJAX security |
| 1565 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1566 |
|
| 1567 |
if(!isset($_REQUEST['data']) || !isset($_REQUEST['postID'])){ |
| 1568 |
return; |
| 1569 |
} |
| 1570 |
|
| 1571 |
$el['atts'] = $_REQUEST['data']; |
| 1572 |
|
| 1573 |
$post = get_post($_REQUEST['postID']); |
| 1574 |
|
| 1575 |
// Need to make this post global |
| 1576 |
$GLOBALS['post'] = $post; |
| 1577 |
|
| 1578 |
$in_same_term = false; |
| 1579 |
$taxonomies = 'category'; |
| 1580 |
$title = ''; |
| 1581 |
$arrows_list = $el['atts']['arrows_list']; |
| 1582 |
|
| 1583 |
if($el['atts']['in_same_term']){ |
| 1584 |
$in_same_term = true; |
| 1585 |
$taxonomies = $el['atts']['taxonomies']; |
| 1586 |
} |
| 1587 |
|
| 1588 |
if($el['atts']['post_title']){ |
| 1589 |
$title = '<span class="pagelayer-post-nav-title">%title</span>'; |
| 1590 |
} |
| 1591 |
|
| 1592 |
$next_label = '<span class="pagelayer-next-holder"> |
| 1593 |
<span class="pagelayer-post-nav-link"> '.$el["atts"]["next_label"].'</span>'.$title.' |
| 1594 |
</span> |
| 1595 |
<span class="pagelayer-post-nav-icon fa fa-'.$arrows_list.'-right"></span>'; |
| 1596 |
|
| 1597 |
$prev_label = '<span class="pagelayer-post-nav-icon fa fa-'.$arrows_list.'-left"></span> |
| 1598 |
<span class="pagelayer-next-holder"> |
| 1599 |
<span class="pagelayer-post-nav-link"> '.$el["atts"]["prev_label"].'</span>'.$title.' |
| 1600 |
</span>'; |
| 1601 |
|
| 1602 |
$el['atts']['next_link'] = get_next_post_link('%link', $next_label, $in_same_term, '', $taxonomies); |
| 1603 |
|
| 1604 |
$el['atts']['prev_link'] = get_previous_post_link('%link', $prev_label, $in_same_term, '', $taxonomies ); |
| 1605 |
|
| 1606 |
pagelayer_json_output($el); |
| 1607 |
|
| 1608 |
} |
| 1609 |
|
| 1610 |
// Get post comment template |
| 1611 |
add_action('wp_ajax_pagelayer_post_comment', 'pagelayer_post_comment'); |
| 1612 |
function pagelayer_post_comment() { |
| 1613 |
global $post; |
| 1614 |
|
| 1615 |
// Some AJAX security |
| 1616 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1617 |
|
| 1618 |
if(!isset($_REQUEST['postID'])){ |
| 1619 |
return true; |
| 1620 |
} |
| 1621 |
|
| 1622 |
$GLOBALS['post'] = get_post($_REQUEST['postID']); |
| 1623 |
$GLOBALS['withcomments'] = true; |
| 1624 |
|
| 1625 |
// Load shortcodes |
| 1626 |
pagelayer_load_shortcodes(); |
| 1627 |
|
| 1628 |
$el = []; |
| 1629 |
pagelayer_sc_post_comment($el); |
| 1630 |
|
| 1631 |
echo $el['atts']['post_comment']; |
| 1632 |
|
| 1633 |
wp_die(); |
| 1634 |
|
| 1635 |
} |
| 1636 |
|
| 1637 |
// Get post comment template |
| 1638 |
add_action('wp_ajax_pagelayer_post_info', 'pagelayer_post_info'); |
| 1639 |
function pagelayer_post_info() { |
| 1640 |
global $post; |
| 1641 |
|
| 1642 |
// Some AJAX security |
| 1643 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1644 |
|
| 1645 |
if(!isset($_REQUEST['postID']) || !isset($_REQUEST['el'])){ |
| 1646 |
return true; |
| 1647 |
} |
| 1648 |
|
| 1649 |
$el['atts'] = $_REQUEST['el']; |
| 1650 |
|
| 1651 |
$GLOBALS['post'] = get_post($_REQUEST['postID']); |
| 1652 |
|
| 1653 |
// Load shortcodes |
| 1654 |
pagelayer_load_shortcodes(); |
| 1655 |
|
| 1656 |
pagelayer_sc_post_info_list($el); |
| 1657 |
|
| 1658 |
pagelayer_json_output($el['atts']); |
| 1659 |
|
| 1660 |
} |
| 1661 |
|
| 1662 |
// Get the Featured Image |
| 1663 |
add_action('wp_ajax_pagelayer_fetch_featured_img', 'pagelayer_fetch_featured_img'); |
| 1664 |
function pagelayer_fetch_featured_img(){ |
| 1665 |
|
| 1666 |
// Some AJAX security |
| 1667 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1668 |
|
| 1669 |
$id = get_post_thumbnail_id( (int) $_POST['post_id'] ); |
| 1670 |
$img = []; |
| 1671 |
|
| 1672 |
if(empty($id)){ |
| 1673 |
pagelayer_json_output($img); |
| 1674 |
} |
| 1675 |
|
| 1676 |
$img = pagelayer_image($id); |
| 1677 |
pagelayer_json_output($img); |
| 1678 |
|
| 1679 |
} |
| 1680 |
|
| 1681 |
// Get the postfolio posts |
| 1682 |
add_action('wp_ajax_pagelayer_fetch_posts', 'pagelayer_fetch_posts'); |
| 1683 |
function pagelayer_fetch_posts(){ |
| 1684 |
|
| 1685 |
// Some AJAX security |
| 1686 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1687 |
|
| 1688 |
// This ajax call is only used during post/page editing |
| 1689 |
if(!current_user_can('edit_posts')){ |
| 1690 |
echo __pl('no_permission'); |
| 1691 |
wp_die(); |
| 1692 |
} |
| 1693 |
|
| 1694 |
$sanitized_post = pagelayer_sanitize_posts_data($_POST); |
| 1695 |
echo pagelayer_widget_posts($sanitized_post); |
| 1696 |
|
| 1697 |
wp_die(); |
| 1698 |
} |
| 1699 |
|
| 1700 |
// Get the Posts |
| 1701 |
add_action('wp_ajax_pagelayer_posts_data', 'pagelayer_posts_data'); |
| 1702 |
function pagelayer_posts_data(){ |
| 1703 |
|
| 1704 |
// Some AJAX security |
| 1705 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1706 |
|
| 1707 |
// This ajax call is only used during post/page editing |
| 1708 |
if(!current_user_can('edit_posts')){ |
| 1709 |
echo __pl('no_permission'); |
| 1710 |
wp_die(); |
| 1711 |
} |
| 1712 |
|
| 1713 |
// Load shortcodes |
| 1714 |
pagelayer_load_shortcodes(); |
| 1715 |
|
| 1716 |
$sanitized_post = pagelayer_sanitize_posts_data($_POST, false); |
| 1717 |
echo pagelayer_posts($sanitized_post); |
| 1718 |
wp_die(); |
| 1719 |
} |
| 1720 |
|
| 1721 |
// Get the Posts |
| 1722 |
add_action('wp_ajax_pagelayer_archive_posts_data', 'pagelayer_archive_posts_data'); |
| 1723 |
function pagelayer_archive_posts_data(){ |
| 1724 |
|
| 1725 |
// Some AJAX security |
| 1726 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1727 |
|
| 1728 |
// Set excerpt length |
| 1729 |
if(!empty($_POST['atts']['exc_length'])){ |
| 1730 |
$exc_length = (int) $_POST['atts']['exc_length']; |
| 1731 |
add_filter( 'excerpt_length', function($length) use($exc_length){ |
| 1732 |
return $exc_length; |
| 1733 |
}, 999 ); |
| 1734 |
} |
| 1735 |
|
| 1736 |
// Load shortcodes |
| 1737 |
pagelayer_load_shortcodes(); |
| 1738 |
|
| 1739 |
foreach($_POST['atts'] as $k => $v){ |
| 1740 |
$v = pagelayer_maybe_implode($v); |
| 1741 |
$r[] = esc_html($k).'="'.pagelayer_escapeHTML($v).'"'; |
| 1742 |
} |
| 1743 |
|
| 1744 |
$string = implode(' ', $r); |
| 1745 |
if(preg_match('/\]/is', $string)){ |
| 1746 |
die('Hacking Attempt'); |
| 1747 |
} |
| 1748 |
|
| 1749 |
$sc = '[pl_archive_posts '.$string.'][/pl_archive_posts]'; |
| 1750 |
|
| 1751 |
echo pagelayer_the_content($sc); |
| 1752 |
wp_die(); |
| 1753 |
} |
| 1754 |
|
| 1755 |
// Handle Contact Form Data |
| 1756 |
add_action('wp_ajax_pagelayer_contact_submit', 'pagelayer_contact_submit'); |
| 1757 |
add_action('wp_ajax_nopriv_pagelayer_contact_submit', 'pagelayer_contact_submit' ); |
| 1758 |
function pagelayer_contact_submit(){ |
| 1759 |
|
| 1760 |
// Some AJAX security |
| 1761 |
check_ajax_referer('pagelayer_global', 'pagelayer_nonce'); |
| 1762 |
|
| 1763 |
// A filter to short circuit this contact form |
| 1764 |
$continue = apply_filters('pagelayer_contact_submit_start', 1); |
| 1765 |
if(empty($continue)){ |
| 1766 |
return false; |
| 1767 |
} |
| 1768 |
|
| 1769 |
$formdata = wp_unslash($_POST); |
| 1770 |
// NOTE : NEVER add anything to $formdata except $_POST vars |
| 1771 |
|
| 1772 |
if(isset($_POST['g-recaptcha-response']) ){ |
| 1773 |
|
| 1774 |
if(!pagelayer_captcha_verify()){ |
| 1775 |
$wp['failed'] = get_option('pagelayer_recaptcha_failed', __pl('cap_ver_fail')); |
| 1776 |
pagelayer_json_output($wp); |
| 1777 |
} |
| 1778 |
|
| 1779 |
unset($formdata['g-recaptcha-response']); |
| 1780 |
} |
| 1781 |
|
| 1782 |
// Unset the nonce |
| 1783 |
unset($formdata['pagelayer_nonce']); |
| 1784 |
|
| 1785 |
$to_mail = get_option('pagelayer_cf_to_email'); |
| 1786 |
$from_mail = get_option('pagelayer_cf_from_email'); |
| 1787 |
$subject = get_option('pagelayer_cf_subject'); |
| 1788 |
$additional_headers = get_option('pagelayer_cf_headers'); |
| 1789 |
$reply_to = ''; |
| 1790 |
$body = ''; |
| 1791 |
$headers = ''; |
| 1792 |
$custom_templ = array(); |
| 1793 |
$use_custom = false; |
| 1794 |
$use_html = false; |
| 1795 |
$pagelayer_id = sanitize_text_field($formdata['cfa-pagelayer-id']); |
| 1796 |
|
| 1797 |
if(isset($formdata['cfa-custom-template']) && !empty($formdata['cfa-post-id'])){ |
| 1798 |
$post_id = (int) $formdata['cfa-post-id']; |
| 1799 |
|
| 1800 |
if(!empty($post_id) && ( get_post_status( $post_id ) === 'publish' || current_user_can('publish_posts') )){ |
| 1801 |
$contact_array = get_post_meta($post_id, 'pagelayer_contact_templates', true); |
| 1802 |
|
| 1803 |
if(!empty($contact_array) && !empty($contact_array[$pagelayer_id])){ |
| 1804 |
$custom_templ = $contact_array[$pagelayer_id]; |
| 1805 |
$use_custom = true; |
| 1806 |
} |
| 1807 |
} |
| 1808 |
} |
| 1809 |
|
| 1810 |
if($use_custom && !empty($custom_templ)){ |
| 1811 |
|
| 1812 |
if(!empty($custom_templ['to_email'])){ |
| 1813 |
$to_mail = $custom_templ['to_email']; |
| 1814 |
} |
| 1815 |
|
| 1816 |
if(!empty($custom_templ['from_email'])){ |
| 1817 |
$from_mail = $custom_templ['from_email']; |
| 1818 |
} |
| 1819 |
|
| 1820 |
if(!empty($custom_templ['cont_subject'])){ |
| 1821 |
$subject = $custom_templ['cont_subject']; |
| 1822 |
} |
| 1823 |
|
| 1824 |
if(!empty($custom_templ['cont_header'])){ |
| 1825 |
$additional_headers = $custom_templ['cont_header']; |
| 1826 |
} |
| 1827 |
|
| 1828 |
if(!empty($custom_templ['cont_body'])){ |
| 1829 |
$body = $custom_templ['cont_body']; |
| 1830 |
} |
| 1831 |
|
| 1832 |
if(!empty($custom_templ['cont_use_html'])){ |
| 1833 |
$use_html = true; |
| 1834 |
$headers .= "Content-Type: text/html\n"; |
| 1835 |
} |
| 1836 |
} |
| 1837 |
|
| 1838 |
if(!empty($from_mail)){ |
| 1839 |
$headers .= "From: $from_mail\n"; |
| 1840 |
} |
| 1841 |
|
| 1842 |
if ( !empty($additional_headers) ) { |
| 1843 |
$headers .= $additional_headers . "\n"; |
| 1844 |
} |
| 1845 |
|
| 1846 |
if ( empty($body) ) { |
| 1847 |
|
| 1848 |
// Make the email content |
| 1849 |
foreach($formdata as $k => $i){ |
| 1850 |
|
| 1851 |
$not_allow = ['cfa-pagelayer-id', 'cfa-redirect', 'cfa-post-id', 'cfa-custom-template', 'pagelayer-contact-submit']; |
| 1852 |
if(in_array($k, $not_allow)){ |
| 1853 |
continue; |
| 1854 |
} |
| 1855 |
|
| 1856 |
$body .= sanitize_text_field($k)."\t : \t $".$k."\n"; |
| 1857 |
|
| 1858 |
} |
| 1859 |
|
| 1860 |
$body .= "\n\n --\n This e-mail was sent from a contact form (".get_home_url().")"; |
| 1861 |
|
| 1862 |
} |
| 1863 |
|
| 1864 |
// Add attachment |
| 1865 |
if(!empty($_FILES)){ |
| 1866 |
add_action('phpmailer_init', 'pagelayer_cf_email_attachment', 10, 1); |
| 1867 |
} |
| 1868 |
|
| 1869 |
$sanitized_data = array(); |
| 1870 |
|
| 1871 |
// If we are using HTML, then we should escape html as well |
| 1872 |
foreach($formdata as $k => $i){ |
| 1873 |
|
| 1874 |
if(is_array($i)){ |
| 1875 |
$i = pagelayer_flat_join($i); |
| 1876 |
} |
| 1877 |
|
| 1878 |
$i = pagelayer_esc_crlf($i); |
| 1879 |
|
| 1880 |
if(!empty($use_html)){ |
| 1881 |
$i = esc_html($i); |
| 1882 |
} |
| 1883 |
|
| 1884 |
// Sanitize text field |
| 1885 |
$i = sanitize_text_field($i); |
| 1886 |
|
| 1887 |
// Record a reply to if it is to be used |
| 1888 |
if(is_email($i) && empty($reply_to)){ |
| 1889 |
$reply_to = $i; |
| 1890 |
} |
| 1891 |
|
| 1892 |
$sanitized_data[$k] = $i; |
| 1893 |
} |
| 1894 |
|
| 1895 |
// Dow we have a reply to in the headers ? |
| 1896 |
if(!preg_match('/reply\-to/is', $headers) && !empty($reply_to)){ |
| 1897 |
$headers .= "Reply-To: $reply_to\n"; |
| 1898 |
} |
| 1899 |
|
| 1900 |
// Add Site Title as option in formdata |
| 1901 |
$sanitized_data['site_title'] = get_bloginfo( 'name' ); |
| 1902 |
|
| 1903 |
// Do parse a variables |
| 1904 |
$to_mail = pagelayer_replace_vars($to_mail, $sanitized_data, '$'); |
| 1905 |
$from_mail = pagelayer_replace_vars($from_mail, $sanitized_data, '$'); |
| 1906 |
$subject = pagelayer_replace_vars($subject, $sanitized_data, '$'); |
| 1907 |
$headers = pagelayer_replace_vars($headers, $sanitized_data, '$'); |
| 1908 |
$body = pagelayer_replace_vars($body, $sanitized_data, '$'); |
| 1909 |
|
| 1910 |
if ( $use_html && ! preg_match( '%<html[>\s].*</html>%is', $body ) ) { |
| 1911 |
$header = '<!doctype html> |
| 1912 |
<html xmlns="http://www.w3.org/1999/xhtml"> |
| 1913 |
<head><title>' . esc_html( $subject ) . '</title></head> |
| 1914 |
<body>'; |
| 1915 |
|
| 1916 |
$footer = '</body></html>'; |
| 1917 |
|
| 1918 |
$body = $header . wpautop( $body ) . $footer; |
| 1919 |
} |
| 1920 |
|
| 1921 |
$to_mail = apply_filters('pagelayer_contact_send', $to_mail, $sanitized_data); |
| 1922 |
|
| 1923 |
// Send the email |
| 1924 |
if(!empty($to_mail)){ |
| 1925 |
$r = wp_mail( $to_mail, $subject, $body, $headers ); |
| 1926 |
} |
| 1927 |
|
| 1928 |
if($r == TRUE){ |
| 1929 |
$wp['success'] = pagelayer_get_option( 'pagelayer_cf_success' ); |
| 1930 |
}else{ |
| 1931 |
$wp['failed'] = pagelayer_get_option( 'pagelayer_cf_failed' ); |
| 1932 |
} |
| 1933 |
|
| 1934 |
pagelayer_json_output($wp); |
| 1935 |
|
| 1936 |
} |
| 1937 |
|
| 1938 |
// Handle Login Submit |
| 1939 |
add_action('wp_ajax_pagelayer_login_submit', 'pagelayer_login_submit'); |
| 1940 |
add_action('wp_ajax_nopriv_pagelayer_login_submit', 'pagelayer_login_submit'); |
| 1941 |
function pagelayer_login_submit(){ |
| 1942 |
|
| 1943 |
// Some AJAX security |
| 1944 |
check_ajax_referer('pagelayer_global', 'pagelayer_nonce'); |
| 1945 |
|
| 1946 |
$creds = array(); |
| 1947 |
$creds['user_login'] = $_REQUEST['username']; |
| 1948 |
$creds['user_password'] = $_REQUEST['password']; |
| 1949 |
$creds['remember'] = $_REQUEST['remember_me']; |
| 1950 |
|
| 1951 |
// Login the user |
| 1952 |
$user = wp_signon( $creds, false ); |
| 1953 |
|
| 1954 |
if ( is_wp_error($user) ){ |
| 1955 |
$data['error'] = $user->get_error_message(); |
| 1956 |
}else{ |
| 1957 |
|
| 1958 |
// If After logout URL, then save |
| 1959 |
if(!empty($_REQUEST['logout_url'])){ |
| 1960 |
update_user_option($user->ID, 'pagelayer_logout_url', sanitize_url($_REQUEST['logout_url'])); |
| 1961 |
} |
| 1962 |
|
| 1963 |
$data['redirect'] = (empty($_REQUEST['login_url']) ? '' : sanitize_url($_REQUEST['login_url'])); |
| 1964 |
$data['error'] = ''; |
| 1965 |
} |
| 1966 |
|
| 1967 |
pagelayer_json_output($data); |
| 1968 |
|
| 1969 |
} |
| 1970 |
|
| 1971 |
// Get Page List for SiteMap |
| 1972 |
add_action('wp_ajax_pagelayer_get_pages_list', 'pagelayer_get_pages_list'); |
| 1973 |
function pagelayer_get_pages_list(){ |
| 1974 |
|
| 1975 |
// Some AJAX security |
| 1976 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 1977 |
|
| 1978 |
if(!current_user_can('edit_posts')){ |
| 1979 |
echo __pl('no_permission'); |
| 1980 |
wp_die(); |
| 1981 |
} |
| 1982 |
|
| 1983 |
$args = array( |
| 1984 |
'post_type' => sanitize_text_field($_POST['type']), |
| 1985 |
'orderby' => sanitize_text_field($_POST['post_order']), |
| 1986 |
'order' => sanitize_text_field($_POST['order']), |
| 1987 |
'hierarchical' => (empty($_POST['hier']) || $_POST['hier'] == null ? '' : sanitize_text_field($_POST['hier'])), |
| 1988 |
'number' => (empty($_POST['depth']) || $_POST['depth'] == null ? '' : sanitize_text_field($_POST['depth'])), |
| 1989 |
'posts_per_page' => -1, |
| 1990 |
); |
| 1991 |
|
| 1992 |
$option = '<ul>'; |
| 1993 |
$pages = new WP_Query($args); |
| 1994 |
$posts = $pages->posts; |
| 1995 |
foreach ( $posts as $page ) { |
| 1996 |
$option .= '<li class="pagelayer-sitemap-list-item" data-postID="'.$page->ID.'"><a class="pagelayer-ele-link" href="'.$page->guid.'">'.$page->post_name.'</a></li>'; |
| 1997 |
} |
| 1998 |
$option .= '</ul>'; |
| 1999 |
|
| 2000 |
echo $option; |
| 2001 |
|
| 2002 |
wp_die(); |
| 2003 |
} |
| 2004 |
|
| 2005 |
// Get the data for template |
| 2006 |
add_action('wp_ajax_pagelayer_search_ids', 'pagelayer_search_ids'); |
| 2007 |
function pagelayer_search_ids() { |
| 2008 |
|
| 2009 |
// Some AJAX security |
| 2010 |
check_ajax_referer('pagelayer_builder', 'pagelayer_nonce'); |
| 2011 |
|
| 2012 |
if ( empty( $_POST['filter_type'] ) || empty( $_POST['search'] ) ) { |
| 2013 |
wp_die(); |
| 2014 |
} |
| 2015 |
|
| 2016 |
$sel_opt = ''; |
| 2017 |
|
| 2018 |
switch ( $_POST['filter_type'] ) { |
| 2019 |
case 'taxonomy': |
| 2020 |
$query_params = [ |
| 2021 |
'taxonomy' => $_POST['object_type'], |
| 2022 |
'search' => $_POST['search'], |
| 2023 |
'hide_empty' => false, |
| 2024 |
]; |
| 2025 |
|
| 2026 |
$terms = get_terms( $query_params ); |
| 2027 |
|
| 2028 |
global $wp_taxonomies; |
| 2029 |
|
| 2030 |
foreach ( $terms as $term ) { |
| 2031 |
$sel_opt .= '<span class="pagelayer-temp-search-sel-span" value="'. $term->term_taxonomy_id .'">'. $term->name .'</span>'; |
| 2032 |
} |
| 2033 |
|
| 2034 |
break; |
| 2035 |
|
| 2036 |
case 'post': |
| 2037 |
$query_params = [ |
| 2038 |
'post_type' => $_POST['object_type'], //$this->extract_post_type( $data ), |
| 2039 |
's' => $_POST['search'], |
| 2040 |
'posts_per_page' => -1, |
| 2041 |
]; |
| 2042 |
|
| 2043 |
if ( 'attachment' === $query_params['post_type'] ) { |
| 2044 |
$query_params['post_status'] = 'inherit'; |
| 2045 |
} |
| 2046 |
|
| 2047 |
$query = new \WP_Query( $query_params ); |
| 2048 |
|
| 2049 |
foreach ( $query->posts as $post ) { |
| 2050 |
$sel_opt .= '<span class="pagelayer-temp-search-sel-span" value="'. $post->ID .'">'. $post->post_title .'</span>'; |
| 2051 |
} |
| 2052 |
break; |
| 2053 |
|
| 2054 |
case 'author': |
| 2055 |
$query_params = [ |
| 2056 |
'capability' => array( 'edit_posts' ), |
| 2057 |
'fields' => [ |
| 2058 |
'ID', |
| 2059 |
'display_name', |
| 2060 |
], |
| 2061 |
'search' => '*' . $_POST["search"] . '*', |
| 2062 |
'search_columns' => [ |
| 2063 |
'user_login', |
| 2064 |
'user_nicename', |
| 2065 |
], |
| 2066 |
]; |
| 2067 |
|
| 2068 |
// Capability queries were only introduced in WP 5.9. |
| 2069 |
if( version_compare( $GLOBALS['wp_version'], '5.9-alpha', '<' ) ){ |
| 2070 |
$args['who'] = 'authors'; |
| 2071 |
unset( $args['capability'] ); |
| 2072 |
} |
| 2073 |
|
| 2074 |
$user_query = new \WP_User_Query( $query_params ); |
| 2075 |
|
| 2076 |
foreach ( $user_query->get_results() as $author ) { |
| 2077 |
$sel_opt .= '<span class="pagelayer-temp-search-sel-span" value="'. $author->ID .'">'. $author->display_name .'</span>'; |
| 2078 |
} |
| 2079 |
break; |
| 2080 |
|
| 2081 |
/* case 'menu': |
| 2082 |
|
| 2083 |
$menuItems = wp_get_nav_menu_items( (int)$_POST['object_type']); |
| 2084 |
|
| 2085 |
foreach ( $menuItems as $item ) { |
| 2086 |
|
| 2087 |
if($item -> menu_item_parent !=0 ){ |
| 2088 |
continue; |
| 2089 |
} |
| 2090 |
$sel_opt .= '<span class="pagelayer-temp-search-sel-span" value="'. $item -> ID .'">'. $item -> title.'</span>'; |
| 2091 |
} |
| 2092 |
|
| 2093 |
break; */ |
| 2094 |
|
| 2095 |
default: |
| 2096 |
$sel_opt = 'Result Not Found'; |
| 2097 |
} |
| 2098 |
|
| 2099 |
if(!empty($sel_opt)){ |
| 2100 |
echo $sel_opt; |
| 2101 |
}else{ |
| 2102 |
echo 'Result Not Found'; |
| 2103 |
} |
| 2104 |
|
| 2105 |
wp_die(); |
| 2106 |
} |
| 2107 |
|
| 2108 |
// Save the post data from pagelayer setting page |
| 2109 |
add_action('wp_ajax_pagelayer_save_template', 'pagelayer_save_template'); |
| 2110 |
function pagelayer_save_template() { |
| 2111 |
|
| 2112 |
// Some AJAX security |
| 2113 |
check_ajax_referer('pagelayer_builder', 'pagelayer_nonce'); |
| 2114 |
|
| 2115 |
$done = []; |
| 2116 |
|
| 2117 |
$post_id = (int) $_GET['postID']; |
| 2118 |
|
| 2119 |
// Are you allowed to edit ? |
| 2120 |
if(!empty($post_id) && !pagelayer_user_can_edit($post_id)){ |
| 2121 |
$done['error'][] = __pl('no_permission'); |
| 2122 |
pagelayer_json_output($done); |
| 2123 |
} |
| 2124 |
|
| 2125 |
// We need to create the post |
| 2126 |
if(empty($post_id)){ |
| 2127 |
|
| 2128 |
if (!current_user_can('edit_posts')) { |
| 2129 |
$done['error'] = __pl('access_denied'); |
| 2130 |
pagelayer_json_output($done); |
| 2131 |
} |
| 2132 |
|
| 2133 |
// Get the template type |
| 2134 |
if(empty($_POST['pagelayer_template_type'])){ |
| 2135 |
$done['error'] = __pl('temp_error_type'); |
| 2136 |
pagelayer_json_output($done); |
| 2137 |
} |
| 2138 |
|
| 2139 |
$ret = wp_insert_post([ |
| 2140 |
'post_title' => $_POST['pagelayer_lib_title'], |
| 2141 |
'post_type' => 'pagelayer-template', |
| 2142 |
'post_status' => 'publish', |
| 2143 |
'comment_status' => 'closed', |
| 2144 |
'ping_status' => 'closed' |
| 2145 |
]); |
| 2146 |
|
| 2147 |
// An error occured |
| 2148 |
if(is_wp_error($ret)){ |
| 2149 |
$done['error'] = __pl('temp_error').' : '.$ret->get_error_message(); |
| 2150 |
pagelayer_json_output($done); |
| 2151 |
} |
| 2152 |
|
| 2153 |
$post_id = $ret; |
| 2154 |
$done['id'] = $post_id; |
| 2155 |
|
| 2156 |
// Save our template type |
| 2157 |
$ret = update_post_meta($post_id, 'pagelayer_template_type', $_POST['pagelayer_template_type']); |
| 2158 |
|
| 2159 |
} |
| 2160 |
|
| 2161 |
// The ID in consideration |
| 2162 |
$done['id'] = $post_id; |
| 2163 |
|
| 2164 |
// Check if the post title in not empty |
| 2165 |
if(!empty($_POST['pagelayer_lib_title'])){ |
| 2166 |
|
| 2167 |
$post = array( |
| 2168 |
'ID' => $post_id, |
| 2169 |
'post_title' => $_POST['pagelayer_lib_title'], |
| 2170 |
); |
| 2171 |
|
| 2172 |
// Update the post into the database |
| 2173 |
$ret = wp_update_post($post); |
| 2174 |
|
| 2175 |
} |
| 2176 |
|
| 2177 |
// Save template library display conditions |
| 2178 |
$condi_array = array(); |
| 2179 |
$condi_len = count($_POST['pagelayer_condition_type']); |
| 2180 |
if($_POST['pagelayer_template_type'] != 'section'){ |
| 2181 |
for( $i =0; $i < $condi_len; $i++ ){ |
| 2182 |
$condi_array[$i] = array( |
| 2183 |
'type' => $_POST['pagelayer_condition_type'][$i], |
| 2184 |
'template' => $_POST['pagelayer_condition_name'][$i], |
| 2185 |
'sub_template' => $_POST['pagelayer_condition_sub_template'][$i], |
| 2186 |
'id' => $_POST['pagelayer_condition_id'][$i], |
| 2187 |
); |
| 2188 |
} |
| 2189 |
} |
| 2190 |
//print_r($condi_array); |
| 2191 |
|
| 2192 |
$ret = update_post_meta($post_id, 'pagelayer_template_conditions', $condi_array); |
| 2193 |
|
| 2194 |
if(is_wp_error($post_id)){ |
| 2195 |
$done['error'] = __pl('temp_error').' : '.$ret->get_error_message(); |
| 2196 |
}else{ |
| 2197 |
$done['success'] = __pl('temp_update_success'); |
| 2198 |
} |
| 2199 |
|
| 2200 |
pagelayer_json_output($done); |
| 2201 |
|
| 2202 |
} |
| 2203 |
|
| 2204 |
// Products Categories Handler |
| 2205 |
add_action('wp_ajax_pagelayer_product_categories', 'pagelayer_product_categories'); |
| 2206 |
function pagelayer_product_categories(){ |
| 2207 |
|
| 2208 |
// Some AJAX security |
| 2209 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 2210 |
|
| 2211 |
$attributes = ''; |
| 2212 |
$attributes .= ' number="'. $_POST['atts']['number'] .'" '; |
| 2213 |
$attributes .= ' columns="'. $_POST['atts']['columns'] .'" '; |
| 2214 |
$attributes .= ' hide_empty="'. (!empty($_POST['atts']['hide_empty']) ? 1 : 0) .'" '; |
| 2215 |
$attributes .= ' orderby="'. $_POST['atts']['nuorderbymber'] .'" '; |
| 2216 |
$attributes .= ' order="'. $_POST['atts']['order'] .'" '; |
| 2217 |
|
| 2218 |
if ( 'by_id' === $_POST['atts']['source'] ) { |
| 2219 |
$attributes .= ' ids="'. $_POST['atts']['by_id'] .'" '; |
| 2220 |
} elseif ( 'by_parent' === $_POST['atts']['source'] ) { |
| 2221 |
$attributes .= ' parent="'. $_POST['atts']['parent'] .'" '; |
| 2222 |
} elseif ( 'current_subcategories' === $_POST['atts']['source'] ) { |
| 2223 |
$attributes .= ' parent="'. get_queried_object_id() .'" '; |
| 2224 |
} |
| 2225 |
|
| 2226 |
$shortcode = '[product_categories '. $attributes .']'; |
| 2227 |
|
| 2228 |
// do_shortcode the shortcode |
| 2229 |
echo pagelayer_the_content($shortcode); |
| 2230 |
|
| 2231 |
wp_die(); |
| 2232 |
} |
| 2233 |
|
| 2234 |
// Products Categories Handler |
| 2235 |
add_action('wp_ajax_pagelayer_products_ajax', 'pagelayer_products_ajax'); |
| 2236 |
function pagelayer_products_ajax(){ |
| 2237 |
|
| 2238 |
// Some AJAX security |
| 2239 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 2240 |
|
| 2241 |
if ( WC()->session ) { |
| 2242 |
wc_print_notices(); |
| 2243 |
} |
| 2244 |
|
| 2245 |
$no_found = $_POST['atts']['no_found']; |
| 2246 |
|
| 2247 |
$attributes = ''; |
| 2248 |
$type = $_POST['atts']['source']; |
| 2249 |
$attributes .= ' columns="'. $_POST['atts']['columns'] .'" '; |
| 2250 |
$attributes .= ' rows="'. $_POST['atts']['rows'] .'" '; |
| 2251 |
$attributes .= ' paginate="'. (!empty($_POST['atts']['paginate']) ? true : false) .'" '; |
| 2252 |
$attributes .= ' orderby="'. $_POST['atts']['orderby'] .'" '; |
| 2253 |
$attributes .= ' order="'. $_POST['atts']['order'] .'" '; |
| 2254 |
$attributes .= ' cache="false" '; |
| 2255 |
|
| 2256 |
// Hide the catalog order |
| 2257 |
if( empty($_POST['atts']['allow_order']) ){ |
| 2258 |
remove_action( 'woocommerce_before_shop_loop', 'woocommerce_catalog_ordering', 30 ); |
| 2259 |
} |
| 2260 |
|
| 2261 |
// Hide the result count |
| 2262 |
if( empty($_POST['atts']['show_result']) ){ |
| 2263 |
remove_action( 'woocommerce_before_shop_loop', 'woocommerce_result_count', 20 ); |
| 2264 |
} |
| 2265 |
|
| 2266 |
if( $type == 'by_id' ){ |
| 2267 |
$type = 'products'; |
| 2268 |
$attributes .= ' ids="'. (!empty($_POST['atts']['ids']) ? $_POST['atts']['ids'] : '') .'" '; |
| 2269 |
}elseif( $type == 'pagelayer_current_query' ){ |
| 2270 |
|
| 2271 |
$atts['paginate'] = (!empty($_POST['atts']['paginate']) ? true : false); |
| 2272 |
$atts['cache'] = false; |
| 2273 |
|
| 2274 |
$type = 'pagelayer_current_query'; |
| 2275 |
|
| 2276 |
// Set the current query |
| 2277 |
add_action( 'woocommerce_shortcode_products_query', 'pagelayer_shortcode_current_query', 10, 10); |
| 2278 |
|
| 2279 |
// If product not found |
| 2280 |
add_action( "woocommerce_shortcode_{$type}_loop_no_results", function ($attributes) use ($no_found){ |
| 2281 |
echo '<div class="pagelayer-product-no-found">'.$no_found.'</div>'; |
| 2282 |
} ); |
| 2283 |
|
| 2284 |
// Get the products list |
| 2285 |
$shortcode = new WC_Shortcode_Products( $atts, $type ); |
| 2286 |
|
| 2287 |
echo $shortcode->get_content(); |
| 2288 |
return true; |
| 2289 |
} |
| 2290 |
|
| 2291 |
$shortcode = '['.$type.' '. $attributes .']'; |
| 2292 |
|
| 2293 |
$content = pagelayer_the_content($shortcode); |
| 2294 |
|
| 2295 |
// If product not found |
| 2296 |
if('<div class="woocommerce columns-'.$_POST['atts']['columns'] .' "></div>' == $content){ |
| 2297 |
$content = '<div class="pagelayer-product-no-found">'. $no_found .'</div>'; |
| 2298 |
} |
| 2299 |
|
| 2300 |
echo $content; |
| 2301 |
|
| 2302 |
wp_die(); |
| 2303 |
} |
| 2304 |
|
| 2305 |
// Markdown Handler |
| 2306 |
add_action('wp_ajax_pagelayer_handle_markdown', 'pagelayer_handle_markdown'); |
| 2307 |
function pagelayer_handle_markdown(){ |
| 2308 |
|
| 2309 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 2310 |
|
| 2311 |
if(!defined('PAGELAYER_PRO_VERSION')){ |
| 2312 |
wp_send_json_error(['message' => __('Markdown feature requires Pagelayer Pro.', 'pagelayer')]); |
| 2313 |
return; |
| 2314 |
} |
| 2315 |
|
| 2316 |
include_once(PAGELAYER_PRO_DIR.'/main/premium_functions.php'); |
| 2317 |
|
| 2318 |
$raw_atts = isset($_POST['data']) && is_array($_POST['data']) ? wp_unslash($_POST['data']) : []; |
| 2319 |
$atts = []; |
| 2320 |
|
| 2321 |
foreach($raw_atts as $key => $value){ |
| 2322 |
$clean_key = sanitize_key($key); |
| 2323 |
|
| 2324 |
// Check for invalid UTF-8 to prevent database errors |
| 2325 |
if(in_array($clean_key, ['markdown_text_file', 'markdown_text_url', 'active_markdown_text'])){ |
| 2326 |
$atts[$clean_key] = wp_check_invalid_utf8($value); |
| 2327 |
} else{ |
| 2328 |
$atts[$clean_key] = sanitize_text_field($value); |
| 2329 |
} |
| 2330 |
} |
| 2331 |
|
| 2332 |
$fetched = pagelayer_get_markdown_content($atts); |
| 2333 |
$current_text = $fetched['text']; |
| 2334 |
$default_text = __pl('Select a Markdown file or enter a URL to load content.'); |
| 2335 |
|
| 2336 |
// Compile HTML |
| 2337 |
$html = ''; |
| 2338 |
if(!empty($fetched['is_error'])){ |
| 2339 |
$html = '<div class="pagelayer-markdown-error">' . esc_html($current_text) . '</div>'; |
| 2340 |
} else if($current_text === $default_text){ |
| 2341 |
$html = '<div class="pagelayer-markdown-placeholder">' . $default_text . '</div>'; |
| 2342 |
} else if(function_exists('pagelayer_markdown_to_html')){ |
| 2343 |
$html = pagelayer_markdown_to_html($current_text); |
| 2344 |
} |
| 2345 |
|
| 2346 |
$wp['html'] = wp_kses_post($html); |
| 2347 |
$wp['raw_text'] = $current_text; |
| 2348 |
$wp['is_error'] = !empty($fetched['is_error']); |
| 2349 |
|
| 2350 |
pagelayer_json_output($wp); |
| 2351 |
|
| 2352 |
wp_die(); |
| 2353 |
} |
| 2354 |
|
| 2355 |
// Get Taxamony List for SiteMap |
| 2356 |
add_action('wp_ajax_pagelayer_get_taxonomy_list', 'pagelayer_get_taxonomy_list'); |
| 2357 |
function pagelayer_get_taxonomy_list(){ |
| 2358 |
|
| 2359 |
// Some AJAX security |
| 2360 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 2361 |
|
| 2362 |
if(!current_user_can('edit_posts')){ |
| 2363 |
echo __pl('no_permission'); |
| 2364 |
wp_die(); |
| 2365 |
} |
| 2366 |
|
| 2367 |
$args = array( |
| 2368 |
'title_li' => 0, |
| 2369 |
'orderby' => $_POST['post_order'], |
| 2370 |
'order' => $_POST['order'], |
| 2371 |
'style' => '', |
| 2372 |
'hide_empty' => $_POST['empty'], |
| 2373 |
'echo' => false, |
| 2374 |
'hierarchical' => (empty($_POST['hier']) || $_POST['hier'] == null ? '' : $_POST['hier']), |
| 2375 |
'taxonomy' => $_POST['type'], |
| 2376 |
'depth' => (empty($_POST['depth']) || $_POST['depth'] == null ? '' : $_POST['depth']), |
| 2377 |
); |
| 2378 |
|
| 2379 |
$taxonomies = get_categories( $args ); |
| 2380 |
|
| 2381 |
$option = '<ul>'; |
| 2382 |
foreach ( $taxonomies as $taxonomy ) { |
| 2383 |
$option .= '<li class="pagelayer-sitemap-list-item" data-postID="'.$taxonomy->term_id.'"><a class="pagelayer-ele-link" href="'.get_term_link($taxonomy->term_id).'">'.$taxonomy->name.'</a></li>'; |
| 2384 |
} |
| 2385 |
$option .= '</ul>'; |
| 2386 |
|
| 2387 |
echo $option; |
| 2388 |
wp_die(); |
| 2389 |
} |
| 2390 |
|
| 2391 |
// Export the template |
| 2392 |
add_action('wp_ajax_pagelayer_export_template', 'pagelayer_export_template'); |
| 2393 |
function pagelayer_export_template(){ |
| 2394 |
|
| 2395 |
global $pagelayer; |
| 2396 |
|
| 2397 |
// Some AJAX security |
| 2398 |
check_ajax_referer('pagelayer_builder', 'pagelayer_nonce'); |
| 2399 |
|
| 2400 |
$done = []; |
| 2401 |
|
| 2402 |
if(!current_user_can('edit_theme_options')){ |
| 2403 |
$done['error'][] = __pl('no_permission'); |
| 2404 |
pagelayer_json_output($done); |
| 2405 |
} |
| 2406 |
|
| 2407 |
// Load the templates |
| 2408 |
pagelayer_builder_load_templates(); |
| 2409 |
|
| 2410 |
if(empty($pagelayer->templates)){ |
| 2411 |
$done['error'] = __pl('temp_export_empty'); |
| 2412 |
pagelayer_json_output($done); |
| 2413 |
} |
| 2414 |
|
| 2415 |
// Load Shortcodes |
| 2416 |
pagelayer_load_shortcodes(); |
| 2417 |
|
| 2418 |
// Get the active theme |
| 2419 |
$theme_dir = get_stylesheet_directory(); |
| 2420 |
$conf = []; |
| 2421 |
|
| 2422 |
$pagelayer->export_mode = 1; |
| 2423 |
|
| 2424 |
// Write the files |
| 2425 |
foreach($pagelayer->templates as $k => $v){ |
| 2426 |
|
| 2427 |
// Are there specific templates to export |
| 2428 |
if(!empty($_POST['templates'])){ |
| 2429 |
if(!isset($_POST['templates'][$v->ID])){ |
| 2430 |
continue; |
| 2431 |
} |
| 2432 |
} |
| 2433 |
|
| 2434 |
// Only blocks allowed |
| 2435 |
if(!has_blocks($v->post_content) && !empty($v->post_content)){ |
| 2436 |
$done['error'] = 'The pagelayer template '.$v->ID.' has Shortcodes which is not allowed for export !'; |
| 2437 |
pagelayer_json_output($done); |
| 2438 |
} |
| 2439 |
|
| 2440 |
$v->post_name = (empty($v->post_name) && $v->post_status == 'draft') ? sanitize_title($v->post_title).'-draft' : $v->post_name; |
| 2441 |
|
| 2442 |
// Write the content |
| 2443 |
file_put_contents($theme_dir.'/'.$v->post_name.'.pgl', pagelayer_export_content($v->post_content)); |
| 2444 |
$conf[$v->post_name] = [ |
| 2445 |
'type' => get_post_meta($v->ID, 'pagelayer_template_type', true), |
| 2446 |
'title' => $v->post_title, |
| 2447 |
'conditions' => get_post_meta($v->ID, 'pagelayer_template_conditions', true), |
| 2448 |
]; |
| 2449 |
} |
| 2450 |
|
| 2451 |
// Write the config |
| 2452 |
file_put_contents($theme_dir.'/pagelayer.conf', json_encode($conf, JSON_PRETTY_PRINT)); |
| 2453 |
|
| 2454 |
$conf = []; |
| 2455 |
|
| 2456 |
// Load the other posts |
| 2457 |
foreach($pagelayer->settings['post_types'] as $type){ |
| 2458 |
|
| 2459 |
// Anything to export for users ? |
| 2460 |
if(!empty($_POST[$type]) && is_array($_POST[$type])){ |
| 2461 |
|
| 2462 |
mkdir($theme_dir.'/data/'); |
| 2463 |
mkdir($theme_dir.'/data/'.$type); |
| 2464 |
|
| 2465 |
$pids = []; |
| 2466 |
|
| 2467 |
foreach($_POST[$type] as $k => $v){ |
| 2468 |
$pids[] = (int) $k; |
| 2469 |
} |
| 2470 |
|
| 2471 |
// Load the type |
| 2472 |
$_query = new WP_Query([ |
| 2473 |
'post_type' => $type, |
| 2474 |
'status' => 'publish', |
| 2475 |
'post__in' => $pids, |
| 2476 |
'posts_per_page' => -1, |
| 2477 |
]); |
| 2478 |
|
| 2479 |
$posts = $_query->posts; |
| 2480 |
|
| 2481 |
// Write the files |
| 2482 |
foreach($posts as $k => $v){ |
| 2483 |
|
| 2484 |
// Only blocks allowed |
| 2485 |
if(!has_blocks($v->post_content) && !empty($v->post_content)){ |
| 2486 |
$done['error'] = 'The '.$type.' '.$v->ID.' has Shortcodes which is not allowed for export !'; |
| 2487 |
pagelayer_json_output($done); |
| 2488 |
} |
| 2489 |
|
| 2490 |
$v->post_name = (empty($v->post_name) && $v->post_status == 'draft') ? sanitize_title($v->post_title).'-draft' : $v->post_name; |
| 2491 |
|
| 2492 |
file_put_contents($theme_dir.'/data/'.$type.'/'.$v->post_name, pagelayer_export_content($v->post_content)); |
| 2493 |
unset($v->post_content); |
| 2494 |
|
| 2495 |
$meta = get_post_meta($v->ID); |
| 2496 |
$meta = array_combine(array_keys($meta), array_column($meta, 0)); |
| 2497 |
|
| 2498 |
// Export media |
| 2499 |
if(!empty($meta['_thumbnail_id'])){ |
| 2500 |
|
| 2501 |
$file = pagelayer_export_media_files($meta['_thumbnail_id'], $exp_img_url); |
| 2502 |
|
| 2503 |
// Did it export ? |
| 2504 |
if(!empty($file)){ |
| 2505 |
$meta['_thumbnail_id'] = $exp_img_url; |
| 2506 |
} |
| 2507 |
|
| 2508 |
} |
| 2509 |
|
| 2510 |
// Also put the meta |
| 2511 |
file_put_contents($theme_dir.'/data/'.$type.'/'.$v->post_name.'.meta', json_encode($meta, JSON_PRETTY_PRINT)); |
| 2512 |
|
| 2513 |
//Export taxonomies in post |
| 2514 |
$taxonomies = get_object_taxonomies( $v->post_type, 'objects' ); |
| 2515 |
$post_taxonomies = wp_filter_object_list( $taxonomies, [ |
| 2516 |
'public' => true, |
| 2517 |
'show_in_nav_menus' => true, |
| 2518 |
] ); |
| 2519 |
|
| 2520 |
foreach( $post_taxonomies as $slug => $object ){ |
| 2521 |
|
| 2522 |
if(empty($v->taxonomies) || !is_array($v->taxonomies)){ |
| 2523 |
$v->taxonomies = array(); |
| 2524 |
} |
| 2525 |
|
| 2526 |
$tax_name = $object->name; |
| 2527 |
$the_terms = get_the_terms($v->ID, $tax_name); |
| 2528 |
$v->taxonomies[$tax_name] = ''; |
| 2529 |
|
| 2530 |
if(!empty($the_terms)){ |
| 2531 |
$v->taxonomies[$tax_name] = implode(',', array_column($the_terms, 'term_id')); |
| 2532 |
} |
| 2533 |
} |
| 2534 |
|
| 2535 |
$conf[$type][$v->post_name] = $v; |
| 2536 |
|
| 2537 |
do_action('pagelayer_'.$type.'_exported', $v, $theme_dir); |
| 2538 |
|
| 2539 |
} |
| 2540 |
|
| 2541 |
ksort($conf[$type]); |
| 2542 |
|
| 2543 |
} |
| 2544 |
|
| 2545 |
} |
| 2546 |
|
| 2547 |
// Export menus |
| 2548 |
if(!empty($pagelayer->export_menus) && is_array($pagelayer->export_menus)){ |
| 2549 |
|
| 2550 |
mkdir($theme_dir.'/data/menus'); |
| 2551 |
|
| 2552 |
foreach($pagelayer->export_menus as $k => $v){ |
| 2553 |
|
| 2554 |
$menu = (int) $k; |
| 2555 |
$menu = wp_get_nav_menu_object( $menu ); |
| 2556 |
|
| 2557 |
if(empty($menu)){ |
| 2558 |
$done['error'] = 'Could not export menu ID - '.$k; |
| 2559 |
continue; |
| 2560 |
} |
| 2561 |
|
| 2562 |
// Menu Items |
| 2563 |
$menu_items = wp_get_nav_menu_items( $menu->term_id ); |
| 2564 |
$data = []; |
| 2565 |
|
| 2566 |
if(is_array($menu_items) && !empty($menu_items)){ |
| 2567 |
foreach($menu_items as $kk => $singlenav){ |
| 2568 |
//$navmetas = get_post_meta($singlenav->ID); |
| 2569 |
//$navmetas = array_combine(array_keys($navmetas), array_column($navmetas, 0)); |
| 2570 |
$data[$kk]['post'] = $singlenav; |
| 2571 |
$navmetas = array(); |
| 2572 |
|
| 2573 |
$pl_content = get_post_meta($singlenav->ID, '_pagelayer_content', true); |
| 2574 |
if(!empty($pl_content)){ |
| 2575 |
$navmetas['_pagelayer_content'] = pagelayer_export_content($pl_content); |
| 2576 |
} |
| 2577 |
|
| 2578 |
$data[$kk]['post_metas'] = $navmetas; |
| 2579 |
} |
| 2580 |
} |
| 2581 |
|
| 2582 |
// Also put the meta |
| 2583 |
file_put_contents($theme_dir.'/data/menus/'.$menu->slug, json_encode($data, JSON_PRETTY_PRINT)); |
| 2584 |
|
| 2585 |
$conf['menus'][$menu->slug] = $menu; |
| 2586 |
|
| 2587 |
do_action('pagelayer_menus_exported', $v, $theme_dir); |
| 2588 |
|
| 2589 |
} |
| 2590 |
|
| 2591 |
} |
| 2592 |
|
| 2593 |
// Export the settings |
| 2594 |
$settings = ['pagelayer_content_width', 'pagelayer_body_font', 'pagelayer_tablet_breakpoint', 'pagelayer_mobile_breakpoint', 'pagelayer_header_code','pagelayer_body_open_code', 'pagelayer_footer_code', 'pagelayer_sidebar', 'page_for_posts', 'pagelayer_global_fonts', 'pagelayer_global_colors']; |
| 2595 |
|
| 2596 |
foreach($settings as $v){ |
| 2597 |
|
| 2598 |
$vv = get_option($v); |
| 2599 |
|
| 2600 |
if($vv){ |
| 2601 |
$conf['conf'][$v] = $vv; |
| 2602 |
} |
| 2603 |
|
| 2604 |
} |
| 2605 |
|
| 2606 |
// Load CSS settings |
| 2607 |
foreach($pagelayer->css_settings as $k => $params){ |
| 2608 |
foreach($pagelayer->screens as $sk => $sv){ |
| 2609 |
$suffix = (!empty($sv) ? '_'.$sv : ''); |
| 2610 |
$setting = empty($params['key']) ? 'pagelayer_'.$k.'_css' : $params['key']; |
| 2611 |
$tmp = get_option($setting.$suffix); |
| 2612 |
if(!empty($tmp)){ |
| 2613 |
$conf['conf'][$setting.$suffix] = $tmp; |
| 2614 |
} |
| 2615 |
} |
| 2616 |
} |
| 2617 |
|
| 2618 |
// Export all the taxonomies |
| 2619 |
$post_types = pagelayer_get_public_post_types(); |
| 2620 |
|
| 2621 |
// Export all the Post Type CSS Settings |
| 2622 |
foreach ( $post_types as $pt_slug => $type ) { |
| 2623 |
|
| 2624 |
if ( $pt_slug == 'attachment' ) { |
| 2625 |
continue; |
| 2626 |
} |
| 2627 |
|
| 2628 |
foreach($pagelayer->css_settings as $k => $params){ |
| 2629 |
foreach($pagelayer->screens as $sk => $sv){ |
| 2630 |
$suffix = (!empty($sv) ? '_'.$sv : ''); |
| 2631 |
$setting = empty($params['key']) ? 'pagelayer_'.$k.'_css_'.$pt_slug : $params['key'].'_'.$pt_slug; |
| 2632 |
$tmp = get_option($setting.$suffix); |
| 2633 |
|
| 2634 |
if(!empty($tmp)){ |
| 2635 |
$conf['conf'][$setting.$suffix] = $tmp; |
| 2636 |
} |
| 2637 |
} |
| 2638 |
} |
| 2639 |
} |
| 2640 |
|
| 2641 |
// Export all the taxonomies |
| 2642 |
foreach ( $post_types as $post_type => $label ) { |
| 2643 |
$type_taxonomies = get_object_taxonomies( $post_type, 'objects' ); |
| 2644 |
$taxonomies = wp_filter_object_list( $type_taxonomies, [ |
| 2645 |
'public' => true, |
| 2646 |
'show_in_nav_menus' => true, |
| 2647 |
] ); |
| 2648 |
|
| 2649 |
foreach( $taxonomies as $slug => $object ){ |
| 2650 |
|
| 2651 |
$query_params = [ |
| 2652 |
'taxonomy' => $object->name, |
| 2653 |
'hide_empty' => false, |
| 2654 |
]; |
| 2655 |
$terms = get_terms( $query_params ); |
| 2656 |
|
| 2657 |
foreach($terms as $term){ |
| 2658 |
$conf['taxonomies'][$term->term_id] = $term; |
| 2659 |
} |
| 2660 |
} |
| 2661 |
|
| 2662 |
} |
| 2663 |
|
| 2664 |
// Write the config |
| 2665 |
if(!empty($conf)){ |
| 2666 |
file_put_contents($theme_dir.'/pagelayer-data.conf', json_encode($conf, JSON_PRETTY_PRINT)); |
| 2667 |
} |
| 2668 |
|
| 2669 |
// Are we to export any media ? |
| 2670 |
if(!empty($pagelayer->media_to_export)){ |
| 2671 |
// TODO |
| 2672 |
//$done['media'] = $pagelayer->media_to_export; |
| 2673 |
} |
| 2674 |
|
| 2675 |
do_action('pagelayer_template_export_completed'); |
| 2676 |
|
| 2677 |
$done['success'] = __pl('temp_export_success'); |
| 2678 |
|
| 2679 |
// Output and die |
| 2680 |
pagelayer_json_output($done); |
| 2681 |
|
| 2682 |
} |
| 2683 |
|
| 2684 |
add_action('wp_ajax_pagelayer_get_cat_checkboxes', 'pagelayer_get_cat_checkboxes'); |
| 2685 |
function pagelayer_get_cat_checkboxes(){ |
| 2686 |
|
| 2687 |
// Some AJAX security |
| 2688 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 2689 |
|
| 2690 |
$ret = []; |
| 2691 |
$cat_name = ''; |
| 2692 |
|
| 2693 |
if(!current_user_can('manage_categories')){ |
| 2694 |
$ret['error'] = __pl('no_permission'); |
| 2695 |
pagelayer_json_output($ret); |
| 2696 |
} |
| 2697 |
|
| 2698 |
if(empty($_POST['postid']) || !is_numeric($_POST['postid'])){ |
| 2699 |
$ret['error'] = __pl('invalid_post_id'); |
| 2700 |
pagelayer_json_output($ret); |
| 2701 |
} |
| 2702 |
|
| 2703 |
$post = (int) $_POST['postid']; |
| 2704 |
$post = get_post($post); |
| 2705 |
|
| 2706 |
if(empty($post) || is_wp_error($post)){ |
| 2707 |
$ret['error'] = __pl('invalid_post_id'); |
| 2708 |
pagelayer_json_output($ret); |
| 2709 |
} |
| 2710 |
|
| 2711 |
$cat_name = pagelayer_post_type_category($post->post_type); |
| 2712 |
|
| 2713 |
if(!empty($_POST['new_cat'])){ |
| 2714 |
parse_str($_POST['new_cat'], $formdata); |
| 2715 |
$ret['new_cat_id'] = wp_insert_category([ |
| 2716 |
'taxonomy' => $cat_name, |
| 2717 |
'cat_name' => $formdata['category_name'], |
| 2718 |
'category_parent' => (($formdata['pagelayer_cat_parent'] == 0) ? '' : $formdata['pagelayer_cat_parent']) |
| 2719 |
]); |
| 2720 |
} |
| 2721 |
|
| 2722 |
$ret += pagelayer_post_cats($post); |
| 2723 |
|
| 2724 |
pagelayer_json_output($ret); |
| 2725 |
|
| 2726 |
} |
| 2727 |
|
| 2728 |
add_action('wp_ajax_pagelayer_get_post_tags', 'pagelayer_get_post_tags'); |
| 2729 |
function pagelayer_get_post_tags(){ |
| 2730 |
|
| 2731 |
// Some AJAX security |
| 2732 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 2733 |
|
| 2734 |
$ret = []; |
| 2735 |
$tag_name = ''; |
| 2736 |
|
| 2737 |
if(!current_user_can('manage_categories')){ |
| 2738 |
$ret['error'] = __pl('no_permission'); |
| 2739 |
pagelayer_json_output($ret); |
| 2740 |
} |
| 2741 |
|
| 2742 |
if(empty($_POST['postid']) || !is_numeric($_POST['postid']) ){ |
| 2743 |
pagelayer_json_output($ret); |
| 2744 |
} |
| 2745 |
|
| 2746 |
$post = (int) $_POST['postid']; |
| 2747 |
$post = get_post($post); |
| 2748 |
|
| 2749 |
if(empty($post) || is_wp_error($post)){ |
| 2750 |
$ret['error'] = __pl('invalid_post_id'); |
| 2751 |
pagelayer_json_output($ret); |
| 2752 |
} |
| 2753 |
|
| 2754 |
$tag_name = pagelayer_post_type_tag($post->post_type); |
| 2755 |
|
| 2756 |
if(!empty($_POST['new_tag'])){ |
| 2757 |
$ret['tag_id'] = wp_insert_term($_POST['new_tag'], $tag_name); |
| 2758 |
$ret['tag_id'] = $ret['tag_id']['term_id']; |
| 2759 |
} |
| 2760 |
|
| 2761 |
$ret += pagelayer_post_tags($post); |
| 2762 |
|
| 2763 |
pagelayer_json_output($ret); |
| 2764 |
|
| 2765 |
} |
| 2766 |
|
| 2767 |
add_action('wp_ajax_pagelayer_custom_font', 'pagelayer_custom_font'); |
| 2768 |
function pagelayer_custom_font(){ |
| 2769 |
|
| 2770 |
// Some AJAX security |
| 2771 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 2772 |
|
| 2773 |
$ret = []; |
| 2774 |
|
| 2775 |
if(empty($_POST['font_name'])){ |
| 2776 |
pagelayer_json_output($ret); |
| 2777 |
} |
| 2778 |
|
| 2779 |
$name = preg_replace('/_plf$/is', '', pagelayer_optREQ('font_name')); |
| 2780 |
//echo $name; |
| 2781 |
|
| 2782 |
$args = [ |
| 2783 |
'post_type' => PAGELAYER_FONT_POST_TYPE, |
| 2784 |
'status' => 'publish', |
| 2785 |
'posts_per_page' => 1, |
| 2786 |
'name' => $name |
| 2787 |
]; |
| 2788 |
|
| 2789 |
//var_dump($pagelayer->fonts); |
| 2790 |
|
| 2791 |
$query = get_posts($args); |
| 2792 |
//var_dump($query); |
| 2793 |
|
| 2794 |
if(empty($query)){ |
| 2795 |
pagelayer_json_output($ret); |
| 2796 |
} |
| 2797 |
|
| 2798 |
$post = $query[0]; |
| 2799 |
$meta_box_value = get_post_meta( $post->ID, 'pagelayer_font_link', true); |
| 2800 |
if(empty($meta_box_value)){ |
| 2801 |
pagelayer_json_output($ret); |
| 2802 |
} |
| 2803 |
|
| 2804 |
$ret['style']= '<style id="'.$name.'_plf" >@font-face { font-family: "'.$name.'_plf"'.'; src: url("'.$meta_box_value.'"); font-weight: 100 200 300 400 500 600 700 800 900;}</style>'; |
| 2805 |
|
| 2806 |
pagelayer_json_output($ret); |
| 2807 |
|
| 2808 |
} |
| 2809 |
|
| 2810 |
add_action('wp_ajax_pagelayer_trash_post', 'pagelayer_trash_post'); |
| 2811 |
function pagelayer_trash_post(){ |
| 2812 |
|
| 2813 |
// Some AJAX security |
| 2814 |
check_ajax_referer('pagelayer_ajax', 'pagelayer_nonce'); |
| 2815 |
|
| 2816 |
$ret = []; |
| 2817 |
|
| 2818 |
if(empty($_POST['postid']) && !is_numeric($_POST['postid'])){ |
| 2819 |
$ret = ['error' => __pl('invalid_post_id')]; |
| 2820 |
pagelayer_json_output($ret); |
| 2821 |
} |
| 2822 |
|
| 2823 |
if(!current_user_can( 'delete_post', $_POST['postid'] )){ |
| 2824 |
$ret = ['error' => __pl('no_permission')]; |
| 2825 |
pagelayer_json_output($ret); |
| 2826 |
} |
| 2827 |
|
| 2828 |
$ret['url'] = admin_url('/edit.php?post_type=') .get_post_type($_POST['postid']); |
| 2829 |
|
| 2830 |
wp_trash_post($_POST['postid']); |
| 2831 |
|
| 2832 |
pagelayer_json_output($ret); |
| 2833 |
|
| 2834 |
} |
| 2835 |
|
| 2836 |
add_action('wp_ajax_pagelayer_infinite_posts', 'pagelayer_infinite_posts'); |
| 2837 |
add_action('wp_ajax_nopriv_pagelayer_infinite_posts', 'pagelayer_infinite_posts'); |
| 2838 |
function pagelayer_infinite_posts(){ |
| 2839 |
|
| 2840 |
// Some AJAX security |
| 2841 |
check_ajax_referer('pagelayer_global', 'pagelayer_nonce'); |
| 2842 |
|
| 2843 |
pagelayer_load_shortcodes(); |
| 2844 |
|
| 2845 |
$tag = 'pl_posts'; |
| 2846 |
|
| 2847 |
if(isset($_REQUEST['data']['tag']) && $_REQUEST['data']['tag'] == 'pl_archive_posts' ){ |
| 2848 |
$tag = 'pl_archive_posts'; |
| 2849 |
} |
| 2850 |
|
| 2851 |
$content = get_comment_delimited_block_content( 'pagelayer/'.$tag, $_REQUEST['data']['atts'] , ''); |
| 2852 |
$wp['posts'] = pagelayer_the_content($content); |
| 2853 |
pagelayer_json_output( $wp ); |
| 2854 |
} |
| 2855 |
|
| 2856 |
add_action('wp_ajax_pagelayer_pro_dismiss_expired_licenses', 'pagelayer_pro_dismiss_expired_licenses'); |
| 2857 |
function pagelayer_pro_dismiss_expired_licenses(){ |
| 2858 |
check_admin_referer('pagelayer_expiry_notice', 'security'); |
| 2859 |
|
| 2860 |
if(!current_user_can('activate_plugins')){ |
| 2861 |
wp_send_json_error(__('You do not have required access to do this action', 'pagelayer')); |
| 2862 |
} |
| 2863 |
|
| 2864 |
update_option('softaculous_expired_licenses', time()); |
| 2865 |
wp_send_json_success(); |
| 2866 |
} |
| 2867 |
|
| 2868 |
add_action('wp_ajax_pagelayer_close_update_notice', 'pagelayer_close_plugin_update_notice'); |
| 2869 |
function pagelayer_close_plugin_update_notice(){ |
| 2870 |
check_ajax_referer('pagelayer_promo_nonce', 'pagelayer_nonce'); |
| 2871 |
|
| 2872 |
if(!current_user_can('manage_options')){ |
| 2873 |
wp_send_json_error('You don\'t have privilege to close this notice!'); |
| 2874 |
} |
| 2875 |
|
| 2876 |
$plugin_update_notice = get_option('softaculous_plugin_update_notice', []); |
| 2877 |
$available_update_list = get_site_transient('update_plugins'); |
| 2878 |
$to_update_plugins = apply_filters('softaculous_plugin_update_notice', []); |
| 2879 |
|
| 2880 |
if(empty($available_update_list) || empty($available_update_list->response)){ |
| 2881 |
return; |
| 2882 |
} |
| 2883 |
|
| 2884 |
foreach($to_update_plugins as $plugin_path => $plugin_name){ |
| 2885 |
if(isset($available_update_list->response[$plugin_path])){ |
| 2886 |
$plugin_update_notice[$plugin_path] = $available_update_list->response[$plugin_path]->new_version; |
| 2887 |
} |
| 2888 |
} |
| 2889 |
|
| 2890 |
update_option('softaculous_plugin_update_notice', $plugin_update_notice); |
| 2891 |
} |