2015-03-31 3 views
1

Я использую производную Kohana View_Core для своих просмотров. Я хотел бы отображать буферизованные представления или пользовательский вид при выключении, например.Kohana - отображение буферизированных представлений или пользовательский вид при выключении

  1. Если были некоторые ошибки/исключения в течение страницы во время выполнения => ошибки отображения
  2. Если выполнен без ошибок => отображать буферизованный вывод

View

class View 
{ 

private $file = ''; 

private $data = array(); 

private static $global_data = array(); 

public static $view = ''; 

private function __construct($file = FALSE, array $data = array()) 
{ 
    if ($file !== FALSE) 
    { 
     $this->set_filename($file); 
    } 

    if (!empty($data)) 
    { 
     $this->data = $data + $this->data; 
    } 
} 

/** 
* Creates new view object and returns it. 
* 
* @param string filename 
* @param array variables 
* @return object View 
*/ 
public static function factory($file = FALSE, array $data = array()) 
{ 
    return new View($file, $data); 
} 

/** 
* Captures the output that is generated when a view is included. 
* The view data will be extracted to make local variables. This method 
* is static to prevent object scope resolution. 
* 
* @param string filename 
* @param array variables 
* @return string 
*/ 
public static function capture($view_filename, array $view_data) 
{ 
    extract($view_data, EXTR_SKIP); 

    ob_start(); 

    try 
    { 
     require $view_filename; 
    } 
    catch (Exception $error) 
    { 
     $ob_handlers = ob_list_handlers(); 

     if (!empty($ob_handlers)) 
     { 
      ob_end_clean(); 
     } 

     throw $error; 
    } 

    return ob_get_clean(); 
} 

/** 
* Load view file 
* 
* @param string filename 
* @return boolean 
* @return object View 
*/ 
public function set_filename($file) 
{ 
    if (strpos($file, APP_DIR) === FALSE) 
    { 
     $extension = strrpos($file, '.') === FALSE ? '.php' : ''; 

     $path = APP_DIR.DIR_SEP.'system'.DIR_SEP.'views'.DIR_SEP.$file.$extension; 
    } 
    else 
    { 
     $path = $file; 
    } 

    if (!file_exists($path)) 
    { 
     Error::throw_throwable('Unable to find file '.$path); 
    } 

    $this->file = $path; 

    return $this; 
} 

/** 
* Sets a global variable, similar to the set() method. 
* 
* @param string variable name 
* @param mixed variable value 
* @return object View 
*/ 
public static function set_global($key, $value = FALSE) 
{ 
    self::$global_data[$key] = $value; 
} 

/** 
* Assigns a variable by name. 
* 
* @param string variable name or an array of variables 
* @param mixed variable value 
* @return object View 
*/ 
public function set($key, $value = FALSE) 
{ 
    if (is_array($key)) 
    { 
     foreach ($key as $name => $value) 
     { 
      $this->data[$name] = $value; 
     } 
    } 
    else 
    { 
     $this->data[$key] = $value; 
    } 

    return $this; 
} 

/** 
* Renders the view object to a string. 
* 
* @throws exception 
* @param string filename 
* @return string 
*/ 
public function render($file = FALSE) 
{ 
    if ($file !== FALSE) 
    { 
     $this->set_filename($file); 
    } 

    if (empty($this->file)) 
    { 
     Error::throw_throwable('Unable to find file '.$this->file); 
    } 

    $data = array_merge(View::$global_data, $this->data); 

    return View::capture($this->file, $data); 
} 

public function __toString() 
{ 
    try 
    { 
     $result = $this->render(); 

     return $result; 
    } 
    catch (Exception $error) 
    { 
     Error::throw_throwable($error); 
    } 
} 

public function __set($key, $value) 
{ 
    $this->set($key, $value); 
} 

public function __get($key) 
{ 
    return isset($this->data[$key]) ? $this->data[$key] : FALSE; 
} 

} 

Использование

$content = View::factory('main/Main') 
      ->set('order', !empty($_SESSION['order']) ? $_SESSION['order'] : FALSE) 
      ->set('order_success', $order_success) 
      ->set('items', $items) 
      ->set('weights', $weights) 
      ->set('ammounts', $ammounts) 
      ->set('prices', $prices) 
      ->set('total_price', $total_price) 
      ->set('validator', FALSE) 
      ; 

$template = $this->get_template(); 

echo $template->set('content', $content); 

Что делают предыдущие строки, это эхо-просмотр содержимого внутри представления шаблона. И это должно быть также результатом того, что мой обработчик останова при необходимости повторяет. Есть ли хороший/простой способ сделать это?

ответ

1

Похоже, что вы хотите показать страницу пользовательской ошибки при возникновении ошибки. То, что я обычно делаю здесь, состоит в том, чтобы расширить класс Kohana_Kohana_Exception (как Kohana_Exception) и переопределить метод public static function handler.

Это позволяет ввести код, который может проверить, что такое ошибка (HTTP_404_Exception или другое), что такое среда (dev/production) и выполнять любое поведение, которое вы хотите.

В моем случае, что-то вроде этого:

// If not production and not an HTTP exception 
if (! ($e instanceof HTTP_Exception) && Kohana::$environment !== Kohana::PRODUCTION) 
{ 
    // Use built in error handler to show stace trace for developers 
    Kohana_Kohana_Exception::handler($e); 
    // ... exit(1); 
} 

// Otherwise 
$injected_routes = array(Route::get('error')); 
echo Request::factory('error-uri', NULL, FALSE, $injected_routes) 
       ->headers(Request::$initial->headers()) 
       ->execute() 
       ->send_headers(TRUE) 
       ->body(); 

Здесь нужен другой маршрут под названием error, который соответствует error-uri и переходит к другому контроллеру ошибки/действие/мнение, что вы можете использовать, чтобы сделать вашу пользовательскую страницу ошибки.


Для этой работы вам необходимо иметь ошибки включены, передавая 'errors' => TRUE вашего Kohana::init вызова в bootstrap.php.

+0

Концепция «View_Class» кажется идеальной - я оставил ее неповрежденной. Однако для этого я написал обертку - еще один статический метод «View_Class», который проверяет, является ли массив ошибок пустым или нет. Но это также стоит посмотреть, если вы используете Kohana Framework в целом. – sitilge

+0

Проверено на использование Kohana. Работает как шарм, попытается воспроизвести/переписать на мои собственные занятия. :) – sitilge