Compare commits

...

2 Commits

Author SHA1 Message Date
krzysiej
a0f06d3bbe Updated api responses for files and books data. 2022-06-10 14:05:23 +02:00
krzysiej
67e970183f Switched getting files with axios request to the api platform. 2022-06-09 14:42:47 +02:00
6 changed files with 40 additions and 21 deletions

View File

@@ -15,14 +15,14 @@
</thead> </thead>
<tbody> <tbody>
<tr v-for="file in files"> <tr v-for="file in files">
<td>{{ file.fileName }} <td>{{ file.file_name }}
<p class="mb-0" v-if="file.book"> <p class="mb-0" v-if="file.book">
<a class="text-decoration-none" :href="'/book/'+file.book.id">{{ <a class="text-decoration-none" :href="'/book/'+file.book.id">{{
file.book.title file.book.title
}}</a> <a href="" class="text-decoration-none link-secondary">{{ file.book.author }}</a> }}</a> <a href="" class="text-decoration-none link-secondary">{{ file.book.author }}</a>
</p> </p>
</td> </td>
<td class="text-end">{{ formatSize(file.fileSize) }}</td> <td class="text-end">{{ file.file_size_human }}</td>
<td>{{ file.extension }}</td> <td>{{ file.extension }}</td>
<td><a :href="'/file/'+ file.id" class="link-secondary">download</a></td> <td><a :href="'/file/'+ file.id" class="link-secondary">download</a></td>
<td><a :href="'/file/delete/'+file.id" @click.prevent="deleteFile(file.id)" class="link-danger">remove</a> <td><a :href="'/file/delete/'+file.id" @click.prevent="deleteFile(file.id)" class="link-danger">remove</a>
@@ -61,21 +61,18 @@ export default {
deleteFile: function (fileId) { deleteFile: function (fileId) {
axios.get(window.location.origin + '/file/delete/' + fileId).then(() => this.getFiles()) axios.get(window.location.origin + '/file/delete/' + fileId).then(() => this.getFiles())
}, },
formatSize: function (bytes) {
if (bytes === 0) {
return "0.00 B";
}
const e = Math.floor(Math.log(bytes) / Math.log(1024));
return (bytes / Math.pow(1024, e)).toFixed(2) + ' ' + ' KMGTP'.charAt(e) + 'B';
},
getFiles: function () { getFiles: function () {
axios.get(this.getFilesEndpoint()).then(response => this.files = response.data) axios.get(this.getFilesEndpoint(), {
headers: {
'accept': 'application/json'
}
}).then(response => this.files = response.data)
}, },
getFilesEndpoint: function () { getFilesEndpoint: function () {
if (this.bookId) { if (this.bookId) {
return '/book/' + this.bookId + '/files'; return `/api/books/${this.bookId}/files`;
} }
return '/file/all'; return `/api/files`;
} }
} }
} }

View File

@@ -111,13 +111,6 @@ class BookController extends AbstractController
]); ]);
} }
#[Route('/{id}/files', name: 'app_book_file', methods: ['GET'])]
public function files(Book $book): JsonResponse
{
return $this->json($book->getFiles(), context: [AbstractNormalizer::IGNORED_ATTRIBUTES => ['book']]);
}
#[Route('/{id}/edit', name: 'app_book_edit', methods: ['GET', 'POST'])] #[Route('/{id}/edit', name: 'app_book_edit', methods: ['GET', 'POST'])]
public function edit( public function edit(
Request $request, Request $request,

View File

@@ -2,20 +2,30 @@
namespace App\Entity; namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Annotation\ApiSubresource;
use ApiPlatform\Core\Bridge\Doctrine\Common\Filter\SearchFilterInterface;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use App\Repository\BookRepository; use App\Repository\BookRepository;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
#[ApiResource]
#[ORM\Entity(repositoryClass: BookRepository::class)] #[ORM\Entity(repositoryClass: BookRepository::class)]
#[ApiFilter(SearchFilter::class, properties: ['title' => SearchFilterInterface::STRATEGY_PARTIAL])]
class Book class Book
{ {
#[ORM\Id] #[ORM\Id]
#[ORM\GeneratedValue] #[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')] #[ORM\Column(type: 'integer')]
#[Groups('file:read')]
private $id; private $id;
#[ORM\Column(type: 'string', length: 255)] #[ORM\Column(type: 'string', length: 255)]
#[Groups('file:read')]
private $title; private $title;
#[ORM\Column(type: 'string', length: 255)] #[ORM\Column(type: 'string', length: 255)]
@@ -33,6 +43,7 @@ class Book
#[ORM\Column(type: 'string', length: 255, nullable: true)] #[ORM\Column(type: 'string', length: 255, nullable: true)]
private $subtitle; private $subtitle;
#[ApiSubresource]
#[ORM\OneToMany(mappedBy: 'book', targetEntity: File::class, orphanRemoval: true)] #[ORM\OneToMany(mappedBy: 'book', targetEntity: File::class, orphanRemoval: true)]
private $files; private $files;
@@ -46,6 +57,7 @@ class Book
private $volume; private $volume;
#[ORM\Column(type: 'string', length: 255)] #[ORM\Column(type: 'string', length: 255)]
#[Groups('file:read')]
private $author; private $author;
#[ORM\Column(type: 'text', nullable: true)] #[ORM\Column(type: 'text', nullable: true)]

View File

@@ -5,23 +5,28 @@ namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource; use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\FileRepository; use App\Repository\FileRepository;
use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation\SerializedName;
#[ApiResource] #[ApiResource(collectionOperations: ['get'], itemOperations: ['get'], denormalizationContext: ['groups' => ['file:write']], normalizationContext: ['groups' => ['file:read']])]
#[ORM\Entity(repositoryClass: FileRepository::class)] #[ORM\Entity(repositoryClass: FileRepository::class)]
class File class File
{ {
#[ORM\Id] #[ORM\Id]
#[ORM\GeneratedValue] #[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')] #[ORM\Column(type: 'integer')]
#[Groups('file:read')]
private $id; private $id;
#[ORM\Column(type: 'string', length: 255)] #[ORM\Column(type: 'string', length: 255)]
#[Groups('file:read')]
private $file_name; private $file_name;
#[ORM\Column(type: 'integer')] #[ORM\Column(type: 'integer')]
private $file_size; private $file_size;
#[ORM\Column(type: 'string', length: 255)] #[ORM\Column(type: 'string', length: 255)]
#[Groups('file:read')]
private $extension; private $extension;
#[ORM\Column(type: 'string', length: 255)] #[ORM\Column(type: 'string', length: 255)]
@@ -29,6 +34,7 @@ class File
#[ORM\ManyToOne(targetEntity: Book::class, inversedBy: 'files')] #[ORM\ManyToOne(targetEntity: Book::class, inversedBy: 'files')]
#[ORM\JoinColumn(nullable: false)] #[ORM\JoinColumn(nullable: false)]
#[Groups('file:read')]
private $book; private $book;
public function getId(): ?int public function getId(): ?int
@@ -53,6 +59,15 @@ class File
return $this->file_size; return $this->file_size;
} }
#[Groups('file:read')]
#[SerializedName('file_size_human')]
public function getFileSizeHuman(): string
{
$base = log($this->file_size) / log(1024);
$suffix = array("B", "KB", "MB", "GB", "TB")[floor($base)];
return round(pow(1024, $base - floor($base)), 2) . $suffix;
}
public function setFileSize(int $file_size): self public function setFileSize(int $file_size): self
{ {
$this->file_size = $file_size; $this->file_size = $file_size;

View File

@@ -19,6 +19,7 @@
<th></th> <th></th>
<th>Title</th> <th>Title</th>
<th>Description</th> <th>Description</th>
<th>Rating</th>
<th>Publisher</th> <th>Publisher</th>
<th>Publish date</th> <th>Publish date</th>
<th>actions</th> <th>actions</th>
@@ -38,6 +39,7 @@
<td><a href="{{ path('app_book_show', {'id': book.id}) }}" <td><a href="{{ path('app_book_show', {'id': book.id}) }}"
class="text-decoration-none">{{ book.title }}</a></td> class="text-decoration-none">{{ book.title }}</a></td>
<td>{{ book.description | slice(0, 200) }}</td> <td>{{ book.description | slice(0, 200) }}</td>
<td>{% if book.rating %}{% for i in range(1, book.rating) %}{% endfor %}{% endif %}</td>
<td>{{ book.publisher }}</td> <td>{{ book.publisher }}</td>
<td>{{ book.publishDate ? book.publishDate|date('Y-m-d') : '' }}</td> <td>{{ book.publishDate ? book.publishDate|date('Y-m-d') : '' }}</td>
<td> <td>

View File

@@ -20,7 +20,7 @@
<h1>{{ book.title }}</h1> <h1>{{ book.title }}</h1>
<h3>{{ book.subtitle }}</h3> <h3>{{ book.subtitle }}</h3>
<p>{{ book.author }}</p> <p>{{ book.author }}</p>
<p>{% for i in range(1, book.rating) %}{% endfor %}</p> <p>{% if book.rating %}{% for i in range(1, book.rating) %}{% endfor %}{% endif %}</p>
</div> </div>
</div> </div>