1

我正在与 SilverStripe 合作,并且正在制作新闻页面。我使用 DataObjectAsPage 模块(http://www.ssbits.com/tutorials/2012/dataobject-as-pages-the-module/),当我使用管理员发布新闻站点时,我得到了它的工作。现在我想使用 DataObjectManager 模块而不是管理模块来管理我的新闻项目。但这就是问题所在。在草稿模式下一切正常,我可以制作一个新的新闻站点,它会显示在草稿中。但是当我想发布一个新站点时,它不会以实时或发布模式出现。

我正在使用以下表:
-Dataobjectaspage 表、
-Dataobjectaspage_live 表、
-NewsArticle 表、
-NewsArticle_Live 表

文章已在 Dataobjectaspage 表和 NewsArticle 表中发布时插入...但不是在 _Live 表中...

似乎在“发布”时未使用 doPublish() 函数。所以我正在尝试使用以下内容:

function onAfterWrite() {
    parent::onAfterWrite();   
    DataObjectAsPage::doPublish();
}

但是当我使用它时,它会出现错误: 这是这张图片

它似乎处于一个循环中......我有 NewsArticle.php 文件,我在其中使用了这个函数:

 function onAfterWrite() {
    parent::onAfterWrite();   
    DataObjectAsPage::doPublish();
}

此函数调用 DataObjectAsPage.php 文件并使用以下代码:

function doPublish() {
        if (!$this->canPublish()) return false;

        $original = Versioned::get_one_by_stage("DataObjectAsPage", "Live", "\"DataObjectAsPage\".\"ID\" = $this->ID");
        if(!$original) $original = new DataObjectAsPage();

        // Handle activities undertaken by decorators
        $this->invokeWithExtensions('onBeforePublish', $original);
        $this->Status = "Published";
        //$this->PublishedByID = Member::currentUser()->ID;
        $this->write();
        $this->publish("Stage", "Live");

        // Handle activities undertaken by decorators
        $this->invokeWithExtensions('onAfterPublish', $original);

        return true;
    }

然后它转到 DataObject.php 文件并使用 write 函数():

public function write($showDebug = false, $forceInsert = false, $forceWrite = false, $writeComponents = false) {
    $firstWrite = false;
    $this->brokenOnWrite = true;
    $isNewRecord = false;

    if(self::get_validation_enabled()) {
        $valid = $this->validate();
        if(!$valid->valid()) {
            // Used by DODs to clean up after themselves, eg, Versioned
            $this->extend('onAfterSkippedWrite');
            throw new ValidationException($valid, "Validation error writing a $this->class object: " . $valid->message() . ".  Object not written.", E_USER_WARNING);
            return false;
        }
    }

    $this->onBeforeWrite();
    if($this->brokenOnWrite) {
        user_error("$this->class has a broken onBeforeWrite() function.  Make sure that you call parent::onBeforeWrite().", E_USER_ERROR);
    }

    // New record = everything has changed

    if(($this->ID && is_numeric($this->ID)) && !$forceInsert) {
        $dbCommand = 'update';

        // Update the changed array with references to changed obj-fields
        foreach($this->record as $k => $v) {
            if(is_object($v) && method_exists($v, 'isChanged') && $v->isChanged()) {
                $this->changed[$k] = true;
            }
        }

    } else{
        $dbCommand = 'insert';

        $this->changed = array();
        foreach($this->record as $k => $v) {
            $this->changed[$k] = 2;
        }

        $firstWrite = true;
    }

    // No changes made
    if($this->changed) {
        foreach($this->getClassAncestry() as $ancestor) {
            if(self::has_own_table($ancestor))
            $ancestry[] = $ancestor;
        }

        // Look for some changes to make
        if(!$forceInsert) unset($this->changed['ID']);

        $hasChanges = false;
        foreach($this->changed as $fieldName => $changed) {
            if($changed) {
                $hasChanges = true;
                break;
            }
        }

        if($hasChanges || $forceWrite || !$this->record['ID']) {

            // New records have their insert into the base data table done first, so that they can pass the
            // generated primary key on to the rest of the manipulation
            $baseTable = $ancestry[0];

            if((!isset($this->record['ID']) || !$this->record['ID']) && isset($ancestry[0])) {  

                DB::query("INSERT INTO \"{$baseTable}\" (\"Created\") VALUES (" . DB::getConn()->now() . ")");
                $this->record['ID'] = DB::getGeneratedID($baseTable);
                $this->changed['ID'] = 2;

                $isNewRecord = true;
            }

            // Divvy up field saving into a number of database manipulations
            $manipulation = array();
            if(isset($ancestry) && is_array($ancestry)) {
                foreach($ancestry as $idx => $class) {
                    $classSingleton = singleton($class);

                    foreach($this->record as $fieldName => $fieldValue) {
                        if(isset($this->changed[$fieldName]) && $this->changed[$fieldName] && $fieldType = $classSingleton->hasOwnTableDatabaseField($fieldName)) {
                            $fieldObj = $this->dbObject($fieldName);
                            if(!isset($manipulation[$class])) $manipulation[$class] = array();

                            // if database column doesn't correlate to a DBField instance...
                            if(!$fieldObj) {
                                $fieldObj = DBField::create('Varchar', $this->record[$fieldName], $fieldName);
                            }

                            // Both CompositeDBFields and regular fields need to be repopulated
                            $fieldObj->setValue($this->record[$fieldName], $this->record);

                            if($class != $baseTable || $fieldName!='ID')
                                $fieldObj->writeToManipulation($manipulation[$class]);
                        }
                    }

                    // Add the class name to the base object
                    if($idx == 0) {
                        $manipulation[$class]['fields']["LastEdited"] = "'".SS_Datetime::now()->Rfc2822()."'";
                        if($dbCommand == 'insert') {
                            $manipulation[$class]['fields']["Created"] = "'".SS_Datetime::now()->Rfc2822()."'";
                            //echo "<li>$this->class - " .get_class($this);
                            $manipulation[$class]['fields']["ClassName"] = "'$this->class'";
                        }
                    }

                    // In cases where there are no fields, this 'stub' will get picked up on
                    if(self::has_own_table($class)) {
                        $manipulation[$class]['command'] = $dbCommand;
                        $manipulation[$class]['id'] = $this->record['ID'];
                    } else {
                        unset($manipulation[$class]);
                    }
                }
            }
            $this->extend('augmentWrite', $manipulation);

            // New records have their insert into the base data table done first, so that they can pass the
            // generated ID on to the rest of the manipulation
            if(isset($isNewRecord) && $isNewRecord && isset($manipulation[$baseTable])) {
                $manipulation[$baseTable]['command'] = 'update';
            }

            DB::manipulate($manipulation);

            if(isset($isNewRecord) && $isNewRecord) {
                DataObjectLog::addedObject($this);
            } else {
                DataObjectLog::changedObject($this);
            }

            $this->onAfterWrite();

            $this->changed = null;
        } elseif ( $showDebug ) {
            echo "<b>Debug:</b> no changes for DataObject<br />";
            // Used by DODs to clean up after themselves, eg, Versioned
            $this->extend('onAfterSkippedWrite');
        }

        // Clears the cache for this object so get_one returns the correct object.
        $this->flushCache();

        if(!isset($this->record['Created'])) {
            $this->record['Created'] = SS_Datetime::now()->Rfc2822();
        }
        $this->record['LastEdited'] = SS_Datetime::now()->Rfc2822();
    } else {
        // Used by DODs to clean up after themselves, eg, Versioned
        $this->extend('onAfterSkippedWrite');
    }

    // Write ComponentSets as necessary
    if($writeComponents) {
        $this->writeComponents(true);
    }
    return $this->record['ID'];
}

看看 $this->onAfterWrite();
它可能会转到我自己在 NewsArticle.php 上的函数,然后开始循环!不过我不确定,所以我需要一些帮助!!

有谁知道如何使用 doPublish() 函数?

4

1 回答 1

1

发生这种情况的原因是在 DataObjectAsPage::publish() 方法中,它正在调用 ->write() - 第三个代码示例的第 11 行。

所以它会调用 ->write(),在 ->write() 结束时调用 onAfterWrite() 方法,该方法调用 publish(),然后再次调用 write()。

如果您删除已添加的 onAfterWrite() 函数,它应该会按预期工作。

DataObjectAsPage 上的 doPublish() 方法将为您处理从 Stage 到 Live 的发布。

于 2013-05-07T10:08:50.450 回答