how do i extended 3rd party classes in cakephp? - cakephp

I want to extend, not just create a new instance of a class I have sitting in my vendors directory. I googled and read the docs but I see no support for it.
Can I do an app import of the 3rd party class, then write up the extended class followed by a component that will use my child class?
i.e
/* vendors/yahooapi/yahoo.class.php */
class YahooAPI {
var $key = 'demo';
}
/* controllers/components/yahoo.php */
App::import("Vendor", "YahooAPI", array("file"=>"yahooapi.class.php"));
class Yahoov2 extends YahooAPI {
var $key = 'newKey';
function go() {}
}
YahooComponent extends Object {
function goFaster() {
$a = new Yahoov2;
return $a->go() * 2;
}
}

Basically, I will tell you how I would do it (at least I've did it in some projects):
1 add your vendor vendors/yahooapi/yahoo.class.php as you did
2 create a file inside the vendors/yahooapi/ or outside in vendors/ which will extend the original vendor class let's say vendors/yahoov2.php
i.e.
include_once('.../vendors/yahooapi/yahoo.class.php');
class Yahoov2 extends YahooAPI {
var $key = 'newKey';
function go() {}
}
3 And finally include in the component your extension as you did in your controller.
I believe that also extending the class in your controller directly would do the job, but it's really a matter of taste.

Related

Cakephp 2.9 passing a variable from Controller to Layouts View

The question i am asking is very similar and already asked question.But It is working for me.
ViewReportsController.php
class ViewReportsController extends AppController {
public function index() {
$count_table = 10;//sample variable that is available in view
$this->set('count_tablen',$count_table);
}
}
APP/View/Layouts/default.ctp
pr($count_tablen);
Now i am getting the error says- Undefined variable: count_tablen [APP/View/Layouts/default.ctp, line 228]
You are using a variable in your main layout template which is likely used by multiple controller actions. Therefore, the code example you've provided would only work on /view_reports/index. If you want to set variables to be used in the layout templates you need to do this in the beforeRender callback of AppController so that it can be used everywhere:-
public function beforeRender() {
parent::beforeRender();
$count_table = 10;
$this->set('count_tablen', $count_table);
}
If you use multiple layout templates you can check which template will be used in beforeRender before setting the variable:-
public function beforeRender() {
parent::beforeRender();
if ($this->layout === 'default') {
$count_table = 10;
$this->set('count_tablen', $count_table);
}
}

how to call function from Class A in different class B function in extjs4

Note:- i want to call ClassA function "deleteEntryInternal" in another class B within "afterRequest function. how can i call this function in other class function.
My code is Below
//here is my Class A
Ext.define('WebCare.UI.OtherServicesEditor', {
extend: 'Ext.WebCare.UI.BaseEditor',
_otherservicesGrid: null,
alias: 'widget.otherserviceseditor',
title: 'Other Services',
defaultType: 'textfield',
id: 'otherservicesEditor',
deleteEntryInternal: function (isDelete) {
this.disableForm();
var self = this;
var selection = self._otherservicesGrid.getSelectionModel().getSelection();
if (selection.length > 0) {
if (isDelete) {
selection[0].data.IsDelete = true;
}
this.deleteServerRecord(selection[0].data, function () { });
vent.trigger(otherServicesStore.storeId, selection[0].data);
}
}
To call this method, you need to obtain instance of this class. And then you can call methods in that class.
1.You can get an instance of Ext.app.Controller by
var controllerInstance = appName.app.getController('appName.controller.controllerName');
controllerInstance.methodToCall();
where appName is name of your Extjs App.
2.If your class is a view which is already rendered , you can get its instance by -
var viewInstance = Ext.getCmp(viewId);
viewInstance.methodToCall();
where viewId is id of your view.
3. Static class -
You can call methods of static class directly like if class MyStaticClass is static class , you can call its methods like -
MyStaticClass.methodToCall();
It is never a good idea to cross reference class methods on any way. Although Harshal's methods will work it is just very bad app design. If your class needs to react to an event what is happening in another class then why don't you just fire an event in class A and set up a listener in class B?

How to properly save self reference with ES6 classes?

Honestly, I'm not sure of what is the cause for the behavior: systemjs, babel or my own fault. I'm using class for custom control controller and saving class reference in self variable. Apparently that gets overriden by any subsequent controller instances.
I created a simple repository to demonstrate:
clone, install, run live-server or your preferred server. You will see 2 buttons, each is a custom control. Clicking on a button only affects one control.
https://github.com/alexkolt/selfIsThis
How can I get this working with ES6 class?
I should have posted the code, sorry.
The reason you'd want to save reference to self is for example in callbacks calling this might result in a different reference.
I was trying to do this:
var self;
class Test {
constructor(dependency) {
self = this;
self.dependency = dependency;
}
method() {
self.dependency().then(value => self.property = value);
}
}
Like it was mentioned before the self becomes shared when declared outside of the module. I didn't realize that would happen as files would be wrapped in a closure. Joe Clay answer is correct, but to do what I was trying to do self needs to be declared in every method that needs it.
class Test {
constructor(dependency) {
this.dependency = dependency;
}
method() {
var self = this;
this.dependency().then(value => self.property = value);
}
}
You're not really using ES6 classes right. You don't need to save a reference to this - just access it directly in class methods. The way you have it at the minute, all your instances of CustomControlController are sharing a single self variable.
class CustomControlController {
constructor() {
this.value = 0;
}
click() {
var newValue = this.value * 2;
this.value = newValue;
}
}
export default CustomControlController;

callback functions for cakephp elements?

This might be a naive question since I am new to cakephp.
I am working on a project where there are many layouts, helpers and elements. Because this is a mutli-language site, I am intercepting the final rendered output to do some language conversion(so each visitor only sees his native language on the site including user input).
I've managed to convert most of the layouts and helpers by adding code in two places: AppController's afterFilter() and AppHeler's afterRender() function. But I can't figure out a centralized way to handle the elements and there are dozens of them.
So here are my questions: do all elements in cakephp have a common ancestor class? If so, does this ancestor class have callback functions like afterRender()?
Many thanks!
I'm not sure such a callback exists specific for 'elements', but looking at the source code, View::element() renders an element using the same _render() method as the View itself, and should trigger beforeRender() and afterRender()
Creating a custom View Class and Custom Callbacks
You may use a custom 'View' class and override the element() method, for example to have your own 'custom' callbacks being triggered in helpers
Something like this;
app/view/app_view.php
class AppViewView extends View {
/**
* custom 'element()' method, triggers custom
* before/aferRenderElement callbacks on all loaded helpers
*/
public function element($name, $params = array(), $loadHelpers = false)
{
$this->_triggerHelpers('beforeRenderElement');
$output = parent::element($name, $params, $loadHelpers);
$this->_triggerHelpers('afterRenderElement');
}
/**
* Names of custom callbacks
*/
protected $_customCallBacks = array(
'beforeRenderElement',
'afterRenderElement',
);
function _triggerHelpers($callback)
{
if (!in_array($callback, $this->_customCallbacks)) {
// it's a standard callback, let the parent class handle it
return parent::_triggerHelpers($callback);
}
if (empty($this->loaded)) {
return false;
}
$helpers = array_keys($this->loaded);
foreach ($helpers as $helperName) {
$helper =& $this->loaded[$helperName];
if (is_object($helper)) {
if (
is_subclass_of($helper, 'Helper')
&& method_exists($helper, $callback)
) {
$helper->{$callback}();
}
}
}
}
}
Then, in your AppController specify the 'view' class to use;
class AppController extends Controller {
public $view = 'AppView';
}

Variables in CakePHP's models: how to acces them from another controller?

What I want to do is the following:
I have a model called "Control":
class Control extends AppModel {
var $name = 'Control';
var $myVariable:
function getMyVariable() {
$this->$myVariable = 'hello';
return ($this->$myVariable);
}
function getMyVariable2() {
$myVariable2 = 'hello';
return ($myVariable2);
}
}
Then, from another controller I do:
class TestsController extends AppController {
var $name = 'Tests';
var $uses = array('Test','Control');
function index() { //whatever }
function doStuff() {
$aux = $this->Control->getMyVariable(); //not working, variable not declared
$aux2 = $this->Control->getMyVariable2(); //works
}
I assumed (probably wrong) that I could declare a variable as a property (or atribute) in a model Class like in any other OO languaje, and access it from other places of the aplication, but I guess it doesn't work like this in CakePHP. Am I missing something? Is there any other way to do this? I mean, to having a variable in a model (which content doesn't come from a table) and acces it from other controllers/views?
$this->$myVariable is the syntax for "variable variables" (or in this case, variable properties). The correct syntax is $this->myVariable. CakePHP does not alter the basics of PHP OOP.
Setting a variable in a getter is pretty weird though, you should not do that.
Also, if you are using getters, you should make the property protected or private, otherwise it's somewhat pointless.

Resources