Author: Thierry Francois @colymba thierry@colymba.com
 /**
  * Update databse record or $model
  *
  * @param String $model the model class to update
  * @param Integer $id The ID of the model to update
  * @param SS_HTTPRequest the original request
  *
  * @return DataObject The updated model 
  */
 function updateModel($model, $id, $request)
 {
     $model = DataObject::get_by_id($model, $id);
     if (!$model) {
         return new RESTfulAPI_Error(404, "Record not found.");
     }
     if (!RESTfulAPI::api_access_control($model, $request->httpMethod())) {
         return new RESTfulAPI_Error(403, "API access denied.");
     }
     $payload = $this->deSerializer->deserialize($request->getBody());
     if ($payload instanceof RESTfulAPI_Error) {
         return $payload;
     }
     if ($model && $payload) {
         $has_one = Config::inst()->get($model->ClassName, 'has_one');
         $has_many = Config::inst()->get($model->ClassName, 'has_many');
         $many_many = Config::inst()->get($model->ClassName, 'many_many');
         $belongs_many_many = Config::inst()->get($model->ClassName, 'belongs_many_many');
         $many_many_extraFields = array();
         if (isset($payload['ManyManyExtraFields'])) {
             $many_many_extraFields = $payload['ManyManyExtraFields'];
             unset($payload['ManyManyExtraFields']);
         }
         $hasChanges = false;
         $hasRelationChanges = false;
         foreach ($payload as $attribute => $value) {
             if (!is_array($value)) {
                 if (is_array($has_one) && array_key_exists($attribute, $has_one)) {
                     $relation = $attribute . 'ID';
                     $model->{$relation} = $value;
                     $hasChanges = true;
                 } else {
                     if ($model->{$attribute} != $value) {
                         $model->{$attribute} = $value;
                         $hasChanges = true;
                     }
                 }
             } else {
                 //has_many, many_many or $belong_many_many
                 if (is_array($has_many) && array_key_exists($attribute, $has_many) || is_array($many_many) && array_key_exists($attribute, $many_many) || is_array($belongs_many_many) && array_key_exists($attribute, $belongs_many_many)) {
                     $hasRelationChanges = true;
                     $ssList = $model->{$attribute}();
                     $ssList->removeAll();
                     //reset list
                     foreach ($value as $id) {
                         // check if there is extraFields
                         if (array_key_exists($attribute, $many_many_extraFields)) {
                             if (isset($many_many_extraFields[$attribute][$id])) {
                                 $ssList->add($id, $many_many_extraFields[$attribute][$id]);
                                 continue;
                             }
                         }
                         $ssList->add($id);
                     }
                 }
             }
         }
         if ($hasChanges || $hasRelationChanges) {
             $model->write(false, false, false, $hasRelationChanges);
         }
     }
     return DataObject::get_by_id($model->ClassName, $model->ID);
 }
 /**
  * Update databse record or $model
  *
  * @param String|DataObject $model the model or class to update
  * @param Integer $id The ID of the model to update
  * @param SS_HTTPRequest the original request
  *
  * @return DataObject The updated model 
  */
 function updateModel($model, $id, $request)
 {
     if (is_string($model)) {
         $model = DataObject::get_by_id($model, $id);
     }
     if (!$model) {
         return new RESTfulAPI_Error(404, "Record not found.");
     }
     if (!RESTfulAPI::api_access_control($model, $request->httpMethod())) {
         return new RESTfulAPI_Error(403, "API access denied.");
     }
     $rawJson = $request->getBody();
     // Before deserialize hook
     if (method_exists($model, 'onBeforeDeserialize')) {
         $model->onBeforeDeserialize($rawJson);
     }
     $model->extend('onBeforeDeserialize', $rawJson);
     $payload = $this->deSerializer->deserialize($rawJson);
     if ($payload instanceof RESTfulAPI_Error) {
         return $payload;
     }
     // After deserialize hook
     if (method_exists($model, 'onAfterDeserialize')) {
         $model->onAfterDeserialize($payload);
     }
     $model->extend('onAfterDeserialize', $payload);
     if ($model && $payload) {
         $has_one = Config::inst()->get($model->ClassName, 'has_one');
         $has_many = Config::inst()->get($model->ClassName, 'has_many');
         $many_many = Config::inst()->get($model->ClassName, 'many_many');
         $belongs_many_many = Config::inst()->get($model->ClassName, 'belongs_many_many');
         $many_many_extraFields = array();
         if (isset($payload['ManyManyExtraFields'])) {
             $many_many_extraFields = $payload['ManyManyExtraFields'];
             unset($payload['ManyManyExtraFields']);
         }
         $hasChanges = false;
         $hasRelationChanges = false;
         foreach ($payload as $attribute => $value) {
             if (!is_array($value)) {
                 if (is_array($has_one) && array_key_exists($attribute, $has_one)) {
                     $relation = $attribute . 'ID';
                     $model->{$relation} = $value;
                     $hasChanges = true;
                 } else {
                     if ($model->{$attribute} != $value) {
                         $model->{$attribute} = $value;
                         $hasChanges = true;
                     }
                 }
             } else {
                 //has_many, many_many or $belong_many_many
                 if (is_array($has_many) && array_key_exists($attribute, $has_many) || is_array($many_many) && array_key_exists($attribute, $many_many) || is_array($belongs_many_many) && array_key_exists($attribute, $belongs_many_many)) {
                     $hasRelationChanges = true;
                     $ssList = $model->{$attribute}();
                     $ssList->removeAll();
                     //reset list
                     foreach ($value as $id) {
                         // check if there is extraFields
                         if (array_key_exists($attribute, $many_many_extraFields)) {
                             if (isset($many_many_extraFields[$attribute][$id])) {
                                 $ssList->add($id, $many_many_extraFields[$attribute][$id]);
                                 continue;
                             }
                         }
                         $ssList->add($id);
                     }
                 }
             }
         }
         if ($hasChanges || !$model->ID) {
             try {
                 $id = $model->write(false, false, false, $hasRelationChanges);
             } catch (ValidationException $exception) {
                 $error = $exception->getResult();
                 return new RESTfulAPI_Error(400, $error->message());
             }
             if (!$id) {
                 return new RESTfulAPI_Error(500, "Error writting data.");
             } else {
                 return DataObject::get_by_id($model->ClassName, $id);
             }
         } else {
             return $model;
         }
     } else {
         return new RESTfulAPI_Error(400, "Missing model or payload.");
     }
 }