Adds the function body for the save method
@param string &$script The script will be modified in this method.
@see addSave()
512441
protected function addSaveBody(&$script)
    {
        $table = $this->getTable();
        $reloadOnUpdate = $table->isReloadOnUpdate();
        $reloadOnInsert = $table->isReloadOnInsert();

        $script .= "
        if (\$this->isDeleted()) {
            throw new PropelException(\"You cannot save an object that has been deleted.\");
        }

        if (\$this->alreadyInSave) {
            return 0;
        }
 
        if (\$con === null) {
            \$con = Propel::getServiceContainer()->getWriteConnection(".$this->getTableMapClass()."::DATABASE_NAME);
        }

        return \$con->transaction(function () use (\$con".($reloadOnUpdate || $reloadOnInsert ? ", \$skipReload" : "").") {";

        if ($this->getBuildProperty('generator.objectModel.addHooks')) {
            // save with runtime hooks
            $script .= "
            \$ret = \$this->preSave(\$con);
            \$isInsert = \$this->isNew();";
            $this->applyBehaviorModifier('preSave', $script, "            ");
            $script .= "
            if (\$isInsert) {
                \$ret = \$ret && \$this->preInsert(\$con);";
            $this->applyBehaviorModifier('preInsert', $script, "                ");
            $script .= "
            } else {
                \$ret = \$ret && \$this->preUpdate(\$con);";
            $this->applyBehaviorModifier('preUpdate', $script, "                ");
            $script .= "
            }
            if (\$ret) {
                \$affectedRows = \$this->doSave(\$con".($reloadOnUpdate || $reloadOnInsert ? ", \$skipReload" : "").");
                if (\$isInsert) {
                    \$this->postInsert(\$con);";
            $this->applyBehaviorModifier('postInsert', $script, "                    ");
            $script .= "
                } else {
                    \$this->postUpdate(\$con);";
            $this->applyBehaviorModifier('postUpdate', $script, "                    ");
            $script .= "
                }
                \$this->postSave(\$con);";
            $this->applyBehaviorModifier('postSave', $script, "                ");
            $script .= "
                ".$this->getTableMapClassName()."::addInstanceToPool(\$this);
            } else {
                \$affectedRows = 0;
            }

            return \$affectedRows;";
        } else {
            // save without runtime hooks
            $script .= "
            \$isInsert = \$this->isNew();";
            $this->applyBehaviorModifier('preSave', $script, "            ");
            if ($this->hasBehaviorModifier('preUpdate')) {
                $script .= "
            if (!\$isInsert) {";
                $this->applyBehaviorModifier('preUpdate', $script, "                ");
                $script .= "
            }";
            }
            if ($this->hasBehaviorModifier('preInsert')) {
                $script .= "
            if (\$isInsert) {";
                $this->applyBehaviorModifier('preInsert', $script, "                ");
                $script .= "
            }";
            }
            $script .= "
            \$affectedRows = \$this->doSave(\$con".($reloadOnUpdate || $reloadOnInsert ? ", \$skipReload" : "").");";
            $this->applyBehaviorModifier('postSave', $script, "            ");
            if ($this->hasBehaviorModifier('postUpdate')) {
                $script .= "
            if (!\$isInsert) {";
                $this->applyBehaviorModifier('postUpdate', $script, "                ");
                $script .= "
            }";
            }
            if ($this->hasBehaviorModifier('postInsert')) {
                $script .= "
            if (\$isInsert) {";
                $this->applyBehaviorModifier('postInsert', $script, "                ");
                $script .= "
            }";
            }
            $script .= "
            ".$this->getTableMapClassName()."::addInstanceToPool(\$this);

            return \$affectedRows;";
        }

        $script .= "
        });";
    }
677022
protected function addClassBody(&$script)
    {
        $table = $this->getTable();

        // FIXME
        // - Probably the build needs to be customized for supporting
        // tables that are "aliases".  -- definitely a fringe usecase, though.

        $this->addConstants($script);

        $this->addCreateRoot($script);

        $this->addRetrieveRoot($script);

        $this->addInsertAsFirstChildOf($script);
        $this->addInsertAsLastChildOf($script);
        $this->addInsertAsPrevSiblingOf($script);
        $this->addInsertAsNextSiblingOf($script);
        $this->addInsertAsParentOf($script);

        $this->addInsertRoot($script);
        $this->addInsertParent($script);

        $this->addDeleteRoot($script);
        $this->addDeleteNode($script);

        $this->addMoveToFirstChildOf($script);
        $this->addMoveToLastChildOf($script);
        $this->addMoveToPrevSiblingOf($script);
        $this->addMoveToNextSiblingOf($script);

        $this->addRetrieveFirstChild($script);
        $this->addRetrieveLastChild($script);
        $this->addRetrievePrevSibling($script);
        $this->addRetrieveNextSibling($script);

        $this->addRetrieveTree($script);
        $this->addRetrieveBranch($script);
        $this->addRetrieveChildren($script);
        $this->addRetrieveDescendants($script);
        $this->addRetrieveSiblings($script);
        $this->addRetrieveParent($script);

        $this->addGetLevel($script);
        $this->addGetNumberOfChildren($script);
        $this->addGetNumberOfDescendants($script);
        $this->addGetPath($script);

        $this->addIsValid($script);
        $this->addIsRoot($script);
        $this->addIsLeaf($script);
        $this->addIsChildOf($script);
        $this->addIsChildOfOrSiblingTo($script);
        $this->addIsEqualTo($script);

        $this->addHasParent($script);
        $this->addHasPrevSibling($script);
        $this->addHasNextSibling($script);
        $this->addHasChildren($script);

        $this->addDeleteDescendants($script);

        $this->addGetNode($script);

        $this->addHydrateDescendants($script);
        $this->addHydrateChildren($script);

        $this->addShiftRParent($script);
        $this->addUpdateLoadedNode($script);
        $this->addUpdateDBNode($script);

        $this->addShiftRLValues($script);
        $this->addShiftRLRange($script);
    }
205093
protected function addClassBody(&$script)
    {
        $this->declareClassFromBuilder($this->getStubPeerBuilder());
        $this->declareClasses('PropelPDO', 'Criteria', 'BasePeer', 'PropelException');
        $this->addFactory($script);
        $this->addPreSelect($script);
        $this->addPreUpdate($script);
        $this->addPreDelete($script);
        $this->addDoDeleteAll($script);
        $this->addFindOneOrCreate($script);
    }
316603
protected function addConstructorBody(&$script)
    {
        $table = $this->getTable();
        $script .= "
        if (null === \$dbName) {
            \$dbName = '" . $table->getDatabase()->getName() . "';
        }
        if (null === \$modelName) {
            \$modelName = '" . addslashes($this->getNewStubObjectBuilder($table)->getFullyQualifiedClassname()) . "';
        }
        parent::__construct(\$dbName, \$modelName, \$modelAlias);";
    }
963620
protected function addCopyInto(&$script)
    {
        $table = $this->getTable();

        $script .= "
    /**
     * Sets contents of passed object to values from current object.
     *
     * If desired, this method can also make copies of all associated (fkey referrers)
     * objects.
     *
     * @param      object \$copyObj An object of ".$this->getObjectClassName(true)." (or compatible) type.
     * @param      boolean \$deepCopy Whether to also copy all rows that refer (by fkey) to the current row.
     * @param      boolean \$makeNew Whether to reset autoincrement PKs and make the object new.
     * @throws PropelException
     */
    public function copyInto(\$copyObj, \$deepCopy = false, \$makeNew = true)
    {";

        $autoIncCols = [];
        foreach ($table->getColumns() as $col) {
            /* @var        $col Column */
            if ($col->isAutoIncrement()) {
                $autoIncCols[] = $col;
            }
        }

        foreach ($table->getColumns() as $col) {
            if (!in_array($col, $autoIncCols, true)) {
                $script .= "
        \$copyObj->set".$col->getPhpName()."(\$this->get".$col->getPhpName()."());";
            }
        } // foreach

        // Avoid useless code by checking to see if there are any referrers
        // to this table:
        if (count($table->getReferrers()) > 0) {
            $script .= "

        if (\$deepCopy) {
            // important: temporarily setNew(false) because this affects the behavior of
            // the getter/setter methods for fkey referrer objects.
            \$copyObj->setNew(false);
";
            foreach ($table->getReferrers() as $fk) {
                //HL: commenting out self-referential check below
                //        it seems to work as expected and is probably desirable to have those referrers from same table deep-copied.
                //if ( $fk->getTable()->getName() != $table->getName() ) {

                if ($fk->isLocalPrimaryKey()) {

                    $afx = $this->getRefFKPhpNameAffix($fk, false);
                    $script .= "
            \$relObj = \$this->get$afx();
            if (\$relObj) {
                \$copyObj->set$afx(\$relObj->copy(\$deepCopy));
            }
";
                } else {

                    $script .= "
            foreach (\$this->get".$this->getRefFKPhpNameAffix($fk, true)."() as \$relObj) {
                if (\$relObj !== \$this) {  // ensure that we don't try to copy a reference to ourselves
                    \$copyObj->add".$this->getRefFKPhpNameAffix($fk)."(\$relObj->copy(\$deepCopy));
                }
            }
";
                }
                // HL: commenting out close of self-referential check
                // } /* if tblFK != table */
            } /* foreach */
            $script .= "
        } // if (\$deepCopy)
";
        } /* if (count referrers > 0 ) */

        $script .= "
        if (\$makeNew) {
            \$copyObj->setNew(true);";

        // Note: we're no longer resetting non-autoincrement primary keys to default values
        // due to: http://propel.phpdb.org/trac/ticket/618
        foreach ($autoIncCols as $col) {
            $coldefval = $col->getPhpDefaultValue();
            $coldefval = var_export($coldefval, true);
            $script .= "
            \$copyObj->set".$col->getPhpName() ."($coldefval); // this is a auto-increment column, so set to default value";
        } // foreach
        $script .= "
        }
    }
";
    }
1312371
protected function addClassClose(&$script)
    {
        // apply behaviors
        $this->applyBehaviorModifier('staticMethods', $script, "	");

        $script .= "
} // " . $this->getClassname() . "
";
        $this->addStaticTableMapRegistration($script);
    }
1340407
protected function addApplyDefaultValuesBody(&$script)
    {
        $table = $this->getTable();
        // FIXME - Apply support for PHP default expressions here
        // see: http://trac.propelorm.org/ticket/378

        $colsWithDefaults = array();
        foreach ($table->getColumns() as $col) {
            $def = $col->getDefaultValue();
            if ($def !== null && !$def->isExpression()) {
                $colsWithDefaults[] = $col;
            }
        }

        $colconsts = array();
        foreach ($colsWithDefaults as $col) {
            $clo = strtolower($col->getName());
            $defaultValue = $this->getDefaultValueString($col);
            $script .= "
        \$this->" . $clo . " = $defaultValue;";
        }
    }
723204
protected function addDoSave(&$script)
    {
        $table = $this->getTable();

        $reloadOnUpdate = $table->isReloadOnUpdate();
        $reloadOnInsert = $table->isReloadOnInsert();

        $script .= "
    /**
     * Performs the work of inserting or updating the row in the database.
     *
     * If the object is new, it inserts it; otherwise an update is performed.
     * All related objects are also updated in this method.
     *
     * @param      ConnectionInterface \$con";
        if ($reloadOnUpdate || $reloadOnInsert) {
            $script .= "
     * @param      boolean \$skipReload Whether to skip the reload for this object from database.";
        }
        $script .= "
     * @return int             The number of rows affected by this insert/update and any referring fk objects' save() operations.
     * @throws PropelException
     * @see save()
     */
    protected function doSave(ConnectionInterface \$con".($reloadOnUpdate || $reloadOnInsert ? ", \$skipReload = false" : "").")
    {
        \$affectedRows = 0; // initialize var to track total num of affected rows
        if (!\$this->alreadyInSave) {
            \$this->alreadyInSave = true;
";
        if ($reloadOnInsert || $reloadOnUpdate) {
            $script .= "
            \$reloadObject = false;
";
        }

        if (count($table->getForeignKeys())) {

            $script .= "
            // We call the save method on the following object(s) if they
            // were passed to this object by their corresponding set
            // method.  This object relates to these object(s) by a
            // foreign key reference.
";

            foreach ($table->getForeignKeys() as $fk) {
                $aVarName = $this->getFKVarName($fk);
                $script .= "
            if (\$this->$aVarName !== null) {
                if (\$this->" . $aVarName . "->isModified() || \$this->" . $aVarName . "->isNew()) {
                    \$affectedRows += \$this->" . $aVarName . "->save(\$con);
                }
                \$this->set".$this->getFKPhpNameAffix($fk, false)."(\$this->$aVarName);
            }
";
            } // foreach foreign k
        } // if (count(foreign keys))

        $script .= "
            if (\$this->isNew() || \$this->isModified()) {
                // persist changes
                if (\$this->isNew()) {
                    \$this->doInsert(\$con);
                    \$affectedRows += 1;";
        if ($reloadOnInsert) {
            $script .= "
                    if (!\$skipReload) {
                        \$reloadObject = true;
                    }";
        }
        $script .= "
                } else {
                    \$affectedRows += \$this->doUpdate(\$con);";
        if ($reloadOnUpdate) {
            $script .= "
                    if (!\$skipReload) {
                        \$reloadObject = true;
                    }";
        }
        $script .= "
                }";

        // We need to rewind any LOB columns
        foreach ($table->getColumns() as $col) {
            $clo = $col->getLowercasedName();
            if ($col->isLobType()) {
                $script .= "
                // Rewind the $clo LOB column, since PDO does not rewind after inserting value.
                if (\$this->$clo !== null && is_resource(\$this->$clo)) {
                    rewind(\$this->$clo);
                }
";
            }
        }

        $script .= "
                \$this->resetModified();
            }
";

        if ($table->hasCrossForeignKeys()) {
            foreach ($table->getCrossFks() as $crossFKs) {
                $this->addCrossFkScheduledForDeletion($script, $crossFKs);
            }
        }

        foreach ($table->getReferrers() as $refFK) {
            if ($refFK->isLocalPrimaryKey()) {
                $varName = $this->getPKRefFKVarName($refFK);
                $script .= "
            if (\$this->$varName !== null) {
                if (!\$this->{$varName}->isDeleted() && (\$this->{$varName}->isNew() || \$this->{$varName}->isModified())) {
                    \$affectedRows += \$this->{$varName}->save(\$con);
                }
            }
";
            } else {
                $this->addRefFkScheduledForDeletion($script, $refFK);

                $collName = $this->getRefFKCollVarName($refFK);
                $script .= "
            if (\$this->$collName !== null) {
                foreach (\$this->$collName as \$referrerFK) {
                    if (!\$referrerFK->isDeleted() && (\$referrerFK->isNew() || \$referrerFK->isModified())) {
                        \$affectedRows += \$referrerFK->save(\$con);
                    }
                }
            }
";
            } // if refFK->isLocalPrimaryKey()
        } /* foreach getReferrers() */

        $script .= "
            \$this->alreadyInSave = false;
";
        if ($reloadOnInsert || $reloadOnUpdate) {
            $script .= "
            if (\$reloadObject) {
                \$this->reload(\$con);
            }
";
        }
        $script .= "
        }

        return \$affectedRows;
    } // doSave()
";

    }
619156
protected function addDoUpdate(&$script)
    {
        $table = $this->getTable();
        $script .= "
    /**
     * Performs an UPDATE on the database, given a " . $this->getObjectClassname() . " or Criteria object.
     *
     * @param      mixed \$values Criteria or " . $this->getObjectClassname() . " object containing data that is used to create the UPDATE statement.
     * @param      PropelPDO \$con The connection to use (specify PropelPDO connection object to exert more control over transactions).
     * @return int             The number of affected rows (if supported by underlying database driver).
     * @throws PropelException Any exceptions caught during processing will be
     *		 rethrown wrapped into a PropelException.
     */
    public static function doUpdate(\$values, PropelPDO \$con = null)
    {
        if (\$con === null) {
            \$con = Propel::getConnection(" . $this->getPeerClassname() . "::DATABASE_NAME, Propel::CONNECTION_WRITE);
        }

        \$selectCriteria = new Criteria(" . $this->getPeerClassname() . "::DATABASE_NAME);

        if (\$values instanceof Criteria) {
            \$criteria = clone \$values; // rename for clarity
";
        foreach ($table->getColumns() as $col) {
            if ($col->isPrimaryKey()) {
                $script .= "
            \$comparison = \$criteria->getComparison(" . $this->getColumnConstant($col) . ");
            \$value = \$criteria->remove(" . $this->getColumnConstant($col) . ");
            if (\$value) {
                \$selectCriteria->add(" . $this->getColumnConstant($col) . ", \$value, \$comparison);
            } else {
                \$selectCriteria->setPrimaryTableName(" . $this->getPeerClassname() . "::TABLE_NAME);
            }
";
            } /* if col is prim key */
        } /* foreach */

        $script .= "
        } else { // \$values is " . $this->getObjectClassname() . " object
            \$criteria = \$values->buildCriteria(); // gets full criteria
            \$selectCriteria = \$values->buildPkeyCriteria(); // gets criteria w/ primary key(s)
        }

        // set the correct dbName
        \$criteria->setDbName(" . $this->getPeerClassname() . "::DATABASE_NAME);

        return {$this->basePeerClassname}::doUpdate(\$selectCriteria, \$criteria, \$con);
    }
";
    }
652617
protected function addDeleteMethods(&$script)
    {
        $this->addDoDeleteAll($script);
        $this->addDelete($script);

        if ($this->isDeleteCascadeEmulationNeeded()) {
            $this->addDoOnDeleteCascade($script);
        }

        if ($this->isDeleteSetNullEmulationNeeded()) {
            $this->addDoOnDeleteSetNull($script);
        }
    }
1200430
protected function addHydrate(&$script)
    {
        $this->addHydrateComment($script);
        $this->addHydrateOpen($script);
        $this->addHydrateBody($script);
        $this->addHydrateClose($script);
    }
1175285
protected function addClassBody(&$script)
    {
        $table = $this->getTable();

        // FIXME
        // - Probably the build needs to be customized for supporting
        // tables that are "aliases".  -- definitely a fringe usecase, though.

        $this->addConstants($script);

        $this->addIsCodeBase($script);

        $this->addRetrieveMethods($script);

        $this->addCreateNewRootNode($script);
        $this->addInsertNewRootNode($script);
        $this->addMoveNodeSubTree($script);
        $this->addDeleteNodeSubTree($script);

        $this->addBuildFamilyCriteria($script);
        $this->addBuildTree($script);

        $this->addPopulateNodes($script);
    }
854710
protected function addMutatorClose(&$script, Column $col)
    {
        $this->addMutatorCloseBody($script, $col);
        $this->addMutatorCloseClose($script, $col);
    }
28882
protected function addManipulationMethods(&$script)
    {
        $this->addReload($script);
        $this->addDelete($script);
        $this->addSave($script);
        $this->addDoSave($script);
        $script .= $this->addDoInsert();
        $script .= $this->addDoUpdate();
    }
453939
protected function addGetOMClassMethod(&$script)
    {
        $table = $this->getTable();
        if ($table->getChildrenColumn()) {
            $this->addGetOMClass_Inheritance($script);
        } else {
            if ($table->isAbstract()) {
                $this->addGetOMClass_NoInheritance_Abstract($script);
            } else {
                $this->addGetOMClass_NoInheritance($script);
            }
        }
    }
17787
protected function addHydrateBody(&$script)
    {
        $table = $this->getTable();
        $platform = $this->getPlatform();

        $tableMap = $this->getTableMapClassName();

        $script .= "
        try {";
        $n = 0;
        foreach ($table->getColumns() as $col) {
            if (!$col->isLazyLoad()) {
                $indexName = "TableMap::TYPE_NUM == \$indexType ? $n + \$startcol : $tableMap::translateFieldName('{$col->getPhpName()}', TableMap::TYPE_PHPNAME, \$indexType)";

                $script .= "

            \$col = \$row[$indexName];";
                $clo = $col->getLowercasedName();
                if ($col->getType() === PropelTypes::CLOB_EMU && $this->getPlatform() instanceof OraclePlatform) {
                    // PDO_OCI returns a stream for CLOB objects, while other PDO adapters return a string...
                    $script .= "
            \$this->$clo = stream_get_contents(\$col);";
                } elseif ($col->isLobType() && !$platform->hasStreamBlobImpl()) {
                    $script .= "
            if (null !== \$col) {
                \$this->$clo = fopen('php://memory', 'r+');
                fwrite(\$this->$clo, \$col);
                rewind(\$this->$clo);
            } else {
                \$this->$clo = null;
            }";
                } elseif ($col->isTemporalType()) {
                    $dateTimeClass = $this->getDateTimeClass($col);
                    $handleMysqlDate = false;
                    if ($this->getPlatform() instanceof MysqlPlatform) {
                        if ($col->getType() === PropelTypes::TIMESTAMP) {
                            $handleMysqlDate = true;
                            $mysqlInvalidDateString = '0000-00-00 00:00:00';
                        } elseif ($col->getType() === PropelTypes::DATE) {
                            $handleMysqlDate = true;
                            $mysqlInvalidDateString = '0000-00-00';
                        }
                        // 00:00:00 is a valid time, so no need to check for that.
                    }
                    if ($handleMysqlDate) {
                        $script .= "
            if (\$col === '$mysqlInvalidDateString') {
                \$col = null;
            }";
                    }
                    $script .= "
            \$this->$clo = (null !== \$col) ? PropelDateTime::newInstance(\$col, null, '$dateTimeClass') : null;";
                } elseif ($col->isPhpPrimitiveType()) {
                    $script .= "
            \$this->$clo = (null !== \$col) ? (".$col->getPhpType().") \$col : null;";
                } elseif ($col->getType() === PropelTypes::OBJECT) {
                    $script .= "
            \$this->$clo = \$col;";
                } elseif ($col->getType() === PropelTypes::PHP_ARRAY) {
                    $cloUnserialized = $clo . '_unserialized';
                    $script .= "
            \$this->$clo = \$col;
            \$this->$cloUnserialized = null;";
                } elseif ($col->isSetType()) {
                    $cloConverted = $clo . '_converted';
                    $script .= "
            \$this->$clo = \$col;
            \$this->$cloConverted = null;";
                } elseif ($col->isPhpObjectType()) {
                    $script .= "
            \$this->$clo = (null !== \$col) ? new ".$col->getPhpType()."(\$col) : null;";
                } else {
                    $script .= "
            \$this->$clo = \$col;";
                }
                $n++;
            } // if col->isLazyLoad()
        } /* foreach */

        if ($this->getBuildProperty("generator.objectModel.addSaveMethod")) {
            $script .= "
            \$this->resetModified();
";
        }

        $script .= "
            \$this->setNew(false);

            if (\$rehydrate) {
                \$this->ensureConsistency();
            }
";

        $this->applyBehaviorModifier('postHydrate', $script, "            ");

        $script .= "
            return \$startcol + $n; // $n = ".$this->getTableMapClass()."::NUM_HYDRATE_COLUMNS.

        } catch (Exception \$e) {
            throw new PropelException(sprintf('Error populating %s object', ".var_export($this->getStubObjectBuilder()->getClassName(), true)."), 0, \$e);
        }";
    }
721163
protected function addClassBody(&$script)
    {
        $table = $this->getTable();

        $this->addAttributes($script);

        $this->addConstructor($script);

        $this->addCallOverload($script);
        $this->addSetIteratorOptions($script);
        $this->addGetIterator($script);

        $this->addGetNodeObj($script);
        $this->addGetNodePath($script);
        $this->addGetNodeIndex($script);
        $this->addGetNodeLevel($script);

        $this->addHasChildNode($script);
        $this->addGetChildNodeAt($script);
        $this->addGetFirstChildNode($script);
        $this->addGetLastChildNode($script);
        $this->addGetSiblingNode($script);

        $this->addGetParentNode($script);
        $this->addGetAncestors($script);
        $this->addIsRootNode($script);

        $this->addSetNew($script);
        $this->addSetDeleted($script);
        $this->addAddChildNode($script);
        $this->addMoveChildNode($script);
        $this->addSave($script);

        $this->addDelete($script);
        $this->addEquals($script);

        $this->addAttachParentNode($script);
        $this->addAttachChildNode($script);
        $this->addDetachParentNode($script);
        $this->addDetachChildNode($script);
        $this->addShiftChildNodes($script);
        $this->addInsertNewChildNode($script);

        $this->addAdjustStatus($script);
        $this->addAdjustNodePath($script);
    }