启动自定义窗口小部件类

so am creating a cms as a way of learning OOP and am kind of stuck. Here's my problem. (the code pasted below are stripped down to bare minimal)

i have a class named ThemeFunctions which has the following code for widgets functionality:

require_once('cmsBase.php');
class ThemeFunctions extends CmsBase{
//All CMS template management related functions will be here.
var $templateName='default';
var $widgetPositions=array();

function show()
{       
    $this->themeOutput();
}
/*apps*/
function appOutput()
{
    $appname=(isset($_REQUEST['app']))?$_REQUEST['app']:'default';
    require_once('applications/'.$appname.'/'.$appname.'.php');
    $application=ucfirst($appname).'Application';
    $app=new $application();
    $app->run();
}


/*widjets*/
function widgetOutput($position='default')
{
    if(!empty($this->widgetPositions[$position]))
    {
        $widgets=$this->widgetPositions[$position];//gets all widgets in given position
        foreach($widgets as $widgetObject)//display each widget
        {
            $widgetName=$widgetObject->name;
            $widgetParameters=$widgetObject->parameters;

            if(file_exists($file = 'widgets/'.$widgetName.'/'.$widgetName.'.php'))
            {
                require_once($file);
                echo 'file loaded';
            } else {echo 'file doesn\'t exist';}

            $widgetclass=ucfirst($widgetName).'Widget';
            $widget=new $widgetclass();
            $widget->run($widgetName,$widgetParameters);
        }
    }
}
function setWidget($position,$widgetName,$params=array())
{
    $widget=new StdClass;
    $widget->name=$widgetName;
    $widget->parameters=$params;
    //if there is no widget in position then create a new array
    if(empty($this->widgetPositions[$position])) 
    {
        $this->widgetPositions[$position]=array($widget);
    }
    //if there is already a widget present in that position then just push new widget in array
    else
    {
        array_push($this->widgetPositions[$position],$widget);
    }        
}

and the class in instantiated in the index file like so:

require_once('libraries/core/themeFunctions.php');
$tmpl=new ThemeFunctions();
$tmpl->show();

The widjet has its own base class called CmsWidjet which has the following code

class CmsWidget extends CmsBase{
var $widgetPath='';
var $widgetName='';
var $parameters=array();

function setWidgetPath($widgetName)
{
    $this->widgetPath='widgets/'.$widgetName.'/';
    $this->widgetName=$widgetName;
}
function getWidgetPath()
{
    return $this->widgetPath;
}
function display()
{
    echo 'this will be default output of widget if this function is not overrided by derived class';
}
function run($widgetName,$params)// this function will be called by template function class to display widget
{
    $this->parameters=$params;
    $this->setWidgetPath($widgetName);
    $this->display();
}
}

and the code for the widjet itself is: (i.e calculator widjet)

require_once('libraries/core/cmsWidget.php');
class CalculatorWidget extends CmsWidget{
function display()
{
  //if use_scientifc parameter is set and its value is true then output scientific calculator
  if(!empty($this->parameters['use_scientific']) and $this->parameters['use_scientific']==true)
  {
    require($this->getWidgetPath().'tmpl/scientific.php');
  }
  else
  {
    require($this->getWidgetPath().'tmpl/default.php');
  }
}
}

Now the tricky part is that ThemeFunctions class is also extended by the themes themselves. Thus when calling the active theme, its class is initiated and its functions called, which in turn call the various (choped) html parts to make the page.

So Initially, the themeFunctions class wasnt extended, instead, it used to just call the themes index.php and the widjets were initiated like this:

*themes index page

 $this->widgetOutput('sidebarPosition');

*main cms index page

 $tmpl->setWidget('sidebarPosition','calculator');

But after extending the themeFunctions class, the above doesnt work. Any help is appreciated.

Also this is just me learning OOP, so please excuse the errors in the code and point me in the correct direction if nessessary.

Your class ThemeFunctions is an other branch of class hierarchy. You have:

CmsBase
|
|--> ThemeFunctions
|
|--> CmsWidget
     |
     |--> CalculatorWidget

To inherit ThemeFunctions functionality you need to extend ThemeFunctions in class CmsWidget. So your structure will be the following:

CmsBase
|
|--> ThemeFunctions
     |
     |--> CmsWidget
          |
          |--> CalculatorWidget

In this structure you can use functions declared in ThemeFunctions.

If it breaks your plans about classes hierarchy you can look at Traits. http://php.net/manual/en/language.oop5.traits.php