如何从锂创下的所有实体删除特定的领域?(How do you remove specific fie

2019-10-30 10:13发布

我使用MySQL作为我的所有车型数据库连接适配器。 我有个下载模型和控制器与呈现任一种的索引函数HTML表格或CSV根据从请求中传递的类型的文件。 我也有一个CSV媒体类型来处理数据的阵列,其被预期运行(输出数组键作为用于数据的每一行标题然后阵列值)。

我希望做同样的查找查询,但随后删除ID从如果设定的记录字段CSV文件将被渲染。 你会注意到,正在获取下载ID,即使它是不是场阵中,所以简单地改变基于请求类型不会下地干活阵列。

我试图在我的下载控制器的索引动作如下:

<?php
namespace app\controllers;
use app\models\Downloads;

class DownloadsController extends \lithium\action\Controller {

    public function index() {

        // Dynamic conditions
        $conditions = array(...);

        $downloads = Downloads::find('all', array(
            'fields' => array('user_id', 'Surveys.name'),
            'conditions' => $conditions,
            'with' => 'Surveys',
            'order' => array('created' => 'desc')
        ));

        if ($this->request->params['type'] == 'csv') {
            $downloads->each(function ($download) {

                // THIS DOES NOT WORK
                unset($download->id, $download->user_id);

                // I HAVE TRIED THIS HERE AND THE ID FIELDS STILL EXIST
                // var_dump($download->data());
                // exit;

                return $download;
            });
            return $this->render(array('csv' => $downloads->to('array')));
        }

        return compact('downloads');
    }

}
?>

我觉得有一个__unset()当你调用的标准,将被称为实体对象的魔术方法PHP unset()函数在一个实体的领域。

这将是巨大的,如果有一个$recordSet->removeField('field')的功能,但我不能找到一个。

任何帮助将不胜感激。

Answer 1:

也许你应该做的$downloads = $downloads->to('array'); 情况下,迭代与一个for循环阵列,从每一行中删除这些字段,则返回该数组。 如果你必须这样做同样的事情有很多动作,你可以设置一个自定义的媒体处理器,可以改变数据,而无需为它逻辑控制器。

看看这个例子的锂媒体类的单元测试。

您也可以不惜一切通过使用自定义处理程序的在你的控制器,它更逻辑。 这个例子也从数据中的键自动生成一个标题行。

config/bootstrap/media.php

Media::type('csv', 'application/csv', array(
    'encode' => function($data, $handler, $response) {
        $request = $handler['request'];
        $privateKeys = null;
        if ($request->privateKeys) {
            $privateKeys = array_fill_keys($request->privateKeys, true);
        }
        // assuming your csv data is the first key in
        // the template data and the first row keys names
        // can be used as headers
        $data = current($data);
        $row = (array) current($data);
        if ($privateKeys) {
            $row = array_diff_key($row, $privateKeys);
        }
        $headers = array_keys($row);
        ob_start();
        $out = fopen('php://output', 'w');
        fputcsv($out, $headers);
        foreach ($data as $record) {
            if (!is_array($record)) {
                $record = (array) $record;
            }
            if ($privateKeys) {
                $record = array_diff_key($record, $privateKeys);
            }
            fputcsv($out, $record);
        }
        fclose($out);
        return ob_get_clean();
    }
));

控制器:

<?php
namespace app\controllers;
use app\models\Downloads;

class DownloadsController extends \lithium\action\Controller {

    public function index() {

        $this->request->privateKeys = array('id', 'user_id');

        // Dynamic conditions
        $conditions = array(...);

        $downloads = Downloads::find('all', array(
            'fields' => array('user_id', 'Surveys.name'),
            'conditions' => $conditions,
            'with' => 'Surveys',
            'order' => array('created' => 'desc')
        ));

        return compact('downloads');
    }

}
?>


Answer 2:

为什么不那么就动态设置你的$fields阵列?

public function index() {
    $type = $this->request->params['type'];
    //Exclude `user_id` if request type is CSV
    $fields = $type == 'csv' ? array('Surveys.name') : array('user_id', 'Surveys.name');
    $conditions = array(...);
    $with = array('Surveys');
    $order = array('created' => 'desc');

    $downloads = Downloads::find('all', compact('conditions', 'fields', 'with', 'order'));
    //Return different render type if CSV
    return $type == 'csv' ? $this->render(array('csv' => $downloads->data())) : compact('downloads');
}

你可以在这个例子中,我如何发送阵列的csv处理程序看,否则它是$downloads即转到视图RecordSet对象。



文章来源: How do you remove specific fields from all entities of a record set in Lithium?