Issues (843)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

require/libs/Predict/Predict.php (15 issues)

Upgrade to new PHP Analysis Engine

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

1
<?php
2
3
/*
4
    A limited PHP port of the gpredict program, done by Bill Shupp.
5
    Original notes and author information is below.  GPL2 license.
6
    ===============================================================
7
8
9
10
    Gpredict: Real-time satellite tracking and orbit prediction program
11
12
    Copyright (C)  2001-2009  Alexandru Csete, OZ9AEC.
13
    Parts are Copyright John A. Magliacane, KD2BD 1991-2003 (indicated below)
14
15
    Authors: Alexandru Csete <[email protected]>
16
             John A. Magliacane, KD2BD.
17
18
    Comments, questions and bugreports should be submitted via
19
    http://sourceforge.net/projects/gpredict/
20
    More details can be found at the project home page:
21
22
            http://gpredict.oz9aec.net/
23
24
    This program is free software; you can redistribute it and/or modify
25
    it under the terms of the GNU General Public License as published by
26
    the Free Software Foundation; either version 2 of the License, or
27
    (at your option) any later version.
28
29
    This program is distributed in the hope that it will be useful,
30
    but WITHOUT ANY WARRANTY; without even the implied warranty of
31
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32
    GNU General Public License for more details.
33
34
    You should have received a copy of the GNU General Public License
35
    along with this program; if not, visit http://www.fsf.org/
36
*/
37
38
require_once 'Predict/Time.php';
39
require_once 'Predict/Math.php';
40
require_once 'Predict/Pass.php';
41
require_once 'Predict/PassDetail.php';
42
require_once 'Predict/Vector.php';
43
require_once 'Predict/Geodetic.php';
44
require_once 'Predict/ObsSet.php';
45
require_once 'Predict/Solar.php';
46
require_once 'Predict/SGPObs.php';
47
require_once 'Predict/SGPSDP.php';
48
49
/**
50
 * The main Predict class.  Contains constants for use by other classes, as well as
51
 * the prediction logic.
52
 */
53
class Predict
54
{
55
    const de2ra    =  1.74532925E-2;   /* Degrees to Radians */
56
    const pi       =  3.1415926535898; /* Pi */
57
    const pio2     =  1.5707963267949; /* Pi/2 */
58
    const x3pio2   =  4.71238898;      /* 3*Pi/2 */
59
    const twopi    =  6.2831853071796; /* 2*Pi  */
60
    const e6a      =  1.0E-6;
61
    const tothrd   =  6.6666667E-1;    /* 2/3 */
62
    const xj2      =  1.0826158E-3;    /* J2 Harmonic */
63
    const xj3      = -2.53881E-6;      /* J3 Harmonic */
64
    const xj4      = -1.65597E-6;      /* J4 Harmonic */
65
    const xke      =  7.43669161E-2;
66
    const xkmper   =  6.378135E3;      /* Earth radius km */
67
    const xmnpda   =  1.44E3;          /* Minutes per day */
68
    const km2mi    =  0.621371;        /* Kilometers per Mile */
69
    const ae       =  1.0;
70
    const ck2      =  5.413079E-4;
71
    const ck4      =  6.209887E-7;
72
    const __f      =  3.352779E-3;
73
    const ge       =  3.986008E5;
74
    const __s__    =  1.012229;
75
    const qoms2t   =  1.880279E-09;
76
    const secday   =  8.6400E4;        /* Seconds per day */
77
    const omega_E  =  1.0027379;
78
    const omega_ER =  6.3003879;
79
    const zns      =  1.19459E-5;
80
    const c1ss     =  2.9864797E-6;
81
    const zes      =  1.675E-2;
82
    const znl      =  1.5835218E-4;
83
    const c1l      =  4.7968065E-7;
84
    const zel      =  5.490E-2;
85
    const zcosis   =  9.1744867E-1;
86
    const zsinis   =  3.9785416E-1;
87
    const zsings   = -9.8088458E-1;
88
    const zcosgs   =  1.945905E-1;
89
    const zcoshs   =  1;
90
    const zsinhs   =  0;
91
    const q22      =  1.7891679E-6;
92
    const q31      =  2.1460748E-6;
93
    const q33      =  2.2123015E-7;
94
    const g22      =  5.7686396;
95
    const g32      =  9.5240898E-1;
96
    const g44      =  1.8014998;
97
    const g52      =  1.0508330;
98
    const g54      =  4.4108898;
99
    const root22   =  1.7891679E-6;
100
    const root32   =  3.7393792E-7;
101
    const root44   =  7.3636953E-9;
102
    const root52   =  1.1428639E-7;
103
    const root54   =  2.1765803E-9;
104
    const thdt     =  4.3752691E-3;
105
    const rho      =  1.5696615E-1;
106
    const mfactor  =  7.292115E-5;
107
    const __sr__   =  6.96000E5;      /*Solar radius - kilometers (IAU 76)*/
108
    const AU       =  1.49597870E8;   /*Astronomical unit - kilometers (IAU 76)*/
109
110
    /* visibility constants */
111
    const SAT_VIS_NONE     = 0;
112
    const SAT_VIS_VISIBLE  = 1;
113
    const SAT_VIS_DAYLIGHT = 2;
114
    const SAT_VIS_ECLIPSED = 3;
115
116
    /* preferences */
117
    public $minEle     = 10; // Minimum elevation
118
    public $timeRes    = 10; // Pass details: time resolution
119
    public $numEntries = 20; // Pass details: number of entries
120
    public $threshold  = -6; // Twilight threshold
121
122
    /**
123
     *  Predict the next pass.
124
     *
125
     * This function simply wraps the get_pass function using the current time
126
     * as parameter.
127
     *
128
     * Note: the data in sat will be corrupt (future) and must be refreshed
129
     *       by the caller, if the caller will need it later on (eg. if the caller
130
     *       is GtkSatList).
131
     *
132
     * @param Predict_Sat $sat   The satellite data.
133
     * @param Predict_QTH $qth   The observer data.
134
     * @param int         $maxdt The maximum number of days to look ahead.
135
     *
136
     * @return Predict_Pass Pointer instance or NULL if no pass can be
137
     *         found.
138
     */
139
    public function get_next_pass(Predict_Sat $sat, Predict_QTH $qth, $maxdt)
140
    {
141
        /* get the current time and call the get_pass function */
142
        $now = Predict_Time::get_current_daynum();
143
144
        return $this->get_pass($sat, $qth, $now, $maxdt);
145
    }
146
147
    /** Predict first pass after a certain time.
148
     *
149
     *  @param Predict_Sat $sat   The satellite data.
0 ignored issues
show
There is no parameter named $sat. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
150
     *  @param Predict_QTH $qth   The observer's location data.
151
     *  @param float       $start Starting time.
152
     *  @param int         $maxdt The maximum number of days to look ahead (0 for no limit).
153
     *
154
     *  @return Predict_Pass or NULL if there was an error.
155
     *
156
     * This function will find the first upcoming pass with AOS no earlier than
157
     * t = start and no later than t = (start+maxdt).
158
     *
159
     *  note For no time limit use maxdt = 0.0
160
     *
161
     *  note the data in sat will be corrupt (future) and must be refreshed
162
     *       by the caller, if the caller will need it later on
163
     */
164
    public function get_pass(Predict_Sat $sat_in, Predict_QTH $qth, $start, $maxdt)
165
    {
166
        $aos = 0.0;    /* time of AOS */
0 ignored issues
show
$aos 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...
167
        $tca = 0.0;    /* time of TCA */
168
        $los = 0.0;    /* time of LOS */
0 ignored issues
show
$los 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...
169
        $dt = 0.0;     /* time diff */
0 ignored issues
show
$dt 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...
170
        $step = 0.0;   /* time step */
0 ignored issues
show
$step 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...
171
        $t0 = $start;
172
        $tres = 0.0;   /* required time resolution */
0 ignored issues
show
$tres 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...
173
        $max_el = 0.0; /* maximum elevation */
174
        $pass = null;
175
        $detail = null;
0 ignored issues
show
$detail 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...
176
        $done = false;
177
        $iter = 0;      /* number of iterations */
178
        /* FIXME: watchdog */
179
180
        /*copy sat_in to a working structure*/
181
        $sat         = clone $sat_in;
182
        $sat_working = clone $sat_in;
0 ignored issues
show
$sat_working 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...
183
184
        /* get time resolution; sat-cfg stores it in seconds */
185
        $tres = $this->timeRes / 86400.0;
186
187
        /* loop until we find a pass with elevation > SAT_CFG_INT_PRED_MIN_EL
188
            or we run out of time
189
            FIXME: we should have a safety break
190
        */
191
        while (!$done) {
192
            /* Find los of next pass or of current pass */
193
            $los = $this->find_los($sat, $qth, $t0, $maxdt); // See if a pass is ongoing
194
            $aos = $this->find_aos($sat, $qth, $t0, $maxdt);
195
            /* sat_log_log(SAT_LOG_LEVEL_MSG, "%s:%s:%d: found aos %f and los %f for t0=%f", */
196
            /*          __FILE__,  */
197
            /*          __FUNCTION__, */
198
            /*          __LINE__, */
199
            /*          aos, */
200
            /*          los,  */
201
            /*          t0); */
202
            if ($aos > $los) {
203
                // los is from an currently happening pass, find previous aos
204
                $aos = $this->find_prev_aos($sat, $qth, $t0);
205
            }
206
207
            /* aos = 0.0 means no aos */
208
            if ($aos == 0.0) {
209
                $done = true;
210
            } else if (($maxdt > 0.0) && ($aos > ($start + $maxdt)) ) {
211
                /* check whether we are within time limits;
212
                    maxdt = 0 mean no time limit.
213
                */
214
                $done = true;
215
            } else {
216
                //los = find_los (sat, qth, aos + 0.001, maxdt); // +1.5 min later
217
                $dt = $los - $aos;
218
219
                /* get time step, which will give us the max number of entries */
220
                $step = $dt / $this->numEntries;
221
222
                /* but if this is smaller than the required resolution
223
                    we go with the resolution
224
                */
225
                if ($step < $tres) {
226
                    $step = $tres;
227
                }
228
229
                /* create a pass_t entry; FIXME: g_try_new in 2.8 */
230
                $pass = new Predict_Pass();
231
232
                $pass->aos      = $aos;
233
                $pass->los      = $los;
234
                $pass->max_el   = 0.0;
235
                $pass->aos_az   = 0.0;
236
                $pass->los_az   = 0.0;
237
                $pass->maxel_az = 0.0;
238
                $pass->vis      = '---';
239
                $pass->satname  = $sat->nickname;
240
                $pass->details  = array();
241
242
                /* iterate over each time step */
243
                for ($t = $pass->aos; $t <= $pass->los; $t += $step) {
244
245
                    /* calculate satellite data */
246
                    $this->predict_calc($sat, $qth, $t);
247
248
                    /* in the first iter we want to store
249
                        pass->aos_az
250
                    */
251
                    if ($t == $pass->aos) {
252
                        $pass->aos_az = $sat->az;
253
                        $pass->orbit  = $sat->orbit;
254
                    }
255
256
                    /* append details to sat->details */
257
                    $detail             = new Predict_PassDetail();
258
                    $detail->time       = $t;
259
                    $detail->pos->x     = $sat->pos->x;
260
                    $detail->pos->y     = $sat->pos->y;
261
                    $detail->pos->z     = $sat->pos->z;
262
                    $detail->pos->w     = $sat->pos->w;
263
                    $detail->vel->x     = $sat->vel->x;
264
                    $detail->vel->y     = $sat->vel->y;
265
                    $detail->vel->z     = $sat->vel->z;
266
                    $detail->vel->w     = $sat->vel->w;
267
                    $detail->velo       = $sat->velo;
268
                    $detail->az         = $sat->az;
269
                    $detail->el         = $sat->el;
270
                    $detail->range      = $sat->range;
271
                    $detail->range_rate = $sat->range_rate;
272
                    $detail->lat        = $sat->ssplat;
273
                    $detail->lon        = $sat->ssplon;
274
                    $detail->alt        = $sat->alt;
275
                    $detail->ma         = $sat->ma;
276
                    $detail->phase      = $sat->phase;
277
                    $detail->footprint  = $sat->footprint;
278
                    $detail->orbit      = $sat->orbit;
279
                    $detail->vis        = $this->get_sat_vis($sat, $qth, $t);
280
281
                    /* also store visibility "bit" */
282
                    switch ($detail->vis) {
283
                        case self::SAT_VIS_VISIBLE:
284
                            $pass->vis[0] = 'V';
285
                            break;
286
                        case self::SAT_VIS_DAYLIGHT:
287
                            $pass->vis[1] = 'D';
288
                            break;
289
                        case self::SAT_VIS_ECLIPSED:
290
                            $pass->vis[2] = 'E';
291
                            break;
292
                        default:
293
                            break;
294
                    }
295
296
                    // Using an array, no need to prepend and reverse the list
297
                    // as gpredict does
298
                    $pass->details[] = $detail;
299
300
                    // Look up apparent magnitude if this is a visible pass
301
                    if ($detail->vis === self::SAT_VIS_VISIBLE) {
302
                        $apmag = $sat->calculateApparentMagnitude($t, $qth);
303
                        if ($pass->max_apparent_magnitude === null || $apmag < $pass->max_apparent_magnitude) {
304
                            $pass->max_apparent_magnitude = $apmag;
305
                        }
306
                    }
307
308
                    /* store elevation if greater than the
309
                        previously stored one
310
                    */
311
                    if ($sat->el > $max_el) {
312
                        $max_el         = $sat->el;
313
                        $tca            = $t;
314
                        $pass->maxel_az = $sat->az;
315
                    }
316
317
                    /*     g_print ("TIME: %f\tAZ: %f\tEL: %f (MAX: %f)\n", */
318
                    /*           t, sat->az, sat->el, max_el); */
319
                }
320
321
                /* calculate satellite data */
322
                $this->predict_calc($sat, $qth, $pass->los);
323
                /* store los_az, max_el and tca */
324
                $pass->los_az = $sat->az;
325
                $pass->max_el = $max_el;
326
                $pass->tca    = $tca;
327
328
                /* check whether this pass is good */
329
                if ($max_el >= $this->minEle) {
330
                    $done = true;
331
                } else {
332
                    $done = false;
333
                    $t0 = $los + 0.014; // +20 min
334
                    $pass = null;
335
                }
336
337
                $iter++;
338
            }
339
        }
340
341
        return $pass;
342
    }
343
344
    /**
345
     * Calculate satellite visibility.
346
     *
347
     * @param Predict_Sat $sat     The satellite structure.
348
     * @param Predict_QTH $qth     The QTH
349
     * @param float       $jul_utc The time at which the visibility should be calculated.
350
     *
351
     * @return int The visiblity constant, 0, 1, 2, or 3 (see above)
352
     */
353
    public function get_sat_vis(Predict_Sat $sat, Predict_QTH $qth, $jul_utc)
354
    {
355
        /* gboolean sat_sun_status;
356
        gdouble  sun_el;
357
        gdouble  threshold;
358
        gdouble  eclipse_depth;
359
        sat_vis_t vis = SAT_VIS_NONE; */
360
361
        $eclipse_depth  = 0.0;
362
        $zero_vector    = new Predict_Vector();
363
        $obs_geodetic   = new Predict_Geodetic();
364
365
        /* Solar ECI position vector  */
366
        $solar_vector = new Predict_Vector();
367
368
        /* Solar observed az and el vector  */
369
        $solar_set = new Predict_ObsSet();
370
371
        /* FIXME: could be passed as parameter */
372
        $obs_geodetic->lon   = $qth->lon * self::de2ra;
373
        $obs_geodetic->lat   = $qth->lat * self::de2ra;
374
        $obs_geodetic->alt   = $qth->alt / 1000.0;
375
        $obs_geodetic->theta = 0;
376
377
        Predict_Solar::Calculate_Solar_Position($jul_utc, $solar_vector);
378
        Predict_SGPObs::Calculate_Obs($jul_utc, $solar_vector, $zero_vector, $obs_geodetic, $solar_set);
379
380
        if (Predict_Solar::Sat_Eclipsed($sat->pos, $solar_vector, $eclipse_depth)) {
381
            /* satellite is eclipsed */
382
            $sat_sun_status = false;
383
        } else {
384
            /* satellite in sunlight => may be visible */
385
            $sat_sun_status = true;
386
        }
387
388
        if ($sat_sun_status) {
389
            $sun_el = Predict_Math::Degrees($solar_set->el);
390
391
            if ($sun_el <= $this->threshold && $sat->el >= 0.0) {
392
                $vis = self::SAT_VIS_VISIBLE;
393
            } else {
394
                $vis = self::SAT_VIS_DAYLIGHT;
395
            }
396
        } else {
397
            $vis = self::SAT_VIS_ECLIPSED;
398
        }
399
400
        return $vis;
401
    }
402
403
    /** Find the AOS time of the next pass.
404
     *  @author Alexandru Csete, OZ9AEC
405
     *  @author John A. Magliacane, KD2BD
406
     *  @param Predict_Sat $sat   The satellite data.
407
     *  @param Predict_QTH $qth   The observer's location (QTH) data.
408
     *  @param float       $start The julian date where calculation should start.
409
     *  @param int         $maxdt The upper time limit in days (0.0 = no limit)
410
     *  @return The julain date of the next AOS or 0.0 if the satellite has no AOS.
411
     *
412
     * This function finds the time of AOS for the first coming pass taking place
413
     * no earlier that start.
414
     * If the satellite is currently within range, the function first calls
415
     * find_los to get the next LOS time. Then the calculations are done using
416
     * the new start time.
417
     *
418
     */
419
    public function find_aos(Predict_Sat $sat, Predict_QTH $qth, $start, $maxdt)
420
    {
421
        $t = $start;
422
        $aostime = 0.0;
423
424
425
        /* make sure current sat values are
426
            in sync with the time
427
        */
428
        $this->predict_calc($sat, $qth, $start);
429
430
        /* check whether satellite has aos */
431
        if (($sat->otype == Predict_SGPSDP::ORBIT_TYPE_GEO) ||
432
            ($sat->otype == Predict_SGPSDP::ORBIT_TYPE_DECAYED) ||
433
            !$this->has_aos($sat, $qth)) {
434
435
            return 0.0;
436
        }
437
438
        if ($sat->el > 0.0) {
439
            $t = $this->find_los($sat, $qth, $start, $maxdt) + 0.014; // +20 min
440
        }
441
442
        /* invalid time (potentially returned by find_los) */
443
        if ($t < 0.1) {
444
            return 0.0;
445
        }
446
447
        /* update satellite data */
448
        $this->predict_calc($sat, $qth, $t);
449
450
        /* use upper time limit */
451
        if ($maxdt > 0.0) {
452
453
            /* coarse time steps */
454
            while (($sat->el < -1.0) && ($t <= ($start + $maxdt))) {
455
                $t -= 0.00035 * ($sat->el * (($sat->alt / 8400.0) + 0.46) - 2.0);
456
                $this->predict_calc($sat, $qth, $t);
457
            }
458
459
            /* fine steps */
460
            while (($aostime == 0.0) && ($t <= ($start + $maxdt))) {
461
462
                if (abs($sat->el) < 0.005) {
463
                    $aostime = $t;
464
                } else {
465
                    $t -= $sat->el * sqrt($sat->alt) / 530000.0;
466
                    $this->predict_calc($sat, $qth, $t);
467
                }
468
            }
469
        } else {
470
            /* don't use upper time limit */
471
472
            /* coarse time steps */
473
            while ($sat->el < -1.0) {
474
475
                $t -= 0.00035 * ($sat->el * (($sat->alt / 8400.0) + 0.46) - 2.0);
476
                $this->predict_calc($sat, $qth, $t);
477
            }
478
479
            /* fine steps */
480
            while ($aostime == 0.0) {
481
482
                if (abs($sat->el) < 0.005) {
483
                    $aostime = $t;
484
                } else {
485
                    $t -= $sat->el * sqrt($sat->alt) / 530000.0;
486
                    $this->predict_calc($sat, $qth, $t);
487
                }
488
489
            }
490
        }
491
492
        return $aostime;
493
    }
494
495
    /** SGP4SDP4 driver for doing AOS/LOS calculations.
496
     *  @param Predict_Sat $sat The satellite data.
497
     *  @param Predict_QTH $qth The QTH observer location data.
498
     *  @param float       $t   The time for calculation (Julian Date)
499
     *
500
     */
501
    public function predict_calc(Predict_Sat $sat, Predict_QTH $qth, $t)
502
    {
503
        $obs_set      = new Predict_ObsSet();
504
        $sat_geodetic = new Predict_Geodetic();
505
        $obs_geodetic = new Predict_Geodetic();
506
507
        $obs_geodetic->lon   = $qth->lon * self::de2ra;
508
        $obs_geodetic->lat   = $qth->lat * self::de2ra;
509
        $obs_geodetic->alt   = $qth->alt / 1000.0;
510
        $obs_geodetic->theta = 0;
511
512
        $sat->jul_utc = $t;
513
        $sat->tsince = ($sat->jul_utc - $sat->jul_epoch) * self::xmnpda;
514
515
        /* call the norad routines according to the deep-space flag */
516
        $sgpsdp = Predict_SGPSDP::getInstance($sat);
517
        if ($sat->flags & Predict_SGPSDP::DEEP_SPACE_EPHEM_FLAG) {
518
            $sgpsdp->SDP4($sat, $sat->tsince);
519
        } else {
520
            $sgpsdp->SGP4($sat, $sat->tsince);
521
        }
522
523
        Predict_Math::Convert_Sat_State($sat->pos, $sat->vel);
524
525
        /* get the velocity of the satellite */
526
        $sat->vel->w = sqrt($sat->vel->x * $sat->vel->x + $sat->vel->y * $sat->vel->y + $sat->vel->z * $sat->vel->z);
0 ignored issues
show
Documentation Bug introduced by
The property $w was declared of type integer, but sqrt($sat->vel->x * $sat...>vel->z * $sat->vel->z) is of type double. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
527
        $sat->velo = $sat->vel->w;
528
        Predict_SGPObs::Calculate_Obs($sat->jul_utc, $sat->pos, $sat->vel, $obs_geodetic, $obs_set);
529
        Predict_SGPObs::Calculate_LatLonAlt($sat->jul_utc, $sat->pos, $sat_geodetic);
530
531
        while ($sat_geodetic->lon < -self::pi) {
532
            $sat_geodetic->lon += self::twopi;
533
        }
534
535
        while ($sat_geodetic->lon > (self::pi)) {
536
            $sat_geodetic->lon -= self::twopi;
537
        }
538
539
        $sat->az = Predict_Math::Degrees($obs_set->az);
540
        $sat->el = Predict_Math::Degrees($obs_set->el);
541
        $sat->range = $obs_set->range;
542
        $sat->range_rate = $obs_set->range_rate;
543
        $sat->ssplat = Predict_Math::Degrees($sat_geodetic->lat);
544
        $sat->ssplon = Predict_Math::Degrees($sat_geodetic->lon);
545
        $sat->alt = $sat_geodetic->alt;
546
        $sat->ma = Predict_Math::Degrees($sat->phase);
547
        $sat->ma *= 256.0 / 360.0;
548
        $sat->phase = Predict_Math::Degrees($sat->phase);
549
550
        /* same formulas, but the one from predict is nicer */
551
        //sat->footprint = 2.0 * xkmper * acos (xkmper/sat->pos.w);
552
        $sat->footprint = 12756.33 * acos(self::xkmper / (self::xkmper + $sat->alt));
553
        $age = $sat->jul_utc - $sat->jul_epoch;
554
        $sat->orbit = floor(($sat->tle->xno * self::xmnpda / self::twopi +
555
                        $age * $sat->tle->bstar * self::ae) * $age +
556
                        $sat->tle->xmo / self::twopi) + $sat->tle->revnum - 1;
557
    }
558
559
    /** Find the LOS time of the next pass.
560
     *  @author Alexandru Csete, OZ9AEC
561
     *  @author John A. Magliacane, KD2BD
562
     *  @param Predict_Sat $sat The satellite data.
563
     *  @param Predict_QTH $qth The QTH observer location data.
564
     *  @param float       $start The time where calculation should start. (Julian Date)
565
     *  @param int         $maxdt The upper time limit in days (0.0 = no limit)
566
     *  @return The time (julian date) of the next LOS or 0.0 if the satellite has no LOS.
567
     *
568
     * This function finds the time of LOS for the first coming pass taking place
569
     * no earlier that start.
570
     * If the satellite is currently out of range, the function first calls
571
     * find_aos to get the next AOS time. Then the calculations are done using
572
     * the new start time.
573
     * The function has a built-in watchdog to ensure that we don't end up in
574
     * lengthy loops.
575
     *
576
     */
577
    public function find_los(Predict_Sat $sat, Predict_QTH $qth, $start, $maxdt)
578
    {
579
        $t = $start;
580
        $lostime = 0.0;
581
582
583
        $this->predict_calc($sat, $qth, $start);
584
585
        /* check whether satellite has aos */
586
        if (($sat->otype == Predict_SGPSDP::ORBIT_TYPE_GEO) ||
587
            ($sat->otype == Predict_SGPSDP::ORBIT_TYPE_DECAYED) ||
588
            !$this->has_aos ($sat, $qth)) {
589
590
            return 0.0;
591
        }
592
593
        if ($sat->el < 0.0) {
594
            $t = $this->find_aos($sat, $qth, $start, $maxdt) + 0.001; // +1.5 min
595
        }
596
597
        /* invalid time (potentially returned by find_aos) */
598
        if ($t < 0.01) {
599
            return 0.0;
600
        }
601
602
        /* update satellite data */
603
        $this->predict_calc($sat, $qth, $t);
604
605
        /* use upper time limit */
606
        if ($maxdt > 0.0) {
607
608
            /* coarse steps */
609
            while (($sat->el >= 1.0) && ($t <= ($start + $maxdt))) {
610
                $t += cos(($sat->el - 1.0) * self::de2ra) * sqrt($sat->alt) / 25000.0;
611
                $this->predict_calc($sat, $qth, $t);
612
            }
613
614
            /* fine steps */
615
            while (($lostime == 0.0) && ($t <= ($start + $maxdt)))  {
616
617
                $t += $sat->el * sqrt($sat->alt) / 502500.0;
618
                $this->predict_calc($sat, $qth, $t);
619
620
                if (abs($sat->el) < 0.005) {
621
                    $lostime = $t;
622
                }
623
            }
624
        } else {
625
        /* don't use upper limit */
626
627
            /* coarse steps */
628
            while ($sat->el >= 1.0) {
629
                $t += cos(($sat->el - 1.0) * self::de2ra) * sqrt($sat->alt) / 25000.0;
630
                $this->predict_calc($sat, $qth, $t);
631
            }
632
633
            /* fine steps */
634
            while ($lostime == 0.0) {
635
636
                $t += $sat->el * sqrt($sat->alt) / 502500.0;
637
                $this->predict_calc($sat, $qth, $t);
638
639
                if (abs($sat->el) < 0.005)
640
                    $lostime = $t;
641
            }
642
        }
643
644
        return $lostime;
645
    }
646
647
    /** Find AOS time of current pass.
648
     *  @param Predict_Sat $sat   The satellite to find AOS for.
649
     *  @param Predict_QTH $qth   The ground station.
650
     *  @param float       $start Start time, prefereably now.
651
     *  @return The time of the previous AOS or 0.0 if the satellite has no AOS.
652
     *
653
     * This function can be used to find the AOS time in the past of the
654
     * current pass.
655
     */
656
    public function find_prev_aos(Predict_Sat $sat, Predict_QTH $qth, $start)
657
    {
658
        $aostime = $start;
659
660
        /* make sure current sat values are
661
            in sync with the time
662
        */
663
        $this->predict_calc($sat, $qth, $start);
664
665
        /* check whether satellite has aos */
666
        if (($sat->otype == Predict_SGPSDP::ORBIT_TYPE_GEO) ||
667
            ($sat->otype == Predict_SGPSDP::ORBIT_TYPE_DECAYED) ||
668
            !$this->has_aos($sat, $qth)) {
669
670
            return 0.0;
671
        }
672
673
        while ($sat->el >= 0.0) {
674
            $aostime -= 0.0005; // 0.75 min
675
            $this->predict_calc($sat, $qth, $aostime);
676
        }
677
678
        return $aostime;
679
    }
680
681
    /** Determine whether satellite ever reaches AOS.
682
     *  @author John A. Magliacane, KD2BD
683
     *  @author Alexandru Csete, OZ9AEC
684
     *  @param Predict_Sat $sat The satellite data.
685
     *  @param Predict_QTH $qth The observer's location data
686
     *  @return bool true if the satellite will reach AOS, false otherwise.
687
     *
688
     */
689
    public function has_aos(Predict_Sat $sat, Predict_QTH $qth)
690
    {
691
         $retcode = false;
0 ignored issues
show
$retcode 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...
692
693
         /* FIXME */
694
         if ($sat->meanmo == 0.0) {
695
              $retcode = false;
696
         } else {
697
698
            /* xincl is already in RAD by select_ephemeris */
699
            $lin = $sat->tle->xincl;
700
            if ($lin >= self::pio2) {
701
                $lin = self::pi - $lin;
702
            }
703
704
            $sma = 331.25 * exp(log(1440.0 / $sat->meanmo) * (2.0 / 3.0));
705
            $apogee = $sma * (1.0 + $sat->tle->eo) - self::xkmper;
706
707
            if ((acos(self::xkmper / ($apogee + self::xkmper)) + ($lin)) > abs($qth->lat * self::de2ra)) {
708
                $retcode = true;
709
            } else {
710
                $retcode = false;
711
            }
712
        }
713
714
        return $retcode;
715
    }
716
717
    /** Predict passes after a certain time.
718
     *
719
     *
720
     * This function calculates num upcoming passes with AOS no earlier
721
     * than t = start and not later that t = (start+maxdt). The function will
722
     *  repeatedly call get_pass until
723
     * the number of predicted passes is equal to num, the time has reached
724
     * limit or the get_pass function returns NULL.
725
     *
726
     * note For no time limit use maxdt = 0.0
727
     *
728
     * note the data in sat will be corrupt (future) and must be refreshed
729
     *      by the caller, if the caller will need it later on (eg. if the caller
730
     *      is GtkSatList).
731
     *
732
     * note Prepending to a singly linked list is much faster than appending.
733
     *      Therefore, the elements are prepended whereafter the GSList is
734
     *      reversed
735
     *
736
     *
737
     * @param Predict_Sat  $sat The satellite data
738
     * @param Predict_QTH  $qth The observer's location data
739
     * @param float $start The start julian date
740
     * @param int   $maxdt The max # of days to look
741
     * @param int   $num   The max # of passes to get
742
     * @return array of Predict_Pass instances if found, empty array otherwise
743
     */
744
    public function get_passes(Predict_Sat $sat, Predict_QTH $qth, $start, $maxdt, $num = 0)
745
    {
746
        $passes = array();
747
748
        /* if no number has been specified
749
            set it to something big */
750
        if ($num == 0) {
751
            $num = 100;
752
        }
753
754
        $t = $start;
755
756
        for ($i = 0; $i < $num; $i++) {
757
            $pass = $this->get_pass($sat, $qth, $t, $maxdt);
758
759
            if ($pass != null) {
760
                $passes[] = $pass;
761
                $t = $pass->los + 0.014; // +20 min
762
763
                /* if maxdt > 0.0 check whether we have reached t = start+maxdt
764
                    if yes finish predictions
765
                */
766
                if (($maxdt > 0.0) && ($t >= ($start + $maxdt))) {
767
                    $i = $num;
768
                }
769
            } else {
770
                /* we can't get any more passes */
771
                $i = $num;
772
            }
773
        }
774
775
        return $passes;
776
    }
777
778
    /**
779
     * Filters out visible passes and adds the visible aos, tca, los, and
780
     * corresponding az and ele for each.
781
     *
782
     * @param array $passes The passes returned from get_passes()
783
     *
784
     * @author Bill Shupp
785
     * @return array
786
     */
787
    public function filterVisiblePasses(array $passes)
788
    {
789
        $filtered = array();
790
791
        foreach ($passes as $result) {
792
            // Dummy check
793
            if ($result->vis[0] != 'V') {
794
                continue;
795
            }
796
797
            $aos    = false;
0 ignored issues
show
$aos 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...
798
            $aos_az = false;
799
            $aos    = false;
800
            $tca    = false;
801
            $los_az = false;
802
            $max_el = 0;
803
804
            foreach ($result->details as $detail) {
805
                if ($detail->vis != Predict::SAT_VIS_VISIBLE) {
806
                    continue;
807
                }
808
                if ($detail->el < $this->minEle) {
809
                    continue;
810
                }
811
812
                if ($aos == false) {
813
                    $aos       = $detail->time;
814
                    $aos_az    = $detail->az;
815
                    $aos_el    = $detail->el;
816
                    $tca       = $detail->time;
817
                    $los       = $detail->time;
818
                    $los_az    = $detail->az;
819
                    $los_el    = $detail->el;
820
                    $max_el    = $detail->el;
821
                    $max_el_az = $detail->el;
822
                    continue;
823
                }
824
                $los    = $detail->time;
825
                $los_az = $detail->az;
826
                $los_el = $detail->el;
827
828
                if ($detail->el > $max_el) {
829
                    $tca       = $detail->time;
830
                    $max_el    = $detail->el;
831
                    $max_el_az = $detail->az;
832
                }
833
            }
834
835
            if ($aos === false) {
836
                // Does not reach minimum elevation, skip
837
                continue;
838
            }
839
840
            $result->visible_aos       = $aos;
841
            $result->visible_aos_az    = $aos_az;
842
            $result->visible_aos_el    = $aos_el;
0 ignored issues
show
The variable $aos_el 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...
843
            $result->visible_tca       = $tca;
844
            $result->visible_max_el    = $max_el;
845
            $result->visible_max_el_az = $max_el_az;
0 ignored issues
show
The variable $max_el_az 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...
846
            $result->visible_los       = $los;
0 ignored issues
show
The variable $los 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...
847
            $result->visible_los_az    = $los_az;
848
            $result->visible_los_el    = $los_el;
0 ignored issues
show
The variable $los_el 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...
849
850
            $filtered[] = $result;
851
        }
852
853
        return $filtered;
854
    }
855
856
    /**
857
     * Translates aziumuth degrees to compass direction:
858
     *
859
     * N (0°), NNE (22.5°), NE (45°), ENE (67.5°), E (90°), ESE (112.5°),
860
     * SE (135°), SSE (157.5°), S (180°), SSW (202.5°), SW (225°),
861
     * WSW (247.5°), W (270°), WNW (292.5°), NW (315°), NNW (337.5°)
862
     *
863
     * @param int $az The azimuth in degrees, defaults to 0
864
     *
865
     * @return string
866
     */
867
    public function azDegreesToDirection($az = 0)
868
    {
869
        $i = floor($az / 22.5);
870
        $m = (22.5 * (2 * $i + 1)) / 2;
871
        $i = ($az >= $m) ? $i + 1 : $i;
872
873
        return trim(substr('N  NNENE ENEE  ESESE SSES  SSWSW WSWW  WNWNW NNWN  ', $i * 3, 3));
874
    }
875
}
876