Moving class binds global helper functions to namespace? - laravel

I have a class like this:
namespace App\Bills;
class Addition
{
public function get()
{
return collect();
}
}
Where collect is actually a global helper function. When I rightclick on the classname and click "Move class" and change Namespace to App\Models\Invoice this happens:
namespace App\Models\Invoice;
use function App\Bills\collect;
class Addition
{
public function get()
{
return collect();
}
}
Which breaks my code with
Error: Call to undefined function App\Bills\collect()
because the method collect() is actually a global Laravel helper.
How can I tell PHPSTORM not to escape global functions?

Related

Laravel eloquent: How does relation inherit functions from query builder?

how do they achieve, that Illuminate\Database\Eloquent\Relations\Relation has access to all query builder functions?
I see they have a $query property, but does not explain how all its methods are available inside relation
If you are aware of php magic methods then you will know __call method
this method will be called when you initialize a php object and you try to call a method which is not available in the class. By using __call method from the Illuminate\Database\Eloquent\Relations\Relation class they are forwarding the call to Illuminate\Database\Eloquent\Builder. I will explain it very clearly by pointing out the code.
Inside the laravel framework there is a trait named as ForwardsCalls . This trait is used in many classes to handle the call forwarding to another class.
So here is how the call from the Relation class is forwarded to Builder class. While initilting the new Relation class Builder class will be initialized. So when you try to call a method from reltion class which is not available it will call __call method. After that it will look for a available macros . So when a macros method is not found. Then it will use forwardDecoratedCallTo from ForwardsCalls Trait.
So forwardDecoratedCallTo will accept 3 arguments namely $object, $method and $parameters. Whereas
$object will be $this->query which has a Illuminate\Database\Eloquent\Builder instance.
$method will be the method the you try to access from Builder Method.
$parameters will be the all the parameters that is be passed to the method.
I will try to Demonstrate will the example without the traits and helpers from laravel
class ClassTwo {
public function classTwoMethodOne()
{
dd(__FUNCTION__.' has been called');
}
public function classTwoMethodTwo()
{
dd(__FUNCTION__.' has been called');
}
public function classTwoMethodThree()
{
//you cannot call this method dynamically
dd(__FUNCTION__.' has been called');
}
}
class ClassOne {
public function classOneMethodOne()
{
dd(__FUNCTION__.' has been called');
}
public function classOneMethodTwo()
{
dd(__FUNCTION__.' has been called');
}
public function __call($methodName, $arguments)
{
$methodsTobeForwarededtoClassTwo = [
'classTwoMethodOne',
'classTwoMethodTwo',
// 'classTwoMethodThree'
//i have commented this method so you cannot access it
//from dynamic calls
];
if(in_array($methodName,$methodsTobeForwarededtoClassTwo))
{
return (new ClassTwo)->{$methodName}($arguments);
}
dd(sprintf(
'Call to undefined method ClassTwo::%s()', $methodName
));
}
}
So here comes the testing part.
$classOneobj = new ClassOne;
Basic Test
dump($classOneobj->classOneMethodOne()); will output as classOneMethodOne has been called
dump($classOneobj->classOneMethodTwo()); will output as classOneMethodTwo has been called
Dynamic Call Test
dump($classOneobj->classTwoMethodOne()); will output as classTwoMethodOne has been called
dump($classOneobj->classTwoMethodTwo()); will output as classOneMethodTwo has been called
dump($classOneobj->classTwoMethodThree()); will output as Call to undefined method ClassTwo::classTwoMethodThree() Because i have commented that method in __call function in ClassOne.
If you still need clarity please post a comment

How to call block function in other custom module's model file?

I am working on Magento 2. I want to use other module's block function to get some data. How can I call that block function in my module's model file ?
The two ways to call you a block class method in custom module class
1) using constructor dependency
like that
public function __construct(Namespace\ModuleName\Helper\Data $helper)
{
$this->helper = $helper;
}
public function MyFunction()
{ $this->helper->HelperDemo();
}
2) using method dependency
public function execute(Namespace\ModuleName\Helper\Data $helper)
{
$helper->HelperDemo();
}
for more detail visit the below link
https://devdocs.magento.com/guides/v2.3/extension-dev-guide/depend-inj.html

Cannot declare class App\Http\SeoInit\SeoInit, because the name is already in use

I am creating a helper function its show this error
Cannot declare class App\Http\SeoInit\SeoInit, because the name is
already in use.
Here is code
namespace App\Http\SeoInit;
class SeoInit
{
public static function Funct_Name()
{
//
}
}
Thanks.
How to define a helper function into app.php aliases, The function is available in app->http Folder

Lumen: Call trait helper file from model file not working

I am using my trait file "CommonTrait" inside my model file as below,
use in namespace,
use App\Http\Helpers\CommonTrait;
use inside class,
class LoginHistory extends Model
{
use CommonTrait;
//use inside function as
protected static function getList($req)
{
$reportFilter= $this->searchCommonFilter($reportDateFilter, $req);
//this is my trait function
}
}
but it gives me error like
Using $this when not in object context
you are accessing a method from a static function, that's what the error message means, you can call other static functions/properties using static::function() or static::property.
In your case the function does not seems to be static, you need to either remove the static declaration from the fuinction or make the function which you are calling to a static one.

How to override a single function in a package for internal use with laravel?

I would like to override a function in vendor/laravel/framework/src/Illuminate/View/Compilers/BladeCompiler.php
or to be precise a function iside the trait Illuminate\View\Compilers\Concerns\CompilesEchos.php used by that file. However I could not find very clear information on how to override packages. Could someone please help me understand how.
I understand that I need to extend BladeCompiler
Let's call it MyBladeCompiler
class MyBladeCompiler extends BladeCompiler
{
public function compileEchoDefaults($value)
{
return 'test';
return preg_replace('/^(?=\$)(.+?)(?:\s+or\s+)(.+?)$/si', 'isset($1) ? $1 : $2', $value);
}
}
I now would like to register it as the new class to be used. I do understand this should be done in a serviceprovider, but how?
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
$this->app->bind(BladeCompiler::class, MyBladeCompiler ::class);
}
}
this does not work
Create a new service provider called ViewServiceProvider, then in it, delete the register and boot methods, and make it extend Illuminate\View\ViewServiceProvider.
Then, add this method:
public function registerBladeEngine($resolver)
{
// The Compiler engine requires an instance of the CompilerInterface, which in
// this case will be the Blade compiler, so we'll first create the compiler
// instance to pass into the engine so it can compile the views properly.
$this->app->singleton('blade.compiler', function () {
return new MyBladeCompiler(
$this->app['files'], $this->app['config']['view.compiled']
);
});
$resolver->register('blade', function () {
return new CompilerEngine($this->app['blade.compiler']);
});
}
Note how in the singleton method, I'm using your blade compiler class.
Then, open config/app.php, and replace the \Illuminate\View\BladeServiceProvider::class, record, with your own service provider.
So the service provider should look like this:
namespace App\Providers;
use MyBladeCompiler
use Illuminate\View\ViewServiceProvider as BaseViewServiceProvider;
class ViewServiceProvider extends BaseViewServiceProvider
{
public function registerBladeEngine($resolver)
{
$this->app->singleton('blade.compiler', function () {
return new MyBladeCompiler(
$this->app['files'], $this->app['config']['view.compiled']
);
});
$resolver->register('blade', function () {
return new CompilerEngine($this->app['blade.compiler']);
});
}
}
This works by extending the Illuminate view service provider, so all existing methods work as expected. Then, you need to override the registerBladeEngine() method so that your overridden one is called, and not the one in the illuminate provider.
In your overridden method, you're specifying that your compiler should be used instead of the original one.
You then specify that your extended view service provider is used instead of the illuminate one by editing the app.php config file.

Resources