我可以订购 Joomla 错误消息吗?

Can I order Joomla error messages?

我使用 JFactory::getApplication()->enqueueMessage('Message goes here', 'error') 向用户显示无法处理请求,它工作正常,但 Joomla 按消息出现的顺序排列消息。因为我的消息发生在捕获 Joomla 保存错误之前,所以用户看到此消息:

you cannot do this operation           //my message
Save failed with the following error:  //Joomla message

我想颠倒顺序,让 Joomla 消息保持原样,然后是我的消息,这样它才有意义:

Save failed with the following error:    // Joomla message
you cannot do this operation            // my message

这可能吗? (没有语言翻译或覆盖?)

在答案的帮助下,我可以进行反转:第一条消息是一个占位符,要使用 getMessageQueue() 进行搜索。尽管您可以在 J.2.5 中删除消息,但在 J.3+ (https://developer.joomla.org/joomlacode-archive/issue-33270.html) 中不再可行。解决方法是反映class解除对队列的保护,替换掉。

public static function reorderMessages()
{
    //error messages
    $err01 = JText::_('COM_COMPONENT_MESSAGE1');
    //you can adapt and add other messages here

    $app = JFactory::getApplication();  
    $new_messages = array();
    $replacement_found = null;
    //mirror protected $_messageQueue
    $appReflection = new ReflectionClass(get_class($app));
    $_messageQueue = $appReflection->getProperty('_messageQueue');
    $_messageQueue->setAccessible(true);
    //get messages
    $messages = $app->getMessageQueue();

    foreach($messages as $key=>$message) 
    {  
        if($messages[$key]['message'] == 'MESSAGE_TO_REPLACE' && $messages[$key]['type'] ==  'error' ) 
        {
            $replacement_found = 1;
            continue;
        }
        $new_messages[] = $message;
    }           
    if($replacement_found)
    { 
      //save all messages
      $_messageQueue->setValue($app, $new_messages);
      //add replacement message to the end of the queue       
      $app->enqueueMessage(JText::_($err01, 'error'); 
    }

    return true;
}

在调用该函数的位置要非常小心,如果消息队列为空,Joomla 将 return 出错并破坏您的代码。确保在调用该函数之前已将第一条消息加入队列。

您可以在应用程序对象(即 $myApp = JFactory::getApplication())上使用 getMessageQueue() 来获取消息队列数组的副本。您可以通过将 true 传递给 getMessageQueue()` 函数调用来清除消息队列。它仍然会return系统消息队列数组的副本。

然后您可以使用正则表达式在数组中查找键并重新排序。我会在翻译文件中找到系统错误消息,并使用翻译 .ini 文件中的错误消息键(而不是错误消息的实际文本)进行正则表达式搜索,这样它就不会中断错误消息更改。我还会在插件和后期生命周期挂钩(可能是 onBeforeRender 事件)中执行此操作。

您可以使用应用程序对象的 enqueueMessage() 方法将修改后的消息队列数组保存回 JApplication class 实例,该方法具有以下签名:

enqueueMessage(string $msg, string $type = 'message') : void

source