Shippit_Shippit - Version 4.3.14

Version Notes

Shippit Magento Integration module, using the Shippit v3 API.

Allows for retrieving shipping quotes during checkout and sending orders to Shippit.

Also adds Australian States and Territories to the available region options and Authority to Leave and Delivery Comments to the checkout process.

Download this release

Release Info

Developer Matthew Muscat
Extension Shippit_Shippit
Version 4.3.14
Comparing to
See all releases


Code changes from version 4.3.11 to 4.3.14

app/code/community/Shippit/Shippit/Helper/Bugsnag.php CHANGED
@@ -23,15 +23,6 @@ class Shippit_Shippit_Helper_Bugsnag extends Mage_Core_Helper_Abstract
23
  public function init()
24
  {
25
  if (!$this->client) {
26
- if (file_exists(Mage::getBaseDir('lib') . '/shippit-bugsnag/Autoload.php')) {
27
- require_once(Mage::getBaseDir('lib') . '/shippit-bugsnag/Autoload.php');
28
- }
29
- else {
30
- Mage::log('Shippit Bugsnag Error', 'Couldn\'t activate Bugsnag Error Monitoring due to missing Bugsnag PHP library!', null, 'shippit.log');
31
-
32
- return false;
33
- }
34
-
35
  // Allow override of bugsnag key
36
  // this can be your own bugsnag api key, or an empty string
37
  // to disable bugsnag logging if required
@@ -47,19 +38,21 @@ class Shippit_Shippit_Helper_Bugsnag extends Mage_Core_Helper_Abstract
47
  return $this->client;
48
  }
49
 
 
 
 
 
 
 
 
 
 
50
  $this->client = new Bugsnag_Client($apiKey);
51
  $this->client->setReleaseStage($this->getReleaseStage())
52
  ->setErrorReportingLevel($this->getErrorReportingLevel())
53
  ->setMetaData($this->getMetaData());
54
 
55
  $this->client->setNotifier($this->getNotiferData());
56
-
57
- set_error_handler(
58
- array($this->client, "errorHandler")
59
- );
60
- set_exception_handler(
61
- array($this->client, "exceptionHandler")
62
- );
63
  }
64
 
65
  return $this->client;
23
  public function init()
24
  {
25
  if (!$this->client) {
 
 
 
 
 
 
 
 
 
26
  // Allow override of bugsnag key
27
  // this can be your own bugsnag api key, or an empty string
28
  // to disable bugsnag logging if required
38
  return $this->client;
39
  }
40
 
41
+ if (file_exists(Mage::getBaseDir('lib') . '/shippit-bugsnag/Autoload.php')) {
42
+ require_once(Mage::getBaseDir('lib') . '/shippit-bugsnag/Autoload.php');
43
+ }
44
+ else {
45
+ Mage::log('Shippit Bugsnag Error', 'Couldn\'t activate Bugsnag Error Monitoring due to missing Bugsnag PHP library!', null, 'shippit.log');
46
+
47
+ return false;
48
+ }
49
+
50
  $this->client = new Bugsnag_Client($apiKey);
51
  $this->client->setReleaseStage($this->getReleaseStage())
52
  ->setErrorReportingLevel($this->getErrorReportingLevel())
53
  ->setMetaData($this->getMetaData());
54
 
55
  $this->client->setNotifier($this->getNotiferData());
 
 
 
 
 
 
 
56
  }
57
 
58
  return $this->client;
app/code/community/Shippit/Shippit/Model/Request/Api/Order.php CHANGED
@@ -46,10 +46,10 @@ class Shippit_Shippit_Model_Request_Api_Order extends Varien_Object
46
  const PARCEL_ATTRIBUTES = 'parcel_attributes';
47
 
48
  // Shippit Service Class API Mappings
49
- const SHIPPING_SERVICE_STANDARD = 'CouriersPlease';
50
- const SHIPPING_SERVICE_EXPRESS = 'eparcelexpress';
51
- const SHIPPING_SERVICE_PRIORITY = 'Bonds';
52
- const SHIPPING_SERVICE_INTERNATIONAL = 'Dhl';
53
 
54
  public function __construct() {
55
  $this->helper = Mage::helper('shippit/sync_order');
46
  const PARCEL_ATTRIBUTES = 'parcel_attributes';
47
 
48
  // Shippit Service Class API Mappings
49
+ const SHIPPING_SERVICE_STANDARD = 'standard';
50
+ const SHIPPING_SERVICE_EXPRESS = 'express';
51
+ const SHIPPING_SERVICE_PRIORITY = 'priority';
52
+ const SHIPPING_SERVICE_INTERNATIONAL = 'international';
53
 
54
  public function __construct() {
55
  $this->helper = Mage::helper('shippit/sync_order');
app/code/community/Shippit/Shippit/Model/Request/Sync/Order.php CHANGED
@@ -89,12 +89,14 @@ class Shippit_Shippit_Model_Request_Sync_Order extends Varien_Object
89
  $itemPrice = $this->_getItemPrice($item);
90
  $itemWeight = $item->getWeight();
91
 
92
- $itemLocation = $this->itemsHelper->getLocation($item);
 
 
93
 
94
  if ($itemQty > 0) {
95
  $this->addItem(
96
  $item->getSku(),
97
- $item->getName(),
98
  $itemQty,
99
  $itemPrice,
100
  $itemWeight,
@@ -115,24 +117,31 @@ class Shippit_Shippit_Model_Request_Sync_Order extends Varien_Object
115
  private function _getItemPrice($item)
116
  {
117
  $rootItem = $this->_getRootItem($item);
 
118
  // Get the item price
119
  // - If the root item is a bundle, use the item price
120
  // Otherwise, use the root item price
121
  if ($rootItem->getProductType() == 'bundle') {
122
  // if we are sending the bundle together
123
  if ($rootItem->getId() == $item->getId()) {
124
- return $rootItem->getPrice();
125
  }
126
  // if we are sending individually
127
  else {
128
- return $item->getPrice();
129
  }
130
  }
131
  else {
132
- return $rootItem->getBasePrice();
133
  }
134
  }
135
 
 
 
 
 
 
 
136
  private function _getRootItem($item)
137
  {
138
  if ($item->getParentItem()) {
@@ -143,6 +152,40 @@ class Shippit_Shippit_Model_Request_Sync_Order extends Varien_Object
143
  }
144
  }
145
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  public function setShippingMethod($shippingMethod)
147
  {
148
  // Standard, express, priority and international options are available
89
  $itemPrice = $this->_getItemPrice($item);
90
  $itemWeight = $item->getWeight();
91
 
92
+ $childItem = $this->_getChildItem($item);
93
+ $itemName = $childItem->getName();
94
+ $itemLocation = $this->itemsHelper->getLocation($childItem);
95
 
96
  if ($itemQty > 0) {
97
  $this->addItem(
98
  $item->getSku(),
99
+ $itemName,
100
  $itemQty,
101
  $itemPrice,
102
  $itemWeight,
117
  private function _getItemPrice($item)
118
  {
119
  $rootItem = $this->_getRootItem($item);
120
+
121
  // Get the item price
122
  // - If the root item is a bundle, use the item price
123
  // Otherwise, use the root item price
124
  if ($rootItem->getProductType() == 'bundle') {
125
  // if we are sending the bundle together
126
  if ($rootItem->getId() == $item->getId()) {
127
+ return $rootItem->getBasePriceInclTax();
128
  }
129
  // if we are sending individually
130
  else {
131
+ return $item->getBasePriceInclTax();
132
  }
133
  }
134
  else {
135
+ return $rootItem->getBasePriceInclTax();
136
  }
137
  }
138
 
139
+ /**
140
+ * Returns the parent item of the item passed
141
+ *
142
+ * @param Mage_Sales_Model_Order_Item $item
143
+ * @return Mage_Sales_Model_Order_Item
144
+ */
145
  private function _getRootItem($item)
146
  {
147
  if ($item->getParentItem()) {
152
  }
153
  }
154
 
155
+ /**
156
+ * Returns the first child item of the item passed
157
+ * - If the item is a bundle and is being shipped together
158
+ * we return the bundle item, as it's the "shipped" product
159
+ *
160
+ * @param Mage_Sales_Model_Order_Item $item
161
+ * @return Mage_Sales_Model_Order_Item
162
+ */
163
+ private function _getChildItem($item)
164
+ {
165
+ if ($item->getHasChildren()) {
166
+ $rootItem = $this->_getRootItem($item);
167
+
168
+ // Get the first child item
169
+ // - If the root item is a bundle, use the item
170
+ // Otherwise, use the root item
171
+ if ($rootItem->getProductType() == 'bundle') {
172
+ // if we are sending the bundle together
173
+ if ($rootItem->getId() == $item->getId()) {
174
+ return $rootItem;
175
+ }
176
+ else {
177
+ return $item->getChildrenItems()[0];
178
+ }
179
+ }
180
+ else {
181
+ return $item->getChildrenItems()[0];
182
+ }
183
+ }
184
+ else {
185
+ return $item;
186
+ }
187
+ }
188
+
189
  public function setShippingMethod($shippingMethod)
190
  {
191
  // Standard, express, priority and international options are available
app/code/community/Shippit/Shippit/Model/Shipping/Carrier/Shippit.php CHANGED
@@ -115,16 +115,25 @@ class Shippit_Shippit_Model_Shipping_Carrier_Shippit extends Mage_Shipping_Model
115
  // Process the response and return available options
116
  foreach ($shippingQuotes as $shippingQuoteKey => $shippingQuote) {
117
  if ($shippingQuote->success) {
118
- if ($shippingQuote->courier_type == 'Bonds'
119
- && $isPriorityAvailable) {
120
- $this->_addPriorityQuote($rateResult, $shippingQuote);
121
- }
122
- elseif ($shippingQuote->courier_type == 'eparcelexpress'
123
- && $isExpressAvailable) {
124
- $this->_addExpressQuote($rateResult, $shippingQuote);
125
- }
126
- elseif ($isStandardAvailable) {
127
- $this->_addStandardQuote($rateResult, $shippingQuote);
 
 
 
 
 
 
 
 
 
128
  }
129
  }
130
  }
115
  // Process the response and return available options
116
  foreach ($shippingQuotes as $shippingQuoteKey => $shippingQuote) {
117
  if ($shippingQuote->success) {
118
+ switch ($shippingQuote->service_level) {
119
+ case 'priority':
120
+ if ($isPriorityAvailable) {
121
+ $this->_addPriorityQuote($rateResult, $shippingQuote);
122
+ }
123
+
124
+ break;
125
+ case 'express':
126
+ if ($isExpressAvailable) {
127
+ $this->_addExpressQuote($rateResult, $shippingQuote);
128
+ }
129
+
130
+ break;
131
+ case 'standard':
132
+ if ($isStandardAvailable) {
133
+ $this->_addStandardQuote($rateResult, $shippingQuote);
134
+ }
135
+
136
+ break;
137
  }
138
  }
139
  }
app/code/community/Shippit/Shippit/controllers/OrderController.php CHANGED
@@ -39,6 +39,29 @@ class Shippit_Shippit_OrderController extends Mage_Core_Controller_Front_Action
39
 
40
  public function updateAction()
41
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  $request = json_decode(file_get_contents('php://input'), true);
43
 
44
  $metaData = array(
@@ -50,14 +73,6 @@ class Shippit_Shippit_OrderController extends Mage_Core_Controller_Front_Action
50
  $this->logger->setMetaData($metaData);
51
  $this->logger->log('Shipment Sync Request Recieved');
52
 
53
- if (!$this->helper->isActive()) {
54
- $this->logger->log('Shipping Sync is not active');
55
- $response = $this->_prepareResponse(false, self::ERROR_SYNC_DISABLED);
56
-
57
- return $this->getResponse()->setBody($response);
58
- }
59
-
60
- $apiKey = $this->getRequest()->getParam('api_key');
61
  $orderIncrementId = $request['retailer_order_number'];
62
  $orderShipmentState = $request['current_state'];
63
 
@@ -71,20 +86,6 @@ class Shippit_Shippit_OrderController extends Mage_Core_Controller_Front_Action
71
  $products = array();
72
  }
73
 
74
- if (empty($apiKey)) {
75
- $response = $this->_prepareResponse(false, self::ERROR_API_KEY_MISSING);
76
- $this->logger->log('Shipment Sync Error - ' . self::ERROR_API_KEY_MISSING, Zend_Log::WARN);
77
-
78
- return $this->getResponse()->setBody($response);
79
- }
80
-
81
- if (!$this->_checkApiKey($apiKey)) {
82
- $response = $this->_prepareResponse(false, self::ERROR_API_KEY_MISMATCH);
83
- $this->logger->log('Shipment Sync Error - ' . self::ERROR_API_KEY_MISMATCH, Zend_Log::WARN);
84
-
85
- return $this->getResponse()->setBody($response);
86
- }
87
-
88
  if (empty($request)) {
89
  $response = $this->_prepareResponse(false, self::ERROR_BAD_REQUEST);
90
  $this->logger->log('Shipment Sync Error - ' . self::ERROR_BAD_REQUEST, Zend_Log::WARN);
39
 
40
  public function updateAction()
41
  {
42
+ if (!$this->helper->isActive()) {
43
+ $this->logger->log('Shipping Sync is not active');
44
+ $response = $this->_prepareResponse(false, self::ERROR_SYNC_DISABLED);
45
+
46
+ return $this->getResponse()->setBody($response);
47
+ }
48
+
49
+ $apiKey = $this->getRequest()->getParam('api_key');
50
+
51
+ if (empty($apiKey)) {
52
+ $response = $this->_prepareResponse(false, self::ERROR_API_KEY_MISSING);
53
+ $this->logger->log('Shipment Sync Error - ' . self::ERROR_API_KEY_MISSING, Zend_Log::WARN);
54
+
55
+ return $this->getResponse()->setBody($response);
56
+ }
57
+
58
+ if (!$this->_checkApiKey($apiKey)) {
59
+ $response = $this->_prepareResponse(false, self::ERROR_API_KEY_MISMATCH);
60
+ $this->logger->log('Shipment Sync Error - ' . self::ERROR_API_KEY_MISMATCH, Zend_Log::WARN);
61
+
62
+ return $this->getResponse()->setBody($response);
63
+ }
64
+
65
  $request = json_decode(file_get_contents('php://input'), true);
66
 
67
  $metaData = array(
73
  $this->logger->setMetaData($metaData);
74
  $this->logger->log('Shipment Sync Request Recieved');
75
 
 
 
 
 
 
 
 
 
76
  $orderIncrementId = $request['retailer_order_number'];
77
  $orderShipmentState = $request['current_state'];
78
 
86
  $products = array();
87
  }
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  if (empty($request)) {
90
  $response = $this->_prepareResponse(false, self::ERROR_BAD_REQUEST);
91
  $this->logger->log('Shipment Sync Error - ' . self::ERROR_BAD_REQUEST, Zend_Log::WARN);
app/code/community/Shippit/Shippit/etc/config.xml CHANGED
@@ -18,7 +18,7 @@
18
  <config>
19
  <modules>
20
  <Shippit_Shippit>
21
- <version>4.3.11</version>
22
  </Shippit_Shippit>
23
  </modules>
24
 
18
  <config>
19
  <modules>
20
  <Shippit_Shippit>
21
+ <version>4.3.14</version>
22
  </Shippit_Shippit>
23
  </modules>
24
 
lib/shippit-bugsnag/Autoload.php CHANGED
@@ -1,15 +1,15 @@
1
  <?php
2
 
3
- # We used to have an autoloader, but it caused problems in some
4
- # environments. So now we manually load the entire library upfront.
5
- #
6
- # The file is still called Autoload so that existing integration
7
- # instructions continue to work.
8
- require_once dirname(__FILE__).DIRECTORY_SEPARATOR."Client.php";
9
- require_once dirname(__FILE__).DIRECTORY_SEPARATOR."Configuration.php";
10
- require_once dirname(__FILE__).DIRECTORY_SEPARATOR."Diagnostics.php";
11
- require_once dirname(__FILE__).DIRECTORY_SEPARATOR."Error.php";
12
- require_once dirname(__FILE__).DIRECTORY_SEPARATOR."ErrorTypes.php";
13
- require_once dirname(__FILE__).DIRECTORY_SEPARATOR."Notification.php";
14
- require_once dirname(__FILE__).DIRECTORY_SEPARATOR."Request.php";
15
- require_once dirname(__FILE__).DIRECTORY_SEPARATOR."Stacktrace.php";
1
  <?php
2
 
3
+ // We used to have an autoloader, but it caused problems in some
4
+ // environments. So now we manually load the entire library upfront.
5
+ //
6
+ // The file is still called Autoload so that existing integration
7
+ // instructions continue to work.
8
+ require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'Client.php';
9
+ require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'Configuration.php';
10
+ require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'Diagnostics.php';
11
+ require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'Error.php';
12
+ require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'ErrorTypes.php';
13
+ require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'Notification.php';
14
+ require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'Request.php';
15
+ require_once dirname(__FILE__).DIRECTORY_SEPARATOR.'Stacktrace.php';
lib/shippit-bugsnag/Client.php CHANGED
@@ -2,15 +2,35 @@
2
 
3
  class Bugsnag_Client
4
  {
 
 
 
 
 
5
  private $config;
6
- /** @var Bugsnag_Notification|null */
 
 
 
 
 
 
 
 
 
 
 
 
7
  private $notification;
8
 
9
  /**
10
- * Initialize Bugsnag
 
 
11
  *
12
- * @param String $apiKey your Bugsnag API key
13
  * @throws Exception
 
 
14
  */
15
  public function __construct($apiKey)
16
  {
@@ -32,9 +52,10 @@ class Bugsnag_Client
32
  }
33
 
34
  /**
35
- * Set your release stage, eg "production" or "development"
 
 
36
  *
37
- * @param String $releaseStage the app's current release stage
38
  * @return $this
39
  */
40
  public function setReleaseStage($releaseStage)
@@ -45,9 +66,10 @@ class Bugsnag_Client
45
  }
46
 
47
  /**
48
- * Set your app's semantic version, eg "1.2.3"
 
 
49
  *
50
- * @param String $appVersion the app's version
51
  * @return $this
52
  */
53
  public function setAppVersion($appVersion)
@@ -58,9 +80,10 @@ class Bugsnag_Client
58
  }
59
 
60
  /**
61
- * Set the host name
 
 
62
  *
63
- * @param String $hostname the host name
64
  * @return $this
65
  */
66
  public function setHostname($hostname)
@@ -71,10 +94,12 @@ class Bugsnag_Client
71
  }
72
 
73
  /**
74
- * Set which release stages should be allowed to notify Bugsnag
75
- * eg array("production", "development")
 
 
 
76
  *
77
- * @param Array $notifyReleaseStages array of release stages to notify for
78
  * @return $this
79
  */
80
  public function setNotifyReleaseStages(array $notifyReleaseStages)
@@ -87,7 +112,8 @@ class Bugsnag_Client
87
  /**
88
  * Set which Bugsnag endpoint to send errors to.
89
  *
90
- * @param String $endpoint endpoint URL
 
91
  * @return $this
92
  */
93
  public function setEndpoint($endpoint)
@@ -100,7 +126,8 @@ class Bugsnag_Client
100
  /**
101
  * Enable debug mode to help diagnose problems.
102
  *
103
- * @param Boolean $debug whether to enable debug mode
 
104
  * @return $this
105
  */
106
  public function setDebug($debug)
@@ -111,11 +138,13 @@ class Bugsnag_Client
111
  }
112
 
113
  /**
114
- * Set whether or not to use SSL when notifying bugsnag
 
 
115
  *
116
- * @param Boolean $useSSL whether to use SSL
117
- * @deprecated you can now pass full URLs to setEndpoint
118
  * @return $this
 
 
119
  */
120
  public function setUseSSL($useSSL)
121
  {
@@ -125,9 +154,10 @@ class Bugsnag_Client
125
  }
126
 
127
  /**
128
- * Set the desired timeout for cURL connection when notifying bugsnag
 
 
129
  *
130
- * @param Integer $timeout the desired timeout in seconds
131
  * @return $this
132
  */
133
  public function setTimeout($timeout)
@@ -139,10 +169,12 @@ class Bugsnag_Client
139
 
140
  /**
141
  * Set the absolute path to the root of your application.
 
142
  * We use this to help with error grouping and to highlight "in project"
143
  * stacktrace lines.
144
  *
145
- * @param String $projectRoot the root path for your application
 
146
  * @return $this
147
  */
148
  public function setProjectRoot($projectRoot)
@@ -153,11 +185,14 @@ class Bugsnag_Client
153
  }
154
 
155
  /**
156
- * Set the path that should be stripped from the beginning of
157
- * any stacktrace file line. This helps to normalise filenames
158
- * for grouping and reduces the noise in stack traces.
 
 
 
 
159
  *
160
- * @param String $stripPath the path to strip from filenames
161
  * @return $this
162
  */
163
  public function setStripPath($stripPath)
@@ -168,10 +203,10 @@ class Bugsnag_Client
168
  }
169
 
170
  /**
171
- * Set the a regular expression for matching filenames in stacktrace lines
172
- * that are part of your application.
 
173
  *
174
- * @param String $projectRootRegex regex matching paths belong to your project
175
  * @return $this
176
  */
177
  public function setProjectRootRegex($projectRootRegex)
@@ -182,10 +217,12 @@ class Bugsnag_Client
182
  }
183
 
184
  /**
185
- * Set the strings to filter out from metaData arrays before sending then
186
- * to Bugsnag. Eg. array("password", "credit_card")
 
 
 
187
  *
188
- * @param Array $filters an array of metaData filters
189
  * @return $this
190
  */
191
  public function setFilters(array $filters)
@@ -196,14 +233,14 @@ class Bugsnag_Client
196
  }
197
 
198
  /**
199
- * Set information about the current user of your app, including
200
- * id, name and email.
201
  *
202
- * @param Array $user an array of user information. Eg:
203
  * array(
204
  * 'name' => 'Bob Hoskins',
205
  * 'email' => 'bob@hoskins.com'
206
  * )
 
207
  * @return $this
208
  */
209
  public function setUser(array $user)
@@ -214,9 +251,11 @@ class Bugsnag_Client
214
  }
215
 
216
  /**
217
- * @deprecated deprecated since version 2.1
218
  * @param $userId
 
219
  * @return $this
 
 
220
  */
221
  public function setUserId($userId)
222
  {
@@ -232,7 +271,8 @@ class Bugsnag_Client
232
  /**
233
  * Set a context representing the current type of request, or location in code.
234
  *
235
- * @param String $context the current context
 
236
  * @return $this
237
  */
238
  public function setContext($context)
@@ -243,11 +283,14 @@ class Bugsnag_Client
243
  }
244
 
245
  /**
246
- * Set the type of application executing the code. This is usually used to
247
- * represent if you are running plain PHP code "php", via a framework,
248
- * eg "laravel", or executing through delayed worker code, eg "resque".
 
 
 
 
249
  *
250
- * @param String $type the current type
251
  * @return $this
252
  */
253
  public function setType($type)
@@ -258,35 +301,44 @@ class Bugsnag_Client
258
  }
259
 
260
  /**
261
- * Set custom metadata to send to Bugsnag with every error. You can use
262
- * this to add custom tabs of data to each error on your Bugsnag dashboard
 
 
263
  *
264
- * @param Array $metaData an array of arrays of custom data. Eg:
265
  * array(
266
- * "user" => array(
267
- * "name" => "James",
268
- * "email" => "james@example.com"
269
  * )
270
  * )
 
 
271
  * @return $this
272
  */
273
- public function setMetaData(array $metaData)
274
  {
275
- $this->config->metaData = $metaData;
 
 
 
 
276
 
277
  return $this;
278
  }
279
 
280
  /**
281
- * Set proxy configuration
282
  *
283
- * @param Array $proxySettings an array with proxy settings. Eg:
284
  * array(
285
- * 'host' => "bugsnag.com",
286
  * 'port' => 42,
287
- * 'user' => "username"
288
- * 'password' => "password123"
289
- * )
 
290
  * @return $this
291
  */
292
  public function setProxySettings(array $proxySettings)
@@ -297,12 +349,13 @@ class Bugsnag_Client
297
  }
298
 
299
  /**
300
- * Set custom curl options
301
  *
302
- * @param Array $curlOptions an array with curl options. Eg:
303
  * array(
304
  * CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4
305
- * )
 
306
  * @return $this
307
  */
308
  public function setCurlOptions(array $curlOptions)
@@ -314,19 +367,22 @@ class Bugsnag_Client
314
 
315
  /**
316
  * Set a custom function to call before notifying Bugsnag of an error.
 
317
  * You can use this to call your own error handling functions, or to add
318
  * custom tabs of data to each error on your Bugsnag dashboard.
319
  *
320
  * // Adding meta-data example
321
  * function before_bugsnag_notify($error) {
322
  * $error->addMetaData(array(
323
- * "user" => array(
324
- * "name" => "James"
325
  * )
326
  * ));
327
  * }
328
- * $bugsnag->setBeforeNotifyFunction("before_bugsnag_notify");
 
329
  * @param callable $beforeNotifyFunction
 
330
  * @return $this
331
  */
332
  public function setBeforeNotifyFunction($beforeNotifyFunction)
@@ -338,11 +394,13 @@ class Bugsnag_Client
338
 
339
  /**
340
  * Set Bugsnag's error reporting level.
 
341
  * If this is not set, we'll use your current PHP error_reporting value
342
  * from your ini file or error_reporting(...) calls.
343
  *
344
- * @param Integer $errorReportingLevel the error reporting level integer
345
  * exactly as you would pass to PHP's error_reporting
 
346
  * @return $this
347
  */
348
  public function setErrorReportingLevel($errorReportingLevel)
@@ -353,10 +411,10 @@ class Bugsnag_Client
353
  }
354
 
355
  /**
356
- * Sets whether Bugsnag should be automatically notified of unhandled
357
- * exceptions and errors.
 
358
  *
359
- * @param Boolean $autoNotify whether to auto notify or not
360
  * @return $this
361
  */
362
  public function setAutoNotify($autoNotify)
@@ -367,10 +425,10 @@ class Bugsnag_Client
367
  }
368
 
369
  /**
370
- * Sets whether errors should be batched together and send at the end of
371
- * each request.
 
372
  *
373
- * @param Boolean $batchSending whether to batch together errors
374
  * @return $this
375
  */
376
  public function setBatchSending($batchSending)
@@ -381,10 +439,12 @@ class Bugsnag_Client
381
  }
382
 
383
  /**
384
- * Sets the notifier to report as to Bugsnag. This should only be
385
- * set by other notifier libraries.
 
 
 
386
  *
387
- * @param Array $notifier an array of name, version, url.
388
  * @return $this
389
  */
390
  public function setNotifier($notifier)
@@ -397,7 +457,8 @@ class Bugsnag_Client
397
  /**
398
  * Sets whether Bugsnag should send $_ENV with each error.
399
  *
400
- * @param Boolean $sendEnvironment whether to send the environment
 
401
  * @return $this
402
  */
403
  public function setSendEnvironment($sendEnvironment)
@@ -410,7 +471,8 @@ class Bugsnag_Client
410
  /**
411
  * Sets whether Bugsnag should send $_COOKIE with each error.
412
  *
413
- * @param Boolean $sendCookies whether to send the environment
 
414
  * @return $this
415
  */
416
  public function setSendCookies($sendCookies)
@@ -423,7 +485,8 @@ class Bugsnag_Client
423
  /**
424
  * Sets whether Bugsnag should send $_SESSION with each error.
425
  *
426
- * @param Boolean $sendSession whether to send the environment
 
427
  * @return $this
428
  */
429
  public function setSendSession($sendSession)
@@ -434,10 +497,12 @@ class Bugsnag_Client
434
  }
435
 
436
  /**
437
- * Should we send a small snippet of the code that crashed to help you
438
- * diagnose even faster from within your dashboard.
 
 
 
439
  *
440
- * @param Boolean $sendCode whether to send code to Bugsnag
441
  * @return $this
442
  */
443
  public function setSendCode($sendCode)
@@ -448,11 +513,13 @@ class Bugsnag_Client
448
  }
449
 
450
  /**
451
- * Notify Bugsnag of a non-fatal/handled throwable
452
  *
453
  * @param Throwable $throwable the throwable to notify Bugsnag about
454
- * @param Array $metaData optional metaData to send with this error
455
- * @param String $severity optional severity of this error (fatal/error/warning/info)
 
 
456
  */
457
  public function notifyException($throwable, array $metaData = null, $severity = null)
458
  {
@@ -465,12 +532,14 @@ class Bugsnag_Client
465
  }
466
 
467
  /**
468
- * Notify Bugsnag of a non-fatal/handled error
 
 
 
 
 
469
  *
470
- * @param String $name the name of the error, a short (1 word) string
471
- * @param String $message the error message
472
- * @param Array $metaData optional metaData to send with this error
473
- * @param String $severity optional severity of this error (fatal/error/warning/info)
474
  */
475
  public function notifyError($name, $message, array $metaData = null, $severity = null)
476
  {
@@ -480,22 +549,41 @@ class Bugsnag_Client
480
  $this->notify($error, $metaData);
481
  }
482
 
483
- // Exception handler callback, should only be called internally by PHP's set_exception_handler
 
 
 
 
 
 
 
 
484
  public function exceptionHandler($throwable)
485
  {
486
- if(!$this->config->autoNotify) {
487
  return;
488
  }
489
 
490
  $error = Bugsnag_Error::fromPHPThrowable($this->config, $this->diagnostics, $throwable);
491
- $error->setSeverity("error");
492
  $this->notify($error);
493
  }
494
 
495
- // Exception handler callback, should only be called internally by PHP's set_error_handler
 
 
 
 
 
 
 
 
 
 
 
496
  public function errorHandler($errno, $errstr, $errfile = '', $errline = 0)
497
  {
498
- if(!$this->config->autoNotify || $this->config->shouldIgnoreErrorCode($errno)) {
499
  return;
500
  }
501
 
@@ -503,8 +591,14 @@ class Bugsnag_Client
503
  $this->notify($error);
504
  }
505
 
506
- // Shutdown handler callback, called when the PHP process has finished running
507
- // Should only be called internally by PHP's register_shutdown_function
 
 
 
 
 
 
508
  public function shutdownHandler()
509
  {
510
  // Get last error
@@ -513,7 +607,7 @@ class Bugsnag_Client
513
  // Check if a fatal error caused this shutdown
514
  if (!is_null($lastError) && Bugsnag_ErrorTypes::isFatal($lastError['type']) && $this->config->autoNotify && !$this->config->shouldIgnoreErrorCode($lastError['type'])) {
515
  $error = Bugsnag_Error::fromPHPError($this->config, $this->diagnostics, $lastError['type'], $lastError['message'], $lastError['file'], $lastError['line'], true);
516
- $error->setSeverity("error");
517
  $this->notify($error);
518
  }
519
 
@@ -525,10 +619,12 @@ class Bugsnag_Client
525
  }
526
 
527
  /**
528
- * Batches up errors into notifications for later sending
529
  *
530
  * @param Bugsnag_Error $error the error to batch up
531
  * @param array $metaData optional meta data to send with the error
 
 
532
  */
533
  public function notify(Bugsnag_Error $error, $metaData = array())
534
  {
@@ -549,7 +645,11 @@ class Bugsnag_Client
549
  }
550
  }
551
 
552
- // Should we send errors immediately or on shutdown
 
 
 
 
553
  private function sendErrorsOnShutdown()
554
  {
555
  return $this->config->batchSending && Bugsnag_Request::isRequest();
2
 
3
  class Bugsnag_Client
4
  {
5
+ /**
6
+ * The config instance.
7
+ *
8
+ * @var Bugsnag_Configuration
9
+ */
10
  private $config;
11
+
12
+ /**
13
+ * The diagnostics instance.
14
+ *
15
+ * @var Bugsnag_Diagnostics
16
+ */
17
+ private $diagnostics;
18
+
19
+ /**
20
+ * The notification instance.
21
+ *
22
+ * @var Bugsnag_Notification|null
23
+ */
24
  private $notification;
25
 
26
  /**
27
+ * Create a new client instance.
28
+ *
29
+ * @param string $apiKey your Bugsnag API key
30
  *
 
31
  * @throws Exception
32
+ *
33
+ * @return void
34
  */
35
  public function __construct($apiKey)
36
  {
52
  }
53
 
54
  /**
55
+ * Set your release stage, eg "production" or "development".
56
+ *
57
+ * @param string $releaseStage the app's current release stage
58
  *
 
59
  * @return $this
60
  */
61
  public function setReleaseStage($releaseStage)
66
  }
67
 
68
  /**
69
+ * Set your app's semantic version, eg "1.2.3".
70
+ *
71
+ * @param string $appVersion the app's version
72
  *
 
73
  * @return $this
74
  */
75
  public function setAppVersion($appVersion)
80
  }
81
 
82
  /**
83
+ * Set the host name.
84
+ *
85
+ * @param string $hostname the host name
86
  *
 
87
  * @return $this
88
  */
89
  public function setHostname($hostname)
94
  }
95
 
96
  /**
97
+ * Set which release stages should be allowed to notify Bugsnag.
98
+ *
99
+ * Eg array('production', 'development').
100
+ *
101
+ * @param array $notifyReleaseStages array of release stages to notify for
102
  *
 
103
  * @return $this
104
  */
105
  public function setNotifyReleaseStages(array $notifyReleaseStages)
112
  /**
113
  * Set which Bugsnag endpoint to send errors to.
114
  *
115
+ * @param string $endpoint endpoint URL
116
+ *
117
  * @return $this
118
  */
119
  public function setEndpoint($endpoint)
126
  /**
127
  * Enable debug mode to help diagnose problems.
128
  *
129
+ * @param bool $debug whether to enable debug mode
130
+ *
131
  * @return $this
132
  */
133
  public function setDebug($debug)
138
  }
139
 
140
  /**
141
+ * Set whether or not to use SSL when notifying bugsnag.
142
+ *
143
+ * @param bool $useSSL whether to use SSL
144
  *
 
 
145
  * @return $this
146
+ *
147
+ * @deprecated since version 2.5. Pass full URLs to setEndpoint.
148
  */
149
  public function setUseSSL($useSSL)
150
  {
154
  }
155
 
156
  /**
157
+ * Set the desired timeout for cURL connection when notifying bugsnag.
158
+ *
159
+ * @param int $timeout the desired timeout in seconds
160
  *
 
161
  * @return $this
162
  */
163
  public function setTimeout($timeout)
169
 
170
  /**
171
  * Set the absolute path to the root of your application.
172
+ *
173
  * We use this to help with error grouping and to highlight "in project"
174
  * stacktrace lines.
175
  *
176
+ * @param string $projectRoot the root path for your application
177
+ *
178
  * @return $this
179
  */
180
  public function setProjectRoot($projectRoot)
185
  }
186
 
187
  /**
188
+ * Set the absolute split path.
189
+ *
190
+ * This is the path that should be stripped from the beginning of any
191
+ * stacktrace file line. This helps to normalise filenames for grouping
192
+ * and reduces the noise in stack traces.
193
+ *
194
+ * @param string $stripPath the path to strip from filenames
195
  *
 
196
  * @return $this
197
  */
198
  public function setStripPath($stripPath)
203
  }
204
 
205
  /**
206
+ * Set the a regular expression for matching filenames in stacktrace lines.
207
+ *
208
+ * @param string $projectRootRegex regex matching paths belong to your project
209
  *
 
210
  * @return $this
211
  */
212
  public function setProjectRootRegex($projectRootRegex)
217
  }
218
 
219
  /**
220
+ * Set the strings to filter out from metaData arrays before sending then.
221
+ *
222
+ * Eg. array('password', 'credit_card').
223
+ *
224
+ * @param array $filters an array of metaData filters
225
  *
 
226
  * @return $this
227
  */
228
  public function setFilters(array $filters)
233
  }
234
 
235
  /**
236
+ * Set information about the current user of your app, including id, name and email.
 
237
  *
238
+ * @param array $user an array of user information. Eg:
239
  * array(
240
  * 'name' => 'Bob Hoskins',
241
  * 'email' => 'bob@hoskins.com'
242
  * )
243
+ *
244
  * @return $this
245
  */
246
  public function setUser(array $user)
251
  }
252
 
253
  /**
 
254
  * @param $userId
255
+ *
256
  * @return $this
257
+ *
258
+ * @deprecated since version 2.1. Use setUser instead.
259
  */
260
  public function setUserId($userId)
261
  {
271
  /**
272
  * Set a context representing the current type of request, or location in code.
273
  *
274
+ * @param string $context the current context
275
+ *
276
  * @return $this
277
  */
278
  public function setContext($context)
283
  }
284
 
285
  /**
286
+ * Set the type of application executing the code.
287
+ *
288
+ * This is usually used to represent if you are running plain PHP code
289
+ * "php", via a framework, eg "laravel", or executing through delayed
290
+ * worker code, eg "resque".
291
+ *
292
+ * @param string $type the current type
293
  *
 
294
  * @return $this
295
  */
296
  public function setType($type)
301
  }
302
 
303
  /**
304
+ * Set custom metadata to send to Bugsnag with every error.
305
+ *
306
+ * You can use this to add custom tabs of data to each error on your
307
+ * Bugsnag dashboard.
308
  *
309
+ * @param array $metaData an array of arrays of custom data. Eg:
310
  * array(
311
+ * 'user' => array(
312
+ * 'name' => 'James',
313
+ * 'email' => 'james@example.com'
314
  * )
315
  * )
316
+ * @param bool $merge optionally merge the meta data
317
+ *
318
  * @return $this
319
  */
320
+ public function setMetaData(array $metaData, $merge = false)
321
  {
322
+ if ($merge) {
323
+ $this->config->metaData = array_merge_recursive((array) $this->config->metaData, $metaData);
324
+ } else {
325
+ $this->config->metaData = $metaData;
326
+ }
327
 
328
  return $this;
329
  }
330
 
331
  /**
332
+ * Set proxy configuration.
333
  *
334
+ * @param array $proxySettings an array with proxy settings. Eg:
335
  * array(
336
+ * 'host' => 'bugsnag.com',
337
  * 'port' => 42,
338
+ * 'user' => 'username'
339
+ * 'password' => 'password123'
340
+ * )
341
+ *
342
  * @return $this
343
  */
344
  public function setProxySettings(array $proxySettings)
349
  }
350
 
351
  /**
352
+ * Set custom curl options.
353
  *
354
+ * @param array $curlOptions an array with curl options. Eg:
355
  * array(
356
  * CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4
357
+ * )
358
+ *
359
  * @return $this
360
  */
361
  public function setCurlOptions(array $curlOptions)
367
 
368
  /**
369
  * Set a custom function to call before notifying Bugsnag of an error.
370
+ *
371
  * You can use this to call your own error handling functions, or to add
372
  * custom tabs of data to each error on your Bugsnag dashboard.
373
  *
374
  * // Adding meta-data example
375
  * function before_bugsnag_notify($error) {
376
  * $error->addMetaData(array(
377
+ * 'user' => array(
378
+ * 'name' => 'James'
379
  * )
380
  * ));
381
  * }
382
+ * $bugsnag->setBeforeNotifyFunction('before_bugsnag_notify');
383
+ *
384
  * @param callable $beforeNotifyFunction
385
+ *
386
  * @return $this
387
  */
388
  public function setBeforeNotifyFunction($beforeNotifyFunction)
394
 
395
  /**
396
  * Set Bugsnag's error reporting level.
397
+ *
398
  * If this is not set, we'll use your current PHP error_reporting value
399
  * from your ini file or error_reporting(...) calls.
400
  *
401
+ * @param int $errorReportingLevel the error reporting level integer
402
  * exactly as you would pass to PHP's error_reporting
403
+ *
404
  * @return $this
405
  */
406
  public function setErrorReportingLevel($errorReportingLevel)
411
  }
412
 
413
  /**
414
+ * Sets whether Bugsnag should be automatically notified of unhandled exceptions and errors.
415
+ *
416
+ * @param bool $autoNotify whether to auto notify or not
417
  *
 
418
  * @return $this
419
  */
420
  public function setAutoNotify($autoNotify)
425
  }
426
 
427
  /**
428
+ * Sets whether errors should be batched together and send at the end of each request.
429
+ *
430
+ * @param bool $batchSending whether to batch together errors
431
  *
 
432
  * @return $this
433
  */
434
  public function setBatchSending($batchSending)
439
  }
440
 
441
  /**
442
+ * Sets the notifier to report as to Bugsnag.
443
+ *
444
+ * This should only be set by other notifier libraries.
445
+ *
446
+ * @param array $notifier an array of name, version, url.
447
  *
 
448
  * @return $this
449
  */
450
  public function setNotifier($notifier)
457
  /**
458
  * Sets whether Bugsnag should send $_ENV with each error.
459
  *
460
+ * @param bool $sendEnvironment whether to send the environment
461
+ *
462
  * @return $this
463
  */
464
  public function setSendEnvironment($sendEnvironment)
471
  /**
472
  * Sets whether Bugsnag should send $_COOKIE with each error.
473
  *
474
+ * @param bool $sendCookies whether to send the environment
475
+ *
476
  * @return $this
477
  */
478
  public function setSendCookies($sendCookies)
485
  /**
486
  * Sets whether Bugsnag should send $_SESSION with each error.
487
  *
488
+ * @param bool $sendSession whether to send the environment
489
+ *
490
  * @return $this
491
  */
492
  public function setSendSession($sendSession)
497
  }
498
 
499
  /**
500
+ * Should we send a small snippet of the code that crashed.
501
+ *
502
+ * This can help you diagnose even faster from within your dashboard.
503
+ *
504
+ * @param bool $sendCode whether to send code to Bugsnag
505
  *
 
506
  * @return $this
507
  */
508
  public function setSendCode($sendCode)
513
  }
514
 
515
  /**
516
+ * Notify Bugsnag of a non-fatal/handled throwable.
517
  *
518
  * @param Throwable $throwable the throwable to notify Bugsnag about
519
+ * @param array $metaData optional metaData to send with this error
520
+ * @param string $severity optional severity of this error (fatal/error/warning/info)
521
+ *
522
+ * @return void
523
  */
524
  public function notifyException($throwable, array $metaData = null, $severity = null)
525
  {
532
  }
533
 
534
  /**
535
+ * Notify Bugsnag of a non-fatal/handled error.
536
+ *
537
+ * @param string $name the name of the error, a short (1 word) string
538
+ * @param string $message the error message
539
+ * @param array $metaData optional metaData to send with this error
540
+ * @param string $severity optional severity of this error (fatal/error/warning/info)
541
  *
542
+ * @return void
 
 
 
543
  */
544
  public function notifyError($name, $message, array $metaData = null, $severity = null)
545
  {
549
  $this->notify($error, $metaData);
550
  }
551
 
552
+ /**
553
+ * Exception handler callback.
554
+ *
555
+ * Should only be called internally by PHP's set_exception_handler.
556
+ *
557
+ * @param Throwable $throwable the exception was was thrown
558
+ *
559
+ * @return void
560
+ */
561
  public function exceptionHandler($throwable)
562
  {
563
+ if (!$this->config->autoNotify) {
564
  return;
565
  }
566
 
567
  $error = Bugsnag_Error::fromPHPThrowable($this->config, $this->diagnostics, $throwable);
568
+ $error->setSeverity('error');
569
  $this->notify($error);
570
  }
571
 
572
+ /**
573
+ * Error handler callback.
574
+ *
575
+ * Should only be called internally by PHP's set_error_handler.
576
+ *
577
+ * @param int $errno the level of the error raised
578
+ * @param string $errstr the error message
579
+ * @param string $errfile the filename that the error was raised in
580
+ * @param int $errline the line number the error was raised at
581
+ *
582
+ * @return void
583
+ */
584
  public function errorHandler($errno, $errstr, $errfile = '', $errline = 0)
585
  {
586
+ if (!$this->config->autoNotify || $this->config->shouldIgnoreErrorCode($errno)) {
587
  return;
588
  }
589
 
591
  $this->notify($error);
592
  }
593
 
594
+ /**
595
+ * Shutdown handler callback.
596
+ *
597
+ * Called when the PHP process has finished running. Should only be called
598
+ * internally by PHP's register_shutdown_function.
599
+ *
600
+ * @return void
601
+ */
602
  public function shutdownHandler()
603
  {
604
  // Get last error
607
  // Check if a fatal error caused this shutdown
608
  if (!is_null($lastError) && Bugsnag_ErrorTypes::isFatal($lastError['type']) && $this->config->autoNotify && !$this->config->shouldIgnoreErrorCode($lastError['type'])) {
609
  $error = Bugsnag_Error::fromPHPError($this->config, $this->diagnostics, $lastError['type'], $lastError['message'], $lastError['file'], $lastError['line'], true);
610
+ $error->setSeverity('error');
611
  $this->notify($error);
612
  }
613
 
619
  }
620
 
621
  /**
622
+ * Batches up errors into notifications for later sending.
623
  *
624
  * @param Bugsnag_Error $error the error to batch up
625
  * @param array $metaData optional meta data to send with the error
626
+ *
627
+ * @return void
628
  */
629
  public function notify(Bugsnag_Error $error, $metaData = array())
630
  {
645
  }
646
  }
647
 
648
+ /**
649
+ * Should we send errors immediately, or on shutdown?
650
+ *
651
+ * @return bool
652
+ */
653
  private function sendErrorsOnShutdown()
654
  {
655
  return $this->config->batchSending && Bugsnag_Request::isRequest();
lib/shippit-bugsnag/Configuration.php CHANGED
@@ -17,9 +17,9 @@ class Bugsnag_Configuration
17
  public $projectRootRegex;
18
  public $proxySettings = array();
19
  public $notifier = array(
20
- 'name' => 'Bugsnag PHP (Official)',
21
- 'version' => '2.7.0',
22
- 'url' => 'https://bugsnag.com',
23
  );
24
  public $sendEnvironment = false;
25
  public $sendCookies = true;
@@ -43,27 +43,49 @@ class Bugsnag_Configuration
43
 
44
  public $debug = false;
45
 
 
 
 
 
 
46
  public function __construct()
47
  {
48
- $this->timeout = Bugsnag_Configuration::$DEFAULT_TIMEOUT;
49
  }
50
 
 
 
 
 
 
51
  public function getNotifyEndpoint()
52
  {
53
  if (is_null($this->endpoint)) {
54
- return $this->useSSL ? Bugsnag_Configuration::$DEFAULT_ENDPOINT : Bugsnag_Configuration::$DEFAULT_NON_SSL_ENDPOINT;
55
  } elseif (preg_match('/^(http:\/\/|https:\/\/)/', $this->endpoint)) {
56
  return $this->endpoint;
57
  } else {
58
- return ($this->useSSL ? "https" : "http")."://".$this->endpoint;
59
  }
60
  }
61
 
 
 
 
 
 
62
  public function shouldNotify()
63
  {
64
  return is_null($this->notifyReleaseStages) || (is_array($this->notifyReleaseStages) && in_array($this->releaseStage, $this->notifyReleaseStages));
65
  }
66
 
 
 
 
 
 
 
 
67
  public function shouldIgnoreErrorCode($code)
68
  {
69
  if (isset($this->errorReportingLevel)) {
@@ -73,21 +95,43 @@ class Bugsnag_Configuration
73
  }
74
  }
75
 
 
 
 
 
 
 
 
76
  public function setProjectRoot($projectRoot)
77
  {
78
  $this->projectRoot = $projectRoot;
79
- $this->projectRootRegex = '/'.preg_quote($projectRoot, '/')."[\\/]?/i";
80
  if (is_null($this->stripPath)) {
81
  $this->setStripPath($projectRoot);
82
  }
83
  }
84
 
 
 
 
 
 
 
 
85
  public function setStripPath($stripPath)
86
  {
87
  $this->stripPath = $stripPath;
88
- $this->stripPathRegex = '/'.preg_quote($stripPath, '/')."[\\/]?/i";
89
  }
90
 
 
 
 
 
 
 
 
 
91
  public function get($prop, $default = null)
92
  {
93
  $configured = $this->$prop;
17
  public $projectRootRegex;
18
  public $proxySettings = array();
19
  public $notifier = array(
20
+ 'name' => 'Bugsnag PHP (Official)',
21
+ 'version' => '2.9.2',
22
+ 'url' => 'https://bugsnag.com',
23
  );
24
  public $sendEnvironment = false;
25
  public $sendCookies = true;
43
 
44
  public $debug = false;
45
 
46
+ /**
47
+ * Create a new config instance.
48
+ *
49
+ * @return void
50
+ */
51
  public function __construct()
52
  {
53
+ $this->timeout = self::$DEFAULT_TIMEOUT;
54
  }
55
 
56
+ /**
57
+ * Get the notify endpoint.
58
+ *
59
+ * @return string
60
+ */
61
  public function getNotifyEndpoint()
62
  {
63
  if (is_null($this->endpoint)) {
64
+ return $this->useSSL ? self::$DEFAULT_ENDPOINT : self::$DEFAULT_NON_SSL_ENDPOINT;
65
  } elseif (preg_match('/^(http:\/\/|https:\/\/)/', $this->endpoint)) {
66
  return $this->endpoint;
67
  } else {
68
+ return ($this->useSSL ? 'https' : 'http').'://'.$this->endpoint;
69
  }
70
  }
71
 
72
+ /**
73
+ * Should we notify?
74
+ *
75
+ * @return bool
76
+ */
77
  public function shouldNotify()
78
  {
79
  return is_null($this->notifyReleaseStages) || (is_array($this->notifyReleaseStages) && in_array($this->releaseStage, $this->notifyReleaseStages));
80
  }
81
 
82
+ /**
83
+ * Should we ignore the given error code?
84
+ *
85
+ * @param int $code the error code
86
+ *
87
+ * @return bool
88
+ */
89
  public function shouldIgnoreErrorCode($code)
90
  {
91
  if (isset($this->errorReportingLevel)) {
95
  }
96
  }
97
 
98
+ /**
99
+ * Set the project root.
100
+ *
101
+ * @param string $projectRoot the project root path
102
+ *
103
+ * @return void
104
+ */
105
  public function setProjectRoot($projectRoot)
106
  {
107
  $this->projectRoot = $projectRoot;
108
+ $this->projectRootRegex = '/'.preg_quote($projectRoot, '/').'[\\/]?/i';
109
  if (is_null($this->stripPath)) {
110
  $this->setStripPath($projectRoot);
111
  }
112
  }
113
 
114
+ /**
115
+ * Set the strip path.
116
+ *
117
+ * @param string $stripPath the absolute strip path
118
+ *
119
+ * @return void
120
+ */
121
  public function setStripPath($stripPath)
122
  {
123
  $this->stripPath = $stripPath;
124
+ $this->stripPathRegex = '/'.preg_quote($stripPath, '/').'[\\/]?/i';
125
  }
126
 
127
+ /**
128
+ * Get the given configuration.
129
+ *
130
+ * @param string $prop the property to get
131
+ * @param mixed $default the value to fallback to
132
+ *
133
+ * @return mixed
134
+ */
135
  public function get($prop, $default = null)
136
  {
137
  $configured = $this->$prop;
lib/shippit-bugsnag/Diagnostics.php CHANGED
@@ -2,13 +2,30 @@
2
 
3
  class Bugsnag_Diagnostics
4
  {
 
 
 
 
 
5
  private $config;
6
 
 
 
 
 
 
 
 
7
  public function __construct(Bugsnag_Configuration $config)
8
  {
9
  $this->config = $config;
10
  }
11
 
 
 
 
 
 
12
  public function getAppData()
13
  {
14
  $appData = array();
@@ -28,6 +45,11 @@ class Bugsnag_Diagnostics
28
  return $appData;
29
  }
30
 
 
 
 
 
 
31
  public function getDeviceData()
32
  {
33
  return array(
@@ -35,11 +57,21 @@ class Bugsnag_Diagnostics
35
  );
36
  }
37
 
 
 
 
 
 
38
  public function getContext()
39
  {
40
  return $this->config->get('context', Bugsnag_Request::getContext());
41
  }
42
 
 
 
 
 
 
43
  public function getUser()
44
  {
45
  $defaultUser = array();
2
 
3
  class Bugsnag_Diagnostics
4
  {
5
+ /**
6
+ * The config instance.
7
+ *
8
+ * @var Bugsnag_Configuration
9
+ */
10
  private $config;
11
 
12
+ /**
13
+ * Create a new diagnostics instance.
14
+ *
15
+ * @param Bugsnag_Configuration $config the configuration instance
16
+ *
17
+ * @return void
18
+ */
19
  public function __construct(Bugsnag_Configuration $config)
20
  {
21
  $this->config = $config;
22
  }
23
 
24
+ /**
25
+ * Get the application information.
26
+ *
27
+ * @return array
28
+ */
29
  public function getAppData()
30
  {
31
  $appData = array();
45
  return $appData;
46
  }
47
 
48
+ /**
49
+ * Get the device information.
50
+ *
51
+ * @return array
52
+ */
53
  public function getDeviceData()
54
  {
55
  return array(
57
  );
58
  }
59
 
60
+ /**
61
+ * Get the error context.
62
+ *
63
+ * @return array
64
+ */
65
  public function getContext()
66
  {
67
  return $this->config->get('context', Bugsnag_Request::getContext());
68
  }
69
 
70
+ /**
71
+ * Get the current user.
72
+ *
73
+ * @return array
74
+ */
75
  public function getUser()
76
  {
77
  $defaultUser = array();
lib/shippit-bugsnag/Error.php CHANGED
@@ -9,38 +9,70 @@ class Bugsnag_Error
9
  );
10
 
11
  public $name;
12
- public $payloadVersion = "2";
13
  public $message;
14
- public $severity = "warning";
15
  /** @var Bugsnag_Stacktrace */
16
  public $stacktrace;
17
  public $metaData = array();
 
18
  public $config;
19
  public $diagnostics;
20
  /** @var Bugsnag_Error|null */
21
  public $previous;
22
  public $groupingHash;
23
 
24
- // Static error creation methods, to ensure that Error object is always complete
 
 
 
 
 
 
 
 
 
 
 
 
25
  public static function fromPHPError(Bugsnag_Configuration $config, Bugsnag_Diagnostics $diagnostics, $code, $message, $file, $line, $fatal = false)
26
  {
27
- $error = new Bugsnag_Error($config, $diagnostics);
28
  $error->setPHPError($code, $message, $file, $line, $fatal);
29
 
30
  return $error;
31
  }
32
 
 
 
 
 
 
 
 
 
 
33
  public static function fromPHPThrowable(Bugsnag_Configuration $config, Bugsnag_Diagnostics $diagnostics, $throwable)
34
  {
35
- $error = new Bugsnag_Error($config, $diagnostics);
36
- $error->setPHPException($throwable);
37
 
38
  return $error;
39
  }
40
 
 
 
 
 
 
 
 
 
 
 
41
  public static function fromNamedError(Bugsnag_Configuration $config, Bugsnag_Diagnostics $diagnostics, $name, $message = null)
42
  {
43
- $error = new Bugsnag_Error($config, $diagnostics);
44
  $error->setName($name)
45
  ->setMessage($message)
46
  ->setStacktrace(Bugsnag_Stacktrace::generate($config));
@@ -48,27 +80,71 @@ class Bugsnag_Error
48
  return $error;
49
  }
50
 
51
- // Private constructor (for use only by the static methods above)
 
 
 
 
 
 
 
 
 
52
  private function __construct(Bugsnag_Configuration $config, Bugsnag_Diagnostics $diagnostics)
53
  {
54
  $this->config = $config;
55
  $this->diagnostics = $diagnostics;
56
  }
57
 
 
 
 
 
 
 
 
 
 
58
  public function setName($name)
59
  {
60
- $this->name = $name;
 
 
 
 
61
 
62
  return $this;
63
  }
64
 
 
 
 
 
 
 
 
 
 
65
  public function setMessage($message)
66
  {
67
- $this->message = $message;
 
 
 
 
 
 
68
 
69
  return $this;
70
  }
71
 
 
 
 
 
 
 
 
72
  public function setGroupingHash($groupingHash)
73
  {
74
  $this->groupingHash = $groupingHash;
@@ -76,6 +152,13 @@ class Bugsnag_Error
76
  return $this;
77
  }
78
 
 
 
 
 
 
 
 
79
  public function setStacktrace(Bugsnag_Stacktrace $stacktrace)
80
  {
81
  $this->stacktrace = $stacktrace;
@@ -83,10 +166,17 @@ class Bugsnag_Error
83
  return $this;
84
  }
85
 
 
 
 
 
 
 
 
86
  public function setSeverity($severity)
87
  {
88
  if (!is_null($severity)) {
89
- if (in_array($severity, Bugsnag_Error::$VALID_SEVERITIES)) {
90
  $this->severity = $severity;
91
  } else {
92
  error_log('Bugsnag Warning: Tried to set error severity to '.$severity.' which is not allowed.');
@@ -96,17 +186,40 @@ class Bugsnag_Error
96
  return $this;
97
  }
98
 
 
 
 
 
 
 
 
 
 
99
  public function setPHPException($exception)
 
 
 
 
 
 
 
 
 
 
 
 
100
  {
101
  if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
102
- if (!$exception instanceof \Throwable) {
103
- error_log('Bugsnag Warning: Exception must implement interface \Throwable.');
104
- return;
 
105
  }
106
  } else {
107
- if (!$exception instanceof \Exception) {
108
- error_log('Bugsnag Warning: Exception must be instance of \Exception.');
109
- return;
 
110
  }
111
  }
112
 
@@ -121,6 +234,17 @@ class Bugsnag_Error
121
  return $this;
122
  }
123
 
 
 
 
 
 
 
 
 
 
 
 
124
  public function setPHPError($code, $message, $file, $line, $fatal = false)
125
  {
126
  if ($fatal) {
@@ -143,6 +267,13 @@ class Bugsnag_Error
143
  return $this;
144
  }
145
 
 
 
 
 
 
 
 
146
  public function setMetaData($metaData)
147
  {
148
  if (is_array($metaData)) {
@@ -152,21 +283,47 @@ class Bugsnag_Error
152
  return $this;
153
  }
154
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  public function setPrevious($exception)
156
  {
157
  if ($exception) {
158
- $this->previous = Bugsnag_Error::fromPHPThrowable($this->config, $this->diagnostics, $exception);
159
  }
160
 
161
  return $this;
162
  }
163
 
 
 
 
 
 
164
  public function toArray()
165
  {
166
  $errorArray = array(
167
  'app' => $this->diagnostics->getAppData(),
168
  'device' => $this->diagnostics->getDeviceData(),
169
- 'user' => $this->diagnostics->getUser(),
170
  'context' => $this->diagnostics->getContext(),
171
  'payloadVersion' => $this->payloadVersion,
172
  'severity' => $this->severity,
@@ -175,12 +332,17 @@ class Bugsnag_Error
175
  );
176
 
177
  if (isset($this->groupingHash)) {
178
- $errorArray['groupingHash'] = $this->groupingHash;
179
  }
180
 
181
  return $errorArray;
182
  }
183
 
 
 
 
 
 
184
  public function exceptionArray()
185
  {
186
  if ($this->previous) {
@@ -198,10 +360,18 @@ class Bugsnag_Error
198
  return $this->cleanupObj($exceptionArray, false);
199
  }
200
 
 
 
 
 
 
 
 
 
201
  private function cleanupObj($obj, $isMetaData)
202
  {
203
  if (is_null($obj)) {
204
- return null;
205
  }
206
 
207
  if (is_array($obj)) {
9
  );
10
 
11
  public $name;
12
+ public $payloadVersion = '2';
13
  public $message;
14
+ public $severity = 'warning';
15
  /** @var Bugsnag_Stacktrace */
16
  public $stacktrace;
17
  public $metaData = array();
18
+ public $user;
19
  public $config;
20
  public $diagnostics;
21
  /** @var Bugsnag_Error|null */
22
  public $previous;
23
  public $groupingHash;
24
 
25
+ /**
26
+ * Create a new error from a PHP error.
27
+ *
28
+ * @param Bugsnag_Configuration $config the config instance
29
+ * @param Bugsnag_Diagnostics $diagnostics the diagnostics instance
30
+ * @param int $code the error code
31
+ * @param string $message the error message
32
+ * @param string $file the error file
33
+ * @param int $line the error line
34
+ * @param bool $fatal if the error was fatal
35
+ *
36
+ * @return self
37
+ */
38
  public static function fromPHPError(Bugsnag_Configuration $config, Bugsnag_Diagnostics $diagnostics, $code, $message, $file, $line, $fatal = false)
39
  {
40
+ $error = new self($config, $diagnostics);
41
  $error->setPHPError($code, $message, $file, $line, $fatal);
42
 
43
  return $error;
44
  }
45
 
46
+ /**
47
+ * Create a new error from a PHP throwable.
48
+ *
49
+ * @param Bugsnag_Configuration $config the config instance
50
+ * @param Bugsnag_Diagnostics $diagnostics the diagnostics instance
51
+ * @param Throwable $throwable te he throwable instance
52
+ *
53
+ * @return self
54
+ */
55
  public static function fromPHPThrowable(Bugsnag_Configuration $config, Bugsnag_Diagnostics $diagnostics, $throwable)
56
  {
57
+ $error = new self($config, $diagnostics);
58
+ $error->setPHPThrowable($throwable);
59
 
60
  return $error;
61
  }
62
 
63
+ /**
64
+ * Create a new error from a named error.
65
+ *
66
+ * @param Bugsnag_Configuration $config the config instance
67
+ * @param Bugsnag_Diagnostics $diagnostics the diagnostics instance
68
+ * @param string $name the error name
69
+ * @param string|null $message the error message
70
+ *
71
+ * @return self
72
+ */
73
  public static function fromNamedError(Bugsnag_Configuration $config, Bugsnag_Diagnostics $diagnostics, $name, $message = null)
74
  {
75
+ $error = new self($config, $diagnostics);
76
  $error->setName($name)
77
  ->setMessage($message)
78
  ->setStacktrace(Bugsnag_Stacktrace::generate($config));
80
  return $error;
81
  }
82
 
83
+ /**
84
+ * Create a new error instance.
85
+ *
86
+ * This is only for for use only by the static methods above.
87
+ *
88
+ * @param Bugsnag_Configuration $config the config instance
89
+ * @param Bugsnag_Diagnostics $diagnostics the diagnostics instance
90
+ *
91
+ * @return void
92
+ */
93
  private function __construct(Bugsnag_Configuration $config, Bugsnag_Diagnostics $diagnostics)
94
  {
95
  $this->config = $config;
96
  $this->diagnostics = $diagnostics;
97
  }
98
 
99
+ /**
100
+ * Set the error name.
101
+ *
102
+ * @param string $name the error name
103
+ *
104
+ * @throws InvalidArgumentException
105
+ *
106
+ * @return $this
107
+ */
108
  public function setName($name)
109
  {
110
+ if (is_scalar($name) || method_exists($name, '__toString')) {
111
+ $this->name = (string) $name;
112
+ } else {
113
+ throw new InvalidArgumentException('Name must be a string.');
114
+ }
115
 
116
  return $this;
117
  }
118
 
119
+ /**
120
+ * Set the error message.
121
+ *
122
+ * @param string|null $message the error message
123
+ *
124
+ * @throws InvalidArgumentException
125
+ *
126
+ * @return $this
127
+ */
128
  public function setMessage($message)
129
  {
130
+ if ($message === null) {
131
+ $this->message = null;
132
+ } elseif (is_scalar($message) || method_exists($message, '__toString')) {
133
+ $this->message = (string) $message;
134
+ } else {
135
+ throw new InvalidArgumentException('Message must be a string.');
136
+ }
137
 
138
  return $this;
139
  }
140
 
141
+ /**
142
+ * Set the grouping hash.
143
+ *
144
+ * @param string $groupingHash the grouping hash
145
+ *
146
+ * @return $this
147
+ */
148
  public function setGroupingHash($groupingHash)
149
  {
150
  $this->groupingHash = $groupingHash;
152
  return $this;
153
  }
154
 
155
+ /**
156
+ * Set the bugsnag stacktrace.
157
+ *
158
+ * @param Bugsnag_Stacktrace $stacktrace the stacktrace instance
159
+ *
160
+ * @return $this
161
+ */
162
  public function setStacktrace(Bugsnag_Stacktrace $stacktrace)
163
  {
164
  $this->stacktrace = $stacktrace;
166
  return $this;
167
  }
168
 
169
+ /**
170
+ * Set the error severity.
171
+ *
172
+ * @param int|null $severity the error severity
173
+ *
174
+ * @return $this
175
+ */
176
  public function setSeverity($severity)
177
  {
178
  if (!is_null($severity)) {
179
+ if (in_array($severity, self::$VALID_SEVERITIES)) {
180
  $this->severity = $severity;
181
  } else {
182
  error_log('Bugsnag Warning: Tried to set error severity to '.$severity.' which is not allowed.');
186
  return $this;
187
  }
188
 
189
+ /**
190
+ * Set the PHP exception.
191
+ *
192
+ * @param Throwable $exception the throwable instance
193
+ *
194
+ * @return $this
195
+ *
196
+ * @deprecated since version 2.9. Use setPHPThrowable instead.
197
+ */
198
  public function setPHPException($exception)
199
+ {
200
+ return $this->setPHPThrowable($exception);
201
+ }
202
+
203
+ /**
204
+ * Set the PHP throwable.
205
+ *
206
+ * @param Throwable $exception the throwable instance
207
+ *
208
+ * @return $this
209
+ */
210
+ public function setPHPThrowable($exception)
211
  {
212
  if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
213
+ if (!$exception instanceof Throwable) {
214
+ error_log('Bugsnag Warning: The exception must implement Throwable.');
215
+
216
+ return $this;
217
  }
218
  } else {
219
+ if (!$exception instanceof Exception) {
220
+ error_log('Bugsnag Warning: The exception must be an Exception.');
221
+
222
+ return $this;
223
  }
224
  }
225
 
234
  return $this;
235
  }
236
 
237
+ /**
238
+ * Set the PHP error.
239
+ *
240
+ * @param int $code the error code
241
+ * @param string $message the error message
242
+ * @param string $file the error file
243
+ * @param int $line the error line
244
+ * @param bool $fatal if the error was fatal
245
+ *
246
+ * @return $this
247
+ */
248
  public function setPHPError($code, $message, $file, $line, $fatal = false)
249
  {
250
  if ($fatal) {
267
  return $this;
268
  }
269
 
270
+ /**
271
+ * Set the error meta data.
272
+ *
273
+ * @param array $metaData the error meta data
274
+ *
275
+ * @return $this
276
+ */
277
  public function setMetaData($metaData)
278
  {
279
  if (is_array($metaData)) {
283
  return $this;
284
  }
285
 
286
+ /**
287
+ * Set the current user.
288
+ *
289
+ * @param array|null $user the current user
290
+ *
291
+ * @return $this
292
+ */
293
+ public function setUser($user)
294
+ {
295
+ $this->user = $user;
296
+
297
+ return $this;
298
+ }
299
+
300
+ /**
301
+ * Set the previous throwable.
302
+ *
303
+ * @param Throwable $exception the previous throwable
304
+ *
305
+ * @return $this
306
+ */
307
  public function setPrevious($exception)
308
  {
309
  if ($exception) {
310
+ $this->previous = self::fromPHPThrowable($this->config, $this->diagnostics, $exception);
311
  }
312
 
313
  return $this;
314
  }
315
 
316
+ /**
317
+ * Get the array representation.
318
+ *
319
+ * @return array
320
+ */
321
  public function toArray()
322
  {
323
  $errorArray = array(
324
  'app' => $this->diagnostics->getAppData(),
325
  'device' => $this->diagnostics->getDeviceData(),
326
+ 'user' => is_null($this->user) ? $this->diagnostics->getUser() : $this->user,
327
  'context' => $this->diagnostics->getContext(),
328
  'payloadVersion' => $this->payloadVersion,
329
  'severity' => $this->severity,
332
  );
333
 
334
  if (isset($this->groupingHash)) {
335
+ $errorArray['groupingHash'] = $this->groupingHash;
336
  }
337
 
338
  return $errorArray;
339
  }
340
 
341
+ /**
342
+ * Get the exception array.
343
+ *
344
+ * @return array
345
+ */
346
  public function exceptionArray()
347
  {
348
  if ($this->previous) {
360
  return $this->cleanupObj($exceptionArray, false);
361
  }
362
 
363
+ /**
364
+ * Cleanup the given object.
365
+ *
366
+ * @param mixed $obj the data to cleanup
367
+ * @param bool $isMetaData if it is meta data
368
+ *
369
+ * @return array|null
370
+ */
371
  private function cleanupObj($obj, $isMetaData)
372
  {
373
  if (is_null($obj)) {
374
+ return;
375
  }
376
 
377
  if (is_array($obj)) {
lib/shippit-bugsnag/ErrorTypes.php CHANGED
@@ -81,33 +81,61 @@ class Bugsnag_ErrorTypes
81
  ),
82
  );
83
 
 
 
 
 
 
 
 
84
  public static function isFatal($code)
85
  {
86
  return self::getSeverity($code) == 'error';
87
  }
88
 
 
 
 
 
 
 
 
89
  public static function getName($code)
90
  {
91
  if (array_key_exists($code, self::$ERROR_TYPES)) {
92
  return self::$ERROR_TYPES[$code]['name'];
93
  } else {
94
- return "Unknown";
95
  }
96
  }
97
 
 
 
 
 
 
 
 
98
  public static function getSeverity($code)
99
  {
100
  if (array_key_exists($code, self::$ERROR_TYPES)) {
101
  return self::$ERROR_TYPES[$code]['severity'];
102
  } else {
103
- return "error";
104
  }
105
  }
106
 
 
 
 
 
 
 
 
107
  public static function getLevelsForSeverity($severity)
108
  {
109
  $levels = 0;
110
- foreach (Bugsnag_ErrorTypes::$ERROR_TYPES as $level => $info) {
111
  if ($info['severity'] == $severity) {
112
  $levels |= $level;
113
  }
81
  ),
82
  );
83
 
84
+ /**
85
+ * Is the given error code fatal?
86
+ *
87
+ * @param int $code the error code
88
+ *
89
+ * @return bool
90
+ */
91
  public static function isFatal($code)
92
  {
93
  return self::getSeverity($code) == 'error';
94
  }
95
 
96
+ /**
97
+ * Get the name of the given error code.
98
+ *
99
+ * @param int $code the error code
100
+ *
101
+ * @return string
102
+ */
103
  public static function getName($code)
104
  {
105
  if (array_key_exists($code, self::$ERROR_TYPES)) {
106
  return self::$ERROR_TYPES[$code]['name'];
107
  } else {
108
+ return 'Unknown';
109
  }
110
  }
111
 
112
+ /**
113
+ * Get the severity of the given error code.
114
+ *
115
+ * @param int $code the error code
116
+ *
117
+ * @return string
118
+ */
119
  public static function getSeverity($code)
120
  {
121
  if (array_key_exists($code, self::$ERROR_TYPES)) {
122
  return self::$ERROR_TYPES[$code]['severity'];
123
  } else {
124
+ return 'error';
125
  }
126
  }
127
 
128
+ /**
129
+ * Get the the levels for the given severity.
130
+ *
131
+ * @param string $severity the given severity
132
+ *
133
+ * @return int
134
+ */
135
  public static function getLevelsForSeverity($severity)
136
  {
137
  $levels = 0;
138
+ foreach (self::$ERROR_TYPES as $level => $info) {
139
  if ($info['severity'] == $severity) {
140
  $levels |= $level;
141
  }
lib/shippit-bugsnag/Notification.php CHANGED
@@ -4,15 +4,40 @@ class Bugsnag_Notification
4
  {
5
  private static $CONTENT_TYPE_HEADER = 'Content-type: application/json';
6
 
 
 
 
 
 
7
  private $config;
8
- /** @var Bugsnag_Error[] */
 
 
 
 
 
9
  private $errorQueue = array();
10
 
 
 
 
 
 
 
 
11
  public function __construct(Bugsnag_Configuration $config)
12
  {
13
  $this->config = $config;
14
  }
15
 
 
 
 
 
 
 
 
 
16
  public function addError(Bugsnag_Error $error, $passedMetaData = array())
17
  {
18
  // Check if this error should be sent to Bugsnag
@@ -40,7 +65,7 @@ class Bugsnag_Notification
40
 
41
  // Add environment meta-data to error
42
  if ($this->config->sendEnvironment && !empty($_ENV)) {
43
- $error->setMetaData(array("Environment" => $_ENV));
44
  }
45
 
46
  // Add user-specified meta-data to error
@@ -61,6 +86,11 @@ class Bugsnag_Notification
61
  }
62
  }
63
 
 
 
 
 
 
64
  public function toArray()
65
  {
66
  $events = array();
@@ -79,32 +109,117 @@ class Bugsnag_Notification
79
  );
80
  }
81
 
 
 
 
 
 
82
  public function deliver()
83
  {
84
- if (!empty($this->errorQueue)) {
85
- // Post the request to bugsnag
86
- $this->postJSON($this->config->getNotifyEndpoint(), $this->toArray());
87
-
88
- // Clear the error queue
89
- $this->errorQueue = array();
90
  }
 
 
 
 
 
 
91
  }
92
 
 
 
 
 
 
 
 
 
93
  public function postJSON($url, $data)
94
  {
95
- $body = json_encode($data);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
  // Prefer cURL if it is installed, otherwise fall back to fopen()
98
  // cURL supports both timeouts and proxies
99
- if (function_exists('curl_version')) {
100
- $this->postWithCurl($url, $body);
101
- } elseif (ini_get('allow_url_fopen')) {
102
- $this->postWithFopen($url, $body);
103
- } else {
104
- error_log('Bugsnag Warning: Couldn\'t notify (neither cURL or allow_url_fopen are available on your PHP installation)');
 
 
 
 
 
105
  }
106
  }
107
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  private function postWithCurl($url, $body)
109
  {
110
  $http = curl_init($url);
@@ -113,7 +228,7 @@ class Bugsnag_Notification
113
  curl_setopt($http, CURLOPT_HEADER, false);
114
  curl_setopt($http, CURLOPT_RETURNTRANSFER, true);
115
  curl_setopt($http, CURLOPT_POST, true);
116
- curl_setopt($http, CURLOPT_HTTPHEADER, array(Bugsnag_Notification::$CONTENT_TYPE_HEADER));
117
  curl_setopt($http, CURLOPT_POSTFIELDS, $body);
118
  curl_setopt($http, CURLOPT_CONNECTTIMEOUT, $this->config->timeout);
119
  curl_setopt($http, CURLOPT_SSL_VERIFYPEER, false);
@@ -125,7 +240,7 @@ class Bugsnag_Notification
125
  }
126
 
127
  if (!empty($this->config->curlOptions)) {
128
- foreach ($this->config->curlOptions as $option => $value) {
129
  curl_setopt($http, $option, $value);
130
  }
131
  }
@@ -151,7 +266,7 @@ class Bugsnag_Notification
151
  if ($statusCode > 200) {
152
  error_log('Bugsnag Warning: Couldn\'t notify ('.$responseBody.')');
153
 
154
- if($this->config->debug) {
155
  error_log('Bugsnag Debug: Attempted to post to URL - "'.$url.'"');
156
  error_log('Bugsnag Debug: Attempted to post payload - "'.$body.'"');
157
  }
@@ -164,6 +279,14 @@ class Bugsnag_Notification
164
  curl_close($http);
165
  }
166
 
 
 
 
 
 
 
 
 
167
  private function postWithFopen($url, $body)
168
  {
169
  // Warn about lack of proxy support if we are using fopen()
@@ -175,9 +298,9 @@ class Bugsnag_Notification
175
  $context = stream_context_create(array(
176
  'http' => array(
177
  'method' => 'POST',
178
- 'header' => Bugsnag_Notification::$CONTENT_TYPE_HEADER.'\r\n',
179
  'content' => $body,
180
- 'timeout' => $this->config->timeout
181
  ),
182
  'ssl' => array(
183
  'verify_peer' => false,
4
  {
5
  private static $CONTENT_TYPE_HEADER = 'Content-type: application/json';
6
 
7
+ /**
8
+ * The config instance.
9
+ *
10
+ * @var Bugsnag_Configuration
11
+ */
12
  private $config;
13
+
14
+ /**
15
+ * The queue of errors to send to Bugsnag.
16
+ *
17
+ * @var Bugsnag_Error[]
18
+ */
19
  private $errorQueue = array();
20
 
21
+ /**
22
+ * Create a new notification instance.
23
+ *
24
+ * @param Bugsnag_Configuration $config the configuration instance
25
+ *
26
+ * @return void
27
+ */
28
  public function __construct(Bugsnag_Configuration $config)
29
  {
30
  $this->config = $config;
31
  }
32
 
33
+ /**
34
+ * Add an error to the queue.
35
+ *
36
+ * @param Bugsnag_Error $config the bugsnag error instance
37
+ * @param array $passedMetaData the associated meta data
38
+ *
39
+ * @return bool
40
+ */
41
  public function addError(Bugsnag_Error $error, $passedMetaData = array())
42
  {
43
  // Check if this error should be sent to Bugsnag
65
 
66
  // Add environment meta-data to error
67
  if ($this->config->sendEnvironment && !empty($_ENV)) {
68
+ $error->setMetaData(array('Environment' => $_ENV));
69
  }
70
 
71
  // Add user-specified meta-data to error
86
  }
87
  }
88
 
89
+ /**
90
+ * Get the array representation.
91
+ *
92
+ * @return array
93
+ */
94
  public function toArray()
95
  {
96
  $events = array();
109
  );
110
  }
111
 
112
+ /**
113
+ * Deliver everything on the queue to Bugsnag.
114
+ *
115
+ * @return void
116
+ */
117
  public function deliver()
118
  {
119
+ if (empty($this->errorQueue)) {
120
+ return;
 
 
 
 
121
  }
122
+
123
+ // Post the request to bugsnag
124
+ $this->postJSON($this->config->getNotifyEndpoint(), $this->toArray());
125
+
126
+ // Clear the error queue
127
+ $this->errorQueue = array();
128
  }
129
 
130
+ /**
131
+ * Post the given data to Bugsnag in json form.
132
+ *
133
+ * @param string $url the url to hit
134
+ * @param array $data the data send
135
+ *
136
+ * @return void
137
+ */
138
  public function postJSON($url, $data)
139
  {
140
+ // Try to send the whole lot, or without the meta data for the first
141
+ // event. If failed, try to send the first event, and then the rest of
142
+ // them, revursively. Decrease by a constant and concquer if you like.
143
+ // Note that the base case is satisfied as soon as the payload is small
144
+ // enought to send, or when it's simply discarded.
145
+ try {
146
+ $body = $this->encode($data);
147
+ } catch (RuntimeException $e) {
148
+ if (count($data['events']) > 1) {
149
+ $event = array_shift($data['events']);
150
+ $this->postJSON($url, array_merge($data, array('events' => array($event))));
151
+ $this->postJSON($url, $data);
152
+ } else {
153
+ error_log('Bugsnag Warning: '.$e->getMessage());
154
+ }
155
+
156
+ return;
157
+ }
158
 
159
  // Prefer cURL if it is installed, otherwise fall back to fopen()
160
  // cURL supports both timeouts and proxies
161
+
162
+ try {
163
+ if (function_exists('curl_version')) {
164
+ $this->postWithCurl($url, $body);
165
+ } elseif (ini_get('allow_url_fopen')) {
166
+ $this->postWithFopen($url, $body);
167
+ } else {
168
+ error_log('Bugsnag Warning: Couldn\'t notify (neither cURL or allow_url_fopen are available on your PHP installation)');
169
+ }
170
+ } catch (Exception $e) {
171
+ error_log('Bugsnag Warning: Couldn\'t notify. '.$e->getMessage());
172
  }
173
  }
174
 
175
+ /**
176
+ * Json encode the given data.
177
+ *
178
+ * We will also strip out the meta data if it's too large.
179
+ *
180
+ * @param array $data the data to encode
181
+ *
182
+ * @throws RuntimeException
183
+ *
184
+ * @return string
185
+ */
186
+ private function encode(array $data)
187
+ {
188
+ $body = json_encode($data);
189
+
190
+ if ($this->length($body) > 500000) {
191
+ unset($data['events'][0]['metaData']);
192
+ }
193
+
194
+ $body = json_encode($data);
195
+
196
+ if ($this->length($body) > 500000) {
197
+ throw new RuntimeException('Payload too large');
198
+ }
199
+
200
+ return $body;
201
+ }
202
+
203
+ /**
204
+ * Get the length of the given string in bytes.
205
+ *
206
+ * @param string $str the string to get the length of
207
+ *
208
+ * @return int
209
+ */
210
+ private function length($str)
211
+ {
212
+ return function_exists('mb_strlen') ? mb_strlen($str, '8bit') : strlen($str);
213
+ }
214
+
215
+ /**
216
+ * Post the given info to Bugsnag using cURL.
217
+ *
218
+ * @param string $url the url to hit
219
+ * @param string $body the request body
220
+ *
221
+ * @return void
222
+ */
223
  private function postWithCurl($url, $body)
224
  {
225
  $http = curl_init($url);
228
  curl_setopt($http, CURLOPT_HEADER, false);
229
  curl_setopt($http, CURLOPT_RETURNTRANSFER, true);
230
  curl_setopt($http, CURLOPT_POST, true);
231
+ curl_setopt($http, CURLOPT_HTTPHEADER, array(self::$CONTENT_TYPE_HEADER, 'Expect:'));
232
  curl_setopt($http, CURLOPT_POSTFIELDS, $body);
233
  curl_setopt($http, CURLOPT_CONNECTTIMEOUT, $this->config->timeout);
234
  curl_setopt($http, CURLOPT_SSL_VERIFYPEER, false);
240
  }
241
 
242
  if (!empty($this->config->curlOptions)) {
243
+ foreach ($this->config->curlOptions as $option => $value) {
244
  curl_setopt($http, $option, $value);
245
  }
246
  }
266
  if ($statusCode > 200) {
267
  error_log('Bugsnag Warning: Couldn\'t notify ('.$responseBody.')');
268
 
269
+ if ($this->config->debug) {
270
  error_log('Bugsnag Debug: Attempted to post to URL - "'.$url.'"');
271
  error_log('Bugsnag Debug: Attempted to post payload - "'.$body.'"');
272
  }
279
  curl_close($http);
280
  }
281
 
282
+ /**
283
+ * Post the given info to Bugsnag using fopen.
284
+ *
285
+ * @param string $url the url to hit
286
+ * @param string $body the request body
287
+ *
288
+ * @return void
289
+ */
290
  private function postWithFopen($url, $body)
291
  {
292
  // Warn about lack of proxy support if we are using fopen()
298
  $context = stream_context_create(array(
299
  'http' => array(
300
  'method' => 'POST',
301
+ 'header' => self::$CONTENT_TYPE_HEADER.'\r\n',
302
  'content' => $body,
303
+ 'timeout' => $this->config->timeout,
304
  ),
305
  'ssl' => array(
306
  'verify_peer' => false,
lib/shippit-bugsnag/Request.php CHANGED
@@ -2,13 +2,29 @@
2
 
3
  class Bugsnag_Request
4
  {
 
 
 
 
 
5
  public static function isRequest()
6
  {
7
  return isset($_SERVER['REQUEST_METHOD']);
8
  }
9
 
 
 
 
 
 
10
  public static function getRequestMetaData()
11
  {
 
 
 
 
 
 
12
  $requestData = array();
13
 
14
  $methodsWithPayload = array('PUT');
@@ -23,25 +39,23 @@ class Bugsnag_Request
23
  if (!empty($_POST)) {
24
  $requestData['request']['params'] = $_POST;
25
  } else {
 
26
 
27
  if (isset($_SERVER['CONTENT_TYPE']) && stripos($_SERVER['CONTENT_TYPE'], 'application/json') === 0) {
28
- $requestData['request']['params'] = json_decode(file_get_contents('php://input'));
29
  }
30
 
31
  if (isset($_SERVER['REQUEST_METHOD']) && in_array(strtoupper($_SERVER['REQUEST_METHOD']), $methodsWithPayload)) {
32
- parse_str(file_get_contents('php://input'),$params);
33
- if(isset($requestData['request']['params']))
34
- {
35
- $requestData['request']['params'] = array_merge($requestData['request']['params'],$params);
36
- }
37
- else
38
- {
39
  $requestData['request']['params'] = $params;
40
  }
41
  }
42
  }
43
 
44
- $requestData['request']['ip'] = self::getRequestIp();
45
  if (isset($_SERVER['HTTP_USER_AGENT'])) {
46
  $requestData['request']['userAgent'] = $_SERVER['HTTP_USER_AGENT'];
47
  }
@@ -54,42 +68,61 @@ class Bugsnag_Request
54
  return $requestData;
55
  }
56
 
 
 
 
 
 
57
  public static function getContext()
58
  {
59
- if (self::isRequest() && isset($_SERVER['REQUEST_METHOD']) && isset($_SERVER["REQUEST_URI"])) {
60
- return $_SERVER['REQUEST_METHOD'].' '.strtok($_SERVER["REQUEST_URI"], '?');
61
- } else {
62
- return null;
63
  }
64
  }
65
 
 
 
 
 
 
66
  public static function getUserId()
67
  {
68
  if (self::isRequest()) {
69
  return self::getRequestIp();
70
- } else {
71
- return null;
72
  }
73
  }
74
 
 
 
 
 
 
75
  public static function getCurrentUrl()
76
  {
77
  $schema = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (!empty($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443)) ? 'https://' : 'http://';
78
 
79
- return $schema.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
 
 
80
  }
81
 
 
 
 
 
 
82
  public static function getRequestIp()
83
  {
84
  return isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
85
  }
86
 
 
 
 
 
 
87
  public static function getRequestHeaders()
88
  {
89
- if (function_exists('getallheaders')) {
90
- return getallheaders();
91
- }
92
-
93
  $headers = array();
94
 
95
  foreach ($_SERVER as $name => $value) {
2
 
3
  class Bugsnag_Request
4
  {
5
+ /**
6
+ * Are we currently processing a request?
7
+ *
8
+ * @return bool
9
+ */
10
  public static function isRequest()
11
  {
12
  return isset($_SERVER['REQUEST_METHOD']);
13
  }
14
 
15
+ /**
16
+ * Get the request formatted as meta data.
17
+ *
18
+ * @return array
19
+ */
20
  public static function getRequestMetaData()
21
  {
22
+ static $requestData;
23
+
24
+ if ($requestData !== null) {
25
+ return $requestData;
26
+ }
27
+
28
  $requestData = array();
29
 
30
  $methodsWithPayload = array('PUT');
39
  if (!empty($_POST)) {
40
  $requestData['request']['params'] = $_POST;
41
  } else {
42
+ $input = file_get_contents('php://input');
43
 
44
  if (isset($_SERVER['CONTENT_TYPE']) && stripos($_SERVER['CONTENT_TYPE'], 'application/json') === 0) {
45
+ $requestData['request']['params'] = json_decode($input, true);
46
  }
47
 
48
  if (isset($_SERVER['REQUEST_METHOD']) && in_array(strtoupper($_SERVER['REQUEST_METHOD']), $methodsWithPayload)) {
49
+ parse_str($input, $params);
50
+ if (isset($requestData['request']['params']) && is_array($requestData['request']['params'])) {
51
+ $requestData['request']['params'] = array_merge($requestData['request']['params'], $params);
52
+ } else {
 
 
 
53
  $requestData['request']['params'] = $params;
54
  }
55
  }
56
  }
57
 
58
+ $requestData['request']['clientIp'] = self::getRequestIp();
59
  if (isset($_SERVER['HTTP_USER_AGENT'])) {
60
  $requestData['request']['userAgent'] = $_SERVER['HTTP_USER_AGENT'];
61
  }
68
  return $requestData;
69
  }
70
 
71
+ /**
72
+ * Get the request context.
73
+ *
74
+ * @return string|null
75
+ */
76
  public static function getContext()
77
  {
78
+ if (self::isRequest() && isset($_SERVER['REQUEST_METHOD']) && isset($_SERVER['REQUEST_URI'])) {
79
+ return $_SERVER['REQUEST_METHOD'].' '.strtok($_SERVER['REQUEST_URI'], '?');
 
 
80
  }
81
  }
82
 
83
+ /**
84
+ * Get the request id.
85
+ *
86
+ * @return string|null
87
+ */
88
  public static function getUserId()
89
  {
90
  if (self::isRequest()) {
91
  return self::getRequestIp();
 
 
92
  }
93
  }
94
 
95
+ /**
96
+ * Get the request url.
97
+ *
98
+ * @return string
99
+ */
100
  public static function getCurrentUrl()
101
  {
102
  $schema = ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (!empty($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443)) ? 'https://' : 'http://';
103
 
104
+ $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
105
+
106
+ return $schema.$host.$_SERVER['REQUEST_URI'];
107
  }
108
 
109
+ /**
110
+ * Get the request ip.
111
+ *
112
+ * @return string
113
+ */
114
  public static function getRequestIp()
115
  {
116
  return isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
117
  }
118
 
119
+ /**
120
+ * Get the request headers.
121
+ *
122
+ * @return array
123
+ */
124
  public static function getRequestHeaders()
125
  {
 
 
 
 
126
  $headers = array();
127
 
128
  foreach ($_SERVER as $name => $value) {
lib/shippit-bugsnag/Stacktrace.php CHANGED
@@ -8,6 +8,13 @@ class Bugsnag_Stacktrace
8
  public $frames = array();
9
  private $config;
10
 
 
 
 
 
 
 
 
11
  public static function generate($config)
12
  {
13
  // Reduce memory usage by omitting args and objects from backtrace
@@ -19,20 +26,39 @@ class Bugsnag_Stacktrace
19
  $backtrace = debug_backtrace();
20
  }
21
 
22
- return self::fromBacktrace($config, $backtrace, "[generator]", 0);
23
  }
24
 
 
 
 
 
 
 
 
 
 
25
  public static function fromFrame($config, $file, $line)
26
  {
27
- $stacktrace = new Bugsnag_Stacktrace($config);
28
- $stacktrace->addFrame($file, $line, "[unknown]");
29
 
30
  return $stacktrace;
31
  }
32
 
 
 
 
 
 
 
 
 
 
 
33
  public static function fromBacktrace($config, $backtrace, $topFile, $topLine)
34
  {
35
- $stacktrace = new Bugsnag_Stacktrace($config);
36
 
37
  // PHP backtrace's are misaligned, we need to shift the file/line down a frame
38
  foreach ($backtrace as $frame) {
@@ -49,7 +75,7 @@ class Bugsnag_Stacktrace
49
  $topFile = $frame['file'];
50
  $topLine = $frame['line'];
51
  } else {
52
- $topFile = "[internal]";
53
  $topLine = 0;
54
  }
55
  }
@@ -60,21 +86,50 @@ class Bugsnag_Stacktrace
60
  return $stacktrace;
61
  }
62
 
 
 
 
 
 
 
 
63
  public static function frameInsideBugsnag($frame)
64
  {
65
  return isset($frame['class']) && strpos($frame['class'], 'Bugsnag_') === 0;
66
  }
67
 
 
 
 
 
 
 
 
68
  public function __construct($config)
69
  {
70
  $this->config = $config;
71
  }
72
 
 
 
 
 
 
73
  public function toArray()
74
  {
75
  return $this->frames;
76
  }
77
 
 
 
 
 
 
 
 
 
 
 
78
  public function addFrame($file, $line, $method, $class = null)
79
  {
80
  // Account for special "filenames" in eval'd code
@@ -86,13 +141,13 @@ class Bugsnag_Stacktrace
86
 
87
  // Construct the frame
88
  $frame = array(
89
- 'lineNumber' => $line,
90
  'method' => $class ? "$class::$method" : $method,
91
  );
92
 
93
  // Attach some lines of code for context
94
- if($this->config->sendCode) {
95
- $frame['code'] = $this->getCode($file, $line, Bugsnag_Stacktrace::$DEFAULT_NUM_LINES);
96
  }
97
 
98
  // Check if this frame is inProject
@@ -108,10 +163,19 @@ class Bugsnag_Stacktrace
108
  $this->frames[] = $frame;
109
  }
110
 
 
 
 
 
 
 
 
 
 
111
  private function getCode($path, $line, $numLines)
112
  {
113
  if (empty($path) || empty($line) || !file_exists($path)) {
114
- return NULL;
115
  }
116
 
117
  try {
@@ -133,13 +197,13 @@ class Bugsnag_Stacktrace
133
 
134
  $file->seek($start - 1);
135
  while ($file->key() < $end) {
136
- $code[$file->key() + 1] = rtrim(substr($file->current(), 0, Bugsnag_Stacktrace::$MAX_LINE_LENGTH));
137
  $file->next();
138
  }
139
 
140
  return $code;
141
  } catch (RuntimeException $ex) {
142
- return null;
143
  }
144
  }
145
  }
8
  public $frames = array();
9
  private $config;
10
 
11
+ /**
12
+ * Generate a new stacktrace using the given config.
13
+ *
14
+ * @param Bugsnag_Configuration $config the configuration instance
15
+ *
16
+ * @return self
17
+ */
18
  public static function generate($config)
19
  {
20
  // Reduce memory usage by omitting args and objects from backtrace
26
  $backtrace = debug_backtrace();
27
  }
28
 
29
+ return self::fromBacktrace($config, $backtrace, '[generator]', 0);
30
  }
31
 
32
+ /**
33
+ * Create a new stacktrace instance from a frame.
34
+ *
35
+ * @param Bugsnag_Configuration $config the configuration instance
36
+ * @param string $file the associated file
37
+ * @param int $line the line number
38
+ *
39
+ * @return self
40
+ */
41
  public static function fromFrame($config, $file, $line)
42
  {
43
+ $stacktrace = new self($config);
44
+ $stacktrace->addFrame($file, $line, '[unknown]');
45
 
46
  return $stacktrace;
47
  }
48
 
49
+ /**
50
+ * Create a new stacktrace instance from a backtrace.
51
+ *
52
+ * @param Bugsnag_Configuration $config the configuration instance
53
+ * @param array $backtrace the associated backtrace
54
+ * @param int $topFile the top file to use
55
+ * @param int $topLine the top line to use
56
+ *
57
+ * @return self
58
+ */
59
  public static function fromBacktrace($config, $backtrace, $topFile, $topLine)
60
  {
61
+ $stacktrace = new self($config);
62
 
63
  // PHP backtrace's are misaligned, we need to shift the file/line down a frame
64
  foreach ($backtrace as $frame) {
75
  $topFile = $frame['file'];
76
  $topLine = $frame['line'];
77
  } else {
78
+ $topFile = '[internal]';
79
  $topLine = 0;
80
  }
81
  }
86
  return $stacktrace;
87
  }
88
 
89
+ /**
90
+ * Does the given frame internally belong to bugsnag.
91
+ *
92
+ * @param array $frame the given frame to check
93
+ *
94
+ * @return bool
95
+ */
96
  public static function frameInsideBugsnag($frame)
97
  {
98
  return isset($frame['class']) && strpos($frame['class'], 'Bugsnag_') === 0;
99
  }
100
 
101
+ /**
102
+ * Create a new stacktrace instance.
103
+ *
104
+ * @param Bugsnag_Configuration $config the configuration instance
105
+ *
106
+ * @return void
107
+ */
108
  public function __construct($config)
109
  {
110
  $this->config = $config;
111
  }
112
 
113
+ /**
114
+ * Get the array representation.
115
+ *
116
+ * @return array
117
+ */
118
  public function toArray()
119
  {
120
  return $this->frames;
121
  }
122
 
123
+ /**
124
+ * Add the given frame to the stacktrace.
125
+ *
126
+ * @param string $file the associated file
127
+ * @param int $line the line number
128
+ * @param string $method the method called
129
+ * @param string|null $class the associated class
130
+ *
131
+ * @return void
132
+ */
133
  public function addFrame($file, $line, $method, $class = null)
134
  {
135
  // Account for special "filenames" in eval'd code
141
 
142
  // Construct the frame
143
  $frame = array(
144
+ 'lineNumber' => (int) $line,
145
  'method' => $class ? "$class::$method" : $method,
146
  );
147
 
148
  // Attach some lines of code for context
149
+ if ($this->config->sendCode) {
150
+ $frame['code'] = $this->getCode($file, $line, self::$DEFAULT_NUM_LINES);
151
  }
152
 
153
  // Check if this frame is inProject
163
  $this->frames[] = $frame;
164
  }
165
 
166
+ /**
167
+ * Extract the code for the given file and lines.
168
+ *
169
+ * @param string $path the path to the file
170
+ * @param int $line the line to centre about
171
+ * @param string $numLines the number of lines to fetch
172
+ *
173
+ * @return string[]|null
174
+ */
175
  private function getCode($path, $line, $numLines)
176
  {
177
  if (empty($path) || empty($line) || !file_exists($path)) {
178
+ return;
179
  }
180
 
181
  try {
197
 
198
  $file->seek($start - 1);
199
  while ($file->key() < $end) {
200
+ $code[$file->key() + 1] = rtrim(substr($file->current(), 0, self::$MAX_LINE_LENGTH));
201
  $file->next();
202
  }
203
 
204
  return $code;
205
  } catch (RuntimeException $ex) {
206
+ return;
207
  }
208
  }
209
  }
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Shippit_Shippit</name>
4
- <version>4.3.11</version>
5
  <stability>stable</stability>
6
  <license>Open Software Licence</license>
7
  <channel>community</channel>
@@ -18,9 +18,9 @@ Allows for retrieving shipping quotes during checkout and sending orders to Ship
18
  &#xD;
19
  Also adds Australian States and Territories to the available region options and Authority to Leave and Delivery Comments to the checkout process.</notes>
20
  <authors><author><name>Matthew Muscat</name><user>matthewmuscat</user><email>matthew@mamis.com.au</email></author><author><name>William On</name><user>williamon</user><email>will@shippit.com</email></author></authors>
21
- <date>2016-08-30</date>
22
- <time>05:02:03</time>
23
- <contents><target name="magelib"><dir name="shippit-bugsnag"><file name="Autoload.php" hash="141a845b8baaebee4232b30540d5cda5"/><file name="Client.php" hash="1899cce9e4e05aa200c5c05ef2c0f52d"/><file name="Configuration.php" hash="c4a28bb83e49dfb24ff15e3daebbe156"/><file name="Diagnostics.php" hash="ee57a579dec73e922465d417cfecccf6"/><file name="Error.php" hash="f8d179e9406a6c0a958d06367b9e64e0"/><file name="ErrorTypes.php" hash="d52493e689517f479abb21599e9c1989"/><file name="Notification.php" hash="98ac2f24e77a96fe8f274e9694a33dd4"/><file name="Request.php" hash="ff8dbf358238351801518bad62138491"/><file name="Stacktrace.php" hash="2f7b8e1172f04071ce70b5b53cfe55ee"/></dir></target><target name="magecommunity"><dir name="Shippit"><dir name="Shippit"><dir name="Block"><dir name="Adminhtml"><dir name="Sales"><dir name="Order"><file name="Grid.php" hash="9208ed6e0b222590610f6a3e2a3ac254"/><file name="Items.php" hash="275116a2c42700de7a65fc9e0a6568c6"/></dir><file name="Order.php" hash="665a08b5f3f6432ba49327ad0d320572"/></dir><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><dir name="Renderer"><dir name="Shipping"><file name="Methods.php" hash="26428642657de1a0f0d22140fd84174d"/></dir><dir name="Shippit"><file name="ServiceClass.php" hash="7573d99e768fa6e2c4dc136a54f0d9fd"/></dir></dir><dir name="Sync"><dir name="Order"><file name="ShippingMethodMapping.php" hash="7296f3ac577b89c36c68693ab1a84a32"/></dir></dir></dir><dir name="Fieldset"><file name="Version.php" hash="6cbff78c307a14e3eed4219f180901b1"/></dir></dir></dir></dir></dir><dir name="Checkout"><dir name="Cart"><file name="Shipping.php" hash="dd5dc61d665da4746e5c2a4fc6df089f"/></dir><dir name="Shipping"><file name="AuthorityToLeave.php" hash="241ff5d226c8f848b9895b767883dc30"/><file name="DeliveryInstructions.php" hash="77b5fb807d9dfdd8b5b6bfab6f8df9a6"/></dir></dir></dir><file name="Exception.php" hash="909594393898823a108bab9c6a2e77ed"/><dir name="Helper"><file name="Api.php" hash="17386e28d75bc9ec3cc38e0e91d597cc"/><file name="Bugsnag.php" hash="ae4f276ee853abaf75ffbaf9de08cc08"/><file name="Carrier.php" hash="f7d031b67b5c9beec38214236ff30b5a"/><file name="Checkout.php" hash="004418f9ee0de6ba090faa32e540d8a3"/><file name="Data.php" hash="df6ea2d54c389f91721dc28c72b1dea1"/><dir name="Sync"><dir name="Order"><file name="Items.php" hash="c2031228b78726051a4096054a80363b"/></dir><file name="Order.php" hash="cbdb9511638e9854de82d67017008739"/><file name="Shipping.php" hash="c19889222cffbddf178a6236f78ae41c"/></dir></dir><dir name="Model"><dir name="Api"><file name="Order.php" hash="8163a93c23b9b90b0dc7ab942bd36f57"/></dir><file name="Logger.php" hash="64ed33a2d7554a9da58a080e3462504e"/><dir name="Observer"><dir name="Adminhtml"><dir name="Sales"><file name="Order.php" hash="44393a4d02ea135f68d74ca8ec37394a"/></dir></dir><dir name="Order"><file name="Sync.php" hash="a4f15047fb0fd2681c950498992d7aac"/></dir><dir name="Quote"><file name="AuthorityToLeave.php" hash="c675772dcb25d6a35372f46060b3a8e4"/><file name="DeliveryInstructions.php" hash="8cf1353e6406710208a5312c9cd68c7d"/></dir><dir name="Shipping"><file name="Tracking.php" hash="988cffc30e8d606ba6a2754ba4b2d3a3"/></dir><file name="Shippit.php" hash="3625385600a8e3f0c64492bfaac9c681"/><dir name="System"><file name="Config.php" hash="e5515b7d0cccde3ad7bb70fbe33a3f0b"/></dir></dir><dir name="Request"><dir name="Api"><file name="Order.php" hash="3137d1dc3bd24413f092b77c35b8832c"/><file name="Shipment.php" hash="af1b78ce51f1d8b89a9c1e9bc6b81ed5"/></dir><dir name="Sync"><file name="Order.php" hash="800acbaab9222c6a9b84d7d7640e188e"/></dir></dir><dir name="Resource"><file name="Setup.php" hash="8eb28f6cf5f637597d5f0ad668b64269"/><dir name="Sync"><dir name="Order"><file name="Collection.php" hash="b6fc680edfd57d6cbf810290799dad2c"/><dir name="Item"><file name="Collection.php" hash="935dd5847558e6629ea671b91ad9a1df"/></dir><file name="Item.php" hash="1ba227660a2d1ad09283c312e7e88a98"/></dir><file name="Order.php" hash="4808f4501b760ac09af24fba0df7494d"/></dir></dir><dir name="Shipping"><dir name="Carrier"><file name="Shippit.php" hash="eaf1fc6ec3a58fc1a3adecf07ec5bd8b"/></dir></dir><file name="Shippit.php" hash="d48601c7f37bf3328b2e863d41d5fe13"/><dir name="Sync"><dir name="Order"><file name="Config.php" hash="f52faaf68213e313746abde13781350e"/><file name="Item.php" hash="dee4de2286845cdaed924f81dfeeab51"/></dir><file name="Order.php" hash="460b020cd0a44d8f956e415fbccae620"/></dir><dir name="System"><dir name="Config"><dir name="Source"><dir name="Catalog"><dir name="Attributes"><file name="Location.php" hash="b2fcaaabfa58d290d731e3b09b0afb5d"/></dir><file name="Attributes.php" hash="1f051ddfcea5034c3b0f299ed35d2c7c"/><file name="Products.php" hash="6e78a631987441e8228ee410fe5addd2"/><dir name="Unit"><file name="Weight.php" hash="9d15b42826be4e39c3f2a105826cf6be"/></dir></dir><dir name="Order"><dir name="Status"><file name="Processing.php" hash="1cd4481df806b98b5b20afefe8c16e38"/></dir></dir><dir name="Shipping"><file name="Methods.php" hash="683dd6c9d412d52be6941ec1aec0e1eb"/></dir><dir name="Shippit"><file name="Environment.php" hash="a71561807ce05052a678a5d8d0656695"/><file name="MaxTimeslots.php" hash="a87f36fb06a9e9b79c1ffdc5ff1c42c0"/><file name="Methods.php" hash="41675a89d439dfb0e6ba17d1f323febd"/><dir name="Order"><file name="Status.php" hash="fcd986d9d3634cf257d58c212ae650c8"/></dir><dir name="Sync"><file name="Mode.php" hash="64ff642d93ad9505f160f48b5061efae"/><file name="SendAllOrders.php" hash="99fc5b1dcb2d49768025194cd02aba0e"/></dir></dir></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><dir name="Shippit"><dir name="Order"><file name="SyncController.php" hash="d5a22ab5fe1346e68d7967e9cad20402"/></dir><file name="OrderController.php" hash="7d4e2c615b524c211d75b4b7c4edc0e7"/></dir></dir><file name="OrderController.php" hash="6d5fe674fd570b6d7b8acc761e450de6"/></dir><dir name="data"><dir name="shippit_setup"><file name="data-install-4.0.0.php" hash="fcc2ad84912ffaf9dc07b866f5fd7460"/><file name="data-upgrade-4.1.0-4.1.1.php" hash="aebc8c802bf8af45219500526da944fa"/><file name="data-upgrade-4.1.6-4.1.7.php" hash="2b2fe61d97645521516728a329cba9ad"/><file name="data-upgrade-4.2.3-4.2.4.php" hash="bd3ed5e70b9349d830fa789e0b394d83"/><file name="data-upgrade-4.3.2-4.3.3.php" hash="3699a8b74b0898f48ec1b9daeb3fcfcc"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="fb2576b73bea6a323cfd157e95c25e90"/><file name="config.xml" hash="bf6ea6fbf10491d8e39d7ce4909dacdf"/><file name="system.xml" hash="f6ea042a7657ed35ee931663068b2908"/></dir><dir name="sql"><dir name="shippit_setup"><file name="install-4.0.0.php" hash="19a0a09b6a10c89b73edc7f0a744fe5a"/><file name="upgrade-4.0.9-4.1.0.php" hash="35e56aeea2b78bba82e845d4c4c16fc1"/><file name="upgrade-4.1.0-4.1.1.php" hash="5c675c05272472cdd7c585aa6db750d9"/><file name="upgrade-4.2.5-4.2.6.php" hash="15dd734c1f7797d8cd0ff5b91a2dda55"/><file name="upgrade-4.2.6-4.3.0.php" hash="635d87318271636ed348a41834c70081"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="shippit.xml" hash="18fa39b7eae780fe993e5140270ffefe"/></dir><dir name="template"><dir name="shippit"><dir name="checkout"><dir name="onepage"><dir name="shipping_method"><file name="authoritytoleave.phtml" hash="7a138531233734c55f97de3cb1641a18"/><file name="deliveryinstructions.phtml" hash="cc64f104584b7be4de3e5de3f2c047c0"/></dir><file name="shipping_method.phtml" hash="c7d804a639749b3c7b21e5e228463f88"/></dir></dir><dir name="email"><dir name="order"><dir name="shipment"><file name="track.phtml" hash="c1450ff14e566880d421799852df4014"/></dir></dir></dir></dir></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="shippit.xml" hash="c0ae616038936a98b9e87124fb1c3127"/></dir><dir name="template"><dir name="shippit"><dir name="system"><dir name="config"><dir name="form"><dir name="field"><file name="array.phtml" hash="46d02a4a01af0e14cb2d0d91665ca03e"/></dir></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Shippit_Shippit.xml" hash="401f33d7db491808587c51209d8d6a8b"/></dir></target></contents>
24
  <compatible/>
25
  <dependencies><required><php><min>5.2.0</min><max>8.0.0</max></php></required></dependencies>
26
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Shippit_Shippit</name>
4
+ <version>4.3.14</version>
5
  <stability>stable</stability>
6
  <license>Open Software Licence</license>
7
  <channel>community</channel>
18
  &#xD;
19
  Also adds Australian States and Territories to the available region options and Authority to Leave and Delivery Comments to the checkout process.</notes>
20
  <authors><author><name>Matthew Muscat</name><user>matthewmuscat</user><email>matthew@mamis.com.au</email></author><author><name>William On</name><user>williamon</user><email>will@shippit.com</email></author></authors>
21
+ <date>2016-09-26</date>
22
+ <time>00:54:11</time>
23
+ <contents><target name="magelib"><dir name="shippit-bugsnag"><file name="Autoload.php" hash="55266ba5e2f5b3d9e9331c6eaa0945d5"/><file name="Client.php" hash="e58b339776f7d039a7486c4381e31134"/><file name="Configuration.php" hash="d303821a0ee820f2191540f8b3df4379"/><file name="Diagnostics.php" hash="fe944e2c0e3cfd06931bf251da18d544"/><file name="Error.php" hash="a23e6f17acc4d295bec537c4ee4897e8"/><file name="ErrorTypes.php" hash="e273be2371c9251dbfdd89d4490280dd"/><file name="Notification.php" hash="77f1f6352d82f69408499c5e5487ea42"/><file name="Request.php" hash="4b5e27bb029d1423ed823ad2b327189d"/><file name="Stacktrace.php" hash="6a0ca0f67fcdf4058b150f7dd602c803"/></dir></target><target name="magecommunity"><dir name="Shippit"><dir name="Shippit"><dir name="Block"><dir name="Adminhtml"><dir name="Sales"><dir name="Order"><file name="Grid.php" hash="9208ed6e0b222590610f6a3e2a3ac254"/><file name="Items.php" hash="275116a2c42700de7a65fc9e0a6568c6"/></dir><file name="Order.php" hash="665a08b5f3f6432ba49327ad0d320572"/></dir><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><dir name="Renderer"><dir name="Shipping"><file name="Methods.php" hash="26428642657de1a0f0d22140fd84174d"/></dir><dir name="Shippit"><file name="ServiceClass.php" hash="7573d99e768fa6e2c4dc136a54f0d9fd"/></dir></dir><dir name="Sync"><dir name="Order"><file name="ShippingMethodMapping.php" hash="7296f3ac577b89c36c68693ab1a84a32"/></dir></dir></dir><dir name="Fieldset"><file name="Version.php" hash="6cbff78c307a14e3eed4219f180901b1"/></dir></dir></dir></dir></dir><dir name="Checkout"><dir name="Cart"><file name="Shipping.php" hash="dd5dc61d665da4746e5c2a4fc6df089f"/></dir><dir name="Shipping"><file name="AuthorityToLeave.php" hash="241ff5d226c8f848b9895b767883dc30"/><file name="DeliveryInstructions.php" hash="77b5fb807d9dfdd8b5b6bfab6f8df9a6"/></dir></dir></dir><file name="Exception.php" hash="909594393898823a108bab9c6a2e77ed"/><dir name="Helper"><file name="Api.php" hash="17386e28d75bc9ec3cc38e0e91d597cc"/><file name="Bugsnag.php" hash="c3a0355601dbf82cf9d5880ad4190b67"/><file name="Carrier.php" hash="f7d031b67b5c9beec38214236ff30b5a"/><file name="Checkout.php" hash="004418f9ee0de6ba090faa32e540d8a3"/><file name="Data.php" hash="df6ea2d54c389f91721dc28c72b1dea1"/><dir name="Sync"><dir name="Order"><file name="Items.php" hash="c2031228b78726051a4096054a80363b"/></dir><file name="Order.php" hash="cbdb9511638e9854de82d67017008739"/><file name="Shipping.php" hash="c19889222cffbddf178a6236f78ae41c"/></dir></dir><dir name="Model"><dir name="Api"><file name="Order.php" hash="8163a93c23b9b90b0dc7ab942bd36f57"/></dir><file name="Logger.php" hash="64ed33a2d7554a9da58a080e3462504e"/><dir name="Observer"><dir name="Adminhtml"><dir name="Sales"><file name="Order.php" hash="44393a4d02ea135f68d74ca8ec37394a"/></dir></dir><dir name="Order"><file name="Sync.php" hash="a4f15047fb0fd2681c950498992d7aac"/></dir><dir name="Quote"><file name="AuthorityToLeave.php" hash="c675772dcb25d6a35372f46060b3a8e4"/><file name="DeliveryInstructions.php" hash="8cf1353e6406710208a5312c9cd68c7d"/></dir><dir name="Shipping"><file name="Tracking.php" hash="988cffc30e8d606ba6a2754ba4b2d3a3"/></dir><file name="Shippit.php" hash="3625385600a8e3f0c64492bfaac9c681"/><dir name="System"><file name="Config.php" hash="e5515b7d0cccde3ad7bb70fbe33a3f0b"/></dir></dir><dir name="Request"><dir name="Api"><file name="Order.php" hash="0421d706b753475696d9574d4630505e"/><file name="Shipment.php" hash="af1b78ce51f1d8b89a9c1e9bc6b81ed5"/></dir><dir name="Sync"><file name="Order.php" hash="ab9a2ba4247d6afb6c75044e60ac5bf6"/></dir></dir><dir name="Resource"><file name="Setup.php" hash="8eb28f6cf5f637597d5f0ad668b64269"/><dir name="Sync"><dir name="Order"><file name="Collection.php" hash="b6fc680edfd57d6cbf810290799dad2c"/><dir name="Item"><file name="Collection.php" hash="935dd5847558e6629ea671b91ad9a1df"/></dir><file name="Item.php" hash="1ba227660a2d1ad09283c312e7e88a98"/></dir><file name="Order.php" hash="4808f4501b760ac09af24fba0df7494d"/></dir></dir><dir name="Shipping"><dir name="Carrier"><file name="Shippit.php" hash="1fe37e4368561831576e737aca28afe2"/></dir></dir><file name="Shippit.php" hash="d48601c7f37bf3328b2e863d41d5fe13"/><dir name="Sync"><dir name="Order"><file name="Config.php" hash="f52faaf68213e313746abde13781350e"/><file name="Item.php" hash="dee4de2286845cdaed924f81dfeeab51"/></dir><file name="Order.php" hash="460b020cd0a44d8f956e415fbccae620"/></dir><dir name="System"><dir name="Config"><dir name="Source"><dir name="Catalog"><dir name="Attributes"><file name="Location.php" hash="b2fcaaabfa58d290d731e3b09b0afb5d"/></dir><file name="Attributes.php" hash="1f051ddfcea5034c3b0f299ed35d2c7c"/><file name="Products.php" hash="6e78a631987441e8228ee410fe5addd2"/><dir name="Unit"><file name="Weight.php" hash="9d15b42826be4e39c3f2a105826cf6be"/></dir></dir><dir name="Order"><dir name="Status"><file name="Processing.php" hash="1cd4481df806b98b5b20afefe8c16e38"/></dir></dir><dir name="Shipping"><file name="Methods.php" hash="683dd6c9d412d52be6941ec1aec0e1eb"/></dir><dir name="Shippit"><file name="Environment.php" hash="a71561807ce05052a678a5d8d0656695"/><file name="MaxTimeslots.php" hash="a87f36fb06a9e9b79c1ffdc5ff1c42c0"/><file name="Methods.php" hash="41675a89d439dfb0e6ba17d1f323febd"/><dir name="Order"><file name="Status.php" hash="fcd986d9d3634cf257d58c212ae650c8"/></dir><dir name="Sync"><file name="Mode.php" hash="64ff642d93ad9505f160f48b5061efae"/><file name="SendAllOrders.php" hash="99fc5b1dcb2d49768025194cd02aba0e"/></dir></dir></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><dir name="Shippit"><dir name="Order"><file name="SyncController.php" hash="d5a22ab5fe1346e68d7967e9cad20402"/></dir><file name="OrderController.php" hash="7d4e2c615b524c211d75b4b7c4edc0e7"/></dir></dir><file name="OrderController.php" hash="34b6ab46d4f1f0d52d52c5cb561f76db"/></dir><dir name="data"><dir name="shippit_setup"><file name="data-install-4.0.0.php" hash="fcc2ad84912ffaf9dc07b866f5fd7460"/><file name="data-upgrade-4.1.0-4.1.1.php" hash="aebc8c802bf8af45219500526da944fa"/><file name="data-upgrade-4.1.6-4.1.7.php" hash="2b2fe61d97645521516728a329cba9ad"/><file name="data-upgrade-4.2.3-4.2.4.php" hash="bd3ed5e70b9349d830fa789e0b394d83"/><file name="data-upgrade-4.3.2-4.3.3.php" hash="3699a8b74b0898f48ec1b9daeb3fcfcc"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="fb2576b73bea6a323cfd157e95c25e90"/><file name="config.xml" hash="98e3815f28039d948154662490b15ca8"/><file name="system.xml" hash="f6ea042a7657ed35ee931663068b2908"/></dir><dir name="sql"><dir name="shippit_setup"><file name="install-4.0.0.php" hash="19a0a09b6a10c89b73edc7f0a744fe5a"/><file name="upgrade-4.0.9-4.1.0.php" hash="35e56aeea2b78bba82e845d4c4c16fc1"/><file name="upgrade-4.1.0-4.1.1.php" hash="5c675c05272472cdd7c585aa6db750d9"/><file name="upgrade-4.2.5-4.2.6.php" hash="15dd734c1f7797d8cd0ff5b91a2dda55"/><file name="upgrade-4.2.6-4.3.0.php" hash="635d87318271636ed348a41834c70081"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="shippit.xml" hash="18fa39b7eae780fe993e5140270ffefe"/></dir><dir name="template"><dir name="shippit"><dir name="checkout"><dir name="onepage"><dir name="shipping_method"><file name="authoritytoleave.phtml" hash="7a138531233734c55f97de3cb1641a18"/><file name="deliveryinstructions.phtml" hash="cc64f104584b7be4de3e5de3f2c047c0"/></dir><file name="shipping_method.phtml" hash="c7d804a639749b3c7b21e5e228463f88"/></dir></dir><dir name="email"><dir name="order"><dir name="shipment"><file name="track.phtml" hash="c1450ff14e566880d421799852df4014"/></dir></dir></dir></dir></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="shippit.xml" hash="c0ae616038936a98b9e87124fb1c3127"/></dir><dir name="template"><dir name="shippit"><dir name="system"><dir name="config"><dir name="form"><dir name="field"><file name="array.phtml" hash="46d02a4a01af0e14cb2d0d91665ca03e"/></dir></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Shippit_Shippit.xml" hash="401f33d7db491808587c51209d8d6a8b"/></dir></target></contents>
24
  <compatible/>
25
  <dependencies><required><php><min>5.2.0</min><max>8.0.0</max></php></required></dependencies>
26
  </package>