Plugin Directory

Changeset 2382782


Ignore:
Timestamp:
09/16/2020 10:05:10 AM (5 years ago)
Author:
techtimo
Message:

Update to version 0.9.1 from GitHub

Location:
spotmap
Files:
14 edited
1 copied

Legend:

Unmodified
Added
Removed
  • spotmap/tags/0.9.1/README.md

    r2319496 r2382782  
    5454## FAQ
    5555### How do I get my Feed ID
    56 First of all you need to create a XML Feed in your Spot account. If you have multiple devices, select only one.
    57 The link to the newly created feed looks similar to the following link: `http://share.findmespot.com/shared/faces/viewspots.jsp?glId=0Wl3diTJcqqvncI6NNsoqJV5ygrFtQfBB`
    58 Everthing after the `=` is your feed id:
    59 `0Wl3diTJcqqvncI6NNsoqJV5ygrFtQfBB`
     56You need to create an XML Feed in your spot account. ([See here](https://github.com/techtimo/spotmap/issues/4#issuecomment-638001718) for more details)
     57Unless you like to group devices under one name, it's good to create one feed per device, so you can manage the devices independently.
     58Your XML Feed id should look similar to this: `0Wl3diTJcqqvncI6NNsoqJV5ygrFtQfBB`
     59### Can I use/add other maps?
     60Have you created your mapbox/thunderforest API key yet? If not this is a good way to start and get other map styles.
     61If you still search for another map search [here](https://leaflet-extras.github.io/leaflet-providers/preview/) and also [here](https://wiki.openstreetmap.org/wiki/Tiles).
     62If you have found a map, create a new post in the [support forum](https://wordpress.org/support/plugin/spotmap/).
    6063
  • spotmap/tags/0.9.1/admin/class-spotmap-admin.php

    r2360204 r2382782  
    108108                'spotmap-thirdparties-group',
    109109                'spotmap-thirdparty',
    110                 ['spotmap_api_tokens['.$index.']', $value
    111                 ]
     110                ['spotmap_api_tokens['.$index.']', $value]
    112111            );
    113112        }
     
    129128                'spotmap-defaults-group',
    130129                'spotmap-defaults',
    131                 ['spotmap_default_values['.$index.']', $value
    132                 ]
     130                ['spotmap_default_values['.$index.']', $value]
    133131            );
    134132        }
  • spotmap/tags/0.9.1/includes/class-spotmap-database.php

    r2360204 r2382782  
    2020    }
    2121
    22     public function get_points($filter,$select = '*',$group_by='',$order= 'feed_name, time'){
    23         error_log(print_r($filter,true));
     22
     23    public function get_points($filter){
     24        // error_log(print_r($filter,true));
     25
     26        $select = empty($filter['select']) ? "*": $filter['select'];
     27        $group_by = empty($filter['groupBy']) ? NULL: $filter['groupBy'];
     28        $order = empty($filter['orderBy']) ? NULL: "ORDER BY " . $filter['orderBy'];
     29        $limit = empty($filter['limit']) ? NULL: "LIMIT " . $filter['limit'];
    2430        global $wpdb;
    2531        $where = '';
     
    6975            $where.= " and id in (SELECT max(id) FROM " . $wpdb->prefix . "spotmap_points GROUP BY ".$group_by." )";
    7076        }
    71         $query = "SELECT ".$select.", custom_message FROM " . $wpdb->prefix . "spotmap_points WHERE 1 ".$where." ORDER BY ".$order;
     77        $query = "SELECT ".$select.", custom_message FROM " . $wpdb->prefix . "spotmap_points WHERE 1 ".$where." ".$order. " " .$limit;
    7278        error_log("Query: " .$query);
    7379        $points = $wpdb->get_results($query);
     
    95101    public function insert_point($point,$multiple = false){
    96102        // error_log(print_r($point,true));
     103        if($point['unixTime'] == 1){
     104            return 0;
     105        }
    97106        $last_point = $this->get_last_point($point['feedId']);
    98107       
  • spotmap/tags/0.9.1/public/class-spotmap-public.php

    r2360204 r2382782  
    8282                'date' => '',
    8383                'date-range-to' => '',
     84                'auto-reload' => '0',
    8485            ], $atts);
    85         foreach (['types','feeds','feeds'] as $value) {
     86        foreach (['types','feeds'] as $value) {
    8687            if(!empty($a[$value]) && !is_array($a[$value])){
    8788                // error_log($a[$value]);
     
    99100        }
    100101       
    101         $types = $a['types'];
    102         $points = $this->db->get_points([
     102        $options = [
     103            'select' => "type,id,message,local_timezone,feed_name, time",
    103104            'type'=>$a['types'],
    104105            'feeds' => $a['feeds'],
     
    108109            ],
    109110            'date' => $a['date'],
    110         ]," type,id,message,local_timezone,feed_name, time",$a['group'],"time DESC LIMIT ".$a['count']);
    111         if (!empty($points["error"]))
    112             return wp_json_encode($points);
    113         error_log(wp_json_encode($points));
    114         $html = '<table class="wp-list-table">';
    115         // header row
    116         $html .= '<tr><th>Type</th><th>Message</th><th>Time</th><th>Local Time</th></tr>';
    117    
    118         // data rows
    119         foreach( $points as $key=>$row){
    120             $html .= '<tr class="spotmap '. $row->type;
    121             $html .= '" id="spotmap_'.$row->id.'">';
    122             $html .= '<td>'.$row->feed_name.'<br>'.$row->type.'</td>';
    123             $html .= '<td>'.$row->message.'</td>';
    124             $html .= '<td>'.$row->time.'<br>'.$row->date.'</td>';
    125             $html .= '<td>'.$row->localtime.'<br>'.$row->localdate.'</td>';
    126 
    127             $html .= '</tr>';
    128         }
    129    
    130    
    131         // finish table and return it
    132    
    133         $html .= '</table>';
    134         return $html;
     111            'orderBy' => "time DESC",
     112            'limit' => $a['count'],
     113            'groupBy' => $a['group'],
     114            'autoReload' => $a['auto-reload'],
     115        ];
     116        $table_id = "spotmap-table-".mt_rand();
     117        return '<table id='.$table_id.'></table>'
     118            .'<script type=text/javascript>var spotmap; jQuery(function(){spotmap = new Spotmap('. wp_json_encode($options).');spotmap.initTable("'.$table_id.'")})</script>';
     119
    135120    }
    136121
     
    258243    public function get_positions(){
    259244        // error_log(print_r($_POST,true));
    260         $points = $this->db->get_points($_POST,'*',$_POST['groupBy'],$_POST['orderBy']);
     245        $points = $this->db->get_points($_POST);
    261246        // error_log(print_r($points,true));
    262247        if(empty($points)){
  • spotmap/tags/0.9.1/public/js/maphandler.js

    r2360204 r2382782  
    1 var _ = lodash
    2 function debug(message,debug){
    3     if(debug == true){
    4         console.log(message)
    5     }
    6 }
     1// TODO: further investigation
     2// overides underscore.js needed for some gutenberg stuff
     3// let _ = lodash
    74
    85class Spotmap {
     
    1512    initMap(){
    1613
    17         this.debug("Lodash version: " + _.VERSION);
     14        this.debug("Lodash version: " + lodash.VERSION);
    1815   
    1916        // load maps
     
    5855        let body = {
    5956            'action': 'get_positions',
    60             'date-range': {
    61                 'from': this.options.dateRange.from,
    62                 'to': this.options.dateRange.to,
    63             },
     57            'select': "*",
     58            'date-range': this.options.dateRange,
    6459            'date': this.options.date,
    6560            'orderBy': 'feed_name, time',
     
    230225            }
    231226            // reverse order in menu to have the first element added last but shown on the menu first again
    232             _.forEachRight(gpxOverlays, function(value,key) { overlays[key] = value });
     227            lodash.forEachRight(gpxOverlays, function(value,key) { overlays[key] = value });
    233228            var displayOverlays = {};
    234229            for (let key in overlays) {
     
    405400            console.log(message)
    406401    }
     402
     403    initTable(id){
     404        // define obj to post data
     405        var body = {
     406            'action': 'get_positions',
     407            'date-range': this.options.dateRange,
     408            'date': this.options.date,
     409            'orderBy': this.options.orderBy,
     410            'limit': this.options.limit,
     411            'groupBy': this.options.groupBy,
     412        }
     413        if (this.options.feeds) {
     414            body.feeds = this.options.feeds;
     415        }
     416        var self = this;
     417        jQuery.post(spotmapjsobj.ajaxUrl, body, function (response) {
     418            let headerElements = ["Type", "Message", "Time"];
     419            let hasLocaltime = false;
     420            if (lodash.find(response, function(o) { return o.local_timezone; })){
     421                headerElements.push("Local Time");
     422                hasLocaltime = true;
     423            }
     424            var table = jQuery('#' + id);
     425            let row = '<tr>';
     426            lodash.each(headerElements,function(element){
     427                row += '<th>' + element + '</th>'
     428            })
     429            row += '<tr>'
     430            table.append(jQuery(row));
     431            lodash.forEach(response,function(entry){
     432                if(!entry.local_timezone){
     433                    entry.localdate = '';
     434                    entry.localtime = '';
     435                }
     436                if(!entry.message)
     437                    entry.message = '';
     438                let row = "<tr class='spotmap "+entry.type+"'><td id='spotmap_"+entry.id+"'>"+entry.type+"</td><td>"+entry.message+"</td><td>"+entry.time+"<br>"+entry.date+"</td>";
     439                if (hasLocaltime)
     440                    row += "<td>"+entry.localtime+"<br>"+entry.localdate+"</td>";
     441                row += "</tr>";
     442                table.append(jQuery(row))
     443            });
     444            if(self.options.autoReload == true){
     445                var oldResponse = response;
     446                var refresh = setInterval(function(){
     447                    jQuery.post(spotmapjsobj.ajaxUrl, body, function (response) {
     448                        if( lodash.head(oldResponse).unixtime < lodash.head(response).unixtime){
     449                            var table = jQuery('#' + id);
     450                            table.empty();
     451                            let headerElements = ["Type", "Message", "Time"];
     452                            let hasLocaltime = false;
     453                            if (lodash.find(response, function(o) { return o.local_timezone; })){
     454                                headerElements.push("Local Time");
     455                                hasLocaltime = true;
     456                            }
     457                            let row = '<tr>';
     458                            lodash.each(headerElements,function(element){
     459                                row += '<th>' + element + '</th>'
     460                            })
     461                            row += '<tr>'
     462                            table.append(jQuery(row));
     463                            lodash.forEach(response,function(entry){
     464                                if(!entry.local_timezone){
     465                                    entry.localdate = '';
     466                                    entry.localtime = '';
     467                                }
     468                                if(!entry.message)
     469                                    entry.message = '';
     470                                let row = "<tr class='spotmap "+entry.type+"'><td id='spotmap_"+entry.id+"'>"+entry.type+"</td><td>"+entry.message+"</td><td>"+entry.time+"<br>"+entry.date+"</td>";
     471                                if (hasLocaltime)
     472                                    row += "<td>"+entry.localtime+"<br>"+entry.localdate+"</td>";
     473                                row += "</tr>";
     474                                table.append(jQuery(row));
     475                            });
     476                        } else {
     477                            console.log('same response!');
     478                        }
     479                       
     480                    });
     481                }, 10000);
     482            }
     483        });
     484    }
    407485}
  • spotmap/tags/0.9.1/readme.txt

    r2360295 r2382782  
    138138
    139139## Changelog
     140= 0.9.1 =
     141
     142Fix Gutenberg editor issue
     143spotmessages supports auto update
     144
     145
    140146= 0.9 =
    141147
     
    168174redoing the whole frontend part. Now it looks much better!
    169175 
    170 = 0.3 =
    171 This version fixes a security related bug.  Upgrade immediately.
  • spotmap/tags/0.9.1/spotmap.php

    r2360204 r2382782  
    44 * Plugin URI:        https://github.com/techtimo/spotmap
    55 * Description:       Add an embedded map that shows the movement of a Spot device
    6  * Version:           0.9
     6 * Version:           0.9.1
    77 * Author:            Timo Giese
    88 * Author URI:        https://github.com/techtimo
  • spotmap/trunk/README.md

    r2319496 r2382782  
    5454## FAQ
    5555### How do I get my Feed ID
    56 First of all you need to create a XML Feed in your Spot account. If you have multiple devices, select only one.
    57 The link to the newly created feed looks similar to the following link: `http://share.findmespot.com/shared/faces/viewspots.jsp?glId=0Wl3diTJcqqvncI6NNsoqJV5ygrFtQfBB`
    58 Everthing after the `=` is your feed id:
    59 `0Wl3diTJcqqvncI6NNsoqJV5ygrFtQfBB`
     56You need to create an XML Feed in your spot account. ([See here](https://github.com/techtimo/spotmap/issues/4#issuecomment-638001718) for more details)
     57Unless you like to group devices under one name, it's good to create one feed per device, so you can manage the devices independently.
     58Your XML Feed id should look similar to this: `0Wl3diTJcqqvncI6NNsoqJV5ygrFtQfBB`
     59### Can I use/add other maps?
     60Have you created your mapbox/thunderforest API key yet? If not this is a good way to start and get other map styles.
     61If you still search for another map search [here](https://leaflet-extras.github.io/leaflet-providers/preview/) and also [here](https://wiki.openstreetmap.org/wiki/Tiles).
     62If you have found a map, create a new post in the [support forum](https://wordpress.org/support/plugin/spotmap/).
    6063
  • spotmap/trunk/admin/class-spotmap-admin.php

    r2360204 r2382782  
    108108                'spotmap-thirdparties-group',
    109109                'spotmap-thirdparty',
    110                 ['spotmap_api_tokens['.$index.']', $value
    111                 ]
     110                ['spotmap_api_tokens['.$index.']', $value]
    112111            );
    113112        }
     
    129128                'spotmap-defaults-group',
    130129                'spotmap-defaults',
    131                 ['spotmap_default_values['.$index.']', $value
    132                 ]
     130                ['spotmap_default_values['.$index.']', $value]
    133131            );
    134132        }
  • spotmap/trunk/includes/class-spotmap-database.php

    r2360204 r2382782  
    2020    }
    2121
    22     public function get_points($filter,$select = '*',$group_by='',$order= 'feed_name, time'){
    23         error_log(print_r($filter,true));
     22
     23    public function get_points($filter){
     24        // error_log(print_r($filter,true));
     25
     26        $select = empty($filter['select']) ? "*": $filter['select'];
     27        $group_by = empty($filter['groupBy']) ? NULL: $filter['groupBy'];
     28        $order = empty($filter['orderBy']) ? NULL: "ORDER BY " . $filter['orderBy'];
     29        $limit = empty($filter['limit']) ? NULL: "LIMIT " . $filter['limit'];
    2430        global $wpdb;
    2531        $where = '';
     
    6975            $where.= " and id in (SELECT max(id) FROM " . $wpdb->prefix . "spotmap_points GROUP BY ".$group_by." )";
    7076        }
    71         $query = "SELECT ".$select.", custom_message FROM " . $wpdb->prefix . "spotmap_points WHERE 1 ".$where." ORDER BY ".$order;
     77        $query = "SELECT ".$select.", custom_message FROM " . $wpdb->prefix . "spotmap_points WHERE 1 ".$where." ".$order. " " .$limit;
    7278        error_log("Query: " .$query);
    7379        $points = $wpdb->get_results($query);
     
    95101    public function insert_point($point,$multiple = false){
    96102        // error_log(print_r($point,true));
     103        if($point['unixTime'] == 1){
     104            return 0;
     105        }
    97106        $last_point = $this->get_last_point($point['feedId']);
    98107       
  • spotmap/trunk/public/class-spotmap-public.php

    r2360204 r2382782  
    8282                'date' => '',
    8383                'date-range-to' => '',
     84                'auto-reload' => '0',
    8485            ], $atts);
    85         foreach (['types','feeds','feeds'] as $value) {
     86        foreach (['types','feeds'] as $value) {
    8687            if(!empty($a[$value]) && !is_array($a[$value])){
    8788                // error_log($a[$value]);
     
    99100        }
    100101       
    101         $types = $a['types'];
    102         $points = $this->db->get_points([
     102        $options = [
     103            'select' => "type,id,message,local_timezone,feed_name, time",
    103104            'type'=>$a['types'],
    104105            'feeds' => $a['feeds'],
     
    108109            ],
    109110            'date' => $a['date'],
    110         ]," type,id,message,local_timezone,feed_name, time",$a['group'],"time DESC LIMIT ".$a['count']);
    111         if (!empty($points["error"]))
    112             return wp_json_encode($points);
    113         error_log(wp_json_encode($points));
    114         $html = '<table class="wp-list-table">';
    115         // header row
    116         $html .= '<tr><th>Type</th><th>Message</th><th>Time</th><th>Local Time</th></tr>';
    117    
    118         // data rows
    119         foreach( $points as $key=>$row){
    120             $html .= '<tr class="spotmap '. $row->type;
    121             $html .= '" id="spotmap_'.$row->id.'">';
    122             $html .= '<td>'.$row->feed_name.'<br>'.$row->type.'</td>';
    123             $html .= '<td>'.$row->message.'</td>';
    124             $html .= '<td>'.$row->time.'<br>'.$row->date.'</td>';
    125             $html .= '<td>'.$row->localtime.'<br>'.$row->localdate.'</td>';
    126 
    127             $html .= '</tr>';
    128         }
    129    
    130    
    131         // finish table and return it
    132    
    133         $html .= '</table>';
    134         return $html;
     111            'orderBy' => "time DESC",
     112            'limit' => $a['count'],
     113            'groupBy' => $a['group'],
     114            'autoReload' => $a['auto-reload'],
     115        ];
     116        $table_id = "spotmap-table-".mt_rand();
     117        return '<table id='.$table_id.'></table>'
     118            .'<script type=text/javascript>var spotmap; jQuery(function(){spotmap = new Spotmap('. wp_json_encode($options).');spotmap.initTable("'.$table_id.'")})</script>';
     119
    135120    }
    136121
     
    258243    public function get_positions(){
    259244        // error_log(print_r($_POST,true));
    260         $points = $this->db->get_points($_POST,'*',$_POST['groupBy'],$_POST['orderBy']);
     245        $points = $this->db->get_points($_POST);
    261246        // error_log(print_r($points,true));
    262247        if(empty($points)){
  • spotmap/trunk/public/js/maphandler.js

    r2360204 r2382782  
    1 var _ = lodash
    2 function debug(message,debug){
    3     if(debug == true){
    4         console.log(message)
    5     }
    6 }
     1// TODO: further investigation
     2// overides underscore.js needed for some gutenberg stuff
     3// let _ = lodash
    74
    85class Spotmap {
     
    1512    initMap(){
    1613
    17         this.debug("Lodash version: " + _.VERSION);
     14        this.debug("Lodash version: " + lodash.VERSION);
    1815   
    1916        // load maps
     
    5855        let body = {
    5956            'action': 'get_positions',
    60             'date-range': {
    61                 'from': this.options.dateRange.from,
    62                 'to': this.options.dateRange.to,
    63             },
     57            'select': "*",
     58            'date-range': this.options.dateRange,
    6459            'date': this.options.date,
    6560            'orderBy': 'feed_name, time',
     
    230225            }
    231226            // reverse order in menu to have the first element added last but shown on the menu first again
    232             _.forEachRight(gpxOverlays, function(value,key) { overlays[key] = value });
     227            lodash.forEachRight(gpxOverlays, function(value,key) { overlays[key] = value });
    233228            var displayOverlays = {};
    234229            for (let key in overlays) {
     
    405400            console.log(message)
    406401    }
     402
     403    initTable(id){
     404        // define obj to post data
     405        var body = {
     406            'action': 'get_positions',
     407            'date-range': this.options.dateRange,
     408            'date': this.options.date,
     409            'orderBy': this.options.orderBy,
     410            'limit': this.options.limit,
     411            'groupBy': this.options.groupBy,
     412        }
     413        if (this.options.feeds) {
     414            body.feeds = this.options.feeds;
     415        }
     416        var self = this;
     417        jQuery.post(spotmapjsobj.ajaxUrl, body, function (response) {
     418            let headerElements = ["Type", "Message", "Time"];
     419            let hasLocaltime = false;
     420            if (lodash.find(response, function(o) { return o.local_timezone; })){
     421                headerElements.push("Local Time");
     422                hasLocaltime = true;
     423            }
     424            var table = jQuery('#' + id);
     425            let row = '<tr>';
     426            lodash.each(headerElements,function(element){
     427                row += '<th>' + element + '</th>'
     428            })
     429            row += '<tr>'
     430            table.append(jQuery(row));
     431            lodash.forEach(response,function(entry){
     432                if(!entry.local_timezone){
     433                    entry.localdate = '';
     434                    entry.localtime = '';
     435                }
     436                if(!entry.message)
     437                    entry.message = '';
     438                let row = "<tr class='spotmap "+entry.type+"'><td id='spotmap_"+entry.id+"'>"+entry.type+"</td><td>"+entry.message+"</td><td>"+entry.time+"<br>"+entry.date+"</td>";
     439                if (hasLocaltime)
     440                    row += "<td>"+entry.localtime+"<br>"+entry.localdate+"</td>";
     441                row += "</tr>";
     442                table.append(jQuery(row))
     443            });
     444            if(self.options.autoReload == true){
     445                var oldResponse = response;
     446                var refresh = setInterval(function(){
     447                    jQuery.post(spotmapjsobj.ajaxUrl, body, function (response) {
     448                        if( lodash.head(oldResponse).unixtime < lodash.head(response).unixtime){
     449                            var table = jQuery('#' + id);
     450                            table.empty();
     451                            let headerElements = ["Type", "Message", "Time"];
     452                            let hasLocaltime = false;
     453                            if (lodash.find(response, function(o) { return o.local_timezone; })){
     454                                headerElements.push("Local Time");
     455                                hasLocaltime = true;
     456                            }
     457                            let row = '<tr>';
     458                            lodash.each(headerElements,function(element){
     459                                row += '<th>' + element + '</th>'
     460                            })
     461                            row += '<tr>'
     462                            table.append(jQuery(row));
     463                            lodash.forEach(response,function(entry){
     464                                if(!entry.local_timezone){
     465                                    entry.localdate = '';
     466                                    entry.localtime = '';
     467                                }
     468                                if(!entry.message)
     469                                    entry.message = '';
     470                                let row = "<tr class='spotmap "+entry.type+"'><td id='spotmap_"+entry.id+"'>"+entry.type+"</td><td>"+entry.message+"</td><td>"+entry.time+"<br>"+entry.date+"</td>";
     471                                if (hasLocaltime)
     472                                    row += "<td>"+entry.localtime+"<br>"+entry.localdate+"</td>";
     473                                row += "</tr>";
     474                                table.append(jQuery(row));
     475                            });
     476                        } else {
     477                            console.log('same response!');
     478                        }
     479                       
     480                    });
     481                }, 10000);
     482            }
     483        });
     484    }
    407485}
  • spotmap/trunk/readme.txt

    r2360295 r2382782  
    138138
    139139## Changelog
     140= 0.9.1 =
     141
     142Fix Gutenberg editor issue
     143spotmessages supports auto update
     144
     145
    140146= 0.9 =
    141147
     
    168174redoing the whole frontend part. Now it looks much better!
    169175 
    170 = 0.3 =
    171 This version fixes a security related bug.  Upgrade immediately.
  • spotmap/trunk/spotmap.php

    r2360204 r2382782  
    44 * Plugin URI:        https://github.com/techtimo/spotmap
    55 * Description:       Add an embedded map that shows the movement of a Spot device
    6  * Version:           0.9
     6 * Version:           0.9.1
    77 * Author:            Timo Giese
    88 * Author URI:        https://github.com/techtimo
Note: See TracChangeset for help on using the changeset viewer.