diff --git a/application/modules/default/Bootstrap.php b/application/modules/default/Bootstrap.php index 3c62c7e1f..07e13a460 100644 --- a/application/modules/default/Bootstrap.php +++ b/application/modules/default/Bootstrap.php @@ -1,1108 +1,1109 @@ . **/ class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { protected function _initAutoload() { $autoloader = new Zend_Application_Module_Autoloader(array( 'namespace' => 'Default', 'basePath' => realpath(dirname(__FILE__)), )); $autoloader->addResourceType('formelements', 'forms/elements', 'Form_Element'); $autoloader->addResourceType('formvalidators', 'forms/validators', 'Form_Validator'); return $autoloader; } protected function _initSessionManagement() { $config = $this->getOption('settings'); if ($config['session']['saveHandler']['replace']['enabled'] == false) { return; } if (APPLICATION_ENV != 'development') { $domain = $this->get_domain($_SERVER['SERVER_NAME']); } else { $domain = $_SERVER['SERVER_NAME']; } $cacheClass = 'Zend_Cache_Backend_'.$config['session']['saveHandler']['cache']['type']; $_cache = new $cacheClass($config['session']['saveHandler']['options']); Zend_Loader::loadClass($config['session']['saveHandler']['class']); Zend_Session::setSaveHandler(new $config['session']['saveHandler']['class']($_cache)); Zend_Session::setOptions(array('cookie_domain' => $domain)); Zend_Session::start(); } /** * @param string $domain * * @return bool|string */ private function get_domain($domain) { if (preg_match('/(?P[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain, $regs)) { return $regs['domain']; } return false; } protected function _initConfig() { /** $config Zend_Config */ $config = $this->getApplication()->getApplicationConfig(); Zend_Registry::set('config', $config); return $config; } protected function _initCache() { if (Zend_Registry::isRegistered('cache')) { return Zend_Registry::get('cache'); } $cache = null; $options = $this->getOption('settings'); if (true == $options['cache']['enabled']) { $cache = Zend_Cache::factory( $options['cache']['frontend']['type'], $options['cache']['backend']['type'], $options['cache']['frontend']['options'], $options['cache']['backend']['options'] ); } else { // Fallback settings for some (maybe development) environments which have no cache management installed. if (false === is_writeable(APPLICATION_CACHE)) { error_log('directory for cache files does not exists or not writable: ' . APPLICATION_CACHE); exit('directory for cache files does not exists or not writable: ' . APPLICATION_CACHE); } $frontendOptions = array( 'lifetime' => 600, 'automatic_serialization' => true, 'cache_id_prefix' => 'front_cache', 'cache' => true ); $backendOptions = array( 'cache_dir' => APPLICATION_CACHE, 'file_locking' => true, 'read_control' => true, 'read_control_type' => 'crc32', 'hashed_directory_level' => 1, 'hashed_directory_perm' => 0700, 'file_name_prefix' => 'ocs', 'cache_file_perm' => 0700 ); $cache = Zend_Cache::factory( 'Core', 'File', $frontendOptions, $backendOptions ); } Zend_Registry::set('cache', $cache); Zend_Locale::setCache($cache); Zend_Locale_Data::setCache($cache); Zend_Currency::setCache($cache); Zend_Translate::setCache($cache); Zend_Translate_Adapter::setCache($cache); Zend_Db_Table_Abstract::setDefaultMetadataCache($cache); Zend_Paginator::setCache($cache); return $cache; } protected function _initViewConfig() { $view = $this->bootstrap('view')->getResource('view'); $view->addHelperPath(APPLICATION_PATH . '/modules/default/views/helpers', 'Default_View_Helper_'); $view->addHelperPath(APPLICATION_LIB . '/Zend/View/Helper', 'Zend_View_Helper_'); $options = $this->getOptions(); $docType = $options['resources']['view']['doctype'] ? $options['resources']['view']['doctype'] : 'XHTML1_TRANSITIONAL'; $view->doctype($docType); } protected function _initLocale() { $configResources = $this->getOption('resources'); Zend_Locale::setDefault($configResources['locale']['default']); Zend_Registry::set($configResources['locale']['registry_key'], $configResources['locale']['default']); } protected function _initTranslate() { $options = $this->getOption('resources'); $options = $options['translate']; if (!isset($options['data'])) { throw new Zend_Application_Resource_Exception( 'not found the file'); } $adapter = isset($options['adapter']) ? $options['adapter'] : Zend_Translate::AN_ARRAY; $session = new Zend_Session_Namespace('aa'); if ($session->locale) { $locale = $session->locale; } else { $locale = isset($options['locale']) ? $options['locale'] : null; } $data = ''; if (isset($options['data'][$locale])) { $data = $options['data'][$locale]; } $translateOptions = isset($options['options']) ? $options['options'] : array(); $translate = new Zend_Translate($adapter, $data, $locale, $translateOptions); Zend_Form::setDefaultTranslator($translate); Zend_Validate_Abstract::setDefaultTranslator($translate); Zend_Registry::set('Zend_Translate', $translate); return $translate; } protected function _initDbAdapter() { $db = $this->bootstrap('db')->getResource('db'); //( if ((APPLICATION_ENV == 'development') OR (APPLICATION_ENV == 'testing')) { // $profiler = new Zend_Db_Profiler_Firebug('All DB Queries'); // $profiler->setEnabled(true); // // // Attach the profiler to your db adapter // $db->setProfiler($profiler); // } Zend_Registry::set('db', $db); Zend_Db_Table::setDefaultAdapter($db); Zend_Db_Table_Abstract::setDefaultAdapter($db); } protected function _initLogger() { $settings = $this->getOption('settings'); $log = new Zend_Log(); $writer = new Zend_Log_Writer_Stream($settings['log']['path'] . 'all_' . date("Y-m-d")); $writer->addFilter(new Local_Log_Filter_MinMax(Zend_Log::WARN, Zend_Log::INFO)); $log->addWriter($writer); $errorWriter = new Zend_Log_Writer_Stream($settings['log']['path'] . 'err_' . date('Y-m-d')); $errorWriter->addFilter(new Zend_Log_Filter_Priority(Zend_Log::ERR)); $log->addWriter($errorWriter); Zend_Registry::set('logger', $log); if ((APPLICATION_ENV == 'development') OR (APPLICATION_ENV == 'testing')) { $firebugWriter = new Zend_Log_Writer_Firebug(); $firebugLog = new Zend_Log($firebugWriter); Zend_Registry::set('firebug_log', $firebugLog); } } protected function _initGlobals() { Zend_Paginator::setDefaultScrollingStyle('Elastic'); Zend_View_Helper_PaginationControl::setDefaultViewPartial('paginationControl.phtml'); Zend_Filter::addDefaultNamespaces('Local_Filter'); $version = $this->getOption('version'); defined('APPLICATION_VERSION') || define('APPLICATION_VERSION', $version); } protected function _initAclRules() { /** @var Zend_Cache_Core $appCache */ $appCache = $this->getResource('cache'); if (false == ($aclRules = $appCache->load('AclRules'))) { $aclRules = new Default_Plugin_AclRules(); Zend_Registry::set('acl', $aclRules); $appCache->save($aclRules, 'AclRules', array('AclRules'), 14400); } return $aclRules; } protected function _initPlugins() { /** @var $front Zend_Controller_Front */ $front = $this->bootstrap('frontController')->getResource('frontController'); $aclRules = $this->bootstrap('aclRules')->getResource('aclRules'); $front->unregisterPlugin('Zend_Controller_Plugin_ErrorHandler'); $front->registerPlugin(new Default_Plugin_ErrorHandler()); $front->registerPlugin(new Default_Plugin_RememberMe(Zend_Auth::getInstance())); $front->registerPlugin(new Default_Plugin_SignOn(Zend_Auth::getInstance())); $front->registerPlugin(new Default_Plugin_Acl(Zend_Auth::getInstance(), $aclRules)); $loader = new Zend_Loader_PluginLoader(); $loader->addPrefixPath('Zend_View_Helper', APPLICATION_LIB . '/Zend/View/Helper/') ->addPrefixPath('Zend_Form_Element', APPLICATION_LIB . '/Zend/Form/Element') ->addPrefixPath('Default_View_Helper', APPLICATION_PATH . '/modules/default/views/helpers') ->addPrefixPath('Default_Form_Helper', APPLICATION_PATH . '/modules/default/forms/helpers') ->addPrefixPath('Default_Form_Element', APPLICATION_PATH . '/modules/default/forms/elements') ->addPrefixPath('Default_Form_Decorator', APPLICATION_PATH . '/modules/default/forms/decorators') ->addPrefixPath('Default_Form_Validator', APPLICATION_PATH . '/modules/default/forms/validators'); } protected function _initAuthSessionNamespace() { $config = $this->getResource('config'); $auth_config = $config->settings->auth_session; $objSessionNamespace = new Zend_Session_Namespace($auth_config->name); $objSessionNamespace->setExpirationSeconds($auth_config->timeout); Zend_Auth::getInstance()->setStorage(new Zend_Auth_Storage_Session($auth_config->name)); } protected function _initThirdParty() { $appConfig = $this->getResource('config'); $imageConfig = $appConfig->images; defined('IMAGES_UPLOAD_PATH') || define('IMAGES_UPLOAD_PATH', $imageConfig->upload->path); defined('IMAGES_MEDIA_SERVER') || define('IMAGES_MEDIA_SERVER', $imageConfig->media->server); // ppload $pploadConfig = $appConfig->third_party->ppload; defined('PPLOAD_API_URI') || define('PPLOAD_API_URI', $pploadConfig->api_uri); defined('PPLOAD_CLIENT_ID') || define('PPLOAD_CLIENT_ID', $pploadConfig->client_id); defined('PPLOAD_SECRET') || define('PPLOAD_SECRET', $pploadConfig->secret); } protected function _initRouter() { $this->bootstrap('frontController'); /** @var $front Zend_Controller_Front */ $front = $this->getResource('frontController'); /** @var Zend_Cache_Core $cache */ $cache = Zend_Registry::get('cache'); if (($router = $cache->load('ProjectRouter'))) { $front->setRouter($router); return $router; } /** @var $router Zend_Controller_Router_Rewrite */ $router = $front->getRouter(); /** RSS Feed */ $router->addRoute( 'rdf_store', new Zend_Controller_Router_Route( '/content.rdf', array( 'module' => 'default', 'controller' => 'rss', 'action' => 'rdf' ) ) ); $router->addRoute( 'rdf_events_hive', new Zend_Controller_Router_Route_Regex( '.*-events.rss', array( 'module' => 'default', 'controller' => 'rss', 'action' => 'rss' ) ) ); $router->addRoute( 'rdf_store_hive', new Zend_Controller_Router_Route_Regex( '.*-content.rdf', array( 'module' => 'default', 'controller' => 'rss', 'action' => 'rdf' ) ) ); $router->addRoute( 'rdf_store_hive_rss', new Zend_Controller_Router_Route_Regex( 'rss/.*-content.rdf', array( 'module' => 'default', 'controller' => 'rss', 'action' => 'rdf' ) ) ); /** new store dependent routing rules */ $router->addRoute( 'store_home', new Zend_Controller_Router_Route( '/s/:domain_store_id/', array( 'module' => 'default', 'controller' => 'home', 'action' => 'index' ) ) ); $router->addRoute( 'store_browse', new Zend_Controller_Router_Route( '/s/:domain_store_id/browse/*', array( 'module' => 'default', 'controller' => 'explore', 'action' => 'index' ) ) ); $router->addRoute( 'store_product', new Zend_Controller_Router_Route( '/s/:domain_store_id/p/:project_id/:action/*', array( 'module' => 'default', 'controller' => 'product', 'action' => 'show' ) ) ); $router->addRoute( 'store_user', new Zend_Controller_Router_Route( '/s/:domain_store_id/member/:member_id/:action/*', array( 'module' => 'default', 'controller' => 'user', 'action' => 'index' ) ) ); /** general routing rules */ $router->addRoute( 'home', new Zend_Controller_Router_Route( '/', array( 'module' => 'default', 'controller' => 'home', 'action' => 'index' ) ) ); $router->addRoute( 'home_ajax', new Zend_Controller_Router_Route( '/showfeatureajax/*', array( 'module' => 'default', 'controller' => 'home', 'action' => 'showfeatureajax' ) ) ); $router->addRoute( 'backend', new Zend_Controller_Router_Route( '/backend/:controller/:action/*', array( 'module' => 'backend', 'controller' => 'index', 'action' => 'index' ) ) ); $router->addRoute( 'browse', new Zend_Controller_Router_Route( '/browse/*', array( 'module' => 'default', 'controller' => 'explore', 'action' => 'index' ) ) ); $router->addRoute( 'button_render', new Zend_Controller_Router_Route( '/button/:project_id/:size/', array( 'module' => 'default', 'controller' => 'button', 'action' => 'render', 'size' => 'large' ) ) ); $router->addRoute( 'button_action', new Zend_Controller_Router_Route( '/button/a/:action/', array( 'module' => 'default', 'controller' => 'button', 'action' => 'index' ) ) ); $router->addRoute( 'supporter_box_show', new Zend_Controller_Router_Route( '/supporterbox/:project_uuid/', array( 'module' => 'default', 'controller' => 'supporterbox', 'action' => 'render' ) ) ); $router->addRoute( 'external_donation_list', new Zend_Controller_Router_Route( '/donationlist/:project_id/', array( 'module' => 'default', 'controller' => 'donationlist', 'action' => 'render' ) ) ); $router->addRoute( 'external_widget', new Zend_Controller_Router_Route( '/widget/:project_id/', array( 'module' => 'default', 'controller' => 'widget', 'action' => 'render' ) ) ); $router->addRoute( 'external_widget_save', new Zend_Controller_Router_Route( '/widget/save/*', array( 'module' => 'default', 'controller' => 'widget', 'action' => 'save' ) ) ); $router->addRoute( 'external_widget_save', new Zend_Controller_Router_Route( '/widget/config/:project_id/', array( 'module' => 'default', 'controller' => 'widget', 'action' => 'config' ) ) ); $router->addRoute( 'external_widget_save_default', new Zend_Controller_Router_Route( '/widget/savedefault/*', array( 'module' => 'default', 'controller' => 'widget', 'action' => 'savedefault' ) ) ); /** * Project/Product */ $router->addRoute( 'product_short_url', new Zend_Controller_Router_Route( '/p/:project_id/:action/*', array( 'module' => 'default', 'controller' => 'product', 'action' => 'show' ) ) ); $router->addRoute( 'product_referrer_url', new Zend_Controller_Router_Route( '/p/:project_id/er/:er/*', array( 'module' => 'default', 'controller' => 'product', 'action' => 'show' ) ) ); $router->addRoute( 'product_add', new Zend_Controller_Router_Route( '/product/add', array( 'module' => 'default', 'controller' => 'product', 'action' => 'add' ) ) ); $router->addRoute( 'search', new Zend_Controller_Router_Route( '/search/*', array( 'module' => 'default', 'controller' => 'product', 'action' => 'search' ) ) ); $router->addRoute( 'product_save', new Zend_Controller_Router_Route( '/p/save/*', array( 'module' => 'default', 'controller' => 'product', 'action' => 'saveproduct' ) ) ); /** * Member */ $router->addRoute( 'member_settings_old', new Zend_Controller_Router_Route( '/settings/:action/*', array( 'module' => 'default', 'controller' => 'settings', 'action' => 'index' ) ) ); $router->addRoute( 'user_show', new Zend_Controller_Router_Route( '/member/:member_id/:action/*', array( 'module' => 'default', 'controller' => 'user', 'action' => 'index' ) ) ); $router->addRoute( 'user_show_short', new Zend_Controller_Router_Route( '/me/:member_id/:action/*', array( 'module' => 'default', 'controller' => 'user', 'action' => 'index' ) ) ); $router->addRoute( 'register', new Zend_Controller_Router_Route_Static( '/register', array( 'module' => 'default', 'controller' => 'authorization', 'action' => 'register' ) ) ); $router->addRoute( 'register_validate', new Zend_Controller_Router_Route_Static( '/register/validate', array( 'module' => 'default', 'controller' => 'authorization', 'action' => 'validate' ) ) ); $router->addRoute( 'verification', new Zend_Controller_Router_Route( '/verification/:vid', array( 'module' => 'default', 'controller' => 'authorization', 'action' => 'verification' ) ) ); $router->addRoute( 'logout', new Zend_Controller_Router_Route_Static( '/logout', array( 'module' => 'default', 'controller' => 'authorization', 'action' => 'logout' ) ) ); $router->addRoute( 'propagatelogout', new Zend_Controller_Router_Route_Static( '/logout/propagate', array( 'module' => 'default', 'controller' => 'authorization', 'action' => 'propagatelogout' ) ) ); $router->addRoute( 'login', new Zend_Controller_Router_Route( '/login', array( 'module' => 'default', 'controller' => 'authorization', 'action' => 'login' ) ) ); $router->addRoute( 'login', new Zend_Controller_Router_Route( '/login/:action/*', array( 'module' => 'default', 'controller' => 'authorization', 'action' => 'login' ) ) ); $router->addRoute( 'content', new Zend_Controller_Router_Route( '/content/:page', array( 'module' => 'default', 'controller' => 'content', 'action' => 'index' ) ) ); $router->addRoute( 'categories_about', new Zend_Controller_Router_Route( '/cat/:page/about', array( 'module' => 'default', 'controller' => 'categories', 'action' => 'about' ) ) ); // **** static routes $router->addRoute( 'static_faq', new Zend_Controller_Router_Route_Static( '/faq', array( 'module' => 'default', 'controller' => 'content', 'action' => 'index', 'page' => 'faq' ) ) ); $router->addRoute( 'static_terms', new Zend_Controller_Router_Route_Static( '/terms', array( 'module' => 'default', 'controller' => 'content', 'action' => 'index', 'page' => 'terms' ) ) ); $router->addRoute( 'static_terms_general', new Zend_Controller_Router_Route_Static( '/terms/general', array( 'module' => 'default', 'controller' => 'content', 'action' => 'index', 'page' => 'terms-general' ) ) ); $router->addRoute( 'static_terms_publish', new Zend_Controller_Router_Route_Static( '/terms/publishing', array( 'module' => 'default', 'controller' => 'content', 'action' => 'index', 'page' => 'terms-publishing' ) ) ); $router->addRoute( 'static_terms_dmca', new Zend_Controller_Router_Route_Static( '/terms/dmca', array( 'module' => 'default', 'controller' => 'content', 'action' => 'index', 'page' => 'terms-dmca' ) ) ); $router->addRoute( 'static_privacy', new Zend_Controller_Router_Route_Static( '/privacy', array( 'module' => 'default', 'controller' => 'content', 'action' => 'index', 'page' => 'privacy' ) ) ); $router->addRoute( 'static_contact', new Zend_Controller_Router_Route_Static( '/contact', array( 'module' => 'default', 'controller' => 'content', 'action' => 'index', 'page' => 'contact' ) ) ); // **** ppload $router->addRoute( 'pploadlogin', new Zend_Controller_Router_Route( '/pploadlogin/*', array( 'module' => 'default', 'controller' => 'authorization', 'action' => 'pploadlogin' ) ) ); // OCS API $router->addRoute( 'ocs_providers_xml', new Zend_Controller_Router_Route( '/ocs/providers.xml', array( 'module' => 'default', 'controller' => 'ocsv1', 'action' => 'providers' ) ) ); $router->addRoute( 'ocs_v1_config', new Zend_Controller_Router_Route( '/ocs/v1/config', array( 'module' => 'default', 'controller' => 'ocsv1', 'action' => 'config' ) ) ); $router->addRoute( 'ocs_v1_person_check', new Zend_Controller_Router_Route( '/ocs/v1/person/check', array( 'module' => 'default', 'controller' => 'ocsv1', 'action' => 'personcheck' ) ) ); $router->addRoute( 'ocs_v1_person_data', new Zend_Controller_Router_Route( '/ocs/v1/person/data', array( 'module' => 'default', 'controller' => 'ocsv1', 'action' => 'persondata' ) ) ); $router->addRoute( 'ocs_v1_person_data_personid', new Zend_Controller_Router_Route( '/ocs/v1/person/data/:personid', array( 'module' => 'default', 'controller' => 'ocsv1', 'action' => 'persondata' ) ) ); $router->addRoute( 'ocs_v1_person_self', new Zend_Controller_Router_Route( '/ocs/v1/person/self', array( 'module' => 'default', 'controller' => 'ocsv1', 'action' => 'personself' ) ) ); $router->addRoute( 'ocs_v1_content_categories', new Zend_Controller_Router_Route( '/ocs/v1/content/categories', array( 'module' => 'default', 'controller' => 'ocsv1', 'action' => 'contentcategories' ) ) ); - //$router->addRoute( - // 'ocs_v1_content_data', - // new Zend_Controller_Router_Route( - // '/ocs/v1/content/data', - // array( - // 'module' => 'default', - // 'controller' => 'ocsv1', - // 'action' => 'contentdata' - // ) - // ) - //); $router->addRoute( 'ocs_v1_content_data_contentid', new Zend_Controller_Router_Route( '/ocs/v1/content/data/:contentid', array( 'module' => 'default', 'controller' => 'ocsv1', 'action' => 'contentdata', 'contentid' => null ) ) ); $router->addRoute( 'ocs_v1_content_download_contentid_itemid', new Zend_Controller_Router_Route( '/ocs/v1/content/download/:contentid/:itemid', array( 'module' => 'default', 'controller' => 'ocsv1', 'action' => 'contentdownload' ) ) ); $router->addRoute( 'ocs_v1_content_previewpic_contentid', new Zend_Controller_Router_Route( '/ocs/v1/content/previewpic/:contentid', array( 'module' => 'default', 'controller' => 'ocsv1', 'action' => 'contentpreviewpic' ) ) ); + $router->addRoute('ocs_v1_comments', + new Zend_Controller_Router_Route( + '/ocs/v1/comments/data/:comment_type/:content_id/:second_id', + array( + 'module' => 'default', + 'controller' => 'ocsv1', + 'action' => 'comments', + 'comment_type' => -1, + 'content_id' => null, + 'second_id' => null + )) + ); // embed $router->addRoute( 'embed_v1_member_projects', new Zend_Controller_Router_Route( '/embed/v1/member/:memberid', array( 'module' => 'default', 'controller' => 'embedv1', 'action' => 'memberprojects' ) ) ); $router->addRoute( 'embed_v1_member_projects_files', new Zend_Controller_Router_Route( '/embed/v1/ppload/:ppload_collection_id', array( 'module' => 'default', 'controller' => 'embedv1', 'action' => 'ppload' ) ) ); $router->addRoute( 'embed_v1_member_projectscomments', new Zend_Controller_Router_Route( '/embed/v1/comments/:id', array( 'module' => 'default', 'controller' => 'embedv1', 'action' => 'comments' ) ) ); $router->addRoute( 'embed_v1_member_projectdetail', new Zend_Controller_Router_Route( '/embed/v1/project/:projectid', array( 'module' => 'default', 'controller' => 'embedv1', 'action' => 'projectdetail' ) ) ); $cache->save($router, 'ProjectRouter', array('router'), 14400); } protected function _initCss() { if (APPLICATION_ENV != "development" && APPLICATION_ENV != "staging") { return; } $appConfig = $this->getResource('config'); if ((boolean)$appConfig->settings->noLESScompile === true) { return; } $sLess = realpath(APPLICATION_PATH . '/../httpdocs/theme/flatui/less/stylesheet.less'); $sCss = realpath(APPLICATION_PATH . '/../httpdocs/theme/flatui/css/stylesheet.css'); /** * @var Zend_Cache_Core $cache */ $cache = Zend_Registry::get('cache'); if (md5_file($sLess) !== $cache->load('md5Less')) { require_once APPLICATION_PATH . "/../library/lessphp/lessc.inc.php"; $oLessc = new lessc($sLess); $oLessc->setFormatter('compressed'); file_put_contents($sCss, $oLessc->parse()); $cache->save(md5_file($sLess), 'md5Less'); } } protected function _initGlobalApplicationVars() { $modelDomainConfig = new Default_Model_DbTable_ConfigStore(); Zend_Registry::set('application_store_category_list', $modelDomainConfig->fetchAllStoresAndCategories()); Zend_Registry::set('application_store_config_list', $modelDomainConfig->fetchAllStoresConfigArray()); Zend_Registry::set('application_store_config_id_list', $modelDomainConfig->fetchAllStoresConfigByIdArray()); } protected function _initStoreDependentVars() { /** @var $front Zend_Controller_Front */ $front = $this->bootstrap('frontController')->getResource('frontController'); $front->registerPlugin(new Default_Plugin_InitGlobalStoreVars()); } // protected function _initOsDependentVars() // { // $modelOsConfig = new Default_Model_DbTable_ConfigOperatingSystem(); // Zend_Registry::set('application_os', $modelOsConfig->fetchOperatingSystems()); // } } diff --git a/application/modules/default/controllers/Ocsv1Controller.php b/application/modules/default/controllers/Ocsv1Controller.php index e73eaa9a3..6071ec7cb 100644 --- a/application/modules/default/controllers/Ocsv1Controller.php +++ b/application/modules/default/controllers/Ocsv1Controller.php @@ -1,1683 +1,1788 @@ . **/ /** * What changes from official OCS v1 spec * * OCS specification: * http://www.freedesktop.org/wiki/Specifications/open-collaboration-services/ * * ---- * * Allow delimiter ',' of value of parameter 'categories' * * Example: * /content/data?categories=1,2,3 * /content/data?categories=1x2x3 * * ---- * * Additional URL queries to '/content/data' * * xdg_types * package_types * * Example: * /content/data?xdg_types=icons,themes,wallpapers * /content/data?package_types=1,2,3 * * package_types: * 1 = AppImage * 2 = Android (apk) * 3 = OS X compatible * 4 = Windows executable * 5 = Debian * 6 = Snappy * 7 = Flatpak * 8 = Electron-Webapp * 9 = Arch * 10 = open/Suse * 11 = Redhat * * ---- * * Additional data field of '/content/categories' * * display_name * parent_id * xdg_type * * ---- * * Additional data field of '/content/data' * * xdg_type * download_package_type{n} * download_package_arch{n} * * ---- * * Additional data field of '/content/download' * * download_package_type * download_package_arch * * ---- * * Additional API method for preview picture * * /content/previewpic/{contentid} * * Example: * /content/previewpic/123456789 * /content/previewpic/123456789?size=medium */ class Ocsv1Controller extends Zend_Controller_Action { + const COMMENT_TYPE_CONTENT = 1; + const COMMENT_TYPE_FORUM = 4; + const COMMENT_TYPE_KNOWLEDGE = 7; + const COMMENT_TYPE_EVENT = 8; + protected $_authData = null; protected $_uriScheme = 'https'; protected $_format = 'xml'; protected $_config = array( 'id' => 'opendesktop.org', 'location' => 'https://www.opendesktop.org/ocs/v1/', 'name' => 'opendesktop.org', 'icon' => '', 'termsofuse' => 'https://www.opendesktop.org/terms', 'register' => 'https://www.opendesktop.org/register', 'version' => '1.7', 'website' => 'www.opendesktop.org', 'host' => 'www.opendesktop.org', 'contact' => 'contact@opendesktop.org', 'ssl' => true, 'user_host' => 'pling.me' ); protected $_params = array(); public function init() { parent::init(); $this->initView(); $this->_initUriScheme(); $this->_initRequestParamsAndFormat(); $this->_initConfig(); $this->_initResponseHeader(); } public function initView() { // Disable render view $this->_helper->layout->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); } protected function _initUriScheme() { if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] === '1')) { $this->_uriScheme = 'https'; } else { $this->_uriScheme = 'http'; } } /** * @throws Zend_Exception */ protected function _initRequestParamsAndFormat() { // Set request parameters switch (strtoupper($_SERVER['REQUEST_METHOD'])) { case 'GET': $this->_params = $_GET; break; case 'PUT': parse_str(file_get_contents('php://input'), $_PUT); $this->_params = $_PUT; break; case 'POST': $this->_params = $_POST; break; default: Zend_Registry::get('logger')->err(__METHOD__ . ' - request method not supported - ' . $_SERVER['REQUEST_METHOD']); exit('request method not supported'); } // Set format option if (isset($this->_params['format']) && strtolower($this->_params['format']) == 'json') { $this->_format = 'json'; } } protected function _initConfig() { $clientConfig = $this->_loadClientConfig(); $credentials = ''; if (!empty($_SERVER['PHP_AUTH_USER']) && !empty($_SERVER['PHP_AUTH_PW'])) { $credentials = $_SERVER['PHP_AUTH_USER'] . ':' . $_SERVER['PHP_AUTH_PW'] . '@'; } $baseUri = $this->_uriScheme . '://' . $credentials . $_SERVER['SERVER_NAME']; $webSite = $_SERVER['SERVER_NAME']; //Mask api.kde-look.org to store.kde.org if (strpos($_SERVER['SERVER_NAME'], 'api.kde-look.org') !== false) { $webSite = 'store.kde.org'; } $this->_config = array( 'id' => $_SERVER['SERVER_NAME'], 'location' => $baseUri . '/ocs/v1/', 'name' => $clientConfig['head']['browser_title'], 'icon' => $baseUri . $clientConfig['logo'], 'termsofuse' => $baseUri . '/content/terms', 'register' => $baseUri . '/register', 'website' => $webSite, 'host' => $_SERVER['SERVER_NAME'] ) + $this->_config; } /** * @return array|null */ protected function _loadClientConfig() { $clientConfigReader = new Backend_Model_ClientFileConfig($this->_getNameForStoreClient()); $clientConfigReader->loadClientConfig(); return $clientConfigReader->getConfig(); } /** * Returns the name for the store client. * If no name were found, the name for the standard store client will be returned. * * @return string */ protected function _getNameForStoreClient() { $clientName = Zend_Registry::get('config')->settings->client->default->name; // default client if (Zend_Registry::isRegistered('store_config_name')) { $clientName = Zend_Registry::get('store_config_name'); } return $clientName; } protected function _initResponseHeader() { $duration = 1800; // in seconds $expires = gmdate("D, d M Y H:i:s", time() + $duration) . " GMT"; $this->getResponse() ->setHeader('X-FRAME-OPTIONS', 'SAMEORIGIN', true) // ->setHeader('Last-Modified', $modifiedTime, true) ->setHeader('Expires', $expires, true) ->setHeader('Pragma', 'cache', true) ->setHeader('Cache-Control', 'max-age=1800, public', true) ; } public function indexAction() { $this->_sendErrorResponse(999, 'unknown request'); } protected function _sendErrorResponse($statuscode, $message = '') { if ($this->_format == 'json') { $response = array( 'status' => 'failed', 'statuscode' => $statuscode, 'message' => $message ); } else { $response = array( 'meta' => array( 'status' => array('@text' => 'failed'), 'statuscode' => array('@text' => $statuscode), 'message' => array('@text' => $message) ) ); } $this->_sendResponse($response, $this->_format); } protected function _sendResponse($response, $format = 'xml', $xmlRootTag = 'ocs') { header('Pragma: public'); header('Cache-Control: cache, must-revalidate'); $duration = 1800; // in seconds $expires = gmdate("D, d M Y H:i:s", time() + $duration) . " GMT"; header('Expires: ' . $expires); if ($format == 'json') { header('Content-Type: application/json; charset=UTF-8'); echo json_encode($response); } else { header('Content-Type: application/xml; charset=UTF-8'); echo $this->_convertXmlDom($response, $xmlRootTag)->saveXML(); } exit; } protected function _convertXmlDom($values, $tagName = 'data', DOMNode &$dom = null, DOMElement &$element = null) { if (!$dom) { $dom = new DomDocument('1.0', 'UTF-8'); } if (!$element) { $element = $dom->appendChild($dom->createElement($tagName)); } if (is_array($values) || is_object($values)) { foreach ($values as $key => $value) { if (is_array($value) || is_object($value)) { $isHash = false; foreach ($value as $_key => $_value) { if (ctype_digit((string)$_key)) { $isHash = true; } break; } if ($isHash) { $this->_convertXmlDom($value, $key, $dom, $element); continue; } if (ctype_digit((string)$key)) { $key = $tagName; } $childElement = $element->appendChild($dom->createElement($key)); $this->_convertXmlDom($value, $key, $dom, $childElement); } else { if ($key == '@text') { if (is_bool($value)) { $value = var_export($value, true); } $element->appendChild($dom->createTextNode($value)); } else if ($key == '@cdata') { if (is_bool($value)) { $value = var_export($value, true); } $element->appendChild($dom->createCDATASection($value)); } else { if (is_bool($value)) { $value = var_export($value, true); } $element->setAttribute($key, $value); } } } } return $dom; } public function providersAction() { // As providers.xml $response = array( 'provider' => array( 'id' => array('@text' => $this->_config['id']), 'location' => array('@text' => $this->_config['location']), 'name' => array('@text' => $this->_config['name']), 'icon' => array('@text' => $this->_config['icon']), 'termsofuse' => array('@text' => $this->_config['termsofuse']), 'register' => array('@text' => $this->_config['register']), 'services' => array( 'person' => array('ocsversion' => $this->_config['version']), 'content' => array('ocsversion' => $this->_config['version']) ) ) ); $this->_sendResponse($response, 'xml', 'providers'); } public function configAction() { if ($this->_format == 'json') { $response = array( 'status' => 'ok', 'statuscode' => 100, 'message' => '', 'data' => array( 'version' => $this->_config['version'], 'website' => $this->_config['website'], 'host' => $this->_config['host'], 'contact' => $this->_config['contact'], 'ssl' => $this->_config['ssl'] ) ); } else { $response = array( 'meta' => array( 'status' => array('@text' => 'ok'), 'statuscode' => array('@text' => 100), 'message' => array('@text' => '') ), 'data' => array( 'version' => array('@text' => $this->_config['version']), 'website' => array('@text' => $this->_config['website']), 'host' => array('@text' => $this->_config['host']), 'contact' => array('@text' => $this->_config['contact']), 'ssl' => array('@text' => $this->_config['ssl']) ) ); } $this->_sendResponse($response, $this->_format); } public function personcheckAction() { $identity = null; $credential = null; if (!empty($this->_params['login'])) { $identity = $this->_params['login']; } if (!empty($this->_params['password'])) { $credential = $this->_params['password']; } if (!$identity) { $this->_sendErrorResponse(101, 'please specify all mandatory fields'); } else { if (!$this->_authenticateUser($identity, $credential)) { $this->_sendErrorResponse(102, 'login not valid'); } } if ($this->_format == 'json') { $response = array( 'status' => 'ok', 'statuscode' => 100, 'message' => '', 'data' => array( array( 'details' => 'check', 'personid' => $this->_authData->username ) ) ); } else { $response = array( 'meta' => array( 'status' => array('@text' => 'ok'), 'statuscode' => array('@text' => 100), 'message' => array('@text' => '') ), 'data' => array( 'person' => array( 'details' => 'check', 'personid' => array('@text' => $this->_authData->username) ) ) ); } $this->_sendResponse($response, $this->_format); } protected function _authenticateUser($identity = null, $credential = null, $force = false) { //////////////////////////////////////////////////////// // BasicAuth enabled testing site workaround if (strrpos($_SERVER['SERVER_NAME'], 'pling.ws') !== false || strrpos($_SERVER['SERVER_NAME'], 'pling.cc') !== false || strrpos($_SERVER['SERVER_NAME'], 'pling.to') !== false || strrpos($_SERVER['SERVER_NAME'], 'ocs-store.com') !== false) { $authData = new stdClass; $authData->username = 'dummy'; $this->_authData = $authData; return true; } //////////////////////////////////////////////////////// if (!$identity && !empty($_SERVER['PHP_AUTH_USER'])) { // Will set user identity or API-Key $identity = $_SERVER['PHP_AUTH_USER']; } if (!$credential && !empty($_SERVER['PHP_AUTH_PW'])) { $credential = $_SERVER['PHP_AUTH_PW']; } $loginMethod = null; //if ($identity && !$credential) { // $loginMethod = 'api-key'; //} if ($identity && ($credential || $loginMethod == 'api-key')) { $authModel = new Default_Model_Authorization(); $authData = $authModel->getAuthDataFromApi($identity, $credential, $loginMethod); if ($authData) { $this->_authData = $authData; return true; } } if ($force) { //header('WWW-Authenticate: Basic realm="Your valid user account or api key"'); header('WWW-Authenticate: Basic realm="Your valid user account"'); header('HTTP/1.0 401 Unauthorized'); exit; } return false; } public function personselfAction() { $this->persondataAction(true); } public function persondataAction($self = false) { if (!$this->_authenticateUser()) { $this->_sendErrorResponse(101, 'person not found'); } $tableMember = new Default_Model_Member(); // Self data or specific person data if ($self || $this->getParam('personid')) { if ($self) { $username = $this->_authData->username; } else { if ($this->getParam('personid')) { $username = $this->getParam('personid'); } } $member = $tableMember->findActiveMemberByIdentity($username); if (!$member) { $this->_sendErrorResponse(101, 'person not found'); } $profilePage = $this->_uriScheme . '://' . $this->_config['user_host'] . '/member/' . $member->member_id; if ($this->_format == 'json') { $response = array( 'status' => 'ok', 'statuscode' => 100, 'message' => '', 'data' => array( array( 'details' => 'full', 'personid' => $member->username, 'privacy' => 0, 'privacytext' => 'public', 'firstname' => $member->firstname, 'lastname' => $member->lastname, 'gender' => '', 'communityrole' => '', 'homepage' => $member->link_website, 'company' => '', 'avatarpic' => $member->profile_image_url, 'avatarpicfound' => true, 'bigavatarpic' => $member->profile_image_url, 'bigavatarpicfound' => true, 'birthday' => '', 'jobstatus' => '', 'city' => $member->city, 'country' => $member->country, 'latitude' => '', 'longitude' => '', 'ircnick' => '', 'ircchannels' => '', 'irclink' => '', 'likes' => '', 'dontlikes' => '', 'interests' => '', 'languages' => '', 'programminglanguages' => '', 'favouritequote' => '', 'favouritemusic' => '', 'favouritetvshows' => '', 'favouritemovies' => '', 'favouritebooks' => '', 'favouritegames' => '', 'description' => $member->biography, 'profilepage' => $profilePage ) ) ); } else { $response = array( 'meta' => array( 'status' => array('@text' => 'ok'), 'statuscode' => array('@text' => 100), 'message' => array('@text' => '') ), 'data' => array( 'person' => array( 'details' => 'full', 'personid' => array('@text' => $member->username), 'privacy' => array('@text' => 0), 'privacytext' => array('@text' => 'public'), 'firstname' => array('@text' => $member->firstname), 'lastname' => array('@text' => $member->lastname), 'gender' => array('@text' => ''), 'communityrole' => array('@text' => ''), 'homepage' => array('@text' => $member->link_website), 'company' => array('@text' => ''), 'avatarpic' => array('@text' => $member->profile_image_url), 'avatarpicfound' => array('@text' => true), 'bigavatarpic' => array('@text' => $member->profile_image_url), 'bigavatarpicfound' => array('@text' => true), 'birthday' => array('@text' => ''), 'jobstatus' => array('@text' => ''), 'city' => array('@text' => $member->city), 'country' => array('@text' => $member->country), 'latitude' => array('@text' => ''), 'longitude' => array('@text' => ''), 'ircnick' => array('@text' => ''), 'ircchannels' => array('@text' => ''), 'irclink' => array('@text' => ''), 'likes' => array('@text' => ''), 'dontlikes' => array('@text' => ''), 'interests' => array('@text' => ''), 'languages' => array('@text' => ''), 'programminglanguages' => array('@text' => ''), 'favouritequote' => array('@text' => ''), 'favouritemusic' => array('@text' => ''), 'favouritetvshows' => array('@text' => ''), 'favouritemovies' => array('@text' => ''), 'favouritebooks' => array('@text' => ''), 'favouritegames' => array('@text' => ''), 'description' => array('@text' => $member->biography), 'profilepage' => array('@text' => $profilePage) ) ) ); } $this->_sendResponse($response, $this->_format); } // Find a specific list of persons else { $limit = 10; // 1 - 100 $offset = 0; $tableMemberSelect = $tableMember->select()->where('is_active = ?', 1)->where('is_deleted = ?', 0); if (!empty($this->_params['name'])) { $isSearchable = false; foreach (explode(' ', $this->_params['name']) as $keyword) { if ($keyword && strlen($keyword) > 2) { $tableMemberSelect->where('username LIKE ?' . ' OR firstname LIKE ?' . ' OR lastname LIKE ?', "%$keyword%"); $isSearchable = true; } } if (!$isSearchable) { $tableMemberSelect->where('username LIKE ?' . ' OR firstname LIKE ?' . ' OR lastname LIKE ?', "%{$this->_params['name']}%"); } } if (!empty($this->_params['country'])) { $tableMemberSelect->where('country = ?', $this->_params['country']); } if (!empty($this->_params['city'])) { $tableMemberSelect->where('city = ?', $this->_params['city']); } if (!empty($this->_params['description'])) { $isSearchable = false; foreach (explode(' ', $this->_params['name']) as $keyword) { if ($keyword && strlen($keyword) > 2) { $tableMemberSelect->where('biography LIKE ?', "%$keyword%"); $isSearchable = true; } } if (!$isSearchable) { $tableMemberSelect->where('biography LIKE ?', "%$this->_params['description']}%"); } } if (!empty($this->_params['pc'])) { } if (!empty($this->_params['software'])) { } if (!empty($this->_params['longitude'])) { } if (!empty($this->_params['latitude'])) { } if (!empty($this->_params['distance'])) { } if (!empty($this->_params['attributeapp'])) { } if (!empty($this->_params['attributekey'])) { } if (!empty($this->_params['attributevalue'])) { } if (isset($this->_params['pagesize']) && ctype_digit((string)$this->_params['pagesize']) && $this->_params['pagesize'] > 0 && $this->_params['pagesize'] < 101) { $limit = $this->_params['pagesize']; } if (isset($this->_params['page']) && ctype_digit((string)$this->_params['page'])) { // page parameter: the first page is 0 $offset = $limit * $this->_params['page']; } $members = $tableMember->fetchAll($tableMemberSelect->limit($limit, $offset)); $tableMemberSelect->reset('columns'); $tableMemberSelect->reset('limitcount'); $tableMemberSelect->reset('limitoffset'); $count = $tableMember->fetchRow($tableMemberSelect->columns(array('count' => 'COUNT(*)'))); if ($count['count'] > 1000) { $this->_sendErrorResponse(102, 'more than 1000 people found.' . ' it is not allowed to fetch such a big resultset.' . ' please specify more search conditions'); } if ($this->_format == 'json') { $response = array( 'status' => 'ok', 'statuscode' => 100, 'message' => '', 'totalitems' => $count['count'], 'itemsperpage' => $limit, 'data' => array() ); } else { $response = array( 'meta' => array( 'status' => array('@text' => 'ok'), 'statuscode' => array('@text' => 100), 'message' => array('@text' => ''), 'totalitems' => array('@text' => $count['count']), 'itemsperpage' => array('@text' => $limit) ), 'data' => array() ); } if (!count($members)) { $this->_sendResponse($response, $this->_format); } $personsList = array(); foreach ($members as $member) { if ($this->_format == 'json') { $personsList[] = array( 'details' => 'summary', 'personid' => $member->username, 'privacy' => 0, 'privacytext' => 'public', 'firstname' => $member->firstname, 'lastname' => $member->lastname, 'gender' => '', 'communityrole' => '', 'company' => '', 'city' => $member->city, 'country' => $member->country ); } else { $personsList[] = array( 'details' => 'summary', 'personid' => array('@text' => $member->username), 'privacy' => array('@text' => 0), 'privacytext' => array('@text' => 'public'), 'firstname' => array('@text' => $member->firstname), 'lastname' => array('@text' => $member->lastname), 'gender' => array('@text' => ''), 'communityrole' => array('@text' => ''), 'company' => array('@text' => ''), 'city' => array('@text' => $member->city), 'country' => array('@text' => $member->country) ); } } if ($this->_format == 'json') { $response['data'] = $personsList; } else { $response['data'] = array('person' => $personsList); } $this->_sendResponse($response, $this->_format); } } public function contentcategoriesAction() { if (!$this->_authenticateUser()) { // $this->_sendErrorResponse(999, ''); } /** @var Zend_Cache_Core $cache */ $cache = Zend_Registry::get('cache'); $cacheName = 'api_content_categories'; if (false == ($categoriesList = $cache->load($cacheName))) { $categoriesList = $this->_buildCategories(); $cache->save($categoriesList, $cacheName, array(), 1800); } if ($this->_format == 'json') { $response = array( 'status' => 'ok', 'statuscode' => 100, 'message' => '', 'totalitems' => count($categoriesList), 'data' => array() ); if (!empty($categoriesList)) { $response['data'] = $categoriesList; } } else { $response = array( 'meta' => array( 'status' => array('@text' => 'ok'), 'statuscode' => array('@text' => 100), 'message' => array('@text' => ''), 'totalitems' => array('@text' => count($categoriesList)) ), 'data' => array() ); if (!empty($categoriesList)) { $response['data'] = array('category' => $categoriesList); } } $this->_sendResponse($response, $this->_format); } protected function _buildCategories() { $modelCategoryTree = new Default_Model_ProjectCategory(); $tree = $modelCategoryTree->fetchCategoryTreeCurrentStore(); return $this->buildResponseTree($tree); } protected function buildResponseTree($tree) { $result = array(); foreach ($tree as $element) { if ($this->_format == 'json') { $result[] = array( 'id' => $element['id'], 'name' => (false === empty($element['name_legacy'])) ? $element['name_legacy'] : $element['title'], 'display_name' => $element['title'], 'parent_id' => (false === empty($element['parent_id'])) ? $element['parent_id'] : '', 'xdg_type' => (false === empty($element['xdg_type'])) ? $element['xdg_type'] : '' ); } else { $result[] = array( 'id' => array('@text' => $element['id']), 'name' => array('@text' => (false === empty($element['name_legacy'])) ? $element['name_legacy'] : $element['title']), 'display_name' => array('@text' => $element['title']), 'parent_id' => array('@text' => (false === empty($element['parent_id'])) ? $element['parent_id'] : ''), 'xdg_type' => array('@text' => (false === empty($element['xdg_type'])) ? $element['xdg_type'] : '') ); } if ($element['has_children']) { $sub_tree = $this->buildResponseTree($element['children']); $result = array_merge($result, $sub_tree); } } return $result; } public function contentdataAction() { if (!$this->_authenticateUser()) { // $this->_sendErrorResponse(999, ''); } $pploadApi = new Ppload_Api(array( 'apiUri' => PPLOAD_API_URI, 'clientId' => PPLOAD_CLIENT_ID, 'secret' => PPLOAD_SECRET )); $previewPicSize = array( 'width' => 770, 'height' => 540 ); $smallPreviewPicSize = array( 'width' => 100, 'height' => 100 ); // Specific content data $requestedId = (int)$this->getParam('contentid') ? (int)$this->getParam('contentid') : null; if ($requestedId) { $response = $this->fetchContent($requestedId, $previewPicSize, $smallPreviewPicSize, $pploadApi); $this->_sendResponse($response, $this->_format); } // Gets a list of a specific set of contents else { $response = $this->fetchCategoryContent($previewPicSize, $smallPreviewPicSize, $pploadApi); $this->_sendResponse($response, $this->_format); } } /** * @param int $contentId * @param array $previewPicSize * @param array $smallPreviewPicSize * @param Ppload_Api $pploadApi * * @return array */ protected function fetchContent( $contentId, $previewPicSize, $smallPreviewPicSize, $pploadApi ) { /** @var Zend_Cache_Core $cache */ $cache = Zend_Registry::get('cache'); $cacheName = 'api_fetch_content_by_id_' . $contentId; if (($response = $cache->load($cacheName))) { return $response; } $tableProject = new Default_Model_Project(); $tableProjectSelect = $this->_buildProjectSelect($tableProject); $project = $tableProject->fetchRow($tableProjectSelect->where('project.project_id = ?', $contentId)); if (!$project) { $this->_sendErrorResponse(101, 'content not found'); } $project->title = Default_Model_HtmlPurify::purify($project->title); $project->description = Default_Model_BBCode::renderHtml(Default_Model_HtmlPurify::purify($project->description)); $project->version = Default_Model_HtmlPurify::purify($project->version); $categoryXdgType = ''; if (!empty($project->cat_xdg_type)) { $categoryXdgType = $project->cat_xdg_type; } $created = date('c', strtotime($project->created_at)); $changed = date('c', strtotime($project->changed_at)); $previewPage = $this->_uriScheme . '://' . $this->_config['website'] . '/p/' . $project->project_id; $donationPage = $previewPage; if (empty($project->paypal_mail) && empty($project->dwolla_id)) { $donationPage = ''; } list($previewPics, $smallPreviewPics) = $this->getGalleryPictures($project, $previewPicSize, $smallPreviewPicSize); $downloads = $project->count_downloads_hive; list($downloadItems, $downloads) = $this->getPPLoadInfo($project, $pploadApi, $downloads); if ($this->_format == 'json') { $response = array( 'status' => 'ok', 'statuscode' => 100, 'message' => '', 'data' => array( array( 'details' => 'full', 'id' => $project->project_id, 'name' => $project->title, 'version' => $project->version, 'typeid' => $project->project_category_id, 'typename' => $project->cat_title, 'xdg_type' => $categoryXdgType, 'language' => '', 'personid' => $project->username, 'created' => $created, 'changed' => $changed, 'downloads' => $downloads, 'score' => $project->laplace_score, 'summary' => '', 'description' => $project->description, 'changelog' => '', 'feedbackurl' => $previewPage, 'homepage' => $previewPage, 'homepagetype' => '', 'donationpage' => $donationPage, 'comments' => $project->count_comments, 'commentspage' => $previewPage, 'fans' => null, 'fanspage' => '', 'knowledgebaseentries' => null, 'knowledgebasepage' => '', 'depend' => '', 'preview1' => $previewPage, 'icon' => '', 'video' => '', 'detailpage' => $previewPage, 'tags' => $project->tags ) + $previewPics + $smallPreviewPics + $downloadItems ) ); } else { foreach ($previewPics as $key => $value) { $previewPics[$key] = array('@text' => $value); } foreach ($smallPreviewPics as $key => $value) { $smallPreviewPics[$key] = array('@text' => $value); } if ($downloadItems) { foreach ($downloadItems as $key => $value) { $downloadItems[$key] = array('@text' => $value); } } $response = array( 'meta' => array( 'status' => array('@text' => 'ok'), 'statuscode' => array('@text' => 100), 'message' => array('@text' => '') ), 'data' => array( 'content' => array( 'details' => 'full', 'id' => array('@text' => $project->project_id), 'name' => array('@text' => $project->title), 'version' => array('@text' => $project->version), 'typeid' => array('@text' => $project->project_category_id), 'typename' => array('@text' => $project->cat_title), 'xdg_type' => array('@text' => $categoryXdgType), 'language' => array('@text' => ''), 'personid' => array('@text' => $project->username), 'created' => array('@text' => $created), 'changed' => array('@text' => $changed), 'downloads' => array('@text' => $downloads), 'score' => array('@text' => $project->laplace_score), 'summary' => array('@text' => ''), 'description' => array('@cdata' => $project->description), 'changelog' => array('@text' => ''), 'feedbackurl' => array('@text' => $previewPage), 'homepage' => array('@text' => $previewPage), 'homepagetype' => array('@text' => ''), 'donationpage' => array('@text' => $donationPage), 'comments' => array('@text' => $project->count_comments), 'commentspage' => array('@text' => $previewPage), 'fans' => array('@text' => null), 'fanspage' => array('@text' => ''), 'knowledgebaseentries' => array('@text' => null), 'knowledgebasepage' => array('@text' => ''), 'depend' => array('@text' => ''), 'preview1' => array('@text' => $previewPage), 'icon' => array('@text' => ''), 'video' => array('@text' => ''), 'detailpage' => array('@text' => $previewPage), 'tags' => array('@text' => $project->tags) ) + $previewPics + $smallPreviewPics + $downloadItems ) ); } $cache->save($response, $cacheName); return $response; } /** * @param Zend_Db_Table $tableProject * * @param bool $withSqlCalcFoundRows * * @return Zend_Db_Table_Select */ protected function _buildProjectSelect($tableProject, $withSqlCalcFoundRows = false) { $tableProjectSelect = $tableProject->select(); if ($withSqlCalcFoundRows) { $tableProjectSelect->from(array('project' => 'stat_projects'), array(new Zend_Db_Expr('SQL_CALC_FOUND_ROWS *'))); } else { $tableProjectSelect->from(array('project' => 'stat_projects')); } $tableProjectSelect->setIntegrityCheck(false)->columns(array( '*', 'member_username' => 'username', 'category_title' => 'cat_title', 'xdg_type' => 'cat_xdg_type', 'name_legacy' => 'cat_name_legacy' - ))->where('project.status = ?', Default_Model_Project::PROJECT_ACTIVE)->where('project.ppload_collection_id IS NOT NULL') + ))->where('project.status = ?', Default_Model_Project::PROJECT_ACTIVE) + ->where('project.ppload_collection_id IS NOT NULL') ; return $tableProjectSelect; } /** * @param Zend_Db_Table_Row_Abstract $project * @param array $previewPicSize * @param array $smallPreviewPicSize * * @return array */ protected function getGalleryPictures($project, $previewPicSize, $smallPreviewPicSize) { /** @var Zend_Cache_Core $cache */ $cache = Zend_Registry::get('cache'); $cacheName = 'api_fetch_gallery_pics_' . $project->project_id; if (($previews = $cache->load($cacheName))) { return $previews; } $viewHelperImage = new Default_View_Helper_Image(); $previewPics = array( 'previewpic1' => $viewHelperImage->Image($project->image_small, $previewPicSize) ); $smallPreviewPics = array( 'smallpreviewpic1' => $viewHelperImage->Image($project->image_small, $smallPreviewPicSize) ); $tableProject = new Default_Model_Project(); $galleryPics = $tableProject->getGalleryPictureSources($project->project_id); if ($galleryPics) { $i = 2; foreach ($galleryPics as $galleryPic) { $previewPics['previewpic' . $i] = $viewHelperImage->Image($galleryPic, $previewPicSize); $smallPreviewPics['smallpreviewpic' . $i] = $viewHelperImage->Image($galleryPic, $smallPreviewPicSize); $i++; } } $cache->save(array($previewPics, $smallPreviewPics), $cacheName); return array($previewPics, $smallPreviewPics); } /** * @param Zend_Db_Table_Row_Abstract $project * @param Ppload_Api $pploadApi * @param int $downloads * * @return array */ protected function getPPLoadInfo($project, $pploadApi, $downloads) { $downloadItems = array(); if (empty($project->ppload_collection_id)) { return array($downloadItems, $downloads); } /** @var Zend_Cache_Core $cache */ $cache = Zend_Registry::get('cache'); $cacheName = 'api_ppload_collection_by_id_' . $project->ppload_collection_id; if (($pploadInfo = $cache->load($cacheName))) { return $pploadInfo; } $filesRequest = array( 'collection_id' => ltrim($project->ppload_collection_id, '!'), 'ocs_compatibility' => 'compatible', 'perpage' => 100 ); $filesResponse = $pploadApi->getFiles($filesRequest); if (isset($filesResponse->status) && $filesResponse->status == 'success') { $i = 1; foreach ($filesResponse->files as $file) { $downloads += (int)$file->downloaded_count; $tags = $this->_parseFileTags($file->tags); $downloadLink = PPLOAD_API_URI . 'files/download/' . 'id/' . $file->id . '/' . $file->name; $downloadItems['downloadway' . $i] = 1; $downloadItems['downloadtype' . $i] = ''; $downloadItems['downloadprice' . $i] = '0'; $downloadItems['downloadlink' . $i] = $downloadLink; $downloadItems['downloadname' . $i] = $file->name; $downloadItems['downloadsize' . $i] = round($file->size / 1024); $downloadItems['downloadgpgfingerprint' . $i] = ''; $downloadItems['downloadgpgsignature' . $i] = ''; $downloadItems['downloadpackagename' . $i] = ''; $downloadItems['downloadrepository' . $i] = ''; $downloadItems['download_package_type' . $i] = $tags['packagetypeid']; $downloadItems['download_package_arch' . $i] = $tags['packagearch']; $i++; } } $cache->save(array($downloadItems, $downloads), $cacheName); return array($downloadItems, $downloads); } /** * @param string $fileTags * * @return array */ protected function _parseFileTags($fileTags) { $tags = explode(',', $fileTags); $parsedTags = array( 'link' => '', 'licensetype' => '', 'packagetypeid' => '', 'packagearch' => '' ); foreach ($tags as $tag) { $tag = trim($tag); if (strpos($tag, 'link##') === 0) { $parsedTags['link'] = urldecode(str_replace('link##', '', $tag)); } else { if (strpos($tag, 'licensetype-') === 0) { $parsedTags['licensetype'] = str_replace('licensetype-', '', $tag); } else { if (strpos($tag, 'packagetypeid-') === 0) { $parsedTags['packagetypeid'] = str_replace('packagetypeid-', '', $tag); } else { if (strpos($tag, 'packagearch-') === 0) { $parsedTags['packagearch'] = str_replace('packagearch-', '', $tag); } } } } } return $parsedTags; } /** * @param array $previewPicSize * @param array $smallPreviewPicSize * @param Ppload_Api $pploadApi * * @return array */ protected function fetchCategoryContent( $previewPicSize, $smallPreviewPicSize, $pploadApi ) { $limit = 10; // 1 - 100 $offset = 0; $tableProject = new Default_Model_Project(); $tableProjectSelect = $this->_buildProjectSelect($tableProject, true); if (!empty($this->_params['categories'])) { // categories parameter: values separated by "," // legacy OCS API compatible: values separated by "x" if (strpos($this->_params['categories'], ',') !== false) { $catList = explode(',', $this->_params['categories']); } else { $catList = explode('x', $this->_params['categories']); } $modelProjectCategories = new Default_Model_DbTable_ProjectCategory(); $allCategories = array_merge($catList, $modelProjectCategories->fetchChildIds($catList)); $tableProjectSelect->where('project.project_category_id IN (?)', $allCategories); } if (!empty($this->_params['xdg_types'])) { // xdg_types parameter: values separated by "," $xdgTypeList = explode(',', $this->_params['xdg_types']); $tableProjectSelect->where('category.xdg_type IN (?)', $xdgTypeList); } if (!empty($this->_params['package_types'])) { // package_types parameter: values separated by "," $packageTypeList = explode(',', $this->_params['package_types']); $storeConfig = Zend_Registry::isRegistered('store_config') ? Zend_Registry::get('store_config') : null; $storePackageTypeIds = null; if ($storeConfig) { $storePackageTypeIds = $storeConfig['package_type']; } if ($storePackageTypeIds) { $tableProjectSelect->join(array( 'package_type' => new Zend_Db_Expr('(SELECT DISTINCT project_id FROM project_package_type WHERE ' . $tableProject->getAdapter()->quoteInto('package_type_id IN (?)', $packageTypeList) . ')') ), 'project.project_id = package_type.project_id', array()); } } $hasSearchPart = false; if (!empty($this->_params['search'])) { foreach (explode(' ', $this->_params['search']) as $keyword) { if ($keyword && strlen($keyword) > 2) { $tableProjectSelect->where('project.title LIKE ? OR project.description LIKE ?', "%$keyword%"); $hasSearchPart = true; } } } if (!empty($this->_params['user'])) { $tableProjectSelect->where('member.username = ?', $this->_params['user']); } if (!empty($this->_params['external'])) { } if (!empty($this->_params['distribution'])) { // distribution parameter: comma separated list of ids } if (!empty($this->_params['license'])) { // license parameter: comma separated list of ids } if (!empty($this->_params['sortmode'])) { // sortmode parameter: new|alpha|high|down switch (strtolower($this->_params['sortmode'])) { case 'new': $tableProjectSelect->order('project.created_at DESC'); break; case 'alpha': $tableProjectSelect->order('project.title ASC'); break; case 'high': $tableProjectSelect->order(new Zend_Db_Expr('laplace_score(project.count_likes,project.count_dislikes) DESC')); break; case 'down': $tableProjectSelect->joinLeft(array('stat_downloads_quarter_year' => 'stat_downloads_quarter_year'), 'project.project_id = stat_downloads_quarter_year.project_id', array()); $tableProjectSelect->order('stat_downloads_quarter_year.amount DESC'); break; default: break; } } if (isset($this->_params['pagesize']) && ctype_digit((string)$this->_params['pagesize']) && $this->_params['pagesize'] > 0 && $this->_params['pagesize'] < 101) { $limit = $this->_params['pagesize']; } if (isset($this->_params['page']) && ctype_digit((string)$this->_params['page'])) { // page parameter: the first page is 0 $offset = $limit * $this->_params['page']; } $tableProjectSelect->limit($limit, $offset); $projects = $tableProject->fetchAll($tableProjectSelect); $count = $tableProject->getAdapter()->fetchRow('select FOUND_ROWS() AS counter'); if ($this->_format == 'json') { $response = array( 'status' => 'ok', 'statuscode' => 100, 'message' => '', 'totalitems' => $count['counter'], 'itemsperpage' => $limit, 'data' => array() ); } else { $response = array( 'meta' => array( 'status' => array('@text' => 'ok'), 'statuscode' => array('@text' => 100), 'message' => array('@text' => ''), 'totalitems' => array('@text' => $count['counter']), 'itemsperpage' => array('@text' => $limit) ), 'data' => array() ); } if (!count($projects)) { return $response; } /** @var Zend_Cache_Core $cache */ $cache = Zend_Registry::get('cache'); $cacheName = 'api_fetch_category_' . md5($tableProjectSelect->__toString()); $contentsList = false; if (false === $hasSearchPart) { $contentsList = $cache->load($cacheName); } if (false == $contentsList) { $contentsList = $this->_buildContentList($previewPicSize, $smallPreviewPicSize, $pploadApi, $projects); if (false === $hasSearchPart) { $cache->save($contentsList, $cacheName, array(), 1800); } } if ($this->_format == 'json') { $response['data'] = $contentsList; } else { $response['data'] = array('content' => $contentsList); } return $response; } /** * @param $previewPicSize * @param $smallPreviewPicSize * @param $pploadApi * @param $projects * * @return array */ protected function _buildContentList($previewPicSize, $smallPreviewPicSize, $pploadApi, $projects) { $contentsList = array(); $helperTruncate = new Default_View_Helper_Truncate(); foreach ($projects as $project) { $project->description = $helperTruncate->truncate(Default_Model_BBCode::renderHtml(Default_Model_HtmlPurify::purify($project->description)),300); $categoryXdgType = ''; if (!empty($project->xdg_type)) { $categoryXdgType = $project->xdg_type; } $created = date('c', strtotime($project->created_at)); $changed = date('c', strtotime($project->changed_at)); $previewPage = $this->_uriScheme . '://' . $this->_config['website'] . '/p/' . $project->project_id; list($previewPics, $smallPreviewPics) = $this->getGalleryPictures($project, $previewPicSize, $smallPreviewPicSize); $downloads = $project->count_downloads_hive; list($downloadItems, $downloads) = $this->getPPLoadInfo($project, $pploadApi, $downloads); if ($this->_format == 'json') { $contentsList[] = array( 'details' => 'summary', 'id' => $project->project_id, 'name' => $project->title, 'version' => $project->version, 'typeid' => $project->project_category_id, 'typename' => $project->cat_title, 'xdg_type' => $categoryXdgType, 'language' => '', 'personid' => $project->member_username, 'created' => $created, 'changed' => $changed, 'downloads' => $downloads, 'score' => $project->laplace_score, 'summary' => '', 'description' => $project->description, 'comments' => $project->count_comments, 'preview1' => $previewPage, 'detailpage' => $previewPage, 'tags' => $project->tags ) + $previewPics + $smallPreviewPics + $downloadItems; } else { foreach ($previewPics as $key => $value) { $previewPics[$key] = array('@text' => $value); } foreach ($smallPreviewPics as $key => $value) { $smallPreviewPics[$key] = array('@text' => $value); } if ($downloadItems) { foreach ($downloadItems as $key => $value) { $downloadItems[$key] = array('@text' => $value); } } $contentsList[] = array( 'details' => 'summary', 'id' => array('@text' => $project->project_id), 'name' => array('@text' => $project->title), 'version' => array('@text' => $project->version), 'typeid' => array('@text' => $project->project_category_id), 'typename' => array('@text' => $project->cat_title), 'xdg_type' => array('@text' => $categoryXdgType), 'language' => array('@text' => ''), 'personid' => array('@text' => $project->member_username), 'created' => array('@text' => $created), 'changed' => array('@text' => $changed), 'downloads' => array('@text' => $downloads), 'score' => array('@text' => $project->laplace_score), 'summary' => array('@text' => ''), 'description' => array('@cdata' => $project->description), 'comments' => array('@text' => $project->count_comments), 'preview1' => array('@text' => $previewPage), 'detailpage' => array('@text' => $previewPage), 'tags' => array('@text' => $project->tags) ) + $previewPics + $smallPreviewPics + $downloadItems; } } return $contentsList; } public function contentdownloadAction() { if (!$this->_authenticateUser()) { //$this->_sendErrorResponse(999, ''); } $pploadApi = new Ppload_Api(array( 'apiUri' => PPLOAD_API_URI, 'clientId' => PPLOAD_CLIENT_ID, 'secret' => PPLOAD_SECRET )); $project = null; $file = null; if ($this->getParam('contentid')) { $tableProject = new Default_Model_Project(); $project = $tableProject->fetchRow( $tableProject->select() ->where('project_id = ?', $this->getParam('contentid')) ->where('status = ?', Default_Model_Project::PROJECT_ACTIVE)); } if (!$project) { $this->_sendErrorResponse(101, 'content not found'); } if ($project->ppload_collection_id && $this->getParam('itemid') && ctype_digit((string)$this->getParam('itemid'))) { $filesRequest = array( 'collection_id' => ltrim($project->ppload_collection_id, '!'), 'ocs_compatibility' => 'compatible', 'perpage' => 1, 'page' => $this->getParam('itemid') ); $filesResponse = $pploadApi->getFiles($filesRequest); if (isset($filesResponse->status) && $filesResponse->status == 'success') { $i = 0; $file = $filesResponse->files->$i; } } if (!$file) { $this->_sendErrorResponse(103, 'content item not found'); } $tags = $this->_parseFileTags($file->tags); $downloadLink = PPLOAD_API_URI . 'files/download/' . 'id/' . $file->id . '/' . $file->name; if ($this->_format == 'json') { $response = array( 'status' => 'ok', 'statuscode' => 100, 'message' => '', 'data' => array( array( 'details' => 'download', 'downloadway' => 1, 'downloadlink' => $downloadLink, 'mimetype' => $file->type, 'gpgfingerprint' => '', 'gpgsignature' => '', 'packagename' => '', 'repository' => '', 'download_package_type' => $tags['packagetypeid'], 'download_package_arch' => $tags['packagearch'] ) ) ); } else { $response = array( 'meta' => array( 'status' => array('@text' => 'ok'), 'statuscode' => array('@text' => 100), 'message' => array('@text' => '') ), 'data' => array( 'content' => array( 'details' => 'download', 'downloadway' => array('@text' => 1), 'downloadlink' => array('@text' => $downloadLink), 'mimetype' => array('@text' => $file->type), 'gpgfingerprint' => array('@text' => ''), 'gpgsignature' => array('@text' => ''), 'packagename' => array('@text' => ''), 'repository' => array('@text' => ''), 'download_package_type' => array('@text' => $tags['packagetypeid']), 'download_package_arch' => array('@text' => $tags['packagearch']) ) ) ); } $this->_sendResponse($response, $this->_format); } public function contentpreviewpicAction() { if (!$this->_authenticateUser()) { //$this->_sendErrorResponse(999, ''); } $project = null; if ($this->getParam('contentid')) { $tableProject = new Default_Model_Project(); $project = $tableProject->fetchRow($tableProject->select() ->where('project_id = ?', $this->getParam('contentid')) ->where('status = ?', Default_Model_Project::PROJECT_ACTIVE)); } if (!$project) { //$this->_sendErrorResponse(101, 'content not found'); header('Location: ' . $this->_config['icon']); exit; } $viewHelperImage = new Default_View_Helper_Image(); $previewPicSize = array( 'width' => 100, 'height' => 100 ); if (!empty($this->_params['size']) && strtolower($this->_params['size']) == 'medium') { $previewPicSize = array( 'width' => 770, 'height' => 540 ); } $previewPicUri = $viewHelperImage->Image($project->image_small, $previewPicSize); header('Location: ' . $previewPicUri); exit; } /** * @param null $tableCategories * @param null $parentCategoryId * @param array $categoriesList * * @return array * @deprecated */ protected function _buildCategoriesList($tableCategories = null, $parentCategoryId = null, $categoriesList = array()) { $categories = null; // Top-level categories if (!$tableCategories) { $tableCategories = new Default_Model_DbTable_ProjectCategory(); if (Zend_Registry::isRegistered('store_category_list')) { $categories = $tableCategories->fetchActive(Zend_Registry::get('store_category_list')); } else { $categories = $tableCategories->fetchAllActive(); } } // Sub-categories else { if ($parentCategoryId) { $categories = $tableCategories->fetchImmediateChildren($parentCategoryId); } } // Build categories list if (!empty($categories)) { foreach ($categories as $category) { if (is_array($category)) { $category = (object)$category; } $categoryName = $category->title; $categoryDisplayName = $category->title; if (!empty($category->name_legacy)) { $categoryName = $category->name_legacy; } $categoryParentId = ''; if (!empty($parentCategoryId)) { $categoryParentId = $parentCategoryId; } $categoryXdgType = ''; if (!empty($category->xdg_type)) { $categoryXdgType = $category->xdg_type; } if ($this->_format == 'json') { $categoriesList[] = array( 'id' => $category->project_category_id, 'name' => $categoryName, 'display_name' => $categoryDisplayName, 'parent_id' => $categoryParentId, 'xdg_type' => $categoryXdgType ); } else { $categoriesList[] = array( 'id' => array('@text' => $category->project_category_id), 'name' => array('@text' => $categoryName), 'display_name' => array('@text' => $categoryDisplayName), 'parent_id' => array('@text' => $categoryParentId), 'xdg_type' => array('@text' => $categoryXdgType) ); } // Update the list recursive $categoriesList = $this->_buildCategoriesList($tableCategories, $category->project_category_id, $categoriesList); } } return $categoriesList; } + public function commentsAction() + { + if ($this->_format == 'json') { + $response = array( + 'status' => 'ok', + 'statuscode' => 100, + 'message' => '', + 'data' => array() + ); + } else { + $response = array( + 'meta' => array( + 'status' => array('@text' => 'ok'), + 'statuscode' => array('@text' => 100), + 'message' => array('@text' => ''), + ), + 'data' => array() + ); + } + + $commentType = (int)$this->getParam('comment_type', -1); + if ($commentType != self::COMMENT_TYPE_CONTENT) { + $this->_sendResponse($response, $this->_format); + } + + $contentId = (int)$this->getParam('content_id', null); + if (empty($contentId)) { + $this->_sendResponse($response, $this->_format); + } + + $page = (int)$this->getParam('page', 0) + 1; + $pagesize = (int)$this->getParam('pagesize', 10); + + /** @var Zend_Cache_Core $cache */ + $cache = Zend_Registry::get('cache'); + $cacheName = 'api_fetch_comments_' . md5("{$commentType}, {$contentId}, {$page}, {$pagesize}"); + + if (($cachedResponse = $cache->load($cacheName))) { + $this->_sendResponse($cachedResponse, $this->_format); + } + + $modelComments = new Default_Model_ProjectComments(); + $comments = $modelComments->getCommentsHierarchic($contentId); + + if ($comments->count() == 0) { + $this->_sendResponse($response, $this->_format); + } + + $comments->setCurrentPageNumber($page); + $comments->setItemCountPerPage($pagesize); + + $response['data'] = array('comment' => $this->_buildCommentList($comments->getCurrentItems())); + $cache->save($response, $cacheName, array(), 1800); + + $this->_sendResponse($response, $this->_format); + } + + /** + * @param Traversable $currentItems + * + * @return array + */ + protected function _buildCommentList($currentItems) + { + $commentList = array(); + foreach ($currentItems as $current_item) { + if ($this->_format == 'json') { + $comment = array( + 'id' => $current_item['comment_id'], + 'subject' => '', + 'text' => Default_Model_HtmlPurify::purify($current_item['comment_text']), + 'childcount' => $current_item['childcount'], + 'user' => $current_item['username'], + 'date' => date('c', strtotime($current_item['comment_created_at'])), + 'score' => 0 + ); + if ($current_item['childcount'] > 0) { + $comment['children'] = $this->_buildCommentList($current_item['children']); + } + } else { + $comment = array( + 'id' => array('@text' => $current_item['comment_id']), + 'subject' => array('@text' => ''), + 'text' => array('@text' => Default_Model_HtmlPurify::purify($current_item['comment_text'])), + 'childcount' => array('@text' => $current_item['childcount']), + 'user' => array('@text' => $current_item['username']), + 'date' => array('@text' => date('c', strtotime($current_item['comment_created_at']))), + 'score' => array('@text' => 0) + ); + if ($current_item['childcount'] > 0) { + $comment['children'] = $this->_buildCommentList($current_item['children']); + } + } + $commentList[] = $comment; + } + + return $commentList; + } + } diff --git a/application/modules/default/models/ProjectComments.php b/application/modules/default/models/ProjectComments.php index 5f04ed767..912a52b0c 100644 --- a/application/modules/default/models/ProjectComments.php +++ b/application/modules/default/models/ProjectComments.php @@ -1,312 +1,351 @@ . **/ class Default_Model_ProjectComments { /** @var string */ protected $_dataTableName; /** @var Default_Model_DbTable_Comments */ protected $_dataTable; /** @var array */ protected $data; /** @var array */ protected $index; /** * PHP 5 allows developers to declare constructor methods for classes. * Classes which have a constructor method call this method on each newly-created object, * so it is suitable for any initialization that the object may need before it is used. * * Note: Parent constructors are not called implicitly if the child class defines a constructor. * In order to run a parent constructor, a call to parent::__construct() within the child constructor is required. * * param [ mixed $args [, $... ]] * * @param string $_dataTableName * * @link http://php.net/manual/en/language.oop5.decon.php */ public function __construct($_dataTableName = 'Default_Model_DbTable_Comments') { $this->_dataTableName = $_dataTableName; $this->_dataTable = new $this->_dataTableName; } public function getCommentWithMember($comment_id) { $sql = " SELECT * FROM comments STRAIGHT_JOIN member ON comments.comment_member_id = member.member_id WHERE comment_id = :comment_id ORDER BY comments.comment_created_at DESC, comment_parent_id "; $rowSet = $this->_dataTable->getAdapter()->fetchAll($sql, array('comment_id' => $comment_id)); if (0 == count($rowSet)) { return array(); } return $rowSet[0]; } public function getCommentFromSource($type = 0, $source_id, $source_pk) { $sql = " SELECT * FROM comments WHERE comment_type = :type AND source_id = :source_id AND source_pk = :source_pk "; $rowset = $this->_dataTable->getAdapter()->fetchRow($sql, array('type' => $type, 'source_id' => $source_id, 'source_pk' => $source_pk)) ; if (!$rowset) { return false; } return $rowset; } /** * @param $project_id * * @return Zend_Paginator */ public function getCommentTreeForProject($project_id) { $sql = " SELECT comment_id, comment_target_id, comment_parent_id, comment_text, comment_created_at, comment_active, comment_type, member_id, username, profile_image_url ,(SELECT (DATE_ADD(max(active_time), INTERVAL 1 YEAR) > now()) from support where support.status_id = 2 AND support.member_id = comments.comment_member_id) AS issupporter FROM comments STRAIGHT_JOIN member ON comments.comment_member_id = member.member_id WHERE comment_active = :status_active AND comment_type = :type_id AND comment_target_id = :project_id AND comment_parent_id = 0 ORDER BY comment_created_at DESC "; $rowset = $this->_dataTable->getAdapter()->fetchAll($sql, array( 'status_active' => 1, 'type_id' => Default_Model_DbTable_Comments::COMMENT_TYPE_PRODUCT, 'project_id' => $project_id )) ; $sql = " SELECT comment_id, comment_target_id, comment_parent_id, comment_text, comment_created_at, comment_active, comment_type, member_id, username, profile_image_url ,(SELECT (DATE_ADD(max(active_time), INTERVAL 1 YEAR) > now()) from support where support.status_id = 2 AND support.member_id = comments.comment_member_id) AS issupporter FROM comments STRAIGHT_JOIN member ON comments.comment_member_id = member.member_id WHERE comment_active = :status_active AND comment_type = :type_id AND comment_target_id = :project_id AND comment_parent_id <> 0 ORDER BY comment_created_at, comment_id "; $rowset2 = $this->_dataTable->getAdapter()->fetchAll($sql, array( 'status_active' => 1, 'type_id' => Default_Model_DbTable_Comments::COMMENT_TYPE_PRODUCT, 'project_id' => $project_id )) ; $rowset = array_merge($rowset, $rowset2); /* create array with comment_id as key */ foreach ($rowset as $item) { $this->data[$item['comment_id']] = $item; } /* create an array with all parent_id's and their immediate children */ foreach ($rowset as $item) { $this->index[$item['comment_parent_id']][] = $item['comment_id']; } /* create the final sorted array */ $list = array(); $this->sort_child_nodes(0, 1, $list); return new Zend_Paginator(new Zend_Paginator_Adapter_Array($list)); } /** * @param int $parent_id * @param int $level * @param null $result * * @return array|null */ function sort_child_nodes($parent_id, $level, &$result = null) { // array(array('comment' => $rootElement, 'level' => 1)); $parent_id = $parent_id === null ? "NULL" : $parent_id; if (isset($this->index[$parent_id])) { foreach ($this->index[$parent_id] as $id) { $result[] = array('comment' => $this->data[$id], 'level' => $level); $this->sort_child_nodes($id, $level + 1, $result); } } } /** * @param int $project_id * * @return Zend_Paginator */ public function getAllCommentsForProject($project_id) { $rootElements = $this->getRootCommentsForProject($project_id); $returnValue = array(); foreach ($rootElements as $rootElement) { $resultElement = array(array('comment' => $rootElement, 'level' => 1)); $childs = $this->getAllChildComments($resultElement); if (0 == count($childs)) { $returnValue = array_merge($returnValue, $resultElement); } else { $returnValue = array_merge($returnValue, $childs); } } return new Zend_Paginator(new Zend_Paginator_Adapter_Array($returnValue)); } /** * @param int $_projectId * * @return array */ public function getRootCommentsForProject($_projectId) { $sql = ' SELECT * FROM comments STRAIGHT_JOIN member ON comments.comment_member_id = member.member_id WHERE comment_target_id = :project_id AND comment_parent_id = 0 AND comment_type = :type_id AND comment_active = :status ORDER BY comments.comment_created_at DESC, comment_parent_id '; $rowset = $this->_dataTable->getAdapter()->fetchAll($sql, array( 'project_id' => $_projectId, 'status' => Default_Model_DbTable_Comments::COMMENT_ACTIVE, 'type_id' => Default_Model_DbTable_Comments::COMMENT_TYPE_PRODUCT )) ; if (0 == count($rowset)) { return array(); } return $rowset; } /** * @param array $element * * @return array */ private function getAllChildComments($element) { $returnValue = array(); $level = $element[0]['level'] + 1; $childs = $this->getChildCommentsForId($element[0]['comment']['comment_id']); if (0 == count($childs)) { return null; } foreach ($childs as $child) { $resultElement = array(array('comment' => $child, 'level' => $level)); $subChilds = $this->getAllChildComments($resultElement); if (0 == count($subChilds)) { $returnValue = array_merge($returnValue, $resultElement); } else { $returnValue = array_merge($returnValue, $subChilds); } } return array_merge($element, $returnValue); } /** * @param int $parent_id * * @return array */ public function getChildCommentsForId($parent_id) { $sql = "SELECT * FROM comments STRAIGHT_JOIN member ON comments.comment_member_id = member.member_id WHERE comment_parent_id = :parent_id AND comment_active = :status ORDER BY comments.comment_created_at, comments.comment_id "; $rowset = $this->_dataTable->getAdapter()->fetchAll($sql, array('parent_id' => $parent_id, 'status' => Default_Model_DbTable_Comments::COMMENT_ACTIVE)) ; if (0 == count($rowset)) { return array(); } return $rowset; } /** * @param array $data * * @return Zend_Db_Table_Row_Abstract * @throws Exception */ public function save($data) { return $this->_dataTable->save($data); } public function setAllCommentsForUserDeleted($member_id) { $sql = ' UPDATE comments SET comment_active = 0 WHERE comment_member_id = :member_id'; $this->_dataTable->getAdapter()->query($sql, array('member_id' => $member_id))->execute(); } public function setAllCommentsForUserActivated($member_id) { $sql = ' UPDATE comments SET comment_active = 1 WHERE comment_member_id = :member_id'; $this->_dataTable->getAdapter()->query($sql, array('member_id' => $member_id))->execute(); } public function setAllCommentsForProjectDeleted($project_id) { $sql = ' UPDATE comments SET comment_active = 0 WHERE comment_target_id = :projectId'; $this->_dataTable->getAdapter()->query($sql, array('projectId' => $project_id))->execute(); } public function setAllCommentsForProjectActivated($project_id) { $sql = ' UPDATE comments SET comment_active = 1 WHERE comment_target_id = :projectId'; $this->_dataTable->getAdapter()->query($sql, array('projectId' => $project_id))->execute(); } + public function getCommentsHierarchic($project_id) + { + $rootElements = $this->getRootCommentsForProject($project_id); + $returnValue = array(); + foreach ($rootElements as $parentComment) { + $childs = $this->getChildCommentsHierarchic($parentComment); + if (0 == count($childs)) { + $parentComment['childcount'] = 0; + } else { + $parentComment['childcount'] = count($childs); + $parentComment['children'] = $childs; + } + $returnValue[] = $parentComment; + } + + return new Zend_Paginator(new Zend_Paginator_Adapter_Array($returnValue)); + } + + protected function getChildCommentsHierarchic($parentComment) + { + $childs = $this->getChildCommentsForId($parentComment['comment_id']); + if (0 == count($childs)) { + return array(); + } + $returnValue = array(); + foreach ($childs as $child) { + $subChilds = $this->getChildCommentsHierarchic($child); + if (0 == count($subChilds)) { + $child['childcount'] = 0; + } else { + $child['childcount'] = count($subChilds); + $child['children'] = $subChilds; + } + $returnValue[] = $child; + } + + return $returnValue; + } + } \ No newline at end of file