diff --git a/app/src/Application.php b/app/src/Application.php index c3605652d..dd259775b 100644 --- a/app/src/Application.php +++ b/app/src/Application.php @@ -20,6 +20,8 @@ use Cake\Http\Middleware\CsrfProtectionMiddleware; use Cake\Routing\Middleware\AssetMiddleware; use Cake\Routing\Middleware\RoutingMiddleware; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; /** * Application setup class. @@ -45,13 +47,30 @@ public function middleware($middlewareQueue) { ->add(AssetMiddleware::class) // Add routing middleware. - ->add(new RoutingMiddleware($this)); - - // Enable CSRF protection using Cake v3.5+ approach. - // Initially, we use the default options, except a different CSRF cookie - // name to avoid conflicts with Registry. - $middlewareQueue->add(new CsrfProtectionMiddleware(['cookieName' => 'matchCsrfToken'])); - + ->add(new RoutingMiddleware($this)) + + // Enable CSRF protection using Cake v3.5+ approach. + // Initially, we use the default options, except a different CSRF cookie + // name to avoid conflicts with Registry. Additionally, we don't want CSRF + // checking enabled on API requests (which are stateless and should not be + // called from web browsers). See eg + // https://stackoverflow.com/questions/47714940/cakephp-3-5-6-disable-csrf-middleware-for-controller + // https://stackoverflow.com/questions/51931406/post-requests-for-cakephp-3-api-are-not-working + + ->add(function(ServerRequestInterface $request, + ResponseInterface $response, + callable $next) { + $params = $request->getAttribute('params'); + + if($params['controller'] == 'TierApi') { + // Do not enable CsrfProtectionMiddleware + return $next($request, $response); + } else { + $csrf = new CsrfProtectionMiddleware(['cookieName' => 'matchCsrfToken']); + return $csrf($request, $response, $next); + } + }); + return $middlewareQueue; } } diff --git a/app/src/Controller/StandardController.php b/app/src/Controller/StandardController.php index 5ff2600c4..6d20f08ea 100644 --- a/app/src/Controller/StandardController.php +++ b/app/src/Controller/StandardController.php @@ -182,7 +182,7 @@ public function edit($id) { $this->getPrimaryLink(); // AutoViewVarsTrait - $this->populateAutoViewVars(); + $this->populateAutoViewVars($obj); // Default view title is edit object display field $field = $this->$modelsName->getDisplayField(); @@ -276,6 +276,9 @@ public function index() { // PrimaryLinkTrait $link = $this->getPrimaryLink(); + // AutoViewVarsTrait + $this->populateAutoViewVars(); + if(!empty($link['linkattr'])) { // If a link attribute is defined but no value is provided, then query // where the link attribute is NULL @@ -297,9 +300,10 @@ public function index() { * Populate any auto view variables, as requested via AutoViewVarsTrait. * * @since COmanage Match v1.0.0 + * @param object $obj Current object (eg: from edit), if set */ - protected function populateAutoViewVars() { + protected function populateAutoViewVars(object $obj=null) { // $this->name = Models $modelsName = $this->name; @@ -338,8 +342,16 @@ protected function populateAutoViewVars() { $linkFilter = $this->$modelsName->getPrimaryLink(); if($linkFilter) { + // Try to find the $linkFilter value + $v = null; + + // We might have been passed an object with the current value + if($obj && !empty($obj->$linkFilter)) { + $v = $obj->$linkFilter; + } elseif(!empty($this->request->getQuery($linkFilter))) { + $v = $this->request->getQuery($linkFilter); + } // XXX also need to check getData()? - $v = $this->request->getQuery($linkFilter); if($v) { $query = $query->find($avv['find'], [$linkFilter => $v]); diff --git a/app/src/Template/Standard/index.ctp b/app/src/Template/Standard/index.ctp index 5e8d19bb5..a6a890733 100644 --- a/app/src/Template/Standard/index.ctp +++ b/app/src/Template/Standard/index.ctp @@ -109,6 +109,26 @@ function _column_key($modelsName, $c) { case 'enum': print __('match.en.'.$cfg['class'].'.'.$entity->$col); break; + case 'fk': + // Assuming $col is of the form foo_id, look to see if the corresponding + // AutoViewVar $foos is set, and if so render the lookup value instead + $f = null; + if(preg_match('/^(.*?)_id$/', $col, $f)) { + $avv = \Cake\Utility\Inflector::pluralize($f[1]); + + if(!empty(${$avv}[$entity->$col])) { + // We found the viewar (eg: $foos), and it has a corresponding value + // (eg: $foos[3]), so render it + print ${$avv}[$entity->$col]; // XXX filter_var? + } else { + // No match, just render the value + print $entity->$col; + } + } else { + // Just print the value + print $entity->$col; + } + break; case 'link': print $this->Html->link($entity->$col, ['action' => $primaryAction, $entity->id]); break;