File indexing completed on 2024-05-12 05:58:45

0001 <?php
0002 
0003 /**
0004  *  ocs-webserver
0005  *
0006  *  Copyright 2016 by pling GmbH.
0007  *
0008  *    This file is part of ocs-webserver.
0009  *
0010  *    This program is free software: you can redistribute it and/or modify
0011  *    it under the terms of the GNU Affero General Public License as
0012  *    published by the Free Software Foundation, either version 3 of the
0013  *    License, or (at your option) any later version.
0014  *
0015  *    This program is distributed in the hope that it will be useful,
0016  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
0017  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0018  *    GNU Affero General Public License for more details.
0019  *
0020  *    You should have received a copy of the GNU Affero General Public License
0021  *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
0022  **/
0023 class Default_Model_Collection extends Default_Model_DbTable_Project
0024 {
0025 
0026     const FILTER_NAME_PROJECT_ID_NOT_IN = 'project_id_not_in';
0027     const FILTER_NAME_RANKING = 'ranking';
0028     const FILTER_NAME_CATEGORY = 'category';
0029     const FILTER_NAME_TAG = 'tag';
0030     const FILTER_NAME_ORIGINAL = 'original';
0031     const FILTER_NAME_MEMBER = 'member';
0032     const FILTER_NAME_ORDER = 'order';
0033     const FILTER_NAME_LOCATION = 'location';
0034 
0035     const ITEM_TYPE_DUMMY = 0;
0036     const ITEM_TYPE_PRODUCT = 1;
0037     const ITEM_TYPE_UPDATE = 2;
0038     const ITEM_TYPE_COLLECTION = 3;
0039 
0040     const TAG_LICENCE_GID = 7;
0041     const TAG_TYPE_ID = 1;
0042 
0043     /**
0044      * @param int $status
0045      * @param int $id
0046      *
0047      * @throws Exception
0048      */
0049     public function setStatus($status, $id)
0050     {
0051         if (false === in_array($status, $this->_allowedStatusTypes)) {
0052             throw new Exception('Wrong value for project status.');
0053         }
0054         $updateValues = array(
0055             'status'     => $status,
0056             'changed_at' => new Zend_Db_Expr('Now()')
0057         );
0058 
0059         if (self::PROJECT_DELETED == $status) {
0060             $updateValues['deleted_at'] = new Zend_Db_Expr('NOW()');
0061         }
0062 
0063         $this->update($updateValues, $this->_db->quoteInto('project_id=?', $id, 'INTEGER'));
0064     }
0065 
0066     /**
0067      * @param int $member_id
0068      * @param int $id
0069      */
0070     public function setClaimedByMember($member_id, $id)
0071     {
0072         $updateValues = array(
0073             'claimed_by_member' => $member_id,
0074             'changed_at'        => new Zend_Db_Expr('Now()')
0075         );
0076 
0077         $this->update($updateValues, $this->_db->quoteInto('project_id=?', $id, 'INTEGER'));
0078     }
0079 
0080     /**
0081      * @param int $id
0082      */
0083     public function resetClaimedByMember($id)
0084     {
0085         $updateValues = array(
0086             'claimed_by_member' => new Zend_Db_Expr('NULL'),
0087             'changed_at'        => new Zend_Db_Expr('Now()')
0088         );
0089 
0090         $this->update($updateValues, $this->_db->quoteInto('project_id=?', $id, 'INTEGER'));
0091     }
0092 
0093     /**
0094      * @param int $id
0095      */
0096     public function transferClaimToMember($id)
0097     {
0098         $updateValues = array(
0099             'member_id'         => new Zend_Db_Expr('claimed_by_member'),
0100             'claimable'         => new Zend_Db_Expr('NULL'),
0101             'claimed_by_member' => new Zend_Db_Expr('NULL')
0102         );
0103 
0104         $this->update($updateValues, $this->_db->quoteInto('project_id=? and claimable = 1', $id, 'INTEGER'));
0105     }
0106 
0107     /**
0108      * @param int $project_id
0109      * @param     $member_id
0110      *
0111      * @throws Zend_Db_Statement_Exception
0112      * @throws Zend_Exception
0113      */
0114     public function setInActive($project_id, $member_id)
0115     {
0116         $project_id = (int)$project_id;
0117         $updateValues = array(
0118             'status'     => self::PROJECT_INACTIVE,
0119             'deleted_at' => new Zend_Db_Expr('Now()')
0120         );
0121 
0122         $this->update($updateValues, 'status > 40 AND project_id=' . $project_id);
0123 
0124         $this->setInActiveForUpdates($project_id);
0125         $this->setDeletedForComments($member_id,$project_id);
0126     }
0127 
0128     /**
0129      * @param int $id
0130      */
0131     protected function setInActiveForUpdates($id)
0132     {
0133         $id = (int)$id;
0134         $updateValues = array(
0135             'status'     => self::PROJECT_INACTIVE,
0136             'changed_at' => new Zend_Db_Expr('Now()')
0137         );
0138 
0139         $this->update($updateValues, 'status > 40 AND pid=' . $id);
0140     }
0141 
0142     /**
0143      * @param int $member_id
0144      * @param int $id
0145      *
0146      * @throws Zend_Db_Statement_Exception
0147      * @throws Zend_Exception
0148      */
0149     private function setDeletedForComments($member_id, $id)
0150     {
0151         $modelComments = new Default_Model_ProjectComments();
0152         $modelComments->setAllCommentsForProjectDeleted($member_id, $id);
0153     }
0154 
0155     /**
0156      * @param int $id
0157      *
0158      * @return mixed
0159      * @throws Zend_Db_Statement_Exception
0160      */
0161     public function fetchActiveBySourcePk($id)
0162     {
0163         $q = $this->select()->where('status = ?', self::PROJECT_ACTIVE)->where('source_pk = ?', (int)$id)
0164                   ->where('source_type = "project"')
0165         ;
0166 
0167         return $q->query()->fetch();
0168     }
0169 
0170     /**
0171      * @param int  $member_id
0172      * @param bool $onlyActiveProjects
0173      *
0174      * @return mixed
0175      */
0176     public function countAllCollectionsForMember($member_id, $onlyActiveProjects = false)
0177     {
0178         $q = $this->select()->from($this, array('countAll' => new Zend_Db_Expr('count(*)')))->setIntegrityCheck(false)
0179                   ->where('project.status >= ?', ($onlyActiveProjects ? self::PROJECT_ACTIVE : self::PROJECT_INACTIVE))
0180                   ->where('project.member_id = ?', $member_id, 'INTEGER')->where('project.type_id = ?', self::PROJECT_TYPE_COLLECTION)
0181         ;
0182         $resultSet = $q->query()->fetchAll();
0183 
0184         return $resultSet[0]['countAll'];
0185     }
0186     
0187     /**
0188      * @param int  $project_id
0189      * @param bool $onlyActiveProjects
0190      *
0191      * @return mixed
0192      */
0193     public function countAllCollectionsForProject($project_id, $onlyActiveProjects = true)
0194     {
0195         $q = $this->select()->from('collection_projects', array('countAll' => new Zend_Db_Expr('count(*)')))->setIntegrityCheck(false)
0196                   ->where('collection_projects.active = 1')
0197                   ->where('collection_projects.project_id = ?', $project_id, 'INTEGER')
0198         ;
0199         $resultSet = $q->query()->fetchAll();
0200 
0201         return $resultSet[0]['countAll'];
0202     }
0203 
0204     /**
0205      * @param int  $member_id
0206      * @param bool $onlyActiveProjects
0207      * @param      $catids
0208      *
0209      * @return mixed
0210      * @throws Zend_Cache_Exception
0211      * @throws Zend_Db_Statement_Exception
0212      */
0213     public function countAllProjectsForMemberCatFilter($member_id, $onlyActiveProjects = false, $catids = null)
0214     {
0215         $q = $this->select()->from($this, array('countAll' => new Zend_Db_Expr('count(*)')))->setIntegrityCheck(false)
0216                   ->where('project.status >= ?', ($onlyActiveProjects ? self::PROJECT_ACTIVE : self::PROJECT_INACTIVE))
0217                   ->where('project.member_id = ?', $member_id, 'INTEGER')->where('project.type_id = ?', self::PROJECT_TYPE_STANDARD)
0218         ;
0219         if (isset($catids)) {
0220             $q->where('project_category_id in (' . $this->_getCatIds($catids) . ')');
0221         }
0222         $resultSet = $q->query()->fetchAll();
0223 
0224         return $resultSet[0]['countAll'];
0225     }
0226 
0227     /**
0228      * @param $catids
0229      *
0230      * @return string
0231      * @throws Zend_Cache_Exception
0232      * @throws Zend_Db_Statement_Exception
0233      */
0234     protected function _getCatIds($catids)
0235     {
0236         $sqlwhereCat = "";
0237         $sqlwhereSubCat = "";
0238 
0239         $idCategory = explode(',', $catids);
0240         if (false === is_array($idCategory)) {
0241             $idCategory = array($idCategory);
0242         }
0243 
0244         $sqlwhereCat .= implode(',', $idCategory);
0245 
0246         $modelCategory = new Default_Model_DbTable_ProjectCategory();
0247         $subCategories = $modelCategory->fetchChildElements($idCategory);
0248 
0249         if (count($subCategories) > 0) {
0250             foreach ($subCategories as $element) {
0251                 $sqlwhereSubCat .= "{$element['project_category_id']},";
0252             }
0253         }
0254 
0255         return $sqlwhereSubCat . $sqlwhereCat;
0256     }
0257 
0258     /**
0259      * By default it will show all projects for a member included the unpublished elements.
0260      *
0261      * @param int      $member_id
0262      * @param int|null $limit
0263      * @param int|null $offset
0264      * @param bool     $onlyActiveProjects
0265      *
0266      * @return Zend_Db_Table_Rowset_Abstract
0267      */
0268     public function fetchAllCollectionsForMember($member_id, $limit = null, $offset = null, $onlyActiveProjects = false)
0269     {
0270         $q = $this->select()->from($this, array(
0271             '*',
0272             'project_validated'  => 'project.validated',
0273             'project_uuid'       => 'project.uuid',
0274             'project_status'     => 'project.status',
0275             'project_created_at' => 'project.created_at',
0276             'project_changed_at' => 'project.changed_at',
0277             'member_type'        => 'member.type',
0278             'project_member_id'  => 'member_id',
0279             'laplace_score'      => new Zend_Db_Expr('laplace_score(count_likes,count_dislikes)'),
0280             'catTitle'           => new Zend_Db_Expr('(SELECT title FROM project_category WHERE project_category_id = project.project_category_id)')
0281         ))->setIntegrityCheck(false)->join('member', 'project.member_id = member.member_id', array('username'))
0282                   ->where('project.status >= ?', ($onlyActiveProjects ? self::PROJECT_ACTIVE : self::PROJECT_INACTIVE))
0283                   ->where('project.member_id = ?', $member_id, 'INTEGER')
0284                   ->where('project.type_id = ?', self::PROJECT_TYPE_COLLECTION)
0285                   ->order('project_changed_at DESC')
0286         ;
0287         if (isset($limit)) {
0288             $q->limit($limit, $offset);
0289         }
0290 
0291         return $this->generateRowSet($q->query()->fetchAll());
0292     }
0293     
0294     
0295     /**
0296      * By default it will show all projects for a project included the unpublished elements.
0297      *
0298      * @param int      $project_id
0299      * @param int|null $limit
0300      * @param int|null $offset
0301      * @param bool     $onlyActiveProjects
0302      *
0303      * @return Zend_Db_Table_Rowset_Abstract
0304      */
0305     public function fetchAllCollectionsForProject($project_id, $limit = null, $offset = null, $onlyActiveProjects = true)
0306     {
0307         $q = $this->select()->from('collection_projects', array(
0308             '*',
0309             'project_validated'  => 'project.validated',
0310             'project_uuid'       => 'project.uuid',
0311             'project_status'     => 'project.status',
0312             'project_created_at' => 'project.created_at',
0313             'project_changed_at' => 'project.changed_at',
0314             'member_type'        => 'member.type',
0315             'laplace_score'      => new Zend_Db_Expr('laplace_score(count_likes,count_dislikes)'),
0316             'catTitle'           => new Zend_Db_Expr('(SELECT title FROM project_category WHERE project_category_id = project.project_category_id)')
0317         ))->setIntegrityCheck(false)
0318                   ->join('project', 'collection_projects.collection_id = project.project_id')
0319                   ->join('member', 'project.member_id = member.member_id', array('username'))
0320                   ->where('collection_projects.active = 1')
0321                   ->where('collection_projects.project_id = ?', $project_id, 'INTEGER')
0322                   ->where('project.status >= ?', ($onlyActiveProjects ? self::PROJECT_ACTIVE : self::PROJECT_INACTIVE))
0323                   ->where('project.type_id = ?', self::PROJECT_TYPE_COLLECTION)
0324                   ->order('project_changed_at DESC')
0325         ;
0326         if (isset($limit)) {
0327             $q->limit($limit, $offset);
0328         }
0329 
0330         return $this->generateRowSet($q->query()->fetchAll());
0331     }
0332 
0333 
0334     /**
0335      * @param array $data
0336      *
0337      * @return Zend_Db_Table_Rowset_Abstract
0338      */
0339     protected function generateRowSet($data)
0340     {
0341         $classRowSet = $this->getRowsetClass();
0342 
0343         return new $classRowSet(array(
0344             'table'    => $this,
0345             'rowClass' => $this->getRowClass(),
0346             'stored'   => true,
0347             'data'     => $data
0348         ));
0349     }
0350 
0351     /**
0352      * By default it will show all projects for a member included the unpublished elements.
0353      *
0354      * @param int      $member_id
0355      * @param int|null $limit
0356      * @param int|null $offset
0357      * @param bool     $onlyActiveProjects
0358      *
0359      * @param null     $catids
0360      *
0361      * @return Zend_Db_Table_Rowset_Abstract
0362      * @throws Zend_Cache_Exception
0363      * @throws Zend_Db_Statement_Exception
0364      */
0365     public function fetchAllProjectsForMemberCatFilter(
0366         $member_id,
0367         $limit = null,
0368         $offset = null,
0369         $onlyActiveProjects = false,
0370         $catids = null
0371     ) {
0372         $q = $this->select()->from($this, array(
0373             '*',
0374             'project_validated'  => 'project.validated',
0375             'project_uuid'       => 'project.uuid',
0376             'project_status'     => 'project.status',
0377             'project_created_at' => 'project.created_at',
0378             'project_changed_at' => 'project.changed_at',
0379             'member_type'        => 'member.type',
0380             'project_member_id'  => 'member_id',
0381             'laplace_score'      => new Zend_Db_Expr('laplace_score(count_likes,count_dislikes)'),
0382             'catTitle'           => new Zend_Db_Expr('(SELECT title FROM project_category WHERE project_category_id = project.project_category_id)')
0383         ))->setIntegrityCheck(false)->join('member', 'project.member_id = member.member_id', array('username'))
0384                   ->where('project.status >= ?', ($onlyActiveProjects ? self::PROJECT_ACTIVE : self::PROJECT_INACTIVE))
0385                   ->where('project.member_id = ?', $member_id, 'INTEGER')->where('project.type_id = ?', self::PROJECT_TYPE_STANDARD)
0386                   ->order('project_changed_at DESC')
0387         ;
0388 
0389         if (isset($catids)) {
0390             $q->where('project_category_id in (' . $this->_getCatIds($catids) . ')');
0391         }
0392 
0393         if (isset($limit)) {
0394             $q->limit($limit, $offset);
0395         }
0396 
0397         return $this->generateRowSet($q->query()->fetchAll());
0398     }
0399 
0400     /**
0401      * @param $collection_id
0402      *
0403      * @return null|Zend_Db_Table_Row_Abstract
0404      */
0405     public function fetchProductForCollectionId($collection_id)
0406     {
0407         $sql = '
0408                 SELECT
0409                   `p`.*
0410                 FROM `project` AS `p`
0411                 WHERE 
0412                   `p`.`ppload_collection_id` = :collectionId
0413                   AND `p`.`status` >= :projectStatus AND `p`.`type_id` = :typeId
0414         ';
0415         $result = $this->_db->fetchRow($sql, array(
0416             'collectionId'  => $collection_id,
0417             'projectStatus' => self::PROJECT_INACTIVE,
0418             'typeId'        => self::PROJECT_TYPE_STANDARD
0419         ));
0420 
0421         if ($result) {
0422             return $this->generateRowClass($result);
0423         } else {
0424             return null;
0425         }
0426     }
0427 
0428     /**
0429      * @param int $project_id
0430      *
0431      * @return null|Zend_Db_Table_Row_Abstract
0432      */
0433     public function fetchProductInfo($project_id)
0434     {
0435         $sql = '
0436                 SELECT
0437                   `p`.*,
0438                   `p`.`validated` AS `project_validated`,
0439                   `p`.`uuid` AS `project_uuid`,
0440                   `p`.`status` AS `project_status`,
0441                   `p`.`created_at` AS `project_created_at`,
0442                   `p`.`major_updated_at` AS `project_major_updated_at`,
0443                   `p`.`changed_at` AS `project_changed_at`,
0444                   `p`.`member_id` AS `project_member_id`,
0445                   `p`.`source_pk` AS `project_source_pk`,
0446                   `p`.`version` AS `project_version`,
0447                   `pc`.`title` AS `cat_title`,
0448                   `m`.`username`,
0449                   `m`.`avatar`,
0450                   `m`.`profile_image_url`,
0451                   `m`.`roleId`,
0452                   `m`.`mail`,
0453                   `m`.`paypal_mail`,
0454                   `m`.`dwolla_id`,
0455                   laplace_score(`p`.`count_likes`,`p`.`count_dislikes`) AS `laplace_score`,
0456                  `view_reported_projects`.`amount_reports` AS `amount_reports`,
0457                 (SELECT `tag`.`tag_fullname` FROM `tag_object`, `tag` WHERE `tag_object`.`tag_id`=`tag`.`tag_id` AND `tag_object_id` = `p`.`project_id` AND `tag_object`.`is_deleted`=0 AND `tag_group_id` = :tag_licence_gid AND `tag_type_id` = :tag_type_id  ORDER BY `tag_object`.`tag_created` DESC LIMIT 1)
0458                                 AS `project_license_title`
0459                 FROM `project` AS `p`
0460                   JOIN `member` AS `m` ON `p`.`member_id` = `m`.`member_id` AND `m`.`is_active` = 1 AND `m`.`is_deleted` = 0
0461                   JOIN `project_category` AS `pc` ON `p`.`project_category_id` = `pc`.`project_category_id`
0462                   LEFT JOIN `view_reported_projects` ON ((`view_reported_projects`.`project_id` = `p`.`project_id`))                  
0463                 WHERE 
0464                   `p`.`project_id` = :projectId
0465                   AND `p`.`status` >= :projectStatus AND `p`.`type_id` = :typeId
0466         ';
0467         $result = $this->_db->fetchRow($sql, array(
0468             'projectId'       => $project_id,
0469             'projectStatus'   => self::PROJECT_INACTIVE,
0470             'typeId'          => self::PROJECT_TYPE_COLLECTION,
0471             'tag_licence_gid' => self::TAG_LICENCE_GID,
0472             'tag_type_id'     => self::TAG_TYPE_ID
0473 
0474         ));
0475 
0476         if ($result) {
0477             return $this->generateRowClass($result);
0478         } else {
0479             return null;
0480         }
0481     }
0482 
0483     /**
0484      * @param array $productInfo
0485      * @return array
0486      */
0487     public static function cleanProductInfoForJson(array $productInfo)
0488     {
0489         if (empty($productInfo)) {
0490             return $productInfo;
0491         }
0492 
0493         $unwantedKeys = array(
0494             'roleId'           => 0,
0495             'mail'             => 0,
0496             'dwolla_id'        => 0,
0497             'paypal_mail'      => 0,
0498             'content_type'     => 0,
0499             'hive_category_id' => 0,
0500             'is_active'        => 0,
0501             'is_deleted'       => 0,
0502             'start_date'       => 0,
0503             'source_id'        => 0,
0504             'source_pk'        => 0,
0505             'source_type'      => 0
0506         );
0507 
0508         $productInfo = array_diff_key($productInfo, $unwantedKeys);
0509 
0510         return $productInfo;
0511     }
0512 
0513     /**
0514      * @param $project_id
0515      *
0516      * @return Zend_Db_Table_Rowset_Abstract
0517      */
0518     public function fetchProjectUpdates($project_id)
0519     {
0520         $projectSel = $this->select()->setIntegrityCheck(false)->from($this->_name)
0521                            ->join('member', 'project.member_id = member.member_id', array('*'))
0522                            ->where('project.pid=?', $project_id, 'INTEGER')->where('project.status>?', self::PROJECT_INACTIVE)
0523                            ->where('project.type_id=?', self::PROJECT_TYPE_UPDATE)->order('RAND()')
0524         ;
0525 
0526         return $this->fetchAll($projectSel);
0527     }
0528 
0529     /**
0530      * @param $project_id
0531      *
0532      * @return Zend_Db_Table_Rowset_Abstract
0533      */
0534     public function fetchAllProjectUpdates($project_id)
0535     {
0536         $projectSel = $this->select()->setIntegrityCheck(false)->from($this->_name)->where('project.pid=?', $project_id, 'INTEGER')
0537                            ->where('project.status>?', self::PROJECT_INACTIVE)->where('project.type_id=?', self::PROJECT_TYPE_UPDATE)
0538         ;
0539 
0540         return $this->fetchAll($projectSel);
0541     }
0542 
0543     /**
0544      * @param     $project
0545      * @param int $count
0546      *
0547      * @return Zend_Db_Table_Rowset_Abstract
0548      */
0549     public function fetchSimilarProjects($project, $count = 10)
0550     {
0551         $count = (int)$count;
0552         $sql = "
0553                 SELECT *
0554                 FROM `project` AS `p`
0555                 WHERE `p`.`project_category_id` = :cat_id AND `project_id` <> :project_id
0556                 ORDER BY `p`.`changed_at` DESC
0557                 LIMIT {$count}
0558         ";
0559 
0560         $result = $this->_db->fetchAll($sql, array(
0561                 'cat_id'     => $project->project_category_id,
0562                 'project_id' => $project->project_id
0563             ));
0564 
0565         return $this->generateRowSet($result);
0566     }
0567 
0568     /**
0569      * @param Zend_Db_Table_Row $project
0570      * @param int               $count
0571      *
0572      * @return Zend_Db_Table_Rowset_Abstract
0573      * @throws Zend_Exception
0574      */
0575     public function fetchMoreCollections($project, $count = 6)
0576     {
0577         $q = $this->select()->from(array('project' => 'project'), array(
0578             'project_id',
0579             'image_small',
0580             'title',
0581             'changed_at'
0582         ))->setIntegrityCheck(false)
0583           ->where('project.status = ?', self::PROJECT_ACTIVE)
0584           ->where('project.member_id = ?', $project->member_id, 'INTEGER')
0585           ->where('project.project_id != ?', $project->project_id, 'INTEGER')
0586           ->where('project.type_id = ?', self::PROJECT_TYPE_COLLECTION)
0587           //->where('project.amount_reports is null')
0588           ->where('project.project_category_id = ?', $project->project_category_id, 'INTEGER')
0589           ->limit($count)
0590           ->order('project.created_at DESC')
0591         ;
0592 
0593         $tagFilter  = Zend_Registry::isRegistered('config_store_tags') ? Zend_Registry::get('config_store_tags') : null;
0594         
0595         if ($tagFilter) {
0596             $q = $this->generateTagFilter($q, array(self::FILTER_NAME_TAG => $tagFilter));
0597         }
0598 
0599         $result = $this->fetchAll($q);
0600 
0601         return $result;
0602     }
0603     
0604     /**
0605      * @param Zend_Db_Select $statement
0606      * @param array          $filterArrayValue
0607      *
0608      * @return Zend_Db_Select
0609      */
0610     protected function generateTagFilter(Zend_Db_Select $statement, $filterArrayValue)
0611     {
0612         if (false == isset($filterArrayValue[self::FILTER_NAME_TAG])) {
0613             return $statement;
0614         }
0615 
0616         $filter = $filterArrayValue[self::FILTER_NAME_TAG];
0617 
0618         if (is_array($filter)) {
0619             
0620             $tagList = $filter;
0621             //build where statement für projects
0622             $selectAnd = $this->select()->from(array('project' => 'stat_projects'));
0623 
0624             foreach($tagList as $item) {
0625                 #and
0626                 $selectAnd->where('find_in_set(?, tag_ids)', $item);
0627             }
0628             $statement->where(implode(' ', $selectAnd->getPart('where')));
0629             
0630             /*
0631             $statement->join(array(
0632                 'tags' => new Zend_Db_Expr('(SELECT DISTINCT project_id FROM stat_project_tagids WHERE tag_id in ('
0633                     . implode(',', $filter) . '))')
0634             ), 'project.project_id = tags.project_id', array());
0635              * 
0636              */
0637             
0638         } else {
0639             $statement->where('find_in_set(?, tag_ids)', $filter);
0640         }
0641 
0642         return $statement;
0643     }
0644 
0645 
0646 
0647 
0648     public function fetchMoreCollectionsOfOtherUsr($project, $count = 8)
0649     {
0650         $sql = "
0651                 SELECT count(1) AS `count`
0652                 FROM `stat_projects`
0653                 WHERE `status` = :current_status
0654                   AND `member_id` <> :current_member_id
0655                   and amount_reports is null
0656                   AND `project_category_id` = :category_id
0657                   AND `type_id` = :project_type
0658         ";
0659 
0660         $result = $this->_db->query($sql, array(
0661             'current_status'    => self::PROJECT_ACTIVE,
0662             'current_member_id' => $project->member_id,
0663             'category_id'       => $project->project_category_id,
0664             'project_type'      => self::PROJECT_TYPE_COLLECTION
0665         ))->fetch()
0666         ;
0667 
0668         if ($result['count'] > $count) {
0669             $offset = rand(0, $result['count'] - $count);
0670         } else {
0671             $offset = 0;
0672         }
0673 
0674         $q = $this->select()->from(array('project' => 'stat_projects'), array(
0675             'project_id',
0676             'image_small',
0677             'title',
0678             'catTitle' => 'cat_title',
0679             'changed_at'
0680         ))->setIntegrityCheck(false)->where('status = ?', self::PROJECT_ACTIVE)
0681                   ->where('member_id != ?', $project->member_id, 'INTEGER')
0682                   ->where('amount_reports is null')
0683                   ->where('type_id = ?', self::PROJECT_TYPE_COLLECTION, 'INTEGER')
0684                   ->where('project_category_id = ?', $project->project_category_id, 'INTEGER')->limit($count, $offset)
0685                   ->order('project_created_at DESC')
0686         ;
0687 
0688         
0689 
0690         $tagFilter  = Zend_Registry::isRegistered('config_store_tags') ? Zend_Registry::get('config_store_tags') : null;
0691 
0692         if ($tagFilter) {
0693             $q = $this->generateTagFilter($q, array(self::FILTER_NAME_TAG => $tagFilter));
0694         }
0695 
0696         $result = $this->fetchAll($q);
0697 
0698         return $result;
0699     }
0700 
0701     /**
0702      * @param     $project
0703      * @param int $count
0704      *
0705      * @return Zend_Db_Table_Rowset_Abstract
0706      * @throws Zend_Db_Statement_Exception
0707      * @throws Zend_Exception
0708      * @todo improve processing speed
0709      */
0710    /* public function fetchMoreCollectionsOfOtherUsr($project, $count = 8)
0711     {
0712         $sql = "
0713                 SELECT count(1) AS `count`                
0714                 FROM `project` as p                 
0715                 WHERE `status` = :current_status
0716                   AND `member_id` <> :current_member_id
0717                   AND `project_category_id` = :category_id                  
0718                   AND `amount_reports is null `
0719                   AND `type_id` = :project_type
0720                   AND spamcnt == 0
0721         ";
0722 
0723         $result = $this->_db->query($sql, array(
0724             'current_status'    => self::PROJECT_ACTIVE,
0725             'current_member_id' => $project->member_id,
0726             'category_id'       => $project->project_category_id,
0727             'project_type'      => self::PROJECT_TYPE_COLLECTION
0728         ))->fetch()
0729         ;
0730 
0731         if ($result['count'] > $count) {
0732             $offset = rand(0, $result['count'] - $count);
0733         } else {
0734             $offset = 0;
0735         }
0736 
0737         $q = $this->select()->from(array('project' => 'project'), array(
0738             'project_id',
0739             'image_small',
0740             'title'
0741         ))->setIntegrityCheck(false)       
0742         ->where('status = ?', self::PROJECT_ACTIVE)
0743                   ->where('member_id != ?', $project->member_id, 'INTEGER')
0744                   ->where('amount_reports is null')
0745                   ->where('project_category_id = ?', $project->project_category_id, 'INTEGER')
0746                   ->where('type_id = ?', self::PROJECT_TYPE_COLLECTION, 'INTEGER')
0747                   ->limit($count, $offset)
0748                   ->order('created_at DESC')
0749         ;
0750 
0751         $tagFilter  = Zend_Registry::isRegistered('config_store_tags') ? Zend_Registry::get('config_store_tags') : null;
0752         
0753         if ($tagFilter) {
0754             $q = $this->generateTagFilter($q, array(self::FILTER_NAME_TAG => $tagFilter));
0755         }
0756 
0757         $result = $this->fetchAll($q);
0758 
0759         return $result;
0760     }
0761 */
0762     /**
0763      * @param int $project_id
0764      *
0765      * @return Zend_Db_Table_Rowset_Abstract
0766      */
0767     public function fetchProjectSupporter($project_id)
0768     {
0769         $plingTable = new Default_Model_DbTable_Plings();
0770 
0771         return $plingTable->getSupporterForProjectId($project_id);
0772     }
0773 
0774     /**
0775      * @param int $project_id
0776      *
0777      * @return Zend_Db_Table_Rowset_Abstract
0778      */
0779     public function fetchProjectSupporterWithPlings($project_id)
0780     {
0781         $plingTable = new Default_Model_DbTable_Plings();
0782 
0783         return $plingTable->getSupporterWithPlingsForProjectId($project_id);
0784     }
0785 
0786     /**
0787      * @param $projectId
0788      * @param $sources
0789      */
0790     public function updateGalleryPictures($projectId, $sources)
0791     {
0792         $galleryPictureTable = new Default_Model_DbTable_ProjectGalleryPicture();
0793         $galleryPictureTable->clean($projectId);
0794         $galleryPictureTable->insertAll($projectId, $sources);
0795     }
0796 
0797     /**
0798      * @param $projectId
0799      *
0800      * @return array
0801      */
0802     public function getGalleryPictureSources($projectId)
0803     {
0804         $galleryPictureTable = new Default_Model_DbTable_ProjectGalleryPicture();
0805         $stmt = $galleryPictureTable->select()->where('project_id = ?', $projectId)->order(array('sequence'));
0806 
0807         $pics = array();
0808         foreach ($galleryPictureTable->fetchAll($stmt) as $pictureRow) {
0809             $pics[] = $pictureRow['picture_src'];
0810         }
0811 
0812         return $pics;
0813     }
0814 
0815     /**
0816      * @param int $project_id
0817      *
0818      * @return array
0819      * @throws Zend_Db_Statement_Exception
0820      */
0821     public function fetchProjectViews($project_id)
0822     {
0823         $sql = "
0824                 SELECT
0825                     `project_id`,
0826                     `count_views`,
0827                     `count_visitor`,
0828                     `last_view`
0829                 FROM
0830                     `stat_page_views_mv`
0831                 WHERE `project_id` = ?
0832                 ";
0833         $database = Zend_Db_Table::getDefaultAdapter();
0834         $sql = $database->quoteInto($sql, $project_id, 'INTEGER', 1);
0835         $resultSet = $database->query($sql)->fetchAll();
0836 
0837         if (count($resultSet) > 0) {
0838             $result = $resultSet[0]['count_views'];
0839         } else {
0840             $result = 0;
0841         }
0842 
0843         return $result;
0844     }
0845 
0846     /**
0847      * @param int $member_id
0848      *
0849      * @return int
0850      * @throws Zend_Db_Statement_Exception
0851      */
0852     public function fetchOverallPageViewsByMember($member_id)
0853     {
0854         $sql = "
0855                 SELECT sum(`stat`.`amount`) AS `page_views`
0856                 FROM `project`
0857                 JOIN (SELECT `project_id`, count(`project_id`) AS `amount` FROM `stat_page_views` GROUP BY `project_id`) AS `stat` ON `stat`.`project_id` = `project`.`project_id`
0858                 WHERE `project`.`member_id` = :member_id AND `project`.`status` = :project_status
0859                 GROUP BY `member_id`
0860               ";
0861 
0862         $result = $this->_db->query($sql, array('member_id' => $member_id, 'project_status' => self::PROJECT_ACTIVE));
0863         if ($result->rowCount() > 0) {
0864             $row = $result->fetch();
0865 
0866             return $row['page_views'];
0867         } else {
0868             return 0;
0869         }
0870     }
0871 
0872     /**
0873      * @return array
0874      * @throws Zend_Db_Statement_Exception
0875      */
0876     public function getStatsForNewProjects()
0877     {
0878         $sql = "
0879                 SELECT
0880                     DATE_FORMAT(`time`, '%M %D') AS `projectdate`,
0881                     count(1) AS `daycount`
0882                 FROM
0883                     `activity_log`
0884                 WHERE
0885                     `activity_type_id` = 0
0886                 GROUP BY DATE_FORMAT(`time`, '%Y%M%D')
0887                 ORDER BY `time` DESC
0888                 LIMIT 14
0889                 ;";
0890         $database = Zend_Db_Table::getDefaultAdapter();
0891         $resultSet = $database->query($sql)->fetchAll();
0892 
0893         return $resultSet;
0894     }
0895 
0896     /**
0897      * @param int     $idCategory
0898      * @param int|null $limit
0899      *
0900      * @return Zend_Db_Table_Rowset_Abstract
0901      * @throws Zend_Cache_Exception
0902      * @throws Zend_Db_Statement_Exception
0903      */
0904     public function fetchProductsByCategory($idCategory, $limit = null)
0905     {
0906         $select =
0907             $this->select()->setIntegrityCheck(false)->from($this->_name)->where('project.project_category_id in (?)', $idCategory)
0908                  ->where('project.status = ?', self::PROJECT_ACTIVE)->where('project.type_id = ?', self::PROJECT_TYPE_STANDARD)
0909                  ->joinLeft(array(
0910                      'pling_amount' => new Zend_Db_Expr('(SELECT
0911                 project_id as plinged_project_id, SUM(amount) AS sumAmount, count(1) as countPlings
0912             FROM
0913                 plings
0914             where status_id >= 2
0915             group by project_id
0916             order by sumAmount DESC)')
0917                  ), 'pling_amount.plinged_project_id = project.project_id')
0918                  ->joinLeft('project_category', 'project_category.project_category_id = project.project_category_id',
0919                      array('cat_title' => 'title'))->order('pling_amount.sumAmount DESC')
0920         ;
0921         if (false === is_null($limit)) {
0922             $select->limit($limit);
0923         }
0924 
0925         $modelCategory = new Default_Model_DbTable_ProjectCategory();
0926         $subCategories = $modelCategory->fetchChildElements($idCategory);
0927 
0928         if (count($subCategories) > 0) {
0929             $sqlwhere = '';
0930             foreach ($subCategories as $element) {
0931                 $sqlwhere .= "{$element['project_category_id']},";
0932             }
0933             $sqlwhere = substr($sqlwhere, 0, -1);
0934             if (!empty($sqlwhere)) {
0935                 $sqlwhere = explode(',', $sqlwhere);
0936             }
0937 
0938             $select->orWhere('project.project_category_id in (?)', $sqlwhere);
0939         }
0940 
0941         return $this->fetchAll($select);
0942     }
0943 
0944     /**
0945      * @param int|array $idCategory id of a category or an array of id's
0946      * @param bool      $withSubCat if was set true it will also count products in sub categories
0947      * @param null      $store_id
0948      *
0949      * @return int count of products in given category
0950      * @throws Zend_Exception
0951      * @deprecated
0952      */
0953     public function countProductsInCategory($idCategory = null, $withSubCat = true, $store_id = null)
0954     {
0955         if (empty($idCategory)) {
0956             throw new Zend_Exception('idCategory param was not set');
0957         }
0958 
0959         if (false == is_array($idCategory)) {
0960             $idCategory = array($idCategory);
0961         }
0962 
0963         if (isset($store_id)) {
0964             $configurations = Zend_Registry::get('application_store_config_id_list');
0965             $store_config = isset($configurations[$store_id]) ? $configurations[$store_id] : null;
0966         } else {
0967             $store_config = Zend_Registry::isRegistered('store_config') ? Zend_Registry::get('store_config') : null;
0968         }
0969         $tagFilter  = Zend_Registry::isRegistered('config_store_tags') ? Zend_Registry::get('config_store_tags') : null;
0970 
0971         $cacheName = __FUNCTION__ . '_' . md5(serialize($idCategory) . $withSubCat . serialize($tagFilter));
0972         /** @var Zend_Cache_Core $cache */
0973         $cache = Zend_Registry::get('cache');
0974 
0975         if (false !== ($resultSet = $cache->load($cacheName))) {
0976             return (int)$resultSet[0]['count_active_projects'];
0977         }
0978 
0979         $select = $this->select()->setIntegrityCheck(false)->from('stat_projects', array('count_active_projects' => 'COUNT(1)'))
0980                        ->where('status = ? ', self::PROJECT_ACTIVE)->where('type_id = ?', self::PROJECT_TYPE_STANDARD)
0981         ;
0982 
0983         $select = $this->generateTagFilter($select, array(self::FILTER_NAME_TAG => $tagFilter));
0984 
0985         if ($withSubCat) {
0986             $modelCategory = new Default_Model_DbTable_ProjectCategory();
0987             $subCategories = $modelCategory->fetchChildIds($idCategory);
0988             $inCategories = implode(',', array_unique(array_merge($idCategory, $subCategories)));
0989         } else {
0990             $inCategories = implode(',', $idCategory);
0991         }
0992 
0993         $select->where('project_category_id in (' . $inCategories . ')');
0994         $resultSet = $this->fetchAll($select)->toArray();
0995 
0996         $cache->save($resultSet, $cacheName, array(), 60);
0997 
0998         return (int)$resultSet[0]['count_active_projects'];
0999     }
1000 
1001     /**
1002      * @param int|array $idCategory
1003      *
1004      * @return int
1005      * @throws Zend_Exception
1006      */
1007     public function countActiveMembersForCategory($idCategory)
1008     {
1009 
1010         $cacheName = __FUNCTION__ . md5(serialize($idCategory));
1011         $cache = Zend_Registry::get('cache');
1012 
1013         $result = $cache->load($cacheName);
1014 
1015         if ($result) {
1016             return (int)$result['count_active_members'];
1017         }
1018 
1019         $sqlwhereCat = "";
1020         $sqlwhereSubCat = "";
1021 
1022         if (false === is_array($idCategory)) {
1023             $idCategory = array($idCategory);
1024         }
1025         $sqlwhereCat .= implode(',', $idCategory);
1026 
1027         $modelCategory = new Default_Model_DbTable_ProjectCategory();
1028         $subCategories = $modelCategory->fetchChildElements($idCategory);
1029 
1030         if (count($subCategories) > 0) {
1031             foreach ($subCategories as $element) {
1032                 $sqlwhereSubCat .= "{$element['project_category_id']},";
1033             }
1034         }
1035 
1036         $selectWhere = 'AND p.project_category_id in (' . $sqlwhereSubCat . $sqlwhereCat . ')';
1037 
1038         $sql = "SELECT count(1) AS `count_active_members` FROM (                    
1039                     SELECT count(1) AS `count_active_projects` FROM `project` `p`
1040                     WHERE `p`.`status` = 100
1041                     AND `p`.`type_id` = 1
1042                     {$selectWhere} GROUP BY p.member_id
1043                 ) AS `A`;";
1044 
1045         $result = $this->_db->fetchRow($sql);
1046         $cache->save($result, $cacheName);
1047 
1048         return (int)$result['count_active_members'];
1049     }
1050 
1051     /**
1052      * @param int $project_id
1053      *
1054      * @return bool
1055      */
1056     public function isProjectFeatured($project_id)
1057     {
1058         $sql_object =
1059             "SELECT `project_id` FROM `project` WHERE `project_id`= :project_id AND  `status` = 100 AND `type_id` = 1 AND `featured` = 1";
1060         $r = $this->getAdapter()->fetchRow($sql_object, array('project_id' => $project_id));
1061         if ($r) {
1062             return true;
1063         } else {
1064             return false;
1065         }
1066     }
1067 
1068 
1069     /**
1070      * @param bool $in_current_store
1071      *
1072      * @return int
1073      * @throws Zend_Exception
1074      */
1075     public function fetchTotalProjectsCount($in_current_store = false)
1076     {
1077         $sql = "SELECT count(1) AS `total_project_count` FROM `stat_projects`";
1078         if ($in_current_store) {
1079             $store_tags = Zend_Registry::isRegistered('config_store_tags') ? Zend_Registry::get('config_store_tags') : null;
1080             /*
1081             if ($store_tags) {
1082                 $sql .= ' JOIN (SELECT DISTINCT project_id FROM stat_project_tagids WHERE tag_id in (' . implode(',', $store_tags)
1083                     . ')) AS tags ON stat_projects.project_id = tags.project_id';
1084             }
1085              * 
1086              */
1087 
1088             $info = new Default_Model_Info();
1089             $activeCategories = $info->getActiveCategoriesForCurrentHost();
1090             $sql .= ' WHERE project_category_id IN (' . implode(',', $activeCategories) . ')';
1091             
1092             //Store Tag Filter
1093             if ($store_tags) {
1094                 $tagList = $store_tags;
1095                 //build where statement für projects
1096                 $sql .= " AND (";
1097 
1098                 if(!is_array($tagList)) {
1099                     $tagList = array($tagList);
1100                 }
1101 
1102                 foreach($tagList as $item) {
1103                     #and
1104                     $sql .= ' find_in_set('.$item.', tag_ids) AND ';
1105                 }
1106                 $sql .= ' 1=1)';;
1107             }
1108             
1109         }
1110         $result = $this->_db->fetchRow($sql);
1111 
1112         return (int)$result['total_project_count'];
1113     }
1114 
1115     /**
1116      * @param $member_id
1117      *
1118      * @throws Zend_Db_Statement_Exception
1119      * @throws Zend_Exception
1120      */
1121     public function setAllProjectsForMemberDeleted($member_id)
1122     {
1123         $sql =
1124             "SELECT `project_id` FROM `project` WHERE `member_id` = :memberId AND `type_id` = :typeId AND `status` > :project_status";
1125         $projectForDelete = $this->_db->fetchAll($sql, array(
1126             'memberId'       => $member_id,
1127             'typeId'         => self::PROJECT_TYPE_STANDARD,
1128             'project_status' => self::PROJECT_DELETED
1129         ));
1130         foreach ($projectForDelete as $item) {
1131             $this->setDeleted($member_id, $item['project_id']);
1132         }
1133 
1134         // set personal page deleted
1135         $sql = "SELECT project_id FROM project WHERE member_id = :memberId AND type_id = :typeId";
1136         $projectForDelete = $this->_db->fetchAll($sql, array(
1137             'memberId' => $member_id,
1138             'typeId'   => self::PROJECT_TYPE_PERSONAL
1139         ));
1140         foreach ($projectForDelete as $item) {
1141             $this->setDeleted($member_id, $item['project_id']);
1142         }
1143         /*
1144         $sql = "UPDATE project SET `status` = :statusCode, deleted_at = NOW() WHERE member_id = :memberId AND type_id = :typeId";
1145         $this->_db->query($sql, array(
1146             'statusCode' => self::PROJECT_DELETED,
1147             'memberId'   => $member_id,
1148             'typeId'     => self::PROJECT_TYPE_PERSONAL
1149         ))->execute();
1150         */
1151     }
1152 
1153     /**
1154      * @param int $member_id
1155      * @param int $id
1156      *
1157      * @throws Zend_Db_Statement_Exception
1158      * @throws Zend_Exception
1159      */
1160     public function setDeleted($member_id, $id)
1161     {
1162         $id = (int)$id;
1163         $updateValues = array(
1164             'status'     => self::PROJECT_DELETED,
1165             'deleted_at' => new Zend_Db_Expr('Now()')
1166         );
1167 
1168         $this->update($updateValues, 'status > 30 AND project_id=' . $id);
1169 
1170         $memberLog = new Default_Model_MemberDeactivationLog();
1171         $memberLog->logProjectAsDeleted($member_id, $id);
1172 
1173         $this->setDeletedForUpdates($member_id, $id);
1174         $this->setDeletedForComments($member_id, $id);
1175         $this->setDeletedInMaterializedView($id);
1176     }
1177 
1178     /**
1179      * @param     $member_id
1180      * @param int $id
1181      */
1182     protected function setDeletedForUpdates($member_id, $id)
1183     {
1184         $id = (int)$id;
1185         $updateValues = array(
1186             'status'     => self::PROJECT_DELETED,
1187             'deleted_at' => new Zend_Db_Expr('Now()')
1188         );
1189 
1190         $this->update($updateValues, 'status > 30 AND pid=' . $id);
1191     }
1192 
1193     /**
1194      * @param $id
1195      *
1196      * @throws Zend_Db_Statement_Exception
1197      */
1198     private function setDeletedInMaterializedView($id)
1199     {
1200         $sql = "UPDATE `stat_projects` SET `status` = :new_status WHERE `project_id` = :project_id";
1201 
1202         $result = $this->_db->query($sql, array('new_status' => self::PROJECT_DELETED, 'project_id' => $id))->execute();
1203     }
1204 
1205     /**
1206      * @param int $member_id
1207      *
1208      * @throws Zend_Exception
1209      */
1210     public function setAllProjectsForMemberActivated($member_id)
1211     {
1212         $sql = "SELECT `p`.`project_id` FROM `project` `p`
1213                 JOIN `member_deactivation_log` `l` ON `l`.`object_type_id` = 3 AND `l`.`object_id` = `p`.`project_id` AND `l`.`deactivation_id` = `p`.`member_id`
1214                 WHERE `p`.`member_id` = :memberId";
1215         $projectForDelete = $this->_db->fetchAll($sql, array(
1216             'memberId' => $member_id
1217         ));
1218         foreach ($projectForDelete as $item) {
1219             $this->setActive($member_id, $item['project_id']);
1220         }
1221     }
1222 
1223     /**
1224      * @param int $member_id
1225      * @param int $id
1226      *
1227      * @throws Zend_Exception
1228      */
1229     public function setActive($member_id, $id)
1230     {
1231         $updateValues = array(
1232             'status'     => self::PROJECT_ACTIVE,
1233             'deleted_at' => null
1234         );
1235 
1236         $this->update($updateValues, $this->_db->quoteInto('project_id=?', $id, 'INTEGER'));
1237 
1238         $memberLog = new Default_Model_MemberDeactivationLog();
1239         $memberLog->removeLogProjectAsDeleted($member_id, $id);
1240 
1241         $this->setActiveForUpdates($member_id, $id);
1242         $this->setActiveForComments($member_id, $id);
1243     }
1244 
1245     /**
1246      * @param int $id
1247      */
1248     protected function setActiveForUpdates($member_id, $id)
1249     {
1250         $updateValues = array(
1251             'status'     => self::PROJECT_ACTIVE,
1252             'deleted_at' => null
1253         );
1254 
1255         $this->update($updateValues, $this->_db->quoteInto('pid=?', $id, 'INTEGER'));
1256     }
1257 
1258     /**
1259      * @param int $member_id
1260      * @param int $project_id
1261      */
1262     private function setActiveForComments($member_id, $project_id)
1263     {
1264         $modelComments = new Default_Model_ProjectComments();
1265         $modelComments->setAllCommentsForProjectActivated($member_id, $project_id);
1266     }
1267 
1268     /**
1269      * @param array    $inputFilterParams
1270      * @param int|null $limit
1271      * @param int|null $offset
1272      *
1273      * @return array
1274      * @throws Zend_Cache_Exception
1275      * @throws Zend_Db_Select_Exception
1276      * @throws Zend_Exception
1277      */
1278     public function fetchProjectsByFilter($inputFilterParams, $limit = null, $offset = null)
1279     {
1280         $cacheName = __FUNCTION__ . '_' . md5(serialize($inputFilterParams) . (string)$limit . (string)$offset);
1281         /** @var Zend_Cache_Core $cache */
1282         $cache = Zend_Registry::get('cache');
1283 
1284         if (false === ($returnValue = $cache->load($cacheName))) {
1285             $statement = $this->generateStatement($inputFilterParams, $limit, $offset);
1286 
1287             if (APPLICATION_ENV == 'development') {
1288                 Zend_Registry::get('logger')->debug(__METHOD__ . ' - ' . $statement->__toString());
1289             }
1290 
1291             /** @var Zend_Db_Table_Rowset $fetchedElements */
1292             $fetchedElements = $this->fetchAll($statement);
1293             $statement->reset('limitcount')->reset('limitoffset');
1294             $statement->reset('columns')->columns(array('count' => new Zend_Db_Expr('count(*)')));
1295             $countElements = $this->fetchRow($statement);
1296             $returnValue = array('elements' => $fetchedElements, 'total_count' => $countElements->count);            
1297             $cache->save($returnValue, $cacheName, array(), 120);
1298         }
1299 
1300         return $returnValue;
1301     }
1302 
1303     /**
1304      * @param array    $inputFilterParams
1305      * @param int|null $limit
1306      * @param int|null $offset
1307      *
1308      * @return Zend_Db_Select
1309      * @throws Zend_Cache_Exception
1310      * @throws Zend_Db_Statement_Exception
1311      */
1312     protected function generateStatement($inputFilterParams, $limit = null, $offset = null)
1313     {
1314         $statement = $this->generateBaseStatement();
1315         $statement = $this->generateCategoryFilter($statement, $inputFilterParams);
1316         $statement = $this->generateOrderFilter($statement, $inputFilterParams);
1317         $statement = $this->generateTagFilter($statement, $inputFilterParams);
1318         $statement = $this->generateOriginalFilter($statement, $inputFilterParams);
1319         $statement = $this->generateReportedSpamFilter($statement);
1320 
1321         $statement->limit($limit, $offset);
1322 
1323         return $statement;
1324     }
1325 
1326     /**
1327      * @return Zend_Db_Select
1328      */
1329     protected function generateBaseStatement()
1330     {
1331         $statement = $this->select()->setIntegrityCheck(false);
1332         //$statement->from(array('project' => $this->_name), array(
1333         $statement->from(array('project' => 'stat_projects'), array(
1334             '*'
1335         ));
1336         $statement->where('project.status = ?', self::PROJECT_ACTIVE)->where('project.type_id=?', self::PROJECT_TYPE_STANDARD);
1337 
1338         return $statement;
1339     }
1340 
1341     /**
1342      * @param Zend_Db_Select $statement
1343      * @param array          $filterArrayValue
1344      *
1345      * @return Zend_Db_Select
1346      * @throws Zend_Cache_Exception
1347      * @throws Zend_Db_Statement_Exception
1348      */
1349     protected function generateCategoryFilter(Zend_Db_Select $statement, $filterArrayValue)
1350     {
1351         if (false == isset($filterArrayValue[self::FILTER_NAME_CATEGORY])) {
1352             return $statement;
1353         }
1354 
1355         $filter = $filterArrayValue[self::FILTER_NAME_CATEGORY];
1356 
1357         if (false === is_array($filter)) {
1358             $filter = array($filter);
1359         }
1360 
1361         // fetch child elements for each category
1362         $modelProjectCategories = new Default_Model_DbTable_ProjectCategory();
1363         $childElements = $modelProjectCategories->fetchChildIds($filter);
1364         $allCategories = array_unique(array_merge($filter, $childElements));
1365         $stringCategories = implode(',', $allCategories);
1366 
1367         $statement->where("(
1368             project.project_category_id IN ({$stringCategories})
1369             )");
1370 
1371         return $statement;
1372     }
1373 
1374     /**
1375      * @param Zend_Db_Select $statement
1376      * @param array          $filterArrayValue
1377      *
1378      * @return Zend_Db_Select
1379      */
1380     protected function generateOrderFilter(Zend_Db_Select $statement, $filterArrayValue)
1381     {
1382         if (!isset($filterArrayValue[self::FILTER_NAME_ORDER])) {
1383             $filterValue = '';
1384         } else {
1385             $filterValue = $filterArrayValue[self::FILTER_NAME_ORDER];
1386         }
1387         switch ($filterValue) {
1388             case 'latest':
1389                 $statement->order('project.major_updated_at DESC');
1390                 //$statement->order('project.changed_at DESC');
1391                 break;
1392 
1393             case 'top':
1394                 //$statement->order(array('amount_received DESC', 'count_plings DESC', 'latest_pling DESC', 'project.created_at DESC'));
1395                 //$statement->order(array(new Zend_Db_Expr('(round(((count_likes + 6) / ((count_likes + count_dislikes) + 12)),2) * 100) DESC'),'amount_received DESC', 'count_plings DESC', 'latest_pling DESC', 'project.created_at DESC'));
1396                 $statement->order(array(
1397                     new Zend_Db_Expr('(round(((count_likes + 6) / ((count_likes + count_dislikes) + 12)),2) * 100) DESC'),
1398                     'project.created_at DESC'
1399                 ));
1400 
1401                 break;
1402 
1403             case 'download':
1404                 $statement->order('project.count_downloads_hive DESC');
1405                 break;
1406             case 'downloadQuarter':
1407                 $statement->order('project.count_downloads_quarter DESC');
1408                 break;
1409 
1410             case 'hot':
1411                 //$statement->order(array('amount_received DESC', 'count_plings DESC', 'latest_pling DESC', 'project.created_at DESC'));
1412                 $statement->order(array(
1413                     new Zend_Db_Expr('(round(((count_likes + 6) / ((count_likes + count_dislikes) + 12)),2) * 100) DESC'),                    
1414                     'count_plings DESC',                    
1415                     'project.created_at DESC'
1416                 ));
1417                 $statement->where(' project.created_at >= (NOW()- INTERVAL 14 DAY)');
1418                 break;
1419 
1420             case 'alpha':
1421             default:
1422                 $statement->order('project.title');
1423         }
1424 
1425         return $statement;
1426     }
1427 
1428     /**
1429      * @param Zend_Db_Select $statement
1430      * @param array          $filterArrayValue
1431      *
1432      * @return Zend_Db_Select
1433      */
1434     protected function generateOriginalFilter(Zend_Db_Select $statement, $filterArrayValue)
1435     {
1436         if (false == isset($filterArrayValue[self::FILTER_NAME_ORIGINAL])) {
1437             return $statement;
1438         }
1439 
1440         $filter = $filterArrayValue[self::FILTER_NAME_ORIGINAL];
1441 
1442         if (is_array($filter)) {
1443             // todo maybe for other tags filter
1444         } else {
1445             $statement->where('find_in_set(?, tags)', $filter);
1446         }
1447 
1448         return $statement;
1449     }
1450 
1451     /**
1452      * @param Zend_Db_Select $statement
1453      *
1454      * @return Zend_Db_Select
1455      */
1456     protected function generateReportedSpamFilter(Zend_Db_Select $statement)
1457     {
1458         return $statement->where('(amount_reports is null)');
1459     }
1460 
1461     /**
1462      * @param int    $member_id
1463      * @param array  $values
1464      * @param string $username
1465      *
1466      * @return Zend_Db_Table_Row_Abstract
1467      * @throws Exception
1468      * @throws Zend_Db_Table_Exception
1469      */
1470     public function createCollection($member_id, $values, $username)
1471     {
1472         $values = (array)$values;
1473         if (empty($member_id)) {
1474             throw new Zend_Db_Table_Exception('member_id is not set');
1475         }
1476         if (empty($username)) {
1477             throw new Zend_Db_Table_Exception('username is not set');
1478         }
1479         // check important values for a new project
1480         $values['uuid'] = (!array_key_exists('uuid', $values)) ? Local_Tools_UUID::generateUUID() : $values['uuid'];
1481         $values['member_id'] = (!array_key_exists('member_id', $values)) ? $member_id : $values['member_id'];
1482         $values['status'] = (!array_key_exists('status', $values)) ? self::PROJECT_INACTIVE : $values['status'];
1483         $values['type_id'] = (!array_key_exists('type_id', $values)) ? self::PROJECT_TYPE_COLLECTION : $values['type_id'];
1484         $values['created_at'] = (!array_key_exists('created_at', $values)) ? new Zend_Db_Expr('NOW()') : $values['created_at'];
1485         $values['start_date'] = (!array_key_exists('start_date', $values)) ? new Zend_Db_Expr('NULL') : $values['start_date'];
1486         $values['creator_id'] = (!array_key_exists('creator_id', $values)) ? $member_id : $values['creator_id'];
1487 
1488         if ($username == 'pling editor') {
1489             $values['claimable'] = (!array_key_exists('claimable', $values)) ? self::PROJECT_CLAIMABLE : $values['claimable'];
1490         }
1491 
1492         $savedRow = $this->save($values);
1493 
1494         return $savedRow;
1495     }
1496     
1497     
1498     
1499 
1500     /**
1501      * @param int   $project_id
1502      * @param array $values
1503      *
1504      * @return Zend_Db_Table_Row_Abstract
1505      * @throws Exception
1506      * @throws Zend_Db_Table_Exception
1507      */
1508     public function updateCollection($project_id, $values)
1509     {
1510         $values = (array)$values;
1511         $projectData = $this->find($project_id)->current();
1512         if (empty($projectData)) {
1513             throw new Zend_Db_Table_Exception('project_id not found');
1514         }
1515 
1516         $projectData->setFromArray($values)->save();
1517 
1518         return $projectData;
1519     }
1520 
1521     /**
1522      * @param int $member_id
1523      *
1524      * @return array|mixed
1525      */
1526     public function fetchMainProject($member_id)
1527     {
1528         $sql = "SELECT * FROM {$this->_name} WHERE type_id = :type AND member_id = :member";
1529 
1530         //        $this->_db->getProfiler()->setEnabled(true);
1531         $result = $this->_db->fetchRow($sql, array('type' => self::PROJECT_TYPE_PERSONAL, 'member' => (int)$member_id));
1532         //        $dummy = $this->_db->getProfiler()->getLastQueryProfile()->getQuery();
1533         //        $this->_db->getProfiler()->setEnabled(true);
1534 
1535         if (count($result) > 0) {
1536             return $result;
1537         } else {
1538             return array();
1539         }
1540     }
1541 
1542     /**
1543      * @param $project_id
1544      *
1545      * @return Zend_Db_Table_Row_Abstract
1546      * @throws Zend_Db_Statement_Exception
1547      */
1548     public function fetchProductDataFromMV($project_id)
1549     {
1550         $sql = "SELECT * FROM `stat_projects` WHERE `project_id` = :project_id";
1551         $resultSet = $this->_db->query($sql, array('project_id' => $project_id))->fetch();
1552         if (false === $resultSet) {
1553             return $this->generateRowClass(array());
1554         }
1555 
1556         return $this->generateRowClass($resultSet);
1557     }
1558 
1559 
1560     /**
1561      * @return array
1562      */
1563     public function fetchGhnsExcludedProjects()
1564     {
1565         $sql = "
1566           SELECT `p`.`project_id`, `p`.`title`, `l`.`member_id` AS `exclude_member_id`, `l`.`time` AS `exclude_time`, `m`.`username` AS `exclude_member_name` FROM `project` `p`
1567                 JOIN `activity_log` `l` ON `l`.`project_id` = `p`.`project_id` AND `l`.`activity_type_id` = 314
1568                 INNER JOIN `member` `m` ON `m`.`member_id` = `l`.`member_id`
1569                 WHERE `p`.`ghns_excluded` = 1
1570 
1571         ";
1572 
1573         $list = $this->_db->fetchAll($sql);
1574 
1575         return $list;
1576     }
1577 
1578     public function getUserCreatingCategorys($member_id)
1579     {
1580         $sql = " 
1581                     select              
1582                        c.title as category1,
1583                        count(1) as cnt
1584                       from project p
1585                       join project_category c on p.project_category_id = c.project_category_id
1586                       where p.status = 100
1587                       and p.member_id =:member_id
1588                       and p.type_id = 1
1589                       group by c.title
1590                       order by cnt desc, c.title asc
1591                   ";
1592         $result = $this->_db->fetchAll($sql, array('member_id' => $member_id));
1593         return $result;       
1594     }
1595 
1596     /**
1597      * @return array
1598      */
1599     public function getUserActiveProjects($member_id, $limit = null, $offset = null)
1600     {
1601         // for member me page
1602         $sql = "
1603                         SELECT
1604                         `p`.`project_id`,
1605                         `p`.`title`,
1606                         `p`.`created_at`  AS `project_created_at`,
1607                         `p`.`changed_at` AS `project_changed_at`,
1608                         `p`.`count_likes`,
1609                         `p`.`count_dislikes`,
1610                         laplace_score(`p`.`count_likes`, `p`.`count_dislikes`) AS `laplace_score`,
1611                         `p`.`member_id`,
1612                         `cat`.`title` AS `catTitle`,
1613                         `p`.`project_category_id`,    
1614                         `p`.`image_small`,
1615                         (SELECT count(1) FROM `project_plings` `l` WHERE `p`.`project_id` = `l`.`project_id` AND `l`.`is_deleted` = 0 AND `l`.`is_active` = 1 ) `countplings`,
1616                         c.cnt cntCategory
1617                         FROM `project` `p`
1618                         join project_category cat on p.project_category_id = cat.project_category_id
1619                         left join stat_cnt_projects_catid_memberid c on p.project_category_id = c.project_category_id and p.member_id = c.member_id
1620                         WHERE `p`.`status` =100
1621                         and `p`.`type_id` = 1
1622                         AND `p`.`member_id` = :member_id       
1623                         ORDER BY cntCategory desc,catTitle asc, `p`.`changed_at` DESC
1624                       
1625         ";
1626 
1627         if (isset($limit)) {
1628             $sql = $sql . ' limit ' . $limit;
1629         }
1630 
1631         if (isset($offset)) {
1632             $sql = $sql . ' offset ' . $offset;
1633         }
1634 
1635         $result = $this->_db->fetchAll($sql, array('member_id' => $member_id));
1636         if ($result) {
1637             return $this->generateRowClass($result);
1638         } else {
1639             return null;
1640         }
1641     }
1642 
1643     // /**
1644     //  * @return array
1645     //  */
1646     // public function getUserActiveProjects($member_id, $limit = null, $offset = null)
1647     // {
1648     //     // for member me page
1649     //     $sql = "
1650     //                     SELECT
1651     //                         SUBSTRING_INDEX(SUBSTRING_INDEX(ancestor_path, '|', 2),'|',-1) as cat1,
1652     //                         SUBSTRING_INDEX(SUBSTRING_INDEX(ancestor_path, '|', 3),'|',-1) as cat2,
1653     //                         SUBSTRING_INDEX(SUBSTRING_INDEX(ancestor_path, '|', 4),'|',-1) as cat3,
1654     //                          SUBSTRING_INDEX(SUBSTRING_INDEX(ancestor_path, '|', 5),'|',-1) as cat4,
1655     //                         SUBSTRING_INDEX(SUBSTRING_INDEX(ancestor_id_path, ',', 2),',',-1) as catid1,
1656     //                         SUBSTRING_INDEX(SUBSTRING_INDEX(ancestor_id_path, ',', 3),',',-1) as catid2,
1657     //                         SUBSTRING_INDEX(SUBSTRING_INDEX(ancestor_id_path, ',', 4),',',-1) as catid3,
1658     //                          SUBSTRING_INDEX(SUBSTRING_INDEX(ancestor_id_path, ',', 5),',',-1) as catid4,
1659     //                     `p`.`project_id`,
1660     //                     `p`.`title`,
1661     //                     `p`.`created_at`  AS `project_created_at`,
1662     //                     `p`.`changed_at` AS `project_changed_at`,
1663     //                     `p`.`count_likes`,
1664     //                     `p`.`count_dislikes`,
1665     //                     laplace_score(`p`.`count_likes`, `p`.`count_dislikes`) AS `laplace_score`,
1666     //                     `p`.`member_id`,
1667     //                     `cat`.`title` AS `catTitle`,
1668     //                     `p`.`project_category_id`,    
1669     //                     `p`.`image_small`,
1670     //                     (SELECT count(1) FROM `project_plings` `l` WHERE `p`.`project_id` = `l`.`project_id` AND `l`.`is_deleted` = 0 AND `l`.`is_active` = 1 ) `countplings`,
1671     //                     (select count(1) from project pp where pp.member_id = p.member_id and pp.status = 100  and  pp.project_category_id = p.project_category_id) cntCategory
1672     //                     FROM `project` `p`
1673     //                     join project_category cat on p.project_category_id = cat.project_category_id
1674     //                     join stat_cat_tree c on p.project_category_id = c.project_category_id
1675     //                     WHERE `p`.`status` =100
1676     //                     AND `p`.`member_id` = :member_id       
1677     //                     ORDER BY cntCategory desc, `p`.`changed_at` DESC
1678                       
1679     //     ";
1680 
1681     //     if (isset($limit)) {
1682     //         $sql = $sql . ' limit ' . $limit;
1683     //     }
1684 
1685     //     if (isset($offset)) {
1686     //         $sql = $sql . ' offset ' . $offset;
1687     //     }
1688 
1689     //     $result = $this->_db->fetchAll($sql, array('member_id' => $member_id));
1690     //     if ($result) {
1691     //         return $this->generateRowClass($result);
1692     //     } else {
1693     //         return null;
1694     //     }
1695     // }
1696 
1697     
1698 
1699     /**
1700      * @param int      $member_id
1701      * @param int|null $limit
1702      * @param int|null $offset
1703      *
1704      * @return null|Zend_Db_Table_Row_Abstract
1705      */
1706     public function fetchAllFeaturedProjectsForMember($member_id, $limit = null, $offset = null)
1707     {
1708         // for member me page
1709         $sql = "
1710                           SELECT
1711                           `p`.`project_id`,
1712                           `p`.`title`,
1713                           `p`.`created_at`  AS `project_created_at`,
1714                           `p`.`changed_at` AS `project_changed_at`,
1715                           `p`.`count_likes`,
1716                           `p`.`count_dislikes`,
1717                           `p`.`laplace_score`,
1718                           `p`.`member_id`,
1719                           `p`.`cat_title` AS `catTitle`,
1720                           `p`.`image_small`,
1721                           (SELECT count(1) FROM `project_plings` `l` WHERE `p`.`project_id` = `l`.`project_id` AND `l`.`is_deleted` = 0 AND `l`.`is_active` = 1 ) `countplings`
1722                           FROM `stat_projects` `p`
1723                           WHERE `p`.`status` =100
1724                           AND `featured` = 1
1725                           AND `p`.`member_id` = :member_id        
1726                           ORDER BY `p`.`changed_at` DESC
1727           ";
1728 
1729         if (isset($limit)) {
1730             $sql = $sql . ' limit ' . $limit;
1731         }
1732 
1733         if (isset($offset)) {
1734             $sql = $sql . ' offset ' . $offset;
1735         }
1736 
1737         $result = $this->_db->fetchAll($sql, array('member_id' => $member_id));
1738         if ($result) {
1739             return $this->generateRowClass($result);
1740         } else {
1741             return null;
1742         }
1743     }
1744 
1745     /**
1746      * @param string   $orderby
1747      * @param int|null $limit
1748      * @param int|null $offset
1749      *
1750      * @return array
1751      */
1752     public function fetchDuplicatedSourceProjects($orderby = 'source_url asc', $limit = null, $offset = null)
1753     {
1754         $sql = "
1755             SELECT 
1756             `source_url`
1757             ,count(1) AS `cnt`,
1758             GROUP_CONCAT(`p`.`project_id` ORDER BY `p`.`created_at`) `pids`
1759             FROM `stat_projects_source_url` `p` 
1760             GROUP BY `source_url`
1761             HAVING count(1)>1         
1762        ";
1763         if (isset($orderby)) {
1764             $sql = $sql . '  order by ' . $orderby;
1765         }
1766 
1767         if (isset($limit)) {
1768             $sql .= ' limit ' . (int)$limit;
1769         }
1770 
1771         if (isset($offset)) {
1772             $sql .= ' offset ' . (int)$offset;
1773         }
1774         $result = $this->_db->fetchAll($sql);
1775 
1776         return $result;
1777     }
1778 
1779     /**
1780      * @return mixed
1781      */
1782     public function getTotalCountDuplicates()
1783     {
1784 
1785         $sql = "
1786           SELECT count(1) AS `cnt` FROM
1787           (
1788                       SELECT 
1789                        `source_url`
1790                        ,count(1) AS `cnt`,
1791                        GROUP_CONCAT(`p`.`project_id` ORDER BY `p`.`created_at`) `pids`
1792                        FROM `stat_projects_source_url` `p` 
1793                        GROUP BY `p`.`source_url`
1794                        HAVING count(1)>1 
1795           ) `a`  
1796       ";
1797         $result = $this->_db->fetchAll($sql);
1798 
1799         return $result[0]['cnt'];;
1800     }
1801 
1802     /**
1803      * @param string $source_url
1804      *
1805      * @return mixed
1806      */
1807     public function getCountSourceUrl($source_url)
1808     {
1809         $last = substr($source_url, -1);
1810         if ($last == '/') {
1811             $source_url = substr($source_url, 0, -1);
1812         }
1813         $sql = "
1814             SELECT count(1) AS `cnt` FROM 
1815             `stat_projects_source_url` `p`  
1816             WHERE `p`.`source_url`= :source_url        
1817       ";
1818         $result = $this->_db->fetchAll($sql, array('source_url' => $source_url));
1819 
1820         return $result[0]['cnt'];
1821     }
1822 
1823     /**
1824      * @param int $member_id
1825      *
1826      * @return mixed
1827      */
1828     public function getCountProjectsDuplicateSourceurl($member_id)
1829     {
1830 
1831         $sql = "
1832            SELECT count(1) AS `cnt`
1833            FROM
1834            (
1835               SELECT DISTINCT `p`.`source_url`
1836               ,(SELECT count(1) FROM `stat_projects_source_url` `pp` WHERE `pp`.`source_url`=`p`.`source_url`) `cnt` 
1837               FROM `stat_projects_source_url` `p` 
1838               WHERE `p`.`member_id` = :member_id 
1839            ) `t` WHERE `t`.`cnt`>1
1840       ";
1841         $result = $this->_db->fetchAll($sql, array('member_id' => $member_id));
1842 
1843         return $result[0]['cnt'];
1844     }
1845 
1846     /**
1847      * @param $ids
1848      *
1849      * @return Zend_Db_Table_Row_Abstract
1850      * @throws Zend_Db_Statement_Exception
1851      */
1852     public function fetchProjects($ids)
1853     {
1854         $sql = "SELECT * FROM stat_projects WHERE project_id in (" . $ids . ")";
1855         $resultSet = $this->_db->fetchAll($sql);
1856 
1857         return $this->generateRowSet($resultSet);
1858     }
1859 
1860     /**
1861      * @param $project_id
1862      * @return true/false
1863      * @throws Zend_Db_Statement_Exception
1864      */
1865     public function validateDeleteProjectFromSpam($project_id)
1866     {
1867       // A product older than 6 months, with more than 5 comments or with at least 1 pling can not be deleted.
1868       $sql ='select count_comments
1869             ,created_at
1870             , (created_at+ INTERVAL 6 MONTH < NOW()) is_old
1871             ,(select count(1) from project_plings f where f.project_id = p.project_id and f.is_deleted = 0) plings
1872             FROM project p where project_id =:project_id';
1873       $result = $this->_db->fetchRow($sql, array(
1874                             'project_id'     => $project_id,          
1875             ));
1876 
1877       if($result['count_comments'] >5 || $result['is_old'] ==1 || $result['plings']>0)
1878       {
1879         return false;
1880       }      
1881       return true;
1882     }
1883 
1884 }