public function handleItem($gridField, $request)
 {
     $controller = $gridField->getForm()->Controller();
     $record = $gridField->getList()->byId($request->param("ID"));
     $handler = Object::create('GridFieldExpandableForm_ItemRequest', $gridField, $this, $record, $controller, 'DetailForm', $this->formorfields);
     return $handler->handleRequest($request, DataModel::inst());
 }
 /**
  * @test
  */
 public function form_appears_and_saves()
 {
     Config::inst()->update('Controller', 'extensions', array('QuickFeedbackExtension'));
     $controller = new TestController();
     $result = $controller->handleRequest(new SS_HTTPRequest('GET', 'form_appears_and_saves'), DataModel::inst());
     $body = $result->getBody();
     $this->assertContains('Form_QuickFeedbackForm', $body);
     $this->assertContains('Form_QuickFeedbackForm_Rating', $body);
     $this->assertContains('Form_QuickFeedbackForm_Comment', $body);
     preg_match('/action="([^"]+)"/', $body, $action);
     if (!count($action)) {
         $this->fail('No form action');
     }
     preg_match('/name="SecurityID" value="([^"]+)"/', $body, $token);
     if (!count($action)) {
         $this->fail('No token');
     }
     $parts = explode('/', $action[1]);
     $action = end($parts);
     $time = time();
     $data = ['SecurityID' => $token[1], 'Rating' => '0', 'Comment' => 'comment at ' . $time];
     $controller->handleRequest(new SS_HTTPRequest('POST', $action, array(), $data), DataModel::inst());
     $existing = Feedback::get()->filter('Comment', 'comment at ' . $time)->first();
     if (!$existing) {
         $this->fail('Record missing');
     }
 }
 protected function fireSilverstripeCommand($url)
 {
     $this->bootSilverstripe($url);
     $_SERVER['REQUEST_URI'] = BASE_URL . '/' . $url;
     // Direct away - this is the "main" function, that hands control to the appropriate controller
     \Director::direct($url, \DataModel::inst());
 }
 public function addfield($gridField, $request)
 {
     $controller = $gridField->getForm()->Controller();
     $record = singleton('MetadataField');
     $handler = Object::create('MetaDataFieldAddForm_ItemRequest', $gridField, $this, $record, $controller, $this->name);
     $handler->setTemplate($this->template);
     return $handler->handleRequest($request, DataModel::inst());
 }
 public function handleManagePresentation(SS_HTTPRequest $r)
 {
     if ($presentation = Presentation::get()->byID($r->param('ID'))) {
         $request = PresentationAPI_PresentationRequest::create($presentation, $this);
         return $request->handleRequest($r, DataModel::inst());
     }
     return $this->httpError(404, "Presentation " . $r->param('ID') . " not found");
 }
 /**
  * Tests to make sure short codes get translated to full paths.
  *
  */
 public function testRedirectingMapping()
 {
     DocumentationPermalinks::add(array('foo' => 'en/framework/subfolder/foo', 'bar' => 'en/cms/bar'));
     $this->autoFollowRedirection = false;
     $v = new DocumentationViewer();
     $response = $v->handleRequest(new SS_HTTPRequest('GET', 'foo'), DataModel::inst());
     $this->assertEquals('301', $response->getStatusCode());
     $this->assertContains('en/framework/subfolder/foo', $response->getHeader('Location'));
 }
 /**
  * @depends testSerializeWithExtraData
  * @covers \Heystack\Core\State\Traits\DataObjectSerializableTrait::unserialize
  */
 public function testUnserializeWithExtraData($data)
 {
     $t = $this->getMockForAbstractClass(__NAMESPACE__ . '\\TestDataObjectSerializableTraitWithExtraData');
     $t->expects($this->once())->method('setExtraData')->with(['test' => true]);
     $t->unserialize($data);
     $this->assertAttributeEquals(get_class($t), 'class', $t);
     $this->assertAttributeEquals(['test' => true], 'record', $t);
     $this->assertAttributeEquals(\DataModel::inst(), 'model', $t);
 }
 /**
  * @covers \Heystack\Ecommerce\Controller\InputController::__construct
  */
 public function testProcessDoesProduceExpectedOutput()
 {
     $controller = new InputController($inputMock = $this->getMock('Heystack\\Core\\Input\\Handler'), $outptuMock = $this->getMock('Heystack\\Core\\Output\\Handler'));
     $request = new \SS_HTTPRequest('GET', '/input/process/test/');
     $inputMock->expects($this->once())->method('process')->with('test', $request)->will($this->returnValue(['success' => true]));
     $outptuMock->expects($this->once())->method('process')->with('test', $controller, ['success' => true])->will($this->returnValue('yay'));
     $response = $controller->handleRequest($request, \DataModel::inst());
     $this->assertEquals('yay', $response->getBody());
 }
 /**
  * @return string
  */
 public function process()
 {
     if ($this->siteUrl) {
         ob_start();
         Director::direct($this->url, \DataModel::inst());
         return ob_get_clean();
     } else {
         return @file_get_contents($this->url);
     }
 }
 /**
  *	Retrieve the correct error page for the current multisite instance.
  *	@param integer
  *	@param SS_HTTPRequest
  *	@throws SS_HTTPResponse_Exception
  */
 public function onBeforeHTTPError($code, $request)
 {
     $errorPage = ErrorPage::get()->filter(array('ErrorCode' => $code, 'SiteID' => Multisites::inst()->getCurrentSiteId()))->first();
     if ($errorPage) {
         Requirements::clear();
         Requirements::clear_combined_files();
         $response = ModelAsController::controller_for($errorPage)->handleRequest($request, DataModel::inst());
         throw new SS_HTTPResponse_Exception($response, $code);
     }
 }
 public function testTemplateFunctionsForOtherSteps()
 {
     $summaryRequest = new SS_HTTPRequest('GET', "summary");
     $this->checkout = new CheckoutPage_Controller();
     $this->checkout->handleRequest($summaryRequest, DataModel::inst());
     //change to summary step
     $this->assertTrue($this->checkout->StepExists('summary'));
     $this->assertFalse($this->checkout->IsPastStep('summary'));
     $this->assertTrue($this->checkout->IsCurrentStep('summary'));
     $this->assertFalse($this->checkout->IsFutureStep('summary'));
     $this->assertFalse($this->checkout->StepExists('nosuchstep'));
 }
 /**
  * @return string
  * @throws \RuntimeException
  */
 public function process()
 {
     $result = $this->getHandleMethod()->invoke(null, $this->request, $this->session, \DataModel::inst());
     if ($result instanceof SS_HTTPResponse) {
         ob_start();
         $result->output();
         return ob_get_clean();
     } elseif (is_string($result)) {
         return $result;
     } else {
         throw new \RuntimeException('Can\'t handle output from request');
     }
 }
 /**
  *
  * @param type $gridField
  * @param type $request
  * @return GridFieldDetailForm_ItemRequest 
  */
 public function handleItem($gridField, $request)
 {
     $controller = $gridField->getForm()->Controller();
     if (is_numeric($request->param('ID'))) {
         $record = $gridField->getList()->byId($request->param("ID"));
     } else {
         $record = Object::create($gridField->getModelClass());
     }
     $class = $this->getItemRequestClass();
     $handler = Object::create($class, $gridField, $this, $record, $controller, $this->name);
     $handler->setTemplate($this->template);
     return $handler->handleRequest($request, DataModel::inst());
 }
 public function handleItem($gridField, $request)
 {
     $controller = $gridField->getForm()->Controller();
     // we can't check on is_numeric, since some datasources use strings as identifiers
     if ($request->param('ID') && $request->param('ID') != 'new') {
         $record = $gridField->getList()->byId($request->param("ID"));
     } else {
         $record = Object::create($gridField->getModelClass());
     }
     $class = $this->getItemRequestClass();
     $handler = Object::create($class, $gridField, $this, $record, $controller, $this->name);
     $handler->setTemplate($this->template);
     return $handler->handleRequest($request, DataModel::inst());
 }
Exemplo n.º 15
0
 /**
  * Get a {@link SS_HTTPResponse} to response to a HTTP error code if an {@link ErrorPage} for that code is present.
  *
  * @param int $statusCode
  * @return SS_HTTPResponse
  */
 public static function response_for($statusCode)
 {
     // first attempt to dynamically generate the error page
     if ($errorPage = DataObject::get_one('ErrorPage', "\"ErrorCode\" = {$statusCode}")) {
         return ModelAsController::controller_for($errorPage)->handleRequest(new SS_HTTPRequest('GET', ''), DataModel::inst());
     }
     // then fall back on a cached version
     $cachedPath = self::get_filepath_for_errorcode($statusCode, class_exists('Translatable') ? Translatable::get_current_locale() : null);
     if (file_exists($cachedPath)) {
         $response = new SS_HTTPResponse();
         $response->setStatusCode($statusCode);
         $response->setBody(file_get_contents($cachedPath));
         return $response;
     }
 }
/**
 * @param string $dataClass
 * @param array $row
 * @return null|\DataObject
 */
function createDataObject($dataClass, $row)
{
    $model = \DataModel::inst();
    if (empty($row['RecordClassName'])) {
        $row['RecordClassName'] = $row['ClassName'];
    }
    if (class_exists($row['RecordClassName'])) {
        $item = \Injector::inst()->create($row['RecordClassName'], $row, false, $model);
    } elseif ($this->dataClass) {
        $item = \Injector::inst()->create($dataClass, $row, false, $model);
    } else {
        return null;
    }
    return $item;
}
 public function handleAddSection($grid, $request)
 {
     $class = $request->param('ClassName');
     if (!is_subclass_of($class, 'MemberProfileSection')) {
         return new SS_HTTPResponse('An invalid section type was specified', 404);
     }
     if (!array_key_exists($class, $this->getAddableSections($grid))) {
         return new SS_HTTPResponse('The section already exists', 400);
     }
     $handler = $this->getItemRequestClass();
     $record = $class::create();
     $handler = $handler::create($grid, $this, $record, $grid->getForm()->Controller(), $this->name);
     $handler->setTemplate($this->template);
     return $handler->handleRequest($request, DataModel::inst());
 }
 public function testOpenSearchControllerAccessible()
 {
     $c = new DocumentationOpenSearchController();
     $response = $c->handleRequest(new SS_HTTPRequest('GET', ''), DataModel::inst());
     $this->assertEquals(404, $response->getStatusCode());
     Config::inst()->update('DocumentationSearch', 'enabled', false);
     $response = $c->handleRequest(new SS_HTTPRequest('GET', 'description/'), DataModel::inst());
     $this->assertEquals(404, $response->getStatusCode());
     // test we get a response to the description. The meta data test will
     // check that the individual fields are valid but we should check urls
     // are there
     Config::inst()->update('DocumentationSearch', 'enabled', true);
     $response = $c->handleRequest(new SS_HTTPRequest('GET', 'description'), DataModel::inst());
     $this->assertEquals(200, $response->getStatusCode());
     $desc = new SimpleXMLElement($response->getBody());
     $this->assertEquals(2, count($desc->Url));
 }
Exemplo n.º 19
0
 public function handleItem($gridField, $request)
 {
     $controller = $gridField->getForm()->Controller();
     //resetting datalist on gridfield to ensure edited object is in list
     //this was causing errors when the modified object was no longer in the results
     $list = $gridField->getList();
     $list = $list->setDataQuery(new DataQuery($list->dataClass()));
     if (is_numeric($request->param('ID'))) {
         $record = $list->byId($request->param("ID"));
     } else {
         $record = Object::create($gridField->getModelClass());
     }
     $class = $this->getItemRequestClass();
     $handler = Object::create($class, $gridField, $this, $record, $controller, $this->name);
     $handler->setTemplate($this->template);
     return $handler->handleRequest($request, DataModel::inst());
 }
 public function testTemplateFunctions()
 {
     //put us at the first step index == membership
     $this->checkout->handleRequest(new SS_HTTPRequest('GET', ""), DataModel::inst());
     $this->assertFalse($this->checkout->IsPastStep('membership'));
     $this->assertTrue($this->checkout->IsCurrentStep('membership'));
     $this->assertFalse($this->checkout->IsFutureStep('membership'));
     $this->checkout->NextStepLink();
     $this->assertFalse($this->checkout->IsPastStep('contactdetails'));
     $this->assertFalse($this->checkout->IsCurrentStep('contactdetails'));
     $this->assertTrue($this->checkout->IsFutureStep('contactdetails'));
     $this->checkout->handleRequest(new SS_HTTPRequest('GET', "summary"), DataModel::inst());
     //change to summary step
     $this->assertFalse($this->checkout->IsPastStep('summary'));
     $this->assertTrue($this->checkout->IsCurrentStep('summary'));
     $this->assertFalse($this->checkout->IsFutureStep('summary'));
 }
Exemplo n.º 21
0
 /**
  * Get a {@link SS_HTTPResponse} to response to a HTTP error code if an
  * {@link ErrorPage} for that code is present. First tries to serve it 
  * through the standard SilverStripe request method. Falls back to a static
  * file generated when the user hit's save and publish in the CMS
  *
  * @param int $statusCode
  *
  * @return SS_HTTPResponse
  */
 public static function response_for($statusCode)
 {
     // first attempt to dynamically generate the error page
     $errorPage = ErrorPage::get()->filter(array("ErrorCode" => $statusCode))->first();
     if ($errorPage) {
         Requirements::clear();
         Requirements::clear_combined_files();
         return ModelAsController::controller_for($errorPage)->handleRequest(new SS_HTTPRequest('GET', ''), DataModel::inst());
     }
     // then fall back on a cached version
     $cachedPath = self::get_filepath_for_errorcode($statusCode, class_exists('Translatable') ? Translatable::get_current_locale() : null);
     if (file_exists($cachedPath)) {
         $response = new SS_HTTPResponse();
         $response->setStatusCode($statusCode);
         $response->setBody(file_get_contents($cachedPath));
         return $response;
     }
 }
 function makeRequest($config, $controller, $url)
 {
     Injector::inst()->load($config);
     // Just doing the following in the test results in two disparate ControllerPolicyRequestFilters: one for the
     // controller, and another for the RequestProcessor - even though it should be injected as a singleton. This
     // prevents us from actually testing anything because our policy is wiped out (am I missing something?).
     // $response = $this->get('CachingPolicy_Controller/test');
     // Instead construct the request pipeline manually. It's ugly, but it works.
     $filter = Injector::inst()->get('ControllerPolicyRequestFilter');
     $processor = Injector::inst()->get('RequestProcessor');
     $processor->setFilters(array($filter));
     // Excercise the controller.
     $controller = Injector::inst()->create($controller);
     $controller->setRequestFilter($filter);
     $controller->extend('onAfterInit');
     $request = new SS_HTTPRequest('GET', 'CachingPolicy_Controller/test');
     $response = new SS_HTTPResponse();
     $processor->postRequest($request, $response, DataModel::inst());
     return $response;
 }
Exemplo n.º 23
0
 /**
  * @return SS_HTTPResponse
  */
 public function onBeforeInit()
 {
     $config = SiteConfig::current_site_config();
     // If Maintenance Mode is Off, skip processing
     if (!$config->MaintenanceMode) {
         return;
     }
     // Check if the visitor is Admin OR if they have an allowed IP.
     if (Permission::check('VIEW_SITE_MAINTENANCE_MODE') || Permission::check('ADMIN') || $this->hasAllowedIP()) {
         return;
     }
     // Are we already on the UtilityPage? If so, skip processing.
     if ($this->owner instanceof UtilityPage_Controller) {
         return;
     }
     // Fetch our utility page instance now.
     /**
      * @var Page $utilityPage
      */
     $utilityPage = UtilityPage::get()->first();
     if (!$utilityPage) {
         return;
     }
     // We need a utility page before we can do anything.
     // Are we configured to prevent redirection to the UtilityPage URL?
     if ($utilityPage->config()->DisableRedirect) {
         // Process the request internally to ensure that the URL is maintained
         // (instead of redirecting to the maintenance page's URL) and skip any further processing.
         $controller = ModelAsController::controller_for($utilityPage);
         $response = $controller->handleRequest(new SS_HTTPRequest('GET', ''), DataModel::inst());
         HTTP::add_cache_headers($response);
         $response->output();
         die;
     }
     // Default: Skip any further processing and immediately respond with a redirect to the UtilityPage.
     $response = new SS_HTTPResponse();
     $response->redirect($utilityPage->AbsoluteLink(), 302);
     HTTP::add_cache_headers($response);
     $response->output();
     die;
 }
 /**
  * Handles the request for an item
  * @param {GridField} $gridField Grid Field reference
  * @param {SS_HTTPRequest} $request HTTP Request
  * @return {mixed} Returns the result of handleRequest on the item request handler
  */
 public function handleItem($gridField, $request)
 {
     $controller = $gridField->getForm()->Controller();
     if (is_numeric($request->param('ID'))) {
         $record = $gridField->getList()->byId($request->param("ID"));
     } else {
         if ($request->getVar('ItemType')) {
             if ($request->getVar('ItemType') == $gridField->getModelClass() || is_subclass_of($request->getVar('ItemType'), $gridField->getModelClass())) {
                 $record = Object::create($request->getVar('ItemType'));
             } else {
                 user_error('Class ' . $request->getVar('ItemType') . ' is not a sub class of ' . $gridField->getModelClass(), E_USER_ERROR);
             }
         } else {
             user_error('No item type selected', E_USER_ERROR);
         }
     }
     $class = $this->getItemRequestClass();
     $handler = Object::create($class, $gridField, $this, $record, $controller, $this->name);
     $handler->setTemplate($this->template);
     return $handler->handleRequest($request, DataModel::inst());
 }
 /**
  *	Display an error page on invalid request.
  *
  *	@parameter <{ERROR_CODE}> integer
  *	@parameter <{ERROR_MESSAGE}> string
  */
 public function httpError($code, $message = null)
 {
     // Determine the error page for the given status code.
     $errorPages = ClassInfo::exists('SiteTree') ? ErrorPage::get()->filter('ErrorCode', $code) : null;
     // Allow extension customisation.
     $this->extend('updateErrorPages', $errorPages);
     // Retrieve the error page response.
     if ($errorPages && ($errorPage = $errorPages->first())) {
         Requirements::clear();
         Requirements::clear_combined_files();
         $response = ModelAsController::controller_for($errorPage)->handleRequest(new SS_HTTPRequest('GET', ''), DataModel::inst());
         throw new SS_HTTPResponse_Exception($response, $code);
     } else {
         if ($errorPages && file_exists($cachedPage = ErrorPage::get_filepath_for_errorcode($code, class_exists('Translatable') ? Translatable::get_current_locale() : null))) {
             $response = new SS_HTTPResponse();
             $response->setStatusCode($code);
             $response->setBody(file_get_contents($cachedPage));
             throw new SS_HTTPResponse_Exception($response, $code);
         } else {
             return parent::httpError($code, $message);
         }
     }
 }
Exemplo n.º 26
0
 /** 
  * Handles a request for a {@link DashboardPanel} object. Can be a new record or existing
  *
  * @param SS_HTTPRequest The current request
  * @return SS_HTTPResponse
  */
 public function handlePanel(SS_HTTPRequest $r)
 {
     if ($r->param('ID') == "new") {
         $class = $r->getVar('type');
         if ($class && class_exists($class) && is_subclass_of($class, "DashboardPanel")) {
             $panel = new $class();
             if ($panel->canCreate()) {
                 $panel->MemberID = Member::currentUserID();
                 $panel->Title = $panel->getLabel();
                 $panel->write();
             } else {
                 $panel = null;
             }
         }
     } else {
         $panel = DashboardPanel::get()->byID((int) $r->param('ID'));
     }
     if ($panel && ($panel->canEdit() || $panel->canView())) {
         $requestClass = $panel->getRequestHandlerClass();
         $handler = Object::create($requestClass, $this, $panel);
         return $handler->handleRequest($r, DataModel::inst());
     }
     return $this->httpError(404);
 }
Exemplo n.º 27
0
 function testFieldMessageEscapeHtml()
 {
     $form = $this->getStubForm();
     $form->Controller()->handleRequest(new SS_HTTPRequest('GET', '/'), DataModel::inst());
     // stub out request
     $form->addErrorMessage('key1', '<em>Escaped HTML</em>', 'good', true);
     $form->setupFormErrors();
     $parser = new CSSContentParser($result = $form->forTemplate());
     $messageEls = $parser->getBySelector('#Form_Form_key1_Holder .message');
     $this->assertContains('&lt;em&gt;Escaped HTML&lt;/em&gt;', $messageEls[0]->asXML());
     $form = $this->getStubForm();
     $form->Controller()->handleRequest(new SS_HTTPRequest('GET', '/'), DataModel::inst());
     // stub out request
     $form->addErrorMessage('key1', '<em>Unescaped HTML</em>', 'good', false);
     $form->setupFormErrors();
     $parser = new CSSContentParser($form->forTemplate());
     $messageEls = $parser->getBySelector('#Form_Form_key1_Holder .message');
     $this->assertContains('<em>Unescaped HTML</em>', $messageEls[0]->asXML());
 }
Exemplo n.º 28
0
 /**
  * Return the first item matching the given query.
  * All calls to get_one() are cached.
  *
  * @param string $callerClass The class of objects to be returned
  * @param string $filter A filter to be inserted into the WHERE clause
  * @param boolean $cache Use caching
  * @param string $orderby A sort expression to be inserted into the ORDER BY clause.
  *
  * @return DataObject The first item matching the query
  */
 public static function get_one($callerClass, $filter = "", $cache = true, $orderby = "")
 {
     $SNG = singleton($callerClass);
     $cacheKey = "{$filter}-{$orderby}";
     if ($extra = $SNG->extend('cacheKeyComponent')) {
         $cacheKey .= '-' . implode("-", $extra);
     }
     $cacheKey = md5($cacheKey);
     // Flush destroyed items out of the cache
     if ($cache && isset(DataObject::$_cache_get_one[$callerClass][$cacheKey]) && DataObject::$_cache_get_one[$callerClass][$cacheKey] instanceof DataObject && DataObject::$_cache_get_one[$callerClass][$cacheKey]->destroyed) {
         DataObject::$_cache_get_one[$callerClass][$cacheKey] = false;
     }
     if (!$cache || !isset(DataObject::$_cache_get_one[$callerClass][$cacheKey])) {
         $dl = DataList::create($callerClass)->where($filter)->sort($orderby);
         $dl->setDataModel(DataModel::inst());
         $item = $dl->First();
         if ($cache) {
             DataObject::$_cache_get_one[$callerClass][$cacheKey] = $item;
             if (!DataObject::$_cache_get_one[$callerClass][$cacheKey]) {
                 DataObject::$_cache_get_one[$callerClass][$cacheKey] = false;
             }
         }
     }
     return $cache ? DataObject::$_cache_get_one[$callerClass][$cacheKey] : $item;
 }
Exemplo n.º 29
0
        return $reloadToken->reloadWithToken();
    }
    // Fail and redirect the user to the login page
    $loginPage = Director::absoluteURL(Config::inst()->get('Security', 'login_url'));
    $loginPage .= "?BackURL=" . urlencode($_SERVER['REQUEST_URI']);
    header('location: ' . $loginPage, true, 302);
    die;
})->thenIfErrored(function () use($reloadToken) {
    if ($reloadToken) {
        $reloadToken->reloadWithToken();
    }
})->execute();
global $databaseConfig;
// Redirect to the installer if no database is selected
if (!isset($databaseConfig) || !isset($databaseConfig['database']) || !$databaseConfig['database']) {
    if (!file_exists(BASE_PATH . '/install.php')) {
        header($_SERVER['SERVER_PROTOCOL'] . " 500 Server Error");
        die('SilverStripe Framework requires a $databaseConfig defined.');
    }
    $s = isset($_SERVER['SSL']) || isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off' ? 's' : '';
    $installURL = "http{$s}://" . $_SERVER['HTTP_HOST'] . BASE_URL . '/install.php';
    // The above dirname() will equate to "\" on Windows when installing directly from http://localhost (not using
    // a sub-directory), this really messes things up in some browsers. Let's get rid of the backslashes
    $installURL = str_replace('\\', '', $installURL);
    header("Location: {$installURL}");
    die;
}
// Direct away - this is the "main" function, that hands control to the appropriate controller
DataModel::set_inst(new DataModel());
Director::direct($url, DataModel::inst());
 /**
  * Handles a request for a record in the table
  *
  * @param SS_HTTPRequest
  * @return SS_HTTPResponse
  */
 public function handleItem(SS_HTTPRequest $r)
 {
     if ($r->param('ID') == "new") {
         $item = Object::create($this->relationClass);
     } else {
         $item = DataList::create($this->relationClass)->byID((int) $r->param('ID'));
     }
     if ($item) {
         $handler = DashboardHasManyRelationEditor_ItemRequest::create($this->controller->getDashboard(), $this->controller, $this, $item);
         return $handler->handleRequest($r, DataModel::inst());
     }
     return $this->httpError(404);
 }