<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Model\User;
use Illuminate\Support\Facades\Auth;
use Socialize;
use Redirect;
use Input;
use Mail;
use App\Mail\verifyEmail;
use Carbon\Carbon;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\File;
class CustomAuthController extends Controller
{
// Register form
private function render() {
$renderer_source = File::get(base_path('node_modules/vue-server-renderer/basic.js'));
$app_source = File::get(public_path('js/entry-server.js'));
$v8 = new \V8Js();
ob_start();
$v8->executeString('var process = { env: { VUE_ENV: "server", NODE_ENV: "production" }}; this.global = { process: process };');
$v8->executeString($renderer_source);
$v8->executeString($app_source);
return ob_get_clean();
}
public function get() {
$ssr = $this->render();
return view('app', ['ssr' => $ssr]);
}
}
I followed https://dzone.com/articles/server-side-rendering-with-laravel-amp-vuejs-25 and installed v8js.But error is $v8->executeString($app_source); make an error that "V8Js::compileString():9272: ReferenceError: window is not defined"
How to fix this bug.i have no idea
=================================================
Update I can run it.i change code in app.js by delete
/** after i delete it.i can run with server side rendering
require('./bootstrap');
require('./bulma-carousel.min')
window.Vue = require('vue');
can you tell me why ?*/
import App from './components/App.vue';
import VeeValidate from 'vee-validate';
import Vue from 'vue';
import router from './router'
Vue.use(VeeValidate);
/**
* Next, we will create a fresh Vue application instance and attach it to
* the page. Then, you may begin adding components to this application
* or customize the JavaScript scaffolding to fit your unique needs.
*/
Vue.component('index-component', require('./components/index.vue'));
export function createApp() {
return new Vue({
render: h => h(App)
});
}
The problem is simple. The bootstrap file you are requesting is probably using window element in it somewhere. Also on this line window.Vue = require('vue'); you are using the window global object. Window as a global object is available in the browser, however javascript run on the server doesn't have the window object. Thus the error. This is the reason we need to make separate javascript files for server and the client. Try to consult with packages you implement on their support for server-side rendering.
Try disabling various imports one by one and find the ones which break your support for SSR and fix those or find alternatives.
Related
I have installed the Laravel in sub-folder and is trying to install the horizon. After routing to "test.com/sub-folder/horizon", all the design in broken and also the internal links are pointing to main domain instead of main-domain-without-subfolder.
After the search, it seems to be the known issue which is already reported in github issue
Has there is any work around to make horizon work when Laravel is installed in sub-folder?
I have a solution that only involves PHP.
The issue, as pointed out by #Isaiahiroko, is the basePath defined for Horizon's interface. That code is in Laravel\Horizon\Http\Controllers\HomeController::index(). The idea is this: we are going to pass to Laravel's service container our own implementation of that controller that will override the basePath definition passed to Horizon's interface.
Create a new controller with code like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Str;
use Illuminate\View\View;
use Laravel\Horizon\Horizon;
use Laravel\Horizon\Http\Controllers\HomeController;
class HorizonHomeController extends HomeController
{
/**
* Overrides default horizon route to support subdirectory hosting.
*/
public function index ()
{
// We use a plain request to check for the base url.
$request = request();
// Set up our base path.
$base_path = Str::substr($request->getBasePath(), 1);
if (!empty($base_path)) {
$base_path .= '/';
}
// Patch default horizon variables with our own base path.
$variables = Horizon::scriptVariables();
$variables['path'] = $base_path . config('horizon.path');
// Render horizon's home view.
return view('horizon::layout', [
'assetsAreCurrent' => Horizon::assetsAreCurrent(),
'horizonScriptVariables' => $variables,
'cssFile' => Horizon::$useDarkTheme ? 'app-dark.css' : 'app.css',
'isDownForMaintenance' => App::isDownForMaintenance(),
]);
}
}
What's left is telling Laravel's service container that when Horizon's HomeController is requested, it should provide our HorizonHomeController class. In your AppServiceProvider, at the end of the register() method, set this up:
// [...]
class AppServiceProvider extends ServiceProvider
{
// [...]
/**
* Register any application services.
*
* #return void
* #throws InvalidConfiguration
*/
public function register()
{
// [...]
// Horizon's subdirectory hack
$this->app->bind(
Laravel\Horizon\Http\Controllers\HomeController::class,
App\Http\Controllers\HorizonHomeController::class
);
}
// [...]
}
After that, you should be able to browse to http(s)://<your-host>/<your-sub-dir>/horizon normally.
Considerations:
To me this feels cleaner that patching a compiled js, which also has the downside that needs to be re-applied every time Horizon is updated (this can be mitigated with a post-update script in composer, tho). Also, for additional points, this solution is only overriding the method that renders the view, but not the route, which means all of Horizon's authentication mechanisms (middlewares and gates) are working exactly as described in the documentation.
If you desperately need to do this, here is a hack:
In public\vendor\horizon\app.js, search for window.Horizon.basePath
replace window.Horizon.basePath="/"+window.Horizon.path; with window.Horizon.basePath="/[you sub-directoy]/"+window.Horizon.path;
It should work...until you run update one day and it mysteriously stop working.
I try to export a csv file with some data, but with my current code I get response 200, and some strange characters, and no download, not sure why.
Source URL here.
Exports/DataExport.php
namespace App\Exports;
use App\ViewData;
use Maatwebsite\Excel\Concerns\FromCollection;
use Excel;
class DataExport implements FromCollection
{
/**
* #return \Illuminate\Support\Collection
*/
public function collection()
{
return ViewData::all();
}
}
Controller
use App\ViewData;
use App\Exports\DataExport;
use Maatwebsite\Excel\Facades\Excel;
.....
// Export CSV data
public function export()
{
return Excel::download(new DataExport, 'data.xlsx');
}
I added in config/app.php file, service provider and aliase.
You are downloading the csv file from a frontend framework, so ofcourse it will gives you some strange characters instead of downloading a whole file, let me gives you a short code for that
downloadCSV() {
let newWindow = window.open();
axios.get('/json/persons/export')
.then(response => {
newWindow.location = 'http://' + window.location.hostname + '/json/persons/export';
});
}
You need to manually hit that url for the download to work. The rest you understand I think.
I can't use binance api in laravel
I installed Php binance api from composer require "jaggedsoft/php-binance-api #dev" but examples not working in laravel.I had some errors when I tried.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
require '../vendor/autoload.php';
class BinanceController extends Controller
{
public function list()
{
$api = new Binance\API();
$key = "----";
$secret = "---";
$api = new Binance\API($key, $secret);
$price = $api->price("BNBBTC");
return $price;
}
}
When I runned the route I got this error:
Symfony\Component\Debug\Exception\FatalThrowableError Class
'App\Http\Controllers\Binance\API' not found
You're not importing Binance\API correctly. Laravel believes the Binance\Api class is located in the App\Http\Controllers\Binance namespace. Which it is not.
Try $api = new \Binance\API();
Or put it in your use cases.
use Binance\API
I also found an old wrapper which you may be able to import if there hasn't been any changes to Binance since but I highly doubt it. Since your case is specific to Laravel, look for a Binance wrapper for Laravel specifically. Here may contain some useful information on how to use non-laravel packages, with laravel
Since Laravel 5.3, the route implicit binding works as middleware called SubstituteBindings. I used to work with Laravel 5.2 and upgraded to 5.3.
I have some custom middlewares in my application and in my tests I need to disable them. So, until now I used $this->withoutMiddleware() in the test methods. But since the update to Laravel 5.3, withoutMiddleware stops the route implicit binding, and all my tests fails.
I don't know if this should be considered as bug, but it is a huge problem for me.
Is there any way to set the SubstituteBindings middleware as mandatory middleware? How can I still use implicit binding and test my tests without other middlewares?
Building on my comment above I had a look at registering a custom router which always adds SubstituteBindings to the list of middleware if middleware was disabled. You can achieve it by registering a custom RoutingServiceProvider and registering your own Router class. Unfortunately since the route is created fairly early on in the app bootstrap process you also need to create a custom App class and use that in bootstrap/app.php too.
RoutingServiceProvider
<?php namespace App\Extensions\Providers;
use Illuminate\Routing\RoutingServiceProvider as IlluminateRoutingServiceProvider;
use App\Extensions\ExtendedRouter;
class RoutingServiceProvider extends IlluminateRoutingServiceProvider
{
protected function registerRouter()
{
$this->app['router'] = $this->app->share(function ($app) {
return new ExtendedRouter($app['events'], $app);
});
}
}
Custom router
This adds the middleware, it just extends the default router but overrides the runRouteWithinStack method and, instead of returning an empty array if $this->container->make('middleware.disable') is true, it returns an array containing the SubstituteBindings class.
<?php namespace App\Extensions;
use Illuminate\Routing\Router;
use Illuminate\Routing\Route;
use Illuminate\Routing\Pipeline;
use Illuminate\Http\Request;
class ExtendedRouter extends Router {
protected function runRouteWithinStack(Route $route, Request $request)
{
$shouldSkipMiddleware = $this->container->bound('middleware.disable') &&
$this->container->make('middleware.disable') === true;
// Make sure SubstituteBindings is always used as middleware
$middleware = $shouldSkipMiddleware ? [
\Illuminate\Routing\Middleware\SubstituteBindings::class
] : $this->gatherRouteMiddleware($route);
return (new Pipeline($this->container))
->send($request)
->through($middleware)
->then(function ($request) use ($route) {
return $this->prepareResponse(
$request, $route->run($request)
);
});
}
}
Custom App Class
<?php namespace App;
use App\Extensions\Providers\RoutingServiceProvider;
class MyCustomApp extends Application
{
protected function registerBaseServiceProviders()
{
parent::registerBaseServiceProviders();
$this->register(new RoutingServiceProvider($this));
}
Using the custom app class
In bootstrap/app.php change the line where the app is instantiated to:
$app = new App\MyCustomApp(
realpath(__DIR__.'/../')
);
--
Warning! I haven't fully tested this, my app loads and my tests pass but there could be issues that I haven't discovered. It's also quite brittle since if the Laravel base Router class changes you might find things break randomly on future upgrades.
--
You might also want to refactor this so the list of middleware in the custom router always contains the SubstituteBindings class so there isn't so much of a difference in behaviour if middleware is disabled.
I'm new to Laravel and what I want to accomplish:
One laravel installation for multiple sites
Have some functions shared amongst all my sites, for instance User handling, while other functionality will be unique to a specific site
I want to pretty much have a wide variety of different sites under one installation, so I then can build an admin view where I can manage all sites.
How would I go about doing this? I have a fresh Laravel 4.2 installation.
You can have a look at the package rbewley4/multi-app-laravel on Github. Another hint can be found at this answer on StackOverflow
1. Create ConfigServiceProvider in app\Providers folder and set code:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Request;
class ConfigServiceProvider extends ServiceProvider {
public function register() {
$template = $_SERVER["SERVER_NAME"];
$config = app('config');
$config->set('template', $template);
}
}
2. Create TemplateServiceProvider in app\Providers folder and set code:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\View\FileViewFinder;
use Illuminate\View\ViewServiceProvider;
class TemplateServiceProvider extends ViewServiceProvider {
public function registerViewFinder() {
$this->app->bind('view.finder', function ($app) {
$template = $app['config']['template'];
if(file_Exists(realpath(base_path('themes/'.$template.'/views')))){
$paths = [realpath(base_path('themes/'.$template.'/views'))];
}else{
$paths = $app['config']['view.paths'];
}
return new FileViewFinder($app['files'], $paths);
});
}
}
3. Set providers in config/app.php :
App\Providers\ConfigServiceProvider::class,
App\Providers\TemplateServiceProvider::class,
4. Create your template forders > themes/{your_domain_name}/views