Jump to content

Recommended Posts

I typically implement slim as follows:
 
<?php

use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require '../vendor/autoload.php';

function getConfig() {
    //...
    return $config;
}
$c = new \Slim\Container(['settings' => array_merge([
    'displayErrorDetails'=>true,                // set to false in production
    'addContentLengthHeader'=>false,            // Allow the web server to send the content-length header
    'determineRouteBeforeAppMiddleware'=>true
    ],getConfig())]
);

$c['view'] = function ($c) {
    $view = new \Slim\Views\Twig(__DIR__.'/../src/templates', [
        //'cache' => 'path/to/cache'    // See auto_reload option
        'debug' => true,
        'strict_variables'=> true
    ]);
    $view->addExtension(new \Slim\Views\TwigExtension(
        $c['router'],
        $c['request']->getUri()
    ));
    $view->addExtension(new \Twig_Extension_Debug());
    //$view->getEnvironment()->addGlobal('path', $uri->getPath());  //If desired on all pages
    return $view;
};

$c['someClass'] = function($c) {
    return new \SomeClass($c['settings']['server']);
};
$c['someOtherClass'] = function($c) {
    return new \SomeOtherClass();
};

$app = new \Slim\App($c);

$app->post('/someEndpoint', function (Request $request, Response $response) {
    $rsp=$this->get('someClass')->someMethod([]);   //Returns array with content and HTTP status code.
    return $response->withJson($rsp[0],$rsp[1]);
});

$app->get('/someEndpoint', function (Request $request, Response $response) {/*...*/});
$app->get('/someOtherEndpoint', function (Request $request, Response $response) {/*...*/});

$app->add(function(Request $request, Response $response, $next) {
    //Add middleware
});

$app->run();
I know need an endpoint which based on a ContentType parameter will either render a page which contains text obtained from another API or will download a file based on this other API, and am using the following:
 
$app->get('/guids/{guid}/logs/{id:[0-9]+}', function (Request $request, Response $response, $args) {
    switch($request->getQueryParam('ContentType')) {
        case 'text':
            return $this->view->render($response, 'log.html', [
                'server'=>$this->get('base')->getServer(),
                'menu_main'=>$this->get('base')->getMenu('/guids'),
                'backupDate'=>$this->get('base')->restApi('get', _VER_.'/backup')[0],
                'content'=>$this->get('base')->restApi('get', _VER_."/guids/$args[guid]/logs/$args[id]",['ContentType'=>'text'])[0],
            ]);
            break;
        case 'file':
            $config=$this->get('settings')['server'];
            $query=$request->getUri()->getQuery();
            $query=$query?"?$query":null;
            $url=$config['ip']._VER_."/guids/$args[guid]/logs/$args[id]$query";
            $context = stream_context_create(['http'=>['header'=>'X-User-Key: '.$config['key']]]);
            $fh = fopen($url, 'rb', false, $context);  //r or rb?
            $stream = new \Slim\Http\Stream($fh);
            $headers = $stream->getMetadata()['wrapper_data'];
            $forwardHeader=[
                'Content-Description'=>'File Transfer',
                'Content-Type'=>'application/octet-stream',
                'Content-Transfer-Encoding'=>'binary',
                'Content-Disposition'=>'attachment; filename="replaced_name"',
                'Expires'=>0,
                'Cache-Control'=>'must-revalidate, post-check=0, pre-check=0',
                'Pragma'=>'public',
                'Content-Length'=>false,   //Possible to get stream length?
            ];
            foreach ($headers as $header) {
                $header=explode(':',$header);
                if($header && count($header)==2 && isset($forwardHeader[$header[0]])){
                    //Should I really be modifying the $response?
                    $response=$response->withHeader($header[0],trim($header[1]));
                    unset($forwardHeader[$header[0]]);
                }
            }
            //Is this necessary?
            foreach ($forwardHeader as $key=>$value) {
                if($value!==false){
                    $response=$response->withHeader($key,$value);
                }
            }
            return $response->withBody($stream);
            break;
        default:
            return $response->withJson('Invalid requested content type',422);
    }
});

To improve readability, I desire my endpoint scripts to be very concise as shown in my previous script, and perhaps I need need to use this script for other endpoints, so I wish to more it to a separate method.  I guess I could (and maybe should) make a separate class with a single method, but I was trying to move it to another function in the container instead and am having issues.  I was thinking of something like the following:

$c['ContentType'] = function ($c) {
    return function($request, $response, $args) {
        switch($request->getQueryParam('ContentType')) {
            case 'text':
                return $this->view->render($response, 'log.html', [
                    //....
                ]);
                break;
            case 'file':
                //....
                return $response->withBody($stream);
                break;
            default:
                return $response->withJson('Invalid requested content type',422);
        }
    };
};

$app->get('/guids/{guid}/logs/{id:[0-9]+}', function (Request $request, Response $response, $args) {
    return $this->ContentType($request, $response, $args);
});

However, no matter what I tried, I either find that ContentType is not a valid method or that I am trying to pass one parameter instead of the expected three to it.  How can this be implemented?

 

Thanks

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.