In CakePHP3.6, how to call function of another controller into other controller? - cakephp-3.0

I am using CakePHP3.6 for my project. I have created following function in Options controller:
public function getValue($id = null){
$options=$this->Options->find()->where(['id'=>$id])->first();
return $options->value;
}
then I am calling this function into function of another controller(any xyz controller) as follow:
$r = $this->Options->getValue(1);
Now I am getting error 'Unknown method "getValue"'.
Same Procedure I followed for CakePHP3.2, it worked well. So Please help me, How to call function of another controller into function of other controller for CakePHP3.6?

You should never be calling a function from one controller in another, and I doubt very much that this worked as shown in 3.2. This function looks very much like it should be in the OptionsTable, not OptionsController. The only change you'd need to make is inside the function body, it will just be $this->find(), not $this->Options->find().

class FirstController extends AppController
{
public function getValue($id = null){
$options=$this->Options->find()->where(['id'=>$id])->first();
return $options->value;
}
}
class SecondController extends AppController
{
public function anotherAction($id = null){
$anotherController = new \App\Controller\FirstController(); 
$r = $anotherController->getValue($id) ;   
}
}

Related

Yii2 Basic calling a function from another file into controller

I create a file in yii2 "actions", and I create a class name actionC
is it possible to call function from
actions/actionC
inside a controller
my calss is
<?php
namespace app\actions;
class ActionC
{
protected function CPost(){
// return something
}
}
is it possible to call my function CPost() inside a controller actionView ?
Hello while your function is protected you can not call it, if you want to call a function of your class it has to be public it would be something like that
Class actionC
<?php
namespace app\actions;
class ActionC
{
protected function CPost()
{
// return something
}
public function BPost()
{
// return something
}
}
And in you View
<?php
$a=new \app\actions\ActionC();
$a->BPost();
//$a->CPost(); //this will be error because is protected

Flex actionscript, get data from AsyncToken call

I have Flex/Java project with blazeDS. Now I have an actionscript file that call a method of another actionscript that call the remoteObject (java class who make a simple select on db)
Here's the code:
Home.as
..
private var _dm:DataManager = new DataManager;
public function getPerson():void { // this is connect to a button in .mxml
_dm.getPerson();
}
..
DataManager.as
public class DataManager {
private var _service:RemoteObject;
private var _url:URLRequest;
private var loCs:ChannelSet = new ChannelSet();
public function DataManager () {
_service = new RemoteObject("PeopleDAO");
loCs.addChannel(new AMFChannel("canale", "http://localhost:8080/FlexTRYOUT/messagebroker/amf"));
_service.channelSet = loCs;
}
private function onFault(event:FaultEvent,token:Object):void {
var _fail:String = "fault";
}
private function onResult(event:ResultEvent,token:Object):void {
per = event.result as People; // is a bean class
Alert.show(per.nome);
}
public function getPerson():void {
var token:AsyncToken = _service.getPersona();
token.addResponder(new AsyncResponder(onResult,onFault));
}
}
The call works fine, it calls java method names getPerson() of the DataManger.java class. It return simply one object with name and surname (it's just a hello world to understand this damned AsyncCall). The problem is that I don't know how send this result to Home.as with a classic (java) return type. I have the result in onResult method and I don't know how to get it.
I try to follow Brian instructions and I just waste my time. Maybe because I'm not a flex actionscript programmer but I added the code Brian posted and:
public function getPerson():void { // this is connect to a button in .mxml
_dm.addEventListener(DATA_RECEIVED, onPersonFound); * compile error 1
_dm.getPerson();
}
error is DATA_RECEIVED is undefined
than in DataManager:
public class DataManager {
public static const DATA_RECEIVED:String = "DATA_RECEIVED";
...
private function onResult(event:ResultEvent,token:Object):void {
per = event.result as People; // is a bean class
dispatchEvent(new DataReceivedEvent(DATA_RECEIVED, per)); * compile error 2
}
}
error 2 is call of possible undefined method dispatchEvent
Where is the mistake? Please guys write the complete code because I'm on flex - actionscript - blazeds from two days and I have a few time to try solution. Thanks
OK, Sorry for all this post, I just create new one (but more elaborated and clear) with the same question. Step by Step I'm studing this language and I manage to implement the Brian code but DataManager.as class must extend EventDispatcher, if I don't extend this I have the compile error I posted. At moment I mangage to obtain the resultEvent data in the method defined in the addEventListener call (onPeopleFound in this case). Thanks a lot Brian I think I surely need your help again in future (at least until acceptance of the project). Bye
You can adjust method getPerson to have two parameters referencing the callback functions.
public function getPerson(onResultCallback:Function, onFaultCallback:Function):void {
var token:AsyncToken = _service.getPersona();
token.addResponder(new AsyncResponder(onResultCallback,onFaultCallback));
}
This way you can receive data in an instance of the class you need.
One option is to dispatch an event when you get the data back from the Java call:
Home.as
...
public function getPerson():void { // this is connect to a button in .mxml
_dm.addEventListener(DATA_RECEIVED, onPersonFound);
_dm.getPerson();
}
private function onPersonFound(dataEvent:DataReceivedEvent):void {
var person:People = dataEvent.people;
//Do important processing...
}
...
In DataManager.as
public class DataManager {
public static const DATA_RECEIVED:String = "DATA_RECEIVED";
...
private function onResult(event:ResultEvent,token:Object):void {
per = event.result as People; // is a bean class
dispatchEvent(new DataReceivedEvent(DATA_RECEIVED, per));
}
}
And DataReceivedEvent.as will look like the answer to How to dispatch an event with added data - AS3
public class DataReceivedEvent extends Event
{
public static const DATA_RECEIVED:String = "DATA_RECEIVED";
// this is the object you want to pass through your event.
public var result:Object;
public function DataReceivedEvent(type:String, result:Object, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
this.result = result;
}
// always create a clone() method for events in case you want to redispatch them.
public override function clone():Event
{
return new DataReceivedEvent(type, result, bubbles, cancelable);
}
}

public function access fail

I have this situation where I declare inside my main class a function that looks like this:
public class Main extends MovieClip
{
public static var instance:Main;
public function Main()
{
// constructor code
welcomeScreen();
instance = this;
}
public final function welcomeScreen():void
{
//some code in here
}
public final function startLevelOne():void
{
//some other code here
}
}
In some other class I use this statement to fire a reset:
restart.addEventListener('click', function() {
Main.instance.welcomeScreen();
});
Somehow in another class I try to use the same statement for 'startLevelOne' but it seems it is not working and gives the fallowing error:
1195: Attempted access of inaccessible method startLevelOne through a reference with static type Main.
Any ideas?
UPDATE #1
The class where I try to access the function is in full this one:
public class LevelBrief extends MovieClip
{
public function LevelBrief()
{
// constructor code
startBut.addEventListener('click', function() {
Main.instance.startLevelOne();
});
}
}
UPDATE #2
I have pasted the full code of the main definition here http://pastebin.com/s6hGv7sT
Also the other class could be found here http://pastebin.com/s6h3Pwbp
UPDATE #3
Even though the problem was solved with a workaround, I still cannot understand where was the problem.
I would recommend to leave the static instance (singleton), and work event-based. Now you make all functions public, which is not desirable. It's not that hard to use custom events. See this is how your Main class could look:
public class Main extends MovieClip
{
public function Main()
{
this.addEventListener(Event.ADDED_TO_STAGE, handleAddedToStage);
}
public function handleAddedToStage(event:Event)
{
this.removeEventListener(Event.ADDED_TO_STAGE, handleAddedToStage);
this.showWelcomeScreen();
stage.addEventListener(ScreenEvent.SHOW_WELCOME_SCREEN, handleScreenEvent);
stage.addEventListener(ScreenEvent.SHOW_LEVEL, handleScreenEvent);
}
private function handleScreenEvent(event:ScreenEvent):void
{
switch (event.type)
{
case ScreenEvent.SHOW_WELCOME_SCREEN:
{
this.showWelcomeScreen()
break;
}
case ScreenEvent.SHOW_LEVEL:
{
// event.data contains level number
this.startLevel(event.data);
break;
}
default:
{
trace("Main.handleScreenEvent :: Cannot find event.type '" + event.type + "'.");
break;
}
}
}
private function showWelcomeScreen():void
{
trace("show WelcomeScreen")
//some private code in here
}
private function startLevel(level:int):void
{
trace("start level: " + level)
//some other private code here
}
}
This is how the custom event class should look (ScreenEvent.as). Note it has an optional parameter called data. You can pass any value (objects, numbers, strings etc) into this. To the example as clear as possible, I used one event-class for both actions, you can also choose to make more specific custom events for other actions with more detailed parameters, you would have names like ScreenEvent, LevelEvent, PlayerEvent, GameEvent etc etc..
At the top of the class the (static constant) types are defined. An event should only have getters.
package
{
import flash.events.Event;
public class ScreenEvent extends Event
{
public static const SHOW_WELCOME_SCREEN:String = "ScreenEvent.showWelcomeScreen";
// event.data contains level number
public static const SHOW_LEVEL:String = "ScreenEvent.showLevel";
private var _data:String;
public function ScreenEvent(type:String, data:String):void
{
super(type);
this._data = data;
}
public function get data():String
{
return this._data;
}
override public function clone():Event
{
return new ScreenEvent(this.type, this._data);
}
}
}
.. Anywhere in your code you can dispatch the event to the stage.
// dispatch event to Main (stage). Should show welcome screen in our case
stage.dispatchEvent(new ScreenEvent(ScreenEvent.SHOW_WELCOME_SCREEN));
// show level 2
stage.dispatchEvent(new ScreenEvent(ScreenEvent.SHOW_LEVEL, 2));
I know, its a bit more code, it looks more difficult at first but if the project grows, it will help a lot. The difference with events is 'this could happen, and when it happens, do this' instead of 'do this here, do that over there'
The advantage is that if you remove the event listener in the Main class, nothing will break (loosely coupled). This makes it easier to maintain, it saves a singleton, and you have the ability to extend the Main class if you want to.
I think you wrote
Main.startLevelOne();
instead of
Main.instance.startLevelOne();
Hmm. Given your code, there is only one serious question - what is PerwollGame? You have there public static var instance:PerwollGame; and you assign it an object of type Main. Perhaps that PerwollGame has a startLevelOne() function with a different signature, that obscures your function in the Main class. Also, the other people who answered you are right as well, you should never use nested functions in your code, really put that listener of yours out from inline declaration.
Judging from your coding style and the error reported, I would assume you did this.
public static function startLevelOne():void
There is a fine line between static methods and instantiated objects.
Also never use nested functions
public class LevelBrief extends MovieClip
{
public function LevelBrief()
{
// constructor code
startBut.addEventListener('click', onMyClick )
}
public functiononMyClick (e:Event) {
Main.instance.startLevelOne();
});
}
}
I assume that when you register the listener Main.instance is not already assigned.
Did you try to trace Main instance here?
public function LevelBrief()
{
// constructor code
startBut.addEventListener('click', function() {
Main.instance.startLevelOne();
});
trace(Main.instance); // I assume Main.instance is null
}
what about if you add the listener in another method in LevelBrief like :
public function registerListeners():void{
trace("Main.instance == null? -> " + (Main.instance == null)); //not null here if called later.
startBut.addEventListener('click', function() {
Main.instance.startLevelOne();
});
}

Calling a function from within that class - php

I have a function called wsGO() inside a class ceff(). I want to be able to run that function from within the class ceff. I used this code:
class ceff{
$ceff_instance = new ceff($this);
$ceff_instance = wsGO();
public function wsGO(){
....
}
}
However this didn't work. Any ideas?
In PHP you can only initialize a property with a constant - NOT functions or constructor calls. You can though do that in a constructor, such as:
class ceff{
public $ceff_instance;
public function __construct() {
$this->ceff_instance = $this->wsGO();
}
public function wsGO(){
....
}
}

Overriding function from another class

I am defining this function in one of my classes:
public function onUse():void {};
Then in another of my classes (let's call it "class2"), I create a object of this class, and then want to override this function with another one. After some Google-Fu, I have found this, and used it...
button.onUse {
variable = value;
}
...but it executes instantly, and not when onUse() is called - which seems to be an empty function, always.
I didn't find anything more than that - I tried a few things myself, like specifying a function inside class2 and using button.onUse = function();, but it always throws errors.
Can anyone tell me whether what I am trying to do is actually possible, and if it is, how can I do it?
You can only override functions when you are extending the class:
public class A {
public function foo():void {
doStuff();
}
}
public class B extends A {
override public function foo():void {
doOtherStuff();
}
}
var n:A = new A();
n.foo(); // => calls doStuff();
var o:B = new B();
o.foo(); // => calls doOtherStuff();
Hence, assigning a different function to a class method of an instance is not possible at runtime.
You can, however, let your original class contain a field of type Function, and then simply assign a different closure to it.
public class A {
public var foo:Function;
}
var n:A = new A();
n.foo = function ():void {
doStuff();
};
n.foo(); // => calls doStuff();
var o:A = new A();
o.foo = function ():void {
doOtherStuff();
}
o.foo(); // => calls doOtherStuff();
check the syntax of
button.onUse {
variable = value;
}
a function would be defined as
public function onUse():void {};
and overwritten with
override public function onUse():void {
}
in a different class
the way you're trying to do it, does not constitute overriding a function.
What I've done in similar circumstances is create a onClickFunction function in the class
public var onClickFunction:Function = null;
and then in the CLICK event listener function add
if(onClickFunction != null){
onClickFunction();
}
then you can assign your on-click functionality by doing something like this
button.onClickFunction = function():void{
variable = value;
// dostuff
}
this is not the best way of doing it, but probably the easiest way of implementing the functionality. And ideally you'd use inheritance the way the spacepirate suggested.