File indexing completed on 2025-02-02 05:43:40
0001 <?php 0002 /** @noinspection PhpStatementHasEmptyBodyInspection */ 0003 /** @noinspection PhpUndefinedFieldInspection */ 0004 /** 0005 * ocs-apiserver 0006 * 0007 * Copyright 2016 by pling GmbH. 0008 * 0009 * This file is part of ocs-apiserver. 0010 * 0011 * This program is free software: you can redistribute it and/or modify 0012 * it under the terms of the GNU Affero General Public License as 0013 * published by the Free Software Foundation, either version 3 of the 0014 * License, or (at your option) any later version. 0015 * 0016 * This program is distributed in the hope that it will be useful, 0017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0019 * GNU Affero General Public License for more details. 0020 * 0021 * You should have received a copy of the GNU Affero General Public License 0022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0023 * 0024 * Created: 01.12.2017 0025 */ 0026 0027 /** 0028 * What changes from official OCS v1 spec 0029 * 0030 * OCS specification: 0031 * https://www.freedesktop.org/wiki/Specifications/open-collaboration-services/ 0032 * 0033 * ---- 0034 * 0035 * Allow delimiter ',' of value of parameter 'categories' 0036 * 0037 * Example: 0038 * /content/data?categories=1,2,3 0039 * /content/data?categories=1x2x3 0040 * 0041 * ---- 0042 * 0043 * Additional URL queries to '/content/data' 0044 * 0045 * xdg_types 0046 * package_types 0047 * 0048 * Example: 0049 * /content/data?xdg_types=icons,themes,wallpapers 0050 * /content/data?package_types=1,2,3 0051 * 0052 * package_types: 0053 * 1 = AppImage 0054 * 2 = Android (apk)c 0055 * 3 = OS X compatible 0056 * 4 = Windows executable 0057 * 5 = Debian 0058 * 6 = Snappy 0059 * 7 = Flatpak 0060 * 8 = Electron-Webapp 0061 * 9 = Arch 0062 * 10 = open/Suse 0063 * 11 = Redhat 0064 * 12 = Source Code 0065 * 0066 * ---- 0067 * 0068 * Additional data field of '/content/categories' 0069 * 0070 * display_name 0071 * parent_id 0072 * xdg_type 0073 * 0074 * ---- 0075 * 0076 * Additional data field of '/content/data' 0077 * 0078 * xdg_type 0079 * download_package_type{n} 0080 * download_package_arch{n} 0081 * 0082 * ---- 0083 * 0084 * Additional data field of '/content/download' 0085 * 0086 * download_package_type 0087 * download_package_arch 0088 * 0089 * ---- 0090 * 0091 * Additional API method for preview picture 0092 * 0093 * /content/previewpic/{contentid} 0094 * 0095 * Example: 0096 * /content/previewpic/123456789 0097 * /content/previewpic/123456789?size=medium 0098 */ 0099 class Ocsv1Controller extends Zend_Controller_Action 0100 { 0101 0102 const COMMENT_TYPE_CONTENT = 1; 0103 const COMMENT_TYPE_FORUM = 4; 0104 const COMMENT_TYPE_KNOWLEDGE = 7; 0105 const COMMENT_TYPE_EVENT = 8; 0106 0107 const DOWNLOAD_PERIOD_VALIDITY = 12; // hours 0108 0109 const CACHE_PERIOD_VALIDITY = 1; // hour 0110 0111 protected $_authData = null; 0112 0113 protected $_uriScheme = 'https'; 0114 0115 protected $_format = 'xml'; 0116 0117 protected $_config = array('id' => 'opendesktop.org', 0118 'location' => 'https://www.opendesktop.org/ocs/v1/', 0119 'name' => 'opendesktop.org', 0120 'icon' => '', 0121 'termsofuse' => 'https://www.opendesktop.org/terms', 0122 'register' => 'https://www.opendesktop.org/register', 0123 'version' => '1.7', 0124 'website' => 'www.opendesktop.org', 0125 'host' => 'www.opendesktop.org', 0126 'contact' => 'contact@opendesktop.org', 0127 'ssl' => true, 0128 'user_host' => 'www.pling.com'); 0129 0130 protected $_params = array(); 0131 0132 protected $_allowed_format = array('json', 'xml'); 0133 0134 /** 0135 * @throws Zend_Exception 0136 */ 0137 public function init() 0138 { 0139 parent::init(); 0140 $this->_initUriScheme(); 0141 $this->_initRequestParamsAndFormat(); 0142 $this->_initConfig(); 0143 $this->_initResponseHeader(); 0144 $this->_initAuthorization(); 0145 } 0146 0147 /** 0148 * 0149 */ 0150 protected function _initUriScheme() 0151 { 0152 $this->_uriScheme = 'http'; 0153 0154 if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] === '1')) { 0155 $this->_uriScheme = 'https'; 0156 0157 return; 0158 } 0159 0160 if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') { 0161 $this->_uriScheme = 'https'; 0162 0163 return; 0164 } 0165 } 0166 0167 /** 0168 * @throws Zend_Exception 0169 */ 0170 protected function _initRequestParamsAndFormat() 0171 { 0172 // Set request parameters 0173 switch (strtoupper($_SERVER['REQUEST_METHOD'])) { 0174 case 'GET': 0175 $this->_params = $_GET + $this->getAllParams(); 0176 break; 0177 case 'PUT': 0178 parse_str(file_get_contents('php://input'), $_PUT); 0179 $this->_params = $_PUT; 0180 break; 0181 case 'POST': 0182 $this->_params = $_POST; 0183 break; 0184 case 'OPTIONS': 0185 header('Allow: GET,POST'); 0186 $this->_sendResponse(null, 'json'); 0187 break; 0188 default: 0189 Zend_Registry::get('logger') 0190 ->err(__METHOD__ . ' - request method not supported - ' . $_SERVER['REQUEST_METHOD']) 0191 ; 0192 exit('request method not supported'); 0193 } 0194 0195 // try to find accept header 0196 /** @var Zend_Controller_Request_Http $request */ 0197 $request = $this->getRequest(); 0198 $accept_header = $request->getHeader('accept'); 0199 //Zend_Registry::get('logger')->debug(__METHOD__ . ' :: ' . print_r($accept_header, true)); 0200 list($format) = sscanf($accept_header, "application/%s"); 0201 //Zend_Registry::get('logger')->debug(__METHOD__ . ' :: ' . print_r($this->_format, true)); 0202 if (in_array(strtolower($format), $this->_allowed_format)) { 0203 $this->_format = $format; 0204 } 0205 0206 // Set format option 0207 if (isset($this->_params['format']) && strtolower($this->_params['format']) == 'json') { 0208 $this->_format = 'json'; 0209 } 0210 } 0211 0212 /** 0213 * @param $response 0214 * @param string $format 0215 * @param string $xmlRootTag 0216 * 0217 * @throws DOMException 0218 */ 0219 protected function _sendResponse($response, $format = 'xml', $xmlRootTag = 'ocs') 0220 { 0221 // header('Pragma: public'); 0222 header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT', true); 0223 0224 header("Access-Control-Allow-Origin: *"); 0225 header("Access-Control-Allow-Headers: Accept,Authorization,X-Requested-With"); 0226 header("Access-Control-Request-Method: GET,POST,OPTIONS"); 0227 header("Vary: Accept, Content-Type"); 0228 0229 $duration = 1800; // in seconds 0230 header('Cache-Control: max-age='.$duration); 0231 // $expires = gmdate("D, d M Y H:i:s", time() + $duration) . " GMT"; 0232 // header('Expires: ' . $expires); 0233 if ($format == 'json') { 0234 header('Content-Type: application/json; charset=UTF-8'); 0235 echo json_encode($response); 0236 } else { 0237 header('Content-Type: application/xml; charset=UTF-8'); 0238 echo $this->_convertXmlDom($response, $xmlRootTag)->saveXML() 0239 ; 0240 } 0241 0242 exit; 0243 } 0244 0245 /** 0246 * @param $values 0247 * @param string $tagName 0248 * @param DOMNode|null $dom 0249 * @param DOMElement|null $element 0250 * 0251 * @return DomDocument|DOMNode 0252 * @throws DOMException 0253 */ 0254 protected function _convertXmlDom($values, $tagName = 'data', DOMNode &$dom = null, DOMElement &$element = null) 0255 { 0256 if (!$dom) { 0257 $dom = new DomDocument('1.0', 'UTF-8'); 0258 } 0259 if (!$element) { 0260 $element = $dom->appendChild($dom->createElement($tagName)); 0261 } 0262 if (is_array($values) || is_object($values)) { 0263 foreach ($values as $key => $value) { 0264 if (is_array($value) || is_object($value)) { 0265 $isHash = false; 0266 foreach ($value as $_key => $_value) { 0267 if (ctype_digit((string)$_key)) { 0268 $isHash = true; 0269 } 0270 break; 0271 } 0272 if ($isHash) { 0273 $this->_convertXmlDom($value, $key, $dom, $element); 0274 continue; 0275 } 0276 if (ctype_digit((string)$key)) { 0277 $key = $tagName; 0278 } 0279 $childElement = $element->appendChild($dom->createElement($key)); 0280 $this->_convertXmlDom($value, $key, $dom, $childElement); 0281 } else { 0282 if ($key == '@text') { 0283 if (is_bool($value)) { 0284 $value = var_export($value, true); 0285 } 0286 $element->appendChild($dom->createTextNode($value)); 0287 } else { 0288 if ($key == '@cdata') { 0289 if (is_bool($value)) { 0290 $value = var_export($value, true); 0291 } 0292 $element->appendChild($dom->createCDATASection($value)); 0293 } else { 0294 if (is_bool($value)) { 0295 $value = var_export($value, true); 0296 } 0297 $element->setAttribute($key, $value); 0298 } 0299 } 0300 } 0301 } 0302 } 0303 0304 return $dom; 0305 } 0306 0307 /** 0308 * @return array|null 0309 * @throws Zend_Exception 0310 */ 0311 protected function _loadClientConfig() 0312 { 0313 $clientConfigReader = new Application_Model_ClientConfig($this->_getNameForStoreClient()); 0314 $clientConfigReader->loadClientConfig(); 0315 0316 return $clientConfigReader->getConfig(); 0317 } 0318 0319 /** 0320 * Returns the name for the store client. 0321 * If no name were found, the name for the standard store client will be returned. 0322 * 0323 * @return string 0324 * @throws Zend_Exception 0325 */ 0326 protected function _getNameForStoreClient() 0327 { 0328 $clientName = Zend_Registry::get('config')->settings->client->default->name; // default client 0329 if (Zend_Registry::isRegistered('store_config_name')) { 0330 $clientName = Zend_Registry::get('store_config_name'); 0331 } 0332 0333 return $clientName; 0334 } 0335 0336 /** 0337 * 0338 */ 0339 protected function _initResponseHeader() 0340 { 0341 $duration = 1800; // in seconds 0342 $expires = gmdate("D, d M Y H:i:s", time() + $duration) . " GMT"; 0343 0344 $this->getResponse() 0345 ->setHeader('X-FRAME-OPTIONS', 'SAMEORIGIN', true) 0346 ->setHeader('Expires', $expires, true) 0347 ->setHeader('Pragma', 'cache', true) 0348 ->setHeader('Cache-Control', 'max-age=1800, public', true) 0349 ; 0350 } 0351 0352 /** 0353 * @throws Zend_Auth_Adapter_Exception 0354 * @throws Zend_Exception 0355 */ 0356 protected function _initAuthorization() 0357 { 0358 $authToken = $this->getAuthToken(); 0359 if ($authToken) { 0360 $this->getAuthDataFromToken($authToken); 0361 0362 return; 0363 } 0364 $this->_authenticateUser(); 0365 } 0366 0367 protected function getAuthToken() 0368 { 0369 $authHeader = $this->getAuthorizationHeader(); 0370 list($authToken) = sscanf($authHeader, "Bearer %s"); 0371 0372 // return sscanf( $authHeader, "Authorization: Bearer %s"); 0373 0374 return $authToken; 0375 } 0376 0377 /** 0378 * Get header Authorization 0379 * */ 0380 protected function getAuthorizationHeader() 0381 { 0382 if (isset($_SERVER['Authorization'])) { 0383 return trim($_SERVER["Authorization"]); 0384 } 0385 if (isset($_SERVER['HTTP_AUTHORIZATION'])) { //Nginx or fast CGI but depends on Webserver Config 0386 return trim($_SERVER["HTTP_AUTHORIZATION"]); 0387 } 0388 if (function_exists('apache_request_headers')) { 0389 $requestHeaders = apache_request_headers(); 0390 // Server-side fix for bug in old Android versions (a nice side-effect of this fix means we don't care about capitalization for Authorization) 0391 $requestHeaders = array_combine(array_map('ucwords', array_keys($requestHeaders)), array_values($requestHeaders)); 0392 //print_r($requestHeaders); 0393 if (isset($requestHeaders['Authorization'])) { 0394 return trim($requestHeaders['Authorization']); 0395 } 0396 } 0397 0398 return ''; 0399 } 0400 0401 /** 0402 * @param $authToken 0403 * 0404 * @return void 0405 */ 0406 protected function getAuthDataFromToken($authToken) 0407 { 0408 try { 0409 $data = Application_Model_Jwt::decode($authToken); 0410 if ($data->exp < microtime()) { 0411 return; 0412 } 0413 0414 $external_id = $data->sub; 0415 if (empty($external_id)) { 0416 return; 0417 } 0418 0419 $modelMember = new Application_Model_Member(); 0420 $member_data = $modelMember->fetchMemberDataByExternalId($external_id); 0421 $this->_authData = (object)$member_data->toArray(); 0422 $auth = Zend_Auth::getInstance(); 0423 $auth->clearIdentity(); 0424 $auth->getStorage()->write((object)$member_data->toArray()) 0425 ; 0426 } catch (Exception $e) { 0427 error_log(__METHOD__ . ' :: ' . $e->getMessage()); 0428 } 0429 } 0430 0431 /** 0432 * @param null $identity 0433 * @param null $credential 0434 * @param bool $force 0435 * 0436 * @return bool 0437 * @throws Zend_Auth_Adapter_Exception 0438 * @throws Zend_Exception 0439 * 0440 */ 0441 protected function _authenticateUser($identity = null, $credential = null, $force = false) 0442 { 0443 if (!$identity && !empty($_SERVER['PHP_AUTH_USER'])) { 0444 // Will set user identity or API-Key 0445 $identity = $_SERVER['PHP_AUTH_USER']; 0446 } 0447 if (!$credential && !empty($_SERVER['PHP_AUTH_PW'])) { 0448 $credential = $_SERVER['PHP_AUTH_PW']; 0449 } 0450 0451 if (isset($identity) && isset($credential)) { 0452 $authModel = new Application_Model_Authorization(); 0453 $authData = $authModel->getAuthDataFromApi($identity, $credential); 0454 if ($authData) { 0455 $this->_authData = $authData; 0456 Zend_Auth::getInstance()->clearIdentity() 0457 ; 0458 Zend_Auth::getInstance()->getStorage()->write($authData) 0459 ; 0460 0461 return true; 0462 } 0463 } 0464 0465 if ($force) { 0466 //header('WWW-Authenticate: Basic realm="Your valid user account or api key"'); 0467 header('WWW-Authenticate: Basic realm="Your valid user account"'); 0468 header('HTTP/1.0 401 Unauthorized'); 0469 exit; 0470 } 0471 0472 return false; 0473 } 0474 0475 /** 0476 * @throws Zend_Exception 0477 */ 0478 public function indexAction() 0479 { 0480 $this->_sendErrorResponse(999, 'unknown request'); 0481 } 0482 0483 /** 0484 * @param $statuscode 0485 * @param string $message 0486 * 0487 * @throws DOMException 0488 * @throws Zend_Exception 0489 */ 0490 protected function _sendErrorResponse($statuscode, $message = '') 0491 { 0492 if ($this->_format == 'json') { 0493 $response = array('status' => 'failed', 0494 'statuscode' => $statuscode, 0495 'message' => $message); 0496 } else { 0497 $response = array('meta' => array('status' => array('@text' => 'failed'), 0498 'statuscode' => array('@text' => $statuscode), 0499 'message' => array('@text' => $message))); 0500 } 0501 0502 Zend_Registry::get('logger')->err(json_encode($response)) 0503 ; 0504 $this->_sendResponse($response, $this->_format); 0505 } 0506 0507 public function providersAction() 0508 { 0509 // As providers.xml 0510 $response = array('provider' => array('id' => array('@text' => $this->_config['id']), 0511 'location' => array('@text' => $this->_config['location']), 0512 'name' => array('@text' => $this->_config['name']), 0513 'icon' => array('@text' => $this->_config['icon']), 0514 'termsofuse' => array('@text' => $this->_config['termsofuse']), 0515 'register' => array('@text' => $this->_config['register']), 0516 'services' => array('person' => array('ocsversion' => $this->_config['version']), 0517 'content' => array('ocsversion' => $this->_config['version'])))); 0518 0519 $this->_sendResponse($response, 'xml', 'providers'); 0520 } 0521 0522 /** 0523 * @throws Zend_Exception 0524 */ 0525 protected function _initConfig() 0526 { 0527 $clientConfig = $this->_loadClientConfig(); 0528 0529 $credentials = ''; 0530 if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) { 0531 $credentials = $_SERVER['PHP_AUTH_USER'] . ':' . $_SERVER['PHP_AUTH_PW'] . '@'; 0532 } 0533 0534 $baseUri = $this->_uriScheme . '://' . $credentials . $_SERVER['SERVER_NAME']; 0535 0536 $webSite = Zend_Registry::get('config')->settings->client->default->website; 0537 0538 //Mask api.kde-look.org to store.kde.org 0539 if (Zend_Registry::get('config')->settings->client->special->mapping_active == true) { 0540 $mapping = Zend_Registry::get('config')->settings->client->special->mapping->toArray(); 0541 0542 $webSite = $mapping[$this->_getNameForStoreClient()] ? $mapping[$this->_getNameForStoreClient()] : $webSite; 0543 } 0544 0545 $this->_config = array('id' => $_SERVER['SERVER_NAME'], 0546 'location' => $baseUri . '/ocs/v1/', 0547 'name' => $clientConfig['head']['browser_title'], 0548 'icon' => $baseUri . $clientConfig['logo'], 0549 'termsofuse' => $webSite . '/content/terms', 0550 'register' => $webSite . '/register', 0551 'website' => $webSite, 0552 'host' => $_SERVER['SERVER_NAME']) + $this->_config; 0553 } 0554 0555 public function configAction() 0556 { 0557 if ($this->_format == 'json') { 0558 $response = array('status' => 'ok', 0559 'statuscode' => 100, 0560 'message' => '', 0561 'data' => array('version' => $this->_config['version'], 0562 'website' => $this->_config['website'], 0563 'host' => $this->_config['host'], 0564 'contact' => $this->_config['contact'], 0565 'ssl' => $this->_config['ssl'])); 0566 } else { 0567 $response = array('meta' => array('status' => array('@text' => 'ok'), 0568 'statuscode' => array('@text' => 100), 0569 'message' => array('@text' => '')), 0570 'data' => array('version' => array('@text' => $this->_config['version']), 0571 'website' => array('@text' => $this->_config['website']), 0572 'host' => array('@text' => $this->_config['host']), 0573 'contact' => array('@text' => $this->_config['contact']), 0574 'ssl' => array('@text' => $this->_config['ssl']))); 0575 } 0576 0577 $this->_sendResponse($response, $this->_format); 0578 } 0579 0580 public function personcheckAction() 0581 { 0582 /** @var Zend_Controller_Request_Http $request */ 0583 $request = $this->getRequest(); 0584 if (false === $request->isPost()) { 0585 $this->_sendErrorResponse(405, "method not allowed"); 0586 } 0587 $identity = $this->getParam('login'); 0588 $credential = $this->getParam('password'); 0589 0590 if (!$identity) { 0591 $this->_sendErrorResponse(101, 'please specify all mandatory fields'); 0592 } 0593 0594 $modelAuth = new Application_Model_Authorization(); 0595 $authResult = $modelAuth->authenticateCredentials($identity, $credential); 0596 0597 if (!$authResult->isValid()) { 0598 $this->_sendErrorResponse(102, 'login not valid'); 0599 } 0600 0601 if ($this->_format == 'json') { 0602 $response = array('status' => 'ok', 0603 'statuscode' => 100, 0604 'message' => '', 0605 'data' => array(array('details' => 'check', 0606 'personid' => $authResult->getIdentity()))); 0607 } else { 0608 $response = array('meta' => array('status' => array('@text' => 'ok'), 0609 'statuscode' => array('@text' => 100), 0610 'message' => array('@text' => '')), 0611 'data' => array('person' => array('details' => 'check', 0612 'personid' => array('@text' => $authResult->getIdentity())))); 0613 } 0614 0615 $this->_sendResponse($response, $this->_format); 0616 } 0617 0618 /** 0619 * Gets a parameter from the {@link $_request Request object}. If the 0620 * parameter does not exist, NULL will be returned. 0621 * 0622 * If the parameter does not exist and $default is set, then 0623 * $default will be returned instead of NULL. 0624 * 0625 * @param string $paramName 0626 * @param mixed $default 0627 * 0628 * @return mixed 0629 */ 0630 public function getParam($paramName, $default = null) 0631 { 0632 $value = isset($this->_params[$paramName]) ? $this->_params[$paramName] : null; 0633 if ((null === $value || '' === $value) && (null !== $default)) { 0634 $value = $default; 0635 } 0636 0637 return $value; 0638 } 0639 0640 public function personselfAction() 0641 { 0642 $this->persondataAction(true); 0643 } 0644 0645 /** 0646 * @param bool $self 0647 * 0648 * @throws DOMException 0649 * @throws Zend_Db_Select_Exception 0650 * @throws Zend_Exception 0651 */ 0652 public function persondataAction($self = false) 0653 { 0654 //See Ticket: https://phabricator.kde.org/T11173: we should show some data instead of an error 0655 $showAll = false; 0656 if (Zend_Auth::getInstance()->hasIdentity()) { 0657 $showAll = true; 0658 } 0659 0660 $tableMember = new Application_Model_Member(); 0661 0662 // Self data or specific person data 0663 if ($self || $this->getParam('personid')) { 0664 if ($self) { 0665 $username = $this->_authData->username; 0666 } else { 0667 if ($this->getParam('personid')) { 0668 $username = $this->getParam('personid'); 0669 } 0670 } 0671 0672 $member = $tableMember->findActiveMemberByIdentity($username); 0673 0674 if (empty($member->member_id)) { 0675 $this->_sendErrorResponse(101, 'person not found'); 0676 } 0677 0678 $profilePage = $this->_uriScheme . '://' . $this->_config['user_host'] . '/u/' . $member->username; 0679 $avatarUrl = $this->_uriScheme . '://' . $this->_config['user_host'] . '/member/avatar/' . md5($member->mail) . '/800'; 0680 0681 $userData = array('details' => $showAll ? 'full' : 'summary', 0682 'personid' => $member->username, 0683 'privacy' => 0, 0684 'privacytext' => 'public', 0685 'firstname' => $member->firstname, 0686 'lastname' => $showAll ? $member->lastname : '', 0687 'gender' => '', 0688 'communityrole' => '', 0689 'homepage' => $member->link_website, 0690 'company' => '', 0691 'avatarpic' => $avatarUrl, 0692 'avatarpicfound' => 1, 0693 'bigavatarpic' => $avatarUrl, 0694 'bigavatarpicfound' => 1, 0695 'birthday' => '', 0696 'jobstatus' => '', 0697 'city' => $showAll ? $member->city : '', 0698 'country' => $showAll ? $member->country : '', 0699 'latitude' => '', 0700 'longitude' => '', 0701 'ircnick' => '', 0702 'ircchannels' => '', 0703 'irclink' => '', 0704 'likes' => '', 0705 'dontlikes' => '', 0706 'interests' => '', 0707 'languages' => '', 0708 'programminglanguages' => '', 0709 'favouritequote' => '', 0710 'favouritemusic' => '', 0711 'favouritetvshows' => '', 0712 'favouritemovies' => '', 0713 'favouritebooks' => '', 0714 'favouritegames' => '', 0715 'description' => $showAll ? $member->biography : '', 0716 'profilepage' => $profilePage); 0717 0718 if ($this->_format == 'json') { 0719 $response = array('status' => 'ok', 0720 'statuscode' => 100, 0721 'message' => '', 0722 'data' => array($userData)); 0723 } else { 0724 $userData = array('details' => $showAll ? 'full' : 'summary', 0725 'personid' => array('@text' => $member->username), 0726 'privacy' => array('@text' => 0), 0727 'privacytext' => array('@text' => 'public'), 0728 'firstname' => array('@text' => $member->firstname), 0729 'lastname' => array('@text' => $showAll ? $member->lastname : ''), 0730 'gender' => array('@text' => ''), 0731 'communityrole' => array('@text' => ''), 0732 'homepage' => array('@text' => $member->link_website), 0733 'company' => array('@text' => ''), 0734 'avatarpic' => array('@text' => $avatarUrl), 0735 'avatarpicfound' => array('@text' => 1), 0736 'bigavatarpic' => array('@text' => $avatarUrl), 0737 'bigavatarpicfound' => array('@text' => 1), 0738 'birthday' => array('@text' => ''), 0739 'jobstatus' => array('@text' => ''), 0740 'city' => array('@text' => $showAll ? $member->city : ''), 0741 'country' => array('@text' => $showAll ? $member->country : ''), 0742 'latitude' => array('@text' => ''), 0743 'longitude' => array('@text' => ''), 0744 'ircnick' => array('@text' => ''), 0745 'ircchannels' => array('@text' => ''), 0746 'irclink' => array('@text' => ''), 0747 'likes' => array('@text' => ''), 0748 'dontlikes' => array('@text' => ''), 0749 'interests' => array('@text' => ''), 0750 'languages' => array('@text' => ''), 0751 'programminglanguages' => array('@text' => ''), 0752 'favouritequote' => array('@text' => ''), 0753 'favouritemusic' => array('@text' => ''), 0754 'favouritetvshows' => array('@text' => ''), 0755 'favouritemovies' => array('@text' => ''), 0756 'favouritebooks' => array('@text' => ''), 0757 'favouritegames' => array('@text' => ''), 0758 'description' => array('@text' => $showAll ? $member->biography : ''), 0759 'profilepage' => array('@text' => $profilePage)); 0760 0761 0762 $response = array('meta' => array('status' => array('@text' => 'ok'), 0763 'statuscode' => array('@text' => 100), 0764 'message' => array('@text' => '')), 0765 'data' => array('person' => $userData)); 0766 } 0767 0768 $this->_sendResponse($response, $this->_format); 0769 } // Find a specific list of persons 0770 else { 0771 //Only auth users can search here 0772 if (!$showAll) { 0773 $this->_sendErrorResponse(101, 'data is private'); 0774 } 0775 0776 $limit = 10; // 1 - 100 0777 $offset = 0; 0778 0779 $tableMemberSelect = $tableMember->select()->where('is_active = ?', 1)->where('is_deleted = ?', 0); 0780 0781 if (!empty($this->_params['name'])) { 0782 $isSearchable = false; 0783 foreach (explode(' ', $this->_params['name']) as $keyword) { 0784 if ($keyword && strlen($keyword) > 2) { 0785 $tableMemberSelect->where('username LIKE ?' . ' OR firstname LIKE ?' . ' OR lastname LIKE ?', "%$keyword%"); 0786 $isSearchable = true; 0787 } 0788 } 0789 if (!$isSearchable) { 0790 $tableMemberSelect->where('username LIKE ?' . ' OR firstname LIKE ?' . ' OR lastname LIKE ?', "%{$this->_params['name']}%"); 0791 } 0792 } 0793 if (!empty($this->_params['country'])) { 0794 $tableMemberSelect->where('country = ?', $this->_params['country']); 0795 } 0796 if (!empty($this->_params['city'])) { 0797 $tableMemberSelect->where('city = ?', $this->_params['city']); 0798 } 0799 if (!empty($this->_params['description'])) { 0800 $isSearchable = false; 0801 foreach (explode(' ', $this->_params['name']) as $keyword) { 0802 if ($keyword && strlen($keyword) > 2) { 0803 $tableMemberSelect->where('biography LIKE ?', "%$keyword%"); 0804 $isSearchable = true; 0805 } 0806 } 0807 if (!$isSearchable) { 0808 $tableMemberSelect->where('biography LIKE ?', "%$this->_params['description']}%"); 0809 } 0810 } 0811 if (!empty($this->_params['pc'])) { 0812 } 0813 if (!empty($this->_params['software'])) { 0814 } 0815 if (!empty($this->_params['longitude'])) { 0816 } 0817 if (!empty($this->_params['latitude'])) { 0818 } 0819 if (!empty($this->_params['distance'])) { 0820 } 0821 if (!empty($this->_params['attributeapp'])) { 0822 } 0823 if (!empty($this->_params['attributekey'])) { 0824 } 0825 if (!empty($this->_params['attributevalue'])) { 0826 } 0827 if (isset($this->_params['pagesize']) && ctype_digit((string)$this->_params['pagesize']) && $this->_params['pagesize'] > 0 && $this->_params['pagesize'] < 101) { 0828 $limit = $this->_params['pagesize']; 0829 } 0830 if (isset($this->_params['page']) && ctype_digit((string)$this->_params['page'])) { 0831 // page parameter: the first page is 0 0832 $offset = $limit * $this->_params['page']; 0833 } 0834 0835 $members = $tableMember->fetchAll($tableMemberSelect->limit($limit, $offset)); 0836 0837 $tableMemberSelect->reset('columns'); 0838 $tableMemberSelect->reset('limitcount'); 0839 $tableMemberSelect->reset('limitoffset'); 0840 0841 $count = $tableMember->fetchRow($tableMemberSelect->columns(array('count' => 'COUNT(*)'))); 0842 0843 if ($count['count'] > 1000) { 0844 $this->_sendErrorResponse(102, 'more than 1000 people found.' . ' it is not allowed to fetch such a big resultset.' . ' please specify more search conditions'); 0845 } 0846 0847 if ($this->_format == 'json') { 0848 $response = array('status' => 'ok', 0849 'statuscode' => 100, 0850 'message' => '', 0851 'totalitems' => $count['count'], 0852 'itemsperpage' => $limit, 0853 'data' => array()); 0854 } else { 0855 $response = array('meta' => array('status' => array('@text' => 'ok'), 0856 'statuscode' => array('@text' => 100), 0857 'message' => array('@text' => ''), 0858 'totalitems' => array('@text' => $count['count']), 0859 'itemsperpage' => array('@text' => $limit)), 0860 'data' => array()); 0861 } 0862 0863 if (!count($members)) { 0864 $this->_sendResponse($response, $this->_format); 0865 } 0866 0867 $personsList = array(); 0868 foreach ($members as $member) { 0869 if ($this->_format == 'json') { 0870 $personsList[] = array('details' => 'summary', 0871 'personid' => $member->username, 0872 'privacy' => 0, 0873 'privacytext' => 'public', 0874 'firstname' => $member->firstname, 0875 'lastname' => $member->lastname, 0876 'gender' => '', 0877 'communityrole' => '', 0878 'company' => '', 0879 'city' => $member->city, 0880 'country' => $member->country); 0881 } else { 0882 $personsList[] = array('details' => 'summary', 0883 'personid' => array('@text' => $member->username), 0884 'privacy' => array('@text' => 0), 0885 'privacytext' => array('@text' => 'public'), 0886 'firstname' => array('@text' => $member->firstname), 0887 'lastname' => array('@text' => $member->lastname), 0888 'gender' => array('@text' => ''), 0889 'communityrole' => array('@text' => ''), 0890 'company' => array('@text' => ''), 0891 'city' => array('@text' => $member->city), 0892 'country' => array('@text' => $member->country)); 0893 } 0894 } 0895 0896 if ($this->_format == 'json') { 0897 $response['data'] = $personsList; 0898 } else { 0899 $response['data'] = array('person' => $personsList); 0900 } 0901 0902 $this->_sendResponse($response, $this->_format); 0903 } 0904 } 0905 0906 /** 0907 * @throws DOMException 0908 * @throws Zend_Cache_Exception 0909 * @throws Zend_Exception 0910 */ 0911 public function contentcategoriesAction() 0912 { 0913 /** @var Zend_Cache_Core $cache */ 0914 $cache = Zend_Registry::get('cache'); 0915 $cacheName = 'content_categories_' . md5($this->_getNameForStoreClient() . $this->_format); 0916 0917 $debugMode = (int)$this->getParam('debug') ? (int)$this->getParam('debug') : false; 0918 0919 if (false == ($categoriesList = $cache->load($cacheName))) { 0920 $categoriesList = $this->_buildCategories(); 0921 $cache->save($categoriesList, $cacheName, array(), 900); 0922 } 0923 0924 if ($this->_format == 'json') { 0925 $response = array('status' => 'ok', 0926 'statuscode' => 100, 0927 'message' => '', 0928 'totalitems' => count($categoriesList), 0929 'data' => array()); 0930 if (!empty($categoriesList)) { 0931 $response['data'] = $categoriesList; 0932 } 0933 } else { 0934 $response = array('meta' => array('status' => array('@text' => 'ok'), 0935 'statuscode' => array('@text' => 100), 0936 'message' => array('@text' => ''), 0937 'totalitems' => array('@text' => count($categoriesList))), 0938 'data' => array()); 0939 if (!empty($categoriesList)) { 0940 $response['data'] = array('category' => $categoriesList); 0941 } 0942 } 0943 0944 if ($debugMode) { 0945 $response['meta']['debug']['store_client_name'] = $this->_getNameForStoreClient(); 0946 $response['meta']['debug']['param_store_client_name'] = $this->getParam('domain_store_id'); 0947 } 0948 0949 $etag = md5(json_encode($response)); 0950 header("Etag: $etag"); 0951 $this->_sendResponse($response, $this->_format); 0952 } 0953 0954 /** 0955 * @return array 0956 */ 0957 protected function _buildCategories() 0958 { 0959 $modelCategoryTree = new Application_Model_ProjectCategory(); 0960 $tree = $modelCategoryTree->fetchCategoryTreeCurrentStore(); 0961 0962 return $this->buildResponseTree($tree); 0963 } 0964 0965 /** 0966 * @param array $tree 0967 * 0968 * @return array 0969 */ 0970 protected function buildResponseTree($tree) 0971 { 0972 $result = array(); 0973 foreach ($tree as $element) { 0974 if ($this->_format == 'json') { 0975 $result[] = array('id' => $element['id'], 0976 'name' => (false === empty($element['name_legacy'])) ? $element['name_legacy'] : $element['title'], 0977 'display_name' => $element['title'], 0978 'parent_id' => (false === empty($element['parent_id'])) ? $element['parent_id'] : '', 0979 'xdg_type' => (false === empty($element['xdg_type'])) ? $element['xdg_type'] : ''); 0980 } else { 0981 $result[] = array('id' => array('@text' => $element['id']), 0982 'name' => array('@text' => (false === empty($element['name_legacy'])) ? $element['name_legacy'] : $element['title']), 0983 'display_name' => array('@text' => $element['title']), 0984 'parent_id' => array('@text' => (false === empty($element['parent_id'])) ? $element['parent_id'] : ''), 0985 'xdg_type' => array('@text' => (false === empty($element['xdg_type'])) ? $element['xdg_type'] : '')); 0986 } 0987 if ($element['has_children']) { 0988 $sub_tree = $this->buildResponseTree($element['children']); 0989 $result = array_merge($result, $sub_tree); 0990 } 0991 } 0992 0993 return $result; 0994 } 0995 0996 /** 0997 * @throws Zend_Auth_Storage_Exception 0998 * @throws Zend_Exception 0999 * @throws Zend_Cache_Exception 1000 * @throws Zend_Auth_Adapter_Exception 1001 * @throws Zend_Db_Select_Exception 1002 * @throws Zend_Db_Statement_Exception 1003 * @throws DOMException 1004 */ 1005 public function contentdataAction() 1006 { 1007 /* @deprecated use Zend_Auth::getInstance() instead */ 1008 //$this->_authenticateUser(); 1009 1010 $pploadApi = new Ppload_Api(array('apiUri' => PPLOAD_API_URI, 1011 'clientId' => PPLOAD_CLIENT_ID, 1012 'secret' => PPLOAD_SECRET)); 1013 $previewPicSize = array('width' => 770, 1014 'height' => 540, 1015 'crop' => 0); 1016 $smallPreviewPicSize = array('width' => 100, 1017 'height' => 100, 1018 'crop' => 0); 1019 1020 $debugMode = (int)$this->getParam('debug') ? (int)$this->getParam('debug') : false; 1021 $nocache = (int)$this->getParam('nocache') ? (int)$this->getParam('nocache') : false; 1022 1023 // Specific content data 1024 $requestedId = (int)$this->getParam('content_id') ? (int)$this->getParam('content_id') : null; 1025 if (!$requestedId) { 1026 $requestedId = (int)$this->getParam('contentid') ? (int)$this->getParam('contentid') : null; 1027 } 1028 1029 1030 if ($requestedId) { 1031 $response = $this->fetchContent($requestedId, $previewPicSize, $smallPreviewPicSize, $pploadApi); 1032 1033 $this->_sendResponse($response, $this->_format); 1034 } // Gets a list of a specific set of contents 1035 else { 1036 $response = $this->fetchCategoryContent($previewPicSize, $smallPreviewPicSize, $pploadApi, $debugMode, $nocache); 1037 1038 $this->_sendResponse($response, $this->_format); 1039 } 1040 } 1041 1042 /** 1043 * @param int $contentId 1044 * @param array $previewPicSize 1045 * @param array $smallPreviewPicSize 1046 * @param Ppload_Api $pploadApi 1047 * 1048 * @return array 1049 * @throws DOMException 1050 * @throws Zend_Cache_Exception 1051 * @throws Zend_Db_Select_Exception 1052 * @throws Zend_Exception 1053 */ 1054 protected function fetchContent($contentId, 1055 $previewPicSize, 1056 $smallPreviewPicSize, 1057 $pploadApi) 1058 { 1059 /** @var Zend_Cache_Core $cache */ 1060 $cache = Zend_Registry::get('cache'); 1061 $cacheName = 'api_fetch_content_by_id_' . $contentId . $this->_format . md5($this->_getNameForStoreClient()); 1062 1063 if (($response = $cache->load($cacheName))) { 1064 return $response; 1065 } 1066 1067 $tableProject = new Application_Model_Project(); 1068 $tableProjectSelect = $this->_buildProjectSelect($tableProject); 1069 1070 $project = $tableProject->fetchRow($tableProjectSelect->where('project.project_id = ?', $contentId)); 1071 1072 if (!$project) { 1073 $this->_sendErrorResponse(101, 'content not found'); 1074 } 1075 1076 $project->title = Application_Model_HtmlPurify::purify($project->title); 1077 $project->description = Application_Model_BBCode::renderHtml(Application_Model_HtmlPurify::purify($project->description)); 1078 $project->version = Application_Model_HtmlPurify::purify($project->version); 1079 1080 $categoryXdgType = ''; 1081 if (!empty($project->cat_xdg_type)) { 1082 $categoryXdgType = $project->cat_xdg_type; 1083 } 1084 1085 $created = date('c', strtotime($project->created_at)); 1086 $changed = date('c', strtotime($project->changed_at)); 1087 1088 $previewPage = $this->_uriScheme . '://' . $this->_config['website'] . '/p/' . $project->project_id; 1089 1090 $donationPage = $previewPage; 1091 if (empty($project->paypal_mail) && empty($project->dwolla_id)) { 1092 $donationPage = ''; 1093 } 1094 1095 list($previewPics, $smallPreviewPics) = $this->getGalleryPictures($project, $previewPicSize, $smallPreviewPicSize); 1096 1097 $downloads = $project->count_downloads_hive; 1098 list($downloadItems, $downloads) = $this->getPPLoadInfo($project, $pploadApi, $downloads); 1099 1100 $score = $project->laplace_score; 1101 $score = round($score / 10, 0); 1102 1103 $projTags = ""; 1104 //special for plasma-version-tags 1105 if (!empty($project->tags)) { 1106 //get File-Tags from Product 1107 $fileTagArray = explode(',', $project->tags); 1108 //collect tags 1109 $tagTable = new Application_Model_Tags(); 1110 $plasmaversionTags = $tagTable->getAllFilePlasmaVersionTags(); 1111 foreach ($fileTagArray as $tag) { 1112 if (in_array($tag, $plasmaversionTags)) { 1113 $version = null; 1114 $pos = strrpos($tag, '-'); 1115 if ($pos) { 1116 $version = substr($tag, $pos + 1); 1117 } 1118 $projTags .= "plasma##majorversion=" . $version . ","; 1119 } else { 1120 $projTags .= $tag . ","; 1121 } 1122 } 1123 1124 $projTags = rtrim($projTags, ","); 1125 } 1126 1127 if ($this->_format == 'json') { 1128 $response = array('status' => 'ok', 1129 'statuscode' => 100, 1130 'message' => '', 1131 'data' => array(array('details' => 'full', 1132 'id' => $project->project_id, 1133 'name' => $project->title, 1134 'version' => $project->version, 1135 'typeid' => $project->project_category_id, 1136 'typename' => $project->cat_title, 1137 'xdg_type' => $categoryXdgType, 1138 'language' => '', 1139 'personid' => $project->username, 1140 'created' => $created, 1141 'changed' => $changed, 1142 'downloads' => $downloads, 1143 'score' => $score, 1144 'summary' => '', 1145 'description' => $project->description, 1146 'changelog' => '', 1147 'feedbackurl' => $previewPage, 1148 'homepage' => $previewPage, 1149 'homepagetype' => '', 1150 'donationpage' => $donationPage, 1151 'comments' => $project->count_comments, 1152 'commentspage' => $previewPage, 1153 'fans' => null, 1154 'fanspage' => '', 1155 'knowledgebaseentries' => null, 1156 'knowledgebasepage' => '', 1157 'depend' => '', 1158 'preview1' => $previewPage, 1159 'icon' => '', 1160 'video' => '', 1161 'detailpage' => $previewPage, 1162 'ghns_excluded' => $project->ghns_excluded, 1163 'tags' => $projTags) + $previewPics + $smallPreviewPics + $downloadItems)); 1164 } else { 1165 foreach ($previewPics as $key => $value) { 1166 $previewPics[$key] = array('@text' => $value); 1167 } 1168 foreach ($smallPreviewPics as $key => $value) { 1169 $smallPreviewPics[$key] = array('@text' => $value); 1170 } 1171 if ($downloadItems) { 1172 foreach ($downloadItems as $key => $value) { 1173 $downloadItems[$key] = array('@text' => $value); 1174 } 1175 } 1176 $response = array('meta' => array('status' => array('@text' => 'ok'), 1177 'statuscode' => array('@text' => 100), 1178 'message' => array('@text' => '')), 1179 'data' => array('content' => array('details' => 'full', 1180 'id' => array('@text' => $project->project_id), 1181 'name' => array('@text' => $project->title), 1182 'version' => array('@text' => $project->version), 1183 'typeid' => array('@text' => $project->project_category_id), 1184 'typename' => array('@text' => $project->cat_title), 1185 'xdg_type' => array('@text' => $categoryXdgType), 1186 'language' => array('@text' => ''), 1187 'personid' => array('@text' => $project->username), 1188 'created' => array('@text' => $created), 1189 'changed' => array('@text' => $changed), 1190 'downloads' => array('@text' => $downloads), 1191 'score' => array('@text' => $score), 1192 'summary' => array('@text' => ''), 1193 'description' => array('@cdata' => $project->description), 1194 'changelog' => array('@text' => ''), 1195 'feedbackurl' => array('@text' => $previewPage), 1196 'homepage' => array('@text' => $previewPage), 1197 'homepagetype' => array('@text' => ''), 1198 'donationpage' => array('@text' => $donationPage), 1199 'comments' => array('@text' => $project->count_comments), 1200 'commentspage' => array('@text' => $previewPage), 1201 'fans' => array('@text' => null), 1202 'fanspage' => array('@text' => ''), 1203 'knowledgebaseentries' => array('@text' => null), 1204 'knowledgebasepage' => array('@text' => ''), 1205 'depend' => array('@text' => ''), 1206 'preview1' => array('@text' => $previewPage), 1207 'icon' => array('@text' => ''), 1208 'video' => array('@text' => ''), 1209 'detailpage' => array('@text' => $previewPage), 1210 'ghns_excluded' => array('@text' => $project->ghns_excluded), 1211 'tags' => array('@text' => $projTags)) + $previewPics + $smallPreviewPics + $downloadItems)); 1212 } 1213 1214 $cache->save($response, $cacheName); 1215 1216 return $response; 1217 } 1218 1219 /** 1220 * @param Zend_Db_Table $tableProject 1221 * 1222 * @param bool $withSqlCalcFoundRows 1223 * 1224 * @return Zend_Db_Table_Select 1225 * @throws Zend_Db_Select_Exception 1226 */ 1227 protected function _buildProjectSelect($tableProject, $withSqlCalcFoundRows = false) 1228 { 1229 $tableProjectSelect = $tableProject->select(); 1230 if ($withSqlCalcFoundRows) { 1231 $tableProjectSelect->from(array('project' => 'stat_projects'), array(new Zend_Db_Expr('SQL_CALC_FOUND_ROWS *'))); 1232 } else { 1233 $tableProjectSelect->from(array('project' => 'stat_projects')); 1234 } 1235 $tableProjectSelect->setIntegrityCheck(false) 1236 ->columns(array( 1237 'member_username' => 'username', 1238 'category_title' => 'cat_title', 1239 'xdg_type' => 'cat_xdg_type', 1240 'name_legacy' => 'cat_name_legacy', 1241 new Zend_Db_Expr("(select count(1) as num_files from ppload.ppload_files f where f.active = 1 and f.collection_id = project.ppload_collection_id group by f.collection_id) as num_files"), 1242 new Zend_Db_Expr("(select count(1) AS `amount` from `stat_downloads_24h` `s` WHERE s.collection_id = project.ppload_collection_id group by `s`.`collection_id`) as num_dls"), 1243 new Zend_Db_Expr("(select sum(downloaded_count) from ppload.ppload_files pf where pf.collection_id = project.ppload_collection_id and `active` = 1 and ocs_compatible = 1) as num_downloads") 1244 ) 1245 ) 1246 ->where('project.status = ?', Application_Model_DbTable_Project::PROJECT_ACTIVE) 1247 ->where('project.ppload_collection_id IS NOT NULL') 1248 ; 1249 $tableProjectSelect->having('num_files > 0'); 1250 1251 return $tableProjectSelect; 1252 } 1253 1254 /** 1255 * @param Zend_Db_Table_Row_Abstract $project 1256 * @param array $previewPicSize 1257 * @param array $smallPreviewPicSize 1258 * 1259 * @return array 1260 * @throws Zend_Cache_Exception 1261 * @throws Zend_Exception 1262 */ 1263 protected function getGalleryPictures($project, $previewPicSize, $smallPreviewPicSize) 1264 { 1265 /** @var Zend_Cache_Core $cache */ 1266 $cache = Zend_Registry::get('cache'); 1267 $cacheName = 'api_fetch_gallery_pics_' . $project->project_id; 1268 1269 if (($previews = $cache->load($cacheName))) { 1270 return $previews; 1271 } 1272 1273 $viewHelperImage = new Application_View_Helper_Image(); 1274 $previewPics = array('previewpic1' => $viewHelperImage->Image($project->image_small, $previewPicSize)); 1275 $smallPreviewPics = array('smallpreviewpic1' => $viewHelperImage->Image($project->image_small, $smallPreviewPicSize)); 1276 1277 $tableProject = new Application_Model_Project(); 1278 $galleryPics = $tableProject->getGalleryPictureSources($project->project_id); 1279 if ($galleryPics) { 1280 $i = 2; 1281 foreach ($galleryPics as $galleryPic) { 1282 $previewPics['previewpic' . $i] = $viewHelperImage->Image($galleryPic, $previewPicSize); 1283 $smallPreviewPics['smallpreviewpic' . $i] = $viewHelperImage->Image($galleryPic, $smallPreviewPicSize); 1284 $i++; 1285 } 1286 } 1287 1288 $cache->save(array($previewPics, $smallPreviewPics), $cacheName); 1289 1290 return array($previewPics, $smallPreviewPics); 1291 } 1292 1293 /** 1294 * @param Zend_Db_Table_Row_Abstract $project 1295 * @param Ppload_Api $pploadApi 1296 * @param int $downloads 1297 * @param string $fileIds 1298 * 1299 * @return array 1300 * @throws Zend_Cache_Exception 1301 * @throws Zend_Exception 1302 */ 1303 protected function getPPLoadInfo($project, $pploadApi, $downloads, $fileIds = null) 1304 { 1305 $downloadItems = array(); 1306 1307 if (empty($project->ppload_collection_id)) { 1308 return array($downloadItems, $downloads); 1309 } 1310 1311 /** @var Zend_Cache_Core $cache */ 1312 $cache = Zend_Registry::get('cache'); 1313 $cacheName = 'api_ppload_collection_by_id_' . $project->ppload_collection_id; 1314 1315 if ($fileIds && count($fileIds) > 0) { 1316 $cacheName .= '_' . md5($fileIds); 1317 } 1318 1319 // if (false !== ($pploadInfo = $cache->load($cacheName))) { 1320 // return $pploadInfo; 1321 // } 1322 1323 $tagTable = new Application_Model_Tags(); 1324 1325 //if filter for fileIds 1326 //if($fileIds && count($fileIds) > 0) { 1327 // $filesRequest['ids'] = $fileIds; 1328 //} 1329 1330 //Load Files from DB 1331 $pploadFileTable = new Application_Model_DbTable_PploadFiles(); 1332 $files = $pploadFileTable->fetchAllActiveFilesForFileInfo($project->ppload_collection_id, $fileIds); 1333 1334 $sql = " SELECT * 1335 FROM `ppload`.`ppload_files` `f` 1336 WHERE `f`.`collection_id` = :collection_id 1337 AND `f`.`ocs_compatible` = 1 1338 AND `f`.`active` = 1 1339 "; 1340 if (null != $fileIds && count($fileIds) > 0) { 1341 $sql .= " and f.id in (" . $fileIds . ")"; 1342 } 1343 1344 $packageTypeTags = $tagTable->getAllFilePackageTypeTags(); 1345 $architectureTags = $tagTable->getAllFileArchitectureTags(); 1346 $plasmaversionTags = $tagTable->getAllFilePlasmaVersionTags(); 1347 1348 $i = 1; 1349 foreach ($files as $file) { 1350 //get File-Tags from DB 1351 $fileTagArray = $tagTable->getTagsAsArray($file['id'], $tagTable::TAG_TYPE_FILE); 1352 1353 //create ppload download hash: secret + collection_id + expire-timestamp 1354 list($timestamp, $hash) = $this->createDownloadHash($project); 1355 1356 //$tags = $this->_parseFileTags($file->tags); 1357 1358 //collect tags 1359 $fileTags = ""; 1360 1361 //mimetype 1362 // $fileTags .= "data##mimetype=" . $file['type'] . ","; 1363 if ($file['type'] && strpos($file['type'], 'charset=') !== false) { 1364 $types = explode(";", $file['type']); 1365 if (sizeof($types) == 2) { 1366 $fileTags .= "data##mimetype=" . trim($types[0]) . ","; 1367 $fileTags .= "data##" . trim($types[1]) . ","; 1368 } else { 1369 $fileTags .= "data##mimetype=" . $file['type'] . ","; 1370 } 1371 } else { 1372 $fileTags .= "data##mimetype=" . $file['type'] . ","; 1373 } 1374 1375 //$fileTags .= "tags=".$fileTagArray->__toString().","; 1376 1377 1378 $tagTable = new Application_Model_Tags(); 1379 1380 foreach ($fileTagArray as $tag) { 1381 if (in_array($tag, $packageTypeTags)) { 1382 $fileTags .= "application##packagetype=" . $tag . ","; 1383 } else { 1384 if (in_array($tag, $architectureTags)) { 1385 $fileTags .= "application##architecture=" . $tag . ","; 1386 } else { 1387 if (in_array($tag, $plasmaversionTags)) { 1388 $version = null; 1389 $pos = strrpos($tag, '-'); 1390 if ($pos) { 1391 $version = substr($tag, $pos + 1); 1392 } 1393 $fileTags .= "plasma##majorversion=" . $version . ","; 1394 } 1395 } 1396 } 1397 } 1398 1399 $fileTags = rtrim($fileTags, ","); 1400 1401 1402 $downloads += (int)$file['downloaded_count']; 1403 1404 //$downloadLink = PPLOAD_API_URI . 'files/download/id/' . $file['id'] . '/s/' . $hash . '/t/' . $timestamp . '/o/1/' . $file['name']; 1405 1406 $payload = array('id' => $file['id'], 'o' => '1'); 1407 $downloadLink = Application_Model_PpLoad::createDownloadUrlJwt($project->ppload_collection_id, $file['name'], $payload); 1408 1409 $downloadItems['downloadway' . $i] = 1; 1410 $downloadItems['downloadtype' . $i] = ''; 1411 $downloadItems['downloadprice' . $i] = '0'; 1412 $downloadItems['downloadlink' . $i] = $downloadLink; 1413 $downloadItems['downloadname' . $i] = $file['name']; 1414 $downloadItems['downloadsize' . $i] = round($file['size'] / 1024); 1415 $downloadItems['downloadgpgfingerprint' . $i] = ''; 1416 $downloadItems['downloadgpgsignature' . $i] = ''; 1417 $downloadItems['downloadpackagename' . $i] = ''; 1418 $downloadItems['downloadrepository' . $i] = ''; 1419 $downloadItems['download_package_type' . $i] = null; 1420 $downloadItems['download_package_arch' . $i] = null; 1421 //$downloadItems['downloadtags' . $i] = empty($tags['filetags']) ? '' : implode(',', $tags['filetags']); 1422 $downloadItems['downloadtags' . $i] = empty($fileTags) ? '' : $fileTags; 1423 $downloadItems['downloadmd5sum' . $i] = empty($file['md5sum']) ? '' : $file['md5sum']; 1424 $i++; 1425 1426 } 1427 1428 $cache->save(array($downloadItems, $downloads), $cacheName, array(), (self::CACHE_PERIOD_VALIDITY * 3600)); 1429 1430 return array($downloadItems, $downloads); 1431 } 1432 1433 /** 1434 * @param $project 1435 * 1436 * @return array 1437 */ 1438 protected function createDownloadHash($project) 1439 { 1440 //create ppload download hash: secret + collection_id + expire-timestamp 1441 $salt = PPLOAD_DOWNLOAD_SECRET; 1442 $collectionID = $project->ppload_collection_id; 1443 $timestamp = time() + (3600 * self::DOWNLOAD_PERIOD_VALIDITY); 1444 $hash = md5($salt . $collectionID . $timestamp); 1445 1446 return array($timestamp, $hash); 1447 } 1448 1449 /** 1450 * @param array $previewPicSize 1451 * @param array $smallPreviewPicSize 1452 * @param Ppload_Api $pploadApi 1453 * @param boolean $debugMode Is debug mode 1454 * 1455 * @param bool $nocache 1456 * 1457 * @return array 1458 * @throws Zend_Auth_Adapter_Exception 1459 * @throws Zend_Auth_Storage_Exception 1460 * @throws Zend_Cache_Exception 1461 * @throws Zend_Db_Select_Exception 1462 * @throws Zend_Db_Statement_Exception 1463 * @throws Zend_Exception 1464 */ 1465 protected function fetchCategoryContent($previewPicSize, 1466 $smallPreviewPicSize, 1467 $pploadApi, 1468 $debugMode, 1469 $nocache = false) 1470 { 1471 $limit = 10; // 1 - 100 1472 $offset = 0; 1473 1474 $tableProject = new Application_Model_Project(); 1475 $tableProjectSelect = $this->_buildProjectSelect($tableProject, true); 1476 1477 $storeTags = Zend_Registry::isRegistered('config_store_tags') ? Zend_Registry::get('config_store_tags') : null; 1478 1479 if ($storeTags) { 1480 $tagList = $storeTags; 1481 //build where statement für projects 1482 $selectAnd = $tableProject->select(); 1483 $selectAndFiles = $tableProject->select(); 1484 1485 $tableTags = new Application_Model_Tags(); 1486 $possibleFileTags = $tableTags->fetchAllFileTagNamesAsArray(); 1487 1488 if (!is_array($tagList)) { 1489 $tagList = array($tagList); 1490 } 1491 1492 foreach ($tagList as $item) { 1493 #and 1494 $selectAnd->where('find_in_set(?, tag_ids)', $item); 1495 if (in_array($item, $possibleFileTags)) { 1496 $selectAndFiles->where('find_in_set(?, tag_ids)', $item); 1497 } else { 1498 $selectAndFiles->where("1=1"); 1499 } 1500 } 1501 $tableProjectSelect->where(implode(' ', $selectAnd->getPart('where'))); 1502 } 1503 1504 if (false === empty($this->_params['categories'])) { 1505 // categories parameter: values separated by "," 1506 // legacy OCS API compatible: values separated by "x" 1507 if (strpos($this->_params['categories'], ',') !== false) { 1508 $catList = explode(',', $this->_params['categories']); 1509 } else { 1510 $catList = explode('x', $this->_params['categories']); 1511 } 1512 1513 $modelProjectCategories = new Application_Model_DbTable_ProjectCategory(); 1514 $allCategories = array_merge($catList, $modelProjectCategories->fetchChildIds($catList)); 1515 $tableProjectSelect->where('project.project_category_id IN (?)', $allCategories); 1516 } 1517 1518 if (!empty($this->_params['xdg_types'])) { 1519 // xdg_types parameter: values separated by "," 1520 $xdgTypeList = explode(',', $this->_params['xdg_types']); 1521 $tableProjectSelect->where('category.xdg_type IN (?)', $xdgTypeList); 1522 } 1523 1524 $hasSearchPart = false; 1525 if (false === empty($this->_params['search'])) { 1526 foreach (explode(' ', $this->_params['search']) as $keyword) { 1527 if ($keyword && strlen($keyword) > 2) { 1528 $tableProjectSelect->where('project.title LIKE ? OR project.description LIKE ?', "%$keyword%"); 1529 $hasSearchPart = true; 1530 } 1531 } 1532 } 1533 1534 if (false === empty($this->_params['tags'])) { 1535 // tags parameter: values separated by "," and | for or filter 1536 if (strpos($this->_params['tags'], ',') !== false) { 1537 $tagList = explode(',', $this->_params['tags']); 1538 } else { 1539 $tagList = array($this->_params['tags']); 1540 } 1541 1542 //build where statement for projects 1543 $selectAnd = $tableProject->select(); 1544 $selectAndFiles = $tableProject->select(); 1545 1546 $tableTags = new Application_Model_Tags(); 1547 $possibleFileTags = $tableTags->fetchAllFileTagNamesAsArray(); 1548 1549 foreach ($tagList as $item) { 1550 if (strpos($item, '|') !== false) { 1551 #or 1552 $selectOr = $tableProject->select(); 1553 $selectOrFiles = $tableProject->select(); 1554 $tagListOr = explode('|', $item); 1555 foreach ($tagListOr as $itemOr) { 1556 $selectOr->orWhere('find_in_set(?, tags)', $itemOr); 1557 if (in_array($itemOr, $possibleFileTags)) { 1558 $selectOrFiles->orWhere('find_in_set(?, tags)', $itemOr); 1559 } 1560 } 1561 $selectAnd->where(implode(' ', $selectOr->getPart('where'))); 1562 1563 $selectAndFiles->where(implode(' ', $selectOrFiles->getPart('where'))); 1564 } else { 1565 #and 1566 $selectAnd->where('find_in_set(?, tags)', $item); 1567 if (in_array($item, $possibleFileTags)) { 1568 $selectAndFiles->where('find_in_set(?, tags)', $item); 1569 } else { 1570 $selectAndFiles->where("1=1"); 1571 } 1572 } 1573 1574 } 1575 $tableProjectSelect->where(implode(' ', $selectAnd->getPart('where'))); 1576 } else { 1577 $selectAndFiles = $tableProject->select(); 1578 $selectAndFiles->where("1=1"); 1579 } 1580 1581 if (!empty($this->_params['ghns_excluded'])) { 1582 $tableProjectSelect->where('project.ghns_excluded = ?', $this->_params['ghns_excluded']); 1583 } 1584 1585 if (!empty($this->_params['user'])) { 1586 $tableProjectSelect->where('project.username = ?', $this->_params['user']); 1587 } 1588 1589 if (!empty($this->_params['external'])) { 1590 } 1591 1592 if (!empty($this->_params['distribution'])) { 1593 // distribution parameter: comma separated list of ids 1594 } 1595 1596 if (!empty($this->_params['showfavorites'])) { 1597 // if = 1 then show auth users favorites 1598 if ($this->_params['showfavorites'] == 1 && null != $this->_authData) { 1599 $member_id = $this->_authData->member_id; 1600 $tableProjectSelect->where('project_follower.member_id = ?', $member_id); 1601 $tableProjectSelect->setIntegrityCheck(false) 1602 ->join('project_follower', 'project.project_id = project_follower.project_id', array('project_follower_id')) 1603 ; 1604 } 1605 } 1606 1607 if (!empty($this->_params['license'])) { 1608 // license parameter: comma separated list of ids 1609 } 1610 1611 if (!empty($this->_params['sortmode'])) { 1612 // sortmode parameter: new|alpha|high|down 1613 switch (strtolower($this->_params['sortmode'])) { 1614 case 'new': 1615 $tableProjectSelect->order('project.created_at DESC'); 1616 1617 break; 1618 case 'alpha': 1619 $tableProjectSelect->order('project.title ASC'); 1620 1621 break; 1622 case 'high': 1623 $tableProjectSelect->order('laplace_score DESC'); 1624 $tableProjectSelect->order('project.created_at DESC'); 1625 1626 break; 1627 case 'down': 1628 $tableProjectSelect->order('num_downloads DESC'); 1629 $tableProjectSelect->order('project.created_at DESC'); 1630 1631 break; 1632 default: 1633 break; 1634 } 1635 } 1636 1637 if (isset($this->_params['pagesize']) && ctype_digit((string)$this->_params['pagesize']) && $this->_params['pagesize'] > 0 && $this->_params['pagesize'] < 101) { 1638 $limit = $this->_params['pagesize']; 1639 } 1640 1641 if (isset($this->_params['page']) && ctype_digit((string)$this->_params['page'])) { 1642 // page parameter: the first page is 0 1643 $offset = $limit * $this->_params['page']; 1644 } 1645 1646 $tableProjectSelect->limit($limit, $offset); 1647 1648 1649 /** @var Zend_Cache_Core $cache */ 1650 $cache = Zend_Registry::get('cache'); 1651 $storeName = Zend_Registry::get('store_config')->name; 1652 $cacheName = 'api_fetch_category_' . md5($tableProjectSelect->__toString() . '_' . $selectAndFiles->__toString() . '_' . $storeName . '_' . $this->_format); 1653 $cacheNameCount = 'api_fetch_category_' . md5($tableProjectSelect->__toString() . '_' . $selectAndFiles->__toString() . '_' . $storeName . '_' . $this->_format) . '_count'; 1654 $contentsList = false; 1655 $count = 0; 1656 $isFromCache = false; 1657 1658 //ignore cache, if param nocache is set 1659 if ($nocache == true) { 1660 $projects = $tableProject->fetchAll($tableProjectSelect); 1661 $counter = $tableProject->getAdapter()->fetchRow('select FOUND_ROWS() AS counter'); 1662 $count = $counter['counter']; 1663 1664 if (count($projects) > 0) { 1665 $contentsList = $this->_buildContentList($previewPicSize, $smallPreviewPicSize, $pploadApi, $projects, implode(' ', $selectAndFiles->getPart('where'))); 1666 } else { 1667 $contentsList = array(); 1668 } 1669 } else { 1670 if (false === $hasSearchPart) { 1671 $contentsList = $cache->load($cacheName); 1672 $count = $cache->load($cacheNameCount); 1673 } 1674 1675 if (false == $contentsList) { 1676 $projects = $tableProject->fetchAll($tableProjectSelect); 1677 $counter = $tableProject->getAdapter()->fetchRow('select FOUND_ROWS() AS counter'); 1678 $count = $counter['counter']; 1679 1680 if (count($projects) > 0) { 1681 $contentsList = $this->_buildContentList($previewPicSize, $smallPreviewPicSize, $pploadApi, $projects, implode(' ', $selectAndFiles->getPart('where'))); 1682 if (false === $hasSearchPart) { 1683 $cache->save($contentsList, $cacheName, array(), 900); 1684 $cache->save($count, $cacheNameCount, array(), 900); 1685 } 1686 } else { 1687 $contentsList = array(); 1688 } 1689 } else { 1690 $isFromCache = true; 1691 } 1692 } 1693 1694 if ($this->_format == 'json') { 1695 $response = array('status' => 'ok', 1696 'statuscode' => 100, 1697 'message' => '', 1698 'totalitems' => $count, 1699 'itemsperpage' => $limit, 1700 'data' => $contentsList); 1701 } else { 1702 $response = array('meta' => array('status' => array('@text' => 'ok'), 1703 'statuscode' => array('@text' => 100), 1704 'message' => array('@text' => ''), 1705 'totalitems' => array('@text' => $count), 1706 'itemsperpage' => array('@text' => $limit)), 1707 'data' => array()); 1708 if (count($contentsList) > 0) { 1709 $response['data']['content'] = $contentsList; 1710 } 1711 } 1712 1713 1714 if ($debugMode) { 1715 $response['meta']['debug']['is_from_cache_now'] = $isFromCache; 1716 $response['meta']['debug']['select_project'] = $tableProjectSelect->__toString(); 1717 $response['meta']['debug']['select_files'] = $selectAndFiles->__toString(); 1718 $response['meta']['debug']['store_client_name'] = $this->_getNameForStoreClient(); 1719 $response['meta']['debug']['param_store_client_name'] = $this->getParam('domain_store_id'); 1720 $response['meta']['debug']['hello'] = 'World'; 1721 } 1722 1723 return $response; 1724 } 1725 1726 /** 1727 * @param $previewPicSize 1728 * @param $smallPreviewPicSize 1729 * @param $pploadApi 1730 * @param $projects 1731 * @param String $selectWhereString 1732 * 1733 * @return array 1734 * @throws Zend_Cache_Exception 1735 * @throws Zend_Exception 1736 */ 1737 protected function _buildContentList($previewPicSize, 1738 $smallPreviewPicSize, 1739 $pploadApi, 1740 $projects, 1741 $selectWhereString) 1742 { 1743 $contentsList = array(); 1744 $helperTruncate = new Application_View_Helper_Truncate(); 1745 $selectWhereString = ' AND ' . $selectWhereString; 1746 foreach ($projects as $project) { 1747 $project->description = $helperTruncate->truncate(Application_Model_BBCode::renderHtml(Application_Model_HtmlPurify::purify($project->description)), 300); 1748 1749 $categoryXdgType = ''; 1750 if (!empty($project->xdg_type)) { 1751 $categoryXdgType = $project->xdg_type; 1752 } 1753 1754 $created = date('c', strtotime($project->created_at)); 1755 $changed = date('c', strtotime($project->changed_at)); 1756 1757 $previewPage = $this->_uriScheme . '://' . $this->_config['website'] . '/p/' . $project->project_id; 1758 1759 list($previewPics, $smallPreviewPics) = $this->getGalleryPictures($project, $previewPicSize, $smallPreviewPicSize); 1760 1761 $downloads = $project->count_downloads_hive; 1762 1763 //Get Files from OCS-API 1764 //get the list of file-ids from tags-filter 1765 $fileIds = ""; 1766 $filesList = array(); 1767 $tableTags = new Application_Model_Tags(); 1768 $filesList = $tableTags->getFilesForTags($project->project_id, $selectWhereString); 1769 1770 //if there is a tag filter and we have found any files, skip this project 1771 if ($selectWhereString <> ' AND (1=1)' && (empty($filesList) || count($filesList) == 0)) { 1772 //echo "No files found for project ".$project->project_id; 1773 continue; 1774 } 1775 1776 foreach ($filesList as $file) { 1777 $fileIds .= $file['file_id'] . ','; 1778 } 1779 $fileIds = rtrim($fileIds, ","); 1780 1781 //var_dump($fileIds); 1782 1783 list($downloadItems, $downloads) = $this->getPPLoadInfo($project, $pploadApi, $downloads, $fileIds); 1784 1785 //If no files available, do not show this project 1786 if (empty($downloadItems)) { 1787 continue; // jump to next product 1788 } 1789 1790 $score = $project->laplace_score; 1791 $score = round($score / 10, 0); 1792 1793 $projTags = ""; 1794 //special for plasma-version-tags 1795 if (!empty($project->tags)) { 1796 //get File-Tags from Product 1797 $fileTagArray = explode(',', $project->tags); 1798 //collect tags 1799 $tagTable = new Application_Model_Tags(); 1800 $plasmaversionTags = $tagTable->getAllFilePlasmaVersionTags(); 1801 foreach ($fileTagArray as $tag) { 1802 if (in_array($tag, $plasmaversionTags)) { 1803 $version = null; 1804 $pos = strrpos($tag, '-'); 1805 if ($pos) { 1806 $version = substr($tag, $pos + 1); 1807 } 1808 $projTags .= "plasma##majorversion=" . $version . ","; 1809 } else { 1810 $projTags .= $tag . ","; 1811 } 1812 } 1813 1814 $projTags = rtrim($projTags, ","); 1815 } 1816 1817 if ($this->_format == 'json') { 1818 $contentsList[] = array('details' => 'summary', 1819 'id' => $project->project_id, 1820 'name' => $project->title, 1821 'version' => $project->version, 1822 'typeid' => $project->project_category_id, 1823 'typename' => $project->cat_title, 1824 'xdg_type' => $categoryXdgType, 1825 'language' => '', 1826 'personid' => $project->member_username, 1827 'created' => $created, 1828 'changed' => $changed, 1829 'downloads' => $project->num_downloads, 1830 'score' => $score, 1831 'summary' => '', 1832 'description' => $project->description, 1833 'comments' => $project->count_comments, 1834 'ghns_excluded' => $project->ghns_excluded, 1835 'preview1' => $previewPage, 1836 'detailpage' => $previewPage, 1837 'tags' => $projTags) + $previewPics + $smallPreviewPics + $downloadItems; 1838 } else { 1839 foreach ($previewPics as $key => $value) { 1840 $previewPics[$key] = array('@text' => $value); 1841 } 1842 foreach ($smallPreviewPics as $key => $value) { 1843 $smallPreviewPics[$key] = array('@text' => $value); 1844 } 1845 if ($downloadItems) { 1846 foreach ($downloadItems as $key => $value) { 1847 $downloadItems[$key] = array('@text' => $value); 1848 } 1849 } 1850 $contentsList[] = array('details' => 'summary', 1851 'id' => array('@text' => $project->project_id), 1852 'name' => array('@text' => $project->title), 1853 'version' => array('@text' => $project->version), 1854 'typeid' => array('@text' => $project->project_category_id), 1855 'typename' => array('@text' => $project->cat_title), 1856 'xdg_type' => array('@text' => $categoryXdgType), 1857 'language' => array('@text' => ''), 1858 'personid' => array('@text' => $project->member_username), 1859 'created' => array('@text' => $created), 1860 'changed' => array('@text' => $changed), 1861 'downloads' => array('@text' => $project->num_downloads), 1862 'score' => array('@text' => $score), 1863 'summary' => array('@text' => ''), 1864 'description' => array('@cdata' => $project->description), 1865 'comments' => array('@text' => $project->count_comments), 1866 'ghns_excluded' => array('@text' => $project->ghns_excluded), 1867 'preview1' => array('@text' => $previewPage), 1868 'detailpage' => array('@text' => $previewPage), 1869 'tags' => array('@text' => $projTags)) + $previewPics + $smallPreviewPics + $downloadItems; 1870 } 1871 } 1872 1873 return $contentsList; 1874 } 1875 1876 /** 1877 * @throws DOMException 1878 * @throws Zend_Exception 1879 */ 1880 public function contentdownloadAction() 1881 { 1882 $project = null; 1883 $file = null; 1884 1885 if ($this->getParam('contentid')) { 1886 $tableProject = new Application_Model_Project(); 1887 $project = $tableProject->fetchRow($tableProject->select() 1888 ->where('project_id = ?', $this->getParam('contentid')) 1889 ->where('status = ?', Application_Model_DbTable_Project::PROJECT_ACTIVE)); 1890 } 1891 1892 if (!$project) { 1893 $this->_sendErrorResponse(101, 'content not found'); 1894 } 1895 1896 if (((int)$this->getParam('itemid')) === 0) { 1897 $this->_sendErrorResponse(103, 'content item not found'); 1898 } 1899 1900 if ($project->ppload_collection_id && $this->getParam('itemid') && ctype_digit((string)$this->getParam('itemid'))) { 1901 $tagTable = new Application_Model_Tags(); 1902 1903 //Load Files from DB 1904 $pploadFileTable = new Application_Model_DbTable_PploadFiles(); 1905 $files = $pploadFileTable->fetchActiveFileWithIndex($project->ppload_collection_id, $this->getParam('itemid')); 1906 1907 if (empty($files)) { 1908 $this->_sendErrorResponse(103, 'content item not found'); 1909 } 1910 1911 $packageTypeTags = $tagTable->getAllFilePackageTypeTags(); 1912 $architectureTags = $tagTable->getAllFileArchitectureTags(); 1913 $plasmaversionTags = $tagTable->getAllFilePlasmaVersionTags(); 1914 1915 $fileTags = ""; 1916 foreach ($files as $file) { 1917 //get File-Tags from DB 1918 $fileTagArray = $tagTable->getTagsAsArray($file['id'], $tagTable::TAG_TYPE_FILE); 1919 1920 //create ppload download hash: secret + collection_id + expire-timestamp 1921 list($timestamp, $hash) = $this->createDownloadHash($project); 1922 1923 //$tags = $this->_parseFileTags($file->tags); 1924 1925 //collect tags 1926 $fileTags = ""; 1927 1928 //mimetype 1929 //$fileTags .= "data##mimetype=" . $file['type'] . ","; 1930 1931 if ($file['type'] && strpos($file['type'], 'charset=') !== false) { 1932 $types = explode(";", $file['type']); 1933 if (sizeof($types) == 2) { 1934 $fileTags .= "data##mimetype=" . trim($types[0]) . ","; 1935 $fileTags .= "data##" . trim($types[1]) . ","; 1936 } else { 1937 $fileTags .= "data##mimetype=" . $file['type'] . ","; 1938 } 1939 } else { 1940 $fileTags .= "data##mimetype=" . $file['type'] . ","; 1941 } 1942 1943 //$fileTags .= "tags=".$fileTagArray->__toString().","; 1944 1945 1946 $tagTable = new Application_Model_Tags(); 1947 1948 foreach ($fileTagArray as $tag) { 1949 if (in_array($tag, $packageTypeTags)) { 1950 $fileTags .= "application##packagetype=" . $tag . ","; 1951 } else { 1952 if (in_array($tag, $architectureTags)) { 1953 $fileTags .= "application##architecture=" . $tag . ","; 1954 } else { 1955 if (in_array($tag, $plasmaversionTags)) { 1956 $version = null; 1957 $pos = strrpos($tag, '-'); 1958 if ($pos) { 1959 $version = substr($tag, $pos + 1); 1960 } 1961 $fileTags .= "plasma##majorversion=" . $version . ","; 1962 } 1963 } 1964 } 1965 } 1966 1967 $fileTags = rtrim($fileTags, ","); 1968 1969 //$downloadLink = PPLOAD_API_URI . 'files/download/id/' . $file['id'] . '/s/' . $hash . '/t/' . $timestamp . '/o/1/' . $file['name']; 1970 1971 $payload = array('id' => $file['id'], 'o' => '1'); 1972 $downloadLink = Application_Model_PpLoad::createDownloadUrlJwt($project->ppload_collection_id, $file['name'], $payload); 1973 1974 if ($this->_format == 'json') { 1975 $response = array('status' => 'ok', 1976 'statuscode' => 100, 1977 'message' => '', 1978 'data' => array(array('details' => 'download', 1979 'downloadway' => 1, 1980 'downloadlink' => $downloadLink, 1981 'mimetype' => $file['type'], 1982 'gpgfingerprint' => '', 1983 'gpgsignature' => '', 1984 'packagename' => '', 1985 'repository' => '', 1986 'download_package_type' => null, 1987 'download_package_arch' => null, 1988 'downloadtags' => empty($fileTags) ? '' : $fileTags, 1989 'downloadmd5sum' => empty($file['md5sum']) ? '' : $file['md5sumd']))); 1990 } else { 1991 $response = array('meta' => array('status' => array('@text' => 'ok'), 1992 'statuscode' => array('@text' => 100), 1993 'message' => array('@text' => '')), 1994 'data' => array('content' => array('details' => 'download', 1995 'downloadway' => array('@text' => 1), 1996 'downloadlink' => array('@text' => $downloadLink), 1997 'mimetype' => array('@text' => $file['type']), 1998 'gpgfingerprint' => array('@text' => ''), 1999 'gpgsignature' => array('@text' => ''), 2000 'packagename' => array('@text' => ''), 2001 'repository' => array('@text' => ''), 2002 'download_package_type' => array('@text' => ''), 2003 'download_package_arch' => array('@text' => ''), 2004 'downloadtags' => array('@text' => empty($fileTags) ? '' : $fileTags), 2005 'downloadmd5sum' => array('@text' => empty($file['md5sum']) ? '' : $file['md5sum'])))); 2006 } 2007 2008 } 2009 2010 } 2011 2012 $this->_sendResponse($response, $this->_format); 2013 } 2014 2015 public function contentpreviewpicAction() 2016 { 2017 $project = null; 2018 2019 if ($this->getParam('contentid')) { 2020 $tableProject = new Application_Model_Project(); 2021 $project = $tableProject->fetchRow($tableProject->select() 2022 ->where('project_id = ?', $this->getParam('contentid')) 2023 ->where('status = ?', Application_Model_DbTable_Project::PROJECT_ACTIVE)); 2024 } 2025 2026 if (!$project) { 2027 //$this->_sendErrorResponse(101, 'content not found'); 2028 header('Location: ' . $this->_config['icon']); 2029 exit; 2030 } 2031 2032 $previewPicSize = array('width' => 100, 2033 'height' => 100); 2034 2035 if (!empty($this->_params['size']) && strtolower($this->_params['size']) == 'medium') { 2036 $previewPicSize = array('width' => 770, 2037 'height' => 540); 2038 } 2039 2040 $viewHelperImage = new Application_View_Helper_Image(); 2041 $previewPicUri = $viewHelperImage->Image($project->image_small, $previewPicSize); 2042 2043 header('Location: ' . $previewPicUri); 2044 exit; 2045 } 2046 2047 /** 2048 * @throws Zend_Exception 2049 * @throws Zend_Cache_Exception 2050 * @throws DOMException 2051 */ 2052 public function commentsAction() 2053 { 2054 if ($this->_format == 'json') { 2055 $response = array('status' => 'ok', 2056 'statuscode' => 100, 2057 'message' => '', 2058 'data' => array()); 2059 } else { 2060 $response = array('meta' => array('status' => array('@text' => 'ok'), 2061 'statuscode' => array('@text' => 100), 2062 'message' => array('@text' => ''),), 2063 'data' => array()); 2064 } 2065 2066 $commentType = (int)$this->getParam('comment_type', -1); 2067 if ($commentType != self::COMMENT_TYPE_CONTENT) { 2068 $this->_sendResponse($response, $this->_format); 2069 } 2070 2071 $contentId = (int)$this->getParam('content_id', null); 2072 if (empty($contentId)) { 2073 $this->_sendResponse($response, $this->_format); 2074 } 2075 2076 $page = (int)$this->getParam('page', 0) + 1; 2077 $pagesize = (int)$this->getParam('pagesize', 10); 2078 2079 /** @var Zend_Cache_Core $cache */ 2080 $cache = Zend_Registry::get('cache'); 2081 $cacheName = 'api_fetch_comments_' . md5("{$commentType}, {$contentId}"); 2082 2083 if (false === ($comments = $cache->load($cacheName))) { 2084 $modelComments = new Application_Model_ProjectComments(); 2085 $comments = $modelComments->getCommentsHierarchic($contentId); 2086 $cache->save($comments, $cacheName, array(), 900); 2087 } 2088 2089 if ($comments->count() == 0) { 2090 $this->_sendResponse($response, $this->_format); 2091 } 2092 2093 $comments->setCurrentPageNumber($page); 2094 $comments->setItemCountPerPage($pagesize); 2095 2096 if ($page > $comments->getPages()->pageCount) { 2097 $this->_sendResponse($response, $this->_format); 2098 } 2099 2100 $response['data'] = $this->_buildCommentList($comments->getCurrentItems()); 2101 2102 $this->_sendResponse($response, $this->_format); 2103 } 2104 2105 /** 2106 * @param Traversable $currentItems 2107 * 2108 * @return array 2109 */ 2110 protected function _buildCommentList($currentItems) 2111 { 2112 $commentList = array(); 2113 foreach ($currentItems as $current_item) { 2114 if ($this->_format == 'json') { 2115 $comment = array('id' => $current_item['comment_id'], 2116 'subject' => $current_item['comment_subject'], 2117 'text' => Application_Model_HtmlPurify::purify($current_item['comment_text_trim']), 2118 'childcount' => $current_item['childcount'], 2119 'user' => $current_item['username'], 2120 'date' => date('c', strtotime($current_item['comment_created_at'])), 2121 'score' => $current_item['comment_score']); 2122 if ($current_item['childcount'] > 0) { 2123 $comment['children'] = $this->_buildCommentList($current_item['children']); 2124 } 2125 } else { 2126 $comment = array('id' => array('@text' => $current_item['comment_id']), 2127 'subject' => array('@text' => $current_item['comment_subject']), 2128 'text' => array('@text' => Application_Model_HtmlPurify::purify($current_item['comment_text_trim'])), 2129 'childcount' => array('@text' => $current_item['childcount']), 2130 'user' => array('@text' => $current_item['username']), 2131 'date' => array('@text' => date('c', strtotime($current_item['comment_created_at']))), 2132 'score' => array('@text' => $current_item['comment_score'])); 2133 if ($current_item['childcount'] > 0) { 2134 $comment['children'] = $this->_buildCommentList($current_item['children']); 2135 } 2136 } 2137 $commentList[] = array('comment' => $comment); 2138 } 2139 2140 return $commentList; 2141 } 2142 2143 /** 2144 * @return void 2145 * @throws DOMException 2146 * @throws Zend_Auth_Adapter_Exception 2147 * @throws Zend_Exception 2148 * @throws DOMException 2149 */ 2150 public function voteAction() 2151 { 2152 //20191215 enable rating 2153 //$this->_sendErrorResponse(405, "method not allowed"); 2154 2155 2156 if ($this->_authenticateUser(null, null, true)) { 2157 2158 Zend_Registry::get('logger')->info('Start Voting') 2159 ; 2160 2161 if ($this->hasParam('contentid') && $this->hasParam('vote')) { 2162 $score = (int)$this->getParam('vote'); 2163 2164 if ($score >= 0 && $score <= 100) { 2165 $msg = ''; 2166 2167 if ($this->hasParam('msg')) { 2168 $msg = trim($this->getParam('msg')); 2169 } 2170 2171 $project_id = (int)$this->getParam('contentid'); 2172 $status = 'ok'; 2173 $message = ''; 2174 2175 Zend_Registry::get('logger')->info('ProjectId: ' . $project_id . ', Vote: ' . $score) 2176 ; 2177 2178 if ($score > 0) { 2179 $score = $this->roundFunction($score) / 10; 2180 } 2181 2182 if ($score == 0) { 2183 $score = 1; 2184 } 2185 2186 if ($msg != '' && strlen($msg) > 0) { 2187 $message = $msg; 2188 } else { 2189 //Get message via score 2190 switch ($score) { 2191 case 1: 2192 $message = '1 ugh'; 2193 break; 2194 case 2: 2195 $message = '2 really bad'; 2196 break; 2197 case 3: 2198 $message = '3 bad'; 2199 break; 2200 case 4: 2201 $message = '4 soso'; 2202 break; 2203 case 5: 2204 $message = '5 average'; 2205 break; 2206 case 6: 2207 $message = '6 okay'; 2208 break; 2209 case 7: 2210 $message = '7 good'; 2211 break; 2212 case 8: 2213 $message = '8 great'; 2214 break; 2215 case 9: 2216 $message = '9 excellent'; 2217 break; 2218 case 10: 2219 $message = '10 the best'; 2220 break; 2221 2222 default: 2223 break; 2224 } 2225 } 2226 2227 Zend_Registry::get('logger')->info('Comment: ' . $message) 2228 ; 2229 2230 //$product = $this->loadProductInfo((int)$this->getParam('p')); 2231 $member_id = $this->_authData->member_id; 2232 2233 Zend_Registry::get('logger')->info('MemberId: ' . $member_id) 2234 ; 2235 2236 /* 2237 if($this->view->product->member_id==$this->view->member_id) 2238 { 2239 $this->_helper->json(array('status' => 'error', 'message' => ' Not allowed. ', 'data' => '')); 2240 return; 2241 } 2242 * 2243 */ 2244 2245 try { 2246 $modelRating = new Application_Model_DbTable_ProjectRating(array('db' => 'db2')); 2247 $modelRating->scoreForProject($project_id, $member_id, $score, $message); 2248 } catch (Exception $exc) { 2249 Zend_Registry::get('logger') 2250 ->err('Error Saving Vote: ' . $exc->getMessage() . PHP_EOL . $exc->getTraceAsString()) 2251 ; 2252 $this->_sendErrorResponse(500, $exc->getMessage() . PHP_EOL . $exc->getTraceAsString()); 2253 } 2254 2255 2256 /* 2257 if($this->view->product){ 2258 //Send a notification to the owner 2259 $this->sendNotificationToOwner($this->view->product, Default_Model_HtmlPurify::purify($this->getParam('msg'))); 2260 } 2261 * 2262 */ 2263 2264 if ($this->_format == 'json') { 2265 $response = array('status' => $status, 2266 'statuscode' => 100, 2267 'message' => $message, 2268 'data' => '', 2269 'score' => $score); 2270 } else { 2271 $response = array('meta' => array('status' => array('@text' => $status), 2272 'statuscode' => array('@text' => 100), 2273 'message' => array('@text' => $message), 2274 'score' => array('@text' => $score)), 2275 'data' => array('@text' => '')); 2276 } 2277 2278 Zend_Registry::get('logger')->info('Done: ' . json_encode($response)) 2279 ; 2280 2281 //$this->_helper->json(array('status' => $status, 'message' => $message, 'data' => '','laplace_score' =>$this->view->product->laplace_score)); 2282 2283 $this->_sendResponse($response, $this->_format); 2284 } else { 2285 2286 $this->_sendErrorResponse(101, 'please specify all mandatory fields'); 2287 2288 } 2289 2290 } else { 2291 2292 $this->_sendErrorResponse(101, 'please specify all mandatory fields'); 2293 2294 } 2295 } else { 2296 $this->_sendErrorResponse(102, 'login not valid'); 2297 } 2298 2299 } 2300 2301 /** 2302 * @param $n 2303 * 2304 * @return float|int 2305 */ 2306 function roundFunction($n) 2307 { 2308 // Smaller multiple 2309 $a = (int)($n / 10) * 10; 2310 2311 // Larger multiple 2312 $b = ($a + 10); 2313 2314 // Return of closest of two 2315 return ($n - $a > $b - $n) ? $b : $a; 2316 } 2317 2318 /** 2319 * @param string $fileTags 2320 * 2321 * @return array 2322 */ 2323 protected function _parseFileTags($fileTags) 2324 { 2325 $tags = explode(',', $fileTags); 2326 $parsedTags = array('link' => '', 2327 'licensetype' => '', 2328 'packagetypeid' => '', 2329 'architectureid' => '', 2330 'packagearch' => '', 2331 'filetags' => ''); 2332 foreach ($tags as $tag) { 2333 $tag = trim($tag); 2334 if (strpos($tag, 'link##') === 0) { 2335 $parsedTags['link'] = urldecode(str_replace('link##', '', $tag)); 2336 } else { 2337 if (strpos($tag, 'licensetype-') === 0) { 2338 $parsedTags['licensetype'] = str_replace('licensetype-', '', $tag); 2339 } else { 2340 if (strpos($tag, 'packagetypeid-') === 0) { 2341 $parsedTags['packagetypeid'] = str_replace('packagetypeid-', '', $tag); 2342 } else { 2343 if (strpos($tag, 'architectureid-') === 0) { 2344 $parsedTags['architectureid'] = str_replace('architectureid-', '', $tag); 2345 } else { 2346 if (strpos($tag, 'packagearch-') === 0) { 2347 $parsedTags['packagearch'] = str_replace('packagearch-', '', $tag); 2348 } else { 2349 if (strpos($tag, '@@@') === 0) { 2350 $strTags = substr($tag, 3, strlen($tag) - 2); 2351 $parsedTags['filetags'] = explode('@@', $strTags); 2352 } 2353 } 2354 } 2355 } 2356 } 2357 } 2358 } 2359 2360 return $parsedTags; 2361 } 2362 2363 }