How can I post an Images on my Laravel App? - php

Basic Informations
I'm developing a simple web app using Laravel.
and I want to add an image upload and stirage function.
My issue
I want to save the binary data of the image to the DataBase.
But there is an error message.
file_get_contents(): Filename cannot be empty
How can I solve this issue?
My Codes
2020_06_12_085454_create_attachments_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateAttachmentsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('attachments', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('path');
$table->text('image');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('attachments');
}
}
index2.blade.php
#extends('layouts.front2')
#section('title','mainpage')
#section('content')
<link rel="stylesheet" href="{{ asset('css/main2.css') }}">
<div class="profile">
<div class="name">
#guest
<a class="nav-link2" href="{{ route('register')}}">{{ __('Create Accout!')}}</a>
#else
<a id="navbarDropdown" class="nav-link2" href="#" role="button">
{{ Auth::user()->name }}<span class="caret"></span></a>
<form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
#csrf
</form>
#endguest
</div>
<div class="aboutme">
<tbody>
#foreach($posts as $profile)
<tr>
<td>{{ \Str::limit($profile->title, 100) }}</td>
<td>{{ \Str::limit($profile->body, 250) }}</td>
</tr>
delete
update
#endforeach
</tbody>
<br>
</div>
</div>
<div class="new">
<div class="newtitle">
<h1>New</h1>
</div>
<div class="container1">
#foreach ($images as $image)
<img src="data:image/png;base64,{{ $image->image }}" class="images" style="height: 250px; width: 250px; border-radius: 50%;">
 delete
#endforeach
<div class="more">
more...
</div>
</div>
</div>
{{ csrf_field() }}
#endsection
StoriesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Story;
use App\Profile;
use Auth;
use App\Posts;
use App\History;
use App\Attachment;
use Carbon\Carbon;
use Storage;
class StoriesController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function index(Request $request)
{
$images = Attachment::all();
$cond_title = $request->cond_title;
if ($cond_title != '') {
$posts = Profile::where('title', $cond_title)->get();
} else {
$posts = Profile::all();
}
return view('stories.index2', compact('images','posts','cond_title'));
}
public function add()
{
return view('stories.create2');
}
public function store(Request $request)
{
$image = new Attachment();
$image->image = base64_encode(file_get_contents($request->image));
$image->save();
}

You need to get the path where the temporary image is stored. To do that do
$request->file('image')
so your code becomes
public function store(Request $request)
{
$image = new Attachment();
$image->image = base64_encode(file_get_contents($request->file('image')));
$image->save();
}

Related

How to change language dinamically in laravel?

I added a button to change language.
This is my controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\RedirectResponse;
class LanguageController extends Controller
{
public function __invoke(String $locale): RedirectResponse
{
app('session')->put('language', $locale);
app()->setLocale($locale);
return redirect()->back();
}
}
My routes:
<?php
use App\Http\Controllers\LanguageController;
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('auth.login');
});
Route::get('/language/{locale}', LanguageController::class)->name('locale');
require __DIR__.'/auth.php';
And I put this in my blade:
#if (app()->getLocale() == 'es')
<x-responsive-nav-link :href="route('locale', ['locale' => 'en'])">
{{ __('English') }}
</x-responsive-nav-link>
#else
<x-responsive-nav-link :href="route('locale', ['locale' => 'es'])">
{{ __('Spanish') }}
</x-responsive-nav-link>
#endif
I tested it changing the locale directly in the config/app.php file and it works.
Also tried to set the locale in the AppServiceProvider but session variable "language" is not set (even though it is on the controller).
How could I do this?
My version.Right now this is the best way for me.
Route:
Route::get('locale/{locale}', function ($locale) {Session::put('locale', $locale);return redirect()->back();})->name('locale');
HeaderController function index:
public function index(): Factory|View|Application
{
$data['languages'] = Language::where('status', '=', 1)->get();
//Get or Set current language
$get_default_lang = 'uk';
$default_lang = $get_default_lang ?? 'en';
if (session()->get('locale') == null) Session::put('locale', $default_lang);
//Get Current Language
$get_current_lang = Session::get('locale');
$session_language = Language::where('code', $get_current_lang)->first();
$data['current_language_name'] = $session_language['name'];
$data['current_language_image'] = url($session_language['image']);
return view('common/header', ['data' => $data]);
}
Header Blade:
<div class="dropdown">
<button type="button" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<img src="{{ $data['current_language_image'] }}" alt="{{ $data['current_language_name'] }}" style="max-width:20px;margin-right:5px;" />
{{ $data['current_language_name'] }}
</button>
<div class="dropdown-menu">
<div class="p-2">
#foreach($data['languages'] as $language)
<a href="{{ route('locale', ['locale' => $language->code]) }}" class="dropdown-item d-flex align-items-center justify-content-between">
<img src="{{ url($language->image) }}" alt="{{ $language->name }}" style="max-width:20px;" />
<span>{{ $language->name }}</span>
</a>
#endforeach
</div>
</div>
</div>
Language migration:
Schema::create('language', function (Blueprint $table) {
$table->bigIncrements('language_id');
$table->string('name', 32);
$table->string('code', 5);
$table->string('image')->nullable();
$table->tinyInteger('status');
$table->timestamps();
});

How to show images in a datatable after submitting them in a form?

I made a form where I add a product with fields like name, price, image and its category. Now I would like to display them in a datatable and I was able to do that. The problem is that for the display, all the fields are displayed but the images alone do not come and shows an icon of an image not loaded. Here's a bit of that in the capture I submitted.
The blade.php:
#extends('layouts.appadmin')
#section('title')
Livres
#endsection
#section('contenu')
<div class="card">
<div class="card-body">
<h4 class="card-title">Livres</h4>
<div class="row">
<div class="col-12">
<div class="table-responsive">
<table id="order-listing" class="table">
<thead>
<tr>
<th>Order #</th>
<th>Nom du livre</th>
<th>Prix</th>
<th>Image</th>
<th>Statut</th>
<th>Catégorie</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#foreach ($livres as $livre)
<tr>
<td>{{$livre->id}}</td>
<td>{{$livre->nomLivre}}</td>
<td>{{$livre->prixLivre}}</td>
<td><img src="/storage/{{$livre->image}}" alt=""></td>
<td>
#if ($livre->statusLivre ==1)
<label class="badge badge-success">Activé</label>
#else
<label class="badge badge-success">Désactivé</label>
#endif
</td>
<td>{{$livre->categorie->category_name}}</td>
<td>
<button class="btn btn-outline-primary">View</button>
<button class="btn btn-outline-danger">Delete</button>
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
#endsection
#section('scripts')
<script src="Administrateur/js/data-table.js"></script>
#endsection
</body>
</html>
Just below, It's the controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Categorie;
use App\Models\Livre;
class LivreController extends Controller
{
//
public function ajouterlivre()
{
$categories = Categorie::all();
return view('admin.ajouterlivre', [
'categories' => $categories,
]);
}
public function sauverlivre(Request $request)
{
$request->validate([
'nomLivre' => 'required|unique:livres',
'prixLivre' => 'required',
'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
'categorie_id' => 'required',
]);
$input = $request->all();
if ($image = $request->file('image')) {
$destinationPath = 'storage/';
$profileImage = date('YmdHis') . "." . $image->getClientOriginalExtension();
$image->move($destinationPath, $profileImage);
$input['image'] = "$profileImage";
}
Livre::create($input);
return redirect('/ajouterlivre')->with('status', 'Un livre a été ajouté avec succès');
}
public function livre()
{
$livres = Livre::get();
return view('admin.livres')->with('livres', $livres);
}
The migration file:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateLivresTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('livres', function (Blueprint $table) {
$table->increments('id');
$table->string('nomLivre')->unique();
$table->integer('prixLivre');
$table->string('image');
$table->integer('statusLivre')->default(0)->nullable();
$table->integer('categorie_id')->unsigned();
$table->foreign('categorie_id')->references('id')->on('categories')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('livres');
}
}
You see that the images are not loaded, right? What could have caused this? Thank you for your attention.

show the categories and project in view

my questions may be a bit of a beginner, but please be patient, thank you
I want to display the projects related to each category in the following code in the second foreach, but now all the projects are displayed
view
#foreach($categories as $category)
<div id="section-{{ $category->id }}" class="section">
<h3 class="fnt_gh fnt-color">{{ $category->category_project }}</h3>
<div class="bigBox">
<div class="container1">
#foreach($projects as $project)
<article class="barghabi">
<a href="#" data-cat="news" data-state="vic">
<img src="{{ $project->image_project }}" alt="">
<h6 class="fnt_gh" style="line-height: normal;">
{{ $project->title_project }}
</h6>
</a>
</article>
#endforeach
<div class="content"></div>
</div>
</div>
</div>
#endforeach
And a categories table and a project table whose models and relationships are as follows:
class Project extends Model
{
protected $fillable = [
'title_project' ,
'period_project' ,
'description_project' ,
'manager_project' ,
'phone_project' ,
'email_project' ,
'image_project'
];
public function categories()
{
return $this->belongsToMany(Category::class);
}
}
class Category extends Model
{
protected $fillable = ['category_project' , 'icon_project'];
public function projects()
{
return $this->belongsToMany(Project::class);
}
}
and pivot :
Schema::create('category_project', function (Blueprint $table) {
$table->unsignedBigInteger('category_id');
$table->foreign('category_id')->references('id')->on('categories')->onDelete('cascade');
$table->unsignedBigInteger('project_id');
$table->foreign('project_id')->references('id')->on('projects')->onDelete('cascade');
$table->primary(['category_id' , 'project_id']);
$table->timestamps();
});
controller:
class ProjectController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
$categories = Category::all();
$projects = Project::all();
return view('home.fa.pages.project.index', compact('categories' , 'projects' ));
}
}
You are calling #foreach($projects as $project) within your loop. You've defined $projects as all projects. Instead, use #foreach($category->projects as $project).
#foreach($categories as $category)
<div id="section-{{ $category->id }}" class="section">
<h3 class="fnt_gh fnt-color">{{ $category->category_project }}</h3>
<div class="bigBox">
<div class="container1">
#foreach($category->projects as $project)
<article class="barghabi">
<a href="#" data-cat="news" data-state="vic">
<img src="{{ $project->image_project }}" alt="">
<h6 class="fnt_gh" style="line-height: normal;">
{{ $project->title_project }}
</h6>
</a>
</article>
#endforeach
<div class="content"></div>
</div>
</div>
</div>
#endforeach
I'm not sure what's in $category->category_project but having a property with the same name as your pivot table is bound to create confusion. You should keep column names simple and readable, not append _project to each one!

Got an error in laravel as:ErrorException Undefined variable: products

I am a newbie to Laravel and this is my first project. I am developing an e-commerce website. Up to now, I have finished the project with the help of StackOverflow and laracasts. Why I am getting this error?
I got an error as,
ErrorException Undefined variable: products
This is my controller.
CartController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Product;
use App\Category;
class CartController extends Controller
{
public function index()
{
$products = Product::get();
return view ('cart')->with(compact('products'));
}
public function create()
{
//
}
public function store(Request $request)
{
//
}
public function show($id)
{
$products = Product::find($id);
return view('cart')->with(compact('product'));
}
public function edit($id)
{
//
}
public function update(Request $request, $id)
{
//
}
public function destroy($id)
{
//
}
}
This is my blade file.
cart.blade.php
#extends('layouts.single')
#section('content')
#foreach($products as $p)
<tr class="">
<td class="text-center">
×
</td>
<td class="d-none d-md-table-cell">
<img class="img-fluid max-width-100 p-1 border border-color-1" alt="Image Description">
</td>
<td data-title="Product">
{{ $p ['prod_name'] }}
</td>
<td data-title="Price">
<span class="">LKR {{ $p ['prod_price'] }}.00</span>
</td>
<td data-title="Quantity">
<span class="sr-only">Quantity</span>
<!-- Quantity -->
<div class="border rounded-pill py-1 width-122 w-xl-80 px-3 border-color-1">
<div class="js-quantity row align-items-center">
<div class="col">
<input class="js-result form-control h-auto border-0 rounded p-0 shadow-none" type="text" value="1">
</div>
<div class="col-auto pr-1">
<a class="js-minus btn btn-icon btn-xs btn-outline-secondary rounded-circle border-0" href="javascript:;">
<small class="fas fa-minus btn-icon__inner"></small>
</a>
<a class="js-plus btn btn-icon btn-xs btn-outline-secondary rounded-circle border-0" href="javascript:;">
<small class="fas fa-plus btn-icon__inner"></small>
</a>
</div>
</div>
</div>
<!-- End Quantity -->
</td>
<td data-title="Total">
<span class="">$1,100.00</span>
</td>
</tr>
#endforeach
#endsection
This is my route.
web.php
Route::get('/cart', 'CartController#index')->name('cart');
Route::get('/cart/{id}', 'CartController#show')->name('cart');
products table
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateProductsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('prod_name');
$table->string('prod_brand')->nullable();
$table->unsignedBigInteger('cat_id');
$table->string('prod_description')->nullable();
$table->string('prod_item_code')->nullable();
$table->string('prod_modal')->nullable();
$table->string('prod_size')->nullable();
$table->string('prod_weight')->nullable();
$table->string('prod_height')->nullable();
$table->string('prod_manufacturer')->nullable();
$table->float('prod_price')->nullable();
$table->float('prod_discount')->nullable();
$table->float('prod_quantity')->nullable();
$table->string('prod_image_path')->nullable();
$table->timestamps();
$table->foreign('cat_id')
->references('id')
->on('categories')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('products');
}
}
Product Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Storage;
class Product extends Model
{
}
Your problem is in the index method of the controller. On the first line, you are trying to assign $products, but that variable does not exist.
public function index()
{
$arr['products'] = $products;
return view('cart')->with($arr);
}
You need to get all of your products to do this. Something like:
public function index(Request $request)
{
$arr['products'] = Product::all();
return view('cart')->with($arr);
}
This example will just give you all of the products in your database. This is not really a good solution, as you can have a lot of products, making the response huge and expensive. To get around this, you can add pagination. Here is a simple example of implementing that:
You need to get all of your products to do this. Something like:
public function index(Request $request)
{
$limit = $request->input('limit', 10);
$page = $request->input('page', 1);
$arr['products'] = Product::paginate($limit, [], 'page', $page)->items();
return view('cart')->with($arr);
}
Again, this is just an example to make you aware of this concept and is probably more for API responses and not view responses, like you are doing here, but nonetheless, something you need to know about eventually. Read more about it here: https://laravel.com/docs/7.x/pagination
EDIT: Since you are trying to show multiple products in the view, you will also have to iterate the products, so you can render them one by one. For this you need to read up on: https://laravel.com/docs/7.x/blade#loops

I want to display username of comment's owner, however, comments table has user_id only

After I send the variable that contains the comments to the view, I can only display the user id. This is why I need to somehow foreach through all the comments and based on their user_id to add a new key-pair value with username-username and send it to the view afterwards. Unfortunately, I'm having trouble figuring how to do that.
public function specificImage($id){
$similarImages = null;
$image = Image::with('comments.user')->find($id);
$subImages = Image::where('parent_id', $id)->get();
$views = $image->views;
$image->views = $views + 1;
$image->save();
$authorId = $image->user_id;
$author = User::find($authorId);
$comments = Comment::where('image_id', $id)->get();
$recentImages = Image::where('parent_id', NULL)->where('user_id', $authorId)->orderBy('created_at', 'desc')->limit(9)->get();
$tag = Tag::whereHas('images', function($q) use ($id) {
return $q->where('taggable_id', $id);
})->first();
if (!empty($tag)) {
$tagId = $tag->id;
}
if (!empty($tagId)) {
$similarImages = Image::where('parent_id', NULL)->whereHas('tags', function($q) use ($tagId) {
return $q->where('tag_id', $tagId);
})->orderBy('created_at', 'desc')->limit(9)->get();
}
return view('specificImage', ['image' => $image,'subImages' => $subImages, 'recentImages' => $recentImages, 'similarImages' => $similarImages, 'author' => $author, 'comments' => $comments]);
}
Table:
Table: Comments
Columns: id, user_id, image_id, comment
Image model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Image extends Model
{
public function user(){
return $this->belongsTo('App\User');
}
public function tags(){
return $this->morphToMany('App\Tag', 'taggable');
}
public function votes(){
return $this->hasMany('App\Vote');
}
public function comments(){
return $this->hasMany('App\Comment');
}
public function updateVotes()
{
$this->upvotes = Vote::where('image_id', $this->id)->where('vote', true)->count();
$this->downvotes = Vote::where('image_id', $this->id)->where('vote', false)->count();
$this->save();
}
public function updateComments()
{
$this->comments = Comment::where('image_id', $this->id)->count();
$this->save();
}
}
Comment model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
public function image(){
return $this->belongsTo('App\Image');
}
public function user(){
return $this->belongsTo('App\User');
}
}
User model:
<?php
namespace App;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
class User extends Model implements Authenticatable
{
use \Illuminate\Auth\Authenticatable;
public function images(){
return $this->hasMany('App\Image');
}
public function comments(){
return $this->hasMany('App\Comment');
}
public function votes(){
return $this->hasMany('App\Vote');
}
public function roles(){
return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');
}
public function hasAnyRole($roles) {
if (is_array($roles)) {
foreach ($roles as $role) {
if ($this->hasRole($role)){
return true;
}
}
} else {
if ($this->hasRole($roles)){
return true;
}
}
return false;
}
public function hasRole($role){
if ($this->roles()->where('name', $role)->first()){
return true;
}
return false;
}
}
Blade
#extends('layouts.app')
#section('content')
<div class="specific-image-flexbox">
<div class="specific-image-column">
<div class='specific-image-container'>
<img class='specific-image' src='{{url("storage/uploads/images/specificImages/".$image->file_name)}}' alt='Random image' />
#foreach($subImages as $subImage)
<img class='specific-image' src='{{url("storage/uploads/images/specificImages/".$subImage->file_name)}}' alt='Random image' />
#endforeach
</div>
</div>
<div class="artwork-info-column">
<div class="artwork-info-container">
<p class='title'>{{ $image->name }}<p>
<p class='author'>на<a href='{{url("profile/".$author->username )}}'><span class='usernameA artwork-info-username-span'>{{$author->username}}</span></a><img class='artwork-info-profile-picture' src='{{url("storage/uploads/profile_pictures/edited/".$author->profile_picture)}}'></p>
#if(Auth::user())
#if(Auth::id() === $image->user_id || Auth::user()->hasRole('Admin'))
<a class='placeholderDelete' href='{{ route('deleteImage', ['image_id' => $image->id]) }}'><i class="far fa-trash-alt"></i> Изтрий изображението</a>
#endif
#endif
<p class='description'>{{ $image->description }}</p>
<p class='description'>Техника: {{ $image->medium }}</p>
<p><i class="far fa-eye"></i> {{ $image->views }} Преглеждания</p>
<p><i class="far fa-thumbs-up"></i> {{ $image->upvotes }} Харесвания</p>
<p class='commentsCount'><i class="far fa-comments"></i> {{ $image->comments }} Коментари</p>
<a class='downloadImage' href="{{url("storage/uploads/images/specificImages/".$image->file_name)}}" download="{{ $image->name }}"><i class="fas fa-file-download"></i> Изтегли</a>
<!--<a class='placeholderDelete fas fa-expand' href='{{url("storage/uploads/images/specificImages/".$image->file_name)}}'></a>-->
<div class='social-container'>
<div class="addthis_inline_share_toolbox"
data-url="{{ url()->full() }}"
data-title="{{ $image->name }} by {{ $author->username }}"
data-description="{{ $image->description }}"
data-media="{{url("storage/uploads/images/specificImages/".$image->file_name)}}">
</div>
</div>
#if(!empty($recentImages))
#if(count($recentImages) >= 9)
<p class='author'>Още произведения на<a href='{{url("profile/".$author->username )}}'><span class='usernameA artwork-info-username-span'>{{$author->username}}</span></a><img class='artwork-info-profile-picture' src='{{url("storage/uploads/profile_pictures/edited/".$author->profile_picture)}}'></p>
<div class="more-images-container">
#foreach($recentImages as $recentImage)
<div class="more-images-container-element">
<a href='{{url("image/".$recentImage->id)}}'>
<img class='more-images' src='{{url("storage/uploads/images/miniImages/".$recentImage->file_name)}}' alt='Random image' />
</a>
</div>
#endforeach
</div>
#endif
#endif
#if(!empty($similarImages))
#if(count($similarImages) >= 9)
<p class='similar-images'>Подобни произведения</p>
<div class="similar-images-container">
#foreach($similarImages as $similarImage)
<div class="similar-images-container-element">
<a href='{{url("image/".$similarImage->id)}}'>
<img class='more-images' src='{{url("storage/uploads/images/miniImages/".$similarImage->file_name)}}' alt='Random image' />
</a>
</div>
#endforeach
</div>
#endif
#endif
#auth
<div class='postComments'>
<form method='POST' action=''>
<textarea class='comment-section' name='comment'></textarea>
<input type="hidden" name="user_id" value="{{ Auth::user()->id }}">
<input type="hidden" name="image_id" value="{{ $image->id }}">
<button class='postComment submit' type='submit' name='commentSubmit'>Изпрати</button>
</form>
</div>
#endauth
<div class='comments'>
#foreach($image->comments as $comment)
{{ $comment->user->username }}
#endforeach
</div>
</div>
</div>
</div>
<script>
var token = '{{ Session::token() }}';
var urlComment = '{{ route('comment') }}';
var urlLike = '{{ route('vote') }}';
</script>
#endsection
I would suggest adding the user relationship to your Comment model as well:
class Comment extends Model
{
public function image()
{
return $this->belongsTo('App\Image');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
You can then eager load the relationships and then access them in your blade file:
public function specificImage($id)
{
$image = Image::with('comments.user')->find($id);
return view('specificImage', ['image' => $image]);
}
Then in your blade file you would have something like:
#foreach($image->comments as $comment)
{{ $comment->user->username }}
#endforeach

Categories