Laravel Package development: Facade alias not found - laravel-7

I try to create an alias for a facade in a Laravel 7 package.
On testing I get the message:
Error: Class 'MemberRequest' not found
Test:
/** #test */
public function a_member_request_can_be_created()
{
$this->assertDatabaseMissing('member_requests', ['created_at' => Date::now()]);
\MemberRequest::create(new CreateMemberRequestRequest(['email_address' => $this->email_address]));
$this->assertDatabaseHas('member_requests', ['created_at' => Date::now()]);
}
I did the following steps:
create a facade (extending the facade class from Laravel Illuminate
Register it in the service provider
add the alias to the config file
add the alias to the composer.json file
Create a Facade:
namespace martijn\UMS\Repositories\Facades;
use Illuminate\Support\Facades\Facade;
class MemberRequestRepositoryFacade extends Facade
{
public static function getFacadeAccessor()
{
return 'MemberRequest';
}
}
Register in serviceProvider:
namespace martijn\UMS\Providers;
use Illuminate\Support\ServiceProvider;
use martijn\UMS\Repositories\MemberRequestRepository;
class UMSBaseServiceProvider extends ServiceProvider
{
public function register()
{
$this->registerFacades();
}
private function registerFacades()
{
// Facades
$this->app->singleton('MemberRequest', function () {
return new MemberRequestRepository();
});
}
}
Add it to a config file:
return [
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
'aliases' => [
'MemberRequest' => \martijn\UMS\Repositories\Facades\MemberRequestRepositoryFacade::class,
]
];
Add it to composer.json:
"aliases": {
"MemberRequest": "martijn\\UMS\\Repositories\\Facades\\MemberRequestRepositoryFacade"
}

I found out that it is done in the boot loader of the service provider like this:
https://laracasts.com/discuss/channels/laravel/dynamic-class-aliases-in-package
In my example it was:
$loader = AliasLoader::getInstance();
$loader->alias('MemberRequest', \martijn\UMS\Repositories\Facades\MemberRequestRepositoryFacade::class);

In your ServiceProvider, try like this:
$this->app->singleton('MemberRequest', function () {
return new MemberRequestRepository;
});

Related

how to make laravel export excel without model

i have already read laravel-export excel. but my project is different, where my project didn't have model. how to make export excel in laravel without make model? laravel8 and maatwebsite3
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromCollection;
class ExportExcel implements FromCollection
{
/**
* #return \Illuminate\Support\Collection
*/
public function collection()
{
//
}
}
what should I type in export controller, exportexcel and the download button
You could always import using DB facade.
public function collection(Collection $rows)
{
foreach ($rows as $row)
{
DB::table('users')->insert([
'email' => $row[0],
]);
}
}
Alternatively you would always create empty shell models, to do insertions. I often do this, if i have to cleanup wordpress data and want the Laravel facades for ease of use.
use Illuminate\Database\Eloquent\Model;
class User extends Model {
protected $fillable = ['name'];
}
Which would enable the following from the documentation to work.
public function model(array $row)
{
return new User([
'name' => $row[0],
]);
}

$this->request->isAJAX() undefined method in codeigniter 4.1.1 where is the problem?

I'm having a problem with my controller, when I try to call request->isAJAX() the program returns the error undefined method
Note : i'm using codeigniter 4.1.1
<?php
namespace App\Controllers;
use App\Models\Mruang;
class Ruang extends BaseController
{
protected $jenis;
public function __construct()
{
$this->jenis = new Mruang();
}
public function index()
{
$data = [
'titel' => 'Jenis Ruang'
];
return view('ruang/index', $data);
}
public function tampil()
{
if ($this->request->isAJAX()) {
$data = [
'ruang' => $this->jenis->findAll(),
'btn' => true
];
$msg = [
'data' => view('ruang/data', $data)
];
echo json_encode($msg);
}
}
}
I run your code at my local machine in a CI 4.1.1 installation and it runs ok, at least the $this->request->isAJAX() worked as expected.
Look at your BaseController and compare it with the default. I pasting the default code bellow
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;
class BaseController extends Controller
{
protected $helpers = [];
public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
{
// Do Not Edit This Line
parent::initController($request, $response, $logger);
}
}
I also would like to recommend you to look if Mruang model has the findAll() methods.

How can I pass parameter in the laravel excel?

I get tutorial from here : https://laravel-excel.maatwebsite.nl/docs/3.0/export/basics
<?php
...
use App\Exports\ItemsDetailsExport;
class ItemController extends Controller
{
...
public function exportToExcel(ItemsDetailsExport $exporter, $id)
{
//dd($id); I get the result
return $exporter->download('Summary Detail.xlsx');
}
}
My export like this :
<?php
namespace App\Exports;
use App\Repositories\Backend\ItemDetailRepository;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\Exportable;
use Illuminate\Support\Facades\Input;
class ItemsDetailsExport implements FromCollection
{
use Exportable;
protected $itemDetailRepository;
public function __construct(ItemDetailRepository $itemDetailRepository)
{
$this->itemDetailRepository = $itemDetailRepository;
}
public function collection()
{
$test = Input::get('id');
dd('yeah', $test);
}
}
I want to pass id parameter to export file. I try like that, but I don't get the id. The id is null
How can I solve this problem?
For passing data from controller to laravel excel function we can pass and use data like below
For example, we have to pass data year like 2019 we will pass like below
in controller
Excel::download(new UsersExport(2019), 'users.xlsx');
In laravel import file
class UsersExport implements FromCollection {
private $year;
public function __construct(int $year)
{
$this->year = $year;
}
public function collection()
{
return Users::whereYear('created_at', $this->year)->get();
}
}
you can refer all following official documentation link
https://docs.laravel-excel.com/3.1/architecture/objects.html#plain-old-php-object
Unfortunately you can't use normal dependency injection when you have a specific parameter. This is what you can do though:
class ItemsDetailsExport implements FromCollection
{
use Exportable;
protected $itemDetailRepository;
protected $id;
public function __construct(ItemDetailRepository $itemDetailRepository, $id)
{
$this->itemDetailRepository = $itemDetailRepository;
$this->id = $id;
}
public function collection()
{
$test = $this->id;
dd('yeah', $test);
}
}
Now the problem is that the container doesn't know how to resolve $id however there are two ways around this.
Manual passing of $id:
public function exportToExcel($id)
{
$exporter = app()->makeWith(ItemsDetailsExport::class, compact('id'));
return $exporter->download('Summary Detail.xlsx');
}
Route injection:
Define your route as:
Route::get('/path/to/export/{itemExport}', 'ItemController#exportToExcel');
In your RouteServiceProvider.php:
public function boot() {
parent::boot();
//Bindings
Route::bind('itemExport', function ($id) { //itemExport must match the {itemExport} name in the route definition
return app()->makeWith(ItemsDetailsExport::class, compact('id'));
});
}
Then your route method is simplified as:
public function exportToExcel(ItemsDetailsExport $itemExport)
{
//It will be injected based on the parameter you pass to the route
return $itemExport->download('Summary Detail.xlsx');
}

Access class inside function

I have a ready() function which contain an es6 class.
I would like to instantiate this class outside the function, however I didn't succeed in making this working.
I don't want to use return function because the function can have more than one class.
Here is an example of what i want to do :
function ready(api) {
class A extends api.C {
contructor() {
this.foo = "bar";
}
}
class B extends A {
contructor() {
this.bar = "foo";
}
}
}
let classA = ready.A; // Here is the problem : I would like to access to the class prototype
The reason is my application have some plugins using remi npm package, and I want to export classes shared between all plugins.
I don't know if it's possible, anybody have an idea ?
[EDIT] :
First thanks all for your hep, In fact I need to be more accurate in my issue.
That's true, I can return back both classes through a classic return. But let me explain what I want to do exactly :
I have a core application which have some plugins. Plugins can be internally integrated to core, or through a classic NPM install. As explained above I use remi plugin loader.
The desired rules are the following : Each plugin get a core API access through a callback. Each plugin can expose classes to be used in other plugins. Each plugins can have inheritance for those exposed (ie exported) plugins.
Here is how I describe a plugin :
/**
* This class is a sample plugin
* #class
*/
class Sample {
constructor(api) {
this.api = api;
}
/**
* Shows a test log
*/
test() {
console.log("======> I'm working !");
}
}
function loaded(api) {
let s = new Sample(api);
}
module.exports = (api, options) => {
};
module.exports.attributes = {
loadedCallback: loaded,
name: "sample-plugin",
version: "0.0.0",
category: "misc",
description: "I'm a sample plugin",
classes: [Sample]
};
The core plugin manager will load the first time all plugins, and will register into an array all classes protoypes exported into the classes attributes property.
Then the loaded(api) function is called and classes can be instantiated through api.classes object.
In another plugin, I can do this :
function loaded(api) {
let sample = new api.classes.Sample(api);
}
And I can instantiate a class described in another plugin.
That's the idea.
However I would like to do a more complex API usage with the multiple inheritance, for example :
Plugin A exposes class A
Plugin B exposes class B extends A
Plugin C exposes class C extends B
To be more clear, I would like to export globally some classes, to get a shared access between NPM modules
You can return class A from ready function, so after calling ready you can access A class
function ready(api) {
class A extends api.C {
contructor() {
this.foo = "bar";
}
}
class B extends A {
contructor() {
this.bar = "foo";
}
}
return {A : A};
}
let classA = ready(api).A;

Create ViewHelper in Symfony 2

How to create a ViewHelper in Symfony 2. I read whole the documentation but it doesn't describe any term like that. It just has autoloading and service.
http://symfony.com/doc/current/cookbook/index.html
You just have to create a class that implements your helper function and extends
Symfony\Component\Templating\Helper\Helper
like this:
namespace Acme\Foo\Helper;
use Symfony\Component\Templating\Helper\Helper;
class MyViewHelper extends Helper {
public function helpMe() {
// do something
return $value;
}
/**
* #inheritdoc
*/
public function getName() {
return "anyCanonicalServiceName";
}
}
Then you have to promote your helper as a service with a special tag in e.g.
Resources/config/services.yml
services:
your_service_name:
class: Acme\Foo\Helper\MyViewHelper
# the tag alias "myViewHelper" is later used in the view to access your service
tags:
- { name: templating.helper, alias: myViewHelper }
Now you can access the helper in a view like this:
echo $view['myViewHelper']->helpMe();

Resources