Extend Yii2's BaseYii class to add static methods - yii

Is it possible to extend Yii2's BaseYii class, so I could add a static method similar to Yii::t() like this: Yii::my_super_method()?
Can't really find any documentation about that, maybe I missed it.

This is possible by creating own Yii class (for example in root of your project):
require __DIR__ . '/vendor/yiisoft/yii2/BaseYii.php';
class Yii extends \yii\BaseYii
{
public static function my_super_method() {
// ...
}
}
spl_autoload_register(['Yii', 'autoload'], true, true);
Yii::$classMap = require __DIR__ . '/vendor/yiisoft/yii2/classes.php';
Yii::$container = new yii\di\Container();
And loading it in index.php instead core class, by replacing:
require __DIR__ . '/../vendor/yiisoft/yii2/Yii.php';
with
require __DIR__ . '/../Yii.php';
But if you want only to add a new method you should probably not do this. Overriding core classes in this way is possible, but this is ugly hack and should be avoided whenever possible. It is better to create own helper with this method than to hacking core classes.

Yes it's possible to extend BaseYii class. show below
namespace app\models;
class ClassName extends \yii\BaseYii
{
public static function my_super_method()
{
......
Here your code
........
}
}
Now access your method like
app\models\ClassName::my_super_method();
Now access t() method
app\models\ClassName::t();

Related

How to extend classes and controllers in PrestaShop 1.7?

I want to extend some core classes and controllers via a module but I don't know how. I can do it with overrides but according to the developers this isn't a good way:
The legacy architecture can still be overridden, though. But in
general, we advise against overriding code. It is better to extend it.
But how can I extend it? Is there any code example?
Best regards
In prestashop docs you can see the override.
Put ur class in /modules/my_module/override/classes
or controller /modules/my_module/override/controllers/{front or admin}
I use it on my modules.
An example of my module, overriding a frontcontroller function:
<?php
class FrontController extends FrontControllerCore
{
protected function smartyOutputContent($content)
{
if (version_compare(_PS_VERSION_, '1.7', '<')) {
//do something
} else {
parent::smartyOutputContent($content);
}
}
}

Symfony - Create Service object with parameters

I created a new service in my symfony application:
namespace AppBundle\Service;
class CustomService {
public function __construct($username, $password) {
// stuff
}
public function getItems() {
}
}
and configured in config.yml:
services:
custom_service:
class: AppBundle\Service\CustomService
My question is, how to create an object from this service with multiple arguments?
Like:
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
class CustomController extends Controller {
public function listAction() {
$custom_service = $this->get('custom_service'); //how to pass multiple arguments here?
// Next i would use my custom service, like:
$items = $custom_service->getItems();
}
}
Anybody knows how to solve this issue?
Thanks and Greetings!
Basically you don't. The container supports injecting dependencies. Doing what you propose kind of defeats the purpose of using a dependency injection container.
One work around is to add an init method to your object.
$custom_service = $this->get('custom_service')->init($additional_arguments);

How to define constructor ?Where?

How to define constructor in Yii application?
Where ?to define the constructors?
I need to create constructors. Where it defines inside model or controller.
Can you guys give some example of formats ?
In a lot of Yii classes there are 2 methods that can be used to define initialization code : __construct() and init():
__construct() is a native php method to instantiate the object.
init() is called when Yii has performed it's own instantiation of the class (for example in a CActiveRecord class Yii has set the scenario name)
it's up to you to use
public function __construct()
{
//Your code
return parent::contruct()
}
or just to use the init method
public function init()
{
//Your code
}
if you use construct be carefull because some classes constructors have some params that you'll also have to set (for example CActiveRecord take the scenario name as a param)
If I were you I'll use the init method as often as possible.

Is there anyway to get the class name that an instance is injected into (using ninject)?

I'm injecting my dependencies into my classes fine, but I'm wondering if it's possible to get the class name I'm injecting into?
For example:
Bind<ISomething>.ToMethod(c => new Something([GIVE INJECTING *TO* CLASS NAME]));
So, if I had:
public class Blah{
public Blah(ISomething something) { /**/ }
}
When injecting Ninject would in effect call:
new Blah(new Something("Blah"));
Can this be done?
Yes, it can be done. You use the IContext you're given in the ToMethod method to get the name of the type you're being injected into like this:
Bind<ISomething>().ToMethod(c => new Something(GetParentTypeName(c)));
Which uses this little helper method (which could also be turned into a nice extension method):
private string GetParentTypeName(IContext context)
{
return context.Request.ParentRequest.ParentRequest.Target.Member.DeclaringType.Name;
}
It has probably changed in later versions of Ninject. As for version v3.2.0 the accepted solution didn't work for me.
The following does though:
Bind<ISomething>().ToMethod((ctx)
=> new Something(ctx.Request.Target?.Member?.DeclaringType?.Name ?? ""));

Base class for common YII functions?

I know how to create a class the will allow me to instantiate it and use across my project. What I want to be able to do is have functions without instantiating classes. For example, I know how to do this:
$core = new core();
$val = $core->convertToMyNotation($anotherval);
But what I want is to be able to do this ANYWHERE in any view, class whatever:
$val = convertToMyNotation($anotherval);
Where would I place these functions in order to be able to do that?
best way to do it, create a public function in components/Controller.php
public function globalFunction(){
// do something here.
}
and access it anywhere by
$this->globalFunction();
You can define a static method as an option.
class core{
public static function convertToMyNotation($value){
//do whatever here
return $value;
}
}
Then call it like so:
$val = core::convertToMyNotation($anotherval);
This requires no instantiation of the object to use. The only restriction is that you cannot use the $this property inside a static method.
Alternately, just define a file with your functions in it and include the file at some point early like, like within the boostrap script in your public_html/index.php file.
Edit: darkheir makes some good suggestions. Include such a class in your protected/components folder, and have it extend CComponent to gain some potentially useful enhancements.
By including the class in the protected/components folder, you gain the advantage of autoloading the class, by default.
There is no definitive question of your answer, it depends a lot on what the function will be doing!
If the function is performing some things specific to a model
(getting the last users, ...) this has to be in the User model as
Willem Renzema described:
class theModelClass {
public static function convertToMyNotation($value){
//do whatever here
return $value;
}
}
And you'll call it like
$val = theModelClass::convertToMyNotation($anotherval);
If the function is handling user inputs (sanitizing he inputs,
checking the values, ...) then it has to go to the controller and
you'll use Hemc solution:
Create a public function in components/Controller.php
public function globalFunction(){
// do something here.
}
and access it anywhere by
$this->globalFunction();
If the function is an Helper: performing some actions that do not
depend on models or user inoput then you can create a new class that
you'll put in your component directory:
class core extends CComponent{
public static function convertToMyNotation($value){
//do whatever here
return $value;
}
}
And
$val = core::convertToMyNotation($anotherval);
Actually, I think you're looking for this answer instead:
http://www.yiiframework.com/wiki/31/use-shortcut-functions-to-reduce-typing/
In essence, in your entry script, before you load up Yii, include a global functions file:
require('path/to/globals.php');
Then, any function defined in that file can be used as a shortcut. Be careful, but enjoy the power! :-)
Create something like
Class Core extends CApplicationComponent{
public function doSomething(){}
}
and in config main.php
'components'=>array(
'core'=>array(
'class' => 'Core'
),
),
and now you can call whenever you want
Yii::app()->core->doSomething();