Silverstripe 4升级-ModelAdmin中未版本化的数据对象将丢失其映像对象
一天来我一直在为这件事发愁,我的google foo已经精疲力尽了。我继承了一个Silverstripe 3.4站点,我们已将其升级到4.4。但在运行MigrateFileTask之后,某些图像出现了一些奇怪的情况 我认为这与将文件附加到通过ModelAdmin访问的未版本对象有关。但我还没有找到一个明确的解决办法 下面是此对象的代码。所遇到的问题都在其范围内Silverstripe 4升级-ModelAdmin中未版本化的数据对象将丢失其映像对象,silverstripe,silverstripe-4,Silverstripe,Silverstripe 4,一天来我一直在为这件事发愁,我的google foo已经精疲力尽了。我继承了一个Silverstripe 3.4站点,我们已将其升级到4.4。但在运行MigrateFileTask之后,某些图像出现了一些奇怪的情况 我认为这与将文件附加到通过ModelAdmin访问的未版本对象有关。但我还没有找到一个明确的解决办法 下面是此对象的代码。所遇到的问题都在其范围内 <?php use SilverStripe\Assets\Image; use gorriecoe\Link\Models\L
<?php
use SilverStripe\Assets\Image;
use gorriecoe\Link\Models\Link;
use SilverStripe\Security\Member;
use SilverStripe\Control\Controller;
use SilverStripe\View\Parsers\URLSegmentFilter;
use SilverStripe\Forms\TextField;
use SilverStripe\Forms\FieldGroup;
use gorriecoe\LinkField\LinkField;
use SilverStripe\TagField\TagField;
use SilverStripe\ORM\DataObject;
use SilverStripe\SelectUpload\SelectUploadField;
class Person extends DataObject
{
private static $db = array(
'FirstName' => 'Varchar(128)',
'LastName' => 'Varchar(128)',
'Role' => 'Varchar(128)',
'DirectDialNumber' => 'Varchar(128)',
'Email' => 'Varchar(128)',
'CellphoneNumber' => 'Varchar(30)',
'DirectDial' => 'Varchar(30)',
'UrlSegment' => 'Varchar(255)',
'Blurb' => 'HTMLText',
'SortOrder' => 'Int'
);
private static $has_one = array(
'Image' => Image::class,
'Office' => 'Office',
'LinkedIn' => Link::class,
'Member' => Member::class
);
private static $many_many = array(
'Interests' => 'Section'
);
private static $belongs_many_many = array(
'ElementCollection' => 'ElementCollection'
);
static $sort_fields = array(
'FirstName' => 'First name',
'LastName' => 'Last name',
'Role' => 'Role'
);
private static $summary_fields = array(
'Name' => 'Name',
'Role' => 'Role',
'Office.Name' => 'Office'
);
private static $searchable_fields = array(
'FirstName',
'LastName',
'Role'
);
// For use with the ElementCollection
public static $templates = array(
'ElementPeople' => 'Default',
'ElementPeopleAlternative' => 'Alternative'
);
public function getCMSFields() {
$fields = parent::getCMSFields();
$fields->removeByName( ['SortOrder', 'ElementCollection', 'FirstName', 'LastName', 'Interests'] );
$firstname = TextField::create('FirstName', 'First name');
$lastname = TextField::create('LastName', 'Last name');
$fields->addFieldsToTab('Root.Main', FieldGroup::create($firstname, $lastname)->setTitle('Name')->setName('Name'), 'Role');
$image = UploadField::create('Image', 'Photo');
$image->setFolderName('Uploads/People');
$image->setCanSelectFolder(false);
$fields->addFieldToTab('Root.Main', $image);
$linkedin = LinkField::create('LinkedIn', 'LinkedIn', $this);
$fields->addFieldToTab('Root.Main', $linkedin);
$interests = TagField::create(
'Interests',
'Interests Tags',
Section::get(),
$this->Interests()
)->setShouldLazyLoad(true)
->setCanCreate(false);
$fields->addFieldToTab('Root.Main', $interests);
return $fields;
}
public function onBeforeWrite()
{
$count = 1;
$this->UrlSegment = $this->generateURLSegment();
while (!$this->validURLSegment()) {
$this->UrlSegment = preg_replace('/-[0-9]+$/', null, $this->UrlSegment) . '-' . $count;
$count++;
}
parent::onBeforeWrite();
}
}
您应该能够通过将映像添加到DataObejct的所有者
属性来解决此问题。基本上加上:
private static $owns = [
'Image'
];
基本上,owns
告诉DataObject
保存时要发布哪些对象:
文档中的更多信息:已找到问题的原因#1。将此保留在此处,以防将来对某人有所帮助:
数据库表文件中的每个文件和文件夹都有一行。此表有一个名为“CanViewType”的列。它存在于Silverstripe 3和4中
对于迁移过程中出现问题的特定文件夹,我发现它是唯一一个将该列设置为“OnlyTheseUsers”的文件夹。其余的设置为“继承”。这是升级前表的状态
我不确定该行是如何或通过什么机制更改的,但问题1的解决方案是在运行FileMigrationTask之前手动将该字段更改为“继承”
问题2依然存在,但这里似乎有两个截然不同的问题。好的。因此,问题2最终得到了解决(参见第1个问题解决方案的其他答案),但它极大地削弱了我们对Silverstripe的信心,并在这里引发了一场会议
未来读者代码:
在未版本化的数据对象中,添加此项。在这种情况下,我的文件对象称为“Image”。如果保存时要发布多个文件,则必须为每个文件添加一个If块
public function onAfterWrite()
{
if ($this->Image()->exists() && !$this->Image()->isPublished()) {
$this->Image()->doPublish();
}
parent::onAfterWrite();
}
旁注:
这种对象/文件关系确实是一种奇怪的设计选择。是否确实存在希望将文件或图像附加到数据对象而不在保存/发布对象/页面的同时发布该文件的情况?开发人员甚至需要在使用$owns的版本化对象上明确定义它——我很高兴打赌,大多数开发人员都需要添加更多次。这真的应该告诉我们一些事情是错误的
将映像添加到CMS系统应该不难。它最多需要阅读基本文档。不用谷歌搜索,不用深度API文档潜水(答案不多),也不用在StackOverlfow上发布(没有人真正知道答案)三天。这是一个图像。产品的核心功能
从v2.4开始,我就一直在与SS合作,并且看到了在进入v4时所学到的所有艰苦的经验教训。但这似乎是一个简单的被过度设计的教科书案例 这是我尝试的第一件事。在网上搜索之后,它看起来实际上对未版本化的对象没有任何作用。当然,它对这个类或其他类似的类没有任何作用。图像仍保存为草稿。您可以添加一个扩展-RecursivePublishable
或类似的功能that@RobbieAverill,根据SS4文档,它已经包含在DataObject中。此处讨论:。两年前有人在这个问题上提出了同样的问题,答案表明当时就有。我认为这是SS4中“一切都是版本化的”推送的一个例子,我认为在某些情况下,未版本化的对象已经推送通过了裂缝。我建议对上面的代码要小心,我在过去使用过类似的代码,由于isPublished()
报告似乎并不总是准确。我发现只要使用$object->publishRecursive()代码>工作得更好,你也不需要检查对象是否已经发布。谢谢@Psycholomo。$object->publishRecursive()
到底会去哪里?尝试交换$this->Image()->doPublish()使用$this->Image()->publishRecursive()
进行编码>。然后还应该能够删除If语句。