Laravel API - Showing individual file through o2m relationship - php

So I have two models User and File, these are connected with a one-to-many relationship.
I have sorted the API routes and controllers to index all users, show specific user and index all files uploaded by that specific user. I do not know how to write the logic that will allow this route 127.0.0.1:8001/api/2/files/1 to show the first file uploaded by the 2nd user. So/2(seconduser)/files(shows all)/1(shows only 1 file)
This is my API code:
Route::group(["prefix" => "/"], function () {
Route::get("", [Users::class, "index"]); //show all users
Route::group(["prefix" => "{user}"], function () {
Route::get("", [Users::class, "show"]); //show specific user
Route::group(["prefix" => "/files"], function () {
Route::get("", [Files::class, "index"]); //show all files
Route::group(["prefix" => "{file}"], function () {
Route::get("", [Files::class, "show"]); //trying to show specific file
});
});
});
});
Files Controller
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\File;
class Files extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index(User $user)
{
return $user->files;
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show(User $user, File $file)
{
}
}
Users Controller
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
class Users extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
return User::all();
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show(User $user)
{
return $user;
}
}

So here's what a typical route declaration would look like. Note the user ID is not relevant to the file request, so the files endpoint is made separate from the users endpoint.
Route::get("/users", [Users::class, "index"]);
Route::get("/users/{user}", [Users::class, "show"]);
Route::get("/users/{user}/files", [Files::class, "index"]);
Route::get("/files/{file}", [Files::class, "show"]);
And then in your controller methods, you're simply returning a list or a single item, mostly as in your original code. Note if you're returning API data, you should explicitly return JSON.
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
use App\Models\File;
class Files extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\JsonResponse
*/
public function index(User $user)
{
return response()->json($user->files);
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\JsonResponse
*/
public function show(File $file)
{
return response()->json($file);
// or perhaps something like this?
return response()
->download($file->path, $file->name, ["Content-Type" => $file->type]);
}
}
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\User;
class Users extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\JsonResponse
*/
public function index()
{
return response()->json(User::all());
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\JsonResponse
*/
public function show(User $user)
{
return response()->json($user);
}
}

Related

Laravel: php artisan migrate:fresh failed ``database.themes`` does not exist

I am trying to run php artisan migrate:fresh to publish a modification to my seeder. It partially worked, it removed all of the tables in the database but it won't recreate them because Table 'database.themes' does not exist. I have included my Themes.php model, my ThemesController.php and any other resources requiring Themes below to hopefully make sense of this.
2020_11_14_125914_create_themes_table (Migration)
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateThemesTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('themes', function (Blueprint $table) {
$table->id('theme_id');
$table->string('theme_title')->default('Main');
$table->string('theme_slug')->default('main')->unique();
$table->text('theme_description')->nullable();
$table->string('theme_uri')->default('laravel.cmsbase.com')->nullable();
$table->string('theme_version')->default('1.0.0')->nullable();
$table->string('theme_license')->default('The MIT License (MIT)')->nullable();
$table->string('theme_tags')->nullable();
$table->string('theme_type')->default('web');
$table->string('author_name')->default('Spencer K Media');
$table->string('author_uri')->nullable();
$table->boolean('is_theme')->default(1)->nullable();
$table->timestamps();
});
DB::table('themes')->insert([
'theme_id' => '1',
'theme_title' => 'Core theme',
'theme_slug' => 'main',
'theme_description' => 'Default theme for the theme package',
'theme_uri' => 'https://laravel.cmsbase.com',
'theme_version' => '1.0.0',
'theme_license' => 'The MIT License (MIT)',
'theme_tags' => 'default, simple, base',
'theme_type' => 'web',
'author_name' => 'Spencer K Media',
'author_uri' => 'https://spencerkmedia.com',
'is_theme' => 1,
]);
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('themes');
}
}
Themes.php (Model)
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Themes extends Model
{
use HasFactory;
protected $fillable = ['theme_title', 'theme_slug', 'theme_uri', 'theme_version', 'theme_license', 'theme_tags', 'theme_type', 'author_name', 'author_uri', 'is_theme'];
}
ThemesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Themes;
use Carbon\Carbon;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Facades\Image;
class ThemeSettingsController extends Controller
{
public $themes;
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
$themes = Themes::get();
return view('admin.settings.theme', compact('themes'));
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function activate()
{
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request, $theme, $json)
{
// Get the path of theme.json
$path = glob("/resources/views/themes/{,*/}theme.json", GLOB_BRACE);
// Parse the json file into array with $json
$json = json_decode(file_get_contents($path), true);
var_dump($json);
$this->validate($request, [
'is_theme' => 'accepted'
]);
$theme = new Themes();
$theme->theme_title = $json->theme_title;
$theme->theme_slug = strtolower($json->theme_title);
$theme->theme_description = $json->theme_description;
$theme->theme_uri = $json->theme_uri;
$theme->theme_version = $json->theme_version;
$theme->theme_license = $json->theme_license;
$theme->theme_tags = $json->theme_tags;
$theme->theme_type = $json->theme_type;
$theme->author_name = $json->author_name;
$theme->author_uri = $json->author_uri;
$theme->is_theme = $request->is_theme;
$theme->save();
notify()->success('Theme successfully enabled :)', 'Success');
return redirect()->back();
}
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param \Illuminate\Http\Request $request
* #param int $id
* #return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}
RouteServiceProvider
<?php
namespace App\Providers;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;
use App\Models\Themes;
class RouteServiceProvider extends ServiceProvider
{
/**
* The path to the "home" route for your application.
*
* This is used by Laravel authentication to redirect users after login.
*
* #var string
*/
public const HOME = '/home';
/**
* The controller namespace for the application.
*
* When present, controller route declarations will automatically be prefixed with this namespace.
*
* #var string|null
*/
// protected $namespace = 'App\\Http\\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* #return void
*/
public function boot()
{
$settings = Themes::get();
$this->configureRateLimiting();
$this->routes(function () use ($settings) {
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes\api.php'));
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes\web.php'));
foreach ($settings as $key => $setting) {
Route::middleware('web')
->group(base_path('resources/views/themes/' . $setting->theme_slug . '/route.php'));
}
});
}
/**
* Configure the rate limiters for the application.
*
* #return void
*/
protected function configureRateLimiting()
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60);
});
}
}
Web.php (Route File)
Route::prefix('settings')->name('settings.')->group(function () {
Route::get('/home', function () {
return view('admin.settings.index');
})->name('index');
Route::get('/general', function () {
return view('admin.settings.general');
})->name('general');
Route::get('/site', function () {
return view('admin.settings.site');
})->name('site');
Route::get('/theme', function () {
return view('admin.settings.theme');
})->name('theme');
});
Any help is appreciated and thank you in advance!
Laravel runs Providers before the command on artisan commands, so its trying to $settings = Themes::get(); on RouteServiceProvider and failing, thus the error. For a temporary fix remove that code and then run the migrate command.
For a more permanent fix, you can check if the model/table exists before running the query:
public function boot()
{
if($settings = Themes::get()){
$this->configureRateLimiting();
$this->routes(function () use ($settings) {
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes\api.php'));
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes\web.php'));
foreach ($settings as $key => $setting) {
Route::middleware('web')
->group(base_path('resources/views/themes/' . $setting->theme_slug . '/route.php'));
}
});
}
}

how to access relationship and pass into a view in laravel

a beginner question here, how can i get the building_name column on my buildings table which has a relationship with information, i wanted to access it inside the show function and display in on the show.views? And i also wanted to know how can i call it inside the show view Please help.
<?php
namespace App\Http\Controllers;
use App\Information;
use App\Building;
use Illuminate\Http\Request;
use Session;
class InformationController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*
* #return \Illuminate\Http\Response
*/
public function create()
{
$buildings = new Building();
$buildings::all();
return view('create', compact('buildings'));
}
/**
* Store a newly created resource in storage.
*
* #param \Illuminate\Http\Request $request
* #return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$this->validate($request, array(
'building_information' => 'required',
'building_id' => 'required'
));
//store in the db
$information = new Information;
$information->building_information = $request->building_information;
$information->building_id = $request->building_id;
$information->save();
Session::flash('success', 'The information was successfully saved!');
//redirect to other page
return redirect()->route('information.show', $information->id);
}
/**
* Display the specified resource.
*
* #param \App\Information $information
* #return \Illuminate\Http\Response
*/
public function show($id)
{
$information = Information::find($id);
return view('show')->with('information', $infomation);
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Building extends Model
{
public function information()
{
return $this->hasMany('App\Information');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Information extends Model
{
public function building()
{
return $this->belongsTo('App\Building');
}
}
Load the relationship too when getting the Information object:
$information = Information::with('building')->find($id);
If there are multiple buildings associated, you can loop through them in your blade view:
#foreach( $information->building as $building)
<li>{{ $building->building_name }}</li>
#endforeach
Just add relationship and pass it to the view
public function show($id)
{
$information = Information::with('building')->findOrFail($id);
return view('show')->with('information', $infomation);
}
In your view:
{{$information->building->building_name}}

ViewComposer Doesn't Work

I have made a header.blade.php which is extended to many View pages. in header menu items come from database.So I used ViewComposer.
Here is my ComposerServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\View;
class ComposerServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
View::composer(['cart.layouts.header'], 'App\Http\ViewComposers\CategoryComposer#compose');
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
//
}
}
here is the CategoryComposer Class:
<?php
namespace App\Http\ViewComposers;
use Illuminate\View\View;
class CategoryComposer
{
public $categoryList = [];
/**
* Create a movie composer.
*
* #return void
*/
public function __construct()
{
$this->categoryList = \DB::table('categories')
->select('categories.*')
->get();
}
/**
* Bind data to the view.
*
* #param View $view
* #return void
*/
public function compose(View $view)
{
$view->with('categories', end($this->categoryList));
}
}
I have also registered the Service Provider in config/app
But the problem is I got error in other pages like Undefined variable: categories
Can you suggest me what could be the Error here?

Laravel : send pivot tables data in view

I'm new to Laravel 5 and I have some difficulties with pivot tables, controllers and repositories.
I have the tables 'users', 'sites', 'site_user', and here is what I have now :
App\Models\User
class User extends Model implements AuthenticatableContract, CanResetPasswordContract {
protected $table = 'users';
public function sites()
{
return $this->belongsToMany('App\Models\Site')
->withPivot('site_id', 'user_id', 'relation');
}
}
App\Models\Site
class Site extends Model {
protected $table = 'sites';
public function user()
{
return $this->belongsToMany('App\Models\User')
->withPivot('site_id', 'user_id', 'relation');
}
}
App\Repositories\SiteRepository
<?php namespace App\Repositories;
use App\Models\Site, App\Models\User;
class SiteRepository extends BaseRepository
{
/**
* The User instance.
*
* #var App\Models\User
*/
protected $user;
/**
* Create a new SiteRepository instance.
*
* #param App\Models\Site $site
* #return void
*/
public function __construct (Site $sites, User $user)
{
$this->model = $sites;
$this->user = $user;
}
/**
* Get sites collection paginate.
*
* #param int $n
* #return Illuminate\Support\Collection
*/
public function index($n)
{
return $this->model
->latest()
->paginate($n);
}
App\Http\Controllers\SiteController
<?php namespace App\Http\Controllers;
use App\Repositories\SiteRepository;
use App\Repositories\UserRepository;
use App\Http\Requests\SiteCreateRequest;
use App\Http\Requests\SiteUpdateRequest;
use App\Models\Site;
use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
class SiteController extends Controller {
/**
* The SiteRepository instance.
*
* #var App\Repositories\SiteRepository
*/
protected $site_gestion;
/**
* The UserRepository instance.
*
* #var App\Repositories\UserRepository
*/
protected $user_gestion;
/**
* Create a new SiteController instance.
*
* #param App\Repositories\SiteRepository $site_gestion
* #param App\Repositories\UserRepository $user_gestion
* #return void
*/
public function __construct (SiteRepository $site_gestion, UserRepository $user_gestion)
{
$this->site_gestion = $site_gestion;
$this->user_gestion = $user_gestion;
$this->middleware('admin');
}
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index(SiteRepository $site_gestion)
{
//$counts = $this->site_gestion->counts();
$sites = $site_gestion->index(25);
$links = $sites->render();
return view('back.sites.index', compact('sites'));
}
views\back\sites\table.blade.php
#foreach ($sites as $site)
[...some code...]
#endforeach
What I want to do is to get all the sites of the logged in user. I've tried many things, but none of them are working. And I'm still not sure where to put the code, repository or controller...
I've read tutorials about pivot in Laravel, and I've tried with some things like this in the repo, but it doesn't work...
$user = $this->user->find(auth()->user()->id); //This line is working
foreach ($user->sites as $site) {
return $site
->latest()
->paginate($n);
}
If you want all sites of a logged user simply do it like this:
$sites = Auth::user()->sites;
That's all you need to do to get to these sites. If you want to use query and pagination try like this:
$sites = Auth::user()->sites()->latest()->paginate($n);
So what you've done seems pretty close.
So you pretty much have it, when iterating over the sites they should be instances of the site model.
$user = auth()->user(); // This is a way of saying your first line without a db query for the user
foreach ($user->sites as $site) {
// each site in here is a site model
$site->pivot->relation;
}
The only other thing that looks slightly strange is how you've defined the pivots. Generally when calling withPivot you wouldn't define the joining ids, if you wish to vary from the defaults you can pass it as an argument to the belongsToMany like so.
return $this->belongsToMany('App\Models\User', 'site_user', 'user_id', 'site_id')
->withPivot('relation');

Laravel Throws ReflectionException Since Update to Version 5.1.7

I'd been working on my portfolio development with a blog alongside on Laravel 5.1.2 lately. It all was working fine till the moment I needed the illuminate/html package. Also, prior to running the composer require illuminate/html command, I ran the composer update command to let all the libraries update to their newer versions.
But that's where the problem crept in. Since, the upgrade to Laravel 5.1.7 and the installation of the illuminate/html package, the project has gone haywire and has been throwing barking mad
ReflectionException in Container.php line 736:
Class view does not exist
And I haven't the slightest clue where this is arising from.
PS: I have also updated the app.php file to include the respective providers and aliases corresponding to illuminate/html.
Update
Here's the code from my controller files if it might be of any help.
PagesController.php (I generated it as a plain stub via the --plain artisan option)
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class PagesController extends Controller
{
public function index()
{
return view('pages.home');
}
}
ArticleController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Article;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class ArticlesController extends Controller
{
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
$articles = Article::all();
return view('blog.index', compact('articles'));
}
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function create()
{
return view('blog.create');
}
/**
* Store a newly created resource in storage.
*
* #return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
*
* #param int $id
* #return Response
*/
public function show($id)
{
$article = Article::findOrFail($id);
return view('blog.show', compact('article'));
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param int $id
* #return Response
*/
public function update($id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return Response
*/
public function destroy($id)
{
//
}
}

Categories