self::MODE_PREVIZ, 'blog'=>self::MODE_BLOG, 'histo'=>self::MODE_HISTO); //DB Tables const PROJ_TABLE = 'projects'; /** * Database Handle * @var Db */ private $oDb; private $iProjectId; private $sName; private $sCodeName; private $sMode; private $asActive; private $asGeo; public function __construct(Db &$oDb, $iProjectId=0) { parent::__construct(__CLASS__); $this->oDb = &$oDb; if($iProjectId > 0) $this->setProjectId($iProjectId); } public function getProjectId() { return $this->iProjectId; } public function setProjectId($iProjectId=0) { if($iProjectId > 0) { $this->iProjectId = $iProjectId; } else { /** * Project 1 [-----------------] * Project 2 [---------------------------] * Project 3 [-----------] * Selected Project [-------Project 1-------][------------Project 2-------------][---------------Project 3------------------ * Mode --P--][--------B--------][--P--][-----------B---------------][---P---][-----B-----][---------H---------- */ $sQuery = "SELECT MAX(id_project) ". "FROM projects ". "WHERE active_to = (". "SELECT MIN(active_to) ". //Select closest project in the future "FROM projects ". "WHERE active_to > NOW() ". //Select Next project "OR active_to = (". //In case there is no next project, select the last one "SELECT MAX(active_to) ". "FROM projects". ")". ")"; $asResult = $this->oDb->getArrayQuery($sQuery, true); $this->iProjectId = array_shift($asResult); } $this->setProjectInfo(); } public function createProjectId() { $this->setProjectId($this->oDb->insertRow(self::PROJ_TABLE, array('codename'=>''))); return $this->getProjectId(); } public function getMode() { return $this->sMode; } public function getProjectName() { return $this->sName; } public function setProjectName($sName) { return $this->updateField('name', $sName); } public function getProjectCodeName() { return $this->sCodeName; } public function setProjectCodeName($sCodeName) { return $this->updateField('codename', $sCodeName); } public function getActivePeriod($sFromTo='') { return ($sFromTo=='')?$this->asActive:$this->asActive[$sFromTo]; } public function setActivePeriod($oValue, $sFromTo='') { if($sFromTo=='') { $this->updateField('active_from', $oValue['from']); return $this->updateField('active_to', $oValue['to']); } else { return $this->updateField('active_'.$sFromTo, $oValue); } } public function getFeedIds() { return $this->oDb->selectColumn( Feed::FEED_TABLE, Db::getId(Feed::FEED_TABLE), array(Db::getId(self::PROJ_TABLE) => $this->getProjectId()) ); } public function getProjects($iProjectId=0) { $bSpecificProj = ($iProjectId > 0); $asInfo = array( 'select'=> array( Db::getId(self::PROJ_TABLE)." AS id", 'codename', 'name', 'active_from', 'active_to', "IF(NOW() BETWEEN active_from AND active_to, 1, IF(NOW() < active_from, 0, 2)) AS mode" ), 'from' => self::PROJ_TABLE ); if($bSpecificProj) $asInfo['constraint'] = array(Db::getId(self::PROJ_TABLE)=>$iProjectId); $asProjects = $this->oDb->selectRows($asInfo, 'codename'); foreach($asProjects as $sCodeName=>&$asProject) { switch($asProject['mode']) { case 0: $asProject['mode'] = self::MODE_PREVIZ; break; case 1: $asProject['mode'] = self::MODE_BLOG; break; case 2: $asProject['mode'] = self::MODE_HISTO; break; } $asProject['editable'] = $this->isModeEditable($asProject['mode']); //$asProject['geofilepath'] = Spot::addTimestampToFilePath(GeoJson::getDistFilePath($sCodeName)); $asProject['gpxfilepath'] = Spot::addTimestampToFilePath(Gpx::getDistFilePath($sCodeName)); $asProject['codename'] = $sCodeName; } return $bSpecificProj?$asProject:$asProjects; } public function getGeoJson() { if($this->sCodeName != '' && !Converter::isGeoJsonValid($this->sCodeName)) Converter::convertToGeoJson($this->sCodeName); return json_decode(file_get_contents(GeoJson::getDistFilePath($this->sCodeName)), true); } public function getProject() { return $this->getProjects($this->getProjectId()); } public function getLastUpdate(): int { $iLastUpdate = INF; $asFeedIds = $this->getFeedIds(); foreach($asFeedIds as $iFeedId) { $iLastUpdate = min($iLastUpdate, (new Feed($this->oDb, $iFeedId))->getLastUpdate()); } return $iLastUpdate; } public function getLastMessageId($asConstraints=array()): int { $iLastMsg = 0; $asFeedIds = $this->getFeedIds(); foreach($asFeedIds as $iFeedId) { $iLastMsg = max($iLastMsg, (new Feed($this->oDb, $iFeedId))->getLastMessageId($asConstraints)); } return $iLastMsg; } private function setProjectInfo() { if($this->getProjectId() > 0) { $asProject = $this->getProject(); $this->sName = $asProject['name']; $this->sCodeName = $asProject['codename']; $this->sMode = $asProject['mode']; $this->asActive = array('from'=>$asProject['active_from'], 'to'=>$asProject['active_to']); $this->asGeo = array(/*'geofile'=>$asProject['geofilepath'], */'gpxfile'=>$asProject['gpxfilepath']); } else $this->addError('Error while setting project: no project ID'); } private function updateField($sField, $oValue) { $bResult = ($this->oDb->updateRow(self::PROJ_TABLE, $this->getProjectId(), array($sField=>$oValue)) > 0); $this->setProjectInfo(); return $bResult; } public function delete() { $asResult = array(); if($this->getProjectId() > 0) { $asFeedIds = $this->getFeedIds(); foreach($asFeedIds as $iFeedId) { $asResult['feed'][] = (new Feed($this->oDb, $iFeedId))->delete(); } $asResult['project'][] = array( 'id' => $this->getProjectId(), 'del' => $this->oDb->deleteRow(self::PROJ_TABLE, $this->getProjectId()), 'desc' => $this->oDb->getLastError() ); } else $asResult['project'][] = array('del'=>false, 'desc'=>'Error while setting project: no project ID'); return $asResult; } public function isEditable() { return self::isModeEditable($this->getMode()); } static public function isModeEditable($sMode) { return ($sMode != self::MODE_HISTO); } }