1

我是使用 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 范围可能是这背后的原因,并会感谢一些帮助。我没有高兴地尝试了明显的“$GLO​​BALS['app']”。

感谢您抽出宝贵的时间和指点赞赏。

4

1 回答 1

2

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

发生了两个不同的问题。

首先,v1.6 部分没有正确初始化“$option”参数。感谢用户 h​​bit 在我提出的这个查询中,我能够解决这个问题。通过如下更改代码:

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

但是,这并没有解决问题,代码仍然在“ob_start”点崩溃。

其次,我无法找到崩溃的实际原因,但寻求了一种解决方法。由于有问题的 ob_start 位位于 /libraries/joomla/application/component/helper.php 中,仅用于将组件输出收集到变量中,因此我通过拉取 '$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');
}

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

于 2011-09-03T16:29:54.073 回答