Completed
Push — master ( 3f174d...72d96f )
by Yannick
12:45
created

SpotterArchive   D

Complexity

Total Complexity 129

Size/Duplication

Total Lines 900
Duplicated Lines 37.33 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 9
Bugs 2 Features 2
Metric Value
c 9
b 2
f 2
dl 336
loc 900
rs 4.4444
wmc 129
lcom 1
cbo 3

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B addSpotterArchiveData() 0 26 5
A getLastArchiveSpotterDataByIdent() 13 13 1
B getLastArchiveSpotterDataById() 24 24 1
A getAllArchiveSpotterDataById() 18 18 2
A getCoordArchiveSpotterDataById() 18 18 2
A getAltitudeArchiveSpotterDataByIdent() 18 18 2
A getAltitudeArchiveSpotterDataById() 18 18 2
A getAltitudeSpeedArchiveSpotterDataById() 18 18 2
A getLastAltitudeArchiveSpotterDataByIdent() 19 19 2
A getSpotterArchiveData() 0 10 1
A deleteSpotterArchiveTrackData() 0 12 2
D getMinLiveSpotterData() 12 48 12
C getMinLiveSpotterDataPlayback() 12 59 12
D getLiveSpotterCount() 15 39 12
F searchSpotterData() 96 326 54
A deleteSpotterArchiveData() 16 16 3
C getSpotterDataByIdent() 0 48 7
B countAllFlightOverCountries() 39 39 6

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like SpotterArchive often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use SpotterArchive, and based on these observations, apply Extract Interface, too.

1
<?php
2
class SpotterArchive {
3
    public $global_query = "SELECT spotter_archive.* FROM spotter_archive";
4
    public $db;
5
6
    function __construct($dbc = null) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
7
            $Connection = new Connection($dbc);
8
            $this->db = $Connection->db;
9
    }
10
11
12
    // Spotter_archive
13
    
14
    function addSpotterArchiveData($flightaware_id = '', $ident = '', $registration = '', $airline_name = '', $airline_icao = '', $airline_country = '', $airline_type = '', $aircraft_icao = '', $aircraft_shadow = '', $aircraft_name = '', $aircraft_manufacturer = '', $departure_airport_icao = '', $departure_airport_name = '', $departure_airport_city = '', $departure_airport_country = '', $departure_airport_time = '',$arrival_airport_icao = '', $arrival_airport_name = '', $arrival_airport_city ='', $arrival_airport_country = '', $arrival_airport_time = '', $route_stop = '', $date = '',$latitude = '', $longitude = '', $waypoints = '', $altitude = '', $heading = '', $ground_speed = '', $squawk = '', $ModeS = '', $pilot_id = '', $pilot_name = '',$verticalrate = '',$format_source = '', $source_name = '', $over_country = '') {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
15
	require_once(dirname(__FILE__).'/class.Spotter.php');
16
        if ($over_country == '') {
17
	        $Spotter = new Spotter($this->db);
18
	        $data_country = $Spotter->getCountryFromLatitudeLongitude($latitude,$longitude);
19
		if (!empty($data_country)) $country = $data_country['iso2'];
20
		else $country = '';
21
	} else $country = $over_country;
22
	if ($airline_type === NULL) $airline_type ='';
23
	
24
	//if ($country == '') echo "\n".'************ UNKNOW COUNTRY ****************'."\n";
1 ignored issue
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
25
	//else echo "\n".'*/*/*/*/*/*/*/ Country : '.$country.' */*/*/*/*/*/*/*/*/'."\n";
1 ignored issue
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
26
27
	// Route is not added in spotter_archive
28
	$query  = "INSERT INTO spotter_archive (flightaware_id, ident, registration, airline_name, airline_icao, airline_country, airline_type, aircraft_icao, aircraft_shadow, aircraft_name, aircraft_manufacturer, departure_airport_icao, departure_airport_name, departure_airport_city, departure_airport_country, departure_airport_time,arrival_airport_icao, arrival_airport_name, arrival_airport_city, arrival_airport_country, arrival_airport_time, route_stop, date,latitude, longitude, waypoints, altitude, heading, ground_speed, squawk, ModeS, pilot_id, pilot_name, verticalrate,format_source,over_country,source_name)
29
                VALUES (:flightaware_id, :ident, :registration, :airline_name, :airline_icao, :airline_country, :airline_type, :aircraft_icao, :aircraft_shadow, :aircraft_name, :aircraft_manufacturer, :departure_airport_icao, :departure_airport_name, :departure_airport_city, :departure_airport_country, :departure_airport_time,:arrival_airport_icao, :arrival_airport_name, :arrival_airport_city, :arrival_airport_country, :arrival_airport_time, :route_stop, :date,:latitude, :longitude, :waypoints, :altitude, :heading, :ground_speed, :squawk, :ModeS, :pilot_id, :pilot_name, :verticalrate, :format_source, :over_country, :source_name)";
30
31
        $query_values = array(':flightaware_id' => $flightaware_id, ':ident' => $ident, ':registration' => $registration, ':airline_name' => $airline_name, ':airline_icao' => $airline_icao, ':airline_country' => $airline_country, ':airline_type' => $airline_type, ':aircraft_icao' => $aircraft_icao, ':aircraft_shadow' => $aircraft_shadow, ':aircraft_name' => $aircraft_name, ':aircraft_manufacturer' => $aircraft_manufacturer, ':departure_airport_icao' => $departure_airport_icao, ':departure_airport_name' => $departure_airport_name, ':departure_airport_city' => $departure_airport_city, ':departure_airport_country' => $departure_airport_country, ':departure_airport_time' => $departure_airport_time,':arrival_airport_icao' => $arrival_airport_icao, ':arrival_airport_name' => $arrival_airport_name, ':arrival_airport_city' => $arrival_airport_city, ':arrival_airport_country' => $arrival_airport_country, ':arrival_airport_time' => $arrival_airport_time, ':route_stop' => $route_stop, ':date' => $date,':latitude' => $latitude, ':longitude' => $longitude, ':waypoints' => $waypoints, ':altitude' => $altitude, ':heading' => $heading, ':ground_speed' => $ground_speed, ':squawk' => $squawk, ':ModeS' => $ModeS, ':pilot_id' => $pilot_id, ':pilot_name' => $pilot_name, ':verticalrate' => $verticalrate, ':format_source' => $format_source, ':over_country' => $country, ':source_name' => $source_name);
32
        try {
33
            $sth = $this->db->prepare($query);
1 ignored issue
show
Bug introduced by
The method prepare cannot be called on $this->db (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
34
            $sth->execute($query_values);
35
        } catch(PDOException $e) {
36
            return "error : ".$e->getMessage();
37
        }
38
        return "success";
39
    }
40
41
42
        /**
43
        * Gets all the spotter information based on a particular callsign
44
        *
45
        * @return Array the spotter information
46
        *
47
        */
48 View Code Duplication
        public function getLastArchiveSpotterDataByIdent($ident)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
49
        {
50
		$Spotter = new Spotter($this->db);
51
                date_default_timezone_set('UTC');
52
53
                $ident = filter_var($ident, FILTER_SANITIZE_STRING);
54
                //$query  = "SELECT spotter_archive.* FROM spotter_archive INNER JOIN (SELECT l.flightaware_id, max(l.date) as maxdate FROM spotter_archive l WHERE l.ident = :ident GROUP BY l.flightaware_id) s on spotter_archive.flightaware_id = s.flightaware_id AND spotter_archive.date = s.maxdate LIMIT 1";
1 ignored issue
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
55
                $query  = "SELECT spotter_archive.* FROM spotter_archive WHERE ident = :ident ORDER BY date DESC LIMIT 1";
56
57
                $spotter_array = $Spotter->getDataFromDB($query,array(':ident' => $ident));
58
59
                return $spotter_array;
60
        }
61
62
63
        /**
64
        * Gets last the spotter information based on a particular id
65
        *
66
        * @return Array the spotter information
67
        *
68
        */
69 View Code Duplication
        public function getLastArchiveSpotterDataById($id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
70
        {
71
    		$Spotter = new Spotter($this->db);
72
                date_default_timezone_set('UTC');
73
                $id = filter_var($id, FILTER_SANITIZE_STRING);
74
                //$query  = SpotterArchive->$global_query." WHERE spotter_archive.flightaware_id = :id";
1 ignored issue
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
75
                //$query  = "SELECT spotter_archive.* FROM spotter_archive INNER JOIN (SELECT l.flightaware_id, max(l.date) as maxdate FROM spotter_archive l WHERE l.flightaware_id = :id GROUP BY l.flightaware_id) s on spotter_archive.flightaware_id = s.flightaware_id AND spotter_archive.date = s.maxdate LIMIT 1";
1 ignored issue
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
76
                $query  = "SELECT * FROM spotter_archive WHERE flightaware_id = :id ORDER BY date DESC LIMIT 1";
77
78
//              $spotter_array = Spotter->getDataFromDB($query,array(':id' => $id));
1 ignored issue
show
Unused Code Comprehensibility introduced by
62% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
79
                  /*
1 ignored issue
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
80
                try {
81
                        $Connection = new Connection();
82
                        $sth = Connection->$db->prepare($query);
83
                        $sth->execute(array(':id' => $id));
84
                } catch(PDOException $e) {
85
                        return "error";
86
                }
87
                $spotter_array = $sth->fetchAll(PDO->FETCH_ASSOC);
88
                */
89
                $spotter_array = $Spotter->getDataFromDB($query,array(':id' => $id));
90
91
                return $spotter_array;
92
        }
93
94
        /**
95
        * Gets all the spotter information based on a particular id
96
        *
97
        * @return Array the spotter information
98
        *
99
        */
100 View Code Duplication
        public function getAllArchiveSpotterDataById($id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
101
        {
102
                date_default_timezone_set('UTC');
103
                $id = filter_var($id, FILTER_SANITIZE_STRING);
104
                $query  = $this->global_query." WHERE spotter_archive.flightaware_id = :id";
105
106
//              $spotter_array = Spotter->getDataFromDB($query,array(':id' => $id));
1 ignored issue
show
Unused Code Comprehensibility introduced by
62% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
107
108
                try {
109
                        $sth = $this->db->prepare($query);
1 ignored issue
show
Bug introduced by
The method prepare cannot be called on $this->db (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
110
                        $sth->execute(array(':id' => $id));
111
                } catch(PDOException $e) {
112
                        return "error";
0 ignored issues
show
Bug Best Practice introduced by
The return type of return 'error'; (string) is incompatible with the return type documented by SpotterArchive::getAllArchiveSpotterDataById of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
113
                }
114
                $spotter_array = $sth->fetchAll(PDO::FETCH_ASSOC);
115
116
                return $spotter_array;
117
        }
118
119
        /**
120
        * Gets coordinate & time spotter information based on a particular id
121
        *
122
        * @return Array the spotter information
123
        *
124
        */
125 View Code Duplication
        public function getCoordArchiveSpotterDataById($id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
126
        {
127
                date_default_timezone_set('UTC');
128
                $id = filter_var($id, FILTER_SANITIZE_STRING);
129
                $query  = "SELECT spotter_archive.latitude, spotter_archive.longitude, spotter_archive.date FROM spotter_archive WHERE spotter_archive.flightaware_id = :id";
130
131
//              $spotter_array = Spotter->getDataFromDB($query,array(':id' => $id));
1 ignored issue
show
Unused Code Comprehensibility introduced by
62% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
132
133
                try {
134
                        $sth = $this->db->prepare($query);
1 ignored issue
show
Bug introduced by
The method prepare cannot be called on $this->db (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
135
                        $sth->execute(array(':id' => $id));
136
                } catch(PDOException $e) {
137
                        return $e->getMessage();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $e->getMessage(); (string) is incompatible with the return type documented by SpotterArchive::getCoordArchiveSpotterDataById of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
138
                }
139
                $spotter_array = $sth->fetchAll(PDO::FETCH_ASSOC);
140
141
                return $spotter_array;
142
        }
143
144
145
        /**
146
        * Gets altitude information based on a particular callsign
147
        *
148
        * @return Array the spotter information
149
        *
150
        */
151 View Code Duplication
        public function getAltitudeArchiveSpotterDataByIdent($ident)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
152
        {
153
154
                date_default_timezone_set('UTC');
155
156
                $ident = filter_var($ident, FILTER_SANITIZE_STRING);
157
                $query  = "SELECT spotter_archive.altitude, spotter_archive.date FROM spotter_archive WHERE spotter_archive.ident = :ident";
158
159
                try {
160
                        $sth = $this->db->prepare($query);
1 ignored issue
show
Bug introduced by
The method prepare cannot be called on $this->db (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
161
                        $sth->execute(array(':ident' => $ident));
162
                } catch(PDOException $e) {
163
                        return "error";
0 ignored issues
show
Bug Best Practice introduced by
The return type of return 'error'; (string) is incompatible with the return type documented by SpotterArchive::getAltit...chiveSpotterDataByIdent of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
164
                }
165
                $spotter_array = $sth->fetchAll(PDO::FETCH_ASSOC);
166
167
                return $spotter_array;
168
        }
169
170
        /**
171
        * Gets altitude information based on a particular id
172
        *
173
        * @return Array the spotter information
174
        *
175
        */
176 View Code Duplication
        public function getAltitudeArchiveSpotterDataById($id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
177
        {
178
179
                date_default_timezone_set('UTC');
180
181
                $id = filter_var($id, FILTER_SANITIZE_STRING);
182
                $query  = "SELECT spotter_archive.altitude, spotter_archive.date FROM spotter_archive WHERE spotter_archive.flightaware_id = :id";
183
184
                try {
185
                        $sth = $this->db->prepare($query);
1 ignored issue
show
Bug introduced by
The method prepare cannot be called on $this->db (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
186
                        $sth->execute(array(':id' => $id));
187
                } catch(PDOException $e) {
188
                        return "error";
0 ignored issues
show
Bug Best Practice introduced by
The return type of return 'error'; (string) is incompatible with the return type documented by SpotterArchive::getAltitudeArchiveSpotterDataById of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
189
                }
190
                $spotter_array = $sth->fetchAll(PDO::FETCH_ASSOC);
191
192
                return $spotter_array;
193
        }
194
195
        /**
196
        * Gets altitude & speed information based on a particular id
197
        *
198
        * @return Array the spotter information
199
        *
200
        */
201 View Code Duplication
        public function getAltitudeSpeedArchiveSpotterDataById($id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
202
        {
203
204
                date_default_timezone_set('UTC');
205
206
                $id = filter_var($id, FILTER_SANITIZE_STRING);
207
                $query  = "SELECT spotter_archive.altitude, spotter_archive.ground_speed, spotter_archive.date FROM spotter_archive WHERE spotter_archive.flightaware_id = :id";
208
209
                try {
210
                        $sth = $this->db->prepare($query);
1 ignored issue
show
Bug introduced by
The method prepare cannot be called on $this->db (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
211
                        $sth->execute(array(':id' => $id));
212
                } catch(PDOException $e) {
213
		        return "error : ".$e->getMessage();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return 'error : ' . $e->getMessage(); (string) is incompatible with the return type documented by SpotterArchive::getAltit...dArchiveSpotterDataById of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
214
                }
215
                $spotter_array = $sth->fetchAll(PDO::FETCH_ASSOC);
216
217
                return $spotter_array;
218
        }
219
220
221
        /**
222
        * Gets altitude information based on a particular callsign
223
        *
224
        * @return Array the spotter information
225
        *
226
        */
227 View Code Duplication
        public function getLastAltitudeArchiveSpotterDataByIdent($ident)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
228
        {
229
230
                date_default_timezone_set('UTC');
231
232
                $ident = filter_var($ident, FILTER_SANITIZE_STRING);
233
                $query  = "SELECT spotter_archive.altitude, spotter_archive.date FROM spotter_archive INNER JOIN (SELECT l.flightaware_id, max(l.date) as maxdate FROM spotter_archive l WHERE l.ident = :ident GROUP BY l.flightaware_id) s on spotter_archive.flightaware_id = s.flightaware_id AND spotter_archive.date = s.maxdate LIMIT 1";
234
//                $query  = "SELECT spotter_archive.altitude, spotter_archive.date FROM spotter_archive WHERE spotter_archive.ident = :ident";
1 ignored issue
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
235
236
                try {
237
                        $sth = $this->db->prepare($query);
1 ignored issue
show
Bug introduced by
The method prepare cannot be called on $this->db (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
238
                        $sth->execute(array(':ident' => $ident));
239
                } catch(PDOException $e) {
240
                        return "error";
0 ignored issues
show
Bug Best Practice introduced by
The return type of return 'error'; (string) is incompatible with the return type documented by SpotterArchive::getLastA...chiveSpotterDataByIdent of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
241
                }
242
                $spotter_array = $sth->fetchAll(PDO::FETCH_ASSOC);
243
244
                return $spotter_array;
245
        }
246
247
248
249
       /**
250
        * Gets all the archive spotter information
251
        *
252
        * @return Array the spotter information
253
        *
254
        */
255
        public function getSpotterArchiveData($ident,$flightaware_id,$date)
256
        {
257
    		$Spotter = new Spotter($this->db);
258
                $ident = filter_var($ident, FILTER_SANITIZE_STRING);
259
                $query  = "SELECT spotter_live.* FROM spotter_live INNER JOIN (SELECT l.flightaware_id, max(l.date) as maxdate FROM spotter_live l WHERE l.ident = :ident AND l.flightaware_id = :flightaware_id AND l.date LIKE :date GROUP BY l.flightaware_id) s on spotter_live.flightaware_id = s.flightaware_id AND spotter_live.date = s.maxdate";
260
261
                $spotter_array = $Spotter->getDataFromDB($query,array(':ident' => $ident,':flightaware_id' => $flightaware_id,':date' => $date.'%'));
262
263
                return $spotter_array;
264
        }
265
        
266
        public function deleteSpotterArchiveTrackData()
267
        {
268
		global $globalArchiveKeepTrackMonths;
269
                date_default_timezone_set('UTC');
270
		$query = 'DELETE FROM spotter_archive WHERE spotter_archive.date < DATE_SUB(UTC_TIMESTAMP(), INTERVAL '.$globalArchiveKeepTrackMonths.' MONTH)';
271
                try {
272
                        $sth = $this->db->prepare($query);
1 ignored issue
show
Bug introduced by
The method prepare cannot be called on $this->db (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
273
                        $sth->execute();
274
                } catch(PDOException $e) {
275
                        return "error";
276
                }
277
	}
278
279
	/**
280
        * Gets Minimal Live Spotter data
281
        *
282
        * @return Array the spotter information
283
        *
284
        */
285
        public function getMinLiveSpotterData($begindate,$enddate,$filter = array())
0 ignored issues
show
Unused Code introduced by
The parameter $enddate is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
286
        {
287
                global $globalDBdriver, $globalLiveInterval;
288
                date_default_timezone_set('UTC');
289
290
                $filter_query = '';
291 View Code Duplication
                if (isset($filter['source']) && !empty($filter['source'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
292
                        $filter_query .= " AND format_source IN ('".implode("','",$filter['source'])."') ";
293
                }
294
                // Use spotter_output also ?
295 View Code Duplication
                if (isset($filter['airlines']) && !empty($filter['airlines'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
296
                        $filter_query .= " INNER JOIN (SELECT flightaware_id FROM spotter_archive_output WHERE spotter_archive_output.airline_icao IN ('".implode("','",$filter['airlines'])."')) so ON so.flightaware_id = spotter_archive.flightaware_id ";
297
                }
298 View Code Duplication
                if (isset($filter['airlinestype']) && !empty($filter['airlinestype'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
299
                        $filter_query .= " INNER JOIN (SELECT flightaware_id FROM spotter_archive_output WHERE spotter_archive_output.airline_type = '".$filter['airlinestype']."') sa ON sa.flightaware_id = spotter_archive.flightaware_id ";
300
                }
301 View Code Duplication
                if (isset($filter['source_aprs']) && !empty($filter['source_aprs'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
302
                        $filter_query = " AND format_source = 'aprs' AND source_name IN ('".implode("','",$filter['source_aprs'])."')";
303
                }
304
305
                //if (!isset($globalLiveInterval)) $globalLiveInterval = '200';
1 ignored issue
show
Unused Code Comprehensibility introduced by
69% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
306
                if ($globalDBdriver == 'mysql') {
307
                        /*
1 ignored issue
show
Unused Code Comprehensibility introduced by
52% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
308
                        $query  = 'SELECT a.aircraft_shadow, spotter_archive.ident, spotter_archive.flightaware_id, spotter_archive.aircraft_icao, spotter_archive.departure_airport_icao as departure_airport, spotter_archive.arrival_airport_icao as arrival_airport, spotter_archive.latitude, spotter_archive.longitude, spotter_archive.altitude, spotter_archive.heading, spotter_archive.ground_speed, spotter_archive.squawk 
309
                    		    FROM spotter_archive 
310
                    		    INNER JOIN (SELECT l.flightaware_id, max(l.date) as maxdate FROM spotter_archive l WHERE (l.date BETWEEN '."'".$begindate."'".' AND '."'".$enddate."'".') GROUP BY l.flightaware_id) s on spotter_archive.flightaware_id = s.flightaware_id AND spotter_archive.date = s.maxdate '.$filter_query.'LEFT JOIN (SELECT aircraft_shadow,icao FROM aircraft) a ON spotter_archive.aircraft_icao = a.icao';
311
			*/
312
			$query  = 'SELECT a.aircraft_shadow, spotter_archive.ident, spotter_archive.flightaware_id, spotter_archive.aircraft_icao, spotter_archive.departure_airport_icao as departure_airport, spotter_archive.arrival_airport_icao as arrival_airport, spotter_archive.latitude, spotter_archive.longitude, spotter_archive.altitude, spotter_archive.heading, spotter_archive.ground_speed, spotter_archive.squawk 
313
				    FROM spotter_archive 
314
				    INNER JOIN (SELECT l.flightaware_id, max(l.date) as maxdate 
315
						FROM spotter_archive l 
316
						WHERE (l.date BETWEEN DATE_SUB('."'".$begindate."'".',INTERVAL '.$globalLiveInterval.' SECOND) AND '."'".$begindate."'".') 
317
						GROUP BY l.flightaware_id) s on spotter_archive.flightaware_id = s.flightaware_id 
318
				    AND spotter_archive.date = s.maxdate '.$filter_query.'LEFT JOIN (SELECT aircraft_shadow,icao FROM aircraft) a ON spotter_archive.aircraft_icao = a.icao';
319
                } else if ($globalDBdriver == 'pgsql') {
320
                        $query  = 'SELECT spotter_archive.ident, spotter_archive.flightaware_id, spotter_archive.aircraft_icao, spotter_archive.departure_airport_icao as departure_airport, spotter_archive.arrival_airport_icao as arrival_airport, spotter_archive.latitude, spotter_archive.longitude, spotter_archive.altitude, spotter_archive.heading, spotter_archive.ground_speed, spotter_archive.squawk, a.aircraft_shadow FROM spotter_archive INNER JOIN (SELECT l.flightaware_id, max(l.date) as maxdate FROM spotter_archive l WHERE DATE_SUB(UTC_TIMESTAMP(),INTERVAL '.$globalLiveInterval.' SECOND) <= l.date GROUP BY l.flightaware_id) s on spotter_archive.flightaware_id = s.flightaware_id AND spotter_archive.date = s.maxdate '.$filter_query.'INNER JOIN (SELECT * FROM aircraft) a on spotter_archive.aircraft_icao = a.icao';
321
                }
322
                //echo $query;
323
                try {
324
                        $sth = $this->db->prepare($query);
1 ignored issue
show
Bug introduced by
The variable $query does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The method prepare cannot be called on $this->db (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
325
                        $sth->execute();
326
                } catch(PDOException $e) {
327
                        return "error";
0 ignored issues
show
Bug Best Practice introduced by
The return type of return 'error'; (string) is incompatible with the return type documented by SpotterArchive::getMinLiveSpotterData of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
328
                }
329
                $spotter_array = $sth->fetchAll(PDO::FETCH_ASSOC);
330
331
                return $spotter_array;
332
        }
333
334
	/**
335
        * Gets Minimal Live Spotter data
336
        *
337
        * @return Array the spotter information
338
        *
339
        */
340
        public function getMinLiveSpotterDataPlayback($begindate,$enddate,$filter = array())
341
        {
342
                global $globalDBdriver, $globalLiveInterval;
343
                date_default_timezone_set('UTC');
344
345
                $filter_query = '';
346 View Code Duplication
                if (isset($filter['source']) && !empty($filter['source'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
347
                        $filter_query .= " AND format_source IN ('".implode("','",$filter['source'])."') ";
348
                }
349
                // FIXME : use spotter_output also
350 View Code Duplication
                if (isset($filter['airlines']) && !empty($filter['airlines'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
351
                        $filter_query .= " INNER JOIN (SELECT flightaware_id FROM spotter_archive_output WHERE spotter_archive_output.airline_icao IN ('".implode("','",$filter['airlines'])."')) so ON so.flightaware_id = spotter_archive.flightaware_id ";
352
                }
353 View Code Duplication
                if (isset($filter['airlinestype']) && !empty($filter['airlinestype'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
354
                        $filter_query .= " INNER JOIN (SELECT flightaware_id FROM spotter_archive_output WHERE spotter_archive_output.airline_type = '".$filter['airlinestype']."') sa ON sa.flightaware_id = spotter_archive.flightaware_id ";
355
                }
356 View Code Duplication
                if (isset($filter['source_aprs']) && !empty($filter['source_aprs'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
357
                        $filter_query = " AND format_source = 'aprs' AND source_name IN ('".implode("','",$filter['source_aprs'])."')";
358
                }
359
360
                //if (!isset($globalLiveInterval)) $globalLiveInterval = '200';
1 ignored issue
show
Unused Code Comprehensibility introduced by
69% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
361
                if ($globalDBdriver == 'mysql') {
362
                        /*
1 ignored issue
show
Unused Code Comprehensibility introduced by
52% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
363
                        $query  = 'SELECT a.aircraft_shadow, spotter_archive.ident, spotter_archive.flightaware_id, spotter_archive.aircraft_icao, spotter_archive.departure_airport_icao as departure_airport, spotter_archive.arrival_airport_icao as arrival_airport, spotter_archive.latitude, spotter_archive.longitude, spotter_archive.altitude, spotter_archive.heading, spotter_archive.ground_speed, spotter_archive.squawk 
364
                    		    FROM spotter_archive 
365
                    		    INNER JOIN (SELECT l.flightaware_id, max(l.date) as maxdate FROM spotter_archive l WHERE (l.date BETWEEN '."'".$begindate."'".' AND '."'".$enddate."'".') GROUP BY l.flightaware_id) s on spotter_archive.flightaware_id = s.flightaware_id AND spotter_archive.date = s.maxdate '.$filter_query.'LEFT JOIN (SELECT aircraft_shadow,icao FROM aircraft) a ON spotter_archive.aircraft_icao = a.icao';
366
			*/
367
			$query  = 'SELECT a.aircraft_shadow, spotter_archive_output.ident, spotter_archive_output.flightaware_id, spotter_archive_output.aircraft_icao, spotter_archive_output.departure_airport_icao as departure_airport, spotter_archive_output.arrival_airport_icao as arrival_airport, spotter_archive_output.latitude, spotter_archive_output.longitude, spotter_archive_output.altitude, spotter_archive_output.heading, spotter_archive_output.ground_speed, spotter_archive_output.squawk 
368
				    FROM spotter_archive_output 
369
				    LEFT JOIN (SELECT aircraft_shadow,icao FROM aircraft) a ON spotter_archive_output.aircraft_icao = a.icao 
370
				    WHERE (spotter_archive_output.date BETWEEN '."'".$begindate."'".' AND '."'".$enddate."'".') 
371
                        	    '.$filter_query.' GROUP BY spotter_archive_output.flightaware_id, spotter_archive_output.ident, spotter_archive_output.aircraft_icao, spotter_archive_output.departure_airport_icao, spotter_archive_output.arrival_airport_icao, spotter_archive_output.latitude, spotter_archive_output.longitude, spotter_archive_output.altitude, spotter_archive_output.heading, spotter_archive_output.ground_speed, spotter_archive_output.squawk, a.aircraft_shadow';
372
373
                } else if ($globalDBdriver == 'pgsql') {
374
                        //$query  = 'SELECT spotter_archive_output.ident, spotter_archive_output.flightaware_id, spotter_archive_output.aircraft_icao, spotter_archive_output.departure_airport_icao as departure_airport, spotter_archive_output.arrival_airport_icao as arrival_airport, spotter_archive_output.latitude, spotter_archive_output.longitude, spotter_archive_output.altitude, spotter_archive_output.heading, spotter_archive_output.ground_speed, spotter_archive_output.squawk, a.aircraft_shadow FROM spotter_archive_output INNER JOIN (SELECT l.flightaware_id, max(l.date) as maxdate FROM spotter_archive_output l WHERE DATE_SUB(UTC_TIMESTAMP(),INTERVAL '.$globalLiveInterval.' SECOND) <= l.date GROUP BY l.flightaware_id) s on spotter_archive_output.flightaware_id = s.flightaware_id AND spotter_archive_output.date = s.maxdate '.$filter_query.'INNER JOIN (SELECT * FROM aircraft) a on spotter_archive_output.aircraft_icao = a.icao';
1 ignored issue
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
375
                        $query  = 'SELECT spotter_archive_output.ident, spotter_archive_output.flightaware_id, spotter_archive_output.aircraft_icao, spotter_archive_output.departure_airport_icao as departure_airport, spotter_archive_output.arrival_airport_icao as arrival_airport, spotter_archive_output.latitude, spotter_archive_output.longitude, spotter_archive_output.altitude, spotter_archive_output.heading, spotter_archive_output.ground_speed, spotter_archive_output.squawk, a.aircraft_shadow
0 ignored issues
show
Unused Code introduced by
$query is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
376
                        	    FROM spotter_archive_output 
377
                        	    INNER JOIN (SELECT * FROM aircraft) a on spotter_archive_output.aircraft_icao = a.icao
378
                        	    WHERE spotter_archive_output.date >= '."'".$begindate."'".' AND spotter_archive_output.date <= '."'".$enddate."'".'
379
                        	    '.$filter_query.' GROUP BY spotter_archive_output.flightaware_id, spotter_archive_output.ident, spotter_archive_output.aircraft_icao, spotter_archive_output.departure_airport_icao, spotter_archive_output.arrival_airport_icao, spotter_archive_output.latitude, spotter_archive_output.longitude, spotter_archive_output.altitude, spotter_archive_output.heading, spotter_archive_output.ground_speed, spotter_archive_output.squawk, a.aircraft_shadow';
380
                        $query  = 'SELECT DISTINCT spotter_output.flightaware_id, spotter_output.ident, spotter_output.aircraft_icao, spotter_output.departure_airport_icao as departure_airport, spotter_output.arrival_airport_icao as arrival_airport, spotter_output.latitude, spotter_output.longitude, spotter_output.altitude, spotter_output.heading, spotter_output.ground_speed, spotter_output.squawk, a.aircraft_shadow
381
                        	    FROM spotter_output 
382
                        	    INNER JOIN (SELECT * FROM aircraft) a on spotter_output.aircraft_icao = a.icao
383
                        	    WHERE spotter_output.date >= '."'".$begindate."'".' AND spotter_output.date <= '."'".$enddate."'".'
384
                        	    '.$filter_query.' LIMIT 200 OFFSET 0';
385
//                        	    .' GROUP BY spotter_output.flightaware_id, spotter_output.ident, spotter_output.aircraft_icao, spotter_output.departure_airport_icao, spotter_output.arrival_airport_icao, spotter_output.latitude, spotter_output.longitude, spotter_output.altitude, spotter_output.heading, spotter_output.ground_speed, spotter_output.squawk, a.aircraft_shadow';
386
                        	    
387
                }
388
                //echo $query;
389
                try {
390
                        $sth = $this->db->prepare($query);
1 ignored issue
show
Bug introduced by
The variable $query does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The method prepare cannot be called on $this->db (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
391
                        $sth->execute();
392
                } catch(PDOException $e) {
393
                        return $e->getMessage();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $e->getMessage(); (string) is incompatible with the return type documented by SpotterArchive::getMinLiveSpotterDataPlayback of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
394
                }
395
                $spotter_array = $sth->fetchAll(PDO::FETCH_ASSOC);
396
397
                return $spotter_array;
398
        }
399
400
	 /**
401
        * Gets count Live Spotter data
402
        *
403
        * @return Array the spotter information
404
        *
405
        */
406
        public function getLiveSpotterCount($begindate,$enddate,$filter = array())
407
        {
408
                global $globalDBdriver, $globalLiveInterval;
409
                date_default_timezone_set('UTC');
410
411
                $filter_query = '';
412 View Code Duplication
                if (isset($filter['source']) && !empty($filter['source'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
413
                        $filter_query .= " AND format_source IN ('".implode("','",$filter['source'])."') ";
414
                }
415 View Code Duplication
                if (isset($filter['airlines']) && !empty($filter['airlines'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
416
                        $filter_query .= " INNER JOIN (SELECT flightaware_id FROM spotter_output WHERE spotter_output.airline_icao IN ('".implode("','",$filter['airlines'])."')) so ON so.flightaware_id = spotter_archive.flightaware_id ";
417
                }
418 View Code Duplication
                if (isset($filter['airlinestype']) && !empty($filter['airlinestype'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
419
                        $filter_query .= " INNER JOIN (SELECT flightaware_id FROM spotter_output WHERE spotter_output.airline_type = '".$filter['airlinestype']."') sa ON sa.flightaware_id = spotter_archive.flightaware_id ";
420
                }
421 View Code Duplication
                if (isset($filter['source_aprs']) && !empty($filter['source_aprs'])) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
422
                        $filter_query = " AND format_source = 'aprs' AND source_name IN ('".implode("','",$filter['source_aprs'])."')";
423
                }
424
425
                //if (!isset($globalLiveInterval)) $globalLiveInterval = '200';
1 ignored issue
show
Unused Code Comprehensibility introduced by
69% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
426
                if ($globalDBdriver == 'mysql') {
427
			$query = 'SELECT COUNT(DISTINCT flightaware_id) as nb 
428
			FROM spotter_archive l 
429
			WHERE (l.date BETWEEN DATE_SUB('."'".$begindate."'".',INTERVAL '.$globalLiveInterval.' SECOND) AND '."'".$begindate."'".')'.$filter_query;
430
431 View Code Duplication
                } else if ($globalDBdriver == 'pgsql') {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
432
			$query = 'SELECT COUNT(DISTINCT flightaware_id) as nb FROM spotter_archive l WHERE (l.date BETWEEN '."'".$begindate."' - INTERVAL '".$globalLiveInterval." SECONDS' AND "."'".$enddate."'".')'.$filter_query;
433
                }
434
                //echo $query;
435
                try {
436
                        $sth = $this->db->prepare($query);
1 ignored issue
show
Bug introduced by
The variable $query does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The method prepare cannot be called on $this->db (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
437
                        $sth->execute();
438
                } catch(PDOException $e) {
439
                        return "error";
0 ignored issues
show
Bug Best Practice introduced by
The return type of return 'error'; (string) is incompatible with the return type documented by SpotterArchive::getLiveSpotterCount of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
440
                }
441
		$result = $sth->fetch(PDO::FETCH_ASSOC);
442
                return $result['nb'];
443
444
        }
445
446
447
448
	// Spotter_Archive_output
449
	
450
    /**
451
    * Gets all the spotter information
452
    *
453
    * @return Array the spotter information
454
    *
455
    */
456
    public function searchSpotterData($q = '', $registration = '', $aircraft_icao = '', $aircraft_manufacturer = '', $highlights = '', $airline_icao = '', $airline_country = '', $airline_type = '', $airport = '', $airport_country = '', $callsign = '', $departure_airport_route = '', $arrival_airport_route = '', $owner = '',$pilot_id = '',$pilot_name = '',$altitude = '', $date_posted = '', $limit = '', $sort = '', $includegeodata = '',$origLat = '',$origLon = '',$dist = '')
457
    {
458
	global $globalTimezone, $globalDbdriver;
459
	require_once(dirname(__FILE__).'/class.Translation.php');
460
	$Translation = new Translation();
461
462
	date_default_timezone_set('UTC');
463
	
464
	$query_values = array();
465
	$additional_query = '';
466
	if ($q != "")
467
	{
468
	    if (!is_string($q))
469
	    {
470
		return false;
471
	    } else {
472
	        
473
		$q_array = explode(" ", $q);
474
		
475
		foreach ($q_array as $q_item){
476
		    $additional_query .= " AND (";
477
		    $additional_query .= "(spotter_archive_output.spotter_id like '%".$q_item."%') OR ";
478
		    $additional_query .= "(spotter_archive_output.aircraft_icao like '%".$q_item."%') OR ";
479
		    $additional_query .= "(spotter_archive_output.aircraft_name like '%".$q_item."%') OR ";
480
		    $additional_query .= "(spotter_archive_output.aircraft_manufacturer like '%".$q_item."%') OR ";
481
		    $additional_query .= "(spotter_archive_output.airline_icao like '%".$q_item."%') OR ";
482
		    $additional_query .= "(spotter_archive_output.airline_name like '%".$q_item."%') OR ";
483
		    $additional_query .= "(spotter_archive_output.airline_country like '%".$q_item."%') OR ";
484
		    $additional_query .= "(spotter_archive_output.departure_airport_icao like '%".$q_item."%') OR ";
485
		    $additional_query .= "(spotter_archive_output.departure_airport_name like '%".$q_item."%') OR ";
486
		    $additional_query .= "(spotter_archive_output.departure_airport_city like '%".$q_item."%') OR ";
487
		    $additional_query .= "(spotter_archive_output.departure_airport_country like '%".$q_item."%') OR ";
488
		    $additional_query .= "(spotter_archive_output.arrival_airport_icao like '%".$q_item."%') OR ";
489
		    $additional_query .= "(spotter_archive_output.arrival_airport_name like '%".$q_item."%') OR ";
490
		    $additional_query .= "(spotter_archive_output.arrival_airport_city like '%".$q_item."%') OR ";
491
		    $additional_query .= "(spotter_archive_output.arrival_airport_country like '%".$q_item."%') OR ";
492
		    $additional_query .= "(spotter_archive_output.registration like '%".$q_item."%') OR ";
493
		    $additional_query .= "(spotter_archive_output.owner_name like '%".$q_item."%') OR ";
494
		    $additional_query .= "(spotter_archive_output.pilot_id like '%".$q_item."%') OR ";
495
		    $additional_query .= "(spotter_archive_output.pilot_name like '%".$q_item."%') OR ";
496
		    $additional_query .= "(spotter_archive_output.ident like '%".$q_item."%') OR ";
497
		    $translate = $Translation->ident2icao($q_item);
498
		    if ($translate != $q_item) $additional_query .= "(spotter_archive_output.ident like '%".$translate."%') OR ";
499
		    $additional_query .= "(spotter_archive_output.highlight like '%".$q_item."%')";
500
		    $additional_query .= ")";
501
		}
502
	    }
503
	}
504
	
505
	if ($registration != "")
506
	{
507
	    $registration = filter_var($registration,FILTER_SANITIZE_STRING);
508
	    if (!is_string($registration))
509
	    {
510
		return false;
511
	    } else {
512
		$additional_query .= " AND (spotter_archive_output.registration = '".$registration."')";
513
	    }
514
	}
515
	
516
	if ($aircraft_icao != "")
517
	{
518
	    $aircraft_icao = filter_var($aircraft_icao,FILTER_SANITIZE_STRING);
519
	    if (!is_string($aircraft_icao))
520
	    {
521
		return false;
522
	    } else {
523
		$additional_query .= " AND (spotter_archive_output.aircraft_icao = '".$aircraft_icao."')";
524
	    }
525
	}
526
	
527
	if ($aircraft_manufacturer != "")
528
	{
529
	    $aircraft_manufacturer = filter_var($aircraft_manufacturer,FILTER_SANITIZE_STRING);
530
	    if (!is_string($aircraft_manufacturer))
531
	    {
532
		return false;
533
	    } else {
534
		$additional_query .= " AND (spotter_archive_output.aircraft_manufacturer = '".$aircraft_manufacturer."')";
535
	    }
536
	}
537
	
538 View Code Duplication
	if ($highlights == "true")
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
539
	{
540
	    if (!is_string($highlights))
541
	    {
542
		return false;
543
	    } else {
544
		$additional_query .= " AND (spotter_archive_output.highlight <> '')";
545
	    }
546
	}
547
	
548
	if ($airline_icao != "")
549
	{
550
	    $registration = filter_var($airline_icao,FILTER_SANITIZE_STRING);
0 ignored issues
show
Unused Code introduced by
$registration is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
551
	    if (!is_string($airline_icao))
552
	    {
553
		return false;
554
	    } else {
555
		$additional_query .= " AND (spotter_archive_output.airline_icao = '".$airline_icao."')";
556
	    }
557
	}
558
	
559
	if ($airline_country != "")
560
	{
561
	    $airline_country = filter_var($airline_country,FILTER_SANITIZE_STRING);
562
	    if (!is_string($airline_country))
563
	    {
564
		return false;
565
	    } else {
566
		$additional_query .= " AND (spotter_archive_output.airline_country = '".$airline_country."')";
567
	    }
568
	}
569
	
570
	if ($airline_type != "")
571
	{
572
	    $airline_type = filter_var($airline_type,FILTER_SANITIZE_STRING);
573 View Code Duplication
	    if (!is_string($airline_type))
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
574
	    {
575
		return false;
576
	    } else {
577
		if ($airline_type == "passenger")
578
		{
579
		    $additional_query .= " AND (spotter_archive_output.airline_type = 'passenger')";
580
		}
581
		if ($airline_type == "cargo")
582
		{
583
		    $additional_query .= " AND (spotter_archive_output.airline_type = 'cargo')";
584
		}
585
		if ($airline_type == "military")
586
		{
587
		    $additional_query .= " AND (spotter_archive_output.airline_type = 'military')";
588
		}
589
	    }
590
	}
591
	
592 View Code Duplication
	if ($airport != "")
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
593
	{
594
	    $airport = filter_var($airport,FILTER_SANITIZE_STRING);
595
	    if (!is_string($airport))
596
	    {
597
		return false;
598
	    } else {
599
		$additional_query .= " AND ((spotter_archive_output.departure_airport_icao = '".$airport."') OR (spotter_archive_output.arrival_airport_icao = '".$airport."'))";
600
	    }
601
	}
602
	
603 View Code Duplication
	if ($airport_country != "")
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
604
	{
605
	    $airport_country = filter_var($airport_country,FILTER_SANITIZE_STRING);
606
	    if (!is_string($airport_country))
607
	    {
608
		return false;
609
	    } else {
610
		$additional_query .= " AND ((spotter_archive_output.departure_airport_country = '".$airport_country."') OR (spotter_archive_output.arrival_airport_country = '".$airport_country."'))";
611
	    }
612
	}
613
    
614
	if ($callsign != "")
615
	{
616
	    $callsign = filter_var($callsign,FILTER_SANITIZE_STRING);
617
	    if (!is_string($callsign))
618
	    {
619
		return false;
620
	    } else {
621
		$translate = $Translation->ident2icao($callsign);
622
		if ($translate != $callsign) {
623
			$additional_query .= " AND (spotter_archive_output.ident = :callsign OR spotter_archive_output.ident = :translate)";
624
			$query_values = array_merge($query_values,array(':callsign' => $callsign,':translate' => $translate));
0 ignored issues
show
Unused Code introduced by
$query_values is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
625
		} else {
626
			$additional_query .= " AND (spotter_archive_output.ident = '".$callsign."')";
627
		}
628
	    }
629
	}
630
631
	if ($owner != "")
632
	{
633
	    $owner = filter_var($owner,FILTER_SANITIZE_STRING);
634
	    if (!is_string($owner))
635
	    {
636
		return false;
637
	    } else {
638
		$additional_query .= " AND (spotter_archive_output.owner_name = '".$owner."')";
639
	    }
640
	}
641
642
	if ($pilot_name != "")
643
	{
644
	    $pilot_name = filter_var($pilot_name,FILTER_SANITIZE_STRING);
645
	    if (!is_string($pilot_name))
646
	    {
647
		return false;
648
	    } else {
649
		$additional_query .= " AND (spotter_archive_output.pilot_name = '".$pilot_name."')";
650
	    }
651
	}
652
	
653
	if ($pilot_id != "")
654
	{
655
	    $pilot_id = filter_var($pilot_id,FILTER_SANITIZE_NUMBER_INT);
656
	    if (!is_string($pilot_id))
657
	    {
658
		return false;
659
	    } else {
660
		$additional_query .= " AND (spotter_archive_output.pilot_id = '".$pilot_id."')";
661
	    }
662
	}
663
	
664
	if ($departure_airport_route != "")
665
	{
666
	    $departure_airport_route = filter_var($departure_airport_route,FILTER_SANITIZE_STRING);
667
	    if (!is_string($departure_airport_route))
668
	    {
669
		return false;
670
	    } else {
671
		$additional_query .= " AND (spotter_archive_output.departure_airport_icao = '".$departure_airport_route."')";
672
	    }
673
	}
674
	
675
	if ($arrival_airport_route != "")
676
	{
677
	    $arrival_airport_route = filter_var($arrival_airport_route,FILTER_SANITIZE_STRING);
678
	    if (!is_string($arrival_airport_route))
679
	    {
680
		return false;
681
	    } else {
682
		$additional_query .= " AND (spotter_archive_output.arrival_airport_icao = '".$arrival_airport_route."')";
683
	    }
684
	}
685
	
686 View Code Duplication
	if ($altitude != "")
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
687
	{
688
	    $altitude_array = explode(",", $altitude);
689
	    
690
	    $altitude_array[0] = filter_var($altitude_array[0],FILTER_SANITIZE_NUMBER_FLOAT,FILTER_FLAG_ALLOW_FRACTION);
691
	    $altitude_array[1] = filter_var($altitude_array[1],FILTER_SANITIZE_NUMBER_FLOAT,FILTER_FLAG_ALLOW_FRACTION);
692
	    
693
694
	    if ($altitude_array[1] != "")
695
	    {                
696
		$altitude_array[0] = substr($altitude_array[0], 0, -2);
697
		$altitude_array[1] = substr($altitude_array[1], 0, -2);
698
		$additional_query .= " AND altitude BETWEEN '".$altitude_array[0]."' AND '".$altitude_array[1]."' ";
699
	    } else {
700
		$altitude_array[0] = substr($altitude_array[0], 0, -2);
701
		$additional_query .= " AND altitude <= '".$altitude_array[0]."' ";
702
	    }
703
	}
704
	
705 View Code Duplication
	if ($date_posted != "")
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
706
	{
707
	    $date_array = explode(",", $date_posted);
708
	    
709
	    $date_array[0] = filter_var($date_array[0],FILTER_SANITIZE_STRING);
710
	    $date_array[1] = filter_var($date_array[1],FILTER_SANITIZE_STRING);
711
	    
712
	    if ($globalTimezone != '') {
713
		date_default_timezone_set($globalTimezone);
714
		$datetime = new DateTime();
715
		$offset = $datetime->format('P');
716
	    } else $offset = '+00:00';
717
718
719
	    if ($date_array[1] != "")
720
	    {                
721
		$date_array[0] = date("Y-m-d H:i:s", strtotime($date_array[0]));
722
		$date_array[1] = date("Y-m-d H:i:s", strtotime($date_array[1]));
723
		if ($globalDBdriver == 'mysql') {
0 ignored issues
show
Bug introduced by
The variable $globalDBdriver does not exist. Did you mean $globalDbdriver?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
724
			$additional_query .= " AND TIMESTAMP(CONVERT_TZ(spotter_archive_output.date,'+00:00', '".$offset."')) >= '".$date_array[0]."' AND TIMESTAMP(CONVERT_TZ(spotter_archive_output.date,'+00:00', '".$offset."')) <= '".$date_array[1]."' ";
725
		} else {
726
			$additional_query .= " AND spotter_archive_output.date::timestamp AT TIME ZONE INTERVAL ".$offset." >= CAST('".$date_array[0]."' AS TIMESTAMP) AND spotter_archive_output.date::timestamp AT TIME ZONE INTERVAL ".$offset." <= CAST('".$date_array[1]."' AS TIMESTAMP) ";
727
		}
728
	    } else {
729
		$date_array[0] = date("Y-m-d H:i:s", strtotime($date_array[0]));
730
                if ($globalDBdriver == 'mysql') {
0 ignored issues
show
Bug introduced by
The variable $globalDBdriver does not exist. Did you mean $globalDbdriver?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
731
			$additional_query .= " AND TIMESTAMP(CONVERT_TZ(spotter_archive_output.date,'+00:00', '".$offset."')) >= '".$date_array[0]."' ";
732
		} else {
733
			$additional_query .= " AND spotter_archive_output.date::timestamp AT TIME ZONE INTERVAL ".$offset." >= CAST('".$date_array[0]."' AS TIMESTAMP) ";
734
		}
735
	    }
736
	}
737
	
738
	if ($limit != "")
739
	{
740
	    $limit_array = explode(",", $limit);
741
	    
742
	    $limit_array[0] = filter_var($limit_array[0],FILTER_SANITIZE_NUMBER_INT);
743
	    $limit_array[1] = filter_var($limit_array[1],FILTER_SANITIZE_NUMBER_INT);
744
	    
745
	    if ($limit_array[0] >= 0 && $limit_array[1] >= 0)
746
	    {
747
		//$limit_query = " LIMIT ".$limit_array[0].",".$limit_array[1];
1 ignored issue
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
748
		$limit_query = " LIMIT ".$limit_array[1]." OFFSET ".$limit_array[0];
749
	    }
750
	}
751
	
752
753
	if ($origLat != "" && $origLon != "" && $dist != "") {
754
		$dist = number_format($dist*0.621371,2,'.','');
755
		$query="SELECT spotter_output.*, 3956 * 2 * ASIN(SQRT( POWER(SIN(($origLat - ABS(CAST(spotter_archive.latitude as double precision)))*pi()/180/2),2)+COS( $origLat *pi()/180)*COS(ABS(CAST(spotter_archive.latitude as double precision))*pi()/180)*POWER(SIN(($origLon-CAST(spotter_archive.longitude as double precision))*pi()/180/2),2))) as distance 
756
                          FROM spotter_output_archive, spotter_archive WHERE spotter_output_archive.flightaware_id = spotter_archive.flightaware_id AND spotter_output.ident <> '' ".$additional_query."AND CAST(spotter_archive.longitude as double precision) between ($origLon-$dist/ABS(cos(radians($origLat))*69)) and ($origLon+$dist/ABS(cos(radians($origLat))*69)) and CAST(spotter_archive.latitude as double precision) between ($origLat-($dist/69)) and ($origLat+($dist/69)) 
757
                          AND (3956 * 2 * ASIN(SQRT( POWER(SIN(($origLat - ABS(CAST(spotter_archive.latitude as double precision)))*pi()/180/2),2)+COS( $origLat *pi()/180)*COS(ABS(CAST(spotter_archive.latitude as double precision))*pi()/180)*POWER(SIN(($origLon-CAST(spotter_archive.longitude as double precision))*pi()/180/2),2)))) < $dist ORDER BY distance";
758
	} else {
759
		if ($sort != "")
760
		{
761
			$search_orderby_array = $this->getOrderBy();
0 ignored issues
show
Bug introduced by
The method getOrderBy() does not seem to exist on object<SpotterArchive>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
762
			$orderby_query = $search_orderby_array[$sort]['sql'];
763
		} else {
764
			$orderby_query = " ORDER BY spotter_archive_output.date DESC";
765
		}
766
	
767
		if ($includegeodata == "true")
768
		{
769
			$additional_query .= " AND (spotter_archive_output.waypoints <> '')";
770
		}
771
772
		$query  = "SELECT spotter_archive_output.* FROM spotter_archive_output 
773
		    WHERE spotter_archive_output.ident <> '' 
774
		    ".$additional_query."
775
		    ".$orderby_query;
776
	}
777
	$Spotter = new Spotter($this->db);
778
	$spotter_array = $Spotter->getDataFromDB($query, array(),$limit_query);
0 ignored issues
show
Bug introduced by
The variable $limit_query does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
779
780
	return $spotter_array;
781
    }
782
783 View Code Duplication
    public function deleteSpotterArchiveData()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
784
    {
785
		global $globalArchiveKeepMonths, $globalDBdriver;
786
                date_default_timezone_set('UTC');
787
                if ($globalDBdriver == 'mysql') {
788
			$query = 'DELETE FROM spotter_archive_output WHERE spotter_archive_output.date < DATE_SUB(UTC_TIMESTAMP(), INTERVAL '.$globalArchiveKeepMonths.' MONTH)';
789
		} else {
790
			$query = "DELETE FROM spotter_archive_output WHERE spotter_archive_output.date < CURRENT_TIMESTAMP AT TIME ZONE 'UTC' - INTERVAL '".$globalArchiveKeepMonths." MONTH'";
791
		}
792
                try {
793
                        $sth = $this->db->prepare($query);
1 ignored issue
show
Bug introduced by
The method prepare cannot be called on $this->db (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
794
                        $sth->execute();
795
                } catch(PDOException $e) {
796
                        return "error";
797
                }
798
	}
799
800
    /**
801
    * Gets all the spotter information based on the callsign
802
    *
803
    * @return Array the spotter information
804
    *
805
    */
806
    public function getSpotterDataByIdent($ident = '', $limit = '', $sort = '')
807
    {
808
	$global_query = "SELECT spotter_archive_output.* FROM spotter_archive_output";
809
	
810
	date_default_timezone_set('UTC');
811
	
812
	$query_values = array();
813
	
814
	if ($ident != "")
815
	{
816
	    if (!is_string($ident))
817
	    {
818
		return false;
819
	    } else {
820
		$additional_query = " AND (spotter_archive_output.ident = :ident)";
821
		$query_values = array(':ident' => $ident);
822
	    }
823
	}
824
	
825
	if ($limit != "")
826
	{
827
	    $limit_array = explode(",", $limit);
828
	    
829
	    $limit_array[0] = filter_var($limit_array[0],FILTER_SANITIZE_NUMBER_INT);
830
	    $limit_array[1] = filter_var($limit_array[1],FILTER_SANITIZE_NUMBER_INT);
831
	    
832
	    if ($limit_array[0] >= 0 && $limit_array[1] >= 0)
833
	    {
834
		//$limit_query = " LIMIT ".$limit_array[0].",".$limit_array[1];
1 ignored issue
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
835
		$limit_query = " LIMIT ".$limit_array[1]." OFFSET ".$limit_array[0];
836
	    }
837
	}
838
839
	if ($sort != "")
840
	{
841
	    $search_orderby_array = $this->getOrderBy();
0 ignored issues
show
Bug introduced by
The method getOrderBy() does not seem to exist on object<SpotterArchive>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
842
	    $orderby_query = $search_orderby_array[$sort]['sql'];
843
	} else {
844
	    $orderby_query = " ORDER BY spotter_archive_output.date DESC";
845
	}
846
847
	$query = $global_query." WHERE spotter_archive_output.ident <> '' ".$additional_query." ".$orderby_query;
0 ignored issues
show
Bug introduced by
The variable $additional_query does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
848
849
	$Spotter = new Spotter($this->db);
850
	$spotter_array = $Spotter->getDataFromDB($query, $query_values, $limit_query);
0 ignored issues
show
Bug introduced by
The variable $limit_query does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
851
852
	return $spotter_array;
853
    }
854
855
    /**
856
    * Gets all number of flight over countries
857
    *
858
    * @return Array the airline country list
859
    *
860
    */
861 View Code Duplication
    public function countAllFlightOverCountries($limit = true,$olderthanmonths = 0,$sincedate = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
862
    {
863
	global $globalDBdriver;
864
	/*
1 ignored issue
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
865
	$query = "SELECT c.name, c.iso3, c.iso2, count(c.name) as nb 
866
		    FROM countries c, spotter_archive s
867
		    WHERE Within(GeomFromText(CONCAT('POINT(',s.longitude,' ',s.latitude,')')), ogc_geom) ";
868
	*/
869
	$query = "SELECT c.name, c.iso3, c.iso2, count(c.name) as nb
870
		    FROM countries c, spotter_archive s
871
		    WHERE c.iso2 = s.over_country ";
872
                if ($olderthanmonths > 0) {
873
            		if ($globalDBdriver == 'mysql') {
874
				$query .= 'AND date < DATE_SUB(UTC_TIMESTAMP(),INTERVAL '.$olderthanmonths.' MONTH) ';
875
			} else {
876
				$query .= "AND date < CURRENT_TIMESTAMP AT TIME ZONE 'UTC' - INTERVAL '".$olderthanmonths." MONTHS'";
877
			}
878
		}
879
                if ($sincedate != '') $query .= "AND date > '".$sincedate."' ";
880
	$query .= "GROUP BY c.name, c.iso3, c.iso2 ORDER BY nb DESC";
881
	if ($limit) $query .= " LIMIT 0,10";
882
      
883
	
884
	$sth = $this->db->prepare($query);
1 ignored issue
show
Bug introduced by
The method prepare cannot be called on $this->db (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
885
	$sth->execute();
886
 
887
	$flight_array = array();
888
	$temp_array = array();
889
        
890
	while($row = $sth->fetch(PDO::FETCH_ASSOC))
891
	{
892
	    $temp_array['flight_count'] = $row['nb'];
893
	    $temp_array['flight_country'] = $row['name'];
894
	    $temp_array['flight_country_iso3'] = $row['iso3'];
895
	    $temp_array['flight_country_iso2'] = $row['iso2'];
896
	    $flight_array[] = $temp_array;
897
	}
898
	return $flight_array;
899
    }
900
901
}
902
?>
1 ignored issue
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...