public static function getUtcTimestamp($dateString = 'now', $timeZone = 'UTC') { try { $obj = new DateTime($dateString, new DateTimeZone($timeZone)); return $obj->getTimestamp(); } catch (Exception $ex) { Logger::warning('Could not get timestamp from string', $dateString, $ex); return null; } }
/** * Do the actual work of the script. */ public function execute() { Logger::info('Info log message'); Logger::debug('Debug log message'); Logger::notice('Notice...'); Logger::getTaggedLogger('RawData')->info('This should be tagged RawData'); Logger::warning('Warning!', array('foo' => 'bar')); try { $this->throwException(); } catch (SmashPigException $ex) { Logger::error('ERROR!!!!', null, $ex); } }
public function execute(ListenerMessage $msg) { $destinationQueue = $msg->getDestinationQueue(); if ($destinationQueue) { $queue = Context::get()->getConfiguration()->object("data-store/{$destinationQueue}"); $queueMsg = $msg->normalizeForQueue(); SourceFields::addToMessage($queueMsg); $queue->push($queueMsg); } else { $class = get_class($msg); Logger::warning("Ignoring message of type {$class}", $msg); } return true; }
/** * Do the actual work of the script. */ public function execute() { $this->datastore = new StompDataStore($this->getOption('queue')); $maxMessages = $this->getOption('max-messages'); $startTime = time(); $messageCount = 0; $raw = $this->getOption('raw'); $ignore = $this->getOption('no-ack'); // Construct the selectors $argId = 0; $selectors = array(); while ($this->hasArgument($argId)) { $selectors[] = $this->getArgument($argId); $argId += 1; } // Open the file for write-append $outfile = $this->getOption('outfile'); $f = fopen($outfile, 'a'); if (!$f) { $this->error("Could not open {$outfile} for write append", true); } // Do the loop! do { // This is actually quite inefficient; but this whole thing is a hack so meh! // ...Ideally we would take the JSON from the store directly instead of walking // it through an object try { $queueObj = $this->datastore->queueGetObject(null, null, $selectors, !$raw); if (!$queueObj) { break; } if ($raw) { fwrite($f, 'raw' . "=" . json_encode($queueObj) . "\n"); } else { fwrite($f, get_class($queueObj) . "=" . $queueObj->toJson(false) . "\n"); } } catch (DataSerializationException $ex) { // We probably caught an anti-message here; log the exception and continue on Logger::warning("Possibly caught an antimessage. Not adding to file.", null, $ex); } if ($ignore) { $this->datastore->queueIgnoreObject(); } else { $this->datastore->queueAckObject(); } $messageCount += 1; } while ($maxMessages === 0 || $messageCount < $maxMessages); $elapsedTime = time() - $startTime; Logger::info("Dumped {$messageCount} messages to {$outfile} in {$elapsedTime} seconds."); }
/** * @param WSDL\sendNotification $var * * @return WSDL\sendNotificationResponse */ public function sendNotification(WSDL\sendNotification $var) { $messages = array(); $respstring = "[failed]"; if ($var->notification instanceof WSDL\NotificationRequest) { if ($var->notification->live) { Logger::info("Notification received from live server."); } else { Logger::info("Notification received from test server."); } // Create Messages from the hideous SOAPy mess if (is_array($var->notification->notificationItems->NotificationRequestItem)) { foreach ($var->notification->notificationItems->NotificationRequestItem as $item) { $obj = $this->createAdyenMsgObjFromItem($item); if ($obj !== false) { $messages[] = $obj; } } } else { $obj = $this->createAdyenMsgObjFromItem($var->notification->notificationItems->NotificationRequestItem); if ($obj !== false) { $messages[] = $obj; } } $numItems = count($messages); Logger::info("Extracted {$numItems} from received message. Beginning processing loop."); // Now process each message to the best of our ability foreach ($messages as $msg) { if ($this->processMessage($msg)) { Logger::debug("Message successfully processed. Moving along..."); } else { Logger::error("Message was not successfully processed!", $msg); } } Logger::info('Finished processing of IPN message, retuning accepted.'); $respstring = '[accepted]'; } else { Logger::warning("Received notification is not instance of NotificationRequest!", $var); $this->server->fault(500, 'Received notification is not instance of NotificationRequest!'); } $response = new WSDL\sendNotificationResponse(); $response->notificationResponse = $respstring; return $response; }
/** * Serialize an object to a JSON string. * * This function will call __sleep() on the object and attempt to save all requested * properties listed (IE: all non-static properties that are not listed in the * propertiesExcludedFromExport list). * * Object properties may be serialized only if they inherit from JsonSerializableObject. * * If $resumeUse is specified 'true' then __wakeup() will be called at the termination of * this function. As this is the case, it is not safe to continue to use the object after * serialization if $resumeUse = false. * * @param bool $resumeUse Set to false if this object reference will not be further used this * session post serialization. * * @return string JSON string representing the object. */ public function toJson($resumeUse = true) { $this->__sleep(); $properties = array(); foreach (get_object_vars($this) as $propName => $propValue) { if (!in_array($propName, $this->propertiesExcludedFromExport)) { if (is_object($propValue)) { if ($propValue instanceof JsonSerializableObject) { $properties[$propName] = $propValue->toJson($resumeUse); } else { $className = get_class(); Logger::warning("Object contained in property {$className}->{$propName} is not instance of JsonSerializableObject."); } } else { $properties[$propName] = $propValue; } } } if ($resumeUse) { $this->__wakeup(); } return json_encode($properties); }
/** * Do the actual work of the script. */ public function execute() { $this->datastore = new StompDataStore($this->getOption('queue')); $this->damagedDatastore = new StompDataStore($this->getOption('damaged-queue')); $startTime = time(); $messageCount = 0; $successCount = 0; do { $jobObj = $this->datastore->queueGetObject(); if (!$jobObj) { // No more jobs available to run :'( break; } $success = false; if ($jobObj instanceof \SmashPig\Core\Jobs\RunnableJob) { try { if ($jobObj->execute()) { $success = true; } else { Logger::info("Job tells us that it did not successfully " . "execute. Sending to damaged message queue."); } } catch (Exception $ex) { Logger::error("Job threw exception. Sending to damaged message queue.", null, $ex); } } else { Logger::warning(get_class($jobObj) . " is not an instance of RunnableJob. " . "Could not execute and sending to damaged message queue."); } if ($success) { $successCount += 1; } else { $this->damagedDatastore->addObject($jobObj); } $this->datastore->queueAckObject(); } while (time() - $startTime < $this->getOption('time-limit') && ++$messageCount < $this->getOption('max-messages')); $elapsedTime = time() - $startTime; Logger::info("Processed {$messageCount} ({$successCount} successful) jobs in {$elapsedTime} seconds."); }
/** * Delete a message from the database * * Note that we delete by (gateway, order_id) internally. * * @param array $message */ public function deleteMessage($message) { if (!isset($message['order_id'])) { $json = json_encode($message); Logger::warning("Trying to delete pending message with no order id: {$json}"); return; } $sql = ' delete from pending where gateway = :gateway and order_id = :order_id'; $params = array('gateway' => $message['gateway'], 'order_id' => $message['order_id']); $this->prepareAndExecute($sql, $params); }
/** * Monolithic function to send an email! * * Several configuration nodes are required for this function: * email/from-address Default address for the From header * email/bounce-address Default address to use when VERPing the email. * IE: bounce+$1@contoso.com * email/archive-addresses A list of addresses to always BCC when this function is used * * @param string $to Email address of recipient * @param string $subject Subject line of email * @param string $textBody Non HTML text of email (fallback text if $htmlBody is defined) * @param null|string|array $from Email address of sender, if null is the value of the configuration * node 'email/from-address'. If passed as an array it is expected that * index 0 is the address and index 1 is the friendly name of the address. * @param null|string $replyTo Address that recipient will reply to. If null will be set from the value * of $from. * @param null|string $htmlBody HTML text of the email * @param array $attach Paths to any attachments. These can have any legal PHP file descriptor. * @param null|string|array $cc Carbon-Copy addresses. * @param null|string|array $bcc Blind carbon-copy addresses. If specified these will always be in addition * to any archival addresses specified by the 'email/archive-addresses' * configuration node. * @param bool|string $useVerp If true will set the MAIL FROM to the value specified under configuration * node 'email/bounce-address'. This can be overriden if a string is passed * instead of strict true. In either case, '$1' will be replaced by the * first $to address, RFC-3986 encoded. * * @returns bool True if successfully sent. False if a PHPMailer exception occurred. Exceptions are logged at the * warning level. */ public static function sendEmail($to, $subject, $textBody, $from = null, $replyTo = null, $htmlBody = null, $attach = array(), $cc = null, $bcc = null, $useVerp = true) { $config = Context::get()->getConfiguration(); $mailer = static::mailbaseFactory(); try { $to = (array) $to; $cc = (array) $cc; $bcc = (array) $bcc; $archives = (array) $config->val('email/archive-addresses'); array_walk($to, function ($value, $key) use($mailer) { $mailer->AddAddress($value); }); array_walk($cc, function ($value, $key) use($mailer) { $mailer->AddCC($value); }); array_walk($bcc, function ($value, $key) use($mailer) { $mailer->AddBCC($value); }); array_walk($archives, function ($value, $key) use($mailer) { $mailer->AddBCC($value); }); array_walk($attach, function ($value, $key) use($mailer) { $mailer->AddAttachment($value); }); // Set the from address if (!$from) { $from = $config->val('email/from-address'); } if (is_array($from)) { $mailer->SetFrom($from[0], $from[1]); } else { $mailer->SetFrom((string) $from); } // Only add reply to manually if requested, otherwise it's set when we call SetFrom if ($replyTo) { $mailer->AddReplyTo($replyTo); } // Set subject and body $mailer->Subject = $subject; if ($htmlBody) { $mailer->MsgHTML($htmlBody); $mailer->AltBody = $textBody; } else { $mailer->Body = $textBody; } // We replace $1 in email/bounce-address or useVerp if string to create the bounce addr if ($useVerp) { $sourceAddr = (array) $to; $sourceAddr = rawurlencode($sourceAddr[0]); if (is_string($useVerp)) { $bounceAddr = $useVerp; } else { $bounceAddr = $config->val('email/bounce-address'); } $bounceAddr = str_replace('$1', $sourceAddr, $bounceAddr); $mailer->Sender = $bounceAddr; } $mailer->Send(); } catch (\phpmailerException $ex) { $toStr = implode(", ", $to); Logger::warning("Could not send email to {$toStr}. PHP Mailer had exception.", null, $ex); return false; } return true; }
/** * Creates or re-uses a subscription to the STOMP backing store. There can only be one active * subscription at a time so if the requested subscription does not match the previous one, * the old one is unsubscribed and a new one is started. * * @param null|string $type Object type to select on * @param null|string $id Correlation ID to select on * @param string[] $custom Array of STOMP selector strings, like "gateway=adyen" */ protected function createSubscription($type, $id, $custom = array()) { static $sType, $sId, $sCustom; $properties = array('ack' => 'client-individual'); sort($custom); if ($this->subscribed && $sType === $type && $sId === $id && !array_diff($sCustom, $custom)) { // Same subscription; just return return; } elseif ($this->subscribed) { // We need to create a new subscription; but we also have to delete the old one $this->deleteSubscription(); if ($this->refreshConnection) { // Apparently the backend STOMP library has some issues clearing // out its buffer so we get old stuff :( Logger::debug("Refreshing STOMP connection object on selector change. refresh-connection = true"); $this->createBackingObject(); } } $sType = $type; $sId = $id; $sCustom = $custom; // Sanitize the custom selectors foreach ($custom as &$selector) { $groups = array(); $result = preg_match('/([^\\=]+)([<>]\\=?|!?\\=)([^\\=]+)/', $selector, $groups); if ($result != 1) { Logger::warning("Custom STOMP selector doesn't make sense: {$selector}"); continue; } $key = $groups[1]; $operator = $groups[2]; $value = $groups[3]; if (is_numeric($value) === true) { if ($this->convertStringExpressions) { // See http://activemq.apache.org/selectors.html $key = "convert_string_expressions:{$key}"; } else { // Nothing, the key is already in canonical form } } else { $value = trim($value, " '\""); $value = "'{$value}'"; } $selector = "{$key}{$operator}{$value}"; } // And build the selection header array $selectorQuery = array(); if ($type) { $selectorQuery[] = "php-message-class='{$type}'"; } if ($id) { $selectorQuery[] = "JMSCorrelationID='{$id}'"; } $selectorQuery += $custom; if ($selectorQuery) { $properties['selector'] = implode(' AND ', $selectorQuery); } Logger::debug("Attempting to STOMP subscribe to '{$this->queue_id}' on '{$this->uri}'", $properties); $this->stompObj->subscribe($this->queue_id, $properties); $this->subscribed = true; }