~jstys-z/helioviewer.org/client5

« back to all changes in this revision

Viewing changes to api/lib/helioviewer/API.php

  • Committer: V. Keith Hughitt
  • Date: 2009-04-01 21:08:05 UTC
  • Revision ID: hughitt1@kore-20090401210805-372f7dgih07vxk42
nightly build 04-01-2009

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
/**
 
3
 * @package Helioviewer API
 
4
 * @author Keith Hughitt <Vincent.K.Hughitt@nasa.gov>
 
5
 */
 
6
/**
 
7
 * @package Helioviewer API
 
8
 */
 
9
error_reporting(E_ALL | E_STRICT);
 
10
class API {
 
11
 
 
12
    /**
 
13
     * @param array An array of parameters relevant to the API call
 
14
     * @param string ["plain-text"|"json"] The format to return results in
 
15
     */
 
16
    public function __construct ($params, $format) {
 
17
        require_once('DbConnection.php');
 
18
        $this->params = $params;
 
19
        $this->format = $format;
 
20
 
 
21
        $_SERVER['HTTP_HOST'] == "localhost" ? require_once('../settings/Config.php') : require_once('../settings/Config.Server.php');
 
22
 
 
23
        try {
 
24
            if (!$this->validate($params["action"]))
 
25
                throw new Exception("Invalid parameters specified for <a href='http://www.helioviewer.org/api/index.php#" . $params['action'] . "'>" . $params['action'] . "</a>.");
 
26
 
 
27
            #if (!call_user_func(array("API" ,"_" . $params["action"])))
 
28
            if (!$this->{"_" . $params["action"]}() === 1)
 
29
                throw new Exception("Unable to execute " . $params["action"] . ". Please make sure you are using valid input and contact the web-admin if problems persist.");
 
30
 
 
31
        } catch (Exception $e) {
 
32
            echo "<br><b>Error:</b> ", $e->getMessage(), "<br>";
 
33
        }
 
34
 
 
35
        exit();
 
36
    }
 
37
 
 
38
    /**
 
39
     * @return int Returns "1" if the action was completed successfully.
 
40
     */
 
41
    private function _getTile () {
 
42
        require_once("Tile.php");
 
43
        $tile = new Tile($this->params['imageId'], $this->params['zoom'], $this->params['x'], $this->params['y'], $this->params['ts']);
 
44
 
 
45
        return 1;
 
46
    }
 
47
 
 
48
    /**
 
49
     * @return int Returns "1" if the action was completed successfully.
 
50
     */
 
51
    private function _getClosestImage () {
 
52
        require_once('ImgIndex.php');
 
53
        $imgIndex = new ImgIndex(new DbConnection());
 
54
 
 
55
        $queryForField = 'abbreviation';
 
56
        foreach(array('observatory', 'instrument', 'detector', 'measurement') as $field) {
 
57
            $src["$field.$queryForField"] = $this->params[$field];
 
58
        }
 
59
 
 
60
        $result = $imgIndex->getClosestImage($this->params['timestamp'], $src);
 
61
 
 
62
        if ($this->format == "json") {
 
63
            header('Content-type: application/json');
 
64
            echo json_encode($result);
 
65
        } else {
 
66
            echo json_encode($result);
 
67
        }
 
68
 
 
69
        return 1;
 
70
    }
 
71
 
 
72
    /**
 
73
     * getViewerImage (aka "getCompositeImage")
 
74
     *
 
75
     * Example usage:
 
76
     *         http://helioviewer.org/api/index.php?action=getViewerImage&layers=SOHEITEIT195&timestamps=1065312000&zoomLevel=10&tileSize=512&xRange=-1,0&yRange=-1,0
 
77
     *         http://helioviewer.org/api/index.php?action=getViewerImage&layers=SOHEITEIT195,SOHLAS0C20WL&timestamps=1065312000,1065312360&zoomLevel=13&tileSize=512&xRange=-1,0&yRange=-1,0&edges=false
 
78
     * 
 
79
     * Notes:
 
80
     *         Building a UTC timestamp in javascript
 
81
     *             var d = new Date(Date.UTC(2003, 9, 5));
 
82
     *             var unix_ts = d.getTime() * 1000;
 
83
     * 
 
84
     *         TODO
 
85
     *             * If no params are passed, print out API usage description (and possibly a query builder form)...
 
86
     *             * Add support for fuzzy timestamp matching. Could default to exact matching unless user specifically requests fuzzy date-matching.
 
87
     *          * Separate out layer details into a Layer PHP class?
 
88
     *
 
89
     * @return int Returns "1" if the action was completed successfully.
 
90
     *
 
91
     */
 
92
    private function _getViewerImage () {
 
93
        require('lib/helioviewer/CompositeImage.php');
 
94
 
 
95
        //Process query string
 
96
        try {
 
97
            // Extract timestamps
 
98
            $timestamps = explode(",", $this->params['timestamps']);
 
99
            if (strlen($this->params['timestamps']) == 0) {
 
100
                throw new Exception("Error: Incorrect number of timestamps specified!");
 
101
            }
 
102
 
 
103
            // Region of interest
 
104
            $x = explode(",", $this->params['xRange']);
 
105
            $y = explode(",", $this->params['yRange']);
 
106
 
 
107
            $xRange = array();
 
108
            $xRange['start'] = $x[0];
 
109
            $xRange['end']   = $x[1];
 
110
 
 
111
            $yRange = array();
 
112
            $yRange['start'] = $y[0];
 
113
            $yRange['end']   = $y[1];
 
114
 
 
115
            // Zoom-level & tilesize
 
116
            $zoomLevel = $this->params['zoomLevel'];
 
117
            $tileSize  = $this->params['tileSize'];
 
118
 
 
119
            // Construct layers
 
120
            $layers = array();
 
121
            $i = 0;
 
122
            foreach (explode(",", $this->params['layers']) as $layer) {
 
123
                array_push($layers, new Layer($layer, $timestamps[$i], $timestamps[$i], $zoomLevel, $xRange, $yRange, $tileSize));
 
124
                $i++;
 
125
            }
 
126
 
 
127
            // Limit to 3 layers
 
128
            if ((sizeOf($layers) > 3) || (strlen($this->params['layers']) == 0)) {
 
129
                throw new Exception("Error: Invalid layer choices! You must specify 1-3 command-separate layernames.");
 
130
            }
 
131
 
 
132
            // Optional parameters
 
133
            $options = array();
 
134
            $options["edgeEnhance"] = $this->params['edges'];
 
135
            $options["sharpen"]     = $this->params['sharpen'];
 
136
        }
 
137
        catch(Exception $e) {
 
138
            echo 'Error: ' .$e->getMessage();
 
139
            exit();
 
140
        }
 
141
 
 
142
        //Create and display composite image
 
143
        $img = new CompositeImage($layers, $zoomLevel, $xRange, $yRange, $options);
 
144
        $img->printImage();
 
145
 
 
146
        return 1;
 
147
    }
 
148
 
 
149
    /**
 
150
     * @return int Returns "1" if the action was completed successfully.
 
151
     */
 
152
    private function _getJP2Image () {
 
153
        require('lib/helioviewer/ImgIndex.php');
 
154
        $imgIndex = new ImgIndex(new DbConnection());
 
155
 
 
156
        $queryForField = 'abbreviation';
 
157
        foreach(array('observatory', 'instrument', 'detector', 'measurement') as $field) {
 
158
            $src["$field.$queryForField"] = $this->params[$field];
 
159
        }
 
160
 
 
161
        $filepath = $imgIndex->getJP2Location($this->params['timestamp'], $src);
 
162
        $filename = end(explode("/", $filepath));
 
163
 
 
164
        if ($this->params['getURL'] == "true") {
 
165
            $url = preg_replace(Config::WEB_ROOT_DIR_REGEX, Config::WEB_ROOT_URL, $filepath);
 
166
            echo $url;
 
167
        }
 
168
        else {
 
169
            $fp = fopen($filepath, 'r');
 
170
 
 
171
            header("Content-Length: " . filesize($filepath));
 
172
            header("Content-Type: "   . image_type_to_mime_type(IMAGETYPE_JP2));
 
173
            header("Content-Disposition: attachment; filename=\"$filename\"");
 
174
 
 
175
            $contents = fread($fp, filesize($filepath));
 
176
 
 
177
            echo $contents;
 
178
             fclose($fp);
 
179
        }
 
180
 
 
181
        return 1;
 
182
    }
 
183
 
 
184
    /**
 
185
     * @return int Returns "1" if the action was completed successfully.
 
186
     */
 
187
    private function _getJP2ImageSeries () {
 
188
        require_once('ImgIndex.php');
 
189
        //date_default_timezone_set('UTC');
 
190
        
 
191
        $startTime = $this->params['startTime'];
 
192
        $endTime   = $this->params['endTime'];
 
193
        $cadence   = $this->params['cadence'];
 
194
        $format    = $this->params['format'];
 
195
 
 
196
        // Layer information
 
197
        foreach(array('observatory', 'instrument', 'detector', 'measurement') as $field) {
 
198
          $src["$field.abbreviation"] = $this->params[$field];
 
199
        }
 
200
 
 
201
        // Connect to database
 
202
        $imgIndex = new ImgIndex(new DbConnection());
 
203
 
 
204
        // Determine number of frames to grab
 
205
        $timeInSecs = $endTime - $startTime;
 
206
        $numFrames  = min(Config::MAX_MOVIE_FRAMES, ceil($timeInSecs / $cadence));
 
207
 
 
208
        // Convert timestamp to a PHP DateTime (See http://us2.php.net/manual/en/function.date-create.php)
 
209
        //$dt = new DateTime("@$startTime");
 
210
        //echo $dt->format("U");
 
211
        //date_add($dt, new DateInterval("T" . $cadence . "S"));
 
212
 
 
213
        $time = $startTime;
 
214
 
 
215
        $images = array();
 
216
 
 
217
        // Get nearest JP2 images to each time-step
 
218
        for ($i = 0; $i < $numFrames; $i++) {
 
219
            $jp2 = $imgIndex->getJP2Location($time, $src);
 
220
            //$url = preg_replace($this->web_root_url_regex, $this->web_root_dir, $url);
 
221
            array_push($images, $jp2);
 
222
            $time += $cadence;
 
223
        }
 
224
 
 
225
        // Append filepaths to kdu_merge command
 
226
        $cmd = Config::KDU_MERGE_BIN . " -i ";
 
227
        foreach($images as $jp2) {
 
228
            $cmd .= "$jp2,";
 
229
        }
 
230
 
 
231
        // Drop trailing comma
 
232
        $cmd = substr($cmd, 0, -1);
 
233
 
 
234
        // Create a temporary directory to store image-series
 
235
        $now = time();
 
236
        $tmpdir = Config::TMP_ROOT_DIR . "/jp2-image-series/";
 
237
        if (!file_exists($tmpdir)) {
 
238
            mkdir($tmpdir);
 
239
            chmod($tmpdir, 0777);
 
240
        }
 
241
 
 
242
        $tmpdir .= "/$now/";
 
243
        if (!file_exists($tmpdir)) {
 
244
            mkdir($tmpdir);
 
245
            chmod($tmpdir, 0777);
 
246
        }
 
247
 
 
248
        $filename = "jhv_image_series." . strtolower($format);
 
249
        $tmpurl = Config::TMP_ROOT_URL . "/jp2-image-series/$now/" . $filename;
 
250
        $output_file = "$tmpdir" . $filename;
 
251
 
 
252
        $cmd .= " -o $output_file";
 
253
 
 
254
        // MJ2
 
255
        if ($format == "MJ2")
 
256
            $cmd .= " -mj2_tracks P:0-@25";
 
257
 
 
258
        // Execute kdu_merge command
 
259
        exec('export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:' . Config::KDU_LIBS_DIR . "; " . escapeshellcmd($cmd), $output, $return);
 
260
 
 
261
        //echo $cmd;
 
262
 
 
263
        echo $tmpurl;
 
264
        return 1;
 
265
    }
 
266
 
 
267
    /**
 
268
     * @return int Returns "1" if the action was completed successfully.
 
269
     * NOTE: Add option to specify XML vs. JSON... FITS vs. Entire header?
 
270
     */
 
271
    private function _getJP2Header () {
 
272
        $id = $this->params["imageId"];
 
273
 
 
274
        $db  = new DbConnection();
 
275
        $sql = sprintf("SELECT uri FROM image WHERE id=%s;", mysqli_real_escape_string($db->link, $id));
 
276
 
 
277
        $row = mysqli_fetch_array($db->query($sql), MYSQL_ASSOC);
 
278
        $url = $row['uri'];
 
279
 
 
280
        // Query header information using Exiftool
 
281
        $cmd = Config::EXIF_TOOL . " $url | grep Fits | grep -v Descr";
 
282
        exec($cmd, $out, $ret);
 
283
 
 
284
        $fits = array();
 
285
        foreach ($out as $index => $line) {
 
286
            $data = explode(":", $line);
 
287
            $param = substr(strtoupper(str_replace(" ", "", $data[0])), 4);
 
288
            $value = $data[1];
 
289
            array_push($fits, $param . ": " . $value);
 
290
        }
 
291
 
 
292
        if ($this->format == "json") {
 
293
            header('Content-type: application/json');
 
294
            echo json_encode($fits);
 
295
        }
 
296
        else {
 
297
            echo json_encode($fits);
 
298
        }
 
299
 
 
300
        return 1;
 
301
    }
 
302
 
 
303
    /**
 
304
     * @return int Returns "1" if the action was completed successfully.
 
305
     */
 
306
    private function _getEventCatalogs () {
 
307
        if ($this->format == "text") {
 
308
            header("Content-type: text/plain");
 
309
            $url = Config::EVENT_SERVER_URL . $_SERVER["QUERY_STRING"] . "&debug=1";
 
310
        }
 
311
        else {
 
312
            header("Content-type: application/json");
 
313
            $url = Config::EVENT_SERVER_URL . "action=getEventCatalogs";
 
314
        }
 
315
        echo file_get_contents($url);        
 
316
        return 1;
 
317
    }
 
318
 
 
319
    /**
 
320
     * @return int Returns "1" if the action was completed successfully.
 
321
     */
 
322
    private function _getEvents () {
 
323
        if ($this->format == "text") {
 
324
            header("Content-type: text/plain");
 
325
            $url = Config::EVENT_SERVER_URL . $_SERVER["QUERY_STRING"] . "&debug=1";
 
326
        }
 
327
        else {
 
328
            header("Content-type: application/json");
 
329
            $url = Config::EVENT_SERVER_URL . "action=getEvents&date=" . $this->params["date"] . "&windowSize=" . $this->params["windowSize"] . "&catalogs=" . $this->params["catalogs"];
 
330
        }
 
331
        echo file_get_contents($url);
 
332
        return 1;
 
333
    }
 
334
 
 
335
    /**
 
336
     * @return int Returns "1" if the action was completed successfully.
 
337
     */
 
338
    private function _launchJHelioviewer () {
 
339
        require_once('lib/helioviewer/JHV.php');
 
340
        $jhv = new JHV();
 
341
        $jhv->launch();
 
342
    }
 
343
 
 
344
    /**
 
345
     * @return int Returns "1" if the action was completed successfully.
 
346
     */
 
347
    private function _buildQuickMovie () {
 
348
        require_once('ImageSeries.php');
 
349
        
 
350
        // Required parameters
 
351
        $startDate = $this->params['startDate'];
 
352
        $zoomLevel = $this->params['zoomLevel'];
 
353
        $numFrames = $this->params['numFrames'];
 
354
        $frameRate = $this->params['frameRate'];
 
355
        
 
356
        $xRange    = $this->params['xRange'];
 
357
        $yRange    = $this->params['yRange'];
 
358
 
 
359
        $hqFormat  = $this->params['format'];
 
360
 
 
361
        // Optional parameters
 
362
        $options = array();
 
363
        $options['enhanceEdges'] = $this->params['edges'] || false;
 
364
        $options['sharpen']      = $this->params['sharpen'] || false;    
 
365
 
 
366
        //Check to make sure values are acceptable
 
367
        try {
 
368
            $layers = explode(",", $this->params['layers']);
 
369
 
 
370
            //Limit number of layers to three
 
371
            if ((sizeOf($layers) > 3) || (strlen($this->params['layers']) == 0)) {
 
372
                throw new Exception("Invalid layer choices! You must specify 1-3 command-separate layernames.");
 
373
            }
 
374
 
 
375
            //Limit number of frames to 100
 
376
            if (($numFrames < 10) || ($numFrames > Config::MAX_MOVIE_FRAMES)) {
 
377
                throw new Exception("Invalid number of frames. Number of frames should be at least 10 and no more than $maxFrames.");
 
378
            }
 
379
 
 
380
            $imgSeries = new ImageSeries($layers, $startDate, $zoomLevel, $numFrames, $frameRate, $hqFormat, $xRange, $yRange, $options);
 
381
            $imgSeries->quickMovie();
 
382
 
 
383
        } catch(Exception $e) {
 
384
            echo 'Error: ' .$e->getMessage();
 
385
            exit();
 
386
        }
 
387
 
 
388
        return 1;
 
389
    }
 
390
 
 
391
    /**
 
392
     * @return int Returns "1" if the action was completed successfully.
 
393
     */
 
394
    private function _playMovie () {
 
395
        $url = $this->params['url'];
 
396
        $hqFormat  = $this->params['format'];
 
397
        $width  = 512;
 
398
        $height = 512;
 
399
 
 
400
        $highQualityVersion = substr($url, 0, -3) . $hqFormat;
 
401
        ?>
 
402
            <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 
403
            <html>
 
404
            <head>
 
405
                <title>Helioviewer.org QuickMovie</title>
 
406
            </head>
 
407
            <body style="background-color: #000, color: #FFF">
 
408
                <!-- MC Media Player -->
 
409
                <div style="text-align: center;">
 
410
                    <script type="text/javascript">
 
411
                        playerFile = "http://www.mcmediaplayer.com/public/mcmp_0.8.swf";
 
412
                        fpFileURL = "<?php print $url?>";
 
413
                        fpButtonSize = "48x48";
 
414
                        fpAction = "play";
 
415
                        cpHidePanel = "mouseout";
 
416
                        cpHideDelay = "1";
 
417
                        defaultEndAction = "repeat";
 
418
                        playerSize = "<?php print $width . 'x' . $height?>";
 
419
                    </script>
 
420
                    <script type="text/javascript" src="http://www.mcmediaplayer.com/public/mcmp_0.8.js"></script>
 
421
                    <!-- / MC Media Player -->
 
422
                </div>
 
423
                <br>
 
424
                <div style="text-align: center;">
 
425
                    <a href="<?php print $highQualityVersion;?>" style="text-decoration: none; color: white; font-weight: bold;">High-quality download.</a>
 
426
                </div>
 
427
            </body>
 
428
            </html>
 
429
        <?php
 
430
        return 1;
 
431
    }
 
432
    /**
 
433
     * @return int Returns "1" if the action was completed successfully.
 
434
     */
 
435
    private function _getLayerAvailability () {
 
436
        $dbConnection = new DbConnection();
 
437
 
 
438
        // Layer parameters
 
439
        $obs  = mysqli_real_escape_string($dbConnection->link, $this->params['observatory']);
 
440
        $inst = mysqli_real_escape_string($dbConnection->link, $this->params['instrument']);
 
441
        $det  = mysqli_real_escape_string($dbConnection->link, $this->params['detector']);
 
442
        $meas = mysqli_real_escape_string($dbConnection->link, $this->params['measurement']);
 
443
 
 
444
        // Validate new combinations (Note: measurement changes are always valid)
 
445
        if (isset($this->params['changed'])) {
 
446
            $changed  = mysqli_real_escape_string($dbConnection->link, $this->params['changed']);
 
447
            $newValue = mysqli_real_escape_string($dbConnection->link, $this->params['value']);
 
448
 
 
449
            // If query returns any matches then the new combination is valid
 
450
            $query = sprintf("SELECT count(*) as count from observatory 
 
451
                                INNER JOIN instrument ON observatory.id = instrument.observatoryId
 
452
                                INNER JOIN detector ON detector.instrumentId = instrument.id
 
453
                                  INNER JOIN measurement ON measurement.detectorId = detector.id
 
454
                                WHERE
 
455
                                observatory.abbreviation = '%s' AND instrument.abbreviation = '%s' and detector.abbreviation='%s' and measurement.abbreviation = '%s';",
 
456
                                $obs, $inst, $det, $meas);
 
457
 
 
458
            $result = $dbConnection->query($query);
 
459
            $row = mysqli_fetch_array($result, MYSQL_ASSOC);
 
460
            $valid = $row['count'];
 
461
 
 
462
            //If combination is invalid, adjust options to provide a valid combination
 
463
            if (!$valid) {
 
464
                //CASE 1: Observatory changed
 
465
 
 
466
                //CASE 2: Instrument changefirst grab a list of valid detectors for the chosen instrumentd
 
467
                if ($changed == "instrument") {
 
468
                    //Find a valid detector for the chosen instrument
 
469
                    $query = sprintf("SELECT detector.abbreviation from detector INNER JOIN instrument ON instrument.id = detector.instrumentId 
 
470
                                      WHERE instrument.abbreviation = '%s' LIMIT 1;", $newValue);
 
471
                    $result = $dbConnection->query($query);
 
472
                    $row = mysqli_fetch_array($result, MYSQL_ASSOC);
 
473
                    $det = $row['abbreviation'];
 
474
 
 
475
                    //Measurements will be automatically updated...
 
476
                }
 
477
 
 
478
                //CASE 3: Detector changed
 
479
 
 
480
                //CASE 4: Measurement change
 
481
                //Do nothing
 
482
            }
 
483
        }
 
484
 
 
485
        /**
 
486
         *
 
487
         * @return Array Allowed values for given field
 
488
         * @param $db Object MySQL Database connection
 
489
         * @param $f1 String Field Objectof interest
 
490
         * @param $f2 String Limiting field
 
491
         * @param $limit String Limiting field value
 
492
         *
 
493
         * Queries one field based on a limit in another. Performs queries of the sort
 
494
         * "Give me all instruments where observatory equals SOHO."
 
495
         */
 
496
        function queryField($db, $format, $f1, $f2, $f1_value) {
 
497
            $values = array();
 
498
            $query = "SELECT $f2.name, $f2.abbreviation from $f2 INNER JOIN $f1 ON $f1.id = $f2.$f1" . "Id" . " WHERE $f1.abbreviation = '$f1_value';";
 
499
 
 
500
            if ($format === "plaintext")
 
501
                echo "<strong>query:</strong><br>$query<br><br>";
 
502
 
 
503
            $result = $db->query($query);
 
504
            while ($row = mysqli_fetch_array($result, MYSQL_ASSOC)) {
 
505
                array_push($values, $row);
 
506
            }
 
507
 
 
508
            return $values;
 
509
        }
 
510
 
 
511
        // Determine appropriate options to display given the current combination of layer parameters
 
512
        $options = array(
 
513
            "observatories" => array(array("name" => "SOHO", "abbreviation" => "SOH")),
 
514
            "instruments" =>   queryField($dbConnection, $this->format, "observatory", "instrument", $obs),
 
515
            "detectors" =>     queryField($dbConnection, $this->format, "instrument", "detector", $inst),
 
516
            "measurements" =>  queryField($dbConnection, $this->format, "detector", "measurement", $det)
 
517
        );
 
518
 
 
519
        //Output results
 
520
        if ($this->format == "json")
 
521
            header("Content-type: application/json");
 
522
 
 
523
        echo json_encode($options);
 
524
        return 1;
 
525
    }
 
526
 
 
527
    /**
 
528
     * @return bool Input validity.
 
529
     * 
 
530
     * Action-specific code for validating input. Currently only input for external-use API's are
 
531
     * validated. All input destined for database use is secured at time of SQL construction. 
 
532
     */
 
533
    private function validate ($action) {
 
534
        // Some useful regexes
 
535
        $layer_regex            = "/^[a-zA-Z0-9]{12}$/";
 
536
        $layer_list_regex       = "/^[a-zA-Z0-9]{12}(,[a-zA-Z0-9]{12})*$/";
 
537
        $timestamp_regex        = "/^[0-9]{1,10}$/";
 
538
        $timestamp_list_regex   = "/^[0-9]{1,10}(,[0-9]{1,10})*$/";
 
539
        $coordinate_range_regex = "/^[0-9]{1,2},[0-9]{1,2}$/";
 
540
 
 
541
        switch ($action) {
 
542
            case "getTile":
 
543
                break;
 
544
            case "getClosestImage":
 
545
                break;
 
546
            case "getViewerImage":
 
547
                if (!isset($this->params["layers"]) or !preg_match($layer_list_regex, $this->params["layers"]))
 
548
                    return false;
 
549
                if (!isset($this->params["timestamps"]) or !preg_match($timestamp_list_regex, $this->params["timestamps"]))
 
550
                    return false;
 
551
                if (!isset($this->params["zoomLevel"]) or !is_numeric($this->params["zoomLevel"]) or $this->params["zoomLevel"] < 0 or $this->params["zoomLevel"] > 20)
 
552
                    return false;
 
553
                if (!isset($this->params["xRange"]))
 
554
                    return false;
 
555
                if (!isset($this->params["yRange"]))
 
556
                    return false;                
 
557
                break;
 
558
 
 
559
            case "getJP2Header":
 
560
                if (!isset($this->params["imageId"]) or !is_numeric($this->params["imageId"]))
 
561
                    return false;
 
562
                break;
 
563
            case "getEventCatalogs":
 
564
                break;
 
565
            case "getEvents":
 
566
                break;
 
567
            case "getLayerAvailability":
 
568
                break;
 
569
            case "getJP2Image":
 
570
                break;
 
571
            case "getJP2ImageSeries":
 
572
                break;
 
573
            case "launchJHelioviewer":
 
574
                break;
 
575
            default:
 
576
                throw new Exception("Invalid action specified. See the <a href='http://www.helioviewer.org/api/'>API Documentation</a> for a list of valid actions.");        
 
577
        }
 
578
 
 
579
        return true;
 
580
    }
 
581
}
 
582
?>