I think uploading packs is more or less working. I nutted out a few bugs in a lot...
authorCameron Ball <cameron@getapproved.com.au>
Mon, 24 Nov 2014 08:45:41 +0000 (16:45 +0800)
committerCameron Ball <cameron@getapproved.com.au>
Mon, 24 Nov 2014 08:45:41 +0000 (16:45 +0800)
20 files changed:
Controllers/PackTestController.php
Controllers/SimfileController.php
DataAccess/DataMapper/DataMapper.php
DataAccess/DataMapper/Helpers/VOMapsHelper.php
Domain/Entities/AbstractEntity.php
Domain/Entities/StepMania/ISimfile.php
Domain/Entities/StepMania/ISimfileBuilder.php
Domain/Entities/StepMania/PackBuilder.php
Domain/Entities/StepMania/PackFactory.php
Domain/Entities/StepMania/PackStepByStepBuilder.php
Domain/Entities/StepMania/Simfile.php
Domain/Entities/StepMania/SimfileBuilder.php
Domain/Entities/StepMania/SimfileFactory.php
Domain/Entities/StepMania/SimfileStepByStepBuilder.php
Domain/VOs/StepMania/StepChart.php
Services/BannerExtracter.php
Services/SimfileParser.php
Services/Uploads/UploadManager.php
Services/ZipParser.php
config/DataMaps.php

index 656f9f9..060514a 100644 (file)
@@ -17,7 +17,7 @@ class PackTestController implements IDivineController
     }\r
     \r
     public function indexAction() {\r
-        $pack = $this->_packRepository->findById(1);\r
+        $pack = $this->_packRepository->findById(10);\r
 \r
         echo '<pre>';\r
         print_r($pack);\r
index 00dc15c..defa951 100644 (file)
@@ -10,6 +10,8 @@ use Services\IZipParser;
 use DataAccess\StepMania\ISimfileRepository;\r
 use DataAccess\StepMania\IPackRepository;\r
 use DataAccess\IFileRepository;\r
+use Domain\Entities\StepMania\ISimfile;\r
+use Domain\Entities\StepMania\IPack;\r
 \r
 class SimfileController implements IDivineController\r
 {\r
@@ -103,20 +105,26 @@ class SimfileController implements IDivineController
             $zipParser->parse($file);\r
             \r
             //save the actual zip in the db\r
-            //$this->_fileRepository->save($file);  \r
-            foreach($zipParser->simfiles() as $simfile)\r
-            {\r
-                $this->_fileRepository->save($simfile->getBanner());\r
-                $this->_fileRepository->save($simfile->getSimfile());\r
-                $this->_simfileRepository->save($simfile);\r
-            }\r
+            $this->_fileRepository->save($file);  \r
             \r
             if($zipParser->isPack())\r
             {\r
+                //XXX: Tricky! pack() uses packbuilder and so returns a new pack each time.\r
+                //I tried to be clever and call pack() multiple times thinking I was getting the same\r
+                //object. Should I cache it in zipparser?\r
                 $pack = $zipParser->pack();\r
                 $this->_fileRepository->save($pack->getBanner());\r
                 $this->_packRepository->save($pack);\r
             }\r
+            \r
+            foreach($zipParser->simfiles() as $simfile)\r
+            {   \r
+                $banner = $simfile->getBanner() ? $this->_fileRepository->save($simfile->getBanner()) : null;\r
+                $simfileZip = $simfile->getSimfile() ? $this->_fileRepository->save($simfile->getSimfile()) : null;\r
+\r
+                if(isset($pack)) $simfile->addToPack($pack);\r
+                $this->_simfileRepository->save($simfile);\r
+            }\r
         }\r
     }\r
 }\r
index 24b7994..24a7d5a 100644 (file)
@@ -23,7 +23,7 @@ class DataMapper implements IDataMapper
     public function map($entityName, IQueryBuilder $queryBuilder)\r
     {\r
         $queryString = $queryBuilder->buildQuery();\r
-        \r
+\r
         $statement = $this->_db->prepare(sprintf($queryString,\r
             $this->_maps[$entityName]['table']\r
         ));\r
@@ -56,6 +56,12 @@ class DataMapper implements IDataMapper
     public function save(IDivineEntity $entity)\r
     {\r
         $queries = AbstractPopulationHelper::generateUpdateSaveQuery($this->_maps, $entity, $entity->getId(), $this->_db);\r
+        $mergeMap = array();\r
+        \r
+        echo 'pre flattened: <br />';\r
+        echo '<pre>';\r
+        print_r($queries);\r
+        echo '</pre>';\r
         \r
         $flattened = array();\r
         $flattened_tables = array();\r
@@ -63,26 +69,49 @@ class DataMapper implements IDataMapper
         {\r
             $this_table = $query['table'];\r
             $this_columns = $query['columns'];\r
-            \r
+            $flatten = true;\r
             for($i = $index+1; $i<count($queries); $i++)\r
             {\r
                 if($queries[$i]['table'] == $this_table && !in_array($queries[$i]['table'], $flattened_tables) && !isset($query['id'])) //only merge create queries, updates are fine to run multiple times\r
                 {\r
-                    $this_columns = array_merge($this_columns, $queries[$i]['columns']);\r
+                    //XXX: This whole biz is tricky. Basically the problem is that when creating a new simfile,\r
+                    //the datamapper spews out a bunch of create queries. When parsing a simfile for example, there can\r
+                    //be huge redundency - it may produce 5 queries that all create the same step artist, for example.\r
+                    //We attempt to flatten equivalent queries. Originally I was basing it purely on the table name or something,\r
+                    //but that is not enough. In the case of steps, it ends up mergin all the steps together, so we need to\r
+                    //check if the arrays are equal as well, which is what this does.\r
+                    if($this_columns === $queries[$i]['columns'])\r
+                    {\r
+                        $this_columns = array_merge($this_columns, $queries[$i]['columns']);\r
+                        //need to keep track of what we merged as future queries might reference the old ids.\r
+                        $mergeMap[$i] = $index;\r
+                    } else {\r
+                        //we need to add these unmerged ones here as further down we record that anything to\r
+                        //do with this table has been sorted out.\r
+//                        $prepared = isset($queries[$i]['prepared']) ? $queries[$i]['prepared'] : null;\r
+//                        $id = isset($queries[$i]['id']) ? $queries[$i]['id'] : null;\r
+//                        $flattened[] = array('columns' => $queries[$i]['columns'], 'table' => $queries[$i]['table'], 'prepared' => $prepared, 'id' => $id);\r
+                        $flatten = false;\r
+                    }\r
                 }\r
             }\r
             \r
             if(!in_array($this_table, $flattened_tables))\r
             {\r
-                $flattened_tables[] = $this_table;\r
+                if($flatten) $flattened_tables[] = $this_table;\r
                 $prepared = isset($query['prepared']) ? $query['prepared'] : null;\r
                 $id = isset($query['id']) ? $query['id'] : null;\r
                 $flattened[] = array('columns' => $this_columns, 'table' => $this_table, 'prepared' => $prepared, 'id' => $id);\r
             }\r
         }\r
         \r
-        $queries = array();\r
+        echo 'flattened: <br />';\r
+        echo '<pre>';\r
+        print_r($flattened);\r
+        echo '</pre>';\r
         \r
+        $queries = array();\r
+                \r
         foreach($flattened as $info)\r
         {\r
             if(isset($info['id']))\r
@@ -99,7 +128,7 @@ class DataMapper implements IDataMapper
             \r
             $queries[] = $query;\r
         }\r
-        \r
+                        \r
        // if($queries['TYPE'] == AbstractPopulationHelper::QUERY_TYPE_CREATE)\r
        // {\r
             $idMap = [];\r
@@ -123,8 +152,15 @@ class DataMapper implements IDataMapper
                 {\r
                     $statement = $this->_db->prepare($query);\r
                     $statement->execute();\r
-                    $refIndex = $index+1;\r
-                    $idMap['INDEX_REF_' . $refIndex] = $this->_db->lastInsertId();\r
+                    //$refIndex = $index+1; This was being used as the index for idMap below. I have nfi why I was adding 1.\r
+                    $idMap['INDEX_REF_' . $index] = $this->_db->lastInsertId();\r
+                    \r
+                    foreach($mergeMap as $oldIndex => $mergedIndex) {\r
+                        if($mergedIndex == $index) {\r
+                            $idMap['INDEX_REF_' . $oldIndex] = $idMap['INDEX_REF_' . $index];\r
+                        }\r
+                    }\r
+                    \r
                     unset($queries[$index]);\r
                 } else {\r
                     //update query so that other references are resolved.\r
@@ -140,8 +176,8 @@ class DataMapper implements IDataMapper
                 $statement->execute();\r
             }\r
         //}\r
-            \r
-        $entity->setId(end($idMap));\r
+        \r
+        if(!$entity->getId()) $entity->setId(end($idMap));\r
         \r
         return $entity;\r
     }\r
index 497d5fe..9a1f2cc 100644 (file)
@@ -48,10 +48,11 @@ class VOMapsHelper
     {\r
         $className = $maps[$this->_voName]['class'];\r
         $table = $maps[$this->_voName]['table'];\r
-\r
+        \r
         // If the table we already have contains the id of a row we need in\r
         // another table        \r
-        if(isset($row[$this->_tableName . '_id'])) {\r
+        //if(isset($row[$this->_tableName . '_id'])) {\r
+        if(array_key_exists($this->_tableName . '_id', $row)) { //this is a better choice as somtimes the array key is set, but is equal to null, and isset doesn't like that\r
             $join_id = $row[$this->_tableName . '_id'];\r
             $statement = $db->prepare(sprintf('SELECT * from %s WHERE id=%u',\r
                 $table,\r
index 7d36796..c847865 100644 (file)
@@ -2,6 +2,7 @@
 \r
 namespace Domain\Entities;\r
 \r
+use Exception;\r
 use Domain\Entities\IDivineEntity;\r
 \r
 abstract class AbstractEntity implements IDivineEntity\r
index 40e179f..655ad6b 100644 (file)
@@ -3,6 +3,7 @@
 namespace Domain\Entities\StepMania;\r
 \r
 use Domain\VOs\StepMania\IStepChart;\r
+use Domain\Entities\StepMania\IPack;\r
 use Domain\Entities\IDivineEntity;\r
 \r
 interface ISimfile extends IDivineEntity\r
@@ -17,7 +18,8 @@ interface ISimfile extends IDivineEntity
     public function hasBgChanges();\r
     public function getBanner();\r
     public function getSimfile();\r
-        \r
+    public function addToPack(IPack $pack);\r
     public function addStepChart(IStepChart $stepChart);\r
     public function getSteps();\r
+    public function getPackId();\r
 }
\ No newline at end of file
index 3f76097..ecbe677 100644 (file)
@@ -17,8 +17,9 @@ interface ISimfileBuilder
     public function With_Stops($const);\r
     public function With_FgChanges($const);\r
     public function With_BgChanges($const);\r
-    public function With_Banner(IFile $banner);\r
-    public function With_Simfile(Ifile $simfile);\r
+    public function With_Banner(IFile $banner = null);\r
+    public function With_Simfile(Ifile $simfile = null);\r
+    public function With_PackId($packId = null);\r
     public function With_Steps(array $steps);\r
     public function build();\r
 }
\ No newline at end of file
index 3a52a36..3abb934 100644 (file)
@@ -56,6 +56,8 @@ class PackBuilder implements IPackBuilder
     {
         return $this->_packFactory->createInstance($this->_title,
                                                    $this->_uploader,
-                                                   $this->_simfiles);
+                                                   $this->_simfiles,
+                                                   $this->_banner,
+                                                   $this->_file);
     }
 }
\ No newline at end of file
index b59c49a..dcaf260 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace Domain\Entities\StepMania;
 
+use Domain\Entities\IFile;
 use Domain\Entities\StepMania\Pack;
 use Domain\Entities\IUser;
 
index cc53507..3c02ed1 100644 (file)
@@ -71,7 +71,7 @@ class PackStepByStepBuilder_With_Simfiles extends AbstractPackStepByStepBuilder
 {
     public function With_Banner(IFile $banner)
     {
-        $this->_packBuilder->With_File($banner);
+        $this->_packBuilder->With_Banner($banner);
         return $this;
     }
     
@@ -83,7 +83,7 @@ class PackStepByStepBuilder_With_Simfiles extends AbstractPackStepByStepBuilder
 
     public function build()
     {
-        return $this->_simfileBuilder
+        return $this->_packBuilder
                     ->build();
     }
 }
index 243f02f..7071e0b 100644 (file)
@@ -5,9 +5,9 @@ namespace Domain\Entities\StepMania;
 use Domain\VOs\StepMania\IArtist;\r
 use Domain\VOs\StepMania\IBPM;\r
 use Domain\VOs\StepMania\IStepChart;\r
-use Domain\ConstantsAndTypes\SIMFILE_CONSTANT;\r
 use Domain\Exception\InvalidStepChartException;\r
 use Domain\Entities\StepMania\ISimfile;\r
+use Domain\Entities\StepMania\IPack;\r
 use Domain\Entities\IUser;\r
 use Domain\Entities\IFile;\r
 use Domain\Entities\AbstractEntity;\r
@@ -25,6 +25,7 @@ class Simfile extends AbstractEntity implements ISimfile
     private $_banner;\r
     private $_simfile;\r
     private $_steps;\r
+    private $_packId;\r
     \r
     public function __construct(\r
         $title,\r
@@ -37,6 +38,7 @@ class Simfile extends AbstractEntity implements ISimfile
         $bgChanges,\r
         IFile $banner = null,\r
         IFile $simfile = null,\r
+        $packId = null,\r
         array $steps\r
     ) {\r
         $this->_title = $title;\r
@@ -49,6 +51,7 @@ class Simfile extends AbstractEntity implements ISimfile
         $this->_bgChanges = $bgChanges;\r
         $this->_banner = $banner;\r
         $this->_simfile = $simfile;\r
+        $this->_packId = $packId;\r
 \r
         foreach($steps as $stepChart) {\r
             if(!$stepChart instanceof IStepChart) {\r
@@ -117,4 +120,13 @@ class Simfile extends AbstractEntity implements ISimfile
     {\r
         return $this->_steps;\r
     }\r
+    \r
+    public function addToPack(IPack $pack) {\r
+        $this->_packId = $pack->getId();\r
+    }\r
+    \r
+    public function getPackId()\r
+    {\r
+        return $this->_packId;\r
+    }\r
 }\r
index c8afcd2..6c87aa9 100644 (file)
@@ -22,6 +22,7 @@ class SimfileBuilder implements ISimfileBuilder
     private $_bgChanges;\r
     private $_banner;\r
     private $_simfile;\r
+    private $_packId;\r
     private $_steps;\r
     \r
     //override parent\r
@@ -70,16 +71,22 @@ class SimfileBuilder implements ISimfileBuilder
         return $this;\r
     }\r
     \r
-    public function With_Banner(IFile $banner) {\r
+    public function With_Banner(IFile $banner = null) {\r
         $this->_banner = $banner;\r
         return $this;\r
     }\r
     \r
-    public function With_Simfile(IFile $simfile) {\r
+    public function With_Simfile(IFile $simfile = null) {\r
         $this->_simfile = $simfile;\r
         return $this;\r
     }\r
     \r
+    public function With_PackId($packId = null)\r
+    {\r
+        $this->_packId = $packId;\r
+        return $this;\r
+    }\r
+    \r
     public function With_Steps(array $steps) {\r
         $this->_steps = $steps;\r
         return $this;\r
@@ -97,6 +104,7 @@ class SimfileBuilder implements ISimfileBuilder
                                      $this->_bgChanges,\r
                                      $this->_banner,\r
                                      $this->_simfile,\r
+                                     $this->_packId,\r
                                      $this->_steps);\r
     }\r
 }\r
index 33c939a..eda0ea3 100644 (file)
@@ -21,6 +21,7 @@ interface ISimfileFactory
         $bgChanges,\r
         IFile $banner,\r
         IFile $simfile,\r
+        $packId = null,\r
         array $steps\r
     );\r
 }\r
@@ -38,6 +39,7 @@ class SimfileFactory implements ISimfileFactory
         $bgChanges,\r
         IFile $banner = null,\r
         IFile $simfile = null,\r
+        $packId = null,\r
         array $steps\r
     ) {\r
         return new Simfile(\r
@@ -51,6 +53,7 @@ class SimfileFactory implements ISimfileFactory
             $bgChanges,\r
             $banner,\r
             $simfile,\r
+            $packId,\r
             $steps\r
         );\r
     }\r
index d0b9971..2408d2f 100644 (file)
@@ -55,8 +55,9 @@ interface ISimfileStepByStepBuilder_With_BgChanges
 \r
 interface ISimfileStepByStepBuilder_With_Steps\r
 {\r
-    public function With_Banner(IFile $banner);\r
-    public function With_Simfile(IFile $simfile);\r
+    public function With_Banner(IFile $banner = null);\r
+    public function With_Simfile(IFile $simfile = null);\r
+    public function With_PackId($packId = null);\r
     public function build();\r
 }\r
 \r
@@ -155,18 +156,24 @@ class SimfileStepByStepBuilder_With_BgChanges extends AbstractSimfileStepByStepB
 \r
 class SimfileStepByStepBuilder_With_Steps extends AbstractSimfileStepByStepBuilder implements ISimfileStepByStepBuilder_With_Steps\r
 {\r
-    public function With_Banner(IFile $banner)\r
+    public function With_Banner(IFile $banner = null)\r
     {\r
         $this->_simfileBuilder->With_Banner($banner);\r
         return new SimfileStepByStepBuilder_With_Steps($this->_simfileBuilder); //TODO: Pretty sure return $this will be OK\r
     }\r
     \r
-    public function With_Simfile(IFile $simfile)\r
+    public function With_Simfile(IFile $simfile = null)\r
     {\r
         $this->_simfileBuilder->With_Simfile($simfile);\r
         return new SimfileStepByStepBuilder_With_Steps($this->_simfileBuilder);\r
     }\r
     \r
+    public function With_PackId($packId = null)\r
+    {\r
+        $this->_simfileBuilder->With_PackId($packId);\r
+        return new SimfileStepByStepBuilder_With_Steps($this->_simfileBuilder);\r
+    }\r
+    \r
     public function build()\r
     {\r
         return $this->_simfileBuilder\r
index 8951b11..a13dea4 100644 (file)
@@ -19,7 +19,7 @@ class StepChart implements IStepChart
     function __construct(\r
         DanceMode $mode,\r
         Difficulty $difficulty,\r
-        StepArtist $artist,\r
+        StepArtist $artist = null,\r
         $rating\r
     ) {\r
         $this->mode = $mode;\r
index 1fc49f3..2de532d 100644 (file)
@@ -84,7 +84,7 @@ class BannerExtracter implements IBannerExtracter
         }
         
         if(!isset($result) || !$result) return null;
-
+        
         $finfo = new finfo(FILEINFO_MIME);
         $mimetype = $finfo->file('../files/banners/' . $this->_destinationFileName);
         $size = filesize('../files/banners/' . $this->_destinationFileName);
index bc75ba0..b5c0c64 100644 (file)
@@ -125,7 +125,7 @@ class SimfileParser implements ISimfileParser
         return new \Domain\VOs\StepMania\StepChart(
             new \Domain\VOs\StepMania\DanceMode($stepData[0]),
             new \Domain\VOs\StepMania\Difficulty($stepData[2]),
-            new \Domain\VOs\StepMania\StepArtist($stepData[1]),
+            empty($stepData[1]) ? null : new \Domain\VOs\StepMania\StepArtist($stepData[1]),
             $stepData[3]
         );
     }
index 7f381c1..8530c2b 100644 (file)
@@ -8,7 +8,6 @@ use Services\Uploads\IFile;
 //This was a bit silly, I have a File object to use with the service but there is also a File entity.
 //It's confusing but if you pay attention it should be OK.
 use Domain\Entities\IFileStepByStepBuilder;
-use DataAccess\IFileRepository;
 use Exception;
 
 class UploadManager implements IUploadManager{        
@@ -18,12 +17,10 @@ class UploadManager implements IUploadManager{
     private $_basePath;
     private $_destination;
     private $_fileBuilder;
-    private $_fileRepository;
         
-    public function __construct(IFileFactory $fileFactory, IFileStepByStepBuilder $builder, IFileRepository $fileRepository) {
+    public function __construct(IFileFactory $fileFactory, IFileStepByStepBuilder $builder) {
         $this->_fileFactory = $fileFactory;
         $this->_fileBuilder = $builder;
-        $this->_fileRepository = $fileRepository;
         
         if($_FILES) {
             foreach($_FILES as $file)
index 822c0fd..d0418a7 100644 (file)
@@ -54,12 +54,13 @@ class ZipParser implements IZipParser
         {         
             $packname = $this->packNameFromFiles();
             $banner = $this->_bannerExtracter->extractPackBanner('../files/StepMania/' . $this->_file->getHash() . '.zip', $packname);
-            
+
             /* @var $builder \Domain\Entities\StepMania\PackStepByStepBuilder */
             $builder = $this->_packBuilder;
             return $builder->With_Title($packname)
                            ->With_Uploader($this->_userSession->getCurrentUser())
-                           ->With_Simfiles($this->_smFiles)
+                           //->With_Simfiles($this->_smFiles)
+                           ->With_Simfiles(array())
                            ->With_Banner($banner)
                            ->With_File($this->_file)
                            ->build();
@@ -89,9 +90,15 @@ class ZipParser implements IZipParser
             if(pathinfo($stat['name'], PATHINFO_EXTENSION) == 'sm')
             {
                 $smData = file_get_contents('zip://../files/StepMania/' . $this->_file->getHash() . '.zip#' . $stat['name']);
-                $this->_smFiles[$stat['name']] = $this->SmDataToSmClass($smData);
+                $this->_smFiles[$stat['name']] = $smData;
             }
         }
+        
+        //XXX: Hack. SmDataToSmClass needs to know whether we are dealing with a pack
+        //or single, but to do that we simply check the number of found sm files. To overcome this
+        //first populate the smFiles array with the raw sm data, then apply SmDataToSmClass on each
+        //array element. This way the check is accurate and the array gets populated as expected.
+        $this->_smFiles = array_map(array($this, 'SmDataToSmClass'), $this->_smFiles);
     }
     
     private function packNameFromFiles()
@@ -115,9 +122,9 @@ class ZipParser implements IZipParser
     {
         $parser = $this->_smParser;
         $parser->parse($smData);
-
         $banner = $this->_bannerExtracter->extractSongBanner('../files/StepMania/' . $this->_file->getHash() . '.zip', $parser->banner());
-
+        $file = $this->isPack() ? null : $this->_file;
+        
         return $this->_smBuilder->With_Title($parser->title())
                                 ->With_Artist($parser->artist())
                                 ->With_Uploader($this->_userSession->getCurrentUser()) //obj
@@ -127,7 +134,7 @@ class ZipParser implements IZipParser
                                 ->With_FgChanges($parser->fgChanges())
                                 ->With_BgChanges($parser->bgChanges())
                                 ->With_Steps($parser->steps())
-                                ->With_Simfile($this->_file)
+                                ->With_Simfile($file)
                                 ->With_Banner($banner)
                                 ->build();
     }
index 1d6a2e7..a647632 100644 (file)
@@ -22,6 +22,7 @@ return [
             'bgChanges' => DataAccess\Int('bg_changes', 'hasBgChanges'),\r
             'banner' => DataAccess\Entity('File', 'getBanner', 'banner_file'),\r
             'simfile' => DataAccess\Entity('File', 'getSimfile', 'simfile_file'),\r
+            'packId' => DataAccess\Int('pack_id', 'getPackId'),\r
             'steps' => DataAccess\VOArray('StepChart', 'getSteps')\r
         ]\r
     ],\r