/** * Returns a Ingo_Transport instance. * * @param array $transport A transport driver name and parameter hash. * * @return Ingo_Transport The Ingo_Transport instance. * @throws Ingo_Exception */ public function create(array $transport) { global $registry; /* Get authentication parameters. */ try { $auth = $GLOBALS['injector']->getInstance('Horde_Core_Hooks')->callHook('transport_auth', 'ingo', array($transport['driver'])); } catch (Horde_Exception_HookNotSet $e) { $auth = null; } if (!is_array($auth)) { $auth = array(); } if (!isset($auth['password'])) { $auth['password'] = $registry->getAuthCredential('password'); } if (!isset($auth['username'])) { $auth['username'] = $registry->getAuth('bare'); } if (!isset($auth['euser'])) { $auth['euser'] = Ingo::getUser(false); } $class = 'Ingo_Transport_' . ucfirst($transport['driver']); if (class_exists($class)) { return new $class(array_merge($auth, $transport['params'])); } throw new Ingo_Exception(sprintf(_("Unable to load the transport driver \"%s\"."), $class)); }
/** * Replaces place holders in a query. * * @param string $query A SQL query with place holders. * @param integer $rule A Ingo::RULE_* constant. * * @return string A valid query. */ protected function _placeHolders($query, $rule) { $transport = $GLOBALS['injector']->getInstance('Ingo_Factory_Transport')->create(isset($this->_params['transport'][$rule]) ? $this->_params['transport'][$rule] : $this->_params['transport'][Ingo::RULE_ALL]); $search = array('%u', '%d'); $replace = array($transport->quote(Ingo::getUser()), $transport->quote(Ingo::getDomain())); switch ($rule) { case Ingo::RULE_VACATION: $vacation = $this->_params['storage']->retrieve(Ingo_Storage::ACTION_VACATION); $search[] = '%m'; $search[] = '%s'; $replace[] = $transport->quote($vacation->getVacationReason()); $replace[] = $transport->quote($vacation->getVacationSubject()); break; } return str_replace($search, $replace, $query); }
/** */ protected function _storeBackend($action, $rule) { $user = Ingo::getUser(); switch ($action) { case self::STORE_ADD: try { $res = $this->_params['db']->aggregate(array(array('$match' => array(self::WHO => $user)), array('$group' => array(self::MONGO_ID => '', 'max' => array('$max' => '$' . self::ORDER))))); if (isset($res['result'])) { $res = current($res['result']); $max = ++$res['max']; } else { $max = 0; } $this->_params['db']->insert(array(self::DATA => serialize($rule), self::ORDER => $max, self::WHO => $user)); } catch (MongoException $e) { throw new Ingo_Exception($e); } break; case self::STORE_DELETE: try { $this->_params['db']->remove(array(self::MONGO_ID => new MongoId($rule->uid), self::WHO => $user)); } catch (MongoException $e) { } break; case self::STORE_SORT: try { foreach ($this->_rules as $key => $val) { $this->_params['db']->update(array(self::MONGO_ID => new MongoId($val->uid), self::WHO => $user), array('$set' => array(self::ORDER => $key))); } } catch (MongoException $e) { } break; case self::STORE_UPDATE: try { $this->_params['db']->update(array(self::MONGO_ID => new MongoId($rule->uid), self::WHO => $user), array('$set' => array(self::DATA => serialize($rule)))); } catch (MongoException $e) { } break; } }
/** * Stores the specified data in the storage backend. * * @access private * * @param Ingo_Storage_Rule|Ingo_Storage_Filters $ob The object to store. */ protected function _store($ob) { switch ($ob->obType()) { case self::ACTION_BLACKLIST: case self::ACTION_WHITELIST: $is_blacklist = (int) ($ob->obType() == self::ACTION_BLACKLIST); if ($is_blacklist) { $filters = $this->retrieve(self::ACTION_FILTERS); $id = $filters->findRuleId(self::ACTION_BLACKLIST); if ($id !== null) { $rule = $filters->getRule($id); if (!isset($rule['action-value']) || $rule['action-value'] != $ob->getBlacklistFolder()) { $rule['action-value'] = $ob->getBlacklistFolder(); $filters->updateRule($rule, $id); } } } $query = sprintf('DELETE FROM %s WHERE list_owner = ? AND list_blacklist = ?', $this->_params['table_lists']); $values = array(Ingo::getUser(), $is_blacklist); try { $this->_params['db']->delete($query, $values); } catch (Horde_Db_Exception $e) { Horde::log($e, 'ERR'); throw new Ingo_Exception($e); } $query = sprintf('INSERT INTO %s (list_owner, list_blacklist, list_address) VALUES (?, ?, ?)', $this->_params['table_lists']); $addresses = $is_blacklist ? $ob->getBlacklist() : $ob->getWhitelist(); foreach ($addresses as $address) { try { $result = $this->_params['db']->insert($query, array(Ingo::getUser(), $is_blacklist, $address)); } catch (Horde_Db_Exception $e) { Horde::log($result, 'ERR'); throw new Ingo_Exception($e); } } $ob->setSaved(true); break; case self::ACTION_FORWARD: $values = array(implode("\n", $ob->getForwardAddresses()), (int) (bool) $ob->getForwardKeep(), Ingo::getUser()); try { if ($ob->isSaved()) { $query = sprintf('UPDATE %s SET forward_addresses = ?, forward_keep = ? WHERE forward_owner = ?', $this->_params['table_forwards']); $this->_params['db']->update($query, $values); } else { $query = sprintf('INSERT INTO %s (forward_addresses, forward_keep, forward_owner) VALUES (?, ?, ?)', $this->_params['table_forwards']); $this->_params['db']->insert($query, $values); } } catch (Horde_Db_Exception $e) { throw new Ingo_Exception($e); } $ob->setSaved(true); break; case self::ACTION_VACATION: $values = array(implode("\n", $ob->getVacationAddresses()), Horde_String::convertCharset($ob->getVacationSubject(), 'UTF-8', $this->_params['charset']), Horde_String::convertCharset($ob->getVacationReason(), 'UTF-8', $this->_params['charset']), (int) $ob->getVacationDays(), (int) $ob->getVacationStart(), (int) $ob->getVacationEnd(), implode("\n", $ob->getVacationExcludes()), (int) (bool) $ob->getVacationIgnorelist(), Ingo::getUser()); try { if ($ob->isSaved()) { $query = sprintf('UPDATE %s SET vacation_addresses = ?, vacation_subject = ?, vacation_reason = ?, vacation_days = ?, vacation_start = ?, vacation_end = ?, vacation_excludes = ?, vacation_ignorelists = ? WHERE vacation_owner = ?', $this->_params['table_vacations']); $this->_params['db']->update($query, $values); } else { $query = sprintf('INSERT INTO %s (vacation_addresses, vacation_subject, vacation_reason, vacation_days, vacation_start, vacation_end, vacation_excludes, vacation_ignorelists, vacation_owner) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', $this->_params['table_vacations']); $this->_params['db']->insert($query, $values); } } catch (Horde_Db_Exception $e) { throw new Ingo_Exception($e); } $ob->setSaved(true); break; case self::ACTION_SPAM: $values = array((int) $ob->getSpamLevel(), $ob->getSpamFolder(), Ingo::getUser()); try { if ($ob->isSaved()) { $query = sprintf('UPDATE %s SET spam_level = ?, spam_folder = ? WHERE spam_owner = ?', $this->_params['table_spam']); $this->_params['db']->update($query, $values); } else { $query = sprintf('INSERT INTO %s (spam_level, spam_folder, spam_owner) VALUES (?, ?, ?)', $this->_params['table_spam']); $this->_params['db']->insert($query, $values); } } catch (Horde_Db_Exception $e) { throw new Ingo_Exception($e); } $ob->setSaved(true); break; } }
/** * Connect to the VFS server. * * @throws Ingo_Exception */ protected function _connect() { /* Do variable substitution. */ if (!empty($this->_params['vfs_path'])) { $this->_params['vfs_path'] = str_replace(array('%u', '%d', '%U'), array(Ingo::getUser(), Ingo::getDomain(), $this->_params['username']), $this->_params['vfs_path']); } if (!empty($this->_vfs)) { return; } try { $this->_vfs = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Vfs')->create('ingo', array('type' => $this->_params['vfstype'], 'params' => $this->_params)); } catch (Horde_Exception $e) { throw new Ingo_Exception($e); } }
/** */ public function getVacationAddresses() { try { return $GLOBALS['injector']->getInstance('Horde_Core_Hooks')->callHook('vacation_addresses', 'ingo', array(Ingo::getUser(), $this->_addr)); } catch (Horde_Exception_HookNotSet $e) { return $this->_addr; } }
/** */ protected function _storeBackend($action, $rule) { switch ($action) { case self::STORE_ADD: try { $query = sprintf('SELECT MAX(rule_order) FROM %s WHERE rule_owner = ?', $this->_params['table_rules']); $values = array(Ingo::getUser()); $max = $this->_params['db']->selectValue($query, $values); } catch (Horde_Db_Exception $e) { throw new Ingo_Exception($e); } $query = sprintf('INSERT INTO %s (rule_owner, rule_name, rule_action, ' . 'rule_value, rule_flags, rule_conditions, rule_combine, ' . 'rule_stop, rule_active, rule_order) ' . 'VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', $this->_params['table_rules']); $d = $this->_ruleToBackend($rule); $values = array(Ingo::getUser(), $d['name'], $d['action'], $d['value'], $d['flags'], $d['conditions'], $d['combine'], $d['stop'], $d['active'], $max + 1); try { $rule->uid = $this->_params['db']->insert($query, $values); } catch (Horde_Db_Exception $e) { throw new Ingo_Exception($e); } break; case self::STORE_DELETE: $query = sprintf('DELETE FROM %s WHERE rule_id = ? AND rule_owner = ?', $this->_params['table_rules']); $values = array($rule->uid, Ingo::getUser()); try { /* No need to alter rule order; it is no longer contiguous, * but that doesn't affect sort order. */ $this->_params['db']->delete($query, $values); } catch (Horde_Db_Exception $e) { throw new Ingo_Exception($e); } break; case self::STORE_UPDATE: $query = sprintf('UPDATE %s SET rule_name = ?, rule_action = ?, ' . 'rule_value = ?, rule_flags = ?, rule_conditions = ?, ' . 'rule_combine = ?, rule_stop = ?, rule_active = ? ' . 'WHERE rule_id = ? AND rule_owner = ?', $this->_params['table_rules']); $d = $this->_ruleToBackend($rule); $values = array($d['name'], $d['action'], $d['value'], $d['flags'], $d['conditions'], $d['combine'], $d['stop'], $d['active'], $rule->uid, Ingo::getUser()); try { $this->_params['db']->update($query, $values); } catch (Horde_Db_Exception $e) { throw new Ingo_Exception($e); } break; case self::STORE_SORT: /* This won't update "invisible" rules based on current script * setup, but that is fine; sorting will still work if rules have * duplicate order IDs, and these invisible rules have no * guarantee of order if they are ever displayed again. */ $query = sprintf('UPDATE %s SET rule_order = ? WHERE rule_id = ?', $this->_params['table_rules']); $this->_params['db']->beginDbTransaction(); try { foreach ($this->_rules as $key => $val) { $this->_params['db']->update($query, array($key, $val->uid)); } } catch (Horde_Db_Exception $e) { $this->_params['db']->rollbackDbTransaction(); throw new Ingo_Exception($e); } $this->_params['db']->commitDbTransaction(); break; } switch ($action) { case self::STORE_ADD: case self::STORE_UPDATE: switch ($class = get_class($rule)) { case 'Ingo_Rule_System_Blacklist': case 'Ingo_Rule_System_Whitelist': $query = sprintf('DELETE FROM %s WHERE list_owner = ? AND ' . 'list_blacklist = ?', $this->_params['table_lists']); $values = array(Ingo::getUser(), intval($class === 'Ingo_Rule_System_Blacklist')); try { $this->_params['db']->delete($query, $values); } catch (Horde_Db_Exception $e) { Horde::log($e, 'ERR'); throw new Ingo_Exception($e); } $query = sprintf('INSERT INTO %s (list_owner, list_blacklist, ' . 'list_address) VALUES (?, ?, ?)', $this->_params['table_lists']); $this->_params['db']->beginDbTransaction(); try { foreach ($rule->addresses as $address) { $this->_params['db']->insert($query, array_merge($values, array($address))); } } catch (Horde_Db_Exception $e) { Horde::log($e, 'ERR'); throw new Ingo_Exception($e); } break; case 'Ingo_Rule_System_Forward': $values = array(implode("\n", $rule->addresses), intval($rule->keep), Ingo::getUser()); try { if ($action === self::STORE_ADD) { $query = sprintf('INSERT INTO %s (forward_addresses, ' . 'forward_keep, forward_owner) VALUES (?, ?, ?)', $this->_params['table_forwards']); $this->_params['db']->insert($query, $values); } else { $query = sprintf('UPDATE %s SET forward_addresses = ?, ' . 'forward_keep = ? WHERE forward_owner = ?', $this->_params['table_forwards']); $this->_params['db']->update($query, $values); } } catch (Horde_Db_Exception $e) { throw new Ingo_Exception($e); } break; case 'Ingo_Rule_System_Spam': $values = array($rule->level, $rule->mailbox, Ingo::getUser()); try { if ($action === self::STORE_ADD) { $query = sprintf('UPDATE %s SET spam_level = ?, ' . 'spam_folder = ? WHERE spam_owner = ?', $this->_params['table_spam']); $this->_params['db']->update($query, $values); } else { $query = sprintf('INSERT INTO %s (spam_level, spam_folder, ' . 'spam_owner) VALUES (?, ?, ?)', $this->_params['table_spam']); $this->_params['db']->insert($query, $values); } } catch (Horde_Db_Exception $e) { throw new Ingo_Exception($e); } break; case 'Ingo_Rule_System_Vacation': $values = array(implode("\n", $rule->addresses), Horde_String::convertCharset($rule->subject, 'UTF-8', $this->_params['charset']), Horde_String::convertCharset($rule->reason, 'UTF-8', $this->_params['charset']), $rule->days, $rule->start, $rule->end, implode("\n", $rule->exclude), intval($rule->ignore_list), Ingo::getUser()); try { if ($action === self::STORE_ADD) { $query = sprintf('INSERT INTO %s (vacation_addresses, ' . 'vacation_subject, vacation_reason, ' . 'vacation_days, vacation_start, vacation_end, ' . 'vacation_excludes, vacation_ignorelists, ' . 'vacation_owner) VALUES ' . '(?, ?, ?, ?, ?, ?, ?, ?, ?)', $this->_params['table_vacations']); $this->_params['db']->insert($query, $values); } else { $query = sprintf('UPDATE %s SET vacation_addresses = ?, ' . 'vacation_subject = ?, vacation_reason = ?, ' . 'vacation_days = ?, vacation_start = ?, ' . 'vacation_end = ?, vacation_excludes = ?, ' . 'vacation_ignorelists = ? WHERE ' . 'vacation_owner = ?', $this->_params['table_vacations']); $this->_params['db']->update($query, $values); } } catch (Horde_Db_Exception $e) { throw new Ingo_Exception($e); } break; } } }
/** * Deletes a rule from the filters list. * * @param integer $id Number of the rule to delete. * * @return boolean True if the rule has been found and deleted. */ public function deleteRule($id) { if (!isset($this->_filters[$id])) { return false; } $query = sprintf('DELETE FROM %s WHERE rule_id = ? AND rule_owner = ?', $this->_params['table_rules']); $values = array($this->_filters[$id]['id'], Ingo::getUser()); try { $this->_db->delete($query, $values); } catch (Horde_Db_Exception $e) { throw new Ingo_Exception($e); } /* Remove the rule from the filter list. */ unset($this->_filters[$id]); $this->_filters = array_combine(range(1, count($this->_filters)), array_values($this->_filters)); $query = sprintf('UPDATE %s SET rule_order = rule_order - 1 WHERE rule_owner = ? AND rule_order > ?', $this->_params['table_rules']); $values = array(Ingo::getUser(), $id); try { $this->_db->update($query, $values); } catch (Horde_Db_Exception $e) { throw new Ingo_Exception($e); } return true; }
/** * Returns the vacation reason with all placeholder replaced. * * @param string $reason The vacation reason including placeholders. * @param integer $start The vacation start timestamp. * @param integer $end The vacation end timestamp. * * @return string The vacation reason suitable for usage in the filter * scripts. */ public static function vacationReason($reason, $start, $end) { global $injector, $prefs; $format = $prefs->getValue('date_format'); $identity = $injector->getInstance('Horde_Core_Factory_Identity')->create(Ingo::getUser()); $replace = array('%NAME%' => $identity->getName(), '%EMAIL%' => $identity->getDefaultFromAddress(), '%SIGNATURE%' => $identity->getValue('signature'), '%STARTDATE%' => $start ? strftime($format, $start) : '', '%ENDDATE%' => $end ? strftime($format, $end) : ''); return str_replace(array_keys($replace), array_values($replace), $reason); }
/** * Get prefs object to use for storage. * * @param string $user Username to use (if not default). * * @return Horde_Prefs Prefs object. */ protected function _prefs($user = null) { global $injector; return $injector->getInstance('Horde_Core_Factory_Prefs')->create('ingo', array('cache' => false, 'user' => is_null($user) ? Ingo::getUser() : $user)); }
/** * Stores the specified data in the storage backend. * * @param Ingo_Storage_Rule|Ingo_Storage_Filters $ob The object to store. */ protected function _store($ob) { $prefs = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Prefs')->create('ingo', array('cache' => false, 'user' => Ingo::getUser())); switch ($ob->obType()) { case self::ACTION_BLACKLIST: $data = array('a' => $ob->getBlacklist(), 'f' => $ob->getBlacklistFolder()); $prefs->setValue('blacklist', serialize($data)); break; case self::ACTION_FILTERS: $prefs->setValue('rules', serialize($ob->getFilterList())); break; case self::ACTION_FORWARD: $data = array('a' => $ob->getForwardAddresses(), 'k' => $ob->getForwardKeep()); $prefs->setValue('forward', serialize($data)); break; case self::ACTION_VACATION: $data = array('addresses' => $ob->getVacationAddresses(), 'days' => $ob->getVacationDays(), 'excludes' => $ob->getVacationExcludes(), 'ignorelist' => $ob->getVacationIgnorelist(), 'reason' => $ob->getVacationReason(), 'subject' => $ob->getVacationSubject(), 'start' => $ob->getVacationStart(), 'end' => $ob->getVacationEnd()); $prefs->setValue('vacation', serialize($data)); break; case self::ACTION_WHITELIST: $prefs->setValue('whitelist', serialize($ob->getWhitelist())); break; case self::ACTION_SPAM: $data = array('folder' => $ob->getSpamFolder(), 'level' => $ob->getSpamLevel()); $prefs->setValue('spam', serialize($data)); break; } }