/**
  * Publishes provided content
  * @param SQLIContent $content
  */
 public function publish(SQLIContent $content)
 {
     $initialLocations = array();
     if ($content->isNew() && !$this->options['parent_node_id']) {
         // Check for initial locations that may have been registered in content
         if ($content->hasInitialLocations()) {
             $initialLocations = $content->getInitialLocations();
             $initialMainLocation = array_shift($initialLocations);
             $this->options['parent_node_id'] = $initialMainLocation->getNodeID();
         } else {
             throw new SQLIContentException(__METHOD__ . ' : Initial location or "parent_node_id" option not defined for new content !');
         }
     }
     $contentObject = $content->getRawContentObject();
     $db = eZDB::instance();
     $db->begin();
     $canPublish = false;
     $version = null;
     // Loop against all fieldsets (by language) and edit attributes
     foreach ($content->fields as $lang => $fieldset) {
         if (!$this->publicationAllowed($content, $lang)) {
             $msg = 'Content object #' . $contentObject->attribute('id') . ' in language ' . $lang . ' has no need to be modified';
             eZDebug::writeNotice($msg, __METHOD__);
             continue;
         }
         if (is_null($version)) {
             $version = $this->createNewVersion($content);
         }
         eZDebug::accumulatorStart('sqlicontentpublisher_' . $lang . '_attributes', 'sqlicontentpublisher', 'Attributes handling for ' . $lang);
         $canPublish = true;
         $fieldset->refreshDataMap($version);
         // Now store attributes one by one
         foreach ($fieldset as $fieldName => $field) {
             $data = $field->getData();
             // Don't update field if its data is null and "update_null_field" option is false
             if ($this->options['update_null_field'] === false && is_null($data)) {
                 continue;
             }
             $field->fromString($data);
             $field->store();
         }
         eZDebug::accumulatorStop('sqlicontentpublisher_' . $lang . '_attributes');
     }
     $db->commit();
     if ($canPublish) {
         // Now do publish for current language
         eZDebug::accumulatorStart('sqlicontentpublisher_publish', 'sqlicontentpublisher', 'Publishing object #' . $contentObject->attribute('id'));
         $operationResult = eZOperationHandler::execute('content', 'publish', array('object_id' => $contentObject->attribute('id'), 'version' => $version->attribute('version')));
         eZDebug::accumulatorStop('sqlicontentpublisher_publish');
         // Now cleaning
         $contentObject->cleanupInternalDrafts();
         $content->refresh();
         $content->addPendingClearCacheIfNeeded();
         // Handling additional "initial" locations. Only for new content
         if (count($initialLocations) > 0) {
             foreach ($initialLocations as $initialAdditionalLocation) {
                 $this->addLocationToContent($initialAdditionalLocation, $content);
             }
         }
     }
     // Now cleaning internal options
     $this->options['parent_node_id'] = null;
 }
    /**
     * Update null field only for active language
     * @param SQLIContent $content
     * @param string $activeLanguage
     * @throws SQLIContentException
     */
    public function publish( SQLIContent $content )
    {
        $options = array('modification_check' => false);
        $this->setOptions(new SQLIContentPublishOptions($options));

        $initialLocations = array();

        if( $content->isNew() && !$this->options['parent_node_id'] ) // parent_node_id is mandatory for new content
        {
            // Check for initial locations that may have been registered in content
            if( $content->hasInitialLocations() )
            {
                $initialLocations = $content->getInitialLocations();
                $initialMainLocation = array_shift( $initialLocations );
                $this->options['parent_node_id'] = $initialMainLocation->getNodeID();
            }
            else
            {
                throw new SQLIContentException( __METHOD__.' : Initial location or "parent_node_id" option not defined for new content !' );
            }
        }

        $contentObject  = $content->getRawContentObject();
        $db             = eZDB::instance();

        $db->begin();

        $canPublish     = false;
        $version        = null;
        $activeLanguage = $content->fields->getActiveLanguage();

        // Loop against all fieldsets (by language) and edit attributes
        foreach( $content->fields as $lang => $fieldset )
        {
            // Publish only if necessary and/or allowed (will let $canPublish to false)
            if( !$this->publicationAllowed( $content, $lang ) )
            {
                $msg = 'Content object #'.$contentObject->attribute( 'id' ).' in language '.$lang.' has no need to be modified';
                eZDebug::writeNotice( $msg, __METHOD__ );
                continue;
            }

            // Create new $version only if necessary (this is an optimization : $version->removeThis() is very very slow !)
            if ( is_null( $version ) )
            {
                $version = $this->createNewVersion( $content );
            }

            $canPublish = true;
            $fieldset->refreshDataMap( $version );

            // Now store attributes one by one
            foreach( $fieldset as $fieldName => $field )
            {
                $data = $field->getData();

                // For non active language, don't update field if its data is null and "update_null_field" option is false
                if( $lang != $activeLanguage && is_null( $data ) )
                    continue;

                self::storeAttributeFromString($field, $data);
            }
        }

        $db->commit();

        // Publication is allowed (content modified)
        if( $canPublish )
        {
            // Now do publish for current language
            eZDebug::accumulatorStart( 'sqlicontentpublisher_publish', 'sqlicontentpublisher', 'Publishing object #'.$contentObject->attribute( 'id' ) );
            $operationResult = eZOperationHandler::execute( 'content', 'publish', array( 'object_id'    => $contentObject->attribute( 'id' ),
                                                                                         'version'      => $version->attribute( 'version' ) ) );
            eZDebug::accumulatorStop( 'sqlicontentpublisher_publish' );

            // Now cleaning
            $contentObject->cleanupInternalDrafts();
            $content->refresh();
            $content->addPendingClearCacheIfNeeded();

            // Handling additional "initial" locations. Only for new content
            if( count( $initialLocations ) > 0 )
            {
                foreach( $initialLocations as $initialAdditionalLocation )
                {
                    $this->addLocationToContent( $initialAdditionalLocation , $content);
                }
            }

            if ( $content->getRawContentObject()->attribute('class_identifier') == 'publisher_folder' )
            {
                eZContentOperationCollection::updateAlwaysAvailable( $content->getRawContentObject()->attribute('id'), true );
            }
        }
        else
        {
            throw new MMSynchException('Nothing to publish for publisher');
        }

        // Now cleaning internal options
        $this->options['parent_node_id'] = null;
    }