Spatie UrlSigner in Laravel 5.5 - php

I have tried and searched everything I could think of and I can not make Spatie UrlSigner work under Laravel.
Basically I have followed the step by step installation guide on his page.
Installed with composer.
Added the provider and facade in config/app.php:
'providers' => [
Spatie\UrlSigner\Laravel\UrlSignerServiceProvider::class,
],
'aliases' => [
'UrlSigner' => Spatie\UrlSigner\Laravel\UrlSignerFacade::class,
],
Then in my controller I included the facade using the alias:
use UrlSigner;
And tried to used it in some function:
public function publicShow() {
$url=UrlSigner::sign('http://example.com', 30);
return $url;
}
This gives me a fatal error:
Class 'UrlSigner' not found
I have tried different methods, even including the class itself which returned a different error about not being allowed to call the method statically. All in all I feel like I've no solution left.
I think this is something trivial that I'm missing but being quite a beginner with Laravel I can't for the life of me find out what it is.
Cheers!

Turns out that this was the correct way to load the package. After trying to install it on a different instance of Laravel and having everything work like a charm I did a bunch of comparing between those two.
Not sure why the very same facade worked on one instance and not on another despite using the exact same code on my end.
Solved it by deleting everything except .gitignore from the bootstrap/cache/ folder as suggested to a similar problem here.
Thanks to everyone who helped!

Related

barryvdh/laravel-debugbar won't allow method calls in Lumen

I'm using Lumen 5.5.2, and the latest version of the laravel-debugbar package I installed via Composer.
I made the necessary changes to these files, as specified in the manual.
app/bootstrap/app.php:
+ $app->register(Barryvdh\Debugbar\LumenServiceProvider::class);
+ $app->configure('debugbar');
app/config/app.php
+ 'aliases' => ['Debugbar' => Barryvdh\Debugbar\Facade::class]
The bar displays fine, but I ran into an issue of not being able to call any methods mentioned in the manual. For example, when I try to report exceptions, using this code in app/Exceptions/Handler.php
public function report(Exception $e)
{
\Debugbar::addException($e);
parent::report($e);
}
I get the following uncaught error: Class 'Debugbar' not found in /home/vagrant/code/lumen/app/Exceptions/Handler.php on line 37.
Considering I registered the alias within my app config, I'm puzzled why Lumen is unable to get the class.
I discovered a solution on my own, provided you've set everything up properly, it's possible to set $var = app('debugbar');, and then call methods relative to $var, ex.: $var->info('Logging info...').
I'm still curious if there is a better solution.

Use a vendor class from composer in Laravel

How would I go around using this class/library in Laravel:
https://github.com/planetteamspeak/ts3phpframework
I tried to include it in config/app.php providers like this:
planetteamspeak\ts3-php-framework\libraries\TeamSpeak3.php::class,
But I keep getting this error, and I couldn't find anything about it that helped me. I also tried to add it without .php at the end but that doesn't help either.
Fatal error: Uncaught ReflectionException: Class log does not exist in PATH-HERE\vendor\laravel\framework\src\Illuminate\Container\Container.php:734
I'll appreciate any help, thanks!
To use your class/library in Laravel, first you should put in your composer.json dependecy for that ts3phpframework
"require": {
"planetteamspeak/ts3phpframework" : "1.*"
}
Inside file app.php you need to do 2 things (something like this, dunno the proper name of alias and provider (be sure to do composer update before doing it)
First add provider (just a hint how to do it)
'providers' => [
ts3phpframework/ts3phpframeworkProvider::class
]
Second add alias (just a hint how to do it)
'aliases' => [
'ts3phpframework' => ts3phpframework\Facades\ts3phpframework::class,
]
If you won't be able to get this library with composer, then add it manually with a help of this. If you won't be able to find alias and provider, then create them manually with a help of this.
And at the end, very similar question already answered here

Can’t send a file response for the storage folder in Laravel 5.2 on Homestead

What I wanted to do, is to protect my private files, so that only their owners could access them. I changed my public disk to storage folder:
'orders' => [
'driver' => 'local',
'root' => storage_path('files/orders'),
],
And created a routed controller to be able to make files private (I intentionally excluded this logic from the example):
Route::get('files/{slug}', [
'as' => 'get.file',
'uses' => 'FileController#getFile',
]);
class FileController extends Controller
{
public function getFile($slug)
{
// I use spatie/laravel-medialibrary
// to manage file uploads.
$media = Media::where('slug', $slug)->first();
return response()->file($media->getPath());
}
}
The getPath() is a spatie/laravel-medialibrary method that returns the correct path to the file: /home/vagrant/code/project/storage/files/orders/2/b414a7416571145ea9dcf9bda9a845a2.jpg. It clearly finds the file, because I can use \Symfony\Component\HttpFoundation\File\File() to get files’ data like their mime type or size (and also don’t get a 404 error as a response); when I follow, say, http://localhost:3000/files/2RmYR3 route I get this blank 200 response—looks like so:
One person tested pretty much the same code on his end, and it worked, but he was on Valet, so it might be a Homestead issue. He also suggested it might be an issue with headers, and I tried sending different headers (content-type/length, for instance), but nothing helped, so please see what I’m receiving without specifying any headers for the response:
I also tried vagrant destroy, just in case, but the issue stayed. In any case, thank you for your time.
It resolved itself. I started stripping pieces from the application to understand which part of the code messes with responses, at first I thought it was my view composer, but no; I did a fresh separate Laravel installation, and copied config/app.php from the fresh installation to my project, then just updated lists of providers and aliases that I had before, and that did it.
My app.php lacked 'log_level' => env('APP_LOG_LEVEL', 'debug'), line that was added at some point to Laravel after I started the project, and maybe that’s why responses didn’t work properly, but I doubt it.

Phalcon webtools not working

So I installed Phalcon and the phalcon devtools. When I try anything, it throws an error (Generate model, generate controller and scaffolding). Looked around and I can see other people had this problem but I cannot find a solution.
Generate Model page:
Error on generate:
webtools.config.php:
define('PTOOLS_IP', '192.168.0.81');
define('PTOOLSPATH', 'C:/phalcon-tools/vendor/phalcon/devtools');
Error on generate controller:
Please specify a controller directory
Error on generate model:
Database configuration cannot be loaded from your config file
Error on scaffolding:
Adapter was not found in the config. Please specify a config variable [database][adapter]
Had this same issue the other day. I found a work around but it's far from ideal.
Find
\devtools\scripts\Phalcon\Builder\
And open Components.php
Inside this file find the line:
foreach (array('/app/config/', 'config/') as $configPath) {
This line needs to be either:
(array('/../app/config/' <- For model Generator to work.
or
(array('../app/config/' <- For scaffolding Generator to work.
I can't for the life of me work why, and it's far from ideal trying to remember to do it every time you need to use the tools, but it works.

Creating a new ServiceProvider / Facade as a package in Laravel 5

Introduction
I've never worked with a framework before (Zend, CakePHP, etc) and finally decided to sit down and learn one. I'm starting with Laravel because the code looks pretty and unlike some other frameworks I tried to install, the "Hello, World!" example worked on the first try.
The Goal
For the time being, I want my app to do something very simple:
User submits a request in the form of: GET /dist/lat,lng
The app uses the remote IP address and MaxMind to determine $latitude1 and $longitude1
This request path is parsed for $latitude2 and $longitude2
Using these two positions, we calculate the distance between them. To do this I'm using Rafael Fragoso's WorldDistance PHP class
Since I plan to re-use this function in later projects, it didn't seem right to throw all of the code into the /app directory. The two reusable parts of the application were:
A service provider that connects to MaxMind and returns a latitude and longitude
A service provider that takes two points on a globe and returns the distance
If I build facades correctly then instead of my routes.php file being a mess of closures within closures, I can simply write:
Route::get('dist/{input}', function($input){
$input = explode( "," , $input );
return Distance::getDistance( GeoIP::getLocation(), $input );
});
What I've tried
Initial Attempt
For the first service provider, I found Daniel Stainback's Laravel 5 GeoIP service provider. It didn't install as easily as it should have (I had to manually copy geoip.php to the /config directory, update /config/app.php by hand, and run composer update and php artisan optimize) however it worked: A request to GET /test returned all of my information.
For the second service provider, I started by trying to mimic the directory structure and file naming convention of the GeoIP service provider. I figured that if I had the same naming convention, the autoloader would be able to locate my class. So I created /vendor/stevendesu/worlddistance/src/Stevendesu/WorldDistance\WorldDistanceServiceProvider.php:
<?php namespace Stevendesu\WorldDistance;
use Illuminate\Support\ServiceProvider;
class WorldDistanceServiceProvider extends ServiceProvider {
protected $defer = false;
public function register()
{
// Register providers.
$this->app['distance'] = $this->app->share(function($app)
{
return new WorldDistance();
});
}
public function provides()
{
return ['distance'];
}
}
I then added this to my /config/app.php:
'Stevendesu\WorldDistance\WorldDistanceServiceProvider',
This fails with a fatal error:
FatalErrorException in ProviderRepository.php line 150:
Class 'Stevendesu\WorldDistance\WorldDistanceServiceProvider' not found
Using WorkBench
Since this utterly failed I figured that there must be some other file dependency: maybe without composer.json or without a README it gives up. I don't know. So I started to look into package creation. Several Google searches for "create package laravel 5" proved fruitless. Either:
They were using Laravel 4.2, in which case the advice was "run php artisan workbench vendor/package --resources"
Or
They were using Laravel 5, in which case the docs were completely useless
The official Laravel 5 docs give you plenty of sample code, saying things like:
All you need to do is tell Laravel where the views for a given namespace are located. For example, if your package is named "courier", you might add the following to your service provider's boot method:
public function boot()
{
$this->loadViewsFrom(__DIR__.'/path/to/views', 'courier');
}
This makes the assumption that you have a service provider to put a boot method in
Nothing in the docs says how to create a service provider in such a way that it will actually be loaded by Laravel.
I also found several different resources all of which assume you have a repository and you just want to include it in your app, or assume you have "workbench". Nothing about creating a new package entirely from scratch.
PHP Artisan did not even have a "workbench" command, and there was no "workbench.php" file in /config, so anything I found related to workbench was worthless. I started doing some research on Workbench and found several different questions on StackOverflow.
After a long time and some experimentation, I managed to get laravel/workbench into my composer.json, composer update, composer install, manually build a workbench.php config file, and finally use the PHP Artisan Workbench command to make a new package:
php artisan workbench Stevendesu/WorldDistance --resources
This created a directory: /workbench/stevendesu/world-distance with a number of sub-directories and only one file: /workbench/stevendesu/world-distance/src/Stevendesu/WorldDistance/WorldDistanceServiceProvider.php
This service provider class looked essentially identical to the file I created before, except that it was in the /workbench directory instead of the /vendor directory. I tried reloading the page and I still got the fatal error:
FatalErrorException in ProviderRepository.php line 150:
Class 'Stevendesu\WorldDistance\WorldDistanceServiceProvider' not found
I also tried php artisan vendor:publish. I don't really know what this command does and the description wasn't helpful, so maybe it would help? It didn't.
Question
How do I create a new service provider as a package so that in future projects I can simply include this package and have all the same functionality? Or rather, what did I do wrong so that the package I created isn't working?
After two days of playing with this I managed to find the solution. I had assumed that the directory structure mapped directly to the autoloader's path that it checked (e.g. attempting to access a class Stevendesu\WorldDistance\WorldDistanceServiceProvider would look in vendor/stevendesu/world-distance/WorldDistanceServiceProvider)... This isn't the case.
Reading through the composer source code to see how it actually loads the files, it builds a "classmap" - essentially a gigantic array mapping classes to their respective files. This file is built when you run composer update or composer install - and it will only be built correctly if composer knows the details of your package. That is - if your package is included in your project's composer.json file
I created a local git repository outside of my app then added my package to my app's composer.json file then ran composer update -- suddenly everything worked perfectly.
As for the:
It didn't install as easily as it should have
the secret sauce here was first add the service provider to /config/app.php then, second run php artisan vendor:publish

Categories