1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* This file contains only a single class. |
4
|
|
|
* |
5
|
|
|
* @file |
6
|
|
|
* @package Tabulate |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
namespace WordPress\Tabulate\Controllers; |
10
|
|
|
|
11
|
|
|
use WordPress\Tabulate\DB\Database; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* The map controller handles display exporting of geographic data. |
15
|
|
|
*/ |
16
|
|
|
class MapController extends ControllerBase { |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* The name of the POINT column. |
20
|
|
|
* |
21
|
|
|
* @var string |
22
|
|
|
*/ |
23
|
|
|
protected $point_col_name; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* The table (should contain a POINT column). |
27
|
|
|
* |
28
|
|
|
* @var \WordPress\Tabulate\DB\Table |
29
|
|
|
*/ |
30
|
|
|
protected $table; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* Set up common parts of the exports. |
34
|
|
|
* This is run for each of the public actions. |
35
|
|
|
* |
36
|
|
|
* @param string[] $args The request arguments. |
37
|
|
|
* @return null If the table doesn't contain any POINT column. |
38
|
|
|
*/ |
39
|
|
|
protected function set_up( $args ) { |
40
|
|
|
$db = new Database( $this->wpdb ); |
41
|
|
|
$this->table = $db->get_table( $args['table'] ); |
42
|
|
|
|
43
|
|
|
// Check that a point column exists. |
44
|
|
|
$points = $this->table->get_columns( 'point' ); |
45
|
|
|
if ( empty( $points ) ) { |
46
|
|
|
return; |
47
|
|
|
} |
48
|
|
|
$point_col = array_shift( $points ); |
49
|
|
|
$this->point_col_name = $point_col->get_name(); |
50
|
|
|
|
51
|
|
|
// Apply filters. |
52
|
|
|
$filter_param = (isset( $args['filter'] )) ? $args['filter'] : array(); |
53
|
|
|
$this->table->add_filters( $filter_param ); |
|
|
|
|
54
|
|
|
$this->table->add_filter( $this->point_col_name, 'not empty', '' ); |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Get the Tabulate 'by line' for inclusion in exports. |
59
|
|
|
* |
60
|
|
|
* @return string |
61
|
|
|
*/ |
62
|
|
|
protected function byline() { |
63
|
|
|
return 'Tabulate ' . TABULATE_VERSION . ' (WordPress plugin)'; |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* Export to OSM format. |
68
|
|
|
* |
69
|
|
|
* @param string[] $args The request arguments. |
70
|
|
|
*/ |
71
|
|
|
public function osm( $args ) { |
72
|
|
|
$this->set_up( $args ); |
73
|
|
|
|
74
|
|
|
// Create XML. |
75
|
|
|
$osm = new \SimpleXMLElement( '<osm />' ); |
76
|
|
|
$osm->addAttribute( 'version', '0.6' ); |
77
|
|
|
$osm->addAttribute( 'generator', $this->byline() ); |
78
|
|
|
$id = -1; |
79
|
|
|
foreach ( $this->table->get_records( false ) as $record ) { |
80
|
|
|
$geom = \geoPHP::load( $record->{$this->point_col_name}() ); |
81
|
|
|
$node = $osm->addChild( 'node' ); |
82
|
|
|
$node->addAttribute( 'id', $id ); |
83
|
|
|
$id--; |
84
|
|
|
$node->addAttribute( 'lat', $geom->getY() ); |
85
|
|
|
$node->addAttribute( 'lon', $geom->getX() ); |
86
|
|
|
$node->addAttribute( 'visible', 'true' ); // Required attribute. |
87
|
|
|
foreach ( $this->table->get_columns() as $col ) { |
88
|
|
|
if ( $col->get_name() === $this->point_col_name ) { |
89
|
|
|
// Don't include the geometry column. |
90
|
|
|
continue; |
91
|
|
|
} |
92
|
|
|
$tag = $node->addChild( 'tag' ); |
93
|
|
|
$col_name = $col->get_name(); |
94
|
|
|
$tag->addAttribute( 'k', $col_name ); |
95
|
|
|
$fktitle = $col_name . \WordPress\Tabulate\DB\Record::FKTITLE; |
96
|
|
|
$tag->addAttribute( 'v', $record->$fktitle() ); |
97
|
|
|
} |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
// Send to browser. |
101
|
|
|
$this->send_file( 'osm', 'application/xml', $osm->asXML() ); |
|
|
|
|
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Export to KML format. |
106
|
|
|
* |
107
|
|
|
* @param string[] $args The request arguments. |
108
|
|
|
*/ |
109
|
|
|
public function kml( $args ) { |
110
|
|
|
$this->set_up( $args ); |
111
|
|
|
|
112
|
|
|
// Create KML. |
113
|
|
|
$kml = new \SimpleXMLElement( '<kml />' ); |
114
|
|
|
$kml->addAttribute( 'xmlns', 'http://www.opengis.net/kml/2.2' ); |
115
|
|
|
$kml_doc = $kml->addChild( 'Document' ); |
116
|
|
|
foreach ( $this->table->get_records( false ) as $record ) { |
117
|
|
|
$placemark = $kml_doc->addChild( 'Placemark' ); |
118
|
|
|
$placemark->addChild( 'name', $record->get_title() ); |
119
|
|
|
$placemark->addChild( 'description', htmlentities( '<a href="' . $record->get_url() . '">View record.</a>' ) ); |
120
|
|
|
$point = $placemark->addChild( 'Point' ); |
121
|
|
|
$geom = \geoPHP::load( $record->{$this->point_col_name}() ); |
122
|
|
|
$point->addChild( 'coordinates', $geom->getX() . ',' . $geom->getY() ); |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
// Send to browser. |
126
|
|
|
$this->send_file( 'kml', 'application/vnd.google-earth.kml+xml', $kml->asXML() ); |
|
|
|
|
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* Export to GPX format. |
131
|
|
|
* |
132
|
|
|
* @param string[] $args The request arguments. |
133
|
|
|
*/ |
134
|
|
|
public function gpx( $args ) { |
135
|
|
|
$this->set_up( $args ); |
136
|
|
|
|
137
|
|
|
// Create GPX. |
138
|
|
|
$gpx = new \SimpleXMLElement( '<gpx xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" />' ); |
139
|
|
|
$gpx->addAttribute( 'version', '1.1' ); |
140
|
|
|
$gpx->addAttribute( 'xmlns', 'http://www.topografix.com/GPX/1/1' ); |
141
|
|
|
$gpx->addAttribute( 'creator', $this->byline() ); |
142
|
|
|
foreach ( $this->table->get_records( false ) as $record ) { |
143
|
|
|
$geom = \geoPHP::load( $record->{$this->point_col_name}() ); |
144
|
|
|
$wpt = $gpx->addChild( 'wpt' ); |
145
|
|
|
$wpt->addAttribute( 'lat', $geom->getY() ); |
146
|
|
|
$wpt->addAttribute( 'lon', $geom->getX() ); |
147
|
|
|
$wpt->addChild( 'name', $record->get_title() ); |
148
|
|
|
$wpt->addChild( 'description', htmlentities( '<a href="' . $record->get_url() . '">View record.</a>' ) ); |
149
|
|
|
$extensions = $wpt->addChild( 'extensions' ); |
150
|
|
|
$waypoint_extension = $extensions->addChild( 'gpxx:WaypointExtension', '', 'gpxx' ); |
151
|
|
|
$categories = $waypoint_extension->addChild( 'gpxx:Categories', '', 'gpxx' ); |
152
|
|
|
foreach ( $this->table->get_columns() as $col ) { |
153
|
|
|
if ( $col->get_name() === $this->point_col_name ) { |
154
|
|
|
// Don't include the geometry column. |
155
|
|
|
continue; |
156
|
|
|
} |
157
|
|
|
$fktitle = $col->get_name() . \WordPress\Tabulate\DB\Record::FKTITLE; |
158
|
|
|
$value = $record->$fktitle(); |
159
|
|
|
$categories->addChild( 'gpxx:Categories', $col->get_title() . ": $value", 'gpxx' ); |
160
|
|
|
$waypoint_extension->addChild( 'gpxx:' . $col->get_name(), $value, 'gpxx' ); |
161
|
|
|
} |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
// Send to browser. |
165
|
|
|
$this->send_file( 'gpx', 'application/gpx+xml', $gpx->asXML() ); |
|
|
|
|
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* Send a file to the client for download. |
170
|
|
|
* |
171
|
|
|
* @param string $ext The file extension. |
172
|
|
|
* @param string $mime The mime type. |
173
|
|
|
* @param string $content File contents. |
174
|
|
|
* @param string $download_name The name of the downloaded file. |
175
|
|
|
*/ |
176
|
|
|
protected function send_file( $ext, $mime, $content, $download_name = false ) { |
177
|
|
|
$download_name = date( 'Y-m-d' ) . '_' . $this->table->get_name(); |
178
|
|
|
parent::send_file( $ext, $mime, $content, $download_name ); |
179
|
|
|
} |
180
|
|
|
} |
181
|
|
|
|
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: