Add Sub Category - Laravel 5.2 - php

I need to insert sub categories into my main categories. I have already done all the work for Showing, Adding, Editing, and Deleting parent Categories. But now im stuck with how to actually add a sub category to one of my parents category.
Here is how the table looks like for the category's and sub categories.
As you can see I already Have a sub category under iPhone's, which I added manually through the database. To add a sub category to a main category, I just click on the + sub-Category link which takes me to the form to add sub category.
Here i my route to show and add a sub category:
Route::group(["middleware" => 'admin'], function(){
/** More category routes here -->, just hidden for shortness **/
/** Show the Admin Add Sub-Categories Page **/
Route::get('admin/categories/addsub/{id}', [
'uses' => '\App\Http\Controllers\CategoriesController#addSubCategories',
'as' => 'admin.category.addsub',
'middleware' => ['auth'],
]);
/** Post the Sub-Category Route **/
Route::post('admin/categories/postsub/{id}', [
'uses' => '\App\Http\Controllers\CategoriesController#addPostSubCategories',
'as' => 'admin.category.postsub',
'middleware' => ['auth'],
]);
});
Here is my CategoriesController.php:
It is shortened just to show sub-categories functions. This is where I'm having trouble adding a sub category to a parent category
class CategoriesController extends Controller
/**
* Return the view for add new sub category
*
* #return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function addSubCategories($id) {
$category = Category::findOrFail($id);
return view('admin.category.addsub', compact('category'));
}
/**
* #param $id
* #param CategoryRequest $request
* #return \Illuminate\Http\RedirectResponse
*/
public function addPostSubCategories($id, CategoryRequest $request) {
// Find the Parent Category ID
$category = Category::findOrFail($id);
// Insert into categories where the Parent_id = to the category ID
$categories = Category::where('parent_id', '=', $category);
// Assign $category to the Category Model, and request all validation rules
$categories = new Category($request->all());
// Then save the newly created category in DB
$categories->save();
// Flash a success message
flash()->success('Success', 'Sub Category added successfully!');
// Redirect back to Show all categories page.
return redirect()->route('admin.category.show');
}
}
My Category.php Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
protected $table = 'categories';
protected $fillable = ['name'];
protected $guarded = ['id'];
public function parent() {
return $this->belongsTo('App\Category', 'parent_id');
}
public function children() {
return $this->hasMany('App\Category', 'parent_id');
}
}
My add sub category form:
<form role="form" method="POST" action="{{ route('admin.category.postsub', $category->id) }}">
{{ csrf_field() }}
<li class="collection-item blue">
<h5 class="white-text text-center">
Sub-Category to {{ $category->name }}
</h5>
</li>
<li class="collection-item">
<div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
<input type="text" class="form-control" name="name" value="{{ old('name') }}" placeholder="Add Sub-Category">
#if($errors->has('name'))
<span class="help-block">{{ $errors->first('name') }}</span>
#endif
</div>
</li>
<li class="collection-item blue">
<div class="form-group text-center">
<button type="submit" class="btn btn-link grey lighten-5">Create Sub-Category</button>
</div>
</li>
</form>
And my Database structure:
I particulary need help in my addPostSubCategories() function in my CategoriesController, because right now if I add a new SUB category, it just adds a new Parent Category, not a sub category

Visit here to see a detailed explanation: https://laravel.com/docs/5.2/eloquent-relationships#inserting-related-models
Here's what you want:
/**
* #param $id
* #param CategoryRequest $request
* #return \Illuminate\Http\RedirectResponse
*/
public function addPostSubCategories($id, CategoryRequest $request) {
// Find the Parent Category
$category = Category::findOrFail($id);
// Create the new Subcategory
$subcategory = new Category($request->all());
// Save the new subcategory into the relationship
$category->children()->save($subcategory);
// Flash a success message
flash()->success('Success', 'Sub Category added successfully!');
// Redirect back to Show all categories page.
return redirect()->route('admin.category.show');
}

Related

Laravel subcategories

For an app, I'm creating a scraper.
At the moment I'm at the page where a user can add items to a list with the possibility to create any subcategories where you can add append those items to a specific subcategory.
At the bottom of the page, there is a section where all the subcategories are listed and below each category should be a list where all the items are who are appended to that specific subcategory.
At the moment, I was able to show all the names of the subcategories and all products that are in my main list are stored in the subcategories that has the id. (I hope you can follow what's going on). But I don't know how I can only show the articles who was that specific subcategory in that list instead of all of the main articles..
My code:
My view:
<div class="bg-gray-100 shadow-xl w-11/12 m-auto p-4 rounded-md space-y-6 relative">
<strong>Mijn sublijsten</strong>
#foreach ($subcats as $scat)
<div class="flex lg:flex-row">
<h2>{{ $scat->name }}</h2>
#if ($wishlists->contains('subcat', $cat->id))
#foreach ($wishlists as $item)
<strong>{{$item->article->title}}</strong>
#endforeach
#endif
</div>
#endforeach
</div>
My Controller
public function dashboard($role, $id)
{
$wishlists = Wishlist::all();
$articles = Article::all();
$websites = Website::all();
$categories = Category::all();
$subcats = Subcat::all();
$subcat = Wishlist::find($id)->get();
return view('dashboard', compact('wishlists', 'articles', 'categories', 'websites', 'subcats', 'subcat'));
}
My Model
class Wishlist extends Model
{
protected $table = "wishlists";
protected $fillable = [
'user_id',
'article_id',
'confirmed',
'available',
'score',
'subcat'
];
protected $casts = [
];
public function user()
{
return $this->belongsTo(User::class);
}
public function article()
{
return $this->belongsTo(Article::class);
}
public function subcat()
{
return $this->belongsTo(Subcat::class);
}
}

How can i display grouped values in Laravel

I'm Trying to display restaurant Menus grouped by the categories, for example...
Lunch
Chicken and Chips
Rice
Breakfast
Tea
Coffee
So I have 3 tables in my database, Restaurants, Categories, And Menus
Category Model
class Category extends Model
{
protected $fillable = [
'name'
];
/**
* #return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function menus_type()
{
return $this->hasMany('App\Menu','category_id');
}
}
Menu Model
class Menu extends Model
{
protected $fillable = [
'name',
'price',
'description',
'photoPath',
'restaurant_id',
'category_id',
];
/**
* Menu belongs to Restaurant
*/
public function restaurant()
{
return $this->belongsTo('App\Restaurant');
}
/**
* Menu belongs to category type
*/
public function category_type()
{
return $this->belongsTo('App\Category', 'category_id');
}
}
Restaurants controller
public function show($slug, RestaurantRepository $repository){
if(! $restaurant = $repository->get(['slug' => $slug], with(['cuisines','user', 'photos', 'thumbs', 'region', 'ratings.user']))) return abort('404');
$menus=Menu::with(['category_type'])->where('restaurant_id',$restaurant->id)->get()->groupBy('category_id');
return view('frontend.restaurant.show', compact('restaurant', 'p','menus'));
}
when i Dump this it looks just fine.
Results have been grouped
Now my trouble is on the View when i try to get results of this i get an error.
#if($menus)
<ul>
#foreach($menus as $m)
<li>
{{$m->name}}
</li>
#endforeach
</ul>
#endif
ErrorException (E_ERROR).
Property [name] does not exist on this collection instance.
Iterate inner loop also. 'groupBy()' creates another array with category_id as key.
#if($menus)
<ul>
#foreach($menus as $category_id=>$outer)
#foreach($outer as $k=>$inner)
<li>
{{$category_id}}: {{$inner->name}}
</li>
#endforeach
#endforeach
</ul>
#endif
Updated you query to get from category
$categories = Category::with('menus_type')->get();
return view('frontend.restaurant.show', compact('restaurant', 'p','categories '));
In your view
#if($categories ?? false)
<ul>
#foreach($categories ?? [] as $cat_key=>$category)
<li>
{{$category->name}}
</li>
<li>
<ul>
#foreach($category->menus_type as $menu_key=>$menu)
<li>
{{$menu->name}}
</li>
#endforeach
</ul>
</li>
#endforeach
</ul>
#endif

Showing Sub-categories on menu only if has products with Laravel

I have simple query which populate menu with Main categories and sub-categories. This work perfectly
// in controller
$cat=Categories::all();
View::share('categories_menu',$cat);
// in view
#foreach($categories_menu as $category_menu)
#if($category_menu->has('subcategories'))
<ul class="nav nav-stacked cat-nav">
<li>
{{ $category_menu['category_name'] }}
#if($category_menu->subcategories->count())
<ul>
#foreach($category_menu->subcategories as $subcategory)
<li class="">{{$subcategory->sub_cat_name}}</li>
#endforeach
</ul>
#endif
</li>
#else
<li><i class="fa fa-link"></i> <span>{{ $category_menu->category_name }}</span></li>
#endif
</ul>
#endforeach
This make output like
Main Category
-Sub Cat
-Sub Cat
Second main category
-Sub in second main category
...
The problem is that it is loading also sub-categories which are empty. I don't want to show them and I tried to change the query with joining all three tables - category, sub_categories, products
This is the query so far
$cat = Categories::select('*', DB::raw('category.category_id AS category_id'))
->leftJoin('products', function($join) {
$join->on('products.category_id', '=', 'category.category_id');
})
->leftJoin('sub_category', function($secondjoin){
$secondjoin->on('sub_category.category_id', '=', 'category.category_id');
})
->whereNotNull('products.sub_cat_id')
->get();
The result is strange ( image )
It's should show me only two main categories each with one sub. On the image you can see my product table
Category 1
-sub1
Category 2
-sub3
If need some more source or something i can provide.
Update with models:
Categories model
class Categories extends Eloquent {
protected $table = 'category';
protected $primaryKey = 'category_id';
public $timestamps = false;
public function products()
{
return $this->hasMany('Product', 'category_id');
}
public function subcategories()
{
return $this->hasMany('SubCategories', 'category_id');
}
}
SubCategories model
class SubCategories extends Eloquent {
protected $table = 'sub_category';
protected $primaryKey = 'sub_cat_id';
public $timestamps = false;
public function category()
{
return $this->belongsTo('Category', 'category_id');
}
public function products()
{
return $this->hasMany('Product', 'sub_cat_id');
}
}
Products model
class Product extends Eloquent {
protected $table = 'products';
protected $primaryKey = 'product_id';
public function categories()
{
return $this->hasMany('Categories', 'category_id');
}
public $timestamps = false;
}
#foreach($categories_menu as $category_menu)
#if($category_menu->has('subcategories'))
<ul class="nav nav-stacked cat-nav">
<li>
{{ $category_menu['category_name'] }}
#if($category_menu->subcategories->count())
<ul>
#foreach($category_menu->subcategories as $subcategory)
#if($subcategory->products->count())
<li class="">{{$subcategory->sub_cat_name}}</li>
#endif
#endforeach
</ul>
#endif
</li>
#else
<li><i class="fa fa-link"></i> <span>{{ $category_menu->category_name }}</span></li>
#endif
</ul>
#endforeach
I added a condition for subcatergy to be displayed only if their products count is above 0.

Trying to get column data from pivot table laravel

Hi I'm trying to output a certain column from my pivot table. To show you what I have tried, I will first show you my models (my pivot tables are ordertasks and tagtasks):
Task table:
class Task extends \Eloquent {
// Add your validation rules here
public static $rules = [
// 'title' => 'required'
];
// Don't forget to fill this array
protected $fillable = ['task_name','task_description','hour','difficulty'];
public function ordertask()
{
//oneToMany
return $this->hasMany('Ordertask', 'id_task', 'id');
}
public function tagtask()
{
//oneToMany
return $this->hasMany('Tagtask', 'id_task', 'id');
}
}
Tagtask table:
<?php
class Tagtask extends \Eloquent {
protected $fillable = ['id_tag','id_task'];
public function task()
{
//manyToOne
return $this->belongsTo('Task', 'id_task', 'id');
//return $this->belongsTo('Task');
}
public function tag()
{
//manyToOne
return $this->belongsTo('Tag', 'id_tag', 'id');
}
}
Ordertask table:
<?php
class Ordertask extends \Eloquent {
// Add your validation rules here
public static $rules = [
// 'title' => 'required'
];
// Don't forget to fill this array
protected $fillable = ['id_order','id_task', 'hour', 'hourprice','id_user', 'createdBy'];
public function user()
{
//manyToOne
return $this->belongsTo('User', 'id_user', 'id');
//return $this->belongsTo('User');
}
public function task()
{
//manyToOne
return $this->belongsTo('Task', 'id_task', 'id');
//return $this->belongsTo('Task');
}
}
Here is my TaskController.php with the following piece of code:
public function index()
{
$Tasks=Task::with('tagtask','ordertask')->get();
return View::make('user.tasks.index', compact('Tasks'));
}
Okay now comes the part where I want to show $Task->ordertask['id_user'] on my browser with the following piece of code:
#if (count($Tasks))
<ul>
#foreach($Tasks as $Task)
<div class="row">
<div class="col-md-3">
<li>
{{--as a third parameter we need to pass in the id of task, because it needs to be fed to
our actual user.task.edit route. --}}
{{link_to_route('user.tasks.edit', $Task['task_name'], array($Task->id))}}
</li>
</div>
<div class="col-md-3">
<li>
{{$Task->ordertask['id_user']}}
</li>
</div>
<div class="col-md-3">
<li>
{{$Task['task_hour']}}
</li>
</div>
<div class="col-md-3">
<li>
{{Form::open(array('route'=>array('user.tasks.destroy',$Task->id),
'method'=>'delete','class'=>'destroy'))}}
{{Form::submit('Delete')}}
{{Form::close()}}
</li>
</div>
</div>
#endforeach
</ul>
#endif
Unfortunately that doesn't work because I get the following error:
Undefined index: id_user
Instead of:
{{$Task->ordertask['id_user']}}
I have also tried this just to see what output it gave me:
{{$Task->ordertask}}
Which gave me the following output:
[{"id":5,"id_order":2,"id_task":1,"hour":63,"hourprice":15,"id_user":5,"createdBy":4,"created_at":"2014-10-13 10:21:33","updated_at":"2014-10-13 10:21:33"}]
So gladly I want to output id_user from the ordertask table. Gladly I'm waiting on your answer. Anyway thanks for your response.
One Task can have many order tasks, so to display users instead of
{{$Task->ordertask['id_user']}}
You should use:
#foreach ($Task->ordertask as $ot)
{{ $ot->id_user }}
#endforeach

Undefined variable "category" in foreach loop laravel 4.2

My Route:
Route::controller('admin' , 'CategoriesController');
Controller:
<?php
class CategoriesController extends BaseController {
/**
* Display a listing of the resource.
* GET /categories
*
* #return Response
*/
public function __construct() {
$this->beforeFilter('csrf', array('on' =>'post' ));
}
public function getIndex()
{
return View::make('categories.index')
->with('categories', Category::all());
}
/**
* Show the form for creating a new resource.
* GET /categories/create
*
* #return Response
*/
public function postCreate()
{
$validator = Validator::make(Input::all(), Category::$rules);
if ($validator->passes()) {
$category = new Category;
$category->name = Input::get('name');
$category->save();
return Redirect::to('admin/categories/index')
->with('message' , 'Category created');
}
return Redirect::to('admin/categories/index')
->with('message' , 'Something went wrong')
->withErrors($validator)
->withInput();
}
/**
* Remove the specified resource from storage.
* DELETE /categories/{id}
*
* #param int $id
* #return Response
*/
public function postDestroy()
{
$category = Category::find(Input::get('id'));
if ($category){
$category->delete();
return Redirect::to('admin/categories/index')
->with('message' , 'category deleted');
}
return Redirect::to('admin/categories/index')
->with('message' , 'something went wronng');
}
}
Model:
<?php
class Category extends \Eloquent {
protected $fillable = array('name');
public static $rules = array('name'=>'required|min:3');
}
view/index.blade :
#section('content')
<div id="admin">
<h1>Categories Admin panel</h1>
<p>Here you can view, delete, and create new categories.</p>
<h2>Categories</h2>
<ul>
#foreach($categories as $category)
<li>
{{ $category->name }}
{{ Form::open(array('url'=>'admin/categories/destroy', 'class' => 'form-inline'))}}
{{ Form::hidden('id' , $category->id) }}
{{ Form::submit('delete')}}
{{ Form::close();}}
</li>
#endforeach
</ul>
<h2>Create New Category</h2>
#if($errors->has)
<div id="form-errors">
<p>The following erros</p>
<ul>
#foreach($errors->all() as $error)
<li>{{ $errors }}</li>
#endforeach
</ul>
</div><!--end form-errors-->
#endif
{{ Form::open(array('url'=>'admin/categories/create'))}}
<p>
{{ Form::label('name')}}
{{ Form::text('name')}}
</p>
{{ Form::submit('Create Category', array('class' => 'secodary-cart-btn'))}}
{{ Form::close()}}
</div><!--end admin-->
#stop
The Problem is: When I run this code in my browser it show undefined variable: category in index.blade.php.
Please check your route you are trying to access in your browser.
Problem is, you are trying to use RESTful Controllers. In that case, you have to access the URL in the restful method.
If you want to access the getIndex() Method in your restful controller, then in your browser, you have to access
http://www.yoursite.com/admin/index
Basically, Route::controller('admin','CategoriesController'); Means, when you have /admin/ in your URL, it will access this CategoriesController. Then the verbs get followed by the URL path will be used.
If you want to take the non RESTful route, then do it one of the following way
Pass the $categories array like this in your route
Route::get('/', function(){
return View::make('categories.index')->with('categories',Category::all());
});
OR
Route::get('/',array('uses'=>'CategoriesController#getIndex'));
And then in your CategoriesController
public function getIndex(){
return View::make('categories.index')
->with('categories', Category::all());
}
Should Fix it :)

Categories