File indexing completed on 2024-05-19 05:59:11

0001 <?php
0002 /**
0003  *  ocs-webserver
0004  *
0005  *  Copyright 2016 by pling GmbH.
0006  *
0007  *    This file is part of ocs-webserver.
0008  *
0009  *    This program is free software: you can redistribute it and/or modify
0010  *    it under the terms of the GNU Affero General Public License as
0011  *    published by the Free Software Foundation, either version 3 of the
0012  *    License, or (at your option) any later version.
0013  *
0014  *    This program is distributed in the hope that it will be useful,
0015  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
0016  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017  *    GNU Affero General Public License for more details.
0018  *
0019  *    You should have received a copy of the GNU Affero General Public License
0020  *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
0021  **/
0022 
0023 /**
0024  * What changes from official OCS v1 spec
0025  *
0026  * OCS specification:
0027  * http://www.freedesktop.org/wiki/Specifications/open-collaboration-services/
0028  *
0029  * ----
0030  *
0031  * Allow delimiter ',' of value of parameter 'categories'
0032  *
0033  * Example:
0034  * /content/data?categories=1,2,3
0035  * /content/data?categories=1x2x3
0036  *
0037  * ----
0038  *
0039  * Additional URL queries to '/content/data'
0040  *
0041  * xdg_types
0042  * package_types
0043  *
0044  * Example:
0045  * /content/data?xdg_types=icons,themes,wallpapers
0046  * /content/data?package_types=1,2,3
0047  *
0048  * package_types:
0049  * 1 = AppImage
0050  * 2 = Android (apk)
0051  * 3 = OS X compatible
0052  * 4 = Windows executable
0053  * 5 = Debian
0054  * 6 = Snappy
0055  * 7 = Flatpak
0056  * 8 = Electron-Webapp
0057  * 9 = Arch
0058  * 10 = open/Suse
0059  * 11 = Redhat
0060  * 12 = Source Code
0061  *
0062  * ----
0063  *
0064  * Additional data field of '/content/categories'
0065  *
0066  * display_name
0067  * parent_id
0068  * xdg_type
0069  *
0070  * ----
0071  *
0072  * Additional data field of '/content/data'
0073  *
0074  * xdg_type
0075  * download_package_type{n}
0076  * download_package_arch{n}
0077  *
0078  * ----
0079  *
0080  * Additional data field of '/content/download'
0081  *
0082  * download_package_type
0083  * download_package_arch
0084  *
0085  * ----
0086  *
0087  * Additional API method for preview picture
0088  *
0089  * /content/previewpic/{contentid}
0090  *
0091  * Example:
0092  * /content/previewpic/123456789
0093  * /content/previewpic/123456789?size=medium
0094  */
0095 class Ocsv1Controller extends Zend_Controller_Action
0096 {
0097 
0098     const COMMENT_TYPE_CONTENT = 1;
0099     const COMMENT_TYPE_FORUM = 4;
0100     const COMMENT_TYPE_KNOWLEDGE = 7;
0101     const COMMENT_TYPE_EVENT = 8;
0102 
0103     protected $_authData = null;
0104 
0105     protected $_uriScheme = 'https';
0106 
0107     protected $_format = 'xml';
0108 
0109     protected $_config = array(
0110         'id'         => 'opendesktop.org',
0111         'location'   => 'https://www.opendesktop.org/ocs/v1/',
0112         'name'       => 'opendesktop.org',
0113         'icon'       => '',
0114         'termsofuse' => 'https://www.opendesktop.org/terms',
0115         'register'   => 'https://www.opendesktop.org/register',
0116         'version'    => '1.7',
0117         'website'    => 'www.opendesktop.org',
0118         'host'       => 'www.opendesktop.org',
0119         'contact'    => 'contact@opendesktop.org',
0120         'ssl'        => true,
0121         'user_host'  => 'pling.me'
0122     );
0123 
0124     protected $_params = array();
0125 
0126     public function init()
0127     {
0128         parent::init();
0129         $this->initView();
0130         $this->_initUriScheme();
0131         $this->_initRequestParamsAndFormat();
0132         $this->_initConfig();
0133         $this->_initResponseHeader();
0134     }
0135 
0136     public function initView()
0137     {
0138         // Disable render view
0139         $this->_helper->layout->disableLayout();
0140         $this->_helper->viewRenderer->setNoRender(true);
0141     }
0142 
0143     protected function _initUriScheme()
0144     {
0145         if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] === '1')) {
0146             $this->_uriScheme = 'https';
0147         } else {
0148             $this->_uriScheme = 'http';
0149         }
0150     }
0151 
0152     /**
0153      * @throws Zend_Exception
0154      */
0155     protected function _initRequestParamsAndFormat()
0156     {
0157         // Set request parameters
0158         switch (strtoupper($_SERVER['REQUEST_METHOD'])) {
0159             case 'GET':
0160                 $this->_params = $_GET;
0161                 break;
0162             case 'PUT':
0163                 parse_str(file_get_contents('php://input'), $_PUT);
0164                 $this->_params = $_PUT;
0165                 break;
0166             case 'POST':
0167                 $this->_params = $_POST;
0168                 break;
0169             default:
0170                 Zend_Registry::get('logger')->err(__METHOD__ . ' - request method not supported - ' . $_SERVER['REQUEST_METHOD']);
0171                 exit('request method not supported');
0172         }
0173 
0174         // Set format option
0175         if (isset($this->_params['format']) && strtolower($this->_params['format']) == 'json') {
0176             $this->_format = 'json';
0177         }
0178     }
0179 
0180     protected function _initConfig()
0181     {
0182         $clientConfig = $this->_loadClientConfig();
0183 
0184         $credentials = '';
0185         if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) {
0186             $credentials = $_SERVER['PHP_AUTH_USER'] . ':' . $_SERVER['PHP_AUTH_PW'] . '@';
0187         }
0188 
0189         $baseUri = $this->_uriScheme . '://' . $credentials . $_SERVER['SERVER_NAME'];
0190 
0191         $webSite = $_SERVER['SERVER_NAME'];
0192 
0193         //Mask api.kde-look.org to store.kde.org
0194         if (strpos($_SERVER['SERVER_NAME'], 'api.kde-look.org') !== false) {
0195             $webSite = 'store.kde.org';
0196         }
0197 
0198         $this->_config = array(
0199                 'id'         => $_SERVER['SERVER_NAME'],
0200                 'location'   => $baseUri . '/ocs/v1/',
0201                 'name'       => $clientConfig['head']['browser_title'],
0202                 'icon'       => $baseUri . $clientConfig['logo'],
0203                 'termsofuse' => $baseUri . '/content/terms',
0204                 'register'   => $baseUri . '/register',
0205                 'website'    => $webSite,
0206                 'host'       => $_SERVER['SERVER_NAME']
0207             ) + $this->_config;
0208     }
0209 
0210     /**
0211      * @return array|null
0212      */
0213     protected function _loadClientConfig()
0214     {
0215         $clientConfigReader = new Backend_Model_ClientFileConfig($this->_getNameForStoreClient());
0216         $clientConfigReader->loadClientConfig();
0217 
0218         return $clientConfigReader->getConfig();
0219     }
0220 
0221     /**
0222      * Returns the name for the store client.
0223      * If no name were found, the name for the standard store client will be returned.
0224      *
0225      * @return string
0226      */
0227     protected function _getNameForStoreClient()
0228     {
0229         $clientName = Zend_Registry::isRegistered('store_config') ? Zend_Registry::get('store_config')->name : Zend_Registry::get('config')->settings->client->default->name;
0230 
0231 
0232         return $clientName;
0233     }
0234 
0235     protected function _initResponseHeader()
0236     {
0237         $duration = 1800; // in seconds
0238         $expires = gmdate("D, d M Y H:i:s", time() + $duration) . " GMT";
0239 
0240         $this->getResponse()
0241              ->setHeader('X-FRAME-OPTIONS', 'SAMEORIGIN', true)
0242 //             ->setHeader('Last-Modified', $modifiedTime, true)
0243              ->setHeader('Expires', $expires, true)
0244              ->setHeader('Pragma', 'cache', true)
0245              ->setHeader('Cache-Control', 'max-age=1800, public', true)
0246         ;
0247     }
0248 
0249     public function indexAction()
0250     {
0251         $this->_sendErrorResponse(999, 'unknown request');
0252     }
0253 
0254     protected function _sendErrorResponse($statuscode, $message = '', $local = false)
0255     {
0256         if ($this->_format == 'json') {
0257             $response = array(
0258                 'status'     => 'failed',
0259                 'statuscode' => $statuscode,
0260                 'message'    => $message
0261             );
0262         } else {
0263             $response = array(
0264                 'meta' => array(
0265                     'status'     => array('@text' => 'failed'),
0266                     'statuscode' => array('@text' => $statuscode),
0267                     'message'    => array('@text' => $message)
0268                 )
0269             );
0270         }
0271 
0272         $this->_sendResponse($response, $this->_format, $xmlRootTag = 'ocs', $local);
0273     }
0274 
0275     protected function _sendResponse($response, $format = 'xml', $xmlRootTag = 'ocs', $local = false)
0276     {
0277         header('Pragma: public');
0278         header('Cache-Control: cache, must-revalidate');
0279         $duration = 1800; // in seconds
0280         $expires = gmdate("D, d M Y H:i:s", time() + $duration) . " GMT";
0281         header('Expires: ' . $expires);
0282         if ($format == 'json') {
0283             header('Content-Type: application/json; charset=UTF-8');
0284             if($local) {
0285                 echo json_encode($response);
0286             } else {
0287                 echo $response;
0288             }
0289         } else {
0290             header('Content-Type: application/xml; charset=UTF-8');
0291             if($local) {
0292                 echo $this->_convertXmlDom($response, $xmlRootTag)->saveXML();
0293             } else {
0294                 echo $response;
0295             }
0296         }
0297 
0298         exit;
0299     }
0300 
0301     protected function _convertXmlDom($values, $tagName = 'data', DOMNode &$dom = null, DOMElement &$element = null)
0302     {
0303         if (!$dom) {
0304             $dom = new DomDocument('1.0', 'UTF-8');
0305         }
0306         if (!$element) {
0307             $element = $dom->appendChild($dom->createElement($tagName));
0308         }
0309         if (is_array($values) || is_object($values)) {
0310             foreach ($values as $key => $value) {
0311                 if (is_array($value) || is_object($value)) {
0312                     $isHash = false;
0313                     foreach ($value as $_key => $_value) {
0314                         if (ctype_digit((string)$_key)) {
0315                             $isHash = true;
0316                         }
0317                         break;
0318                     }
0319                     if ($isHash) {
0320                         $this->_convertXmlDom($value, $key, $dom, $element);
0321                         continue;
0322                     }
0323                     if (ctype_digit((string)$key)) {
0324                         $key = $tagName;
0325                     }
0326                     $childElement = $element->appendChild($dom->createElement($key));
0327                     $this->_convertXmlDom($value, $key, $dom, $childElement);
0328                 } else {
0329                     if ($key == '@text') {
0330                         if (is_bool($value)) {
0331                             $value = var_export($value, true);
0332                         }
0333                         $element->appendChild($dom->createTextNode($value));
0334                     } else if ($key == '@cdata') {
0335                         if (is_bool($value)) {
0336                             $value = var_export($value, true);
0337                         }
0338                         $element->appendChild($dom->createCDATASection($value));
0339                     } else {
0340                         if (is_bool($value)) {
0341                             $value = var_export($value, true);
0342                         }
0343                         $element->setAttribute($key, $value);
0344                     }
0345                 }
0346             }
0347         }
0348 
0349         return $dom;
0350     }
0351 
0352     public function providersAction()
0353     {
0354         // As providers.xml
0355         $response = array(
0356             'provider' => array(
0357                 'id'         => array('@text' => $this->_config['id']),
0358                 'location'   => array('@text' => $this->_config['location']),
0359                 'name'       => array('@text' => $this->_config['name']),
0360                 'icon'       => array('@text' => $this->_config['icon']),
0361                 'termsofuse' => array('@text' => $this->_config['termsofuse']),
0362                 'register'   => array('@text' => $this->_config['register']),
0363                 'services'   => array(
0364                     'person'  => array('ocsversion' => $this->_config['version']),
0365                     'content' => array('ocsversion' => $this->_config['version'])
0366                 )
0367             )
0368         );
0369 
0370         $this->_sendResponse($response, 'xml', 'providers', true);
0371     }
0372 
0373     public function configAction()
0374     {
0375         if ($this->_format == 'json') {
0376             $response = array(
0377                 'status'     => 'ok',
0378                 'statuscode' => 100,
0379                 'message'    => '',
0380                 'data'       => array(
0381                     'version' => $this->_config['version'],
0382                     'website' => $this->_config['website'],
0383                     'host'    => $this->_config['host'],
0384                     'contact' => $this->_config['contact'],
0385                     'ssl'     => $this->_config['ssl']
0386                 )
0387             );
0388         } else {
0389             $response = array(
0390                 'meta' => array(
0391                     'status'     => array('@text' => 'ok'),
0392                     'statuscode' => array('@text' => 100),
0393                     'message'    => array('@text' => '')
0394                 ),
0395                 'data' => array(
0396                     'version' => array('@text' => $this->_config['version']),
0397                     'website' => array('@text' => $this->_config['website']),
0398                     'host'    => array('@text' => $this->_config['host']),
0399                     'contact' => array('@text' => $this->_config['contact']),
0400                     'ssl'     => array('@text' => $this->_config['ssl'])
0401                 )
0402             );
0403         }
0404 
0405         $this->_sendResponse($response, $this->_format, 'ocs', true);
0406     }
0407 
0408     public function personcheckAction()
0409     {
0410         $identity = null;
0411         $credential = null;
0412         if (!empty($this->_params['login'])) {
0413             $identity = $this->_params['login'];
0414         }
0415         if (!empty($this->_params['password'])) {
0416             $credential = $this->_params['password'];
0417         }
0418 
0419         if (!$identity) {
0420             $this->_sendErrorResponse(101, 'please specify all mandatory fields');
0421         } else {
0422             if (!$this->_authenticateUser($identity, $credential)) {
0423                 $this->_sendErrorResponse(102, 'login not valid');
0424             }
0425         }
0426 
0427         if ($this->_format == 'json') {
0428             $response = array(
0429                 'status'     => 'ok',
0430                 'statuscode' => 100,
0431                 'message'    => '',
0432                 'data'       => array(
0433                     array(
0434                         'details'  => 'check',
0435                         'personid' => $this->_authData->username,
0436                         'ptype'    => $this->_authData->password_type
0437                     )
0438                 )
0439             );
0440         } else {
0441             $response = array(
0442                 'meta' => array(
0443                     'status'     => array('@text' => 'ok'),
0444                     'statuscode' => array('@text' => 100),
0445                     'message'    => array('@text' => '')
0446                 ),
0447                 'data' => array(
0448                     'person' => array(
0449                         'details'  => 'check',
0450                         'personid' => array('@text' => $this->_authData->username),
0451                         'ptype' => array('@text' => $this->_authData->password_type)
0452                     )
0453                 )
0454             );
0455         }
0456 
0457         $this->_sendResponse($response, $this->_format, 'ocs', true);
0458     }
0459 
0460     protected function _authenticateUser($identity = null, $credential = null, $force = false)
0461     {
0462         ////////////////////////////////////////////////////////
0463         // BasicAuth enabled testing site workaround
0464         if (strrpos($_SERVER['SERVER_NAME'], 'pling.ws') !== false
0465             || strrpos($_SERVER['SERVER_NAME'], 'pling.cc') !== false
0466             || strrpos($_SERVER['SERVER_NAME'], 'pling.to') !== false
0467             || strrpos($_SERVER['SERVER_NAME'], 'ocs-store.com') !== false) {
0468             $authData = new stdClass;
0469             $authData->username = 'dummy';
0470             $this->_authData = $authData;
0471 
0472             return true;
0473         }
0474         ////////////////////////////////////////////////////////
0475 
0476         if (!$identity && !empty($_SERVER['PHP_AUTH_USER'])) {
0477             // Will set user identity or API-Key
0478             $identity = $_SERVER['PHP_AUTH_USER'];
0479         }
0480         if (!$credential && !empty($_SERVER['PHP_AUTH_PW'])) {
0481             $credential = $_SERVER['PHP_AUTH_PW'];
0482         }
0483 
0484         $loginMethod = null;
0485         //if ($identity && !$credential) {
0486         //    $loginMethod = 'api-key';
0487         //}
0488 
0489         if ($identity && ($credential || $loginMethod == 'api-key')) {
0490             $authModel = new Default_Model_Authorization();
0491             $authData = $authModel->getAuthDataFromApi($identity, $credential, $loginMethod);
0492             if ($authData) {
0493                 $this->_authData = $authData;
0494 
0495                 return true;
0496             }
0497         }
0498 
0499         if ($force) {
0500             //header('WWW-Authenticate: Basic realm="Your valid user account or api key"');
0501             header('WWW-Authenticate: Basic realm="Your valid user account"');
0502             header('HTTP/1.0 401 Unauthorized');
0503             exit;
0504         }
0505 
0506         return false;
0507     }
0508 
0509     public function personselfAction()
0510     {
0511         $this->persondataAction(true);
0512     }
0513 
0514     public function persondataAction($self = false)
0515     {
0516         if (!$this->_authenticateUser()) {
0517             $this->_sendErrorResponse(101, 'person not found');
0518         }
0519 
0520         $tableMember = new Default_Model_Member();
0521 
0522         // Self data or specific person data
0523         if ($self || $this->getParam('personid')) {
0524             if ($self) {
0525                 $username = $this->_authData->username;
0526             } else {
0527                 if ($this->getParam('personid')) {
0528                     $username = $this->getParam('personid');
0529                 }
0530             }
0531 
0532             $member = $tableMember->findActiveMemberByIdentity($username);
0533 
0534             if (!$member) {
0535                 $this->_sendErrorResponse(101, 'person not found');
0536             }
0537 
0538             $profilePage = $this->_uriScheme . '://' . $this->_config['user_host'] . '/member/' . $member->member_id;
0539 
0540             if ($this->_format == 'json') {
0541                 $response = array(
0542                     'status'     => 'ok',
0543                     'statuscode' => 100,
0544                     'message'    => '',
0545                     'data'       => array(
0546                         array(
0547                             'details'              => 'full',
0548                             'personid'             => $member->username,
0549                             'privacy'              => 0,
0550                             'privacytext'          => 'public',
0551                             'firstname'            => $member->firstname,
0552                             'lastname'             => $member->lastname,
0553                             'gender'               => '',
0554                             'communityrole'        => '',
0555                             'homepage'             => $member->link_website,
0556                             'company'              => '',
0557                             'avatarpic'            => $member->profile_image_url,
0558                             'avatarpicfound'       => true,
0559                             'bigavatarpic'         => $member->profile_image_url,
0560                             'bigavatarpicfound'    => true,
0561                             'birthday'             => '',
0562                             'jobstatus'            => '',
0563                             'city'                 => $member->city,
0564                             'country'              => $member->country,
0565                             'latitude'             => '',
0566                             'longitude'            => '',
0567                             'ircnick'              => '',
0568                             'ircchannels'          => '',
0569                             'irclink'              => '',
0570                             'likes'                => '',
0571                             'dontlikes'            => '',
0572                             'interests'            => '',
0573                             'languages'            => '',
0574                             'programminglanguages' => '',
0575                             'favouritequote'       => '',
0576                             'favouritemusic'       => '',
0577                             'favouritetvshows'     => '',
0578                             'favouritemovies'      => '',
0579                             'favouritebooks'       => '',
0580                             'favouritegames'       => '',
0581                             'description'          => $member->biography,
0582                             'profilepage'          => $profilePage
0583                         )
0584                     )
0585                 );
0586             } else {
0587                 $response = array(
0588                     'meta' => array(
0589                         'status'     => array('@text' => 'ok'),
0590                         'statuscode' => array('@text' => 100),
0591                         'message'    => array('@text' => '')
0592                     ),
0593                     'data' => array(
0594                         'person' => array(
0595                             'details'              => 'full',
0596                             'personid'             => array('@text' => $member->username),
0597                             'privacy'              => array('@text' => 0),
0598                             'privacytext'          => array('@text' => 'public'),
0599                             'firstname'            => array('@text' => $member->firstname),
0600                             'lastname'             => array('@text' => $member->lastname),
0601                             'gender'               => array('@text' => ''),
0602                             'communityrole'        => array('@text' => ''),
0603                             'homepage'             => array('@text' => $member->link_website),
0604                             'company'              => array('@text' => ''),
0605                             'avatarpic'            => array('@text' => $member->profile_image_url),
0606                             'avatarpicfound'       => array('@text' => true),
0607                             'bigavatarpic'         => array('@text' => $member->profile_image_url),
0608                             'bigavatarpicfound'    => array('@text' => true),
0609                             'birthday'             => array('@text' => ''),
0610                             'jobstatus'            => array('@text' => ''),
0611                             'city'                 => array('@text' => $member->city),
0612                             'country'              => array('@text' => $member->country),
0613                             'latitude'             => array('@text' => ''),
0614                             'longitude'            => array('@text' => ''),
0615                             'ircnick'              => array('@text' => ''),
0616                             'ircchannels'          => array('@text' => ''),
0617                             'irclink'              => array('@text' => ''),
0618                             'likes'                => array('@text' => ''),
0619                             'dontlikes'            => array('@text' => ''),
0620                             'interests'            => array('@text' => ''),
0621                             'languages'            => array('@text' => ''),
0622                             'programminglanguages' => array('@text' => ''),
0623                             'favouritequote'       => array('@text' => ''),
0624                             'favouritemusic'       => array('@text' => ''),
0625                             'favouritetvshows'     => array('@text' => ''),
0626                             'favouritemovies'      => array('@text' => ''),
0627                             'favouritebooks'       => array('@text' => ''),
0628                             'favouritegames'       => array('@text' => ''),
0629                             'description'          => array('@text' => $member->biography),
0630                             'profilepage'          => array('@text' => $profilePage)
0631                         )
0632                     )
0633                 );
0634             }
0635 
0636             $this->_sendResponse($response, $this->_format, 'ocs', true);
0637         } // Find a specific list of persons
0638         else {
0639             $limit = 10; // 1 - 100
0640             $offset = 0;
0641 
0642             $tableMemberSelect = $tableMember->select()->where('is_active = ?', 1)->where('is_deleted = ?', 0);
0643 
0644             if (!empty($this->_params['name'])) {
0645                 $isSearchable = false;
0646                 foreach (explode(' ', $this->_params['name']) as $keyword) {
0647                     if ($keyword && strlen($keyword) > 2) {
0648                         $tableMemberSelect->where('username LIKE ?' . ' OR firstname LIKE ?' . ' OR lastname LIKE ?', "%$keyword%");
0649                         $isSearchable = true;
0650                     }
0651                 }
0652                 if (!$isSearchable) {
0653                     $tableMemberSelect->where('username LIKE ?' . ' OR firstname LIKE ?' . ' OR lastname LIKE ?',
0654                         "%{$this->_params['name']}%");
0655                 }
0656             }
0657             if (!empty($this->_params['country'])) {
0658                 $tableMemberSelect->where('country = ?', $this->_params['country']);
0659             }
0660             if (!empty($this->_params['city'])) {
0661                 $tableMemberSelect->where('city = ?', $this->_params['city']);
0662             }
0663             if (!empty($this->_params['description'])) {
0664                 $isSearchable = false;
0665                 foreach (explode(' ', $this->_params['name']) as $keyword) {
0666                     if ($keyword && strlen($keyword) > 2) {
0667                         $tableMemberSelect->where('biography LIKE ?', "%$keyword%");
0668                         $isSearchable = true;
0669                     }
0670                 }
0671                 if (!$isSearchable) {
0672                     $tableMemberSelect->where('biography LIKE ?', "%$this->_params['description']}%");
0673                 }
0674             }
0675             if (!empty($this->_params['pc'])) {
0676             }
0677             if (!empty($this->_params['software'])) {
0678             }
0679             if (!empty($this->_params['longitude'])) {
0680             }
0681             if (!empty($this->_params['latitude'])) {
0682             }
0683             if (!empty($this->_params['distance'])) {
0684             }
0685             if (!empty($this->_params['attributeapp'])) {
0686             }
0687             if (!empty($this->_params['attributekey'])) {
0688             }
0689             if (!empty($this->_params['attributevalue'])) {
0690             }
0691             if (isset($this->_params['pagesize'])
0692                 && ctype_digit((string)$this->_params['pagesize'])
0693                 && $this->_params['pagesize'] > 0
0694                 && $this->_params['pagesize'] < 101) {
0695                 $limit = $this->_params['pagesize'];
0696             }
0697             if (isset($this->_params['page'])
0698                 && ctype_digit((string)$this->_params['page'])) {
0699                 // page parameter: the first page is 0
0700                 $offset = $limit * $this->_params['page'];
0701             }
0702 
0703             $members = $tableMember->fetchAll($tableMemberSelect->limit($limit, $offset));
0704 
0705             $tableMemberSelect->reset('columns');
0706             $tableMemberSelect->reset('limitcount');
0707             $tableMemberSelect->reset('limitoffset');
0708 
0709             $count = $tableMember->fetchRow($tableMemberSelect->columns(array('count' => 'COUNT(*)')));
0710 
0711             if ($count['count'] > 1000) {
0712                 $this->_sendErrorResponse(102, 'more than 1000 people found.' . ' it is not allowed to fetch such a big resultset.'
0713                     . ' please specify more search conditions');
0714             }
0715 
0716             if ($this->_format == 'json') {
0717                 $response = array(
0718                     'status'       => 'ok',
0719                     'statuscode'   => 100,
0720                     'message'      => '',
0721                     'totalitems'   => $count['count'],
0722                     'itemsperpage' => $limit,
0723                     'data'         => array()
0724                 );
0725             } else {
0726                 $response = array(
0727                     'meta' => array(
0728                         'status'       => array('@text' => 'ok'),
0729                         'statuscode'   => array('@text' => 100),
0730                         'message'      => array('@text' => ''),
0731                         'totalitems'   => array('@text' => $count['count']),
0732                         'itemsperpage' => array('@text' => $limit)
0733                     ),
0734                     'data' => array()
0735                 );
0736             }
0737 
0738             if (!count($members)) {
0739                 $this->_sendResponse($response, $this->_format, 'ocs', true);
0740             }
0741 
0742             $personsList = array();
0743             foreach ($members as $member) {
0744                 if ($this->_format == 'json') {
0745                     $personsList[] = array(
0746                         'details'       => 'summary',
0747                         'personid'      => $member->username,
0748                         'privacy'       => 0,
0749                         'privacytext'   => 'public',
0750                         'firstname'     => $member->firstname,
0751                         'lastname'      => $member->lastname,
0752                         'gender'        => '',
0753                         'communityrole' => '',
0754                         'company'       => '',
0755                         'city'          => $member->city,
0756                         'country'       => $member->country
0757                     );
0758                 } else {
0759                     $personsList[] = array(
0760                         'details'       => 'summary',
0761                         'personid'      => array('@text' => $member->username),
0762                         'privacy'       => array('@text' => 0),
0763                         'privacytext'   => array('@text' => 'public'),
0764                         'firstname'     => array('@text' => $member->firstname),
0765                         'lastname'      => array('@text' => $member->lastname),
0766                         'gender'        => array('@text' => ''),
0767                         'communityrole' => array('@text' => ''),
0768                         'company'       => array('@text' => ''),
0769                         'city'          => array('@text' => $member->city),
0770                         'country'       => array('@text' => $member->country)
0771                     );
0772                 }
0773             }
0774 
0775             if ($this->_format == 'json') {
0776                 $response['data'] = $personsList;
0777             } else {
0778                 $response['data'] = array('person' => $personsList);
0779             }
0780 
0781             $this->_sendResponse($response, $this->_format, 'ocs', true);
0782         }
0783     }
0784 
0785     public function contentcategoriesAction()
0786     {
0787 
0788         if (!$this->_authenticateUser()) {
0789             //    $this->_sendErrorResponse(999, '');
0790         }
0791 
0792         /** @var Zend_Cache_Core $cache */
0793         $cache = Zend_Registry::get('cache');
0794         $storeName = $this->_getNameForStoreClient();
0795         $cacheName = 'api_content_categories'.md5($storeName);
0796 
0797         if (false == ($categoriesList = $cache->load($cacheName))) {
0798             $categoriesList = $this->_buildCategories();
0799             $cache->save($categoriesList, $cacheName, array(), 1800);
0800         }
0801 
0802         if ($this->_format == 'json') {
0803             $response = array(
0804                 'status'     => 'ok',
0805                 'statuscode' => 100,
0806                 'message'    => '',
0807                 'totalitems' => count($categoriesList),
0808                 'data'       => array()
0809             );
0810             if (!empty($categoriesList)) {
0811                 $response['data'] = $categoriesList;
0812             }
0813         } else {
0814             $response = array(
0815                 'meta' => array(
0816                     'status'     => array('@text' => 'ok'),
0817                     'statuscode' => array('@text' => 100),
0818                     'message'    => array('@text' => ''),
0819                     'totalitems' => array('@text' => count($categoriesList))
0820                 ),
0821                 'data' => array()
0822             );
0823             if (!empty($categoriesList)) {
0824                 $response['data'] = array('category' => $categoriesList);
0825             }
0826         }
0827 
0828         $this->_sendResponse($response, $this->_format, 'ocs', true);
0829     }
0830 
0831     protected function _buildCategories()
0832     {
0833         $modelCategoryTree = new Default_Model_ProjectCategory();
0834         $tree = $modelCategoryTree->fetchCategoryTreeCurrentStore();
0835 
0836         return $this->buildResponseTree($tree);
0837     }
0838 
0839     protected function buildResponseTree($tree)
0840     {
0841         $modelCategory = new Default_Model_DbTable_ProjectCategory();
0842         $result = array();
0843         foreach ($tree as $element) {
0844             if ($this->_format == 'json') {
0845                 $name = (false === empty($element['name_legacy'])) ? $element['name_legacy'] : $element['title'];
0846                 //set parent name to name, if neeed
0847                 if(isset($element['parent_id'])) {
0848                     $parent = $modelCategory->find($element['parent_id'])->current();
0849                     if($parent) {
0850                         $name = $parent['title'] . "/ " . $name;
0851                     }
0852                 }
0853                 $result[] = array(
0854                     'id'           => $element['id'],
0855                     'name'         => $name,
0856                     'display_name' => $element['title'],
0857                     'parent_id'    => (false === empty($element['parent_id'])) ? $element['parent_id'] : '',
0858                     'xdg_type'     => (false === empty($element['xdg_type'])) ? $element['xdg_type'] : ''
0859                 );
0860             } else {
0861                 $name = (false === empty($element['name_legacy'])) ? $element['name_legacy'] : $element['title'];
0862 
0863                 //set parent name to name, if neeed
0864                 if(isset($element['parent_id'])) {
0865                     $parent = $modelCategory->find($element['parent_id'])->current();
0866                     if($parent) {
0867                         $name = $parent['title'] . "/ " . $name;
0868                     }
0869                 }
0870 
0871                 $result[] = array(
0872                     'id'           => array('@text' => $element['id']),
0873                     'name'         => array('@text' => $name),
0874                     'display_name' => array('@text' => $element['title']),
0875                     'parent_id'    => array('@text' => (false === empty($element['parent_id'])) ? $element['parent_id'] : ''),
0876                     'xdg_type'     => array('@text' => (false === empty($element['xdg_type'])) ? $element['xdg_type'] : '')
0877                 );
0878 
0879             }
0880             if ($element['has_children']) {
0881                 $sub_tree = $this->buildResponseTree($element['children']);
0882                 $result = array_merge($result, $sub_tree);
0883             }
0884         }
0885 
0886         return $result;
0887     }
0888 
0889     public function contentdataAction()
0890     {
0891 
0892         $uri = $this->view->url();
0893 
0894         $params = $this->getRequest()->getParams();
0895         $params['domain_store_id'] = $this->_getNameForStoreClient();
0896 
0897         $result = $this->_request('GET', $uri, $params);
0898         $this->_sendResponse($result, $this->_format);
0899 
0900         /*
0901 
0902         if (!$this->_authenticateUser()) {
0903             //    $this->_sendErrorResponse(999, '');
0904         }
0905 
0906         $pploadApi = new Ppload_Api(array(
0907             'apiUri'   => PPLOAD_API_URI,
0908             'clientId' => PPLOAD_CLIENT_ID,
0909             'secret'   => PPLOAD_SECRET
0910         ));
0911         $previewPicSize = array(
0912             'width'  => 770,
0913             'height' => 540,
0914             'crop'   => 0
0915         );
0916         $smallPreviewPicSize = array(
0917             'width'  => 100,
0918             'height' => 100
0919         );
0920 
0921         // Specific content data
0922         $requestedId = (int)$this->getParam('contentid') ? (int)$this->getParam('contentid') : null;
0923         $requestedTags = $this->getParam('tags') ? $this->getParam('tags') : null;
0924         if ($requestedId) {
0925             $response = $this->fetchContent($requestedId, $requestedTags, $previewPicSize, $smallPreviewPicSize, $pploadApi);
0926 
0927             $this->_sendResponse($response, $this->_format);
0928         } // Gets a list of a specific set of contents
0929         else {
0930             $response = $this->fetchCategoryContent($requestedTags, $previewPicSize, $smallPreviewPicSize, $pploadApi);
0931 
0932             $this->_sendResponse($response, $this->_format);
0933         }
0934          *
0935          */
0936     }
0937 
0938     /**
0939      * @param int        $contentId
0940      * @param array|null $tags
0941      * @param array      $previewPicSize
0942      * @param array      $smallPreviewPicSize
0943      * @param Ppload_Api $pploadApi
0944      *
0945      * @return array
0946      */
0947     protected function fetchContent(
0948         $contentId,
0949         $tags,
0950         $previewPicSize,
0951         $smallPreviewPicSize,
0952         $pploadApi
0953     ) {
0954         if(null == $tags) {
0955             $tags = '';
0956         }
0957         /** @var Zend_Cache_Core $cache */
0958         $cache = Zend_Registry::get('cache');
0959         $cacheName = 'api_fetch_content_by_id_' . $contentId . '_tags_' . md5($tags) . '_format_' . $this->_format;
0960 
0961         if (($response = $cache->load($cacheName))) {
0962             return $response;
0963         }
0964 
0965         $tableProject = new Default_Model_Project();
0966         $tableProjectSelect = $this->_buildProjectSelect($tableProject);
0967 
0968         $project = $tableProject->fetchRow($tableProjectSelect->where('project.project_id = ?', $contentId));
0969 
0970         if (!$project) {
0971             $this->_sendErrorResponse(101, 'content not found');
0972         }
0973 
0974         $project->title = Default_Model_HtmlPurify::purify($project->title);
0975         $project->description = Default_Model_BBCode::renderHtml(Default_Model_HtmlPurify::purify($project->description));
0976         $project->version = Default_Model_HtmlPurify::purify($project->version);
0977 
0978         $categoryXdgType = '';
0979         if (!empty($project->cat_xdg_type)) {
0980             $categoryXdgType = $project->cat_xdg_type;
0981         }
0982 
0983         $created = date('c', strtotime($project->created_at));
0984         $changed = date('c', strtotime($project->changed_at));
0985 
0986         $previewPage = $this->_uriScheme . '://' . $this->_config['website'] . '/p/' . $project->project_id;
0987 
0988         $donationPage = $previewPage;
0989         if (empty($project->paypal_mail) && empty($project->dwolla_id)) {
0990             $donationPage = '';
0991         }
0992 
0993         list($previewPics, $smallPreviewPics) = $this->getGalleryPictures($project, $previewPicSize, $smallPreviewPicSize);
0994 
0995         $downloads = $project->count_downloads_hive;
0996         list($downloadItems, $downloads) = $this->getPPLoadInfo($project, $pploadApi, $downloads, $tags);
0997 
0998         if ($this->_format == 'json') {
0999             $response = array(
1000                 'status'     => 'ok',
1001                 'statuscode' => 100,
1002                 'message'    => '',
1003                 'data'       => array(
1004                     array(
1005                         'details'              => 'full',
1006                         'id'                   => $project->project_id,
1007                         'name'                 => $project->title,
1008                         'version'              => $project->version,
1009                         'typeid'               => $project->project_category_id,
1010                         'typename'             => $project->cat_title,
1011                         'xdg_type'             => $categoryXdgType,
1012                         'language'             => '',
1013                         'personid'             => $project->username,
1014                         'created'              => $created,
1015                         'changed'              => $changed,
1016                         'downloads'            => $downloads,
1017                         'score'                => $project->laplace_score,
1018                         'summary'              => '',
1019                         'description'          => $project->description,
1020                         'changelog'            => '',
1021                         'feedbackurl'          => $previewPage,
1022                         'homepage'             => $previewPage,
1023                         'homepagetype'         => '',
1024                         'donationpage'         => $donationPage,
1025                         'comments'             => $project->count_comments,
1026                         'commentspage'         => $previewPage,
1027                         'fans'                 => null,
1028                         'fanspage'             => '',
1029                         'knowledgebaseentries' => null,
1030                         'knowledgebasepage'    => '',
1031                         'depend'               => '',
1032                         'preview1'             => $previewPage,
1033                         'icon'                 => '',
1034                         'video'                => '',
1035                         'detailpage'           => $previewPage,
1036                         'ghns_excluded'        => $project->ghns_excluded,
1037                         'tags'                 => $project->tags
1038                     ) + $previewPics + $smallPreviewPics + $downloadItems
1039                 )
1040             );
1041         } else {
1042             foreach ($previewPics as $key => $value) {
1043                 $previewPics[$key] = array('@text' => $value);
1044             }
1045             foreach ($smallPreviewPics as $key => $value) {
1046                 $smallPreviewPics[$key] = array('@text' => $value);
1047             }
1048             if ($downloadItems) {
1049                 foreach ($downloadItems as $key => $value) {
1050                     $downloadItems[$key] = array('@text' => $value);
1051                 }
1052             }
1053             $response = array(
1054                 'meta' => array(
1055                     'status'     => array('@text' => 'ok'),
1056                     'statuscode' => array('@text' => 100),
1057                     'message'    => array('@text' => '')
1058                 ),
1059                 'data' => array(
1060                     'content' => array(
1061                             'details'              => 'full',
1062                             'id'                   => array('@text' => $project->project_id),
1063                             'name'                 => array('@text' => $project->title),
1064                             'version'              => array('@text' => $project->version),
1065                             'typeid'               => array('@text' => $project->project_category_id),
1066                             'typename'             => array('@text' => $project->cat_title),
1067                             'xdg_type'             => array('@text' => $categoryXdgType),
1068                             'language'             => array('@text' => ''),
1069                             'personid'             => array('@text' => $project->username),
1070                             'created'              => array('@text' => $created),
1071                             'changed'              => array('@text' => $changed),
1072                             'downloads'            => array('@text' => $downloads),
1073                             'score'                => array('@text' => $project->laplace_score),
1074                             'summary'              => array('@text' => ''),
1075                             'description'          => array('@cdata' => $project->description),
1076                             'changelog'            => array('@text' => ''),
1077                             'feedbackurl'          => array('@text' => $previewPage),
1078                             'homepage'             => array('@text' => $previewPage),
1079                             'homepagetype'         => array('@text' => ''),
1080                             'donationpage'         => array('@text' => $donationPage),
1081                             'comments'             => array('@text' => $project->count_comments),
1082                             'commentspage'         => array('@text' => $previewPage),
1083                             'fans'                 => array('@text' => null),
1084                             'fanspage'             => array('@text' => ''),
1085                             'knowledgebaseentries' => array('@text' => null),
1086                             'knowledgebasepage'    => array('@text' => ''),
1087                             'depend'               => array('@text' => ''),
1088                             'preview1'             => array('@text' => $previewPage),
1089                             'icon'                 => array('@text' => ''),
1090                             'video'                => array('@text' => ''),
1091                             'detailpage'           => array('@text' => $previewPage),
1092                             'ghns_excluded'        => array('@text' => $project->ghns_excluded),
1093                             'tags'                 => array('@text' => $project->tags)
1094                         ) + $previewPics + $smallPreviewPics + $downloadItems
1095                 )
1096             );
1097         }
1098 
1099         $cache->save($response, $cacheName);
1100 
1101         return $response;
1102     }
1103 
1104     /**
1105      * @param Zend_Db_Table $tableProject
1106      *
1107      * @param bool          $withSqlCalcFoundRows
1108      *
1109      * @return Zend_Db_Table_Select
1110      */
1111     protected function _buildProjectSelect($tableProject, $withSqlCalcFoundRows = false)
1112     {
1113         $tableProjectSelect = $tableProject->select();
1114         if ($withSqlCalcFoundRows) {
1115             $tableProjectSelect->from(array('project' => 'stat_projects'), array(new Zend_Db_Expr('SQL_CALC_FOUND_ROWS *')));
1116         } else {
1117             $tableProjectSelect->from(array('project' => 'stat_projects'));
1118         }
1119         $tableProjectSelect->setIntegrityCheck(false)->columns(array(
1120             '*',
1121             'member_username' => 'username',
1122             'category_title'  => 'cat_title',
1123             'xdg_type'        => 'cat_xdg_type',
1124             'name_legacy'     => 'cat_name_legacy'
1125         ))->where('project.status = ?', Default_Model_Project::PROJECT_ACTIVE)
1126           ->where('project.ppload_collection_id IS NOT NULL')
1127         ;
1128 
1129         return $tableProjectSelect;
1130     }
1131 
1132     /**
1133      * @param Zend_Db_Table_Row_Abstract $project
1134      * @param array                      $previewPicSize
1135      * @param array                      $smallPreviewPicSize
1136      *
1137      * @return array
1138      */
1139     protected function getGalleryPictures($project, $previewPicSize, $smallPreviewPicSize)
1140     {
1141         /** @var Zend_Cache_Core $cache */
1142         $cache = Zend_Registry::get('cache');
1143         $cacheName = 'api_fetch_gallery_pics_' . $project->project_id;
1144 
1145         if (($previews = $cache->load($cacheName))) {
1146             return $previews;
1147         }
1148 
1149         $viewHelperImage = new Default_View_Helper_Image();
1150         $previewPics = array(
1151             'previewpic1' => $viewHelperImage->Image($project->image_small, $previewPicSize)
1152         );
1153         $smallPreviewPics = array(
1154             'smallpreviewpic1' => $viewHelperImage->Image($project->image_small, $smallPreviewPicSize)
1155         );
1156 
1157         $tableProject = new Default_Model_Project();
1158         $galleryPics = $tableProject->getGalleryPictureSources($project->project_id);
1159         if ($galleryPics) {
1160             $i = 2;
1161             foreach ($galleryPics as $galleryPic) {
1162                 $previewPics['previewpic' . $i] = $viewHelperImage->Image($galleryPic, $previewPicSize);
1163                 $smallPreviewPics['smallpreviewpic' . $i] = $viewHelperImage->Image($galleryPic, $smallPreviewPicSize);
1164                 $i++;
1165             }
1166         }
1167 
1168         $cache->save(array($previewPics, $smallPreviewPics), $cacheName);
1169 
1170         return array($previewPics, $smallPreviewPics);
1171     }
1172 
1173     /**
1174      * @param Zend_Db_Table_Row_Abstract $project
1175      * @param Ppload_Api                 $pploadApi
1176      * @param int                        $downloads
1177      *
1178      * @return array
1179      */
1180     protected function getPPLoadInfo($project, $pploadApi, $downloads, $tags)
1181     {
1182         $downloadItems = array();
1183 
1184         if (empty($project->ppload_collection_id)) {
1185             return array($downloadItems, $downloads);
1186         }
1187 
1188         /** @var Zend_Cache_Core $cache */
1189         $cache = Zend_Registry::get('cache');
1190         $cacheName = 'api_ppload_collection_by_id_' . $project->ppload_collection_id . '_tags_'.md5($tags);
1191 
1192         if (($pploadInfo = $cache->load($cacheName))) {
1193             return $pploadInfo;
1194         }
1195 
1196         $filesRequest = array(
1197             'collection_id'     => $project->ppload_collection_id,
1198             'ocs_compatibility' => 'compatible',
1199             'tags'              => $tags,
1200             'perpage'           => 1000
1201         );
1202 
1203         $filesResponse = $pploadApi->getFiles($filesRequest);
1204 
1205         if (isset($filesResponse->status) && $filesResponse->status == 'success') {
1206             $i = 1;
1207             foreach ($filesResponse->files as $file) {
1208                 //create ppload download hash: secret + collection_id + expire-timestamp
1209                 $salt = PPLOAD_DOWNLOAD_SECRET;
1210                 $collectionID = $project->ppload_collection_id;
1211                 $timestamp = time() + (3600 * 12); // 12 hours valid
1212                 $hash = md5($salt . $collectionID . $timestamp);
1213 
1214                 $downloads += (int)$file->downloaded_count;
1215                 $tags = $this->_parseFileTags($file->tags);
1216                 $downloadLink = PPLOAD_API_URI . 'files/download/id/' . $file->id . '/s/' . $hash . '/t/' . $timestamp . '/o/1/' . $file->name;
1217                 $downloadItems['downloadway' . $i] = 1;
1218                 $downloadItems['downloadtype' . $i] = '';
1219                 $downloadItems['downloadprice' . $i] = '0';
1220                 $downloadItems['downloadlink' . $i] = $downloadLink;
1221                 $downloadItems['downloadname' . $i] = $file->name;
1222                 $downloadItems['downloadsize' . $i] = round($file->size / 1024);
1223                 $downloadItems['downloadgpgfingerprint' . $i] = '';
1224                 $downloadItems['downloadgpgsignature' . $i] = '';
1225                 $downloadItems['downloadpackagename' . $i] = '';
1226                 $downloadItems['downloadrepository' . $i] = '';
1227                 $downloadItems['download_package_type' . $i] = $tags['packagetypeid'];
1228                 $downloadItems['download_package_arch' . $i] = $tags['packagearch'];
1229                 $downloadItems['download_architecture' . $i] = $tags['architectureid'];
1230                 $downloadItems['downloadtags' . $i] = empty($tags['filetags'])?'':implode(',',$tags['filetags']);
1231                 $i++;
1232             }
1233         }
1234 
1235         $cache->save(array($downloadItems, $downloads), $cacheName);
1236 
1237         return array($downloadItems, $downloads);
1238     }
1239 
1240     /**
1241      * @param string $fileTags
1242      *
1243      * @return array
1244      */
1245     protected function _parseFileTags($fileTags)
1246     {
1247         $tags = explode(',', $fileTags);
1248         $parsedTags = array(
1249             'link'          => '',
1250             'licensetype'   => '',
1251             'packagetypeid' => '',
1252             'packagearch'   => '',
1253             'filetags'      => '',
1254             'architectureid'  => ''
1255         );
1256         foreach ($tags as $tag) {
1257             $tag = trim($tag);
1258             if (strpos($tag, 'link##') === 0) {
1259                 $parsedTags['link'] = urldecode(str_replace('link##', '', $tag));
1260             } elseif (strpos($tag, 'licensetype-') === 0) {
1261                     $parsedTags['licensetype'] = str_replace('licensetype-', '', $tag);
1262             } elseif (strpos($tag, 'packagetypeid-') === 0) {
1263                     $parsedTags['packagetypeid'] = str_replace('packagetypeid-', '', $tag);
1264             } elseif (strpos($tag, 'packagearch-') === 0) {
1265                     $parsedTags['packagearch'] = str_replace('packagearch-', '', $tag);
1266             } elseif (strpos($tag, 'architectureid-') === 0) {
1267                     $parsedTags['architectureid'] = str_replace('architectureid-', '', $tag);
1268             } elseif (strpos($tag, '@@@') === 0) {
1269                 $strTags = substr($tag, 3, strlen($tag) - 2);
1270                 $parsedTags['filetags'] = explode('@@', $strTags);
1271             }
1272         }
1273 
1274         return $parsedTags;
1275     }
1276 
1277     /**
1278      * @param array      $tags
1279      * @param array      $previewPicSize
1280      * @param array      $smallPreviewPicSize
1281      * @param Ppload_Api $pploadApi
1282      *
1283      * @return array
1284      */
1285     protected function fetchCategoryContent(
1286         $tags,
1287         $previewPicSize,
1288         $smallPreviewPicSize,
1289         $pploadApi
1290     ) {
1291         $limit = 10; // 1 - 100
1292         $offset = 0;
1293 
1294         $tableProject = new Default_Model_Project();
1295         $tableProjectSelect = $this->_buildProjectSelect($tableProject, true);
1296 
1297         if (!empty($this->_params['categories'])) {
1298             // categories parameter: values separated by ","
1299             // legacy OCS API compatible: values separated by "x"
1300             if (strpos($this->_params['categories'], ',') !== false) {
1301                 $catList = explode(',', $this->_params['categories']);
1302             } else {
1303                 $catList = explode('x', $this->_params['categories']);
1304             }
1305 
1306             $modelProjectCategories = new Default_Model_DbTable_ProjectCategory();
1307             $allCategories = array_merge($catList, $modelProjectCategories->fetchChildIds($catList));
1308             $tableProjectSelect->where('project.project_category_id IN (?)', $allCategories);
1309         }
1310 
1311         if (!empty($this->_params['xdg_types'])) {
1312             // xdg_types parameter: values separated by ","
1313             $xdgTypeList = explode(',', $this->_params['xdg_types']);
1314             $tableProjectSelect->where('category.xdg_type IN (?)', $xdgTypeList);
1315         }
1316 
1317         if (!empty($this->_params['package_types'])) {
1318             // package_types parameter: values separated by ","
1319             $packageTypeList = explode(',', $this->_params['package_types']);
1320 
1321             $storeConfig = Zend_Registry::isRegistered('store_config') ? Zend_Registry::get('store_config') : null;
1322             $storePackageTypeIds = null;
1323             if ($storeConfig) {
1324                 $storePackageTypeIds = $storeConfig->package_type;
1325             }
1326 
1327             if ($storePackageTypeIds) {
1328                 $tableProjectSelect->join(array(
1329                     'package_type' => new Zend_Db_Expr('(SELECT DISTINCT project_id FROM project_package_type WHERE '
1330                         . $tableProject->getAdapter()->quoteInto('package_type_id IN (?)', $packageTypeList) . ')')
1331                 ), 'project.project_id = package_type.project_id', array());
1332             }
1333         }
1334 
1335         if (!empty($this->_params['tags'])) {
1336             // package_types parameter: values separated by ","
1337             $tagList = explode(',', $this->_params['tags']);
1338 
1339             foreach ($tagList as $tag) {
1340                 $tagKeyValue = explode('-', $tag);
1341                 $tagName = $tagKeyValue[0];
1342                 $tagValue = $tagKeyValue[1];
1343 
1344                 if($tagName == 'architectureid') {
1345                     $tableProjectSelect->join(array(
1346                         $tagName => new Zend_Db_Expr('(SELECT DISTINCT tag_parent_object_id as project_id FROM tag_object WHERE  is_deleted = 0 and '
1347                             . $tableProject->getAdapter()->quoteInto('tag_id = ?', $tagValue)
1348                             . ' AND ' . $tableProject->getAdapter()->quoteInto('tag_type_id = ?', Default_Model_Tags::TAG_TYPE_FILE)
1349                             . ')')
1350                     ), 'project.project_id = '.$tagName. '.project_id', array());
1351                 } else {
1352                     $tableProjectSelect->join(array(
1353                         $tagName => new Zend_Db_Expr('(SELECT DISTINCT tag_object_id as project_id FROM tag_object WHERE is_deleted = 0 and  '
1354                             . $tableProject->getAdapter()->quoteInto('tag_id = ?', $tagValue) . ')')
1355                     ), 'project.project_id = '.$tagName. '.project_id', array());
1356                 }
1357             }
1358 
1359         }
1360 
1361         $hasSearchPart = false;
1362         if (!empty($this->_params['search'])) {
1363             foreach (explode(' ', $this->_params['search']) as $keyword) {
1364                 if ($keyword && strlen($keyword) > 2) {
1365                     $tableProjectSelect->where('project.title LIKE ? OR project.description LIKE ?', "%$keyword%");
1366                     $hasSearchPart = true;
1367                 }
1368             }
1369         }
1370 
1371         if (!empty($this->_params['user'])) {
1372             $tableProjectSelect->where('member.username = ?', $this->_params['user']);
1373         }
1374 
1375         if (!empty($this->_params['external'])) {
1376         }
1377 
1378         if (!empty($this->_params['distribution'])) {
1379             // distribution parameter: comma separated list of ids
1380         }
1381 
1382         if (!empty($this->_params['license'])) {
1383             // license parameter: comma separated list of ids
1384         }
1385 
1386         if (!empty($this->_params['sortmode'])) {
1387             // sortmode parameter: new|alpha|high|down
1388             switch (strtolower($this->_params['sortmode'])) {
1389                 case 'new':
1390                     $tableProjectSelect->order('project.created_at DESC');
1391                     break;
1392                 case 'alpha':
1393                     $tableProjectSelect->order('project.title ASC');
1394                     break;
1395                 case 'high':
1396                     $tableProjectSelect->order(new Zend_Db_Expr('laplace_score(project.count_likes,project.count_dislikes) DESC'));
1397                     break;
1398                 case 'down':
1399                     $tableProjectSelect->joinLeft(array('stat_downloads_quarter_year' => 'stat_downloads_quarter_year'),
1400                         'project.project_id = stat_downloads_quarter_year.project_id', array());
1401                     $tableProjectSelect->order('stat_downloads_quarter_year.amount DESC');
1402                     break;
1403                 default:
1404                     break;
1405             }
1406         }
1407 
1408         if (isset($this->_params['pagesize'])
1409             && ctype_digit((string)$this->_params['pagesize'])
1410             && $this->_params['pagesize'] > 0
1411             && $this->_params['pagesize'] < 101) {
1412             $limit = $this->_params['pagesize'];
1413         }
1414 
1415         if (isset($this->_params['page'])
1416             && ctype_digit((string)$this->_params['page'])) {
1417             // page parameter: the first page is 0
1418             $offset = $limit * $this->_params['page'];
1419         }
1420 
1421         $tableProjectSelect->limit($limit, $offset);
1422 
1423         $projects = $tableProject->fetchAll($tableProjectSelect);
1424         $count = $tableProject->getAdapter()->fetchRow('select FOUND_ROWS() AS counter');
1425 
1426         if ($this->_format == 'json') {
1427             $response = array(
1428                 'status'       => 'ok',
1429                 'statuscode'   => 100,
1430                 'message'      => '',
1431                 'totalitems'   => $count['counter'],
1432                 'itemsperpage' => $limit,
1433                 'data'         => array()
1434             );
1435         } else {
1436             $response = array(
1437                 'meta' => array(
1438                     'status'       => array('@text' => 'ok'),
1439                     'statuscode'   => array('@text' => 100),
1440                     'message'      => array('@text' => ''),
1441                     'totalitems'   => array('@text' => $count['counter']),
1442                     'itemsperpage' => array('@text' => $limit)
1443                 ),
1444                 'data' => array()
1445             );
1446         }
1447 
1448         if (!count($projects)) {
1449             return $response;
1450         }
1451 
1452         /** @var Zend_Cache_Core $cache */
1453         $cache = Zend_Registry::get('cache');
1454         $cacheName = 'api_fetch_category_' . md5($tableProjectSelect->__toString().'-'.$tags);
1455         $contentsList = false;
1456 
1457         if (false === $hasSearchPart) {
1458             $contentsList = $cache->load($cacheName);
1459         }
1460 
1461         if (false == $contentsList) {
1462             $contentsList = $this->_buildContentList($previewPicSize, $smallPreviewPicSize, $pploadApi, $projects, $tags);
1463 
1464             if (!count($contentsList)) {
1465                 if ($this->_format == 'json') {
1466                     $response = array(
1467                         'status'       => 'ok',
1468                         'statuscode'   => 100,
1469                         'message'      => '',
1470                         'totalitems'   => 0,
1471                         'itemsperpage' => $limit,
1472                         'data'         => array()
1473                     );
1474                 } else {
1475                     $response = array(
1476                         'meta' => array(
1477                             'status'       => array('@text' => 'ok'),
1478                             'statuscode'   => array('@text' => 100),
1479                             'message'      => array('@text' => ''),
1480                             'totalitems'   => array('@text' => 0),
1481                             'itemsperpage' => array('@text' => $limit)
1482                         ),
1483                         'data' => array()
1484                     );
1485                 }
1486                 return $response;
1487             }
1488 
1489             if (false === $hasSearchPart) {
1490                 $cache->save($contentsList, $cacheName, array(), 1800);
1491             }
1492         }
1493 
1494         if ($this->_format == 'json') {
1495             $response['totalitems'] = count($contentsList);
1496             $response['data'] = $contentsList;
1497         } else {
1498             $response['meta']['totalitems'] = array('@text' => count($contentsList));
1499             $response['data'] = array('content' => $contentsList);
1500         }
1501 
1502         return $response;
1503     }
1504 
1505     /**
1506      * @param $previewPicSize
1507      * @param $smallPreviewPicSize
1508      * @param $pploadApi
1509      * @param $projects
1510      *
1511      * @return array
1512      */
1513     protected function _buildContentList($previewPicSize, $smallPreviewPicSize, $pploadApi, $projects, $tags)
1514     {
1515         $contentsList = array();
1516         $helperTruncate = new Default_View_Helper_Truncate();
1517         foreach ($projects as $project) {
1518             $project->description = $helperTruncate->truncate(Default_Model_BBCode::renderHtml(Default_Model_HtmlPurify::purify($project->description)),300);
1519 
1520             $categoryXdgType = '';
1521             if (!empty($project->xdg_type)) {
1522                 $categoryXdgType = $project->xdg_type;
1523             }
1524 
1525             $created = date('c', strtotime($project->created_at));
1526             $changed = date('c', strtotime($project->changed_at));
1527 
1528             $previewPage = $this->_uriScheme . '://' . $this->_config['website'] . '/p/' . $project->project_id;
1529 
1530             list($previewPics, $smallPreviewPics) = $this->getGalleryPictures($project, $previewPicSize, $smallPreviewPicSize);
1531 
1532             $downloads = $project->count_downloads_hive;
1533             list($downloadItems, $downloads) = $this->getPPLoadInfo($project, $pploadApi, $downloads, $tags);
1534 
1535             if(count($downloadItems)>0) {
1536                 if ($this->_format == 'json') {
1537                     $contentsList[] = array(
1538                             'details'     => 'summary',
1539                             'id'          => $project->project_id,
1540                             'name'        => $project->title,
1541                             'version'     => $project->version,
1542                             'typeid'      => $project->project_category_id,
1543                             'typename'    => $project->cat_title,
1544                             'xdg_type'    => $categoryXdgType,
1545                             'language'    => '',
1546                             'personid'    => $project->member_username,
1547                             'created'     => $created,
1548                             'changed'     => $changed,
1549                             'downloads'   => $downloads,
1550                             'score'       => $project->laplace_score,
1551                             'summary'     => '',
1552                             'description' => $project->description,
1553                             'comments'    => $project->count_comments,
1554                             'ghns_excluded' => $project->ghns_excluded,
1555                             'preview1'    => $previewPage,
1556                             'detailpage'  => $previewPage,
1557                             'tags'        => $project->tags
1558                         ) + $previewPics + $smallPreviewPics + $downloadItems;
1559                 } else {
1560                     foreach ($previewPics as $key => $value) {
1561                         $previewPics[$key] = array('@text' => $value);
1562                     }
1563                     foreach ($smallPreviewPics as $key => $value) {
1564                         $smallPreviewPics[$key] = array('@text' => $value);
1565                     }
1566                     if ($downloadItems) {
1567                         foreach ($downloadItems as $key => $value) {
1568                             $downloadItems[$key] = array('@text' => $value);
1569                         }
1570                     }
1571                     $contentsList[] = array(
1572                             'details'     => 'summary',
1573                             'id'          => array('@text' => $project->project_id),
1574                             'name'        => array('@text' => $project->title),
1575                             'version'     => array('@text' => $project->version),
1576                             'typeid'      => array('@text' => $project->project_category_id),
1577                             'typename'    => array('@text' => $project->cat_title),
1578                             'xdg_type'    => array('@text' => $categoryXdgType),
1579                             'language'    => array('@text' => ''),
1580                             'personid'    => array('@text' => $project->member_username),
1581                             'created'     => array('@text' => $created),
1582                             'changed'     => array('@text' => $changed),
1583                             'downloads'   => array('@text' => $downloads),
1584                             'score'       => array('@text' => $project->laplace_score),
1585                             'summary'     => array('@text' => ''),
1586                             'description' => array('@cdata' => $project->description),
1587                             'comments'    => array('@text' => $project->count_comments),
1588                             'ghns_excluded' => array('@text' => $project->ghns_excluded),
1589                             'preview1'    => array('@text' => $previewPage),
1590                             'detailpage'  => array('@text' => $previewPage),
1591                             'tags'        => array('@text' => $project->tags)
1592                         ) + $previewPics + $smallPreviewPics + $downloadItems;
1593                 }
1594             }
1595         }
1596 
1597         return $contentsList;
1598     }
1599 
1600     public function contentdownloadAction()
1601     {
1602 
1603         $uri = $this->view->url();
1604 
1605         $params = $this->getRequest()->getParams();
1606         $params['domain_store_id'] = $this->_getNameForStoreClient();
1607 
1608         $result = $this->_request('GET', $uri, $params);
1609         $this->_sendResponse($result, $this->_format);
1610 
1611         /*
1612 
1613         if (!$this->_authenticateUser()) {
1614             //$this->_sendErrorResponse(999, '');
1615         }
1616 
1617         $pploadApi = new Ppload_Api(array(
1618             'apiUri'   => PPLOAD_API_URI,
1619             'clientId' => PPLOAD_CLIENT_ID,
1620             'secret'   => PPLOAD_SECRET
1621         ));
1622 
1623         $project = null;
1624         $file = null;
1625 
1626         if ($this->getParam('contentid')) {
1627             $tableProject = new Default_Model_Project();
1628             $project = $tableProject->fetchRow(
1629                 $tableProject->select()
1630                              ->where('project_id = ?', $this->getParam('contentid'))
1631                              ->where('status = ?', Default_Model_Project::PROJECT_ACTIVE));
1632         }
1633 
1634         if (!$project) {
1635             $this->_sendErrorResponse(101, 'content not found');
1636         }
1637 
1638         if ($project->ppload_collection_id
1639             && $this->getParam('itemid')
1640             && ctype_digit((string)$this->getParam('itemid'))
1641         ) {
1642             $filesRequest = array(
1643                 'collection_id'     => $project->ppload_collection_id,
1644                 'ocs_compatibility' => 'compatible',
1645                 'perpage'           => 1,
1646                 'page'              => $this->getParam('itemid')
1647             );
1648 
1649             $filesResponse = $pploadApi->getFiles($filesRequest);
1650 
1651             if (isset($filesResponse->status)
1652                 && $filesResponse->status == 'success') {
1653                 $i = 0;
1654                 $file = $filesResponse->files->$i;
1655             }
1656         }
1657 
1658         if (!$file) {
1659             $this->_sendErrorResponse(103, 'content item not found');
1660         }
1661 
1662         //create ppload download hash: secret + collection_id + expire-timestamp
1663         $salt = PPLOAD_DOWNLOAD_SECRET;
1664         $collectionID = $project->ppload_collection_id;
1665         $timestamp = time() + (3600 * 12); // 12 hours valid
1666         $hash = md5($salt . $collectionID . $timestamp);
1667 
1668         $tags = $this->_parseFileTags($file->tags);
1669         $downloadLink = PPLOAD_API_URI . 'files/download/id/' . $file->id . '/s/' . $hash . '/t/' . $timestamp . '/o/1/' . $file->name;
1670 
1671         if ($this->_format == 'json') {
1672             $response = array(
1673                 'status'     => 'ok',
1674                 'statuscode' => 100,
1675                 'message'    => '',
1676                 'data'       => array(
1677                     array(
1678                         'details'               => 'download',
1679                         'downloadway'           => 1,
1680                         'downloadlink'          => $downloadLink,
1681                         'mimetype'              => $file->type,
1682                         'gpgfingerprint'        => '',
1683                         'gpgsignature'          => '',
1684                         'packagename'           => '',
1685                         'repository'            => '',
1686                         'download_package_type' => $tags['packagetypeid'],
1687                         'download_package_arch' => $tags['packagearch'],
1688                         'architecture' => $tags['architectureid'],
1689                         'downloadtags'          => empty($tags['filetags'])?'':implode(',',$tags['filetags'])
1690                     )
1691                 )
1692             );
1693         } else {
1694             $response = array(
1695                 'meta' => array(
1696                     'status'     => array('@text' => 'ok'),
1697                     'statuscode' => array('@text' => 100),
1698                     'message'    => array('@text' => '')
1699                 ),
1700                 'data' => array(
1701                     'content' => array(
1702                         'details'               => 'download',
1703                         'downloadway'           => array('@text' => 1),
1704                         'downloadlink'          => array('@text' => $downloadLink),
1705                         'mimetype'              => array('@text' => $file->type),
1706                         'gpgfingerprint'        => array('@text' => ''),
1707                         'gpgsignature'          => array('@text' => ''),
1708                         'packagename'           => array('@text' => ''),
1709                         'repository'            => array('@text' => ''),
1710                         'download_package_type' => array('@text' => $tags['packagetypeid']),
1711                         'download_package_arch' => array('@text' => $tags['packagearch']),
1712                         'architecture' => array('@text' => $tags['architectureid']),
1713                         'downloadtags'          => array('@text' => empty($tags['filetags'])?'':implode(',',$tags['filetags']))
1714                     )
1715                 )
1716             );
1717         }
1718 
1719         $this->_sendResponse($response, $this->_format);
1720          *
1721          */
1722     }
1723 
1724     public function contentpreviewpicAction()
1725     {
1726 
1727         $uri = $this->view->url();
1728 
1729         $params = $this->getRequest()->getParams();
1730         $params['domain_store_id'] = $this->_getNameForStoreClient();
1731 
1732         $result = $this->_request('GET', $uri, $params);
1733         $this->_sendResponse($result, $this->_format);
1734 
1735 
1736 
1737         /*
1738         if (!$this->_authenticateUser()) {
1739             //$this->_sendErrorResponse(999, '');
1740         }
1741 
1742         $project = null;
1743 
1744         if ($this->getParam('contentid')) {
1745             $tableProject = new Default_Model_Project();
1746             $project = $tableProject->fetchRow($tableProject->select()
1747                                                             ->where('project_id = ?', $this->getParam('contentid'))
1748                                                             ->where('status = ?', Default_Model_Project::PROJECT_ACTIVE));
1749         }
1750 
1751         if (!$project) {
1752             //$this->_sendErrorResponse(101, 'content not found');
1753             header('Location: ' . $this->_config['icon']);
1754             exit;
1755         }
1756 
1757         $viewHelperImage = new Default_View_Helper_Image();
1758         $previewPicSize = array(
1759             'width'  => 100,
1760             'height' => 100
1761         );
1762 
1763         if (!empty($this->_params['size'])
1764             && strtolower($this->_params['size']) == 'medium') {
1765             $previewPicSize = array(
1766                 'width'  => 770,
1767                 'height' => 540
1768             );
1769         }
1770 
1771         $previewPicUri = $viewHelperImage->Image($project->image_small, $previewPicSize);
1772 
1773         header('Location: ' . $previewPicUri);
1774         exit;
1775          *
1776          */
1777     }
1778 
1779     /**
1780      * @param null  $tableCategories
1781      * @param null  $parentCategoryId
1782      * @param array $categoriesList
1783      *
1784      * @return array
1785      * @deprecated
1786      */
1787     protected function _buildCategoriesList($tableCategories = null, $parentCategoryId = null, $categoriesList = array())
1788     {
1789         $categories = null;
1790 
1791         // Top-level categories
1792         if (!$tableCategories) {
1793             $tableCategories = new Default_Model_DbTable_ProjectCategory();
1794             if (Zend_Registry::isRegistered('store_category_list')) {
1795                 $categories = $tableCategories->fetchActive(Zend_Registry::get('store_category_list'));
1796             } else {
1797                 $categories = $tableCategories->fetchAllActive();
1798             }
1799         } // Sub-categories
1800         else {
1801             if ($parentCategoryId) {
1802                 $categories = $tableCategories->fetchImmediateChildren($parentCategoryId);
1803             }
1804         }
1805 
1806         // Build categories list
1807         if (!empty($categories)) {
1808             foreach ($categories as $category) {
1809                 if (is_array($category)) {
1810                     $category = (object)$category;
1811                 }
1812 
1813                 $categoryName = $category->title;
1814                 $categoryDisplayName = $category->title;
1815                 if (!empty($category->name_legacy)) {
1816                     $categoryName = $category->name_legacy;
1817                 }
1818                 $categoryParentId = '';
1819                 if (!empty($parentCategoryId)) {
1820                     $categoryParentId = $parentCategoryId;
1821                 }
1822                 $categoryXdgType = '';
1823                 if (!empty($category->xdg_type)) {
1824                     $categoryXdgType = $category->xdg_type;
1825                 }
1826 
1827                 if ($this->_format == 'json') {
1828                     $categoriesList[] = array(
1829                         'id'           => $category->project_category_id,
1830                         'name'         => $categoryName,
1831                         'display_name' => $categoryDisplayName,
1832                         'parent_id'    => $categoryParentId,
1833                         'xdg_type'     => $categoryXdgType
1834                     );
1835                 } else {
1836                     $categoriesList[] = array(
1837                         'id'           => array('@text' => $category->project_category_id),
1838                         'name'         => array('@text' => $categoryName),
1839                         'display_name' => array('@text' => $categoryDisplayName),
1840                         'parent_id'    => array('@text' => $categoryParentId),
1841                         'xdg_type'     => array('@text' => $categoryXdgType)
1842                     );
1843                 }
1844 
1845                 // Update the list recursive
1846                 $categoriesList = $this->_buildCategoriesList($tableCategories, $category->project_category_id, $categoriesList);
1847             }
1848         }
1849 
1850         return $categoriesList;
1851     }
1852 
1853     public function commentsAction()
1854     {
1855         $uri = $this->view->url();
1856 
1857         $params = $this->getRequest()->getParams();
1858         $params['domain_store_id'] = $this->_getNameForStoreClient();
1859 
1860         $result = $this->_request('GET', $uri, $params);
1861         $this->_sendResponse($result, $this->_format);
1862 
1863         /*
1864         if ($this->_format == 'json') {
1865             $response = array(
1866                 'status'     => 'ok',
1867                 'statuscode' => 100,
1868                 'message'    => '',
1869                 'data'       => array()
1870             );
1871         } else {
1872             $response = array(
1873                 'meta' => array(
1874                     'status'     => array('@text' => 'ok'),
1875                     'statuscode' => array('@text' => 100),
1876                     'message'    => array('@text' => ''),
1877                 ),
1878                 'data' => array()
1879             );
1880         }
1881 
1882         $commentType = (int)$this->getParam('comment_type', -1);
1883         if ($commentType != self::COMMENT_TYPE_CONTENT) {
1884             $this->_sendResponse($response, $this->_format);
1885         }
1886 
1887         $contentId = (int)$this->getParam('content_id', null);
1888         if (empty($contentId)) {
1889             $this->_sendResponse($response, $this->_format);
1890         }
1891 
1892         $page = (int)$this->getParam('page', 0) + 1;
1893         $pagesize = (int)$this->getParam('pagesize', 10);
1894 
1895         ** @var Zend_Cache_Core $cache *
1896         $cache = Zend_Registry::get('cache');
1897         $cacheName = 'api_fetch_comments_' . md5("{$commentType}, {$contentId}, {$page}, {$pagesize}" . '_format_' . $this->_format);
1898 
1899         if (($cachedResponse = $cache->load($cacheName))) {
1900             $this->_sendResponse($cachedResponse, $this->_format);
1901         }
1902 
1903         $modelComments = new Default_Model_ProjectComments();
1904         $comments = $modelComments->getCommentsHierarchic($contentId);
1905 
1906         if ($comments->count() == 0) {
1907             $this->_sendResponse($response, $this->_format);
1908         }
1909 
1910         $comments->setCurrentPageNumber($page);
1911         $comments->setItemCountPerPage($pagesize);
1912 
1913         $response['data'] = array('comment' => $this->_buildCommentList($comments->getCurrentItems()));
1914         $cache->save($response, $cacheName, array(), 1800);
1915 
1916         $this->_sendResponse($response, $this->_format);
1917          *
1918          */
1919     }
1920 
1921     /**
1922      * @param Traversable $currentItems
1923      *
1924      * @return array
1925      */
1926     protected function _buildCommentList($currentItems)
1927     {
1928         $commentList = array();
1929         foreach ($currentItems as $current_item) {
1930             if ($this->_format == 'json') {
1931                 $comment = array(
1932                     'id'         => $current_item['comment_id'],
1933                     'subject'    => '',
1934                     'text'       => Default_Model_HtmlPurify::purify($current_item['comment_text']),
1935                     'childcount' => $current_item['childcount'],
1936                     'user'       => $current_item['username'],
1937                     'date'       => date('c', strtotime($current_item['comment_created_at'])),
1938                     'score'      => 0
1939                 );
1940                 if ($current_item['childcount'] > 0) {
1941                     $comment['children'] = $this->_buildCommentList($current_item['children']);
1942                 }
1943             } else {
1944                 $comment = array(
1945                     'id'         => array('@text' => $current_item['comment_id']),
1946                     'subject'    => array('@text' => ''),
1947                     'text'       => array('@text' => Default_Model_HtmlPurify::purify($current_item['comment_text'])),
1948                     'childcount' => array('@text' => $current_item['childcount']),
1949                     'user'       => array('@text' => $current_item['username']),
1950                     'date'       => array('@text' => date('c', strtotime($current_item['comment_created_at']))),
1951                     'score'      => array('@text' => 0)
1952                 );
1953                 if ($current_item['childcount'] > 0) {
1954                     $comment['children'] = $this->_buildCommentList($current_item['children']);
1955                 }
1956             }
1957             $commentList[] = $comment;
1958         }
1959 
1960         return $commentList;
1961     }
1962 
1963 
1964     protected function _request($method, $uri = '', array $params = null)
1965     {
1966 
1967         $config = Zend_Registry::get('config');
1968         $static_config = $config->settings->ocs_server;
1969 
1970         $ocsServer = $static_config->apiUri;
1971 
1972         $timeout = 60;
1973         $postFields = array();
1974         if ($params) {
1975             $postFields = $postFields + $params;
1976         }
1977         if (isset($postFields['file'])) {
1978             $timeout = 600;
1979             if ($postFields['file'][0] != '@') {
1980                 $postFields['file'] = $this->_getCurlValue($postFields['file']);
1981             }
1982         }
1983         else {
1984             $postFields = http_build_query($postFields, '', '&');
1985         }
1986 
1987         //var_dump($ocsServer . $uri . '?' . $postFields);
1988 
1989 
1990         $curl = curl_init();
1991         curl_setopt_array($curl, array(
1992             CURLOPT_URL => $ocsServer . $uri,
1993             CURLOPT_HEADER => false,
1994             CURLOPT_POST => true,
1995             CURLOPT_POSTFIELDS => $postFields,
1996             CURLOPT_RETURNTRANSFER => true,
1997             CURLOPT_TIMEOUT => $timeout
1998         ));
1999 
2000         $response = curl_exec($curl);
2001         curl_close($curl);
2002 
2003         if ($response) {
2004             return $response;
2005         }
2006         return false;
2007     }
2008 
2009     public function voteAction()
2010     {
2011         $this->_sendErrorResponse(405, 'method not allowed', true);
2012     }
2013 
2014 }