public function save($data)
 {
     if (isset($data['id']) && intval($data['id']) > 0) {
         $gpService = new EngineBlock_Service_GroupProvider();
         $gp = $gpService->fetchById(intval($data['id']));
     } else {
         $gp = new EngineBlock_Model_GroupProvider();
     }
     $gp->populate($data);
     $form = new EngineBlock_Form_GroupProvider();
     if (!$form->isValid($gp->toArray())) {
         $formErrors = $form->getErrors();
         $modelErrors = array();
         foreach ($formErrors as $fieldName => $fieldErrors) {
             foreach ($fieldErrors as $fieldError) {
                 switch ($fieldError) {
                     case 'isEmpty':
                         $error = 'Field is obligatory, but no input given';
                         break;
                     default:
                         $error = $fieldError;
                 }
                 if (!isset($modelErrors[$fieldName])) {
                     $modelErrors[$fieldName] = array();
                 }
                 $modelErrors[$fieldName][] = $error;
             }
         }
         $gp->errors = $modelErrors;
     } else {
         $mapper = new EngineBlock_Model_Mapper_GroupProvider(new EngineBlock_Model_DbTable_GroupProvider());
         $gp = $mapper->save($gp, !(intval($data['id']) > 0));
     }
     return $gp;
 }
 protected function _mapGroupProviderToRow(EngineBlock_Model_GroupProvider $groupProvider, Zend_Db_Table_Row_Abstract $row, $optionRows)
 {
     // the basics
     $row['id'] = $groupProvider->id;
     $row['identifier'] = $groupProvider->identifier;
     $row['name'] = $groupProvider->name;
     $row['logo_url'] = $groupProvider->logoUrl;
     // transformations model->row:
     // * authentication type -> classname
     if (isset($groupProvider->authentication)) {
         $authType = is_array($groupProvider->authentication) ? $groupProvider->authentication[0] : "GROUPER";
         switch ($authType) {
             case 'BASIC':
                 $row['classname'] = EngineBlock_Model_GroupProvider::getClassname('OPENSOCIAL_BASIC');
                 break;
             case 'OAUTH':
                 $row['classname'] = EngineBlock_Model_GroupProvider::getClassname('OPENSOCIAL_OAUTH');
                 break;
             case 'GROUPER':
                 $row['classname'] = EngineBlock_Model_GroupProvider::getClassname('GROUPER');
                 break;
             default:
                 $row['classname'] = $groupProvider->fullClassname;
                 break;
         }
     } else {
         if (isset($groupProvider->classname)) {
             $row['classname'] = EngineBlock_Model_GroupProvider::getClassname($groupProvider->classname);
         }
     }
     // *
     // special case: grouper URL is split into several components
     if ($groupProvider->classname == "GROUPER" && strlen(trim($groupProvider->url)) > 0) {
         $components = parse_url(trim($groupProvider->url));
         if (is_array($components)) {
             $groupProvider->protocol = $components['scheme'];
             $groupProvider->host = $components['host'];
             $pathList = array_filter(explode("/", $components['path']));
             $groupProvider->version = array_shift($pathList);
             $groupProvider->path = '/' . implode("/", $pathList);
         }
         unset($groupProvider->url);
     }
     // map preconditions
     $preconditions = array();
     if ($groupProvider->classname == 'OPENSOCIAL_OAUTH') {
         // mandatory precondition for OAuth
         $preconditions[] = array('group_provider_id' => $groupProvider->id, 'classname' => 'EngineBlock_Group_Provider_Precondition_OpenSocial_Oauth_AccessTokenExists');
     }
     if ($groupProvider->user_id_match == 'on') {
         // user id must match
         $preconditions[] = array('group_provider_id' => $row['id'], 'classname' => 'EngineBlock_Group_Provider_Precondition_UserId_PregMatch', 'options' => array(array('name' => 'search', 'value' => $groupProvider->user_id_match_search)));
     }
     $decorators = array();
     if ($groupProvider->modify_group_id == 'on') {
         // group id modifier
         $decorators[] = array('group_provider_id' => $row['id'], 'classname' => 'EngineBlock_Group_Provider_Decorator_GroupIdReplace', 'options' => array(array('name' => 'search', 'value' => $groupProvider->modify_group_id_search), array('name' => 'replace', 'value' => $groupProvider->modify_group_id_replace)));
     }
     if ($groupProvider->modify_user_id == 'on') {
         // user id modifier
         $decorators[] = array('group_provider_id' => $row['id'], 'classname' => 'EngineBlock_Group_Provider_Decorator_UserIdReplace', 'options' => array(array('name' => 'search', 'value' => $groupProvider->modify_user_id_search), array('name' => 'replace', 'value' => $groupProvider->modify_user_id_replace)));
     }
     $filters = array();
     if ($groupProvider->modify_group == 'on') {
         foreach ($groupProvider->modify_group_rule as $rule) {
             $filters[] = array('group_provider_id' => $row['id'], 'classname' => 'EngineBlock_Group_Provider_Filter_ModelProperty_PregReplace', 'type' => 'group', 'options' => array(array('name' => 'property', 'value' => $rule['property']), array('name' => 'search', 'value' => $rule['search']), array('name' => 'replace', 'value' => $rule['replace'])));
         }
     }
     if ($groupProvider->modify_user == 'on') {
         foreach ($groupProvider->modify_user_rule as $rule) {
             $filters[] = array('group_provider_id' => $row['id'], 'classname' => 'EngineBlock_Group_Provider_Filter_ModelProperty_PregReplace', 'type' => 'groupMember', 'options' => array(array('name' => 'property', 'value' => $rule['property']), array('name' => 'search', 'value' => $rule['search']), array('name' => 'replace', 'value' => $rule['replace'])));
         }
     }
     // map existing and new options to new option rows
     $gpoTable = new EngineBlock_Model_DbTable_GroupProviderOption();
     $newOptionRows = array();
     foreach (EngineBlock_Model_GroupProvider::$allowedOptions as $column => $option) {
         if (isset($groupProvider->{$column})) {
             // update?
             $updated = false;
             foreach ($optionRows as $optionRow) {
                 if ($optionRow->name == $option) {
                     $optionRow->value = $groupProvider->{$column};
                     $newOptionRows[] = $optionRow;
                     $updated = true;
                     break;
                 }
             }
             // insert?
             if (!$updated) {
                 $newOptionRow = $gpoTable->createRow();
                 $newOptionRow->group_provider_id = $row['id'];
                 $newOptionRow->name = $option;
                 $newOptionRow->value = $groupProvider->{$column};
                 $newOptionRows[] = $newOptionRow;
             }
         }
     }
     return array($row, $newOptionRows, $preconditions, $decorators, $filters);
 }