'auth', 'project'=>true), array('name'=>'course', 'project'=>true), array('name'=>'note', 'project'=>true), array('name'=>'doc', 'project'=>true), array('name'=>'definition', 'project'=>true) ); parent::__construct($oClassManagement, $sProcessPage, $asClasses, true , __FILE__); //if($this->oDb->sDbState == Db::DB_PEACHY) $this->oAuth = new Auth($this->oDb, Settings::API_KEY); $this->oAuth = new Auth($this->oDb, Settings::API_KEY); } protected function install() { //Install DB $this->oDb->install(); $this->oDb->loadFile('db_build.sql'); } protected function getSqlOptions() { return array ( 'tables' => array ( Auth::USER_TABLE => array(Db::getText(Auth::USER_TABLE), 'nickname', 'pass', 'cookie'), Course::WS_TABLE => array('dates'), Course::COURSE_TABLE => array(Db::getId(Course::WS_TABLE), 'description', 'timeslot'), Note::NOTE_TABLE => array(Db::getId(Auth::USER_TABLE), Db::getId(Course::COURSE_TABLE), 'notes'), Definition::DEF_TABLE => array(Db::getId(Auth::USER_TABLE), 'title', 'description'), Doc::DOC_TABLE => array(Db::getId(Auth::USER_TABLE), Db::getId(Course::WS_TABLE), 'type', 'filename', 'filehash'), 'todos' => array(Db::getId(Auth::USER_TABLE), Db::getId(Course::COURSE_TABLE), 'description') ), 'types' => array ( Db::getText(Auth::USER_TABLE) => "VARCHAR(32) NOT NULL", 'nickname' => "VARCHAR(60) NOT NULL", 'pass' => "VARCHAR(256) NOT NULL", 'cookie' => "VARCHAR(255)", 'dates' => "VARCHAR(50)", 'title' => "VARCHAR(50)", 'description' => "VARCHAR(200)", 'timeslot' => "ENUM('SAT-M', 'SAT-A', 'SUN-M', 'SUN-A')", 'notes' => "LONGTEXT", 'type' => "VARCHAR(10)", 'filename' => "VARCHAR(200)", 'filehash' => "VARCHAR(40)" ), 'constraints' => array ( Doc::DOC_TABLE => "UNIQUE KEY `uni_file` (`filename`)", Definition::DEF_TABLE => "UNIQUE KEY `uni_def_title` (`title`)" ) ); } private function getVars() { return array( 'id' => $this->oAuth->getUserId(), 'log_in' => $this->isLoggedIn() ); } public function getAppMainPage() { return self::getMainPage( array( 'consts' => array( 'token_sep' => Auth::TOKEN_SEP, 'error' => self::ERROR, 'success' => self::SUCCESS, 'context' => $this->asContext, 'cookie' => Auth::USER_COOKIE_PASS, 'workshops' => (new Course($this->oDb))->getWorkshops(), 'courses' => (new Course($this->oDb))->getCourses(), 'server' => Settings::SERVER_URL ), 'vars' => $this->getVars() ), 'index', array( 'filepath_css' => self::addTimestampToFilePath('style/catc.css'), 'filepath_js_catc' => self::addTimestampToFilePath('scripts/catc.js'), 'filepath_js_common'=> self::addTimestampToFilePath('scripts/common.js'), ) ); } /* Authorizations handling */ public function register($sToken, $sNickname) { $asResult = $this->oAuth->register($sToken, $sNickname); if($asResult['success']) return $this->logMeIn($sToken); else return self::getJsonResult($asResult['success'], $asResult['desc']); } public function isLoggedIn() { return $this->oAuth->isLoggedIn(); } public function logMeIn($sToken) { $asLogResult = $this->oAuth->logMeIn($sToken); return self::getJsonResult($asLogResult['success'], $asLogResult['desc'], $this->getVars()); } public function checkApiKey($sApiKey) { return $this->oAuth->checkApiKey($sApiKey); } /* Notes*/ public function getNoteOld($iCourseId) { $oNote = new Note($this->oDb, $this->oAuth->getUserId(), $iCourseId); $asNote = $oNote->getNoteOld(); return self::getJsonResult(!empty($asNote), '', $asNote); } public function getNote($iCourseId) { $oNote = new Note($this->oDb, $this->oAuth->getUserId(), $iCourseId); $asNote = $oNote->getNote(); return self::getJsonResult(!empty($asNote), '', $asNote); } public function setNote($iCourseId, $sNotes) { $oNote = new Note($this->oDb, $this->oAuth->getUserId(), $iCourseId); $sError = $oNote->setNote($sNotes); $bSuccess = ($sError==''); $asData = ($bSuccess)?array('led_time' => $oNote->getNote()['led_time']):array(); return self::getJsonResult($bSuccess, $sError, $asData); } /* Docs */ public function getDocs($iWorkshopId) { $oDoc = new Doc($this->oDb, $this->oAuth->getUserId(), $iWorkshopId); $asDocList = $oDoc->getList(); return self::getJsonResult(!empty($asDocList), '', $asDocList); } public function uploadDoc($iWorkshopId) { $this->oClassManagement->incClass('uploader', true); $oDoc = new Doc($this->oDb, $this->oAuth->getUserId(), $iWorkshopId); $oUploader = new Uploader($oDoc); return $oUploader->sBody; } public function deleteDoc($iDocId) { $oDoc = new Doc($this->oDb); $oDoc->setDocId($iDocId); $asDoc = $oDoc->getDoc(); $bResult = $oDoc->delete(); return self::getJsonResult($bResult, '', $asDoc); } /* Defs */ public function getDefs() { $oDef = new Definition($this->oDb, $this->oAuth->getUserId()); return self::getJsonResult(true, '', $oDef->getDefinitions()); } public function setDef($iDefId, $sTitle, $sDesc) { $bNew = ($iDefId == 0); $oDef = new Definition($this->oDb, $this->oAuth->getUserId(), $iDefId); $bResult = $oDef->setDefinition($sTitle, $sDesc); return self::getJsonResult($bResult, '', array('new_def'=>$bNew, 'def'=>$oDef->getDefinition())); } /* Sync */ public function pushToServer() { $bSuccess = false; $sDesc = ''; if(Settings::SERVER_URL == '') $sDesc = 'No remote server configured'; else { $sBackup = $this->oDb->getBackup(); if($sBackup === false) $sDesc = 'Error executing mysqldump'; else { //Store backup as a zip file $sBackupFile = uniqid('backup_').'.sql.gz'; $sBackupPath = Doc::DOC_FOLDER.'db/'.$sBackupFile; file_put_contents($sBackupPath, gzencode($sBackup, self::GZ_LVL)); //Send backup $asResult = self::sendFilesToServer('server_update', array('filepath'=>$sBackupPath, 'filename'=>$sBackupFile)); unlink($sBackupPath); if($asResult['result']) { $asData = $asResult['content']; $bSuccess = ($asData['result'] == self::SUCCESS); $sDesc = $asData['desc']; //Send missing files if($bSuccess && isset($asData['data']['files'])) { foreach($asData['data']['files'] as $asFile) { $asResult = $this->sendFilesToServer('file_update', $asFile); $bSuccess = false; if($asResult['result']) { $asData = $asResult['content']; $bSuccess = ($asData['result'] == self::SUCCESS); $sDesc = $asData['desc']; } else $sDesc = $asResult['desc']; if(!$bSuccess) break; } } else $this->addNotice('No missing files identified'); } else $sDesc = $asResult['desc']; } } return self::getJsonResult($bSuccess, $sDesc); } private static function sendFilesToServer($sAction, $asFiles) { if(is_string($asFiles)) $asFiles = array(array('filepath'=>$asFiles, 'filename'=>'file')); elseif(array_key_exists('filepath', $asFiles)) $asFiles = array($asFiles); $asPostData = array('a'=>$sAction, 'api'=>Settings::SERVER_KEY); $asMoves = array(); foreach($asFiles as $iIndex=>$asFile) { $asPathInfo = pathinfo($asFile['filepath']); $asMove = array('origin'=>$asFile['filepath'], 'safe'=>$asPathInfo['dirname'].'/'.uniqid('file_').'.'.$asPathInfo['extension']); rename($asMove['origin'], $asMove['safe']); $asPostData['files['.$iIndex.']'] = new CURLFile(realpath($asMove['safe']), mime_content_type($asMove['safe']), $asFile['filename']); $asMoves[] = $asMove; } $asResult = ToolBox::curl(Settings::SERVER_URL, false, $asPostData, 'json'); foreach($asMoves as $asMove) rename($asMove['safe'], $asMove['origin']); return $asResult; } public function updateServer() { $bSuccess = false; $sDesc = ''; $asMissingFiles = array(); //Replace DB $asFilePaths = $this->updateFiles(Doc::DOC_FOLDER.'db/', true); if(empty($asFilePaths)) $sDesc = 'Missing db file on remote server'; else { $sCompressedPath = array_shift($asFilePaths); $sBackupPath = str_replace('.gz', '', $sCompressedPath); file_put_contents($sBackupPath, gzdecode(file_get_contents($sCompressedPath))); unlink($sCompressedPath); $sDesc = $this->oDb->restoreBackup($sBackupPath); $bSuccess = ($sDesc==''); unlink($sBackupPath); if($bSuccess) { //Reset passwords $this->oAuth->resetPass(); //Check for missing files $asMissingFiles = (new Doc($this->oDb))->getMissingFiles(); } } //Send list of missing files back return self::getJsonResult($bSuccess, $sDesc, array('files'=>$asMissingFiles)); } public function updateFiles($sFolder=Doc::DOC_FOLDER, $bInternal=false) { $bSuccess = false; $sDesc = ''; $asFilePaths = array(); if(!empty($_FILES)) { $asFiles = $_FILES['files']; for($iIndex=0 ; $iIndex < count($asFiles['name']) ; $iIndex++) { $sFilePath = $sFolder.$asFiles['name'][$iIndex]; move_uploaded_file($asFiles['tmp_name'][$iIndex], $sFilePath); $asFilePaths[] = $sFilePath; //TODO Check data integrity } $bSuccess = true; } else $sDesc = 'No file to update'; return $bInternal?$asFilePaths:self::getJsonResult($bSuccess, $sDesc); } }