123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- <?php
- ini_set("session.use_only_cookies", 0);
- set_time_limit(0);
- session_cache_limiter("must-revalidate");
-
- require_once('slideshow_music.inc.php');
-
- class SlideshowMusicAPI extends WebAPI {
- private $operationPemission = "admin";
- protected $idPrefix = 'slideshowmusic_';
- private $mimeType = array(
- 'mp3' => 'audio/mpeg'
- );
-
- function __construct() {
- parent::__construct(SZ_WEBAPI_API_DESCRIPTION_PATH);
- }
-
- protected function Process()
- {
- if (!strcasecmp($this->method, "list")) {
- $this->SlideshowMusicList();
- } elseif (!strcasecmp($this->method, "get")) {
- session_write_close();
- $this->GetMusic();
- } else if (!strcasecmp($this->method, "add")) {
- $this->AddItem();
- } else if (!strcasecmp($this->method, "edit")) {
- $this->Edit();
- } else if (!strcasecmp($this->method, "delete")) {
- $this->Delete();
- }
- }
-
- private function SlideshowMusicList()
- {
- $resp = array();
-
- $params = $this->GetParams_List();
-
- $data = SlideshowMusic::ListItem($params['offset'], $params['limit']);
- $items = array();
- foreach ($data['data'] as $k => $v) {
- $v['id'] = $this->EncodeItemId($k);
- $items[] = $v;
- }
- $resp['items'] = $items;
- $resp['total'] = $data['total'];
- $offset = (0 > (int)$params['limit']) ? $resp['total'] : $params['offset'] + $params['limit'];
- $resp['offset'] = ($offset > $resp['total']) ? $resp['total'] : $offset;
- $this->SetResponse($resp);
- }
-
- private function GetMusic()
- {
- $id = $this->DecodeItemId($_REQUEST['id']);
- if (false === $id) {
- $this->SetError(WEBAPI_ERR_BAD_REQUEST);
- goto End;
- }
-
- $path = SlideshowMusic::GetMusicPath($id);
- if (!$path) {
- $this->SetError(PHOTOSTATION_SLIDESHOWMUSIC_NO_FILE);
- goto End;
- }
-
- @header("Content-Type: audio/mpeg");
- @header("Content-Transfer-Encoding: binary");
-
- $this->GetRangeDownload($path);
- exit;
-
- End:
- return;
- }
-
- private function GetRangeDownload($file)
- {
- $fp = @fopen($file, 'rb');
- if (false == $fp) {
- return false;
- }
-
- $size = filesize($file); // File size
- $length = $size; // Content length
- $start = 0; // Start byte
- $end = $size - 1; // End byte
- // Now that we've gotten so far without errors we send the accept range header
- // At the moment we only support single ranges.
- // Multiple ranges requires some more work to ensure it works correctly
- // and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
- //
- // Multirange support annouces itself with:
- // header('Accept-Ranges: bytes');
- //
- // Multirange content must be sent with multipart/byteranges mediatype,
- // (mediatype = mimetype)
- // as well as a boundry header to indicate the various chunks of data.
- //
- //header("Accept-Ranges: 0-$length");
- header('Accept-Ranges: bytes');
- // multipart/byteranges
- // http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
- if (isset($_SERVER['HTTP_RANGE'])) {
- $c_start = $start;
- $c_end = $end;
- // Extract the range string
- list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
- // Make sure the client hasn't sent us a multibyte range
- if (strpos($range, ',') !== false) {
-
- // (?) Shoud this be issued here, or should the first
- // range be used? Or should the header be ignored and
- // we output the whole content?
- header('HTTP/1.1 416 Requested Range Not Satisfiable');
- header("Content-Range: bytes $start-$end/$size");
- // (?) Echo some info to the client?
- exit;
- }
- // If the range starts with an '-' we start from the beginning
- // If not, we forward the file pointer
- // And make sure to get the end byte if spesified
- if ($range{0} == '-') {
-
- // The n-number of the last bytes is requested
- $c_start = $size - substr($range, 1);
- } else {
-
- $range = explode('-', $range);
- $c_start = $range[0];
- $c_end = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
- }
- // Check the range and make sure it's treated according to the specs.
- // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
- //
- // End bytes can not be larger than $end.
- $c_end = ($c_end > $end) ? $end : $c_end;
- // Validate the requested range and return an error if it's not correct.
- if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
-
- header('HTTP/1.1 416 Requested Range Not Satisfiable');
- header("Content-Range: bytes $start-$end/$size");
- // (?) Echo some info to the client?
- exit;
- }
- $start = $c_start;
- $end = $c_end;
- $length = $end - $start + 1; // Calculate new content length
- header('HTTP/1.1 206 Partial Content');
- }
- // Notify the client the byte range we'll be outputting
- header("Content-Range: bytes $start-$end/$size");
- header("Content-Length: $length");
-
-
- // Start buffered download
- $this->OutputFileWithRange($fp, $start, $end);
- fclose($fp);
- }
-
- // this function output contain $end
- private function OutputFileWithRange($fp, $start, $end)
- {
- fseek($fp, $start);
- $buffer = 1024 * 8;
- while (!feof($fp) && ($end == -1 || ($p = ftell($fp)) <= $end)) {
-
- if ($p + $buffer > $end && $end != -1) {
-
- // In case we're only outputtin a chunk, make sure we don't
- // read past the length
- $buffer = $end - $p + 1;
- }
-
- echo fread($fp, $buffer);
- flush(); // Free up memory. Otherwise large files will trigger PHP's memory limit.
- }
- }
-
- private function AddItem()
- {
- $filename = $_FILES['file']['name'];
- $title = $_REQUEST['title'];
-
- if (!csSYNOPhotoMisc::IsMusicFile($filename)) {
- $this->SetError(PHOTOSTATION_SLIDESHOWMUSIC_FILE_EXT_ERR);
- goto End;
- }
- if (!isset($_FILES['file'])) {
- $this->SetError(PHOTOSTATION_SLIDESHOWMUSIC_NO_FILE);
- goto End;
- }
-
- if ($_FILES['file']['error'] > 0) { // files is not uploaded successfully by form upload
- $this->SetError(PHOTOSTATION_SLIDESHOWMUSIC_UPLOAD_ERROR);
- goto End;
- }
-
- if (SlideshowMusic::LIMIT <= SlideshowMusic::GetCount()) {
- $this->SetError(array(PHOTOSTATION_SLIDESHOWMUSIC_EXCEED_LIMIT, SlideshowMusic::LIMIT));
- goto End;
- }
-
- if (!SlideshowMusic::Add($filename, $_FILES['file']['tmp_name'], $title)) {
- $this->SetError(PHOTOSTATION_SLIDESHOWMUSIC_SET_FAIL);
- goto End;
- }
- $resp = SlideshowMusic::GetLastInsertMusic();
- $resp['id'] = $this->EncodeItemId($resp['id']);
- $this->SetResponse($resp);
- End:
- return;
- }
-
- private function Edit()
- {
- $params = $this->GetParams_Edit();
-
- if (!$params) {
- $this->SetError(WEBAPI_ERR_BAD_REQUEST);
- goto End;
- }
-
- $res = SlideshowMusic::EditById($params['id'], $params['title'], $params['default']);
-
- if (!$res) {
- $this->SetError(PHOTOSTATION_SLIDESHOWMUSIC_SET_FAIL);
- }
- End:
- return;
- }
-
- private function Delete()
- {
- $params = $this->GetParams_Delete();
-
- if (!$params) {
- $this->SetError(WEBAPI_ERR_BAD_REQUEST);
- goto End;
- }
- $res = SlideshowMusic::DeleteById($params['id']);
-
- if (!$res) {
- $this->SetError(PHOTOSTATION_SLIDESHOWMUSIC_SET_FAIL);
- }
- End:
- return;
- }
-
- private function GetParams_List()
- {
- // $variable + 0 => convert to integer
- $params = array(
- 'offset' => !isset($_REQUEST['offset']) || $_REQUEST['offset'] < 0 ? 0 : $_REQUEST['offset'] + 0,
- 'limit' => !isset($_REQUEST['limit']) || $_REQUEST['limit'] < 0 ? NULL : $_REQUEST['limit'] + 0,
- );
- return $params;
- }
-
- private function GetParams_Edit()
- {
- if (!isset($_REQUEST['id']) || !((isset($_REQUEST['title']) && '' !== $_REQUEST['title']) || isset($_REQUEST['default']))) {
- return false;
- }
-
- $id = $this->DecodeItemId($_REQUEST['id']);
-
- if (false === $id) {
- return false;
- }
-
- $params = array(
- 'id' => $id,
- 'title' => $_REQUEST['title'],
- 'default' => isset($_REQUEST['default']) ? ("true" === $_REQUEST['default'] ? true : false) : NULL
- );
- return $params;
- }
-
- private function GetParams_Delete()
- {
- if (!isset($_REQUEST['id'])){
- return false;
- }
-
- $ids = explode(',', $_REQUEST['id']);
- $validIds= array();
- foreach($ids as $id) {
- $decodeId = $this->DecodeItemId($id);
- if(false === $decodeId) {
- continue;
- }
- $validIds[] = $decodeId;
- }
-
- if (!count($validIds)) {
- return false;
- }
-
- $params = array(
- 'id' => $validIds
- );
- return $params;
- }
-
- protected function CheckPermission()
- {
- $res = true;
- $check = array(
- "add" => $this->operationPemission,
- "edit" => $this->operationPemission,
- "delete" => $this->operationPemission
- );
- if (!array_key_exists($this->method, $check)) {
- goto End;
- }
-
- $funcName = "check_".$check[$this->method];
-
- if (!method_exists($this, $funcName)) {
- $res = false;
- goto End;
- }
-
- $res = $this->$funcName();
-
- End:
- if (!$res) {
- $this->SetError(PHOTOSTATION_SLIDESHOWMUSIC_ACCESS_DENY);
- }
- return $res;
- }
-
- private function check_admin()
- {
- csSYNOPhotoDB::GetDBInstance()->SetSessionCache();
- csSYNOPhotoMisc::CheckSessionTimeOut(true);
- return isset($_SESSION[SYNOPHOTO_ADMIN_USER]['admin_syno_user']);
- }
- }
- $api = new SlideshowMusicAPI();
- $api->Run();
-
- ?>
|