I have a custom component that handles the application options.
For some reason, when I access the method like so:
Yii::$app->option->user('setting_name');
I get the following error:
Calling unknown method: app\models\Option::user()
Here is a partial snippet of the class:
namespace app\models;
use Yii;
use yii\base\Component;
class Option extends Component
{
public function getUser($key)
{
$options = self::getAllOptions('user');
return $options[$key];
}
public function setUser($key, $value)
{
$return = self::getAllOptions('user', true);
$model = $return['model'];
$options = $return['options'];
// update the specific option
$options[$key] = $value;
self::setAllOptions('user', $options, $model);
}
}
And here is the component registration in the application configuration:
...
'components' => [
'option' => [
'class' => 'app\models\Option',
],
],
...
Why isn't it recognizing the property using the getter and setter methods?
You should simply use :
Yii::$app->option->getUser('setting_name');
Your getUser() and setUser() functions are not getter/setter functions since a getter doesn't have any arguments, and a setter has only one argument.
Even if it was a valid getter, you simply cannot use it like this, properties defined by getters can be used like class variables, not functions !
Read more : http://www.yiiframework.com/doc-2.0/guide-concept-properties.html
Related
How to call "functionA" from "ClassA" in "functionB" inside "ClassB" ?
class Base extends BaseController
{
public function header()
{
echo view('common/header');
echo view('common/header-nav');
}
}
class Example extends BaseController
{
public function myfunction()
// how to call function header from base class
return view('internet/swiatlowod');
}
}
Well there are many ways to do this...
One such way, might be like...
Assume that example.php is the required Frontend so we will need a route to it.
In app\Config\Routes.php we need the entry
$routes->get('/example', 'Example::index');
This lets us use the URL your-site dot com/example
Now we need to decide how we want to use the functions in Base inside Example. So we could do the following...
<?php namespace App\Controllers;
class Example extends BaseController {
protected $base;
/**
* This is the main entry point for this example.
*/
public function index() {
$this->base = new Base(); // Create an instance
$this->myfunction();
}
public function myfunction() {
echo $this->base->header(); // Output from header
echo view('internet/swiatlowod'); // Output from local view
}
}
When and where you use new Base() is up to you, but you need to use before you need it (obviously).
You could do it in a constructor, you could do it in a parent class and extend it so it is common to a group of controllers.
It's up to you.
Passing different class objects into a function and getting it's properties ?
For example:
I have two different class objects :
screenA = new ScreenA();
screenB = new ScreenB();
I pass the objects in the tween:
switch (state)
{
case States.SCREEN_A:
{
Actuate.tween(screenA, 0.6, {alpha: 1} ).ease(Sine.easeIn).autoVisible (true).onComplete(onComp, [screenA]);
}
case States.SCREEN_B:
{
Actuate.tween(screenB, 0.6, {alpha: 1} ).ease(Sine.easeIn).autoVisible (true).onComplete(onComp, [screenB]);
}
}
Now i want to access a method of the passed object here, when tween completes.
Tween is passing the object but i am unable to cast it in the function to get the object methods.
private function onComp(screen:?)
{
screen.load();
}
And compiler is always asking for the type. I have tried Dynamic / Any but then it says "load method not found", If i pass the object without any type arguments in the function then it is getting it as an object but not the class object.
There're a lot of ways you could do this, but one is with a common interface:
class ScreenA implements OnTweenComplete { ... }
class ScreenB implements OnTweenComplete { ... }
interface OnTweenComplete {
public function on_tween_complete();
}
Then your function is:
private function onComp(screen:OnTweenComplete)
{
screen.on_tween_complete();
}
Or perhaps, type-check it with Std.is and cast it:
private function onComp(screen:Dynamic)
{
if (Std.is(screen, OnTweenComplete)) {
(cast screen).on_tween_complete();
}
}
In this exact example, you can use load in the onComplete callback to simplify your code:
Actuate.tween (screenA, 0.6, { alpha: 1 }).ease (Sine.easeIn).onComplete (screenA.load);
I have an mvc controller which has a helper class injected into it. I would like to convert from a viewmodel to a dto using automapper. most of the properties are simple mappings but one involves calling the helper class with a parameter from the viewmodel. Ideally I would want to do something like this:
Mapper.CreateMap<TheViewModel, TheDto>()
.ForMember(dest => dest.Url, o => o.MapFrom(src => _urlHelper.GenerateUrlFromUsername(src.Username)));
...but I cannot because I cannot access a non-static field.
What is the best approach?
EDIT:
OK, so I have a custom resolver but how do I hook this in to my IoC container?
public class CustomResolver : ValueResolver<TheViewModel, string>
{
private readonly IUrlHelper _urlHelper;
public CustomResolver(IUrlHelper urlHelper)
{
_urlHelper = urlHelper;
}
protected override string ResolveCore(TheViewModel source)
{
return _urlHelper.GenerateUrlFromUsername(source.Username);
}
}
Use a custom resolver in this case:
http://automapper.codeplex.com/wikipage?title=Custom%20Value%20Resolvers
Custom resolvers can be instantiated from a container, so you can get whatever instance fields of services you need.
I'm trying to design an application following Misko Heverys insights. It's an interesting experiment and a challenge. Currently I'm struggling with my ViewHelper implementation.
The ViewHelper decouples the model from the view. In my implementation it wraps the model and provides the API for the view to use. I'm using PHP, but I hope the implementation is readable for everyone:
class PostViewHelper {
private $postModel;
public function __construct(PostModel $postModel) {
$this->postModel = $postModel;
}
public function title() {
return $this->postModel->getTitle();
}
}
In my template (view) file this could be called like this:
<h1><?php echo $this->post->title(); ?></h1>
So far so good. The problem I have is when I want to attach a filter to the ViewHelpers. I want to have plugins that filter the output of the title() call. The method would become like this:
public function title() {
return $this->filter($this->postModel->getTitle());
}
I need to get observers in there, or an EventHandler, or whatever service (in what I see as a newable, so it needs to be passed in through the stack). How can I do this following the principles of Misko Hevery? I know how I can do this without it. I'm interested in how for I can take it and currently I don't see a solution. ViewHelper could be an injectable too, but then getting the model in there is the problem.
I didn't find the blog post you referenced very interesting or insightful.
What you are describing seems more like a Decorator than anything to do with dependency injection. Dependency injection is how you construct your object graphs, not their state once constructed.
That said, I'd suggest taking your Decorator pattern and running with it.
interface PostInterface
{
public function title();
}
class PostModel implements PostInterface
{
public function title()
{
return $this->title;
}
}
class PostViewHelper implements PostInterface
{
public function __construct(PostInterface $post)
{
$this->post = $post;
}
public function title()
{
return $this->post->title();
}
}
class PostFilter implements PostInterface
{
public function __construct(PostInterface $post)
{
$this->post = $post;
}
public function title()
{
return $this->filter($this->post->title());
}
protected function filter($str)
{
return "FILTERED:$str";
}
}
You'd simply use whatever DI framework you have to build this object graph like so:
$post = new PostFilter(new PostViewHelper($model)));
I often use this approach when building complex nested objects.
One problem you might run into is defining "too many" functions in your PostInterface. It can be a pain to have to implement these in every decorator class. I take advantage of the PHP magic functions to get around this.
interface PostInterface
{
/**
* Minimal interface. This is the accessor
* for the unique ID of this Post.
*/
public function getId();
}
class SomeDecoratedPost implements PostInterface
{
public function __construct(PostInterface $post)
{
$this->_post = $post;
}
public function getId()
{
return $this->_post->getId();
}
/**
* The following magic functions proxy all
* calls back to the decorated Post
*/
public function __call($name, $arguments)
{
return call_user_func_array(array($this->_post, $name), $arguments);
}
public function __get($name)
{
return $this->_post->get($name);
}
public function __set($name, $value)
{
$this->_post->__set($name, $value);
}
public function __isset($name)
{
return $this->_post->__isset($name);
}
public function __unset($name)
{
$this->_post->__unset($name);
}
}
With this type of decorator in use, I can selectively override whatever method I need to provide the decorated functionality. Anything I don't override is passed back to the underlying object. Multiple decorations can occur all while maintaining the interface of the underlying object.
Is there a way to pass the parameters to the LoadControl function when loading the user control dynamically?
I found a solution that uses reflection here
All you need to do is create a descendant of the UserControl class, add a default constructor and another constructor that takes your parameters. The parameterless constructor is necessary for designer support.
public class MyControl : UserControl
{
public MyControl() : base()
{
// do initialization stuff...
}
public MyControl(int parameter) : this()
{
// do additional stuff with parameter
}
}