Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

All other Modules /

Discuss all other Modules here.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

how to use the doPublish() function


Reply


615 Views

Avatar
phokki

Community Member, 14 Posts

11 June 2012 at 10:24pm

I am working with SilverStripe, and I am working on making a newspage.
I use the DataObjectAsPage Module( http://www.ssbits.com/tutorials/2012/dataobject-as-pages-the-module/ ), I got it working when I use the admin to publish newsitems.
Now I want to use the DataObjectManager ( http://www.silverstripe.org/dataobjectmanager-module/ ) instead of the admin module to manage my news items. But this is where the problem exists. Everything works fine in draft mode, I can make a new newsitem and it shows up in draft. But when I want to publish a newsitem, it won't show up in the live or published mode.

I'm using the following tables:
-Dataobjectaspage table,
-Dataobjectaspage_live table,
-NewsArticle table,
-NewsArticle_Live table

The Articles have been inserted while publishing in the Dataobjectaspage table and in the NewsArticle table... But not in the _Live tables...

Seems the doPublish() function hasn't been used while 'Publishing'.
So I'm trying the use the following:

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

But when I use this, it gets an error:
http://imageshare.web.id/images/3eoxlqtl71xzin6nqwc.png

It seems to be in a loop....
I've got the NewsArticle.php file where I use this function:

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

This function calls the DataObjectAsPage.php file and uses this code:

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;
   }

And then it goes to DataObject.php file and uses the write function ():

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'];
   }

Look at the $this->onAfterWrite();
It probably goes to my own function on NewsArticle.php and there starts the loop! I'm not sure though, so i could need some help!!

Does anyone knows how to use the doPublish() function?

Attached Files