【问题标题】:Yii framework - multiple downloadYii 框架 - 多重下载
【发布时间】:2015-05-06 09:41:36
【问题描述】:

我正在使用 Yii 框架开发一个数据库接口。我有一个名为 take 的表,用于存储音频文件。我在索引页面中添加了高级搜索和一个下载搜索结果的所有文件的链接,如下:

<?php
/* @var $this takeController */
/* @var $dataProvider CActiveDataProvider */

$this->breadcrumbs=array(
    'Takes',
);

$this->menu=array(
    array('label'=>'Create take', 'url'=>array('create')),
    array('label'=>'Create multiple take', 'url'=>array('create_multiple')),
    array('label'=>'Manage take', 'url'=>array('admin')),
);
Yii::app()->clientScript->registerScript('search', "
$('.search-button').click(function(){
    $('.search-form').toggle();
    return false;
});
$('.search-form form').submit(function(){

    $.fn.yiiListView.update('takelistview', { 

        data: $(this).serialize()
    });

    return false;
});
");
?>

<h1>Takes</h1>

<?php echo CHtml::link('Advanced Search','#',array('class'=>'search-button')); ?>
<div class="search-form" style="display:none">
<?php  $this->renderPartial('_search',array(
    'model'=>$model,
)); ?>
</div>

<?php $this->widget('zii.widgets.CListView', array(
    'dataProvider'=>$dataProvider,
    'itemView'=>'_view',
    'id'=>'takelistview',
    'sortableAttributes'=>array('id', 'data', 'take_mono_nf_id', 'take_mono_ff_id')
)); ?>

<?php echo CHtml::link('Download all','#',array('class'=>'download-button')); ?>

<form style="display: hidden" action="index.php?r=take/download_several" method="POST" id="form">

</form>
<script>
    $('.download-button').click(function(){
        var i = 0;
        var indexes = [];   
        while($.fn.yiiListView.getKey('takelistview', i)){
            indexes[i] = $.fn.yiiListView.getKey('takelistview', i);

            var newdiv = document.createElement('div');
            newdiv.innerHTML = '<input type="hidden" id="indexes" name="indexes[]" value="'+indexes[i]+'"/>';
            document.getElementById('form').appendChild(newdiv);            
            i++;
        }
        newdiv = document.createElement('div');
        //newdiv.innerHTML = '<input type="hidden" id="folder" name="folder" value="'+folder+'"/>';
        document.getElementById('form').appendChild(newdiv);    
        //$("#indexes").val(indexes);
        $("#form").submit();

    });

</script>

在控制器文件中,download_several 操作会创建一个 zip 文件并下载它:

public function actionDownload_several(){
        $indexes = $_POST['indexes'];       
        $zip = new ZipArchive();
        $zip_name = "files.zip"; // Zip name
        $zip->open($zip_name,  ZipArchive::CREATE);     

        foreach($indexes as $i){
            /* query to retrieve the file name starting from the index */
            $file = Yii::app()->basePath.'/../data/'.$name.'/takes/'.$filename;
            $zip->addFromString(basename($file),  file_get_contents($file)); 
            //file_put_contents($folder.$file, file_get_contents($myfile));     //provare ftp_nb_get
        }
        $zip->close();
        header('Content-Type: application/zip');
        header('Content-disposition: attachment; filename='.$zip_name);
        header('Content-Length: ' . filesize($zip_name));
        readfile($zip_name);
        unlink($zip_name);
    }

问题如下。在视图页面中,高级搜索的结果被分成页面。当我按下“全部下载”链接时,只会下载当前页面中的文件。 我想下载所有结果。我很确定问题出在$.fn.yiiListView,但我不知道要改变什么。

【问题讨论】:

    标签: php yii


    【解决方案1】:

    所以函数$.fn.yiiListView.getKey()只返回当前html的索引:

    /**
     * Returns the key value for the specified row
     * @param id string the ID of the list view container
     * @param index integer the zero-based index of the data item
     * @return string the key value
     */
    $.fn.yiiListView.getKey = function(id, index) {
            return $('#'+id+' > div.keys > span:eq('+index+')').text();
    };
    

    分页阻止函数获取所有键,因为它没有加载到页面上。

    要获取所有数据,您需要在视图中使用 html 发送所有索引。例如在 js array 这样的:

    <script>    
    var allIndexes = [<?php echo '"'.implode('","', $allIndexes).'"' ?>]; //creates js array from php array
    </script> 
    

    上面的脚本将 PHP 数组 $allIndexes 中的值回显到 js var allIndexes

    现在您需要获取$allIndexes PHP 数组中的索引。 您可以在Controller 中执行此操作。

    例如:

    $criteria = ... // create your criteria to only get the id's consistent with your ListView
    $allIndexes = Take::model()->findAll($criteria); //if Take is your model name.
    

    现在只在您创建的downloadAll onclick() 函数中发布来自allIndexes js array 的所有索引,它应该会下载所有内容。

    祝你好运!

    -- 编辑--

    每次单击“下一页”时,takes 都会更新为数据库的当前状态。

    我建议您在此活动中更新您的js array,这样一切都始终是最新且一致的。

    【讨论】:

    • 您好,非常感谢您的回答。我不明白最后两行代码。如果我没记错的话,在高级搜索后加载索引页面时,我必须检索搜索条件并调用 findAll() 方法。但是如何检索条件?
    • 它们在您使用的$dataProvider 中:docs 在您的 CListView 小部件中。从您的视图来看,您正在 Controller 中创建它们
    • 好吧,回顾一下:我从$dataProvider 获取标准,然后使用findAll() 查询模型,最后我调用我的函数传递结果索引。正确的?再次感谢
    • 使用criteria 是一个建议。我假设您将takes 存储在某个数据库中,并使用ListView 显示它们。您希望js array 中的takesListView 中的相同。你如何得到它们取决于你,因为我不知道你的应用程序的其余部分是什么样的。所以你可以使用findAll(),也可以不使用,这取决于你:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多