作者:schoc
项目:Runalyz
/**
* Parse laps
*/
protected function parseLaps()
{
if (isset($this->XML->result->laps)) {
foreach ($this->XML->result->laps->lap as $Lap) {
$distance = round((double) $Lap->distance / 1000, 2);
$Time = new Duration((string) $Lap->duration);
$this->TrainingObject->Splits()->addSplit($distance, $Time->seconds());
}
}
}
作者:guanci
项目:Runalyz
/**
* Find a pace goal within a string
*
* This method can be used to extract the demanded pace within a description,
* e.g. to find '3:20' within '6x1000m in 3:20, 400m pauses'.
* It will look for a time string directly after the given search pattern.
* The time string will be interpreted as time per kilometer.
*
* @param string $searchPattern [optional] String that must occur directly before the pace
* @return int Pace in s/km, 0 if nothing found
*/
public function findDemandedPace($searchPattern = ' in ')
{
$Lookup = explode($searchPattern, $this->String);
if (count($Lookup) < 2) {
return 0;
}
$cutPosition = strpos($Lookup[1], ' ');
$timeString = $cutPosition !== false ? substr($Lookup[1], 0, $cutPosition) : $Lookup[1];
$Duration = new Duration($timeString);
return $Duration->seconds();
}
作者:n0rthfac
项目:Runalyz
/**
* Display data
*/
protected function setDataToCode()
{
$this->Code .= '<table class="fullwidth zebra-style">';
$this->Code .= '<thead><tr>';
$this->Code .= '<th></th>';
$this->Code .= '<th>' . __('Distance') . '</th>';
$this->Code .= '<th>' . __('Time') . '</th>';
$this->Code .= '<th>' . __('Swolf') . '</th>';
$this->Code .= '<th>' . __('Strokes') . '</th>';
$this->Code .= '<th>' . __('Type') . '</th>';
$this->Code .= '</tr></thead>';
$this->Code .= '<tbody>';
$Loop = new Swimdata\Loop($this->Context->swimdata());
$TrackLoop = new Trackdata\Loop($this->Context->trackdata());
$Stroketype = new Stroketype(Stroketype::FREESTYLE);
$Distance = new Distance(0);
$max = $Loop->num();
for ($i = 1; $i <= $max; ++$i) {
$Stroketype->set($Loop->stroketype());
$Distance->set($TrackLoop->distance());
$this->Code .= '<tr class="r">';
$this->Code .= '<td>' . $i . '.</td>';
$this->Code .= '<td>' . $Distance->stringMeter() . '</td>';
$this->Code .= '<td>' . Duration::format($TrackLoop->difference(Trackdata\Object::TIME)) . '</td>';
$this->Code .= '<td>' . $Loop->swolf() . '</td>';
$this->Code .= '<td>' . $Loop->stroke() . '</td>';
$this->Code .= '<td>' . $Stroketype->shortstring() . '</td>';
$this->Code .= '</tr>';
$TrackLoop->nextStep();
$Loop->nextStep();
}
$this->Code .= '</tbody>';
$this->Code .= '</table>';
}
作者:guanci
项目:Runalyz
/**
* @return \Runalyze\Activity\Pace
*/
public function pace()
{
if (null == $this->LapPace) {
$this->LapPace = new Pace($this->LapDuration->seconds(), $this->LapDistance->kilometer());
}
return $this->LapPace;
}
作者:guanci
项目:Runalyz
/**
* Format pace
* @param int $secondsPerKm
* @return string
*/
public function format($secondsPerKm)
{
if ($secondsPerKm == 0) {
return '-:--';
}
return Duration::format(round($secondsPerKm * $this->factorForUnit()));
}
作者:guanci
项目:Runalyz
/**
* @param \Runalyze\Model\Activity\Splits\Entity $Splits
* @return string
* @codeCoverageIgnore
*/
protected function stringForActiveLaps(Entity $Splits)
{
$laps = [];
$onlyActiveSplits = $Splits->hasActiveAndInactiveLaps();
foreach ($Splits->asArray() as $Split) {
if (!$onlyActiveSplits || $Split->isActive()) {
$laps[] = Activity\Duration::format($Split->time());
}
}
return str_replace(' ', ' ', implode(' / ', $laps));
}
作者:rob-s
项目:Runalyz
/**
* Convert data
*/
private function convertData()
{
$totalTime = 0;
$totalDist = 0;
foreach ($this->Data as $Info) {
$totalTime += $Info['time'];
$totalDist += $Info['distance'];
}
foreach ($this->Data as $i => $Info) {
if ($totalTime > 0) {
$percentage = round(100 * $Info['time'] / $totalTime, 1);
} elseif ($totalDist > 0) {
$percentage = round(100 * $Info['distance'] / $totalDist, 1);
} else {
$percentage = '-';
}
$this->Data[$i]['percentage'] = $percentage;
$this->Data[$i]['time'] = $totalTime > 0 ? Duration::format($Info['time']) : '-';
$this->Data[$i]['distance'] = $totalDist > 0 ? Distance::format($Info['distance']) : '-';
}
}
作者:rob-s
项目:Runalyz
/**
* Get elapsed time
* @return string
*/
public function elapsedTime()
{
if ($this->Activity->elapsedTime() < $this->Activity->duration()) {
return '-:--:--';
}
return Duration::format($this->Activity->elapsedTime());
}
作者:n0rthfac
项目:Runalyz
<?php
use Runalyze\Activity\Duration;
use Runalyze\Activity\Distance;
$Duration = new Duration();
?>
<table id="jd-tables-prognosis" class="zebra-style r" style="width: 700px;">
<thead>
<tr>
<?php
foreach ($this->Configuration()->value('pace_distances') as $km) {
?>
<th><?php
echo Distance::format($km, $km <= 3, 1);
?>
</th>
<?php
}
?>
</tr>
</thead>
<tbody>
<?php
foreach ($this->Range as $sPer400m) {
?>
<tr>
<?php
foreach ($this->Configuration()->value('pace_distances') as $km) {
?>
<?php
$Duration->fromSeconds($km * $sPer400m / 0.4);
作者:n0rthfac
项目:Runalyz
/**
* Get string for time
* @return string
*/
public function getTimeString()
{
return Duration::format($this->getTime());
}
作者:n0rthfac
项目:Runalyz
/**
* Get link with icon as text
* @return string HTML-link to this training
*/
public function linkWithSportIcon()
{
$Sport = new Sport($this->Activity->sportid());
$Time = new Duration($this->Activity->duration());
$tooltip = $Sport->name() . ': ' . $Time->string();
return $this->link($Sport->Icon($tooltip));
}
作者:Nugma
项目:Runalyz
/**
* Display table
*/
public function displayTable()
{
if (is_null($this->Equipment)) {
$this->initTableData();
}
echo '<table id="list-of-all-equipment" class="fullwidth zebra-style">
<thead>
<tr>
<th class="{sorter: \'x\'} small">' . __('x-times') . '</th>
<th>' . __('Name') . '</th>
<th class="{sorter: \'germandate\'} small">' . __('since') . '</th>
<th class="{sorter: \'distance\'}">Ø ' . Runalyze\Configuration::General()->distanceUnitSystem()->distanceUnit() . '</th>
<th>Ø ' . __('Pace') . '</th>
<th class="{sorter: \'distance\'} small"><small>' . __('max.') . '</small> ' . Runalyze\Configuration::General()->distanceUnitSystem()->distanceUnit() . '</th>
<th class="small"><small>' . __('min.') . '</small> ' . __('Pace') . '</th>
<th class="{sorter: \'resulttime\'}">' . __('Time') . '</th>
<th class="{sorter: \'distance\'}">' . __('Distance') . '</th>
<th>' . __('Notes') . '</th>
</tr>
</thead>
<tbody>';
if (!empty($this->Equipment)) {
foreach ($this->Equipment as $data) {
$Object = new Model\Equipment\Object($data);
$in_use = $Object->isInUse() ? '' : ' unimportant';
$Pace = new Pace($Object->duration(), $Object->distance());
$MaxPace = new Pace($data['pace_in_s'], 1);
echo '<tr class="' . $in_use . ' r" style="position: relative">
<td class="small">' . $data['num'] . 'x</td>
<td class="b l">' . SearchLink::to('equipmentid', $Object->id(), $Object->name()) . '</td>
<td class="small">' . $this->formatData($Object->startDate()) . '</td>
<td>' . ($data['num'] != 0 ? Distance::format($Object->distance() / $data['num']) : '-') . '</td>
<td>' . ($Object->duration() > 0 ? $Pace->asMinPerKm() . '/km' : '-') . '</td>
<td class="small">' . Distance::format($data['dist']) . '</td>
<td class="small">' . $MaxPace->asMinPerKm() . '/km' . '</td>
<td>' . Duration::format($Object->duration()) . '</td>
<td>' . Distance::format($Object->totalDistance()) . '</td>
<td class="small">' . $Object->notes() . '</td>
</tr>';
}
} else {
echo '<tr><td colspan="9">' . __('You don\'t have any shoes') . '</td></tr>';
}
echo '</tbody>';
echo '</table>';
Ajax::createTablesorterFor("#list-of-all-equipment", true);
}
作者:guanci
项目:Runalyz
/**
* Compare
* @param \Runalyze\Activity\Duration $other
* @param boolean $invert [optional] by default, larger is 'better'; set to true to invert that
* @param boolean $raw [optional]
* @throws \InvalidArgumentException
* @return string
*/
public function compareTo(Duration $other, $invert = false, $raw = false)
{
if ($this->seconds() == 0 || $other->seconds() == 0) {
return '';
}
$CompareTime = new Duration(round(abs($this->seconds() - $other->seconds())));
$isPositive = !$invert ? $this->seconds() > $other->seconds() : $this->seconds() <= $other->seconds();
return $this->formatComparison($CompareTime->string(), $isPositive, $raw);
}
作者:guanci
项目:Runalyz
/**
* @param string $commaSeparatedString
* @return array
*/
private static function explodeTimeStrings($commaSeparatedString)
{
$timeStrings = explode(',', $commaSeparatedString);
return array_map(function ($string) {
$Time = new Duration($string);
return $Time->seconds();
}, $timeStrings);
}
作者:n0rthfac
项目:Runalyz
/**
* Display the table with general records
*/
private function displayRekorde()
{
foreach ($this->rekorde as $rekord) {
echo '<table class="fullwidth zebra-style">';
echo '<thead><tr><th colspan="11" class="l">' . $rekord['name'] . '</th></tr></thead>';
echo '<tbody>';
$output = false;
$sports = DB::getInstance()->query($rekord['sportquery'])->fetchAll();
$Request = DB::getInstance()->prepare($rekord['datquery']);
foreach ($sports as $sport) {
$Request->bindValue('sportid', $sport['id']);
$Request->execute();
$data = $Request->fetchAll();
if (!empty($data)) {
$output = true;
echo '<tr class="r">';
echo '<td class="b l">' . Icon::getSportIconForGif($sport['img'], $sport['name']) . ' ' . $sport['name'] . '</td>';
$j = 0;
foreach ($data as $j => $dat) {
if ($rekord['speed']) {
$Pace = new Pace($dat['s'], $dat['distance'], SportFactory::getSpeedUnitFor($sport['id']));
$code = $Pace->valueWithAppendix();
} else {
$code = $dat['distance'] != 0 ? Distance::format($dat['distance']) : Duration::format($dat['s']);
}
echo '<td class="small"><span title="' . date("d.m.Y", $dat['time']) . '">
' . Ajax::trainingLink($dat['id'], $code) . '
</span></td>';
}
for (; $j < 9; $j++) {
echo HTML::emptyTD();
}
echo '</tr>';
}
}
if (!$output) {
echo '<tr><td colspan="11"><em>' . __('No data available') . '</em></td></tr>';
}
echo '</tbody>';
echo '</table>';
}
}
作者:rob-s
项目:Runalyz
/**
* Parse all trackpoints for one lap
* @param SimpleXMLElement $Lap
*/
protected function parseTrackpoints(&$Lap)
{
$this->lastPoint = 0;
foreach ($Lap->Track as $Track) {
if ($this->lastPoint > 0) {
$this->lastPointWasEmpty = true;
}
if (count($Track->xpath('./Trackpoint')) > 0) {
$this->distancesAreEmpty = count($Track->xpath('./Trackpoint/DistanceMeters')) == 0;
if (strtotime((string) $Lap['StartTime']) + 8 < strtotime((string) $Track->Trackpoint[0]->Time)) {
$this->lastPointWasEmpty = true;
}
foreach ($Track->Trackpoint as $Trackpoint) {
$this->parseTrackpoint($Trackpoint);
}
}
}
if (self::$DEBUG_SPLITS) {
Error::getInstance()->addDebug('computed: ' . Duration::format(end($this->gps['time_in_s'])) . ', ' . Distance::format(end($this->gps['km'])));
}
}
作者:n0rthfac
项目:Runalyz
/**
* Show prognosis for a given distance
* @param double $distance
*/
protected function showPrognosis($distance)
{
$PB = new PersonalBest($distance);
$PBTime = $PB->exists() ? Duration::format($PB->seconds()) : '-';
$Prognosis = new Duration($this->Prognosis->inSeconds($distance));
$Distance = new Distance($distance);
$Pace = new Pace($Prognosis->seconds(), $distance, Pace::MIN_PER_KM);
echo '<p>
<span class="right">
' . sprintf(__('<small>from</small> %s <small>to</small> <strong>%s</strong>'), $PBTime, $Prognosis->string(Duration::FORMAT_AUTO, 0)) . '
<small>(' . $Pace->valueWithAppendix() . ')</small>
</span>
<strong>' . $Distance->string(Distance::FORMAT_AUTO, 1) . '</strong>
</p>';
}
作者:n0rthfac
项目:Runalyz
/**
* Init calculations
*/
protected function runCalculations()
{
foreach ($this->Distances as $km) {
$Prognosis = $this->PrognosisObject->inSeconds($km);
$PB = new PersonalBest($km, DB::getInstance(), false);
$PB->lookupWithDetails();
$VDOTprognosis = new VDOT();
$VDOTprognosis->fromPace($km, $Prognosis);
$VDOTpb = new VDOT();
$VDOTpb->fromPace($km, $PB->seconds());
$PacePrognosis = new Pace($Prognosis, $km, Pace::MIN_PER_KM);
$PacePB = new Pace($PB->seconds(), $km, Pace::MIN_PER_KM);
$DateWithLink = Ajax::trainingLink($PB->activityId(), date('d.m.Y', $PB->timestamp()), true);
$this->Prognoses[] = array('distance' => Distance::format($km, $km <= 3), 'prognosis' => Duration::format($Prognosis), 'prognosis-pace' => $PacePrognosis->valueWithAppendix(), 'prognosis-vdot' => $VDOTprognosis->uncorrectedValue(), 'diff' => !$PB->exists() ? '-' : ($PB->seconds() > $Prognosis ? '+ ' : '- ') . Duration::format(abs(round($PB->seconds() - $Prognosis))), 'diff-class' => $PB->seconds() > $Prognosis ? 'plus' : 'minus', 'pb' => $PB->seconds() > 0 ? Duration::format($PB->seconds()) : '-', 'pb-pace' => $PB->seconds() > 0 ? $PacePB->valueWithAppendix() : '-', 'pb-vdot' => $PB->seconds() > 0 ? $VDOTpb->uncorrectedValue() : '-', 'pb-date' => $PB->seconds() > 0 ? $DateWithLink : '-');
}
}
作者:rob-s
项目:Runalyz
/**
* Format time
* @return string
*/
private function timeAsString()
{
return Duration::format($this->Time);
}
作者:guanci
项目:Runalyz
/**
* Add tab for general statistics
*/
protected function addTabForGeneralStatistics()
{
$User = $this->FrontendSharedList->getUser();
$Stats = DB::getInstance()->query('
SELECT
SUM(1) as num,
SUM(distance) as dist_sum,
SUM(s) as time_sum
FROM `' . PREFIX . 'training`
WHERE `accountid`="' . $User['id'] . '"
GROUP BY `accountid`
LIMIT 1
')->fetch();
$Content = '
<table class="fullwidth">
<tbody>
<tr>
<td class="b">' . __('Total distance:') . '</td>
<td>' . Distance::format($Stats['dist_sum']) . '</td>
<td class="b">' . __('Number of activities:') . '</td>
<td>' . $Stats['num'] . 'x</td>
<td class="b">' . __('Registered since:') . '</td>
<td>' . date('d.m.Y', $User['registerdate']) . '</td>
</tr>
<tr>
<td class="b">' . __('Total duration:') . '</td>
<td>' . Duration::format($Stats['time_sum']) . '</td>
<td class="b">' . __('First activity:') . '</td>
<td>' . date('d.m.Y', START_TIME) . '</td>
<td class="b">' . __('Last login:') . '</td>
<td>' . date('d.m.Y', $User['lastaction']) . '</td>
</tr>
</tbody>
</table>';
$this->StatisticTabs->addTab(__('General statistics'), 'statistics-general', $Content);
}