prefix = $prefix; $this->configBase = ( $prefix == null ) ? 'urls' : $prefix; } public function setPackage( Package $package ) { if ( $this->package !== null ) { throw new Exception( 'trying to call setPackage() twice' ); } $this->package = $package; } public function fromPathInfo( ) { if ( array_key_exists( 'PATH_INFO' , $_SERVER ) ) { $path = $_SERVER[ 'PATH_INFO' ]; } else { $path = '/' . $this->package->config( $this->configBase . '/default' , 'home' ); } $this->fromPath( $path ); } public function fromPath( $path ) { if ( ! preg_match( '/^(\/[a-z0-9]+)+$/' , $path ) ) { $this->showPageNotFound( ); return; } if ( $this->prefix == null ) { $path = substr( $path , 1 ); } else { $path = $this->prefix . $path; } try { $this->showPageFor( $path ); } catch ( URLMapperException $e ) { $this->showPageNotFound( $path ); } } private function showPageNotFound( $requestPath = '' ) { $path = $this->package->config( $this->configBase . '/errors/404', 'errors/404' ); $this->showPageFor( $path . '/' . $requestPath , false ); } private function showPageFor( $path ) { $split = split( '/' , $path ); $extras = array( ); while ( !empty( $split ) ) { $name = join( '_' , $split ); try { $page = Loader::Page( $name ); break; } catch ( LoaderException $e ) { array_unshift( $extras , array_pop( $split ) ); } } if ( empty( $split ) ) { throw new URLMapperException( $path ); } $this->handlePage( $path , $page , join( '/' , $extras ) ); } private function handlePage( $requestPath , Page $page , $extraPath = '' , $pathFailure = true ) { if ( $page instanceof PathAware ) { $success = $page->setExtraPath( $extraPath ); } else { $success = ( $extraPath === '' ); } if ( $pathFailure && !$success ) { $this->showPageNotFound( $requestPath ); } else { $page->handle( ); } } } class View_BasicErrorDisplay implements View { private $error; private $site; private $path; public function __construct( $extraPath ) { $this->error = array_shift( $extraPath ); if ( ! empty( $extraPath ) ) { $this->site = array_shift( $extraPath ); $this->path = join( '/' , $extraPath ); } } public function render( ) { $text = HTML::make( 'p' ) ->setAttribute( 'class' , 'error' ) ->appendText( 'An error occurred while trying to access this page.' ) ->appendElement( HTML::make( 'br' ) ) ->appendText( 'Error code ' ) ->appendElement( HTML::make( 'strong' )->appendText( $this->error ) ) ->appendText( ' was encountered' ); if ( $this->site !== null ) { $text->appendText( ' while trying to access ' ) ->appendElement( HTML::make( 'strong' )->appendText( '/' . $this->path ) ) ->appendText( ' on site ' ) ->appendElement( HTML::make( 'strong' )->appendText( $this->site ) ); } return $text->appendText( '.' ); } } class Page_Errors extends Page_Basic implements PathAware { private $httpError; public function setExtraPath( $extraPath ) { $extraPath = split( '/' , $extraPath ); if ( (int)$extraPath[ 0 ] != 0 ) { $this->httpError = (int) $extraPath[ 0 ]; } $this->setTitle( 'Error ' . $extraPath[ 0 ] ); $this->addView( Loader::View( 'basic_error_display' , $extraPath ) ); return true; } public function render( ) { if ( $this->httpError !== null ) { header( 'HTTP/1.0 ' . $this->httpError ); } return parent::render( ); } }