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

533 Views

Avatar
phokki

11 June 2012 at 10:24pm Community Member, 14 Posts

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