質問

In my Controller I have a function called get which sends the client a file. When a user clicks a link which calls the get function it works properly. I have another function called get_veeva which first downloads the file from veeva to the server, then calls the get function to send the file to the user. This does not work properly. get_veeva downloads the file correctly, calls get, but the user doesn't receive the file, instead I just get a blank page. I know the file permissions and ownership are not the problem as I've tested by hardcoding the veeva files to the media class params in get and hitting get directly using the first method. Neither function has a View. Here are the two functions:

function get($name, $ext, $original_name, $mime)
{
    $this->viewClass = 'Media';
    $params = array(
        'id' => sprintf("%s.%s", $name, $ext),
        'name' => basename($original_name, '.' . $ext),
        'download' => true,
        'ext' => $ext,
        'mimeType' => $mime,
        'path' => APP . "webroot/uploads" . DS
    );
    $this->set($params);
}

public function get_veeva($id = null)
{
    $this->autoRender = false;

    $asset = $this->Asset->findById($id);
    $vault = $asset['VeevaVault'];

    App::import('Vendor', 'phpVeeva', array('file' => 'veeva' . DS . 'veeva.php'));
    $veeva = new phpVeeva();

    $file = $veeva->getVeevaAsset($vault['veeva_id'], $vault['title']);
    $filename = $file['filename'];
    $ext = $filename['ext'];
    $mime = $filename['mime'];

    $this->get($filename, $ext, $filename, $mime);
}

Here is the getVeevaAsset function which downloads the file:

public function getVeevaAsset($id, $filename)
{
    $this->Auth();

    $url = self::VVURL . "/objects/documents/" . $id . "/file";

    set_time_limit(0);

    $path = APP . 'webroot/uploads/';
    $info = $this->getInfo($id);
    $mime = $info['format__v'];
    $ext = $this->extensions[$mime];

    $fullFilename = $filename . "." . $ext;
    $uri = $path . $fullFilename;

    $fp = fopen($uri, 'w+');

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
    curl_setopt($ch, CURLOPT_TIMEOUT, 50);
    curl_setopt($ch, CURLOPT_FILE, $fp);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-type: application/json;charset=UTF-8", "Authorization: ".$this->sessID));
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

    $json_response = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    if($status != 200)
    {
      die('Error:  call to URL $url failed with status "' . $status .'", response "' . $json_response. '", curl_error "' . curl_error($curl) . '", curl_errno "'  . curl_errno($curl). '"');
    }
    curl_close($ch);
    fclose($fp);

    chmod($uri, 0777);

    $file['path'] = $path;
    $file['filename'] = $filename;
    $file['ext'] = $ext;
    $file['mime'] = $mime;

    return $file;
}

I'm thinking either there's something happening in the getVeevaAsset function which doesn't let the get run properly (The download script is interfering with the mediaclass transfer?). Or the get function only runs properly if it is called directly by a user and not by another function. But these are just guesses. I can't use CakeResponse because I'm running Cake version 2.2.5.

I need to get this working for my client really soon so if anybody can help I'd really appreciate it.

役に立ちましたか?

解決

When disabling auto-rendering ($this->autoRender = false;) you have to call Controller::render() at some point.

public function get_veeva($id = null)
{
    $this->autoRender = false;

    // ...

    $this->get($filename, $ext, $filename, $mime);

    $this->render();
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top