Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2023-0088: swifty-page-manager.php in swifty-page-manager/trunk – WordPress Plugin Repository

The Swifty Page Manager plugin for WordPress is vulnerable to Cross-Site Request Forgery in versions up to, and including, 3.0.1. This is due to missing or incorrect nonce validation on several AJAX actions handling page creation and deletion among other things. This makes it possible for unauthenticated attackers to invoke those functions, via forged request granted they can trick a site administrator into performing an action such as clicking on a link.

CVE
#sql#google#js#java#wordpress#php#auth

1<?php2/*3Plugin Name: Swifty Page Manager4Description: Easily create, move and delete pages. Manage page settings.5Author: SwiftyOnline6Version: 3.0.17Author URI: http://swifty.online/plugins/8Plugin URI: http://swifty.online/plugins/swifty-page-manager/9*/10if ( ! defined( ‘ABSPATH’ ) ) exit;1112global $swifty_build_use;13$swifty_build_use = 'build’;1415class SwiftyPageManager16{17 protected $plugin_file;18 protected $plugin_dir;19 protected $plugin_basename;20 protected $plugin_dir_url;21 protected $plugin_url;22 protected $_plugin_version = '3.0.1’;23 protected $_post_status = 'any’;24 protected $_post_type = 'page’;25 protected $_tree = null;26 protected $_by_page_id = null;27 protected $is_ssm_active = false;28 protected $is_ssd_active = false;29 protected $is_ss_advanced = false;30 protected $front_page_id = 0;31 protected $swifty_admin_page = 'swifty_page_manager_admin’;32 protected $areas = array( 'topbar’, 'header’, 'navbar’, 'sidebar’, 'extrasidebar’, 'footer’, ‘bottombar’ );3334 private $script_refresh_tree = ‘$SPMTree.jstree( \’refresh\’ );’;3536 /**37 * Constructor38 */39 public function __construct()40 {41 $this->plugin_file = __FILE__;42 $this->plugin_dir = dirname( $this->plugin_file );43 $this->plugin_basename = basename( $this->plugin_dir );44 $this->plugin_dir_url = plugins_url( rawurlencode( basename( $this->plugin_dir ) ) );45 $this->plugin_url = $_SERVER[ ‘REQUEST_URI’ ];4647 require_once plugin_dir_path( __FILE__ ) . 'lib/swifty_plugin/php/autoload.php’;48 if( is_null( LibSwiftyPlugin::get_instance() ) ) {49 new LibSwiftyPlugin();50 }5152 add_filter( 'swifty_active_plugins’, array( $this, ‘hook_swifty_active_plugins’ ) );53 add_filter( 'swifty_active_plugin_versions’, array( $this, ‘hook_swifty_active_plugin_versions’ ) );5455 // postpone further initialization to allow loading other plugins56 add_action( 'plugins_loaded’, array( $this, ‘plugins_loaded’ ) );5758 // remove ninja-forms admin notices59 add_filter( 'nf_admin_notices’, array( $this, ‘hook_nf_admin_notices’ ), 11 );60 }6162 /**63 * Called via Swifty filter 'swifty_active_plugins’64 *65 * Add the plugin name to the array66 */67 public function hook_swifty_active_plugins( $plugins )68 {69 $plugins[] = 'swifty-page-manager’;70 return $plugins;71 }7273 /**74 * Called via Swifty filter 'swifty_active_plugin_versions’75 *76 * Add the plugin name as key to the array with plugin version77 */78 public function hook_swifty_active_plugin_versions( $plugins )79 {80 $plugins[‘swifty-page-manager’] = array( ‘version’ => $this->_plugin_version );81 return $plugins;82 }8384 /**85 * Called via WP Action 'plugins_loaded’86 *87 * Initialize actions and filter88 */89 function plugins_loaded()90 {91 $this->is_ssm_active = LibSwiftyPluginView::is_required_plugin_active( ‘swifty-site’ );9293 // Priority high, so $required_theme_active_swifty_site_designer is set.94 add_action( 'after_setup_theme’, array( $this, ‘action_after_setup_theme’ ), 9999 );9596 // Actions for visitors viewing the site97 add_action( 'parse_request’, array( $this, ‘parse_request’ ) );98 add_filter( 'page_link’, array( $this, ‘page_link’ ), 10, 2 );99 if ( $this->is_ssm_active ) {100 add_filter( 'wp_title’, array( $this, ‘seo_wp_title’ ), 10/*, 2*/ );101 add_filter( 'document_title_parts’, array( $this, ‘seo_document_title_parts’ ) );102 add_filter( 'wpseo_title’, array( $this, ‘seo_wp_title’ ) );103 add_filter( 'admin_footer_text’, array( $this, ‘empty_footer_text’ ) );104 add_filter( 'update_footer’, array( $this, ‘empty_footer_text’ ), 999 );105 }106107 // Actions for admins, warning: is_admin is not a security check108 if ( is_admin() ) {109 add_action( 'init’, array( $this, ‘admin_init’ ) );110 add_action( 'admin_init’, array( $this, ‘hook_admin_init’ ) );111 }112113 }114115 public function action_after_setup_theme() {116 $this->is_ssd_active = LibSwiftyPluginView::$required_theme_active_swifty_site_designer;117 }118119 /**120 * return true when the page manager is showed or pagelist with trashed pages121 *122 * @return bool123 */124 public function is_pagemanager_page() {125 $currentScreen = get_current_screen();126 return ($currentScreen && ( ‘pages_page_page-tree’ === $currentScreen->base ||127 ( ‘edit’ === $currentScreen->base && ‘page’ === $currentScreen->post_type && ‘trash’ === get_query_var( ‘post_status’ ) ) ) );128 }129130 /** hide ninja forms notices when showing pagemanager or pagelist with trashed pages131 * do this by removing all ninja notices from array132 */133 public function hook_nf_admin_notices( $notices ) {134135 if( $this->is_pagemanager_page() ) {136 $notices = array();137 }138 return $notices;139 }140141 public function empty_footer_text() {142 return '’;143 }144145 /**146 * Called via WP Action ‘init’ if is_admin147 *148 * Load translations149 */150 function admin_init()151 {152 if ( current_user_can( ‘edit_pages’ ) ) {153 // get_user_option is used safe when ‘init’ action is triggered. Using this earlier can cause compatibility154 // issues with other plugins, like BBPress.155 $this->is_ss_advanced = get_user_option( ‘swifty_gui_mode’ ) === 'advanced’;156157 if ( ! empty( $_GET[‘status’] ) ) {158 $this->_post_status = $_GET[‘status’];159 }160161 load_plugin_textdomain( 'swifty-page-manager’, false, ‘/swifty-page-manager/languages’ );162163 add_action( 'admin_head’, array( $this, ‘admin_head’ ) );164 add_action( 'admin_menu’, array( $this, ‘admin_menu’) );165 add_filter( 'admin_add_swifty_menu’, array( &$this, ‘hook_admin_add_swifty_menu’ ), 1, 4 );166 add_filter( 'admin_add_swifty_admin’, array( &$this, ‘hook_admin_add_swifty_admin’ ), 1, 8 );167 add_action( 'wp_ajax_spm_get_childs’, array( $this, ‘ajax_get_childs’ ) );168 add_action( 'wp_ajax_spm_save_page’, array( $this, ‘ajax_save_page’ ) );169 add_action( 'wp_ajax_spm_post_settings’, array( $this, ‘ajax_post_settings’ ) );170 add_action( 'wp_ajax_spm_move_page’, array( $this, ‘ajax_move_page’ ) );171172 if ( current_user_can( ‘delete_pages’ ) ) {173 add_action( 'wp_ajax_spm_delete_page’, array( $this, ‘ajax_delete_page’ ) );174 }175176 if ( current_user_can( ‘publish_pages’ ) ) {177 add_action( 'wp_ajax_spm_publish_page’, array( $this, ‘ajax_publish_page’ ) );178 }179180 add_action( 'admin_enqueue_scripts’, array( $this, ‘add_plugin_css’ ) );181182 if ( $this->is_ssm_active ) {183 add_action( 'wp_ajax_spm_sanitize_url_and_check’, array( $this, ‘ajax_sanitize_url_and_check’ ) );184 add_action( 'save_post’, array( $this, ‘restore_page_status’ ), 10, 2 );185 add_filter( 'wp_insert_post_data’, array( $this, ‘set_tmp_page_status’ ), 10, 2 );186 add_filter( 'wp_list_pages’, array( $this, ‘wp_list_pages’ ) );187 add_filter( 'status_header’, array( $this, ‘status_header’ ) );188 }189190 require_once plugin_dir_path( __FILE__ ) . 'lib/swifty_plugin/php/autoload.php’;191 if ( ! class_exists( ‘LibSwiftyPlugin’ ) ) {192 new LibSwiftyPlugin();193 }194195 $this->front_page_id = ‘page’ == get_option(‘show_on_front’) ? (int) get_option( ‘page_on_front’ ) : 0;196 }197 }198199 /**200 * add the spm options and settings and bind them to the correct setting section201 */202 function hook_admin_init()203 {204 // setting group name, name of option205 register_setting( 'spm_plugin_options’, ‘spm_plugin_options’ );206207 add_settings_section(208 'spm_plugin_options_main_id’,209 '’,210 array( $this, ‘spm_plugin_options_main_text_callback’ ),211 'spm_plugin_options_page’212 );213214 add_settings_field(215 'spm_plugin_options_page_tree_max_width’,216 __( 'Page tree max. width’, ‘swifty-page-manager’ ),217 array( $this, ‘plugin_setting_page_tree_max_width’ ),218 'spm_plugin_options_page’,219 'spm_plugin_options_main_id’220 );221 }222223 function spm_plugin_options_main_text_callback()224 {225 }226227 function plugin_setting_page_tree_max_width()228 {229 echo ‘<input’230 . ' type="text"’231 . ' id="spm_plugin_options_page_tree_max_width"’232 . ' name="spm_plugin_options[page_tree_max_width]"’233 . ' value="’ . $this->get_page_tree_max_width() . '"’234 . ' />’;235 }236237 function get_page_tree_max_width()238 {239 $options = get_option( ‘spm_plugin_options’ );240241 if( ! $options242 || ! isset( $options[ ‘page_tree_max_width’ ] )243 || ! $options[ ‘page_tree_max_width’ ]244 ) {245 $options[ ‘page_tree_max_width’ ] = 900;246247 update_option( 'spm_plugin_options’, $options );248 }249250 return $options[ ‘page_tree_max_width’ ];251 }252253 public function get_admin_page_title()254 {255 $swifty_SS2_hosting_name = apply_filters( 'swifty_SS2_hosting_name’, false );256 if( $swifty_SS2_hosting_name ) {257 $admin_page_title = __( 'SwiftySite Pages’, ‘swifty-page-manager’ );258 } else {259 $admin_page_title = 'Swifty Page Manager’;260 }261 return $admin_page_title;262 }263264 /**265 /**266 * @param string $title267 * @param string $sep268 * @return string269 */270 public function seo_wp_title( $title/*, $sep*/ )271 {272 if( is_feed() ) {273 return $title;274 }275276 $seoTitle = get_post_meta( get_the_ID(), 'spm_page_title_seo’, true );277278 if( ! empty( $seoTitle ) ) {279280 if( defined( ‘WPSEO_VERSION’ ) && class_exists( ‘WPSEO_Meta’ ) ) {281 if( $title !== $seoTitle ) {282 $yoastTitle = WPSEO_Meta::get_value( 'title’, get_the_ID() );283284 if( ! empty( $yoastTitle ) ) {285 if( $yoastTitle !== $seoTitle ) {286 // If a specific Yoast title is set AND a specific SPM title is set, we overwrite the Yoast title with the SPM title.287 WPSEO_Meta::set_value( 'title’, $seoTitle, get_the_ID() );288 }289 }290 }291 }292293 return “$seoTitle";294 }295296 return $title;297 }298299 /**300 * Change title for themes supporting the 'title-tag’.301 * Return only seo title when set in SPM.302 *303 * @param $title_parts304 * @return array305 */306 public function seo_document_title_parts( $title_parts ) {307 if( is_feed() ) {308 return $title_parts;309 }310311 $seoTitle = get_post_meta( get_the_ID(), 'spm_page_title_seo’, true );312313 if( ! empty( $seoTitle ) ) {314 return array( ‘title’ => $seoTitle );315 }316317 return $title_parts;318 }319320 /**321 * Called via WP Filter 'wp_insert_post_data’, if can_edit_pages && is_ssm_active322 *323 * @param array $data324 * @param array $postarr325 * @return array326 */327 public function set_tmp_page_status( $data, $postarr )328 {329 // Only do this when creating a page.330 if ( $data[‘post_type’] === ‘page’ &&331 $data[‘post_status’] === ‘draft’ &&332 empty( $postarr[‘ID’] )333 ) {334 $data[‘post_status’] = '__TMP__’;335 }336337 return $data;338 }339340 /**341 * Called via WP Action 'save_post’, if can_edit_pages && is_ssm_active342 *343 * @param integer $post_id344 * @param WP_Post $post345 */346 public function restore_page_status( $post_id, $post )347 {348 if ( ! current_user_can( ‘edit_pages’ ) ) {349 wp_die( __( ‘You do not have sufficient permissions to access this page. #314’ ) );350 }351352 // Check it’s not an auto save routine353 if ( defined( ‘DOING_AUTOSAVE’ ) && DOING_AUTOSAVE ) {354 return;355 }356357 if ( ! wp_is_post_revision( $post_id ) &&358 $post->post_type === ‘page’ &&359 $post->post_status === ‘__TMP__’360 ) {361 $post_data = array(362 ‘ID’ => $post_id,363 ‘post_status’ => $_POST[‘post_status’],364 );365 // no need to restore autosave, because this is only used for new pages which366 // do not yet have an autosave367 wp_update_post( $post_data );368 }369 }370371 /*372 * Search in DB for spm_url and return post id when found373 *374 */375 protected function get_post_id_from_spm_url( $url )376 {377 /** @var wpdb $wpdb - Wordpress Database */378 global $wpdb;379380 $query = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key=’spm_url’ AND meta_value=’%s’",381 $url );382 return $wpdb->get_var( $query );383 }384385 /**386 * Called via WP Action 'parse_request’387 *388 * Action function to make our overridden URLs work by changing the query params.389 * the meta data “spm_url” contains the wanted url (without domain)390 *391 * @param wp $wp - WordPress object392 */393 public function parse_request( &$wp )394 {395 if( ! empty( $wp->request ) ) {396 $post_id = $this->get_post_id_from_spm_url( $wp->request );397398 if( $post_id ) {399 $wp->query_vars = array( ‘pagename’ => get_page_uri( $post_id ) );400 // disable seo-redirect plugin for this url (other solution would be to set $_SERVER[“REQUEST_URI”] to the uri)401 remove_action( 'wp’, 'WPSR_redirect’, 1 );402 }403 }404 }405406 /**407 * Called via WP Filter 'page_link’, if is_ssm_active408 *409 * Filter function called when the link to a page is needed.410 * We return our custom URL if it has been set.411 *412 * @param string $link413 * @param bool|integer $post_id414 * @return string415 */416 public function page_link( /** @noinspection PhpUnusedParameterInspection */ $link, $post_id=false )417 {418 if( $post_id ) {419 $spm_url = get_post_meta( $post_id, 'spm_url’, true );420421 if( $spm_url ) {422 $link = get_site_url( null, $spm_url );423 } else {424 if( $this->is_ssm_active ) {425 $post = get_post( $post_id );426427 // Hack: get_page_link() would return ugly permalink for drafts, so we will fake that our post is published.428 if( in_array( $post->post_status, array( 'draft’, ‘pending’ ) ) ) {429 $post->post_status = 'publish’;430 $post->post_name = sanitize_title( $post->post_name ? $post->post_name : $post->post_title, $post->ID );431 }432433 // If calling get_page_link inside page_link action, unhook this function so it doesn’t loop infinitely434 remove_filter( 'page_link’, array( $this, ‘page_link’ ) );435436 $link = get_page_link( $post );437438 // Re-hook this function439 add_filter( 'page_link’, array( $this, ‘page_link’ ), 10, 2 );440 }441 }442 }443 return $link;444 }445446 /**447 * Called via WP Filter 'wp_list_pages’, if can_edit_pages && is_ssm_active448 *449 * Filter function to add “spm-hidden” class to hidden menu items in <li> tree.450 *451 * @param $output452 * @return string453 */454 public function wp_list_pages( $output )455 {456 $output = preg_replace_callback(457 '/\bpage-item-(\d+)\b/’,458 array( $this, ‘_wp_list_pages_replace_callback’ ),459 $output460 );461462 return $output;463 }464465 /**466 * Called via WP Filter 'status_header’, if can_edit_pages && is_ssm_active467 *468 * Status header filter function.469 * When a 404 error occurs check if we can find the URL in a post’s spm_old_url_XXX field.470 * If found, 301 redirect to the post.471 *472 * @param $code473 * @return mixed474 */475 public function status_header( $code )476 {477 /** @var wpdb $wpdb - Wordpress Database */478 global $wpdb;479 global $wp;480481 if ( preg_match( '|\b404\b|’, $code ) ) {482 if ( ! empty( $wp->request ) ) {483 $query = $wpdb->prepare(484 “SELECT post_id FROM $wpdb->postmeta WHERE meta_key LIKE ‘spm_old_url_%%’ AND meta_value=’%s’",485 $wp->request );486487 $post_id = $wpdb->get_var( $query );488489 if ( $post_id ) {490 $link = get_page_link( $post_id );491492 if ( $link ) {493 header( 'Location: ' . $link, true, 301 );494 exit();495 }496 }497 }498 }499500 return $code;501 }502503 /**504 * Called via WP Action ‘admin_head’ if can_edit_pages505 *506 * Output header for admin page507 */508 public function admin_head()509 {510 if ( ! current_user_can( ‘edit_pages’ ) ) {511 wp_die( __( ‘You do not have sufficient permissions to access this page. #314’ ) );512 }513514 // hide update notices from this page515 remove_action( 'admin_notices’, 'update_nag’, 3 );516517 if ( $this->is_pagemanager_page() ) {518 $currentScreen = get_current_screen();519 if ( ‘pages_page_page-tree’ === $currentScreen->base ) {520 /** @noinspection PhpIncludeInspection */521 require $this->plugin_dir . '/view/admin_head.php’;522 }523524 if( $this->is_ssm_active ) {525 require $this->plugin_dir . '/view/swifty_admin_head.php’;526 }527 }528 }529530 /**531 * Called via WP Action ‘admin_menu’ if can_edit_pages532 *533 * Add submenu to admin left menu534 */535 public function admin_menu()536 {537 add_submenu_page( ‘edit.php?post_type=’ . $this->_post_type,538 $this->get_admin_page_title(),539 $this->get_admin_page_title(),540 'edit_pages’,541 'page-tree’,542 array( $this, ‘view_page_tree’ ) );543544 add_filter( ‘swifty_admin_page_links_’ . $this->swifty_admin_page, array( $this, ‘hook_swifty_admin_page_links’ ) );545546 LibSwiftyPlugin::get_instance()->admin_add_swifty_menu( $this->get_admin_page_title(), __('Pages’, ‘swifty-page-manager’), $this->swifty_admin_page, array( &$this, ‘admin_spm_menu_page’ ), true );547548 if( get_option( ‘ss2_hosting_name’ ) !== ‘AMH’ ) {549 do_action( 'swifty_setup_plugin_action_links’, $this->plugin_basename, 'https://www.swifty.online/?rss3=wpaplgpg’, __( 'More Swifty Plugins’, ‘swifty-page-manager’ ) );550 }551 }552553 function hook_admin_add_swifty_menu( $page, $name, $key, $func )554 {555 if( ! $page ) {556 $page = add_submenu_page( 'swifty_admin’, $name, $name, 'manage_options’, $key, $func );557 }558 return $page;559 }560561 function hook_admin_add_swifty_admin( $done, $v1, $v2, $v3, $v4, $v5, $v6, $v7 )562 {563 if( ! $done ) {564 add_menu_page( $v1, $v2, $v3, $v4, $v5, $v6, $v7 );565 }566 return true;567 }568569 /**570 * Called via admin_menu hook571 *572 * Add links to admin menu573 */574 public function hook_swifty_admin_page_links( $settings_links )575 {576 $settings_links[‘general’] = array( ‘title’ => __( 'General’, ‘swifty-page-manager’ ), ‘method’ => array( &$this, ‘spm_tab_options_content’ ) );577578 return $settings_links;579 }580581 /**582 * Called via WP do_action if can_edit_pages583 *584 * Show page tree585 */586 public function view_page_tree()587 {588 if ( ! current_user_can( ‘edit_pages’ ) ) {589 wp_die( __( ‘You do not have sufficient permissions to access this page. #314’ ) );590 }591592 // renamed from cookie to fix problems with mod_security593 wp_enqueue_script( 'jquery-cookie’, $this->plugin_dir_url . $this->_find_minified( ‘/js/jquery.biscuit.js’ ), array( ‘jquery’ ) );594 wp_enqueue_script( ‘jquery-ui-tooltip’ );595 wp_enqueue_script( 'jquery-jstree’, $this->plugin_dir_url . $this->_find_minified( ‘/js/jquery.jstree.js’ ), false,596 $this->_plugin_version );597 wp_enqueue_script( 'jquery-alerts’, $this->plugin_dir_url . $this->_find_minified( ‘/js/jquery.alerts.js’ ), false,598 $this->_plugin_version );599 wp_enqueue_script( 'spm’, $this->plugin_dir_url . $this->_find_minified( ‘/js/swifty-page-manager.js’ ), false,600 $this->_plugin_version );601602 wp_enqueue_style( 'jquery-alerts’, $this->plugin_dir_url . '/css/jquery.alerts.css’, false,603 $this->_plugin_version );604 wp_enqueue_style( 'spm-font-awesome’, '//netdna.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css’,605 false, $this->_plugin_version );606607 $oLocale = array(608 ‘status_draft_ucase’ => ucfirst( __( 'draft’, ‘swifty-page-manager’ ) ),609 ‘status_future_ucase’ => ucfirst( __( 'future’, ‘swifty-page-manager’ ) ),610 ‘status_password_ucase’ => ucfirst( __( 'protected’, ‘swifty-page-manager’ ) ),611 ‘status_pending_ucase’ => ucfirst( __( 'pending’, ‘swifty-page-manager’ ) ),612 ‘status_private_ucase’ => ucfirst( __( 'private’, ‘swifty-page-manager’ ) ),613 ‘status_trash_ucase’ => ucfirst( __( 'trash’, ‘swifty-page-manager’ ) ),614 ‘password_protected_page’ => __( 'Password protected page’, ‘swifty-page-manager’ ),615 ‘no_pages_found’ => __( 'No pages found.’, ‘swifty-page-manager’ ),616 ‘hidden_page’ => __( 'Hidden’, ‘swifty-page-manager’ ),617 ‘checking_url’ => __( 'Checking url’, ‘swifty-page-manager’ ),618 ‘no_sub_page_when_draft’ => __( “Unfortunately you can not create a sub page under a page with status ‘Draft’ because the draft page has not yet been published and thus technically does not exist yet. For now, just create it as a regular page and later you can drag and drop it to become a sub page.", ‘swifty-page-manager’ ),619 ‘status_published_draft_content_ucase’ => ucfirst( __( 'published - draft content’, ‘swifty-page-manager’ ) )620 );621622 wp_localize_script( 'spm’, 'spm_l10n’, $oLocale );623 wp_localize_script( 'spm’, 'spm_data’, array(624 ‘is_ssm_active’ => $this->is_ssm_active,625 ‘is_ssd_active’ => $this->is_ssd_active,626 ‘is_ss_advanced’ => $this->is_ss_advanced627 ) );628629 /** @noinspection PhpIncludeInspection */630 require( $this->plugin_dir . ‘/view/page_tree.php’ );631632 do_action( ‘swifty_page_manager_view_page_tree’ );633 }634635 // Our plugin admin menu page636 function admin_spm_menu_page()637 {638 LibSwiftyPlugin::get_instance()->admin_options_menu_page( $this->swifty_admin_page );639 }640641 function spm_tab_options_content()642 {643 settings_fields( ‘spm_plugin_options’ );644 do_settings_sections( ‘spm_plugin_options_page’ );645 submit_button();646647 echo ‘<p>’ . 'Swifty Page Manager ' . $this->_plugin_version . '</p>’;648 }649650 /**651 * Called via WP Ajax Action ‘wp_ajax_spm_get_childs’ if can_edit_pages652 *653 * Return JSON with tree children, called from Ajax654 */655 public function ajax_get_childs()656 {657 if ( ! current_user_can( ‘edit_pages’ ) ) {658 wp_die( __( ‘You do not have sufficient permissions to access this page. #359’ ) );659 }660661 header( ‘Content-type: application/json’ );662663 $action = $_GET[‘action’];664665 // Check if user is allowed to get the list. For example subscribers should not be allowed to666 // Use same capability that is required to add the menu667 $post_type_object = get_post_type_object( $this->_post_type );668669 if ( ! current_user_can( $post_type_object->cap->edit_posts ) ) {670 wp_die( __( ‘You do not have sufficient permissions to access this page. #371’ ) );671 }672673 if ( $action ) { // regular get674 $id = ( isset( $_GET[‘id’] ) ) ? $_GET[‘id’] : null;675 $id = (int) str_replace( 'spm-id-', '’, $id );676677 $jstree_open = array();678679 if ( isset( $_COOKIE[‘jstree_open’] ) ) {680 $jstree_open = $_COOKIE[‘jstree_open’]; // like this: [jstree_open] => spm-id-1282,spm-id-1284,spm-id-3681 $jstree_open = explode( ',’, $jstree_open );682683 for ( $i = 0; $i < sizeof( $jstree_open ); $i++ ) {684 $jstree_open[ $i ] = (int) str_replace( '#spm-id-', '’, $jstree_open[ $i ] );685 }686 }687688 $this->get_tree();689 $json_data = $this->get_json_data( $this->_by_page_id[ $id ], $jstree_open );690 print json_encode( $json_data );691 exit;692 }693694 exit;695 }696697 /**698 * Called via WP Ajax Action ‘wp_ajax_spm_move_page’ if can_edit_pages699 *700 * Ajax function to move a page701 */702 public function ajax_move_page()703 {704 if ( ! current_user_can( ‘edit_pages’ ) ) {705 wp_die( __( ‘You do not have sufficient permissions to access this page. #465’ ) );706 }707708 /*709 the node that was moved,710 the reference node in the move,711 the new position relative to the reference node (one of “before", “after” or “inside”)712 */713714 $node_id = $_POST[‘node_id’]; // the node that was moved715 $ref_node_id = $_POST[‘ref_node_id’];716 $type = $_POST[‘type’];717718 $node_id = str_replace( 'spm-id-', '’, $node_id );719 $ref_node_id = str_replace( 'spm-id-', '’, $ref_node_id );720721 $_POST[‘skip_sitepress_actions’] = true; // sitepress.class.php->save_post_actions722723 if ( $node_id && $ref_node_id ) {724 $post_node = get_post( $node_id );725 $post_ref_node = get_post( $ref_node_id );726727 // first check that post_node (moved post) is not in trash. we do not move them728 if ( $post_node->post_status === ‘trash’ ) {729 exit;730 }731732 $post_to_save = array(733 ‘ID’ => $post_node->ID,734 ‘menu_order’ => $this->_createSpaceForMove( $post_ref_node, $type ),735 ‘post_parent’ => ( ‘inside’ === $type ) ? $post_ref_node->ID : $post_ref_node->post_parent,736 ‘post_type’ => $this->_post_type737 );738739 // $id_saved = wp_update_post( $post_to_save ); < now keeping autosave740 $id_saved = LibSwiftyPlugin::get_instance()->wp_update_post_keep_autosave( $post_node->ID, $post_to_save );741742 if ( ‘inside’ === $type && $id_saved ) {743 $show_ref_page_in_menu = get_post_meta( $ref_node_id, 'spm_show_in_menu’, true );744745 if ( ! empty( $show_ref_page_in_menu ) && $show_ref_page_in_menu !== ‘show’ ) {746 update_post_meta( $id_saved, 'spm_show_in_menu’, ‘hide’ );747 }748 }749750 echo 'did ' . $type;751752 // Store the moved page id in the jstree_select cookie753 setcookie( 'jstree_select’, '#spm-id-' . $post_node->ID );754755 } else {756 // error757 }758759 do_action( ‘spm_node_move_finish’ );760761 exit;762 }763764 /**765 * return true when given post_name is unique as slug and spm_url766 */767 public function spm_is_unique_spm_url( $post_id, $post_parent_id, $post_name )768 {769 // look for other pages using this post_name in the spm_url (is it not used for other pages?)770 $spm_url_post_id = $this->get_post_id_from_spm_url( $post_name );771 if( $spm_url_post_id && ( $spm_url_post_id != $post_id ) ) {772 return false;773 }774 // look for other pages using this post_name as slug (is it unique in siblings?)775 global $wpdb;776 $check_sql = “SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( 'page’, ‘attachment’ ) AND ID != %d AND post_parent = %d LIMIT 1";777 $post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $post_name, $post_id, $post_parent_id ) );778 if( $post_name_check ) {779 return false;780 }781 return true;782 }783784 /**785 * Called via WP Ajax Action ‘ajax_save_page’ if can_edit_pages786 *787 * Ajax funtion to save a page788 */789 public function ajax_save_page()790 {791 if ( ! current_user_can( ‘edit_pages’ ) ) {792 wp_die( __( ‘You do not have sufficient permissions to access this page. #588’ ) );793 }794795 // post_name is de menu slug796 $post_id = ! empty( $_POST[‘post_ID’] ) ? intval( $_POST[‘post_ID’] ) : null;797 $post_title = ! empty( $_POST[‘post_title’] ) ? trim( $_POST[‘post_title’] ) : '’;798 $post_name = ! empty( $_POST[‘post_name’] ) ? trim( $_POST[‘post_name’] ) : '’;799 $post_status = $_POST[‘post_status’];800801 // better be safe with our menu slugs802 $post_name = preg_replace(“~[ ]~", "-“, $post_name);803 $post_name = preg_replace(“~[^a-z0-9//_-]~i", “", $post_name);804 $post_name = rtrim( $post_name, ‘/’ );805806 if ( ! $post_title ) {807 $post_title = __( 'New page’, ‘swifty-page-manager’ );808 }809810 $spm_is_custom_url = ! empty( $_POST[‘spm_is_custom_url’] ) ? intval( $_POST[‘spm_is_custom_url’] ) : null;811 $spm_page_title_seo = ! empty( $_POST[‘spm_page_title_seo’] ) ? trim( $_POST[‘spm_page_title_seo’] ) : '’;812 $spm_page_description_seo = ! empty( $_POST[‘spm_page_description_seo’] ) ? trim( $_POST[‘spm_page_description_seo’] ) : '’;813 $spm_show_in_menu = ! empty( $_POST[‘spm_show_in_menu’] ) ? $_POST[‘spm_show_in_menu’] : null;814815 $yoast_se_noindex = $_POST[‘spm_page_se_noindex’];816 $yoast_se_nofollow = $_POST[‘spm_page_se_nofollow’];817818 $post_data = array();819820 $post_data[‘post_title’] = $post_title;821 $post_data[‘post_status’] = $post_status;822 $post_data[‘post_type’] = $_POST[‘post_type’];823// $post_data[‘page_template’] = $_POST[‘page_template’];824825 if ( isset( $post_id ) && ! empty( $post_id ) ) { // We’re in edit mode826 $post_data[‘ID’] = $post_id;827828 // $post_id = wp_update_post( $post_data ); < now keeping autosave829 $post_id = LibSwiftyPlugin::get_instance()->wp_update_post_keep_autosave( $post_id, $post_data );830831 if( $post_id ) {832 if( $this->is_ssm_active ) {833 $post = get_post( $post_id );834 $spm_show_as_first = isset( $_POST[‘spm_show_as_first’] ) ? $_POST[‘spm_show_as_first’] : null;835 $spm_alt_menu_text = isset( $_POST[‘spm_alt_menu_text’] ) ? trim( $_POST[‘spm_alt_menu_text’] ) : null;836837 if( $this->spm_is_unique_spm_url( $post_id, $post->post_parent, $post_name ) ) {838 $cur_spm_url = get_post_meta( $post_id, 'spm_url’, true );839840 if( ! empty( $cur_spm_url ) ) {841 if( $cur_spm_url !== $post_name ) {842 $this->save_old_url( $post_id, $cur_spm_url );843 }844 } else {845 if( $spm_is_custom_url ) {846 $this->save_old_url( $post_id, wp_make_link_relative( get_page_link( $post_id ) ) );847 }848 }849850 update_post_meta( $post_id, 'spm_url’, $spm_is_custom_url ? $post_name : ‘’ );851 }852853 update_post_meta( $post_id, 'spm_show_in_menu’, $spm_show_in_menu );854 update_post_meta( $post_id, 'spm_page_title_seo’, $spm_page_title_seo );855 if( defined( ‘WPSEO_VERSION’ ) && class_exists( ‘WPSEO_Meta’ ) ) {856 if( ! empty( $spm_page_title_seo ) ) {857 WPSEO_Meta::set_value( 'title’, $spm_page_title_seo, $post_id );858 }859 if( ! empty( $spm_page_description_seo ) ) {860 WPSEO_Meta::set_value( 'metadesc’, $spm_page_description_seo, $post_id );861 }862 WPSEO_Meta::set_value( 'meta-robots-noindex’, $yoast_se_noindex, $post_id );863 WPSEO_Meta::set_value( 'meta-robots-nofollow’, $yoast_se_nofollow, $post_id );864 }865866 foreach( $this->areas as $area ) {867 $area_visibility = ‘spm_’ . $area . '_visibility’;868869 update_post_meta(870 $post_id,871 $area_visibility,872 ! empty( $_POST[ $area_visibility ] ) ? $_POST[ $area_visibility ] : null873 );874 }875876 if ( ! is_null( $spm_show_as_first ) ) {877 update_post_meta( $post_id, 'spm_show_as_first’, $spm_show_as_first );878 }879880 if ( ! is_null( $spm_alt_menu_text ) ) {881 if ( $spm_show_as_first === ‘show’ ) {882 update_post_meta( $post_id, 'spm_alt_menu_text’, $spm_alt_menu_text );883 }884 }885 }886887 echo '1’;888 } else {889 echo '0’; // fail, tell js890 }891 }892 else { // We’re in create mode893 $parent_id = $_POST[‘parent_id’];894 $parent_id = intval( str_replace( 'spm-id-', '’, $parent_id ) );895 $ref_post = get_post( $parent_id );896 $add_mode = $_POST[‘add_mode’];897 $parent_post_meta = get_post_meta( $parent_id );898 $page_type = $_POST[‘page_type’];899900 $post_data[‘post_content’] = '’;901 $post_data[‘menu_order’] = $this->_createSpaceForMove( $ref_post, $add_mode );902 $post_data[‘post_parent’] = ( ‘inside’ === $add_mode ) ? $ref_post->ID : $ref_post->post_parent;903904 $post_id = wp_insert_post( $post_data );905 $post_id = intval( $post_id );906907 if ( $post_id ) {908909 $post = get_post( $post_id );910 if ( $this->is_ssm_active ) {911 // make sure the menu url is unique912 if( $post_name === ‘’ ) {913 $post_name = $post->post_name;914 }915916 $nr = 2;917 $original_post_name = $post_name;918 while ( ! $this->spm_is_unique_spm_url( $post_id, $post->post_parent, $post_name ) ) {919 $post_name = $original_post_name . '-' . $nr++;920 $spm_is_custom_url = true;921 }922923 add_post_meta( $post_id, 'spm_url’, $spm_is_custom_url ? $post_name : '’, 1 );924 add_post_meta( $post_id, 'spm_show_in_menu’, $spm_show_in_menu, 1 );925 add_post_meta( $post_id, 'spm_page_title_seo’, $spm_page_title_seo, 1 );926 if( defined( ‘WPSEO_VERSION’ ) && class_exists( ‘WPSEO_Meta’ ) ) {927 if( ! empty( $spm_page_title_seo ) ) {928 WPSEO_Meta::set_value( 'title’, $spm_page_title_seo, $post_id );929 }930 if( ! empty( $spm_page_description_seo ) ) {931 WPSEO_Meta::set_value( 'metadesc’, $spm_page_description_seo, $post_id );932 }933 WPSEO_Meta::set_value( 'meta-robots-noindex’, $yoast_se_noindex, $post_id );934 WPSEO_Meta::set_value( 'meta-robots-nofollow’, $yoast_se_nofollow, $post_id );935 }936937 foreach( $this->areas as $area ) {938 $v_key = ‘spm_’ . $area . '_visibility’;939940 // Page will be a copy of the parent, with or without the parent’s content.941 if( $page_type && $page_type !== ‘default’ ) {942 $t_key = ‘spm_’ . $area . '_template’;943944 foreach ( array( $v_key, $t_key ) as $key ) {945 if( isset( $parent_post_meta[ $key ] ) ) {946 $val = $parent_post_meta[ $key ];947 $val = ( is_array( $val ) && count( $val ) === 1 ) ? $val[ 0 ] : $val;948949 add_post_meta( $post_id, $key, $val, 1 );950 }951 }952 } else {953 add_post_meta(954 $post_id,955 $v_key,956 ! empty( $_POST[ $v_key ] ) ? $_POST[ $v_key ] : null,957 1958 );959 }960 }961962 if( $page_type && $page_type === ‘copy’ ) {963 $parent_content = $ref_post->post_content;964 $autosave_content = LibSwiftyPluginView::get_instance()->get_autosave_version_if_newer( $parent_id );965966 if( $autosave_content ) {967 $parent_content = $autosave_content;968 }969970 wp_update_post( array(971 ‘ID’ => $post_id,972 ‘post_content’ => $parent_content,973 ) );974 }975 }976977 // Store the new page id in the jstree_select cookie978 setcookie( 'jstree_select’, '#spm-id-' . $post_id );979980 echo '1’;981 } else {982 echo '0’; // fail, tell js983 }984 }985986 exit;987 }988989 /**990 * Called via WP Ajax action ‘wp_ajax_spm_delete_page’ if can_edit_pages991 *992 * Ajax function to delete a page993 */994 public function ajax_delete_page()995 {996 if ( ! current_user_can( ‘delete_pages’ ) ) {997 wp_die( __( ‘You do not have sufficient permissions to access this page. #708’ ) );998 }9991000 header( ‘Content-Type: text/javascript’ );10011002 $post_id = intval( $_POST[‘post_ID’] );10031004 if ( isset( $post_id ) && ! empty( $post_id ) ) {1005 $menu_items = wp_get_associated_nav_menu_items( $post_id, 'post_type’, ‘page’ );10061007 foreach ( $menu_items as $menu_item_id ) {1008 wp_delete_post( $menu_item_id, true );1009 }10101011 wp_delete_post( $post_id, false );1012 }1013 // always refresh the tree1014 echo $this->script_refresh_tree;10151016 exit;1017 }10181019 /**1020 * Called via WP Ajax action ‘wp_ajax_spm_publish_page’ if can_edit_pages1021 *1022 * Ajax function to publish a page1023 */1024 public function ajax_publish_page()1025 {1026 if ( ! current_user_can( ‘publish_pages’ ) ) {1027 wp_die( __( ‘You do not have sufficient permissions to access this page. #747’ ) );1028 }10291030 header( ‘Content-Type: text/javascript’ );10311032 $post_id = intval( $_POST[‘post_ID’] );10331034 if ( isset( $post_id ) && ! empty( $post_id ) ) {1035 $this->_update_post_status( $post_id, ‘publish’ );10361037 // return refresh, unless overwritten in filter (scc wants to run some js code)1038 echo apply_filters( 'swifty_page_manager_publish_ajax_succes’, $this->script_refresh_tree, $post_id );1039 } else {1040 // fail, only refresh tree1041 echo $this->script_refresh_tree;1042 }10431044 exit;1045 }10461047 /**1048 * Called via WP Ajax ‘wp_ajax_spm_post_settings’ if can_edit_pages1049 *1050 * Ajax function to set the settings of a post1051 */1052 public function ajax_post_settings()1053 {1054 if ( ! current_user_can( ‘edit_pages’ ) ) {1055 wp_die( __( ‘You do not have sufficient permissions to access this page. #771’ ) );1056 }10571058 header( ‘Content-Type: text/javascript’ );10591060 $post_id = intval( $_REQUEST[‘post_ID’] );1061 $post = get_post( $post_id );1062 $post_meta = get_post_meta( $post_id );1063 $post_status = ( $post->post_status === ‘private’ ) ? ‘publish’ : $post->post_status; // _status1064 $spm_show_in_menu = ( $post->post_status === ‘private’ ) ? ‘hide’ : 'show’;1065 $spm_is_custom_url = 0;10661067 foreach( $post_meta as $key => $val ) {1068 if( is_array( $val ) && count( $val ) === 1 ) {1069 $post_meta[ $key ] = $val[ 0 ];1070 }1071 }10721073 $defaults = array(1074 ‘spm_show_in_menu’ => 'show’,1075 ‘spm_page_title_seo’ => $post->post_title,1076 );10771078 foreach( $this->areas as $area ) {1079 $defaults[ ‘spm_’ . $area . ‘_visibility’ ] = 'default’;1080 }10811082 if( $this->is_ssm_active ) {1083 $defaults = array_merge( $defaults, array(1084 ‘spm_show_as_first’ => 'show’,1085 ‘spm_alt_menu_text’ => '’1086 ) );1087 }10881089 foreach ( $defaults as $key => $val ) {1090 if ( ! isset( $post_meta[ $key ] ) ) {1091 $post_meta[ $key ] = $val;1092 }1093 }10941095 if ( $this->is_ssm_active ) {1096 if ( ! empty( $post_meta[‘spm_url’] ) ) {1097 $spm_page_url = $post_meta[‘spm_url’];1098 $spm_is_custom_url = 1;1099 } else {1100 $spm_page_url = wp_make_link_relative( get_page_link( $post_id ) );1101 }1102 } else {1103 $spm_page_url = $post->post_name;1104 }11051106 $spm_page_url = trim( $spm_page_url, ‘/’ );11071108 if ( $post_meta[‘spm_show_in_menu’] === ‘show’ ) {1109 // post_status can be private, so then the page must not be visible in the menu.1110 $post_meta[‘spm_show_in_menu’] = $spm_show_in_menu;1111 }11121113 if ( empty( $post_meta[‘spm_show_in_menu’] ) ) {1114 $post_meta[‘spm_show_in_menu’] = 'show’;1115 }11161117 $spm_alt_menu_text = '’;11181119 if( $this->is_ssm_active ) {1120 if( $post_meta[ ‘spm_show_as_first’ ] === ‘hide’ ) {1121 $spm_alt_menu_text = $post_meta[ ‘spm_alt_menu_text’ ];1122 $post_meta[ ‘spm_alt_menu_text’ ] = '’;1123 }1124 }11251126 if( defined( ‘WPSEO_VERSION’ ) && class_exists( ‘WPSEO_Meta’ ) ) {1127 if( empty( $post_meta[‘spm_page_title_seo’] ) ) {1128 $yoastTitle = WPSEO_Meta::get_value( 'title’, $post_id );1129 if( ! empty( $yoastTitle ) ) {1130 // If we don’t have an SPM title, use the Yoast title, if available.1131 $post_meta[‘spm_page_title_seo’] = $yoastTitle;1132 }1133 }11341135 $yoastDescription = WPSEO_Meta::get_value( 'metadesc’, $post_id );1136 if( ! empty( $yoastDescription ) ) {1137 $post_meta[‘spm_page_description_seo’] = $yoastDescription;1138 }11391140 $post_meta[‘yoast_se_noindex’] = WPSEO_Meta::get_value( 'meta-robots-noindex’, $post_id );1141 $post_meta[‘yoast_se_nofollow’] = WPSEO_Meta::get_value( 'meta-robots-nofollow’, $post_id );1142 }11431144 ?>1145 var li = jQuery( ‘#spm-id-<?php echo $post_id; ?>’ );11461147 li.find( ‘#spm_post_name_error’ ).html( ‘’ );1148 li.find( ‘#spm_post_name_message’ ).html( ‘’ );1149 li.find( 'input[name="post_title”]' ).val( <?php echo json_encode( $post->post_title ); ?> );1150 li.find( 'input[name="post_status”]' ).val( [ <?php echo json_encode( $post_status ); ?> ] );1151 li.find( 'input[name="post_name”]' ).val( <?php echo json_encode( $spm_page_url ); ?> );1152 li.find( 'input[name="spm_is_custom_url”]' ).val( <?php echo json_encode( $spm_is_custom_url ); ?> );1153 li.find( 'input[name="spm_show_in_menu”]' ).val( [ <?php echo json_encode( $post_meta[‘spm_show_in_menu’] ); ?> ] );1154 li.find( 'input[name="spm_page_title_seo”]' ).val( <?php echo json_encode( $post_meta[‘spm_page_title_seo’] ); ?> );1155 li.find( 'textarea[name="spm_page_description_seo”]' ).val( <?php echo json_encode( $post_meta[‘spm_page_description_seo’] ); ?> );1156 li.find( 'input[name="spm_se_noindex”]' ).val( [ <?php echo json_encode( $post_meta[‘yoast_se_noindex’] ); ?> ] );1157 li.find( 'input[name="spm_se_nofollow”]' ).val( [ <?php echo json_encode( $post_meta[‘yoast_se_nofollow’] ); ?> ] );1158 <?php if ( $this->is_ssm_active ):1159 foreach( $this->areas as $area ) { ?>1160 li.find( 'input[name="spm_<?php echo $area; ?>_visibility"]' ).val( [ <?php echo json_encode( $post_meta[‘spm_’ . $area . ‘_visibility’] ); ?> ] );1161 <?php } ?>1162 li.find( 'input[name="spm_show_as_first"]' ).val( [ <?php echo json_encode( $post_meta[ ‘spm_show_as_first’ ] ); ?> ] );1163 li.find( 'input[name="spm_alt_menu_text"]' ).val( <?php echo json_encode( $post_meta[ ‘spm_alt_menu_text’ ] ); ?> );11641165 if ( li.find( ‘input[name="spm_show_as_first"]:checked’ ).val() === ‘hide’ ) {1166 li.find( 'input[name="spm_alt_menu_text"]' )1167 .attr( 'data-alt_menu_text’, <?php echo json_encode( $spm_alt_menu_text ); ?> )1168 .prop( ‘disabled’, true )1169 .val( ‘’ );1170 }11711172 <?php endif;1173 exit;1174 }11751176 /**1177 * Called via WP Admin Ajax ‘wp_ajax_spm_sanitize_url’ if can_edit_pages && is_ssm_active1178 *1179 * Ajax function to use Wordpress’ sanitize_title_with_dashes function to prepare an URL string1180 * and check the URL string for uniqueness1181 * _POST[ ‘post_parent’ ] - the parent ID of the post, use -1 with valid post_id to get the parent ID from the post1182 * _POST[ ‘post_id’ ] - the post id, use 0 and valid post_parent for a new post1183 * _POST[ ‘url’ ] - url that will be sanitized / checked1184 * _POST[ ‘path’ ] - is the path of the post_parent, when creating a new post1185 * _POST[ ‘do_sanitize’ ] - 0 or 1 use the WP sanitize functions, used when a post title is used for the url1186 *1187 * returned json1188 * message - result of the call, no errors1189 * error - a error was detected in the given url: wrong characters / existing url1190 * url - if do_sanitize = 1, return the sanitized url, otherwise return the given url1191 *1192 */1193 public function ajax_sanitize_url_and_check()1194 {1195 $result = array();1196 $result[ ‘message’ ] = __( 'Url is unique.’, ‘swifty-page-manager’ ); // no message everything is ok1197 $result[ ‘error’ ] = '’; // no message everything is ok11981199 if( isset( $_POST[ ‘url’ ] ) && isset( $_POST[ ‘post_parent’ ] ) && isset( $_POST[ ‘post_id’ ] ) && isset( $_POST[ ‘path’ ] ) && isset( $_POST[ ‘do_sanitize’ ] ) ) {1200 $url = $_POST[ ‘url’ ];1201 $path = $_POST[ ‘path’ ];1202 $post_id = intval( $_POST[ ‘post_id’ ] );1203 $post_parent = intval( $_POST[ ‘post_parent’ ] );12041205 $url = rtrim( $url, ‘/’ );1206 if( $_POST[ ‘do_sanitize’ ] ) {1207 $url = sanitize_title_with_dashes( $url );1208 }12091210 // this is the sanitize action that will be used when saving settings1211 $post_name = preg_replace("~[ ]~", "-", $url);1212 $post_name = preg_replace("~[^a-z0-9//_-]~i", “", $post_name);12131214 if( $post_name !== $url ) {1215 $result[ ‘message’ ] = '’;1216 $result[ ‘error’ ] = __( 'Url contains forbidden characters.’, ‘swifty-page-manager’ );1217 } else if( $post_id || ($post_parent >= 0)) {1218 // make sure no path delimeters are surrounding the post_name even when path is empty1219 $post_name = trim( $path, ‘/’ ) . ‘/’ . trim( $post_name, ‘/’ );1220 $post_name = trim( $post_name, ‘/’ );12211222 if( ( $post_parent === -1 ) && $post_id ) {1223 $post = get_post( $post_id );1224 $post_parent = $post->post_parent;1225 }12261227 if( ! $this->spm_is_unique_spm_url( $post_id, $post_parent, $post_name ) ) {1228 $result[ ‘message’ ] = '’;1229 $result[ ‘error’ ] = __( 'Url is not unique.’, ‘swifty-page-manager’ );1230 }1231 }1232 $result[ ‘url’ ] = $url;1233 }12341235 echo json_encode( $result );1236 exit;1237 }12381239 /**1240 * Get page tree as PHP class.1241 *1242 * @return StdClass1243 */1244 public function get_tree()1245 {1246 if ( is_null( $this->_tree ) ) {1247 $this->_tree = new StdClass();1248 $this->_tree->menuItem = new StdClass();1249 $this->_tree->menuItem->ID = 0; // Fake menu item as root.1250 $this->_tree->children = array();1251 $this->_by_page_id = array();1252 $this->_by_page_id[0] = &$this->_tree;1253 $this->_add_all_pages();1254 }12551256 return $this->_tree;1257 }12581259 /**1260 * Get the JSON data for a branch of the tree, or the whole tree1261 *1262 * @param $branch1263 * @return array1264 */1265 public function get_json_data( &$branch )1266 {1267 $result = array();1268 $children = $branch->children;12691270 // Sort children by menu_order and post_title1271 usort( $children, array( $this, ‘_sort_children’ ) );12721273 foreach ( $children as $child ) {1274 if ( isset( $child->page ) ) {1275 $new_branch = $this->_get_page_json_data( $child->page );12761277 /**1278 * if no children, output no state1279 * if viewing trash, don’t get children. we watch them “flat” instead1280 */1281 if ( $this->get_post_status() !== ‘trash’ ) {1282 $new_branch[‘children’] = $this->get_json_data( $child );12831284 if ( count( $new_branch[‘children’] ) ) {1285 $new_branch[‘state’] = 'closed’;1286 }1287 }12881289 $result[] = $new_branch;1290 }1291 }12921293 return $result;1294 }12951296 /**1297 * Save an old page URL, we create a redirect for old links from other sites and Google.1298 * USAGE: $this->save_old_url( 469, ‘old/url/path’ );1299 *1300 * @param $post_id1301 * @param $old_url1302 */1303 function save_old_url( $post_id, $old_url )1304 {1305 /** @var wpdb $wpdb - Wordpress Database */1306 global $wpdb;13071308 $old_url = preg_replace( ‘|^’ . preg_quote( get_site_url(), ‘|’ ) . '|’, '’, $old_url ); // Remove root URL1309 $old_url = trim( $old_url, " \t\n\r\0\x0B/” ); // Remove leading and trailing slashes or whitespaces13101311 $exist_query = $wpdb->prepare(1312 "SELECT COUNT(*) FROM $wpdb->postmeta WHERE post_id = %d AND meta_key LIKE ‘spm_old_url_%%’ AND meta_value=’%s’",1313 $post_id,1314 $old_url );13151316 $exists = intval( $wpdb->get_var( $exist_query ) );13171318 if ( ! $exists ) {1319 $last_key_query = $wpdb->prepare(1320 "SELECT REPLACE( meta_key, 'spm_old_url_’, ‘’ ) FROM $wpdb->postmeta WHERE post_id = %d AND meta_key LIKE ‘spm_old_url_%%’ ORDER BY meta_key DESC",1321 $post_id );13221323 $last_key = $wpdb->get_var( $last_key_query );1324 $number = intval( $last_key ) + 1;13251326 add_post_meta( $post_id, ‘spm_old_url_’ . $number, $old_url );1327 }1328 }13291330 /**1331 * Get current post status filter. The user can choose this.1332 * - any1333 * - publish1334 * - trash1335 *1336 * @return string1337 */1338 public function get_post_status()1339 {1340 return $this->_post_status;1341 }13421343 /**1344 * Get the URL of this plugin, for example:1345 * http://domain.com/wp-admin/edit.php?post_type=page&page=page-tree1346 *1347 * @return string1348 */1349 public function get_plugin_url()1350 {1351 return $this->plugin_url;1352 }13531354 /**1355 * Adds the plugin css to the head tag.1356 */1357 public function add_plugin_css()1358 {1359 wp_enqueue_style( 'spm’, $this->plugin_dir_url . '/css/styles.css’, false, $this->_plugin_version );1360 }13611362 ////////////////////////////////////////////////////////////////////////////////////////13631364 /**1365 * Sort children by menu_order and post_title1366 */1367 protected function _sort_children( $a, $b )1368 {1369 $result = 0;13701371 if ( isset( $a->page ) && isset( $b->page ) ) {1372 $result = $a->page->menu_order - $b->page->menu_order;13731374 if ( 0 == $result ) {1375 $result = strcmp( $a->page->post_title, $b->page->post_title );1376 }1377 }13781379 return $result;1380 }13811382 /**1383 * @param integer $post_id1384 * @param string $post_status1385 */1386 protected function _update_post_status( $post_id, $post_status )1387 {1388 if( $this->is_ssm_active && ( $post_status === ‘publish’ ) ) {1389 // use autosave content when publishing, remove autosave (no newer autosave record)1390 $autosave_content = LibSwiftyPluginView::get_instance()->get_autosave_version_if_newer( $post_id );1391 $post_data = array(1392 ‘ID’ => $post_id,1393 ‘post_status’ => $post_status1394 );13951396 if( $autosave_content ) {1397 $post_data[ ‘post_content’ ] = $autosave_content;1398 }13991400 wp_update_post( $post_data );1401 } else {1402 // remember current autosave1403 LibSwiftyPlugin::get_instance()->wp_update_post_keep_autosave( $post_id,1404 array(1405 ‘ID’ => $post_id,1406 ‘post_status’ => $post_status1407 ) );1408 }1409 do_action( 'swifty_page_manager_publish’, $post_id );1410 }14111412 /**1413 *1414 */1415 protected function _add_all_pages()1416 {1417 $args = array();1418 $args[‘post_type’] = 'page’;1419 $args[‘post_status’] = $this->get_post_status();1420 $args[‘numberposts’] = -1;1421 $args[‘orderby’] = 'menu_order title’;1422 $args[‘order’] = 'ASC’;1423 $args[‘suppress_filters’] = 0; // WPML plugin support1424 $pages = get_posts( $args );1425 $added = true;14261427 while ( ! empty( $pages ) && $added ) {1428 $added = false;1429 $keys = array_keys( $pages );14301431 foreach ( $keys as $key ) {1432 $page = $pages[ $key ];14331434 // we now check for this page, when we have the need for blacklisting more pages we can1435 // create a filter for it1436 if( $this->is_ssm_active && ( ‘ninja_forms_preview_page’ === $page->post_title ) ) {1437 unset( $pages[ $key ] );1438 } else {1439 if( isset( $this->_by_page_id[ $page->ID ] ) ) {1440 $branch = &$this->_by_page_id[ $page->ID ];1441 $branch->page = $page;14421443 unset( $branch );1444 unset( $pages[ $key ] );14451446 $added = true;1447 } else if( isset( $this->_by_page_id[ $page->post_parent ] ) ) {1448 $parent_branch = &$this->_by_page_id[ $page->post_parent ];1449 $new_branch = new stdClass();1450 $new_branch->page = $page;1451 $new_branch->children = array();1452 $this->_by_page_id[ $new_branch->page->ID ] = &$new_branch;1453 $parent_branch->children[ ] = &$new_branch; // Warning, does not sort children correctly14541455 unset( $new_branch );1456 unset( $pages[ $key ] );14571458 $added = true;1459 }1460 }1461 }1462 }14631464 // Add rest to root1465 $parent_branch = &$this->_tree;14661467 foreach ( $pages as $page ) {1468 $new_branch = new stdClass();1469 $new_branch->page = $page;1470 $new_branch->children = array();1471 $this->_by_page_id[ $new_branch->page->ID ] = &$new_branch;1472 $parent_branch->children[] = &$new_branch;1473 unset( $new_branch );1474 }1475 }14761477 /**1478 * @param WP_Post $one_page1479 * @return array1480 */1481 protected function _get_page_json_data( $one_page )1482 {1483 $page_json_data = array();14841485 $page_id = $one_page->ID;14861487 $post_statuses = get_post_statuses();1488 $post_type_object = get_post_type_object( $this->_post_type );1489 $editLink = get_edit_post_link( $one_page->ID, ‘notDisplay’ );14901491 // type of node1492 $rel = $one_page->post_status;14931494 if ( $one_page->post_password ) {1495 $rel = 'password’;1496 }14971498 // modified time1499 $post_modified_time = strtotime( $one_page->post_modified );1500 $post_modified_time = date_i18n( get_option( ‘date_format’ ), $post_modified_time, false );15011502 // last edited by1503 setup_postdata( $one_page );15041505 if ( $last_id = get_post_meta( $one_page->ID, '_edit_last’, true ) ) {1506 $last_user = get_userdata( $last_id );15071508 if ( $last_user !== false ) {1509 $post_author = apply_filters( 'the_modified_author’, $last_user->display_name );1510 }1511 }15121513 if ( empty( $post_author ) ) {1514 $post_author = __( 'Unknown user’, ‘swifty-page-manager’ );1515 }15161517 $title = get_the_title( $one_page->ID ); // so hooks and stuff will do their work15181519 if ( empty( $title ) ) {1520 $title = __( '[untitled page]', ‘swifty-page-manager’ );1521 }15221523 $arr_page_css_styles = array();15241525 if ( current_user_can( $post_type_object->cap->edit_post, $page_id ) ) {1526 $arr_page_css_styles[] = 'spm-can-edit’;1527 }15281529 if ( current_user_can( $post_type_object->cap->create_posts, $page_id ) && ‘draft’ !== $one_page->post_status ) {1530 $arr_page_css_styles[] = 'spm-can-add-inside’;1531 }15321533 if ( current_user_can( $post_type_object->cap->create_posts, $one_page->post_parent ) ) {1534 $arr_page_css_styles[] = 'spm-can-add-after’;1535 }15361537 if ( current_user_can( $post_type_object->cap->publish_posts, $page_id ) ) {1538 $arr_page_css_styles[] = 'spm-can-publish’;1539 }15401541 if ( current_user_can( $post_type_object->cap->delete_post, $page_id ) ) {1542 if( !$this->is_ssm_active || $one_page->post_parent ) {1543 $arr_page_css_styles[] = 'spm-can-delete’;1544 } else {1545 // we can not delete the front page1546 if( $this->front_page_id !== $page_id ) {1547 $page_count = count( get_pages( ‘parent=0’ ) );1548 // we are not allowed to remove the last published page1549 if( ( $page_count > 1 ) || ( $one_page->post_status !== ‘publish’ ) ) {1550 $arr_page_css_styles[] = 'spm-can-delete’;1551 }1552 }1553 }1554 }15551556 if ( $this->is_ssm_active ) {1557 $show_page_in_menu = get_post_meta( $page_id, 'spm_show_in_menu’, true );15581559 if ( empty( $show_page_in_menu ) ) {1560 $show_page_in_menu = 'show’;1561 }15621563 $arr_page_css_styles[] = 'spm-show-page-in-menu-' . ( $show_page_in_menu === ‘show’ ? ‘yes’ : ‘no’ );1564 }15651566 $page_json_data[‘data’] = array();1567 $page_json_data[‘data’][‘title’] = $title;15681569 $page_json_data[‘attr’] = array();1570 $page_json_data[‘attr’][‘id’] = 'spm-id-' . $one_page->ID;1571 $page_json_data[‘attr’][‘class’] = join( ' ', $arr_page_css_styles );15721573 $page_json_data[‘metadata’] = array();1574 $page_json_data[‘metadata’][‘id’] = 'spm-id-' . $one_page->ID;1575 $page_json_data[‘metadata’][‘post_id’] = $one_page->ID;1576 $page_json_data[‘metadata’][‘post_type’] = $one_page->post_type;1577 $page_json_data[‘metadata’][‘post_status’] = $one_page->post_status;15781579 if ( isset( $post_statuses[ $one_page->post_status ] ) ) {1580 $page_json_data[‘metadata’][‘post_status_translated’] = $post_statuses[ $one_page->post_status ];1581 } else {1582 $page_json_data[‘metadata’][‘post_status_translated’] = $one_page->post_status;1583 }15841585 $page_json_data[‘metadata’][‘rel’] = $rel;1586 $page_json_data[‘metadata’][‘permalink’] = htmlspecialchars_decode( get_permalink( $one_page->ID ) );1587 $page_json_data[‘metadata’][‘swifty_edit_url’] = add_query_arg( 'swcreator_edit’, 'main’, htmlspecialchars_decode( get_permalink( $one_page->ID ) ) );1588 $page_json_data[‘metadata’][‘editlink’] = htmlspecialchars_decode( $editLink );1589 $page_json_data[‘metadata’][‘modified_time’] = $post_modified_time;1590 $page_json_data[‘metadata’][‘modified_author’] = $post_author;1591 $page_json_data[‘metadata’][‘post_title’] = $title;1592 $page_json_data[‘metadata’][‘delete_nonce’] = wp_create_nonce( ‘delete-page_’ . $one_page->ID, ‘_trash’ );1593 $page_json_data[‘metadata’][‘published_draft_content’] = LibSwiftyPlugin::get_instance()->get_autosave_version_if_newer( $page_id );15941595 return $page_json_data;1596 }15971598 /**1599 * Usage: $seo_version = $this->get_plugin_version(‘wordpress-seo/*’);1600 *1601 * @param string $plugin_match - For example "wordpress-seo/*"1602 * @return bool|string - false if plugin not installed or not active1603 */1604 protected function get_plugin_version( $plugin_match )1605 {1606 $result = false;1607 $regexp = preg_quote( $plugin_match, ‘#’ );1608 $regexp = str_replace( array( '\*’, ‘\?’ ), array( '.*’, ‘.’ ), $regexp );1609 $regexp = ‘#^’ . $regexp . '$#i’;16101611 if ( ! function_exists( ‘get_plugin_data’ ) ) {1612 require_once( ABSPATH . ‘/wp-admin/includes/plugin.php’ );1613 }16141615 $plugins = get_option( 'active_plugins’, array() ); // returns only active plugins16161617 foreach ( $plugins as $plugin ) {1618 if ( preg_match( $regexp, $plugin ) ) {1619 $data = get_plugin_data( WP_PLUGIN_DIR . ‘/’ . $plugin );1620 $result = ( ! empty( $data[‘Version’] ) ) ? $data[‘Version’] : '0.0.1’;16211622 break;1623 }1624 }16251626 return $result;1627 }16281629 /**1630 * Usage: $have_seo = $this->_is_plugin_minimal( 'wordpress-seo/*’, ‘1.0.0’ );1631 *1632 * @param $plugin_match - For example "wordpress-seo/*"1633 * @param $require_version1634 * @return bool|mixed1635 */1636 protected function _is_plugin_minimal( $plugin_match, $require_version )1637 {1638 $result = false;1639 $plugin_version = $this->get_plugin_version( $plugin_match );16401641 if ( $plugin_version ) {1642 $result = version_compare( $plugin_version, $require_version, ‘>=’ );1643 }16441645 return $result;1646 }16471648 /**1649 * Callback function for the wp_list_pages() filter function.1650 *1651 * @param $match - matches from preg_replace_callback1652 * @return string - replacement, $match[0] is replaced by this1653 */1654 protected function _wp_list_pages_replace_callback( $match )1655 {1656 $result = $match[0];1657 $post_id = $match[1];1658 $show = get_post_meta( $post_id, 'spm_show_in_menu’, true );16591660 if ( ! empty( $show ) && ‘hide’ === $show ) {1661 $result .= ' spm-hidden’;1662 };16631664 return $result;1665 }16661667 /**1668 * Return minified filename, if exists; otherwise original filename1669 */1670 protected function _find_minified( $file_name )1671 {1672 $file_name_min = preg_replace( '|\.js$|’, '.min.js’, $file_name );16731674 if ( file_exists( $this->plugin_dir . $file_name_min ) ) {1675 $file_name = $file_name_min;1676 }16771678 return $file_name;1679 }16801681 /**1682 * Get a menu_order space to move/insert a page1683 *1684 * @param WP_Post $ref_post1685 * @param string $direction, can be ‘before’,’after’ or 'inside’1686 * @return int1687 */1688 protected function _createSpaceForMove( $ref_post, $direction = ‘after’ ) {1689 /** @var wpdb $wpdb */1690 global $wpdb;16911692 if ( ‘inside’ === $direction ) {1693 $query = $wpdb->prepare( “SELECT MAX(menu_order) FROM $wpdb->posts WHERE post_parent = %d", $ref_post->ID );1694 $result = $wpdb->get_var( $query ) + 1;1695 } else { // after or before1696 $result = $ref_post->menu_order;16971698 if ( ‘after’ === $direction ) {1699 $result++;1700 }17011702 $posts = get_posts( array(1703 ‘post_status’ => 'any’,1704 ‘post_type’ => $this->_post_type,1705 ‘numberposts’ => -1,1706 ‘offset’ => 0,1707 ‘orderby’ => 'menu_order title’,1708 ‘order’ => 'asc’,1709 ‘post_parent’ => $ref_post->post_parent,1710 ‘suppress_filters’ => false1711 ) );1712 $has_passed_ref_post = false;17131714 foreach ( $posts as $one_post ) {1715 if ( $has_passed_ref_post or ( ‘before’ === $direction && $ref_post->ID === $one_post->ID ) ) {1716 $post_update = array(1717 ‘ID’ => $one_post->ID,1718 ‘menu_order’ => $one_post->menu_order + 21719 );1720 //$return_id = wp_update_post( $post_update, true ); < now keeping autosave1721 $return_id = LibSwiftyPlugin::get_instance()->wp_update_post_keep_autosave( $one_post->ID, $post_update, true );17221723 if (is_wp_error($return_id)) {1724 die( 'Error: could not update post with id ' . $post_update[‘ID’] . '<br>Technical details: ' . print_r( $return_id, true ) );1725 }1726 }17271728 if ( ! $has_passed_ref_post && $ref_post->ID === $one_post->ID ) {1729 $has_passed_ref_post = true;1730 }1731 }1732 }17331734 return $result;1735 }17361737 /**1738 * echo simple language switcher for WPML, ‘sitepress’ is used as plugin translation domain1739 */1740 function admin_language_switcher() {1741 // do nothing if WPML is not active1742 if( ! class_exists( ‘SitePress’ ) ) {1743 return;1744 }1745 // If check_settings_integrity exists then it should not fail, otherwise ignore.1746 if( method_exists( 'SitePress’, ‘check_settings_integrity’ ) && ! SitePress::check_settings_integrity() ) {1747 return;1748 }17491750 global $sitepress;17511752 // We need those methods, so make sure they are available.1753 if( !method_exists( $sitepress, ‘get_current_language’ ) ||1754 !method_exists( $sitepress, ‘get_default_language’ ) ||1755 !method_exists( $sitepress, ‘get_active_languages’ )) {1756 return;1757 }17581759 $languages_links = array();17601761 $current_language = $sitepress->get_current_language();1762 $current_language = $current_language ? $current_language : $sitepress->get_default_language();17631764 if ( isset( $_SERVER[ ‘QUERY_STRING’ ] ) ) {1765 parse_str( $_SERVER[ ‘QUERY_STRING’ ], $query_vars );1766 unset( $query_vars[ ‘lang’ ], $query_vars[ ‘admin_bar’ ] );1767 } else {1768 $query_vars = array();1769 }1770 $query_string = http_build_query( $query_vars );1771 if ( empty( $query_string ) ) {1772 $query_string = '?’;1773 } else {1774 $query_string = ‘?’ . $query_string . '&’;1775 }17761777 foreach ( $sitepress->get_active_languages() as $lang ) {17781779 $query = $query_string . ‘lang=’ . $lang[ ‘code’ ]; // the default language need to specified explicitly yoo in order to set the lang cookie17801781 $link_url = admin_url( basename( $_SERVER[ ‘SCRIPT_NAME’ ] ) . $query );17821783 $languages_links[ $lang[ ‘code’ ] ] = array(1784 ‘url’ => $link_url,1785 ‘current’ => $lang[ ‘code’ ] == $current_language,1786 ‘anchor’ => $lang[ ‘display_name’ ]1787 );1788 }17891790 $query = $query_string . 'lang=all’;1791 $link_url = admin_url( basename( $_SERVER[ ‘SCRIPT_NAME’ ] ) . $query );17921793 $languages_links[ ‘all’ ] = array(1794 ‘url’ => $link_url, ‘current’ => ‘all’ == $current_language, ‘anchor’ => __( 'All languages’, ‘sitepress’ )1795 );17961797 // We start with the current language in our select.1798 $lang = $languages_links[ $current_language ];17991800 if ( $languages_links ) {1801?>1802<select onchange="window.location=this.value” style="margin: 0 0 0 20px;">1803<option value="<?php echo esc_url( $lang[ ‘url’ ] ); ?>"><?php echo $lang[ ‘anchor’ ]; ?></option>1804<?php1805 foreach ( $languages_links as $code => $lang ) {1806 if ( $code == $current_language )1807 continue;1808 ?>1809 <option value="<?php echo esc_url( $lang[ ‘url’ ] ); ?>"><?php echo $lang[ ‘anchor’ ]; ?></option>1810 <?php1811 }1812?>1813</select>1814<?php1815 }1816 }18171818} // End of class SwiftyPageManager18191820// Start the plugin1821$SwiftyPageManager = new SwiftyPageManager();

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda
CVE-2023-6905
CVE-2023-6903
CVE-2023-6904
CVE-2023-3907