Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Remove the dependency on Horde's YAML library.

Add ability to specify the environment the app is running in.
Support v2 of the Hoptoad API.
  • Loading branch information...
commit 26a1e7a18bb15a21c34fa7b8ba15d89978a3a396 1 parent 9448129
@rich rich authored
Showing with 179 additions and 130 deletions.
  1. +173 −119 Hoptoad.php
  2. +5 −10 README.markdown
  3. +1 −1  example.php
View
292 Hoptoad.php
@@ -1,123 +1,177 @@
<?php
-if (!class_exists('HTTP_Request')) require_once('HTTP/Request.php');
-if (!class_exists('Horde_Yaml')) require_once('Horde/Yaml.php');
-if (!class_exists('Horde_Yaml_Dumper')) require_once('Horde/Yaml/Dumper.php');
+if (!class_exists('HTTP_Request2')) require_once('HTTP/Request2.php');
+if (!class_exists('HTTP_Request2_Adapter_Socket')) require_once 'HTTP/Request2/Adapter/Socket.php';
class Hoptoad
{
- /**
- * Install the error and exception handlers that connect to Hoptoad
- *
- * @return void
- * @author Rich Cavanaugh
- */
- public static function installHandlers($api_key=NULL)
- {
- if (isset($api_key)) define('HOPTOAD_API_KEY', $api_key);
-
- set_error_handler(array("Hoptoad", "errorHandler"));
- set_exception_handler(array("Hoptoad", "exceptionHandler"));
- }
-
- /**
- * Handle a php error
- *
- * @param string $code
- * @param string $message
- * @param string $file
- * @param string $line
- * @return void
- * @author Rich Cavanaugh
- */
- public static function errorHandler($code, $message, $file, $line)
- {
- if ($code == E_STRICT) return;
-
- $trace = Hoptoad::tracer();
- Hoptoad::notifyHoptoad(HOPTOAD_API_KEY, $message, $file, $line, $trace, null);
- }
-
- /**
- * Handle a raised exception
- *
- * @param string $exception
- * @return void
- * @author Rich Cavanaugh
- */
- public static function exceptionHandler($exception)
- {
- $trace = Hoptoad::tracer($exception->getTrace());
-
- Hoptoad::notifyHoptoad(HOPTOAD_API_KEY, $exception->getMessage(), $exception->getFile(), $exception->getLine(), $trace, null);
- }
-
- /**
- * Pass the error and environment data on to Hoptoad
- *
- * @package default
- * @author Rich Cavanaugh
- */
- public static function notifyHoptoad($api_key, $message, $file, $line, $trace, $error_class=null)
- {
- $req =& new HTTP_Request("http://hoptoadapp.com/notices/", array("method" => "POST", "timeout" => 2));
- $req->addHeader('Accept', 'text/xml, application/xml');
- $req->addHeader('Content-type', 'application/x-yaml');
-
- array_unshift($trace, "$file:$line");
-
- if (isset($_SESSION)) {
- $session = array('key' => session_id(), 'data' => $_SESSION);
- } else {
- $session = array();
- }
-
- $url = "http://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
- $body = array(
- 'api_key' => $api_key,
- 'error_class' => $error_class,
- 'error_message' => $message,
- 'backtrace' => $trace,
- 'request' => array("params" => $_REQUEST, "url" => $url),
- 'session' => $session,
- 'environment' => $_SERVER
- );
-
- $req->setBody(Horde_Yaml::dump(array("notice" => $body)));
- $req->sendRequest();
- }
-
- /**
- * Build a trace that is formatted in the way Hoptoad expects
- *
- * @param string $trace
- * @return void
- * @author Rich Cavanaugh
- */
- public static function tracer($trace = NULL)
- {
- $lines = Array();
-
- $trace = $trace ? $trace : debug_backtrace();
-
- $indent = '';
- $func = '';
-
- foreach($trace as $val) {
- if (isset($val['class']) && $val['class'] == 'Hoptoad') continue;
-
- $file = isset($val['file']) ? $val['file'] : 'Unknown file';
- $line_number = isset($val['line']) ? $val['line'] : '';
- $func = isset($val['function']) ? $val['function'] : '';
- $class = isset($val['class']) ? $val['class'] : '';
-
- $line = $file;
- if ($line_number) $line .= ':' . $line_number;
- if ($func) $line .= ' in function ' . $func;
- if ($class) $line .= ' in class ' . $class;
-
- $lines[] = $line;
- }
-
- return $lines;
- }
-}
+ const NOTIFIER_NAME = 'php-hoptoad-notifier';
+ const NOTIFIER_VERSION = '0.2.0';
+ const NOTIFIER_URL = 'http://github.com/rich/php-hoptoad-notifier';
+ const NOTIFIER_API_VERSION = '2.0';
+
+ /**
+ * Install the error and exception handlers that connect to Hoptoad
+ *
+ * @return void
+ * @author Rich Cavanaugh
+ */
+ public static function installHandlers($api_key=NULL, $environment=NULL)
+ {
+ if (isset($api_key)) define('HOPTOAD_API_KEY', $api_key);
+ if (isset($environment)) define('HOPTOAD_APP_ENVIRONMENT', $environment);
+
+ set_error_handler(array("Hoptoad", "errorHandler"));
+ set_exception_handler(array("Hoptoad", "exceptionHandler"));
+ }
+
+ /**
+ * Handle a php error
+ *
+ * @param string $code
+ * @param string $message
+ * @param string $file
+ * @param string $line
+ * @return void
+ * @author Rich Cavanaugh
+ */
+ public static function errorHandler($code, $message, $file, $line)
+ {
+ if ($code == E_STRICT) return;
+
+ $trace = Hoptoad::tracer();
+ Hoptoad::notifyHoptoad(HOPTOAD_API_KEY, $message, $file, $line, $trace, null, HOPTOAD_APP_ENVIRONMENT);
+ }
+
+ /**
+ * Handle a raised exception
+ *
+ * @param string $exception
+ * @return void
+ * @author Rich Cavanaugh
+ */
+ public static function exceptionHandler($exception)
+ {
+ $trace = Hoptoad::tracer($exception->getTrace());
+
+ Hoptoad::notifyHoptoad(HOPTOAD_API_KEY, $exception->getMessage(), $exception->getFile(), $exception->getLine(), $trace, null, HOPTOAD_APP_ENVIRONMENT);
+ }
+
+ /**
+ * Pass the error and environment data on to Hoptoad
+ *
+ * @package default
+ * @author Rich Cavanaugh
+ */
+ public static function notifyHoptoad($api_key, $message, $file, $line, $trace, $error_class=null, $environment='production')
+ {
+ array_unshift($trace, "$file:$line");
+
+ $adapter = new HTTP_Request2_Adapter_Socket;
+ $req = new HTTP_Request2("http://hoptoadapp.com/notifier_api/v2/notices", HTTP_Request2::METHOD_POST);
+ $req->setAdapter($adapter);
+ $req->setHeader(array(
+ 'Accept' => 'text/xml, application/xml',
+ 'Content-Type' => 'text/xml'
+ ));
+ $req->setBody(self::buildXmlNotice($api_key, $message, $trace, $error_class, $environment));
+ echo $req->send()->getBody();
+ }
+
+ /**
+ * Build up the XML to post according to the documentation at:
+ * http://help.hoptoadapp.com/faqs/api-2/notifier-api-v2
+ * @return string
+ * @author Rich Cavanaugh
+ **/
+ public static function buildXmlNotice($api_key, $message, $trace, $error_class, $environment, $component='')
+ {
+ $doc = new SimpleXMLElement('<notice />');
+ $doc->addAttribute('version', self::NOTIFIER_API_VERSION);
+ $doc->addChild('api-key', $api_key);
+
+ $notifier = $doc->addChild('notifier');
+ $notifier->addChild('name', self::NOTIFIER_NAME);
+ $notifier->addChild('version', self::NOTIFIER_VERSION);
+ $notifier->addChild('url', self::NOTIFIER_URL);
+
+ $error = $doc->addChild('error');
+ $error->addChild('class', $error_class);
+ $error->addChild('message', $message);
+
+ $backtrace = $error->addChild('backtrace');
+ foreach ($trace as $line) {
+ $line_node = $backtrace->addChild('line');
+ list($file, $number) = explode(':', $line);
+ $line_node->addAttribute('file', $file);
+ $line_node->addAttribute('number', $number);
+ $line_node->addAttribute('method', '');
+ }
+
+ $request = $doc->addChild('request');
+ $request->addChild('url', "http://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}");
+ $request->addChild('component', $component);
+
+ if (isset($_REQUEST) && !empty($_REQUEST)) {
+ $params = $request->addChild('params');
+ foreach ($_REQUEST as $key => $val) {
+ $var_node = $params->addChild('var', $val);
+ $var_node->addAttribute('key', $key);
+ }
+ }
+
+ if (isset($_SESSION) && !empty($_SESSION)) {
+ $session = $request->addChild('session');
+ foreach ($_SESSION as $key => $val) {
+ $var_node = $session->addChild('var', $val);
+ $var_node->addAttribute('key', $key);
+ }
+ }
+
+ $cgi_data = $request->addChild('cgi-data');
+ foreach ($_SERVER as $key => $val) {
+ $var_node = $cgi_data->addChild('var', $val);
+ $var_node->addAttribute('key', $key);
+ }
+
+ $env = $doc->addChild('server-environment');
+ $env->addChild('project-root', $_SERVER['DOCUMENT_ROOT']);
+ $env->addChild('environment-name', $environment);
+
+ return $doc->asXML();
+ }
+
+ /**
+ * Build a trace that is formatted in the way Hoptoad expects
+ *
+ * @param string $trace
+ * @return void
+ * @author Rich Cavanaugh
+ */
+ public static function tracer($trace = NULL)
+ {
+ $lines = Array();
+
+ $trace = $trace ? $trace : debug_backtrace();
+
+ $indent = '';
+ $func = '';
+
+ foreach($trace as $val) {
+ if (isset($val['class']) && $val['class'] == 'Hoptoad') continue;
+
+ $file = isset($val['file']) ? $val['file'] : 'Unknown file';
+ $line_number = isset($val['line']) ? $val['line'] : '';
+ $func = isset($val['function']) ? $val['function'] : '';
+ $class = isset($val['class']) ? $val['class'] : '';
+
+ $line = $file;
+ if ($line_number) $line .= ':' . $line_number;
+ if ($func) $line .= ' in function ' . $func;
+ if ($class) $line .= ' in class ' . $class;
+
+ $lines[] = $line;
+ }
+
+ return $lines;
+ }
+}
View
15 README.markdown
@@ -1,6 +1,6 @@
# Introduction
-This is a simple [Hoptoad](http://hoptoadapp.com) notifier for PHP. It's been used in a few production sites now with success. It's not quite as fully featured as the official Ruby notifier but it works well.
+This is a simple [Hoptoad](http://hoptoadapp.com) notifier for PHP. It's been used in a few production sites now with success. It's not quite as fully featured as the official Ruby notifier but it works well.
# Limitations
@@ -10,18 +10,13 @@ For deploy tracking, since I use Capistrano to deploy my PHP apps, I simply use
# Requirements
-The notifier uses the Horde_Yaml class. You can install this class using the commands below.
+Install Pear's HTTP_Request2:
- pear channel-discover pear.horde.org
- pear install horde/yaml
-
-It also uses Pear's HTTP_Request:
-
- pear install HTTP_Request
+ pear install HTTP_Request2
# License
-Copyright (c) 2009, Rich Cavanaugh
+Copyright (c) 2010, Rich Cavanaugh
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
@@ -30,4 +25,4 @@ Redistribution and use in source and binary forms, with or without modification,
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
View
2  example.php
@@ -1,4 +1,4 @@
<?php
require_once('Hoptoad.php');
- Hoptoad::installHandlers("YOUR_HOPTOAD_API_KEY");
+ Hoptoad::installHandlers("YOUR_HOPTOAD_API_KEY", 'production');
Please sign in to comment.
Something went wrong with that request. Please try again.