diff --git a/inc/core/Dataset/Query.php b/inc/core/Dataset/Query.php
index 8faedd0b34..122050e002 100644
--- a/inc/core/Dataset/Query.php
+++ b/inc/core/Dataset/Query.php
@@ -305,7 +305,7 @@ protected function collectColumnsForKeys(array $keys)
*/
protected function defaultColumns()
{
- return array_merge(array('sportid', 'time', 'use_vdot'), $this->AdditionalColumns);
+ return array_merge(array('sportid', 'time', 'use_vdot', 'is_track'), $this->AdditionalColumns);
}
/**
diff --git a/inc/training/search/class.FormularSelectSearchSort.php b/inc/training/search/class.FormularSelectSearchSort.php
index 87993a6e36..19c08d1ed4 100644
--- a/inc/training/search/class.FormularSelectSearchSort.php
+++ b/inc/training/search/class.FormularSelectSearchSort.php
@@ -3,12 +3,18 @@
* This file contains class::FormularSelectSearchSort
* @package Runalyze\HTML\Formular
*/
+
+use Runalyze\Dataset\Keys;
+
/**
* Class for a double field for sort value and order
* @author Hannes Christiansen
* @package Runalyze\HTML\Formular
*/
class FormularSelectSearchSort extends FormularField {
+ /** @var array */
+ protected $SortByOptions = [];
+
/**
* Validate value
* @return boolean
@@ -25,30 +31,61 @@ protected function getFieldCode() {
$code = '';
$code .= '
';
- $sortByOptions = array(
- 'time' => __('Date'),
- 'distance' => __('Distance'),
- 's' => __('Duration'),
- 'pace' => __('Pace'),
- 'elevation' => __('Elevation'),
- 'pulse_avg' => __('avg. Heartrate'),
- 'pulse_max' => __('max. Heartrate'),
- 'temperature' => __('Temperature'),
- 'cadence' => __('Cadence'),
- 'stride_length' => __('Stride length'),
- 'groundcontact' => __('Ground contact'),
- 'vertical_oscillation' => __('Vertical oscillation'),
- 'vertical_ratio' => __('Vertical ratio'),
- 'vdot' => __('VDOT'),
- 'trimp' => __('TRIMP'),
- 'jd_intensity' => __('JDpoints')
- );
-
- $code .= HTML::selectBox('search-sort-by', $sortByOptions);
+ $this->addOptionsFor([
+ ['time', __('Date')],
+ Keys::DISTANCE,
+ Keys::DURATION,
+ ['pace', __('Pace')],
+ Keys::ELAPSED_TIME,
+ Keys::ELEVATION,
+ ['gradient', __('Gradient')],
+ Keys::HEARTRATE_AVG,
+ Keys::HEARTRATE_MAX,
+ Keys::TRIMP,
+ Keys::RPE,
+ Keys::JD_INTENSITY,
+ Keys::CALORIES,
+ Keys::VDOT_VALUE,
+ Keys::POWER,
+ Keys::CADENCE,
+ Keys::STRIDE_LENGTH,
+ Keys::GROUNDCONTACT,
+ Keys::GROUNDCONTACT_BALANCE,
+ Keys::VERTICAL_OSCILLATION,
+ Keys::VERTICAL_RATIO,
+ Keys::TOTAL_STROKES,
+ Keys::SWOLF,
+ Keys::FIT_VO2MAX_ESTIMATE,
+ Keys::FIT_RECOVERY_TIME,
+ Keys::FIT_HRV_ANALYSIS,
+ Keys::FIT_TRAINING_EFFECT,
+ Keys::FIT_PERFORMANCE_CONDITION,
+ Keys::TEMPERATURE,
+ ['wind_speed', __('Wind speed')],
+ ['wind_deg', __('Wind direction')],
+ Keys::HUMIDITY,
+ Keys::AIR_PRESSURE
+ ]);
+
+ $code .= HTML::selectBox('search-sort-by', $this->SortByOptions);
$code .= HTML::selectBox('search-sort-order', array('DESC' => __('descending'), 'ASC' => __('ascending')));
$code .= '
';
return $code;
}
+
+ /**
+ * @param array $keyIds
+ */
+ protected function addOptionsFor(array $keyIds) {
+ foreach ($keyIds as $keyIdOrArray) {
+ if (is_array($keyIdOrArray)) {
+ $this->SortByOptions[$keyIdOrArray[0]] = $keyIdOrArray[1];
+ } else {
+ $Key = Keys::get($keyIdOrArray);
+ $this->SortByOptions[$Key->column()] = $Key->label();
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/inc/training/search/class.SearchFormular.php b/inc/training/search/class.SearchFormular.php
index 4627809e98..fed14738f2 100644
--- a/inc/training/search/class.SearchFormular.php
+++ b/inc/training/search/class.SearchFormular.php
@@ -8,6 +8,8 @@
use Runalyze\Data\Weather\Humidity;
use Runalyze\Data\Weather\WindSpeed;
use Runalyze\Data\Weather\Pressure;
+use Runalyze\Dataset;
+
/**
* Search formular
*
@@ -157,41 +159,58 @@ protected function initConditions() {
$this->addConditionFieldWithChosen('typeid', 'type', 'name', __('Type'), __('Choose activity type(s)'));
$this->addConditionFieldWithChosen('weatherid', 'weather', 'name', __('Weather'), __('Choose weather conditions'));
$this->addConditionFieldWithChosen('equipmentid', 'equipment', 'name', __('Equipment'), __('Choose equipment'));
- $this->addConditionFieldWithChosen('tagid', 'tag', 'tag', __('Tag'), __('Choose tag'));
-
+ $this->addConditionFieldWithChosen('tagid', 'tag', 'tag', __('Tag'), __('Choose tag'));
$this->addFieldNotes();
+ // Currently there's a fixed 3-column layout
+ // We try to order the fields column-wise, not row-wise
$this->addNumericConditionField('distance', __('Distance'), FormularInput::$SIZE_SMALL, Configuration::General()->distanceUnitSystem()->distanceUnit());
$this->addNumericConditionField('elevation', __('Elevation'), FormularInput::$SIZE_SMALL, Configuration::General()->distanceUnitSystem()->elevationUnit());
$this->addStringConditionField('route', __('Route'), FormularInput::$SIZE_MIDDLE);
+
$this->addDurationField('s', __('Duration'));
- $this->addNumericConditionField('temperature', __('Temperature'), FormularInput::$SIZE_SMALL, Configuration::General()->temperatureUnit()->unit());
- $this->addNumericConditionField('humidity', __('Humidity'), FormularInput::$SIZE_SMALL, (new Humidity())->unit());
- $this->addNumericConditionField('pressure', __('Pressure'), FormularInput::$SIZE_SMALL, (new Pressure())->unit());
- $this->addNumericConditionField('wind_speed', __('Wind Speed'), FormularInput::$SIZE_SMALL, (new WindSpeed())->unit());
+ $this->addNumericConditionField('gradient', __('Gradient'), FormularInput::$SIZE_SMALL, FormularUnit::$PERCENT);
$this->addStringConditionField('comment', __('Title'), FormularInput::$SIZE_MIDDLE);
- $this->addNumericConditionField('pulse_avg', __('avg. HR'), FormularInput::$SIZE_SMALL, FormularUnit::$BPM);
- $this->addNumericConditionField('kcal', __('Calories'), FormularInput::$SIZE_SMALL, FormularUnit::$KCAL);
- $this->addStringConditionField('partner', __('Partner'), FormularInput::$SIZE_MIDDLE);
- $this->addNumericConditionField('pulse_max', __('max. HR'), FormularInput::$SIZE_SMALL, FormularUnit::$BPM);
+
+ $this->addNumericConditionField('pace', __('Pace'), FormularInput::$SIZE_SMALL, FormularUnit::$PACE);
$this->addNumericConditionField('cadence', __('Cadence'), FormularInput::$SIZE_SMALL, FormularUnit::$SPM);
+ $this->addStringConditionField('partner', __('Partner'), FormularInput::$SIZE_MIDDLE);
+
+ $this->addNumericConditionField('pulse_avg', __('avg. HR'), FormularInput::$SIZE_SMALL, FormularUnit::$BPM);
+ $this->addNumericConditionField('stride_length', __('Stride length'), FormularInput::$SIZE_SMALL, Configuration::General()->distanceUnitSystem()->strideLengthUnit());
$this->addBooleanField('is_public', __('Is public'));
- $this->addNumericConditionField('jd_intensity', __('JD points'), FormularInput::$SIZE_SMALL);
- $this->addNumericConditionField('groundcontact', __('Ground contact'), FormularInput::$SIZE_SMALL, FormularUnit::$MS);
- $this->addNumericConditionField('groundcontact_balance', __('Ground Contact Balance'), FormularInput::$SIZE_SMALL, 'L'. FormularUnit::$PERCENT);
+
+ $this->addNumericConditionField('pulse_max', __('max. HR'), FormularInput::$SIZE_SMALL, FormularUnit::$BPM);
+ $this->addNumericConditionFIeld('power', __('Power'), FormularInput::$SIZE_SMALL, FormularUnit::$POWER);
+ $this->addBooleanField('is_race', __('Is race'));
+
+ $this->addNumericConditionField(Configuration::Vdot()->useElevationCorrection() ? 'vdot_with_elevation' : 'vdot', __('VDOT'), FormularInput::$SIZE_SMALL);
$this->addNumericConditionField('vertical_oscillation', __('Vertical oscillation'), FormularInput::$SIZE_SMALL, FormularUnit::$CM);
- $this->addNumericConditionField('vertical_ratio', __('Vertical ratio'), FormularInput::$SIZE_SMALL, FormularUnit::$PERCENT);
- $this->addNumericConditionField('stride_length', __('Stride length'), FormularInput::$SIZE_SMALL, Configuration::General()->distanceUnitSystem()->strideLengthUnit());
- if(Configuration::Vdot()->useElevationCorrection()) {
- $this->addNumericConditionField('vdot_with_elevation', __('VDOT'), FormularInput::$SIZE_SMALL);
- } else {
- $this->addNumericConditionField('vdot', __('VDOT'), FormularInput::$SIZE_SMALL);
- }
$this->addBooleanField('use_vdot', __('Uses VDOT'));
+
$this->addNumericConditionField('trimp', __('TRIMP'), FormularInput::$SIZE_SMALL);
+ $this->addNumericConditionField('vertical_ratio', __('Vertical ratio'), FormularInput::$SIZE_SMALL, FormularUnit::$PERCENT);
+ $this->addBooleanField('is_track', __('Track'));
+
$this->addNumericConditionField('rpe', __('RPE'), FormularInput::$SIZE_SMALL);
+ $this->addNumericConditionField('groundcontact', __('Ground contact'), FormularInput::$SIZE_SMALL, FormularUnit::$MS);
+ $this->addNumericConditionField('temperature', __('Temperature'), FormularInput::$SIZE_SMALL, Configuration::General()->temperatureUnit()->unit());
+
+ $this->addNumericConditionField('jd_intensity', __('JD points'), FormularInput::$SIZE_SMALL);
+ $this->addNumericConditionField('groundcontact_balance', __('Ground Contact Balance'), FormularInput::$SIZE_SMALL, 'L'. FormularUnit::$PERCENT);
+ $this->addNumericConditionField('wind_speed', __('Wind Speed'), FormularInput::$SIZE_SMALL, (new WindSpeed())->unit());
+
+ $this->addNumericConditionField('kcal', __('Calories'), FormularInput::$SIZE_SMALL, FormularUnit::$KCAL);
$this->addNumericConditionField('fit_training_effect', __('Training Effect'), FormularInput::$SIZE_SMALL);
+ $this->addNumericConditionField('humidity', __('Humidity'), FormularInput::$SIZE_SMALL, (new Humidity())->unit());
+
+ $this->addNumericConditionField('fit_vdot_estimate', Dataset\Keys::get(Dataset\Keys::FIT_VO2MAX_ESTIMATE)->label(), FormularInput::$SIZE_SMALL);
+ $this->addNumericConditionField('fit_recovery_time', Dataset\Keys::get(Dataset\Keys::FIT_RECOVERY_TIME)->label(), FormularInput::$SIZE_SMALL);
+ $this->addNumericConditionField('pressure', __('Pressure'), FormularInput::$SIZE_SMALL, (new Pressure())->unit());
+
+ // Currently missing/not supported:
+ // elapsed_time, fit_hrv_analysis, fit_performance_condition, total_strokes, swolf, wind_deg, is_night
}
/**
diff --git a/inc/training/search/class.SearchResults.php b/inc/training/search/class.SearchResults.php
index 12b5243d19..3e732e9e05 100644
--- a/inc/training/search/class.SearchResults.php
+++ b/inc/training/search/class.SearchResults.php
@@ -7,6 +7,7 @@
use Runalyze\Activity\Distance;
use Runalyze\Activity\Duration;
use Runalyze\Activity\Elevation;
+use Runalyze\Activity\Pace;
use Runalyze\Activity\StrideLength;
use Runalyze\Configuration;
use Runalyze\Util\LocalTime;
@@ -26,11 +27,17 @@ class SearchResults {
const MAX_LIMIT_FOR_MULTI_EDITOR = 100;
/**
- * Allowed keys
+ * Allowed keys to search for
* @var array
*/
protected $AllowedKeys = array();
+ /** @var array */
+ protected $KeysThatShouldIgnoreNull = array();
+
+ /** @var array */
+ protected $KeysThatShouldIgnoreZero = array();
+
/**
* Colspan
* @var int
@@ -88,6 +95,8 @@ public function __construct($withResults = true) {
$this->ResultsPerPage = Configuration::Misc()->searchResultsPerPage();
$this->setAllowedKeys();
+ $this->setKeysThatShouldIgnoreNull();
+ $this->setKeysThatShouldIgnoreZero();
if ($withResults) {
$this->initDataset();
@@ -97,52 +106,95 @@ public function __construct($withResults = true) {
/**
* Set allowed keys
+ *
+ * These keys are valid for 'sort by' and for any condition.
+ * `sportid` and `time` are valid anyway, they don't need to be set here.
*/
protected function setAllowedKeys() {
+ // Keys are sorted as in structure.sql
$this->AllowedKeys = array(
'typeid',
- 'weatherid',
-
+ 'is_public',
+ 'is_track',
'distance',
's',
- 'pulse_avg',
-
+ 'elapsed_time',
'elevation',
- 'temperature',
- 'wind_speed',
- 'humdity',
- 'pressure',
-
'kcal',
-
- 'partner',
- 'route',
- 'comment',
-
+ 'pulse_avg',
'pulse_max',
+ 'vdot',
+ 'vdot_with_elevation',
+ 'use_vdot',
+ 'fit_vdot_estimate',
+ 'fit_recovery_time',
+ 'fit_hrv_analysis',
+ 'fit_training_effect',
+ 'fit_performance_condition',
'jd_intensity',
'rpe',
- 'fit_training_effect',
'trimp',
-
'cadence',
+ 'power',
+ 'total_strokes',
+ 'swolf',
'stride_length',
'groundcontact',
+ 'groundcontact_balance',
'vertical_oscillation',
'vertical_ratio',
- 'groundcontact_balance',
-
- 'use_vdot',
- 'vdot',
- 'vdot_with_elevation',
- 'is_public'
+ 'temperature',
+ 'wind_speed',
+ 'wind_deg',
+ 'humidity',
+ 'pressure',
+ 'is_night',
+ 'weatherid',
+ 'route',
+ 'comment',
+ 'partner',
+ 'notes'
);
+ }
- // Some additional keys
- $this->AllowedKeys[] = 'power';
- $this->AllowedKeys[] = 'is_track';
- $this->AllowedKeys[] = 'notes';
+ /**
+ * The following keys will add a `IS NOT NULL` if they have a condition (or order by)
+ */
+ protected function setKeysThatShouldIgnoreNull() {
+ $this->KeysThatShouldIgnoreNull = [
+ 'fit_training_effect',
+ 'fit_performance_condition',
+ 'rpe',
+ 'temperature',
+ 'wind_speed',
+ 'wind_deg',
+ 'humidity',
+ 'pressure'
+ ];
+ }
+ /**
+ * The following keys will add a `!= 0` if they have a condition (or order by)
+ */
+ protected function setKeysThatShouldIgnoreZero() {
+ $this->KeysThatShouldIgnoreZero = [
+ 'distance',
+ 'pulse_avg',
+ 'pulse_max',
+ 'vdot',
+ 'fit_vdot_estimate',
+ 'fit_recovery_time',
+ 'fit_hrv_analysis',
+ 'cadence',
+ 'power',
+ 'total_strokes',
+ 'swolf',
+ 'stride_length',
+ 'groundcontact',
+ 'groundcontact_balance',
+ 'vertical_oscillation',
+ 'vertical_ratio'
+ ];
}
/**
@@ -162,7 +214,9 @@ protected function initDataset() {
* Search trainings
*/
protected function searchTrainings() {
- $this->TotalNumberOfTrainings = DB::getInstance()->query('SELECT COUNT(*) FROM `'.PREFIX.'training` AS `t` '.$this->getWhere().$this->getOrder().' LIMIT 1')->fetchColumn();
+ $where = $this->getWhere();
+
+ $this->TotalNumberOfTrainings = DB::getInstance()->query('SELECT COUNT(*) FROM `'.PREFIX.'training` AS `t` '.$this->joinRaceResultIfRequired().' '.$where.' LIMIT 1')->fetchColumn();
$this->Page = (int)Request::param('page');
if (($this->Page-1)*$this->ResultsPerPage > $this->TotalNumberOfTrainings)
@@ -178,14 +232,38 @@ protected function searchTrainings() {
', '.$this->DatasetQuery->queryToSelectAllKeys().' '.
$this->DatasetQuery->queryToSelectJoinedFields()
).'
+ '.$this->columnFromRaceResultIfRequired().'
FROM `'.PREFIX.'training` AS `t`
+ '.$this->joinRaceResultIfRequired().'
'.$this->DatasetQuery->queryToJoinTables().'
- '.$this->getWhere().' '.
+ '.$where.' '.
$this->DatasetQuery->queryToGroupByActivity().
- $this->getOrder().$this->getLimit()
+ $this->getOrder().$this->getLimit()
)->fetchAll();
}
+ /**
+ * @return string
+ */
+ protected function columnFromRaceResultIfRequired() {
+ if (isset($_POST['is_race']) && $_POST['is_race'] != '') {
+ return ', `rr`.`activity_id`';
+ }
+
+ return '';
+ }
+
+ /**
+ * @return string
+ */
+ protected function joinRaceResultIfRequired() {
+ if (isset($_POST['is_race']) && $_POST['is_race'] != '') {
+ return 'LEFT JOIN `'.PREFIX.'raceresult` AS `rr` ON `t`.`id` = `rr`.`activity_id`';
+ }
+
+ return '';
+ }
+
/**
* Get where
* @return string
@@ -193,11 +271,7 @@ protected function searchTrainings() {
protected function getWhere() {
$conditions = array('`t`.`accountid`="'.$this->AccountID.'"');
- if (isset($_POST['sportid']))
- $this->addSportCondition($conditions);
-
- if (isset($_POST['date-from']) && isset($_POST['date-to']))
- $this->addTimeRangeCondition($conditions);
+ $this->addSpecialConditions($conditions);
if (isset($_POST['s']) && strlen($_POST['s']) > 0) {
$Time = new Duration($_POST['s']);
@@ -216,7 +290,67 @@ protected function getWhere() {
$this->addConditionsForOrder($conditions);
- return $this->getEquipmentCondition().$this->getTagCondition().' WHERE '.implode(' AND ', $conditions);
+ return $this->getEquipmentCondition().$this->getTagCondition().' WHERE '.implode(' AND ', array_unique($conditions));
+ }
+
+ /**
+ * @param array $conditions
+ */
+ protected function addSpecialConditions(array &$conditions) {
+ if (isset($_POST['sportid'])) {
+ $this->addSportCondition($conditions);
+ }
+
+ if (isset($_POST['date-from']) && isset($_POST['date-to'])) {
+ $this->addTimeRangeCondition($conditions);
+ }
+
+ if (isset($_POST['pace']) && $_POST['pace'] != '') {
+ $this->addPaceCondition($conditions);
+ }
+
+ if (isset($_POST['gradient']) && $_POST['gradient'] != '') {
+ $this->addGradientCondition($conditions);
+ }
+
+ if (isset($_POST['is_race']) && $_POST['is_race'] != '') {
+ $this->addIsRaceCondition($conditions);
+ }
+ }
+
+ /**
+ * @param array $conditions
+ */
+ protected function addPaceCondition(array &$conditions) {
+ $Pace = new Pace(0);
+ $Pace->fromMinPerKm($_POST['pace']);
+ $value = $Pace->secondsPerKm();
+ $sign = $this->signForKey('pace');
+
+ $conditions[] = '`t`.`distance` > 0';
+ $conditions[] = ($sign == '=' ? 'ROUND(`t`.`s`/`t`.`distance`)' : '`t`.`s`/`t`.`distance`').' '.$sign.' '.DB::getInstance()->escape($value);
+ }
+
+ /**
+ * @param array $conditions
+ */
+ protected function addGradientCondition(array &$conditions) {
+ $value = 10*(float)str_replace(',', '.', $_POST['gradient']);
+
+ $conditions[] = '`t`.`distance` > 0';
+ $conditions[] = '`t`.`elevation` > 0';
+ $conditions[] = '`t`.`elevation`/`t`.`distance` '.$this->signForKey('gradient').' '.DB::getInstance()->escape($value);
+ }
+
+ /**
+ * @param array $conditions
+ */
+ protected function addIsRaceCondition(array &$conditions) {
+ if ($_POST['is_race'] == 1) {
+ $conditions[] = '`rr`.`activity_id` IS NOT NULL';
+ } else {
+ $conditions[] = '`rr`.`activity_id` IS NULL';
+ }
}
/**
@@ -246,47 +380,63 @@ protected function addConditionFor($key, array &$conditions) {
if ($sign == ' LIKE ') {
$conditions[] = '`t`.`'.$key.'` '.$sign.' "%'.DB::getInstance()->escape($_POST[$key], false).'%"';
} else {
- if (in_array($key, array('distance', 'vertical_oscillation', 'stride_length'))) {
- $_POST[$key] = (float)str_replace(',', '.', $_POST[$key]);
- }
-
- if ($key == 'elevation') {
- $value = (new Elevation())->setInPreferredUnit($_POST[$key])->meter();
- } elseif ($key == 'distance') {
- $value = (new Distance())->setInPreferredUnit($_POST[$key])->kilometer();
- } elseif ($key == 'vertical_oscillation') {
- $value = 10*$_POST[$key];
- } elseif ($key == 'vertical_ratio') {
- $value = 10*$_POST[$key];
- } elseif ($key == 'groundcontact_balance') {
- $value = 100*$_POST[$key];
- } elseif ($key == 'stride_length') {
- $value = (new StrideLength())->setInPreferredUnit($_POST[$key])->cm();
- } elseif ($key == 'temperature') {
- $value = (new Temperature())->setInPreferredUnit($_POST[$key])->celsius();
- } elseif ($key == 'wind_speed') {
- $value = (new WindSpeed())->setInPreferredUnit($_POST[$key])->value();
- } elseif ($key == 'vdot' || $key == 'vdot_with_elevation') {
- if(!Configuration::Vdot()->useCorrectionFactor()) {
- $value = $_POST[$key];
- } else {
- $value = $_POST[$key] * Configuration::Data()->vdotFactor();
- }
- } else {
- $value = $_POST[$key];
- }
+ $value = $this->transformValueForDatabase($key, $_POST[$key]);
$conditions[] = '`t`.`'.$key.'` '.$sign.' '.DB::getInstance()->escape($value);
- if (
- ($sign == '<' || $sign == '<=') &&
- in_array($key, array('distance', 'pulse_avg', 'pulse_max', 'cadence', 'groundcontact', 'vertical_oscillation', 'vertical_ratio', 'groundcontact_balance', 'stride_length'))
- ) {
- $conditions[] = '`t`.`'.$key.'` != 0';
+ if ($sign == '<' || $sign == '<=') {
+ if (in_array($key, $this->KeysThatShouldIgnoreZero)) {
+ $conditions[] = '`t`.`'.$key.'` != 0';
+ } elseif (in_array($key, $this->KeysThatShouldIgnoreNull)) {
+ $conditions[] = '`t`.`'.$key.'` IS NOT NULL';
+ }
}
}
}
+ /**
+ * @param string $key
+ * @param string $value
+ * @return float|int
+ */
+ protected function transformValueForDatabase($key, $value) {
+ if (in_array($key, array('distance', 'vertical_oscillation', 'vertical_ratio', 'stride_length', 'groundcontact_balance', 'fit_training_effect'))) {
+ $value = (float)str_replace(',', '.', $value);
+ }
+
+ if ($key == 'elevation') {
+ $value = (new Elevation())->setInPreferredUnit($value)->meter();
+ } elseif ($key == 'distance') {
+ $value = (new Distance())->setInPreferredUnit($value)->kilometer();
+ } elseif ($key == 'vertical_oscillation' || $key == 'vertical_ratio') {
+ $value *= 10;
+ } elseif ($key == 'groundcontact_balance') {
+ $value *= 100;
+ } elseif ($key == 'stride_length') {
+ $value = (new StrideLength())->setInPreferredUnit($value)->cm();
+ } elseif ($key == 'temperature') {
+ $value = (new Temperature())->setInPreferredUnit($value)->celsius();
+ } elseif ($key == 'wind_speed') {
+ $value = (new WindSpeed())->setInPreferredUnit($value)->value();
+ } elseif (($key == 'vdot' || $key == 'vdot_with_elevation') && Configuration::Vdot()->useCorrectionFactor()) {
+ $value *= Configuration::Data()->vdotFactor();
+ }
+
+ return $value;
+ }
+
+ /**
+ * @param string $key
+ * @return string
+ */
+ protected function signForKey($key) {
+ if (isset($_POST['opt'][$key])) {
+ return $this->signFor($_POST['opt'][$key]);
+ }
+
+ return '=';
+ }
+
/**
* Equality sign
* @param string $postSign from $_POST
@@ -390,18 +540,25 @@ function ($value) {
* @return string
*/
protected function getOrder() {
- $sort = (!isset($_POST['search-sort-by']) || array_key_exists($_POST['search-sort-by'], $this->AllowedKeys)) ? '`time`' : $this->DB->escape($_POST['search-sort-by'], false);
$order = (!isset($_POST['search-sort-order'])) ? 'DESC' : $this->DB->escape($_POST['search-sort-order'], false);
- if ($sort == 'vdot' && Configuration::Vdot()->useElevationCorrection()) {
+ if ($_POST['search-sort-by'] == 'vdot' && Configuration::Vdot()->useElevationCorrection()) {
return ' ORDER BY IF(`t`.`vdot_with_elevation`>0, `t`.`vdot_with_elevation`, `t`.`vdot`) '.$order;
}
- if ($sort == 'pace') {
- return ' ORDER BY IF(`t`.`distance`>0, `t`.`s`/`t`.`distance`, 0) '.$order;
+ if ($_POST['search-sort-by'] == 'pace') { // addConditionsForOrder() guarantees that `distance` > 0
+ return ' ORDER BY `t`.`s`/`t`.`distance` '.$order;
+ }
+
+ if ($_POST['search-sort-by'] == 'gradient') { // addConditionsForOrder() guarantees that `distance` > 0
+ return ' ORDER BY `t`.`elevation`/`t`.`distance` '.$order;
+ }
+
+ if (isset($_POST['search-sort-by']) && in_array($_POST['search-sort-by'], $this->AllowedKeys)) {
+ return ' ORDER BY `t`.'.$this->DB->escape($_POST['search-sort-by'], false).' '.$order;
}
- return ' ORDER BY `t`.'.$sort.' '.$order;
+ return ' ORDER BY `t`.`time` '.$order;
}
/**
@@ -414,8 +571,13 @@ protected function addConditionsForOrder(array &$conditions) {
if ($_POST['search-sort-by'] == 'pace') {
$conditions[] = '`t`.`distance` > 0';
- } elseif (in_array($_POST['search-sort-by'], array('pulse_avg', 'pulse_max', 'cadence', 'stride_length', 'groundcontact', 'vertical_oscillation', 'vertical_ratio'))) {
- $conditions[] = '`t`.`'.$_POST['search-sort-by'].'` > 0';
+ } elseif ($_POST['search-sort-by'] == 'gradient') {
+ $conditions[] = '`t`.`distance` > 0';
+ $conditions[] = '`t`.`elevation` > 0';
+ } elseif (in_array($_POST['search-sort-by'], $this->KeysThatShouldIgnoreZero)) {
+ $conditions[] = '`t`.`'.$_POST['search-sort-by'].'` != 0';
+ } elseif (in_array($_POST['search-sort-by'], $this->KeysThatShouldIgnoreNull)) {
+ $conditions[] = '`t`.`'.$_POST['search-sort-by'].'` IS NOT NULL';
}
}