       1:    2:    3:    4:    5:    6:    7:    8:    9:   10:   11:   12:   13:   14:   15:   16:   17:   18:   19:   20:   21:   22:   23:   24:   25:   26:   27:   28:   29:   30:   31:   32:   33:   34:   35:   36:   37:   38:   39:   40:   41:   42:   43:   44:   45:   46:   47:   48:   49:   50:   51:   52:   53:   54:   55:   56:   57:   58:   59:   60:   61:   62:   63:   64:   65:   66:   67:   68:   69:   70:   71:   72:   73:   74:   75:   76:   77:   78:   79:   80:   81:   82:   83:   84:   85:   86:   87:   88:   89:   90:   91:   92:   93:   94:   95:   96:   97:   98:   99:  100:  101:  102:  103:  104:  105:  106:  107:  108:  109:  110:  111:  112:  113:  114:  115:  116:  117:  118:  119:  120:  121:  122:  123:  124:  125:  126:  127:  128:  129:  130:  131:  132:  133:  134:  135:  136:  137:  138:  139:  140:  141:  142:  143:  144:  145:  146:  147:  148:  149:  150:  151:  152:  153:  154:  155:  156:  157:  158:  159:  160:  161:  162:  163:  164:  165:  166:  167:  168:  169:  170:  171:  172:  173:  174:  175:  176:  177:  178:  179:  180:  181:  182:  183:  184:  185:  186:  187:  188:  189:  190:  191:  192:  193:  194:  195:  196:  197:  198:  199:  200:  201:  202:  203:  204:  205:  206:  207:  208:  209:  210:  211:  212:  213:  214:  215:  216:  217:  218:  219:  220:  221:  222:  223:  224:  225:  226:  227:  228:  229:  230:  231:  232:  233:  234:  235:  236:  237:  238:  239:  240:  241:  242:  243:  244:  245:  246:  247:  248:  249:  250:  251:  252:  253:  254:  255:  256:  257:  258:  259:  260:  261:  262:  263:  264:  265:  266:  267:  268:  269:  270:  271:  272:  273:  274:  275:  276:  277:  278:  279:  280:  281:  282:  283:  284:  285:  286:  287:  288:  289:  290:  291:  292:  293:  294:  295:  296:  297:  298:  299:  300:  301:  302:  303:  304:  305:  306:  307:  308:  309:  310:  311:  312:  313:  314:  315:  316:  317:  318:  319:  320:  321:  322:  323:  324:  325:  326:  327:  328:  329:  330:  331:  332:  333:  334:  335:  336:  337:  338:  339:  340:  341:  342:  343:  344:  345:  346:  347:  348:  349:  350:  351:  352:  353:  354:  355:  356:  357:  358:  359:  360:  361:  362:  363:  364:  365:  366:  367:  368:  369:  370:  371:  372:  373:  374:  375:  376:  377:  378:  379:  380:  381:  382:  383:  384:  385:  386:  387:  388:  389:  390:  391:  392:  393:  394:  395:  396:  397:  398:  399:  400:  401:  402:  403:  404:  405:  406:  407:  408:  409:  410:  411:  412:  413:  414:  415:  416:  417:  418:  419:  420:  421:  422:  423:  424:  425:  426:  427:  428:  429:  430:  431:  432:  433:  434:  435:  436:  437:  438:  439:  440:  441:  442:  443:  444:  445:  446:  447:  448:  449:  450:  451:  452:  453:  454:  455:  456:  457:  458:  459:  460:  461:  462:  463:  464:  465:  466:  467:  468:  469:  470:  471:  472:  473:  474:  475:  476:  477:  478:  479:  480:  481:  482:  483:  484:  485:  486:  487:  488:  489:  490:  491:  492:  493:  494:  495:  496:  497:  498:  499:  500:  501:  502:  503:  504:  505:  506:  507:  508:  509:  510:  511:  512:  513:  514:  515:  516:  517:  518:  519:  520:  521:  522:  523:  524:  525:  526:  527:  528:  529:  530:  531:  532:  533:  534:  535:  536:  537:  538:  539:  540:  541:  542:  543:  544:  545:  546:  547:  548:  549:  550:  551:  552:  553:  554:  555:  556:  557:  558:  559:  560:  561:  562:  563:  564:  565:  566:  567:  568:  569:  570:  571:  572:  573:  574:  575:  576:  577:  578:  579:  580:  581:  582:  583:  584:  585:  586:  587:  588:  589:  590:  591:  592:  593:  594:  595:  596:  597:  598:  599:  600:  601:  602:  603:  604:  605:  606:  607:  608:  609:  610:  611:  612:  613:  614:  615:  616:  617:  618:  619:  620:  621:  622:  623:  624:  625:  626:  627:  628:  629:  630:  631:  632:  633:  634:  635:  636:  637:  638:  639:  640:  641:  642:  643:  644:  645:  646:  647:  648:  649:  650:  651:  652:  653:  654:  655:  656:  657:  658:  659:  660:  661:  662:  663:  664:  665:  666:  667:  668:  669:  670:  671:  672:  673:  674:  675:  676:  677:  678:  679:  680:  681:  682:  683:  684:  685:  686:  687:  688:  689:  690:  691:  692:  693:  694:  695:  696:  697:  698:  699:  700:  701:  702:  703:  704:  705:  706:  707:  708:  709:  710:  711:  712:  713:  714:  715:  716:  717:  718:  719:  720:  721:  722:  723:  724:  725:  726:  727:  728:  729:  730:  731:  732:  733:  734:  735:  736:  737:  738:  739:  740:  741:  742:  743:  744:  745:  746:  747:  748:  749:  750:  751:  752:  753:  754:  755:  756:  757:  758:  759:  760:  761:  762:  763:  764:  765:  766:  767:  768:  769:  770:  771:  772:  773:  774:  775:  776:  777:  778:  779:  780:  781:  782:  783:  784:  785:  786:  787:  788:  789:  790:  791:  792:  793:  794:  795:  796:  797:  798:  799:  800:  801:  802:  803:  804:  805:  806:  807:  808:  809:  810:  811:  812:  813:  814:  815:  816:  817:  818:  819:  820:  821:  822:  823:  824:  825:  826:  827:  828:  829:  830:  831:  832:  833:  834:  835:  836:  837:  838:  839:  840:  841:  842:  843:  844:  845:  846:  847:  848:  849:  850:  851:  852:  853:  854:  855:  856:  857:  858:  859:  860:  861:  862:  863:  864:  865:  866:  867:  868:  869:  870:  871:  872:  873:  874:  875:  876:  877:  878:  879:  880:  881:  882:  883:  884:  885:  886:  887:  888:  889:  890:  891:  892:  893:  894:  895:  896:  897:  898:  899:  900:  901:  902:  903:  904:  905:  906:  907:  908:  909:  910:  911:  912:  913:  914:  915:  916:  917:  918:  919:  920:  921:  922:  923:  924:  925:  926:  927:  928:  929:  930:  931:  932:  933:  934:  935:  936:  937:  938:  939:  940:  941:  942:  943:  944:  945:  946:  947:  948:  949:  950:  951:  952:  953:  954:  955:  956:  957:  958:  959:  960:  961:  962:  963:  964:  965:  966:  967:  968:  969:  970:  971:  972:  973:  974:  975:  976:  977:  978:  979:  980:  981:  982:  983:  984:  985:  986:  987:  988:  989:  990:  991:  992:  993:  994:  995:  996:  997:  998:  999: 1000: 1001: 1002: 1003: 1004: 1005: 1006: 1007: 1008: 1009: 1010: 1011: 1012: 1013: 1014: 1015: 1016: 1017: 1018: 1019: 1020: 1021: 1022: 1023: 1024: 1025: 1026: 1027: 1028: 1029: 1030: 1031: 1032: 1033: 1034: 1035: 1036: 1037: 1038: 1039: 1040: 1041: 1042: 1043: 1044: 1045: 1046: 1047: 1048: 1049: 1050: 1051: 1052: 1053: 1054: 1055: 1056: 1057: 1058: 1059: 1060: 1061: 1062: 1063: 1064: 1065: 1066: 1067: 1068: 1069: 1070: 1071: 1072: 1073: 1074: 1075: 1076: 1077: 1078: 1079: 1080: 1081: 1082: 1083: 1084: 1085: 1086: 1087: 1088: 1089: 1090: 1091: 1092: 1093: 1094: 1095: 1096: 1097: 1098: 1099: 1100: 1101: 1102: 1103: 1104: 1105: 1106: 1107: 1108: 1109: 1110: 1111: 1112: 1113: 1114: 1115: 1116: 1117: 1118: 1119: 1120: 1121: 1122: 1123: 1124: 1125: 1126: 1127: 1128: 1129: 1130: 1131: 1132: 1133: 1134: 1135: 1136: 1137: 1138: 1139: 1140: 1141: 1142: 1143: 1144: 1145: 1146: 1147: 1148: 1149: 1150: 1151: 1152: 1153: 1154: 1155: 1156: 1157: 1158: 1159: 1160: 1161: 1162: 1163: 1164: 1165: 1166: 1167: 1168: 1169: 1170: 1171: 1172: 1173: 1174: 1175: 1176: 1177: 1178: 1179: 1180: 1181: 1182: 1183: 1184:

    <?php
    /**
     * WP Google Maps Pro Import / Export API: ImportCSV class
     *
     * @package WPGMapsPro\ImportExport
     * @since 7.0.0
     */

    namespace WPGMZA;

    /**
     * CSV importer for WP Google Maps Pro
     *
     * This handles importing of files.
     *
     * @since 7.0.0
     */
    class ImportCSV extends Import {

        /**
         * Import type.
         *
         * The type of import ie. map, marker, polyline etc.
         *
         * @var string Import type.
         */
        protected $import_type = '';

        /**
         * Header map.
         *
         * Maps header key string to array indexes.
         *
         * @var array Key is header string, value is array index.
         */
        protected $header_map = array();

        /**
         * Error messages by handle
         */
        protected $failure_message_by_handle;
        protected $failed_rows_by_handle;

        public function __construct($file='', $file_url='', $options=array())
        {
            Import::__construct($file, $file_url, $options);

            $this->failure_message_by_handle = array(
                'geocode_failed'    => __('Failed to geocode address', 'wp-google-maps')
            );
            $this->failed_rows_by_handle = array();
        }

        /**
         * Appends a line to the log
         * @return void
         */
        protected function failure($handle, $row_index) {

            if(!isset($this->failed_rows_by_handle[$handle]))
                $this->failed_rows_by_handle[$handle] = array();

            $this->failed_rows_by_handle[$handle][] = $row_index;

        }

        /**
         * Turns an array of numerical values, eg 2, 3, 4, 7, 8, 9, 10 and
         * condenses them down insto a string eg 2 - 4, 7 - 10
         * @return string
         */
        protected function condense_row_ids($ids) {

            if(empty($ids))
                return "";

            $len = count($ids);
            $prev = null;
            $parts = array();
            $range = null;
            $result = '';

            for($i = 0; $i < $len; $i++)
            {
                $value = $ids[$i];

                if($prev === null || $value > $prev + 1)
                {
                    // Start new range
                    $range = (object)array(
                        'start' => $value,
                        'end' => $value
                    );
                    $parts[] = $range;
                }
                else
                {
                    // Continue existing range
                    $parts[count($parts) - 1]->end = $value;
                }

                $prev = $value;
            }

            foreach($parts as $range)
            {
                if($range->start == $range->end)
                    $result .= $range->start;
                else
                    $result .= $range->start . ' - ' . $range->end;
                $result .= ', ';
            }

            return rtrim($result, ', ');

        }

        /**
         * Get the import failure notices
         * @return string The HTML
         */
        public function get_admin_notices() {

            $notices = array();

            foreach($this->failed_rows_by_handle as $handle => $row_indicies)
            {
                $message = $this->failure_message_by_handle[$handle];

                if(!empty($row_indicies)) {
                    $message .= __(' on row(s) ', 'wp-google-maps');
                    $message .= $this->condense_row_ids($row_indicies);
                }

                $notices[] = $message;
            }

            return $notices;

        }

        /**
         * Check options.
         *
         * @throws \Exception On malformed options.
         */
        protected function check_options() {

            if ( ! is_array( $this->options ) ) {

                if(empty($this->options))
                    $this->options = array();
                else
                    throw new \Exception( __( 'Error: Malformed options.', 'wp-google-maps' ) );

            }

            $this->options['geocode'] = isset( $this->options['geocode'] ) ? true : false;
            $this->options['apply']   = isset( $this->options['apply'] ) ? true : false;
            $this->options['replace'] = isset( $this->options['replace'] ) ? true : false;
            $this->options['applys']  = isset( $this->options['applys'] ) ? explode( ',', $this->options['applys'] ) : array();

            if ( $this->options['apply'] && empty( $this->options['applys'] ) ) {

                $this->options['applys'] = import_export_get_maps_list( 'ids' );

            }

            $this->options['applys'] = $this->check_ids( $this->options['applys'] );

        }

        /**
         * Parse file data.
         *
         * @throws \Exception When no header data found in file.
         */
        protected function parse_file() {

            // Convert newlines to <br/> and remove newlines, this ensures proper newline support
            $lines = array();

            $fp = fopen('php://memory', 'r+');
            fwrite($fp, $this->file_data);
            rewind($fp);

            while($cells = fgetcsv($fp))
            {
                foreach($cells as $key => $value)
                    $cells[$key] = preg_replace('/[\r\n]/', '', nl2br($value));

                $lines[] = $cells;
            }

            fclose($fp);

            $fp = fopen('php://memory', 'r+');
            $this->file_data = array();

            foreach($lines as $line)
            {
                fputcsv($fp, $line);
                rewind($fp);

                $string = fread($fp, 65536);
                $this->file_data[] = $string;

                ftruncate($fp, 0);
            }

            $headers = array_map( 'strtolower', str_getcsv( $this->file_data[0] ) );
            unset( $this->file_data[0] );

            foreach ( $headers as $index => $header ) {

                if ( strlen( $header ) > 0 ) {

                    $header = str_replace( ' ', '_', $header );
                    $this->header_map[ $header ] = $index;

                }
            }

            if( in_array('map_title', $headers, true) ) {

                $this->import_type = 'map';
                return;

            }

            if ( in_array( 'address', $headers, true ) ||
                 ( in_array( 'lat', $headers, true ) && ( in_array( 'lng', $headers, true ) ) ) ) {

                $this->import_type = 'marker';
                return;

            }

            if ( in_array( 'center_x', $headers, true ) && in_array( 'center_y', $headers, true ) &&
                 in_array( 'radius', $headers, true ) ) {

                $this->import_type = 'circle';
                return;

            }

            if ( in_array( 'polydata', $headers, true ) && in_array( 'innerpolydata', $headers, true ) ) {

                $this->import_type = 'polygon';
                return;

            }

            if ( in_array( 'polydata', $headers, true ) ) {

                $this->import_type = 'polyline';
                return;

            }

            if ( in_array( 'corner_ax', $headers, true ) && in_array( 'corner_ay', $headers, true ) &&
                 in_array( 'corner_bx', $headers, true ) && in_array( 'corner_by', $headers, true ) ) {

                $this->import_type = 'rectangle';
                return;

            }

            if ( in_array( 'dataset', $headers, true ) ) {

                $this->import_type = 'dataset';
                return;

            }

            throw new \Exception( __( 'We couldn\'t establish what kind of data you are trying to import (is the header row missing?)', 'wp-google-maps' ) );

        }

        /**
         * Output admin import options.
         *
         * @return string Options html.
         */
        public function admin_options() {

            $doing_edit = ! empty( $_POST['schedule_id'] ) ? true : false;

            $source = !empty( $this->file ) ? esc_html( basename( $this->file ) ) : ( ! empty( $this->file_url ) ? esc_html( $this->file_url ) : '' );

            $maps = import_export_get_maps_list( 'apply', $doing_edit ? $this->options['applys'] : false );

            ob_start();
            ?>
            <h2><?php esc_html_e( 'Import', 'wp-google-maps' ); ?></h2>
            <h4 data-wpgmza-import-source='<?php echo $source; ?>'><?php echo $source; ?></h4>
            <p>
            <h2><?php esc_html_e( 'CSV Data', 'wp-google-maps' ); ?></h2>
            </p>
            <p>
            <?php
            switch ( $this->import_type ) {
                case 'map':
                    esc_html_e( 'Map data found.', 'wp-google-maps' );
                    break;
                case 'marker':
                    esc_html_e( 'Marker data found.', 'wp-google-maps' );
                    break;
                case 'circle':
                    esc_html_e( 'Circle data found.', 'wp-google-maps' );
                    break;
                case 'polygon':
                    esc_html_e( 'Polygon data found.', 'wp-google-maps' );
                    break;
                case 'polyline':
                    esc_html_e( 'Polyline data found.', 'wp-google-maps' );
                    break;
                case 'rectangle':
                    esc_html_e( 'Rectangle data found.', 'wp-google-maps' );
                    break;
                case 'dataset':
                    esc_html_e( 'Heatmap data found.', 'wp-google-maps' );
                    break;
            } ?>
            </p>

            <?php
            if($this->import_type != 'map')
            {
                ?>
                <div class="switch"><input id="geocode_import" class="csv_data_import cmn-toggle cmn-toggle-round-flat" type="checkbox" <?php echo $doing_edit && $this->options['geocode'] ? 'checked' : ''; ?>><label for="geocode_import"></label></div><?php esc_html_e( 'Find Addresses or Latitude and Longitude when missing', 'wp-google-maps' ); ?><br>
                <span style="font-style:italic;"><?php esc_html_e( 'Requires Google Maps Geocoding API to be enabled.', 'wp-google-maps' ); ?></span> <a href="https://www.wpgmaps.com/documentation/creating-a-google-maps-api-key/" target="_blank">[?]</a><br>
                <br>
                <div class="switch"><input id="apply_import" class="csv_data_import cmn-toggle cmn-toggle-round-flat" type="checkbox" <?php echo empty( $maps ) ? 'disabled' : ( $doing_edit && $this->options['apply'] ? 'checked' : '' ); ?>><label for="apply_import"></label></div><?php esc_html_e( 'Apply import data to', 'wp-google-maps' ); ?>
                <br>
                <div id="maps_apply_import" style="<?php echo empty( $maps ) ? 'display:none;' : ( $doing_edit && $this->options['apply'] ? '' : 'display:none;' ); ?>width:100%;">
                    <?php if ( empty( $maps ) ) { ?>
                        <br><?php esc_html_e( 'No maps available for import to.', 'wp-google-maps' ); ?>
                    <?php } else { ?>
                        <br>
                        <div class="switch"><input id="replace_import" class="csv_data_import cmn-toggle cmn-toggle-round-flat" type="checkbox" <?php echo $doing_edit && $this->options['replace'] ? 'checked' : ''; ?>><label for="replace_import"></label></div><?php esc_html_e( 'Replace map data', 'wp-google-maps' ); ?>
                        <br>

                        <table class="wp-list-table widefat fixed striped wpgmza-listing" style="width:100%;">
                            <thead style="display:block;border-bottom:1px solid #e1e1e1;">
                            <tr style="display:block;width:100%;">
                                <th style="width:2.2em;border:none;"></th>
                                <th style="width:80px;border:none;"><?php esc_html_e( 'ID', 'wp-google-maps' ); ?></th>
                                <th style="border:none;"><?php esc_html_e( 'Title', 'wp-google-maps' ); ?></th>
                            </tr>
                            </thead>
                            <tbody style="display:block;max-height:370px;overflow-y:scroll;">
                            <?php echo $maps; ?>
                            </tbody>
                        </table>
                        <button id="maps_apply_select_all" class="wpgmza_general_btn"><?php esc_html_e( 'Select All', 'wp-google-maps' ); ?></button> <button id='maps_apply_select_none' class='wpgmza_general_btn'><?php esc_html_e( 'Select None', 'wp-google-maps' ); ?></button><br><br>
                    <?php } ?>
                </div>
                <?php
            }
            else
            {
                ?>
                <div class="switch"><input id="replace_import" class="csv_data_import cmn-toggle cmn-toggle-round-flat" type="checkbox" <?php echo $doing_edit && $this->options['replace'] ? 'checked' : ''; ?>><label for="replace_import"></label></div><?php esc_html_e( 'Replace map data', 'wp-google-maps' ); ?>
                <?php
            }
            ?>

            <br>

            <div class="delete-after-import">
                <div class="switch"><input id="delete_import" class="csv_data_import cmn-toggle cmn-toggle-round-flat" type="checkbox" <?php echo $doing_edit ? 'disabled' : ''; ?>><label for="delete_import"></label></div><?php esc_html_e( 'Delete import file after import', 'wp-google-maps' ); ?>
            </div>
            <br><br>
            <div id="import-schedule-csv-options" <?php if ( ! $doing_edit ) { ?>style="display:none;"<?php } ?>>
                <h2><?php esc_html_e( 'Scheduling Options', 'wp-google-maps' ); ?></h2>
                <?php esc_html_e( 'Start Date', 'wp-google-maps' ); ?>
                <br>
                <input type="date" id="import-schedule-csv-start" class="import-schedule-csv-options" <?php echo $doing_edit ? 'value="' . $this->options['start'] . '"' : ''; ?>>
                <br><br>
                <?php esc_html_e( 'Interval', 'wp-google-maps' ); ?>
                <br>
                <select id="import-schedule-csv-interval" class="import-schedule-csv-options">
                    <?php
                    $schedule_intervals = wp_get_schedules();
                    foreach ( $schedule_intervals as $schedule_interval_key => $schedule_interval ) { ?>
                        <option value="<?php echo esc_attr( $schedule_interval_key ); ?>" <?php echo $doing_edit && $schedule_interval_key === $this->options['interval'] ? 'selected' : ''; ?>><?php echo esc_html( $schedule_interval['display'] ); ?></option>
                    <?php } ?>
                </select>
                <br><br>
            </div>
            <p>
                <button id="import-csv" class="wpgmza_general_btn" <?php if ( $doing_edit ) { ?>style="display:none;"<?php } ?>><?php esc_html_e( 'Import', 'wp-google-maps' ); ?></button>
                <button id="import-schedule-csv" class="wpgmza_general_btn"><?php echo $doing_edit ? esc_html__( 'Update Schedule', 'wp-google-maps' ) : esc_html__( 'Schedule', 'wp-google-maps' ); ?></button>
                <button id="import-schedule-csv-cancel" class="wpgmza_general_btn" <?php if ( ! $doing_edit ) { ?>style="display:none;"<?php } ?>><?php esc_html_e( 'Cancel', 'wp-google-maps' ); ?></button>
            </p>
            <script>
                // TODO: Put this in a separate JS file and localize all the data that's using in inline PHP here

                (function($) {
                    <?php if ( ! $doing_edit ) { ?>$('.maps_apply').prop('checked', false);<?php } ?>
                    $('#maps_apply_select_all').click(function () {
                        $('.maps_apply').prop('checked', true);
                    });
                    $('#maps_apply_select_none').click(function () {
                        $('.maps_apply').prop('checked', false);
                    });
                    $('#apply_import').click(function () {
                        if ($(this).prop('checked')) {
                            $('#maps_apply_import').slideDown(300);
                        } else {
                            $('#maps_apply_import').slideUp(300);
                        }
                    });
                    function csv_get_import_options(){
                        var import_options = {};
                        var apply_check = $('.maps_apply:checked');
                        var apply_ids = [];
                        $('.csv_data_import').each(function(){
                            if ($(this).prop('checked')){
                                import_options[ $(this).attr('id').replace('_import', '') ] = '';
                            }
                        });
                        if ($('#apply_import').prop('checked')){
                            if (apply_check.length < 1){
                                alert('<?php echo wp_slash( __( 'Please select at least one map to import to, or deselect the "Apply import data to" option.', 'wp-google-maps' ) ); ?>');
                                return {};
                            }
                            apply_check.each(function(){
                                apply_ids.push($(this).val());
                            });
                            if (apply_ids.length < $('.maps_apply').length){
                                import_options['applys'] = apply_ids.join(',');
                            }
                        }
                        return import_options;
                    }
                    $('#import-csv').click(function(){
                        var import_options = csv_get_import_options();

                        // NB: Commented out, this prevents map data import if no boxes are checked
                        /*if (Object.keys(import_options).length < 1){
                            return;
                        }*/

                        $('#import_loader_text').html('<br/>\
                            <?php
                            echo wp_slash( __( 'Importing, this may take a moment...', 'wp-google-maps' ) );
                            ?> \
                            <br/>\
                            <progress id="wpgmza-import-csv-progress"/>\
                            ');

                        $('#import_loader').show();
                        $('#import_options').hide();

                        var source = $("[data-wpgmza-import-source]").attr("data-wpgmza-import-source");
                        var progressIntervalID = setInterval(function() {

                            wp.ajax.send({
                                data: {
                                    action: 'wpgmaps_get_import_progress',
                                    source: source,
                                    wpgmaps_security: WPGMZA.import_security_nonce
                                },
                                success: function(data) {
                                    $("#wpgmza-import-csv-progress").val(data);
                                }
                            })

                        }, 5000);

                        wp.ajax.send({
                            data: {
                                action: 'wpgmza_import',
                                <?php echo isset( $_POST['import_id'] ) ? 'import_id: ' . absint( $_POST['import_id'] ) . ',' : ( isset( $_POST['import_url'] ) ? "import_url: '" . $_POST['import_url'] . "'," : '' ); ?>

                                options: import_options,
                                wpgmaps_security: WPGMZA.import_security_nonce
                            },
                            success: function (data) {

                                clearInterval(progressIntervalID);

                                $('#import_loader').hide();

                                if (typeof data !== 'undefined' && data.hasOwnProperty('id')) {

                                    var type = "success";
                                    if(data.notices.length > 0)
                                        type = "warning";

                                    wpgmaps_import_add_notice('<p><?php
                                        echo wp_slash( __( 'Import completed.', 'wp-google-maps' ) );
                                    ?></p>', type);

                                    for(var i = 0; i < data.notices.length; i++) {
                                        wpgmaps_import_add_notice('<p>' + data.notices[i] + '</p>', 'error', true);
                                    }

                                    if (data.hasOwnProperty('del') && 1 === data.del){
                                        $('#import_options').html('');
                                        $('#import-list-item-' + data.id).remove();
                                        $('#import_files').show();
                                        return;
                                    }
                                }

                                $('#import_options').show();
                            },
                            error: function (data) {

                                var string = (typeof data == "string" ? data : data.statusText);

                                clearInterval(progressIntervalID);

                                if (typeof data !== 'undefined') {
                                    wpgmaps_import_add_notice(data, 'error');
                                }
                                $('#import_loader').hide();
                                $('#import_options').show();
                            }
                        });
                    });
                    $('#import-schedule-csv').click(function(){
                        if ($('#import-csv').is(':visible')) {
                            $('#import-csv,.delete-after-import').hide();
                            $('#import-schedule-csv-cancel').show();
                            $('#import-schedule-csv-options').slideDown(300);
                        } else {
                            var import_options = csv_get_import_options();
                            if (Object.keys(import_options).length < 1){
                                return;
                            }
                            if ($('#import-schedule-csv-start').val().length < 1){
                                alert('<?php echo wp_slash( __( 'Please enter a start date.', 'wp-google-maps' ) ); ?>');
                                return;
                            }
                            $('#import_loader_text').html('<br><?php echo wp_slash( __( 'Scheduling, this may take a moment...', 'wp-google-maps' ) ); ?>');
                            $('#import_loader').show();
                            $('#import_options').hide();
                            wp.ajax.send({
                                data: {
                                    action: 'wpgmza_import_schedule',
                                    <?php echo isset( $_POST['import_id'] ) ? 'import_id: ' . absint( $_POST['import_id'] ) . ',' : ( isset( $_POST['import_url'] ) ? "import_url: '" . $_POST['import_url'] . "'," : '' ); ?>

                                    options: import_options,
                                    <?php echo isset( $_POST['schedule_id'] ) ? "schedule_id: '" . $_POST['schedule_id'] . "'," : ''; ?>

                                    start: $('#import-schedule-csv-start').val(),
                                    interval: $('#import-schedule-csv-interval').val(),
                                    wpgmaps_security: WPGMZA.import_security_nonce
                                },
                                success: function (data) {
                                    if (typeof data !== 'undefined' && data.hasOwnProperty('schedule_id') && data.hasOwnProperty('next_run')) {
                                        wpgmaps_import_add_notice('<p><?php echo wp_slash( __( 'Scheduling completed.', 'wp-google-maps' ) ); ?></p>');
                                        $('#import_loader').hide();
                                        $('#import_options').html('').hide();
                                        $('#import_files').show();
                                        $('a[href="#schedule-tab"').click();
                                        var schedule_listing = '<tr id="import-schedule-list-item-' + data.schedule_id + '"><td><strong><span class="import_schedule_title" style="font-size:larger;">' + data.title + '</span></strong><br>' +
                                            '<a href="javascript:void(0);" class="import_schedule_edit" data-schedule-id="' + data.schedule_id + '"><?php esc_html_e( 'Edit', 'wp-google-maps' ); ?></a>' +
                                            ' | <a href="javascript:void(0);" class="import_schedule_delete" data-schedule-id="' + data.schedule_id + '"><?php esc_html_e( 'Delete', 'wp-google-maps' ); ?></a>' +
                                            ' | ' + ((data.next_run.length < 1 || !data.next_run) ? '<?php esc_html_e( 'No schedule found', 'wp-google-maps' ); ?>' :
                                                '<?php esc_html_e( 'Next Scheduled Run', 'wp-google-maps' ); ?>: ' + data.next_run) + '</td></tr>';
                                        if ($('#import-schedule-list-item-' + data.schedule_id).length > 0){
                                            $('#import-schedule-list-item-' + data.schedule_id).replaceWith(schedule_listing);
                                        } else {
                                            $('#wpgmap_import_schedule_list_table tbody').prepend(schedule_listing);
                                        }
                                        wpgmaps_import_setup_schedule_links(data.schedule_id);
                                        $('#wpgmaps_import_schedule_list').show();
                                    }
                                },
                                error: function (data) {
                                    if (typeof data !== 'undefined') {
                                        wpgmaps_import_add_notice(data, 'error');
                                        $('#import_loader').hide();
                                        $('#import_options').show();
                                    }
                                }
                            });
                        }
                    });
                    $('#import-schedule-csv-cancel').click(function(){
                        $('#import-csv,.delete-after-import').show();
                        $('#import-schedule-csv-cancel').hide();
                        $('#import-schedule-csv-options').slideUp(300);
                    });
                })(jQuery);
            <?php

            return ob_get_clean();

        }

        /**
         * Import the CSV file.
         */
        public function import() {

            if ( !empty($this->options['replace']) ) {

                $this->clear_map_data();

            }

            if($this->import_type != 'map')
                $this->create_map();

            $import_method = "import_{$this->import_type}s";
            $this->{$import_method}();

            $this->onImportComplete();
        }

        /**
         * Clear map data from applys.
         */
        protected function clear_map_data() {

            if ( empty( $this->options['applys'] ) && $this->import_type != "map" ) {

                return;

            }

            global $wpdb;
            global $wpgmza_tblname;
            global $wpgmza_tblname_maps;
            global $wpgmza_tblname_circles;
            global $wpgmza_tblname_datasets;
            global $wpgmza_tblname_polylines;
            global $wpgmza_tblname_poly;
            global $wpgmza_tblname_rectangles;

            $applys_in = implode( ',', $this->options['applys'] );

            switch ( $this->import_type ) {

                case 'marker':
                    $wpdb->query( "DELETE FROM `$wpgmza_tblname` WHERE `map_id` IN ($applys_in)" );
                    break;

                case 'circle':
                    $wpdb->query( "DELETE FROM `$wpgmza_tblname_circles` WHERE `map_id` IN ($applys_in)" );
                    break;

                case 'polygon':
                    $wpdb->query( "DELETE FROM `$wpgmza_tblname_poly` WHERE `map_id` IN ($applys_in)" );
                    break;

                case 'polyline':
                    $wpdb->query( "DELETE FROM `$wpgmza_tblname_polylines` WHERE `map_id` IN ($applys_in)" );
                    break;

                case 'rectangle':
                    $wpdb->query( "DELETE FROM `$wpgmza_tblname_rectangles` WHERE `map_id` IN ($applys_in)" );
                    break;

                case 'dataset':
                    $wpdb->query( "DELETE FROM `$wpgmza_tblname_datasets` WHERE `map_id` IN ($applys_in)" );
                    break;

                case "map":
                    $wpdb->query("DELETE FROM `$wpgmza_tblname_maps`");
                    break;

            }
        }

        /**
         * Create map.
         */
        protected function create_map() {

            if ( !empty($this->options['apply']) ) {

                return;

            }

            global $wpdb;
            global $wpgmza_tblname_maps;

            $map = array();
            $map['map_title'] = isset( $this->file ) ? basename( $this->file ) : ( isset( $this->file_url ) ? basename( $this->file_url ) : __( 'New CSV Map Import', 'wp-google-maps' ) );
            $map['map_start_lat'] = 0;
            $map['map_start_lng'] = 0;

            $success = $wpdb->insert( $wpgmza_tblname_maps, array(
                'map_title'            => isset( $map['map_title'] ) ? $map['map_title'] : 'New Imported Map',
                'map_width'            => isset( $map['map_width'] ) ? $map['map_width'] : 100,
                'map_height'           => isset( $map['map_height'] ) ? $map['map_height'] : 400,
                'map_start_lat'        => isset( $map['map_start_lat'] ) ? $map['map_start_lat'] : '',
                'map_start_lng'        => isset( $map['map_start_lng'] ) ? $map['map_start_lng'] : '',
                'map_start_location'   => isset( $map['map_start_location'] ) ? $map['map_start_location'] : '',
                'map_start_zoom'       => isset( $map['map_start_zoom'] ) ? $map['map_start_zoom'] : 15,
                'default_marker'       => isset( $map['default_marker'] ) ? $map['default_marker'] : 0,
                'type'                 => isset( $map['type'] ) ? $map['type'] : 3,
                'alignment'            => isset( $map['alignment'] ) ? $map['alignment'] : 1,
                'directions_enabled'   => isset( $map['directions_enabled'] ) ? $map['directions_enabled'] : 1,
                'styling_enabled'      => isset( $map['styling_enabled'] ) ? $map['styling_enabled'] : 0,
                'styling_json'         => isset( $map['styling_json'] ) ? $map['styling_json'] : '',
                'active'               => isset( $map['active'] ) ? $map['active'] : 0,
                'kml'                  => isset( $map['kml'] ) ? $map['kml'] : '',
                'bicycle'              => isset( $map['bicycle'] ) ? $map['bicycle'] : 2,
                'traffic'              => isset( $map['traffic'] ) ? $map['traffic'] : 2,
                'dbox'                 => isset( $map['dbox'] ) ? $map['dbox'] : 4,
                'dbox_width'           => isset( $map['dbox_width'] ) ? $map['dbox_width'] : 100,
                'listmarkers'          => isset( $map['listmarkers'] ) ? $map['listmarkers'] : 0,
                'listmarkers_advanced' => isset( $map['listmarkers_advanced'] ) ? $map['listmarkers_advanced'] : 0,
                'filterbycat'          => isset( $map['filterbycat'] ) ? $map['filterbycat'] : 0,
                'ugm_enabled'          => isset( $map['ugm_enabled'] ) ? $map['ugm_enabled'] : 0,
                'ugm_category_enabled' => isset( $map['ugm_category_enabled'] ) ? $map['ugm_category_enabled'] : 0,
                'fusion'               => isset( $map['fusion'] ) ? $map['fusion'] : '',
                'map_width_type'       => isset( $map['map_width_type'] ) ? $map['map_width_type'] : '\%',
                'map_height_type'      => isset( $map['map_height_type'] ) ? $map['map_height_type'] : 'px',
                'mass_marker_support'  => isset( $map['mass_marker_support'] ) ? $map['mass_marker_support'] : 0,
                'ugm_access'           => isset( $map['ugm_access'] ) ? $map['ugm_access'] : 0,
                'order_markers_by'     => isset( $map['order_markers_by'] ) ? $map['order_markers_by'] : 2,
                'order_markers_choice' => isset( $map['order_markers_choice'] ) ? $map['order_markers_choice'] : 1,
                'show_user_location'   => isset( $map['show_user_location'] ) ? $map['show_user_location'] : 1,
                'default_to'           => isset( $map['default_to'] ) ? $map['default_to'] : '',
                'other_settings'       => isset( $map['other_settings'] ) ? $map['other_settings'] : '',
            ), array(
                '%s',
                '%d',
                '%d',
                '%f',
                '%f',
                '%s',
                '%d',
                '%d',
                '%d',
                '%d',
                '%d',
                '%d',
                '%s',
                '%d',
                '%s',
                '%d',
                '%d',
                '%d',
                '%d',
                '%d',
                '%d',
                '%d',
                '%d',
                '%d',
                '%s',
                '%s',
                '%s',
                '%d',
                '%d',
                '%d',
                '%d',
                '%d',
                '%s',
                '%s',
            ) );

            if ( false !== $success ) {

                $this->options['applys'] = array(
                    $wpdb->insert_id
                );

            }
        }

        protected function import_maps() {

            global $wpdb;
            global $wpgmza_tblname_maps;

            if('map' !== $this->import_type)
                return;

            $header_count = count( $this->header_map );
            $header_map = $this->header_map;

            $columns = array_keys($header_map);
            $columns_imploded = implode(', ', $columns);

            $placeholders = array_fill(0, $header_count, '%s');
            $placeholders_imploded = implode(', ', $placeholders);

            foreach ( $this->file_data as $row_string ) {
                $row = str_getcsv($row_string);

                $qstr = "INSERT INTO $wpgmza_tblname_maps ($columns_imploded) VALUES ($placeholders_imploded)";
                $stmt = $wpdb->prepare($qstr, $row);
                $wpdb->query($stmt);

                $this->bail_if_near_time_limit();
            }
        }

        /**
         * Import markers.
         */
        protected function import_markers() {

            if ( 'marker' !== $this->import_type ) {

                return;

            }

            global $wpdb;
            global $wpgmza_tblname;

            $header_count = count( $this->header_map );

            $this->header_map['address'] = isset( $this->header_map['address'] ) ? $this->header_map['address'] : $header_count;
            $this->header_map['lat']     = isset( $this->header_map['lat'] ) ? $this->header_map['lat'] : $header_count + 1;
            $this->header_map['lng']     = isset( $this->header_map['lng'] ) ? $this->header_map['lng'] : $header_count + 2;

            $row_index = 1;
            $total_rows = count( $this->file_data );

            foreach ( $this->file_data as $marker_csv_string ) {

                $this->set_progress( $row_index / $total_rows );
                $row_index++;

                $marker = str_getcsv( $marker_csv_string );

                if ( $this->options['geocode'] ) {

                    if ( ! empty( $marker[ $this->header_map['address'] ] ) &&
                         ( empty( $marker[ $this->header_map['lat'] ] ) || empty( $marker[ $this->header_map['lng'] ] ) ) ) {

                        $latlng = $this->geocode( $marker[ $this->header_map['address'] ] );

                        if ( $latlng == false ) {

                            if ( ! empty( $this->geocode_response->status ) && ! empty( $this->geocode_response->error_message ) ) {

                                $status = $this->geocode_response->status;
                                $error_message = $this->geocode_response->error_message;

                                if ( ! isset( $this->failure_message_by_handle[ $status ] ) ) {

                                    $this->failure_message_by_handle[ $status ] = rtrim( $error_message, ' .' );

                                }

                                $this->failure( $status, $row_index );

                            } else {

                                $this->failure( 'geocode_failed', $row_index );

                            }

                            continue;

                        }

                        $marker[ $this->header_map['lat'] ] = isset( $latlng[0] ) ? $latlng[0] : 0;
                        $marker[ $this->header_map['lng'] ] = isset( $latlng[1] ) ? $latlng[1] : 0;

                    }

                    if ( empty( $marker[ $this->header_map['address'] ] ) &&
                         ! empty( $marker[ $this->header_map['lat'] ] ) && ! empty( $marker[ $this->header_map['lng'] ] ) ) {

                        $marker[ $this->header_map['address'] ] = $this->geocode( "{$marker[ $this->header_map['lat'] ]},{$marker[ $this->header_map['lng'] ]}", 'latlng' );

                    }
                }

                if ( empty( $marker[ $this->header_map['lat'] ] ) ) {

                    $marker[ $this->header_map['lat'] ] = 0;

                }

                if ( empty( $marker[ $this->header_map['lng'] ] ) ) {

                    $marker[ $this->header_map['lng'] ] = 0;

                }

                if ( empty( $marker[ $this->header_map['address'] ] ) ) {

                    $marker[ $this->header_map['address'] ] = "{$marker[ $this->header_map['lat'] ]},{$marker[ $this->header_map['lng'] ]}";

                }

                foreach ( $this->options['applys'] as $map_id ) {

                    $columnsAndPlaceholders = array(
                        'map_id'        => '%d',
                        'address'       => '%s',
                        'description'   => '%s',
                        'pic'           => '%s',
                        'link'          => '%s',
                        'icon'          => '%s',
                        'lat'           => '%s',
                        'lng'           => '%s',
                        'anim'          => '%s',
                        'title'         => '%s',
                        'infoopen'      => '%s',
                        'category'      => '%s',
                        'approved'      => '%d',
                        'retina'        => '%d',
                        'type'          => '%d',
                        'did'           => '%s',
                        'other_data'    => '%s',
                        'latlng'        => 'POINT(%f,%f)'
                    );

                    $params = array();
                    foreach($columnsAndPlaceholders as $column => $placeholder)
                    {
                        $default = ($placeholder == '%s' ? '' : 0);

                        switch($column)
                        {
                            case 'map_id':
                                $params[] = $map_id;
                                break;

                            case 'latlng':
                                $lat = $lng = 0;

                                if(isset($this->header_map[$column]) && !empty($marker[$mapped]) && preg_match_all('/-?\d*(\.\d+)?/', $marker[$mapped], $m))
                                {
                                    $lat = $m[0][0];
                                    $lng = $m[0][2];
                                }
                                else if(isset($marker[$this->header_map['lat']]) && isset($marker[$this->header_map['lng']]))
                                {
                                    $lat = $marker[ $this->header_map['lat'] ];
                                    $lng = $marker[ $this->header_map['lng'] ];
                                }

                                $params[] = $lat;
                                $params[] = $lng;

                                break;

                            default:
                                $mapped = (isset($this->header_map[$column]) ? $this->header_map[$column] : null);
                                $param = (empty($this->header_map[$mapped]) && isset($marker[$mapped]) ? $marker[$mapped] : $default);

                                if(function_exists('iconv') && function_exists('mb_detect_encoding') && function_exists('mb_detect_order'))
                                    $param = iconv(mb_detect_encoding($param, mb_detect_order(), true), "UTF-8", $param);

                                $params[] = $param;
                                break;
                        }
                    }

                    $columns        = implode(',', array_keys($columnsAndPlaceholders));
                    $placeholders   = implode(',', array_values($columnsAndPlaceholders));

                    $stmt = $wpdb->prepare("INSERT INTO `$wpgmza_tblname` ($columns) VALUES ($placeholders)", $params);

                    if(!$wpdb->query($stmt))
                    {
                        $status = 'no-row-inserted';
                        $this->failure_message_by_handle[ $status ] = 'No row was inserted';
                        $this->failure($status, $row_index);
                    }

                }

                $this->bail_if_near_time_limit();

            } // End foreach().
        }

        /**
         * Import circles.
         */
        protected function import_circles() {

            if ( 'circle' !== $this->import_type ) {

                return;

            }

            global $wpdb;
            global $wpgmza_tblname_circles;

            foreach ( $this->file_data as $circle_csv_string ) {

                $circle = str_getcsv( $circle_csv_string );

                foreach ( $this->options['applys'] as $map_id ) {

                    $success = $wpdb->query( $wpdb->prepare( "INSERT INTO `$wpgmza_tblname_circles`
                    (`map_id`,`name`,`center`,`radius`,`color`,`opacity`)
                    VALUES (%d,%s,POINT(%f,%f),%f,%s,%f)",
                        $map_id,
                        isset( $this->header_map['name'], $circle[ $this->header_map['name'] ] ) ? $circle[ $this->header_map['name'] ] : __( 'New Imported Circle', 'wp-google-maps' ),
                        isset( $this->header_map['center_x'], $circle[ $this->header_map['center_x'] ] ) ? $circle[ $this->header_map['center_x'] ] : 0,
                        isset( $this->header_map['center_y'], $circle[ $this->header_map['center_y'] ] ) ? $circle[ $this->header_map['center_y'] ] : 0,
                        isset( $this->header_map['radius'], $circle[ $this->header_map['radius'] ] ) ? $circle[ $this->header_map['radius'] ] : 20,
                        isset( $this->header_map['color'], $circle[ $this->header_map['color'] ] ) ? $circle[ $this->header_map['color'] ] : '#ff0000',
                        isset( $this->header_map['opacity'], $circle[ $this->header_map['opacity'] ] ) ? $circle[ $this->header_map['opacity'] ] : 0.6
                    ) );

                }
            }
        }

        /**
         * Import polygons.
         */
        protected function import_polygons() {

            if ( 'polygon' !== $this->import_type ) {

                return;

            }

            global $wpdb;
            global $wpgmza_tblname_poly;

            foreach ( $this->file_data as $polygon_csv_string ) {

                $polygon = str_getcsv( $polygon_csv_string );

                foreach ( $this->options['applys'] as $map_id ) {

                    $success = $wpdb->insert( $wpgmza_tblname_poly, array(
                        'map_id'        => $map_id,
                        'polydata'      => isset( $this->header_map['polydata'], $polygon[ $this->header_map['polydata'] ] ) ? $polygon[ $this->header_map['polydata'] ] : '',
                        'innerpolydata' => isset( $this->header_map['innerpolydata'], $polygon[ $this->header_map['innerpolydata'] ] ) ? $polygon[ $this->header_map['innerpolydata'] ] : '',
                        'linecolor'     => isset( $this->header_map['linecolor'], $polygon[ $this->header_map['linecolor'] ] ) ? $polygon[ $this->header_map['linecolor'] ] : '000000',
                        'lineopacity'   => isset( $this->header_map['lineopacity'], $polygon[ $this->header_map['lineopacity'] ] ) ? $polygon[ $this->header_map['lineopacity'] ] : 0.5,
                        'fillcolor'     => isset( $this->header_map['fillcolor'], $polygon[ $this->header_map['fillcolor'] ] ) ? $polygon[ $this->header_map['fillcolor'] ] : '66FF00',
                        'opacity'       => isset( $this->header_map['opacity'], $polygon[ $this->header_map['opacity'] ] ) ? $polygon[ $this->header_map['opacity'] ] : 0.5,
                        'title'         => isset( $this->header_map['title'], $polygon[ $this->header_map['title'] ] ) ? $polygon[ $this->header_map['title'] ] : '',
                        'link'          => isset( $this->header_map['link'], $polygon[ $this->header_map['link'] ] ) ? $polygon[ $this->header_map['link'] ] : '',
                        'ohfillcolor'   => isset( $this->header_map['ohfillcolor'], $polygon[ $this->header_map['ohfillcolor'] ] ) ? $polygon[ $this->header_map['ohfillcolor'] ] : '57FF78',
                        'ohlinecolor'   => isset( $this->header_map['ohlinecolor'], $polygon[ $this->header_map['ohlinecolor'] ] ) ? $polygon[ $this->header_map['ohlinecolor'] ] : '737373',
                        'ohopacity'     => isset( $this->header_map['opacity'], $polygon[ $this->header_map['opacity'] ] ) ? $polygon[ $this->header_map['opacity'] ] : 0.7,
                        'polyname'      => isset( $this->header_map['polyname'], $polygon[ $this->header_map['polyname'] ] ) ? $polygon[ $this->header_map['polyname'] ] : __( 'New Imported Polygon', 'wp-google-maps' ),
                    ), array(
                        '%d',
                        '%s',
                        '%s',
                        '%s',
                        '%f',
                        '%s',
                        '%f',
                        '%s',
                        '%s',
                        '%s',
                        '%s',
                        '%f',
                        '%s',
                    ) );

                }
            } // End foreach().
        }

        /**
         * Import polylines.
         */
        protected function import_polylines() {

            if ( 'polyline' !== $this->import_type ) {

                return;

            }

            global $wpdb;
            global $wpgmza_tblname_polylines;

            foreach ( $this->file_data as $polyline_csv_string ) {

                $polyline = str_getcsv( $polyline_csv_string );

                foreach ( $this->options['applys'] as $map_id ) {

                    $success = $wpdb->insert( $wpgmza_tblname_polylines, array(
                        'map_id'        => $map_id,
                        'polydata'      => isset( $this->header_map['polydata'], $polyline[ $this->header_map['polydata'] ] ) ? $polyline[ $this->header_map['polydata'] ] : '',
                        'linecolor'     => isset( $this->header_map['linecolor'], $polyline[ $this->header_map['linecolor'] ] ) ? $polyline[ $this->header_map['linecolor'] ] : '000000',
                        'linethickness' => isset( $this->header_map['linethickness'], $polyline[ $this->header_map['linethickness'] ] ) ? $polyline[ $this->header_map['linethickness'] ] : 4,
                        'opacity'       => isset( $this->header_map['opacity'], $polyline[ $this->header_map['opacity'] ] ) ? $polyline[ $this->header_map['opacity'] ] : 0.8,
                        'polyname'      => isset( $this->header_map['polyname'], $polyline[ $this->header_map['polyname'] ] ) ? $polyline[ $this->header_map['polyname'] ] : __( 'New Imported Polyline', 'wp-google-maps' ),
                    ), array(
                        '%d',
                        '%s',
                        '%s',
                        '%f',
                        '%f',
                        '%s',
                    ) );

                }
            }
        }

        /**
         * Import rectangles.
         */
        protected function import_rectangles() {

            if ( 'rectangle' !== $this->import_type ) {

                return;

            }

            global $wpdb;
            global $wpgmza_tblname_rectangles;

            foreach ( $this->file_data as $rectangle_csv_string ) {

                $rectangle = str_getcsv( $rectangle_csv_string );

                foreach ( $this->options['applys'] as $map_id ) {

                    $success = $wpdb->query( $wpdb->prepare( "INSERT INTO `$wpgmza_tblname_rectangles`
                    (`map_id`,`name`,`cornerA`,`cornerB`,`color`,`opacity`)
                    VALUES (%d,%s,POINT(%f,%f),POINT(%f,%f),%s,%f)",
                        $map_id,
                        isset( $this->header_map['name'], $rectangle[ $this->header_map['name'] ] ) ? $rectangle[ $this->header_map['name'] ] : __( 'New Imported Rectangle', 'wp-google-maps' ),
                        isset( $this->header_map['corner_ax'], $rectangle[ $this->header_map['corner_ax'] ] ) ? $rectangle[ $this->header_map['corner_ax'] ] : 0,
                        isset( $this->header_map['corner_ay'], $rectangle[ $this->header_map['corner_ay'] ] ) ? $rectangle[ $this->header_map['corner_ay'] ] : 0,
                        isset( $this->header_map['corner_bx'], $rectangle[ $this->header_map['corner_bx'] ] ) ? $rectangle[ $this->header_map['corner_bx'] ] : 0,
                        isset( $this->header_map['corner_by'], $rectangle[ $this->header_map['corner_by'] ] ) ? $rectangle[ $this->header_map['corner_by'] ] : 0,
                        isset( $this->header_map['color'], $rectangle[ $this->header_map['color'] ] ) ? $rectangle[ $this->header_map['color'] ] : '#ff0000',
                        isset( $this->header_map['opacity'], $rectangle[ $this->header_map['opacity'] ] ) ? $rectangle[ $this->header_map['opacity'] ] : 0.6
                    ) );

                }
            }
        }

        /**
         * Import datasets.
         */
        protected function import_datasets() {

            if ( 'dataset' !== $this->import_type ) {

                return;

            }

            global $wpdb;
            global $wpgmza_tblname_datasets;

            foreach ( $this->file_data as $dataset_csv_string ) {

                $dataset = str_getcsv( $dataset_csv_string );

                foreach ( $this->options['applys'] as $map_id ) {

                    $success = $wpdb->insert( $wpgmza_tblname_datasets, array(
                        'map_id'        => $map_id,
                        'type'         => isset( $this->header_map['type'], $dataset[ $this->header_map['type'] ] ) ? $dataset[ $this->header_map['type'] ] : 0,
                        'dataset_name' => isset( $this->header_map['dataset_name'], $dataset[ $this->header_map['dataset_name'] ] ) ? $dataset[ $this->header_map['dataset_name'] ] : __( 'New Imported Dataset', 'wp-google-maps' ),
                        'dataset'      => isset( $this->header_map['dataset'], $dataset[ $this->header_map['dataset'] ] ) ? $dataset[ $this->header_map['dataset'] ] : '',
                        'options'      => isset( $this->header_map['options'], $dataset[ $this->header_map['options'] ] ) ? $dataset[ $this->header_map['options'] ] : '',
                    ), array(
                        '%d',
                        '%d',
                        '%s',
                        '%s',
                        '%s',
                    ) );

                }
            }
        }
    }