1
0
mirror of https://koodu.h-i.works/projects/thebadspace synced 2025-06-25 16:04:37 -05:00

Location Editing Part. 1

Now that full-text searching is set up in the DB, the next step is
data population. The adding and editing templates were added as long as
routes and base functionality to add single locations.

Adding works and editing is almost there but both still need to cleaned
up. The basic plumbing will be completed and then the tweaking to
account for roles and login status for the sake of security.

Part 2 will include clean up and and bulk uploads through the use of CSV
files.
This commit is contained in:
Ro
2022-12-30 14:41:49 -08:00
parent e424df18aa
commit 3410abd70a
19 changed files with 879 additions and 21 deletions

View File

@ -0,0 +1,167 @@
<?php
// src/Controller/DataImport.php
// Grab data from transfer app
namespace App\Controller\Routes\Back;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RequestStack;
use Doctrine\Persistence\ManagerRegistry;
use App\Service\HandleLocations;
//use App\Utils\PageRender;
//use App\Utils\StringTools;
use App\Service\Auth;
use App\Service\FileUploader;
class Locations extends AbstractController
{
/**
* @Route("/den/locations", name="den-reroute-index")
*/
public function rerouteIndex()
{
header("Location:/den/locations/page/1");
return new Response("<html><body>LOGGED IN</body></html>");
}
/**
* @Route("/den/locations/page/{pageNum}", name="den-locations")
*/
public function locationIndex(
Request $request,
RequestStack $requestStack,
Auth $auth,
HandleLocations $locations,
string $pageNum
): Response {
$result = $auth->status();
if ($result["status"]) {
$session = $requestStack->getSession();
$member = $session->get("member");
$list = $locations->getLocationsPage($pageNum);
return $this->render("back/locations.twig", [
"title" => "Bad Space | Locations",
"handle" => $member->getHandle(),
"list" => $list,
"mode" => "index"
]);
} else {
return $this->render("back/index.twig", [
"title" => "Close the door behind you",
]);
}
}
/**
* @Route("/den/locations/add", name="location-add")
*/
public function addLocation(
Request $request,
Auth $auth,
HandleLocations $locations,
ManagerRegistry $doctrine,
FileUploader $uploader
): Response {
$result = $auth->status();
if ($result["status"]) {
if ($request->getMethod() == "GET") {
return $this->render("back/locations.twig", [
"title" => "Bad Space | Locations | Add",
"mode" => "add"
]);
} else {
//add new member
$token = $request->get("token");
$notice = "";
$entityManager = $doctrine->getManager();
//token check
if (!$this->isCsrfTokenValid("upload", $token)) {
$logger->info("CSRF failure");
return new Response(
"Operation not allowed",
Response::HTTP_BAD_REQUEST,
[
"content-type" => "text/plain",
]
);
}
$examples = [];
$files = $request->files->get("loc_examples");
if (!empty($files)) {
for ($i = 0; $i < count($files); $i++) {
$path = $files[$i]->getClientOriginalName();
array_push($examples, ["image_index" => $i, "path" => urlencode($path)]);
$uploader->uploadExamples("../public/assets/images/examples", $files[$i]);
}
}
if (
$request->request->get("loc_name") == "" ||
$request->request->get("loc_url") == "" ||
$request->request->get("loc_desc") == "" ||
$request->request->get("loc_tags") == ""
) {
$notice = "All fields are required, champ.";
return $this->render("back/locations.twig", [
"title" => "Bad Space | Locations | Add",
"notice" => $notice,
"mode" => "add"
]);
}
//check clear, call add method
$response = $locations->addLocation($request, $result["id"]);
if ($response["status"]) {
$notice = "New location added! Take a break.";
return $this->render("back/locations.twig", [
"title" => "Bad Space | Locations | Add",
"notice" => $notice,
"mode" => "add"
]);
} else {
return $this->render("back/locations.twig", [
"title" => "Bad Space | Locations | Add",
"notice" => $response["message"],
"mode" => "add"
]);
}
}
} else {
//back to index to login
header("Location:/den");
return new Response("<html><body>LOGGED IN</body></html>");
}
}
/**
* @Route("/den/locations/edit/{uuid}", name="location-edit")
*/
public function editLocation(
Request $request,
Auth $auth,
HandleLocations $locations,
ManagerRegistry $doctrine,
FileUploader $uploader,
string $uuid = "1"
): Response {
$result = $auth->status();
if ($result["status"]) {
$location = $locations->getLocationbyUUID($uuid);
return $this->render("back/locations.twig", [
"title" => "Bad Space | Locations | Edit",
"mode" => "edit",
"location" => $location[0]
]);
} else {
header("Location:/den");
return new Response("<html><body>LOGGED IN</body></html>");
}
}
}

View File

@ -137,7 +137,7 @@ class Members extends AbstractController
}
} else {
//back to index to login
header("Location:/knockknock");
header("Location:/den");
return new Response("<html><body>LOGGED IN</body></html>");
}
}

186
src/Entity/Location.php Normal file
View File

@ -0,0 +1,186 @@
<?php
namespace App\Entity;
use App\Repository\LocationRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: LocationRepository::class)]
class Location
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $uuid = null;
#[ORM\Column(length: 255)]
private ?string $name = null;
#[ORM\Column(length: 255)]
private ?string $url = null;
#[ORM\Column(type: Types::TEXT)]
private ?string $description = null;
#[ORM\Column(nullable: true)]
private array $images = [];
#[ORM\Column]
private ?bool $active = null;
#[ORM\Column(length: 255)]
private ?string $rating = null;
#[ORM\Column]
private ?int $addedBy = null;
#[ORM\Column]
private ?\DateTimeImmutable $createdAt = null;
#[ORM\Column]
private ?\DateTimeImmutable $updatedAt = null;
#[ORM\Column(length: 255)]
private ?string $tags = null;
public function getId(): ?int
{
return $this->id;
}
public function getUuid(): ?string
{
return $this->uuid;
}
public function setUuid(string $uuid): self
{
$this->uuid = $uuid;
return $this;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getUrl(): ?string
{
return $this->url;
}
public function setUrl(string $url): self
{
$this->url = $url;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(string $description): self
{
$this->description = $description;
return $this;
}
public function getImages(): array
{
return $this->images;
}
public function setImages(?array $images): self
{
$this->images = $images;
return $this;
}
public function isActive(): ?bool
{
return $this->active;
}
public function setActive(bool $active): self
{
$this->active = $active;
return $this;
}
public function getRating(): ?string
{
return $this->rating;
}
public function setRating(string $rating): self
{
$this->rating = $rating;
return $this;
}
public function getAddedBy(): ?int
{
return $this->addedBy;
}
public function setAddedBy(int $addedBy): self
{
$this->addedBy = $addedBy;
return $this;
}
public function getCreatedAt(): ?\DateTimeImmutable
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeImmutable $createdAt): self
{
$this->createdAt = $createdAt;
return $this;
}
public function getUpdatedAt(): ?\DateTimeImmutable
{
return $this->updatedAt;
}
public function setUpdatedAt(\DateTimeImmutable $updatedAt): self
{
$this->updatedAt = $updatedAt;
return $this;
}
public function getTags(): ?string
{
return $this->tags;
}
public function setTags(string $tags): self
{
$this->tags = $tags;
return $this;
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace App\Repository;
use App\Entity\Location;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<Location>
*
* @method Location|null find($id, $lockMode = null, $lockVersion = null)
* @method Location|null findOneBy(array $criteria, array $orderBy = null)
* @method Location[] findAll()
* @method Location[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class LocationRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Location::class);
}
public function save(Location $entity, bool $flush = false): void
{
$this->getEntityManager()->persist($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
public function remove(Location $entity, bool $flush = false): void
{
$this->getEntityManager()->remove($entity);
if ($flush) {
$this->getEntityManager()->flush();
}
}
// /**
// * @return Location[] Returns an array of Location objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('l')
// ->andWhere('l.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('l.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// public function findOneBySomeField($value): ?Location
// {
// return $this->createQueryBuilder('l')
// ->andWhere('l.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}

View File

@ -81,13 +81,20 @@ class Auth
public function status()
{
$response = [];
//checks to see if member session exists
if ($this->session->get("member")) {
//$member = $this->session->get("member");
$response = [
"status" => true,
"role" => $this->session->get("member")->getRole(),
"token" => $this->session->get("token"),
];
//checks if token is still valid
$verify = Token::validateExpiration($this->session->get("token"), $this->secret);
if ($verify) {
$response = [
"status" => true,
"role" => $this->session->get("member")->getRole(),
"id" => $this->session->get("member")->getId(),
"token" => $this->session->get("token"),
];
} else {
$response = ["status" => false, "role" => null];
}
} else {
$response = ["status" => false, "role" => null];
}

View File

@ -0,0 +1,46 @@
<?php
namespace App\Service;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Psr\Log\LoggerInterface;
class FileUploader
{
private $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
}
public function upload($uploadDir, $file, $filename)
{
try {
$file->move($uploadDir, $filename);
} catch (FileException $e) {
$this->logger->error("failed to upload image: " . $e->getMessage());
throw new FileException("Failed to upload file");
}
}
public function uploadExamples($examplesDir, $file)
{
try {
$file->move($examplesDir, urldecode($file->getClientOriginalName()));
} catch (FileException $e) {
$this->logger->error("failed to upload image: " . $e->getMessage());
throw new FileException("Failed to upload image file");
}
}
public function uploadAvatar($avatarsDir, $file)
{
try {
$file->move($avatarsDir, $file->getClientOriginalName());
} catch (FileException $e) {
$this->logger->error("failed to upload image: " . $e->getMessage());
throw new FileException("Failed to upload image file");
}
}
}

View File

@ -0,0 +1,142 @@
<?php
// src/Controller/ProductController.php
namespace App\Service;
use Doctrine\DBAL\DBALException;
use Doctrine\ORM\ORMException;
use PDOException;
use Exception;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Uid\Uuid;
use App\Entity\Location;
//use App\Utils\StringTools;
/**
* Members
*
* Data class for interacting with Member data from the DB
*/
class HandleLocations
{
private $session;
private $entityManager;
private $limit = 4;
public function __construct(
EntityManagerInterface $entityManager,
RequestStack $requestStack
) {
$this->entityManager = $entityManager;
$this->session = $requestStack->getSession();
}
public function getActiveLocations()
{
$listings = $this->entityManager->getRepository(Location::class);
$locations = $listings->findBy(["active" => true]);
return $locations;
}
public function getLocationByUUID(string $uuid)
{
return $this->entityManager->getRepository(Location::class)->findBy(["uuid" => $uuid]);
}
public function getLocationsPage(int $page)
{
$locations = $this->entityManager->getRepository(Location::class);
$list = $locations->findBy(
[],
["id" => "ASC"]
);
$count = ceil(count($list) / $this->limit);
$totalCount = count($list);
$shelf = [];
$range = $page * $this->limit - $this->limit;
for ($i = 0; $i <= $this->limit; $i++) {
try {
array_push($shelf, $list[$i + $range]);
} catch (Exception $error) {
}
}
return [
"locations" => $shelf,
"total" => $count,
"totalLocations" => $totalCount,
];
}
/**
* Add new location to db
*
* @param Request $request object containing posted data
* @return JSON
*/
public function addLocation($request, $memberId)
{
$errorMessage = null;
$location = new Location();
//submitted values
$name = $request->request->get("loc_name");
$location->setName($name);
$url = $request->request->get("loc_url");
$location->setUrl($url);
$desc = $request->request->get("loc_desc");
$location->setDescription($desc);
$tags = $request->request->get("loc_tags");
$location->setTags($tags);
$rating = $request->request->get("rating");
$location->setRating($rating);
//get images
$files = $request->files->get("loc_examples");
if (!empty($files)) {
$examples = [];
for ($i = 0; $i < count($files); $i++) {
$path = $files[$i]->getClientOriginalName();
array_push($examples, ["image_index" => $i, "path" => urlencode($path)]);
}
$location->setImages($examples);
}
//set defaults
$location->setUuid(Uuid::v4());
$location->setActive(false);
$location->setCreatedAt(new \DateTimeImmutable());
$location->setUpdatedAt(new \DateTimeImmutable());
$location->setAddedBy($memberId);
$this->entityManager->persist($location);
try {
$this->entityManager->flush();
} catch (PDOException $error) {
$errorMessage = $error->getMessage();
} catch (DBALException $error) {
$errorMessage = $error->getMessage();
} catch (ORMException $error) {
$errorMessage = $error->getMessage();
} catch (Exception $error) {
$errorMessage = $error->getMessage();
} catch (SyntaxErrorException $e) {
$errorMessage = $error->getMessage();
}
// return result status
if ($errorMessage == null) {
return $response = [
"status" => true,
"message" => "New member added. Woohoo!",
];
} else {
return $response = ["status" => false, "message" => $errorMessage];
}
}
}