$weight) { $sectionWeights[$section] = $weight / (float) $allWeights; } // // determine the date boundaries // if ($lookback < 1) { throw new LogicException('lookback must be greater or equal to 1'); } $dateCopy = new DateTime(); $dateCopy->setTimestamp($date->getTimestamp()); $dateBoundaries = array( $dateCopy->format('Y-m-d 23:59:59'), $dateCopy->sub(new DateInterval('P'.$lookback.'D'))->format('Y-m-d 00:00:00') ); // // now recalculate the values for all projects // $projects = Pluf::factory('IDF_Project')->getList(); foreach ($projects as $project) { self::recalculateTaxonomy($date, $project, $dateBoundaries, $sectionWeights); } } private static function recalculateTaxonomy(DateTime $date, IDF_Project $project, array $dateBoundaries, array $sectionWeights) { $conf = new IDF_Conf(); $conf->setProject($project); $sectionClasses = array( 'source' => array('IDF_Commit'), 'issues' => array('IDF_Issue'), 'wiki' => array('IDF_Wiki_Page', 'IDF_Wiki_Resource'), 'review' => array('IDF_Review'), 'downloads' => array('IDF_Upload') ); $value = 0; foreach ($sectionWeights as $section => $weight) { // skip closed / non-existant sections if ($conf->getVal($section.'_access_rights') === 'none') continue; if (!array_key_exists($section, $sectionClasses)) continue; $sectionValue = self::calculateActivityValue( $dateBoundaries, $sectionClasses[$section], $project->id); $value = ((1 - $weight) * $value) + ($weight * $sectionValue); } echo "project {$project->name} has an activity value of $value\n"; $sql = new Pluf_SQL('project=%s AND date=%s', array($project->id, $date->format('Y-m-d'))); $activity = Pluf::factory('IDF_ProjectActivity')->getOne(array('filter' => $sql->gen())); if ($activity == null) { $activity = new IDF_ProjectActivity(); $activity->project = $project; $activity->date = $date->format('Y-m-d'); $activity->value = $value; $activity->create(); } else { $activity->value = $value; $activity->update(); } } private static function calculateActivityValue(array $dateBoundaries, array $classes, $projectId) { $allCount = self::countActivityFor($dateBoundaries, $classes); if ($allCount == 0) return 0; $prjCount = self::countActivityFor($dateBoundaries, $classes, $projectId); return $prjCount / (float) $allCount; } private static function countActivityFor(array $dateBoundaries, array $classes, $projectId = null) { static $cache = array(); $argIdent = md5(serialize(func_get_args())); if (array_key_exists($argIdent, $cache)) { return $cache[$argIdent]; } $cache[$argIdent] = 0; list($higher, $lower) = $dateBoundaries; $db = Pluf::db(); $classes_esc = array(); foreach ($classes as $class) { $classes_esc[] = $db->esc($class); } $sql = new Pluf_SQL('model_class IN ('.implode(',', $classes_esc).') '. 'AND creation_dtime >= %s AND creation_dtime <= %s', array($lower, $higher)); if ($projectId !== null) { $sql->SAnd(new Pluf_SQL('project=%s', array($projectId))); } $cache[$argIdent] = Pluf::factory('IDF_Timeline')->getCount(array('filter' => $sql->gen())); return $cache[$argIdent]; } }