/** * Calculate vertical ratio for activity * Use this method if trackdata is not available * @param \Runalyze\Model\Activity\Entity $activity * @return int [%o] */ public static function forActivity(Activity\Entity $activity) { if ($activity->verticalOscillation() > 0 && $activity->strideLength() > 0) { return round(100 * $activity->verticalOscillation() / $activity->strideLength()); } return 0; }
/** * Tasks to run after update */ protected function afterUpdate() { if (null !== $this->NewActivity) { $this->updateEquipment(array_diff($this->OtherIDsNew, $this->OtherIDsOld), $this->NewActivity->distance(), $this->NewActivity->duration()); } if (null !== $this->NewActivity && null !== $this->OldActivity) { $this->updateEquipment(array_intersect($this->OtherIDsNew, $this->OtherIDsOld), $this->NewActivity->distance() - $this->OldActivity->distance(), $this->NewActivity->duration() - $this->OldActivity->duration()); } }
/** * @param \Runalyze\Model\Activity\Entity $activity * @param \Runalyze\Model\Route\Entity $route * @param int $offset * @return \Runalyze\Calculation\NightDetector $this-reference */ public function setFromEntities(Activity\Entity $activity, Route\Entity $route, $offset = 0) { if ($route->hasGeohashes() && $route->get(Route\Entity::STARTPOINT) != '') { $timestamp = $activity->timestamp() + 0.5 * $activity->duration(); $coordinate = (new Geohash())->decode($route->get(Route\Entity::STARTPOINT))->getCoordinate(); $this->setFrom($timestamp, $coordinate, $offset); } else { $this->Value = null; } return $this; }
/** * Construct context * @var int $activityID * @var int $accountID */ public function __construct($activityID, $accountID) { $Factory = new Factory((int) $accountID); $this->Activity = $Factory->activity((int) $activityID); $this->Trackdata = $Factory->trackdata((int) $activityID); $this->Swimdata = $Factory->swimdata((int) $activityID); $this->Route = $this->Activity->get(Activity\Entity::ROUTEID) ? $Factory->route($this->Activity->get(Activity\Entity::ROUTEID)) : null; $this->HRV = $Factory->hrv((int) $activityID); $this->Sport = $Factory->sport($this->Activity->sportid()); $this->Swimdata->fillDistanceArray($this->Trackdata); $this->Swimdata->fillSwolfArray($this->Trackdata); $this->Dataview = new Dataview($this->Activity); }
/** * Construct updater * @param \PDO $connection * @param int $accountID * @param \Runalyze\Model\Activity\Entity $activity * @param \Runalyze\Model\Factory $factory */ public function __construct(\PDO $connection, $accountID, Entity $activity, Model\Factory $factory) { $this->PDO = $connection; $this->AccountID = $accountID; $this->Activity = $activity; $this->OldActivity = clone $activity; $this->Trackdata = $factory->trackdata($activity->id()); $this->OldTrackdata = clone $this->Trackdata; $this->Route = $factory->route($activity->get(Entity::ROUTEID)); $this->OldRoute = clone $this->Route; // TODO: What's with STRIDE_LENGTH and VERTICAL_RATIO? // - so far, there are updateStrideLength() and updateVerticalRatio() in Activity\Updater $this->ActivityKeysForTrackdataKeys = [Model\Trackdata\Entity::HEARTRATE => Model\Activity\Entity::HR_AVG, Model\Trackdata\Entity::CADENCE => Model\Activity\Entity::CADENCE, Model\Trackdata\Entity::VERTICAL_OSCILLATION => Model\Activity\Entity::VERTICAL_OSCILLATION, Model\Trackdata\Entity::GROUNDCONTACT => Model\Activity\Entity::GROUNDCONTACT, Model\Trackdata\Entity::POWER => Model\Activity\Entity::POWER, Model\Trackdata\Entity::TEMPERATURE => Model\Activity\Entity::TEMPERATURE]; }
/** * Update basic endurance */ protected function updateBasicEndurance() { $timestampLimit = time() - 182 * DAY_IN_S; if (($this->hasChanged(Entity::DISTANCE) || $this->hasChanged(Entity::TIMESTAMP) || $this->hasChanged(Entity::SPORTID)) && ($this->NewObject->sportid() == Configuration::General()->runningSport() && $this->NewObject->timestamp() > $timestampLimit || $this->knowsOldObject() && $this->OldObject->sportid() == Configuration::General()->runningSport() && $this->OldObject->timestamp() > $timestampLimit)) { BasicEndurance::recalculateValue(); } }
/** * Update basic endurance */ protected function updateBasicEndurance() { $timestampLimit = time() - 182 * DAY_IN_S; if ($this->Object->sportid() == Configuration::General()->runningSport() && $this->Object->timestamp() > $timestampLimit) { BasicEndurance::recalculateValue(); } }
/** * @return string */ public function mapIcon() { if ($this->Activity->get(Activity\Entity::ROUTEID) > 0) { $Icon = new Icon(Icon::MAP_ARROW); $Icon->setTooltip(__('Route data available')); return $Icon->code(); } return ''; }
/** * VDOT icon * @return string */ public function vdotIcon() { $value = $this->usedVdot() * Configuration::Data()->vdotFactor(); if ($value > 0) { $Icon = new VdotIcon($value); if (!$this->Activity->usesVDOT()) { $Icon->setTransparent(); } return $Icon->code(); } return ''; }
/** * Calculate for activity object * * This method does not lookup trackdata of the activity! * If you want an exact intensity value, use `calculateByTrackdata(...)` * * @param \Runalyze\Model\Activity\Entity $activity * @return int */ public function calculateByActivity(Activity\Entity $activity) { if ($activity->hrAvg() > 0) { return $this->calculateByHeartrateAverage($activity->hrAvg(), $activity->duration()); } return $this->calculateByPace($activity->distance(), $activity->duration()); }
/** * Calculate stride length for activity * Use this method if trackdata is not available * @param \Runalyze\Model\Activity\Entity $activity * @return int [cm] */ public static function forActivity(Activity\Entity $activity) { if ($activity->cadence() > 0 && $activity->duration() > 0) { return round($activity->distance() * 1000 * 100 / ($activity->cadence() * 2 / 60 * $activity->duration())); } return 0; }
/** * Set activity * @param \Runalyze\Model\Activity\Entity $object activity object */ public function setActivity(Model\Activity\Entity $object) { $this->Activity = $object; $this->Dataview = new Dataview($object); $this->Linker = new Linker($object); $this->Sport = $this->Activity->sportid() > 0 ? $this->Factory->sport($this->Activity->sportid()) : null; $this->Type = $this->Activity->typeid() > 0 ? $this->Factory->type($this->Activity->typeid()) : null; $this->ActivityData = $this->Activity->completeData(); $this->IsRunning = $this->hasSport() && $this->Sport->id() == \Runalyze\Configuration::General()->runningSport(); }
/** * Save changes for route */ protected function saveChangesForRoute() { if (null === $this->Route || $this->OldRoute->isEmpty()) { return; } $this->Route->synchronize(); if ($this->Route->isEmpty()) { $Deleter = new Model\Route\Deleter($this->PDO, $this->Route); $Deleter->setAccountID($this->AccountID); $Deleter->delete(); $this->Route = null; $this->Activity->set(Entity::ROUTEID, 0); $this->Activity->set(Entity::ELEVATION, 0); } else { $Updater = new Model\Route\Updater($this->PDO, $this->Route, $this->OldRoute); $Updater->setAccountID($this->AccountID); $Updater->update(); } }
/** * Calculate trimp * @return int */ public function calculateTrimp() { if ($this->knowsTrackdata() && $this->Trackdata->has(Model\Trackdata\Entity::HEARTRATE)) { $Collector = new Trimp\DataCollector($this->Trackdata->heartRate(), $this->Trackdata->time()); $data = $Collector->result(); } elseif ($this->Activity->hrAvg() > 0) { $data = array($this->Activity->hrAvg() => $this->Activity->duration()); } else { $Factory = Context::Factory(); if ($this->Activity->typeid() > 0) { $data = array($Factory->type($this->Activity->typeid())->hrAvg() => $this->Activity->duration()); } else { $data = array($Factory->sport($this->Activity->sportid())->avgHR() => $this->Activity->duration()); } } $Athlete = Context::Athlete(); $Calculator = new Trimp\Calculator($Athlete, $data); return round($Calculator->value()); }
/** * Keys to insert * @return array */ protected function keys() { return array_merge(array(self::ACCOUNTID), Entity::allDatabaseProperties()); }
/** * Display table-row for a competition * @param array $data */ private function displayWKTr(array $data) { $Activity = new Activity\Entity($data); $Linker = new Linker($Activity); $Dataview = new Dataview($Activity); echo '<tr class="r"> <td>' . $this->getIconForCompetition($data['id']) . '</td> <td class="c small">' . $Linker->weekLink() . '</a></td> <td class="l"><strong>' . $Linker->linkWithComment() . '</strong></td> <td>' . $Dataview->distance(1) . '</td> <td>' . $Dataview->duration()->string(Duration::FORMAT_COMPETITION) . '</td> <td class="small">' . $Dataview->pace()->value() . '</td> <td class="small">' . Helper::Unknown($Activity->hrAvg()) . ' / ' . Helper::Unknown($Activity->hrMax()) . ' bpm</td> <td class="small">' . ($Activity->weather()->isEmpty() ? '' : $Activity->weather()->fullString($Activity->isNight())) . '</td> </tr>'; }
/** * Get id * @return int */ public function id() { return $this->Object->id(); }
/** * Calculate factor from activity * * Simply calculates the ratio of vdot by time and by heart rate. * This method does not regard any other correction (e.g. elevation, ...). * * @param \Runalyze\Model\Activity\Entity $activity */ public function fromActivity(Activity\Entity $activity) { if ($activity->vdotByHeartRate() > 0) { $this->Factor = $activity->vdotByTime() / $activity->vdotByHeartRate(); } else { $this->Factor = 1; } }
/** * Display the images */ private function displayTable() { if ($this->sportid > 0) { $sports_not_short = $this->sportid . ','; } else { $sports_not_short = ''; $sports = DB::getInstance()->query('SELECT `id` FROM `' . PREFIX . 'sport` WHERE `short`=0 AND `accountid` = ' . SessionAccountHandler::getId())->fetchAll(); foreach ($sports as $sport) { $sports_not_short .= $sport['id'] . ','; } } $nights = DB::getInstance()->query('SELECT * FROM ( SELECT id, time, s, sportid, distance, is_track, HOUR(FROM_UNIXTIME(`time`)) as `H`, MINUTE(FROM_UNIXTIME(`time`)) as `MIN` FROM `' . PREFIX . 'training` WHERE `sportid` IN(' . substr($sports_not_short, 0, -1) . ') AND `accountid` = ' . SessionAccountHandler::getId() . ' AND (HOUR(FROM_UNIXTIME(`time`))!=0 OR MINUTE(FROM_UNIXTIME(`time`))!=0) ' . $this->getYearDependenceForQuery() . ' ORDER BY ABS(12-(`H`+10)%24-`MIN`/60) ASC, `MIN` DESC LIMIT 20 ) t ORDER BY (`H`+12)%24 ASC, `MIN` ASC')->fetchAll(); if (empty($nights)) { $this->dataIsMissing = true; return; } echo '<table class="fullwidth zebra-style">'; echo '<thead><tr class="b c"><th colspan="8">' . __('Nightly activities') . '</th></tr></thead>'; echo '<tbody>'; foreach ($nights as $i => $data) { $Activity = new Activity\Entity($data); $Linker = new Linker($Activity); $View = new Dataview($Activity); if ($i % 2 == 0) { echo '<tr">'; } echo '<td class="b">' . $View->daytime() . '</td> <td>' . $Linker->linkWithSportIcon() . '</td> <td>' . $View->distanceOrDuration() . ' ' . SportFactory::name($Activity->sportid()) . '</td> <td>' . $Linker->weekLink() . '</td>'; if ($i % 2 == 1) { echo '</tr>'; } } echo '</tbody></table>'; // TODO: Find a better description. echo '<p class="text">'; echo __('2 a.m. is considered as <em>most extreme</em> time for a training. '); echo __('The 20 trainings being nearest to that time are listed.'); echo '</p>'; }
/** * Shape deviation in percent * @return string */ public function shapeDeviation() { $Difference = 100 * ($this->prognosisByShapeInSeconds() - $this->Activity->duration()) / $this->Activity->duration(); return HTML::plusMinus(sprintf("%01.2f", $Difference), 2) . ' %'; }
/** * Small edit link * @return string */ public function smallEditLink() { return self::editLink($this->Activity->id()); }