diff --git a/Source/src/DB.php b/Source/src/DB.php index 91e2145..dadd52c 100644 --- a/Source/src/DB.php +++ b/Source/src/DB.php @@ -51,6 +51,8 @@ class DB $this->createUsers($schema); $this->createCodes($schema); $this->createSources($schema); + $this->createLikes($schema); + $this->createSaves($schema); } private function createUsers(Doctrine\DBAL\Schema\AbstractSchemaManager $schema){ @@ -96,7 +98,7 @@ class DB $sources = new Doctrine\DBAL\Schema\Table('Sources'); $sources->addColumn('IDC','integer',array('unsigned' => true, 'autoincrement' => true)); - $sources->addColumn('IDU','integer',array('unsigned' => true,'autoincrement' => true)); + $sources->addColumn('IDU','integer',array('unsigned' => true)); $sources->addColumn('Lang','string',array('length' => 15)); $sources->addColumn('Version','integer', array('unsigned' => true)); $sources->addColumn('Modification','integer', array('unsigned' => true)); @@ -109,8 +111,43 @@ class DB $sources->addForeignKeyConstraint('Users',array('IDU'),array('IDU')); $sources->addForeignKeyConstraint('Codes',array('IDC'),array('IDC'),array('onUpdate'=>'CASCADE','onDelete'=>'CASCADE')); - $schema->createTable($sources) + $schema->createTable($sources); + } + } + private function createLikes(\Doctrine\DBAL\Schema\AbstractSchemaManager $schema){ + if(!$schema->tablesExist(array('Likes'))){ + $like = new Doctrine\DBAL\Schema\Table('Likes'); + + $like->addColumn('IDC','integer',array('unsigned' => true)); + $like->addColumn('Lang','string',array('length' => 15)); + $like->addColumn('IDU','integer' ,array('unsigned'=>true)); + + $like->addIndex(array('IDU')); + $like->addIndex(array('IDC','Lang')); + $like->addForeignKeyConstraint('Users',array('IDU'),array('IDU'),array('onUpdate'=>'CASCADE','onDelete'=>'CASCADE') ); + $like->addForeignKeyConstraint('Sources',array('IDC','Lang'),array('IDC','Lang'),array('onUpdate'=>'CASCADE','onDelete'=>'CASCADE')); + $like->setPrimaryKey(array('IDC','Lang','IDU')); + + $schema->createTable($like); + } + } + + private function createSaves(\Doctrine\DBAL\Schema\AbstractSchemaManager $schema){ + if(!$schema->tablesExist(array('Saves'))){ + $save = new Doctrine\DBAL\Schema\Table('Saves'); + + $save->addColumn('IDC','integer',array('unsigned' => true)); + $save->addColumn('Lang','string',array('length' => 15)); + $save->addColumn('IDU','integer' ,array('unsigned'=>true)); + + $save->addIndex(array('IDU')); + $save->addIndex(array('IDC','Lang')); + $save->addForeignKeyConstraint('Users',array('IDU'),array('IDU'),array('onUpdate'=>'CASCADE','onDelete'=>'CASCADE')); + $save->addForeignKeyConstraint('Sources',array('IDC','Lang'),array('IDC','Lang'),array('onUpdate'=>'CASCADE','onDelete'=>'CASCADE')); + $save->setPrimaryKey(array('IDC','Lang','IDU')); + + $schema->createTable($save); } } @@ -737,12 +774,18 @@ class DB $queryBuilder ->select('token') ->from('users') - ->where($queryBuilder->expr()-eq('nick','?')) + ->where($queryBuilder->expr()->eq('nick','?')) ->setParameter(0,$nick); $tk = $this->getData($queryBuilder)[0]['token']; return $tk == hash('sha256',"$token-$timestamp"); } + /** + * Generate a random token to restore password + * + * @param $email email from user to restore + * @return string token with timestamp + */ public function createRestoreToken($email){ $token = randomString(75); $now = time(); @@ -756,4 +799,233 @@ class DB $this->execute($queryBuilder); return "$token-$now"; } + + /* Save and like */ + + /** + * Vote or save a code by user + * + * @param $idu user identifier + * @param $idc code identifier + * @param $lang lang of source + * @param $table table, Votes or Save + * @return int 0 if correct, 1 if error + */ + private function voteOrSave($idu,$idc,$lang,$table){ + $queryBuilder = $this->newQueryBuilder(); + $queryBuilder + ->insert($table) + ->values( + array( + "IDU" => '?', + "IDC" => '?', + "Lang"=> '?' + ) + ) + ->setParameters(array($idu,$idc,$lang)); + + try{ + $this->execute($queryBuilder); + return 0; + }catch(Exception $ex){ + return 1; + } + } + + /** + * Vote a code source + * + * @param $idu user identifier + * @param $idc code identifier + * @param $lang source's lang + * @return int 0 if correct, 1 if error + */ + public function vote($idu,$idc,$lang){ + return $this->voteOrSave($idu,$idc,$lang,"Votes"); + } + + /** + * Save a code source + * + * @param $idu user identifier + * @param $idc code identifier + * @param $lang source's lang + * @return int 0 if correct, 1 if error + */ + public function save($idu,$idc,$lang){ + return $this->voteOrSave($idu,$idc,$lang,"Saves"); + } + + /** + * Remove a vote or save + * + * @param $idu user identifier + * @param $idc code identifier + * @param $lang lang of source + * @param $table table, Votes or Saves + * @return int 0 if correct, 1 if error + */ + private function unvoteOrUnsave($idu,$idc,$lang,$table){ + $queryBuilder = $this->newQueryBuilder(); + $queryBuilder + ->delete($table) + ->where($queryBuilder->expr()->andX( + $queryBuilder->expr()->eq('IDU','?'), + $queryBuilder->expr()->eq('IDC','?'), + $queryBuilder->expr()->eq('Lang','?') + )) + ->setParameters(array($idu,$idc,$lang)); + try{ + $this->execute($queryBuilder); + return 0; + }catch(Exception $ex){ + return 1; + } + } + + /** + * Unvote a code source + * + * @param $idu user identifier + * @param $idc code identifier + * @param $lang source's lang + * @return int 0 if correct, 1 if error + */ + public function unvote($idu,$idc,$lang){ + return $this->unvoteOrUnsave($idu,$idc,$lang,"Votes"); + } + + /** + * Unsave a code source + * + * @param $idu user identifier + * @param $idc code identifier + * @param $lang source's lang + * @return int 0 if correct, 1 if error + */ + public function unsave($idu,$idc,$lang){ + return $this->unvoteOrUnsave($idu,$idc,$lang,"Saves"); + } + + /** + * Get all sources saved by user + * + * @param $idu user identifier + * @return array IDC, Lang and Version + */ + public function allSaves($idu){ + $queryBuilder = $this->newQueryBuilder(); + $subQuery = $this->newQueryBuilder(); + $queryBuilder + ->select(array('s.IDC','s.Lang','s.Version')) + ->from('Saves','sa') + ->join('sa','Sources','s', + $queryBuilder->expr()->andX( + $queryBuilder->expr()->eq("sa.IDC","s.IDC"), + $queryBuilder->expr()->eq("sa.Lang","s.Lang") + )) + ->where( + $queryBuilder->expr()->andX( + $queryBuilder->expr()->eq("IDU",'?'), + $queryBuilder->expr()->eq( + 'so.Version','('. + $subQuery + ->select('MAX(Version)') + ->from('Sources') + ->where( + $subQuery->expr()->andX( + $subQuery->expr()->eq('s.Lang','Lang'), + $subQuery->expr()->eq('s.IDC','IDC') + )) + ->getSql() + .')') + ) + ) + ->setParameter(0,$idu); + return $this->getData($queryBuilder); + } + + /** + * Count how many saved sources have an user + * + * @param $idu user identifier + * @return int how many saves + */ + public function allSavesCount($idu){ + $queryBuilder = $this->newQueryBuilder(); + $queryBuilder + ->select('COUNT(*)') + ->from('Saves') + ->where($queryBuilder->expr()->eq("IDU",'?')) + ->setParameter(0,$idu); + return $this->getData($queryBuilder)[0]['MAX(*)']; + } + + /** + * Know if user votes or saves a source + * + * @param $idu user identifier + * @param $idc code identifier + * @param $lang source's lang + * @param $table Votes or Saves + * @return int 0 or 1 + */ + private function iVoteSave($idu,$idc,$lang,$table){ + $queryBuilder = $this->newQueryBuilder(); + $queryBuilder + ->select('COUNT(IDU)') + ->from($table) + ->where($queryBuilder->expr()->andX( + $queryBuilder->expr()->eq('IDU','?'), + $queryBuilder->expr()->eq('IDC','?'), + $queryBuilder->expr()->eq('Lang','?') + )) + ->setParameters(array($idu,$idc,$lang)); + return $this->getData($queryBuilder)[0]['COUNT(IDU)']; + } + + /** + * Know if user votes or saves a source + * + * @param $idu user identifier + * @param $idc code identifier + * @param $lang source's lang + * @return int 0 or 1 + */ + public function iVote($idu,$idc,$lang){ + return $this->iVoteSave($idu,$idc,$lang,"Votes"); + } + + /** + * Know if user votes saves a source + * + * @param $idu user identifier + * @param $idc code identifier + * @param $lang source's lang + * @return int 0 or 1 + */ + public function iSave($idu,$idc,$lang){ + return $this->iVoteSave($idu,$idc,$lang,"Saves"); + } + + /** + * How many votes have a source + * + * @param $idc code identifier + * @param $lang source's lang + * @return int number of votes + */ + public function sourceLikes($idc,$lang){ + $queryBuilder = $this->newQueryBuilder(); + $queryBuilder + ->select('COUNT(IDU)') + ->from('Votes') + ->where($queryBuilder->expr()->andX( + $queryBuilder->expr()->eq("IDC",'?'), + $queryBuilder->expr()->eq("Lang",'?') + )) + ->setParameters(array($idc,$lang)); + + return $this->getData($queryBuilder)[0]['COUNT(IDU)']; + } } \ No newline at end of file diff --git a/Source/src/app.php b/Source/src/app.php index 2750225..1d92541 100644 --- a/Source/src/app.php +++ b/Source/src/app.php @@ -317,7 +317,7 @@ $app->get('/code/{lang}-{idc}-{version}', function (Request $request, $lang, $id )); })->bind('code')->method('GET|POST'); -function updateCode($request,$idc,$lang,$version,$user){ +function updateCode(Request $request,$idc,$lang,$version,$user){ global $app; $lang2 = $request->request->all()['lang']; @@ -424,9 +424,53 @@ $app->get('/restore/{nick}/{token}-{timestamp}', function(Request $request, $nic if(!$app['data']->checkRestoreToken($nick,$token,$timestamp)) $app->abort(408); if($request->getMethod()=='POST'){ - + $pass = $request->get('pwdre'); + $passre = $request->get('pwdre-re'); + if($pass != $passre){ + return "NO_MATCH"; + } + else{ + $idu = $app['daata']->loadIDU($request->get('emailre')); + $iduC = $app['data']->loadIDU($nick,'nick'); + if($idu != $iduC) + return "BAD_EMAIL"; + $app['data']->updatePass($idu,$pass); + } + return "UPDATE"; }else{ - + $page = array( + "title" => "Restore your password", + "description" => "Page to restore your password", + "page" => "NONE", + "nick" => $nick, + "token" => $token, + "timestamp" => $timestamp, + ); + return $app['twig']->render($app['fronthtml']."/restorePass.twig",array("page" => $page)); } } -})->bind('restorePass')->method('GET|POST'); \ No newline at end of file +})->bind('restorePass')->method('GET|POST'); + +/* Votes and saves */ + +$app->post('/vote-save',function(Request $request) use($app){ + + $user = getUser($app); + if ($user == null) + return 1; + + $data = str_replace('"','"',$request->getContent()); + $data = json_decode($data,true); + switch($data['mode']){ + case "vote": + return $app['data']->vote($user['idu'],$data['idc'],$data['lang']); + case "unvote": + return $app['data']->unvote($user['idu'],$data['idc'],$data['lang']); + case "save": + return $app['data']->save($user['idu'],$data['idc'],$data['lang']); + case "unsave": + return $app['data']->unsave($user['idu'],$data['idc'],$data['lang']); + } + return 1; + +})->bind('vote-save'); \ No newline at end of file