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

src/Controllers/MapController.php (3 issues)

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