Source of file MongoDBDAL.php
Size: 9,449 Bytes - Last Modified: 2017-08-13T05:38:14+02:00
C:/xampp/htdocs/PodTube/src/classes/DB/MongoDBDAL.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 | <?php /** * Created by PhpStorm. * User: Mike * Date: 8/8/2017 * Time: 8:08 PM */ namespace AudioDidact\DB; use AudioDidact\User; use AudioDidact\Video; use MongoDB\Client; class MongoDBDAL extends DAL { private $feeds; private $users; /** * MongoDBDAL constructor. * * @param $connectionString */ public function __construct($connectionString){ $client = new Client($connectionString); $db = $client->selectDatabase(DB_DATABASE); $this->feeds = $db->selectCollection("feeds"); $this->users = $db->selectCollection("users"); } /** * Returns User class built from the database * * @param int $id * @return User */ public function getUserByID($id){ $data = $this->users->findOne(["_id" => $id]); return $this->setUser($data); } /** * Makes a new user object from a database select command. * * @param $row array Database row retrieved from another method * @return User */ private function setUser($row){ if($row == null){ return null; } $user = new User(); $user->setUserID($row["_id"]); $user->setUsername($row["username"]); $user->setPasswdDB($row["password"]); $user->setEmail($row["email"]); $user->setFname($row["firstname"]); $user->setLname($row["lastname"]); $user->setGender($row["gender"]); $user->setWebID($row["webID"]); $user->setFeedText($row["feedText"]); $user->setFeedLength($row["feedLength"]); $user->setFeedDetails($row["feedDetails"]); $user->setPrivateFeed($row["privateFeed"]); $user->setEmailVerificationCodes($row["emailVerificationCodes"]); $user->setPasswordRecoveryCodes($row["passwordRecoveryCodes"]); $user->setEmailVerified($row["emailVerified"]); return $user; } /** * Puts user into the database * * @param User $user * @return void * @throws \Exception */ public function addUser(User $user){ if(!$this->usernameExists($user->getUsername()) && !$this->emailExists($user->getEmail())){ $result = $this->users->insertOne($this->makeUserArrayMongo($user)); $user->setUserID($result->getInsertedId()); } else{ throw new \Exception("Username or Email Address Already Exists!"); } } private function makeUserArrayMongo(User $user){ return [ "username" => $user->getUsername(), "password" => $user->getPasswd(), "email" => $user->getEmail(), "firstname" => $user->getFname(), "lastname" => $user->getLname(), "gender" => $user->getGender(), "webID" => $user->getWebID(), "feedText" => $user->getFeedText(), "feedLength" => $user->getFeedLength(), "feedDetails" => $user->getFeedDetails(), "privateFeed" => $user->isPrivateFeed(), "emailVerified" => $user->isEmailVerified(), "emailVerificationCodes" => $user->getEmailVerificationCodes(), "passwordRecoveryCodes" => $user->getPasswordRecoveryCodes() ]; } /** * Adds video into the video database for a specific user * * @param Video $vid * @param User $user * @return mixed */ public function addVideo(Video $vid, User $user){ $result = $this->feeds->findOne(["userID" => $user->getUserID()], ["projection" => ["orderID" => 1], "sort" => ["orderID" => -1]]); if($result == null){ $order = 1; } else{ $order = intval($result["orderID"]) + 1; } $vid->setOrder($order); $vid->setTime(time()); $this->feeds->insertOne($this->makeVideoArrayMongo($vid, $user)); return true; } private function makeVideoArrayMongo(Video $vid, User $user){ return [ "userID" => $user->getUserID(), "videoID" => $vid->getId(), "url" => $vid->getURL(), "videoAuthor" => $vid->getAuthor(), "description" => $vid->getDesc(), "timeAdded" => $vid->getTime(), "videoTitle" => $vid->getTitle(), "duration" => $vid->getDuration(), "orderID" => $vid->getOrder(), "filename" => $vid->getFilename(), "thumbnailFilename" => $vid->getThumbnailFilename(), "isVideo" => $vid->isIsVideo() ]; } /** * Updates an existing video in the video database for a specific user * * @param Video $vid * @param User $user * @return mixed */ public function updateVideo(Video $vid, User $user){ $this->feeds->findOneAndReplace(["userID" => $user->getUserID(), "videoID" => $vid->getId(), "orderID" => $vid->getOrder()], $this->makeVideoArrayMongo($vid, $user)); return true; } /** * Sets feed xml text for a user * * @param User $user * @param $feed * @return mixed */ public function setFeedText(User $user, $feed){ $this->users->findOneAndUpdate(["_id" => $user->getUserID()], ['$set' => ["feedText" => $feed]]); return true; } /** * Updates user entry in the database * * @param User $user */ public function updateUser(User $user){ $this->users->findOneAndReplace(["_id" => $user->getUserID()], $this->makeUserArrayMongo($user)); } /** * Updates only a user's password in the database * * @param User $user */ public function updateUserPassword(User $user){ $this->users->findOneAndUpdate(["_id" => $user->getUserID()], ['$set' => ["password" => $user->getPasswd()]]); } /** * Updates only a user's email verification and password recovery codes in the database * * @param User $user */ public function updateUserEmailPasswordCodes(User $user){ $this->users->findOneAndUpdate(["_id" => $user->getUserID()], ['$set' => ["emailVerificationCodes" => $user->getEmailVerificationCodes(), "passwordRecoveryCodes" => $user->getPasswordRecoveryCodes()]]); } /** * Gets all the videos from the database in the user's current feed * limited by the max number of items the user has set * * @param User $user * @return mixed */ public function getFeed(User $user){ $rows = $this->feeds->find(["userID" => $user->getUserID()], ["sort" => ["orderID" => -1], "limit" => intval ($user->getFeedLength())]); if($rows == null){ return null; } $returner = []; foreach($rows as $row){ $returner[] = $this->setVideo($row); } return $returner; } /** * Makes a new video object from a database select command. * * @param $row array Database rows retrieved from another method * @return Video */ private function setVideo($row){ $vid = new Video(); $vid->setAuthor($row["videoAuthor"]); $vid->setDesc($row["description"]); $vid->setId($row["videoID"]); $vid->setTime($row["timeAdded"]); $vid->setDuration(intval($row["duration"])); $vid->setTitle($row["videoTitle"]); $vid->setOrder($row["orderID"]); $vid->setURL($row["url"]); $vid->setIsVideo($row["isVideo"]); $vid->setFilename($row["filename"]); $vid->setThumbnailFilename($row["thumbnailFilename"]); return $vid; } /** * Gets all the videos from the database * * @param User $user * @return mixed */ public function getFullFeedHistory(User $user){ $rows = $this->feeds->find(["userID" => $user->getUserID()], ["sort" => ["orderID" => -1]]); if($rows == null){ return null; } $returner = []; foreach($rows as $row){ $returner[] = $this->setVideo($row); } return $returner; } /** * Returns User class built from the database * * @param string $username * @return User */ public function getUserByUsername($username){ $data = $this->users->findOne(["username" => $username]); return $this->setUser($data); } /** * Returns User class built from the database * * @param string $webID * @return User */ public function getUserByWebID($webID){ $data = $this->users->findOne(["webID" => $webID]); return $this->setUser($data); } /** * Returns User class built from the database * * @param string $email * @return User */ public function getUserByEmail($email){ $data = $this->users->findOne(["email" => $email]); return $this->setUser($data); } /** * Sets up any database necessary * * @param int $code * @return mixed */ public function makeDB($code){ return; } public function verifyDB(){ return 0; } /** * Returns an array of video IDs that can be safely deleted * * @return array */ public function getPrunableVideos(){ // Get maximum order ID for each user $cursor = $this->feeds->aggregate([['$group' => ['_id' => '$userID', 'maxOrderID' => ['$max' => '$orderID']]]]); $usersAndMaxOrderIDs = []; foreach($cursor as $a){ $usersAndMaxOrderIDs[$a["_id"]->__toString()] = $a["maxOrderID"]; } // Get feed length for each user and set the order ID for the latest video that is out of their feed $usersAndMaxOutOfFeed = []; foreach($usersAndMaxOrderIDs as $userID => $maxOrderID){ $result = $this->users->findOne(["_id" => $userID], ["projection" => ["feedLength" => 1]]); $usersAndMaxOutOfFeed[$userID] = $maxOrderID - $result["feedLength"]; } $videosInFeeds = []; $videosOutOfFeeds = []; foreach($usersAndMaxOutOfFeed as $userID => $maxOrderID){ $userVideos = $this->feeds->find(["userID" => $userID], ["projection" => ["videoID" => 1, "orderID" => 1, "userID" => 1]])->toArray(); foreach($userVideos as $video){ if($video["orderID"] < $maxOrderID){ if(!in_array($video["videoID"], $videosOutOfFeeds, true)){ $videosOutOfFeeds[] = $video["videoID"]; } } else{ if(!in_array($video["videoID"], $videosInFeeds, true)){ $videosInFeeds[] = $video["videoID"]; } } } } // Remove all videos that are in people's feeds from the list of videos out of people's feeds return array_diff($videosOutOfFeeds, $videosInFeeds); } } |