Initial commit
This commit is contained in:
0
src/Controller/.gitignore
vendored
Normal file
0
src/Controller/.gitignore
vendored
Normal file
19
src/Controller/DefaultController.php
Normal file
19
src/Controller/DefaultController.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class DefaultController extends AbstractController {
|
||||
#[Route('/dashboard', name: 'bo_dashboard', methods: ['GET'])]
|
||||
public function dashboard(): Response {
|
||||
return $this->render('_dashboard/base.html.twig');
|
||||
}
|
||||
|
||||
// #[Route('/sandbox', name: 'sandbox', methods: 'GET')]
|
||||
// public function sandbox(): Response {
|
||||
// return $this->render('sandbox/sandbox.html.twig');
|
||||
// }
|
||||
}
|
||||
128
src/Controller/GridController.php
Normal file
128
src/Controller/GridController.php
Normal file
@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\Grid;
|
||||
use App\Entity\Region;
|
||||
use App\Kernel;
|
||||
use App\Repository\GridRepository;
|
||||
use App\Repository\MapRepository;
|
||||
use App\Service\FileManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
#[Route('/dashboard/regions/region-{regionId}/grid')]
|
||||
#[ParamConverter(data: 'region', class: Region::class, options: ['id' => 'regionId'])]
|
||||
class GridController extends AbstractController {
|
||||
public function __construct(private EntityManagerInterface $_em,
|
||||
private FileManager $fileManager,
|
||||
private GridRepository $gridRepository,
|
||||
private MapRepository $mapRepository) {}
|
||||
|
||||
#[Route('', name: 'bo_region_grid_index', methods: ['GET'])]
|
||||
public function index(Request $request, Region $region): Response {
|
||||
$version = $request->query->get('v');
|
||||
$version = !$version || !in_array(floatval($version), Kernel::SUPPORTED_GAME_VERSION) ? Kernel::GAME_VERSION : floatval($version);
|
||||
|
||||
$cells = $this->gridRepository->getGridCells($region);
|
||||
$maps = $this->mapRepository->getCellsMap($cells, $version);
|
||||
$grid = $this->gridRepository->buildWorldmap($version, $cells, $maps, true);
|
||||
|
||||
return $this->render('_dashboard/grid/index.html.twig', array(
|
||||
'region' => $region,
|
||||
'grid' => $grid,
|
||||
'version' => $version,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/edit', name: 'bo_region_grid_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(Request $request, Region $region): Response {
|
||||
$logs=array();
|
||||
$form = $this->gridRepository->getGridForm('bo_region_grid_edit', $region);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted() && $form->isValid()) {
|
||||
if(is_array($form->get('positions')->getData())) {
|
||||
if(in_array('row_before', $form->get('positions')->getData())) {
|
||||
$this->addRow($region, $this->gridRepository->getGridCells($region), true);
|
||||
$logs[]='• Added one row before.';
|
||||
}
|
||||
|
||||
if(in_array('row_after', $form->get('positions')->getData())) {
|
||||
$this->addRow($region, $this->gridRepository->getGridCells($region), false);
|
||||
$logs[]='• Added one row after.';
|
||||
}
|
||||
|
||||
if(in_array('column_before', $form->get('positions')->getData())) {
|
||||
$this->addColumn($region, $this->gridRepository->getGridCells($region), true);
|
||||
$logs[]='• Added one column before.';
|
||||
}
|
||||
|
||||
if(in_array('column_after', $form->get('positions')->getData())) {
|
||||
$this->addColumn($region, $this->gridRepository->getGridCells($region), false);
|
||||
$logs[]='• Added one column after.';
|
||||
}
|
||||
|
||||
$form = $this->gridRepository->getGridForm('bo_region_grid_edit', $region);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->renderForm('_dashboard/grid/edit.html.twig', array(
|
||||
'region' => $region,
|
||||
'form' => $form,
|
||||
'logs' => $logs,
|
||||
));
|
||||
}
|
||||
|
||||
private function addColumn(Region $region, array $cells, bool $isBefore) {
|
||||
if($isBefore) {
|
||||
foreach($cells as $_cell) {
|
||||
$_cell->setCol($_cell->getCol() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
for($n = 1; $n <= $region->getGridHeight(); $n++) {
|
||||
$cell = new Grid();
|
||||
$cell->setRegion($region)
|
||||
->setCol($isBefore ? 1 : $region->getGridWidth() + 1)
|
||||
->setRow($n);
|
||||
|
||||
$this->_em->persist($cell);
|
||||
}
|
||||
|
||||
$region->setGridWidth($region->getGridWidth() + 1);
|
||||
|
||||
$this->_em->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Region $region
|
||||
* @param Grid[] $cells
|
||||
* @param bool $isBefore
|
||||
* @return void
|
||||
*/
|
||||
private function addRow(Region $region, array $cells, bool $isBefore) {
|
||||
if($isBefore) {
|
||||
foreach($cells as $_cell) {
|
||||
$_cell->setRow($_cell->getRow() + 1);
|
||||
}
|
||||
}
|
||||
|
||||
for($n = 1; $n <= $region->getGridWidth(); $n++) {
|
||||
$cell = new Grid();
|
||||
$cell->setRegion($region)
|
||||
->setCol($n)
|
||||
->setRow($isBefore ? 1 : $region->getGridHeight() + 1);
|
||||
|
||||
$this->_em->persist($cell);
|
||||
}
|
||||
|
||||
$region->setGridHeight($region->getGridHeight() + 1);
|
||||
|
||||
$this->_em->flush();
|
||||
}
|
||||
}
|
||||
88
src/Controller/ItemCategoryController.php
Normal file
88
src/Controller/ItemCategoryController.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\ItemCategory;
|
||||
use App\Form\ItemCategoryType;
|
||||
use App\Repository\ItemCategoryRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
#[Route('/dashboard/items-categories')]
|
||||
class ItemCategoryController extends AbstractController {
|
||||
public function __construct(private EntityManagerInterface $_em,
|
||||
private ItemCategoryRepository $itemCategoryRepository) {}
|
||||
|
||||
#[Route('', name: 'bo_item_category_index', methods: ['GET'])]
|
||||
public function index(): Response {
|
||||
$itemsCategories = $this->itemCategoryRepository->findBy(array(), array('sortOrder' => 'ASC'));
|
||||
|
||||
return $this->render('_dashboard/item_category/index.html.twig', array(
|
||||
'itemsCategories' => $itemsCategories,
|
||||
));
|
||||
}
|
||||
|
||||
//ToDo set form to XHR for errors
|
||||
#[Route('/new', name: 'bo_item_category_new', methods: ['GET', 'POST'])]
|
||||
public function new(Request $request): Response {
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
$itemCategory = new ItemCategory();
|
||||
$form = $this->itemCategoryRepository->getForm('bo_item_category_new', $itemCategory);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted() && $form->isValid()) {
|
||||
$this->_em->persist($itemCategory);
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->redirectToRoute('bo_item_category_index', array(), Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
$itemsCategories=$this->itemCategoryRepository->findBy(array(), array('sortOrder'=>'ASC'));
|
||||
|
||||
return $this->renderForm('_dashboard/item_category/new.html.twig', array(
|
||||
'itemsCategories'=>$itemsCategories,
|
||||
'itemCategory'=>$itemCategory,
|
||||
'form'=>$form,
|
||||
));
|
||||
}
|
||||
|
||||
//ToDo set form to XHR for errors
|
||||
#[Route('/category-{id}', name: 'bo_item_category_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(Request $request, ItemCategory $itemCategory): Response {
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
$form = $this->itemCategoryRepository->getForm('bo_item_category_edit', $itemCategory);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted() && $form->isValid()) {
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->redirectToRoute('bo_item_category_index', array(), Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
$itemsCategories=$this->itemCategoryRepository->findBy(array(), array('sortOrder'=>'ASC'));
|
||||
|
||||
return $this->renderForm('_dashboard/item_category/edit.html.twig', [
|
||||
'itemsCategories'=>$itemsCategories,
|
||||
'itemCategory'=>$itemCategory,
|
||||
'form'=>$form,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/delete-{id}', name: 'bo_item_category_delete', methods: ['POST'])]
|
||||
public function delete(Request $request, ItemCategory $itemCategory): RedirectResponse {
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
if($this->isCsrfTokenValid('delete'.$itemCategory->getId(), $request->request->get('_token'))) {
|
||||
$this->_em->remove($itemCategory);
|
||||
$this->_em->flush();
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('bo_item_category_index', array(), Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
}
|
||||
239
src/Controller/ItemController.php
Normal file
239
src/Controller/ItemController.php
Normal file
@ -0,0 +1,239 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\Item;
|
||||
use App\Entity\ItemCategory;
|
||||
use App\Repository\ItemCategoryRepository;
|
||||
use App\Repository\ItemRepository;
|
||||
use App\Repository\WorldmarkRepository;
|
||||
use App\Service\FileManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
#[Route('/dashboard/items-categories/category-{itemCategoryId}/items')]
|
||||
#[ParamConverter(data: 'itemCategory', class: ItemCategory::class, options: ['id' => 'itemCategoryId'])]
|
||||
class ItemController extends AbstractController {
|
||||
public function __construct(private EntityManagerInterface $_em,
|
||||
private FileManager $fileManager,
|
||||
private ItemCategoryRepository $itemCategoryRepository,
|
||||
private ItemRepository $itemRepository) {}
|
||||
|
||||
#[Route('', name: 'bo_item_index', methods: ['GET'])]
|
||||
public function index(ItemCategory $itemCategory): Response {
|
||||
$itemsCategories=$this->itemCategoryRepository->findBy(array(), array('sortOrder'=>'ASC'));
|
||||
$items=$this->itemRepository->findBy(array('category'=>$itemCategory), array('name'=>'ASC'));
|
||||
|
||||
return $this->render('_dashboard/item/index.html.twig', array(
|
||||
'itemsCategories'=>$itemsCategories,
|
||||
'itemCategory'=>$itemCategory,
|
||||
'items'=>$items,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/new', name: 'bo_item_new', methods: ['GET', 'POST'])]
|
||||
public function new(Request $request, ItemCategory $itemCategory): Response {
|
||||
$this->denyAccessUnlessGranted('ROLE_SENIOR');
|
||||
|
||||
if($request->isMethod('POST') && !$request->isXmlHttpRequest()) {
|
||||
throw new NotFoundHttpException("Page not found");
|
||||
}
|
||||
|
||||
$item=new Item();
|
||||
$item->setCategory($itemCategory);
|
||||
|
||||
$form=$this->itemRepository->getForm('bo_item_new', $itemCategory, $item);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted()) {
|
||||
if($form->isValid()) {
|
||||
if($item->getIcon() instanceof UploadedFile) {
|
||||
$uploadedFile=$this->fileManager->uploadItemIcon($item->getIcon());
|
||||
|
||||
if($uploadedFile['error']) {
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => $uploadedFile['message'],
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
$item->setIcon($uploadedFile['filename']);
|
||||
}
|
||||
|
||||
$this->_em->persist($item);
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'redirect',
|
||||
'params' => array(
|
||||
'url' => $this->generateUrl('bo_item_index', array('itemCategoryId' => $itemCategory->getId())),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => 'Invalid form',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
$itemsCategories=$this->itemCategoryRepository->findBy(array(), array('sortOrder'=>'ASC'));
|
||||
|
||||
return $this->renderForm('_dashboard/item/new.html.twig', array(
|
||||
'itemsCategories'=>$itemsCategories,
|
||||
'itemCategory'=>$itemCategory,
|
||||
'item'=>$item,
|
||||
'form'=>$form,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/item-{id}', name: 'bo_item_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(Request $request, WorldmarkRepository $worldmarkRepository, ItemCategory $itemCategory, Item $item): Response {
|
||||
$this->denyAccessUnlessGranted('ROLE_SENIOR');
|
||||
|
||||
if($request->isMethod('POST') && !$request->isXmlHttpRequest()) {
|
||||
throw new NotFoundHttpException("Page not found");
|
||||
}
|
||||
|
||||
$icon=$item->getIcon();
|
||||
|
||||
$form=$this->itemRepository->getForm('bo_item_edit', $itemCategory, $item);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted()) {
|
||||
if($form->isValid()) {
|
||||
if(!$form->get('removeFile')->getData()) {
|
||||
if($item->getIcon() instanceof UploadedFile) {
|
||||
$uploadedFile=$this->fileManager->uploadItemIcon($item->getIcon());
|
||||
|
||||
if($uploadedFile['error']) {
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => $uploadedFile['message'],
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
if($icon) {
|
||||
$this->fileManager->removeItemIcon($icon);
|
||||
}
|
||||
|
||||
$item->setIcon($uploadedFile['filename']);
|
||||
$worldmark = $worldmarkRepository->findOneBy(array('item'=>$item));
|
||||
|
||||
if($worldmark) {
|
||||
$uploadedFile=$this->fileManager->getWorldmarkIconFromEntity($item);
|
||||
|
||||
if($uploadedFile['error']) {
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => $uploadedFile['message'],
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
if($worldmark->getIcon()) {
|
||||
$this->fileManager->removeWorldmarkIcon($icon);
|
||||
}
|
||||
|
||||
$worldmark->setIcon($uploadedFile['filename']);
|
||||
}
|
||||
} else {
|
||||
$item->setIcon($icon);
|
||||
}
|
||||
} else {
|
||||
$this->fileManager->removeItemIcon($icon);
|
||||
|
||||
$item->setIcon(null);
|
||||
}
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'redirect',
|
||||
'params' => array(
|
||||
'url' => $this->generateUrl('bo_item_index', array('itemCategoryId' => $itemCategory->getId())),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => 'Invalid form',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
$itemsCategories=$this->itemCategoryRepository->findBy(array(), array('sortOrder'=>'ASC'));
|
||||
|
||||
return $this->renderForm('_dashboard/item/edit.html.twig', [
|
||||
'itemsCategories'=>$itemsCategories,
|
||||
'itemCategory'=>$itemCategory,
|
||||
'item'=>$item,
|
||||
'form'=>$form,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/delete-{id}', name: 'bo_item_delete', methods: ['POST'])]
|
||||
public function delete(Request $request, ItemCategory $itemCategory, Item $item): RedirectResponse {
|
||||
$this->denyAccessUnlessGranted('ROLE_SENIOR');
|
||||
|
||||
if($this->isCsrfTokenValid('delete'.$item->getId(), $request->request->get('_token'))) {
|
||||
if($item->getIcon()) {
|
||||
$this->fileManager->removeItemIcon($item->getIcon());
|
||||
}
|
||||
|
||||
$this->_em->remove($item);
|
||||
$this->_em->flush();
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('bo_item_index', array('itemCategoryId'=>$itemCategory->getId()), Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
}
|
||||
198
src/Controller/MapController.php
Normal file
198
src/Controller/MapController.php
Normal file
@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\Grid;
|
||||
use App\Entity\Map;
|
||||
use App\Repository\MapRepository;
|
||||
use App\Service\FileManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
#[Route('/dashboard/grid/cell-{cellId}/maps')]
|
||||
#[ParamConverter(data: 'cell', class: Grid::class, options: ['id' => 'cellId'])]
|
||||
class MapController extends AbstractController {
|
||||
public function __construct(private EntityManagerInterface $_em,
|
||||
private FileManager $fileManager,
|
||||
private MapRepository $mapRepository) {}
|
||||
|
||||
#[Route('/new', name: 'bo_map_new', methods: ['POST'])]
|
||||
public function new(Request $request, Grid $cell): JsonResponse {
|
||||
if($request->isXmlHttpRequest()) {
|
||||
$map = new Map();
|
||||
$map->setGrid($cell);
|
||||
|
||||
$form = $this->mapRepository->getForm('bo_map_new', $cell, $map);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted()) {
|
||||
if($form->isValid()) {
|
||||
if($map->getFile() instanceof UploadedFile) {
|
||||
$uploadedFile = $this->fileManager->uploadMapFile($map->getFile());
|
||||
|
||||
if($uploadedFile['error']) {
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => $uploadedFile['message'],
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
$map->setFile($uploadedFile['filename']);
|
||||
|
||||
$this->_em->persist($map);
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'success',
|
||||
'message' => 'Map updated',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => 'No file found or uploaded',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => 'Invalid form',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => 'No form submitted',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
throw $this->createNotFoundException();
|
||||
}
|
||||
|
||||
#[Route('/map-{id}', name: 'bo_map_edit', methods: ['POST'])]
|
||||
public function edit(Request $request, Grid $cell, Map $map): JsonResponse {
|
||||
if($request->isXmlHttpRequest()) {
|
||||
$file = $map->getFile();
|
||||
|
||||
$form = $this->mapRepository->getForm('bo_map_edit', $cell, $map);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted()) {
|
||||
if($form->isValid()) {
|
||||
if($map->getFile() instanceof UploadedFile) {
|
||||
$uploadedFile=$this->fileManager->uploadMapFile($map->getFile());
|
||||
|
||||
if($uploadedFile['error']) {
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => $uploadedFile['message'],
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
$map->setFile($uploadedFile['filename']);
|
||||
$this->fileManager->removeMapFile($file);
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'success',
|
||||
'message' => 'Map updated',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => 'No file found or uploaded',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => 'Invalid form',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => 'No form submitted',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
throw $this->createNotFoundException();
|
||||
}
|
||||
}
|
||||
85
src/Controller/MonsterCategoryController.php
Normal file
85
src/Controller/MonsterCategoryController.php
Normal file
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\MonsterCategory;
|
||||
use App\Repository\MonsterCategoryRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
#[Route('/dashboard/monsters-categories')]
|
||||
class MonsterCategoryController extends AbstractController {
|
||||
public function __construct(private EntityManagerInterface $_em,
|
||||
private MonsterCategoryRepository $monsterCategoryRepository) {}
|
||||
|
||||
#[Route('', name: 'bo_monster_category_index', methods: ['GET'])]
|
||||
public function index(): Response {
|
||||
$monstersCategories = $this->monsterCategoryRepository->findBy(array(), array('name' => 'ASC'));
|
||||
|
||||
return $this->render('_dashboard/monster_category/index.html.twig', array(
|
||||
'monstersCategories' => $monstersCategories,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/new', name: 'bo_monster_category_new', methods: ['GET', 'POST'])]
|
||||
public function new(Request $request): RedirectResponse|Response {
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
$monstersCategories = $this->monsterCategoryRepository->findBy(array(), array('name' => 'ASC'));
|
||||
|
||||
$monsterCategory = new MonsterCategory();
|
||||
$form = $this->monsterCategoryRepository->getForm('bo_monster_category_new', $monsterCategory);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted() && $form->isValid()) {
|
||||
$this->_em->persist($monsterCategory);
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->redirectToRoute('bo_monster_category_index', array(), Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->renderForm('_dashboard/monster_category/new.html.twig', array(
|
||||
'monstersCategories' => $monstersCategories,
|
||||
'monsterCategory' => $monsterCategory,
|
||||
'form' => $form,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/category-{id}', name: 'bo_monster_category_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(Request $request, MonsterCategory $monsterCategory): RedirectResponse|Response {
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
$monstersCategories = $this->monsterCategoryRepository->findBy(array(), array('name' => 'ASC'));
|
||||
|
||||
$form = $this->monsterCategoryRepository->getForm('bo_monster_category_edit', $monsterCategory);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted() && $form->isValid()) {
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->redirectToRoute('bo_monster_category_index', array(), Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->renderForm('_dashboard/monster_category/edit.html.twig', array(
|
||||
'monstersCategories' => $monstersCategories,
|
||||
'monsterCategory' => $monsterCategory,
|
||||
'form' => $form,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/delete-{id}', name: 'bo_monster_category_delete', methods: ['POST'])]
|
||||
public function delete(Request $request, MonsterCategory $monsterCategory): RedirectResponse {
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
if($this->isCsrfTokenValid('delete'.$monsterCategory->getId(), $request->request->get('_token'))) {
|
||||
$this->_em->remove($monsterCategory);
|
||||
$this->_em->flush();
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('bo_monster_category_index', [], Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
}
|
||||
214
src/Controller/MonsterController.php
Normal file
214
src/Controller/MonsterController.php
Normal file
@ -0,0 +1,214 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\Monster;
|
||||
use App\Entity\MonsterCategory;
|
||||
use App\Repository\MonsterCategoryRepository;
|
||||
use App\Repository\MonsterRepository;
|
||||
use App\Service\FileManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
#[Route('/dashboard/monsters-categories/category-{monsterCategoryId}/monsters')]
|
||||
#[ParamConverter(data: 'monsterCategory', class: MonsterCategory::class, options: ['id' => 'monsterCategoryId'])]
|
||||
class MonsterController extends AbstractController {
|
||||
public function __construct(private EntityManagerInterface $_em,
|
||||
private FileManager $fileManager,
|
||||
private MonsterCategoryRepository $monsterCategoryRepository,
|
||||
private MonsterRepository $monsterRepository) {}
|
||||
|
||||
#[Route('', name: 'bo_monster_index', methods: ['GET'])]
|
||||
public function index(MonsterCategory $monsterCategory): Response {
|
||||
$monstersCategories = $this->monsterCategoryRepository->findBy(array(), array('name' => 'ASC'));
|
||||
$monsters = $this->monsterRepository->findBy(array('category' => $monsterCategory), array('name' => 'ASC'));
|
||||
|
||||
return $this->render('_dashboard/monster/index.html.twig', array(
|
||||
'monstersCategories' => $monstersCategories,
|
||||
'monsterCategory' => $monsterCategory,
|
||||
'monsters' => $monsters,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/new', name: 'bo_monster_new', methods: ['GET', 'POST'])]
|
||||
public function new(Request $request, MonsterCategory $monsterCategory): JsonResponse|Response {
|
||||
$this->denyAccessUnlessGranted('ROLE_SENIOR');
|
||||
|
||||
if($request->isMethod('POST') && !$request->isXmlHttpRequest()) {
|
||||
throw new NotFoundHttpException("Page not found");
|
||||
}
|
||||
|
||||
$monstersCategories = $this->monsterCategoryRepository->findBy(array(), array('name' => 'ASC'));
|
||||
|
||||
$monster = new Monster();
|
||||
$monster->setCategory($monsterCategory);
|
||||
|
||||
$form = $this->monsterRepository->getForm('bo_monster_new', $monsterCategory, $monster);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted()) {
|
||||
if($form->isValid()) {
|
||||
if($monster->getIcon() instanceof UploadedFile) {
|
||||
$uploadedFile = $this->fileManager->uploadMonsterIcon($monster->getIcon());
|
||||
|
||||
if($uploadedFile['error']) {
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => $uploadedFile['message'],
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
$monster->setIcon($uploadedFile['filename']);
|
||||
}
|
||||
|
||||
$this->_em->persist($monster);
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'redirect',
|
||||
'params' => array(
|
||||
'url' => $this->generateUrl('bo_monster_index', array('monsterCategoryId' => $monsterCategory->getId())),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => 'Invalid form',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->renderForm('_dashboard/monster/new.html.twig', array(
|
||||
'monstersCategories' => $monstersCategories,
|
||||
'monsterCategory' => $monsterCategory,
|
||||
'monster' => $monster,
|
||||
'form' => $form,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/monster-{id}', name: 'bo_monster_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(Request $request, MonsterCategory $monsterCategory, Monster $monster): JsonResponse|Response {
|
||||
$this->denyAccessUnlessGranted('ROLE_SENIOR');
|
||||
|
||||
if($request->isMethod('POST') && !$request->isXmlHttpRequest()) {
|
||||
throw new NotFoundHttpException("Page not found");
|
||||
}
|
||||
|
||||
$monstersCategories = $this->monsterCategoryRepository->findBy(array(), array('name' => 'ASC'));
|
||||
|
||||
$icon = $monster->getIcon();
|
||||
|
||||
$form = $this->monsterRepository->getForm('bo_monster_edit', $monsterCategory, $monster);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted()) {
|
||||
if($form->isValid()) {
|
||||
if(!$form->get('removeFile')->getData()) {
|
||||
if($monster->getIcon() instanceof UploadedFile) {
|
||||
$uploadedFile = $this->fileManager->uploadMonsterIcon($monster->getIcon());
|
||||
|
||||
if($uploadedFile['error']) {
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => $uploadedFile['message'],
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
if($icon) {
|
||||
$this->fileManager->removeMonsterIcon($icon);
|
||||
}
|
||||
|
||||
$monster->setIcon($uploadedFile['filename']);
|
||||
} else {
|
||||
$monster->setIcon($icon);
|
||||
}
|
||||
} else {
|
||||
$this->fileManager->removeMonsterIcon($icon);
|
||||
|
||||
$monster->setIcon(null);
|
||||
}
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'redirect',
|
||||
'params' => array(
|
||||
'url' => $this->generateUrl('bo_monster_index', array('monsterCategoryId' => $monsterCategory->getId())),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => 'Invalid form',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->renderForm('_dashboard/monster/edit.html.twig', array(
|
||||
'monstersCategories' => $monstersCategories,
|
||||
'monsterCategory' => $monsterCategory,
|
||||
'monster' => $monster,
|
||||
'form' => $form,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/delete-{id}', name: 'bo_monster_delete', methods: ['POST'])]
|
||||
public function delete(Request $request, MonsterCategory $monsterCategory, Monster $monster): RedirectResponse {
|
||||
$this->denyAccessUnlessGranted('ROLE_SENIOR');
|
||||
|
||||
if($this->isCsrfTokenValid('delete'.$monster->getId(), $request->request->get('_token'))) {
|
||||
if($monster->getIcon()) {
|
||||
$this->fileManager->removeMonsterIcon($monster->getIcon());
|
||||
}
|
||||
|
||||
$this->_em->remove($monster);
|
||||
$this->_em->flush();
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('bo_monster_index', array('monsterCategoryId' => $monsterCategory->getId()), Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
}
|
||||
426
src/Controller/NodeController.php
Normal file
426
src/Controller/NodeController.php
Normal file
@ -0,0 +1,426 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\Grid;
|
||||
use App\Entity\Node;
|
||||
use App\Entity\Worldmark;
|
||||
use App\Repository\NodeRepository;
|
||||
use App\Service\FileManager;
|
||||
use DateTime;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
#[Route('/dashboard/grid-{gridId}/worldmark-{worldmarkId}/nodes')]
|
||||
#[ParamConverter(data: 'grid', class: Grid::class, options: ['id' => 'gridId'])]
|
||||
#[ParamConverter(data: 'worldmark', class: Worldmark::class, options: ['id' => 'worldmarkId'])]
|
||||
class NodeController extends AbstractController {
|
||||
public function __construct(private EntityManagerInterface $_em,
|
||||
private FileManager $fileManager,
|
||||
private NodeRepository $nodeRepository) {}
|
||||
|
||||
#[Route('/new', name: 'bo_node_new', methods: ['POST'])]
|
||||
public function new(Request $request, Grid $grid, Worldmark $worldmark): JsonResponse {
|
||||
if($request->isXmlHttpRequest()) {
|
||||
if($this->isGranted('ROLE_CONTRIBUTOR')) {
|
||||
$node = new Node();
|
||||
$node->setGrid($grid)
|
||||
->setWorldmark($worldmark);
|
||||
|
||||
$form = $this->nodeRepository->getForm('bo_node_new', $grid, $worldmark, $node);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted()) {
|
||||
if($form->isValid()) {
|
||||
$errors = array();
|
||||
$uploadedFiles = array();
|
||||
$screenshotSetMethods = array('setScreenshotA', 'setScreenshotB', 'setScreenshotC', 'setScreenshotD', 'setScreenshotE');
|
||||
$screenshotGetMethods = array('getScreenshotA', 'getScreenshotB', 'getScreenshotC', 'getScreenshotD', 'getScreenshotE');
|
||||
|
||||
foreach($screenshotSetMethods as $key => $method) {
|
||||
if(is_callable(array($node, $method)) && is_callable(array($node, $screenshotGetMethods[$key]))) {
|
||||
$uploadedFiles[$method] = ($node->{$screenshotGetMethods[$key]}() instanceof UploadedFile)
|
||||
? $this->fileManager->uploadScreenshot($node->{$screenshotGetMethods[$key]}())
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($uploadedFiles as $method => $uploadedFile) {
|
||||
if($uploadedFile) {
|
||||
if($uploadedFile['error']) {
|
||||
$errors[] = $uploadedFile['message'];
|
||||
} elseif(is_callable(array($node, $method))) {
|
||||
$node->$method($uploadedFile['filename']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(count($errors)) {
|
||||
$messages = array();
|
||||
|
||||
foreach($screenshotGetMethods as $method) {
|
||||
if(is_callable(array($node, $method)) && is_string($node->$method())) {
|
||||
$this->fileManager->removeScreenshot($node->$method());
|
||||
}
|
||||
}
|
||||
|
||||
foreach($errors as $error) {
|
||||
$messages[] = array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => $error,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return $this->json(array('::function' => $messages));
|
||||
}
|
||||
|
||||
$this->_em->persist($node);
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name'=>'paq_event',
|
||||
'params' => array(
|
||||
'type' => 'trackEvent',
|
||||
'name' => "Contribution: Nodes",
|
||||
'value' => "Nodes created by {$this->getUser()->getUserIdentifier()}",
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => 'paq_event',
|
||||
'params' => array(
|
||||
'type' => 'trackEvent',
|
||||
'name' => "Contribution: {$node->getWorldmark()->getCategory()->getName()} nodes category",
|
||||
'value' => "Nodes created by {$this->getUser()->getUserIdentifier()}",
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => 'paq_event',
|
||||
'params' => array(
|
||||
'type' => 'trackEvent',
|
||||
'name' => "Contribution: {$node->getGrid()->getRegion()->getName()} nodes log",
|
||||
'value' => "[{$node->getModifiedAt()->format('Y-m-d H:i:s')}] Node {$node->getId()} was created by {$this->getUser()->getUserIdentifier()}",
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => 'node_validateForm',
|
||||
'params' => array(
|
||||
'gridId' => $grid->getId(),
|
||||
'htmlString' => $this->renderView('woldmap/_node.html.twig', array(
|
||||
'grid' => $grid,
|
||||
'worldmark' => $worldmark,
|
||||
'node' => $node,
|
||||
'directRender'=>true,
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => 'Invalid form',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'node_loadForm',
|
||||
'params' => array(
|
||||
'gridId' => $grid->getId(),
|
||||
'coordinate' => array('x' => '50', 'y' => '50'),
|
||||
'htmlString' => $this->renderView('_dashboard/node/_form.html.twig', array(
|
||||
'grid' => $grid,
|
||||
'worldmark' => $worldmark,
|
||||
'node' => $node,
|
||||
'form' => $form->createView(),
|
||||
)),
|
||||
'nodeId' => null,
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array('error' => 'Not found'), 404);
|
||||
}
|
||||
|
||||
throw $this->createNotFoundException();
|
||||
}
|
||||
|
||||
#[Route('/node-{id}', name: 'bo_node_edit', methods: ['POST'])]
|
||||
public function edit(Request $request, Grid $grid, Worldmark $worldmark, Node $node): JsonResponse {
|
||||
if($request->isXmlHttpRequest()) {
|
||||
if($this->isGranted('ROLE_CONTRIBUTOR')) {
|
||||
$screenshots = array(
|
||||
'ScreenshotA' => $node->getScreenshotA(),
|
||||
'ScreenshotB' => $node->getScreenshotB(),
|
||||
'ScreenshotC' => $node->getScreenshotC(),
|
||||
'ScreenshotD' => $node->getScreenshotD(),
|
||||
'ScreenshotE' => $node->getScreenshotE(),
|
||||
);
|
||||
|
||||
$form = $this->nodeRepository->getForm('bo_node_edit', $grid, $worldmark, $node);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted()) {
|
||||
if($form->isValid()) {
|
||||
$errors = array();
|
||||
$uploadedFiles = array();
|
||||
$screenshotSetMethods = array('setScreenshotA', 'setScreenshotB', 'setScreenshotC', 'setScreenshotD', 'setScreenshotE');
|
||||
$screenshotGetMethods = array('getScreenshotA', 'getScreenshotB', 'getScreenshotC', 'getScreenshotD', 'getScreenshotE');
|
||||
|
||||
foreach($screenshotSetMethods as $key => $method) {
|
||||
if(is_callable(array($node, $method)) && is_callable(array($node, $screenshotGetMethods[$key]))) {
|
||||
$uploadedFiles[$method] = ($node->{$screenshotGetMethods[$key]}() instanceof UploadedFile)
|
||||
? $this->fileManager->uploadScreenshot($node->{$screenshotGetMethods[$key]}())
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($uploadedFiles as $method => $uploadedFile) {
|
||||
if($uploadedFile) {
|
||||
if($uploadedFile['error']) {
|
||||
$errors[] = $uploadedFile['message'];
|
||||
} elseif(is_callable(array($node, $method))) {
|
||||
$node->$method($uploadedFile['filename']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(count($errors)) {
|
||||
$messages = array();
|
||||
|
||||
foreach($screenshotGetMethods as $method) {
|
||||
if(is_callable(array($node, $method)) && is_string($node->$method())) {
|
||||
$this->fileManager->removeScreenshot($node->$method());
|
||||
}
|
||||
}
|
||||
|
||||
foreach($errors as $error) {
|
||||
$messages[] = array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => $error,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return $this->json(array('::function' => $messages));
|
||||
}
|
||||
|
||||
foreach($screenshotGetMethods as $key => $method) {
|
||||
if(is_callable(array($node, $method))
|
||||
&& is_callable(array($node, $screenshotSetMethods[$key]))
|
||||
&& $node->$method() === null) {
|
||||
$node->{$screenshotSetMethods[$key]}($screenshots[substr($method, 3)]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->_em->persist($node);
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'paq_event',
|
||||
'params' => array(
|
||||
'type' => 'trackEvent',
|
||||
'name' => "Contribution: Nodes",
|
||||
'value' => "Nodes edited by {$this->getUser()->getUserIdentifier()}",
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name'=>'paq_event',
|
||||
'params' => array(
|
||||
'type' => 'trackEvent',
|
||||
'name' => "Contribution: {$node->getWorldmark()->getCategory()->getName()} nodes category",
|
||||
'value' => "Nodes edited by {$this->getUser()->getUserIdentifier()}",
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => 'paq_event',
|
||||
'params' => array(
|
||||
'type' => 'trackEvent',
|
||||
'name' => "Contribution: {$node->getGrid()->getRegion()->getName()} nodes log",
|
||||
'value' => "[{$node->getModifiedAt()->format('Y-m-d H:i:s')}] Node {$node->getId()} was edited by {$this->getUser()->getUserIdentifier()}",
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => 'node_validateForm',
|
||||
'params' => array(
|
||||
'gridId' => $grid->getId(),
|
||||
'htmlString' => $this->renderView('woldmap/_node.html.twig', array(
|
||||
'grid' => $grid,
|
||||
'worldmark' => $worldmark,
|
||||
'node' => $node,
|
||||
'directRender'=>true,
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => 'Invalid form',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'node_loadForm',
|
||||
'params' => array(
|
||||
'gridId' => $grid->getId(),
|
||||
'coordinate' => array('x' => '50', 'y' => '50'),
|
||||
'htmlString' => $this->renderView('_dashboard/node/_form.html.twig', array(
|
||||
'grid' => $grid,
|
||||
'worldmark' => $worldmark,
|
||||
'node' => $node,
|
||||
'form' => $form->createView(),
|
||||
)),
|
||||
'nodeId' => $node->getId(),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array('error' => 'Not found'), 404);
|
||||
}
|
||||
|
||||
throw $this->createNotFoundException();
|
||||
}
|
||||
|
||||
#[Route('/delete-{id}', name: 'bo_node_delete', methods: ['POST'])]
|
||||
public function delete(Request $request, Grid $grid, Worldmark $worldmark, Node $node): JsonResponse {
|
||||
if($request->isXmlHttpRequest()) {
|
||||
if($this->isGranted('ROLE_CONTRIBUTOR')) {
|
||||
$form = $this->nodeRepository->getForm('bo_node_delete', $grid, $worldmark, $node);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted()) {
|
||||
if($form->isValid()) {
|
||||
$nodeId = $node->getId();
|
||||
|
||||
if($this->isGranted('ROLE_ADMIN')) {
|
||||
$screenshotGetMethods = array('getScreenshotA', 'getScreenshotB', 'getScreenshotC', 'getScreenshotD', 'getScreenshotE');
|
||||
|
||||
foreach($screenshotGetMethods as $method) {
|
||||
if(is_callable(array($node, $method)) && $node->$method() !== null) {
|
||||
$this->fileManager->removeScreenshot($node->$method());
|
||||
}
|
||||
}
|
||||
|
||||
$this->_em->remove($node);
|
||||
}
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
$deleteDate=new DateTime();
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name'=>'paq_event',
|
||||
'params' => array(
|
||||
'type' => 'trackEvent',
|
||||
'name' => "Contribution: Nodes",
|
||||
'value' => "Nodes deleted by {$this->getUser()->getUserIdentifier()}",
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => 'paq_event',
|
||||
'params' => array(
|
||||
'type' => 'trackEvent',
|
||||
'name' => "Contribution: {$node->getWorldmark()->getCategory()->getName()} nodes category",
|
||||
'value' => "Nodes deleted by {$this->getUser()->getUserIdentifier()}",
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => 'paq_event',
|
||||
'params' => array(
|
||||
'type' => 'trackEvent',
|
||||
'name' => "Contribution: {$node->getGrid()->getRegion()->getName()} nodes log",
|
||||
'value' => "[{$deleteDate->format('Y-m-d H:i:s')}] Node {$node->getId()} was deleted by {$this->getUser()->getUserIdentifier()}",
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => 'node_removeElement',
|
||||
'params' => array(
|
||||
'gridId' => $grid->getId(),
|
||||
'nodeId' => $nodeId,
|
||||
),
|
||||
),
|
||||
array(
|
||||
'name' => 'modal_unload',
|
||||
'params' => null,
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => 'Invalid form',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'modal_load',
|
||||
'params' => array(
|
||||
'htmlString' => $this->renderView('_dashboard/node/_delete_form.html.twig', array(
|
||||
'grid' => $grid,
|
||||
'worldmark' => $worldmark,
|
||||
'node' => $node,
|
||||
'form' => $form->createView(),
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array('error' => 'Not found'), 404);
|
||||
}
|
||||
|
||||
throw $this->createNotFoundException();
|
||||
}
|
||||
}
|
||||
179
src/Controller/RegionController.php
Normal file
179
src/Controller/RegionController.php
Normal file
@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\Grid;
|
||||
use App\Entity\Region;
|
||||
use App\Kernel;
|
||||
use App\Repository\GridRepository;
|
||||
use App\Repository\MapRepository;
|
||||
use App\Repository\NodeRepository;
|
||||
use App\Repository\RegionRepository;
|
||||
use App\Repository\WorldmarkCategoryRepository;
|
||||
use App\Repository\WorldmarkRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
class RegionController extends AbstractController {
|
||||
public function __construct(private EntityManagerInterface $_em,
|
||||
private RegionRepository $regionRepository,
|
||||
private GridRepository $gridRepository,
|
||||
private MapRepository $mapRepository,
|
||||
private WorldmarkCategoryRepository $worldmarkCategoryRepository,
|
||||
private WorldmarkRepository $worldmarkRepository,
|
||||
private NodeRepository $nodeRepository) {}
|
||||
|
||||
#[Route('/worldmap', name: 'fo_worldmap_redirect_a', methods: ['GET'])]
|
||||
public function redirectA(): RedirectResponse {
|
||||
return $this->redirectToRoute('fo_region_show', array('slug'=>'mondstadt'), Response::HTTP_MOVED_PERMANENTLY);
|
||||
}
|
||||
|
||||
#[Route('/worldmap/{slug}', name: 'fo_worldmap_redirect_b', methods: ['GET'])]
|
||||
public function redirectB(Region $region): RedirectResponse {
|
||||
return $this->redirectToRoute('fo_region_show', array('slug'=>$region->getSlug()), Response::HTTP_MOVED_PERMANENTLY);
|
||||
}
|
||||
|
||||
#[Route('/{slug}', name: 'fo_region_show', methods: ['GET'])]
|
||||
public function show(Request $request, ?Region $region): Response {
|
||||
$version = $request->query->get('v');
|
||||
|
||||
if(!$version
|
||||
|| !in_array(floatval($version), Kernel::SUPPORTED_GAME_VERSION)
|
||||
|| (floatval($version) < Kernel::GAME_VERSION && !$this->isGranted('ROLE_ADMIN'))
|
||||
|| (floatval($version) > Kernel::GAME_VERSION && !$this->isGranted('ROLE_CONTRIBUTOR'))) {
|
||||
$version = Kernel::GAME_VERSION;
|
||||
} else {
|
||||
$version = floatval($version);
|
||||
}
|
||||
|
||||
if(!$region
|
||||
|| $region->getVersion() > $version
|
||||
|| !$region->getIsActive() && !$this->isGranted('ROLE_CONTRIBUTOR')) {
|
||||
throw $this->createNotFoundException();
|
||||
}
|
||||
|
||||
$_region = $region->getIsAlias() ? $region->getParentRegion() : $region;
|
||||
|
||||
$cells = $this->gridRepository->getGridCells($_region);
|
||||
$maps = $this->mapRepository->getCellsMap($cells, $version);
|
||||
$grid = $this->gridRepository->buildWorldmap($version, $cells, $maps, true);
|
||||
|
||||
$worldmarks = $this->worldmarkRepository->getRegionWorldmarks($_region, $version);
|
||||
$nodes = $this->nodeRepository->getGridNodes($cells, $worldmarks, $version, $this->isGranted('ROLE_ADMIN'));
|
||||
|
||||
$worldmarksData = array();
|
||||
foreach($worldmarks as $worldmark) {
|
||||
if(!array_key_exists($worldmark->getCategory()->getSlug(), $worldmarksData)) {
|
||||
$worldmarksData[$worldmark->getCategory()->getSlug()]['_data'] = $worldmark->getCategory();
|
||||
$worldmarksData[$worldmark->getCategory()->getSlug()]['_worldmarks'] = array();
|
||||
}
|
||||
|
||||
$worldmarksData[$worldmark->getCategory()->getSlug()]['_worldmarks'][] = $worldmark;
|
||||
}
|
||||
|
||||
$nodesData = array();
|
||||
foreach($nodes as $node) {
|
||||
$nodesData["grid_{$node->getGrid()->getId()}"][] = $node;
|
||||
}
|
||||
|
||||
return $this->render('woldmap/show.html.twig', array(
|
||||
// 'title' => "Genshin Impact interactive map of {$_region->getName()}",
|
||||
'title' => "{$_region->getName()} interactive map - Genshin Impact - Genshin World",
|
||||
'region' => $_region,
|
||||
'regionSlug' => $region->getSlug(),
|
||||
'version' => $version,
|
||||
'grid' => $grid,
|
||||
'worldmarksData' => $worldmarksData,
|
||||
'nodes' => $nodesData,
|
||||
'anchor' => $region->getIsAlias() ? $region->getAnchor() : null,
|
||||
'filter'=>$request->get('filter'),
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/dashboard/regions', name: 'bo_region_index', methods: ['GET'])]
|
||||
public function index(): Response {
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
return $this->render('_dashboard/region/index.html.twig', array(
|
||||
'title' => "Dashboard: Regions index",
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/dashboard/regions/new', name: 'bo_region_new', methods: ['GET', 'POST'])]
|
||||
public function new(Request $request): Response {
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
$region = new Region();
|
||||
$form = $this->regionRepository->getForm('bo_region_new', $region);
|
||||
|
||||
$form->handleRequest($request);
|
||||
if($form->isSubmitted() && $form->isValid()) {
|
||||
$this->_em->persist($region);
|
||||
|
||||
if($region->getIsAlias()) {
|
||||
$region->setGridHeight(0);
|
||||
$region->setGridWidth(0);
|
||||
}
|
||||
|
||||
if($region->getGridHeight() > 0 && $region->getGridWidth() > 0) {
|
||||
for($row = 1; $row <= $region->getGridHeight(); $row++) {
|
||||
for($col = 1; $col <= $region->getGridWidth(); $col++) {
|
||||
$grid = new Grid();
|
||||
|
||||
$grid->setRegion($region)
|
||||
->setRow($row)
|
||||
->setCol($col);
|
||||
|
||||
$this->_em->persist($grid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->redirectToRoute('bo_region_index', array(), Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->renderForm('_dashboard/region/new.html.twig', array(
|
||||
'title' => "Dashboard: Create region",
|
||||
'region' => $region,
|
||||
'form' => $form,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/dashboard/regions/region-{id}', name: 'bo_region_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(Request $request, Region $region): Response {
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
$form = $this->regionRepository->getForm('bo_region_edit', $region);
|
||||
|
||||
$form->handleRequest($request);
|
||||
if($form->isSubmitted() && $form->isValid()) {
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->redirectToRoute('bo_region_index', array(), Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->renderForm('_dashboard/region/edit.html.twig', array(
|
||||
'title' => "Dashboard: Edit region",
|
||||
'region' => $region,
|
||||
'form' => $form,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/dashboard/regions/delete-{id}', name: 'bo_region_delete', methods: ['POST'])]
|
||||
public function delete(Request $request, Region $region): RedirectResponse {
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
if($this->isCsrfTokenValid('delete'.$region->getId(), $request->request->get('_token'))) {
|
||||
$this->_em->remove($region);
|
||||
$this->_em->flush();
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('bo_region_index', array(), Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
}
|
||||
71
src/Controller/SecurityController.php
Normal file
71
src/Controller/SecurityController.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Repository\UserRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||
|
||||
class SecurityController extends AbstractController {
|
||||
public function __construct(
|
||||
private readonly EntityManagerInterface $_em,
|
||||
private readonly UserRepository $userRepository,
|
||||
private readonly UserPasswordHasherInterface $userPasswordHasher) {
|
||||
}
|
||||
|
||||
// #[Route('/035c7785-2c2f-11ec-aaf0-ac1f6b44f230/register', name: 'security_register')]
|
||||
public function register(Request $request): Response {
|
||||
$user = new User();
|
||||
$form = $this->userRepository->getForm('security_register', $user);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted() && $form->isValid()) {
|
||||
// encode the plain password
|
||||
$user->setPassword(
|
||||
$this->userPasswordHasher->hashPassword(
|
||||
$user,
|
||||
$form->get('plainPassword')->getData()
|
||||
)
|
||||
);
|
||||
|
||||
$this->_em->persist($user);
|
||||
$this->_em->flush();
|
||||
|
||||
// do anything else you need here, like send an email
|
||||
|
||||
return $this->redirectToRoute('security_login', array(), Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->renderForm('security/register.html.twig', array(
|
||||
'form' => $form,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route(path: '/035c7785-2c2f-11ec-aaf0-ac1f6b44f230/login', name: 'security_login')]
|
||||
public function login(AuthenticationUtils $authenticationUtils): Response {
|
||||
// if ($this->getUser()) {
|
||||
// return $this->redirectToRoute('target_path');
|
||||
// }
|
||||
|
||||
// get the login error if there is one
|
||||
$error = $authenticationUtils->getLastAuthenticationError();
|
||||
// last username entered by the user
|
||||
$lastUsername = $authenticationUtils->getLastUsername();
|
||||
|
||||
return $this->render('security/login.html.twig', array(
|
||||
'last_username' => $lastUsername,
|
||||
'error' => $error,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route(path: '/035c7785-2c2f-11ec-aaf0-ac1f6b44f230/logout', name: 'security_logout')]
|
||||
public function logout(): void {
|
||||
// throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
|
||||
}
|
||||
}
|
||||
81
src/Controller/WorldmarkCategoryController.php
Normal file
81
src/Controller/WorldmarkCategoryController.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\WorldmarkCategory;
|
||||
use App\Repository\WorldmarkCategoryRepository;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
#[Route('/dashboard/worldmarks-categories')]
|
||||
class WorldmarkCategoryController extends AbstractController {
|
||||
public function __construct(private EntityManagerInterface $_em,
|
||||
private WorldmarkCategoryRepository $worldmarkCategoryRepository) {}
|
||||
|
||||
#[Route('', name: 'bo_worldmark_category_index', methods: ['GET'])]
|
||||
public function index(): Response {
|
||||
return $this->render('_dashboard/worldmark_category/index.html.twig', array(
|
||||
'worldmarksCategories' => $this->worldmarkCategoryRepository->findBy(array(), array('sortOrder' => 'ASC'))
|
||||
));
|
||||
}
|
||||
|
||||
//ToDo set foirm to XHR for errors
|
||||
#[Route('/new', name: 'bo_worldmark_category_new', methods: ['GET', 'POST'])]
|
||||
public function new(Request $request): Response {
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
$category=new WorldmarkCategory();
|
||||
$form=$this->worldmarkCategoryRepository->getForm('bo_worldmark_category_new', $category);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted() && $form->isValid()) {
|
||||
$this->_em->persist($category);
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->redirectToRoute('bo_worldmark_category_index', array(), Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->renderForm('_dashboard/worldmark_category/new.html.twig', array(
|
||||
'worldmarksCategories' => $this->worldmarkCategoryRepository->findBy(array(), array('sortOrder' => 'ASC')),
|
||||
'worldmarkCategory'=>$category,
|
||||
'form'=>$form,
|
||||
));
|
||||
}
|
||||
|
||||
//ToDo set foirm to XHR for errors
|
||||
#[Route('/category-{id}', name: 'bo_worldmark_category_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(Request $request, WorldmarkCategory $worldmarkCategory): Response {
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
$form=$this->worldmarkCategoryRepository->getForm('bo_worldmark_category_edit', $worldmarkCategory);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted() && $form->isValid()) {
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->redirectToRoute('bo_worldmark_category_index', array(), Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
|
||||
return $this->renderForm('_dashboard/worldmark_category/edit.html.twig', array(
|
||||
'worldmarksCategories' => $this->worldmarkCategoryRepository->findBy(array(), array('sortOrder' => 'ASC')),
|
||||
'worldmarkCategory'=>$worldmarkCategory,
|
||||
'form'=>$form,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/delete-{id}', name: 'bo_worldmark_category_delete', methods: ['POST'])]
|
||||
public function delete(Request $request, WorldmarkCategory $worldmarkCategory): RedirectResponse {
|
||||
$this->denyAccessUnlessGranted('ROLE_ADMIN');
|
||||
|
||||
if($this->isCsrfTokenValid('delete'.$worldmarkCategory->getId(), $request->request->get('_token'))) {
|
||||
$this->_em->remove($worldmarkCategory);
|
||||
$this->_em->flush();
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('bo_worldmark_category_index', array(), Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
}
|
||||
240
src/Controller/WorldmarkController.php
Normal file
240
src/Controller/WorldmarkController.php
Normal file
@ -0,0 +1,240 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\Worldmark;
|
||||
use App\Entity\WorldmarkCategory;
|
||||
use App\Repository\ItemCategoryRepository;
|
||||
use App\Repository\MonsterCategoryRepository;
|
||||
use App\Repository\WorldmarkCategoryRepository;
|
||||
use App\Repository\WorldmarkRepository;
|
||||
use App\Service\FileManager;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
#[Route('/dashboard/worldmarks-categories/category-{worldmarkCategoryId}/worldmarks')]
|
||||
#[ParamConverter(data: 'worldmarkCategory', class: WorldmarkCategory::class, options: ['id' => 'worldmarkCategoryId'])]
|
||||
class WorldmarkController extends AbstractController {
|
||||
public function __construct(private EntityManagerInterface $_em,
|
||||
private FileManager $fileManager,
|
||||
private WorldmarkCategoryRepository $worldmarkCategoryRepository,
|
||||
private ItemCategoryRepository $itemCategoryRepository,
|
||||
private MonsterCategoryRepository $monsterCategoryRepository,
|
||||
private WorldmarkRepository $worldmarkRepository) {}
|
||||
|
||||
#[Route('', name: 'bo_worldmark_index', methods: ['GET'])]
|
||||
public function index(WorldmarkCategory $worldmarkCategory): Response {
|
||||
$worldmarksCategories = $this->worldmarkCategoryRepository->findBy(array(), array('sortOrder' => 'ASC'));
|
||||
$worldmarks = $this->worldmarkRepository->findBy(array('category' => $worldmarkCategory), array('sortOrder' => 'ASC'));
|
||||
|
||||
return $this->render('_dashboard/worldmark/index.html.twig', array(
|
||||
'worldmarksCategories' => $worldmarksCategories,
|
||||
'worldmarkCategory' => $worldmarkCategory,
|
||||
'worldmarks' => $worldmarks,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/new', name: 'bo_worldmark_new', methods: ['GET', 'POST'])]
|
||||
public function new(Request $request, WorldmarkCategory $worldmarkCategory): JsonResponse|Response {
|
||||
$this->denyAccessUnlessGranted('ROLE_SENIOR');
|
||||
|
||||
if($request->isMethod('POST') && !$request->isXmlHttpRequest()) {
|
||||
throw new NotFoundHttpException("Page not found");
|
||||
}
|
||||
|
||||
$worldmark = new Worldmark();
|
||||
$worldmark->setCategory($worldmarkCategory);
|
||||
|
||||
$form = $this->worldmarkRepository->getForm('bo_worldmark_new', $worldmarkCategory, $worldmark);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted()) {
|
||||
if($form->isValid()) {
|
||||
if($worldmark->getItem() || $worldmark->getMonster() || $worldmark->getIcon() instanceof UploadedFile) {
|
||||
if($worldmark->getItem()) {
|
||||
$uploadedFile = $this->fileManager->getWorldmarkIconFromEntity($worldmark->getItem());
|
||||
} elseif($worldmark->getMonster()) {
|
||||
$uploadedFile = $this->fileManager->getWorldmarkIconFromEntity($worldmark->getMonster());
|
||||
} elseif($worldmark->getIcon() instanceof UploadedFile) {
|
||||
$uploadedFile = $this->fileManager->uploadWorldmarkIcon($worldmark->getIcon());
|
||||
} else {
|
||||
$uploadedFile = array(
|
||||
'error' => true,
|
||||
'filename' => null,
|
||||
'message' => 'An internal error occurred',
|
||||
);
|
||||
}
|
||||
|
||||
if($uploadedFile['error']) {
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => $uploadedFile['message'],
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
$worldmark->setIcon($uploadedFile['filename']);
|
||||
}
|
||||
|
||||
$this->_em->persist($worldmark);
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'redirect',
|
||||
'params' => array(
|
||||
'url' => $this->generateUrl('bo_worldmark_index', array('worldmarkCategoryId' => $worldmarkCategory->getId())),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => 'Invalid form',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
$worldmarksCategories = $this->worldmarkCategoryRepository->findBy(array(), array('sortOrder' => 'ASC'));
|
||||
|
||||
return $this->renderForm('_dashboard/worldmark/new.html.twig', array(
|
||||
'worldmarksCategories' => $worldmarksCategories,
|
||||
'worldmarkCategory' => $worldmarkCategory,
|
||||
'worldmark' => $worldmark,
|
||||
'form' => $form,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/worldmark-{id}', name: 'bo_worldmark_edit', methods: ['GET', 'POST'])]
|
||||
public function edit(Request $request, WorldmarkCategory $worldmarkCategory, Worldmark $worldmark): JsonResponse|Response {
|
||||
$this->denyAccessUnlessGranted('ROLE_SENIOR');
|
||||
|
||||
if($request->isMethod('POST') && !$request->isXmlHttpRequest()) {
|
||||
throw new NotFoundHttpException("Page not found");
|
||||
}
|
||||
|
||||
$icon = $worldmark->getIcon();
|
||||
$item = $worldmark->getItem();
|
||||
$monster = $worldmark->getMonster();
|
||||
|
||||
$form = $this->worldmarkRepository->getForm('bo_worldmark_edit', $worldmarkCategory, $worldmark);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if($form->isSubmitted()) {
|
||||
if($form->isValid()) {
|
||||
if(($worldmark->getItem() && $worldmark->getItem()->getId() !== $item->getId())
|
||||
|| ($worldmark->getMonster() && $worldmark->getMonster()->getId() !== $monster->getId())
|
||||
|| $worldmark->getIcon() instanceof UploadedFile) {
|
||||
if($worldmark->getItem()) {
|
||||
$uploadedFile = $this->fileManager->getWorldmarkIconFromEntity($worldmark->getItem());
|
||||
} elseif($worldmark->getMonster()) {
|
||||
$uploadedFile = $this->fileManager->getWorldmarkIconFromEntity($worldmark->getMonster());
|
||||
} elseif($worldmark->getIcon() instanceof UploadedFile) {
|
||||
$uploadedFile = $this->fileManager->uploadWorldmarkIcon($worldmark->getIcon());
|
||||
} else {
|
||||
$uploadedFile = array(
|
||||
'error' => true,
|
||||
'filename' => null,
|
||||
'message' => 'An internal error occurred',
|
||||
);
|
||||
}
|
||||
|
||||
if($uploadedFile['error']) {
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => $uploadedFile['message'],
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
if($icon) {
|
||||
$this->fileManager->removeWorldmarkIcon($icon);
|
||||
}
|
||||
|
||||
$worldmark->setIcon($uploadedFile['filename']);
|
||||
} else {
|
||||
$worldmark->setIcon($icon);
|
||||
}
|
||||
|
||||
$this->_em->flush();
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'redirect',
|
||||
'params' => array(
|
||||
'url' => $this->generateUrl('bo_worldmark_index', array('worldmarkCategoryId' => $worldmarkCategory->getId())),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
return $this->json(array(
|
||||
'::function' => array(
|
||||
array(
|
||||
'name' => 'messageInfo',
|
||||
'params' => array(
|
||||
'type' => 'error',
|
||||
'message' => 'Invalid form',
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
$worldmarksCategories = $this->worldmarkCategoryRepository->findBy(array(), array('sortOrder' => 'ASC'));
|
||||
|
||||
return $this->renderForm('_dashboard/worldmark/edit.html.twig', array(
|
||||
'worldmarksCategories' => $worldmarksCategories,
|
||||
'worldmarkCategory' => $worldmarkCategory,
|
||||
'worldmark' => $worldmark,
|
||||
'form' => $form,
|
||||
));
|
||||
}
|
||||
|
||||
#[Route('/delete-{id}', name: 'bo_worldmark_delete', methods: ['POST'])]
|
||||
public function delete(Request $request, WorldmarkCategory $worldmarkCategory, Worldmark $worldmark): RedirectResponse {
|
||||
$this->denyAccessUnlessGranted('ROLE_SENIOR');
|
||||
|
||||
if($this->isCsrfTokenValid('delete'.$worldmark->getId(), $request->request->get('_token'))) {
|
||||
if($worldmark->getIcon()) {
|
||||
$this->fileManager->removeWorldmarkIcon($worldmark->getIcon());
|
||||
}
|
||||
|
||||
$this->_em->remove($worldmark);
|
||||
$this->_em->flush();
|
||||
}
|
||||
|
||||
return $this->redirectToRoute('bo_worldmark_index', array('worldmarkCategoryId' => $worldmarkCategory->getId()), Response::HTTP_SEE_OTHER);
|
||||
}
|
||||
}
|
||||
67
src/Doctrine/DBAL/Types/TinyintType.php
Normal file
67
src/Doctrine/DBAL/Types/TinyintType.php
Normal file
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace App\Doctrine\DBAL\Types;
|
||||
|
||||
use Doctrine\DBAL\ParameterType;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
|
||||
class TinyintType extends Type {
|
||||
private const TINYINT='tinyint';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string {
|
||||
return self::TINYINT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $column
|
||||
* @param AbstractPlatform $platform
|
||||
* @return string
|
||||
*/
|
||||
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string {
|
||||
$declaration="TINYINT(1)";
|
||||
|
||||
if(array_key_exists('unsigned', $column) && $column['unsigned'] === true) {
|
||||
$declaration.=" UNSIGNED";
|
||||
}
|
||||
|
||||
$declaration.=" COMMENT '(DC2Type:tinyint)'";
|
||||
|
||||
return $declaration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function canRequireSQLConversion(): bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param AbstractPlatform $platform
|
||||
* @return int|null
|
||||
*/
|
||||
public function convertToPHPValue($value, AbstractPlatform $platform): ?int {
|
||||
return $value === null ? null : (int)$value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $value
|
||||
* @param AbstractPlatform $platform
|
||||
* @return int|null
|
||||
*/
|
||||
public function convertToDatabaseValue($value, AbstractPlatform $platform): ?int {
|
||||
return $value === null ? null : (int)$value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getBindingType(): int {
|
||||
return ParameterType::INTEGER;
|
||||
}
|
||||
}
|
||||
0
src/Entity/.gitignore
vendored
Normal file
0
src/Entity/.gitignore
vendored
Normal file
58
src/Entity/Grid.php
Normal file
58
src/Entity/Grid.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\GridRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity(repositoryClass: GridRepository::class)]
|
||||
class Grid {
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
private $id;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: Region::class)]
|
||||
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
|
||||
private $region;
|
||||
|
||||
#[ORM\Column(name: '`row`', type: 'tinyint')]
|
||||
private $row;
|
||||
|
||||
#[ORM\Column(type: 'tinyint')]
|
||||
private $col;
|
||||
|
||||
public function getId(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getRegion(): ?Region {
|
||||
return $this->region;
|
||||
}
|
||||
|
||||
public function setRegion(?Region $region): self {
|
||||
$this->region=$region;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRow() {
|
||||
return $this->row;
|
||||
}
|
||||
|
||||
public function setRow($row): self {
|
||||
$this->row=$row;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCol() {
|
||||
return $this->col;
|
||||
}
|
||||
|
||||
public function setCol($col): self {
|
||||
$this->col=$col;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
106
src/Entity/Item.php
Normal file
106
src/Entity/Item.php
Normal file
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\ItemRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
|
||||
#[ORM\Entity(repositoryClass: ItemRepository::class)]
|
||||
#[ORM\Index(columns: ['slug'])]
|
||||
#[UniqueEntity(fields: ['slug'], message: 'There is already an item with this slug')]
|
||||
class Item {
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
private $id;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: ItemCategory::class)]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private $category;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 60)]
|
||||
private $name;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 60, unique: true)]
|
||||
private $slug;
|
||||
|
||||
#[ORM\Column(type: 'text', nullable: true)]
|
||||
private $description;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, nullable: true)]
|
||||
private $icon;
|
||||
|
||||
#[ORM\Column(type: 'float')]
|
||||
private $version;
|
||||
|
||||
public function __toString(): string {
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
public function getId(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getCategory(): ItemCategory {
|
||||
return $this->category;
|
||||
}
|
||||
|
||||
public function setCategory(ItemCategory $category): self {
|
||||
$this->category = $category;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName(): ?string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): self {
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSlug(): ?string {
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function setSlug(string $slug): self {
|
||||
$this->slug = $slug;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescription(): ?string {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription(?string $description): self {
|
||||
$this->description = $description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
public function getIcon(): string|UploadedFile|null {
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
public function setIcon(string|UploadedFile|null $icon): self {
|
||||
$this->icon = $icon;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getVersion(): ?float {
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
public function setVersion(float $version): self {
|
||||
$this->version = $version;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
65
src/Entity/ItemCategory.php
Normal file
65
src/Entity/ItemCategory.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\ItemCategoryRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
|
||||
#[ORM\Entity(repositoryClass: ItemCategoryRepository::class)]
|
||||
#[ORM\Index(columns: ['slug'])]
|
||||
#[UniqueEntity(fields: ['name'], message: 'There is already an item category with this name')]
|
||||
#[UniqueEntity(fields: ['slug'], message: 'There is already an item category with this slug')]
|
||||
class ItemCategory {
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
private $id;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, unique: true)]
|
||||
private $name;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, unique: true)]
|
||||
private $slug;
|
||||
|
||||
#[ORM\Column(type: 'smallint', options: ['default' => 65535, 'unsigned' => true])]
|
||||
private $sortOrder;
|
||||
|
||||
public function __toString(): string {
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
public function getId(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getName(): ?string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): self {
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSlug(): ?string {
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function setSlug(string $slug): self {
|
||||
$this->slug = $slug;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSortOrder(): ?int {
|
||||
return $this->sortOrder;
|
||||
}
|
||||
|
||||
public function setSortOrder(int $sortOrder): self {
|
||||
$this->sortOrder = $sortOrder;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
89
src/Entity/Map.php
Normal file
89
src/Entity/Map.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\MapRepository;
|
||||
use DateTime;
|
||||
use DateTimeInterface;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
|
||||
#[ORM\Entity(repositoryClass: MapRepository::class)]
|
||||
#[ORM\HasLifecycleCallbacks]
|
||||
#[UniqueEntity(fields: ['file'], message: 'There is already a file with this name')]
|
||||
class Map {
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
private $id;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: Grid::class)]
|
||||
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
|
||||
private $grid;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, unique: true)]
|
||||
private $file;
|
||||
|
||||
#[ORM\Column(type: 'datetime')]
|
||||
private $modifiedAt;
|
||||
|
||||
#[ORM\Column(type: 'float')]
|
||||
private $version;
|
||||
|
||||
public function __toString(): string {
|
||||
return $this->getFile();
|
||||
}
|
||||
|
||||
#[ORM\PrePersist]
|
||||
#[ORM\PreUpdate]
|
||||
public function updateLifecycle() {
|
||||
$this->setModifiedAt(new DateTime());
|
||||
}
|
||||
|
||||
public function getId(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getGrid(): ?Grid
|
||||
{
|
||||
return $this->grid;
|
||||
}
|
||||
|
||||
public function setGrid(?Grid $grid): self
|
||||
{
|
||||
$this->grid = $grid;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFile(): string|UploadedFile|null {
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
public function setFile(string|UploadedFile|null $file): self {
|
||||
$this->file=$file;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getModifiedAt(): ?DateTimeInterface {
|
||||
return $this->modifiedAt;
|
||||
}
|
||||
|
||||
public function setModifiedAt(DateTimeInterface $modifiedAt): self {
|
||||
$this->modifiedAt=$modifiedAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getVersion(): ?float {
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
public function setVersion(float $version): self {
|
||||
$this->version=$version;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
105
src/Entity/Monster.php
Normal file
105
src/Entity/Monster.php
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\MonsterRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
|
||||
#[ORM\Entity(repositoryClass: MonsterRepository::class)]
|
||||
#[ORM\Index(columns: ['slug'])]
|
||||
#[UniqueEntity(fields: ['slug'], message: 'There is already a monster with this slug')]
|
||||
class Monster {
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
private $id;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: MonsterCategory::class)]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private $category;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 60)]
|
||||
private $name;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 60, unique: true)]
|
||||
private $slug;
|
||||
|
||||
#[ORM\Column(type: 'text', nullable: true)]
|
||||
private $description;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, nullable: true)]
|
||||
private $icon;
|
||||
|
||||
#[ORM\Column(type: 'float')]
|
||||
private $version;
|
||||
|
||||
public function __toString(): string {
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
public function getId(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getCategory(): MonsterCategory {
|
||||
return $this->category;
|
||||
}
|
||||
|
||||
public function setCategory(MonsterCategory $category): self {
|
||||
$this->category=$category;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName(): ?string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): self {
|
||||
$this->name=$name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSlug(): ?string {
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function setSlug(string $slug): self {
|
||||
$this->slug=$slug;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescription(): ?string {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription(?string $description): self {
|
||||
$this->description=$description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIcon(): string|UploadedFile|null {
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
public function setIcon(string|UploadedFile|null $icon): self {
|
||||
$this->icon=$icon;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getVersion(): ?float {
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
public function setVersion(float $version): self {
|
||||
$this->version=$version;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
52
src/Entity/MonsterCategory.php
Normal file
52
src/Entity/MonsterCategory.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\MonsterCategoryRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
|
||||
#[ORM\Entity(repositoryClass: MonsterCategoryRepository::class)]
|
||||
#[ORM\Index(columns: ['slug'])]
|
||||
#[UniqueEntity(fields: ['name'], message: 'There is already a monster category with this name')]
|
||||
#[UniqueEntity(fields: ['slug'], message: 'There is already a monster category with this slug')]
|
||||
class MonsterCategory {
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
private $id;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, unique: true)]
|
||||
private $name;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, unique: true)]
|
||||
private $slug;
|
||||
|
||||
public function __toString(): string {
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
public function getId(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getName(): ?string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): self {
|
||||
$this->name=$name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSlug(): ?string {
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function setSlug(string $slug): self {
|
||||
$this->slug=$slug;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
230
src/Entity/Node.php
Normal file
230
src/Entity/Node.php
Normal file
@ -0,0 +1,230 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\NodeRepository;
|
||||
use DateTime;
|
||||
use DateTimeInterface;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
|
||||
#[ORM\Entity(repositoryClass: NodeRepository::class)]
|
||||
#[ORM\HasLifecycleCallbacks]
|
||||
class Node {
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
private ?int $id;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: Grid::class)]
|
||||
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
|
||||
private ?Grid $grid;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: Worldmark::class)]
|
||||
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
|
||||
private ?Worldmark $worldmark;
|
||||
|
||||
#[ORM\Column(type: 'text', nullable: true)]
|
||||
private ?string $description;
|
||||
|
||||
#[ORM\Column(type: 'tinyint', options: ['default' => 1])]
|
||||
private int $quantity;
|
||||
|
||||
#[ORM\Column(type: 'smallint', options: ['default' => 0, 'unsigned' => true])]
|
||||
private ?int $primogem;
|
||||
|
||||
#[ORM\Column(type: 'json')]
|
||||
private array $coordinate;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, nullable: true)]
|
||||
private string|UploadedFile|null $screenshotA;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, nullable: true)]
|
||||
private string|UploadedFile|null $screenshotB;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, nullable: true)]
|
||||
private string|UploadedFile|null $screenshotC;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, nullable: true)]
|
||||
private string|UploadedFile|null $screenshotD;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, nullable: true)]
|
||||
private string|UploadedFile|null $screenshotE;
|
||||
|
||||
#[ORM\Column(type: 'datetime')]
|
||||
private ?DateTimeInterface $modifiedAt;
|
||||
|
||||
#[ORM\Column(type: 'float')]
|
||||
private ?float $version;
|
||||
|
||||
#[ORM\Column(type: 'boolean')]
|
||||
private bool $isDeleted;
|
||||
|
||||
public function __construct() {
|
||||
$this->id = null;
|
||||
$this->description = null;
|
||||
$this->quantity = 1;
|
||||
$this->primogem = 0;
|
||||
$this->coordinate = array(
|
||||
'x' => 50,
|
||||
'y' => 50,
|
||||
);
|
||||
$this->screenshotA = null;
|
||||
$this->screenshotB = null;
|
||||
$this->screenshotC = null;
|
||||
$this->screenshotD = null;
|
||||
$this->screenshotE = null;
|
||||
$this->version = null;
|
||||
$this->isDeleted = false;
|
||||
}
|
||||
|
||||
#[ORM\PrePersist]
|
||||
#[ORM\PreUpdate]
|
||||
public function updateLifecycle() {
|
||||
$this->setModifiedAt(new DateTime());
|
||||
}
|
||||
|
||||
public function getId(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getGrid(): ?Grid {
|
||||
return $this->grid;
|
||||
}
|
||||
|
||||
public function setGrid(?Grid $grid): self {
|
||||
$this->grid = $grid;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getWorldmark(): ?Worldmark {
|
||||
return $this->worldmark;
|
||||
}
|
||||
|
||||
public function setWorldmark(?Worldmark $worldmark): self {
|
||||
$this->worldmark = $worldmark;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescription(): ?string {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription(?string $description): self {
|
||||
$this->description = $description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getQuantity(): int {
|
||||
return $this->quantity;
|
||||
}
|
||||
|
||||
public function setQuantity($quantity): self {
|
||||
$this->quantity = $quantity;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getPrimogem(): int {
|
||||
return $this->primogem;
|
||||
}
|
||||
|
||||
public function setPrimogem($primogem): self {
|
||||
$this->primogem = $primogem;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCoordinate(): array {
|
||||
return $this->coordinate;
|
||||
}
|
||||
|
||||
public function setCoordinate(array $coordinate): self {
|
||||
$this->coordinate = $coordinate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getScreenshotA(): string|UploadedFile|null {
|
||||
return $this->screenshotA;
|
||||
}
|
||||
|
||||
public function setScreenshotA(string|UploadedFile|null $screenshotA): self {
|
||||
$this->screenshotA = $screenshotA;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getScreenshotB(): string|UploadedFile|null {
|
||||
return $this->screenshotB;
|
||||
}
|
||||
|
||||
public function setScreenshotB(string|UploadedFile|null $screenshotB): self {
|
||||
$this->screenshotB = $screenshotB;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getScreenshotC(): string|UploadedFile|null {
|
||||
return $this->screenshotC;
|
||||
}
|
||||
|
||||
public function setScreenshotC(string|UploadedFile|null $screenshotC): self {
|
||||
$this->screenshotC = $screenshotC;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getScreenshotD(): string|UploadedFile|null {
|
||||
return $this->screenshotD;
|
||||
}
|
||||
|
||||
public function setScreenshotD(string|UploadedFile|null $screenshotD): self {
|
||||
$this->screenshotD = $screenshotD;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getScreenshotE(): string|UploadedFile|null {
|
||||
return $this->screenshotE;
|
||||
}
|
||||
|
||||
public function setScreenshotE(string|UploadedFile|null $screenshotE): self {
|
||||
$this->screenshotE = $screenshotE;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getModifiedAt(): ?DateTimeInterface {
|
||||
return $this->modifiedAt;
|
||||
}
|
||||
|
||||
public function setModifiedAt(DateTimeInterface $modifiedAt): self {
|
||||
$this->modifiedAt = $modifiedAt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getVersion(): ?float {
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
public function setVersion(float $version): self {
|
||||
$this->version = $version;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIsDeleted(): ?bool {
|
||||
return $this->isDeleted;
|
||||
}
|
||||
|
||||
public function setIsDeleted(bool $isDeleted): self {
|
||||
$this->isDeleted = $isDeleted;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
234
src/Entity/Region.php
Normal file
234
src/Entity/Region.php
Normal file
@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\RegionRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
|
||||
#[ORM\Entity(repositoryClass: RegionRepository::class)]
|
||||
#[ORM\Index(columns: ['slug'])]
|
||||
#[UniqueEntity(fields: ['name'], message: 'There is already an region with this name')]
|
||||
#[UniqueEntity(fields: ['slug'], message: 'There is already an region with this slug')]
|
||||
class Region {
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
private ?int $id;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: self::class, inversedBy: 'subRegions')]
|
||||
private ?Region $parentRegion;
|
||||
|
||||
#[ORM\OneToMany(mappedBy: 'parentRegion', targetEntity: self::class)]
|
||||
private Collection $subRegions;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, unique: true)]
|
||||
private ?string $name;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, unique: true)]
|
||||
private ?string $slug;
|
||||
|
||||
#[ORM\Column(type: 'boolean', options: ['default' => 0])]
|
||||
private ?bool $isAlias;
|
||||
|
||||
#[ORM\Column(type: 'json', length: 20, nullable: true)]
|
||||
private ?string $anchor;
|
||||
|
||||
#[ORM\Column(type: 'text', nullable: true)]
|
||||
private ?string $description;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50)]
|
||||
private ?string $icon;
|
||||
|
||||
#[ORM\Column(type: 'tinyint', options: ['default' => 0, 'unsigned' => true])]
|
||||
private ?int $gridHeight;
|
||||
|
||||
#[ORM\Column(type: 'tinyint', options: ['default' => 0, 'unsigned' => true])]
|
||||
private ?int $gridWidth;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50)]
|
||||
private ?string $mapBackground;
|
||||
|
||||
#[ORM\Column(type: 'float')]
|
||||
private ?float $version;
|
||||
|
||||
#[ORM\Column(type: 'smallint', options: ['default' => 65535, 'unsigned' => true])]
|
||||
private ?int $sortOrder;
|
||||
|
||||
#[ORM\Column(type: 'boolean', options: ['default' => 1])]
|
||||
private int $isActive;
|
||||
|
||||
#[ORM\ManyToMany(targetEntity: Worldmark::class, mappedBy: 'regions')]
|
||||
private Collection $worldmarks;
|
||||
|
||||
public function __construct() {
|
||||
$this->id = null;
|
||||
$this->mapBackground = null;
|
||||
$this->worldmarks = new ArrayCollection();
|
||||
$this->subRegions = new ArrayCollection();
|
||||
$this->isAlias = 0;
|
||||
$this->isActive = 1;
|
||||
}
|
||||
|
||||
public function __toString(): string {
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
public function getId(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getParentRegion(): ?self {
|
||||
return $this->parentRegion;
|
||||
}
|
||||
|
||||
public function setParentRegion(?self $parentRegion): self {
|
||||
$this->parentRegion = $parentRegion;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSubRegions(): Collection {
|
||||
return $this->subRegions;
|
||||
}
|
||||
|
||||
public function getName(): ?string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): self {
|
||||
$this->name=$name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSlug(): ?string {
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function setSlug(string $slug): self {
|
||||
$this->slug=$slug;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIsAlias(): ?bool {
|
||||
return $this->isAlias;
|
||||
}
|
||||
|
||||
public function setIsAlias(bool $isAlias): self {
|
||||
$this->isAlias = $isAlias;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAnchor(): ?string {
|
||||
return $this->anchor;
|
||||
}
|
||||
|
||||
public function setAnchor(?string $anchor): self {
|
||||
$this->anchor = $anchor;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescription(): ?string {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription(?string $description): self {
|
||||
$this->description = $description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIcon(): ?string {
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
public function setIcon(string $icon): self {
|
||||
$this->icon=$icon;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getGridHeight(): ?int {
|
||||
return $this->gridHeight;
|
||||
}
|
||||
|
||||
public function setGridHeight(int $gridHeight): self {
|
||||
$this->gridHeight=$gridHeight;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getGridWidth(): ?int {
|
||||
return $this->gridWidth;
|
||||
}
|
||||
|
||||
public function setGridWidth(int $gridWidth): self {
|
||||
$this->gridWidth=$gridWidth;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMapBackground(): ?string {
|
||||
return $this->mapBackground;
|
||||
}
|
||||
|
||||
public function setMapBackground(string $mapBackground): self {
|
||||
$this->mapBackground=$mapBackground;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getVersion(): ?float {
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
public function setVersion(float $version): self {
|
||||
$this->version=$version;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSortOrder(): ?int {
|
||||
return $this->sortOrder;
|
||||
}
|
||||
|
||||
public function setSortOrder(int $sortOrder): self {
|
||||
$this->sortOrder=$sortOrder;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIsActive(): bool {
|
||||
return $this->isActive;
|
||||
}
|
||||
|
||||
public function setIsActive(bool $isActive): self {
|
||||
$this->isActive=$isActive;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getWorldmarks(): Collection {
|
||||
return $this->worldmarks;
|
||||
}
|
||||
|
||||
public function addWorldmark(Worldmark $worldmark): self {
|
||||
if(!$this->worldmarks->contains($worldmark)) {
|
||||
$this->worldmarks[]=$worldmark;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeWorldmark(Worldmark $worldmark): self {
|
||||
$this->worldmarks->removeElement($worldmark);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
138
src/Entity/User.php
Normal file
138
src/Entity/User.php
Normal file
@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\UserRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
|
||||
#[ORM\Entity(repositoryClass: UserRepository::class)]
|
||||
#[ORM\HasLifecycleCallbacks]
|
||||
#[UniqueEntity(fields: ['username'], message: 'There is already an account with this username')]
|
||||
#[UniqueEntity(fields: ['email'], message: 'There is already an account with this email')]
|
||||
class User implements UserInterface, PasswordAuthenticatedUserInterface {
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
private $id;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 180, unique: true)]
|
||||
private $username;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 255, nullable: true)]
|
||||
private $email;
|
||||
|
||||
#[ORM\Column(type: 'integer', nullable: true, options: ["unsigned" => true])]
|
||||
private $uid;
|
||||
|
||||
#[ORM\Column(type: 'string')]
|
||||
private $password;
|
||||
|
||||
#[ORM\Column(type: 'json')]
|
||||
private $roles = [];
|
||||
|
||||
public function __toString(): string {
|
||||
return $this->getUserIdentifier();
|
||||
}
|
||||
|
||||
#[ORM\PrePersist]
|
||||
public function setFirstRole() {
|
||||
$this->setRoles(array());
|
||||
}
|
||||
|
||||
public function getId(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* A visual identifier that represents this user.
|
||||
*
|
||||
* @see UserInterface
|
||||
*/
|
||||
public function getUserIdentifier(): string {
|
||||
return (string)$this->username;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since Symfony 5.3, use getUserIdentifier instead
|
||||
*/
|
||||
public function getUsername(): string {
|
||||
return (string)$this->username;
|
||||
}
|
||||
|
||||
public function setUsername(string $username): self {
|
||||
$this->username = $username;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getEmail(): ?string {
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
public function setEmail(?string $email): self {
|
||||
$this->email = $email;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUid(): ?int {
|
||||
return $this->uid;
|
||||
}
|
||||
|
||||
public function setUid(?int $uid): self {
|
||||
$this->uid = $uid;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see PasswordAuthenticatedUserInterface
|
||||
*/
|
||||
public function getPassword(): string {
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
public function setPassword(string $password): self {
|
||||
$this->password = $password;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see UserInterface
|
||||
*/
|
||||
public function getRoles(): array {
|
||||
return $this->roles;
|
||||
}
|
||||
|
||||
public function setRoles(array $roles): self {
|
||||
if(!in_array('ROLE_USER', $roles)) {
|
||||
array_unshift($roles, 'ROLE_USER');
|
||||
}
|
||||
|
||||
$this->roles = array_unique($roles);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returning a salt is only needed, if you are not using a modern
|
||||
* hashing algorithm (e.g. bcrypt or sodium) in your security.yaml.
|
||||
*
|
||||
* @see UserInterface
|
||||
*/
|
||||
public function getSalt(): ?string {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see UserInterface
|
||||
*/
|
||||
public function eraseCredentials() {
|
||||
// If you store any temporary, sensitive data on the user, clear it here
|
||||
// $this->plainPassword = null;
|
||||
}
|
||||
}
|
||||
217
src/Entity/Worldmark.php
Normal file
217
src/Entity/Worldmark.php
Normal file
@ -0,0 +1,217 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\WorldmarkRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
|
||||
#[ORM\Entity(repositoryClass: WorldmarkRepository::class)]
|
||||
#[ORM\Index(columns: ['slug'])]
|
||||
#[UniqueEntity(fields: ['slug'], message: 'There is already a worldmark with this slug')]
|
||||
class Worldmark {
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
private $id;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: WorldmarkCategory::class)]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private $category;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: Item::class)]
|
||||
private $item;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: Monster::class)]
|
||||
private $monster;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 60)]
|
||||
private $name;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 60, unique: true)]
|
||||
private $slug;
|
||||
|
||||
#[ORM\Column(type: 'text', nullable: true)]
|
||||
private $description;
|
||||
|
||||
#[ORM\Column(type: 'tinyint', options: ['default' => 1, 'unsigned' => true])]
|
||||
private $defaultQuantityValue;
|
||||
|
||||
#[ORM\Column(type: 'tinyint', options: ['default' => 0, 'unsigned' => true])]
|
||||
private $defaultPrimogemValue;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, nullable: true)]
|
||||
private $icon;
|
||||
|
||||
#[ORM\Column(type: 'boolean', options: ['default' => 1])]
|
||||
private $canBeHidden;
|
||||
|
||||
#[ORM\Column(type: 'float')]
|
||||
private $version;
|
||||
|
||||
#[ORM\Column(type: 'smallint', options: ['default' => 65535, 'unsigned' => true])]
|
||||
private $sortOrder;
|
||||
|
||||
#[ORM\ManyToMany(targetEntity: Region::class, inversedBy: 'worldmarks')]
|
||||
#[ORM\JoinTable(name: 'region_worldmark')]
|
||||
private $regions;
|
||||
|
||||
public function __construct() {
|
||||
$this->defaultQuantityValue = 1;
|
||||
$this->defaultPrimogemValue = 0;
|
||||
$this->canBeHidden = 1;
|
||||
$this->regions=new ArrayCollection();
|
||||
}
|
||||
|
||||
public function __toString(): string {
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
public function getId(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getCategory(): WorldmarkCategory {
|
||||
return $this->category;
|
||||
}
|
||||
|
||||
public function setCategory(WorldmarkCategory $category): self {
|
||||
$this->category=$category;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getItem(): ?Item {
|
||||
return $this->item;
|
||||
}
|
||||
|
||||
public function setItem(?Item $item): self {
|
||||
$this->item=$item;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMonster(): ?Monster {
|
||||
return $this->monster;
|
||||
}
|
||||
|
||||
public function setMonster(?Monster $monster): self {
|
||||
$this->monster=$monster;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName(): ?string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): self {
|
||||
$this->name=$name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSlug(): ?string {
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function setSlug(string $slug): self {
|
||||
$this->slug=$slug;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDescription(): ?string {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
public function setDescription(?string $description): self {
|
||||
$this->description=$description;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDefaultQuantityValue() {
|
||||
return $this->defaultQuantityValue;
|
||||
}
|
||||
|
||||
public function setDefaultQuantityValue($defaultQuantityValue): self {
|
||||
$this->defaultQuantityValue = $defaultQuantityValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDefaultPrimogemValue() {
|
||||
return $this->defaultPrimogemValue;
|
||||
}
|
||||
|
||||
public function setDefaultPrimogemValue($defaultPrimogemValue): self {
|
||||
$this->defaultPrimogemValue = $defaultPrimogemValue;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIcon(): string|UploadedFile|null {
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
public function setIcon(string|UploadedFile|null $icon): self {
|
||||
$this->icon=$icon;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCanBeHidden(): ?bool {
|
||||
return $this->canBeHidden;
|
||||
}
|
||||
|
||||
public function setCanBeHidden(bool $canBeHidden): self {
|
||||
$this->canBeHidden=$canBeHidden;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getVersion(): ?float {
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
public function setVersion(float $version): self {
|
||||
$this->version=$version;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSortOrder(): ?int {
|
||||
return $this->sortOrder;
|
||||
}
|
||||
|
||||
public function setSortOrder(int $sortOrder): self {
|
||||
$this->sortOrder=$sortOrder;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRegions(): Collection {
|
||||
return $this->regions;
|
||||
}
|
||||
|
||||
public function addRegion(Region $region): self {
|
||||
if(!$this->regions->contains($region)) {
|
||||
$this->regions[]=$region;
|
||||
$region->addWorldmark($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeRegion(Region $region): self {
|
||||
if($this->regions->removeElement($region)) {
|
||||
$region->removeWorldmark($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
65
src/Entity/WorldmarkCategory.php
Normal file
65
src/Entity/WorldmarkCategory.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\WorldmarkCategoryRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
|
||||
#[ORM\Entity(repositoryClass: WorldmarkCategoryRepository::class)]
|
||||
#[ORM\Index(columns: ['slug'])]
|
||||
#[UniqueEntity(fields: ['name'], message: 'There is already a worldmark category with this name')]
|
||||
#[UniqueEntity(fields: ['slug'], message: 'There is already a worldmark category with this slug')]
|
||||
class WorldmarkCategory {
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: 'integer', options: ['unsigned' => true])]
|
||||
private $id;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, unique: true)]
|
||||
private $name;
|
||||
|
||||
#[ORM\Column(type: 'string', length: 50, unique: true)]
|
||||
private $slug;
|
||||
|
||||
#[ORM\Column(type: 'smallint', options: ['default' => 65535, 'unsigned' => true])]
|
||||
private $sortOrder;
|
||||
|
||||
public function __toString(): string {
|
||||
return $this->getName();
|
||||
}
|
||||
|
||||
public function getId(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getName(): ?string {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): self {
|
||||
$this->name=$name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSlug(): ?string {
|
||||
return $this->slug;
|
||||
}
|
||||
|
||||
public function setSlug(string $slug): self {
|
||||
$this->slug=$slug;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSortOrder(): ?int {
|
||||
return $this->sortOrder;
|
||||
}
|
||||
|
||||
public function setSortOrder(int $sortOrder): self {
|
||||
$this->sortOrder=$sortOrder;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
79
src/EventListener/KernelListener.php
Normal file
79
src/EventListener/KernelListener.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\EventListener;
|
||||
|
||||
use App\Extension\PhpExtension;
|
||||
use App\Kernel;
|
||||
use App\Repository\RegionRepository;
|
||||
use App\Repository\WorldmarkCategoryRepository;
|
||||
use Detection\MobileDetect;
|
||||
use Symfony\Component\HttpKernel\Event\ControllerEvent;
|
||||
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
|
||||
use Symfony\Component\HttpKernel\Event\RequestEvent;
|
||||
use Symfony\Component\HttpKernel\Event\ResponseEvent;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Twig\Environment as TwigEnvironment;
|
||||
|
||||
class KernelListener {
|
||||
public function __construct(private Security $security,
|
||||
private RouterInterface $router,
|
||||
private TwigEnvironment $twigEnvironment,
|
||||
private PhpExtension $phpExtension,
|
||||
// private MobileDetect $mobileDetect,
|
||||
private RegionRepository $regionRepository,
|
||||
private WorldmarkCategoryRepository $worldmarkCategoryRepository) {}
|
||||
|
||||
public function onKernelRequest(RequestEvent $requestEvent) {
|
||||
$request=$requestEvent->getRequest();
|
||||
|
||||
if(!$requestEvent->isMainRequest() || $request->isXmlHttpRequest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(($this->phpExtension->strStartWith($request->attributes->get('_route'), 'bo_')
|
||||
&& !$this->security->isGranted('ROLE_CONTRIBUTOR'))
|
||||
|| ($this->phpExtension->strStartWith($request->getRequestUri(), '/dev')
|
||||
&& (!$this->security->getUser() || !$this->security->isGranted('ROLE_ADMIN')))) {
|
||||
|
||||
throw new NotFoundHttpException("Page not found");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function onKernelController(ControllerEvent $controllerEvent) {
|
||||
if(!$controllerEvent->isMainRequest()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$request = $controllerEvent->getRequest();
|
||||
|
||||
$route = $request->attributes->get('_route');
|
||||
|
||||
$this->twigEnvironment->addGlobal('user', $this->security->getUser());
|
||||
$this->twigEnvironment->addGlobal('route', $route);
|
||||
$this->twigEnvironment->addGlobal('locale', $request->getLocale());
|
||||
$this->twigEnvironment->addGlobal('gameVersion', Kernel::GAME_VERSION);
|
||||
$this->twigEnvironment->addGlobal('supportedGameVersion', Kernel::SUPPORTED_GAME_VERSION);
|
||||
$this->twigEnvironment->addGlobal('isTouchDevice', $this->isTouchDevice());
|
||||
|
||||
$regions = $this->regionRepository->getRegions();
|
||||
$this->twigEnvironment->addGlobal('regions', $regions);
|
||||
}
|
||||
|
||||
public function onKernelResponse(ResponseEvent $responseEvent) {
|
||||
}
|
||||
|
||||
public function onKernelException(ExceptionEvent $exceptionEvent) {
|
||||
}
|
||||
|
||||
private function isTouchDevice(): array {
|
||||
$detect = new MobileDetect();
|
||||
|
||||
return array(
|
||||
'isTablet' => $detect->isTablet(),
|
||||
'isMobile' => $detect->isMobile(),
|
||||
);
|
||||
}
|
||||
}
|
||||
49
src/Extension/PhpExtension.php
Normal file
49
src/Extension/PhpExtension.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extension;
|
||||
|
||||
class PhpExtension {
|
||||
public function strStartWith(string $str, string $needle): bool {
|
||||
if($str === '' || $needle === '' || strlen($needle) > strlen($str) || substr_compare($str, $needle, 0, strlen($needle)) !== 0) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function strEndWith(string $str, string $needle): bool {
|
||||
if($str === '' || $needle === '' || strlen($needle) > strlen($str) || substr_compare($str, $needle, strlen($str)-strlen($needle), strlen($needle)) !== 0) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function strLike(string $str, string $needle, bool $ignoreCase = false): bool {
|
||||
if($ignoreCase) {
|
||||
return str_contains(strtolower($str), strtolower($needle));
|
||||
} else {
|
||||
return str_contains($str, $needle);
|
||||
}
|
||||
}
|
||||
|
||||
public function strPad(string $str, int $padLength, string $padString, string $direction='left'): string {
|
||||
$strPad=null;
|
||||
if($direction == 'left') {
|
||||
$strPad=STR_PAD_LEFT;
|
||||
} elseif($direction == 'right') {
|
||||
$strPad=STR_PAD_RIGHT;
|
||||
} elseif($direction == 'both') {
|
||||
$strPad=STR_PAD_BOTH;
|
||||
}
|
||||
if($strPad !== null) {
|
||||
return str_pad($str, $padLength, $padString, $strPad);
|
||||
} else {
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
public function trim($input): array|string {
|
||||
return !is_array($input) ? trim($input) : array_map(array($this, 'trim',), $input);
|
||||
}
|
||||
}
|
||||
105
src/Extension/TwigExtension.php
Normal file
105
src/Extension/TwigExtension.php
Normal file
@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace App\Extension;
|
||||
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFilter;
|
||||
use Twig\TwigFunction;
|
||||
|
||||
class TwigExtension extends AbstractExtension {
|
||||
public function getFunctions(): array {
|
||||
return array(
|
||||
new TwigFunction('getUuid', array($this, 'getUuidFunction')),
|
||||
);
|
||||
}
|
||||
|
||||
public function getFilters(): array {
|
||||
return array(
|
||||
new TwigFilter('json_decode', array($this, 'jsonDecodeFilter')),
|
||||
new TwigFilter('start_with', array($this, 'strStartWithFilter')),
|
||||
new TwigFilter('end_with', array($this, 'strEndWithFilter')),
|
||||
new TwigFilter('like', array($this, 'strLikeFilter')),
|
||||
new TwigFilter('pad', array($this, 'strPadFilter')),
|
||||
new TwigFilter('trim', array($this, 'trimFilter')),
|
||||
new TwigFilter('shuffle_array', array($this, 'shuffleArrayFilter')),
|
||||
);
|
||||
}
|
||||
|
||||
//<editor-fold desc="TWIG FUNCTIONS">
|
||||
public function getUuidFunction(): string {
|
||||
return Uuid::uuid1()->toString();
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
//<editor-fold desc="TWIG FILTERS">
|
||||
public function jsonDecodeFilter($json): mixed {
|
||||
if($this->isJson($json)) {
|
||||
return json_decode($json);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function strStartWithFilter(string $str, string $needle): bool {
|
||||
if($str === '' || $needle === '' || strlen($needle) > strlen($str) || substr_compare($str, $needle, 0, strlen($needle)) !== 0) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function strEndWithFilter(string $str, string $needle): bool {
|
||||
if($str === '' || $needle === '' || strlen($needle) > strlen($str) || substr_compare($str, $needle, strlen($str) - strlen($needle), strlen($needle)) !== 0) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public function strLikeFilter(string $str, string $needle, bool $ignoreCase = false): bool {
|
||||
if($ignoreCase) {
|
||||
return str_contains(strtolower($str), strtolower($needle));
|
||||
} else {
|
||||
return str_contains($str, $needle);
|
||||
}
|
||||
}
|
||||
|
||||
public function strPadFilter(string $str, int $padLength, string $padString, string $direction = 'left'): string {
|
||||
$strPad = null;
|
||||
if($direction == 'left') {
|
||||
$strPad = STR_PAD_LEFT;
|
||||
} elseif($direction == 'right') {
|
||||
$strPad = STR_PAD_RIGHT;
|
||||
} elseif($direction == 'both') {
|
||||
$strPad = STR_PAD_BOTH;
|
||||
}
|
||||
if($strPad !== null) {
|
||||
return str_pad($str, $padLength, $padString, $strPad);
|
||||
} else {
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
public function trimFilter($input): array|string {
|
||||
return !is_array($input) ? trim($input) : array_map(array($this, 'trim',), $input);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $array
|
||||
* @return array
|
||||
*/
|
||||
public function shuffleArrayFilter(array $array): array {
|
||||
shuffle($array);
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
//</editor-fold>
|
||||
|
||||
private function isJson($string): bool {
|
||||
json_decode($string);
|
||||
|
||||
return (json_last_error() == JSON_ERROR_NONE);
|
||||
}
|
||||
}
|
||||
37
src/Form/GridType.php
Normal file
37
src/Form/GridType.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\Grid;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class GridType extends AbstractType {
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void {
|
||||
// $builder->add('row')
|
||||
// ->add('col')
|
||||
// ->add('region');
|
||||
$builder->add('positions', ChoiceType::class, array(
|
||||
'choices' => array(
|
||||
'Add row before' => 'row_before',
|
||||
'Add row after' => 'row_after',
|
||||
'Add column before' => 'column_before',
|
||||
'Add column after' => 'column_after',
|
||||
),
|
||||
'data'=>null,
|
||||
'mapped'=>false,
|
||||
'expanded'=>true,
|
||||
'multiple'=>true,
|
||||
'required'=>false,
|
||||
));
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void {
|
||||
$resolver->setDefaults(array(
|
||||
'data_class' => Grid::class,
|
||||
'data_route' => null,
|
||||
));
|
||||
}
|
||||
}
|
||||
33
src/Form/ItemCategoryType.php
Normal file
33
src/Form/ItemCategoryType.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\ItemCategory;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class ItemCategoryType extends AbstractType {
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void {
|
||||
$builder->add('name', TextType::class, array(
|
||||
'attr' => array('data-slug-target' => 'item_category_name')
|
||||
))
|
||||
->add('slug', TextType::class, array(
|
||||
'attr' => array(
|
||||
'data-slug-source' => 'item_category_name',
|
||||
'readonly' => 'readonly',
|
||||
),
|
||||
))
|
||||
->add('sortOrder', TextType::class, array(
|
||||
// 'attr' => array('pattern'=>'^([1-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$'),
|
||||
));
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void {
|
||||
$resolver->setDefaults(array(
|
||||
'data_class' => ItemCategory::class,
|
||||
'data_route' => null,
|
||||
));
|
||||
}
|
||||
}
|
||||
56
src/Form/ItemType.php
Normal file
56
src/Form/ItemType.php
Normal file
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\Item;
|
||||
use App\Extension\PhpExtension;
|
||||
use App\Kernel;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FileType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class ItemType extends AbstractType {
|
||||
public function __construct(private PhpExtension $phpExtension) {}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void {
|
||||
$builder->add('name', TextType::class, array(
|
||||
'attr'=>array('data-slug-target'=>'item_name')
|
||||
))
|
||||
->add('slug', TextType::class, array(
|
||||
'attr'=>array(
|
||||
'data-slug-source'=>'item_name',
|
||||
'readonly'=>'readonly'
|
||||
)
|
||||
))
|
||||
->add('description', TextareaType::class, array(
|
||||
'required'=>false
|
||||
))
|
||||
->add('icon', FileType::class, array(
|
||||
'data'=>null,
|
||||
'required'=>false,
|
||||
))
|
||||
->add('version', ChoiceType::class, array(
|
||||
'choices'=>array_combine(Kernel::SUPPORTED_GAME_VERSION, Kernel::SUPPORTED_GAME_VERSION),
|
||||
'data'=>$this->phpExtension->strEndWith($options['data_route'], '_new') ? Kernel::GAME_VERSION : $options['data']->getVersion(),
|
||||
));
|
||||
|
||||
if($this->phpExtension->strEndWith($options['data_route'], '_edit')) {
|
||||
$builder->add('removeFile', CheckboxType::class, array(
|
||||
'mapped'=>false,
|
||||
'required'=>false,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void {
|
||||
$resolver->setDefaults(array(
|
||||
'data_class' => Item::class,
|
||||
'data_route' => null,
|
||||
));
|
||||
}
|
||||
}
|
||||
51
src/Form/MapFragmentType.php
Normal file
51
src/Form/MapFragmentType.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\Map;
|
||||
use App\Extension\PhpExtension;
|
||||
use App\Kernel;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FileType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class MapFragmentType extends AbstractType {
|
||||
public function __construct(private PhpExtension $phpExtension) {}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void {
|
||||
$builder->add('row', TextType::class, array(
|
||||
'attr'=>array('pattern'=>'[0-9]'),
|
||||
))
|
||||
->add('col', TextType::class, array(
|
||||
'attr'=>array('pattern'=>'[0-9]'),
|
||||
))
|
||||
->add('fragment', FileType::class, array(
|
||||
'data_class'=>null,
|
||||
'required'=>false,
|
||||
))
|
||||
->add('version', ChoiceType::class, array(
|
||||
'choices'=>array_combine(Kernel::SUPPORTED_GAME_VERSION, Kernel::SUPPORTED_GAME_VERSION),
|
||||
'data'=>$this->phpExtension->strEndWith($options['data_route'], '_new') ? Kernel::GAME_VERSION : $options['data']->getVersion(),
|
||||
));
|
||||
// ->add('modifiedAt')
|
||||
// ->add('region');
|
||||
|
||||
if($this->phpExtension->strEndWith($options['data_route'], '_edit')) {
|
||||
$builder->add('blank', CheckboxType::class, array(
|
||||
'mapped'=>false,
|
||||
'required'=>false,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void {
|
||||
$resolver->setDefaults([
|
||||
'data_class'=>Map::class,
|
||||
'data_route'=>null,
|
||||
]);
|
||||
}
|
||||
}
|
||||
33
src/Form/MapType.php
Normal file
33
src/Form/MapType.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\Map;
|
||||
use App\Extension\PhpExtension;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FileType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class MapType extends AbstractType {
|
||||
public function __construct(private PhpExtension $phpExtension) {}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void {
|
||||
$builder->add('file', FileType::class, array(
|
||||
'data_class'=>null,
|
||||
'required'=>false,
|
||||
));
|
||||
|
||||
if($this->phpExtension->strEndWith($options['data_route'], '_new')) {
|
||||
$builder->add('version', HiddenType::class);
|
||||
}
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void {
|
||||
$resolver->setDefaults(array(
|
||||
'data_class'=>Map::class,
|
||||
'data_route'=>null,
|
||||
));
|
||||
}
|
||||
}
|
||||
30
src/Form/MonsterCategoryType.php
Normal file
30
src/Form/MonsterCategoryType.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\MonsterCategory;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class MonsterCategoryType extends AbstractType {
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void {
|
||||
$builder->add('name', TextType::class, array(
|
||||
'attr'=>array('data-slug-target'=>'monster_category_name')
|
||||
))
|
||||
->add('slug', TextType::class, array(
|
||||
'attr'=>array(
|
||||
'data-slug-source'=>'monster_category_name',
|
||||
'readonly'=>'readonly'
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void {
|
||||
$resolver->setDefaults(array(
|
||||
'data_class'=>MonsterCategory::class,
|
||||
'data_route'=>null,
|
||||
));
|
||||
}
|
||||
}
|
||||
58
src/Form/MonsterType.php
Normal file
58
src/Form/MonsterType.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\Monster;
|
||||
use App\Extension\PhpExtension;
|
||||
use App\Kernel;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FileType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class MonsterType extends AbstractType {
|
||||
public function __construct(private PhpExtension $phpExtension) {}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void {
|
||||
$builder->add('name', TextType::class, array(
|
||||
'attr'=>array(
|
||||
'data-slug-target'=>'monster_name'
|
||||
)
|
||||
))
|
||||
->add('slug', TextType::class, array(
|
||||
'attr'=>array(
|
||||
'data-slug-source'=>'monster_name',
|
||||
'readonly'=>'readonly'
|
||||
)
|
||||
))
|
||||
->add('description', TextareaType::class, array(
|
||||
'required'=>false
|
||||
))
|
||||
->add('icon', FileType::class, array(
|
||||
'data'=>null,
|
||||
'required'=>false,
|
||||
))
|
||||
->add('version', ChoiceType::class, array(
|
||||
'choices'=>array_combine(Kernel::SUPPORTED_GAME_VERSION, Kernel::SUPPORTED_GAME_VERSION),
|
||||
'data'=>$this->phpExtension->strEndWith($options['data_route'], '_new') ? Kernel::GAME_VERSION : $options['data']->getVersion(),
|
||||
));
|
||||
|
||||
if($this->phpExtension->strEndWith($options['data_route'], '_edit')) {
|
||||
$builder->add('removeFile', CheckboxType::class, array(
|
||||
'mapped'=>false,
|
||||
'required'=>false,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void {
|
||||
$resolver->setDefaults(array(
|
||||
'data_class'=>Monster::class,
|
||||
'data_route'=>null,
|
||||
));
|
||||
}
|
||||
}
|
||||
126
src/Form/NodeType.php
Normal file
126
src/Form/NodeType.php
Normal file
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\Node;
|
||||
use App\Extension\PhpExtension;
|
||||
use App\Kernel;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\CallbackTransformer;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FileType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\NumberType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class NodeType extends AbstractType {
|
||||
public function __construct(private PhpExtension $phpExtension) {}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void {
|
||||
/** @var Node $node */
|
||||
$node =$options['data'];
|
||||
|
||||
|
||||
if($options['data_route'] == 'bo_node_delete') {
|
||||
$builder->add('isDeleted', HiddenType::class, array(
|
||||
'data'=>true,
|
||||
'required'=>true
|
||||
));
|
||||
} else {
|
||||
$coordinate = $node->getCoordinate();
|
||||
$versions=Kernel::SUPPORTED_GAME_VERSION;
|
||||
|
||||
foreach($versions as $key=>$version) {
|
||||
if($version < Kernel::GAME_VERSION) {
|
||||
unset($versions[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
$builder->add('quantity', TextType::class, array(
|
||||
'attr'=>array(
|
||||
'pattern'=>'^([1-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$',
|
||||
),
|
||||
'data' => $this->phpExtension->strEndWith($options['data_route'], '_new') ? $node->getWorldmark()->getDefaultQuantityValue() : $node->getQuantity()
|
||||
))
|
||||
->add('primogem', TextType::class, array(
|
||||
'attr'=>array(
|
||||
'pattern'=>'^([0-9]|[1-9][0-9]{1-2})$',
|
||||
),
|
||||
'data' => $this->phpExtension->strEndWith($options['data_route'], '_new') ? $node->getWorldmark()->getDefaultPrimogemValue() : $node->getPrimogem()
|
||||
))
|
||||
->add('coordinate', HiddenType::class)
|
||||
->add('coordX', NumberType::class, array(
|
||||
'attr'=>array(
|
||||
'readonly'=>true,
|
||||
'disabled'=>true,
|
||||
),
|
||||
'data'=>$coordinate['x'],
|
||||
'mapped'=>false,
|
||||
))
|
||||
->add('coordY', NumberType::class, array(
|
||||
'attr'=>array(
|
||||
'readonly'=>true,
|
||||
'disabled'=>true,
|
||||
),
|
||||
'data'=>$coordinate['y'],
|
||||
'mapped'=>false,
|
||||
))
|
||||
->add('description', TextareaType::class, array(
|
||||
'required'=>false
|
||||
))
|
||||
->add('screenshotA', FileType::class, array(
|
||||
'data'=>null,
|
||||
'required'=>false,
|
||||
))
|
||||
->add('screenshotB', FileType::class, array(
|
||||
'data'=>null,
|
||||
'required'=>false,
|
||||
))
|
||||
->add('screenshotC', FileType::class, array(
|
||||
'data'=>null,
|
||||
'required'=>false,
|
||||
))
|
||||
->add('screenshotD', FileType::class, array(
|
||||
'data'=>null,
|
||||
'required'=>false,
|
||||
))
|
||||
->add('screenshotE', FileType::class, array(
|
||||
'data'=>null,
|
||||
'required'=>false,
|
||||
))
|
||||
->add('version', ChoiceType::class, array(
|
||||
'choices' => array_combine($versions, $versions),
|
||||
'data' => $this->phpExtension->strEndWith($options['data_route'], '_new') ? Kernel::GAME_VERSION : ($options['data']->getVersion() < Kernel::GAME_VERSION ? Kernel::GAME_VERSION : $options['data']->getVersion()),
|
||||
'expanded' => true,
|
||||
'multiple' => false,
|
||||
'required' => true,
|
||||
));
|
||||
// ->add('createAt')
|
||||
// ->add('modifiedAt')
|
||||
|
||||
// ->add('isDeleted')
|
||||
// ->add('grid')
|
||||
// ->add('worldmark')
|
||||
|
||||
$builder->get('coordinate')
|
||||
->addModelTransformer(new CallbackTransformer(
|
||||
function($array) use ($builder) {
|
||||
return json_encode($array);
|
||||
},
|
||||
function($string) use ($builder) {
|
||||
return json_decode($string, true);
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void {
|
||||
$resolver->setDefaults(array(
|
||||
'data_class'=>Node::class,
|
||||
'data_route'=>null,
|
||||
));
|
||||
}
|
||||
}
|
||||
107
src/Form/RegionType.php
Normal file
107
src/Form/RegionType.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\Region;
|
||||
use App\Extension\PhpExtension;
|
||||
use App\Kernel;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class RegionType extends AbstractType {
|
||||
private array $parameters;
|
||||
|
||||
public function __construct(ParameterBagInterface $parameterBag,
|
||||
private PhpExtension $phpExtension) {
|
||||
$this->parameters=array('assets'=>$parameterBag->get('assets'));
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void {
|
||||
$icons=array();
|
||||
$finder=new Finder();
|
||||
$finder->files()->in($this->parameters['assets']['img']['region'])
|
||||
->name('*.png')
|
||||
->sortByName();
|
||||
|
||||
foreach($finder as $fileInfo) {
|
||||
$icons[$fileInfo->getBasename()]=$fileInfo->getBasename();
|
||||
}
|
||||
|
||||
$builder->add('parentRegion')
|
||||
->add('name', TextType::class, array(
|
||||
'attr'=>array(
|
||||
'data-slug-target'=>'region_name'
|
||||
)
|
||||
))
|
||||
->add('slug', TextType::class, array(
|
||||
'attr'=>array(
|
||||
'data-slug-source'=>'region_name',
|
||||
'readonly'=>'readonly'
|
||||
)
|
||||
))
|
||||
->add('isAlias', ChoiceType::class, array(
|
||||
'choices'=>array('No'=>0, 'Yes'=>1),
|
||||
'data'=>$this->phpExtension->strEndWith($options['data_route'], '_new') ? 0 : $options['data']->getIsAlias(),
|
||||
'expanded' => true,
|
||||
'multiple' => false,
|
||||
'required' => true,
|
||||
))
|
||||
->add('anchor', TextType::class, array('required' => false))
|
||||
->add('description', TextareaType::class, array(
|
||||
'required'=>false
|
||||
))
|
||||
->add('icon', ChoiceType::class, array(
|
||||
'choices'=>$icons,
|
||||
'expanded'=>true,
|
||||
'required'=>true,
|
||||
))
|
||||
->add('mapBackground', ChoiceType::class, array(
|
||||
'choices' => array(
|
||||
'Sea' => 'sea',
|
||||
'Sand' => 'sand',
|
||||
),
|
||||
'expanded'=>true,
|
||||
'required' => true,
|
||||
))
|
||||
->add('version', ChoiceType::class, array(
|
||||
'choices'=>array_combine(Kernel::SUPPORTED_GAME_VERSION, Kernel::SUPPORTED_GAME_VERSION),
|
||||
'data'=>$this->phpExtension->strEndWith($options['data_route'], '_new') ? Kernel::GAME_VERSION : $options['data']->getVersion(),
|
||||
))
|
||||
->add('sortOrder', TextType::class, array(
|
||||
// 'attr'=>array('pattern'=>'^([1-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$'),
|
||||
))
|
||||
->add('isActive', ChoiceType::class, array(
|
||||
'choices'=>array('No'=>0, 'Yes'=>1),
|
||||
'data'=>$this->phpExtension->strEndWith($options['data_route'], '_new') ? 1 : $options['data']->getIsActive(),
|
||||
'expanded' => true,
|
||||
'multiple' => false,
|
||||
'required' => true,
|
||||
));
|
||||
|
||||
if($this->phpExtension->strEndWith($options['data_route'], '_new')) {
|
||||
$builder->add('gridHeight', TextType::class, array(
|
||||
'attr'=>array(
|
||||
'pattern'=>'^([1-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$',
|
||||
),
|
||||
))
|
||||
->add('gridWidth', TextType::class, array(
|
||||
'attr'=>array(
|
||||
'pattern'=>'^([1-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$',
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void {
|
||||
$resolver->setDefaults(array(
|
||||
'data_class'=>Region::class,
|
||||
'data_route'=>null,
|
||||
));
|
||||
}
|
||||
}
|
||||
48
src/Form/SecurityType.php
Normal file
48
src/Form/SecurityType.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\User;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Component\Validator\Constraints\IsTrue;
|
||||
use Symfony\Component\Validator\Constraints\Length;
|
||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||
|
||||
class SecurityType extends AbstractType {
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void {
|
||||
$builder->add('username')
|
||||
->add('plainPassword', PasswordType::class, array(
|
||||
// instead of being set onto the object directly,
|
||||
// this is read and encoded in the controller
|
||||
'mapped' => false,
|
||||
'attr' => array('autocomplete' => 'new-password'),
|
||||
'constraints' => array(
|
||||
new NotBlank(array('message' => 'Please enter a password')),
|
||||
new Length(array(
|
||||
'min' => 6,
|
||||
'minMessage' => 'Your password should be at least {{ limit }} characters',
|
||||
// max length allowed by Symfony for security reasons
|
||||
'max' => 4096,
|
||||
)),
|
||||
),
|
||||
))
|
||||
->add('agreeTerms', CheckboxType::class, array(
|
||||
'mapped' => false,
|
||||
'constraints' => array(
|
||||
new IsTrue(array('message' => 'You should agree to our terms.')),
|
||||
),
|
||||
'label' => 'Agree non-existing terms',
|
||||
));
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void {
|
||||
$resolver->setDefaults(array(
|
||||
'data_class' => User::class,
|
||||
'data_route' => null,
|
||||
));
|
||||
}
|
||||
}
|
||||
33
src/Form/WorldmarkCategoryType.php
Normal file
33
src/Form/WorldmarkCategoryType.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\WorldmarkCategory;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class WorldmarkCategoryType extends AbstractType {
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void {
|
||||
$builder->add('name', TextType::class, array(
|
||||
'attr' => array('data-slug-target' => 'worldmark_category_name'),
|
||||
))
|
||||
->add('slug', TextType::class, array(
|
||||
'attr' => array(
|
||||
'data-slug-source' => 'worldmark_category_name',
|
||||
'readonly' => 'readonly',
|
||||
),
|
||||
))
|
||||
->add('sortOrder', TextType::class, array(
|
||||
// 'attr' => array('pattern'=>'^([1-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$'),
|
||||
));
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void {
|
||||
$resolver->setDefaults(array(
|
||||
'data_class' => WorldmarkCategory::class,
|
||||
'data_route' => null,
|
||||
));
|
||||
}
|
||||
}
|
||||
103
src/Form/WorldmarkType.php
Normal file
103
src/Form/WorldmarkType.php
Normal file
@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
namespace App\Form;
|
||||
|
||||
use App\Entity\Item;
|
||||
use App\Entity\Monster;
|
||||
use App\Entity\Region;
|
||||
use App\Entity\Worldmark;
|
||||
use App\Extension\PhpExtension;
|
||||
use App\Kernel;
|
||||
use Doctrine\ORM\EntityRepository;
|
||||
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FileType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
class WorldmarkType extends AbstractType {
|
||||
public function __construct(private PhpExtension $phpExtension) {}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void {
|
||||
$builder->add('name', TextType::class, array(
|
||||
'attr' => array('data-slug-target' => 'worldmark_name'),
|
||||
))
|
||||
->add('slug', TextType::class, array(
|
||||
'attr' => array(
|
||||
'data-slug-source' => 'worldmark_name',
|
||||
// 'readonly' => 'readonly',
|
||||
),
|
||||
))
|
||||
->add('description', TextareaType::class, array(
|
||||
'required' => false,
|
||||
))
|
||||
->add('defaultQuantityValue', TextType::class, array(
|
||||
'attr' => array(
|
||||
'pattern' => '^([1-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$',
|
||||
),
|
||||
))
|
||||
->add('defaultPrimogemValue', TextType::class, array(
|
||||
'attr' => array(
|
||||
'pattern' => '^([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$',
|
||||
),
|
||||
))
|
||||
->add('icon', FileType::class, array(
|
||||
'data' => null,
|
||||
'required' => false,
|
||||
))
|
||||
->add('canBeHidden')
|
||||
->add('item', EntityType::class, array(
|
||||
'class' => Item::class,
|
||||
'query_builder' => function(EntityRepository $er) {
|
||||
$qb = $er->createQueryBuilder("item");
|
||||
|
||||
return $qb->addSelect("category")
|
||||
->join("item.category", "category")
|
||||
->orderBy("category.name")
|
||||
->addOrderBy("item.name");
|
||||
},
|
||||
'group_by' => 'category',
|
||||
'required' => false,
|
||||
))
|
||||
->add('monster', EntityType::class, array(
|
||||
'class' => Monster::class,
|
||||
'query_builder' => function(EntityRepository $er) {
|
||||
$qb = $er->createQueryBuilder("monster");
|
||||
|
||||
return $qb->addSelect("category")
|
||||
->join("monster.category", "category")
|
||||
->orderBy("category.name")
|
||||
->addOrderBy("monster.name");
|
||||
},
|
||||
'group_by' => 'category',
|
||||
'required' => false,
|
||||
))
|
||||
->add('regions', EntityType::class, array(
|
||||
'class' => Region::class,
|
||||
'query_builder' => function(EntityRepository $er) {
|
||||
$qb = $er->createQueryBuilder("regions");
|
||||
|
||||
return $qb->andWhere($qb->expr()->eq("regions.isActive", 1));
|
||||
},
|
||||
'expanded' => true,
|
||||
'multiple' => true,
|
||||
))
|
||||
->add('version', ChoiceType::class, array(
|
||||
'choices' => array_combine(Kernel::SUPPORTED_GAME_VERSION, Kernel::SUPPORTED_GAME_VERSION),
|
||||
'data' => $this->phpExtension->strEndWith($options['data_route'], '_new') ? Kernel::GAME_VERSION : $options['data']->getVersion(),
|
||||
))
|
||||
->add('sortOrder', TextType::class, array(
|
||||
// 'attr'=>array('pattern'=>'^([1-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$'),
|
||||
));
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void {
|
||||
$resolver->setDefaults(array(
|
||||
'data_class'=>Worldmark::class,
|
||||
'data_route'=>null,
|
||||
));
|
||||
}
|
||||
}
|
||||
17
src/Kernel.php
Normal file
17
src/Kernel.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
||||
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
|
||||
|
||||
class Kernel extends BaseKernel {
|
||||
use MicroKernelTrait;
|
||||
|
||||
public const GAME_VERSION = 3.6;
|
||||
public const SUPPORTED_GAME_VERSION=array(
|
||||
1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6,
|
||||
2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8,
|
||||
3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6
|
||||
);
|
||||
}
|
||||
0
src/Repository/.gitignore
vendored
Normal file
0
src/Repository/.gitignore
vendored
Normal file
116
src/Repository/GridRepository.php
Normal file
116
src/Repository/GridRepository.php
Normal file
@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Grid;
|
||||
use App\Entity\Map;
|
||||
use App\Entity\Region;
|
||||
use App\Form\GridType;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use LogicException;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
|
||||
/**
|
||||
* @method Grid|null find($id, $lockMode=null, $lockVersion=null)
|
||||
* @method Grid|null findOneBy(array $criteria, array $orderBy=null)
|
||||
* @method Grid[] findAll()
|
||||
* @method Grid[] findBy(array $criteria, array $orderBy=null, $limit=null, $offset=null)
|
||||
*/
|
||||
class GridRepository extends ServiceEntityRepository {
|
||||
public function __construct(ManagerRegistry $registry,
|
||||
private RouterInterface $router,
|
||||
private FormFactoryInterface $formFactory,
|
||||
private MapRepository $mapRepository) {
|
||||
parent::__construct($registry, Grid::class);
|
||||
}
|
||||
|
||||
public function getForm(string $route, Grid $grid): FormInterface {
|
||||
$params=$grid->getId() !== null ? array('id'=>$grid->getId()) : array();
|
||||
|
||||
return $this->formFactory->create(GridType::class, $grid, array(
|
||||
'action'=>$this->router->generate($route, $params),
|
||||
'method'=>'post',
|
||||
'data_route'=>$route,
|
||||
));
|
||||
}
|
||||
|
||||
public function getGridForm(string $route, Region $region): FormInterface {
|
||||
return $this->formFactory->create(GridType::class, null, array(
|
||||
'action'=>$this->router->generate($route, array('regionId'=>$region->getId())),
|
||||
'method'=>'post',
|
||||
'data_route'=>$route,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Region $region
|
||||
* @return Grid[]
|
||||
*/
|
||||
public function getGridCells(Region $region): array {
|
||||
$qb=$this->_em->createQueryBuilder();
|
||||
|
||||
$qb->select("grid")
|
||||
->from(Grid::class, "grid")
|
||||
->andWhere($qb->expr()->eq("grid.region", ":param_region"))
|
||||
->orderBy("grid.row")
|
||||
->addOrderBy("grid.col");
|
||||
|
||||
$qb->setParameter('param_region', $region->getId(), Types::INTEGER);
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
|
||||
public function buildWorldmap(float $version, array $cells, array $maps, bool $withForm=false): array {
|
||||
$grid=array();
|
||||
|
||||
/** @var Map $map */
|
||||
foreach($maps as $key=>$map) {
|
||||
if(!($map instanceof Map)) {
|
||||
throw new LogicException(sprintf(
|
||||
'Variable passed must be an instance of "%s". "%s" given',
|
||||
Map::class,
|
||||
gettype($map)
|
||||
));
|
||||
}
|
||||
|
||||
$maps["cell_{$map->getGrid()->getId()}"]=array(
|
||||
'map'=>$map,
|
||||
'form'=>$withForm ? $this->mapRepository->getForm('bo_map_edit', $map->getGrid(), $map)->createView() : null
|
||||
);
|
||||
|
||||
unset($maps[$key]);
|
||||
}
|
||||
|
||||
/** @var Grid $cell */
|
||||
foreach($cells as $cell) {
|
||||
if(!($cell instanceof Grid)) {
|
||||
throw new LogicException(sprintf(
|
||||
'Variable passed must be an instance of "%s". "%s" given',
|
||||
Grid::class,
|
||||
gettype($map)
|
||||
));
|
||||
}
|
||||
|
||||
if(!array_key_exists("cell_{$cell->getId()}", $maps)) {
|
||||
$_map=new Map();
|
||||
$_map->setVersion($version);
|
||||
|
||||
$maps["cell_{$cell->getId()}"]=array(
|
||||
'map'=>$_map,
|
||||
'form'=>$withForm ? $this->mapRepository->getForm('bo_map_new', $cell, $_map)->createView() : null
|
||||
);
|
||||
}
|
||||
|
||||
$grid[$cell->getRow()][$cell->getCol()]=array(
|
||||
'id'=>$cell->getId(),
|
||||
'map_data'=>$maps["cell_{$cell->getId()}"],
|
||||
);
|
||||
}
|
||||
|
||||
return $grid;
|
||||
}
|
||||
}
|
||||
35
src/Repository/ItemCategoryRepository.php
Normal file
35
src/Repository/ItemCategoryRepository.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\ItemCategory;
|
||||
use App\Form\ItemCategoryType;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
|
||||
/**
|
||||
* @method ItemCategory|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method ItemCategory|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method ItemCategory[] findAll()
|
||||
* @method ItemCategory[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
class ItemCategoryRepository extends ServiceEntityRepository {
|
||||
public function __construct(ManagerRegistry $registry,
|
||||
private RouterInterface $router,
|
||||
private FormFactoryInterface $formFactory) {
|
||||
parent::__construct($registry, ItemCategory::class);
|
||||
}
|
||||
|
||||
public function getForm(string $route, ItemCategory $itemCategory): FormInterface {
|
||||
$params=$itemCategory->getId() !== null ? array('id'=>$itemCategory->getId()) : array();
|
||||
|
||||
return $this->formFactory->create(ItemCategoryType::class, $itemCategory, array(
|
||||
'action'=>$this->router->generate($route, $params),
|
||||
'method'=>'post',
|
||||
'data_route'=>$route,
|
||||
));
|
||||
}
|
||||
}
|
||||
36
src/Repository/ItemRepository.php
Normal file
36
src/Repository/ItemRepository.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Item;
|
||||
use App\Entity\ItemCategory;
|
||||
use App\Form\ItemType;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
|
||||
/**
|
||||
* @method Item|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method Item|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method Item[] findAll()
|
||||
* @method Item[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
class ItemRepository extends ServiceEntityRepository {
|
||||
public function __construct(ManagerRegistry $registry,
|
||||
private RouterInterface $router,
|
||||
private FormFactoryInterface $formFactory) {
|
||||
parent::__construct($registry, Item::class);
|
||||
}
|
||||
|
||||
public function getForm(string $route, ItemCategory $itemCategory, Item $item): FormInterface {
|
||||
$params=$item->getId() !== null ? array('itemCategoryId'=>$itemCategory->getId(), 'id'=>$item->getId()) : array('itemCategoryId'=>$itemCategory->getId());
|
||||
|
||||
return $this->formFactory->create(ItemType::class, $item, array(
|
||||
'action'=>$this->router->generate($route, $params),
|
||||
'method'=>'post',
|
||||
'data_route'=>$route,
|
||||
));
|
||||
}
|
||||
}
|
||||
57
src/Repository/MapRepository.php
Normal file
57
src/Repository/MapRepository.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Grid;
|
||||
use App\Entity\Map;
|
||||
use App\Form\MapType;
|
||||
use App\Kernel;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
|
||||
/**
|
||||
* @method Map|null find($id, $lockMode=null, $lockVersion=null)
|
||||
* @method Map|null findOneBy(array $criteria, array $orderBy=null)
|
||||
* @method Map[] findAll()
|
||||
* @method Map[] findBy(array $criteria, array $orderBy=null, $limit=null, $offset=null)
|
||||
*/
|
||||
class MapRepository extends ServiceEntityRepository {
|
||||
public function __construct(ManagerRegistry $registry,
|
||||
private RouterInterface $router,
|
||||
private FormFactoryInterface $formFactory) {
|
||||
parent::__construct($registry, Map::class);
|
||||
}
|
||||
|
||||
public function getForm(string $route, Grid $cell, Map $map): FormInterface {
|
||||
$params=$map->getId() !== null ? array('cellId'=>$cell->getId(), 'id'=>$map->getId()) : array('cellId'=>$cell->getId());
|
||||
|
||||
return $this->formFactory->create(MapType::class, $map, array(
|
||||
'action'=>$this->router->generate($route, $params),
|
||||
'method'=>'post',
|
||||
'data_route'=>$route,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $cells
|
||||
* @param float $version
|
||||
* @return Map[]
|
||||
*/
|
||||
public function getCellsMap(array $cells, float $version=Kernel::GAME_VERSION): array {
|
||||
$qb=$this->_em->createQueryBuilder();
|
||||
|
||||
$qb->select("map")
|
||||
->from(Map::class, "map")
|
||||
->andWhere($qb->expr()->eq("map.version", ":param_version"))
|
||||
->andWhere($qb->expr()->in("map.grid", ":param_in"));
|
||||
|
||||
$qb->setParameter('param_in', $cells)
|
||||
->setParameter("param_version", $version, Types::FLOAT);
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
}
|
||||
35
src/Repository/MonsterCategoryRepository.php
Normal file
35
src/Repository/MonsterCategoryRepository.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\MonsterCategory;
|
||||
use App\Form\MonsterCategoryType;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
|
||||
/**
|
||||
* @method MonsterCategory|null find($id, $lockMode=null, $lockVersion=null)
|
||||
* @method MonsterCategory|null findOneBy(array $criteria, array $orderBy=null)
|
||||
* @method MonsterCategory[] findAll()
|
||||
* @method MonsterCategory[] findBy(array $criteria, array $orderBy=null, $limit=null, $offset=null)
|
||||
*/
|
||||
class MonsterCategoryRepository extends ServiceEntityRepository {
|
||||
public function __construct(ManagerRegistry $registry,
|
||||
private RouterInterface $router,
|
||||
private FormFactoryInterface $formFactory) {
|
||||
parent::__construct($registry, MonsterCategory::class);
|
||||
}
|
||||
|
||||
public function getForm(string $route, MonsterCategory $monsterCategory): FormInterface {
|
||||
$params=$monsterCategory->getId() !== null ? array('id'=>$monsterCategory->getId()) : array();
|
||||
|
||||
return $this->formFactory->create(MonsterCategoryType::class, $monsterCategory, array(
|
||||
'action'=>$this->router->generate($route, $params),
|
||||
'method'=>'post',
|
||||
'data_route'=>$route,
|
||||
));
|
||||
}
|
||||
}
|
||||
36
src/Repository/MonsterRepository.php
Normal file
36
src/Repository/MonsterRepository.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Monster;
|
||||
use App\Entity\MonsterCategory;
|
||||
use App\Form\MonsterType;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
|
||||
/**
|
||||
* @method Monster|null find($id, $lockMode=null, $lockVersion=null)
|
||||
* @method Monster|null findOneBy(array $criteria, array $orderBy=null)
|
||||
* @method Monster[] findAll()
|
||||
* @method Monster[] findBy(array $criteria, array $orderBy=null, $limit=null, $offset=null)
|
||||
*/
|
||||
class MonsterRepository extends ServiceEntityRepository {
|
||||
public function __construct(ManagerRegistry $registry,
|
||||
private RouterInterface $router,
|
||||
private FormFactoryInterface $formFactory) {
|
||||
parent::__construct($registry, Monster::class);
|
||||
}
|
||||
|
||||
public function getForm(string $route, MonsterCategory $monsterCategory, Monster $monster): FormInterface {
|
||||
$params=$monster->getId() !== null ? array('monsterCategoryId'=>$monsterCategory->getId(), 'id'=>$monster->getId()) : array('monsterCategoryId'=>$monsterCategory->getId());
|
||||
|
||||
return $this->formFactory->create(MonsterType::class, $monster, array(
|
||||
'action'=>$this->router->generate($route, $params),
|
||||
'method'=>'post',
|
||||
'data_route'=>$route,
|
||||
));
|
||||
}
|
||||
}
|
||||
77
src/Repository/NodeRepository.php
Normal file
77
src/Repository/NodeRepository.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Grid;
|
||||
use App\Entity\Node;
|
||||
use App\Entity\Worldmark;
|
||||
use App\Form\NodeType;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
|
||||
/**
|
||||
* @method Node|null find($id, $lockMode=null, $lockVersion=null)
|
||||
* @method Node|null findOneBy(array $criteria, array $orderBy=null)
|
||||
* @method Node[] findAll()
|
||||
* @method Node[] findBy(array $criteria, array $orderBy=null, $limit=null, $offset=null)
|
||||
*/
|
||||
class NodeRepository extends ServiceEntityRepository {
|
||||
private RouterInterface $router;
|
||||
private FormFactoryInterface $formFactory;
|
||||
|
||||
public function __construct(ManagerRegistry $registry, RouterInterface $router, FormFactoryInterface $formFactory) {
|
||||
parent::__construct($registry, Node::class);
|
||||
$this->router=$router;
|
||||
$this->formFactory=$formFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Grid[] $grid
|
||||
* @param Worldmark[] $worldmarks
|
||||
* @param float $version
|
||||
* @param bool $includeDeleted
|
||||
* @return Node[]
|
||||
*/
|
||||
public function getGridNodes(array $grid, array $worldmarks, float $version, bool $includeDeleted = false): array {
|
||||
$qb=$this->_em->createQueryBuilder();
|
||||
|
||||
$qb->select("node")
|
||||
->from(Node::class, "node")
|
||||
->andWhere($qb->expr()->in("node.grid", ":param_inGridId"))
|
||||
->andWhere($qb->expr()->in("node.worldmark", ":param_inWorldmarkId"))
|
||||
->andWhere($qb->expr()->lte("node.version", ":param_version"))
|
||||
->orderBy("node.grid");
|
||||
|
||||
$qb->setParameters(array(
|
||||
'param_inGridId' => $grid,
|
||||
'param_inWorldmarkId' => $worldmarks,
|
||||
'param_version' => $version,
|
||||
));
|
||||
|
||||
if(!$includeDeleted) {
|
||||
$qb->andWhere($qb->expr()->eq("node.isDeleted", 0));
|
||||
}
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
|
||||
public function getForm(string $route, Grid $grid, Worldmark $worldmark, Node $node): FormInterface {
|
||||
$params=$node->getId() !== null ? array(
|
||||
'gridId'=>$grid->getId(),
|
||||
'worldmarkId'=>$worldmark->getId(),
|
||||
'id'=>$node->getId(),
|
||||
) : array(
|
||||
'gridId'=>$grid->getId(),
|
||||
'worldmarkId'=>$worldmark->getId(),
|
||||
);
|
||||
|
||||
return $this->formFactory->create(NodeType::class, $node, array(
|
||||
'action'=>$this->router->generate($route, $params),
|
||||
'method'=>'post',
|
||||
'data_route'=>$route,
|
||||
));
|
||||
}
|
||||
}
|
||||
49
src/Repository/RegionRepository.php
Normal file
49
src/Repository/RegionRepository.php
Normal file
@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Region;
|
||||
use App\Form\RegionType;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
|
||||
/**
|
||||
* @method Region|null find($id, $lockMode=null, $lockVersion=null)
|
||||
* @method Region|null findOneBy(array $criteria, array $orderBy=null)
|
||||
* @method Region[] findAll()
|
||||
* @method Region[] findBy(array $criteria, array $orderBy=null, $limit=null, $offset=null)
|
||||
*/
|
||||
class RegionRepository extends ServiceEntityRepository {
|
||||
public function __construct(ManagerRegistry $registry,
|
||||
private RouterInterface $router,
|
||||
private FormFactoryInterface $formFactory) {
|
||||
parent::__construct($registry, Region::class);
|
||||
}
|
||||
|
||||
|
||||
public function getRegions() {
|
||||
$qb=$this->_em->createQueryBuilder();
|
||||
|
||||
$qb->addSelect("region")
|
||||
->addSelect("subRegions")
|
||||
->from(Region::class, "region")
|
||||
->leftJoin("region.subRegions", "subRegions")
|
||||
->andWhere($qb->expr()->isNull("region.parentRegion"))
|
||||
->orderBy("region.sortOrder");
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
|
||||
public function getForm(string $route, Region $region): FormInterface {
|
||||
$params=$region->getId() !== null ? array('id'=>$region->getId()) : array();
|
||||
|
||||
return $this->formFactory->create(RegionType::class, $region, array(
|
||||
'action'=>$this->router->generate($route, $params),
|
||||
'method'=>'post',
|
||||
'data_route'=>$route,
|
||||
));
|
||||
}
|
||||
}
|
||||
52
src/Repository/UserRepository.php
Normal file
52
src/Repository/UserRepository.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\User;
|
||||
use App\Form\SecurityType;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
||||
use function get_class;
|
||||
|
||||
/**
|
||||
* @method User|null find($id, $lockMode = null, $lockVersion = null)
|
||||
* @method User|null findOneBy(array $criteria, array $orderBy = null)
|
||||
* @method User[] findAll()
|
||||
* @method User[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
|
||||
*/
|
||||
class UserRepository extends ServiceEntityRepository implements PasswordUpgraderInterface {
|
||||
public function __construct(ManagerRegistry $registry,
|
||||
private RouterInterface $router,
|
||||
private FormFactoryInterface $formFactory) {
|
||||
parent::__construct($registry, User::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to upgrade (rehash) the user's password automatically over time.
|
||||
*/
|
||||
public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void {
|
||||
if(!$user instanceof User) {
|
||||
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
|
||||
}
|
||||
|
||||
$user->setPassword($newHashedPassword);
|
||||
$this->_em->persist($user);
|
||||
$this->_em->flush();
|
||||
}
|
||||
|
||||
public function getForm(string $route, User $user): FormInterface {
|
||||
$params=$user->getId() !== null ? array('id'=>$user->getId(),) : array();
|
||||
|
||||
return $this->formFactory->create(SecurityType::class, $user, array(
|
||||
'action'=>$this->router->generate($route, $params),
|
||||
'method'=>'post',
|
||||
'data_route'=>$route,
|
||||
));
|
||||
}
|
||||
}
|
||||
35
src/Repository/WorldmarkCategoryRepository.php
Normal file
35
src/Repository/WorldmarkCategoryRepository.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\WorldmarkCategory;
|
||||
use App\Form\WorldmarkCategoryType;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
|
||||
/**
|
||||
* @method WorldmarkCategory|null find($id, $lockMode=null, $lockVersion=null)
|
||||
* @method WorldmarkCategory|null findOneBy(array $criteria, array $orderBy=null)
|
||||
* @method WorldmarkCategory[] findAll()
|
||||
* @method WorldmarkCategory[] findBy(array $criteria, array $orderBy=null, $limit=null, $offset=null)
|
||||
*/
|
||||
class WorldmarkCategoryRepository extends ServiceEntityRepository {
|
||||
public function __construct(ManagerRegistry $registry,
|
||||
private RouterInterface $router,
|
||||
private FormFactoryInterface $formFactory) {
|
||||
parent::__construct($registry, WorldmarkCategory::class);
|
||||
}
|
||||
|
||||
public function getForm(string $route, WorldmarkCategory $worldmarkCategory): FormInterface {
|
||||
$params=$worldmarkCategory->getId() !== null ? array('id'=>$worldmarkCategory->getId()) : array();
|
||||
|
||||
return $this->formFactory->create(WorldmarkCategoryType::class, $worldmarkCategory, array(
|
||||
'action'=>$this->router->generate($route, $params),
|
||||
'method'=>'post',
|
||||
'data_route'=>$route,
|
||||
));
|
||||
}
|
||||
}
|
||||
68
src/Repository/WorldmarkRepository.php
Normal file
68
src/Repository/WorldmarkRepository.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Region;
|
||||
use App\Entity\Worldmark;
|
||||
use App\Entity\WorldmarkCategory;
|
||||
use App\Form\WorldmarkType;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Routing\RouterInterface;
|
||||
|
||||
/**
|
||||
* @method Worldmark|null find($id, $lockMode=null, $lockVersion=null)
|
||||
* @method Worldmark|null findOneBy(array $criteria, array $orderBy=null)
|
||||
* @method Worldmark[] findAll()
|
||||
* @method Worldmark[] findBy(array $criteria, array $orderBy=null, $limit=null, $offset=null)
|
||||
*/
|
||||
class WorldmarkRepository extends ServiceEntityRepository {
|
||||
/**
|
||||
* @param ManagerRegistry $registry
|
||||
* @param RouterInterface $router
|
||||
* @param FormFactoryInterface $formFactory
|
||||
*/
|
||||
public function __construct(ManagerRegistry $registry,
|
||||
private RouterInterface $router,
|
||||
private FormFactoryInterface $formFactory) {
|
||||
parent::__construct($registry, Worldmark::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Region $region
|
||||
* @param float $version
|
||||
* @return Worldmark[]
|
||||
*/
|
||||
public function getRegionWorldmarks(Region $region, float $version): array {
|
||||
$qb=$this->_em->createQueryBuilder();
|
||||
|
||||
$qb->select("worldmark")
|
||||
->addSelect("category")
|
||||
->from(Worldmark::class, "worldmark")
|
||||
->join("worldmark.regions", "regions")
|
||||
->join("worldmark.category", "category")
|
||||
->andWhere($qb->expr()->eq("regions.id", ":param_regionId"))
|
||||
->andWhere($qb->expr()->lte("worldmark.version", ":param_version"))
|
||||
->orderBy("category.sortOrder")
|
||||
->addOrderBy("worldmark.sortOrder");
|
||||
|
||||
$qb->setParameters(array(
|
||||
'param_regionId'=>$region->getId(),
|
||||
'param_version'=>$version,
|
||||
));
|
||||
|
||||
return $qb->getQuery()->getResult();
|
||||
}
|
||||
|
||||
public function getForm(string $route, WorldmarkCategory $worldmarkCategory, Worldmark $worldmark): FormInterface {
|
||||
$params=$worldmark->getId() !== null ? array('worldmarkCategoryId'=>$worldmarkCategory->getId(), 'id'=>$worldmark->getId()) : array('worldmarkCategoryId'=>$worldmarkCategory->getId());
|
||||
|
||||
return $this->formFactory->create(WorldmarkType::class, $worldmark, array(
|
||||
'action'=>$this->router->generate($route, $params),
|
||||
'method'=>'post',
|
||||
'data_route'=>$route,
|
||||
));
|
||||
}
|
||||
}
|
||||
58
src/Security/Authenticator.php
Normal file
58
src/Security/Authenticator.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Security;
|
||||
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Security;
|
||||
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\RememberMeBadge;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
|
||||
use Symfony\Component\Security\Http\Util\TargetPathTrait;
|
||||
|
||||
class Authenticator extends AbstractLoginFormAuthenticator {
|
||||
use TargetPathTrait;
|
||||
|
||||
public const LOGIN_ROUTE = 'security_login';
|
||||
private UrlGeneratorInterface $urlGenerator;
|
||||
|
||||
public function __construct(UrlGeneratorInterface $urlGenerator) {
|
||||
$this->urlGenerator = $urlGenerator;
|
||||
}
|
||||
|
||||
public function authenticate(Request $request): Passport {
|
||||
$username = $request->request->get('username', '');
|
||||
|
||||
$request->getSession()->set(Security::LAST_USERNAME, $username);
|
||||
|
||||
return new Passport(
|
||||
new UserBadge($username),
|
||||
new PasswordCredentials($request->request->get('password', '')),
|
||||
array(
|
||||
new CsrfTokenBadge('authenticate', $request->request->get('_csrf_token')),
|
||||
new RememberMeBadge(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response {
|
||||
if($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
|
||||
return new RedirectResponse($targetPath);
|
||||
}
|
||||
|
||||
// For example:
|
||||
//return new RedirectResponse($this->urlGenerator->generate('some_route'));
|
||||
// throw new \Exception('TODO: provide a valid redirect inside '.__FILE__);
|
||||
return new RedirectResponse($this->urlGenerator->generate('fo_region_show', array('slug'=>'mondstadt')));
|
||||
}
|
||||
|
||||
protected function getLoginUrl(Request $request): string {
|
||||
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
|
||||
}
|
||||
}
|
||||
401
src/Service/FileManager.php
Normal file
401
src/Service/FileManager.php
Normal file
@ -0,0 +1,401 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Entity\Item;
|
||||
use App\Entity\Monster;
|
||||
use Exception;
|
||||
use Imagick;
|
||||
use ImagickPixel;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symfony\Component\HttpFoundation\File\File;
|
||||
use Symfony\Component\HttpFoundation\File\UploadedFile;
|
||||
|
||||
class FileManager {
|
||||
private Filesystem $filesystem;
|
||||
private array $parameters;
|
||||
|
||||
public function __construct(ParameterBagInterface $parameterBag) {
|
||||
$this->filesystem=new Filesystem();
|
||||
$this->parameters=array(
|
||||
'assets'=>$parameterBag->get('assets'),
|
||||
'env'=>$parameterBag->get('kernel.environment')
|
||||
);
|
||||
}
|
||||
|
||||
private function generateUuid(?string $directory): bool|string {
|
||||
if($directory) {
|
||||
$scan=scandir($directory);
|
||||
if($scan) {
|
||||
do {
|
||||
$filename=Uuid::uuid1()->toString();
|
||||
} while(in_array($filename, $scan));
|
||||
|
||||
return $filename;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return Uuid::uuid1()->toString();
|
||||
}
|
||||
}
|
||||
|
||||
private function resizeJpeg(string $sourceFile, string $targetPath, string $filename, int $width, int $height, int $quality = 100): array {
|
||||
try {
|
||||
$img = new Imagick();
|
||||
$img->setResolution(72, 72);
|
||||
$img->setBackgroundColor((new ImagickPixel('#1B283B')));
|
||||
$img->setInterlaceScheme(Imagick::INTERLACE_LINE);
|
||||
|
||||
$img->readImage($sourceFile);
|
||||
$img->setImageUnits(Imagick::RESOLUTION_PIXELSPERINCH);
|
||||
$img->setImageResolution(72, 72);
|
||||
|
||||
$img->setImageFormat('jpeg');
|
||||
$img->setImageCompression(Imagick::COMPRESSION_JPEG);
|
||||
$img->setImageCompressionQuality($quality);
|
||||
|
||||
if($img->getImageWidth() > $width) {
|
||||
$img->scaleImage($width, $height, true);
|
||||
}
|
||||
|
||||
$img->extentImage($width, $height, (($img->getImageWidth() - $width) / 2), (($img->getImageHeight() - $height) / 2));
|
||||
|
||||
$img->stripImage();
|
||||
$img->writeImage("$targetPath/$filename.jpeg");
|
||||
$img->clear();
|
||||
$img->destroy();
|
||||
|
||||
return array(
|
||||
'error'=>false,
|
||||
'message'=>null,
|
||||
);
|
||||
} catch(Exception) {
|
||||
return array(
|
||||
'error'=>true,
|
||||
'message'=>'Could not write file to disk',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function resizePng(string $sourceFile, string $targetPath, string $filename, int $width, int $height): array {
|
||||
try {
|
||||
$img=new Imagick();
|
||||
$img->setResolution(72, 72);
|
||||
$img->setBackgroundColor((new ImagickPixel('transparent')));
|
||||
|
||||
$img->readImage($sourceFile);
|
||||
$img->setImageUnits(Imagick::RESOLUTION_PIXELSPERINCH);
|
||||
$img->setImageResolution(72, 72);
|
||||
$img->setImageFormat('png');
|
||||
|
||||
$img->scaleImage($width, $height, true);
|
||||
$img->extentImage($width, $height, (($img->getImageWidth() - $width) / 2), (($img->getImageHeight() - $height) / 2));
|
||||
|
||||
$img->stripImage();
|
||||
$img->writeImage("$targetPath/$filename.png");
|
||||
$img->clear();
|
||||
$img->destroy();
|
||||
|
||||
return array(
|
||||
'error'=>false,
|
||||
'message'=>null,
|
||||
);
|
||||
} catch(Exception) {
|
||||
return array(
|
||||
'error'=>true,
|
||||
'message'=>'Could not write file to disk',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function uploadFile(UploadedFile $uploadedFile, string $type): array {
|
||||
if(!in_array($type, array('map', 'screenshot', 'item', 'monster', 'worldmark'))) {
|
||||
return array(
|
||||
'error'=>true,
|
||||
'filename'=>null,
|
||||
'message'=>'File could not be processed',
|
||||
);
|
||||
}
|
||||
|
||||
$ext=$uploadedFile->guessExtension();
|
||||
|
||||
if(!$ext) {
|
||||
return array(
|
||||
'error'=>true,
|
||||
'filename'=>null,
|
||||
'message'=>'Cannot guess file extension from mimetype',
|
||||
);
|
||||
}
|
||||
|
||||
if(!in_array($ext, $this->parameters['assets'][$type]['ext'])) {
|
||||
return array(
|
||||
'error'=>true,
|
||||
'filename'=>null,
|
||||
'message'=>sprintf("File type not supported. Supported files types are [%s]", implode(', ', $this->parameters['assets'][$type]['ext'])),
|
||||
);
|
||||
}
|
||||
|
||||
$this->filesystem->mkdir($this->parameters['assets'][$type]['upload_path'], 0775);
|
||||
$filename=$this->generateUuid($this->parameters['assets'][$type]['upload_path']);
|
||||
|
||||
$uploadedFile->move($this->parameters['assets'][$type]['upload_path'], "$filename.$ext");
|
||||
|
||||
if(in_array($type, array('item', 'monster', 'worldmark'))) {
|
||||
$imgWidth = match ($type) {
|
||||
'item', 'monster' => $imgHeight = 160,
|
||||
'worldmark' => $imgHeight = 48,
|
||||
default => $imgHeight = null,
|
||||
};
|
||||
|
||||
if($imgWidth === null) {
|
||||
return array(
|
||||
'error'=>true,
|
||||
'filename'=>null,
|
||||
'message'=>'Could not define image dimensions',
|
||||
);
|
||||
}
|
||||
|
||||
$process=$this->resizePng("{$this->parameters['assets'][$type]['upload_path']}/$filename.$ext",
|
||||
$this->parameters['assets'][$type]['upload_path'], $filename, $imgWidth, $imgHeight);
|
||||
|
||||
if($process['error']) {
|
||||
if($type == 'item') {
|
||||
$this->removeItemIcon("$filename.$ext");
|
||||
} elseif($type == 'monster') {
|
||||
$this->removeMonsterIcon("$filename.$ext");
|
||||
} elseif($type == 'worldmark') {
|
||||
$this->removeWorldmarkIcon("$filename.$ext");
|
||||
}
|
||||
|
||||
|
||||
return array(
|
||||
'error'=>true,
|
||||
'filename'=>null,
|
||||
'message'=>'Could not write item file to disk',
|
||||
);
|
||||
}
|
||||
} else if($type == 'screenshot') {
|
||||
$imgSizes=getimagesize("{$this->parameters['assets'][$type]['upload_path']}/$filename.$ext");
|
||||
|
||||
if($imgSizes[0] < 1280 || $imgSizes[1] < 720) {
|
||||
$this->filesystem->remove("{$this->parameters['assets'][$type]['upload_path']}/$filename.$ext");
|
||||
|
||||
return array(
|
||||
'error'=>true,
|
||||
'filename'=>null,
|
||||
'message'=>'Screenshot must be at least 1280*720 pixels',
|
||||
);
|
||||
}
|
||||
|
||||
$process=$this->resizeJpeg("{$this->parameters['assets'][$type]['upload_path']}/$filename.$ext",
|
||||
$this->parameters['assets'][$type]['upload_path'], $filename,
|
||||
1280, 720);
|
||||
|
||||
if($process['error']) {
|
||||
$this->removeScreenshot("$filename.$ext");
|
||||
|
||||
return array(
|
||||
'error'=>true,
|
||||
'filename'=>null,
|
||||
'message'=>'Could not write screenshot file to disk',
|
||||
);
|
||||
}
|
||||
|
||||
if(in_array($ext, ['jpg', 'png'])) {
|
||||
$this->filesystem->remove("{$this->parameters['assets'][$type]['upload_path']}/$filename.$ext");
|
||||
$ext = 'jpeg';
|
||||
}
|
||||
|
||||
$process=$this->resizeJpeg("{$this->parameters['assets'][$type]['upload_path']}/$filename.$ext",
|
||||
$this->parameters['assets'][$type]['thumbnail_path'], $filename, 320, 180, 65);
|
||||
|
||||
if($process['error']) {
|
||||
$this->removeScreenshot("$filename.$ext");
|
||||
|
||||
return array(
|
||||
'error'=>true,
|
||||
'filename'=>null,
|
||||
'message'=>'Could not write screenshot file to disk',
|
||||
);
|
||||
}
|
||||
|
||||
if($this->parameters['env'] == 'dev') {
|
||||
$this->filesystem->copy("{$this->parameters['assets'][$type]['thumbnail_path']}/$filename.$ext",
|
||||
str_replace("dev.genshin-world.com",
|
||||
"genshin-world.com",
|
||||
"{$this->parameters['assets'][$type]['thumbnail_path']}/$filename.$ext"));
|
||||
} elseif($this->parameters['env'] == 'prod') {
|
||||
$this->filesystem->copy("{$this->parameters['assets'][$type]['thumbnail_path']}/$filename.$ext",
|
||||
str_replace("genshin-world.com",
|
||||
"dev.genshin-world.com",
|
||||
"{$this->parameters['assets'][$type]['thumbnail_path']}/$filename.$ext"));
|
||||
}
|
||||
}
|
||||
|
||||
if($this->parameters['env'] == 'dev') {
|
||||
$this->filesystem->copy("{$this->parameters['assets'][$type]['upload_path']}/$filename.$ext",
|
||||
str_replace("dev.genshin-world.com",
|
||||
"genshin-world.com",
|
||||
"{$this->parameters['assets'][$type]['upload_path']}/$filename.$ext"));
|
||||
} elseif($this->parameters['env'] == 'prod') {
|
||||
$this->filesystem->copy("{$this->parameters['assets'][$type]['upload_path']}/$filename.$ext",
|
||||
str_replace("genshin-world.com",
|
||||
"dev.genshin-world.com",
|
||||
"{$this->parameters['assets'][$type]['upload_path']}/$filename.$ext"));
|
||||
}
|
||||
|
||||
return array(
|
||||
'error'=>false,
|
||||
'filename'=>"$filename.$ext",
|
||||
'message'=>null,
|
||||
);
|
||||
}
|
||||
|
||||
private function removeLocalFile(string $filePath) {
|
||||
$this->filesystem->remove($filePath);
|
||||
}
|
||||
|
||||
public function uploadMapFile(UploadedFile $uploadedFile): array {
|
||||
return $this->uploadFile($uploadedFile, 'map');
|
||||
}
|
||||
|
||||
public function removeMapFile(string $filename) {
|
||||
$this->removeLocalFile("{$this->parameters['assets']['map']['upload_path']}/$filename");
|
||||
|
||||
if($this->parameters['env'] == 'dev') {
|
||||
$this->removeLocalFile(str_replace("dev.genshin-world.com",
|
||||
"genshin-world.com",
|
||||
"{$this->parameters['assets']['map']['upload_path']}/$filename"));
|
||||
} elseif($this->parameters['env'] == 'prod') {
|
||||
$this->removeLocalFile(str_replace("genshin-world.com",
|
||||
"dev.genshin-world.com",
|
||||
"{$this->parameters['assets']['map']['upload_path']}/$filename"));
|
||||
}
|
||||
}
|
||||
|
||||
public function uploadItemIcon(UploadedFile $uploadedFile): array {
|
||||
return $this->uploadFile($uploadedFile, 'item');
|
||||
}
|
||||
|
||||
public function removeItemIcon(string $filename) {
|
||||
$this->removeLocalFile("{$this->parameters['assets']['item']['upload_path']}/$filename");
|
||||
|
||||
if($this->parameters['env'] == 'dev') {
|
||||
$this->removeLocalFile(str_replace("dev.genshin-world.com",
|
||||
"genshin-world.com",
|
||||
"{$this->parameters['assets']['item']['upload_path']}/$filename"));
|
||||
} elseif($this->parameters['env'] == 'prod') {
|
||||
$this->removeLocalFile(str_replace("genshin-world.com",
|
||||
"dev.genshin-world.com",
|
||||
"{$this->parameters['assets']['item']['upload_path']}/$filename"));
|
||||
}
|
||||
}
|
||||
|
||||
public function uploadMonsterIcon(UploadedFile $uploadedFile): array {
|
||||
return $this->uploadFile($uploadedFile, 'monster');
|
||||
}
|
||||
|
||||
public function removeMonsterIcon(string $filename) {
|
||||
$this->removeLocalFile("{$this->parameters['assets']['monster']['upload_path']}/$filename");
|
||||
|
||||
if($this->parameters['env'] == 'dev') {
|
||||
$this->removeLocalFile(str_replace("dev.genshin-world.com",
|
||||
"genshin-world.com",
|
||||
"{$this->parameters['assets']['monster']['upload_path']}/$filename"));
|
||||
} elseif($this->parameters['env'] == 'prod') {
|
||||
$this->removeLocalFile(str_replace("genshin-world.com",
|
||||
"dev.genshin-world.com",
|
||||
"{$this->parameters['assets']['monster']['upload_path']}/$filename"));
|
||||
}
|
||||
}
|
||||
|
||||
public function uploadWorldmarkIcon(UploadedFile $uploadedFile): array {
|
||||
return $this->uploadFile($uploadedFile, 'worldmark');
|
||||
}
|
||||
|
||||
public function getWorldmarkIconFromEntity(Item|Monster $entity): array {
|
||||
$type = $entity instanceof Item ? 'item' : 'monster';
|
||||
|
||||
if(!$this->filesystem->exists("{$this->parameters['assets'][$type]['upload_path']}/{$entity->getIcon()}")) {
|
||||
return array(
|
||||
'error'=>true,
|
||||
'filename'=>null,
|
||||
'message'=>'Could not find any file to copy',
|
||||
);
|
||||
}
|
||||
|
||||
$itemFile=new File("{$this->parameters['assets'][$type]['upload_path']}/{$entity->getIcon()}");
|
||||
$ext=$itemFile->guessExtension();
|
||||
|
||||
$filename=$this->generateUuid($this->parameters['assets']['worldmark']['upload_path']);
|
||||
|
||||
$this->filesystem->mkdir($this->parameters['assets']['worldmark']['upload_path'], 0775);
|
||||
$this->filesystem->copy("{$this->parameters['assets'][$type]['upload_path']}/{$entity->getIcon()}",
|
||||
"{$this->parameters['assets']['worldmark']['upload_path']}/$filename.$ext");
|
||||
|
||||
$process=$this->resizePng("{$this->parameters['assets']['worldmark']['upload_path']}/$filename.$ext",
|
||||
$this->parameters['assets']['worldmark']['upload_path'], $filename, 48, 48);
|
||||
|
||||
if($this->parameters['env'] == 'dev') {
|
||||
$this->filesystem->copy("{$this->parameters['assets']['worldmark']['upload_path']}/$filename.$ext",
|
||||
str_replace("dev.genshin-world.com",
|
||||
"genshin-world.com",
|
||||
"{$this->parameters['assets']['worldmark']['upload_path']}/$filename.$ext"));
|
||||
} elseif($this->parameters['env'] == 'prod') {
|
||||
$this->filesystem->copy("{$this->parameters['assets']['worldmark']['upload_path']}/$filename.$ext",
|
||||
str_replace("genshin-world.com",
|
||||
"dev.genshin-world.com",
|
||||
"{$this->parameters['assets']['worldmark']['upload_path']}/$filename.$ext"));
|
||||
}
|
||||
|
||||
if($process['error']) {
|
||||
$this->removeItemIcon($filename);
|
||||
|
||||
return array(
|
||||
'error'=>true,
|
||||
'filename'=>null,
|
||||
'message'=>'Could not write item icon file to disk',
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
'error'=>false,
|
||||
'filename'=>"$filename.$ext",
|
||||
'message'=>null,
|
||||
);
|
||||
}
|
||||
|
||||
public function removeWorldmarkIcon(string $filename) {
|
||||
$this->removeLocalFile("{$this->parameters['assets']['worldmark']['upload_path']}/$filename");
|
||||
}
|
||||
|
||||
public function uploadScreenshot(UploadedFile $uploadedFile): array {
|
||||
return $this->uploadFile($uploadedFile, 'screenshot');
|
||||
}
|
||||
|
||||
public function removeScreenshot(string $filename) {
|
||||
$this->removeLocalFile("{$this->parameters['assets']['screenshot']['upload_path']}/$filename");
|
||||
$this->removeLocalFile("{$this->parameters['assets']['screenshot']['thumbnail_path']}/$filename");
|
||||
|
||||
if($this->parameters['env'] == 'dev') {
|
||||
$this->removeLocalFile(str_replace("dev.genshin-world.com",
|
||||
"genshin-world.com",
|
||||
"{$this->parameters['assets']['screenshot']['upload_path']}/$filename"));
|
||||
|
||||
$this->removeLocalFile(str_replace("dev.genshin-world.com",
|
||||
"genshin-world.com",
|
||||
"{$this->parameters['assets']['screenshot']['thumbnail_path']}/$filename"));
|
||||
} elseif($this->parameters['env'] == 'prod') {
|
||||
$this->removeLocalFile(str_replace("genshin-world.com",
|
||||
"dev.genshin-world.com",
|
||||
"{$this->parameters['assets']['screenshot']['upload_path']}/$filename"));
|
||||
|
||||
$this->removeLocalFile(str_replace("genshin-world.com",
|
||||
"dev.genshin-world.com",
|
||||
"{$this->parameters['assets']['screenshot']['thumbnail_path']}/$filename"));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user