2012-11-06 71 views
10

Tôi gặp sự cố với thư Magento. Tôi đang xây dựng mô-đun tùy chỉnh theo lý thuyết nên có thể hạn chế quyền truy cập vào một số phần của cửa hàng. Tôi đã tạo một người quan sát móc vào sự kiện controller_action_predispatch và kiểm tra xem người dùng có thể truy cập yêu cầu hiện tại hay không. Nếu không thể truy cập hành động, người quan sát sẽ chuyển hướng người dùng và đặt thông tin lỗi. Tôi muốn đặt url chuyển hướng đến trang mà khách hàng đến từ để tránh nhấp qua toàn bộ cửa hàng. Tôi đang xem HTTP_REFERER và sử dụng nó nếu nó được thiết lập, nếu không tôi chuyển hướng khách hàng đến trang chủ. Vấn đề là trong trường hợp sau (chuyển hướng trang chủ) mọi thứ hoạt động tốt nhưng khi tôi đặt url dựa trên referer tôi không thấy thông báo lỗi trong hộp tin nhắn.Magento mất thông báo sau khi chuyển hướng

Mã từ người quan sát ($name biến là một chuỗi):

Mage::getSingleton('core/session')->addError('Acces to '.$name.' section is denied'); 
$url = Mage::helper('core/http')->getHttpReferer() ? Mage::helper('core/http')->getHttpReferer() : Mage::getUrl(); 
Mage::app()->getResponse()->setRedirect($url); 

Những gì tôi thấy thú vị là nếu tôi làm bất kỳ thay đổi trong file quan sát và lưu nó, sau đó yêu cầu tiếp theo mà thất bại và được chuyển hướng đến url của người giới thiệu hiển thị thông tin lỗi nhưng bất kỳ thông tin nào tiếp theo sẽ mất các thông báo.

Tôi đã suy nghĩ rằng vấn đề là ở toàn bộ url và instalation địa phương của tôi (Tôi đang sử dụng miền .local) nhưng vì vậy tôi đã cố gắng thêm

$url = str_replace(Mage::getBaseUrl(), '/', $url); 

nhưng điều này đã không giúp đỡ.

Tôi cũng đã thử chuyển hướng bằng cách sử dụng chức năng php header() mà không có bất kỳ kết quả nào.

Tất cả bộ nhớ cache bị tắt. Các công việc mà gây nên các vấn đề như sau:

  1. Tôi sẽ bất kỳ trang truy cập (ví dụ/khách hàng/tài khoản)
  2. Bấm vào giỏ hàng liên kết (giỏ cho tài khoản này bị vô hiệu hóa)
  3. Return to/khách hàng/tài khoản và các thông báo lỗi được hiển thị
  4. Bấm vào giỏ hàng liên kết lại
  5. Return to/khách hàng/tài khoản nhưng không có thông báo lỗi

Bất kỳ gợi ý về nơi để tìm sẽ được đánh giá cao.

+0

Bạn có thể tắt tất cả bộ đệm (+ FPC nếu magento EE) để xem đó có phải là sự cố bộ nhớ cache không? Nhân tiện, tôi không hiểu tất cả những gì bạn thấy, bạn hiểu rằng các thông báo lỗi phiên bị xóa sau lần hiển thị đầu tiên? –

+0

Tôi mở rộng mô tả, hy vọng nó rõ ràng bây giờ. – Zefiryn

Trả lời

4

Tin nhắn của bạn bị lạc vì bạn sử dụng một cách không thuận lợi cho một chuyển hướng trong controller_action_predispatch. Giải pháp của bạn gây ra một mặt "tin nhắn bị mất" và mặt khác, nó lãng phí sức mạnh xử lý của máy chủ của bạn.

Khi bạn xem Mage_Core_Controller_Varien_Action::dispatch(), bạn sẽ thấy rằng giải pháp của bạn không ngừng thực hiện hành động hiện tại, nhưng nó sẽ làm điều đó với chuyển hướng. Thay vào đó, Magento thực hiện hành động hiện tại để kết thúc, bao gồm cả việc hiển thị thông báo mà bạn đã thêm trước đó. Vì vậy, không có thắc mắc tại sao tin nhắn bị mất với yêu cầu khách hàng tiếp theo, Magento đã có nó đã được trả trước, với các phản ứng máy chủ bao gồm chuyển hướng của bạn.

Hơn nữa, bạn sẽ chỉ thấy trong Mage_Core_Controller_Varien_Action::dispatch() chỉ một khả năng dừng thực hiện hành động hiện tại và bỏ qua trực tiếp đến chuyển hướng, nằm trong dòng 428 catch (Mage_Core_Controller_Varien_Exception $e) [...]. Vì vậy, bạn phải sử dụng Mage_Core_Controller_Varien_Exception mà là khá phổ biến, nhưng giải pháp duy nhất phù hợp với mục đích của bạn. Vấn đề duy nhất là, lớp này có lỗi vì nó được giới thiệu trong Magento 1.3.2. Nhưng điều này có thể dễ dàng sửa chữa.

Chỉ cần tạo lớp của riêng bạn mà có nguồn gốc từ Mage_Core_Controller_Varien_Exception:

/** 
* Controller exception that can fork different actions, 
* cause forward or redirect 
*/ 
class Your_Module_Controller_Varien_Exception 
    extends Mage_Core_Controller_Varien_Exception 
{ 
    /** 
    * Bugfix 
    * 
    * @see Mage_Core_Controller_Varien_Exception::prepareRedirect() 
    */ 
    public function prepareRedirect($path, $arguments = array()) 
    { 
     $this->_resultCallback = self::RESULT_REDIRECT; 
     $this->_resultCallbackParams = array($path, $arguments); 
     return $this; 
    } 
} 

Vì vậy, bây giờ bạn có thể thực hiện giải pháp của bạn thực sự sạch với điều đó:

/** 
* Your observer 
*/ 
class Your_Module_Model_Observer 
{ 
    /** 
    * Called before frontend action dispatch 
    * (controller_action_predispatch) 
    * 
    * @param Varien_Event_Observer $observer 
    */ 
    public function onFrontendActionDispatch($observer) 
    { 
     // [...] 

     /* @var $action Mage_Core_Model_Session */ 
     $session = Mage::getSingleton('core/session'); 
     /* @var $helper Mage_Core_Helper_Http */ 
     $helper = Mage::helper('core/http'); 
     // puts your message in the session 
     $session->addError('Your message'); 
     // prepares the redirect url 
     $params = array(); 
     $params['_direct'] = $helper->getHttpReferer() 
      ? $helper->getHttpReferer() : Mage::getHomeUrl(); 
     // force the redirect 
     $exception = new Your_Module_Controller_Varien_Exception(); 
     $exception->prepareRedirect('', $params); 
     throw $exception; 
    } 
} 
24
//A Success Message 
Mage::getSingleton('core/session')->addSuccess("Some success message"); 

//A Error Message 
Mage::getSingleton('core/session')->addError("Some error message"); 

//A Info Message (See link below) 
Mage::getSingleton('core/session')->addNotice("This is just a FYI message..."); 

//These lines are required to get it to work 
session_write_close(); //THIS LINE IS VERY IMPORTANT! 
$this->_redirect('module/controller/action'); 

// or 
$url = 'path/to/your/page'; 
$this->_redirectUrl($url); 

này sẽ làm việc trong một bộ điều khiển, nhưng nếu bạn đang cố gắng để chuyển hướng sau khi sản lượng đã được gửi đi, sau đó bạn chỉ có thể làm điều đó thông qua javascript:

<script language=”javascript” type=”text/javascript”> 
window.location.href=”module/controller/action/getparam1/value1/etc"; 
</script>  
+7

Cảm ơn, session_write_close(); đã làm các trick cho tôi. –

+0

+1 cho session_write_close(), bị kẹt vĩnh viễn! cám ơn –

0

này sẽ làm việc, vì vậy hãy thử nó:

$url = 'path/to/your/page'; 
$this->_redirectUrl($url); 
return false; 

Điều này có nghĩa là bạn không cho phép thực hiện lại bất kỳ điều gì khác.

Các vấn đề liên quan