1550 lines
45 KiB
PHP
1550 lines
45 KiB
PHP
<?php
|
||
defined( 'ABSPATH' ) or die();
|
||
|
||
/**
|
||
* Enqueue Gutenberg block assets for backend editor.
|
||
*
|
||
* @since 1.0.0
|
||
*/
|
||
require_once burst_path . 'settings/config/config.php';
|
||
require_once burst_path . 'settings/rest-api-optimizer/rest-api-optimizer.php';
|
||
require_once burst_path . 'settings/media/media-override.php';
|
||
|
||
/**
|
||
* WordPress doesn't allow for translation of chunks resulting of code splitting.
|
||
* Several workarounds have popped up in JetPack and Woocommerce: https://developer.wordpress.com/2022/01/06/wordpress-plugin-i18n-webpack-and-composer/
|
||
* Below is mainly based on the Woocommerce solution, which seems to be the most simple approach. Simplicity is king here.
|
||
*
|
||
* @return array
|
||
*/
|
||
function burst_get_chunk_translations( $dir ): array
|
||
{
|
||
$text_domain = 'burst-statistics';
|
||
$languages_dir = defined('burst_pro') ? burst_path . 'languages' : WP_CONTENT_DIR . '/languages/plugins';
|
||
$json_translations = [];
|
||
$locale = determine_locale();
|
||
$languages = [];
|
||
|
||
if ( is_dir($languages_dir) ) {
|
||
// Get all JSON files matching text domain & locale
|
||
foreach (glob("$languages_dir/{$text_domain}-{$locale}-*.json") as $language_file) {
|
||
$languages[] = basename($language_file);
|
||
}
|
||
}
|
||
|
||
foreach ($languages as $src) {
|
||
$hash = str_replace([$text_domain . '-', $locale . '-', '.json'], '', $src);
|
||
wp_register_script($hash, plugins_url($src, __FILE__), [], true);
|
||
$localeData = load_script_textdomain($hash, $text_domain, $languages_dir);
|
||
wp_deregister_script($hash);
|
||
|
||
if ( !empty($localeData) ) {
|
||
$json_translations[] = $localeData;
|
||
}
|
||
}
|
||
$js_files = glob(burst_path . $dir."/index*.js");
|
||
$asset_files = glob(burst_path . $dir."/index*.asset.php");
|
||
$js_filename = !empty($js_files) ? basename($js_files[0]) : '';
|
||
$asset_filename = !empty($asset_files) ? basename($asset_files[0]) : '';
|
||
$asset_file = require burst_path . $dir . '/' . $asset_filename;
|
||
|
||
if ( empty( $js_filename ) ) {
|
||
return [];
|
||
}
|
||
|
||
return [
|
||
'json_translations' => $json_translations,
|
||
'js_file' => $js_filename,
|
||
'dependencies' => $asset_file['dependencies'],
|
||
'version' => $asset_file['version'],
|
||
];
|
||
}
|
||
|
||
function burst_plugin_admin_scripts() {
|
||
$js_data = burst_get_chunk_translations( 'settings/build' );
|
||
if ( empty( $js_data ) ) {
|
||
return;
|
||
}
|
||
burst_wp_enqueue_media();
|
||
wp_enqueue_script(
|
||
'burst-settings',
|
||
plugins_url( 'build/' . $js_data['js_file'], __FILE__ ),
|
||
$js_data['dependencies'],
|
||
$js_data['version'],
|
||
true
|
||
);
|
||
$path = defined( 'burst_pro' ) ? burst_path . 'languages' : false;
|
||
wp_set_script_translations( 'burst-settings', 'burst-statistics', $path );
|
||
|
||
wp_localize_script(
|
||
'burst-settings',
|
||
'burst_settings',
|
||
burst_localized_settings( $js_data )
|
||
);
|
||
}
|
||
|
||
function burst_localized_settings( $js_data ) {
|
||
return apply_filters(
|
||
'burst_localize_script',
|
||
[
|
||
'json_translations' => $js_data['json_translations'],
|
||
'menu' => burst_menu(),
|
||
'site_url' => get_rest_url(),
|
||
'admin_ajax_url' => add_query_arg( array( 'action' => 'burst_rest_api_fallback' ), admin_url( 'admin-ajax.php' ) ),
|
||
'dashboard_url' => burst_admin_url( 'burst' ),
|
||
'plugin_url' => burst_url,
|
||
'network_link' => network_site_url( 'plugins.php' ),
|
||
'is_pro' => burst_is_pro(),
|
||
'nonce' => wp_create_nonce( 'wp_rest' ), // to authenticate the logged in user
|
||
'burst_nonce' => wp_create_nonce( 'burst_nonce' ),
|
||
'current_ip' => burst_get_ip_address(),
|
||
'user_roles' => burst_get_user_roles(),
|
||
'date_ranges' => burst_get_date_ranges(),
|
||
'date_format' => get_option( 'date_format' ),
|
||
'tour_shown' => burst_get_option( 'burst_tour_shown_once' ),
|
||
'gmt_offset' => get_option( 'gmt_offset' ),
|
||
'goals_information_shown' => (int) get_option( 'burst_goals_information_shown' ),
|
||
'burst_version' => burst_version,
|
||
'burst_pro' => defined( 'burst_pro' ),
|
||
]
|
||
);
|
||
}
|
||
|
||
/**
|
||
* If the rest api is blocked, the code will try an admin ajax call as fall back.
|
||
*
|
||
* @return void
|
||
*/
|
||
function burst_rest_api_fallback() {
|
||
$response = [];
|
||
$error = $action = $do_action = $data = $data_type = false;
|
||
if ( ! burst_user_can_view() ) {
|
||
$error = true;
|
||
}
|
||
|
||
// if the site is using this fallback, we want to show a notice
|
||
update_option( 'burst_ajax_fallback_active', time(), false );
|
||
if ( isset( $_GET['rest_action'] ) ) {
|
||
$action = sanitize_text_field( $_GET['rest_action'] );
|
||
if ( strpos( $action, 'burst/v1/data/' ) !== false ) {
|
||
$data_type = strtolower( str_replace( 'burst/v1/data/', '', $action ) );
|
||
}
|
||
}
|
||
|
||
// get all of the rest of the $_GET parameters so we can forward them in the REST request
|
||
$get_params = $_GET;
|
||
// remove the rest_action parameter
|
||
unset($get_params['rest_action']);
|
||
|
||
// convert get metrics to array if it is a string
|
||
if ( isset( $get_params['metrics'] ) && is_string( $get_params['metrics'] ) ) {
|
||
$get_params['metrics'] = explode(',', $get_params['metrics']);
|
||
}
|
||
|
||
// Handle filters - check if it's a string and needs slashes removed
|
||
if ( isset( $get_params['filters'] ) ) {
|
||
if (is_string($get_params['filters'])) {
|
||
// Remove slashes but keep as JSON string for later decoding
|
||
$get_params['filters'] = stripslashes($get_params['filters']);
|
||
}
|
||
}
|
||
|
||
|
||
|
||
$requestData = json_decode( file_get_contents( 'php://input' ), true );
|
||
if ( $requestData ) {
|
||
$action = $requestData['path'] ?? false;
|
||
|
||
$action = sanitize_text_field( $action );
|
||
$data = $requestData['data'] ?? false;
|
||
if ( strpos( $action, 'burst/v1/do_action/' ) !== false ) {
|
||
$do_action = strtolower( str_replace( 'burst/v1/do_action/', '', $action ) );
|
||
}
|
||
}
|
||
|
||
|
||
$request = new WP_REST_Request();
|
||
$args = array( 'type', 'nonce', 'date_start', 'date_end', 'args', 'search', 'filters', 'metrics', 'group_by' );
|
||
foreach ( $args as $arg ) {
|
||
if ( isset( $get_params[ $arg ] ) ) {
|
||
$request->set_param( $arg, $get_params[ $arg ] );
|
||
}
|
||
}
|
||
|
||
if ( ! $error ) {
|
||
if ( strpos( $action, '/fields/get' ) !== false ) {
|
||
$response = burst_rest_api_fields_get( $request );
|
||
} elseif ( strpos( $action, '/fields/set' ) !== false ) {
|
||
$response = burst_rest_api_fields_set( $request, $data );
|
||
} elseif ( strpos( $action, '/options/set' ) !== false ) {
|
||
$response = burst_rest_api_options_set( $request, $data );
|
||
} elseif ( strpos( $action, '/goals/get' ) !== false ) {
|
||
$response = burst_rest_api_goals_get( $request );
|
||
} elseif ( strpos( $action, '/goals/add' ) !== false ) {
|
||
$response = burst_rest_api_goals_add( $request, $data );
|
||
} elseif ( strpos( $action, '/goals/delete' ) !== false ) {
|
||
$response = burst_rest_api_goals_delete( $request, $data );
|
||
} elseif ( strpos( $action, '/goal_fields/get' ) !== false ) {
|
||
$response = burst_rest_api_goal_fields_get( $request );
|
||
} elseif ( strpos( $action, '/goals/set' ) !== false ) {
|
||
$response = burst_rest_api_goals_set( $request, $data );
|
||
} elseif ( strpos( $action, '/posts/' ) !== false ) {
|
||
$response = burst_get_posts( $request, $data );
|
||
} elseif ( strpos( $action, '/data/' ) ) {
|
||
$request->set_param( 'type', $data_type );
|
||
$response = burst_get_data( $request );
|
||
} elseif ( $do_action ) {
|
||
$request = new WP_REST_Request();
|
||
$request->set_param( 'action', $do_action );
|
||
$response = burst_do_action( $request, $data );
|
||
}
|
||
}
|
||
|
||
header( 'Content-Type: application/json' );
|
||
echo json_encode( $response );
|
||
exit;
|
||
}
|
||
|
||
add_action( 'wp_ajax_burst_rest_api_fallback', 'burst_rest_api_fallback' );
|
||
|
||
function burst_add_option_menu() {
|
||
if ( ! burst_user_can_view() ) {
|
||
return;
|
||
}
|
||
|
||
// if track network wide is enabled, show the menu only on the main site
|
||
if ( is_multisite() && get_site_option( 'burst_track_network_wide' ) && burst_is_networkwide_active() ) {
|
||
if ( ! is_main_site() ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
$menu_label = __( 'Statistics', 'burst-statistics' );
|
||
$warnings = BURST()->notices->count_plusones( array( 'plus_ones' => true ) );
|
||
$warning_title = esc_attr( burst_sprintf( '%d plugin warnings', $warnings ) );
|
||
if ( $warnings > 0 ) {
|
||
$warning_title .= ' ' . esc_attr( burst_sprintf( '(%d plus ones)', $warnings ) );
|
||
$menu_label .=
|
||
"<span class='update-plugins count-$warnings' title='$warning_title'>
|
||
<span class='update-count'>
|
||
" . number_format_i18n( $warnings ) . '
|
||
</span>
|
||
</span>';
|
||
}
|
||
|
||
$page_hook_suffix = add_menu_page(
|
||
'Burst Statistics',
|
||
$menu_label,
|
||
'view_burst_statistics',
|
||
'burst',
|
||
'burst_dashboard',
|
||
burst_url . 'assets/img/burst-wink.svg',
|
||
apply_filters('burst_menu_position', 3)
|
||
);
|
||
|
||
add_submenu_page(
|
||
'burst',
|
||
__('Statistics', 'burst-statistics'),
|
||
__('Statistics', 'burst-statistics'),
|
||
'view_burst_statistics',
|
||
'burst#statistics',
|
||
'burst_dashboard'
|
||
);
|
||
|
||
add_submenu_page(
|
||
'burst',
|
||
__('Settings', 'burst-statistics'),
|
||
__('Settings', 'burst-statistics'),
|
||
'view_burst_statistics',
|
||
'burst#settings',
|
||
'burst_dashboard'
|
||
);
|
||
|
||
if ( !defined( 'burst_pro' ) ) {
|
||
global $submenu;
|
||
if (isset($submenu['burst'])) {
|
||
$class = 'burst-link-upgrade';
|
||
$highest_index = count($submenu['burst']);
|
||
$submenu['burst'][] = array(
|
||
__( 'Upgrade to Pro', 'burst-statistics' ),
|
||
'manage_burst_statistics',
|
||
burst_get_website_url('pricing/', ['burst_source' => 'plugin-submenu-upgrade'])
|
||
);
|
||
if ( isset( $submenu['burst'][$highest_index] ) ) {
|
||
if (! isset ($submenu['burst'][$highest_index][4])) $submenu['burst'][$highest_index][4] = '';
|
||
$submenu['burst'][$highest_index][4] .= ' ' . $class;
|
||
}
|
||
}
|
||
}
|
||
|
||
add_action( "admin_print_scripts-{$page_hook_suffix}", 'burst_plugin_admin_scripts' );
|
||
}
|
||
add_action( 'admin_menu', 'burst_add_option_menu' );
|
||
|
||
function burst_fix_duplicate_menu_item() {
|
||
?>
|
||
<script>
|
||
window.addEventListener("load", () => {
|
||
let burstMain = document.querySelector('li.wp-has-submenu.toplevel_page_burst a.wp-first-item');
|
||
if (burstMain) {
|
||
burstMain.innerHTML = burstMain.innerHTML.replace('<?php esc_html_e(__( 'Statistics', 'burst-statistics'))?>', '<?php esc_html_e(__( 'Dashboard', 'burst-statistics'))?>');
|
||
}
|
||
});
|
||
</script>
|
||
|
||
<?php
|
||
/**
|
||
* Ensure the items are selected in sync with the burst react menu.
|
||
*/
|
||
if(isset($_GET['page']) && $_GET['page']==='burst') {
|
||
?>
|
||
<script>
|
||
const burstSetActive = (obj) => {
|
||
obj.classList.add('current');
|
||
obj.parentNode.classList.add('current');
|
||
}
|
||
|
||
window.addEventListener("load", () => {
|
||
let burstMain = document.querySelector('li.wp-has-submenu.toplevel_page_burst a.wp-first-item');
|
||
if (burstMain) {
|
||
burstMain.href = '#';
|
||
}
|
||
});
|
||
//get the hash from the current url
|
||
let burstHash = window.location.hash;
|
||
//strip off anything after a /
|
||
if ( burstHash.indexOf('/') !== -1 ) {
|
||
burstHash = burstHash.substring(0, burstHash.indexOf('/'));
|
||
}
|
||
if ( !burstHash ) {
|
||
let burstMain = document.querySelector('li.wp-has-submenu.toplevel_page_burst a.wp-first-item');
|
||
burstSetActive(burstMain);
|
||
} else {
|
||
let burstMenuItems = document.querySelector('li.wp-has-submenu.toplevel_page_burst').querySelectorAll('a');
|
||
for (const link of burstMenuItems) {
|
||
if (burstHash && link.href.indexOf(burstHash) !== -1) {
|
||
burstSetActive(link);
|
||
} else {
|
||
link.classList.remove('current');
|
||
link.parentNode.classList.remove('current');
|
||
}
|
||
}
|
||
}
|
||
|
||
window.addEventListener('click', (e) => {
|
||
const burstTargetHref = e.target && e.target.href;
|
||
let burstIsMainMenu = false;
|
||
let burstIsWpMenu = false;
|
||
if (burstTargetHref && e.target.classList.contains('burst-main')) {
|
||
burstIsMainMenu = true;
|
||
} else if (burstTargetHref && burstTargetHref.indexOf('admin.php')!==-1) {
|
||
burstIsWpMenu = true;
|
||
}
|
||
if (!burstIsWpMenu && !burstIsMainMenu) {
|
||
return;
|
||
}
|
||
if (burstIsWpMenu) {
|
||
if (burstTargetHref && burstTargetHref.indexOf('page=burst') !== -1) {
|
||
const parentElement = e.target.parentNode.parentNode;
|
||
const childLinks = parentElement.querySelectorAll('li, a');
|
||
// Loop through each 'a' element and add the class
|
||
for (const link of childLinks) {
|
||
link.classList.remove('current');
|
||
}
|
||
e.target.classList.add('current');
|
||
e.target.parentNode.classList.add('current');
|
||
}
|
||
} else {
|
||
//find burstTargetHref in wordpress menu
|
||
let burstMenuItems = document.querySelector('li.wp-has-submenu.toplevel_page_burst').querySelectorAll('a');
|
||
for (const link of burstMenuItems) {
|
||
//check if last character of link.href is '#'
|
||
if (burstTargetHref.indexOf('dashboard')!==-1 && link.href.charAt(link.href.length - 1) === '#'){
|
||
burstSetActive(link);
|
||
} else if (burstTargetHref && link.href.indexOf(burstTargetHref) !== -1) {
|
||
burstSetActive(link);
|
||
} else {
|
||
link.classList.remove('current');
|
||
link.parentNode.classList.remove('current');
|
||
}
|
||
}
|
||
}
|
||
});
|
||
</script>
|
||
<?php
|
||
}
|
||
}
|
||
add_action('admin_footer', 'burst_fix_duplicate_menu_item', 1);
|
||
|
||
function burst_remove_fallback_notice() {
|
||
if ( get_option( 'burst_ajax_fallback_active' ) !== false ) {
|
||
delete_option( 'burst_ajax_fallback_active' );
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Render the settings page
|
||
*/
|
||
function burst_dashboard() {
|
||
if ( ! burst_user_can_view() ) {
|
||
return;
|
||
}
|
||
?>
|
||
<div id="burst-statistics" class="burst">
|
||
<div class="burst-header-container">
|
||
<div class="burst-header">
|
||
<img class="burst-logo"
|
||
src="<?php echo burst_url . 'assets/img/burst-logo.svg'; ?>"
|
||
alt="Burst Statistics logo"/>
|
||
</div>
|
||
</div>
|
||
<div class="burst-content-area burst-grid burst-dashboard burst-page-placeholder">
|
||
<div class="burst-grid-item burst-column-2 burst-row-2 "></div>
|
||
<div class="burst-grid-item burst-row-2"></div>
|
||
<div class="burst-grid-item burst-row-2"></div>
|
||
<div class="burst-grid-item burst-column-2"></div>
|
||
</div>
|
||
</div>
|
||
<div id="burst-statistics-modal"></div>
|
||
<?php
|
||
}
|
||
|
||
add_action( 'rest_api_init', 'burst_settings_rest_route', 1 );
|
||
function burst_settings_rest_route() {
|
||
register_rest_route(
|
||
'burst/v1',
|
||
'menu',
|
||
array(
|
||
'methods' => 'GET',
|
||
'callback' => 'burst_rest_api_menu',
|
||
'permission_callback' => function () {
|
||
return burst_user_can_manage();
|
||
},
|
||
)
|
||
);
|
||
|
||
// setOption
|
||
register_rest_route(
|
||
'burst/v1',
|
||
'options/set',
|
||
array(
|
||
'methods' => 'POST',
|
||
'callback' => 'burst_rest_api_options_set',
|
||
'permission_callback' => function () {
|
||
return burst_user_can_manage();
|
||
},
|
||
)
|
||
);
|
||
|
||
register_rest_route(
|
||
'burst/v1',
|
||
'fields/get',
|
||
[
|
||
'methods' => 'GET',
|
||
'callback' => 'burst_rest_api_fields_get',
|
||
'permission_callback' => function () {
|
||
return burst_user_can_manage();
|
||
},
|
||
]
|
||
);
|
||
|
||
register_rest_route(
|
||
'burst/v1',
|
||
'fields/set',
|
||
[
|
||
'methods' => 'POST',
|
||
'callback' => 'burst_rest_api_fields_set',
|
||
'permission_callback' => function () {
|
||
return burst_user_can_manage();
|
||
},
|
||
]
|
||
);
|
||
|
||
register_rest_route(
|
||
'burst/v1',
|
||
'goals/get',
|
||
[
|
||
'methods' => 'GET',
|
||
'callback' => 'burst_rest_api_goals_get',
|
||
'permission_callback' => function () {
|
||
return burst_user_can_view();
|
||
},
|
||
]
|
||
);
|
||
|
||
register_rest_route(
|
||
'burst/v1',
|
||
'goals/delete',
|
||
[
|
||
'methods' => 'POST',
|
||
'callback' => 'burst_rest_api_goals_delete',
|
||
'permission_callback' => function () {
|
||
return burst_user_can_manage();
|
||
},
|
||
]
|
||
);
|
||
|
||
register_rest_route(
|
||
'burst/v1',
|
||
'goals/add_predefined',
|
||
[
|
||
'methods' => 'POST',
|
||
'callback' => 'burst_rest_api_goals_add_predefined',
|
||
'permission_callback' => function () {
|
||
return burst_user_can_manage();
|
||
},
|
||
]
|
||
);
|
||
// add_predefined
|
||
register_rest_route(
|
||
'burst/v1',
|
||
'goals/add',
|
||
[
|
||
'methods' => 'POST',
|
||
'callback' => 'burst_rest_api_goals_add',
|
||
'permission_callback' => function () {
|
||
return burst_user_can_manage();
|
||
},
|
||
]
|
||
);
|
||
|
||
register_rest_route(
|
||
'burst/v1',
|
||
'goals/set',
|
||
[
|
||
'methods' => 'POST',
|
||
'callback' => 'burst_rest_api_goals_set',
|
||
'permission_callback' => function () {
|
||
return burst_user_can_manage();
|
||
},
|
||
]
|
||
);
|
||
|
||
register_rest_route(
|
||
'burst/v1',
|
||
'data/(?P<type>[a-z\_\-]+)',
|
||
[
|
||
'methods' => 'GET',
|
||
'callback' => 'burst_get_data',
|
||
'permission_callback' => function () {
|
||
return burst_user_can_view();
|
||
},
|
||
]
|
||
);
|
||
|
||
register_rest_route(
|
||
'burst/v1',
|
||
'do_action/(?P<action>[a-z\_\-]+)',
|
||
[
|
||
'methods' => 'POST',
|
||
'callback' => 'burst_do_action',
|
||
'permission_callback' => function () {
|
||
return burst_user_can_view();
|
||
},
|
||
]
|
||
);
|
||
|
||
register_rest_route(
|
||
'burst/v1',
|
||
'/posts/',
|
||
[
|
||
'methods' => 'GET',
|
||
'callback' => 'burst_get_posts',
|
||
'args' => [
|
||
'search_input' => [
|
||
'required' => false,
|
||
'sanitize_callback' => 'sanitize_title',
|
||
],
|
||
],
|
||
'permission_callback' => function () {
|
||
return burst_user_can_manage();
|
||
},
|
||
]
|
||
);
|
||
}
|
||
|
||
|
||
/**
|
||
* @param WP_REST_Request $request
|
||
*
|
||
* @return WP_REST_Response | WP_Error
|
||
*/
|
||
function burst_do_action( $request, $ajax_data = false ) {
|
||
if ( ! burst_user_can_view() ) {
|
||
return new WP_Error( 'rest_forbidden', 'You do not have permission to perform this action.', [ 'status' => 403 ] );
|
||
}
|
||
$action = sanitize_title( $request->get_param( 'action' ) );
|
||
$data = $ajax_data ?: $request->get_params();
|
||
$nonce = $data['nonce'];
|
||
if ( ! burst_verify_nonce( $nonce, 'burst_nonce' ) ) {
|
||
return new WP_Error( 'rest_invalid_nonce', 'The provided nonce is not valid.', [ 'status' => 400 ] );
|
||
}
|
||
|
||
$data = $data['action_data'];
|
||
if ( ! $ajax_data ) {
|
||
burst_remove_fallback_notice();
|
||
}
|
||
|
||
switch ( $action ) {
|
||
case 'plugin_actions':
|
||
$data = burst_plugin_actions( $request, $data );
|
||
break;
|
||
case 'notices':
|
||
$data = BURST()->notices->get();
|
||
break;
|
||
case 'dismiss_task':
|
||
$data = BURST()->notices->dismiss_notice( $data );
|
||
break;
|
||
case 'otherpluginsdata':
|
||
$data = burst_other_plugins_data();
|
||
break;
|
||
case 'tracking':
|
||
$data = BURST()->endpoint->get_tracking_status_and_time();
|
||
break;
|
||
default:
|
||
$data = apply_filters( 'burst_do_action', array(), $action, $data );
|
||
}
|
||
|
||
if ( ob_get_length() ) {
|
||
ob_clean();
|
||
}
|
||
|
||
return new WP_REST_Response(
|
||
[
|
||
'data' => $data,
|
||
'request_success' => true,
|
||
],
|
||
200
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Process plugin installation or activation actions
|
||
*
|
||
* @param WP_REST_Request $request
|
||
*
|
||
* @return array
|
||
*/
|
||
function burst_plugin_actions( $request, $data ) {
|
||
if ( ! burst_user_can_manage() ) {
|
||
return array();
|
||
}
|
||
$slug = sanitize_title( $data['slug'] );
|
||
$action = sanitize_title( $data['pluginAction'] );
|
||
$installer = new burst_installer( $slug );
|
||
if ( $action === 'download' ) {
|
||
$installer->download_plugin();
|
||
} elseif ( $action === 'activate' ) {
|
||
$installer->activate_plugin();
|
||
}
|
||
|
||
return burst_other_plugins_data( $slug );
|
||
}
|
||
|
||
/**
|
||
* Get plugin data for other plugin section
|
||
*
|
||
* @param string $slug
|
||
*
|
||
* @return array
|
||
*/
|
||
function burst_other_plugins_data( $slug = false ) {
|
||
if ( ! burst_user_can_view() ) {
|
||
return array();
|
||
}
|
||
$plugins = [
|
||
[
|
||
'slug' => 'all-in-one-wp-security-and-firewall',
|
||
'constant_free' => 'AIO_WP_SECURITY_VERSION',
|
||
'constant_pro' => false,
|
||
'wordpress_url' => 'https://wordpress.org/plugins/all-in-one-wp-security-and-firewall/',
|
||
'upgrade_url' => 'https://aiosplugin.com/product/all-in-one-wp-security-and-firewall-premium/?src=plugin-burst-other-plugins',
|
||
'title' => 'All-In-One Security – Simply secure your site',
|
||
],
|
||
[
|
||
'slug' => 'updraftplus',
|
||
'constant_free' => 'UPDRAFTPLUS_DIR',
|
||
'constant_pro' => false,
|
||
'wordpress_url' => 'https://wordpress.org/plugins/updraftplus/',
|
||
'upgrade_url' => 'https://updraftplus.com/shop/updraftplus-premium/?src=plugin-burst-other-plugins',
|
||
'title' => 'UpdraftPlus - Back-up & migrate your site with ease',
|
||
],
|
||
[
|
||
'slug' => 'wp-optimize',
|
||
'constant_free' => 'WPO_VERSION',
|
||
'wordpress_url' => 'https://wordpress.org/plugins/wp-optimize/',
|
||
'upgrade_url' => 'https://getwpo.com/buy/?src=plugin-burst-other-plugins',
|
||
'title' => 'WP-Optimize – Easily boost your page speed',
|
||
],
|
||
];
|
||
|
||
foreach ( $plugins as $index => $plugin ) {
|
||
$installer = new burst_installer( $plugin['slug'] );
|
||
if ( isset( $plugin['constant_pro'] ) && defined( $plugin['constant_pro'] ) ) {
|
||
$plugins[ $index ]['pluginAction'] = 'installed';
|
||
} elseif ( ! $installer->plugin_is_downloaded() && ! $installer->plugin_is_activated() ) {
|
||
$plugins[ $index ]['pluginAction'] = 'download';
|
||
} elseif ( $installer->plugin_is_downloaded() && ! $installer->plugin_is_activated() ) {
|
||
$plugins[ $index ]['pluginAction'] = 'activate';
|
||
} elseif ( isset( $plugin['constant_pro'] ) ) {
|
||
$plugins[ $index ]['pluginAction'] = 'upgrade-to-pro';
|
||
} else {
|
||
$plugins[ $index ]['pluginAction'] = 'installed';
|
||
}
|
||
}
|
||
|
||
if ( $slug ) {
|
||
foreach ( $plugins as $plugin ) {
|
||
if ( $plugin['slug'] === $slug ) {
|
||
return $plugin;
|
||
}
|
||
}
|
||
}
|
||
|
||
return $plugins;
|
||
}
|
||
|
||
/**
|
||
* @param WP_REST_Request $request
|
||
*
|
||
* @return WP_Error | WP_REST_Response
|
||
*/
|
||
function burst_get_data( WP_REST_Request $request ) {
|
||
if ( ! burst_user_can_view() ) {
|
||
return new WP_Error( 'rest_forbidden', 'You do not have permission to perform this action.', [ 'status' => 403 ] );
|
||
}
|
||
$nonce = $request->get_param( 'nonce' );
|
||
if ( ! burst_verify_nonce( $nonce, 'burst_nonce' ) ) {
|
||
return new WP_Error( 'rest_invalid_nonce', 'The provided nonce is not valid.', [ 'status' => 400 ] );
|
||
}
|
||
|
||
$type = sanitize_title( $request->get_param( 'type' ) );
|
||
//in the database, the UTC time is stored, so we query by the corrected unix time.
|
||
$args = [
|
||
'date_start' => BURST()->statistics->convert_date_to_unix( $request->get_param( 'date_start' ) . ' 00:00:00' ),
|
||
// add 00:00:00 to date,
|
||
'date_end' => BURST()->statistics->convert_date_to_unix( $request->get_param( 'date_end' ) . ' 23:59:59' ),
|
||
// add 23:59:59 to date
|
||
];
|
||
|
||
|
||
// possible args
|
||
$available_args = ['filters', 'metrics', 'group_by'];
|
||
// check for args from $request->get_param( 'filters') etc. and add to $args
|
||
foreach ($available_args as $arg) {
|
||
if ($request->get_param($arg)) {
|
||
$args[$arg] = $request->get_param($arg);
|
||
}
|
||
}
|
||
|
||
$args['filters'] = isset($args['filters']) ? burst_sanitize_filters( json_decode($args['filters'])) : array();
|
||
|
||
switch ( $type ) {
|
||
case 'live-visitors':
|
||
$data = BURST()->statistics->get_live_visitors_data();
|
||
break;
|
||
case 'today':
|
||
$data = BURST()->statistics->get_today_data( $args );
|
||
break;
|
||
case 'goals':
|
||
$args['goal_id'] = $request_args['goal_id'] ?? 0;
|
||
$data = BURST()->goal_statistics->get_goals_data( $args );
|
||
break;
|
||
case 'live-goals':
|
||
$args['goal_id'] = $request_args['goal_id'] ?? 0;
|
||
$data = BURST()->goal_statistics->get_live_goals_data( $args );
|
||
break;
|
||
case 'insights':
|
||
$data = BURST()->statistics->get_insights_data( $args );
|
||
break;
|
||
case 'compare':
|
||
if ( isset( $args['filters']['goal_id'] ) ) {
|
||
$data = BURST()->statistics->get_compare_goals_data( $args );
|
||
} else {
|
||
$data = BURST()->statistics->get_compare_data( $args );
|
||
}
|
||
break;
|
||
case 'devicestitleandvalue':
|
||
$data = BURST()->statistics->get_devices_title_and_value_data( $args );
|
||
break;
|
||
case 'devicessubtitle':
|
||
$data = BURST()->statistics->get_devices_subtitle_data( $args );
|
||
break;
|
||
case 'datatable':
|
||
$data = BURST()->statistics->get_datatables_data( $args );
|
||
break;
|
||
case 'referrers':
|
||
$data = BURST()->statistics->get_referrers_data( $args );
|
||
break;
|
||
default:
|
||
$data = apply_filters( 'burst_get_data', [], $type, $args, $request );
|
||
}
|
||
if ( ob_get_length() ) {
|
||
ob_clean();
|
||
}
|
||
|
||
if ( isset( $data['error'] ) ) {
|
||
return new WP_Error( 'rest_invalid_data', $data['error'], [ 'status' => 400 ] );
|
||
}
|
||
|
||
return new WP_REST_Response(
|
||
[
|
||
'data' => $data,
|
||
'request_success' => true,
|
||
],
|
||
200
|
||
);
|
||
}
|
||
|
||
|
||
function burst_rest_api_options_set( $request, $ajax_data = false ) {
|
||
if ( ! burst_user_can_manage() ) {
|
||
return new WP_Error( 'rest_forbidden', 'You do not have permission to perform this action.', [ 'status' => 403 ] );
|
||
}
|
||
$data = $ajax_data ?: $request->get_json_params();
|
||
|
||
// get the nonce
|
||
$nonce = $data['nonce'];
|
||
$options = $data['option'];
|
||
if ( ! burst_verify_nonce( $nonce, 'burst_nonce' ) ) {
|
||
return new WP_Error( 'rest_invalid_nonce', 'The provided nonce is not valid.', [ 'status' => 400 ] );
|
||
}
|
||
|
||
// sanitize the options
|
||
$option = sanitize_title( $options['option'] );
|
||
$value = sanitize_text_field( $options['value'] );
|
||
|
||
// option should be prefixed with burst_, if not add it
|
||
if ( strpos( $option, 'burst_' ) !== 0 ) {
|
||
$option = 'burst_' . $option;
|
||
}
|
||
update_option( $option, $value );
|
||
if ( ob_get_length() ) {
|
||
ob_clean();
|
||
}
|
||
|
||
return new WP_REST_Response(
|
||
[
|
||
'status' => 'success',
|
||
'request_success' => true,
|
||
],
|
||
200
|
||
);
|
||
}
|
||
|
||
/**
|
||
* List of allowed field types
|
||
*
|
||
* @param $type
|
||
*
|
||
* @return mixed|string
|
||
*/
|
||
function burst_sanitize_field_type( $type ) {
|
||
$types = array(
|
||
'hidden',
|
||
'database',
|
||
'checkbox',
|
||
'radio',
|
||
'text',
|
||
'textarea',
|
||
'number',
|
||
'email',
|
||
'select',
|
||
'ip_blocklist',
|
||
'email_reports',
|
||
'user_role_blocklist',
|
||
'license',
|
||
);
|
||
if ( in_array( $type, $types ) ) {
|
||
return $type;
|
||
}
|
||
|
||
return 'checkbox';
|
||
}
|
||
|
||
/**
|
||
* @param WP_REST_Request $request
|
||
*
|
||
* @return WP_ERROR|WP_REST_Response
|
||
*/
|
||
function burst_rest_api_fields_set( $request, $ajax_data = false ) {
|
||
if ( ! burst_user_can_manage() ) {
|
||
return new WP_Error( 'rest_forbidden', 'You do not have permission to perform this action.', [ 'status' => 403 ] );
|
||
}
|
||
|
||
$data = $ajax_data ?: $request->get_json_params();
|
||
if ( ! $ajax_data ) {
|
||
burst_remove_fallback_notice();
|
||
}
|
||
// get the nonce
|
||
$nonce = $data['nonce'];
|
||
$fields = $data['fields'];
|
||
|
||
if ( ! burst_verify_nonce( $nonce, 'burst_nonce' ) ) {
|
||
return new WP_Error( 'rest_invalid_nonce', 'The provided nonce is not valid.', [ 'status' => 400 ] );
|
||
}
|
||
|
||
$config_fields = burst_fields( false );
|
||
$config_ids = array_column( $config_fields, 'id' );
|
||
foreach ( $fields as $index => $field ) {
|
||
$config_field_index = array_search( $field['id'], $config_ids );
|
||
if ( ! $config_field_index ) {
|
||
unset( $fields[ $index ] );
|
||
continue;
|
||
}
|
||
$type = burst_sanitize_field_type( $field['type'] );
|
||
$field_id = sanitize_text_field( $field['id'] );
|
||
$value = burst_sanitize_field( $field['value'], $type, $field_id );
|
||
|
||
$field['value'] = $value;
|
||
$fields[ $index ] = $field;
|
||
}
|
||
|
||
$options = get_option( 'burst_options_settings', array() );
|
||
|
||
// build a new options array
|
||
foreach ( $fields as $field ) {
|
||
$prev_value = isset( $options[ $field['id'] ] ) ? $options[ $field['id'] ] : false;
|
||
do_action( 'burst_before_save_option', $field['id'], $field['value'], $prev_value, $field['type'] );
|
||
$options[ $field['id'] ] = $field['value'];
|
||
}
|
||
|
||
if ( ! empty( $options ) ) {
|
||
update_option( 'burst_options_settings', $options );
|
||
}
|
||
|
||
foreach ( $fields as $field ) {
|
||
do_action( 'burst_after_save_field', $field['id'], $field['value'], $prev_value, $field['type'] );
|
||
}
|
||
do_action( 'burst_after_saved_fields', $fields );
|
||
|
||
$response_data = [
|
||
'success' => true,
|
||
'request_success' => true,
|
||
'progress' => BURST()->notices->get(),
|
||
'fields' => burst_fields( true ),
|
||
];
|
||
if ( ob_get_length() ) {
|
||
ob_clean();
|
||
}
|
||
|
||
return new WP_REST_Response( $response_data, 200 );
|
||
}
|
||
|
||
/**
|
||
* Update a burst option
|
||
*
|
||
* @param string $name
|
||
* @param mixed $value
|
||
*
|
||
* @return void
|
||
*/
|
||
function burst_update_option( $name, $value ) {
|
||
if ( ! burst_user_can_manage() && ! wp_doing_cron() ) {
|
||
return;
|
||
}
|
||
|
||
$config_fields = burst_fields( false );
|
||
$config_ids = array_column( $config_fields, 'id' );
|
||
$config_field_index = array_search( $name, $config_ids );
|
||
if ( $config_field_index === false ) {
|
||
return;
|
||
}
|
||
|
||
$config_field = $config_fields[ $config_field_index ];
|
||
$type = isset( $config_field['type'] ) ? $config_field['type'] : false;
|
||
if ( ! $type ) {
|
||
return;
|
||
}
|
||
$options = get_option( 'burst_options_settings', [] );
|
||
if ( ! is_array( $options ) ) {
|
||
$options = [];
|
||
}
|
||
$prev_value = $options[ $name ] ?? false;
|
||
$name = sanitize_text_field( $name );
|
||
$type = burst_sanitize_field_type( $config_field['type'] );
|
||
$value = burst_sanitize_field( $value, $type, $name );
|
||
$value = apply_filters( 'burst_fieldvalue', $value, sanitize_text_field( $name ), $type );
|
||
$options[ $name ] = $value;
|
||
update_option( 'burst_options_settings', $options, true ); // autoload as this is important for front end as well
|
||
do_action( 'burst_after_save_field', $name, $value, $prev_value, $type );
|
||
}
|
||
|
||
/**
|
||
* Get the rest api fields
|
||
*
|
||
* @return WP_ERROR | WP_REST_Response
|
||
*/
|
||
function burst_rest_api_fields_get( $request ) {
|
||
|
||
if ( ! burst_user_can_view() ) {
|
||
return new WP_Error( 'rest_forbidden', 'You do not have permission to perform this action.', array( 'status' => 403 ) );
|
||
}
|
||
|
||
$nonce = $request->get_param( 'nonce' );
|
||
if ( ! burst_verify_nonce( $nonce, 'burst_nonce' ) ) {
|
||
return new WP_Error( 'rest_invalid_nonce', 'The provided nonce is not valid.', array( 'status' => 400 ) );
|
||
}
|
||
|
||
$output = [];
|
||
$fields = burst_fields();
|
||
$menu = burst_menu();
|
||
foreach ( $fields as $index => $field ) {
|
||
/**
|
||
* Load data from source
|
||
*/
|
||
if ( isset( $field['data_source'] ) ) {
|
||
$data_source = $field['data_source'];
|
||
if ( is_array( $data_source ) ) {
|
||
$main = $data_source[0];
|
||
$class = $data_source[1];
|
||
$function = $data_source[2];
|
||
$field['value'] = [];
|
||
if ( function_exists( $main ) ) {
|
||
$field['value'] = $main()->$class->$function();
|
||
}
|
||
} elseif ( function_exists( $field['data_source'] ) ) {
|
||
$func = $field['data_source'];
|
||
$field['value'] = $func();
|
||
}
|
||
}
|
||
|
||
$fields[ $index ] = $field;
|
||
}
|
||
|
||
// remove empty menu items
|
||
foreach ( $menu as $key => $menu_group ) {
|
||
$menu_group['menu_items'] = burst_drop_empty_menu_items( $menu_group['menu_items'], $fields );
|
||
$menu[ $key ] = $menu_group;
|
||
}
|
||
|
||
$output['fields'] = $fields;
|
||
$output['request_success'] = true;
|
||
$output['progress'] = BURST()->notices->get();
|
||
|
||
$output = apply_filters( 'burst_rest_api_fields_get', $output );
|
||
if ( ob_get_length() ) {
|
||
ob_clean();
|
||
}
|
||
|
||
return new WP_REST_Response( $output, 200 );
|
||
}
|
||
|
||
function burst_rest_api_goals_get( $request ) {
|
||
if ( ! burst_user_can_view() ) {
|
||
return new WP_Error( 'rest_forbidden', 'You do not have permission to perform this action.', array( 'status' => 403 ) );
|
||
}
|
||
|
||
$nonce = $request->get_param( 'nonce' );
|
||
if ( ! burst_verify_nonce( $nonce, 'burst_nonce' ) ) {
|
||
return new WP_Error( 'rest_invalid_nonce', 'The provided nonce is not valid.', array( 'status' => 400 ) );
|
||
}
|
||
|
||
$goals = BURST()->goals->get_goals();
|
||
|
||
$goals = apply_filters( 'burst_rest_api_goals_get', $goals );
|
||
|
||
$predefined_goals = BURST()->goals->get_predefined_goals();
|
||
if ( ob_get_length() ) {
|
||
ob_clean();
|
||
}
|
||
|
||
return new WP_REST_Response(
|
||
array(
|
||
'request_success' => true,
|
||
'goals' => $goals,
|
||
'predefinedGoals' => $predefined_goals,
|
||
'goalFields' => burst_goal_fields(),
|
||
),
|
||
200
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Get the rest api fields
|
||
*
|
||
* @return \WP_Error | \WP_REST_Response
|
||
*/
|
||
function burst_rest_api_goal_fields_get( $request ) {
|
||
if ( ! burst_user_can_manage() ) {
|
||
return new WP_Error( 'rest_forbidden', 'You do not have permission to perform this action.', array( 'status' => 403 ) );
|
||
}
|
||
|
||
$nonce = $request->get_param( 'nonce' );
|
||
if ( ! burst_verify_nonce( $nonce, 'burst_nonce' ) ) {
|
||
return new WP_Error( 'rest_invalid_nonce', 'The provided nonce is not valid.', array( 'status' => 400 ) );
|
||
}
|
||
|
||
$goals = apply_filters( 'burst_rest_api_goals_get', BURST()->goals->get_goals() );
|
||
if ( ob_get_length() ) {
|
||
ob_clean();
|
||
}
|
||
|
||
$response = new WP_REST_Response(
|
||
array(
|
||
'request_success' => true,
|
||
'goals' => $goals,
|
||
)
|
||
);
|
||
$response->set_status( 200 );
|
||
|
||
return $response;
|
||
}
|
||
|
||
|
||
/**
|
||
* @param WP_REST_Request $request
|
||
*
|
||
* @return WP_REST_Response | WP_Error
|
||
*/
|
||
function burst_rest_api_goals_set( $request, $ajax_data = false ) {
|
||
if ( ! burst_user_can_manage() ) {
|
||
return new WP_Error( 'rest_forbidden', 'You do not have permission to perform this action.', array( 'status' => 403 ) );
|
||
}
|
||
$data = $ajax_data ?: $request->get_json_params();
|
||
$nonce = $data['nonce'];
|
||
$goals = $data['goals'];
|
||
// get the nonce
|
||
if ( ! burst_verify_nonce( $nonce, 'burst_nonce' ) ) {
|
||
return new WP_Error( 'rest_invalid_nonce', 'The provided nonce is not valid.', array( 'status' => 400 ) );
|
||
}
|
||
|
||
require_once burst_path . 'goals/class-goal.php';
|
||
foreach ( $goals as $index => $goal_data ) {
|
||
$id = (int) $goal_data['id'];
|
||
unset( $goal_data['id'] );
|
||
|
||
$goal = new burst_goal( $id );
|
||
foreach ( $goal_data as $name => $value ) {
|
||
if ( property_exists( $goal, $name ) ) {
|
||
$goal->{$name} = $value;
|
||
}
|
||
}
|
||
$goal->save();
|
||
|
||
}
|
||
if ( ob_get_length() ) {
|
||
ob_clean();
|
||
}
|
||
$response = new WP_REST_Response(
|
||
array(
|
||
'request_success' => true,
|
||
)
|
||
);
|
||
$response->set_status( 200 );
|
||
|
||
return $response;
|
||
}
|
||
|
||
/**
|
||
* @param WP_REST_Request $request
|
||
*
|
||
* @return WP_REST_Response | WP_Error
|
||
*/
|
||
function burst_rest_api_goals_delete( $request, $ajax_data = false ) {
|
||
if ( ! burst_user_can_manage() ) {
|
||
return new WP_Error( 'rest_forbidden', 'You do not have permission to perform this action.', array( 'status' => 403 ) );
|
||
}
|
||
$data = $ajax_data ?: $request->get_json_params();
|
||
$nonce = $data['nonce'];
|
||
if ( ! burst_verify_nonce( $nonce, 'burst_nonce' ) ) {
|
||
return new WP_Error( 'rest_invalid_nonce', 'The provided nonce is not valid.', array( 'status' => 400 ) );
|
||
}
|
||
$id = $data['id'];
|
||
|
||
require_once burst_path . 'goals/class-goal.php';
|
||
$goal = new burst_goal( $id );
|
||
$deleted = $goal->delete();
|
||
|
||
// get resulting goals, in case the last one was deleted, and a new one was created.
|
||
// ensure at least one goal
|
||
$goals = BURST()->goals->get_goals();
|
||
// if not null return true
|
||
$response_data = array(
|
||
'deleted' => $deleted !== null,
|
||
'request_success' => true,
|
||
);
|
||
if ( ob_get_length() ) {
|
||
ob_clean();
|
||
}
|
||
$response = new WP_REST_Response( $response_data );
|
||
$response->set_status( 200 );
|
||
|
||
return $response;
|
||
}
|
||
|
||
/**
|
||
* @param WP_REST_Request $request
|
||
*
|
||
* @return WP_REST_Response|WP_Error $response
|
||
*/
|
||
function burst_rest_api_goals_add_predefined( $request, $ajax_data = false ) {
|
||
if ( ! burst_user_can_manage() ) {
|
||
return new WP_Error( 'rest_forbidden', 'You do not have permission to perform this action.', array( 'status' => 403 ) );
|
||
}
|
||
$data = $ajax_data ?: $request->get_json_params();
|
||
$nonce = $data['nonce'];
|
||
if ( ! burst_verify_nonce( $nonce, 'burst_nonce' ) ) {
|
||
return new WP_Error( 'rest_invalid_nonce', 'The provided nonce is not valid.', array( 'status' => 400 ) );
|
||
}
|
||
$id = $data['id'];
|
||
|
||
require_once burst_path . 'goals/class-goal.php';
|
||
$goal = new burst_goal();
|
||
$goal = $goal->add_predefined( $id );
|
||
if ( ob_get_length() ) {
|
||
ob_clean();
|
||
}
|
||
|
||
if ( ! $goal ) {
|
||
return new WP_Error( 'rest_goal_not_added', 'The predefined goal was not added.', array( 'status' => 400 ) );
|
||
}
|
||
|
||
$response = new WP_REST_Response(
|
||
array(
|
||
'request_success' => true,
|
||
'goal' => $goal,
|
||
)
|
||
);
|
||
$response->set_status( 200 );
|
||
|
||
return $response;
|
||
}
|
||
|
||
/**
|
||
* @param WP_REST_Request $request
|
||
*
|
||
* @return WP_REST_Response|WP_Error $response
|
||
*/
|
||
function burst_rest_api_goals_add( $request, $ajax_data = false ) {
|
||
if ( ! burst_user_can_manage() ) {
|
||
return new WP_Error( 'rest_forbidden', 'You do not have permission to perform this action.', array( 'status' => 403 ) );
|
||
}
|
||
$goal = $ajax_data ?: $request->get_json_params();
|
||
|
||
if ( ! burst_verify_nonce( $goal['nonce'], 'burst_nonce' ) ) {
|
||
return new WP_Error( 'rest_invalid_nonce', 'The provided nonce is not valid.', array( 'status' => 400 ) );
|
||
}
|
||
|
||
require_once burst_path . 'goals/class-goal.php';
|
||
$goal = new burst_goal();
|
||
$goal->save();
|
||
|
||
if ( ob_get_length() ) {
|
||
ob_clean();
|
||
}
|
||
$response = new WP_REST_Response(
|
||
array(
|
||
'request_success' => true,
|
||
'goal' => $goal,
|
||
)
|
||
);
|
||
$response->set_status( 200 );
|
||
|
||
return $response;
|
||
}
|
||
|
||
/**
|
||
* @param WP_REST_Request $request
|
||
*
|
||
* @return WP_REST_Response | WP_Error
|
||
*/
|
||
function burst_rest_api_menu( $request ) {
|
||
if ( ! burst_user_can_manage() ) {
|
||
return new WP_Error( 'rest_forbidden', 'You do not have permission to perform this action.', array( 'status' => 403 ) );
|
||
}
|
||
if ( ob_get_length() ) {
|
||
ob_clean();
|
||
}
|
||
|
||
return burst_menu();
|
||
}
|
||
|
||
/**
|
||
* Checks if there are field linked to menu_item if not removes menu_item from menu_item array
|
||
*
|
||
* @param $menu_items
|
||
* @param $fields
|
||
*
|
||
* @return array
|
||
*/
|
||
function burst_drop_empty_menu_items( $menu_items, $fields ) {
|
||
if ( ! burst_user_can_manage() ) {
|
||
return $menu_items;
|
||
}
|
||
$new_menu_items = $menu_items;
|
||
foreach ( $menu_items as $key => $menu_item ) {
|
||
$searchResult = array_search( $menu_item['id'], array_column( $fields, 'menu_id' ) );
|
||
if ( $searchResult === false ) {
|
||
unset( $new_menu_items[ $key ] );
|
||
// reset array keys to prevent issues with react
|
||
$new_menu_items = array_values( $new_menu_items );
|
||
} elseif ( isset( $menu_item['menu_items'] ) ) {
|
||
$updatedValue = burst_drop_empty_menu_items( $menu_item['menu_items'], $fields );
|
||
$new_menu_items[ $key ]['menu_items'] = $updatedValue;
|
||
}
|
||
}
|
||
|
||
return $new_menu_items;
|
||
}
|
||
|
||
/**
|
||
* Sanitize a field
|
||
*
|
||
* @param mixed $value
|
||
* @param string $type
|
||
*
|
||
* @oaram string $id
|
||
*
|
||
* @return array|bool|int|string|void
|
||
*/
|
||
function burst_sanitize_field( $value, $type, $id ) {
|
||
if ( ! burst_user_can_manage() ) {
|
||
return false;
|
||
}
|
||
|
||
switch ( $type ) {
|
||
case 'checkbox':
|
||
case 'hidden':
|
||
case 'database':
|
||
return (int) $value;
|
||
case 'select':
|
||
case 'text':
|
||
return sanitize_text_field( $value );
|
||
case 'textarea':
|
||
return sanitize_text_field( $value );
|
||
case 'multicheckbox':
|
||
case 'user_role_blocklist':
|
||
if ( ! is_array( $value ) ) {
|
||
$value = array( $value );
|
||
}
|
||
|
||
return array_map( 'sanitize_text_field', $value );
|
||
case 'email':
|
||
|
||
return sanitize_email( $value );
|
||
case 'url':
|
||
return esc_url_raw( $value );
|
||
case 'number':
|
||
return (int) $value;
|
||
case 'ip_blocklist':
|
||
return burst_sanitize_ip_field( $value );
|
||
case 'email_reports':
|
||
return burst_sanitize_email_reports( $value );
|
||
default:
|
||
return sanitize_text_field( $value );
|
||
}
|
||
}
|
||
|
||
function burst_sanitize_ip_field( $value ) {
|
||
if ( ! burst_user_can_manage() ) {
|
||
return false;
|
||
}
|
||
|
||
$ips = explode( PHP_EOL, $value );
|
||
$ips = array_map( 'trim', $ips ); // remove whitespace
|
||
$ips = array_filter( $ips ); // remove empty lines
|
||
$ips = array_unique( $ips ); // remove duplicates
|
||
$ips = array_map( 'sanitize_text_field', $ips ); // sanitize each ip
|
||
|
||
return implode( PHP_EOL, $ips );
|
||
}
|
||
|
||
/**
|
||
* Sanitize and validate filters for email reports.
|
||
*
|
||
* @param array $email_reports Array of email reports to sanitize and validate.
|
||
*
|
||
* @return array|bool Sanitized and validated array, or false if user can't manage.
|
||
*/
|
||
function burst_sanitize_email_reports($email_reports) {
|
||
// Check if the current user has the capability to manage the settings.
|
||
if (!burst_user_can_manage()) {
|
||
return false;
|
||
}
|
||
|
||
$sanitized_email_reports = [];
|
||
if ( !is_array($email_reports )) {
|
||
$email_reports = [];
|
||
}
|
||
foreach ($email_reports as $report) {
|
||
// Initialize an array to hold sanitized report.
|
||
$sanitized_report = [];
|
||
|
||
// Sanitize the email field.
|
||
if (isset($report['email'])) {
|
||
$sanitized_report['email'] = sanitize_email($report['email']);
|
||
}
|
||
|
||
// Validate and sanitize the frequency field.
|
||
if (isset($report['frequency']) && in_array($report['frequency'], ['monthly', 'weekly'], true)) {
|
||
$sanitized_report['frequency'] = $report['frequency'];
|
||
} else {
|
||
$sanitized_report['frequency'] = 'monthly';
|
||
}
|
||
|
||
// Add the sanitized report to the array.
|
||
$sanitized_email_reports[] = $sanitized_report;
|
||
}
|
||
// maximum of 10 email reports
|
||
$sanitized_email_reports = array_slice($sanitized_email_reports, 0, 10);
|
||
return $sanitized_email_reports;
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* Get user roles for the settings page in Burst
|
||
*
|
||
* @return array
|
||
*/
|
||
function burst_get_user_roles(): array {
|
||
if ( ! burst_user_can_manage() ) {
|
||
return [];
|
||
}
|
||
|
||
global $wp_roles;
|
||
|
||
return $wp_roles->get_names();
|
||
}
|
||
|
||
function burst_get_posts( $request, $ajax_data = false ) {
|
||
if ( ! burst_user_can_view() ) {
|
||
return new WP_Error( 'rest_forbidden', 'You do not have permission to perform this action.', array( 'status' => 403 ) );
|
||
}
|
||
|
||
$max_post_count = 100;
|
||
|
||
global $wpdb;
|
||
$data = $ajax_data ?: $request->get_params();
|
||
$nonce = $data['nonce'];
|
||
$search = isset( $data['search'] ) ? $data['search'] : '';
|
||
|
||
if ( ! burst_verify_nonce( $nonce, 'burst_nonce' ) ) {
|
||
return new WP_Error( 'rest_invalid_nonce', 'The provided nonce is not valid.', array( 'status' => 400 ) );
|
||
}
|
||
|
||
//do full search for string length above 3, but set a cap at 1000
|
||
if ( strlen($search)>3 ) {
|
||
$max_post_count = 1000;
|
||
}
|
||
|
||
$resultArray = [];
|
||
$args = [
|
||
'post_type' => ['post', 'page'],
|
||
'numberposts' => $max_post_count,
|
||
'order' => 'DESC',
|
||
'orderby' => 'meta_value_num',
|
||
'meta_query' => array(
|
||
'key' => 'burst_total_pageviews_count',
|
||
'type' => 'NUMERIC',
|
||
),
|
||
];
|
||
$posts = get_posts( $args );
|
||
foreach ( $posts as $post ) {
|
||
$page_url = get_permalink( $post );
|
||
$resultArray[] = array(
|
||
'page_url' => str_replace( site_url(), '', $page_url),
|
||
'page_id' => $post->ID,
|
||
'post_title' => $post->post_title,
|
||
'pageviews' => (int) get_post_meta( $post->ID, 'burst_total_pageviews_count', true ),
|
||
);
|
||
}
|
||
|
||
if ( ob_get_length() ) {
|
||
ob_clean();
|
||
}
|
||
|
||
return new WP_REST_Response(
|
||
array(
|
||
'request_success' => true,
|
||
'posts' => $resultArray,
|
||
'max_post_count' => $max_post_count,
|
||
),
|
||
200
|
||
);
|
||
|
||
//}
|
||
//
|
||
// // Initialize an empty array for results
|
||
// $resultArray = [];
|
||
// // Base query for wp_posts
|
||
// $posts_query = "
|
||
// SELECT REPLACE(p.guid, %s, '') AS stripped_url, p.post_title, p.ID as page_id, 0 AS pageviews
|
||
// FROM {$wpdb->prefix}posts p
|
||
// LEFT JOIN {$wpdb->prefix}burst_summary s ON p.guid = CONCAT(%s, s.page_url)
|
||
// WHERE p.post_title LIKE %s AND p.post_status = 'publish'
|
||
// GROUP BY stripped_url, p.post_title, p.ID
|
||
// ";
|
||
//
|
||
// // Base query for wp_burst_summary
|
||
// $stats_query = "
|
||
// SELECT s.page_url AS stripped_url, '' AS post_title, 0 as page_id, COUNT(*) AS pageviews
|
||
// FROM {$wpdb->prefix}burst_summary s
|
||
// WHERE s.page_url LIKE %s
|
||
// GROUP BY stripped_url
|
||
// ";
|
||
//
|
||
// // Combine the two queries using UNION and sort by pageviews
|
||
// $site_url = get_site_url();
|
||
// $final_query = $wpdb->prepare(
|
||
// 'SELECT stripped_url, SUM(pageviews) as total_pageviews, MAX(page_id) as page_id, post_title FROM (
|
||
// (' . $posts_query . ') UNION ALL (' . $stats_query . ')
|
||
// ) AS combined
|
||
// GROUP BY stripped_url, post_title
|
||
// ORDER BY total_pageviews DESC
|
||
// LIMIT %d',
|
||
// $site_url,
|
||
// $site_url,
|
||
// '%' . $wpdb->esc_like( $search ) . '%',
|
||
// '%' . $wpdb->esc_like( $search ) . '%',
|
||
// $max_post_count
|
||
// );
|
||
// $results = $wpdb->get_results( $final_query, ARRAY_A );
|
||
// $results = is_array($results) ? $results : [];
|
||
//
|
||
// foreach ( $results as $row ) {
|
||
// $page_url = $row['stripped_url'];
|
||
// $resultArray[] = array(
|
||
// 'page_url' => $page_url,
|
||
// 'page_id' => $row['page_id'] ?? 0,
|
||
// 'post_title' => $row['post_title'],
|
||
// 'pageviews' => (int) $row['total_pageviews'],
|
||
// );
|
||
// }
|
||
//
|
||
// if ( ob_get_length() ) {
|
||
// ob_clean();
|
||
// }
|
||
// $resultArray = ! empty( $resultArray ) ? $resultArray : [];
|
||
//
|
||
// return new WP_REST_Response(
|
||
// array(
|
||
// 'request_success' => true,
|
||
// 'posts' => $resultArray,
|
||
// 'max_post_count' => $max_post_count,
|
||
// ),
|
||
// 200
|
||
// );
|
||
}
|
||
|
||
/**
|
||
* If the track_network_wide option is saved, we update the site_option which is used to handle this behaviour.
|
||
*
|
||
* @param $name
|
||
* @param $value
|
||
* @param $prev_value
|
||
* @param $type
|
||
*
|
||
* @return void
|
||
*/
|
||
function burst_update_for_multisite( $name, $value, $prev_value, $type ) {
|
||
if ( $name === 'track_network_wide' ) {
|
||
update_site_option( 'burst_track_network_wide', (bool) $value );
|
||
}
|
||
}
|
||
add_action( 'burst_after_save_field', 'burst_update_for_multisite', 10, 4 );
|
||
|
||
|
||
|