Bleh
authorCameron Ball <cameron@getapproved.com.au>
Mon, 10 Nov 2014 09:01:16 +0000 (17:01 +0800)
committerCameron Ball <cameron@getapproved.com.au>
Mon, 10 Nov 2014 09:01:16 +0000 (17:01 +0800)
Controllers/SimfileController.php
DataAccess/UserRepository.php
Services/ISimfileParser.php
Services/IUserSession.php [new file with mode: 0644]
Services/SimfileParser.php
Services/Uploads/UserSession.php [new file with mode: 0644]
config/DI.php
public_html/index.php
public_html/upload.html

index 3a042d7..8585cc5 100644 (file)
@@ -2,11 +2,16 @@
 \r
 namespace Controllers;\r
 \r
+use ZipArchive;\r
+use Exception;\r
 use Controllers\IDivineController;\r
 use Services\Http\IHttpRequest;\r
 use Services\Http\IHttpResponse;\r
 use Services\Uploads\IUploadManager;\r
+use Services\ISimfileParser;\r
 use DataAccess\StepMania\ISimfileRepository;\r
+use DataAccess\IUserRepository;\r
+use Domain\Entities\StepMania\ISimfileStepByStepBuilder;\r
 \r
 class SimfileController implements IDivineController\r
 {\r
@@ -14,17 +19,26 @@ class SimfileController implements IDivineController
     private $_response;\r
     private $_request;\r
     private $_uploadManager;\r
+    private $_simfileParser;\r
+    private $_simfileBuilder;\r
+    private $_userRepository;\r
     \r
     public function __construct(\r
         IHttpRequest $request,\r
         IHttpResponse $response,\r
         IUploadManager $uploadManager,\r
-        ISimfileRepository $repository\r
+        ISimfileRepository $repository,\r
+        IUserRepository $userRepository,\r
+        ISimfileParser $simfileParser,\r
+        ISimfileStepByStepBuilder $simfileBuilder\r
     ) {\r
         $this->_request = $request;\r
         $this->_response = $response;\r
         $this->_uploadManager = $uploadManager;\r
         $this->_simfileRepository = $repository;\r
+        $this->_userRepository = $userRepository;\r
+        $this->_simfileParser = $simfileParser;\r
+        $this->_simfileBuilder = $simfileBuilder;\r
     }\r
     \r
     public function indexAction() {\r
@@ -81,22 +95,52 @@ class SimfileController implements IDivineController
     public function uploadAction()\r
     {        \r
         //logic for if pack or individual file\r
-        \r
+        $request = $this->_request->post();\r
+        //XXX: Could be a place UserService could look for token ?\r
+        $token = $request['token'];\r
+                \r
         //TODO: Put directory in config ?\r
         $filenames = $this->_uploadManager->setDestination('../files/StepMania/')\r
                                           ->process();\r
         \r
-        //parse .sm files and save to DB. should use SimfileParser service\r
-        \r
-        echo '<pre>';\r
         print_r($filenames);\r
-        echo '</pre>';\r
-    }\r
-    \r
-    public function testAction($testArg)\r
-    {\r
-        $this->_response->setHeader('Content-Type', 'application/json')\r
-                        ->setBody(json_encode(array('testArg' => $testArg)))\r
-                        ->sendResponse();\r
+        foreach($filenames as $filename => $hash)\r
+        {\r
+            $za = new ZipArchive();\r
+            //XXX: We assume all files are zips. Should be enforced by validation elsewhere.\r
+            $res = $za->open('../files/StepMania/' . $hash . '.zip');\r
+            \r
+            if($res !== true) throw new Exception ('Could not open zip for reading.');\r
+            \r
+            for($i=0; $i<$za->numFiles; $i++)\r
+            {\r
+                $stat = $za->statIndex($i);\r
+                if(pathinfo($stat['name'], PATHINFO_EXTENSION) == 'sm')\r
+                {\r
+                    $smData = file_get_contents('zip://../files/StepMania/' . $hash . '.zip#' . $stat['name']);\r
+                    break;\r
+                }\r
+            }\r
+        }\r
+        \r
+        if(!$smData) throw new Exception('Could not extract simfile.');\r
+        \r
+        /* @var $parser \Services\ISimfileParser */\r
+        $parser = $this->_simfileParser;\r
+        $parser->parse($smData);\r
+\r
+        //TODO: Instantiating VOs like this bad ?\r
+        $this->_simfileBuilder->With_Title($parser->title())\r
+                              ->With_Artist(new \Domain\VOs\StepMania\Artist($parser->artist()))\r
+                              ->With_Uploader($this->_userRepository->findByAuthToken($token)) //obj\r
+                              ->With_BPM($bpm) //obj\r
+                              ->With_BpmChanges($parser->bpmChanges())\r
+                              ->With_Stops($parser->stops())\r
+                              ->With_FgChanges($parser->fgChanges())\r
+                              ->With_BgChanges($parser->bgChanges())\r
+                              ->With_Steps($steps) //obj\r
+                              ->build();\r
+\r
+        //parse .sm files and save to DB. should use SimfileParser service\r
     }\r
 }\r
index b98ddd2..e4acdc3 100644 (file)
@@ -7,6 +7,8 @@ use DataAccess\DataMapper\IDataMapper;
 use Domain\Entities\IUser;
 use DataAccess\Queries\IQueryBuilderFactory;
 use Services\IFacebookSessionFactory;
+use Facebook\FacebookRequest;
+use Facebook\GraphUser;
 
 //TODO: Implement some sort of caching. Probably OK for now not to worry.
 class UserRepository implements IUserRepository
@@ -53,7 +55,9 @@ class UserRepository implements IUserRepository
     
     public function findByAuthToken($token) {
         $facebookSession = $this->_facebookSessionFactory->createInstance($token);
-        $id = $facebookSession->getGraphObject(GraphUser::className())->getId();
+        $facebookRequest = (new FacebookRequest($facebookSession, 'GET', '/me?fields=hometown,first_name,last_name'))->execute();
+        
+        $id = $facebookRequest->getGraphObject(GraphUser::className())->getId();
         
         return $this->findByFacebookId($id);
     }
index a7e2208..059dec0 100644 (file)
@@ -4,8 +4,10 @@ namespace Services;
 
 interface ISimfileParser
 {
+    public function parse($smFileData);
     public function title();
     public function subtitle();
+    public function artist();
     public function bpmChanges();
     public function stops();
     public function bgChanges();
diff --git a/Services/IUserSession.php b/Services/IUserSession.php
new file mode 100644 (file)
index 0000000..96b13dd
--- /dev/null
@@ -0,0 +1,9 @@
+<?php
+
+namespace Services;
+
+interface IUserSession
+{
+    public function getCurrentUser();
+}
+
index 8eb0409..ee485e7 100644 (file)
@@ -18,48 +18,109 @@ class SimfileParser implements ISimfileParser
     
     private $_smFileLines;
         
-    public function __construct($simfileData)
+    public function parse($simfileData)
     {
         //XXX: Should I explode on ';' instead? That seems like it might be a more reliable delimiter
-        $this->_smFileLines = explode("\n", $simfileData);
+        $this->_smFileLines = explode(";", $simfileData);
     }
     
     public function title()
     {
         $title = $this->extractKey('TITLE');
-        if(!$title) throw new Exception ('Invalid SM file. Title missing');
+        if(!$title) throw new Exception ('Invalid SM file. TITLE missing');
         
         return $title;
     }
     
+    public function artist()
+    {
+        $artist = $this->extractKey('ARTIST');
+        if(!$artist) throw new Exception ('Invalid SM file. ARTIST missing');
+        
+        return $artist;
+    }
+    
     public function stops()
     {
-        return $this->extractKey('STOPS') ? 'Yes' : 'No';
+        $stops = $this->extractKey('STOPS') ? 'Yes' : 'No';
+        if(!$stops) throw new Exception ('Invalid SM file. STOPS missing');
+        
+        return $stops;
     }
     
-    public function steps($mode, $difficulty)
+    public function fgChanges()
     {
-        $steps = array();
+        $fgChanges = $this->extractKey('FGCHANGES') ? 'Yes' : 'No';
+        if(!$fgChanges) throw new Exception ('Invalid SM file. FGCHANGES missing');
+        
+        return $fgChanges;
+    }
+    
+    public function bgChanges()
+    {
+        $bgChanges = $this->extractKey('BGCHANGES') ? 'Yes' : 'No';
+        if(!$bgChanges) throw new Exception ('Invalid SM file. BGCHANGES missing');
+        
+        return $bgChanges;
+    }
+    
+    public function bpmChanges() 
+    {
+        $bmpChanges = $this->extractKey('BPMS') ? 'Yes' : 'No';
+        if(!$bpmChanges) throw new Exception ('Invalid SM file. BPMS missing');
+        
+        return $bpmChanges;
+    }
+    
+    public function subtitle()
+    {
+        $subtitle = $this->extractKey('SUBTITLE');
+        if(!$subtitle) throw new Exception ('Invalid SM file. SUBTITLE missing');
         
-        foreach ($this->_smFileLines as $index => $line) {
-            if (strpos($line, '#NOTES') !== false) {
-                $mode = substr(trim($lines[$index + 1]), 0, -1) == 'dance-single' ? 'single' : null;
-                $notes[$mode][] = array(
-                    'artist' => substr(trim($lines[$index + 2]), 0, -1),
-                    'difficulty' => substr(trim($lines[$index + 3]), 0, -1),
-                    'rating' => substr(trim($lines[$index + 4]), 0, -1)
-                );
+        return $subtitle;
+    }
+    
+    function steps()
+    {
+        if(empty($this->_smFileLines)) throw new Exception('SM file data not set.');
+        $allSteps = array();
+
+        foreach ($this->_smFileLines as $line)
+        {
+            $pos = strpos($line, '#NOTES:');
+            if ($pos !== false)
+            {
+                $noteData = trim(substr($line, $pos + 9));
+                $allSteps = array_merge($allSteps, $this->stepsArrayFromNoteData($noteData));
             }
         }
 
+        if(empty($allSteps)) throw new Exception('Invalid Sm file. NOTES missing');
+        return $allSteps;
+    }
+
+    private function stepsArrayFromNoteData($noteData)
+    {
+        $stepData = array_map('trim', explode(':', $noteData));
+        $steps = array();
+        $mode = $stepData[0] == 'dance-single' ? 'single' : null;
+        $steps[$mode][] = array(
+            'artist' => $stepData[1],
+            'difficulty' => $stepData[2],
+            'rating' => $stepData[3]
+        );
+        
         return $steps;
     }
     
-    private function extractKey($key) {
-        foreach ($lines as $line) {
+    private function extractKey($key)
+    {
+        if(empty($this->_smFileLines)) throw new Exception('SM file data not set.');
+        
+        foreach ($this->_smFileLines as $line)
+        {
             $pos = strpos($line, '#' . $key . ':');
-            if($pos !== false) return substr(trim($line), strlen($key) + 2, -1);
+            if ($pos !== false) return trim(substr($line, $pos + strlen($key) + 2));
         }
     }
-
 }
diff --git a/Services/Uploads/UserSession.php b/Services/Uploads/UserSession.php
new file mode 100644 (file)
index 0000000..ec941e6
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+namespace Services;
+
+use Services\IUserSession;
+use Services\Http\IHttpRequest;
+use DataAccess\IUserRepository;
+
+class UserSession implements IUserSession
+{
+    private $_httpRequest;
+    private $_userRepository;
+    private $_currentUser;
+    
+    public function __construct(IHttpRequest $httpRequest, IUserRepository $userRepository)
+    {
+        $this->_httpRequest = $httpRequest;
+        $this->_userRepository = $userRepository;
+    }
+    
+    public function getCurrentUser() {
+        if(empty($this->_currentUser))
+        {
+            $request = $this->_httpRequest->isGet() ? $this->_httpRequest->get() 
+                                                    : json_decode($this->_httpRequest->getBody(), true);
+
+            $token = isset($request['token']) ? $request['token'] : null;
+            $this->_currentUser = $this->_userRepository->findByAuthToken($token);
+        }
+        
+        return $this->_currentUser;
+    }
+}
+
index 86dbb1f..c5afcff 100644 (file)
@@ -12,6 +12,9 @@ return [
     'Domain\Entities\IUserStepByStepBuilder' => DI\object('Domain\Entities\UserStepByStepBuilder'),\r
     'Domain\Entities\IUserBuilder' => DI\object('Domain\Entities\UserBuilder'),\r
     'Domain\Entities\IUserFactory' => DI\object('Domain\Entities\UserFactory'),\r
+    'Domain\Entities\StepMania\ISimfileStepByStepBuilder' => DI\object('Domain\Entities\StepMania\SimfileStepByStepBuilder'),\r
+    'Domain\Entities\StepMania\ISimfileBuilder' => DI\object('Domain\Entities\StepMania\SimfileBuilder'),\r
+    'Domain\Entities\StepMania\ISimfileFactory' => DI\object('Domain\Entities\StepMania\SimfileFactory'),\r
     \r
     //services\r
     'Services\Http\IHttpResponse' => DI\object('Services\Http\HttpResponse'),\r
@@ -22,6 +25,7 @@ return [
     'Services\Uploads\IFileFactory' => DI\object('Services\Uploads\FileFactory'),\r
     'Services\IFacebookSessionFactory' => DI\object('Services\FacebookSessionFactory')\r
         ->constructor(DI\link('facebook.app')),\r
+    'Services\ISimfileParser' => DI\object('Services\SimfileParser'),\r
     \r
     //DA\r
     'DataAccess\StepMania\ISimfileRepository' => DI\object('DataAccess\StepMania\SimfileRepository'),\r
index 17e529f..7b8f8dd 100644 (file)
@@ -25,4 +25,3 @@ $controller = $container->get('Controllers\\' . ucfirst($controllerName) . 'Cont
 \r
 // Last thing to do, call the action on the specified controller.\r
 call_user_func_array(array($controller, $controllerAction . 'Action'), $controllerActionArgs);\r
-\r
index 953aeb4..a551bb2 100644 (file)
@@ -2,6 +2,7 @@
     <body>
         <form action="/simfiles/upload" method="post" enctype="multipart/form-data">
             <input type="file" name="file" id="file" />
+            <input type="hidden" name="token" value="CAAFdJomTiBABAJqHJZBRqz3CMkFMfTlSbtUJsEeZCBUuPxl1ugT9Q4mVfwnYLdfAlwblEjFcYqliNwZBNIplbEZCNCEZBZCjX2Xp3bIvflBv0YYAATZCRgJkzq0S2SdfOY5pFEvRCWxZCH9SHBh1R6eqMmuDR1h5vSq4SDY9sMpf0G1nwtw5VRGz" />
             <input type="submit" name="submit" value="submit" />
         </form>
     </body>