Sindbad~EG File Manager
<?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 ) {
// get all files from the settings/build folder
$buildDirPath = burst_path . $dir;
$filenames = scandir( $buildDirPath );
// filter the filenames to get the JavaScript and asset filenames
$jsFilename = '';
$assetFilename = '';
$json_translations = [];
foreach ( $filenames as $filename ) {
if ( strpos( $filename, 'index.' ) === 0 ) {
if ( substr( $filename, -3 ) === '.js' ) {
$jsFilename = $filename;
} elseif ( substr( $filename, -10 ) === '.asset.php' ) {
$assetFilename = $filename;
}
}
if ( strpos( $filename, '.js' ) === false ) {
continue;
}
// remove extension from $filename
$chunk_handle = str_replace( '.js', '', $filename );
// temporarily register the script, so we can get a translations object.
wp_register_script( $chunk_handle, plugins_url( 'build/' . $filename, __FILE__ ), [], true );
$path = defined( 'burst_pro' ) ? burst_path . 'languages' : false;
$localeData = load_script_textdomain( $chunk_handle, 'burst-statistics', $path );
if ( ! empty( $localeData ) ) {
$json_translations[] = $localeData;
}
wp_deregister_script( $chunk_handle );
}
$asset_file = require $buildDirPath . '/' . $assetFilename;
if ( empty( $jsFilename ) ) {
return [];
}
return [
'json_translations' => $json_translations,
'js_file' => $jsFilename,
'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' => add_query_arg( [ 'page' => 'burst' ], burst_admin_url() ),
'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 ) );
}
}
$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' );
foreach ( $args as $arg ) {
if ( isset( $_GET[ $arg ] ) ) {
$request->set_param( $arg, stripcslashes( $_GET[ $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' => 'POST',
'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 ( ! wp_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' => 'really-simple-ssl',
'constant_free' => 'rsssl_version',
'constant_pro' => 'rsssl_pro',
'wordpress_url' => 'https://wordpress.org/plugins/really-simple-ssl/',
'upgrade_url' => 'https://really-simple-ssl.com/pro?src=plugin-burst-other-plugins',
'title' => 'Really Simple Security - ' . __( 'Simple and performant security', 'burst-statistics' ),
],
[
'slug' => 'complianz-gdpr',
'constant_free' => 'cmplz_plugin',
'constant_pro' => 'cmplz_premium',
'wordpress_url' => 'https://wordpress.org/plugins/complianz-gdpr/',
'upgrade_url' => 'https://complianz.io/pricing?src=plugin-burst-other-plugins',
'title' => __( 'Complianz Privacy Suite - Cookie Consent Management as it should be', 'burst-statistics' ),
],
[
'slug' => 'complianz-terms-conditions',
'constant_free' => 'cmplz_tc_version',
'wordpress_url' => 'https://wordpress.org/plugins/complianz-terms-conditions/',
'upgrade_url' => 'https://complianz.io?src=plugin-burst-other-plugins',
'title' => 'Complianz - ' . __( 'Terms and Conditions', 'burst-statistics' ),
],
];
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 ( ! wp_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
];
if ( isset( $request->get_params()['args'] ) ) {
$request_args = json_decode( $request->get_param( 'args' ), true );
} else {
$request_args = array();
}
// merge get_json_params with request_args
$post_args = $request->get_json_params();
if ( $post_args ) {
$request_args = array_merge( $request_args, $post_args );
}
$args['metrics'] = $request_args['metrics'] ?? array();
$args['filters'] = burst_sanitize_filters( $request_args['filters'] ?? array() );
$args['group_by'] = $request_args['group_by'] ?? 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 ( ! wp_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 ( ! wp_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 );
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 ( ! wp_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 ( ! wp_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 ( ! wp_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 ( ! wp_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 ( ! wp_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 ( ! wp_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 ( ! wp_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 ( ! wp_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 );
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists