12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187 |
- <?PHP
-
- require_once('photo.inc.php');
- require_once('albumutil.php');
- require_once('photoutil.php');
-
- define("PHOTO_ACTION_TMP", '/tmp/photostation_');
- define("PHOTO_ACTION_MVCP_KEY", 'SYNOPS_MVCP');
- define("PHOTO_ACTION_DEL_KEY", 'SYNOPS_DEL');
-
- class PhotoAPI extends WebAPI
- {
- function __construct()
- {
- parent::__construct(SZ_WEBAPI_API_DESCRIPTION_PATH);
- }
-
- protected function Process()
- {
- if (isset($_REQUEST['public_share_id'])) {
- csSYNOPhotoDB::GetDBInstance()->SetPublicShareSessionCache($_REQUEST['public_share_id']);
- } else if (isset($_REQUEST['filter_public_share'])) {
- csSYNOPhotoDB::GetDBInstance()->SetPublicShareSessionCache($_REQUEST['filter_public_share']);
- }
-
- if (!strcasecmp($this->method, "list")) {
- $force = "true" === $_REQUEST['force_update'] ? true : false;
- csSYNOPhotoDB::GetDBInstance()->SetSessionCache($force);
- session_write_close();
- $this->ListItem();
- } else if (!strcasecmp($this->method, "listexif")) {
- session_write_close();
- $this->ListExif();
- } else if (!strcasecmp($this->method, "listfeatureditem")) {
- $force = "true" === $_REQUEST['force_update'] ? true : false;
- csSYNOPhotoDB::GetDBInstance()->SetSessionCache($force);
- session_write_close();
- $this->ListFeaturedItem();
- } else if (!strcasecmp($this->method, "listgpsgroup")) {
- session_write_close();
- $this->ListGPSGroup();
- } else if (!strcasecmp($this->method, "listgpsgroupeditem")) {
- session_write_close();
- $this->ListGPSGroupedItem();
- } else if (!strcasecmp($this->method, "getinfo")) {
- csSYNOPhotoDB::GetDBInstance()->SetSessionCache();
- session_write_close();
- $this->GetInfo();
- } else if (!strcasecmp($this->method, "getexif")) {
- session_write_close();
- $this->GetExif();
- } else {
- csSYNOPhotoDB::GetDBInstance()->SetSessionCache();
- csSYNOPhotoMisc::CheckSessionTimeOut(true);
-
- if (!strcasecmp($this->method, "edit")) {
- $this->Edit();
- }
- if (!strcasecmp($this->method, "delete")) {
- session_write_close();
- $this->DeleteItem();
- }
- if (!strcasecmp($this->method, "copy")) {
- csSYNOPhotoDB::GetDBInstance()->ExpireSessionCache();
- session_write_close();
- $this->CopyItem();
- }
- if (!strcasecmp($this->method, "cancel")) {
- session_write_close();
- $this->Cancel();
- }
- }
- }
-
- private function GetInfo()
- {
- $ret = false;
- $resp = array();
- /* return when lack of params */
- if (!isset($_REQUEST['id'])) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
-
- $publicShareId = NULL;
- if (isset($_REQUEST['public_share_id'])) {
- $publicShareId = $_REQUEST['public_share_id'];
- if (!SharedAlbum::CheckPublicSharePermission($publicShareId)) {
- $this->SetError(PHOTOSTATION_PHOTO_ACCESS_DENY);
- goto End;
- }
- $publicShareInfo = SharedAlbum::GetInfoByPublicShare($publicShareId);
- if (NULL === $publicShareInfo || 'valid' !== $publicShareInfo['share_status']) {
- $this->SetError(PHOTOSTATION_PHOTO_ACCESS_DENY);
- goto End;
- }
- }
-
- $additional = isset($_REQUEST['additional']) ? explode(',', $_REQUEST['additional']) : array();
- $ids = explode(',', $_REQUEST['id']);
- foreach ($ids as $id_str) {
- $id_arr = explode('_', $id_str);
- if (3 !== count($id_arr) || ('photo' !== $id_arr[0] && 'video' !== $id_arr[0])) {
- continue;
- }
- $albumName = @pack('H*', $id_arr[1]);
- $fileName = @pack('H*', $id_arr[2]);
- $path = SYNOPHOTO_SERVICE_REAL_DIR . "/" . ("/" === $albumName ? "" : $albumName . "/") . $fileName;
-
- if (!csSynoPhotoMisc::CheckPathValid($path)) {
- continue;
- }
-
- if (!csSYNOPhotoMisc::CheckAlbumAccessible($albumName, false, $publicShareId)) {
- continue;
- }
- $filePath = ('/' === $albumName ? "" : $albumName . "/") . $fileName;
- if (NULL !== $publicShareId && !SharedAlbum::CheckSharedAlbumItemValid($filePath, $id_arr[0], $publicShareId)) {
- continue;
- }
-
- if (@file_exists($path)) {
- if (false !== ($item = PhotoAPIUtil::getItemByPath($path, $additional, $id_arr[0], false))) {
- $resp[] = $item;
- }
- }
- }
- $ret = true;
- $this->SetResponse($resp);
- End:
- return $ret;
- }
-
- private function GetParams_ListItem()
- {
- global $SYNOPHOTO_ALLOW_SORT_TYPE;
-
- if (!isset($_REQUEST['offset']) || !isset($_REQUEST['limit']) || !isset($_REQUEST['type'])) {
- return false;
- }
- $params = array(
- 'offset' => $_REQUEST['offset'] + 0,
- 'limit' => $_REQUEST['limit'] + 0,
- 'type' => explode(',', $_REQUEST['type']),
- 'labelIds' => array()
- );
-
- foreach ($params['type'] as $_) {
- if (!in_array($_, array('photo', 'video'))) {
- return false;
- }
- }
-
- $options_params = array(
- // key => default value
- 'sort_by' => 'filename',
- 'sort_direction' => 'asc',
- 'filter_smart' => '',
- 'filter_tag' => '',
- 'filter_album' => '',
- 'filter_shared_album' => '',
- 'filter_public_share' => '',
- 'item_id' => '',
- 'additional' => array(),
- 'gps' => false
- );
-
- foreach ($options_params as $k => $v) {
- if (!isset($_REQUEST[$k])) {
- $params[$k] = $v;
- continue;
- }
- if ('sort_by' === $k) {
- if (in_array($_REQUEST[$k], $SYNOPHOTO_ALLOW_SORT_TYPE)) {
- $params[$k] = $_REQUEST[$k];
- } else {
- $params[$k] = 'filename';
- }
- } else if ('sort_direction' === $k) {
- $params[$k] = 'desc' === $_REQUEST[$k] ? 'desc' : 'asc';
- } else if ('additional' === $k) {
- $params[$k] = explode(',', $_REQUEST[$k]);
- } else if ('gps' === $k) {
- $params[$k] = 'true' === $_REQUEST[$k];
- } else if ('filter_tag' === $k) {
- $temps = explode(",", $_REQUEST['filter_tag']);
- $ids = array();
- foreach ($temps as $tagId) {
- if (SYNOPHOTO_UNCONFIRM_TAG_ID === $tagId) {
- $ids[] = SYNOPHOTO_UNCONFIRM_TAG_ID;
- } else {
- $arrs = explode("tag_", $tagId);
- $ids[] = $arrs[1] + 0;
- }
- }
- $params['labelIds'] = $ids;
- } else {
- $params[$k] = $_REQUEST[$k];
- }
- }
-
- // compatible with [time] [time1,time2] [time1,] [,time2]
- if (isset($_REQUEST['taken_date'])) {
- $taken_dates = explode(',' , trim($_REQUEST['taken_date']));
- if (1 === count($taken_dates)) {
- if ($taken_dates[0]) {
- $taken_date = date_create($taken_dates[0]);
- if ($taken_date) {
- $date_begin = $taken_date;
- }
- }
- $params['date_end'] = $params['date_begin'] = $date_begin->format('Y-m-d');
- } else {
- if ($taken_dates[0]) {
- $taken_date = date_create($taken_dates[0]);
- if ($taken_date) {
- $date_begin = $taken_date;
- }
- }
- if ($taken_dates[1]) {
- $taken_date_end = date_create($taken_dates[1]);
- if ($taken_date_end) {
- $date_end = $taken_date_end;
- }
- }
- if ($date_begin && $date_end) {
- if ($date_begin > $date_end) {
- list($params['date_begin'], $params['date_end']) = array($date_end->format('Y-m-d'), $date_begin->format('Y-m-d'));
- } else {
- list($params['date_begin'], $params['date_end']) = array($date_begin->format('Y-m-d'), $date_end->format('Y-m-d'));
- }
- } else if ($date_begin) {
- $params['date_begin'] = $date_begin->format('Y-m-d');
- } else if ($date_end) {
- $params['date_end'] = $date_end->format('Y-m-d');
- } else {
- return false;
- }
- }
- }
- return $params;
- }
-
- private function ListItem()
- {
- $ret = false;
- $resp = array();
- $items = array();
- /* return when lack of params */
- $params = $this->GetParams_ListItem();
- if (!$params) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
- $hasPhoto = in_array('photo', $params['type']);
- $hasVideo = in_array('video', $params['type']);
-
- // create the variable which name is the same as the key of params
- foreach ($params as $k => $v) {
- ${$k} = $v;
- }
-
- if ('' !== $filter_album) {
- $arr = explode('_', $filter_album);
- if ('album' !== $arr[0]) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
- $albumName = empty($arr[1]) ? '/' : @pack('H*', $arr[1]);
- $sharename = $albumName;
- /* users may have no access right to root album but can access layer one album
- * (Setting: Set photos and videos stored at the root folder of Photo Station as public)*/
- if ($albumName !== "/" && !csSYNOPhotoMisc::CheckAlbumAccessible($albumName)) {
- $this->SetError(PHOTOSTATION_PHOTO_ACCESS_DENY);
- goto End;
- }
- $albumPath = SYNOPHOTO_SERVICE_REAL_DIR . ("/" === $albumName ? "" : "/" . $albumName);
- if (false === csSynoPhotoMisc::CheckPathValid($albumPath)) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
-
- $personalAlbumPath = @pack('H*', $arr[1]);
- } else {
- $albumPath = SYNOPHOTO_SERVICE_REAL_DIR;
- $sharename = '/';
- $personalAlbumPath = '';
- }
-
- if ('root' !== SYNOPHOTO_ADMIN_USER) { //personal photo station
- if ('' !== $filter_album && '' !== $personalAlbumPath) {
- $escPath = "$personalAlbumPath/%";
- } else {
- $escPath = "$personalAlbumPath%";
- }
- } else {
- $escPath = "$albumPath/%";
- }
-
- $getRealPath = ('root' === SYNOPHOTO_ADMIN_USER) ? false : true;
-
- $total = 0;
- /* unconfirmed people tag */
- if ($hasPhoto && in_array(SYNOPHOTO_UNCONFIRM_TAG_ID, $params['labelIds'])) {
- $list = AlbumAPIUtil::GetUnConfirmItemList($limit, $offset);
- foreach ($list as $key => $value) {
- if (false !== ($item = PhotoAPIUtil::getItemByPath($key, $additional, 'photo', false))) {
- $items[] = $item;
- }
- }
- $total = intval($list['total']);
- } elseif ('' !== $filter_shared_album || '' !== $filter_public_share) {
- // check permission
- $publicShareId = '' !== $filter_public_share ? $filter_public_share : NULL;
- if (!SharedAlbum::CheckPublicSharePermission($publicShareId)) {
- $this->SetError(PHOTOSTATION_PHOTO_ACCESS_DENY);
- goto End;
- }
-
- $dbPath = NULL;
- $blSingleItem = false;
- if ('' !== $filter_shared_album) {
- // filter by shared album id, check userid in session own this shared album
- $id_arr = explode("_", $filter_shared_album);
- if (2 !== count($id_arr) || 'sharedalbum' != $id_arr[0]) {
- $this->SetError(PHOTOSTATION_SHARED_ALBUM_BAD_PARAMS);
- goto End;
- }
- if ($id_arr[1] === 'single') {
- $sharedAlbum = SharedAlbum::GetHiddenAlbumInfo();
- $blSingleItem = true;
- $id_arr[1] = explode("_", $sharedAlbum['id'])[1];
- } else {
- $sharedAlbum = SharedAlbum::GetInfoById($id_arr[1], array('public_share'));
- }
- if ($sharedAlbum === NULL) {
- $this->SetError(PHOTOSTATION_PHOTO_ACCESS_DENY);
- goto End;
- }
-
- $userid = isset($_SESSION[SYNOPHOTO_ADMIN_USER]['reg_syno_userid']) ? $_SESSION[SYNOPHOTO_ADMIN_USER]['reg_syno_userid'] : 0;
- $sharedAlbumId = $id_arr[1];
- $shareStatus = $sharedAlbum['additional']['public_share']['share_status'];
- // for generating public share url
- // equal to publicShareId, avoid GetAccessibleAlbumQueryConditionWithExcludeFormat use wrong session data
- $publicShareLink = $sharedAlbum['additional']['public_share']['shareid'];
- } else if ('' !== $filter_public_share) {
- // filter by public share link, check public share is existent and valid
- $publicShareInfo = SharedAlbum::GetInfoByPublicShare($publicShareId);
- if (NULL === $publicShareInfo || 'valid' !== $publicShareInfo['share_status']) {
- $this->SetError(PHOTOSTATION_PHOTO_ACCESS_DENY);
- goto End;
- }
- $sharedAlbumId = (int)$publicShareInfo['id'];
- $userid = (int)$publicShareInfo['userid'];
- $publicShareLink = $publicShareId;
- $shareStatus = $publicShareInfo['share_status'];
- if ('' !== $item_id) {
- $id_arr = explode("_", $item_id);
- $type = $id_arr[0];
- if (count($id_arr) !== 3 || ($type !== 'photo' && $type !== 'video')) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
- $albumName = @pack('H*', $id_arr[1]);
- $fileName = @pack('H*', $id_arr[2]);
- $filePath = ('/' === $albumName ? "" : $albumName . "/") . $fileName;
- $dbPath = SYNOPHOTO_SERVICE_REAL_DIR_PATH . $filePath;
- }
- }
-
- $albumCondition = csSYNOPhotoMisc::GetAccessibleAlbumQueryConditionWithExcludeFormat('A', $publicShareId);
- if (!$albumCondition['albumCond']) {
- $this->SetError(PHOTOSTATION_PHOTO_ACCESS_DENY);
- goto End;
- }
-
- $PublicSharePhotoTable = SHARED_ALBUM_PHOTO_TABLE_NAME;
- $PublicShareVideoTable = SHARED_ALBUM_VIDEO_TABLE_NAME;
- if (0 === $userid) {
- $PublicSharePhotoTable = SHARED_ALBUM_PHOTO_ADMIN_TABLE_NAME;
- $PublicShareVideoTable = SHARED_ALBUM_VIDEO_ADMIN_TABLE_NAME;
- }
-
- $sqlParam = array();
- $photoQuery = '';
- if ($hasPhoto) {
- $photoQuery = "SELECT A.path as path, A.name as filename, A.timetaken as takendate, A.create_time as createdate, 'photo' as type FROM photo_image A, $PublicSharePhotoTable B WHERE A.id = B.photoid AND B.collectionid = ?";
- $sqlParam[] = $sharedAlbumId;
- if ($dbPath !== NULL) {
- $photoQuery .= " AND A.path = ?";
- $sqlParam[] = $dbPath;
- }
-
- $photoQuery .= " AND {$albumCondition['albumCond']} ";
- $sqlParam = array_merge($sqlParam, $albumCondition['sqlParam']);
- }
-
- $videoQuery = '';
- if ($hasVideo) {
- $videoQuery = "SELECT A.path as path, A.title as filename, A.mdate as takendate, A.date as createdate, 'video' as type FROM video A, $PublicShareVideoTable B WHERE A.id = B.videoid AND B.collectionid = ?";
- $sqlParam[] = $sharedAlbumId;
- if ($dbPath !== NULL) {
- $videoQuery .= " AND A.path = ?";
- $sqlParam[] = $dbPath;
- }
- $videoQuery .= " AND {$albumCondition['albumCond']} ";
- $sqlParam = array_merge($sqlParam, $albumCondition['sqlParam']);
- }
-
- $limitOffsetString = PHOTO_DB_GetLimitOffsetString($limit, $offset);
-
- if ('' !== $photoQuery && '' !== $videoQuery) {
- $query = "$photoQuery UNION $videoQuery ORDER BY $sort_by $sort_direction $limitOffsetString";
- $queryCount = "SELECT COUNT(*) FROM ($photoQuery UNION $videoQuery) AS totalCount";
- } elseif ('' === $photoQuery) {
- $query = "$videoQuery ORDER BY $sort_by $sort_direction $limitOffsetString";
- $queryCount = "SELECT COUNT(*) FROM ($videoQuery) AS totalCount";
- } else {
- $query = "$photoQuery ORDER BY $sort_by $sort_direction $limitOffsetString";
- $queryCount = "SELECT COUNT(*) FROM ($photoQuery) AS totalCount";
- }
-
- $db_result = PHOTO_DB_Query($query, $sqlParam);
- $serverHost = csSYNOPhotoMisc::GetServerHost(true);
- while ($row = PHOTO_DB_FetchRow($db_result)) {
- if (false !== ($item = PhotoAPIUtil::getItemByPath($row['path'], $additional, $row['type'], $getRealPath))) {
- if ($shareStatus === 'valid') {
- $item['public_share_url'] = $serverHost . SYNOPHOTO_URL_PREFIX . '/photo/share/' . $publicShareLink . ($blSingleItem ? '/' : '#!List/') . $item['id'];
- }
- $items[] = File::FormatDBData($item);
- }
- }
- $db_result = PHOTO_DB_Query($queryCount, $sqlParam);
- $row = PHOTO_DB_FetchRow($db_result);
- $total = intval($row[0]);
- } elseif ('' === $filter_smart) {
- /* filter by albumname and tag */
- $itemObjs = File::ListItems($hasPhoto, $hasVideo, array(
- 'sharename' => $sharename,
- 'labels' => $params['labelIds'],
- 'date_begin' => $params['date_begin'],
- 'date_end' => $params['date_end'],
- 'gps' => $params['gps']
- ), $sort_by, $sort_direction, 0 > $limit ? NULL : $limit, $offset >= 0 ? $offset : NULL);
-
- $formularExtraParam = array(
- 'needThumbSize' => in_array('thumb_size', $params['additional']),
- 'param' => $params
- );
-
- $total = $itemObjs['total'];
- $items = array();
- foreach ($itemObjs['items'] as $obj) {
- if ('photo' === $obj['type']) {
- $items[] = Decorator::PhotoFormula($obj, $formularExtraParam);
- } else if ('video' === $obj['type']) {
- $items[] = Decorator::VideoFormula($obj, $formularExtraParam);
- }
- }
- } else {
- /* for smart album */
- $arr = explode('_', $filter_smart);
- if ('smart' !== $arr[0]) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
- $albumName = @pack('H*', $arr[1]);
- $data = array(
- "name" => $albumName,
- "offset" => $offset,
- "limit" => $limit,
- 'date_begin' => $params['date_begin'],
- 'date_end' => $params['date_end']
- );
- $smart = json_decode(SmartAlbum::GetSmartAlbumInstance()->ListItem(json_encode($data), $sort_by, $sort_direction), true);
- if (!$smart['success']) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
- $itemLists = $smart['data']['itemList'];
- $gpsTotal = 0;
-
- $idx = $offset;
- foreach ($itemLists as $row) {
- if (!in_array($row['type'], $params['type'])) {
- continue;
- }
-
- if (false !== ($item = PhotoAPIUtil::getItemByPath($row['path'], $additional, $row['type'], false))) {
- $item['pos'] = $idx++;
- if ($gps) {
- // special filter for map view
- if (null !== $item['additional']['photo_exif']['gps']) {
- $gpsTotal++;
- $items[] = $item;
- }
- } else {
- $items[] = $item;
- }
- }
- }
- $total = $gps ? $gpsTotal : $smart['data']['total'];
- }
-
- /* set return data */
- $resp['total'] = $total;
- $resp['offset'] = (-1 == $limit || $offset + $limit > $total) ? $total : $offset + $limit;
- $resp['items'] = $items;
- $this->SetResponse($resp);
- $ret = true;
- End:
- return $ret;
- }
-
- private function GetParams_ListFeaturedItem ()
- {
- $params = array();
-
- if (!isset($_REQUEST['taken_date']) || !isset($_REQUEST['count'])) {
- return false;
- }
- if (!isset($_REQUEST['filter_smart']) && !isset($_REQUEST['filter_album']) && !isset($_REQUEST['filter_tag'])) {
- return false;
- }
-
- $listType = false;
- if (isset($_REQUEST['filter_album'])) {
- if ($_REQUEST['filter_album']) {
- $sharename = $this->DecodeItemId($_REQUEST['filter_album'], "album_");
- } else {
- $sharename = "/";
- }
- if (!$sharename) {
- return false;
- }
- $params['sharename'] = $sharename;
- $listType = "album";
- } else if (isset($_REQUEST['filter_tag'])) {
- $temps = explode(",", $_REQUEST['filter_tag']);
- $ids = array();
- foreach ($temps as $tagId) {
- if (SYNOPHOTO_UNCONFIRM_TAG_ID === $tagId) {
- $ids[] = SYNOPHOTO_UNCONFIRM_TAG_ID;
- } else {
- $arrs = explode("tag_", $tagId);
- $ids[] = $arrs[1] + 0;
- }
- }
- $params['labelIds'] = $ids;
- $listType = "label";
- } else if (isset($_REQUEST['filter_smart'])) {
- $smart = $this->DecodeItemId($_REQUEST['filter_smart'], "smart_");
- $params['smart'] = $smart;
- $listType = "smart";
- }
-
- if (false === $listType) {
- return false;
- }
- $params['listType'] = $listType;
-
- // compatible with [time] [time1,time2] [time1,] [,time2]
- $taken_dates = explode(',' , trim($_REQUEST['taken_date']));
- if (1 === count($taken_dates)) {
- if ($taken_dates[0]) {
- $taken_date = date_create($taken_dates[0]);
- if ($taken_date) {
- $date_begin = $taken_date;
- }
- }
- $params['date_end'] = $params['date_begin'] = $date_begin->format('Y-m-d');
- } else {
- if ($taken_dates[0]) {
- $taken_date = date_create($taken_dates[0]);
- if ($taken_date) {
- $date_begin = $taken_date;
- }
- }
- if ($taken_dates[1]) {
- $taken_date_end = date_create($taken_dates[1]);
- if ($taken_date_end) {
- $date_end = $taken_date_end;
- }
- }
- if ($date_begin && $date_end) {
- if ($date_begin > $date_end) {
- list($params['date_begin'], $params['date_end']) = array($date_end->format('Y-m-d'), $date_begin->format('Y-m-d'));
- } else {
- list($params['date_begin'], $params['date_end']) = array($date_begin->format('Y-m-d'), $date_end->format('Y-m-d'));
- }
- } else if ($date_begin) {
- $params['date_begin'] = $date_begin->format('Y-m-d');
- } else if ($date_end) {
- $params['date_end'] = $date_end->format('Y-m-d');
- } else {
- return false;
- }
- }
-
- // count = -1 means all
- $params['count'] = $_REQUEST['count'] + 0;
- $params['type'] = explode(',', $_REQUEST['type']);
- $params['additional'] = explode(',', $_REQUEST['additional']);
-
- return $params;
- }
-
- private function ListFeaturedItem ()
- {
- $resp = array();
- $items = array();
- /* return when lack of params */
- $params = $this->GetParams_ListFeaturedItem();
- if (!$params) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
-
- if ("album" === $params['listType']) {
- $itemObjs = File::ListFeatured($params['date_begin'], $params['date_end'], $params['sharename'], $params['count'], array(),
- in_array('photo', $params['type']), in_array('video', $params['type']));
-
- } else if ("label" === $params["listType"]) {
- $itemObjs = File::ListFeatured($params['date_begin'], $params['date_end'], '/', $params['count'], $params['labelIds'],
- in_array('photo', $params['type']), in_array('video', $params['type']));
-
- } else if ("smart" === $params["listType"]) {
- $smart = json_decode(SmartAlbum::GetSmartAlbumInstance()->ListItem(json_encode(array(
- 'name' => $params['smart'],
- 'offset' => 0,
- 'limit' => -1,
- 'date_begin' => $params['date_begin'],
- 'date_end' => $params['date_end']
- )), 'takendate', 'asc'), true);
- if (!$smart['success']) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
- $data = SmartAlbum::FilterFeatured($smart['data']['itemList'], $smart['data']['total'], $params['count']);
- $itemObjs = array(
- 'items' => $data,
- 'total' => $smart['data']['total']
- );
- }
-
- $formularExtraParam = array(
- 'needThumbSize' => in_array('thumb_size', $params['additional']),
- 'param' => $params
- );
- foreach ($itemObjs['items'] as $obj) {
- if ('photo' === $obj['type']) {
- $items[] = Decorator::PhotoFormula($obj, $formularExtraParam);
- } else if ('video' === $obj['type']) {
- $items[] = Decorator::VideoFormula($obj, $formularExtraParam);
- }
- }
-
- $resp['total'] = $itemObjs['total'];
- $resp['items'] = $items;
- $this->SetResponse($resp);
- End:
- return;
- }
- private function GetParams_ListGPSGroup()
- {
- $params = array();
-
- if (!isset($_REQUEST['filter_smart']) && !isset($_REQUEST['filter_album']) && !isset($_REQUEST['filter_tag'])) {
- return false;
- }
-
- $listType = false;
- if (isset($_REQUEST['filter_album'])) {
- if ($_REQUEST['filter_album']) {
- $sharename = $this->DecodeItemId($_REQUEST['filter_album'], "album_");
- } else {
- $sharename = "/";
- }
- if (!$sharename) {
- return false;
- }
- $params['sharename'] = $sharename;
- $listType = "album";
- } else if (isset($_REQUEST['filter_tag'])) {
- $temps = explode(",", $_REQUEST['filter_tag']);
- $ids = array();
- foreach ($temps as $tagId) {
- if (SYNOPHOTO_UNCONFIRM_TAG_ID === $tagId) {
- $ids[] = SYNOPHOTO_UNCONFIRM_TAG_ID;
- } else {
- $arrs = explode("tag_", $tagId);
- $ids[] = $arrs[1] + 0;
- }
- }
- $params['labelIds'] = $ids;
- $listType = "label";
- } else if (isset($_REQUEST['filter_smart'])) {
- $smart = $this->DecodeItemId($_REQUEST['filter_smart'], "smart_");
- $params['smart'] = $smart;
- $listType = "smart";
- }
- $params['listType'] = $listType;
-
- if ($_REQUEST['bounds']) {
- $bounds = json_decode($_REQUEST['bounds'], true);
- $params['bounds'] = array(
- 'sw' => array(
- 'lat' => $bounds['sw']['lat'] + 0,
- 'lng' => $bounds['sw']['lng'] + 0
- ),
- 'ne' => array(
- 'lat' => $bounds['ne']['lat'] + 0,
- 'lng' => $bounds['ne']['lng'] + 0
- )
- );
- }
- if ($_REQUEST['gps_idx']) {
- $params['gps_idx'] = json_decode($_REQUEST['gps_idx'], true);
- if (null === $params['gps_idx']['lat'] || null === $params['gps_idx']['lng']) {
- return false;
- }
- }
-
- if ($_REQUEST['limit']) {
- $params['limit'] = $_REQUEST['limit'] + 0;
- }
- if ($_REQUEST['offset']) {
- $params['offset'] = $_REQUEST['offset'] + 0;
- }
-
- $params['zoom'] = $_REQUEST['zoom'] ? (int)$_REQUEST['zoom'] : 5;
- $params['type'] = explode(',', $_REQUEST['type']);
- $params['additional'] = explode(',', $_REQUEST['additional']);
-
- return $params;
- }
-
- private function ListGPSGroup ()
- {
- $resp = array();
- $items = array();
- /* return when lack of params */
- $params = $this->GetParams_ListGPSGroup();
- if (!$params) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
-
- if ("album" === $params['listType']) {
- $itemObjs = File::ListGPSGroup($params['sharename'], array(), $params['bounds'], $params['zoom'], in_array('photo', $params['type']), false);
-
- } else if ("label" === $params["listType"]) {
- $itemObjs = File::ListGPSGroup('/', $params['labelIds'], $params['bounds'], $params['zoom'], in_array('photo', $params['type']), false);
-
- } else if ("smart" === $params["listType"]) {
- $itemObjs = SmartAlbum::GetSmartAlbumInstance()->ListGPSGroup($params['smart'], $params['bounds'], $params['zoom']);
- }
-
- $formularExtraParam = array(
- 'needThumbSize' => in_array('thumb_size', $params['additional']),
- 'param' => $params
- );
- $output = array();
- foreach ($itemObjs['groups'] as $group) {
- $item = Decorator::PhotoFormula($group['item'], $formularExtraParam);
- $groupItem = array(
- 'count' => $group['count'],
- 'item' => $item,
- 'gps_idx' => $group['gps_idx']
- );
- $output[] = $groupItem;
- }
-
- $resp['total'] = $itemObjs['total'];
- $resp['items'] = $output;
- $this->SetResponse($resp);
- End:
- return;
- }
-
- private function ListGPSGroupedItem ()
- {
- $params = $this->GetParams_ListGPSGroup();
- if (!$params) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
- if ("album" === $params['listType']) {
- $itemObjs = File::ListGPSGroupedItems($params['sharename'], array(), $params['gps_idx'], $params['zoom'], $params['limit'], $params['offset']);
-
- } else if ("label" === $params["listType"]) {
- $itemObjs = File::ListGPSGroupedItems('/', $params['labelIds'], $params['gps_idx'], $params['zoom'], $params['limit'], $params['offset']);
-
- } else if ("smart" === $params["listType"]) {
- $itemObjs = SmartAlbum::GetSmartAlbumInstance()->ListGPSGroupedItem($params['smart'], $params['gps_idx'], $params['zoom'], $params['limit'], $params['offset']);
- }
- $formularExtraParam = array(
- 'needThumbSize' => in_array('thumb_size', $params['additional']),
- 'param' => $params
- );
- $output = array();
- foreach ($itemObjs['items'] as $item) {
- $item = Decorator::PhotoFormula($item, $formularExtraParam);
- $output[] = $item;
- }
-
- $resp['total'] = $itemObjs['total'];
- $resp['items'] = $output;
- $this->SetResponse($resp);
- End:
- return;
- }
-
- private function ListExif()
- {
- $resp = array();
- if (!isset($_REQUEST['type'])) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
- $map = array(
- "focal_length" => "focal_length_v2",
- "flash" => "flash_v2",
- "lens" => "lens_v2"
- );
- $column = $type = $_REQUEST['type'];
-
- if (array_key_exists($type, $map)) {
- $column = $map[$type];
- }
-
- $results = csSYNOPhotoDB::GetDBInstance()->getExifList($column);
- if (false === $results) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
-
- $items = array();
- foreach ($results as $result) {
- if ('flash' === $type) {
- $item['id'] = $type.'_'.str_replace(',', '#', $result);
- } else {
- $item['id'] = $type.'_'.$result;
- }
- $item['name'] = $result;
- $item['type'] = 'exif';
- $item['tag_type'] = $type;
- $items[] = $item;
- }
-
- $resp['total'] = count($results);
- $resp['tags'] = $items;
- $this->SetResponse($resp);
-
- End:
- return;
- }
-
- private function GetExif()
- {
- $resp = array();
- if (!isset($_REQUEST['id'])) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
- $id_arr = explode('_', $_REQUEST['id']);
- if ('photo' !== $id_arr[0]) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
- $albumName = @pack('H*', $id_arr[1]);
- $fileName = @pack('H*', $id_arr[2]);
- $path = SYNOPHOTO_SERVICE_REAL_DIR . "/" . ("/" === $albumName ? "" : $albumName . "/") . $fileName;
- if (!csSynoPhotoMisc::CheckPathValid($path)) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
-
- $command = "/usr/syno/bin/exiv2 -pa " . escapeshellarg($path);
- $commandTagLabel = "/usr/syno/bin/exiv2 -Pl " . escapeshellarg($path);
- @exec($command, $outputs, $retval);
- @exec($commandTagLabel, $outputsTagLabel, $retvalTagLabel);
- $tagLableCount = count($outputsTagLabel);
- $items = array();
- foreach ($outputs as $i => $output) {
- unset($item);
- $nonEmptyString = 0;
- $data = explode(" ", $output);
- $item['label'] = ($tagLableCount > $i) ? $outputsTagLabel[$i] : 'Unknown';
- foreach ($data as $datum) {
- if("" !== $datum) {
- if (3 <= $nonEmptyString) {
- //Last is the value of the tag
- $item['value'] = ($item['value']) ? $item['value'] . " " . $datum : $datum;
- }
- $nonEmptyString ++;
- }
- //check utf-8
- $value = iconv('UTF-8', 'UTF-8//IGNORE', $item['value']);
- $item['value'] = ($value) ? $value : '';
- }
- $items[] = $item;
- }
-
- $resp = array();
- $resp['total'] = count($items);
- $resp['exifs'] = $items;
- $this->SetResponse($resp);
- End:
- return;
- }
-
- private function Edit()
- {
- $ret = false;
- $resp = array();
- /* return when lack of params */
- if (!isset($_REQUEST['id'])) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
-
- /* set optional params */
- $title = isset($_REQUEST['title']) ? $_REQUEST['title'] : '';
- $description = isset($_REQUEST['description']) ? $_REQUEST['description'] : '';
-
- /* update records */
- $ids = explode(',', $_REQUEST['id']);
- foreach ($ids as $idStr) {
- self::OutputSingleSpace();
- $id_arr = explode('_', $idStr);
- $albumName = @pack('H*', $id_arr[1]);
- $fileName = @pack('H*', $id_arr[2]);
- $path = SYNOPHOTO_SERVICE_REAL_DIR . "/" . ("/" === $albumName ? "" : $albumName . "/") . $fileName;
-
- if (!csSynoPhotoMisc::CheckPathValid($path)) {
- continue;
- }
-
- if (!csSYNOPhotoMisc::CheckAlbumManageable($albumName)) {
- continue;
- }
- if (isset($_REQUEST['title']) || isset($_REQUEST['description'])) {
- $dbPath = $this->GetDbPath($path);
- if ('photo' === $id_arr[0]) {
- $require_update = false;
- $query = "UPDATE photo_image SET ";
- $queryParam = array();
- if (isset($_REQUEST['title'])) {
- $query .= "title = ? ";
- $queryParam[] = $_REQUEST['title'];
- $require_update = true;
- }
- if (isset($_REQUEST['description'])) {
- if ($require_update) {
- $query .= ", ";
- }
- $query .= "description = ? ";
- $queryParam[] = $_REQUEST['description'];
- $require_update = true;
-
- $description = str_replace('"', '\"', $_REQUEST['description']);
-
- File::UpdateDescriptionMetadata($path, $description);
- }
- $query .= "WHERE path = ?";
- $queryParam[] = $dbPath;
- PHOTO_DB_Query($query, $queryParam);
- } elseif ('video' === $id_arr[0]) {
- $require_update = false;
- $query = "UPDATE video_desc SET ";
- $queryParam = array();
- if (isset($_REQUEST['title'])) {
- $query .= "title = ? ";
- $queryParam[] = $_REQUEST['title'];
- $require_update = true;
- }
- if (isset($_REQUEST['description'])) {
- if ($require_update) {
- $query .= ", ";
- }
- $query .= "description = ? ";
- $queryParam[] = $_REQUEST['description'];
- }
- $query .= "WHERE path = ?";
- $queryParam[] = $dbPath;
-
- $db_result = PHOTO_DB_Query($query, $queryParam);
- if (false === ($row = PHOTO_DB_FetchRow($db_result))) {
- $query = "INSERT INTO video_desc (path, title, description) VALUES (?, ?, ?)";
- $sqlParam = array($dbPath, $title, $description);
- PHOTO_DB_Query($query, $sqlParam);
- }
- }
- }
- if (isset($_REQUEST['gps_lat']) && isset($_REQUEST['gps_lng'])) {
- if (is_numeric($_REQUEST['gps_lat']) && is_numeric($_REQUEST['gps_lng'])) {
- SYNOPHOTO_GPS_UTIL_SetGPSLatLng($path, $_REQUEST['gps_lat'], $_REQUEST['gps_lng']);
- }
- }
- }
- $ret = true;
- End:
- return $ret;
- }
-
- private function DeleteItem()
- {
- $ret = false;
- /* return when lack of params */
- if (!isset($_REQUEST['id'])) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
-
- $cancelPath = PHOTO_ACTION_TMP.md5(PHOTO_ACTION_DEL_KEY.$_REQUEST['id']);
- /* delete records */
- $ids = explode(',', $_REQUEST['id']);
- foreach ($ids as $idStr) {
- self::OutputSingleSpace();
- if (file_exists($cancelPath)) {
- @unlink($cancelPath);
- break;
- }
-
- $id_arr = explode('_', $idStr);
- $albumName = trim(@pack('H*', $id_arr[1]));
- $fileName = trim(@pack('H*', $id_arr[2]));
-
- if (!$albumName || !$fileName || $fileName == '/') {
- continue;
- }
-
- if (!csSYNOPhotoMisc::CheckAlbumManageable($albumName)) {
- continue;
- }
- $path = SYNOPHOTO_SERVICE_REAL_DIR . "/" . ("/" === $albumName ? "" : $albumName . "/") . $fileName;
- if (!csSynoPhotoMisc::CheckPathValid($path)) {
- continue;
- }
- $isPhoto = 'photo' === $id_arr[0] ? true : false;
- SYNOPHOTO_ADMIN_DeleteItemByPath($path, $isPhoto);
- SYNOPHOTO_LABEL_UTIL_Check_Photo_Label();
- PhotoLog::Add("File [".$fileName."] was deleted from album [".$albumName."].", true, strtolower(GetLoginUsername()));
-
- }
-
- $ret = true;
- End:
- return $ret;
- }
-
- private function CopyItem()
- {
- $ret = false;
- $resp = array();
- /* return when lack of params */
- if (!isset($_REQUEST['id']) || !isset($_REQUEST['sharepath']) || !isset($_REQUEST['mode']) || !isset($_REQUEST['duplicate'])) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
-
- /* set params */
- if (preg_match('/^album_/', $_REQUEST['sharepath'])) {
- $ids = explode('_', $_REQUEST['sharepath']);
- $destShareName = @pack('H*', $ids[1]);
- } else {
- $destShareName = @pack('H*', $_REQUEST['sharepath']);
- }
- $destPath = SYNOPHOTO_SERVICE_REAL_DIR . "/" . $destShareName;
- if (!csSynoPhotoMisc::CheckPathValid($destPath)) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
- $mode = $_REQUEST['mode'];
- if ('copy' !== $mode && 'move' !== $mode) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
-
- if (!csSYNOPhotoMisc::CheckAlbumUploadable('' == $destShareName ? '/' : $destShareName)) {
- $this->SetError(PHOTOSTATION_PHOTO_ACCESS_DENY);
- goto End;
- }
- $dirpath = $destShareName ? $destShareName : '/';
-
- $ids = explode(',', $_REQUEST['id']);
- $items = array();
- foreach ($ids as $idStr) {
- $id_arr = explode('_', $idStr);
- $albumName = @pack('H*', $id_arr[1]);
- $fileName = @pack('H*', $id_arr[2]);
- if ($albumName === $dirpath) {
- $this->SetError(PHOTOSTATION_PHOTO_SELECT_CONFLICT);
- goto End;
- }
- $item = array(
- 'albumName' => $albumName,
- 'fileName' => $fileName,
- 'type' => $id_arr[0]
- );
- $items[] = $item;
- }
-
- $dup = 'rename' === $_REQUEST['duplicate'] ? 2 : ('ignore' === $_REQUEST['duplicate'] ? 0 : 1);
-
- $cancelPath = PHOTO_ACTION_TMP.md5(PHOTO_ACTION_MVCP_KEY.$_REQUEST['id']);
- foreach($items as $item) {
- self::OutputSingleSpace();
- if (file_exists($cancelPath)) {
- @unlink($cancelPath);
- break;
- }
-
- $path = SYNOPHOTO_SERVICE_REAL_DIR . "/" . ("/" === $item['albumName'] ? "" : $item['albumName'] . "/") . $item['fileName'];
- if (!csSynoPhotoMisc::CheckPathValid($path)) {
- continue;
- }
-
- if (!csSYNOPhotoMisc::CheckAlbumManageable($item['albumName'])) {
- continue;
- }
-
- $dbPath = $this->GetDbPath($path);
- /* get item id first */
- if ('photo' === $item['type']) {
- $query = "SELECT id FROM photo_image WHERE path = ?";
- } elseif ('video' === $item['type']) {
- $query = "SELECT id FROM video WHERE path = ?";
- }
- $db_result = PHOTO_DB_Query($query, array($dbPath));
- if ($row = PHOTO_DB_FetchRow($db_result)) {
- $id = $row['id'];
- if ('copy' === $mode) {
- if ('photo' === $item['type']) {
- SYNOPHOTO_ADMIN_CopyOnePhoto($destShareName, $id, $dup);
- @exec("/usr/syno/bin/synomkthumb -a " . escapeshellarg($destPath));
- } elseif ('video' === $item['type']) {
- SYNOPHOTO_ADMIN_CopyOneVideo($destShareName, $id, $dup);
- }
- } elseif ('move' === $mode) {
- if ('photo' === $item['type']) {
- SYNOPHOTO_ADMIN_MoveOnePhoto($destShareName, $id, $dup);
- @exec("/usr/syno/bin/synomkthumb -a " . escapeshellarg($destPath));
- } elseif ('video' === $item['type']) {
- SYNOPHOTO_ADMIN_MoveOneVideo($destShareName, $id, $dup);
- }
- }
- }
- }
-
- $ret = true;
- End:
- return $ret;
- }
-
- private function Cancel()
- {
- $ret = false;
- $resp = array();
- /* return when lack of params */
- if (!isset($_REQUEST['id']) || !isset($_REQUEST['action'])) {
- $this->SetError(PHOTOSTATION_PHOTO_BAD_PARAMS);
- goto End;
- }
-
- if ('mvcp' === $_REQUEST['action']) {
- $key = PHOTO_ACTION_MVCP_KEY;
- } else if ('delete' === $_REQUEST['action']) {
- $key = PHOTO_ACTION_DEL_KEY;
- }
- $filePath = PHOTO_ACTION_TMP.md5($key.$_REQUEST['id']);
- @file_put_contents($filePath, "");
- $ret = true;
- End:
- return $ret;
- }
-
- private function GetDbPath($path)
- {
- return substr($path, strlen(SYNOPHOTO_SERVICE_REAL_DIR_PREFIX));
- }
- }
-
- $api = new PhotoAPI();
- $api->Run();
|