Can someone explain this code in Silverstripe:
public function init() {
RSSFeed::linkToFeed($this->Link() . "rss");
parent::init();
}
What exactly is init function?
what parent::init();
exactly do in code
in php classes when you overwrite a method of parent class you still can call the parent class with this code, it will help you to put some code at the beginning of the real method without removing it.
you can find out more about it at php documentation
The upmost init() method is defined in the Controller class.
Then ContentController extends Controller, which overrides the Controller class's init() method, but it's also calling parent::init() on the first line. Then usually you define all your page controller classes like this (for any new page type), in the example below for the default Page_Controller class:
class Page_Controller extends ContentController {
public function init() {
parent::init();
// do your own stuff here
}
}
So this is the traditional PHP based class extension mechanism, but Silverstripe also allows you to use Extensions and Data Extensions, which is basically extending the functionality of already existing controllers, data objects. I won't go into details with this... You can find out more about this here: https://docs.silverstripe.org/en/4/developer_guides/extending/extensions/
I usually have something like this in my controller classes:
class Page_Controller extends ContentController {
public function init() {
parent::init();
// do your own stuff here
$this->extend('updateInit');
}
}
Notice the $this->extend('updateInit'); line above.
I can have another extension defined for the Page_Controller class inside a YAML config file somewhere, and than have the updateInit() method defined in that class. Example:
class Page_Controller_Extension extends Extension {
public function updateInit() {
// do some more stuff here
}
}
...and in this case you would have something like this in a YAML config file:
---
Name: siteextensions
After:
- 'framework/*'
- 'cms/*'
---
Page_Controller:
extensions:
- Page_Controller_Extension
Note that this is not really the traditional way of extending classes, like in PHP, it's more like defining some decorators for a controller class. Also, to refer to the parent, or object being decorated, you can't use just $this, you'll need to use $this->owner. Example below:
class Page_Controller_Extension extends Extension {
public function updateInit() {
// do some more stuff here
if ($this->owner->IsFeatured) {
// do something here
}
}
}
You usually decorate controllers extending the Extension class, and you extend the DataExtension class if you want to decorate DataObjects - works the same way as explained above.
Related
$this is use for current class and view is method but what is load. Is this a property?
Is this example correct?
class super{
public $property;
public function superf1()
{
echo "hello";
}
public function col()
{
$this->superf1();
}
$this->property->super1();
}
Yes, load is a property.
Think of it like this:
class Loader {
public function view() {
//code...
}
}
class MyClass {
private $load;
public __constructor() {
$this->load = new Loader();
}
public someMethod() {
$this->load->view();
}
}
This syntax is called chaining.
Your controller inherits CI_Controller. So, if you look in application/system/core/Controller.php you'll find something interesting : $this->load =& load_class('Loader', 'core'); (l.50 with CI2). So, $this->load refer to the file application/system/core/Loader.php which have a function public function view (l.418 with CI2)
In the context of a class that extends CI_Controller (in other words: a controller) the symbol $this is the Codeigniter "super object". Which is, more or less, the central object for CI sites and contains (among other things) a list of loaded classes. load is one of the classes you'll always find there because it is automatically loaded by the CI system.
Technically, the class creates objects of the type CI_Loader. view() is just one of the many methods in the load class. Other commonly used class methods are model(), library(), config(), helper(), and database(). There are others.
So, in short, load is a class used to load other resources.
load is a class belongs to the loader class
codeigniter official documentation
view, model and others are methods
In PHP 8.1
use return("viewname", $data)
Considering this subclass of Zend_Form
class Form_Mine extends Zend_Form
{
public function init()
{
//form
}
Then in
Class MineController extends Zend_controller_Action
{
public function formAction()
{
$form = new Form_Mine();
}
}
How does the controller know of 'Form_Mine's existence in order to be instantiated?
I understand that through the Zend_Form's constructor the function init() is called setting up the form however through what chain or routing does the controller get access to 'Form_Mine'?
The class name is significant. By default, given a class named My_Form_Mine, Zend would look for the class in file: /library/My/Form/Mine.php. My understanding is that this is handled by the autoloader: http://framework.zend.com/manual/1.12/en/zend.loader.autoloader.html
I am creating a plugin for a CMS that provides a few base classes (let's say one of these classes is called Base). This class has a few helper methods that must be overwritten in the extending class. We should note that the base methods have default parameters/values provided. In one version of the LMS these values are provided by reference in the next version just by value.
For example (CMS v1.0):
function prepareTable(&$table){...
CMS v1.1:
function prepareTable($table){...
When you extend the Base class and overwrite the prepareTable method you have to declare it with the same default parameters/values as well, otherwise a STRICT PHP warning is displayed (on by default in PHP 5.4).
My question is, how do I conditionally overwrite the method from the parent class in a working way, knowing the version of the parent CMS?
Here's what I have currently (not working at the moment):
class Base{
function prepareTable(&$table){
}
}
class Extending extends Base{
if(CMS_VERSION=='1.0')
function prepareTable(&$table){
else
function prepareTable($table){
echo $table;
}
}
Obviously, I can not edit the Base and its method directly.
EDIT: Here's the exact error message:
Strict standards: Declaration of Extending::prepareTable() should be compatible with Base::prepareTable($table) in.
the only way I can think of achieving this without duplicating the code inside prepareTable is to create a pseudo function that gets called inside prepareTable and then declare that in the final extended class
if(CMS_VERSION=='1.0') {
class Base2 extends Base{
function prepareTable(&$table){
return $this->prepareTable2($table);
}
function prepareTable2(&$table){
}
}
} else {
class Base2 extends Base{
function prepareTable($table){
return $this->prepareTable2($table);
}
function prepareTable2(&$table){
}
}
}
class Extending extends Base2{
function prepareTable2(&$table){
echo $table;
}
}
if(CMS_VERSION=='1.0') {
class Extending extends Base{
function prepareTable(&$table){
}
}
} else {
class Extending extends Base{
function prepareTable($table){
}
}
}
Note that the if/else check must be done before the class is defined, not inside the class. Essentially, you are building two different versions of the class.
Side Note: If you need to include shared methods, that won't be changed between the two versions of the class, you can define a new class that will extend Extending, create the shared methods there and use this new class.
For example (place this after the code above):
class ExtendingFull extends Extending{
// Here you may include your shared methods
// e.g:
public function sharedMethod(){
echo 'test';
}
}
I was just wondering if the next situation could be possible or not, I've read the PHP Manual documentation, but I would like another perspective because it's not so clear for me.
So I have for example one class:
class SomeClass {
public function someFunction() {
...
}
}
And an extension of it:
class Extension extends SomeClass {
public function someOtherFunction() {
...
}
}
My question is, could I be able to use the public functions inside the classes on both ways, the main class's function inside the extended function and the other way around?
And would I be doing that how?
You can use both functions from class Extension, but only someFunction() from class SomeClass.
Extension does not change the original class, it just incorporates it into a new one.
You can use the public and protectedfunctions of your parent in the extended (child) class:
class Extension extends SomeClass
{
public function someOtherFunction() {
$foo = $this->someFunction(); // from parent class
return $foo;
}
}
When class "Extension" is created, its basically a copy of "SomeClass" which you can modify in the way as you can add new functions or overwrite those of the parent class.
The parent does not know about the Extension (it can be extended multiple times, eg "JSONRequest extends Request", "XMLRequest extends Request"). Calling extended functions from within the parent makes no sense, since the parent class can never know which childs function it should call in such a situation. This type of Inheritance is one of the basic concepts of OOP and clear interfaces.
In other words, no it will never work the other way round. And it should not.
Is it possible to call the member function of another controller in zend framework, if yes then how?
<?php
class FirstController extends Zend_Controller_Action {
public function indexAction() {
// general action
}
public function memberFunction() {
// a resuable function
}
}
Here's another controller
<?php
class SecondController extends Zend_Controller_Action {
public indexAction() {
// here i need to call memberFunction() of FirstController
}
}
Please explain how i can access memberFunction() from second controller.
Solution
Better idea is to define a AppController and make all usual controllers to extend AppController which further extends Zend_Controller_Action.
class AppController extends Zend_Controller_Action {
public function memberFunction() {
// a resuable function
}
}
class FirstController extends AppController {
public function indexAction() {
// call function from any child class
$this->memberFunction();
}
}
Now memberFunction can be invoked from controllers extending AppController as a rule of simple inheritance.
Controllers aren't designed to be used in that way. If you want to execute an action of the other controller after your current controller, use the _forward() method:
// Invokes SecondController::otherActionAction() after the current action has been finished.
$this->_forward('other-action', 'second');
Note that this only works for action methods (“memberAction”), not arbitrary member functions!
If SecondController::memberFunction() does something that is needed across multiple controllers, put that code in a action helper or library class, so that both controllers can access the shared functionality without having to depend on each other.
You should consider factoring out the code into either an action helper or to your model so that it can be called from both controllers that need it.
Regards,
Rob...
I would suggest you to follow DRY and move those functions to common library place. For example create in library folder
My/Util/
and file
CommonFunctions.php
then call your class
My_Util_CommonFunctions
and define your methods
Now you can call them from any place in the code using your new namespace which you have to register.
$loader = Zend_Loader_Autoloader::getInstance();
$loader->registerNamespace(array('My_'));
in any controller you can call your custom methods by using:
My_Util_CustomFunctions::yourCustomMethod($params);