在 CMS 中通过 CSV 导出产品 table

Export products table via CSV in CMS

我一直在尝试扩展 ProductCatalogAdmin,因为那是保存我要导出的产品的 ModelAdmin。下面的代码在添加到核心代码时工作正常(我不想这样做),但在添加为扩展时无法执行任何操作。

PHP

<?php

class ProductCatalogAdminExtension extends DataExtension {

    public function getExportFields() {
            return array(
                'ID' => 'ID',
                'InternalItemID' => 'InternalItemID',
                'Model' => 'Model',
                'Content' => 'Content',
                'CostPrice' => 'CostPrice',
                'BasePrice' => 'BasePrice',
                'Weight' => 'Weight',
                'Height' => 'Height',
                'Width' => 'Width',
                'Depth' => 'Depth',
                'Featured' => 'Featured',
                'AllowPurchase' => 'AllowPurchase',
                'Popularity' => 'Popularity',
                'PromoActive' => 'PromoActive',
                'PromoDisplay' => 'PromoDisplay',
                'PromoType' => 'PromoType',
                'PromoAmount' => 'PromoAmount',
                'PromoPercent' => 'PromoPercent',
                'PromoStartDate' => 'PromoStartDate',
                'PromoEndDate' => 'PromoEndDate',
                'Image.URL' => 'Image',
                'WholesalePrice' => 'WholesalePrice',
                'ParentID' => 'ParentID',
                'ProductCategory.ID' => 'AdditionalCategories'
            );
    }

}

YML

---
Name: mysite
After:
  - 'framework/*'
  - 'cms/*'
---
# YAML configuration for SilverStripe
# See http://doc.silverstripe.org/framework/en/topics/configuration
# Caution: Indentation through two spaces, not tabs
SSViewer:
  theme: 'simple'
SiteConfig:
  extensions:
    - SiteConfigExtension
ProductCatalogAdmin:
  extensions:
    - ProductCatalogAdminExtension

有人告诉我,ModelAdmin 的 getExportFields() 没有 extend() 调用,所以我必须使用继承而不是扩展。然而,在 ModelAdmin 的继承下进行它似乎也无济于事。 有趣的是,我没有收到任何错误消息,它并没有真正失败。

是的,在这种情况下您需要子类化 ProductCatalogAdmin 并告诉 SilverStripe 使用您的子类。

class MyProductCatalogAdmin extends ProductCatalogAdmin

    public function getExportFields() {
        //your stuff here
    }
}

然后在你的 config.yml 中你写:

Injector:
  ProductCatalogAdmin:
    class: MyProductCatalogAdmin

现在,当任何地方 ProductCatalogAdmin::create() 被调用时,您的子类将由 Injector 返回。它不适用于 new ProductCatalogAdmin()

另见 Injector Docs

您可以子类化 ProductCatalogAdmin 并使用 Injector,正如 wmk 所指出的,但您也可以改用 Extension。这适用于任何 ModelAdmin 设置:

<?php
class CustomExportExtension extends Extension
{
    private $exportFields = [
        'ID' => 'ID',
        'Reference' => 'Order Number',
        // … all your other fields
    ];

    public function updateEditForm($form) {
        // Get the gridfield for the model we want, in this case 'Product'
        if ($gridField = $form->Fields()->fieldByName('Product')) {
            // Get the export button instance from the GridField config
            if ($exportButton = $gridField->getConfig()->getComponentByType(GridFieldExportButton::class)) {
                // Apply custom export columns to the export button
                $exportButton->setExportColumns($this->exportFields);
            }
        }
    }
}

然后只需将扩展名应用到 ProductCatalogAdmin,就像您通过 YML 所做的那样:

ProductCatalogAdmin:
  extensions:
    - CustomExportExtension

您还可以重写扩展,使其更灵活并可重复用于任何 ModelAdmin,方法是将扩展附加到 DataObject 配置的 exportFields 部分。但是对于像您这样的单个用例,上面的方法就可以了。

一种可重用的方法

这是上述扩展的略微修改版本,可用于在 any ModelAdmin 上配置导出字段,而无需创建多个扩展。

<?php
class CustomExportExtension extends Extension
{
    private $modelClass = null;

    public function updateEditForm($form)
    {
        // Get the gridfield for the current model
        if ($gridField = $form->Fields()->fieldByName($this->modelClass)) {
            // Get the export button instance from the gridfield config
            if ($exportButton = $gridField->getConfig()->getComponentByType(GridFieldExportButton::class)) {
                // Look for custom exportFields config
                $exportFields = Config::inst()->get($this->modelClass, 'exportFields');
                // If custom exportFields aren't set, fall back to summaryfields
                if (!$exportFields || !is_array($exportFields)) {
                    $exportFields = $this->owner->getExportFields();
                }
                $exportButton->setExportColumns($exportFields);
            }
        }
    }

    public function onBeforeInit() {
        // Grab the current model-class from the controller
        $this->modelClass = $this->owner->getRequest()->param('ModelClass');
    }
}

此扩展在应导出的模型上查找配置设置 exportFields。如果给出 none,则使用默认值 summary_fields

以下是如何将该扩展应用于不同的模型管理员:

# In your YML File
ProductCatalogAdmin:
  extensions:
    - CustomExportExtension

Product:
  exportFields:
    ID: ID
    Model: Model
    # More fields to export

OrdersAdmin:
  extensions:
    - CustomExportExtension

Order:
  exportFields:
    ID: ID
    Reference: 'Order Number'
    # More fields to export