Joomla 1.6外部PHP交互问题

时间:2011-08-12 11:02:16

标签: php joomla joomla-extensions joomla1.6

我是Joomla的新手,我正在调整我为v1.5编写的外部php类。 基本上,我没有涉及所有细节,我使用一个函数来加载Joomla环境,之后Joomla中的所有内容都可用于该类。 这基本上是使用index.php文件完成的。

它与v1.5一起正常工作并且已经做了一段时间但是试图将其调整为v1.6,它会失败。

这是功能:

    private function loadJoomla() {
        $path_base = rtrim($this->joomFullPath, '/');

        // Set flag that this is a parent file
        define( '_JEXEC', 1 );
        define( 'DS', DIRECTORY_SEPARATOR );

        switch ($joomlaVersion) {
            case 'v1.6':
                if (file_exists($path_base . '/defines.php')) {
                    include_once $path_base . '/defines.php';
                }
                if (!defined('_JDEFINES')) {
                    define('JPATH_BASE', $path_base);
                    require_once JPATH_BASE.'/includes/defines.php';
                }
                require_once JPATH_BASE.'/includes/framework.php';

                // Mark afterLoad in the profiler.
                JDEBUG ? $_PROFILER->mark('afterLoad') : null;

                // Instantiate the application.
                $app = JFactory::getApplication('site');

                // Initialise the application.
                $app->initialise();

                // Mark afterIntialise in the profiler.
                JDEBUG ? $_PROFILER->mark('afterInitialise') : null;

                // Route the application.
                $app->route();

                // Mark afterRoute in the profiler.
                JDEBUG ? $_PROFILER->mark('afterRoute') : null;

                // Dispatch the application.
                $app->dispatch();

                // Mark afterDispatch in the profiler.
                JDEBUG ? $_PROFILER->mark('afterDispatch') : null;

                // Render the application.
                $app->render();

                // Mark afterRender in the profiler.
                JDEBUG ? $_PROFILER->mark('afterRender') : null;

                // Return the response.
                return $app;
            break;
            case 'v1.5':
                // PREPARE
                define('JPATH_BASE', $path_base);
                require_once ( JPATH_BASE .DS.'includes'.DS.'defines.php' );
                require_once ( JPATH_BASE .DS.'includes'.DS.'framework.php' );
                JDEBUG ? $_PROFILER->mark( 'afterLoad' ) : NULL;

                // CREATE THE APPLICATION
                $GLOBALS['mainframe'] =& JFactory::getApplication('site');

                // INITIALISE THE APPLICATION
                /* set the language */
                $GLOBALS['mainframe']->initialise();
                JPluginHelper::importPlugin('system');
                /* trigger the onAfterInitialise events */
                JDEBUG ? $_PROFILER->mark('afterInitialise') : NULL;
                $GLOBALS['mainframe']->triggerEvent('onAfterInitialise');

                // ROUTE THE APPLICATION
                $GLOBALS['mainframe']->route();
                /* authorization */
                $GLOBALS['Itemid'] = JRequest::getInt( 'Itemid');
                $GLOBALS['mainframe']->authorize($GLOBALS['Itemid']);
                /* trigger the onAfterRoute events */
                JDEBUG ? $_PROFILER->mark('afterRoute') : NULL;
                $GLOBALS['mainframe']->triggerEvent('onAfterRoute');

                // DISPATCH THE APPLICATION
                $GLOBALS['option'] = JRequest::getCmd('option');
                $GLOBALS['mainframe']->dispatch($GLOBALS['option']);
                /* trigger the onAfterDispatch events */
                JDEBUG ? $_PROFILER->mark('afterDispatch') : NULL;
                $GLOBALS['mainframe']->triggerEvent('onAfterDispatch');

                // RENDER  THE APPLICATION
                $GLOBALS['mainframe']->render();
                /* trigger the onAfterRender events */
                JDEBUG ? $_PROFILER->mark('afterRender') : NULL;
                $GLOBALS['mainframe']->triggerEvent('onAfterRender');

                // RETURN THE RESPONSE
                return JResponse::toString($GLOBALS['mainframe']->getCfg('gzip'));
            break;
            default:
                return NULL;
            break;
        }

如上所述,v1.5位工作正常,只是index.php文件,主机变量为全局变量。 v1.6位落在'$ app-> dispatch();'。

使用'die'调试流程使我在/libraries/joomla/application.php中进行函数调度,在那里我发现掉落点是'$ contents = JComponentHelper :: renderComponent($ component);'这让我在/libraries/joomla/application/component/helper.php中运行renderComponent

一些'死'之后,我发现了摔倒点,等待它,'ob_start();'。 完全困惑,特别是自检查v1.5代码以来,我可以看到它与v1.6完全相同。

我怀疑$ app范围可能是背后的原因,并会感谢一些帮助。我尝试了明显的“$ GLOBALS ['app']”,没有任何快乐。

感谢您抽出宝贵的时间和精力。

1 个答案:

答案 0 :(得分:2)

我设法解决了这个问题如下。

发生了两个不同的问题。

首先,v1.6部分没有正确初始化“$ option”参数。感谢this query I made中的用户hbit,我能够解决这个问题。通过更改代码如下:

// Dispatch the application.
$option = JRequest::getCmd('option');
$app->dispatch($option);

然而,这并没有解决问题,代码仍然在'ob_start'点崩溃。

其次,我无法了解崩溃的实际原因,但是找到了解决方法。由于位于/libraries/joomla/application/component/helper.php中的ob_start位仅用于将组件输出收集到变量中,因此我通过拉动'$ app-> dispatch的代码解决了这个问题。 ($ option)'触发我的文件并修改问题部分。

首先,我修改了主要部分如下:

// Dispatch the application.
$option = JRequest::getCmd('option');
/** The process crashes here for some reason 
* (See https://stackoverflow.com/questions/7039162/).
* So we comment out the Joomla! function, pull the code in here and 
* push the component content into the Joomla document buffer ourselves.
**/
//$app->dispatch($option);
$this->joomdispatch($option);

然后我写了一个'joomdispatch'函数如下:

private function joomdispatch($option) {
    /************************
     * This is pulled from function 'render' 
     * in /libraries/joomla/application.php
     ************************/
    $document = JFactory::getDocument();
    $document->setTitle(JApplication::getCfg('sitename'). ' - ' .JText::_('JADMINISTRATION'));
    $document->setDescription(JApplication::getCfg('MetaDesc'));

    /************************
     * This is pulled from function 'renderComponent' 
     * in /libraries/joomla/application/component/helper.php
     * Function 'renderComponent' is called by the
     * '$contents = JComponentHelper::renderComponent($component);' line
     * We exclude that line and jump to the function code
     ************************/

    // Initialise variables.
    $app = JFactory::getApplication();

    // Load template language files.
    $template   = $app->getTemplate(true)->template;
    $lang = JFactory::getLanguage();
    $lang->load('tpl_'.$template, JPATH_BASE, null, false, false)
        ||  $lang->load('tpl_'.$template, JPATH_THEMES."/$template", null, false, false)
        ||  $lang->load('tpl_'.$template, JPATH_BASE, $lang->getDefault(), false, false)
        ||  $lang->load('tpl_'.$template, JPATH_THEMES."/$template", $lang->getDefault(), false, false);

    $scope = $app->scope; //record the scope
    $app->scope = $option;  //set scope to component name

    // Build the component path.
    $option = preg_replace('/[^A-Z0-9_\.-]/i', '', $option);
    $file   = substr($option, 4);

    // Define component path.
    define('JPATH_COMPONENT',               JPATH_BASE.DS.'components'.DS.$option);
    define('JPATH_COMPONENT_SITE',          JPATH_SITE.DS.'components'.DS.$option);
    define('JPATH_COMPONENT_ADMINISTRATOR', JPATH_ADMINISTRATOR.DS.'components'.DS.$option);

    // get component path
    if ($app->isAdmin() && file_exists(JPATH_COMPONENT.DS.'admin.'.$file.'.php')) {
        $path = JPATH_COMPONENT.DS.'admin.'.$file.'.php';
    } else {
        $path = JPATH_COMPONENT.DS.$file.'.php';
    }

    $task = JRequest::getString('task');

    // Load common and local language files.
    $lang->load($option, JPATH_BASE, null, false, false)
        ||  $lang->load($option, JPATH_COMPONENT, null, false, false)
        ||  $lang->load($option, JPATH_BASE, $lang->getDefault(), false, false)
        ||  $lang->load($option, JPATH_COMPONENT, $lang->getDefault(), false, false);

    // Handle template preview outlining.
    $contents = null;

    // Get component html
    /************************
     * This has been edited from the native 'ob_start'.
     * Could use curl as well
      ***********************/
    $contents = file_get_contents($this->joomUrl . '/index.php?' . $this->joomQS);

    // Build the component toolbar
    jimport('joomla.application.helper');

    if (($path = JApplicationHelper::getPath('toolbar')) && $app->isAdmin()) {
        // Get the task again, in case it has changed
        $task = JRequest::getString('task');

        // Make the toolbar
        include_once $path;
    }

    $app->scope = $scope; //revert the scope

    /************************
     * Back to function 'renderComponent' code
     * to complete process
     ************************/
    $document->setBuffer($contents, 'component');

    // Trigger the onAfterDispatch event.
    JPluginHelper::importPlugin('system');
    JApplication::triggerEvent('onAfterDispatch');
}

有了这个,一切正常。没有得到(奇怪的)错误的底部,但设法解决它。