[TYPO3-mvc] Problem with attaching objects to a model

Lang, Patrik Patrik.Lang at centaur.de
Tue May 11 16:19:59 CEST 2010


Hi,

I have a problem with attaching objects to a model. The objects are attached, but the relations won't be saved to database.

I think this is a bit complexe because I don't have "normal" models. I extended the models Tx_Extbase_Domain_Model_FrontendUser and Tx_Extbase_Domain_Model_FrontendUserGroup.

I have my two models Tx_Xchange_Domain_Model_User and Tx_Xchange_Domain_Model_Group with their Repositories Tx_Xchange_Domain_Repository_UserRepository and Tx_Xchange_Domain_Repository_GroupRepository.

This is my User model (partial):

/**
 * A User
 *
 * @version $Id:$
 * @copyright Copyright belongs to the respective authors
 * @scope prototype
 * @entity
 */
class Tx_Xchange_Domain_Model_User extends Tx_Extbase_Domain_Model_FrontendUser {
     /**
      * @var Tx_Extbase_Persistence_ObjectStorage<Tx_Xchange_Domain_Model_Group>
      * @lazy
      */
     protected $usergroup;

     ...

     /**
      * Sets the usergroups. Keep in mind that the property is called "usergroup"
      * although it can hold several usergroups.
      *
      * @param Tx_Extbase_Persistence_ObjectStorage<Tx_Xchange_Domain_Model_Group> $usergroups An object storage containing the usergroups to add
      * @return void
      * @api
      */
     public function setUsergroup(Tx_Extbase_Persistence_ObjectStorage $usergroups) {
          $this->usergroups = $usergroups;
     }

     /**
      * Adds a usergroup to the frontend user
      *
      * @param Tx_Xchange_Domain_Model_Group $usergroup
      * @return void
      * @api
      */
     public function addUsergroup(Tx_Xchange_Domain_Model_Group $usergroup) {
          $this->usergroup->attach($usergroup);
     }

     /**
      * Removes a usergroup from the frontend user
      *
      * @param Tx_Xchange_Domain_Model_Group $usergroup
      * @return void
      * @api
      */
     public function removeUsergroup(Tx_Xchange_Domain_Model_Group $usergroup) {
          $this->usergroup->detach($usergroup);
     }

     /**
      * Removes all usergroups from the frontend user
      *
      * @return void
      * @api
      */
     public function removeAllUsergroups() {
          $this->usergroup = new Tx_Extbase_Persistence_ObjectStorage();
     }
}

The creation of the StorageObject for usergroup is in parent class

And my Group Model:

/**
 * A Group
 *
 * @version $Id:$
 * @copyright Copyright belongs to the respective authors
 * @scope prototype
 * @entity
 */
class Tx_Xchange_Domain_Model_Group extends Tx_Extbase_Domain_Model_FrontendUserGroup {

     /**
      * @var Tx_Extbase_Persistence_ObjectStorage<Tx_Xchange_Domain_Model_Group>
      */
     protected $subgroup;


     /**
      * Sets the subgroups. Keep in mind that the property is called "subgroup"
      * although it can hold several subgroups.
      *
      * @param Tx_Extbase_Persistence_ObjectStorage<Tx_Xchange_Domain_Model_Group> $subgroup An object storage containing the subgroups to add
      * @return void
      * @api
      */
     public function setSubgroup(Tx_Extbase_Persistence_ObjectStorage $subgroup) {
          $this->subgroup = $subgroup;
     }

     /**
      * Adds a subgroup to the frontend user
      *
      * @param Tx_Xchange_Domain_Model_Group $subgroup
      * @return void
      * @api
      */
     public function addSubgroup(Tx_Xchange_Domain_Model_Group $subgroup) {
          $this->subgroup->attach($subgroup);
     }

     /**
      * Removes a subgroup from the frontend user group
      *
      * @param Tx_Xchange_Domain_Model_Group $subgroup
      * @return void
      * @api
      */
     public function removeSubgroup(Tx_Xchange_Domain_Model_Group $subgroup) {
          $this->subgroup->detach($subgroup);
     }
}

I added the recordType in ext_tables.php:

t3lib_div::loadTCA('fe_users');
$TCA['fe_users']['types']['Tx_Xchange_Domain_Model_User'] = $TCA['fe_users']['types']['0'];
array_push($TCA['fe_users']['columns']['tx_extbase_type']['config']['items'], array('LLL:EXT:'.$_EXTKEY.'/Resources/Private/Language/locallang_db.xml:fe_users.tx_extbase_type.Tx_Xchange_Domain_Model_User', 'Tx_Xchange_Domain_Model_User'));

t3lib_div::loadTCA('fe_groups');
$TCA['fe_groups']['types']['Tx_Xchange_Domain_Model_Group'] = $TCA['fe_groups']['types']['0'];
array_push($TCA['fe_groups']['columns']['tx_extbase_type']['config']['items'], array('LLL:EXT:'.$_EXTKEY.'/Resources/Private/Language/locallang_db.xml:fe_groups.tx_extbase_type.Tx_Xchange_Domain_Model_Group', 'Tx_Xchange_Domain_Model_Group'));

This is my TS:

Extbase config:

config.tx_extbase.persistence.classes {
     Tx_Xchange_Domain_Model_User {
          mapping.tableName = fe_users
          subclasses {
                Tx_Xchange_Domain_Model_User = Tx_Xchange_Domain_Model_User
          }
     }

     Tx_Xchange_Domain_Model_Group {
          mapping.tableName = fe_groups
          subclasses {
                Tx_Xchange_Domain_Model_Group = Tx_Xchange_Domain_Model_Group
          }
     }
}

Extension config (partial)

Plugin.tx_xchange {
     ...
     persistence {
          storagePid = 4,6,14
          classes {
                Tx_Xchange_Domain_Model_User {
                     newRecordStoragePid = 6
                     mapping {
                          tableName = fe_users
                          recordType = Tx_Xchange_Domain_Model_User
                          columns.usergroup.foreignClass = Tx_Xchange_Domain_Model_Group
                     }
                }
                Tx_Xchange_Domain_Model_Group {
                     newRecordStoragePid = 6
                     mapping {
                          tableName = fe_groups
                          recordType = Tx_Xchange_Domain_Model_Group
                          columns.subgroup.foreignClass = Tx_Xchange_Domain_Model_Group
                     }
                }
                Tx_Xchange_Domain_Model_File {
                     newRecordStoragePid = 4
                     mapping {
                          tableName = tx_dam
                          columns {
                               x_fe_groups.foreignClass = Tx_Xchange_Domain_Model_Group
                               x_fe_users.foreignClass = Tx_Xchange_Domain_Model_User
                               x_uploader.foreignClass = Tx_Xchange_Domain_Model_User
                          }
                     }
                }
          }
     }
}

Now I created a backend module to manage the users and some more. I have already a table which displays all users and their assigned usergroups (assigned by TYPO3 backend)

When I now edit a user I have two HTML select. One for displaying already assigned groups and one which shows the available groups.

With these selects you can assign new groups or delete them like in the TYPO3 backend, just in my own way to look more like ExtJs (I tried Itemselector, but it doesn't work with the integrated ExtJs version)

I tried to do it with one select (<f:form.select property="usergroup" ... />) but when I then submit the form I get an error "Core: Exception handler (WEB): Uncaught TYPO3 Exception: #1255082824: Request hash (HMAC) checking failed. The parameter __hmac was invalid or not set, and objects were modified. | Tx_Extbase_MVC_Exception_InvalidOrNoRequestHash thrown in file ..."

When I now submit the form I get three parameters in my saveAction:

     /**
      * Save or add given user to database
      *
      * @param Tx_Xchange_Domain_Model_User $user
      * @param string $usergroups comma separated list of usergroup uids (optional)
      * @param int $close state if the edit form should be close (optional)
      * @dontvalidate $usergroups
      * @dontvalidate $close
      * @return void
      */
     public function saveAction(Tx_Xchange_Domain_Model_User $user, $usergroups = '', $close = 0) {
          $user->removeAllUsergroups();

          $usergroupUids = explode(',', $usergroups);
          foreach($usergroupUids as $usergroupUid) {
                $usergroupUid = intval(trim($usergroupUid));
                $usergroup = $this->groupRepository->findByUid($usergroupUid);
                $user->addUsergroup($usergroup);
          }

          $uid = $user->getUid();
          if(!empty($uid)) {
                $this->userRepository->update($user);
                $msg = str_replace('###username###', $user->getUsername(),
                     $this->translate('be_user_flash_saved'));
          } else {
                $this->userRepository->add($user);
                $msg = str_replace('###username###', $user->getUsername(),
                     $this->translate('be_user_flash_added'));
          }
          unset($uid);
          $this->flashMessages->add($msg);

          if($close == 1)
          {
                $this->redirect('index');
          }
          $this->redirect('edit', 'User', $this->_EXTNAME, array(
                'user' => $user
          ));
     }

As you see the usergroups are submitted as comma separated list which gets exploded. Then I fetch the usergroup objects and attach them to the user.

Do I now debug the $user with print_r, var_dump or t3lib_div::debug I get the assigned usergroups, but if the redirect is done, they are gone.

So does anybody know this issue?

Thanks
Patrik

P.S. can someone tell me how to answer to an anwser of this thread, because everytime I awnser by clicking of the email address of the poster it will be created a new thread (see [TYPO3-mvc] Error Tx_Extbase_MVC_Exception_InvalidArgumentValue)

I use Outlook 2007

________________________________
Diese Information ist ausschliesslich fuer die adressierte Person oder Organisation bestimmt und koennte vertrauliches und/oder privilegiertes Material enthalten. Personen oder Organisationen, fuer die diese Information nicht bestimmt ist, ist es nicht gestattet, diese zu lesen, erneut zu uebertragen, zu verbreiten, anderweitig zu verwenden oder sich durch sie veranlasst zu sehen, Massnahmen irgendeiner Art zu ergreifen. Sollten Sie diese Nachricht irrtuemlich erhalten haben, bitten wir Sie, sich mit dem Absender in Verbindung zu setzen und das Material von Ihrem Computer zu loeschen.

Sie haben uns gebeten, mit Ihnen ueber das Internet per E-Mail zu korrespondieren. Unbeschadet dessen ist allein die von uns unterzeichnete schriftliche Fassung verbindlich. Wir weisen darauf hin, dass derartige Nachrichten mit und ohne Zutun von Dritten verloren gehen, veraendert oder verfaelscht werden koennen. Herkoemmliche E-Mails sind nicht gegen den Zugriff von Dritten geschuetzt und deshalb ist auch die Vertraulichkeit unter Umstaenden nicht gewahrt Wir haften deshalb nicht fuer die Unversehrtheit von E-Mails nachdem sie unseren Herrschaftsbereich verlassen haben und koennen Ihnen hieraus entstehende Schaeden nicht ersetzen. Sollte trotz der von uns verwendeten Virus-Schutz-Programmen durch die Zusendung von E-Mails ein Virus in Ihre Systeme gelangen, haften wir nicht fuer eventuell hieraus entstehende Schaeden. Dieser Haftungsausschluss gilt nur soweit gesetzlich zulaessig.


More information about the TYPO3-project-typo3v4mvc mailing list