I'm trying to convert a closure-based routes to use a single action controller
So on my fuzzy.php inside routes folder i did this
write the codes
Route::get('theme/{file?}', 'FuzzyController')->name('fuzzy-theme.get');
and on my FuzzyController.php inside Core\Controllers\Assets
<?php
//namespace App\Http\Controllers;
namespace Core\Controllers\Assets;
// use App\User;
use App\Http\Controllers\Controller;
class FuzzyController extends Controller
{
/**
* Show the profile for the given user.
*
* #param int $id
* #return View
*/
public function __invoke(Request $request, $file = null)
{
$path = base_path(config('path.themes', 'themes').'/'.settings('active_theme', 'default'))."/$file";
$fileArray = explode('/', $file);
$lastFile = end($fileArray);
$extension = explode(".", $lastFile);
$fileExtension = end($extension);
$isCss = 'css' === $fileExtension ? true : false;
if (! in_array($fileExtension, config('downloadables', []))) {
return abort(403);
}
if (\File::exists($path)) {
$headers = [
'Cache-Control' => 'public',
'Content-Type' => 'text/css'
];
return response()->file($path, $isCss ? $headers : []);
}
return abort(404);
// return view('user.profile', ['user' => User::findOrFail($id)]);
}
}
can some explain why do i get an invalid route action thanks :D
The issue is because you haven't used namespace in your route definition. Change your route definition to:
Route::get('theme/{file?}', 'Core\Controllers\Assets\FuzzyController')->name('fuzzy-theme.get');
Hope this helps.
Related
Basic Information
I'm developing a simple Web Application that it can post photo using Laravel.
My Question
I want to create several image post form using another variable.
How can I make work my Controllers using another variable?
My Codes
routes/web.php
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('login');
Route::group(['middleweare' => 'auth'], function () {
Route::get('/', 'StoriesController#index');
Route::post('/', 'StoriesController#store');
Route::get('/stories/create', 'StoriesController#add');
Route::post('/stories/create', 'StoriesController#uplaod');
});
Route::group(['middleweare' => 'auth','name'=>'profile'], function () {
Route::get('/profile/edit', 'ProfileController#edit');
Route::get('/profile/create', 'ProfileController#add');
Route::post('/profile/create', 'ProfileController#store');
Route::post('/profile/create', 'ProfileController#upload');
});
Route::get('/home', 'HomeController#index')->name('home');
Auth::routes();
app/Http/Controllers/StoriesController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Story;
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();
return view('stories.index2', compact('images'));
}
public function add()
{
return view('stories.create2');
}
public function store(Request $request)
{
$d = new \DateTime();
$d->setTimeZone(new \DateTimeZone('Asia/Tokyo'));
$dir = $d->format('Y/m');
$path = sprintf('public/images/%s', $dir);
$data = $request->except('_token');
foreach ($data['images'] as $k => $v) {
$filename = '';
$attachments = Attachment::take(1)->orderBy('id', 'desc')->get();
foreach ($attachments as $attachment) {
$filename = $attachment->id + 1 . '_' . $v->getClientOriginalName();
}
unset($attachment);
if ($filename == false) {
$filename = 1 . '_' . $v->getClientOriginalName();
}
$v->storeAs($path, $filename);
$attachment_data = [
'path' => sprintf('images/%s/', $dir),
'name' => $filename
];
$a = new Attachment();
$a->fill($attachment_data)->save();
}
unset($k, $v);
return redirect('/');
}
public function upload(Request $request)
{
dd($request->all());
$this->validate($request, [
'file' => [
'required',
'file',
'image',
'mimes:jpeg,png',
]
]);
if ($request->file('file')->isValid([])) {
$path = $request->file->store('public');
return view('stories.index2')->with('filename', basename($path));
} else {
return redirect('/')
->back()
->withInput()
->withErrors();
}
}
}
I made a profile image post form, and general image post form.
And I want to view those image on same page.
I have my slug stored in my database. In my controller i retrieve my slug en then add a view to it.
It all works fine if i have a url like domain.com/prices.
But when i have a url like domain.com/prices/somethingelse then the app breaks.
Looks like i cannot handle the /
In my datebase i have the right url..
This is my controller:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Content;
use App\Models\Product;
use App\Models\Brand;
use App\Models\Thumbnail;
use App\Models\Content_blocks;
use App\Models\Basiscontent;
use App\Models\Contentcategory as Contentcategories;
use App\Models\View as viewValue;
use App\Models\Banners as Banner;
use App\Models\Aanbieding;
use Illuminate\Http\Request;
use Illuminate\View\View as template;
use Illuminate\Support\Facades\View;
class ContentController extends Controller
{
/**
* Gebruikerslijst
*
* #param Request $request
* #param string $slug
* #param string $value
*
* #return template
*/
public function index(Request $request, string $slug = '', string $value = '', int $id = null): template
{
if ($slug == '') {
$slug = '/';
}
$content = Content::getContentBySlug($slug);
if ($content === null) {
return abort(404);
}
$pageSlug = $content->slug;
$view = $content->view()->first();
if ($view === null) {
$view = 'index';
} else {
// $pageView = $content->view()->first()->value;
// $view = $pageSlug !== $pageView ? 'index' : $pageView;
$view = $content->view()->first()->value;
};
$id = $content->id;
$content_blocks = Content_blocks::getContentBlock($id);
$content_block_thumb = Content_blocks::getContentThumb($id);
// dd(Content_blocks::categorie());
// dd($contentcategory = Contentcategories::all());
// $content_block_thumb = Content_blocks::getContentBlock();
// dd(Content::getContentBySlug($slug)->title);
// dd(Content_blocks::getContentBlock($id)->id);
// dd(Thumbnail::getFile(1));
$content_blocks_cat = Content_blocks::orderBy("order", "ASC");
// dd($content_blocks_cat->get());
return view::make($view)
->with('products', Product::all()->sortBy('order'))
->with('brands', Brand::all())
->with('banners', Banner::all())
->with('aanbiedingen', Aanbieding::all())
->with('contentcategory', Contentcategories::all())
->with('basiscontent', Basiscontent::all())
->with('content', $content)
// ->with('content_blocks', Content_blocks::all());
->with('content_blocks', $content_block_thumb)
->with('content_blocks_cat', $content_blocks_cat->get());
// ->with('thumbnail', Thumbnail::getFile($content_block_thumb->thumbnail_id));
// ->with('thumbnail', Thumbnail::getFile(1));
}
}
Route:
Route::get('{slug?}', '\App\Http\Controllers\ContentController#index');
Hope you can help me out.
Thanks!
For extra slashes, you need to add another layer check for the route:
Route::get('{slug1}/{slug2?}', '\App\Http\Controllers\ContentController#index');
Add as many for the route depths as needed. You'll need to adjust your function to accept the additional paramters as well.
I'm trying to use Image Intervention with laravel to resize images.
my code :
<?php
namespace App\Http\Controllers;
use App\Ad;
use App\Categorie;
use App\Http\Requests\AdsRequest;
use App\Mail\RejectedAd;
use App\Mail\ValidatedAd;
use Carbon\Carbon;
use Exception;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use Intervention\Image\Facades\Image;
class AdController extends Controller
{
/**
* AdController constructor.
*/
public function __construct()
{
$this->middleware('auth', ['except' => ['index', 'show']]);
}
/**
* Store a newly created resource in storage.
*
* #param AdsRequest $request
* #return \Illuminate\Http\Response
*/
public function store(AdsRequest $request)
{
$validated = $request->validated();
$idAuthor = Auth::user()->id;
if (Auth::user()->activite !== 'particulier') {
$pro_ad = true;
} else {
$pro_ad = false;
}
$ad = new Ad();
$ad->title = $validated['title'];
$ad->content = $validated['content'];
$ad->price = $validated['price'];
$ad->zip = $validated['zip'];
$ad->city = $validated['city'];
$ad->categorie_id = $validated['categorie'];
$ad->user_id = $idAuthor;
$ad->publication_date = Carbon::now('Europe/Paris')->addDay(2);
if (isset($validated['descr']) && $validated['descr'] !== null) {
$ad->subcategory = $validated['descr'];
}
$ad->pro = $pro_ad;
$ad->save();
if (isset($validated['tag']) && $validated['tag'] !== null) {
$ad->Tag()->attach($validated['tag']);
}
$ad->save();
if ($request->hasFile('file')) {
Storage::disk('public')->makeDirectory("ad-$ad->id");
foreach ($request->file('file') as $image) {
if ($image) {
// Get filename with the extension
$filenameWithExt = $image->getClientOriginalName();
// Get just filename
$filename = pathinfo($filenameWithExt, PATHINFO_FILENAME);
//Get just extension
$extension = $image->getClientOriginalExtension();
// Filename to store
$filenameToStore = $filename . '_' . time() . '.' . $extension;
// Upload image
$image->storeAs("/public/ad-$ad->id", $filenameToStore);
print_r('resize');
$img = Image::make(storage_path('app/public') . "/ad-$ad->id/" . $filenameToStore)->resize(400, 150, function ($constraint) {
$constraint->aspectRatio();
});
$img->save(storage_path('app/public') . "/ad-$ad->id/" . $filenameToStore);
print_r('resize fin');
$ad->File()->create(['path' => $filenameToStore]);
}
}
}
$ad->save();
return redirect(route('annonces.show', ['id' => $ad->id]));
}
}
but only the first print_r is displayed the rest is as not run.
Thank you in advance for your answers.
Nicolas
does anyone know a way of mapping the controller methods with permissions authorisation?
Let's say that I have 20 controllers, with index,store,show and delete methods and I don't wanna put in each method of this controller the correspondent permission, just for the sake of ... DRY.
What I wanna do instead is trying to map the permissions with controller actions.
An example would be:
https://laravel.com/docs/5.5/authorization#writing-gates
Gate::resource('posts', 'PostPolicy');
This is identical to manually defining the following Gate definitions:
Gate::define('posts.view', 'PostPolicy#view');
Gate::define('posts.create', 'PostPolicy#create');
Gate::define('posts.update', 'PostPolicy#update');
Gate::define('posts.delete', 'PostPolicy#delete');
for me something like this would fit:
Permission::map('route', 'permission');
Permission::map('users.store', 'create-user');
or even better
Permission::mapResource('users', '????');
I created a Trait for that, if you have a better suggestion please.
namespace App\Traits;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Pluralizer;
use Spatie\Permission\Exceptions\UnauthorizedException;
trait Authorisation
{
private $permissions = [
'index' => 'view',
'store' => 'create',
'show' => 'view',
'update' => 'edit',
'destroy' => 'delete'
];
private $action;
public function callAction($method, $parameters)
{
$permission = $this->getPermission($method);
if(($permission && Auth::user()->can($permission)) || !$permission)
return parent::callAction($method, $parameters);
if(Request::ajax()) {
return response()->json([
'response' => str_slug($permission.'_not_allowed', '_')
], 403);
}
throw UnauthorizedException::forPermissions([$permission]);
}
public function getPermission($method)
{
if(!$this->action = array_get($this->getPermissions(), $method)) return null;
return $this->routeName() ? $this->actionRoute() : $this->action;
}
public function registerActionPermission($action, $permission) {
$this->permissions[$action] = $permission;
}
private function actionRoute() {
return Pluralizer::singular($this->action . '-' . $this->routeName());
}
private function routeName() {
return explode('.', Request::route()->getName())[0];
}
private function getPermissions()
{
return $this->permissions;
}
}
And use it in controller like:
use Authorisation;
and if a want a custom permission for an action which does not exist in the $permissions:
$this->registerActionPermission('action_name', 'action-permission');
I've written this image upload service but the problem is that I keep getting the following error.
I've tried a number of suggestions but I don't seem to get over it.
error type ReflectionException, message Class upload.image does not exist","file":"C:\xampp\htdocs\tippy\vendor\laravel\framework\src\Illuminate\Container\Container.php", line 501
ImageUploadService.php
namespace Tippy\Services\Upload;
use Intervention\Image\Image;
use Illuminate\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class ImageUploadService
{
protected $directory = 'assets/img/uploads/temp';
protected $extension = 'jpg';
protected $size = 160;
protected $quality = 65;
protected $filesystem;
public function __construct(Filesystem $filesystem)
{
$this->filesystem = $filesystem;
}
public function enableCORS($origin)
{
$allowHeaders = [
'Origin',
'X-Requested-With',
'Content-Range',
'Content-Disposition',
'Content-Type'
];
header('Access-Control-Allow-Origin: ' . $origin);
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: ' . implode(', ', $allowHeaders));
}
protected function getFullPath($path)
{
return public_path() . '/' . $path;
}
protected function makeFileName()
{
return Sha1(time() . time()) . '.{$this->extension}';
}
protected function getFile($path)
{
$this->filesytem->get($path);
}
protected function getFileSize($path)
{
return $this->filesytem->size($path);
}
protected function getDataUrl($mime, $path)
{
$base = base64_encode($this->getFile($path));
return 'data:' . $mime . ';base64,' $base;
}
protected function getJsonBody($filename, $mime, $path)
{
return [
'images' => [
'filename' => $filename,
'mime' => $mime,
'size' => $this->getFileSize($path),
'dataURL' => $this->getDataUrl($mime, $path)
]
];
}
public function handle(UploadedFile $file)
{
$mime = $file->getMimeType();
$filename = $this->makeFileName();
$path = $this->getFullPath($this->directory . '/' . $filename);
$success = Image::make($file->getRealPath())
->resize($this->size, $this->size, true, false)
->save($path, $this->quality);
if (! $success) {
return false;
}
return $this->getJsonBody($filename, $mime, $path);
}
}
Here is UploadServiceProvider.php
namespace Tippy\Providers;
use Illuminate\Support\ServiceProvider;
use Tippy\Services\Upload\ImageUploadService;
class UploadServiceProvider extends ServiceProvider
{
public function register()
{
$this->app['upload.image'] = $this->app->share(function ($app) {
return new ImageUploadService($app['files']);
});
}
}
Here's my ImageUpload.php Facade
protected static function getFacadeAccessor()
{
return 'upload.image';
}
And finally I've autoloaded the provider
'Tippy\Providers\UploadServiceProvider',
And aliased the class
'ImageUpload' => 'Tippy\Facades\ImageUpload',
Any help would be much appreciated.
Before diving into the world of Facades & Services,
You have to take a look at PSR-0 convention. PSR-0 tells composer how to load your classes (facades, services & the lot).
Link to useful resources:
What is PSR-0
Using a PSR-0 Directory Structure
Setup your own library