为 SilverStripe 创建自定义 CSV 导入器
Creating a custom CSV importer for SilverStripe
我正在为 SilverStripe 网站构建自定义导入控件,因为不幸的是,将要使用的 CSV 文件格式不正确且无法改进(我们必须使用我们正在使用的给定的,基本上)。这些文件包含 semi-color 分隔的数据,每行是一个条目:
"[ID]";"[First Name]";"[Middle Initial]";"[Last Name]";"[Title]";"[University/College]";"[Specialty]";"[Graduation Date]"
这些值中的任何一个都可以为空(即条目可能没有中间名首字母或可能没有列出的专业)。然后这些字段被标记为一对双引号内的单个 space:
"[ID]";"[First Name]";" ";"[Last Name]";"[Title]";"[University/College]";" ";"[Graduation Date]"
同样重要的是要注意,CSV 文件没有 headers,而且他们不太可能拥有它们。我读过有关 SilverStripe 的 CSVBulkLoader class,但似乎没有 headers 就很难使用它。另外,像我提到的那样,空字段存在问题。
是否可以设置一个文件来破坏 semi-colon 处的 CSV 文件中的数据?这样我就可以在一行中获取每个值,并且可以将它们映射到 SilverStripe 管理模型中的字段。
这是我目前正在处理的管理模型:
<?php
class PhysicianEducationAdmin extends ModelAdmin {
private static $managed_models = array('PhysicianEducation');
private static $url_segment = 'physicianeducation';
private static $menu_title = 'Physician Education Info';
}
<?php
class PhysicianEducation extends DataObject {
private static $db = array(
'ProviderID' => 'varchar',
'FirstName' => 'varchar(250)',
'MiddleName' => 'varchar(250)',
'LastName' => 'varchar(250)',
'Title' => 'varchar(10)',
'Institution' => 'varchar(550)',
'Education' => 'varchar(250)',
'Specialty' => 'varchar(250)',
'EndDate' => 'Date',
);
public static $summary_fields = array(
'ProviderID' => 'Provider ID',
'FirstName' => 'First Name',
'MiddleName' => 'Middle Initial',
'LastName' => 'Last Name',
'Title' => 'Title',
'Institution' => 'Institution',
'Education' => 'Education',
'Specialty' => 'Speciality',
'EndDate' => 'End Date',
);
}
您应该能够使用 fgetcsv() 函数 http://php.net/manual/en/function.fgetcsv.php。
它允许您指定分隔符(对于您的 ';')和附件(对于您的 '"'),这是默认设置。
Silverstripe 包含一个可用于此目的的 CSVParser class。您可以将分隔符作为构造函数的第二个参数传递。由于该文件没有 header 行,您可以使用 provideHeaderRow
函数为其提供一个行。 CSVParser 实现了 Iterator 接口,所以你可以在一个循环中遍历 object:
$physicians = CSVParser::create('myfile.csv', ';');
$physicians->provideHeaderRow(array(...));
foreach($physicians as $physician) {
$pe = PhysicianEducation::create()->update($physician);
$pe->write();
}
您需要向 DataObject 添加一些验证(可能在 onBeforeWrite 中进行一些检查,或者创建 Validator 的子类)以防止创建无效记录(例如空字段)。
我正在为 SilverStripe 网站构建自定义导入控件,因为不幸的是,将要使用的 CSV 文件格式不正确且无法改进(我们必须使用我们正在使用的给定的,基本上)。这些文件包含 semi-color 分隔的数据,每行是一个条目:
"[ID]";"[First Name]";"[Middle Initial]";"[Last Name]";"[Title]";"[University/College]";"[Specialty]";"[Graduation Date]"
这些值中的任何一个都可以为空(即条目可能没有中间名首字母或可能没有列出的专业)。然后这些字段被标记为一对双引号内的单个 space:
"[ID]";"[First Name]";" ";"[Last Name]";"[Title]";"[University/College]";" ";"[Graduation Date]"
同样重要的是要注意,CSV 文件没有 headers,而且他们不太可能拥有它们。我读过有关 SilverStripe 的 CSVBulkLoader class,但似乎没有 headers 就很难使用它。另外,像我提到的那样,空字段存在问题。
是否可以设置一个文件来破坏 semi-colon 处的 CSV 文件中的数据?这样我就可以在一行中获取每个值,并且可以将它们映射到 SilverStripe 管理模型中的字段。
这是我目前正在处理的管理模型:
<?php
class PhysicianEducationAdmin extends ModelAdmin {
private static $managed_models = array('PhysicianEducation');
private static $url_segment = 'physicianeducation';
private static $menu_title = 'Physician Education Info';
}
<?php
class PhysicianEducation extends DataObject {
private static $db = array(
'ProviderID' => 'varchar',
'FirstName' => 'varchar(250)',
'MiddleName' => 'varchar(250)',
'LastName' => 'varchar(250)',
'Title' => 'varchar(10)',
'Institution' => 'varchar(550)',
'Education' => 'varchar(250)',
'Specialty' => 'varchar(250)',
'EndDate' => 'Date',
);
public static $summary_fields = array(
'ProviderID' => 'Provider ID',
'FirstName' => 'First Name',
'MiddleName' => 'Middle Initial',
'LastName' => 'Last Name',
'Title' => 'Title',
'Institution' => 'Institution',
'Education' => 'Education',
'Specialty' => 'Speciality',
'EndDate' => 'End Date',
);
}
您应该能够使用 fgetcsv() 函数 http://php.net/manual/en/function.fgetcsv.php。
它允许您指定分隔符(对于您的 ';')和附件(对于您的 '"'),这是默认设置。
Silverstripe 包含一个可用于此目的的 CSVParser class。您可以将分隔符作为构造函数的第二个参数传递。由于该文件没有 header 行,您可以使用 provideHeaderRow
函数为其提供一个行。 CSVParser 实现了 Iterator 接口,所以你可以在一个循环中遍历 object:
$physicians = CSVParser::create('myfile.csv', ';');
$physicians->provideHeaderRow(array(...));
foreach($physicians as $physician) {
$pe = PhysicianEducation::create()->update($physician);
$pe->write();
}
您需要向 DataObject 添加一些验证(可能在 onBeforeWrite 中进行一些检查,或者创建 Validator 的子类)以防止创建无效记录(例如空字段)。