Changeset 2382782
- Timestamp:
- 09/16/2020 10:05:10 AM (5 years ago)
- Location:
- spotmap
- Files:
-
- 14 edited
- 1 copied
-
tags/0.9.1 (copied) (copied from spotmap/trunk)
-
tags/0.9.1/README.md (modified) (1 diff)
-
tags/0.9.1/admin/class-spotmap-admin.php (modified) (2 diffs)
-
tags/0.9.1/includes/class-spotmap-database.php (modified) (3 diffs)
-
tags/0.9.1/public/class-spotmap-public.php (modified) (4 diffs)
-
tags/0.9.1/public/js/maphandler.js (modified) (5 diffs)
-
tags/0.9.1/readme.txt (modified) (2 diffs)
-
tags/0.9.1/spotmap.php (modified) (1 diff)
-
trunk/README.md (modified) (1 diff)
-
trunk/admin/class-spotmap-admin.php (modified) (2 diffs)
-
trunk/includes/class-spotmap-database.php (modified) (3 diffs)
-
trunk/public/class-spotmap-public.php (modified) (4 diffs)
-
trunk/public/js/maphandler.js (modified) (5 diffs)
-
trunk/readme.txt (modified) (2 diffs)
-
trunk/spotmap.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
spotmap/tags/0.9.1/README.md
r2319496 r2382782 54 54 ## FAQ 55 55 ### 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` 56 You need to create an XML Feed in your spot account. ([See here](https://github.com/techtimo/spotmap/issues/4#issuecomment-638001718) for more details) 57 Unless you like to group devices under one name, it's good to create one feed per device, so you can manage the devices independently. 58 Your XML Feed id should look similar to this: `0Wl3diTJcqqvncI6NNsoqJV5ygrFtQfBB` 59 ### Can I use/add other maps? 60 Have you created your mapbox/thunderforest API key yet? If not this is a good way to start and get other map styles. 61 If 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). 62 If you have found a map, create a new post in the [support forum](https://wordpress.org/support/plugin/spotmap/). 60 63 -
spotmap/tags/0.9.1/admin/class-spotmap-admin.php
r2360204 r2382782 108 108 'spotmap-thirdparties-group', 109 109 'spotmap-thirdparty', 110 ['spotmap_api_tokens['.$index.']', $value 111 ] 110 ['spotmap_api_tokens['.$index.']', $value] 112 111 ); 113 112 } … … 129 128 'spotmap-defaults-group', 130 129 'spotmap-defaults', 131 ['spotmap_default_values['.$index.']', $value 132 ] 130 ['spotmap_default_values['.$index.']', $value] 133 131 ); 134 132 } -
spotmap/tags/0.9.1/includes/class-spotmap-database.php
r2360204 r2382782 20 20 } 21 21 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']; 24 30 global $wpdb; 25 31 $where = ''; … … 69 75 $where.= " and id in (SELECT max(id) FROM " . $wpdb->prefix . "spotmap_points GROUP BY ".$group_by." )"; 70 76 } 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; 72 78 error_log("Query: " .$query); 73 79 $points = $wpdb->get_results($query); … … 95 101 public function insert_point($point,$multiple = false){ 96 102 // error_log(print_r($point,true)); 103 if($point['unixTime'] == 1){ 104 return 0; 105 } 97 106 $last_point = $this->get_last_point($point['feedId']); 98 107 -
spotmap/tags/0.9.1/public/class-spotmap-public.php
r2360204 r2382782 82 82 'date' => '', 83 83 'date-range-to' => '', 84 'auto-reload' => '0', 84 85 ], $atts); 85 foreach (['types','feeds' ,'feeds'] as $value) {86 foreach (['types','feeds'] as $value) { 86 87 if(!empty($a[$value]) && !is_array($a[$value])){ 87 88 // error_log($a[$value]); … … 99 100 } 100 101 101 $ types = $a['types'];102 $points = $this->db->get_points([102 $options = [ 103 'select' => "type,id,message,local_timezone,feed_name, time", 103 104 'type'=>$a['types'], 104 105 'feeds' => $a['feeds'], … … 108 109 ], 109 110 '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 135 120 } 136 121 … … 258 243 public function get_positions(){ 259 244 // error_log(print_r($_POST,true)); 260 $points = $this->db->get_points($_POST ,'*',$_POST['groupBy'],$_POST['orderBy']);245 $points = $this->db->get_points($_POST); 261 246 // error_log(print_r($points,true)); 262 247 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 7 4 8 5 class Spotmap { … … 15 12 initMap(){ 16 13 17 this.debug("Lodash version: " + _.VERSION);14 this.debug("Lodash version: " + lodash.VERSION); 18 15 19 16 // load maps … … 58 55 let body = { 59 56 '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, 64 59 'date': this.options.date, 65 60 'orderBy': 'feed_name, time', … … 230 225 } 231 226 // 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 }); 233 228 var displayOverlays = {}; 234 229 for (let key in overlays) { … … 405 400 console.log(message) 406 401 } 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 } 407 485 } -
spotmap/tags/0.9.1/readme.txt
r2360295 r2382782 138 138 139 139 ## Changelog 140 = 0.9.1 = 141 142 Fix Gutenberg editor issue 143 spotmessages supports auto update 144 145 140 146 = 0.9 = 141 147 … … 168 174 redoing the whole frontend part. Now it looks much better! 169 175 170 = 0.3 =171 This version fixes a security related bug. Upgrade immediately. -
spotmap/tags/0.9.1/spotmap.php
r2360204 r2382782 4 4 * Plugin URI: https://github.com/techtimo/spotmap 5 5 * Description: Add an embedded map that shows the movement of a Spot device 6 * Version: 0.9 6 * Version: 0.9.1 7 7 * Author: Timo Giese 8 8 * Author URI: https://github.com/techtimo -
spotmap/trunk/README.md
r2319496 r2382782 54 54 ## FAQ 55 55 ### 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` 56 You need to create an XML Feed in your spot account. ([See here](https://github.com/techtimo/spotmap/issues/4#issuecomment-638001718) for more details) 57 Unless you like to group devices under one name, it's good to create one feed per device, so you can manage the devices independently. 58 Your XML Feed id should look similar to this: `0Wl3diTJcqqvncI6NNsoqJV5ygrFtQfBB` 59 ### Can I use/add other maps? 60 Have you created your mapbox/thunderforest API key yet? If not this is a good way to start and get other map styles. 61 If 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). 62 If you have found a map, create a new post in the [support forum](https://wordpress.org/support/plugin/spotmap/). 60 63 -
spotmap/trunk/admin/class-spotmap-admin.php
r2360204 r2382782 108 108 'spotmap-thirdparties-group', 109 109 'spotmap-thirdparty', 110 ['spotmap_api_tokens['.$index.']', $value 111 ] 110 ['spotmap_api_tokens['.$index.']', $value] 112 111 ); 113 112 } … … 129 128 'spotmap-defaults-group', 130 129 'spotmap-defaults', 131 ['spotmap_default_values['.$index.']', $value 132 ] 130 ['spotmap_default_values['.$index.']', $value] 133 131 ); 134 132 } -
spotmap/trunk/includes/class-spotmap-database.php
r2360204 r2382782 20 20 } 21 21 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']; 24 30 global $wpdb; 25 31 $where = ''; … … 69 75 $where.= " and id in (SELECT max(id) FROM " . $wpdb->prefix . "spotmap_points GROUP BY ".$group_by." )"; 70 76 } 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; 72 78 error_log("Query: " .$query); 73 79 $points = $wpdb->get_results($query); … … 95 101 public function insert_point($point,$multiple = false){ 96 102 // error_log(print_r($point,true)); 103 if($point['unixTime'] == 1){ 104 return 0; 105 } 97 106 $last_point = $this->get_last_point($point['feedId']); 98 107 -
spotmap/trunk/public/class-spotmap-public.php
r2360204 r2382782 82 82 'date' => '', 83 83 'date-range-to' => '', 84 'auto-reload' => '0', 84 85 ], $atts); 85 foreach (['types','feeds' ,'feeds'] as $value) {86 foreach (['types','feeds'] as $value) { 86 87 if(!empty($a[$value]) && !is_array($a[$value])){ 87 88 // error_log($a[$value]); … … 99 100 } 100 101 101 $ types = $a['types'];102 $points = $this->db->get_points([102 $options = [ 103 'select' => "type,id,message,local_timezone,feed_name, time", 103 104 'type'=>$a['types'], 104 105 'feeds' => $a['feeds'], … … 108 109 ], 109 110 '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 135 120 } 136 121 … … 258 243 public function get_positions(){ 259 244 // error_log(print_r($_POST,true)); 260 $points = $this->db->get_points($_POST ,'*',$_POST['groupBy'],$_POST['orderBy']);245 $points = $this->db->get_points($_POST); 261 246 // error_log(print_r($points,true)); 262 247 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 7 4 8 5 class Spotmap { … … 15 12 initMap(){ 16 13 17 this.debug("Lodash version: " + _.VERSION);14 this.debug("Lodash version: " + lodash.VERSION); 18 15 19 16 // load maps … … 58 55 let body = { 59 56 '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, 64 59 'date': this.options.date, 65 60 'orderBy': 'feed_name, time', … … 230 225 } 231 226 // 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 }); 233 228 var displayOverlays = {}; 234 229 for (let key in overlays) { … … 405 400 console.log(message) 406 401 } 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 } 407 485 } -
spotmap/trunk/readme.txt
r2360295 r2382782 138 138 139 139 ## Changelog 140 = 0.9.1 = 141 142 Fix Gutenberg editor issue 143 spotmessages supports auto update 144 145 140 146 = 0.9 = 141 147 … … 168 174 redoing the whole frontend part. Now it looks much better! 169 175 170 = 0.3 =171 This version fixes a security related bug. Upgrade immediately. -
spotmap/trunk/spotmap.php
r2360204 r2382782 4 4 * Plugin URI: https://github.com/techtimo/spotmap 5 5 * Description: Add an embedded map that shows the movement of a Spot device 6 * Version: 0.9 6 * Version: 0.9.1 7 7 * Author: Timo Giese 8 8 * Author URI: https://github.com/techtimo
Note: See TracChangeset
for help on using the changeset viewer.