* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2 * @author Icinga Development Team */ // {{{ICINGA_LICENSE_HEADER}}} namespace Icinga\User\Preferences; use Icinga\User; use SplSubject; use Zend_Db_Adapter_Abstract; use Icinga\Exception\ProgrammingError; use Icinga\User\Preferences; /** * Store user preferences in database */ class DbStore implements LoadInterface, FlushObserverInterface { /** * Column name for username */ const COLUMN_USERNAME = 'username'; /** * Column name for preference */ const COLUMN_PREFERENCE = 'preference'; /** * Column name for value */ const COLUMN_VALUE = 'value'; /** * User object * * @var User */ private $user; /** * Zend database adapter * * @var Zend_Db_Adapter_Abstract */ private $dbAdapter; /** * Table name * * @var string */ private $table = 'preferences'; /** * Setter for user * * @param User $user */ public function setUser(User $user) { $this->user = $user; } /** * Setter for db adapter * * @param Zend_Db_Adapter_Abstract $dbAdapter */ public function setDbAdapter(Zend_Db_Adapter_Abstract $dbAdapter) { $this->dbAdapter = $dbAdapter; $this->dbAdapter->getProfiler()->setEnabled(true); } /** * Setter for table * * @param string $table */ public function setTable($table) { $this->table = $table; } /** * Load preferences from source * * @return array */ public function load() { $res = $this->dbAdapter->select()->from($this->table) ->where('username=?', $this->user->getUsername()) ->query(); $out = array(); foreach ($res->fetchAll() as $row) { $out[$row[self::COLUMN_PREFERENCE]] = $row[self::COLUMN_VALUE]; } return $out; } /** * Helper to create zend db suitable where condition * * @param string $preference * @return array */ private function createWhereCondition($preference) { return array( self::COLUMN_USERNAME. '=?' => $this->user->getUsername(), self::COLUMN_PREFERENCE. '=?' => $preference ); } /** * Create operation * * @param string $preference * @param mixed $value * @return int */ private function doCreate($preference, $value) { return $this->dbAdapter->insert( $this->table, array( self::COLUMN_USERNAME => $this->user->getUsername(), self::COLUMN_PREFERENCE => $preference, self::COLUMN_VALUE => $value ) ); } /** * Update operation * * @param string $preference * @param mixed $value * @return int */ private function doUpdate($preference, $value) { return $this->dbAdapter->update( $this->table, array( self::COLUMN_VALUE => $value ), $this->createWhereCondition($preference) ); } /** * Delete preference operation * * @param string $preference * @return int */ private function doDelete($preference) { return $this->dbAdapter->delete( $this->table, $this->createWhereCondition($preference) ); } /** * Receive update from subject * * @link http://php.net/manual/en/splobserver.update.php * @param SplSubject $subject * @throws ProgrammingError */ public function update(SplSubject $subject) { if (!$subject instanceof Preferences) { throw new ProgrammingError('Not compatible with '. get_class($subject)); } $changeSet = $subject->getChangeSet(); foreach ($changeSet->getCreate() as $key => $value) { $retVal = $this->doCreate($key, $value); if (!$retVal) { throw new ProgrammingError('Could not create preference value in db: '. $key. '='. $value); } } foreach ($changeSet->getUpdate() as $key => $value) { $retVal = $this->doUpdate($key, $value); /* * Fallback if we switch storage type while user logged in */ if (!$retVal) { $retVal = $this->doCreate($key, $value); if (!$retVal) { throw new ProgrammingError('Could not create preference value in db: '. $key. '='. $value); } } } foreach ($changeSet->getDelete() as $key) { $retVal = $this->doDelete($key); if (!$retVal) { throw new ProgrammingError('Could not delete preference value in db: '. $key); } } } }