method, "list")) { $this->TagList(); } elseif (!strcasecmp($this->method, "getinfo")) { $this->GetInfo(); } else { csSYNOPhotoMisc::CheckSessionTimeOut(true); if (!strcasecmp($this->method, "create")) { $this->Create(); } else if (!strcasecmp($this->method, "searchplace")) { $this->SearchPlace(); } else { csSYNOPhotoMisc::CheckSessionTimeOut(); if (!strcasecmp($this->method, "edit")) { $this->Edit(); } elseif (!strcasecmp($this->method, "delete")) { $this->Delete(); } elseif (!strcasecmp($this->method, "delete_unconfirmed_tag")) { $this->DeleteUnconfirmedTag(); } } } } private function GetParams_SearchPlace() { if (!isset($_REQUEST['query']) || !isset($_REQUEST['location'])) { return false; } $params = array(); $params['query'] = $_REQUEST['query']; $params['location'] = $_REQUEST['location']; $params['radius'] = (isset($_REQUEST['radius'])) ? $_REQUEST['radius'] : '500'; $params['format'] = $_REQUEST['format'] === 'true'; return $params; } private function GetParams_Edit() { if (!isset($_REQUEST['id']) || !isset($_REQUEST['name'])) { return false; } $arr = explode('tag_', $_REQUEST['id']); if (2 !== count($arr)) { return false; } $params['id'] = (int) $arr[1]; $params['name'] = $_REQUEST['name']; // for geo tag $params['place_id'] = (isset($_REQUEST['place_id'])) ? $_REQUEST['place_id'] : null; $params['reference'] = (isset($_REQUEST['reference'])) ? $_REQUEST['reference'] : null; $params['lat'] = (isset($_REQUEST['lat'])) ? $_REQUEST['lat'] : null; $params['lng'] = (isset($_REQUEST['lng'])) ? $_REQUEST['lng'] : null; $params['address'] = (isset($_REQUEST['address'])) ? $_REQUEST['address'] : null; return $params; } private function GetParams_Create() { if (!isset($_REQUEST['name']) || !isset($_REQUEST['type'])) { return false; } $params['name'] = $_REQUEST['name']; $params['type'] = $_REQUEST['type']; if (!in_array($params['type'], array('people', 'geo', 'desc'))) { return false; } // for geo tag if ('geo' === $params['type']) { $params['place_id'] = (isset($_REQUEST['place_id'])) ? $_REQUEST['place_id'] : null; $params['reference'] = (isset($_REQUEST['reference'])) ? $_REQUEST['reference'] : null; $params['lat'] = (isset($_REQUEST['lat'])) ? $_REQUEST['lat'] : null; $params['lng'] = (isset($_REQUEST['lng'])) ? $_REQUEST['lng'] : null; $params['address'] = (isset($_REQUEST['address'])) ? $_REQUEST['address'] : null; } return $params; } private function GetParams_Info() { if (!isset($_REQUEST['id'])) { return false; } $params['id'] = array(); $arr = explode(',', $_REQUEST['id']); foreach ($arr as $item) { $split = explode('tag_', $item); if (2 !== count($split)) { return false; } $params['id'][] = (int) $split[1]; } $params['thumbnail_status'] = isset($_REQUEST['thumbnail_status']) ? $_REQUEST['thumbnail_status'] : 'false'; if (!in_array($params['thumbnail_status'], array('true', 'false'))) { return false; } $params['additional'] = explode(',', $_REQUEST['additional']); return $params; } private function GetParams_List() { if (!isset($_REQUEST['offset']) || !isset($_REQUEST['limit']) || !isset($_REQUEST['type'])) { return false; } if (!is_numeric($_REQUEST['offset']) || !is_numeric($_REQUEST['limit'])) { return false; } $params['offset'] = (int)$_REQUEST['offset']; $params['limit'] = (int)$_REQUEST['limit']; $params['type'] = explode(',', $_REQUEST['type']); foreach ($params['type'] as $type) { if (!in_array($type, array('people', 'geo', 'desc'))) { return false; } } $params['thumbnail_status'] = isset($_REQUEST['thumbnail_status']) ? $_REQUEST['thumbnail_status'] : 'false'; if (!in_array($params['thumbnail_status'], array('true', 'false'))) { return false; } $params['sort_by'] = (isset($_REQUEST['sort_by'])) ? $_REQUEST['sort_by'] : 'title'; if ((null !== $params['sort_by']) && !in_array($params['sort_by'], array('title'))) { return false; } $params['sort_direction'] = (isset($_REQUEST['sort_direction'])) ? $_REQUEST['sort_direction'] : 'asc'; if ((null !== $params['sort_direction']) && !in_array($params['sort_direction'], array('asc', 'desc'))) { return false; } $params['unconfirm_people_tag'] = isset($_REQUEST['unconfirm_people_tag']) ? $_REQUEST['unconfirm_people_tag'] : 'false'; if (!in_array($params['unconfirm_people_tag'], array('true', 'false'))) { return false; } $params['additional'] = explode(',', $_REQUEST['additional']); return $params; } private function CategoryNameToNum($name) { if (!isset($name)) { return false; } switch ($name) { case 'people': $codeNum = Label::PEOPLE; break; case 'geo': $codeNum = Label::GEO; break; case 'desc': $codeNum = Label::DESC; break; default: return false; break; } return $codeNum; } private function FormListTags($data, $params) { $extraConfig = array( 'needThumbSize' => in_array('thumb_size', $params['additional']), 'param' => $params ); $tags = array(); foreach ($data as $key => $value) { // 0 - people tag; 1 - geo tag; 2 - desc tag if (Label::PEOPLE === $key && !in_array('people', $params['type'])) { continue; } if (Label::GEO === $key && !in_array('geo', $params['type'])) { continue; } if (Label::DESC === $key && !in_array('desc', $params['type'])) { continue; } foreach ($data[$key] as $item) { $tag = Decorator::TagFormula($item, $extraConfig); $tags[] = $tag; } } return $tags; } private function FormInfoTags($data, $params) { $tags = array(); $extraConfig = array( 'needThumbSize' => in_array('thumb_size', $params['additional']), 'param' => $params ); foreach ($data as $item) { $tag = Decorator::TagFormula($item, $extraConfig); $tags[] = $tag; } return $tags; } private function AddUnConfirmTag($list, $params, &$tags) { $needThumbSize = in_array('thumb_size', $params['additional']); $arr = array(); $unConfirmTag['id'] = SYNOPHOTO_UNCONFIRM_TAG_ID; $unConfirmTag['type'] = 'tag'; $unConfirmTag['tag_type'] = 'people'; $unConfirmTag['name'] = ''; $coverPath = ''; if (is_array($list)) { $pathList = array_keys($list); $coverPath = $pathList[0]; } $blConversion = csSYNOPhotoMisc::IsAlbumAllowConversion(dirname($coverPath)); list($orig_resolutionx, $orig_resolutiony, $blThumbRotated) = AlbumAPIUtil::GetCoverResolutionRotation($coverPath); AlbumAPIUtil::FillThumbStatus($unConfirmTag, $coverPath, $needThumbSize, $orig_resolutionx, $orig_resolutiony, $blThumbRotated, $blConversion); array_push($arr, $unConfirmTag); array_splice($tags, 0, 0, $arr); } private function SortTags($sortBy, $sortDirection, &$sortTags) { if ('title' === $sortBy) { if ('asc' === $sortDirection) { return; } else { $sortTags = array_reverse($sortTags); } } } private function TagList() { if (false === ($params = $this->GetParams_List())) { $this->SetError(WEBAPI_ERR_BAD_REQUEST); goto End; } // get category type number - people(0), geo(1), desc(2) $types = array(); foreach ($params['type'] as $type) { if (false === ($num = $this->CategoryNameToNum($type))) { $this->SetError(WEBAPI_ERR_BAD_REQUEST); goto End; } array_push($types, $num); } // database query $result = Label::GetByCategoryPermission($types, isset($_SESSION[SYNOPHOTO_ADMIN_USER]['admin_syno_user'])); $totalTags = $this->FormListTags($result, $params); // sorting $this->SortTags($params['sort_by'], $params['sort_direction'], $totalTags); // add people unconfirm tag if (in_array('people', $params['type']) && 'true' === $params['unconfirm_people_tag']) { $list = AlbumAPIUtil::GetUnConfirmItemList(); if (0 < (int)$list['total']) { $this->AddUnConfirmTag($list, $params, $totalTags); } } $total = count($totalTags); // set offset and limit if (0 > $params['limit']) { $tags = array_slice($totalTags, $params['offset']); } else { $tags = array_slice($totalTags, $params['offset'], $params['limit']); } $resp['total'] = (int)$total; $offset = (0 > $params['limit']) ? $resp['total'] : $params['offset'] + $params['limit']; $resp['offset'] = ($offset > $total) ? (int)$total : (int)$offset; $resp['tags'] = $tags; $this->SetResponse($resp); End: return; } private function GetInfo() { if (false === ($params = $this->GetParams_Info())) { $this->SetError(WEBAPI_ERR_BAD_REQUEST); goto End; } // database query if (false === ($result = Label::GetByIds($params['id']))) { $this->SetError(PHOTOSTATION_TAG_GETINFO_FAIL); goto End; } // form to webapi format $tags = $this->FormInfoTags($result, $params); $resp['tags'] = $tags; $this->SetResponse($resp); End: return; } private function Create() { if (false === ($params = $this->GetParams_Create())) { $this->SetError(WEBAPI_ERR_BAD_REQUEST); goto End; } // add label parameter $label['name'] = $params['name']; $label['category'] = $this->CategoryNameToNum($params['type']); $label['info'] = ''; if ('geo' === $params['type']) { $info['placeId'] = ''; if (null !== $params['place_id']) { $info['placeId'] = $params['place_id']; } if (null !== $params['reference']) { $info['reference'] = $params['reference']; } if (null !== $params['lat']) { $info['lat'] = $params['lat']; } if (null !== $params['lng']) { $info['lng'] = $params['lng']; } if (null !== $params['address']) { $info['address'] = $params['address']; } if (!empty($info)) { $json = json_encode($info); $label['info'] = $json; } } $blCreateNewTag = false; if ('geo' === $params['type']) { // (name, place_id) as primary key in geo tag if (false === ($row = Label::GetGeoLabelByNamePlaceId($label['name'], $info['placeId']))) { $blCreateNewTag = true; } } elseif ('people' === $params['type'] || 'desc' === $params['type']) { // (name, category) as primary key in people, desc tag if (false === ($row = Label::GetByNameCategory($label['name'], $label['category']))) { $blCreateNewTag = true; } } if ($blCreateNewTag) { // database query if (false === ($lastinsertId = Label::Add($label['name'], $label['category'], $label['info']))) { $this->SetError(PHOTOSTATION_TAG_CREATE_FAIL); goto End; } $row = array('id' => $lastinsertId); } $resp['id'] = 'tag_'.$row['id']; $this->SetResponse($resp); End: return; } private function Edit() { if (false === ($params = $this->GetParams_Edit())) { $this->SetError(WEBAPI_ERR_BAD_REQUEST); goto End; } // get original label $id = $params['id']; if (false === ($label_objs = Label::GetByIds(array($id)))) { $this->SetError(PHOTOSTATION_TAG_EDIT_FAIL); goto End; } $result = $label_objs[$id]; $origLabel = json_decode($result['info'], true); $type = $result['category']; // add label parameter $label['info'] = ''; if (Label::GEO === $type) { $info['placeId'] = (null !== $params['place_id']) ? $params['place_id'] : $origLabel['placeId']; $info['reference'] = (null !== $params['reference']) ? $params['reference'] : $origLabel['reference']; $info['lat'] = (null !== $params['lat']) ? $params['lat'] : $origLabel['lat']; $info['lng'] = (null !== $params['lng']) ? $params['lng'] : $origLabel['lng']; $info['address'] = (null !== $params['address']) ? $params['address'] : $origLabel['address']; if ('' === $info['placeId'] || null === $info['placeId']) { unset($info['placeId']); } if ('' === $info['reference'] || null === $info['reference']) { unset($info['reference']); } if ('' === $info['lat'] || null === $info['lat']) { unset($info['lat']); } if ('' === $info['lng'] || null === $info['lng']) { unset($info['lng']); } if ('' === $info['address'] || null === $info['address']) { unset($info['address']); } $label['info'] = json_encode($info); } // check tag exist if (Label::isDuplicated($params['id'], $params['name'], $info['placeId'], $type)) { $this->SetError(PHOTOSTATION_TAG_HAS_EXIST); goto End; } // database query if (0 === Label::EditById($params['id'], $params['name'], $label['info'])) { $this->SetError(PHOTOSTATION_TAG_EDIT_FAIL); goto End; } // update metadata if (Label::GEO !== $type) { $image_label_objs = ItemLabel::GetPhotoLabelByLabelIds(array($params['id'])); foreach ($image_label_objs as $objs) { self::OutputSingleSpace(); ItemLabel::UpdatePhotoMetadata($objs['image_id'], $result['category']); } } End: return; } private function Delete() { if (false === ($params = $this->GetParams_Info())) { $this->SetError(WEBAPI_ERR_BAD_REQUEST); goto End; } foreach ($params['id'] as $id) { // To avoid cgi timeout, have to delete label one by one // Label::DeleteAllByIds support delete multilabels self::OutputSingleSpace(); Label::DeleteAllByIds(array($id)); } End: return; } private function DeleteUnconfirmedTag() { $unconfirmedLabelId = ItemLabel::GetUnconfirmedLabelId(); Label::DeleteAllByIds($unconfirmedLabelId, false); } private function SearchPlace() { if (false === ($params = $this->GetParams_SearchPlace())) { $this->SetError(WEBAPI_ERR_BAD_REQUEST); goto End; } $query = escapeshellarg($params['query']); $location = escapeshellarg($params['location']); $radius = escapeshellarg($params['radius']); $language = escapeshellarg($_SESSION[SYNOPHOTO_ADMIN_USER]['lang']); $phppath = '/var/packages/PhotoStation/target/photo_scripts/encrypted/tag_place_search.php'; $cmd = PHP_CMD." $phppath -q $query -l $location -r $radius -n $language"; @exec($cmd, $output, $ret); if (0 !== $ret) { $this->SetError(PHOTOSTATION_TAG_SEARCH_FAIL); goto End; } $json = json_decode(implode('', $output), true); $searchPlaces = array(); $existPlace = array(); if (is_array($json['results'])) { foreach ($json['results'] as $place) { $item = array(); $item['address'] = $place['formatted_address']; $item['gps'] = $place['geometry']['location']; $item['placeId'] = $place['id']; $item['name'] = $place['name']; $item['tagId'] = -1; $item['type'] = 'search'; $searchPlaces[] = $item; } } $existPlace = Label::SearchGeoLabel($params['query']); if ($params['format']) { for($i=0; $i < count($existPlace); ++$i) { $existPlace[$i]['type'] = 'db'; } $resp = array_merge($existPlace, $searchPlaces); } else { $resp['existPlaces'] = $existPlace; $resp['searchPlaces'] = $searchPlaces; } $this->SetResponse($resp); End: return; } protected function CheckPermission() { csSYNOPhotoDB::GetDBInstance()->SetSessionCache(); $res = true; $check = array( "edit" => "admin", "delete" => "admin", "delete_unconfirmed_tag" => "admin", "create" => "manage", "searchplace" => "manage" ); 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_TAG_ACCESS_DENY); } return $res; } private function check_admin() { return isset($_SESSION[SYNOPHOTO_ADMIN_USER]['admin_syno_user']); } private function check_manage() { if (isset($_SESSION[SYNOPHOTO_ADMIN_USER]['admin_syno_user'])) { return true; } if (0 < count($_SESSION[SYNOPHOTO_ADMIN_USER]['manageable_album'])) { return true; } return false; } } $api = new TagAPI(); $api->Run(); ?>