File indexing completed on 2025-05-04 05:29:33
0001 <?php 0002 /** 0003 * ocs-webserver 0004 * 0005 * Copyright 2016 by pling GmbH. 0006 * 0007 * This file is part of ocs-webserver. 0008 * 0009 * This program is free software: you can redistribute it and/or modify 0010 * it under the terms of the GNU Affero General Public License as 0011 * published by the Free Software Foundation, either version 3 of the 0012 * License, or (at your option) any later version. 0013 * 0014 * This program is distributed in the hope that it will be useful, 0015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0017 * GNU Affero General Public License for more details. 0018 * 0019 * You should have received a copy of the GNU Affero General Public License 0020 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0021 **/ 0022 class Statistics_Model_GoalStatistics 0023 { 0024 0025 const MYSQL_DATE_FORMAT = "Y-m-d H:i:s"; 0026 const DEFAULT_RANKING_PLUGIN = 'Statistics_Ranking_WeightedAverageRanking'; 0027 0028 /** @var Statistics_Ranking_RankingInterface */ 0029 protected $_rankingPlugin; 0030 0031 0032 /** 0033 * @param Statistics_Ranking_RankingInterface $rankingPlugin 0034 */ 0035 function __construct(Statistics_Ranking_RankingInterface $rankingPlugin = null) 0036 { 0037 if (is_null($rankingPlugin)) { 0038 $default = self::DEFAULT_RANKING_PLUGIN; 0039 $this->_rankingPlugin = new $default; 0040 return $this; 0041 } 0042 $this->_rankingPlugin = $rankingPlugin; 0043 } 0044 0045 public function setupDatabase() 0046 { 0047 exit(0); 0048 0049 $sql = " 0050 CREATE TABLE `stat_daily` ( 0051 `daily_id` INT(11) NOT NULL AUTO_INCREMENT COMMENT 'ID', 0052 `project_id` INT(11) NOT NULL COMMENT 'ID of the project', 0053 `project_category_id` INT(11) DEFAULT '0' COMMENT 'Category', 0054 `project_type` INT(11) NOT NULL COMMENT 'type of the project', 0055 `count_views` INT(11) DEFAULT '0', 0056 `count_plings` INT(11) DEFAULT '0', 0057 `count_updates` INT(11) DEFAULT NULL, 0058 `count_comments` INT(11) DEFAULT NULL, 0059 `count_followers` INT(11) DEFAULT NULL, 0060 `count_supporters` INT(11) DEFAULT NULL, 0061 `created_at` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP, 0062 `year` INT(11) DEFAULT NULL COMMENT 'z.B.: 1988', 0063 `month` INT(11) DEFAULT NULL COMMENT 'z.b: 1-12', 0064 `day` INT(11) DEFAULT NULL COMMENT 'z.B. 1-31', 0065 `year_week` INT(11) DEFAULT NULL COMMENT 'z.b.: 201232', 0066 PRIMARY KEY (`daily_id`) 0067 ) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COMMENT='Store daily statistic'; 0068 0069 CREATE TABLE `app_config` ( 0070 `config_id` INT(11) NOT NULL AUTO_INCREMENT, 0071 `group` VARCHAR(20) NOT NULL, 0072 `name` VARCHAR(20) NOT NULL, 0073 `value` VARCHAR(20) NOT NULL, 0074 PRIMARY KEY (`config_id`), 0075 KEY `index_group` (`group`) 0076 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Store config for statistic'; 0077 "; 0078 0079 $sql_alter = " 0080 ALTER TABLE pling.stat_daily 0081 ADD ranking_value INT AFTER year_week; 0082 ALTER TABLE pling.stat_daily 0083 ADD count_money FLOAT AFTER count_supporters; 0084 ALTER TABLE pling.stat_daily 0085 CHANGE ranking_value ranking_value FLOAT; 0086 ALTER TABLE pling.stat_daily 0087 CHANGE project_type project_type_id INT(11) NOT NULL COMMENT 'type of the project'; 0088 "; 0089 0090 $database = Zend_Db_Table::getDefaultAdapter(); 0091 $database->query($sql)->execute(); 0092 $database->query($sql_alter)->execute(); 0093 } 0094 0095 public function dailyPageviews() 0096 { 0097 $sql = ' 0098 insert into stat_daily_pageviews 0099 select project_id 0100 ,count(project_id) cnt 0101 ,(select p.project_category_id from project p where v.project_id = p.project_id) project_category_id 0102 ,CURDATE() created_at 0103 from stat_page_views v where v.created_at > date_sub(CURDATE(), interval 6 month) 0104 group by project_id 0105 '; 0106 $database = Zend_Db_Table::getDefaultAdapter(); 0107 $database->query($sql)->execute(); 0108 } 0109 0110 public function migrateStatistics() 0111 { 0112 $database = Zend_Db_Table::getDefaultAdapter(); 0113 0114 $sqlTruncate = "TRUNCATE stat_daily"; 0115 $result = $database->query($sqlTruncate); 0116 0117 0118 $sql = " 0119 SELECT DATE_FORMAT(stat_page_views.created_at,\"%d.%m.%Y\") AS stat_date 0120 FROM pling.stat_page_views stat_page_views 0121 GROUP BY stat_date 0122 ORDER BY created_at ASC; 0123 "; 0124 0125 $queryObject = $database->query($sql); 0126 $resultSet = $queryObject->fetchAll(); 0127 0128 $addedRows = 0; 0129 $resultMessage = new stdClass(); 0130 0131 if (count($resultSet) > 0) { 0132 foreach ($resultSet as $element) { 0133 $resultMessage = $this->generateDailyStatistics($element['stat_date']); 0134 if ($resultMessage->result === false) { 0135 break; 0136 } 0137 $addedRows += $resultMessage->AffectedRows; 0138 } 0139 0140 } 0141 0142 $resultMessage->AffectedRows = $addedRows; 0143 $resultMessage->Environment = APPLICATION_ENV; 0144 0145 return $resultMessage; 0146 } 0147 0148 /** 0149 * @param string|null $forDate 0150 * @return stdClass 0151 */ 0152 public function generateDailyStatistics($forDate = null) 0153 { 0154 $database = Zend_Db_Table::getDefaultAdapter(); 0155 0156 $dateCreatedAt = new DateTime(); 0157 $mysqlCreatedAt = $dateCreatedAt->format(self::MYSQL_DATE_FORMAT); 0158 0159 if (is_null($forDate)) { 0160 $generateForDateObject = new DateTime(); 0161 } else { 0162 $generateForDateObject = new DateTime($forDate); 0163 } 0164 0165 $generateForDateObject->setTime(0, 0, 0); 0166 $mysqlStartDate = $generateForDateObject->format(self::MYSQL_DATE_FORMAT); 0167 0168 $generateForDateObject->setTime(23, 59, 59); 0169 $mysqlEndDate = $generateForDateObject->format(self::MYSQL_DATE_FORMAT); 0170 0171 $sql = " 0172 select 0173 prj.project_id, 0174 prj.type_id as project_type_id, 0175 prj.project_category_id, 0176 (select count(1) from stat_page_views pv where pv.project_id = prj.project_id and pv.created_at between '{$mysqlStartDate}' and '{$mysqlEndDate}' group by pv.project_id) AS count_views, 0177 (select count(1) from plings p where p.project_id = prj.project_id and p.pling_time between '{$mysqlStartDate}' and '{$mysqlEndDate}' AND p.status_id in (2,3,4) group by p.project_id) AS count_plings, 0178 (select count(1) from project pu where pu.pid = prj.project_id and (pu.created_at between '{$mysqlStartDate}' and '{$mysqlEndDate}') and pu.type_id = 2 group by pu.pid) AS count_updates, 0179 (select count(1) from project_follower pf where pf.project_id = prj.project_id) AS count_followers, 0180 (SELECT count(1) FROM plings WHERE status_id >= 2 AND create_time BETWEEN '{$mysqlStartDate}' AND '{$mysqlEndDate}' AND project_id = prj.project_id AND comment is not null GROUP BY project_id) AS count_comments, 0181 (SELECT count(member_id) FROM (SELECT member_id, project_id FROM plings WHERE status_id >= 2 AND create_time BETWEEN '{$mysqlStartDate}' AND '{$mysqlEndDate}' GROUP BY member_id, project_id) AS tempCountProjectSupporter WHERE project_id = prj.project_id) AS count_supporters, 0182 (SELECT sum(amount) FROM plings WHERE status_id >= 2 AND create_time BETWEEN '{$mysqlStartDate}' AND '{$mysqlEndDate}' AND project_id = prj.project_id GROUP BY project_id) AS count_money, 0183 '" . $mysqlCreatedAt . "' AS created_at, 0184 DATE_FORMAT('{$mysqlStartDate}', '%Y') AS year, 0185 DATE_FORMAT('{$mysqlStartDate}', '%m') AS month, 0186 DATE_FORMAT('{$mysqlStartDate}', '%d') AS day, 0187 YEARWEEK('{$mysqlStartDate}',1) AS year_week 0188 from 0189 project as prj 0190 where 0191 prj.status = " . Default_Model_DbTable_Project::PROJECT_ACTIVE . " 0192 and prj.type_id = " . Default_Model_DbTable_Project::PROJECT_TYPE_STANDARD . " 0193 group by prj.project_id; 0194 "; 0195 0196 $statement = $database->query($sql); 0197 0198 $statTable = new Statistics_Model_DbTable_StatDaily(); 0199 0200 while ($row = $statement->fetch(Zend_Db::FETCH_ASSOC, Zend_Db::FETCH_ORI_NEXT)) { 0201 $row['ranking_value'] = $this->_rankingPlugin->calculateRankingValue($row); 0202 $statTable->save($row); 0203 } 0204 0205 $resultMessage = new stdClass(); 0206 $resultMessage->result = $statement->errorCode() == '00000' ? true : false; 0207 $resultMessage->errorMessage = implode(' ', $statement->errorInfo()); 0208 $resultMessage->errorCode = $statement->errorCode(); 0209 $resultMessage->AffectedRows = $statement->rowCount(); 0210 0211 return $resultMessage; 0212 0213 } 0214 0215 /** 0216 * @param string $identifier 0217 * @param int $year 0218 * @param int $month 0219 * @param int $day 0220 * @return array 0221 */ 0222 public function getDailyStatistics($identifier, $year, $month, $day) 0223 { 0224 $sql = " 0225 SELECT sd.count_views AS views, sd.count_plings AS plings, sd.count_updates AS updates, sd.count_comments AS comments, sd.count_followers AS followers, sd.count_supporters AS supporters 0226 FROM stat_daily AS sd 0227 WHERE 0228 sd.project_id = ? 0229 AND sd.year = ? 0230 AND sd.month = ? 0231 AND sd.day = ?; 0232 "; 0233 $database = Zend_Db_Table::getDefaultAdapter(); 0234 $sql = $database->quoteInto($sql, $identifier, 'INTEGER', 1); 0235 $sql = $database->quoteInto($sql, $year, 'INTEGER', 1); 0236 $sql = $database->quoteInto($sql, $month, 'INTEGER', 1); 0237 $sql = $database->quoteInto($sql, $day, 'INTEGER', 1); 0238 0239 $resultSet = $database->query($sql)->fetchAll(); 0240 0241 return $resultSet; 0242 } 0243 0244 /** 0245 * @param string $identifier 0246 * @param int $year 0247 * @param int $month 0248 * @return array 0249 */ 0250 public function getMonthlyStatistics($identifier, $year, $month) 0251 { 0252 $sql = " 0253 SELECT sd.year_week, sum(sd.count_views) AS views, sum(sd.count_plings) AS plings, sum(sd.count_updates) AS updates, sum(sd.count_comments) AS comments, avg(sd.count_followers) AS followers, avg(sd.count_supporters) AS supporters 0254 FROM stat_daily AS sd 0255 WHERE 0256 sd.project_id = ? 0257 AND sd.year = ? 0258 AND sd.month = ? 0259 GROUP BY sd.year_week 0260 ORDER BY sd.day ASC; 0261 "; 0262 $database = Zend_Db_Table::getDefaultAdapter(); 0263 $sql = $database->quoteInto($sql, $identifier, 'INTEGER', 1); 0264 $sql = $database->quoteInto($sql, $year, 'INTEGER', 1); 0265 $sql = $database->quoteInto($sql, $month, 'INTEGER', 1); 0266 0267 $resultSet = $database->query($sql)->fetchAll(); 0268 0269 return $resultSet; 0270 0271 } 0272 0273 /** 0274 * @param string $identifier 0275 * @param int $yearWeek 0276 * @return array 0277 */ 0278 public function getWeeklyStatistics($identifier, $yearWeek) 0279 { 0280 $sql = " 0281 SELECT sd.day, sd.count_views AS views, sd.count_plings AS plings, sd.count_updates AS updates, sd.count_comments AS comments, sd.count_followers AS followers, sd.count_supporters AS supporters 0282 FROM stat_daily AS sd 0283 WHERE 0284 sd.project_id = ? 0285 AND sd.year_week = ? 0286 ORDER BY sd.day ASC; 0287 "; 0288 $database = Zend_Db_Table::getDefaultAdapter(); 0289 $sql = $database->quoteInto($sql, $identifier, 'INTEGER', 1); 0290 $sql = $database->quoteInto($sql, $yearWeek, 'INTEGER', 1); 0291 0292 $resultSet = $database->query($sql)->fetchAll(); 0293 0294 return $resultSet; 0295 0296 } 0297 0298 /** 0299 * @param DateTime $forDate 0300 * @throws Exception 0301 */ 0302 protected function generateRanking(DateTime $forDate) 0303 { 0304 throw new Exception('this code is outdated'); 0305 0306 $statisticsTable = new Statistics_Model_DbTable_StatDaily(); 0307 0308 $statement = $statisticsTable->select(); 0309 $statement->setIntegrityCheck(false)->where('year = ?', $forDate->format('Y')) 0310 ->where('month = ?', $forDate->format('m')) 0311 ->where('day = ?', $forDate->format('d')) 0312 ->forUpdate(true); 0313 0314 $rowSet = $statisticsTable->fetchAll($statement); 0315 0316 foreach ($rowSet as $row) { 0317 $row->ranking_value = $this->_rankingPlugin->calculateRankingValue($row->toArray()); 0318 $row->save(); 0319 } 0320 0321 } 0322 0323 }