/** * Ends the benchmark and log the result. */ public function end() { if ($this->_logger) { // Compute elapsed time and build message. $elapsed = microtime(true) - $this->_start; $message = sprintf('%s (%.5f)', $this->_message, $elapsed); // Log message (level may be specified as integer or string). if (is_integer($this->_level)) { $this->_logger->log($message, $this->_level); } else { $this->_logger->{$this->_level}($message); } } }
/** * Check authentication. Different backends may handle * authentication in different ways. The base class implementation * checks for HTTP Authentication against the Horde auth setup. * * @return boolean Returns true if authentication is successful. * Should send appropriate "not authorized" headers * or other response codes/body if auth fails, * and take care of exiting. */ public function authorize() { $this->_logger->debug('Horde_Rpc::authorize() starting'); if (!$this->_requireAuthorization) { return true; } // @TODO: inject this $auth = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Auth')->create(); $serverVars = $this->_request->getServerVars(); if (!empty($serverVars['PHP_AUTH_USER'])) { $user = $serverVars['PHP_AUTH_USER']; $pass = $serverVars['PHP_AUTH_PW']; } elseif (!empty($serverVars['Authorization'])) { $hash = str_replace('Basic ', '', $serverVars['Authorization']); $hash = base64_decode($hash); if (strpos($hash, ':') !== false) { list($user, $pass) = explode(':', $hash, 2); } } if (!isset($user) || !$auth->authenticate($user, array('password' => $pass))) { if ($this->_requestMissingAuthorization) { header('WWW-Authenticate: Basic realm="Horde RPC"'); } header('HTTP/1.0 401 Unauthorized'); echo '401 Unauthorized'; exit; } $this->_logger->debug('Horde_Rpc::authorize() exiting'); return true; }
/** * Import a folder change from the wbxml stream * * @param string $uid The folder uid * @param string $displayname The folder display name * @param string $parent The parent folder id. * @param integer $type The EAS Folder type. @since 2.9.0 * * @return Horde_ActiveSync_Message_Folder The new folder object. */ public function importFolderChange($uid, $displayname, $parent = Horde_ActiveSync::FOLDER_ROOT, $type = null) { $this->_logger->info(sprintf('[%s] Horde_ActiveSync_Connector_Importer::importFolderChange(%s, %s, %s, %s)', $this->_procid, $uid, $displayname, $parent, $type)); // Convert the uids to serverids. $collections = $this->_as->getCollectionsObject(); $parent_sid = !empty($parent) ? $collections->getBackendIdForFolderUid($parent) : $parent; $folderid = !empty($uid) ? $collections->getBackendIdForFolderUid($uid) : false; // Perform the creation in the backend. try { $results = $this->_as->driver->changeFolder($folderid, $displayname, $parent_sid, $uid, $type); } catch (Horde_ActiveSync_Exception $e) { $this->_logger->err($e->getMessage()); throw $e; } // @todo Horde 6 this should always return an object. if ($results instanceof Horde_ActiveSync_Message_Folder) { $folderid = $results->_serverid; $uid = $results->serverid; } else { // @TODO Remove for 3.0 Need to build a message folder object here // for BC reasons. $serverid = $results; $results = $this->_as->messageFactory('Folder'); $results->serverid = $serverid; $results->_serverid = $folderid; } $change = array(); $change['id'] = $uid; $change['folderid'] = $folderid; $change['mod'] = $displayname; $change['parent'] = $parent; $this->_state->updateState(Horde_ActiveSync::CHANGE_TYPE_CHANGE, $change, Horde_ActiveSync::CHANGE_ORIGIN_PIM); return $results; }
/** * Get all server changes for the specified collection * * @param string $collection The collection type (a Horde interface name - * calendar, contacts, tasks) * @param integer $from_ts Starting timestamp or modification sequence. * @param integer $to_ts Ending timestamp or modification sequence. * @param string $server_id The server id of the collection. If null, uses * multiplexed. * * @return array A hash of add, modify, and delete uids * @throws InvalidArgumentException, Horde_Exception */ public function getChanges($collection, $from_ts, $to_ts, $server_id) { if (!in_array($collection, array('calendar', 'contacts', 'tasks', 'notes'))) { throw new InvalidArgumentException('collection must be one of calendar, contacts, tasks or notes'); } $app = $this->_registry->hasInterface($collection); if (!$app || $this->_registry->isInactive($app)) { throw new Horde_Exception(sprintf('The %s interface is not active in Horde.', $collection)); } // We can use modification sequences. if ($this->hasFeature('modseq', $collection)) { $this->_logger->info(sprintf('[%s] Fetching changes for %s using MODSEQ.', getmypid(), $collection)); try { return $this->_registry->{$collection}->getChangesByModSeq($from_ts, $to_ts, $server_id); } catch (Exception $e) { return array('add' => array(), 'modify' => array(), 'delete' => array()); } } // Older API, use timestamps. $this->_logger->info(sprintf('[%s] Fetching changes for %s using TIMESTAMPS.', getmypid(), $collection)); try { return $this->_registry->{$collection}->getChanges($from_ts, $to_ts, false, $server_id); } catch (Exception $e) { return array('add' => array(), 'modify' => array(), 'delete' => array()); } }
/** * Notifies the user about any active alarms. * * @param string $user Notify this user, all users if null, or guest * users if empty. * @param boolean $load Update active alarms from all applications? * @param boolean $preload Preload alarms that go off within the next * ttl time span? * @param array $exclude Don't notify with these methods. * * @throws Horde_Alarm_Exception if loading of alarms fails, but not if * notifying of individual alarms fails. */ public function notify($user = null, $load = true, $preload = true, array $exclude = array()) { try { $alarms = $this->listAlarms($user, null, $load, $preload); } catch (Horde_Alarm_Exception $e) { if ($this->_logger) { $this->_logger->log($e, 'ERR'); } throw $e; } if (empty($alarms)) { return; } $handlers = $this->handlers(); foreach ($alarms as $alarm) { foreach ($alarm['methods'] as $alarm_method) { if (isset($handlers[$alarm_method]) && !in_array($alarm_method, $exclude)) { try { $handlers[$alarm_method]->notify($alarm); } catch (Horde_Alarm_Exception $e) { $this->_errors[] = $e; } } } } }
/** * Get an activesync uid for the given backend serverid. If we've seen this * serverid before, return the previously created uid, otherwise return * a new one. * * @param string $id The server's current folder name E.g., INBOX * @param string $type The folder type, a Horde_ActiveSync::FOLDER_TYPE_* * constant. If empty, assumes FOLDER_TYPE_USER_MAIL * @param string $old_id The previous folder name for this folder, if the * folder is being renamed. @since 2.15.0 * @todo This is tempoarary until 3.0 (H6) when we * will have the collection manager take care of ALL * of the folder name <-> UID mapping management. * * @return string A unique identifier for the specified backend folder id. * The first character indicates the foldertype as such: * 'F' - Email * 'C' - Contact * 'A' - Appointment * 'T' - Task * 'N' - Note * @since 2.4.0 */ protected function _getFolderUidForBackendId($id, $type = null, $old_id = null) { // Always use 'RI' for Recipient cache. if ($id == 'RI') { return 'RI'; } $map = $this->_state->getFolderUidToBackendIdMap(); // Rename? if (!empty($old_id) && !empty($map[$old_id])) { $this->_tempMap[$id] = $map[$old_id]; } if (!empty($map[$id])) { return $map[$id]; } elseif (!empty($this->_tempMap[$id])) { return $this->_tempMap[$id]; } // Convert TYPE to CLASS $type = $this->_getClassFromType($type); $rMap = array_flip($this->_typeMap); $prefix = $rMap[$type]; // None found, generate a new UID. $this->_tempMap[$id] = sprintf('%s%04x%04x', $prefix, mt_rand(0, 0xffff), mt_rand(0, 0xffff)); $this->_logger->info(sprintf('[%s] Creating new folder uuid for %s: %s', getmypid(), $id, $this->_tempMap[$id])); return $this->_tempMap[$id]; }
protected function _logError($error, $name, $runtime = null) { if ($this->_logger) { $name = (empty($name) ? '' : $name) . (empty($runtime) ? '' : sprintf(" (%.4fs)", $runtime)); $this->_logger->err($this->_formatLogEntry($name, $error)); } }
/** * * @param Horde_Imap_Client_Mailbox $mbox The mailbox * @param array $uids An array of message uids * @param array $options An options array * - headers: (boolean) Fetch header text if true. * DEFAULT: false (Do not fetch header text). * - structure: (boolean) Fetch message structure. * DEFAULT: true (Fetch message structure). * - flags: (boolean) Fetch messagge flags. * DEFAULT: true (Fetch message flags). * - envelope: (boolen) Fetch the envelope data. * DEFAULT: false (Do not fetch envelope). @since 2.4.0 * * @return Horde_Imap_Fetch_Results The results. * @throws Horde_ActiveSync_Exception */ protected function _getMailMessages(Horde_Imap_Client_Mailbox $mbox, array $uids, array $options = array()) { $options = array_merge(array('headers' => false, 'structure' => true, 'flags' => true, 'envelope' => false), $options); $imap = $this->_getImapOb(); $query = new Horde_Imap_Client_Fetch_Query(); if ($options['structure']) { $query->structure(); } if ($options['flags']) { $query->flags(); } if ($options['envelope']) { $query->envelope(); } if (!empty($options['headers'])) { $query->headerText(array('peek' => true)); } $ids = new Horde_Imap_Client_Ids($uids); try { return $imap->fetch($mbox, $query, array('ids' => $ids, 'exists' => true)); } catch (Horde_Imap_Client_Exception $e) { $this->_logger->err(sprintf('[%s] Unable to fetch message: %s', $this->_procid, $e->getMessage())); throw new Horde_ActiveSync_Exception($e); } }
/** * Force reset all collection's PINGABLE flag. Used to force client * to issue a non-empty PING request. * */ public function resetPingCache() { $collections = $this->_cache->getCollections(false); foreach ($collections as $id => $collection) { $this->_logger->info(sprintf('UNSETTING collection %s (%s) PINGABLE flag.', $collection['serverid'], $id)); $this->_cache->removePingableCollection($id); } }
/** * Destroy the data for a particular session identifier in the backend. * This method should only be called internally by PHP via * session_set_save_handler(). * * @param string $id The session identifier. * * @return boolean True on success, false otherwise. */ public function destroy($id) { if ($this->_storage->destroy($id)) { $this->_logger->log('Session data destroyed (' . $id . ')', 'DEBUG'); return true; } $this->_logger->log('Failed to destroy session data (' . $id . ')', 'DEBUG'); return false; }
/** * Logs an entry. * * @since 2.5.0 * * @param Horde_Core_Log_Object $ob Log entry object. */ public function logObject(Horde_Core_Log_Object $ob) { if (!$ob->logged) { parent::log($ob->toArray()); if ($bt = $ob->backtrace) { parent::log(strval($bt), Horde_Log::DEBUG); } $ob->logged = true; } }
protected function _reorderChanges(array $ensure) { $changes = array(); foreach ($this->_changes as $change) { if (array_search($change['id'], $ensure) !== false) { $this->_logger->info(sprintf('Placing %s at beginning of changes array.', $change['id'])); array_unshift($changes, $change); } else { $changes[] = $change; } } return $changes; }
/** * Runs the compression command and returns the output. * * @param string $text The javascript text. * @param string $cmd Command. * @param Horde_Log_Logger $log Logging object. * * @return string The compressed javascript. */ public function runCmd($text, $cmd, Horde_Log_Logger $log) { $descspec = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')); $process = proc_open($cmd, $descspec, $pipes); fwrite($pipes[0], $text); fclose($pipes[0]); $out = ''; while (!feof($pipes[1])) { $out .= fread($pipes[1], 8192); } $error = ''; while (!feof($pipes[2])) { $error .= fread($pipes[2], 8192); } if (strlen($error)) { $log->log(sprintf('Output from %s: %s', $cmd, $error), 'WARN'); } fclose($pipes[1]); fclose($pipes[2]); proc_close($process); return $out; }
/** * Update the history log for an object. * * @param string $object The object ID. * @param string $bid The backend ID of the object. * @param boolean $force Force update */ protected function _updateLog($object, $bid, $force = false) { $last = $this->_history->getLatestEntry($object); if ($last === false) { // New, unknown object $this->_logger->debug(sprintf('[KOLAB_STORAGE] New object to log in Horde_History: %s, uid: %d', $object, $bid)); $this->_history->log($object, array('action' => 'add', 'bid' => $bid), true); } else { // If the last action for this object was 'delete', we issue an 'add'. // Objects can vanish and re-appear using the same object uid. // (a foreign client is sending an update over a slow link) if ($last['action'] == 'delete') { $this->_logger->debug(sprintf('[KOLAB_STORAGE] Re-adding previously deleted object in Horde_History: %s, uid: %d', $object, $bid)); $this->_history->log($object, array('action' => 'add', 'bid' => $bid), true); } if (!isset($last['bid']) || $last['bid'] != $bid || $force) { $this->_logger->debug(sprintf('[KOLAB_STORAGE] Modifying object in Horde_History: %s, uid: %d, force: %d', $object, $bid, $force)); $this->_history->log($object, array('action' => 'modify', 'bid' => $bid), true); } } }
/** * Do initialization. * * @throws Horde_Memcache_Exception */ public function _init() { $this->_memcache = new Memcache(); for ($i = 0, $n = count($this->_params['hostspec']); $i < $n; ++$i) { $res = $this->_memcache->addServer($this->_params['hostspec'][$i], empty($this->_params['port'][$i]) ? 0 : $this->_params['port'][$i], !empty($this->_params['persistent']), !empty($this->_params['weight'][$i]) ? $this->_params['weight'][$i] : 1, 1, 15, true, array($this, 'failover')); if ($res) { $this->_servers[] = $this->_params['hostspec'][$i] . (!empty($this->_params['port'][$i]) ? ':' . $this->_params['port'][$i] : ''); } } /* Check if any of the connections worked. */ if (empty($this->_servers)) { throw new Horde_Memcache_Exception('Could not connect to any defined memcache servers.'); } if (!empty($this->_params['c_threshold'])) { $this->_memcache->setCompressThreshold($this->_params['c_threshold']); } // Force consistent hashing ini_set('memcache.hash_strategy', 'consistent'); if (isset($this->_params['logger'])) { $this->_logger = $this->_params['logger']; $this->_logger->log('Connected to the following memcache servers:' . implode($this->_servers, ', '), 'DEBUG'); } }
/** * Fetches a template from the specified file and return the parsed * contents. * * @param string $filename The file to fetch the template from. * * @return string The parsed template. */ public function fetch($filename = null) { $file = $this->_basepath . $filename; $force = $this->getOption('forcecompile'); if (!is_null($filename) && $file != $this->_templateFile) { $this->_template = $this->_templateFile = null; } /* First, check for a cached compiled version. */ $parts = array('horde_template', filemtime($file), $file); if ($this->getOption('gettext')) { $parts[] = setlocale(LC_ALL, 0); } $cacheid = implode('|', $parts); if (!$force && is_null($this->_template) && $this->_cache) { $this->_template = $this->_cache->get($cacheid, 0); if ($this->_template === false) { $this->_template = null; } } /* Parse and compile the template. */ if ($force || is_null($this->_template)) { $this->_template = str_replace("\n", " \n", file_get_contents($file)); $this->_parse(); if ($this->_cache) { $this->_cache->set($cacheid, $this->_template); if ($this->_logger) { $this->_logger->log(sprintf('Saved compiled template file for "%s".', $file), 'DEBUG'); } } } $this->_templateFile = $file; /* Template debugging. */ if ($this->getOption('debug')) { echo '<pre>' . htmlspecialchars($this->_template) . '</pre>'; } return $this->parse(); }
/** * Do initialization. * * @throws Horde_Memcache_Exception */ public function _init() { if (class_exists('Memcached')) { if (empty($this->_params['persistent'])) { $this->_memcache = new Memcached(); } else { $this->_memcache = new Memcached('horde_memcache'); } $this->_params['large_items'] = false; $this->_memcache->setOptions(array(Memcached::OPT_COMPRESSION => $this->_params['compression'], Memcached::OPT_DISTRIBUTION => Memcached::DISTRIBUTION_CONSISTENT, Memcached::OPT_HASH => Memcached::HASH_MD5, Memcached::OPT_LIBKETAMA_COMPATIBLE => true, Memcached::OPT_PREFIX_KEY => $this->_params['prefix'])); } else { // Force consistent hashing ini_set('memcache.hash_strategy', 'consistent'); $this->_memcache = new Memcache(); } for ($i = 0, $n = count($this->_params['hostspec']); $i < $n; ++$i) { if ($this->_memcache instanceof Memcached) { $res = $this->_memcache->addServer($this->_params['hostspec'][$i], empty($this->_params['port'][$i]) ? 0 : $this->_params['port'][$i], !empty($this->_params['weight'][$i]) ? $this->_params['weight'][$i] : 0); } else { $res = $this->_memcache->addServer($this->_params['hostspec'][$i], empty($this->_params['port'][$i]) ? 0 : $this->_params['port'][$i], !empty($this->_params['persistent']), !empty($this->_params['weight'][$i]) ? $this->_params['weight'][$i] : 1, 1, 15, true, array($this, 'failover')); } if ($res) { $this->_servers[] = $this->_params['hostspec'][$i] . (!empty($this->_params['port'][$i]) ? ':' . $this->_params['port'][$i] : ''); } } /* Check if any of the connections worked. */ if (empty($this->_servers)) { throw new Horde_Memcache_Exception('Could not connect to any defined memcache servers.'); } if ($this->_memcache instanceof Memcache && !empty($this->_params['c_threshold'])) { $this->_memcache->setCompressThreshold($this->_params['c_threshold']); } if (isset($this->_params['logger'])) { $this->_logger = $this->_params['logger']; $this->_logger->log('Connected to the following memcache servers:' . implode($this->_servers, ', '), 'DEBUG'); } }
/** * Log the message */ protected function _logMessage() { $this->_logger->info("MAIL \n" . $this->_getFullMessage()); }
/** * Load and initialize the sync state * * @param array $collection The collection array for the collection, if * a FOLDERSYNC, pass an empty array. * @param string $syncKey The synckey of the state to load. If empty will * force a reset of the state for the class * specified in $id * @param string $type The type of state a * Horde_ActiveSync::REQUEST_TYPE constant. * @param string $id The folder id this state represents. If empty * assumed to be a foldersync state. * * @throws Horde_ActiveSync_Exception, Horde_ActiveSync_Exception_StateGone */ public function loadState(array $collection, $syncKey, $type = null, $id = null) { // Initialize the local members. $this->_collection = $collection; $this->_changes = null; $this->_type = $type; // If this is a FOLDERSYNC, mock the device id. if ($type == Horde_ActiveSync::REQUEST_TYPE_FOLDERSYNC && empty($id)) { $id = Horde_ActiveSync::REQUEST_TYPE_FOLDERSYNC; } // synckey == 0 is an initial sync or reset. if (empty($syncKey)) { $this->_logger->notice(sprintf('[%s] %s::loadState: clearing folder state.', $this->_procid, __CLASS__)); if ($type == Horde_ActiveSync::REQUEST_TYPE_FOLDERSYNC) { $this->_folder = array(); } else { // Create a new folder object. $this->_folder = $this->_collection['class'] == Horde_ActiveSync::CLASS_EMAIL ? new Horde_ActiveSync_Folder_Imap($this->_collection['serverid'], Horde_ActiveSync::CLASS_EMAIL) : ($this->_collection['serverid'] == 'RI' ? new Horde_ActiveSync_Folder_RI('RI', 'RI') : new Horde_ActiveSync_Folder_Collection($this->_collection['serverid'], $this->_collection['class'])); } $this->_syncKey = '0'; $this->_resetDeviceState($id); return; } $this->_logger->info(sprintf('[%s] Loading state for synckey %s', $this->_procid, $syncKey)); // Check if synckey is allowed if (!preg_match('/^\\{([0-9A-Za-z-]+)\\}([0-9]+)$/', $syncKey, $matches)) { throw new Horde_ActiveSync_Exception('Invalid sync key'); } $this->_syncKey = $syncKey; // Cleanup older syncstates $this->_gc($syncKey); // Load the state $this->_loadState($type); }
/** * Encodes this object (and any sub-objects) as wbxml to the output stream. * Output is ordered according to $_mapping * * @param Horde_ActiveSync_Wbxml_Encoder $encoder The wbxml stream encoder */ public function encodeStream(Horde_ActiveSync_Wbxml_Encoder &$encoder) { foreach ($this->_mapping as $tag => $map) { if (isset($this->{$map}[self::KEY_ATTRIBUTE])) { // Variable is available if (is_object($this->{$map}[self::KEY_ATTRIBUTE]) && !$this->{$map}[self::KEY_ATTRIBUTE] instanceof Horde_Date) { // Subobjects can do their own encoding $encoder->startTag($tag); $this->{$map}[self::KEY_ATTRIBUTE]->encodeStream($encoder); $encoder->endTag(); } elseif (isset($map[self::KEY_VALUES]) && is_array($this->{$map}[self::KEY_ATTRIBUTE])) { // Array of objects. Note that some array values must be // send as an empty tag if they contain no elements. if (count($this->{$map}[self::KEY_ATTRIBUTE])) { $encoder->startTag($tag); foreach ($this->{$map}[self::KEY_ATTRIBUTE] as $element) { if (is_object($element)) { // Outputs object container (eg Attachment) $encoder->startTag($map[self::KEY_VALUES]); $element->encodeStream($encoder); $encoder->endTag(); } else { // Do not ever output empty items here if (strlen($element) > 0) { $encoder->startTag($map[self::KEY_VALUES]); $encoder->content($element); $encoder->endTag(); } } } $encoder->endTag(); } elseif ($this->_checkSendEmpty($tag)) { $encoder->startTag($tag, null, true); } } else { // Simple type if (!is_resource($this->{$map}[self::KEY_ATTRIBUTE]) && strlen($this->{$map}[self::KEY_ATTRIBUTE]) == 0) { // Do not output empty items except for the following: if ($this->_checkSendEmpty($tag)) { $encoder->startTag($tag, $this->{$map}[self::KEY_ATTRIBUTE], true); } continue; } elseif ($encoder->multipart && in_array($tag, array(Horde_ActiveSync::SYNC_DATA, Horde_ActiveSync::AIRSYNCBASE_DATA, Horde_ActiveSync_Request_ItemOperations::ITEMOPERATIONS_DATA))) { $this->_logger->info('HANDLING MULTIPART OUTPUT'); $encoder->addPart($this->{$map}[self::KEY_ATTRIBUTE]); $encoder->startTag(Horde_ActiveSync_Request_ItemOperations::ITEMOPERATIONS_PART); $encoder->content((string) (count($encoder->getParts()) - 1)); $encoder->endTag(); continue; } $encoder->startTag($tag); if (isset($map[self::KEY_TYPE]) && ($map[self::KEY_TYPE] == self::TYPE_DATE || $map[self::KEY_TYPE] == self::TYPE_DATE_DASHES)) { if (!empty($this->{$map}[self::KEY_ATTRIBUTE])) { // don't output 1-1-1970 $encoder->content($this->_formatDate($this->{$map}[self::KEY_ATTRIBUTE], $map[self::KEY_TYPE])); } } elseif (isset($map[self::KEY_TYPE]) && $map[self::KEY_TYPE] == self::TYPE_HEX) { $encoder->content(Horde_String::upper(bin2hex($this->{$map}[self::KEY_ATTRIBUTE]))); } elseif (isset($map[self::KEY_TYPE]) && $map[self::KEY_TYPE] == self::TYPE_MAPI_STREAM) { $encoder->content($this->{$map}[self::KEY_ATTRIBUTE]); } else { $encoder->content($this->_checkEncoding($this->{$map}[self::KEY_ATTRIBUTE], $tag)); } $encoder->endTag(); } } } }
/** * Destructor. * * Logs the counted events. */ public function __destruct() { foreach ($this->_count as $method => $count) { $this->_logger->debug(sprintf('Horde_Kolab_Server: Method %s called %s times.', $method, $count)); } }
/** * Handle device checks. Takes into account permissions and restrictions * via various callback methods. * * @param string $devId The client provided device id. * * @return boolean If EAS version is > 12.1 returns false on any type of * failure in allowing the device to connect. Sets * appropriate internal variables to indicate the type of * error to return to the client. Failure on EAS version * < 12.1 results in throwing exceptions. Otherwise, return * true. * @throws Horde_ActiveSync_Exception, Horde_Exception_AuthenticationFailure */ protected function _handleDevice($devId) { $get = $this->getGetVars(); $version = $this->getProtocolVersion(); // Does device exist AND does the user have an account on the device? if (!$this->_state->deviceExists($devId, $this->_driver->getUser())) { // Device might exist, but with a new (additional) user account if ($this->_state->deviceExists($devId)) { self::$_device = $this->_state->loadDeviceInfo($devId); } else { self::$_device = new Horde_ActiveSync_Device($this->_state); } self::$_device->policykey = 0; self::$_device->userAgent = $this->_request->getHeader('User-Agent'); self::$_device->deviceType = !empty($get['DeviceType']) ? $get['DeviceType'] : ''; self::$_device->rwstatus = self::RWSTATUS_NA; self::$_device->user = $this->_driver->getUser(); self::$_device->id = $devId; self::$_device->needsVersionUpdate($this->getSupportedVersions()); self::$_device->version = $version; // @TODO: Remove is_callable check for H6. // Combine this with the modifyDevice callback? Allow $device // to be modified here? if (is_callable(array($this->_driver, 'createDeviceCallback'))) { $callback_ret = $this->_driver->createDeviceCallback(self::$_device); if ($callback_ret !== true) { $msg = sprintf('The device %s was disallowed for user %s per policy settings.', self::$_device->id, self::$_device->user); self::$_logger->err($msg); // Always throw exception in place of status code since we // won't have a version number before the device is created. throw new Horde_Exception_AuthenticationFailure($msg, $callback_ret); } else { // Give the driver a chance to modify device properties. if (is_callable(array($this->_driver, 'modifyDeviceCallback'))) { self::$_device = $this->_driver->modifyDeviceCallback(self::$_device); } } } } else { self::$_device = $this->_state->loadDeviceInfo($devId, $this->_driver->getUser()); // If the device state was removed from storage, we may lose the // device properties, so try to repopulate what we can. userAgent // is ALWAYS available, so if it's missing, the state is gone. if (empty(self::$_device->userAgent)) { self::$_device->userAgent = $this->_request->getHeader('User-Agent'); self::$_device->deviceType = !empty($get['DeviceType']) ? $get['DeviceType'] : ''; self::$_device->user = $this->_driver->getUser(); } if (empty(self::$_device->version)) { self::$_device->version = $version; } if (self::$_device->version < $this->_maxVersion && self::$_device->needsVersionUpdate($this->getSupportedVersions())) { $this->_needMsRp = true; } // Give the driver a chance to modify device properties. if (is_callable(array($this->_driver, 'modifyDeviceCallback'))) { self::$_device = $this->_driver->modifyDeviceCallback(self::$_device); } } // Save the device now that we know it is at least allowed to connect, // or it has connected successfully at least once in the past. self::$_device->save(); if (is_callable(array($this->_driver, 'deviceCallback'))) { $callback_ret = $this->_driver->deviceCallback(self::$_device); if ($callback_ret !== true) { $msg = sprintf('The device %s was disallowed for user %s per policy settings.', self::$_device->id, self::$_device->user); self::$_logger->err($msg); if ($version > self::VERSION_TWELVEONE) { // Use a status code here, since the device has already // connected. $this->_globalError = $callback_ret; return false; } else { throw new Horde_Exception_AuthenticationFailure($msg, $callback_ret); } } } // Lastly, check if the device has been set to blocked. if (self::$_device->blocked) { $msg = sprintf('The device %s was blocked.', self::$_device->id); self::$_logger->err($msg); if ($version > self::VERSION_TWELVEONE) { $this->_globalError = Horde_ActiveSync_Status::DEVICE_BLOCKED_FOR_USER; return false; } else { throw new Horde_ActiveSync_Exception($msg); } } return true; }
/** * Return the logger. * * @return Horde_Log_Logger The logger. */ public function createLogger() { $logger = new Horde_Log_Logger(); $configuration = $this->_injector->getInstance('Horde_Kolab_FreeBusy_Configuration'); $logger_params = isset($configuration['logger']) ? $configuration['logger'] : array(); if (empty($params)) { $handlers = array('Horde_Log_Handler_Null' => array()); } else { $handlers = $logger_params['logger']; } foreach ($handlers as $name => $params) { if (!empty($params['params'])) { /** * We need to pass parameters to the constructor so use * reflection. */ $reflectionObj = new ReflectionClass($name); $handler = $reflectionObj->newInstanceArgs($params['params']); } else { $handler = new $name(); } if (!empty($params['options'])) { foreach ($params['options'] as $key => $value) { $handler->setOption($key, $value); } } $logger->addHandler($handler); } return $logger; }
/** * @param string $text */ public function log($text = '') { if ($this->_logger) { $this->_logger->info($text); } }
/** * Calls the specified normal REST API method. * * @param string $method Name of the Facebook method to invoke * @param array $params A map of param names => param values * * @return mixed Result of method call */ public function callMethod($method, array $params = array()) { $this->_logger->debug(sprintf('Calling method %s with parameters %s', $method, print_r($params, true))); $request = new Horde_Service_Facebook_Request_Rest($this, $method, $params); return $request->run(); }
/** * Clean up after initial pairing. Initial pairing can happen either as a * result of either a FOLDERSYNC or PROVISION command, depending on the * device capabilities. */ protected function _cleanUpAfterPairing() { // Android sends a bogus device id of 'validate' during initial // handshake. This data is never used again, and the resulting // FOLDERSYNC response is ignored by the client. Remove the entry, // to avoid having 2 device entries for every android client. if ($this->_device->id == 'validate') { $this->_logger->info(sprintf('[%s] Removing state for bogus VALIDATE device.', $this->_procid)); $this->_state->removeState(array('devId' => 'validate')); } }
/** * Log the missing scope. * * @param Exception $e The exception that occurred. * @param string $scope The scope that was attempted to get. * * @return NULL */ private function _logMissingScope(Exception $e, $scope) { if ($this->_logger !== null) { $this->_logger->debug(sprintf(__CLASS__ . ': No preference information available for scope %s (%s).', $scope, $e->getMessage())); } }
/** * Update a collection in the cache. * * @param array $collection The collection data to add/update. * @param array $options Options: * - newsynckey: (boolean) Set the new synckey in the collection. * DEFAULT: false (Do not set the new synckey). * - unsetChanges: (boolean) Unset the GETCHANGES flag in the collection. * DEFAULT: false (Do not unset the GETCHANGES flag). * - unsetPingChangeFlag: (boolean) Unset the PINGCHANGES flag in the collection. * DEFUALT: false (Do not uset the PINGCHANGES flag). * @since 2.3.0 */ public function updateCollection(array $collection, array $options = array()) { $options = array_merge(array('newsynckey' => false, 'unsetChanges' => false, 'unsetPingChangeFlag' => false), $options); if (!empty($collection['id'])) { if ($options['newsynckey']) { $this->_data['collections'][$collection['id']]['synckey'] = $collection['newsynckey']; $this->_markCollectionsDirty($collection['id']); } elseif (isset($collection['synckey'])) { $this->_data['collections'][$collection['id']]['synckey'] = $collection['synckey']; $this->_markCollectionsDirty($collection['id']); } if (isset($collection['class'])) { $this->_data['collections'][$collection['id']]['class'] = $collection['class']; $this->_markCollectionsDirty($collection['id']); } if (isset($collection['windowsize'])) { $this->_data['collections'][$collection['id']]['windowsize'] = $collection['windowsize']; $this->_markCollectionsDirty($collection['id']); } if (isset($collection['deletesasmoves'])) { $this->_data['collections'][$collection['id']]['deletesasmoves'] = $collection['deletesasmoves']; $this->_markCollectionsDirty($collection['id']); } if (isset($collection['filtertype'])) { $this->_data['collections'][$collection['id']]['filtertype'] = $collection['filtertype']; $this->_markCollectionsDirty($collection['id']); } if (isset($collection['truncation'])) { $this->_data['collections'][$collection['id']]['truncation'] = $collection['truncation']; $this->_markCollectionsDirty($collection['id']); } if (isset($collection['rtftruncation'])) { $this->_data['collections'][$collection['id']]['rtftruncation'] = $collection['rtftruncation']; $this->_markCollectionsDirty($collection['id']); } if (isset($collection['mimesupport'])) { $this->_data['collections'][$collection['id']]['mimesupport'] = $collection['mimesupport']; $this->_markCollectionsDirty($collection['id']); } if (isset($collection['mimetruncation'])) { $this->_data['collections'][$collection['id']]['mimetruncation'] = $collection['mimetruncation']; $this->_markCollectionsDirty($collection['id']); } if (isset($collection['conflict'])) { $this->_data['collections'][$collection['id']]['conflict'] = $collection['conflict']; $this->_markCollectionsDirty($collection['id']); } if (isset($collection['bodyprefs'])) { $this->_data['collections'][$collection['id']]['bodyprefs'] = $collection['bodyprefs']; $this->_markCollectionsDirty($collection['id']); } if (isset($collection['bodypartprefs'])) { $this->_data['collections'][$collection['id']]['bodypartprefs'] = $collection['bodypartprefs']; } if (isset($collection['pingable'])) { $this->_data['collections'][$collection['id']]['pingable'] = $collection['pingable']; $this->_markCollectionsDirty($collection['id']); } if (isset($collection['serverid'])) { $this->_data['collections'][$collection['id']]['serverid'] = $collection['serverid']; $this->_markCollectionsDirty($collection['id']); } if ($options['unsetChanges']) { unset($this->_data['collections'][$collection['id']]['getchanges']); $this->_markCollectionsDirty($collection['id']); } if ($options['unsetPingChangeFlag']) { unset($this->_data['collections'][$collection['id']]['pingchange']); $this->_markCollectionsDirty($collection['id']); } } else { $this->_logger->info(sprintf('[%s] Collection without id found: %s', $this->_procid, serialize($collection))); } }
/** * React on detection of more than one default folder. * * @param string $first The first default folder name. * @param string $second The second default folder name. * @param string $type The folder type. * @param string $owner The folder owner. */ protected function doubleDefault($first, $second, $owner, $type) { $this->_logger->err(sprintf('Both folders "%s" and "%s" of owner "%s" are marked as default folder of type "%s"!', $first, $second, $owner, $type)); }
public function testAddLogLevel() { $logger = new Horde_Log_Logger($this->handler); $logger->addLevel($levelName = 'EIGHT', $level = 8); $logger->eight($message = 'eight message'); rewind($this->log); $logdata = stream_get_contents($this->log); $this->assertContains($levelName, $logdata); $this->assertContains($message, $logdata); }