Joomla 1.6 Внешняя проблема взаимодействия с PHP - PullRequest
1 голос
/ 12 августа 2011

Я новичок в работе с Joomla и адаптирую внешний класс php, который я написал для v1.5. Не вдаваясь во все детали, в основном, я использую функцию для загрузки среды 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 с переменной mainframe, сделанной глобальной. Бит v1.6 падает в '$ app-> dispatch ();'.

При отладке потока с помощью команды die я отправил функцию dispatch в /libraries/joomla/application.php, где я обнаружил, что точка перепадания была '$ contents = JComponentHelper :: renderComponent ($ component); который взял меня к функции renderComponent в /libraries/joomla/application/component/helper.php

Несколько «спустя» умирает, я обнаружил, что точка падения - это ожидание, «ob_start ();». Полностью сбит с толку, особенно после проверки кода v1.5, я вижу, что он точно такой же, как v1.6 здесь.

Я подозреваю, что причиной этого может быть область $ app, и я буду признателен за некоторую помощь. Я попробовал очевидное "$ GLOBALS ['app']" без радости.

Спасибо, что нашли время и указатели оценены.

1 Ответ

2 голосов
/ 03 сентября 2011

Мне удалось решить эту проблему следующим образом.

Произошли две отдельные проблемы.

Во-первых, в разделе v1.6 не был правильно инициализирован параметр «option». Благодаря пользователю hbit в этот запрос, который я сделал , я смог решить. изменив код следующим образом:

// 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 /5795806/joomla-1-6-vneshnyaya-problema-vzaimodeistviya-s-php).
* 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');
}

С этим все отлично работает. Не дошел до (странной) ошибки, но сумел ее обойти.

...