Completed
Push — master ( 6cab57...287bd7 )
by Sam
02:34
created

src/Controllers/MapController.php (3 issues)

Check for possibly unhandled errors passed.

Bug Security Major

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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() );
0 ignored issues
show
It seems like $osm->asXML() targeting SimpleXMLElement::asXML() can also be of type false; however, WordPress\Tabulate\Contr...Controller::send_file() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
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() );
0 ignored issues
show
It seems like $kml->asXML() targeting SimpleXMLElement::asXML() can also be of type false; however, WordPress\Tabulate\Contr...Controller::send_file() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
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() );
0 ignored issues
show
It seems like $gpx->asXML() targeting SimpleXMLElement::asXML() can also be of type false; however, WordPress\Tabulate\Contr...Controller::send_file() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
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