PluginProbe
MainWP Key Maker / 1.2
MainWP Key Maker v1.2
trunk 0.1 0.2 1.0 1.1 1.2 1.3
mainwp-key-maker / mainwp-key-maker.php

mainwp-key-maker.php in MainWP Key Maker 1.2, at mainwp-key-maker.php

680 lines 21.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: MainWP Key Maker
4 Plugin URI: https://mainwp.com/
5 Description: Easily convert a form into a "key" to use with the MainWP Bulk Settings Manager Extension
6 Author: MainWP
7 Author URI: https://mainwp.com
8 Version: 1.2
9 */
10
11 // Check whether we made a redirection in this session.
12 $mainwp_key_maker_is_redirect = false;
13
14 // Store current user session id.
15 $mainwp_key_maker_session_id = "";
16
17 if ( ! function_exists( "mainwp_key_maker_get_session_id" ) ) {
18
19 /**
20 * Get current user session id.
21 */
22 function mainwp_key_maker_get_session_id() {
23
24 /**
25 * MainWP Key Maker session ID.
26 *
27 * @global string $mainwp_key_maker_session_id
28 */
29 global $mainwp_key_maker_session_id;
30
31 // We use global so this happen only once .
32 if (empty($mainwp_key_maker_session_id)) {
33 if ( defined( "AUTH_COOKIE" ) && isset( $_COOKIE[ AUTH_COOKIE ] )) {
34 // Different users can share one account - so use session id
35 $cookie_elements = explode( '|', $_COOKIE[ AUTH_COOKIE ] );
36 if ( isset( $cookie_elements[2] ) ) {
37 $mainwp_key_maker_session_id = substr( (string) $cookie_elements[2], 0, 30 );
38 }
39 } else if ( defined( "SECURE_AUTH_COOKIE" ) && isset( $_COOKIE[ SECURE_AUTH_COOKIE ] )) {
40 // Different users can share one account - so use session id
41 $cookie_elements = explode( '|', $_COOKIE[ SECURE_AUTH_COOKIE ] );
42 if ( isset( $cookie_elements[2] ) ) {
43 $mainwp_key_maker_session_id = substr( (string) $cookie_elements[2], 0, 30 );
44 }
45 }
46 }
47 }
48 }
49
50 if ( ! function_exists( "mainwp_key_maker_store_request" ) ) {
51
52 /**
53 * Store $_GET and $_POST inside transient for further use.
54 *
55 * @param false $temp_saving Check whether or not the data is to be temporarily saved.
56 */
57 function mainwp_key_maker_store_request( $temp_saving = false ) {
58
59 /**
60 * @global string $mainwp_key_maker_session_id MainWP Key Maker session ID.
61 * @global bool $mainwp_key_maker_is_redirect Whether this is a redirect.
62 */
63 global $mainwp_key_maker_session_id, $mainwp_key_maker_is_redirect;
64
65 mainwp_key_maker_get_session_id();
66
67 // Only for logged.
68 if ( ! empty( $mainwp_key_maker_session_id ) ) {
69
70 // Skip heartbleed WordPress action.
71 if ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'heartbeat' && isset( $_REQUEST['screen_id'] ) ) {
72 return;
73 }
74
75 $saved_datas = get_transient( 'mainwp_eir_' . $mainwp_key_maker_session_id );
76
77 if ( $saved_datas === false ) {
78 $saved_datas = array();
79 }
80
81 $previous_datas = array();
82
83 if (!$temp_saving) {
84 foreach ( $saved_datas as $data_counter => $data ) {
85 if (isset($data['_temp_saving'])) {
86 continue; // avoid.
87 }
88 $previous_datas[] = $data;
89 }
90 } else {
91 $previous_datas = $saved_datas;
92 }
93
94 $datas = array();
95
96 // Store values in transient so we have access to them in next page.
97 $datas['post'] = $_POST;
98 $datas['get'] = $_GET;
99 $datas['url'] = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
100 $datas['time'] = time();
101
102 if ($temp_saving) {
103 $datas['_temp_saving'] = true;
104 }
105
106 $previous_datas[] = $datas;
107
108 set_transient( 'mainwp_eir_' . $mainwp_key_maker_session_id, $previous_datas, 90 );
109 $mainwp_key_maker_is_redirect = true;
110 }
111 }
112 }
113
114 // We add additional functionality to wp_redirect and wp_verify_nonce for administrators.
115 if ( ! function_exists( 'wp_redirect' ) ) :
116
117 /**
118 * Redirects to another page
119 * Additionally, stores $_GET, $_POST and url in transient.
120 *
121 * @since 1.5.1
122 *
123 * @global bool $is_IIS
124 *
125 * @param string $location The path to redirect to.
126 * @param int $status Status code to use.
127 *
128 * @return bool False if $location is not provided, true otherwise.
129 */
130 function wp_redirect( $location, $status = 302 ) {
131
132 /** @global object $is_IIS IIS instance. */
133 global $is_IIS;
134
135 /**
136 * Filter the redirect location.
137 *
138 * @since 2.1.0
139 *
140 * @param string $location The path to redirect to.
141 * @param int $status Status code to use.
142 */
143 $location = apply_filters( 'wp_redirect', $location, $status );
144
145 /**
146 * Filter the redirect status code.
147 *
148 * @since 2.3.0
149 *
150 * @param int $status Status code to use.
151 * @param string $location The path to redirect to.
152 */
153 $status = apply_filters( 'wp_redirect_status', $status, $location );
154
155 if ( ! $location ) {
156 return false;
157 }
158
159 $location = wp_sanitize_redirect( $location );
160
161 if ( ! $is_IIS && PHP_SAPI != 'cgi-fcgi' ) {
162 status_header( $status );
163 } // This causes problems on IIS and some FastCGI setups.
164
165 mainwp_key_maker_store_request();
166
167 header( "Location: $location", true, $status );
168
169 return true;
170 }
171 endif;
172
173 if ( ! function_exists( 'wp_verify_nonce' ) ) :
174
175 /**
176 * Verify that correct nonce was used with time limit,
177 * Additionally stores name of nonce action in transient.
178 *
179 * The user is given an amount of time to use the token, so therefore, since the
180 * UID and $action remain the same, the independent variable is the time.
181 *
182 * @since 2.0.3
183 *
184 * @param string $nonce Nonce that was used in the form to verify.
185 * @param string|int $action Should give context to what is taking place and be the same when nonce was created.
186 *
187 * @return false|int False if the nonce is invalid, 1 if the nonce is valid and generated between
188 * 0-12 hours ago, 2 if the nonce is valid and generated between 12-24 hours ago.
189 */
190 function wp_verify_nonce( $nonce, $action = - 1 ) {
191
192 /**
193 * MainWP Key Maker session ID.
194 *
195 * @global string $mainwp_key_maker_session_id
196 */
197 global $mainwp_key_maker_session_id;
198
199 if ( ! empty( $mainwp_key_maker_session_id ) ) {
200 $key_maker = get_transient( 'mainwp_ein_' . $mainwp_key_maker_session_id );
201 if ( $key_maker === false ) {
202 $key_maker = array();
203 }
204
205 $key_maker[ trim( $nonce ) ] = $action;
206 set_transient( 'mainwp_ein_' . $mainwp_key_maker_session_id, $key_maker );
207 }
208
209 $nonce = (string) $nonce;
210 $user = wp_get_current_user();
211 $uid = (int) $user->ID;
212 if ( ! $uid ) {
213
214 /**
215 * Filter whether the user who generated the nonce is logged out.
216 *
217 * @since 3.5.0
218 *
219 * @param int $uid ID of the nonce-owning user.
220 * @param string $action The nonce action.
221 */
222 $uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
223 }
224
225 if ( empty( $nonce ) ) {
226 return false;
227 }
228
229 $token = wp_get_session_token();
230 $i = wp_nonce_tick();
231
232 // Nonce generated 0-12 hours ago.
233 $expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), - 12, 10 );
234 if ( hash_equals( $expected, $nonce ) ) {
235 return 1;
236 }
237
238 // Nonce generated 12-24 hours ago.
239 $expected = substr( wp_hash( ( $i - 1 ) . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), - 12, 10 );
240 if ( hash_equals( $expected, $nonce ) ) {
241 return 2;
242 }
243
244 // Invalid nonce.
245 return false;
246 }
247 endif;
248
249 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
250
251 // We want to support ajax calls also.
252 mainwp_key_maker_store_request();
253 }
254
255 /**
256 * Class MainWP_Key_Maker.
257 */
258 class MainWP_Key_Maker {
259
260 /**
261 * MainWP_Key_Maker constructor.
262 */
263 public function __construct() {
264 add_action( 'init', array( $this, 'init' ) );
265 }
266
267 /**
268 * Initiate
269 */
270 public function init() {
271 mainwp_key_maker_get_session_id();
272
273 if ( ! current_user_can( 'manage_options' ) || ! is_admin() ) {
274 return;
275 }
276
277 /** @global bool $mainwp_key_maker_is_redirect Redirect check. */
278 global $mainwp_key_maker_is_redirect;
279
280 // Display redirect data on next page.
281 if ( $mainwp_key_maker_is_redirect ) {
282 return;
283 }
284
285 // Skip Ajax.
286 if ( defined( 'XMLRPC_REQUEST' ) || defined( 'DOING_AJAX' ) || defined( 'IFRAME_REQUEST' ) ) {
287 return;
288 }
289
290 // Don't process if fatal error.
291 $error = error_get_last();
292 if ( ! empty( $error ) && ( $error['type'] & ( E_ERROR | E_USER_ERROR | E_RECOVERABLE_ERROR ) ) ) {
293 return;
294 }
295
296 // temporary saving to fix if none wp-redirect.
297 mainwp_key_maker_store_request($temp = true);
298
299 add_action( 'wp_before_admin_bar_render', array( $this, 'bar_render' ), 999 );
300 add_action( 'admin_footer', array( $this, 'toolbar' ), 999 );
301 }
302
303 /**
304 * Render Key Maker button inside admin bar &
305 * Display content using thickbox popup.
306 */
307 public function bar_render() {
308
309 /** @global object $wp_admin_bar WordPress Admin Bar instance. */
310 global $wp_admin_bar;
311
312 wp_register_script( 'mainwp-key-maker-colorbox', plugins_url( '/js/jquery.colorbox-min.js', __FILE__ ), array( 'jquery' ) );
313 wp_enqueue_script( 'mainwp-key-maker-colorbox' );
314
315 wp_enqueue_script( 'mainwp-clipboard', plugins_url( '/js/clipboard.min.js', __FILE__ ), array( 'jquery' ) );
316
317 wp_register_style( 'mainwp-key-maker-colorbox', plugins_url( '/css/colorbox.css', __FILE__ ) );
318 wp_enqueue_style( 'mainwp-key-maker-colorbox' );
319
320 $args = array(
321 'id' => 'mainwp-key-maker-adminbar-node',
322 'title' => __( 'MainWP Key Maker', 'mainwp-key-maker' ),
323 'href' => '#mainwp-key-maker-box'
324 );
325
326 $wp_admin_bar->add_node( $args );
327 ?>
328 <style>
329 #wp-admin-bar-mainwp-key-maker {
330 cursor: pointer;
331 }
332 .mainwp-km-info {
333 margin-top: 1em;
334 padding: .6em;
335 border-left: 4px Solid #7fb100;
336 box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
337 -webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
338 }
339 </style>
340 <script>
341 jQuery( document ).ready( function ($) {
342 new ClipboardJS('.mainwp-key-maker-copy-button');
343 //Copy to clipboard.
344 jQuery(document).on('click', '.mainwp-key-maker-copy-button', function () {
345 var btn = this;
346 jQuery(btn).val('<?php _e('Copied to Clipboard!', 'mainwp-key-maker'); ?>');
347 jQuery(btn).removeClass('button-primary');
348 setInterval(function () {
349 jQuery(btn).val('<?php _e('Copy to Clipboard', 'mainwp-key-maker'); ?>');
350 jQuery(btn).addClass('button-primary');
351 }, 3000);
352 return false;
353 });
354
355 jQuery("#wp-admin-bar-mainwp-key-maker-adminbar-node a").colorbox({inline: true, width: "1230px"});
356
357 jQuery(".mainwp-key-maker-debug-a").on("click", function () {
358 jQuery("#mainwp-key-maker-debug-" + jQuery(this).attr("ids")).toggle();
359 });
360 });
361 </script>
362
363 <?php
364 }
365
366 /**
367 * Display content for admin bar button.
368 */
369 public function toolbar() {
370 /**
371 * MainWP Key Maker session ID.
372 *
373 * @global string $mainwp_key_maker_session_id
374 */
375 global $mainwp_key_maker_session_id;
376
377 // Check if we have anything to display.
378 $is_any_info = false;
379 $is_there_pre_request = false;
380 ?>
381 <div style="display:none;">
382 <div id="mainwp-key-maker-box">
383 <span style="float: right;">
384 <a href="https://mainwp.com" target="_blank" title="MainWP"><img style="height: 40px; margin-right: 15px;" src="<?php echo plugins_url('images/logo.png', __FILE__); ?>" alt="MainWP" /></a>
385 </span>
386 <h1><?php _e( 'MainWP Key Maker', 'mainwp-key-maker'); ?></h1>
387 <div style="clear: both;"></div>
388 <?php
389
390 $nonce = get_transient( 'mainwp_ein_' . $mainwp_key_maker_session_id );
391
392 if ( $nonce === false ) {
393 $nonce = array();
394 }
395
396 $previous_datas = get_transient( 'mainwp_eir_' . $mainwp_key_maker_session_id );
397
398 if ( $previous_datas !== false ) {
399 delete_transient( 'mainwp_ein_' . $mainwp_key_maker_session_id );
400 delete_transient( 'mainwp_eir_' . $mainwp_key_maker_session_id );
401 foreach ( $previous_datas as $previous_counter => $previous_data ):
402 if ( ( isset( $previous_data['post'] ) && ! empty( $previous_data['post'] ) ) || ( isset( $previous_data['get'] ) && ! empty( $previous_data['get'] ) ) ):
403
404 if (isset($previous_data['_temp_saving'])) {
405 unset($previous_data['_temp_saving']);
406 }
407
408 $is_any_info = true;
409 $is_there_pre_request = true;
410 ?>
411 <div style="padding-bottom: 1em; margin-bottom: 1px Solid #000;">
412 <?php
413 if ( $is_there_pre_request ):
414 ?>
415 <div class="mainwp-km-info">
416 <em><?php _e('The "Verify Form Fields and Values" button allows you to tell if the Key will contain the information you want.', 'mainwp-key-maker'); ?></em><br/>
417 <em><?php _e('If it does not, you may need to submit the form in order for the Key Maker to be able to correctly gather the form fields and values.', 'mainwp-key-maker'); ?></em>
418 </div>
419 <?php
420 endif;
421 ?>
422 <p>
423 <h2 style="margin-bottom: .3em;"><?php _e( 'Post-submission Request', 'mainwp-key-maker' ); ?></h2>
424 <em>( <?php echo date_i18n( "d-m-Y H:i:s", $previous_data['time'] ); ?> )</em>
425 <?php echo( isset( $previous_data['url'] ) ? esc_html( $previous_data['url'] ) : __( 'Unknown url', 'mainwp-key-maker' ) ); ?>
426 <span style="float: right; margin-right: 1.5em;">
427 <a href="#"
428 class="mainwp-key-maker-debug-a button"
429 style="text-decoration: none;"
430 ids="<?php echo esc_attr( $previous_counter ); ?>"><?php _e( 'Verify Form Fields and Values', 'mainwp-key-maker' ); ?>
431 </a>
432 <input type="submit"
433 id="mainwp-key-maker-textarea-previous-<?php echo esc_attr( $previous_counter ); ?>-button"
434 data-clipboard-target="#mainwp-key-maker-textarea-previous-<?php echo esc_attr( $previous_counter ); ?>"
435 class="mainwp-key-maker-copy-button button button-primary"
436 value="<?php _e( 'Copy to Clipboard', 'mainwp-key-maker' ); ?>">
437 </span>
438 </p>
439 <div id="mainwp-key-maker-debug-<?php echo esc_attr( $previous_counter ); ?>"
440 style="display:none; width: 1170px !important; margin-bottom: 1em;"
441 class="postbox">
442 <div class="inside">
443 <pre><?php echo $this->custom_print_r( $previous_data, $nonce ); ?></pre>
444 </div>
445 </div>
446
447 <textarea rows="12"
448 cols="90"
449 style="width: 1170px;"
450 class="mainwp-key-maker-textarea"
451 id="mainwp-key-maker-textarea-previous-<?php echo esc_attr( $previous_counter ); ?>"
452 readonly><?php echo esc_textarea( $this->parse_data( $previous_data, $nonce ) ); ?></textarea>
453 </div>
454 <?php
455 endif;
456 endforeach;
457
458
459 }
460
461 $current_data = array();
462 $current_data['post'] = $_POST;
463 $current_data['get'] = $_GET;
464 $current_data['url'] = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
465 $current_data['time'] = time();
466 ?>
467 <div style="padding-bottom: 1em; margin-bottom: 1px Solid #000;">
468 <?php
469 if (!empty($current_data['post']) || !empty($current_data['get'])):
470 $is_any_info = true;
471 ?>
472 <?php
473 if ( ! $is_there_pre_request ):
474 ?>
475 <div class="mainwp-km-info">
476 <em><?php _e('The "Verify Form Fields and Values" button allows you to tell if the Key will contain the information you want.', 'mainwp-key-maker'); ?></em><br/>
477 <em><?php _e('If it does not, you may need to submit the form in order for the Key Maker to be able to correctly gather the form fields and values.', 'mainwp-key-maker'); ?></em>
478 </div>
479 <?php
480 endif;
481 ?>
482 <p>
483 <h2 style="margin-bottom: .3em;"><?php _e('Pre-submission Request', 'mainwp-key-maker'); ?></h2>
484 <em>( <?php echo date_i18n("d-m-Y H:i:s", $current_data['time']); ?> )</em>
485 <?php echo esc_html($current_data['url']); ?>
486 <span style="float: right; margin-right: 1.5em;">
487 <a
488 href="#"
489 class="mainwp-key-maker-debug-a button"
490 ids="current"
491 style="text-decoration: none;"><?php _e('Verify Form Fields and Values', 'mainwp-key-maker'); ?>
492 </a>
493 <input type="submit"
494 id="mainwp-key-maker-textarea-button"
495 data-clipboard-target="#mainwp-key-maker-textarea"
496 class="mainwp-key-maker-copy-button button button-primary"
497 value="<?php _e('Copy to clipboard', 'mainwp-key-maker'); ?>">
498 </span>
499 </p>
500
501 <div id="mainwp-key-maker-debug-current"
502 style="display:none; width: 1170px !important; margin-bottom: 1em;"
503 class="postbox">
504 <div class="inside">
505 <pre><?php echo $this->custom_print_r($current_data, $nonce); ?></pre>
506 </div>
507 </div>
508
509
510 <textarea rows="12"
511 cols="90"
512 style="width: 1170px;"
513 class="mainwp-key-maker-textarea"
514 id="mainwp-key-maker-textarea"
515 readonly><?php echo esc_textarea($this->parse_data($current_data, $nonce)); ?></textarea>
516 <?php
517 endif;
518
519 if ( ! $is_any_info ):
520 ?>
521 <div class="mainwp-km-info"><?php _e( 'No form detected. You may have to submit the form before Key Maker is able to find the form and make the Key.', 'mainwp-key-maker' ); ?></div>
522 <?php
523 endif;
524 ?>
525 </div>
526 </div>
527 </div>
528 <?php
529 }
530
531 /**
532 * Custom sanitized print_r() function.
533 *
534 * Print $_GET and $_POST using print_r with XSS protection.
535 *
536 * @param string $data Data to print.
537 * @param string $nonce Security nonce.
538 *
539 * @return string Return escaped string & print to screen.
540 */
541 public function custom_print_r( $data, $nonce ) {
542 return esc_html( print_r( $this->check_nonces( $data, $nonce ), true ) );
543 }
544
545 /**
546 * Recursive check if nonce field exists in array.
547 *
548 * @param array $data Data to print.
549 * @param string $nonce Security nonce.
550 *
551 * @return array Return trimmed array.
552 */
553 public function check_nonces( $data, $nonce ) {
554 $new = array();
555 foreach ( $data as $key => $val ) {
556 if ( is_array( $val ) ) {
557 $new[ $key ] = $this->check_nonces( $val, $nonce );
558 } else {
559 $val = trim( $val );
560 if ( isset( $nonce[ $val ] ) ) {
561 $new[ $key ] = __( 'NONCE FIELD', 'mainwp-key-maker' ) . ' - ' . $nonce[ $val ];
562 } else {
563 $new[ $key ] = $val;
564 }
565 }
566 }
567
568 return $new;
569 }
570
571 /**
572 * Parse data in readable format for Skeleton Key.
573 *
574 * @param array $data Data to print.
575 * @param string $nonce Security nonce.
576 *
577 * @return string Return string in readable format.
578 */
579 public function parse_data( $data, $nonce ) {
580 $out = array();
581 if ( isset( $data['post'] ) ) {
582 foreach ( $this->flatten_array( $data['post'] ) as $key => $val ) {
583 $array = array();
584 $val = trim( $val );
585
586 if ( isset( $nonce[ $val ] ) ) {
587 $array['field_type'] = 'nonce_field';
588 $array['nonce_field_name'] = $nonce[ $val ];
589 $array['nonce_field_arg'] = $key;
590 } else {
591 if ( strpos( $val, "\n" ) !== false || strpos( $val, "\r" ) !== false ) {
592 $array['field_type'] = 'textarea_field';
593 $array['textarea_field_description'] = $val;
594 $array['textarea_field_name'] = $key;
595 $array['textarea_field_value'] = $val;
596 $array['textarea_field_type'] = 'post';
597 } else {
598 $array['field_type'] = 'text_field';
599 $array['text_field_description'] = $val;
600 $array['text_field_name'] = $key;
601 $array['text_field_value'] = $val;
602 $array['text_field_type'] = 'post';
603 }
604 }
605
606 $out[] = http_build_query( $array );
607 }
608 }
609
610 if ( isset( $data['get'] ) ) {
611 foreach ( $this->flatten_array( $data['get'] ) as $key => $val ) {
612 $array = array();
613 $val = trim( $val );
614
615 if ( isset( $nonce[ $val ] ) ) {
616 $array['field_type'] = 'nonce_field';
617 $array['nonce_field_name'] = $nonce[ $val ];
618 $array['nonce_field_arg'] = $key;
619 } else {
620 $array['field_type'] = 'text_field';
621 $array['text_field_description'] = $val;
622 $array['text_field_name'] = $key;
623 $array['text_field_value'] = $val;
624 $array['text_field_type'] = 'get';
625 }
626
627 $out[] = http_build_query( $array );
628 }
629 }
630
631 $url = "";
632 if ( isset( $data['url'] ) ) {
633 $url = parse_url( $data['url'] );
634 $url = ( isset( $url['path'] ) ? $url['path'] : '' ) . ( isset( $url['query'] ) ? '?' . $url['query'] : '' );
635 }
636
637 $array = array();
638 $array['field_type'] = 'settings_field';
639 $array['settings_field_name'] = __( 'Imported', 'mainwp-key-maker' ) . ' ' . current_time( "d-m-Y H:i:s" );
640 $array['settings_field_url'] = $url;
641
642 $content = http_build_query( $array ) . '&' . implode( '&', $out );
643 $hash = sha1( $content );
644
645 $return = "-----BEGIN BULK SETTINGS MANAGER KEY-----\r\n";
646 $return .= base64_encode( $hash . '|' . $content );
647 $return .= "\r\n-----END BULK SETTINGS MANAGER KEY-----\r\n";
648
649 return $return;
650 }
651
652 /**
653 * Convert multidimensional array into single dimensional array
654 * Something like http[like][array][structure].
655 *
656 * @param array $array Multidimensional array.
657 * @param string $previous Previous value.
658 *
659 * @return array Return formatted array.
660 */
661 public function flatten_array( $array, $previous = "" ) {
662 $out = array();
663 foreach ( $array as $key => $val ) {
664 if ( is_array( $val ) ) {
665 $out = array_merge( $this->flatten_array( $val, ( $previous == "" ? $key : $previous . '[' . $key . ']' ) ), $out );
666 } else {
667 if ( $previous == "" ) {
668 $out[ $key ] = $val;
669 } else {
670 $out[ $previous . '[' . $key . ']' ] = $val;
671 }
672 }
673 }
674
675 return $out;
676 }
677 }
678
679 $mainWP = new MainWP_Key_Maker();
680