--- /dev/null
+<?php\r
+\r
+namespace Controllers;\r
+\r
+use Controllers\IDivineController;\r
+use DataAccess\StepMania\IPackRepository;\r
+use DataAccess\StepMania\ISimfileRepository;\r
+\r
+class PackTestController implements IDivineController\r
+{\r
+ private $_packRepository;\r
+ \r
+ public function __construct(\r
+ IPackRepository $repository\r
+ ) {\r
+ $this->_packRepository = $repository;\r
+ }\r
+ \r
+ public function indexAction() {\r
+ $pack = $this->_packRepository->findById(1);\r
+\r
+ echo '<pre>';\r
+ print_r($pack);\r
+ echo '</pre>';\r
+ }\r
+}\r
\r
namespace Controllers;\r
\r
-use ZipArchive;\r
-use Exception;\r
use Controllers\IDivineController;\r
use Services\Http\IHttpResponse;\r
use Services\Uploads\IUploadManager;\r
-use Services\ISimfileParser;\r
use Services\IUserSession;\r
-use Services\IBannerExtracter;\r
+use Services\IZipParser;\r
use DataAccess\StepMania\ISimfileRepository;\r
-use Domain\Entities\StepMania\ISimfileStepByStepBuilder;\r
+use DataAccess\StepMania\IPackRepository;\r
+use DataAccess\IFileRepository;\r
\r
class SimfileController implements IDivineController\r
{\r
private $_simfileRepository;\r
+ private $_packRepository;\r
+ private $_fileRepository;\r
private $_response;\r
private $_uploadManager;\r
- private $_simfileParser;\r
- private $_simfileBuilder;\r
- private $_userRepository;\r
private $_userSession;\r
- private $_bannerExtracter;\r
+ private $_zipParser;\r
\r
public function __construct(\r
IHttpResponse $response,\r
IUploadManager $uploadManager,\r
- ISimfileRepository $repository,\r
+ ISimfileRepository $simfileRepository,\r
+ IPackRepository $packRepository,\r
+ IFileRepository $fileRepository,\r
IUserSession $userSession,\r
- ISimfileParser $simfileParser,\r
- ISimfileStepByStepBuilder $simfileBuilder,\r
- IBannerExtracter $bannerExtracter\r
+ IZipParser $zipParser\r
) {\r
$this->_response = $response;\r
$this->_uploadManager = $uploadManager;\r
- $this->_simfileRepository = $repository;\r
+ $this->_simfileRepository = $simfileRepository;\r
+ $this->_packRepository = $packRepository;\r
+ $this->_fileRepository = $fileRepository;\r
$this->_userSession = $userSession;\r
- $this->_simfileParser = $simfileParser;\r
- $this->_simfileBuilder = $simfileBuilder;\r
- $this->_bannerExtracter = $bannerExtracter;\r
+ $this->_zipParser = $zipParser;\r
}\r
\r
public function indexAction() {\r
\r
foreach($files as $file)\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/' . $file->getHash() . '.zip');\r
+ $zipParser = $this->_zipParser;\r
+ $zipParser->parse($file);\r
\r
- if($res !== true) throw new Exception ('Could not open zip for reading.');\r
- \r
- for($i=0; $i<$za->numFiles; $i++)\r
+ //save the actual zip in the db\r
+ //$this->_fileRepository->save($file); \r
+ foreach($zipParser->simfiles() as $simfile)\r
{\r
- $stat = $za->statIndex($i);\r
- if(pathinfo($stat['name'], PATHINFO_EXTENSION) == 'sm')\r
- {\r
- $smData = file_get_contents('zip://../files/StepMania/' . $file->getHash() . '.zip#' . $stat['name']);\r
- break;\r
- }\r
+ $this->_fileRepository->save($simfile->getBanner());\r
+ $this->_fileRepository->save($simfile->getSimfile());\r
+ $this->_simfileRepository->save($simfile);\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
- $banner = $this->_bannerExtracter->extractBanner('../files/StepMania/' . $file->getHash() . '.zip', $parser->banner());\r
- \r
- //TODO: Create file object for banner and .zip then link them up\r
- //shouldn't need to use repository as the mapper can create the db entries\r
- //all in one go (I think ...)\r
- //\r
- //Need to make FileBuilder and FileStepByStepBuilder\r
- $simfile = $this->_simfileBuilder->With_Title($parser->title())\r
- ->With_Artist($parser->artist())\r
- ->With_Uploader($this->_userSession->getCurrentUser()) //obj\r
- ->With_BPM($parser->bpm())\r
- ->With_BpmChanges($parser->bpmChanges())\r
- ->With_Stops($parser->stops())\r
- ->With_FgChanges($parser->fgChanges())\r
- ->With_BgChanges($parser->bgChanges())\r
- ->With_Steps($parser->steps())\r
- ->With_Simfile($file)\r
- ->With_Banner($banner)\r
- ->build();\r
\r
- $this->_simfileRepository->save($simfile);\r
+ if($zipParser->isPack())\r
+ {\r
+ $pack = $zipParser->pack();\r
+ $this->_fileRepository->save($pack->getBanner());\r
+ $this->_packRepository->save($pack);\r
+ }\r
}\r
}\r
}\r
$class->setId($row['id']);\r
$entities[$row['id']] = $class;\r
}\r
-\r
+ \r
return $entities;\r
}\r
\r
foreach($queries as $query)\r
{\r
$query = str_replace('%MAIN_QUERY_ID%', end($idMap), $query);\r
- echo $query;\r
$statement = $this->_db->prepare($query);\r
$statement->execute();\r
}\r
\r
namespace DataAccess\DataMapper\Helpers;\r
\r
-use DataAccess\DataMapper\Helpers\VOMapsHelper;\r
-use Domain\Entities\IDivineEntity;\r
use Exception;\r
\r
class AbstractPopulationHelper\r
static function getConstrutorArray($maps, $entity, $row, $db)\r
{\r
$constructors = array();\r
- \r
+ \r
foreach($maps[$entity]['maps'] as $constructor => $mapsHelper)\r
{\r
switch(get_class($mapsHelper))\r
case 'DataAccess\DataMapper\Helpers\VOMapsHelper':\r
case 'DataAccess\DataMapper\Helpers\VOArrayMapsHelper':\r
case 'DataAccess\DataMapper\Helpers\EntityMapsHelper':\r
+ case 'DataAccess\DataMapper\Helpers\EntityArrayMapsHelper':\r
$constructors[$constructor] = $mapsHelper->populate($maps, $db, $entity, $row);\r
break;\r
}\r
}\r
- \r
return $constructors;\r
}\r
\r
// in the case of setting up a new entity, the VOs should never\r
// exist in the first place, so we just make them.\r
case 'DataAccess\DataMapper\Helpers\VOArrayMapsHelper':\r
+ case 'DataAccess\DataMapper\Helpers\EntityArrayMapsHelper':\r
if($id && isset($property[0]))\r
{\r
// If we assume that all elements in the array are the same then\r
// we can just use the first one to figure out which maps entry to use\r
\r
$subEntityMapsIndex = self::getMapsNameFromEntityObject($property[0], $maps);\r
+ //TODO: I think this function will work with Entities too, but I should probably rename it at some point\r
$voIds = self::mapVOArrayToIds($maps[$subEntityMapsIndex]['table'],\r
array(strtolower($entityMapsIndex . '_id'), $id),\r
$db);\r
\r
foreach($property as $index => $propertyArrayElement)\r
{\r
+ //XXX: I wanted this to only run on VOs, not entities. But there's a problem with that.\r
+ //when creating a pack, the simfile entities need to reference the pack, and the only way for\r
+ //that to happen is here. What I do instead is check that the entity has an id (which implies\r
+ //it has already been created and save) if it is a IDivineEntity. If it doesn't, complain.\r
+ //this ensures consistent behaviour with other parts of this mapper.\r
+ if($property instanceof \Domain\Entities\IDivineEntity && !$property->getId())\r
+ {\r
+ throw new Exception(sprintf(\r
+ 'Could not find referenced entity, %s, in the database. Has it been saved yet?',\r
+ $mapsHelper->getEntityName()));\r
+ }\r
+ \r
$extra = array(strtolower($entityMapsIndex . '_id') => $id);\r
if(isset($voIds[$index]))\r
{\r
} else {\r
foreach($property as $propertyArrayElement)\r
{\r
+ //XXX: I wanted this to only run on VOs, not entities. But there's a problem with that.\r
+ //when creating a pack, the simfile entities need to reference the pack, and the only way for\r
+ //that to happen is here. What I do instead is check that the entity has an id (which implies\r
+ //it has already been created and save) if it is a IDivineEntity. If it doesn't, complain.\r
+ //this ensures consistent behaviour with other parts of this mapper.\r
+ if($property instanceof \Domain\Entities\IDivineEntity && !$property->getId())\r
+ {\r
+ throw new Exception(sprintf(\r
+ 'Could not find referenced entity, %s, in the database. Has it been saved yet?',\r
+ $mapsHelper->getEntityName()));\r
+ }\r
+ \r
// TODO: TRICKY! Since this is a back-reference, it\r
// needs the ID of the object we're trying to save\r
// to complete\r
}\r
}\r
}\r
-// \r
-// if($id)\r
-// {\r
-// $query = substr($query, 0, -2);\r
-// $query .= sprintf(' WHERE id=%u', $id);\r
-// $queries['TYPE'] = self::QUERY_TYPE_UPDATE;\r
-// } else {\r
-// $queryColumnNamesAndValues = array_merge($queryColumnNamesAndValues, $extraColumns);\r
-// $query = sprintf('INSERT INTO %s (%s) VALUES (%s)',\r
-// $maps[$entityMapsIndex]['table'],\r
-// implode(', ', array_keys($queryColumnNamesAndValues)),\r
-// implode(', ', $queryColumnNamesAndValues));\r
-// $queries['TYPE'] = self::QUERY_TYPE_CREATE;\r
-// }\r
-// print_r($queryColumnNamesAndValues);\r
-// echo '<br />';\r
\r
if($id)\r
{\r
--- /dev/null
+<?php\r
+\r
+namespace DataAccess\DataMapper\Helpers;\r
+\r
+use ReflectionClass;\r
+\r
+class EntityArrayMapsHelper\r
+{\r
+ private $_entityName;\r
+ private $_tableName;\r
+ private $_accessor;\r
+ \r
+ public function __construct($entityName, $accessor, $tableName)\r
+ {\r
+ $this->_entityName = $entityName;\r
+ \r
+ if($tableName) {\r
+ $this->_tableName = $tableName;\r
+ } else {\r
+ $this->_tableName = strtolower($entityName);\r
+ }\r
+ \r
+ if($accessor)\r
+ {\r
+ $this->_accessor = $accessor;\r
+ } else\r
+ {\r
+ $this->_accessor = 'get'. str_replace('_', '', $entityName);\r
+ }\r
+ }\r
+ \r
+ public function getEntityName()\r
+ {\r
+ return $this->_entityName;\r
+ }\r
+ \r
+ public function getAccessor()\r
+ {\r
+ return $this->_accessor;\r
+ }\r
+ \r
+ public function getTableName()\r
+ {\r
+ return $this->_tableName;\r
+ }\r
+ \r
+ public function populate($maps, $db, $parent, $row)\r
+ {\r
+ $className = $maps[$this->_entityName]['class'];\r
+ $table = $maps[$this->_entityName]['table'];\r
+ $entityArray = array();\r
+\r
+ // in this case we look in another table for this row's id\r
+ $join_id = $row['id']; \r
+ $statement = $db->prepare(sprintf('SELECT * from %s WHERE %s=%u',\r
+ $table,\r
+ strtolower($parent . '_id'),\r
+ $join_id\r
+ ));\r
+ \r
+ $statement->execute();\r
+ $rows = $statement->fetchAll();\r
+ \r
+ foreach($rows as $row)\r
+ { \r
+ $constructors = AbstractPopulationHelper::getConstrutorArray($maps, $this->_entityName, $row, $db);\r
+\r
+ if(count($constructors) == 0)\r
+ {\r
+ $class = new $className;\r
+ } else {\r
+ $r = new ReflectionClass($className);\r
+ $class = $r->newInstanceArgs($constructors);\r
+ }\r
+ \r
+ $class->setId($row['id']);\r
+ $entityArray[] = $class;\r
+ }\r
+ \r
+ return $entityArray;\r
+ }\r
+}
\ No newline at end of file
use DataAccess\IFileRepository;
use DataAccess\DataMapper\IDataMapper;
use DataAccess\Queries\IQueryBuilderFactory;
-use Domain\Entities\IFile;
class FileRepository implements IFileRepository
{
--- /dev/null
+<?php
+
+namespace DataAccess\StepMania;
+
+use DataAccess\IRepository;
+use Domain\Entities\StepMania\IPack;
+
+interface IPackRepository extends IRepository
+{
+ public function findByTitle($title);
+ public function findByContributor($contributor);
+ public function save(IPack $entity);
+ public function remove(IPack $entity);
+}
+
+
--- /dev/null
+<?php\r
+\r
+namespace DataAccess\StepMania;\r
+\r
+use DataAccess\StepMania\IPackRepository;\r
+use DataAccess\DataMapper\IDataMapper;\r
+use DataAccess\Queries\IQueryBuilderFactory;\r
+use Domain\Entities\StepMania\IPack;\r
+\r
+//TODO: Implement some sort of caching. Probably OK for now not to worry.\r
+class PackRepository implements IPackRepository\r
+{\r
+ private $_dataMapper;\r
+ private $_queryBuilderFactory;\r
+ \r
+ public function __construct(IDataMapper $dataMapper, IQueryBuilderFactory $queryBuilderFactory) {\r
+ $this->_dataMapper = $dataMapper;\r
+ $this->_queryBuilderFactory = $queryBuilderFactory;\r
+ }\r
+ \r
+ public function findById($id) {\r
+ $queryBuilder = $this->_queryBuilderFactory->createInstance();\r
+ $queryBuilder->where('id', '=', $id);\r
+ \r
+ $result = $this->_dataMapper->map('Pack', $queryBuilder);\r
+ return reset($result);\r
+ }\r
+ \r
+ public function findRange($id, $limit)\r
+ {\r
+ $queryBuilder = $this->_queryBuilderFactory->createInstance();\r
+ $queryBuilder->where('id', '>=', $id)->limit($limit);\r
+ \r
+ return $this->_dataMapper->map('Pack', $queryBuilder);\r
+ }\r
+ \r
+ public function save(IPack $entity) {\r
+ return $this->_dataMapper->save($entity);\r
+ }\r
+ \r
+ //TODO: Implement\r
+ public function remove(IPack $entity) {\r
+ ;\r
+ }\r
+ \r
+ public function findByTitle($title)\r
+ {\r
+ $queryBuilder = $this->_queryBuilderFactory->createInstance();\r
+ $queryBuilder->where('title', 'LIKE', "%%$title%%");\r
+ \r
+ return $this->_dataMapper->map('Pack', $queryBuilder);\r
+ }\r
+ \r
+ public function findByContributor($artistName)\r
+ {\r
+ $queryBuilder = $this->_queryBuilderFactory->createInstance();\r
+ $queryBuilder->join('inner', 'packs', 'id', 'simfiles', 'pack_id')\r
+ ->join('inner', 'simfiles', 'id', 'steps', 'simfile_id')\r
+ ->join('inner', 'steps', 'step_artist_id', 'step_artists', 'id')\r
+ ->where('tag', 'LIKE', "%%$artistName%%");\r
+ \r
+ return $this->_dataMapper->map('Pack', $queryBuilder);\r
+ }\r
+}\r
public function findById($id) {\r
$queryBuilder = $this->_queryBuilderFactory->createInstance();\r
$queryBuilder->where('id', '=', $id);\r
- \r
- return $this->_dataMapper->map('Simfile', $queryBuilder);\r
+ \r
+ $result = $this->_dataMapper->map('Simfile', $queryBuilder);\r
+ return reset($result);\r
}\r
\r
public function findRange($id, $limit)\r
namespace DataAccess;\r
\r
use DataAccess\DataMapper\Helpers\EntityMapsHelper;\r
+use DataAccess\DataMapper\Helpers\EntityArrayMapsHelper;\r
use DataAccess\DataMapper\Helpers\VOMapsHelper;\r
use DataAccess\DataMapper\Helpers\VOArrayMapsHelper;\r
use DataAccess\DataMapper\Helpers\IntMapsHelper;\r
return new EntityMapsHelper($mapName, $accessor, $tableName);\r
}\r
\r
+function EntityArray($mapName, $accessor=null, $tableName = null)\r
+{\r
+ return new EntityArrayMapsHelper($mapName, $accessor, $tableName);\r
+}\r
+\r
function VO($mapName, $accessor=null, $tableName = null)\r
{\r
return new VOMapsHelper($mapName, $accessor, $tableName);\r
<?php
-namespace Domain\Entities;
+namespace Domain\Entities\StepMania;
use Domain\Entities\IDivineEntity;
public function getUploader();
public function getContributors();
public function getSimfiles();
+ public function getBanner();
public function getFile();
}
public function With_Title($title);
public function With_Uploader(IUser $uploader);
public function With_Simfiles(array $simfiles);
+ public function With_Banner(IFile $banner);
public function With_File(IFile $file);
public function build();
}
\ No newline at end of file
use Domain\Entities\StepMania\ISimfile;
use Domain\Entities\IUser;
use Domain\Entities\IFile;
-use Domain\Entities\IPack;
+use Domain\Entities\StepMania\IPack;
use Domain\Entities\AbstractEntity;
class Pack extends AbstractEntity implements IPack
private $_title;
private $_uploader;
private $_simfiles;
+ private $_banner;
private $_file;
public function __construct(
$title,
IUser $uploader,
array $simfiles,
+ IFile $banner = null,
IFile $file = null
) {
$this->_title = $title;
$this->_uploader = $uploader;
+ $this->_banner = $banner;
$this->_file = $file;
foreach($simfiles as $simfile) {
return $this->_uploader;
}
+ public function getBanner()
+ {
+ return $this->_banner;
+ }
+
private function getAllStepArtistsFromSimfile(ISimfile $simfile)
{
$artists = array();
private $_title;
private $_uploader;
private $_simfiles;
+ private $_banner;
private $_file;
//override parent
return $this;
}
+ public function With_Banner(IFile $banner)
+ {
+ $this->_banner = $banner;
+ }
+
public function With_File(IFile $file)
{
$this->_file = $file;
$title,
IUser $uploader,
array $simfiles,
+ IFile $banner = null,
IFile $file = null
);
}
$title,
IUser $uploader,
array $simfiles,
+ IFile $banner = null,
IFile $file = null
) {
return new Pack(
$title,
$uploader,
$simfiles,
+ $banner,
$file
);
}
interface IPackStepByStepBuilder_With_Simfiles
{
+ public function With_Banner(IFile $banner);
public function With_File(IFile $file);
public function build();
}
{
public function With_Uploader(IUser $user)
{
- $this->_packBuilder->With_Artist($artist);
- return new PackStepByStepBuilder_With_Artist($this->_packBuilder);
+ $this->_packBuilder->With_Uploader($user);
+ return new PackStepByStepBuilder_With_Uploader($this->_packBuilder);
}
}
class PackStepByStepBuilder_With_Simfiles extends AbstractPackStepByStepBuilder implements IPackStepByStepBuilder_With_Simfiles
{
+ public function With_Banner(IFile $banner)
+ {
+ $this->_packBuilder->With_File($banner);
+ return $this;
+ }
+
public function With_File(Ifile $file)
{
$this->_packBuilder->With_File($file);
+ return $this;
}
-
+
public function build()
{
return $this->_simfileBuilder
public function With_Banner(IFile $banner)\r
{\r
$this->_simfileBuilder->With_Banner($banner);\r
- return new SimfileStepByStepBuilder_With_Steps($this->_simfileBuilder);\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
use finfo;
use Exception;
use Services\IBannerExtracter;
-use DataAccess\IFileRepository;
use Domain\Entities\IFileStepByStepBuilder;
+//TODO: This class can probably be refactored to be nicer. Also perhaps the methods could be static?
class BannerExtracter implements IBannerExtracter
{
private $_builder;
private $_destinationFileName;
private $_hash;
- private $_fileRepository;
- public function __construct(IFileStepByStepBuilder $builder, IFileRepository $fileRepository) {
+ public function __construct(IFileStepByStepBuilder $builder) {
$this->_builder = $builder;
- $this->_fileRepository = $fileRepository;
}
- public function extractBanner($zipfile, $bannerName) {
+ public function extractSongBanner($zipfile, $bannerName) {
$za = new ZipArchive();
//XXX: We assume all files are zips. Should be enforced by validation elsewhere.
$res = $za->open($zipfile);
}
}
- if(!isset($result) || !$result) throw new Exception('Could not extract banner.');
+ if(!isset($result) || !$result) return null;
$finfo = new finfo(FILEINFO_MIME);
$mimetype = $finfo->file('../files/banners/' . $this->_destinationFileName);
$size = filesize('../files/banners/' . $this->_destinationFileName);
/* @var $fff \Domain\Entities\FileStepByStepBuilder */
- $file= $this->_builder->With_Hash($this->_hash)
+ return $this->_builder->With_Hash($this->_hash)
->With_Path('banners')
->With_Filename($bannerName)
->With_Mimetype($mimetype)
->With_Size($size)
->With_UploadDate(time())
->build();
+ }
+
+ public function extractPackBanner($zipfile, $packname)
+ {
+ $bannerName = '';
+ $za = new ZipArchive();
+ //XXX: We assume all files are zips. Should be enforced by validation elsewhere.
+ $res = $za->open($zipfile);
+
+ if($res !== true) throw new Exception ('Could not open zip for reading.');
+
+ for($i=0; $i<$za->numFiles; $i++)
+ {
+ $stat = $za->statIndex($i);
+ $type = @exif_imagetype('zip://' . $zipfile . '#' . $stat['name']);
+
+ if($type !== false)
+ {
+ $pathComponents = explode('/',$stat['name']);
+
+ //replace 3spooty with packname variable
+ if(count($pathComponents) == 2 && $pathComponents[0] == $packname)
+ {
+ $this->_hash = $this->randomFilename($stat['name']);
+ $this->_destinationFileName = $this->_hash . '.' . pathinfo($stat['name'], PATHINFO_EXTENSION);
+ $bannerName = $pathComponents[1];
+ $result = copy('zip://' . $zipfile . '#' . $stat['name'], '../files/banners/' . $this->_destinationFileName);
+ break;
+ }
+ }
+ }
- return $this->_fileRepository->save($file);
+ if(!isset($result) || !$result) return null;
+
+ $finfo = new finfo(FILEINFO_MIME);
+ $mimetype = $finfo->file('../files/banners/' . $this->_destinationFileName);
+ $size = filesize('../files/banners/' . $this->_destinationFileName);
+ /* @var $fff \Domain\Entities\FileStepByStepBuilder */
+ return $this->_builder->With_Hash($this->_hash)
+ ->With_Path('banners')
+ ->With_Filename($bannerName)
+ ->With_Mimetype($mimetype)
+ ->With_Size($size)
+ ->With_UploadDate(time())
+ ->build();
}
private function randomFilename($seed)
interface IBannerExtracter
{
- public function extractBanner($zipfile, $bannerName);
+ public function extractSongBanner($zipfile, $bannerName);
+ public function extractPackBanner($zipfile, $packname);
}
--- /dev/null
+<?php
+
+namespace Services;
+
+use Domain\Entities\IFile;
+
+interface IZipParser
+{
+ public function parse(IFile $zipFile);
+ public function isPack();
+ public function isSingle();
+ public function pack();
+ public function simfiles();
+}
\ No newline at end of file
public function parse($simfileData)
{
- //XXX: Should I explode on ';' instead? That seems like it might be a more reliable delimiter
$this->_smFileLines = explode(";", $simfileData);
}
$hash = $this->saveFile($file);
/* @var $file \Services\Uploads\IFile */
- $file = $this->_fileBuilder->With_Hash($hash)
+ $results[] = $this->_fileBuilder->With_Hash($hash)
->With_Path(rtrim($this->_destination, '/'))
->With_Filename($file->getName())
->With_Mimetype($file->getType())
->With_Size($file->getSize())
->With_UploadDate(time())
->build();
-
- $results[] = $this->_fileRepository->save($file);
}
return $results;
--- /dev/null
+<?php
+
+namespace Services;
+
+use Exception;
+use ZipArchive;
+use Services\ISimfileParser;
+use Services\IBannerExtracter;
+use Domain\Entities\IFile;
+use Domain\Entities\StepMania\ISimfileStepByStepBuilder;
+use Domain\Entities\StepMania\IPackStepByStepBuilder;
+use Services\IZipParser;
+use Services\IUserSession;
+
+class ZipParser implements IZipParser
+{
+ private $_za;
+ private $_smFiles = array();
+ private $_smParser;
+ private $_smBuilder;
+ private $_packBuilder;
+ private $_bannerExtracter;
+ private $_userSession;
+ private $_file;
+
+ public function __construct(
+ ISimfileParser $smParser,
+ ISimfileStepByStepBuilder $smBuilder,
+ IPackStepByStepBuilder $packBuilder,
+ IBannerExtracter $bannerExtracter,
+ IUserSession $userSession
+ ) {
+ $this->_smParser = $smParser;
+ $this->_smBuilder = $smBuilder;
+ $this->_packBuilder = $packBuilder;
+ $this->_bannerExtracter = $bannerExtracter;
+ $this->_userSession = $userSession;
+ }
+
+ public function parse(IFile $file)
+ {
+ $this->_file = $file;
+ $this->_za = new ZipArchive();
+ //XXX: We assume all files are zips. Should be enforced by validation elsewhere.
+ $res = $this->_za->open('../files/StepMania/' . $file->getHash() . '.zip');
+
+ if($res !== true) throw new Exception ('Could not open zip for reading.');
+ $this->findSms();
+ }
+
+ public function pack()
+ {
+ if(count($this->_smFiles) > 1)
+ {
+ $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_Banner($banner)
+ ->With_File($this->_file)
+ ->build();
+ }
+ }
+
+ public function simfiles()
+ {
+ return $this->_smFiles;
+ }
+
+ public function isPack()
+ {
+ return count($this->_smFiles) > 1;
+ }
+
+ public function isSingle()
+ {
+ return count($this->_smFiles) == 1;
+ }
+
+ private function findSms()
+ {
+ for($i=0; $i<$this->_za->numFiles; $i++)
+ {
+ $stat = $this->_za->statIndex($i);
+ 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);
+ }
+ }
+ }
+
+ private function packNameFromFiles()
+ {
+ $packName = '';
+ $smpaths = array_keys($this->_smFiles);
+ foreach($smpaths as $path)
+ {
+ $pathComponents = explode('/', $path);
+
+ if(empty($packName)) $packName = $pathComponents[0];
+
+ if($packName != $pathComponents[0])
+ throw new Exception('Malformed zip. I found more than 1 sm file but the directory structure is not consistent with a pack.');
+ }
+
+ return $packName;
+ }
+
+ private function SmDataToSmClass($smData)
+ {
+ $parser = $this->_smParser;
+ $parser->parse($smData);
+
+ $banner = $this->_bannerExtracter->extractSongBanner('../files/StepMania/' . $this->_file->getHash() . '.zip', $parser->banner());
+
+ return $this->_smBuilder->With_Title($parser->title())
+ ->With_Artist($parser->artist())
+ ->With_Uploader($this->_userSession->getCurrentUser()) //obj
+ ->With_BPM($parser->bpm())
+ ->With_BpmChanges($parser->bpmChanges())
+ ->With_Stops($parser->stops())
+ ->With_FgChanges($parser->fgChanges())
+ ->With_BgChanges($parser->bgChanges())
+ ->With_Steps($parser->steps())
+ ->With_Simfile($this->_file)
+ ->With_Banner($banner)
+ ->build();
+ }
+}
\ No newline at end of file
'facebook.app' => '../config/FacebookApp.php',\r
\r
//entites\r
- 'Domain\Entities\StepMania\ISimfile' => DI\object('Domain\Entities\StepMania\Simfile'),\r
- '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\ISimfileFactory' => DI\object('Domain\Entities\StepMania\SimfileFactory'),\r
+ 'Domain\Entities\StepMania\ISimfileBuilder' => DI\object('Domain\Entities\StepMania\SimfileBuilder'),\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
- 'Domain\Entities\IFileStepByStepBuilder' => DI\object('Domain\Entities\FileStepByStepBuilder'),\r
- 'Domain\Entities\IFileBuilder' => DI\object('Domain\Entities\FileBuilder'),\r
- 'Domain\Entities\IFileFactory' => DI\object('Domain\Entities\FileFactory'),\r
- \r
+\r
+ 'Domain\Entities\StepMania\IPackFactory' => DI\object('Domain\Entities\StepMania\PackFactory'),\r
+ 'Domain\Entities\StepMania\IPackBuilder' => DI\object('Domain\Entities\StepMania\PackBuilder'),\r
+ 'Domain\Entities\StepMania\IPackStepByStepBuilder' => DI\object('Domain\Entities\StepMania\PackStepByStepBuilder'),\r
+\r
+ 'Domain\Entities\IUserFactory' => DI\object('Domain\Entities\UserFactory'),\r
+ 'Domain\Entities\IUserBuilder' => DI\object('Domain\Entities\UserBuilder'),\r
+ 'Domain\Entities\IUserStepByStepBuilder' => DI\object('Domain\Entities\UserStepByStepBuilder'),\r
+\r
+ 'Domain\Entities\IFileFactory' => DI\object('Domain\Entities\FileFactory'),\r
+ 'Domain\Entities\IFileBuilder' => DI\object('Domain\Entities\FileBuilder'),\r
+ 'Domain\Entities\IFileStepByStepBuilder' => DI\object('Domain\Entities\FileStepByStepBuilder'),\r
+\r
//services\r
- 'Services\Http\IHttpResponse' => DI\object('Services\Http\HttpResponse'),\r
- 'Services\Http\IHttpRequest' => DI\object('Services\Http\HttpRequest'),\r
- 'Services\Routing\IRouter' => DI\object('Services\Routing\Router')\r
- ->constructor(DI\link('router.maps')),\r
- 'Services\Uploads\IUploadManager' => DI\object('Services\Uploads\UploadManager'),\r
- 'Services\IUserSession' => DI\object('Services\UserSession'),\r
- '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
- 'Services\IBannerExtracter' => DI\object('Services\BannerExtracter'),\r
+ 'Services\Http\IHttpResponse' => DI\object('Services\Http\HttpResponse'),\r
+ 'Services\Http\IHttpRequest' => DI\object('Services\Http\HttpRequest'),\r
+ 'Services\Routing\IRouter' => DI\object('Services\Routing\Router')\r
+ ->constructor(DI\link('router.maps')),\r
+ 'Services\Uploads\IUploadManager' => DI\object('Services\Uploads\UploadManager'),\r
+ 'Services\IUserSession' => DI\object('Services\UserSession'),\r
+ '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
+ 'Services\IZipParser' => DI\object('Services\ZipParser'),\r
+ 'Services\IBannerExtracter' => DI\object('Services\BannerExtracter'),\r
\r
//DA\r
- 'DataAccess\StepMania\ISimfileRepository' => DI\object('DataAccess\StepMania\SimfileRepository'),\r
- 'DataAccess\IUserRepository' => DI\object('DataAccess\UserRepository'),\r
- 'DataAccess\IFileRepository' => DI\object('DataAccess\FileRepository'),\r
- 'DataAccess\IDatabaseFactory' => DI\object('DataAccess\DatabaseFactory')\r
- ->constructor(DI\link('db.credentials')),\r
- 'DataAccess\DataMapper\IDataMapper' => DI\object('DataAccess\DataMapper\DataMapper')\r
- ->constructor(DI\link('datamapper.maps')),\r
- 'DataAccess\Queries\IQueryBuilderFactory' => DI\object('DataAccess\Queries\QueryBuilderFactory'),\r
+ 'DataAccess\StepMania\ISimfileRepository' => DI\object('DataAccess\StepMania\SimfileRepository'),\r
+ 'DataAccess\StepMania\IPackRepository' => DI\object('DataAccess\StepMania\PackRepository'),\r
+ 'DataAccess\IUserRepository' => DI\object('DataAccess\UserRepository'),\r
+ 'DataAccess\IFileRepository' => DI\object('DataAccess\FileRepository'),\r
+ 'DataAccess\IDatabaseFactory' => DI\object('DataAccess\DatabaseFactory')\r
+ ->constructor(DI\link('db.credentials')),\r
+ 'DataAccess\DataMapper\IDataMapper' => DI\object('DataAccess\DataMapper\DataMapper')\r
+ ->constructor(DI\link('datamapper.maps')),\r
+ 'DataAccess\Queries\IQueryBuilderFactory' => DI\object('DataAccess\Queries\QueryBuilderFactory'),\r
\r
];\r
]\r
],\r
\r
+ 'Pack' => [\r
+ 'class' => 'Domain\Entities\StepMania\Pack',\r
+ 'table' => 'packs',\r
+ 'maps' => [\r
+ 'title' => DataAccess\Varchar('title'),\r
+ 'uploader' => DataAccess\Entity('User', 'getUploader'),\r
+ 'simfiles' => DataAccess\EntityArray('Simfile', 'getSimfiles'),\r
+ 'banner' => DataAccess\Entity('File', 'getBanner', 'banner_file'),\r
+ 'file' => DataAccess\Entity('File', 'getFile')\r
+ ]\r
+ ],\r
+ \r
'BPM' => [\r
'class' => 'Domain\VOs\StepMania\BPM',\r
'table' => 'simfiles',\r
'controller' => 'Simfile',\r
'action' => 'upload'\r
],\r
+ \r
+ //XXX: Test, delete later\r
+ '/simfiles/pack' => [\r
+ 'methods' => ['GET'],\r
+ 'controller' => 'PackTest',\r
+ ],\r
\r
'/simfiles/argTest/:testarg' => [\r
'methods' => ['GET'],\r