/** * Saves (updates or creates) a user. * * @param User $user * @throws Exception * @return User */ public function save(User $user) { $connection = $this->userTable->getAdapter()->getDriver()->getConnection(); if (!$connection->inTransaction()) { $connection->beginTransaction(); $transaction = true; } else { $transaction = false; } try { if ($user->get('uid')) { /* Update existing user */ /* Determine updated properties */ $updates = array(); foreach ($user->need('updatedProperties') as $property) { $updates[$property] = $user->get($property); } if ($updates) { $this->userTable->update($updates, array('uid' => $user->get('uid'))); } /* Determine new meta properties */ foreach ($user->need('insertedMetaProperties') as $metaProperty) { $this->userMetaTable->insert(array('uid' => $user->get('uid'), 'key' => $metaProperty, 'value' => $user->needMeta($metaProperty))); } /* Determine updated meta properties */ foreach ($user->need('updatedMetaProperties') as $metaProperty) { $this->userMetaTable->update(array('value' => $user->needMeta($metaProperty)), array('uid' => $user->get('uid'), 'key' => $metaProperty)); } /* Determine removed meta properties */ foreach ($user->need('removedMetaProperties') as $metaProperty) { $this->userMetaTable->delete(array('uid' => $user->get('uid'), 'key' => $metaProperty)); } $user->reset(); $this->getEventManager()->trigger('save.update', $user); } else { /* Insert user */ $created = date('Y-m-d H:i:s'); if ($user->getExtra('nuid')) { $uid = $user->getExtra('nuid'); } else { $uid = null; } $this->userTable->insert(array('uid' => $uid, 'alias' => $user->need('alias'), 'status' => $user->need('status'), 'email' => $user->get('email'), 'pw' => $user->get('pw'), 'login_attempts' => $user->get('login_attempts'), 'login_detent' => $user->get('login_detent'), 'last_activity' => $user->get('last_activity'), 'last_ip' => $user->get('last_ip'), 'created' => $user->get('created', $created))); $uid = $this->userTable->getLastInsertValue(); if (!(is_numeric($uid) && $uid > 0)) { throw new RuntimeException('Failed to save user'); } foreach ($user->need('meta') as $key => $value) { $this->userMetaTable->insert(array('uid' => $uid, 'key' => $key, 'value' => $value)); if (!$this->userMetaTable->getLastInsertValue()) { throw new RuntimeException(sprintf('Failed to save user meta key "%s"', $key)); } } $user->add('uid', $uid); if (!$user->get('created')) { $user->add('created', $created); } $this->getEventManager()->trigger('save.insert', $user); } if ($transaction) { $connection->commit(); } $this->getEventManager()->trigger('save', $user); return $user; } catch (Exception $e) { if ($transaction) { $connection->rollback(); } throw $e; } }