Download Silverstripe 3.2:如何使用按钮强制从CMS下载文件?

Download Silverstripe 3.2:如何使用按钮强制从CMS下载文件?,download,httprequest,httpresponse,silverstripe,Download,Httprequest,Httpresponse,Silverstripe,我在从CMS中单击按钮下载pdf文件时遇到问题。我正在和模块一起工作。按钮本身工作正常,但下载文件时出错。我总是会遇到这样的错误: 加载资源失败:服务器响应状态为500 (第257行的警告) /Applications/MAMP/htdocs/myproject/framework/control/HTTPResponse.php) 及 无法找到类SS_HTTPResponse的[Recoverable Error]对象 转换为字符串 所以我假设这条线 返回SS_HTTPRequest::sen

我在从CMS中单击按钮下载pdf文件时遇到问题。我正在和模块一起工作。按钮本身工作正常,但下载文件时出错。我总是会遇到这样的错误:

加载资源失败:服务器响应状态为500 (第257行的警告) /Applications/MAMP/htdocs/myproject/framework/control/HTTPResponse.php)

无法找到类SS_HTTPResponse的[Recoverable Error]对象 转换为字符串

所以我假设这条线

返回SS_HTTPRequest::send_file($filedata,$fileName), "申请表格(pdf);

$filedata有问题或有问题。。。正确的方法是什么

我的代码:

在我的Dataobject中,我有下载按钮:

private static $better_buttons_actions = array (
            'printFilesPDF'
);

public function getBetterButtonsActions() {
        $fields = parent::getBetterButtonsActions();
        $fields->push(BetterButtonCustomAction::create('printFilesPDF', 'Print files'));
        return $fields;
}

public function printFilesPDF() {

        $filedata = File::find("assets/PDF/myFile.pdf");
        $fileName = "myFile.pdf";
        return SS_HTTPRequest::send_file($filedata, $fileName, 'application/pdf');

}
您希望向send_File函数传递字符串,而不是传递“File”对象

我要换电话

 $filedata = File::find("assets/PDF/myFile.pdf");

但是,最好编写此代码来检查File::find(…)是否返回文件且不为null

您希望向send_File函数传递字符串,而不是传递“File”对象

我要换电话

 $filedata = File::find("assets/PDF/myFile.pdf");

但是,最好编写此代码来检查File::find(…)是否返回文件且不为null

File::find()如果文件存在,则返回文件对象;如果文件不存在,则返回null。它从不返回二进制数据,这就是为什么HTTPResponse不会将其转换为字符串

如果文件\u get\u内容不起作用,请检查您的计算机上是否未禁用该文件

//attempt to find the file
$file = File::find("path/to/my/file.txt");

//you need to check that the file is File and not null
if($file && $file instanceof File) {
    //get the file path
    $path = $file->getFullPath();

    //get the file data. If file_get_contents() doesn't work, you might need fopen() or file() instead
    $fileData = file_get_contents($path);
    $fileName = "myFile.pdf";
    return SS_HTTPRequest::send_file($fileData, $fileName, 'application/pdf');
}
如果文件存在,则返回文件对象;如果文件不存在,则返回null。它从不返回二进制数据,这就是为什么HTTPResponse不会将其转换为字符串

如果文件\u get\u内容不起作用,请检查您的计算机上是否未禁用该文件

//attempt to find the file
$file = File::find("path/to/my/file.txt");

//you need to check that the file is File and not null
if($file && $file instanceof File) {
    //get the file path
    $path = $file->getFullPath();

    //get the file data. If file_get_contents() doesn't work, you might need fopen() or file() instead
    $fileData = file_get_contents($path);
    $fileName = "myFile.pdf";
    return SS_HTTPRequest::send_file($fileData, $fileName, 'application/pdf');
}

我找到了解决办法。这不是最好的,但对我来说很有效

我让文件在新选项卡中打开,以便用户可以自己下载或在浏览器窗口中查看:

首先,我使用
BetterButtonLink
,而不是使用
BetterButtonCustomAction

public function getBetterButtonsActions() {
    $fields = parent::getBetterButtonsActions();
    $fields->push(new BetterButtonLink('Download the file', "assets/myfile.pdf"));
}
通过使用
BetterButtonLink
我面临以下问题: 每次我点击这个按钮,它都会试图通过一个AJAX请求在CMS管理员中打开PDF,结果显示编码文本。您可以在此处找到一个简单的解决方案:

所以我最后的代码是

public function getBetterButtonsActions() {
    $fields = parent::getBetterButtonsActions();
    $fields->push(new BetterButtonLink_NewWindow('Download the file', "assets/myfile.pdf"));
}
以及
BetterButtonLink\u new窗口
code:

class BetterButtonLink_NewWindow extends BetterButtonLink {

    /**
     * Gets the HTML representing the button
     * @return string
     */
    public function getButtonHTML() {
        return sprintf(
            '<a class="ss-ui-button %s" href="%s" target="_blank">%s</a>',
            $this->extraClass(),
            $this->getButtonLink(),
            $this->getButtonText()
        );
    }

}
class BetterButtonLink\u新窗口扩展BetterButtonLink{
/**
*获取表示该按钮的HTML
*@返回字符串
*/
公共函数getButtonHTML(){
回程冲刺(
'',
$this->extraClass(),
$this->getButtonLink(),
$this->getButtonText()
);
}
}

我找到了一个解决方案。这不是最好的,但对我来说很有效

我让文件在新选项卡中打开,以便用户可以自己下载或在浏览器窗口中查看:

首先,我使用
BetterButtonLink
,而不是使用
BetterButtonCustomAction

public function getBetterButtonsActions() {
    $fields = parent::getBetterButtonsActions();
    $fields->push(new BetterButtonLink('Download the file', "assets/myfile.pdf"));
}
通过使用
BetterButtonLink
我面临以下问题: 每次我点击这个按钮,它都会试图通过一个AJAX请求在CMS管理员中打开PDF,结果显示编码文本。您可以在此处找到一个简单的解决方案:

所以我最后的代码是

public function getBetterButtonsActions() {
    $fields = parent::getBetterButtonsActions();
    $fields->push(new BetterButtonLink_NewWindow('Download the file', "assets/myfile.pdf"));
}
以及
BetterButtonLink\u new窗口
code:

class BetterButtonLink_NewWindow extends BetterButtonLink {

    /**
     * Gets the HTML representing the button
     * @return string
     */
    public function getButtonHTML() {
        return sprintf(
            '<a class="ss-ui-button %s" href="%s" target="_blank">%s</a>',
            $this->extraClass(),
            $this->getButtonLink(),
            $this->getButtonText()
        );
    }

}
class BetterButtonLink\u新窗口扩展BetterButtonLink{
/**
*获取表示该按钮的HTML
*@返回字符串
*/
公共函数getButtonHTML(){
回程冲刺(
'',
$this->extraClass(),
$this->getButtonLink(),
$this->getButtonText()
);
}
}
我们可以使用创建指向文件的链接。通过将链接的类设置为
ssui按钮
,我们可以使链接看起来像一个按钮

以下是指向特定文件的示例链接:

LiteralField::create(
    'DownloadLink',
    '<a href="assets/myfile.pdf" target="_blank" class="ss-ui-button" download>Download the file</a>'
);
我们可以使用创建指向文件的链接。通过将链接的类设置为
ssui按钮
,我们可以使链接看起来像一个按钮

以下是指向特定文件的示例链接:

LiteralField::create(
    'DownloadLink',
    '<a href="assets/myfile.pdf" target="_blank" class="ss-ui-button" download>Download the file</a>'
);

每当您收到返回的“500错误”时,您需要切换到开发模式,这将给您一个错误,可能会帮助您解决问题,或者这里的其他人帮助您解决问题。谢谢你这么快回答。我处于开发模式。。单击按钮[Recoverable error]后重新加载页面,发现“real”错误。SS_HTTPResponse类的对象无法转换为字符串。不幸的是,我仍然不知道该怎么办:(…你能帮我吗?@iraira我遇到了同样的问题。你找到解决办法了吗?@csy_dot_io是的,我找到了一个解决办法。我会在家里的时候把它作为一个答案发布。那太好了。非常感谢!每当你遇到“500个错误”返回您需要更改为开发模式,这将给您一个错误,可能会帮助您解决,或者这里的其他人帮助您解决。您好。感谢您这么快回答。我处于开发模式。单击按钮后,在重新加载页面后发现“真实”错误:[可恢复错误]类SS_HTTPResponse的对象无法转换为字符串。遗憾的是,仍然不知道要做什么:(…你能帮我吗?@iraira我遇到了同样的问题。你找到解决方案了吗?@csy_dot_io是的,我找到了一个解决方案。我会在家后将其作为答案发布。那太好了。非常感谢!我尝试了你的解决方案,但仍然得到相同的错误:“SS_HTTPResponse类的对象无法转换为字符串”你能不能先用一个简单的返回进行测试,比如
return SS_HTTPRequest::send_file(“test”,“test.html”,“text/html”);
。只是为了确定错误在哪里。Barrys提示应该可以工作,但你仍然会遇到这个错误,这似乎很奇怪。你使用的是什么SS版本?那么我的com