Expressly - Version 0.2.0

Version Notes

https://github.com/expressly/magento

Download this release

Release Info

Developer Expressly
Extension Expressly
Version 0.2.0
Comparing to
See all releases


Version 0.2.0

Files changed (337) hide show
  1. app/code/community/Expressly/Expressly/Block/Banner.php +37 -0
  2. app/code/community/Expressly/Expressly/Block/Popup.php +12 -0
  3. app/code/community/Expressly/Expressly/Block/System/Config/Form/ImageUrl.php +19 -0
  4. app/code/community/Expressly/Expressly/Block/System/Config/Form/Register.php +25 -0
  5. app/code/community/Expressly/Expressly/Helper/Client.php +56 -0
  6. app/code/community/Expressly/Expressly/Helper/Data.php +5 -0
  7. app/code/community/Expressly/Expressly/Model/Observer.php +54 -0
  8. app/code/community/Expressly/Expressly/Model/Resource/Setup.php +14 -0
  9. app/code/community/Expressly/Expressly/composer.json +26 -0
  10. app/code/community/Expressly/Expressly/composer.lock +988 -0
  11. app/code/community/Expressly/Expressly/controllers/AbstractController.php +45 -0
  12. app/code/community/Expressly/Expressly/controllers/BatchController.php +99 -0
  13. app/code/community/Expressly/Expressly/controllers/CustomerController.php +277 -0
  14. app/code/community/Expressly/Expressly/controllers/UtilityController.php +16 -0
  15. app/code/community/Expressly/Expressly/etc/config.xml +128 -0
  16. app/code/community/Expressly/Expressly/etc/system.xml +75 -0
  17. app/code/community/Expressly/Expressly/lib/MerchantProvider.php +80 -0
  18. app/code/community/Expressly/Expressly/sql/expressly_expressly_setup/mysql4-install-0.1.0.php +27 -0
  19. app/code/community/Expressly/Expressly/vendor/autoload.php +7 -0
  20. app/code/community/Expressly/Expressly/vendor/composer/ClassLoader.php +413 -0
  21. app/code/community/Expressly/Expressly/vendor/composer/LICENSE +21 -0
  22. app/code/community/Expressly/Expressly/vendor/composer/autoload_classmap.php +10 -0
  23. app/code/community/Expressly/Expressly/vendor/composer/autoload_namespaces.php +21 -0
  24. app/code/community/Expressly/Expressly/vendor/composer/autoload_psr4.php +15 -0
  25. app/code/community/Expressly/Expressly/vendor/composer/autoload_real.php +50 -0
  26. app/code/community/Expressly/Expressly/vendor/composer/installed.json +1005 -0
  27. app/code/community/Expressly/Expressly/vendor/deralex/yaml-config-service-provider/.gitignore +17 -0
  28. app/code/community/Expressly/Expressly/vendor/deralex/yaml-config-service-provider/.travis.yml +9 -0
  29. app/code/community/Expressly/Expressly/vendor/deralex/yaml-config-service-provider/README.md +73 -0
  30. app/code/community/Expressly/Expressly/vendor/deralex/yaml-config-service-provider/composer.json +31 -0
  31. app/code/community/Expressly/Expressly/vendor/deralex/yaml-config-service-provider/composer.lock +923 -0
  32. app/code/community/Expressly/Expressly/vendor/deralex/yaml-config-service-provider/spec/DerAlex/Silex/YamlConfigServiceProviderSpec.php +19 -0
  33. app/code/community/Expressly/Expressly/vendor/deralex/yaml-config-service-provider/spec/Fixtures/config.yml +4 -0
  34. app/code/community/Expressly/Expressly/vendor/deralex/yaml-config-service-provider/src/DerAlex/Silex/YamlConfigServiceProvider.php +79 -0
  35. app/code/community/Expressly/Expressly/vendor/doctrine/collections/.gitignore +1 -0
  36. app/code/community/Expressly/Expressly/vendor/doctrine/collections/.travis.yml +21 -0
  37. app/code/community/Expressly/Expressly/vendor/doctrine/collections/LICENSE +19 -0
  38. app/code/community/Expressly/Expressly/vendor/doctrine/collections/README.md +25 -0
  39. app/code/community/Expressly/Expressly/vendor/doctrine/collections/composer.json +29 -0
  40. app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php +343 -0
  41. app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php +387 -0
  42. app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Collection.php +263 -0
  43. app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Criteria.php +259 -0
  44. app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php +227 -0
  45. app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Comparison.php +103 -0
  46. app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/CompositeExpression.php +90 -0
  47. app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Expression.php +35 -0
  48. app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ExpressionVisitor.php +82 -0
  49. app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Value.php +52 -0
  50. app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php +166 -0
  51. app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Selectable.php +48 -0
  52. app/code/community/Expressly/Expressly/vendor/doctrine/collections/phpunit.xml.dist +31 -0
  53. app/code/community/Expressly/Expressly/vendor/doctrine/collections/tests/Doctrine/Tests/Common/Collections/AbstractLazyCollectionTest.php +20 -0
  54. app/code/community/Expressly/Expressly/vendor/doctrine/collections/tests/Doctrine/Tests/Common/Collections/ArrayCollectionTest.php +296 -0
  55. app/code/community/Expressly/Expressly/vendor/doctrine/collections/tests/Doctrine/Tests/Common/Collections/ClosureExpressionVisitorTest.php +250 -0
  56. app/code/community/Expressly/Expressly/vendor/doctrine/collections/tests/Doctrine/Tests/Common/Collections/CollectionTest.php +265 -0
  57. app/code/community/Expressly/Expressly/vendor/doctrine/collections/tests/Doctrine/Tests/Common/Collections/CriteriaTest.php +83 -0
  58. app/code/community/Expressly/Expressly/vendor/doctrine/collections/tests/Doctrine/Tests/Common/Collections/ExpressionBuilderTest.php +125 -0
  59. app/code/community/Expressly/Expressly/vendor/doctrine/collections/tests/Doctrine/Tests/LazyArrayCollection.php +22 -0
  60. app/code/community/Expressly/Expressly/vendor/doctrine/collections/tests/Doctrine/Tests/TestInit.php +21 -0
  61. app/code/community/Expressly/Expressly/vendor/expressly/php-common/.gitignore +13 -0
  62. app/code/community/Expressly/Expressly/vendor/expressly/php-common/.htaccess +5 -0
  63. app/code/community/Expressly/Expressly/vendor/expressly/php-common/LICENSE +22 -0
  64. app/code/community/Expressly/Expressly/vendor/expressly/php-common/README.md +96 -0
  65. app/code/community/Expressly/Expressly/vendor/expressly/php-common/assets/js/expressly.js +4 -0
  66. app/code/community/Expressly/Expressly/vendor/expressly/php-common/assets/scss/default.scss +5 -0
  67. app/code/community/Expressly/Expressly/vendor/expressly/php-common/bootstrap/bootstrap.php +43 -0
  68. app/code/community/Expressly/Expressly/vendor/expressly/php-common/bootstrap/config.php +6 -0
  69. app/code/community/Expressly/Expressly/vendor/expressly/php-common/bootstrap/database.php +12 -0
  70. app/code/community/Expressly/Expressly/vendor/expressly/php-common/bootstrap/services.php +15 -0
  71. app/code/community/Expressly/Expressly/vendor/expressly/php-common/composer.json +32 -0
  72. app/code/community/Expressly/Expressly/vendor/expressly/php-common/gulpfile.js +26 -0
  73. app/code/community/Expressly/Expressly/vendor/expressly/php-common/package.json +28 -0
  74. app/code/community/Expressly/Expressly/vendor/expressly/php-common/phpunit.xml +19 -0
  75. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Client.php +20 -0
  76. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Address.php +163 -0
  77. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/ArraySerializeable.php +30 -0
  78. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Cart.php +34 -0
  79. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Customer.php +193 -0
  80. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Email.php +33 -0
  81. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Generic.php +33 -0
  82. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Invoice.php +32 -0
  83. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Merchant.php +176 -0
  84. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/MerchantType.php +13 -0
  85. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Meta.php +61 -0
  86. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Order.php +75 -0
  87. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Phone.php +54 -0
  88. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Route.php +139 -0
  89. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Social.php +10 -0
  90. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/AcknowledgeableEvent.php +21 -0
  91. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/BannerEvent.php +21 -0
  92. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/CustomerEvent.php +22 -0
  93. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/CustomerMigrateEvent.php +30 -0
  94. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/CustomerUpdateEvent.php +21 -0
  95. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/MerchantEvent.php +20 -0
  96. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/MerchantUpdatePasswordEvent.php +27 -0
  97. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/OrderUpdateEvent.php +29 -0
  98. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/PasswordedEvent.php +38 -0
  99. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/ResponseEvent.php +48 -0
  100. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Exception/ExceptionFormatter.php +21 -0
  101. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Exception/GenericException.php +17 -0
  102. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Exception/InvalidURIException.php +7 -0
  103. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Helper/BannerHelper.php +27 -0
  104. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Logger/DummyLogger.php +44 -0
  105. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Presenter/BatchCustomerPresenter.php +31 -0
  106. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Presenter/BatchInvoicePresenter.php +26 -0
  107. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Presenter/CustomerMigratePresenter.php +43 -0
  108. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Presenter/PingPresenter.php +13 -0
  109. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Presenter/PresenterInterface.php +8 -0
  110. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Provider/ConfigProviderInterface.php +8 -0
  111. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Provider/CountryCodeProvider.php +70 -0
  112. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Provider/ExternalRouteProvider.php +46 -0
  113. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Provider/JavaScriptProvider.php +18 -0
  114. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Provider/MerchantProvider.php +106 -0
  115. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Provider/MerchantProviderInterface.php +12 -0
  116. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Proxy/.gitkeep +0 -0
  117. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/config/config.yml +315 -0
  118. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/css/default.css +1 -0
  119. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/images/Logo_Blue_s.jpg +0 -0
  120. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/images/cross.png +0 -0
  121. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/images/tick.png +0 -0
  122. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/js/expressly.js +1 -0
  123. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/translations/de.yml +0 -0
  124. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/translations/en.yml +0 -0
  125. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/view/landing.html.twig +17 -0
  126. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/view/offer.html.twig +0 -0
  127. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/ServiceProvider/CountryCodeServiceProvider.php +19 -0
  128. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/ServiceProvider/DatabaseServiceProvider.php +23 -0
  129. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/ServiceProvider/ExternalRouteServiceProvider.php +25 -0
  130. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/ServiceProvider/JavaScriptServiceProvider.php +21 -0
  131. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/ServiceProvider/MerchantServiceProvider.php +21 -0
  132. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/ServiceProvider/ValidatorServiceProvider.php +24 -0
  133. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/ServiceProvider/VersionServiceProvider.php +18 -0
  134. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Subscriber/BannerSubscriber.php +44 -0
  135. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Subscriber/CustomerMigrationSubscriber.php +89 -0
  136. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Subscriber/MerchantSubscriber.php +95 -0
  137. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Subscriber/UtilitySubscriber.php +37 -0
  138. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Tests/Helper/BannerHelperTest.php +79 -0
  139. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Tests/Subscriber/BannerSubscriberTest.php +83 -0
  140. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Validator/EmailValidator.php +36 -0
  141. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Validator/UuidValidator.php +36 -0
  142. app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Validator/ValidatorInterface.php +12 -0
  143. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/.gitignore +5 -0
  144. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/.travis.yml +25 -0
  145. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/LICENSE +19 -0
  146. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/README.md +28 -0
  147. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/composer.json +32 -0
  148. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Browser.php +195 -0
  149. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Client/AbstractClient.php +62 -0
  150. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Client/AbstractCurl.php +231 -0
  151. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Client/AbstractStream.php +44 -0
  152. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Client/BatchClientInterface.php +27 -0
  153. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Client/ClientInterface.php +20 -0
  154. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Client/Curl.php +60 -0
  155. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Client/FileGetContents.php +91 -0
  156. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Client/MultiCurl.php +114 -0
  157. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Exception/ClientException.php +10 -0
  158. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Exception/ExceptionInterface.php +10 -0
  159. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Exception/InvalidArgumentException.php +10 -0
  160. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Exception/LogicException.php +10 -0
  161. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Exception/RequestException.php +32 -0
  162. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Exception/RuntimeException.php +7 -0
  163. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Listener/BasicAuthListener.php +27 -0
  164. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Listener/CallbackListener.php +49 -0
  165. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Listener/History/Entry.php +42 -0
  166. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Listener/History/Journal.php +76 -0
  167. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Listener/HistoryListener.php +33 -0
  168. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Listener/ListenerChain.php +40 -0
  169. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Listener/ListenerInterface.php +12 -0
  170. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Listener/LoggerListener.php +36 -0
  171. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/AbstractMessage.php +154 -0
  172. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/Factory/Factory.php +26 -0
  173. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/Factory/FactoryInterface.php +12 -0
  174. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/Form/FormRequest.php +187 -0
  175. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/Form/FormRequestInterface.php +27 -0
  176. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/Form/FormUpload.php +118 -0
  177. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/Form/FormUploadInterface.php +13 -0
  178. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/MessageInterface.php +74 -0
  179. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/Request.php +174 -0
  180. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/RequestInterface.php +75 -0
  181. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/Response.php +193 -0
  182. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Util/Cookie.php +216 -0
  183. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Util/CookieJar.php +79 -0
  184. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Util/Url.php +190 -0
  185. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/phpunit.xml.dist +20 -0
  186. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/BrowserTest.php +182 -0
  187. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Client/AbstractStreamTest.php +57 -0
  188. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Client/ClientTest.php +36 -0
  189. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Client/FunctionalTest.php +287 -0
  190. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Listener/BasicAuthListenerTest.php +20 -0
  191. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Listener/CallbackListenerTest.php +34 -0
  192. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Listener/History/EntryTest.php +15 -0
  193. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Listener/History/JournalTest.php +119 -0
  194. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Listener/HistoryListenerTest.php +39 -0
  195. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Listener/ListenerChainTest.php +36 -0
  196. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Listener/LoggerListenerTest.php +31 -0
  197. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Message/AbstractMessageTest.php +129 -0
  198. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Message/FactoryTest.php +61 -0
  199. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Message/Fixtures/google.png +0 -0
  200. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Message/FormRequestTest.php +120 -0
  201. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Message/FormUploadTest.php +44 -0
  202. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Message/RequestTest.php +141 -0
  203. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Message/ResponseTest.php +114 -0
  204. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Util/CookieJarTest.php +73 -0
  205. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Util/CookieTest.php +151 -0
  206. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Util/UrlTest.php +57 -0
  207. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/etc/nginx.conf +49 -0
  208. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/etc/squid.conf +2 -0
  209. app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/server.php +18 -0
  210. app/code/community/Expressly/Expressly/vendor/monolog/monolog/.php_cs +15 -0
  211. app/code/community/Expressly/Expressly/vendor/monolog/monolog/CHANGELOG.mdown +217 -0
  212. app/code/community/Expressly/Expressly/vendor/monolog/monolog/LICENSE +19 -0
  213. app/code/community/Expressly/Expressly/vendor/monolog/monolog/README.mdown +292 -0
  214. app/code/community/Expressly/Expressly/vendor/monolog/monolog/composer.json +54 -0
  215. app/code/community/Expressly/Expressly/vendor/monolog/monolog/doc/extending.md +76 -0
  216. app/code/community/Expressly/Expressly/vendor/monolog/monolog/doc/sockets.md +37 -0
  217. app/code/community/Expressly/Expressly/vendor/monolog/monolog/doc/usage.md +162 -0
  218. app/code/community/Expressly/Expressly/vendor/monolog/monolog/phpunit.xml.dist +15 -0
  219. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/ErrorHandler.php +208 -0
  220. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php +79 -0
  221. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php +87 -0
  222. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php +104 -0
  223. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php +36 -0
  224. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php +111 -0
  225. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php +140 -0
  226. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php +116 -0
  227. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php +159 -0
  228. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php +47 -0
  229. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php +165 -0
  230. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php +105 -0
  231. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php +150 -0
  232. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php +48 -0
  233. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php +113 -0
  234. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php +184 -0
  235. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php +66 -0
  236. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php +92 -0
  237. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php +98 -0
  238. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php +184 -0
  239. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php +117 -0
  240. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php +204 -0
  241. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php +72 -0
  242. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/CubeHandler.php +145 -0
  243. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php +45 -0
  244. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php +89 -0
  245. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php +128 -0
  246. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php +82 -0
  247. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/FilterHandler.php +140 -0
  248. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php +28 -0
  249. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php +59 -0
  250. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php +34 -0
  251. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php +150 -0
  252. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php +195 -0
  253. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php +126 -0
  254. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php +103 -0
  255. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php +72 -0
  256. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php +80 -0
  257. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php +90 -0
  258. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/HipChatHandler.php +306 -0
  259. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php +55 -0
  260. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php +98 -0
  261. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/MailHandler.php +55 -0
  262. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/MandrillHandler.php +69 -0
  263. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php +21 -0
  264. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php +55 -0
  265. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php +176 -0
  266. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php +176 -0
  267. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php +45 -0
  268. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/PsrHandler.php +56 -0
  269. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/PushoverHandler.php +172 -0
  270. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/RavenHandler.php +187 -0
  271. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php +58 -0
  272. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.php +73 -0
  273. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php +153 -0
  274. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/SamplingHandler.php +82 -0
  275. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php +280 -0
  276. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php +284 -0
  277. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php +104 -0
  278. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php +87 -0
  279. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php +67 -0
  280. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php +46 -0
  281. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php +80 -0
  282. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php +140 -0
  283. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php +57 -0
  284. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php +95 -0
  285. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Logger.php +615 -0
  286. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/GitProcessor.php +64 -0
  287. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php +82 -0
  288. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php +40 -0
  289. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php +63 -0
  290. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php +40 -0
  291. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php +31 -0
  292. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php +48 -0
  293. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php +34 -0
  294. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php +38 -0
  295. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php +105 -0
  296. app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Registry.php +134 -0
  297. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/ErrorHandlerTest.php +31 -0
  298. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/ChromePHPFormatterTest.php +158 -0
  299. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/ElasticaFormatterTest.php +79 -0
  300. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/FlowdockFormatterTest.php +55 -0
  301. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/GelfMessageFormatterTest.php +204 -0
  302. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/JsonFormatterTest.php +78 -0
  303. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/LineFormatterTest.php +208 -0
  304. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/LogglyFormatterTest.php +40 -0
  305. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/LogstashFormatterTest.php +289 -0
  306. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/MongoDBFormatterTest.php +253 -0
  307. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/NormalizerFormatterTest.php +253 -0
  308. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/ScalarFormatterTest.php +98 -0
  309. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/WildfireFormatterTest.php +142 -0
  310. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/AbstractHandlerTest.php +115 -0
  311. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/AbstractProcessingHandlerTest.php +80 -0
  312. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/AmqpHandlerTest.php +137 -0
  313. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/BrowserConsoleHandlerTest.php +130 -0
  314. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/BufferHandlerTest.php +158 -0
  315. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/ChromePHPHandlerTest.php +141 -0
  316. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/CouchDBHandlerTest.php +41 -0
  317. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php +52 -0
  318. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/DynamoDbHandlerTest.php +73 -0
  319. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/ElasticSearchHandlerTest.php +239 -0
  320. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/ErrorLogHandlerTest.php +66 -0
  321. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/FilterHandlerTest.php +170 -0
  322. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/FingersCrossedHandlerTest.php +240 -0
  323. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/FirePHPHandlerTest.php +96 -0
  324. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/Fixtures/.gitkeep +0 -0
  325. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/FleepHookHandlerTest.php +85 -0
  326. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/FlowdockHandlerTest.php +88 -0
  327. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerLegacyTest.php +95 -0
  328. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerTest.php +117 -0
  329. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/GelfMockMessagePublisher.php +25 -0
  330. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/GroupHandlerTest.php +89 -0
  331. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/HipChatHandlerTest.php +178 -0
  332. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/LogEntriesHandlerTest.php +84 -0
  333. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/MailHandlerTest.php +75 -0
  334. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/MockRavenClient.php +26 -0
  335. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/MongoDBHandlerTest.php +65 -0
  336. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/NativeMailerHandlerTest.php +61 -0
  337. app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/NewRelicHandlerTest.php +45 -0
app/code/community/Expressly/Expressly/Block/Banner.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use Expressly\Event\BannerEvent;
4
+ use Expressly\Exception\GenericException;
5
+ use Expressly\Helper\BannerHelper;
6
+ use Expressly\Subscriber\BannerSubscriber;
7
+
8
+ class Expressly_Expressly_Block_Banner extends Mage_Core_Block_Template
9
+ {
10
+ protected function _toHtml()
11
+ {
12
+ $helper = new Expressly_Expressly_Helper_Client();
13
+ $app = $helper->getApp();
14
+
15
+ $provider = $app['merchant.provider'];
16
+
17
+ $merchant = $provider->getMerchant();
18
+ $email = Mage::getSingleton('customer/session')->getCustomer()->getEmail();
19
+
20
+ $event = new BannerEvent($merchant, $email);
21
+
22
+ try {
23
+ $helper->dispatcher->dispatch(BannerSubscriber::BANNER_REQUEST, $event);
24
+
25
+ if (!$event->isSuccessful()) {
26
+ throw new GenericException(Expressly_Expressly_Helper_Client::errorFormatter($event));
27
+ }
28
+
29
+ } catch (GenericException $e) {
30
+ $helper->logger->error($e);
31
+
32
+ return '';
33
+ }
34
+
35
+ return BannerHelper::toHtml($event);
36
+ }
37
+ }
app/code/community/Expressly/Expressly/Block/Popup.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ *
5
+ */
6
+ class Expressly_Expressly_Block_Popup extends Mage_Core_Block_Abstract
7
+ {
8
+ public function _toHtml($text)
9
+ {
10
+ return '<script type="text/javascript"></script>';
11
+ }
12
+ }
app/code/community/Expressly/Expressly/Block/System/Config/Form/ImageUrl.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ *
5
+ */
6
+ class Expressly_Expressly_Block_System_Config_Form_ImageUrl extends Mage_Adminhtml_Block_System_Config_Form_Field
7
+ {
8
+
9
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
10
+ {
11
+ $extra = '';
12
+
13
+ if ($element->getValue()) {
14
+ $extra = '<img style="max-height:100px;" src="' . $element->getValue() . '" /><br />';
15
+ }
16
+
17
+ return $extra . parent::_getElementHtml($element);
18
+ }
19
+ }
app/code/community/Expressly/Expressly/Block/System/Config/Form/Register.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Expressly_Expressly_Block_System_Config_Form_Register extends Mage_Adminhtml_Block_System_Config_Form_Field
4
+ {
5
+ protected function _prepareLayout()
6
+ {
7
+ parent::_prepareLayout();
8
+ if (!$this->getTemplate()) {
9
+ $this->setTemplate('expressly/register.phtml');
10
+ }
11
+
12
+ return $this;
13
+ }
14
+
15
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
16
+ {
17
+ $originalData = $element->getOriginalData();
18
+ $this->addData(array(
19
+ 'button_label' => Mage::helper('customer')->__($originalData['button_label']),
20
+ 'html_id' => $element->getHtmlId()
21
+ ));
22
+
23
+ return $this->_toHtml();
24
+ }
25
+ }
app/code/community/Expressly/Expressly/Helper/Client.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use Expressly\Client;
4
+ use Expressly\Entity\MerchantType;
5
+ use Expressly\Expressly\MerchantProvider;
6
+
7
+ class Expressly_Expressly_Helper_Client extends Mage_Core_Helper_Abstract
8
+ {
9
+ private $app;
10
+
11
+ public function __construct()
12
+ {
13
+ require_once __DIR__ . '/../vendor/autoload.php';
14
+ require_once __DIR__ . '/../controllers/AbstractController.php';
15
+
16
+ $client = new Client(MerchantType::MAGENTO);
17
+ $app = $client->getApp();
18
+
19
+ $app['merchant.provider'] = $app->share(function () use ($app) {
20
+ return new MerchantProvider($app);
21
+ });
22
+
23
+ $this->app = $app;
24
+ $this->dispatcher = $app['dispatcher'];
25
+ $this->logger = $app['logger'];
26
+ }
27
+
28
+ public function getApp()
29
+ {
30
+ return $this->app;
31
+ }
32
+
33
+ public static function errorFormatter($event)
34
+ {
35
+ $content = $event->getContent();
36
+ $message = array(
37
+ $content['description']
38
+ );
39
+ $addBulletpoints = function ($key, $title) use ($content, &$message) {
40
+ if (!empty($content[$key])) {
41
+ $message[] = '<br>';
42
+ $message[] = $title;
43
+ $message[] = '<ul>';
44
+ foreach ($content[$key] as $point) {
45
+ $message[] = "<li>{$point}</li>";
46
+ }
47
+ $message[] = '</ul>';
48
+ }
49
+ };
50
+ // TODO: translatable
51
+ $addBulletpoints('causes', 'Possible causes:');
52
+ $addBulletpoints('actions', 'Possible resolutions:');
53
+
54
+ return implode('', $message);
55
+ }
56
+ }
app/code/community/Expressly/Expressly/Helper/Data.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ class Expressly_Expressly_Helper_Data extends Mage_Core_Helper_Abstract
4
+ {
5
+ }
app/code/community/Expressly/Expressly/Model/Observer.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use Expressly\Event\MerchantEvent;
4
+ use Expressly\Event\PasswordedEvent;
5
+ use Expressly\Exception\ExceptionFormatter;
6
+ use Expressly\Exception\GenericException;
7
+
8
+ class Expressly_Expressly_Model_Observer extends Varien_Event_Observer
9
+ {
10
+ public function controllerFrontInitBefore($observer)
11
+ {
12
+ require_once __DIR__ . '/../controllers/AbstractController.php';
13
+ }
14
+
15
+ public function registerUpdateMerchant($observer)
16
+ {
17
+ $helper = new Expressly_Expressly_Helper_Client();
18
+ $app = $helper->getApp();
19
+ $provider = $app['merchant.provider'];
20
+ $dispatcher = $app['dispatcher'];
21
+ // get uuid
22
+ $merchant = $provider->getMerchant();
23
+ $uuid = $merchant->getUuid();
24
+ $password = $merchant->getPassword();
25
+ $event = new PasswordedEvent($merchant);
26
+
27
+ try {
28
+ if (empty($uuid) && empty($password)) {
29
+ $event = new MerchantEvent($merchant);
30
+ $dispatcher->dispatch('merchant.register', $event);
31
+ } else {
32
+ $dispatcher->dispatch('merchant.update', $event);
33
+ }
34
+
35
+ $content = $event->getContent();
36
+ if (!$event->isSuccessful()) {
37
+ throw new GenericException($content);
38
+ }
39
+
40
+ if (empty($uuid) && empty($password)) {
41
+ $merchant
42
+ ->setUuid($content['merchantUuid'])
43
+ ->setPassword($content['secretKey']);
44
+
45
+ $provider->setMerchant($merchant);
46
+ }
47
+ } catch (\Exception $e) {
48
+ $app['logger']->error(ExceptionFormatter::format($e));
49
+
50
+ $response = array('error' => -1, 'message' => $helper->__('Your values could not be transmitted to the server. Please try resubmitting, or contacting info@buyexpressly.com'));
51
+ \Mage::app()->getResponse()->setBody(Mage::helper('core')->jsonEncode($response));
52
+ }
53
+ }
54
+ }
app/code/community/Expressly/Expressly/Model/Resource/Setup.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Expressly_Expressly_Model_Resource_Setup extends Mage_Core_Model_Resource_Setup
4
+ {
5
+ public static function getResourceModel()
6
+ {
7
+ return \Mage::getResourceModel('core/config');
8
+ }
9
+
10
+ public static function getBaseUrl()
11
+ {
12
+ return \Mage::app()->getStore()->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_DIRECT_LINK, true);
13
+ }
14
+ }
app/code/community/Expressly/Expressly/composer.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "expressly/magento",
3
+ "description": "Expressly Magento 1.5-1.9 Module",
4
+ "type": "module",
5
+ "license": "MIT",
6
+ "authors": [
7
+ {
8
+ "name": "Sam Pratt",
9
+ "email": "sam@buyexpressly.com"
10
+ }
11
+ ],
12
+ "require": {
13
+ "expressly/php-common": "~1.1.0"
14
+ },
15
+ "repositories": [
16
+ {
17
+ "type": "vcs",
18
+ "url": "https://github.com/expressly/php-common"
19
+ }
20
+ ],
21
+ "autoload": {
22
+ "psr-4": {
23
+ "Expressly\\Expressly\\": "lib/"
24
+ }
25
+ }
26
+ }
app/code/community/Expressly/Expressly/composer.lock ADDED
@@ -0,0 +1,988 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_readme": [
3
+ "This file locks the dependencies of your project to a known state",
4
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5
+ "This file is @generated automatically"
6
+ ],
7
+ "hash": "952759db2a2a80728e819fea23aa91e0",
8
+ "content-hash": "83584061f998b698f84b223584dc87d1",
9
+ "packages": [
10
+ {
11
+ "name": "deralex/yaml-config-service-provider",
12
+ "version": "1.0.1",
13
+ "source": {
14
+ "type": "git",
15
+ "url": "https://github.com/deralex/YamlConfigServiceProvider.git",
16
+ "reference": "5923f60e6fbb16432e47310cf9680fe658c8dc0e"
17
+ },
18
+ "dist": {
19
+ "type": "zip",
20
+ "url": "https://api.github.com/repos/deralex/YamlConfigServiceProvider/zipball/5923f60e6fbb16432e47310cf9680fe658c8dc0e",
21
+ "reference": "5923f60e6fbb16432e47310cf9680fe658c8dc0e",
22
+ "shasum": ""
23
+ },
24
+ "require": {
25
+ "silex/silex": ">=1.0 <=1.3",
26
+ "symfony/yaml": "~2.4"
27
+ },
28
+ "require-dev": {
29
+ "phpspec/phpspec": "2.0.*@dev"
30
+ },
31
+ "suggest": {
32
+ "symfony/yaml": "~2.4"
33
+ },
34
+ "type": "library",
35
+ "extra": {
36
+ "branch-alias": {
37
+ "dev-master": "1.0-dev"
38
+ }
39
+ },
40
+ "autoload": {
41
+ "psr-0": {
42
+ "DerAlex\\Silex": "src"
43
+ }
44
+ },
45
+ "notification-url": "https://packagist.org/downloads/",
46
+ "license": [
47
+ "MIT"
48
+ ],
49
+ "authors": [
50
+ {
51
+ "name": "Alexander Kluth",
52
+ "email": "contact@alexanderkluth.com"
53
+ }
54
+ ],
55
+ "description": "Silex ServiceProvider for using YAML configuration files",
56
+ "keywords": [
57
+ "silex"
58
+ ],
59
+ "time": "2015-03-10 12:58:27"
60
+ },
61
+ {
62
+ "name": "doctrine/collections",
63
+ "version": "v1.3.0",
64
+ "source": {
65
+ "type": "git",
66
+ "url": "https://github.com/doctrine/collections.git",
67
+ "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a"
68
+ },
69
+ "dist": {
70
+ "type": "zip",
71
+ "url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
72
+ "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
73
+ "shasum": ""
74
+ },
75
+ "require": {
76
+ "php": ">=5.3.2"
77
+ },
78
+ "require-dev": {
79
+ "phpunit/phpunit": "~4.0"
80
+ },
81
+ "type": "library",
82
+ "extra": {
83
+ "branch-alias": {
84
+ "dev-master": "1.2.x-dev"
85
+ }
86
+ },
87
+ "autoload": {
88
+ "psr-0": {
89
+ "Doctrine\\Common\\Collections\\": "lib/"
90
+ }
91
+ },
92
+ "notification-url": "https://packagist.org/downloads/",
93
+ "license": [
94
+ "MIT"
95
+ ],
96
+ "authors": [
97
+ {
98
+ "name": "Roman Borschel",
99
+ "email": "roman@code-factory.org"
100
+ },
101
+ {
102
+ "name": "Benjamin Eberlei",
103
+ "email": "kontakt@beberlei.de"
104
+ },
105
+ {
106
+ "name": "Guilherme Blanco",
107
+ "email": "guilhermeblanco@gmail.com"
108
+ },
109
+ {
110
+ "name": "Jonathan Wage",
111
+ "email": "jonwage@gmail.com"
112
+ },
113
+ {
114
+ "name": "Johannes Schmitt",
115
+ "email": "schmittjoh@gmail.com"
116
+ }
117
+ ],
118
+ "description": "Collections Abstraction library",
119
+ "homepage": "http://www.doctrine-project.org",
120
+ "keywords": [
121
+ "array",
122
+ "collections",
123
+ "iterator"
124
+ ],
125
+ "time": "2015-04-14 22:21:58"
126
+ },
127
+ {
128
+ "name": "expressly/php-common",
129
+ "version": "1.1.6",
130
+ "source": {
131
+ "type": "git",
132
+ "url": "https://github.com/expressly/php-common.git",
133
+ "reference": "7fcf212fdcd4967b23ce087cf19a6fed440b1b52"
134
+ },
135
+ "dist": {
136
+ "type": "zip",
137
+ "url": "https://api.github.com/repos/expressly/php-common/zipball/7fcf212fdcd4967b23ce087cf19a6fed440b1b52",
138
+ "reference": "7fcf212fdcd4967b23ce087cf19a6fed440b1b52",
139
+ "shasum": ""
140
+ },
141
+ "require": {
142
+ "deralex/yaml-config-service-provider": "1.0.1",
143
+ "doctrine/collections": "1.3.0",
144
+ "kriswallsmith/buzz": "0.13",
145
+ "monolog/monolog": "1.13.1",
146
+ "php": ">=5.3.0",
147
+ "predis/predis": "1.0.1",
148
+ "silex/silex": "1.2.4",
149
+ "symfony/config": "2.6.7",
150
+ "symfony/yaml": "2.6.7"
151
+ },
152
+ "require-dev": {
153
+ "phpunit/phpunit": "4.6.6"
154
+ },
155
+ "type": "library",
156
+ "autoload": {
157
+ "psr-4": {
158
+ "Expressly\\": "src/"
159
+ }
160
+ },
161
+ "license": [
162
+ "MIT"
163
+ ],
164
+ "authors": [
165
+ {
166
+ "name": "Sam Pratt",
167
+ "email": "sam@buyexpressly.com"
168
+ }
169
+ ],
170
+ "description": "Expressly common PHP library",
171
+ "support": {
172
+ "source": "https://github.com/expressly/php-common/tree/1.1.6",
173
+ "issues": "https://github.com/expressly/php-common/issues"
174
+ },
175
+ "time": "2015-09-25 12:59:26"
176
+ },
177
+ {
178
+ "name": "kriswallsmith/buzz",
179
+ "version": "v0.13",
180
+ "source": {
181
+ "type": "git",
182
+ "url": "https://github.com/kriswallsmith/Buzz.git",
183
+ "reference": "487760b05d6269a4c2c374364325326cfa65b12c"
184
+ },
185
+ "dist": {
186
+ "type": "zip",
187
+ "url": "https://api.github.com/repos/kriswallsmith/Buzz/zipball/487760b05d6269a4c2c374364325326cfa65b12c",
188
+ "reference": "487760b05d6269a4c2c374364325326cfa65b12c",
189
+ "shasum": ""
190
+ },
191
+ "require": {
192
+ "php": ">=5.3.0"
193
+ },
194
+ "require-dev": {
195
+ "phpunit/phpunit": "3.7.*"
196
+ },
197
+ "suggest": {
198
+ "ext-curl": "*"
199
+ },
200
+ "type": "library",
201
+ "autoload": {
202
+ "psr-0": {
203
+ "Buzz": "lib/"
204
+ }
205
+ },
206
+ "notification-url": "https://packagist.org/downloads/",
207
+ "license": [
208
+ "MIT"
209
+ ],
210
+ "authors": [
211
+ {
212
+ "name": "Kris Wallsmith",
213
+ "email": "kris.wallsmith@gmail.com",
214
+ "homepage": "http://kriswallsmith.net/"
215
+ }
216
+ ],
217
+ "description": "Lightweight HTTP client",
218
+ "homepage": "https://github.com/kriswallsmith/Buzz",
219
+ "keywords": [
220
+ "curl",
221
+ "http client"
222
+ ],
223
+ "time": "2014-09-15 12:42:36"
224
+ },
225
+ {
226
+ "name": "monolog/monolog",
227
+ "version": "1.13.1",
228
+ "source": {
229
+ "type": "git",
230
+ "url": "https://github.com/Seldaek/monolog.git",
231
+ "reference": "c31a2c4e8db5da8b46c74cf275d7f109c0f249ac"
232
+ },
233
+ "dist": {
234
+ "type": "zip",
235
+ "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c31a2c4e8db5da8b46c74cf275d7f109c0f249ac",
236
+ "reference": "c31a2c4e8db5da8b46c74cf275d7f109c0f249ac",
237
+ "shasum": ""
238
+ },
239
+ "require": {
240
+ "php": ">=5.3.0",
241
+ "psr/log": "~1.0"
242
+ },
243
+ "provide": {
244
+ "psr/log-implementation": "1.0.0"
245
+ },
246
+ "require-dev": {
247
+ "aws/aws-sdk-php": "~2.4, >2.4.8",
248
+ "doctrine/couchdb": "~1.0@dev",
249
+ "graylog2/gelf-php": "~1.0",
250
+ "phpunit/phpunit": "~4.0",
251
+ "raven/raven": "~0.5",
252
+ "ruflin/elastica": "0.90.*",
253
+ "swiftmailer/swiftmailer": "~5.3",
254
+ "videlalvaro/php-amqplib": "~2.4"
255
+ },
256
+ "suggest": {
257
+ "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
258
+ "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
259
+ "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
260
+ "ext-mongo": "Allow sending log messages to a MongoDB server",
261
+ "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
262
+ "raven/raven": "Allow sending log messages to a Sentry server",
263
+ "rollbar/rollbar": "Allow sending log messages to Rollbar",
264
+ "ruflin/elastica": "Allow sending log messages to an Elastic Search server",
265
+ "videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib"
266
+ },
267
+ "type": "library",
268
+ "extra": {
269
+ "branch-alias": {
270
+ "dev-master": "1.13.x-dev"
271
+ }
272
+ },
273
+ "autoload": {
274
+ "psr-4": {
275
+ "Monolog\\": "src/Monolog"
276
+ }
277
+ },
278
+ "notification-url": "https://packagist.org/downloads/",
279
+ "license": [
280
+ "MIT"
281
+ ],
282
+ "authors": [
283
+ {
284
+ "name": "Jordi Boggiano",
285
+ "email": "j.boggiano@seld.be",
286
+ "homepage": "http://seld.be"
287
+ }
288
+ ],
289
+ "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
290
+ "homepage": "http://github.com/Seldaek/monolog",
291
+ "keywords": [
292
+ "log",
293
+ "logging",
294
+ "psr-3"
295
+ ],
296
+ "time": "2015-03-09 09:58:04"
297
+ },
298
+ {
299
+ "name": "pimple/pimple",
300
+ "version": "v1.1.1",
301
+ "source": {
302
+ "type": "git",
303
+ "url": "https://github.com/silexphp/Pimple.git",
304
+ "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d"
305
+ },
306
+ "dist": {
307
+ "type": "zip",
308
+ "url": "https://api.github.com/repos/silexphp/Pimple/zipball/2019c145fe393923f3441b23f29bbdfaa5c58c4d",
309
+ "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d",
310
+ "shasum": ""
311
+ },
312
+ "require": {
313
+ "php": ">=5.3.0"
314
+ },
315
+ "type": "library",
316
+ "extra": {
317
+ "branch-alias": {
318
+ "dev-master": "1.1.x-dev"
319
+ }
320
+ },
321
+ "autoload": {
322
+ "psr-0": {
323
+ "Pimple": "lib/"
324
+ }
325
+ },
326
+ "notification-url": "https://packagist.org/downloads/",
327
+ "license": [
328
+ "MIT"
329
+ ],
330
+ "authors": [
331
+ {
332
+ "name": "Fabien Potencier",
333
+ "email": "fabien@symfony.com"
334
+ }
335
+ ],
336
+ "description": "Pimple is a simple Dependency Injection Container for PHP 5.3",
337
+ "homepage": "http://pimple.sensiolabs.org",
338
+ "keywords": [
339
+ "container",
340
+ "dependency injection"
341
+ ],
342
+ "time": "2013-11-22 08:30:29"
343
+ },
344
+ {
345
+ "name": "predis/predis",
346
+ "version": "v1.0.1",
347
+ "source": {
348
+ "type": "git",
349
+ "url": "https://github.com/nrk/predis.git",
350
+ "reference": "7a170b3d8123c556597b4fbdb88631f99de180c2"
351
+ },
352
+ "dist": {
353
+ "type": "zip",
354
+ "url": "https://api.github.com/repos/nrk/predis/zipball/7a170b3d8123c556597b4fbdb88631f99de180c2",
355
+ "reference": "7a170b3d8123c556597b4fbdb88631f99de180c2",
356
+ "shasum": ""
357
+ },
358
+ "require": {
359
+ "php": ">=5.3.2"
360
+ },
361
+ "require-dev": {
362
+ "phpunit/phpunit": "~4.0"
363
+ },
364
+ "suggest": {
365
+ "ext-curl": "Allows access to Webdis when paired with phpiredis",
366
+ "ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol"
367
+ },
368
+ "type": "library",
369
+ "autoload": {
370
+ "psr-4": {
371
+ "Predis\\": "src/"
372
+ }
373
+ },
374
+ "notification-url": "https://packagist.org/downloads/",
375
+ "license": [
376
+ "MIT"
377
+ ],
378
+ "authors": [
379
+ {
380
+ "name": "Daniele Alessandri",
381
+ "email": "suppakilla@gmail.com",
382
+ "homepage": "http://clorophilla.net"
383
+ }
384
+ ],
385
+ "description": "Flexible and feature-complete PHP client library for Redis",
386
+ "homepage": "http://github.com/nrk/predis",
387
+ "keywords": [
388
+ "nosql",
389
+ "predis",
390
+ "redis"
391
+ ],
392
+ "time": "2015-01-02 12:51:34"
393
+ },
394
+ {
395
+ "name": "psr/log",
396
+ "version": "1.0.0",
397
+ "source": {
398
+ "type": "git",
399
+ "url": "https://github.com/php-fig/log.git",
400
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
401
+ },
402
+ "dist": {
403
+ "type": "zip",
404
+ "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
405
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
406
+ "shasum": ""
407
+ },
408
+ "type": "library",
409
+ "autoload": {
410
+ "psr-0": {
411
+ "Psr\\Log\\": ""
412
+ }
413
+ },
414
+ "notification-url": "https://packagist.org/downloads/",
415
+ "license": [
416
+ "MIT"
417
+ ],
418
+ "authors": [
419
+ {
420
+ "name": "PHP-FIG",
421
+ "homepage": "http://www.php-fig.org/"
422
+ }
423
+ ],
424
+ "description": "Common interface for logging libraries",
425
+ "keywords": [
426
+ "log",
427
+ "psr",
428
+ "psr-3"
429
+ ],
430
+ "time": "2012-12-21 11:40:51"
431
+ },
432
+ {
433
+ "name": "silex/silex",
434
+ "version": "v1.2.4",
435
+ "source": {
436
+ "type": "git",
437
+ "url": "https://github.com/silexphp/Silex.git",
438
+ "reference": "417deb440eecf776df868d8760d0b7d8e2c4e6d1"
439
+ },
440
+ "dist": {
441
+ "type": "zip",
442
+ "url": "https://api.github.com/repos/silexphp/Silex/zipball/417deb440eecf776df868d8760d0b7d8e2c4e6d1",
443
+ "reference": "417deb440eecf776df868d8760d0b7d8e2c4e6d1",
444
+ "shasum": ""
445
+ },
446
+ "require": {
447
+ "php": ">=5.3.3",
448
+ "pimple/pimple": "~1.0",
449
+ "symfony/event-dispatcher": "~2.3,<2.7",
450
+ "symfony/http-foundation": "~2.3,<2.7",
451
+ "symfony/http-kernel": "~2.3,<2.7",
452
+ "symfony/routing": "~2.3,<2.7"
453
+ },
454
+ "require-dev": {
455
+ "doctrine/dbal": "~2.2",
456
+ "monolog/monolog": "~1.4,>=1.4.1",
457
+ "swiftmailer/swiftmailer": "5.*",
458
+ "symfony/browser-kit": "~2.3,<2.7",
459
+ "symfony/config": "~2.3,<2.7",
460
+ "symfony/css-selector": "~2.3,<2.7",
461
+ "symfony/debug": "~2.3,<2.7",
462
+ "symfony/dom-crawler": "~2.3,<2.7",
463
+ "symfony/finder": "~2.3,<2.7",
464
+ "symfony/form": "~2.3,<2.7",
465
+ "symfony/locale": "~2.3,<2.7",
466
+ "symfony/monolog-bridge": "~2.3,<2.7",
467
+ "symfony/options-resolver": "~2.3,<2.7",
468
+ "symfony/process": "~2.3,<2.7",
469
+ "symfony/security": "~2.3,<2.7",
470
+ "symfony/serializer": "~2.3,<2.7",
471
+ "symfony/translation": "~2.3,<2.7",
472
+ "symfony/twig-bridge": "~2.3,<2.7",
473
+ "symfony/validator": "~2.3,<2.7",
474
+ "twig/twig": ">=1.8.0,<2.0-dev"
475
+ },
476
+ "suggest": {
477
+ "symfony/browser-kit": "~2.3",
478
+ "symfony/css-selector": "~2.3",
479
+ "symfony/dom-crawler": "~2.3",
480
+ "symfony/form": "~2.3"
481
+ },
482
+ "type": "library",
483
+ "extra": {
484
+ "branch-alias": {
485
+ "dev-master": "1.2.x-dev"
486
+ }
487
+ },
488
+ "autoload": {
489
+ "psr-0": {
490
+ "Silex": "src/"
491
+ }
492
+ },
493
+ "notification-url": "https://packagist.org/downloads/",
494
+ "license": [
495
+ "MIT"
496
+ ],
497
+ "authors": [
498
+ {
499
+ "name": "Fabien Potencier",
500
+ "email": "fabien@symfony.com"
501
+ },
502
+ {
503
+ "name": "Igor Wiedler",
504
+ "email": "igor@wiedler.ch"
505
+ }
506
+ ],
507
+ "description": "The PHP micro-framework based on the Symfony2 Components",
508
+ "homepage": "http://silex.sensiolabs.org",
509
+ "keywords": [
510
+ "microframework"
511
+ ],
512
+ "time": "2015-04-11 12:43:27"
513
+ },
514
+ {
515
+ "name": "symfony/config",
516
+ "version": "v2.6.7",
517
+ "target-dir": "Symfony/Component/Config",
518
+ "source": {
519
+ "type": "git",
520
+ "url": "https://github.com/symfony/config.git",
521
+ "reference": "b6fddb4aa2daaa2b06f0040071ac131b4a1ecf25"
522
+ },
523
+ "dist": {
524
+ "type": "zip",
525
+ "url": "https://api.github.com/repos/symfony/config/zipball/b6fddb4aa2daaa2b06f0040071ac131b4a1ecf25",
526
+ "reference": "b6fddb4aa2daaa2b06f0040071ac131b4a1ecf25",
527
+ "shasum": ""
528
+ },
529
+ "require": {
530
+ "php": ">=5.3.3",
531
+ "symfony/filesystem": "~2.3"
532
+ },
533
+ "require-dev": {
534
+ "symfony/phpunit-bridge": "~2.7"
535
+ },
536
+ "type": "library",
537
+ "extra": {
538
+ "branch-alias": {
539
+ "dev-master": "2.6-dev"
540
+ }
541
+ },
542
+ "autoload": {
543
+ "psr-0": {
544
+ "Symfony\\Component\\Config\\": ""
545
+ }
546
+ },
547
+ "notification-url": "https://packagist.org/downloads/",
548
+ "license": [
549
+ "MIT"
550
+ ],
551
+ "authors": [
552
+ {
553
+ "name": "Fabien Potencier",
554
+ "email": "fabien@symfony.com"
555
+ },
556
+ {
557
+ "name": "Symfony Community",
558
+ "homepage": "https://symfony.com/contributors"
559
+ }
560
+ ],
561
+ "description": "Symfony Config Component",
562
+ "homepage": "https://symfony.com",
563
+ "time": "2015-05-02 15:18:45"
564
+ },
565
+ {
566
+ "name": "symfony/debug",
567
+ "version": "v2.7.5",
568
+ "source": {
569
+ "type": "git",
570
+ "url": "https://github.com/symfony/debug.git",
571
+ "reference": "c79c361bca8e5ada6a47603875a3c964d03b67b1"
572
+ },
573
+ "dist": {
574
+ "type": "zip",
575
+ "url": "https://api.github.com/repos/symfony/debug/zipball/c79c361bca8e5ada6a47603875a3c964d03b67b1",
576
+ "reference": "c79c361bca8e5ada6a47603875a3c964d03b67b1",
577
+ "shasum": ""
578
+ },
579
+ "require": {
580
+ "php": ">=5.3.9",
581
+ "psr/log": "~1.0"
582
+ },
583
+ "conflict": {
584
+ "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
585
+ },
586
+ "require-dev": {
587
+ "symfony/class-loader": "~2.2",
588
+ "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2",
589
+ "symfony/phpunit-bridge": "~2.7"
590
+ },
591
+ "type": "library",
592
+ "extra": {
593
+ "branch-alias": {
594
+ "dev-master": "2.7-dev"
595
+ }
596
+ },
597
+ "autoload": {
598
+ "psr-4": {
599
+ "Symfony\\Component\\Debug\\": ""
600
+ }
601
+ },
602
+ "notification-url": "https://packagist.org/downloads/",
603
+ "license": [
604
+ "MIT"
605
+ ],
606
+ "authors": [
607
+ {
608
+ "name": "Fabien Potencier",
609
+ "email": "fabien@symfony.com"
610
+ },
611
+ {
612
+ "name": "Symfony Community",
613
+ "homepage": "https://symfony.com/contributors"
614
+ }
615
+ ],
616
+ "description": "Symfony Debug Component",
617
+ "homepage": "https://symfony.com",
618
+ "time": "2015-09-14 08:41:38"
619
+ },
620
+ {
621
+ "name": "symfony/event-dispatcher",
622
+ "version": "v2.6.11",
623
+ "target-dir": "Symfony/Component/EventDispatcher",
624
+ "source": {
625
+ "type": "git",
626
+ "url": "https://github.com/symfony/event-dispatcher.git",
627
+ "reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02"
628
+ },
629
+ "dist": {
630
+ "type": "zip",
631
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/672593bc4b0043a0acf91903bb75a1c82d8f2e02",
632
+ "reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02",
633
+ "shasum": ""
634
+ },
635
+ "require": {
636
+ "php": ">=5.3.3"
637
+ },
638
+ "require-dev": {
639
+ "psr/log": "~1.0",
640
+ "symfony/config": "~2.0,>=2.0.5",
641
+ "symfony/dependency-injection": "~2.6",
642
+ "symfony/expression-language": "~2.6",
643
+ "symfony/phpunit-bridge": "~2.7",
644
+ "symfony/stopwatch": "~2.3"
645
+ },
646
+ "suggest": {
647
+ "symfony/dependency-injection": "",
648
+ "symfony/http-kernel": ""
649
+ },
650
+ "type": "library",
651
+ "extra": {
652
+ "branch-alias": {
653
+ "dev-master": "2.6-dev"
654
+ }
655
+ },
656
+ "autoload": {
657
+ "psr-0": {
658
+ "Symfony\\Component\\EventDispatcher\\": ""
659
+ }
660
+ },
661
+ "notification-url": "https://packagist.org/downloads/",
662
+ "license": [
663
+ "MIT"
664
+ ],
665
+ "authors": [
666
+ {
667
+ "name": "Fabien Potencier",
668
+ "email": "fabien@symfony.com"
669
+ },
670
+ {
671
+ "name": "Symfony Community",
672
+ "homepage": "https://symfony.com/contributors"
673
+ }
674
+ ],
675
+ "description": "Symfony EventDispatcher Component",
676
+ "homepage": "https://symfony.com",
677
+ "time": "2015-05-02 15:18:45"
678
+ },
679
+ {
680
+ "name": "symfony/filesystem",
681
+ "version": "v2.7.5",
682
+ "source": {
683
+ "type": "git",
684
+ "url": "https://github.com/symfony/filesystem.git",
685
+ "reference": "a17f8a17c20e8614c15b8e116e2f4bcde102cfab"
686
+ },
687
+ "dist": {
688
+ "type": "zip",
689
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/a17f8a17c20e8614c15b8e116e2f4bcde102cfab",
690
+ "reference": "a17f8a17c20e8614c15b8e116e2f4bcde102cfab",
691
+ "shasum": ""
692
+ },
693
+ "require": {
694
+ "php": ">=5.3.9"
695
+ },
696
+ "require-dev": {
697
+ "symfony/phpunit-bridge": "~2.7"
698
+ },
699
+ "type": "library",
700
+ "extra": {
701
+ "branch-alias": {
702
+ "dev-master": "2.7-dev"
703
+ }
704
+ },
705
+ "autoload": {
706
+ "psr-4": {
707
+ "Symfony\\Component\\Filesystem\\": ""
708
+ }
709
+ },
710
+ "notification-url": "https://packagist.org/downloads/",
711
+ "license": [
712
+ "MIT"
713
+ ],
714
+ "authors": [
715
+ {
716
+ "name": "Fabien Potencier",
717
+ "email": "fabien@symfony.com"
718
+ },
719
+ {
720
+ "name": "Symfony Community",
721
+ "homepage": "https://symfony.com/contributors"
722
+ }
723
+ ],
724
+ "description": "Symfony Filesystem Component",
725
+ "homepage": "https://symfony.com",
726
+ "time": "2015-09-09 17:42:36"
727
+ },
728
+ {
729
+ "name": "symfony/http-foundation",
730
+ "version": "v2.6.11",
731
+ "target-dir": "Symfony/Component/HttpFoundation",
732
+ "source": {
733
+ "type": "git",
734
+ "url": "https://github.com/symfony/http-foundation.git",
735
+ "reference": "e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c"
736
+ },
737
+ "dist": {
738
+ "type": "zip",
739
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c",
740
+ "reference": "e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c",
741
+ "shasum": ""
742
+ },
743
+ "require": {
744
+ "php": ">=5.3.3"
745
+ },
746
+ "require-dev": {
747
+ "symfony/expression-language": "~2.4",
748
+ "symfony/phpunit-bridge": "~2.7"
749
+ },
750
+ "type": "library",
751
+ "extra": {
752
+ "branch-alias": {
753
+ "dev-master": "2.6-dev"
754
+ }
755
+ },
756
+ "autoload": {
757
+ "psr-0": {
758
+ "Symfony\\Component\\HttpFoundation\\": ""
759
+ },
760
+ "classmap": [
761
+ "Symfony/Component/HttpFoundation/Resources/stubs"
762
+ ]
763
+ },
764
+ "notification-url": "https://packagist.org/downloads/",
765
+ "license": [
766
+ "MIT"
767
+ ],
768
+ "authors": [
769
+ {
770
+ "name": "Fabien Potencier",
771
+ "email": "fabien@symfony.com"
772
+ },
773
+ {
774
+ "name": "Symfony Community",
775
+ "homepage": "https://symfony.com/contributors"
776
+ }
777
+ ],
778
+ "description": "Symfony HttpFoundation Component",
779
+ "homepage": "https://symfony.com",
780
+ "time": "2015-07-22 10:08:40"
781
+ },
782
+ {
783
+ "name": "symfony/http-kernel",
784
+ "version": "v2.6.11",
785
+ "target-dir": "Symfony/Component/HttpKernel",
786
+ "source": {
787
+ "type": "git",
788
+ "url": "https://github.com/symfony/http-kernel.git",
789
+ "reference": "a3f0ed713255c0400a2db38b3ed01989ef4b7322"
790
+ },
791
+ "dist": {
792
+ "type": "zip",
793
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/a3f0ed713255c0400a2db38b3ed01989ef4b7322",
794
+ "reference": "a3f0ed713255c0400a2db38b3ed01989ef4b7322",
795
+ "shasum": ""
796
+ },
797
+ "require": {
798
+ "php": ">=5.3.3",
799
+ "psr/log": "~1.0",
800
+ "symfony/debug": "~2.6,>=2.6.2",
801
+ "symfony/event-dispatcher": "~2.6,>=2.6.7",
802
+ "symfony/http-foundation": "~2.5,>=2.5.4"
803
+ },
804
+ "require-dev": {
805
+ "symfony/browser-kit": "~2.3",
806
+ "symfony/class-loader": "~2.1",
807
+ "symfony/config": "~2.0,>=2.0.5",
808
+ "symfony/console": "~2.3",
809
+ "symfony/css-selector": "~2.0,>=2.0.5",
810
+ "symfony/dependency-injection": "~2.2",
811
+ "symfony/dom-crawler": "~2.0,>=2.0.5",
812
+ "symfony/expression-language": "~2.4",
813
+ "symfony/finder": "~2.0,>=2.0.5",
814
+ "symfony/phpunit-bridge": "~2.7",
815
+ "symfony/process": "~2.0,>=2.0.5",
816
+ "symfony/routing": "~2.2",
817
+ "symfony/stopwatch": "~2.3",
818
+ "symfony/templating": "~2.2",
819
+ "symfony/translation": "~2.0,>=2.0.5",
820
+ "symfony/var-dumper": "~2.6"
821
+ },
822
+ "suggest": {
823
+ "symfony/browser-kit": "",
824
+ "symfony/class-loader": "",
825
+ "symfony/config": "",
826
+ "symfony/console": "",
827
+ "symfony/dependency-injection": "",
828
+ "symfony/finder": "",
829
+ "symfony/var-dumper": ""
830
+ },
831
+ "type": "library",
832
+ "extra": {
833
+ "branch-alias": {
834
+ "dev-master": "2.6-dev"
835
+ }
836
+ },
837
+ "autoload": {
838
+ "psr-0": {
839
+ "Symfony\\Component\\HttpKernel\\": ""
840
+ }
841
+ },
842
+ "notification-url": "https://packagist.org/downloads/",
843
+ "license": [
844
+ "MIT"
845
+ ],
846
+ "authors": [
847
+ {
848
+ "name": "Fabien Potencier",
849
+ "email": "fabien@symfony.com"
850
+ },
851
+ {
852
+ "name": "Symfony Community",
853
+ "homepage": "https://symfony.com/contributors"
854
+ }
855
+ ],
856
+ "description": "Symfony HttpKernel Component",
857
+ "homepage": "https://symfony.com",
858
+ "time": "2015-07-26 10:44:22"
859
+ },
860
+ {
861
+ "name": "symfony/routing",
862
+ "version": "v2.6.11",
863
+ "target-dir": "Symfony/Component/Routing",
864
+ "source": {
865
+ "type": "git",
866
+ "url": "https://github.com/symfony/Routing.git",
867
+ "reference": "0a1764d41bbb54f3864808c50569ac382b44d128"
868
+ },
869
+ "dist": {
870
+ "type": "zip",
871
+ "url": "https://api.github.com/repos/symfony/Routing/zipball/0a1764d41bbb54f3864808c50569ac382b44d128",
872
+ "reference": "0a1764d41bbb54f3864808c50569ac382b44d128",
873
+ "shasum": ""
874
+ },
875
+ "require": {
876
+ "php": ">=5.3.3"
877
+ },
878
+ "require-dev": {
879
+ "doctrine/annotations": "~1.0",
880
+ "doctrine/common": "~2.2",
881
+ "psr/log": "~1.0",
882
+ "symfony/config": "~2.2",
883
+ "symfony/expression-language": "~2.4",
884
+ "symfony/http-foundation": "~2.3",
885
+ "symfony/phpunit-bridge": "~2.7",
886
+ "symfony/yaml": "~2.0,>=2.0.5"
887
+ },
888
+ "suggest": {
889
+ "doctrine/annotations": "For using the annotation loader",
890
+ "symfony/config": "For using the all-in-one router or any loader",
891
+ "symfony/expression-language": "For using expression matching",
892
+ "symfony/yaml": "For using the YAML loader"
893
+ },
894
+ "type": "library",
895
+ "extra": {
896
+ "branch-alias": {
897
+ "dev-master": "2.6-dev"
898
+ }
899
+ },
900
+ "autoload": {
901
+ "psr-0": {
902
+ "Symfony\\Component\\Routing\\": ""
903
+ }
904
+ },
905
+ "notification-url": "https://packagist.org/downloads/",
906
+ "license": [
907
+ "MIT"
908
+ ],
909
+ "authors": [
910
+ {
911
+ "name": "Fabien Potencier",
912
+ "email": "fabien@symfony.com"
913
+ },
914
+ {
915
+ "name": "Symfony Community",
916
+ "homepage": "https://symfony.com/contributors"
917
+ }
918
+ ],
919
+ "description": "Symfony Routing Component",
920
+ "homepage": "https://symfony.com",
921
+ "keywords": [
922
+ "router",
923
+ "routing",
924
+ "uri",
925
+ "url"
926
+ ],
927
+ "time": "2015-07-09 16:02:48"
928
+ },
929
+ {
930
+ "name": "symfony/yaml",
931
+ "version": "v2.6.7",
932
+ "target-dir": "Symfony/Component/Yaml",
933
+ "source": {
934
+ "type": "git",
935
+ "url": "https://github.com/symfony/Yaml.git",
936
+ "reference": "f157ab074e453ecd4c0fa775f721f6e67a99d9e2"
937
+ },
938
+ "dist": {
939
+ "type": "zip",
940
+ "url": "https://api.github.com/repos/symfony/Yaml/zipball/f157ab074e453ecd4c0fa775f721f6e67a99d9e2",
941
+ "reference": "f157ab074e453ecd4c0fa775f721f6e67a99d9e2",
942
+ "shasum": ""
943
+ },
944
+ "require": {
945
+ "php": ">=5.3.3"
946
+ },
947
+ "require-dev": {
948
+ "symfony/phpunit-bridge": "~2.7"
949
+ },
950
+ "type": "library",
951
+ "extra": {
952
+ "branch-alias": {
953
+ "dev-master": "2.6-dev"
954
+ }
955
+ },
956
+ "autoload": {
957
+ "psr-0": {
958
+ "Symfony\\Component\\Yaml\\": ""
959
+ }
960
+ },
961
+ "notification-url": "https://packagist.org/downloads/",
962
+ "license": [
963
+ "MIT"
964
+ ],
965
+ "authors": [
966
+ {
967
+ "name": "Fabien Potencier",
968
+ "email": "fabien@symfony.com"
969
+ },
970
+ {
971
+ "name": "Symfony Community",
972
+ "homepage": "https://symfony.com/contributors"
973
+ }
974
+ ],
975
+ "description": "Symfony Yaml Component",
976
+ "homepage": "https://symfony.com",
977
+ "time": "2015-05-02 15:18:45"
978
+ }
979
+ ],
980
+ "packages-dev": [],
981
+ "aliases": [],
982
+ "minimum-stability": "stable",
983
+ "stability-flags": [],
984
+ "prefer-stable": false,
985
+ "prefer-lowest": false,
986
+ "platform": [],
987
+ "platform-dev": []
988
+ }
app/code/community/Expressly/Expressly/controllers/AbstractController.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Expressly;
4
+
5
+ use Expressly\Event\ResponseEvent;
6
+
7
+ abstract class AbstractController extends \Mage_Core_Controller_Front_Action
8
+ {
9
+ protected $app;
10
+ protected $dispatcher;
11
+ protected $logger;
12
+
13
+ public function __construct(
14
+ \Zend_Controller_Request_Abstract $request,
15
+ \Zend_Controller_Response_Abstract $response,
16
+ array $invokeArgs = array()
17
+ ) {
18
+ $helper = new \Expressly_Expressly_Helper_Client();
19
+ $this->app = $helper->getApp();
20
+ $this->dispatcher = $this->app['dispatcher'];
21
+ $this->logger = $this->app['logger'];
22
+
23
+ parent::__construct($request, $response, $invokeArgs);
24
+ }
25
+
26
+ public function processError(ResponseEvent $event)
27
+ {
28
+ $content = $event->getContent();
29
+ $message = array(
30
+ $content['description']
31
+ );
32
+
33
+ $addBulletPoints = function($data, $header) use (&$message) {
34
+ $message[] = $header;
35
+ foreach ($data as $point) {
36
+ $message[] = $point;
37
+ }
38
+ };
39
+
40
+ $addBulletPoints($content['causes'], 'Possible Causes:');
41
+ $addBulletPoints($content['actions'], 'Possible Actions:');
42
+
43
+ return implode(',', $message);
44
+ }
45
+ }
app/code/community/Expressly/Expressly/controllers/BatchController.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use Expressly\Entity\Invoice;
4
+ use Expressly\Entity\Order;
5
+ use Expressly\Exception\ExceptionFormatter;
6
+ use Expressly\Exception\GenericException;
7
+ use Expressly\Expressly\AbstractController;
8
+ use Expressly\Presenter\BatchCustomerPresenter;
9
+ use Expressly\Presenter\BatchInvoicePresenter;
10
+
11
+ class Expressly_Expressly_BatchController extends AbstractController
12
+ {
13
+ public function invoiceAction()
14
+ {
15
+ $json = file_get_contents('php://input');
16
+ $json = json_decode($json);
17
+ $invoices = array();
18
+
19
+ try {
20
+ if (!property_exists($json, 'customers')) {
21
+ throw new GenericException('Invalid JSON input');
22
+ }
23
+
24
+ $orderModel = Mage::getModel('sales/order');
25
+
26
+ foreach ($json->customers as $customer) {
27
+ if (!property_exists($customer, 'email')) {
28
+ continue;
29
+ }
30
+
31
+ $mageOrders = $orderModel
32
+ ->getCollection()
33
+ ->addFieldToFilter('customer_email', $customer->email)
34
+ ->setOrder('created_at', 'desc');
35
+
36
+ $invoice = new Invoice();
37
+ $invoice->setEmail($customer->email);
38
+ foreach ($mageOrders as $mageOrder) {
39
+ $total = $mageOrder->getData('base_grand_total');
40
+ $tax = $mageOrder->getData('base_tax_amount');
41
+
42
+ $order = new Order();
43
+ $order
44
+ ->setId($mageOrder->getData('increment_id'))
45
+ ->setDate(new \DateTime($mageOrder->getData('created_at')))
46
+ ->setCurrency($mageOrder->getData('base_currency_code'))
47
+ ->setTotal((double)$total - (double)$tax, (double)$tax)
48
+ ->setItemCount((int)$mageOrder->getData('total_qty_ordered'))
49
+ ->setCoupon($mageOrder->getData('coupon_code'));
50
+
51
+ $invoice->addOrder($order);
52
+ }
53
+
54
+ $invoices[] = $invoice;
55
+ }
56
+ } catch (\Exception $e) {
57
+ $this->logger->error(ExceptionFormatter::format($e));
58
+ }
59
+
60
+ $presenter = new BatchInvoicePresenter($invoices);
61
+ $this->getResponse()->setHeader('Content-type', 'application/json');
62
+ $this->getResponse()->setBody(json_encode($presenter->toArray()));
63
+ }
64
+
65
+ public function customerAction()
66
+ {
67
+ $json = file_get_contents('php://input');
68
+ $json = json_decode($json);
69
+ $customers = array();
70
+
71
+ try {
72
+ if (!property_exists($json, 'emails')) {
73
+ throw new GenericException('Invalid JSON input');
74
+ }
75
+
76
+ $customerModel = Mage::getModel('customer/customer');
77
+ $customerModel->setWebsiteId(Mage::app()->getWebsite()->getId());
78
+
79
+ foreach ($json->emails as $email) {
80
+ $customerModel->loadByEmail($email);
81
+
82
+ if ($customerModel->getId()) {
83
+ if ($customerModel->getData('is_active')) {
84
+ $customers['existing'][] = $email;
85
+ continue;
86
+ }
87
+
88
+ $customers['pending'][] = $email;
89
+ }
90
+ }
91
+ } catch (\Exception $e) {
92
+ $this->logger->error(ExceptionFormatter::format($e));
93
+ }
94
+
95
+ $presenter = new BatchCustomerPresenter($customers);
96
+ $this->getResponse()->setHeader('Content-type', 'application/json');
97
+ $this->getResponse()->setBody(json_encode($presenter->toArray()));
98
+ }
99
+ }
app/code/community/Expressly/Expressly/controllers/CustomerController.php ADDED
@@ -0,0 +1,277 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use Expressly\Entity\Address;
4
+ use Expressly\Entity\Customer;
5
+ use Expressly\Entity\Email;
6
+ use Expressly\Entity\Phone;
7
+ use Expressly\Event\CustomerMigrateEvent;
8
+ use Expressly\Exception\ExceptionFormatter;
9
+ use Expressly\Exception\GenericException;
10
+ use Expressly\Expressly\AbstractController;
11
+ use Expressly\Presenter\CustomerMigratePresenter;
12
+
13
+ class Expressly_Expressly_CustomerController extends AbstractController
14
+ {
15
+ public function showAction()
16
+ {
17
+ $this->getResponse()->setHeader('Content-type', 'application/json');
18
+ $emailAddress = $this->getRequest()->getParam('email');
19
+ $merchant = $this->app['merchant.provider']->getMerchant();
20
+
21
+ try {
22
+ $mageCustomer = \Mage::getModel('customer/customer');
23
+ $mageCustomer->setWebsiteId(\Mage::app()->getWebsite()->getId());
24
+ $mageCustomer->loadByEmail($emailAddress);
25
+
26
+ $reference = $mageCustomer->getId();
27
+ if ($reference) {
28
+ $customer = new Customer();
29
+ $customer
30
+ ->setFirstName($mageCustomer->getFirstname())
31
+ ->setLastName($mageCustomer->getLastname());
32
+
33
+ $email = new Email();
34
+ $email
35
+ ->setAlias('default')
36
+ ->setEmail($emailAddress);
37
+ $customer->addEmail($email);
38
+
39
+ $defaultBilling = $mageCustomer->getDefaultBilling();
40
+ $defaultShipping = $mageCustomer->getDefaultShipping();
41
+ foreach ($mageCustomer->getAddresses() as $mageAddress) {
42
+ $address = new Address();
43
+ $address
44
+ ->setFirstName($mageAddress->getFirstname())
45
+ ->setLastName($mageAddress->getLastname())
46
+ ->setCompanyName($mageAddress->getCompany())
47
+ ->setAddress1($mageAddress->getStreet1())
48
+ ->setAddress2($mageAddress->getStreet2())
49
+ ->setCity($mageAddress->getCity())
50
+ ->setStateProvince($mageAddress->getRegionCode())
51
+ ->setCountry($mageAddress->getCountry());
52
+
53
+ $phone = new Phone();
54
+ $phone
55
+ ->setType(Phone::PHONE_TYPE_HOME)
56
+ ->setNumber($mageAddress->getTelephone());
57
+ $customer->addPhone($phone);
58
+ $address->setPhonePosition($customer->getPhoneIndex($phone));
59
+
60
+ $primary = false;
61
+ $type = null;
62
+ if ($mageAddress->getId() == $defaultBilling) {
63
+ $primary = true;
64
+ $type = Address::ADDRESS_BILLING;
65
+ }
66
+ if ($mageAddress->getId() == $defaultShipping) {
67
+ $primary = true;
68
+ $type = ($type == Address::ADDRESS_BILLING) ? Address::ADDRESS_BOTH : Address::ADDRESS_SHIPPING;
69
+ }
70
+
71
+ $customer->addAddress($address, $primary, $type);
72
+ };
73
+
74
+ $presenter = new CustomerMigratePresenter($merchant, $customer, $emailAddress, $reference);
75
+ $this->getResponse()->setBody(json_encode($presenter->toArray()));
76
+ }
77
+ } catch (\Exception $e) {
78
+ $this->logger->error(ExceptionFormatter::format($e));
79
+ $this->getResponse()->setBody(json_encode(array()));
80
+ }
81
+ }
82
+
83
+ public function migrateAction()
84
+ {
85
+ $uuid = $this->getRequest()->getParam('uuid');
86
+ $exists = false;
87
+
88
+ try {
89
+ $merchant = $this->app['merchant.provider']->getMerchant();
90
+ $event = new CustomerMigrateEvent($merchant, $uuid);
91
+ $this->dispatcher->dispatch('customer.migrate.data', $event);
92
+
93
+ $json = $event->getContent();
94
+ if (!$event->isSuccessful()) {
95
+ if (!empty($json['code']) && $json['code'] == 'USER_ALREADY_MIGRATED') {
96
+ $exists = true;
97
+ }
98
+
99
+ throw new GenericException($this->processError($event));
100
+ }
101
+
102
+ $mageCustomer = \Mage::getModel('customer/customer');
103
+ $mageCustomer->setWebsiteId(\Mage::app()->getWebsite()->getId());
104
+
105
+ $email = $json['migration']['data']['email'];
106
+ $mageCustomer->loadByEmail($email);
107
+
108
+ if ($mageCustomer->getId()) {
109
+ $exists = true;
110
+ $event = new CustomerMigrateEvent($merchant, $uuid, CustomerMigrateEvent::EXISTING_CUSTOMER);
111
+ } else {
112
+ $customer = $json['migration']['data']['customerData'];
113
+
114
+ $mageCustomer
115
+ ->setStore(\Mage::app()->getStore())
116
+ ->setFirstname($customer['firstName'])
117
+ ->setLastname($customer['lastName'])
118
+ ->setEmail($email)
119
+ ->setPassword(md5('xly' . microtime()))
120
+ ->setIsSubscribed(true);
121
+
122
+ $mageCustomer->save();
123
+
124
+ $countryProvider = $this->app['country_code.provider'];
125
+ foreach ($customer['addresses'] as $index => $address) {
126
+ $mageAddress = \Mage::getModel('customer/address');
127
+
128
+ $safelyGet = function ($key) use ($address) {
129
+ if (!empty($address[$key])) {
130
+ return $address[$key];
131
+ }
132
+
133
+ return '';
134
+ };
135
+
136
+ $mageAddress
137
+ ->setCustomerId($mageCustomer->getId())
138
+ ->setFirstname($address['firstName'])
139
+ ->setLastname($address['lastName'])
140
+ ->setCountryId($countryProvider->getIso2($address['country']))
141
+ ->setPostcode($safelyGet('zip'))
142
+ ->setCity($safelyGet('city'))
143
+ ->setRegion($safelyGet('stateProvince'))
144
+ ->setTelephone($customer['phones'][$address['phone']]['number'])
145
+ ->setCompany($safelyGet('company'))
146
+ ->setStreet(sprintf("%s\n%s", $safelyGet('address1'), $safelyGet('address2')))
147
+ ->setSaveInAddressBook(true);
148
+
149
+ if ($customer['billingAddress'] == $index) {
150
+ $mageAddress->setIsDefaultBilling(true);
151
+ }
152
+
153
+ if ($customer['shippingAddress'] == $index) {
154
+ $mageAddress->setIsDefaultShipping(true);
155
+ }
156
+
157
+ $mageAddress->save();
158
+ }
159
+
160
+ // Send out password forgotten email
161
+ $token = \Mage::helper('customer')->generateResetPasswordLinkToken();
162
+ $mageCustomer->changeResetPasswordLinkToken($token);
163
+ $mageCustomer->sendPasswordReminderEmail();
164
+ $mageCustomer->save();
165
+
166
+ // log user in
167
+ \Mage::getSingleton('customer/session')->setCustomerAsLoggedIn($mageCustomer);
168
+ }
169
+
170
+ if (!empty($json['cart']['productId'])) {
171
+ $cart = \Mage::getModel('checkout/cart');
172
+ $cart->truncate();
173
+ $cart->addProduct($json['cart']['productId']);
174
+ $cart->save();
175
+ }
176
+
177
+ if (!empty($json['cart']['couponCode'])) {
178
+ \Mage::getSingleton('checkout/cart')
179
+ ->getQuote()
180
+ ->getShippingAddress()
181
+ ->setCollectShippingRates(true);
182
+
183
+ \Mage::getSingleton('checkout/cart')
184
+ ->getQuote()
185
+ ->setCouponCode($json['cart']['couponCode'])
186
+ ->collectTotals()
187
+ ->save();
188
+ }
189
+
190
+
191
+ $this->dispatcher->dispatch('customer.migrate.success', $event);
192
+ } catch (\Exception $e) {
193
+ $this->logger->error(ExceptionFormatter::format($e));
194
+ }
195
+
196
+ if (!$exists) {
197
+ $this->getResponse()->setRedirect(Mage::getBaseUrl());
198
+ } else {
199
+ $this->mimicFrontPage();
200
+
201
+ $js = '<script type="text/javascript">
202
+ (function () {
203
+ setTimeout(function() {
204
+ var login = confirm("Your email address has already been registered on this store. Please login with your credentials. Pressing OK will redirect you to the login page.");
205
+ if (login) {
206
+ window.location.replace(window.location.origin + "/customer/account/login");
207
+ }
208
+ }, 500);
209
+ })();
210
+ </script>';
211
+
212
+ $this->getResponse()->appendBody($js);
213
+ }
214
+ }
215
+
216
+ public function popupAction()
217
+ {
218
+ $uuid = $this->getRequest()->getParam('uuid');
219
+ $merchant = $this->app['merchant.provider']->getMerchant();
220
+ $event = new CustomerMigrateEvent($merchant, $uuid);
221
+
222
+ try {
223
+ $this->dispatcher->dispatch('customer.migrate.popup', $event);
224
+
225
+ if (!$event->isSuccessful()) {
226
+ throw new GenericException($this->processError($event));
227
+ }
228
+
229
+ $this->mimicFrontPage();
230
+ // XML injection doesn't work to add this javascript as we're overriding the page completely
231
+ $js = '<script type="text/javascript">
232
+ (function() {
233
+ popupContinue = function (event) {
234
+ event.style.display = \'none\';
235
+ var loader = event.nextElementSibling;
236
+ loader.style.display = \'block\';
237
+ loader.nextElementSibling.style.display = \'none\';
238
+
239
+ window.location.replace(window.location.origin + window.location.pathname + \'/migrate\');
240
+ };
241
+
242
+ popupClose = function (event) {
243
+ window.location.replace(window.location.origin);
244
+ };
245
+
246
+ openTerms = function (event) {
247
+ window.open(event.href, \'_blank\');
248
+ };
249
+
250
+ openPrivacy = function (event) {
251
+ window.open(event.href, \'_blank\');
252
+ };
253
+
254
+ (function () {
255
+ // make sure our popup is on top or hierarchy
256
+ content = document.getElementById(\'xly\');
257
+ document.body.insertBefore(content, document.body.children[0]);
258
+ })();
259
+ })();
260
+ </script>';
261
+ $this->getResponse()->appendBody($js);
262
+ $this->getResponse()->appendBody($event->getContent());
263
+ } catch (\Exception $e) {
264
+ $this->logger->error(ExceptionFormatter::format($e));
265
+
266
+ $this->getResponse()->setRedirect(Mage::getBaseUrl());
267
+ }
268
+ }
269
+
270
+ private function mimicFrontPage()
271
+ {
272
+ $page = \Mage::getModel('cms/page');
273
+ $page->setStoreId(\Mage::app()->getStore()->getId());
274
+ $page->load(\Mage::getStoreConfig('web/default/cms_home_page'), 'identifier');
275
+ \Mage::helper('cms/page')->renderPage($this, $page->getId());
276
+ }
277
+ }
app/code/community/Expressly/Expressly/controllers/UtilityController.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use Expressly\Expressly\AbstractController;
4
+ use Expressly\Presenter\PingPresenter;
5
+
6
+ class Expressly_Expressly_UtilityController extends AbstractController
7
+ {
8
+ public function pingAction()
9
+ {
10
+ $helper = new Expressly_Expressly_Helper_Client();
11
+
12
+ $presenter = new PingPresenter();
13
+ $this->getResponse()->setHeader('Content-type', 'application/json');
14
+ $this->getResponse()->setBody(json_encode($presenter->toArray()));
15
+ }
16
+ }
app/code/community/Expressly/Expressly/etc/config.xml ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Expressly_Expressly>
5
+ <version>0.1.0</version>
6
+ </Expressly_Expressly>
7
+ </modules>
8
+ <frontend>
9
+ <layout>
10
+ <updates>
11
+ <expressly>
12
+ <file>expressly.xml</file>
13
+ </expressly>
14
+ </updates>
15
+ </layout>
16
+ <routers>
17
+ <expressly>
18
+ <use>standard</use>
19
+ <args>
20
+ <module>Expressly_Expressly</module>
21
+ <frontName>expressly</frontName>
22
+ </args>
23
+ </expressly>
24
+ </routers>
25
+ </frontend>
26
+ <global>
27
+ <blocks>
28
+ <expressly>
29
+ <class>Expressly_Expressly_Block</class>
30
+ </expressly>
31
+ </blocks>
32
+ <helpers>
33
+ <expressly>
34
+ <class>Expressly_Expressly_Helper</class>
35
+ </expressly>
36
+ </helpers>
37
+ <resources>
38
+ <expressly_expressly_setup>
39
+ <setup>
40
+ <module>Expressly_Expressly</module>
41
+ <class>Expressly_Expressly_Model_Resource_Setup</class>
42
+ </setup>
43
+ <connection>
44
+ <use>core_setup</use>
45
+ </connection>
46
+ </expressly_expressly_setup>
47
+ </resources>
48
+ <events>
49
+ <controller_front_init_before>
50
+ <observers>
51
+ <expressly_expressly>
52
+ <type>singleton</type>
53
+ <class>Expressly_Expressly_Model_Observer</class>
54
+ <method>controllerFrontInitBefore</method>
55
+ </expressly_expressly>
56
+ </observers>
57
+ </controller_front_init_before>
58
+
59
+ <admin_system_config_changed_section_expressly>
60
+ <observers>
61
+ <expressly_expressly>
62
+ <type>singleton</type>
63
+ <class>Expressly_Expressly_Model_Observer</class>
64
+ <method>registerUpdateMerchant</method>
65
+ </expressly_expressly>
66
+ </observers>
67
+ </admin_system_config_changed_section_expressly>
68
+ </events>
69
+ <rewrite>
70
+ <expressly_api_utility_ping>
71
+ <from><![CDATA[#^/expressly/api/ping/?$#]]></from>
72
+ <to><![CDATA[/expressly/utility/ping]]></to>
73
+ <complete>1</complete>
74
+ </expressly_api_utility_ping>
75
+
76
+ <expressly_api_batch_invoice>
77
+ <from><![CDATA[#^/expressly/api/batch/invoice/?$#]]></from>
78
+ <to><![CDATA[/expressly/batch/invoice]]></to>
79
+ <complete>1</complete>
80
+ </expressly_api_batch_invoice>
81
+
82
+ <expressly_api_batch_customer>
83
+ <from><![CDATA[#^/expressly/api/batch/customer/?$#]]></from>
84
+ <to><![CDATA[/expressly/batch/customer]]></to>
85
+ <complete>1</complete>
86
+ </expressly_api_batch_customer>
87
+
88
+ <expressly_api_customer_show>
89
+ <from><![CDATA[#^/expressly/api/user/([A-Za-z0-9_.\-]+@[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)?\.[A-Za-z]+)/?$#]]></from>
90
+ <to><![CDATA[/expressly/customer/show/email/$1]]></to>
91
+ <complete>1</complete>
92
+ </expressly_api_customer_show>
93
+
94
+ <expressly_api_customer_migrate>
95
+ <from><![CDATA[#^/expressly/api/([A-Za-z0-9\-]+)/migrate/?$#]]></from>
96
+ <to><![CDATA[/expressly/customer/migrate/uuid/$1]]></to>
97
+ <complete>1</complete>
98
+ </expressly_api_customer_migrate>
99
+
100
+ <expressly_api_customer_popup>
101
+ <from><![CDATA[#^/expressly/api/([A-Za-z0-9\-]+)/?$#]]></from>
102
+ <to><![CDATA[/expressly/customer/popup/uuid/$1]]></to>
103
+ <complete>1</complete>
104
+ </expressly_api_customer_popup>
105
+ </rewrite>
106
+ </global>
107
+ <adminhtml>
108
+ <acl>
109
+ <resources>
110
+ <admin>
111
+ <children>
112
+ <system>
113
+ <children>
114
+ <config>
115
+ <children>
116
+ <expressly>
117
+ <title>Expressly Section</title>
118
+ </expressly>
119
+ </children>
120
+ </config>
121
+ </children>
122
+ </system>
123
+ </children>
124
+ </admin>
125
+ </resources>
126
+ </acl>
127
+ </adminhtml>
128
+ </config>
app/code/community/Expressly/Expressly/etc/system.xml ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <expressly translate="label" module="expressly">
5
+ <label>Expressly</label>
6
+ <tab>general</tab>
7
+ <frontend_type>text</frontend_type>
8
+ <sort_order>90</sort_order>
9
+ <show_in_default>1</show_in_default>
10
+ <show_in_website>1</show_in_website>
11
+ <show_in_store>1</show_in_store>
12
+ <groups>
13
+ <expressly_general translate="label">
14
+ <label>General</label>
15
+ <frontend_type>text</frontend_type>
16
+ <sort_order>0</sort_order>
17
+ <show_in_default>1</show_in_default>
18
+ <show_in_website>1</show_in_website>
19
+ <show_in_store>1</show_in_store>
20
+ <fields>
21
+ <expressly_image transtale="label">
22
+ <label>Image URL</label>
23
+ <comment>URL for the Logo of your store.</comment>
24
+ <frontend_model>expressly/system_config_form_imageUrl</frontend_model>
25
+ <sort_order>10</sort_order>
26
+ <show_in_default>1</show_in_default>
27
+ <show_in_website>1</show_in_website>
28
+ <show_in_store>1</show_in_store>
29
+ </expressly_image>
30
+
31
+ <expressly_terms transtale="label">
32
+ <label>Terms URL</label>
33
+ <comment>Terms and Conditions URL for your store.</comment>
34
+ <frontend_type>text</frontend_type>
35
+ <sort_order>20</sort_order>
36
+ <show_in_default>1</show_in_default>
37
+ <show_in_website>1</show_in_website>
38
+ <show_in_store>1</show_in_store>
39
+ </expressly_terms>
40
+
41
+ <expressly_policy transtale="label">
42
+ <label>Privacy Policy URL</label>
43
+ <comment>Privacy Policy URL for your store.</comment>
44
+ <frontend_type>text</frontend_type>
45
+ <sort_order>30</sort_order>
46
+ <show_in_default>1</show_in_default>
47
+ <show_in_website>1</show_in_website>
48
+ <show_in_store>1</show_in_store>
49
+ </expressly_policy>
50
+
51
+ <expressly_password transtale="label">
52
+ <label>Password</label>
53
+ <comment>Password for your store. If your password field is blank, please press Save changes to register, and retrieve your password.</comment>
54
+ <frontend_type>text</frontend_type>
55
+ <sort_order>40</sort_order>
56
+ <show_in_default>1</show_in_default>
57
+ <show_in_website>1</show_in_website>
58
+ <show_in_store>1</show_in_store>
59
+ </expressly_password>
60
+
61
+ <expressly_register translate="button_label">
62
+ <label></label>
63
+ <button_label>Register</button_label>
64
+ <frontend_model>expressly/system_config_form_register</frontend_model>
65
+ <sort_order>50</sort_order>
66
+ <show_in_default>1</show_in_default>
67
+ <show_in_website>1</show_in_website>
68
+ <show_in_store>0</show_in_store>
69
+ </expressly_register>
70
+ </fields>
71
+ </expressly_general>
72
+ </groups>
73
+ </expressly>
74
+ </sections>
75
+ </config>
app/code/community/Expressly/Expressly/lib/MerchantProvider.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Expressly;
4
+
5
+ use Expressly\Entity\Merchant;
6
+ use Expressly\Provider\MerchantProviderInterface;
7
+ use Silex\Application;
8
+
9
+ class MerchantProvider implements MerchantProviderInterface
10
+ {
11
+ private $app;
12
+ private $merchant;
13
+
14
+ const DESTINATION = 'expressly/expressly_general/expressly_destination';
15
+ const PATH = 'expressly/expressly_general/expressly_path';
16
+ const HOST = 'expressly/expressly_general/expressly_host';
17
+ const IMAGE = 'expressly/expressly_general/expressly_image';
18
+ const NAME = 'design/header/logo_alt';
19
+ const OFFER = 'expressly/expressly_general/expressly_offer';
20
+ const PASSWORD = 'expressly/expressly_general/expressly_password';
21
+ const POLICY = 'expressly/expressly_general/expressly_policy';
22
+ const TERMS = 'expressly/expressly_general/expressly_terms';
23
+ const UUID = 'expressly/expressly_general/expressly_uuid';
24
+
25
+ public function __construct(Application $app)
26
+ {
27
+ $this->app = $app;
28
+
29
+ $this->updateMerchant();
30
+ }
31
+
32
+ private function updateMerchant()
33
+ {
34
+ $merchant = new Merchant();
35
+ $merchant
36
+ ->setDestination($this->getParameter(self::DESTINATION))
37
+ ->setPath($this->getParameter(self::PATH))
38
+ ->setHost($this->getParameter(self::HOST))
39
+ ->setImage($this->getParameter(self::IMAGE))
40
+ ->setName($this->getParameter(self::NAME))
41
+ ->setOffer($this->getParameter(self::OFFER))
42
+ ->setPassword($this->getParameter(self::PASSWORD))
43
+ ->setPolicy($this->getParameter(self::POLICY))
44
+ ->setTerms($this->getParameter(self::TERMS))
45
+ ->setUuid($this->getParameter(self::UUID));
46
+
47
+ $this->merchant = $merchant;
48
+ }
49
+
50
+ private function getParameter($key)
51
+ {
52
+ return \Mage::getStoreConfig($key, \Mage::app()->getStore());
53
+ }
54
+
55
+ public function setMerchant(Merchant $merchant)
56
+ {
57
+ $model = \Mage::getModel('core/config');
58
+
59
+ $model->saveConfig(self::DESTINATION, $merchant->getDestination(), 'default', 0);
60
+ $model->saveConfig(self::PATH, $merchant->getPath(), 'default', 0);
61
+ $model->saveConfig(self::HOST, $merchant->getHost(), 'default', 0);
62
+ $model->saveConfig(self::IMAGE, $merchant->getImage(), 'default', 0);
63
+ $model->saveConfig(self::OFFER, $merchant->getOffer(), 'default', 0);
64
+ $model->saveConfig(self::PASSWORD, $merchant->getPassword(), 'default', 0);
65
+ $model->saveConfig(self::POLICY, $merchant->getPolicy(), 'default', 0);
66
+ $model->saveConfig(self::TERMS, $merchant->getTerms(), 'default', 0);
67
+ $model->saveConfig(self::UUID, $merchant->getUuid(), 'default', 0);
68
+
69
+ $this->merchant = $merchant;
70
+ }
71
+
72
+ public function getMerchant($update = false)
73
+ {
74
+ if ($update) {
75
+ $this->updateMerchant();
76
+ }
77
+
78
+ return $this->merchant;
79
+ }
80
+ }
app/code/community/Expressly/Expressly/sql/expressly_expressly_setup/mysql4-install-0.1.0.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once __DIR__ . '/../../vendor/autoload.php';
4
+
5
+ use Expressly\Expressly\MerchantProvider;
6
+
7
+ $installer = $this;
8
+ $installer->startSetup();
9
+
10
+ $resource = $installer->getResourceModel();
11
+ $resource->loadToXml(\Mage::getConfig());
12
+ $storeId = \Mage::app()->getStore()->getId();
13
+ $host = (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'];
14
+ $base = \Mage::getBaseUrl(\Mage_Core_Model_Store::URL_TYPE_WEB);
15
+ $path = trim(str_replace($host, '', $base));
16
+
17
+ $resource->saveConfig(MerchantProvider::DESTINATION, '/', 'default', 0);
18
+ $resource->saveConfig(MerchantProvider::PATH, ($path == '/') ? '' : $path, 'default', 0);
19
+ $resource->saveConfig(MerchantProvider::HOST, $host, 'default', 0);
20
+ $resource->saveConfig(MerchantProvider::IMAGE, $base . \Mage::getStoreConfig('design/header/logo_src'), 'default', 0);
21
+ $resource->saveConfig(MerchantProvider::OFFER, true, 'default', 0);
22
+ $resource->saveConfig(MerchantProvider::PASSWORD, '', 'default', 0);
23
+ $resource->saveConfig(MerchantProvider::POLICY, $base, 'default', 0);
24
+ $resource->saveConfig(MerchantProvider::TERMS, $base, 'default', 0);
25
+ $resource->saveConfig(MerchantProvider::UUID, '', 'default', 0);
26
+
27
+ $installer->endSetup();
app/code/community/Expressly/Expressly/vendor/autoload.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload.php @generated by Composer
4
+
5
+ require_once __DIR__ . '/composer' . '/autoload_real.php';
6
+
7
+ return ComposerAutoloaderInitd439793af87401f4cbb5f79c78a3091c::getLoader();
app/code/community/Expressly/Expressly/vendor/composer/ClassLoader.php ADDED
@@ -0,0 +1,413 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Composer.
5
+ *
6
+ * (c) Nils Adermann <naderman@naderman.de>
7
+ * Jordi Boggiano <j.boggiano@seld.be>
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Composer\Autoload;
14
+
15
+ /**
16
+ * ClassLoader implements a PSR-0 class loader
17
+ *
18
+ * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
19
+ *
20
+ * $loader = new \Composer\Autoload\ClassLoader();
21
+ *
22
+ * // register classes with namespaces
23
+ * $loader->add('Symfony\Component', __DIR__.'/component');
24
+ * $loader->add('Symfony', __DIR__.'/framework');
25
+ *
26
+ * // activate the autoloader
27
+ * $loader->register();
28
+ *
29
+ * // to enable searching the include path (eg. for PEAR packages)
30
+ * $loader->setUseIncludePath(true);
31
+ *
32
+ * In this example, if you try to use a class in the Symfony\Component
33
+ * namespace or one of its children (Symfony\Component\Console for instance),
34
+ * the autoloader will first look for the class under the component/
35
+ * directory, and it will then fallback to the framework/ directory if not
36
+ * found before giving up.
37
+ *
38
+ * This class is loosely based on the Symfony UniversalClassLoader.
39
+ *
40
+ * @author Fabien Potencier <fabien@symfony.com>
41
+ * @author Jordi Boggiano <j.boggiano@seld.be>
42
+ */
43
+ class ClassLoader
44
+ {
45
+ // PSR-4
46
+ private $prefixLengthsPsr4 = array();
47
+ private $prefixDirsPsr4 = array();
48
+ private $fallbackDirsPsr4 = array();
49
+
50
+ // PSR-0
51
+ private $prefixesPsr0 = array();
52
+ private $fallbackDirsPsr0 = array();
53
+
54
+ private $useIncludePath = false;
55
+ private $classMap = array();
56
+
57
+ private $classMapAuthoritative = false;
58
+
59
+ public function getPrefixes()
60
+ {
61
+ if (!empty($this->prefixesPsr0)) {
62
+ return call_user_func_array('array_merge', $this->prefixesPsr0);
63
+ }
64
+
65
+ return array();
66
+ }
67
+
68
+ public function getPrefixesPsr4()
69
+ {
70
+ return $this->prefixDirsPsr4;
71
+ }
72
+
73
+ public function getFallbackDirs()
74
+ {
75
+ return $this->fallbackDirsPsr0;
76
+ }
77
+
78
+ public function getFallbackDirsPsr4()
79
+ {
80
+ return $this->fallbackDirsPsr4;
81
+ }
82
+
83
+ public function getClassMap()
84
+ {
85
+ return $this->classMap;
86
+ }
87
+
88
+ /**
89
+ * @param array $classMap Class to filename map
90
+ */
91
+ public function addClassMap(array $classMap)
92
+ {
93
+ if ($this->classMap) {
94
+ $this->classMap = array_merge($this->classMap, $classMap);
95
+ } else {
96
+ $this->classMap = $classMap;
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Registers a set of PSR-0 directories for a given prefix, either
102
+ * appending or prepending to the ones previously set for this prefix.
103
+ *
104
+ * @param string $prefix The prefix
105
+ * @param array|string $paths The PSR-0 root directories
106
+ * @param bool $prepend Whether to prepend the directories
107
+ */
108
+ public function add($prefix, $paths, $prepend = false)
109
+ {
110
+ if (!$prefix) {
111
+ if ($prepend) {
112
+ $this->fallbackDirsPsr0 = array_merge(
113
+ (array) $paths,
114
+ $this->fallbackDirsPsr0
115
+ );
116
+ } else {
117
+ $this->fallbackDirsPsr0 = array_merge(
118
+ $this->fallbackDirsPsr0,
119
+ (array) $paths
120
+ );
121
+ }
122
+
123
+ return;
124
+ }
125
+
126
+ $first = $prefix[0];
127
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
128
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
129
+
130
+ return;
131
+ }
132
+ if ($prepend) {
133
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
134
+ (array) $paths,
135
+ $this->prefixesPsr0[$first][$prefix]
136
+ );
137
+ } else {
138
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
139
+ $this->prefixesPsr0[$first][$prefix],
140
+ (array) $paths
141
+ );
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Registers a set of PSR-4 directories for a given namespace, either
147
+ * appending or prepending to the ones previously set for this namespace.
148
+ *
149
+ * @param string $prefix The prefix/namespace, with trailing '\\'
150
+ * @param array|string $paths The PSR-0 base directories
151
+ * @param bool $prepend Whether to prepend the directories
152
+ *
153
+ * @throws \InvalidArgumentException
154
+ */
155
+ public function addPsr4($prefix, $paths, $prepend = false)
156
+ {
157
+ if (!$prefix) {
158
+ // Register directories for the root namespace.
159
+ if ($prepend) {
160
+ $this->fallbackDirsPsr4 = array_merge(
161
+ (array) $paths,
162
+ $this->fallbackDirsPsr4
163
+ );
164
+ } else {
165
+ $this->fallbackDirsPsr4 = array_merge(
166
+ $this->fallbackDirsPsr4,
167
+ (array) $paths
168
+ );
169
+ }
170
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
171
+ // Register directories for a new namespace.
172
+ $length = strlen($prefix);
173
+ if ('\\' !== $prefix[$length - 1]) {
174
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
175
+ }
176
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
177
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
178
+ } elseif ($prepend) {
179
+ // Prepend directories for an already registered namespace.
180
+ $this->prefixDirsPsr4[$prefix] = array_merge(
181
+ (array) $paths,
182
+ $this->prefixDirsPsr4[$prefix]
183
+ );
184
+ } else {
185
+ // Append directories for an already registered namespace.
186
+ $this->prefixDirsPsr4[$prefix] = array_merge(
187
+ $this->prefixDirsPsr4[$prefix],
188
+ (array) $paths
189
+ );
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Registers a set of PSR-0 directories for a given prefix,
195
+ * replacing any others previously set for this prefix.
196
+ *
197
+ * @param string $prefix The prefix
198
+ * @param array|string $paths The PSR-0 base directories
199
+ */
200
+ public function set($prefix, $paths)
201
+ {
202
+ if (!$prefix) {
203
+ $this->fallbackDirsPsr0 = (array) $paths;
204
+ } else {
205
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Registers a set of PSR-4 directories for a given namespace,
211
+ * replacing any others previously set for this namespace.
212
+ *
213
+ * @param string $prefix The prefix/namespace, with trailing '\\'
214
+ * @param array|string $paths The PSR-4 base directories
215
+ *
216
+ * @throws \InvalidArgumentException
217
+ */
218
+ public function setPsr4($prefix, $paths)
219
+ {
220
+ if (!$prefix) {
221
+ $this->fallbackDirsPsr4 = (array) $paths;
222
+ } else {
223
+ $length = strlen($prefix);
224
+ if ('\\' !== $prefix[$length - 1]) {
225
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
226
+ }
227
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
228
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
229
+ }
230
+ }
231
+
232
+ /**
233
+ * Turns on searching the include path for class files.
234
+ *
235
+ * @param bool $useIncludePath
236
+ */
237
+ public function setUseIncludePath($useIncludePath)
238
+ {
239
+ $this->useIncludePath = $useIncludePath;
240
+ }
241
+
242
+ /**
243
+ * Can be used to check if the autoloader uses the include path to check
244
+ * for classes.
245
+ *
246
+ * @return bool
247
+ */
248
+ public function getUseIncludePath()
249
+ {
250
+ return $this->useIncludePath;
251
+ }
252
+
253
+ /**
254
+ * Turns off searching the prefix and fallback directories for classes
255
+ * that have not been registered with the class map.
256
+ *
257
+ * @param bool $classMapAuthoritative
258
+ */
259
+ public function setClassMapAuthoritative($classMapAuthoritative)
260
+ {
261
+ $this->classMapAuthoritative = $classMapAuthoritative;
262
+ }
263
+
264
+ /**
265
+ * Should class lookup fail if not found in the current class map?
266
+ *
267
+ * @return bool
268
+ */
269
+ public function isClassMapAuthoritative()
270
+ {
271
+ return $this->classMapAuthoritative;
272
+ }
273
+
274
+ /**
275
+ * Registers this instance as an autoloader.
276
+ *
277
+ * @param bool $prepend Whether to prepend the autoloader or not
278
+ */
279
+ public function register($prepend = false)
280
+ {
281
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
282
+ }
283
+
284
+ /**
285
+ * Unregisters this instance as an autoloader.
286
+ */
287
+ public function unregister()
288
+ {
289
+ spl_autoload_unregister(array($this, 'loadClass'));
290
+ }
291
+
292
+ /**
293
+ * Loads the given class or interface.
294
+ *
295
+ * @param string $class The name of the class
296
+ * @return bool|null True if loaded, null otherwise
297
+ */
298
+ public function loadClass($class)
299
+ {
300
+ if ($file = $this->findFile($class)) {
301
+ includeFile($file);
302
+
303
+ return true;
304
+ }
305
+ }
306
+
307
+ /**
308
+ * Finds the path to the file where the class is defined.
309
+ *
310
+ * @param string $class The name of the class
311
+ *
312
+ * @return string|false The path if found, false otherwise
313
+ */
314
+ public function findFile($class)
315
+ {
316
+ // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
317
+ if ('\\' == $class[0]) {
318
+ $class = substr($class, 1);
319
+ }
320
+
321
+ // class map lookup
322
+ if (isset($this->classMap[$class])) {
323
+ return $this->classMap[$class];
324
+ }
325
+ if ($this->classMapAuthoritative) {
326
+ return false;
327
+ }
328
+
329
+ $file = $this->findFileWithExtension($class, '.php');
330
+
331
+ // Search for Hack files if we are running on HHVM
332
+ if ($file === null && defined('HHVM_VERSION')) {
333
+ $file = $this->findFileWithExtension($class, '.hh');
334
+ }
335
+
336
+ if ($file === null) {
337
+ // Remember that this class does not exist.
338
+ return $this->classMap[$class] = false;
339
+ }
340
+
341
+ return $file;
342
+ }
343
+
344
+ private function findFileWithExtension($class, $ext)
345
+ {
346
+ // PSR-4 lookup
347
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
348
+
349
+ $first = $class[0];
350
+ if (isset($this->prefixLengthsPsr4[$first])) {
351
+ foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
352
+ if (0 === strpos($class, $prefix)) {
353
+ foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
354
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
355
+ return $file;
356
+ }
357
+ }
358
+ }
359
+ }
360
+ }
361
+
362
+ // PSR-4 fallback dirs
363
+ foreach ($this->fallbackDirsPsr4 as $dir) {
364
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
365
+ return $file;
366
+ }
367
+ }
368
+
369
+ // PSR-0 lookup
370
+ if (false !== $pos = strrpos($class, '\\')) {
371
+ // namespaced class name
372
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
373
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
374
+ } else {
375
+ // PEAR-like class name
376
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
377
+ }
378
+
379
+ if (isset($this->prefixesPsr0[$first])) {
380
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
381
+ if (0 === strpos($class, $prefix)) {
382
+ foreach ($dirs as $dir) {
383
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
384
+ return $file;
385
+ }
386
+ }
387
+ }
388
+ }
389
+ }
390
+
391
+ // PSR-0 fallback dirs
392
+ foreach ($this->fallbackDirsPsr0 as $dir) {
393
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
394
+ return $file;
395
+ }
396
+ }
397
+
398
+ // PSR-0 include paths.
399
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
400
+ return $file;
401
+ }
402
+ }
403
+ }
404
+
405
+ /**
406
+ * Scope isolated include.
407
+ *
408
+ * Prevents access to $this/self from included files.
409
+ */
410
+ function includeFile($file)
411
+ {
412
+ include $file;
413
+ }
app/code/community/Expressly/Expressly/vendor/composer/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Copyright (c) 2015 Nils Adermann, Jordi Boggiano
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished
9
+ to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+
app/code/community/Expressly/Expressly/vendor/composer/autoload_classmap.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_classmap.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ 'SessionHandlerInterface' => $vendorDir . '/symfony/http-foundation/Symfony/Component/HttpFoundation/Resources/stubs/SessionHandlerInterface.php',
10
+ );
app/code/community/Expressly/Expressly/vendor/composer/autoload_namespaces.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_namespaces.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ 'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'),
10
+ 'Symfony\\Component\\Routing\\' => array($vendorDir . '/symfony/routing'),
11
+ 'Symfony\\Component\\HttpKernel\\' => array($vendorDir . '/symfony/http-kernel'),
12
+ 'Symfony\\Component\\HttpFoundation\\' => array($vendorDir . '/symfony/http-foundation'),
13
+ 'Symfony\\Component\\EventDispatcher\\' => array($vendorDir . '/symfony/event-dispatcher'),
14
+ 'Symfony\\Component\\Config\\' => array($vendorDir . '/symfony/config'),
15
+ 'Silex' => array($vendorDir . '/silex/silex/src'),
16
+ 'Psr\\Log\\' => array($vendorDir . '/psr/log'),
17
+ 'Pimple' => array($vendorDir . '/pimple/pimple/lib'),
18
+ 'Doctrine\\Common\\Collections\\' => array($vendorDir . '/doctrine/collections/lib'),
19
+ 'DerAlex\\Silex' => array($vendorDir . '/deralex/yaml-config-service-provider/src'),
20
+ 'Buzz' => array($vendorDir . '/kriswallsmith/buzz/lib'),
21
+ );
app/code/community/Expressly/Expressly/vendor/composer/autoload_psr4.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_psr4.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ 'Symfony\\Component\\Filesystem\\' => array($vendorDir . '/symfony/filesystem'),
10
+ 'Symfony\\Component\\Debug\\' => array($vendorDir . '/symfony/debug'),
11
+ 'Predis\\' => array($vendorDir . '/predis/predis/src'),
12
+ 'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
13
+ 'Expressly\\Expressly\\' => array($baseDir . '/lib'),
14
+ 'Expressly\\' => array($vendorDir . '/expressly/php-common/src'),
15
+ );
app/code/community/Expressly/Expressly/vendor/composer/autoload_real.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_real.php @generated by Composer
4
+
5
+ class ComposerAutoloaderInitd439793af87401f4cbb5f79c78a3091c
6
+ {
7
+ private static $loader;
8
+
9
+ public static function loadClassLoader($class)
10
+ {
11
+ if ('Composer\Autoload\ClassLoader' === $class) {
12
+ require __DIR__ . '/ClassLoader.php';
13
+ }
14
+ }
15
+
16
+ public static function getLoader()
17
+ {
18
+ if (null !== self::$loader) {
19
+ return self::$loader;
20
+ }
21
+
22
+ spl_autoload_register(array('ComposerAutoloaderInitd439793af87401f4cbb5f79c78a3091c', 'loadClassLoader'), true, true);
23
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInitd439793af87401f4cbb5f79c78a3091c', 'loadClassLoader'));
25
+
26
+ $map = require __DIR__ . '/autoload_namespaces.php';
27
+ foreach ($map as $namespace => $path) {
28
+ $loader->set($namespace, $path);
29
+ }
30
+
31
+ $map = require __DIR__ . '/autoload_psr4.php';
32
+ foreach ($map as $namespace => $path) {
33
+ $loader->setPsr4($namespace, $path);
34
+ }
35
+
36
+ $classMap = require __DIR__ . '/autoload_classmap.php';
37
+ if ($classMap) {
38
+ $loader->addClassMap($classMap);
39
+ }
40
+
41
+ $loader->register(true);
42
+
43
+ return $loader;
44
+ }
45
+ }
46
+
47
+ function composerRequired439793af87401f4cbb5f79c78a3091c($file)
48
+ {
49
+ require $file;
50
+ }
app/code/community/Expressly/Expressly/vendor/composer/installed.json ADDED
@@ -0,0 +1,1005 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "name": "predis/predis",
4
+ "version": "v1.0.1",
5
+ "version_normalized": "1.0.1.0",
6
+ "source": {
7
+ "type": "git",
8
+ "url": "https://github.com/nrk/predis.git",
9
+ "reference": "7a170b3d8123c556597b4fbdb88631f99de180c2"
10
+ },
11
+ "dist": {
12
+ "type": "zip",
13
+ "url": "https://api.github.com/repos/nrk/predis/zipball/7a170b3d8123c556597b4fbdb88631f99de180c2",
14
+ "reference": "7a170b3d8123c556597b4fbdb88631f99de180c2",
15
+ "shasum": ""
16
+ },
17
+ "require": {
18
+ "php": ">=5.3.2"
19
+ },
20
+ "require-dev": {
21
+ "phpunit/phpunit": "~4.0"
22
+ },
23
+ "suggest": {
24
+ "ext-curl": "Allows access to Webdis when paired with phpiredis",
25
+ "ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol"
26
+ },
27
+ "time": "2015-01-02 12:51:34",
28
+ "type": "library",
29
+ "installation-source": "dist",
30
+ "autoload": {
31
+ "psr-4": {
32
+ "Predis\\": "src/"
33
+ }
34
+ },
35
+ "notification-url": "https://packagist.org/downloads/",
36
+ "license": [
37
+ "MIT"
38
+ ],
39
+ "authors": [
40
+ {
41
+ "name": "Daniele Alessandri",
42
+ "email": "suppakilla@gmail.com",
43
+ "homepage": "http://clorophilla.net"
44
+ }
45
+ ],
46
+ "description": "Flexible and feature-complete PHP client library for Redis",
47
+ "homepage": "http://github.com/nrk/predis",
48
+ "keywords": [
49
+ "nosql",
50
+ "predis",
51
+ "redis"
52
+ ]
53
+ },
54
+ {
55
+ "name": "doctrine/collections",
56
+ "version": "v1.3.0",
57
+ "version_normalized": "1.3.0.0",
58
+ "source": {
59
+ "type": "git",
60
+ "url": "https://github.com/doctrine/collections.git",
61
+ "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a"
62
+ },
63
+ "dist": {
64
+ "type": "zip",
65
+ "url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
66
+ "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
67
+ "shasum": ""
68
+ },
69
+ "require": {
70
+ "php": ">=5.3.2"
71
+ },
72
+ "require-dev": {
73
+ "phpunit/phpunit": "~4.0"
74
+ },
75
+ "time": "2015-04-14 22:21:58",
76
+ "type": "library",
77
+ "extra": {
78
+ "branch-alias": {
79
+ "dev-master": "1.2.x-dev"
80
+ }
81
+ },
82
+ "installation-source": "dist",
83
+ "autoload": {
84
+ "psr-0": {
85
+ "Doctrine\\Common\\Collections\\": "lib/"
86
+ }
87
+ },
88
+ "notification-url": "https://packagist.org/downloads/",
89
+ "license": [
90
+ "MIT"
91
+ ],
92
+ "authors": [
93
+ {
94
+ "name": "Roman Borschel",
95
+ "email": "roman@code-factory.org"
96
+ },
97
+ {
98
+ "name": "Benjamin Eberlei",
99
+ "email": "kontakt@beberlei.de"
100
+ },
101
+ {
102
+ "name": "Guilherme Blanco",
103
+ "email": "guilhermeblanco@gmail.com"
104
+ },
105
+ {
106
+ "name": "Jonathan Wage",
107
+ "email": "jonwage@gmail.com"
108
+ },
109
+ {
110
+ "name": "Johannes Schmitt",
111
+ "email": "schmittjoh@gmail.com"
112
+ }
113
+ ],
114
+ "description": "Collections Abstraction library",
115
+ "homepage": "http://www.doctrine-project.org",
116
+ "keywords": [
117
+ "array",
118
+ "collections",
119
+ "iterator"
120
+ ]
121
+ },
122
+ {
123
+ "name": "psr/log",
124
+ "version": "1.0.0",
125
+ "version_normalized": "1.0.0.0",
126
+ "source": {
127
+ "type": "git",
128
+ "url": "https://github.com/php-fig/log.git",
129
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
130
+ },
131
+ "dist": {
132
+ "type": "zip",
133
+ "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
134
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
135
+ "shasum": ""
136
+ },
137
+ "time": "2012-12-21 11:40:51",
138
+ "type": "library",
139
+ "installation-source": "dist",
140
+ "autoload": {
141
+ "psr-0": {
142
+ "Psr\\Log\\": ""
143
+ }
144
+ },
145
+ "notification-url": "https://packagist.org/downloads/",
146
+ "license": [
147
+ "MIT"
148
+ ],
149
+ "authors": [
150
+ {
151
+ "name": "PHP-FIG",
152
+ "homepage": "http://www.php-fig.org/"
153
+ }
154
+ ],
155
+ "description": "Common interface for logging libraries",
156
+ "keywords": [
157
+ "log",
158
+ "psr",
159
+ "psr-3"
160
+ ]
161
+ },
162
+ {
163
+ "name": "monolog/monolog",
164
+ "version": "1.13.1",
165
+ "version_normalized": "1.13.1.0",
166
+ "source": {
167
+ "type": "git",
168
+ "url": "https://github.com/Seldaek/monolog.git",
169
+ "reference": "c31a2c4e8db5da8b46c74cf275d7f109c0f249ac"
170
+ },
171
+ "dist": {
172
+ "type": "zip",
173
+ "url": "https://api.github.com/repos/Seldaek/monolog/zipball/c31a2c4e8db5da8b46c74cf275d7f109c0f249ac",
174
+ "reference": "c31a2c4e8db5da8b46c74cf275d7f109c0f249ac",
175
+ "shasum": ""
176
+ },
177
+ "require": {
178
+ "php": ">=5.3.0",
179
+ "psr/log": "~1.0"
180
+ },
181
+ "provide": {
182
+ "psr/log-implementation": "1.0.0"
183
+ },
184
+ "require-dev": {
185
+ "aws/aws-sdk-php": "~2.4, >2.4.8",
186
+ "doctrine/couchdb": "~1.0@dev",
187
+ "graylog2/gelf-php": "~1.0",
188
+ "phpunit/phpunit": "~4.0",
189
+ "raven/raven": "~0.5",
190
+ "ruflin/elastica": "0.90.*",
191
+ "swiftmailer/swiftmailer": "~5.3",
192
+ "videlalvaro/php-amqplib": "~2.4"
193
+ },
194
+ "suggest": {
195
+ "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
196
+ "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
197
+ "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
198
+ "ext-mongo": "Allow sending log messages to a MongoDB server",
199
+ "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
200
+ "raven/raven": "Allow sending log messages to a Sentry server",
201
+ "rollbar/rollbar": "Allow sending log messages to Rollbar",
202
+ "ruflin/elastica": "Allow sending log messages to an Elastic Search server",
203
+ "videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib"
204
+ },
205
+ "time": "2015-03-09 09:58:04",
206
+ "type": "library",
207
+ "extra": {
208
+ "branch-alias": {
209
+ "dev-master": "1.13.x-dev"
210
+ }
211
+ },
212
+ "installation-source": "dist",
213
+ "autoload": {
214
+ "psr-4": {
215
+ "Monolog\\": "src/Monolog"
216
+ }
217
+ },
218
+ "notification-url": "https://packagist.org/downloads/",
219
+ "license": [
220
+ "MIT"
221
+ ],
222
+ "authors": [
223
+ {
224
+ "name": "Jordi Boggiano",
225
+ "email": "j.boggiano@seld.be",
226
+ "homepage": "http://seld.be"
227
+ }
228
+ ],
229
+ "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
230
+ "homepage": "http://github.com/Seldaek/monolog",
231
+ "keywords": [
232
+ "log",
233
+ "logging",
234
+ "psr-3"
235
+ ]
236
+ },
237
+ {
238
+ "name": "kriswallsmith/buzz",
239
+ "version": "v0.13",
240
+ "version_normalized": "0.13.0.0",
241
+ "source": {
242
+ "type": "git",
243
+ "url": "https://github.com/kriswallsmith/Buzz.git",
244
+ "reference": "487760b05d6269a4c2c374364325326cfa65b12c"
245
+ },
246
+ "dist": {
247
+ "type": "zip",
248
+ "url": "https://api.github.com/repos/kriswallsmith/Buzz/zipball/487760b05d6269a4c2c374364325326cfa65b12c",
249
+ "reference": "487760b05d6269a4c2c374364325326cfa65b12c",
250
+ "shasum": ""
251
+ },
252
+ "require": {
253
+ "php": ">=5.3.0"
254
+ },
255
+ "require-dev": {
256
+ "phpunit/phpunit": "3.7.*"
257
+ },
258
+ "suggest": {
259
+ "ext-curl": "*"
260
+ },
261
+ "time": "2014-09-15 12:42:36",
262
+ "type": "library",
263
+ "installation-source": "dist",
264
+ "autoload": {
265
+ "psr-0": {
266
+ "Buzz": "lib/"
267
+ }
268
+ },
269
+ "notification-url": "https://packagist.org/downloads/",
270
+ "license": [
271
+ "MIT"
272
+ ],
273
+ "authors": [
274
+ {
275
+ "name": "Kris Wallsmith",
276
+ "email": "kris.wallsmith@gmail.com",
277
+ "homepage": "http://kriswallsmith.net/"
278
+ }
279
+ ],
280
+ "description": "Lightweight HTTP client",
281
+ "homepage": "https://github.com/kriswallsmith/Buzz",
282
+ "keywords": [
283
+ "curl",
284
+ "http client"
285
+ ]
286
+ },
287
+ {
288
+ "name": "symfony/yaml",
289
+ "version": "v2.6.7",
290
+ "version_normalized": "2.6.7.0",
291
+ "target-dir": "Symfony/Component/Yaml",
292
+ "source": {
293
+ "type": "git",
294
+ "url": "https://github.com/symfony/Yaml.git",
295
+ "reference": "f157ab074e453ecd4c0fa775f721f6e67a99d9e2"
296
+ },
297
+ "dist": {
298
+ "type": "zip",
299
+ "url": "https://api.github.com/repos/symfony/Yaml/zipball/f157ab074e453ecd4c0fa775f721f6e67a99d9e2",
300
+ "reference": "f157ab074e453ecd4c0fa775f721f6e67a99d9e2",
301
+ "shasum": ""
302
+ },
303
+ "require": {
304
+ "php": ">=5.3.3"
305
+ },
306
+ "require-dev": {
307
+ "symfony/phpunit-bridge": "~2.7"
308
+ },
309
+ "time": "2015-05-02 15:18:45",
310
+ "type": "library",
311
+ "extra": {
312
+ "branch-alias": {
313
+ "dev-master": "2.6-dev"
314
+ }
315
+ },
316
+ "installation-source": "dist",
317
+ "autoload": {
318
+ "psr-0": {
319
+ "Symfony\\Component\\Yaml\\": ""
320
+ }
321
+ },
322
+ "notification-url": "https://packagist.org/downloads/",
323
+ "license": [
324
+ "MIT"
325
+ ],
326
+ "authors": [
327
+ {
328
+ "name": "Fabien Potencier",
329
+ "email": "fabien@symfony.com"
330
+ },
331
+ {
332
+ "name": "Symfony Community",
333
+ "homepage": "https://symfony.com/contributors"
334
+ }
335
+ ],
336
+ "description": "Symfony Yaml Component",
337
+ "homepage": "https://symfony.com"
338
+ },
339
+ {
340
+ "name": "pimple/pimple",
341
+ "version": "v1.1.1",
342
+ "version_normalized": "1.1.1.0",
343
+ "source": {
344
+ "type": "git",
345
+ "url": "https://github.com/silexphp/Pimple.git",
346
+ "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d"
347
+ },
348
+ "dist": {
349
+ "type": "zip",
350
+ "url": "https://api.github.com/repos/silexphp/Pimple/zipball/2019c145fe393923f3441b23f29bbdfaa5c58c4d",
351
+ "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d",
352
+ "shasum": ""
353
+ },
354
+ "require": {
355
+ "php": ">=5.3.0"
356
+ },
357
+ "time": "2013-11-22 08:30:29",
358
+ "type": "library",
359
+ "extra": {
360
+ "branch-alias": {
361
+ "dev-master": "1.1.x-dev"
362
+ }
363
+ },
364
+ "installation-source": "dist",
365
+ "autoload": {
366
+ "psr-0": {
367
+ "Pimple": "lib/"
368
+ }
369
+ },
370
+ "notification-url": "https://packagist.org/downloads/",
371
+ "license": [
372
+ "MIT"
373
+ ],
374
+ "authors": [
375
+ {
376
+ "name": "Fabien Potencier",
377
+ "email": "fabien@symfony.com"
378
+ }
379
+ ],
380
+ "description": "Pimple is a simple Dependency Injection Container for PHP 5.3",
381
+ "homepage": "http://pimple.sensiolabs.org",
382
+ "keywords": [
383
+ "container",
384
+ "dependency injection"
385
+ ]
386
+ },
387
+ {
388
+ "name": "silex/silex",
389
+ "version": "v1.2.4",
390
+ "version_normalized": "1.2.4.0",
391
+ "source": {
392
+ "type": "git",
393
+ "url": "https://github.com/silexphp/Silex.git",
394
+ "reference": "417deb440eecf776df868d8760d0b7d8e2c4e6d1"
395
+ },
396
+ "dist": {
397
+ "type": "zip",
398
+ "url": "https://api.github.com/repos/silexphp/Silex/zipball/417deb440eecf776df868d8760d0b7d8e2c4e6d1",
399
+ "reference": "417deb440eecf776df868d8760d0b7d8e2c4e6d1",
400
+ "shasum": ""
401
+ },
402
+ "require": {
403
+ "php": ">=5.3.3",
404
+ "pimple/pimple": "~1.0",
405
+ "symfony/event-dispatcher": "~2.3,<2.7",
406
+ "symfony/http-foundation": "~2.3,<2.7",
407
+ "symfony/http-kernel": "~2.3,<2.7",
408
+ "symfony/routing": "~2.3,<2.7"
409
+ },
410
+ "require-dev": {
411
+ "doctrine/dbal": "~2.2",
412
+ "monolog/monolog": "~1.4,>=1.4.1",
413
+ "swiftmailer/swiftmailer": "5.*",
414
+ "symfony/browser-kit": "~2.3,<2.7",
415
+ "symfony/config": "~2.3,<2.7",
416
+ "symfony/css-selector": "~2.3,<2.7",
417
+ "symfony/debug": "~2.3,<2.7",
418
+ "symfony/dom-crawler": "~2.3,<2.7",
419
+ "symfony/finder": "~2.3,<2.7",
420
+ "symfony/form": "~2.3,<2.7",
421
+ "symfony/locale": "~2.3,<2.7",
422
+ "symfony/monolog-bridge": "~2.3,<2.7",
423
+ "symfony/options-resolver": "~2.3,<2.7",
424
+ "symfony/process": "~2.3,<2.7",
425
+ "symfony/security": "~2.3,<2.7",
426
+ "symfony/serializer": "~2.3,<2.7",
427
+ "symfony/translation": "~2.3,<2.7",
428
+ "symfony/twig-bridge": "~2.3,<2.7",
429
+ "symfony/validator": "~2.3,<2.7",
430
+ "twig/twig": ">=1.8.0,<2.0-dev"
431
+ },
432
+ "suggest": {
433
+ "symfony/browser-kit": "~2.3",
434
+ "symfony/css-selector": "~2.3",
435
+ "symfony/dom-crawler": "~2.3",
436
+ "symfony/form": "~2.3"
437
+ },
438
+ "time": "2015-04-11 12:43:27",
439
+ "type": "library",
440
+ "extra": {
441
+ "branch-alias": {
442
+ "dev-master": "1.2.x-dev"
443
+ }
444
+ },
445
+ "installation-source": "dist",
446
+ "autoload": {
447
+ "psr-0": {
448
+ "Silex": "src/"
449
+ }
450
+ },
451
+ "notification-url": "https://packagist.org/downloads/",
452
+ "license": [
453
+ "MIT"
454
+ ],
455
+ "authors": [
456
+ {
457
+ "name": "Fabien Potencier",
458
+ "email": "fabien@symfony.com"
459
+ },
460
+ {
461
+ "name": "Igor Wiedler",
462
+ "email": "igor@wiedler.ch"
463
+ }
464
+ ],
465
+ "description": "The PHP micro-framework based on the Symfony2 Components",
466
+ "homepage": "http://silex.sensiolabs.org",
467
+ "keywords": [
468
+ "microframework"
469
+ ]
470
+ },
471
+ {
472
+ "name": "deralex/yaml-config-service-provider",
473
+ "version": "1.0.1",
474
+ "version_normalized": "1.0.1.0",
475
+ "source": {
476
+ "type": "git",
477
+ "url": "https://github.com/deralex/YamlConfigServiceProvider.git",
478
+ "reference": "5923f60e6fbb16432e47310cf9680fe658c8dc0e"
479
+ },
480
+ "dist": {
481
+ "type": "zip",
482
+ "url": "https://api.github.com/repos/deralex/YamlConfigServiceProvider/zipball/5923f60e6fbb16432e47310cf9680fe658c8dc0e",
483
+ "reference": "5923f60e6fbb16432e47310cf9680fe658c8dc0e",
484
+ "shasum": ""
485
+ },
486
+ "require": {
487
+ "silex/silex": ">=1.0 <=1.3",
488
+ "symfony/yaml": "~2.4"
489
+ },
490
+ "require-dev": {
491
+ "phpspec/phpspec": "2.0.*@dev"
492
+ },
493
+ "suggest": {
494
+ "symfony/yaml": "~2.4"
495
+ },
496
+ "time": "2015-03-10 12:58:27",
497
+ "type": "library",
498
+ "extra": {
499
+ "branch-alias": {
500
+ "dev-master": "1.0-dev"
501
+ }
502
+ },
503
+ "installation-source": "dist",
504
+ "autoload": {
505
+ "psr-0": {
506
+ "DerAlex\\Silex": "src"
507
+ }
508
+ },
509
+ "notification-url": "https://packagist.org/downloads/",
510
+ "license": [
511
+ "MIT"
512
+ ],
513
+ "authors": [
514
+ {
515
+ "name": "Alexander Kluth",
516
+ "email": "contact@alexanderkluth.com"
517
+ }
518
+ ],
519
+ "description": "Silex ServiceProvider for using YAML configuration files",
520
+ "keywords": [
521
+ "silex"
522
+ ]
523
+ },
524
+ {
525
+ "name": "symfony/config",
526
+ "version": "v2.6.7",
527
+ "version_normalized": "2.6.7.0",
528
+ "target-dir": "Symfony/Component/Config",
529
+ "source": {
530
+ "type": "git",
531
+ "url": "https://github.com/symfony/config.git",
532
+ "reference": "b6fddb4aa2daaa2b06f0040071ac131b4a1ecf25"
533
+ },
534
+ "dist": {
535
+ "type": "zip",
536
+ "url": "https://api.github.com/repos/symfony/config/zipball/b6fddb4aa2daaa2b06f0040071ac131b4a1ecf25",
537
+ "reference": "b6fddb4aa2daaa2b06f0040071ac131b4a1ecf25",
538
+ "shasum": ""
539
+ },
540
+ "require": {
541
+ "php": ">=5.3.3",
542
+ "symfony/filesystem": "~2.3"
543
+ },
544
+ "require-dev": {
545
+ "symfony/phpunit-bridge": "~2.7"
546
+ },
547
+ "time": "2015-05-02 15:18:45",
548
+ "type": "library",
549
+ "extra": {
550
+ "branch-alias": {
551
+ "dev-master": "2.6-dev"
552
+ }
553
+ },
554
+ "installation-source": "dist",
555
+ "autoload": {
556
+ "psr-0": {
557
+ "Symfony\\Component\\Config\\": ""
558
+ }
559
+ },
560
+ "notification-url": "https://packagist.org/downloads/",
561
+ "license": [
562
+ "MIT"
563
+ ],
564
+ "authors": [
565
+ {
566
+ "name": "Fabien Potencier",
567
+ "email": "fabien@symfony.com"
568
+ },
569
+ {
570
+ "name": "Symfony Community",
571
+ "homepage": "https://symfony.com/contributors"
572
+ }
573
+ ],
574
+ "description": "Symfony Config Component",
575
+ "homepage": "https://symfony.com"
576
+ },
577
+ {
578
+ "name": "symfony/routing",
579
+ "version": "v2.6.11",
580
+ "version_normalized": "2.6.11.0",
581
+ "target-dir": "Symfony/Component/Routing",
582
+ "source": {
583
+ "type": "git",
584
+ "url": "https://github.com/symfony/Routing.git",
585
+ "reference": "0a1764d41bbb54f3864808c50569ac382b44d128"
586
+ },
587
+ "dist": {
588
+ "type": "zip",
589
+ "url": "https://api.github.com/repos/symfony/Routing/zipball/0a1764d41bbb54f3864808c50569ac382b44d128",
590
+ "reference": "0a1764d41bbb54f3864808c50569ac382b44d128",
591
+ "shasum": ""
592
+ },
593
+ "require": {
594
+ "php": ">=5.3.3"
595
+ },
596
+ "require-dev": {
597
+ "doctrine/annotations": "~1.0",
598
+ "doctrine/common": "~2.2",
599
+ "psr/log": "~1.0",
600
+ "symfony/config": "~2.2",
601
+ "symfony/expression-language": "~2.4",
602
+ "symfony/http-foundation": "~2.3",
603
+ "symfony/phpunit-bridge": "~2.7",
604
+ "symfony/yaml": "~2.0,>=2.0.5"
605
+ },
606
+ "suggest": {
607
+ "doctrine/annotations": "For using the annotation loader",
608
+ "symfony/config": "For using the all-in-one router or any loader",
609
+ "symfony/expression-language": "For using expression matching",
610
+ "symfony/yaml": "For using the YAML loader"
611
+ },
612
+ "time": "2015-07-09 16:02:48",
613
+ "type": "library",
614
+ "extra": {
615
+ "branch-alias": {
616
+ "dev-master": "2.6-dev"
617
+ }
618
+ },
619
+ "installation-source": "dist",
620
+ "autoload": {
621
+ "psr-0": {
622
+ "Symfony\\Component\\Routing\\": ""
623
+ }
624
+ },
625
+ "notification-url": "https://packagist.org/downloads/",
626
+ "license": [
627
+ "MIT"
628
+ ],
629
+ "authors": [
630
+ {
631
+ "name": "Fabien Potencier",
632
+ "email": "fabien@symfony.com"
633
+ },
634
+ {
635
+ "name": "Symfony Community",
636
+ "homepage": "https://symfony.com/contributors"
637
+ }
638
+ ],
639
+ "description": "Symfony Routing Component",
640
+ "homepage": "https://symfony.com",
641
+ "keywords": [
642
+ "router",
643
+ "routing",
644
+ "uri",
645
+ "url"
646
+ ]
647
+ },
648
+ {
649
+ "name": "symfony/http-foundation",
650
+ "version": "v2.6.11",
651
+ "version_normalized": "2.6.11.0",
652
+ "target-dir": "Symfony/Component/HttpFoundation",
653
+ "source": {
654
+ "type": "git",
655
+ "url": "https://github.com/symfony/http-foundation.git",
656
+ "reference": "e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c"
657
+ },
658
+ "dist": {
659
+ "type": "zip",
660
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c",
661
+ "reference": "e8fd1b73ac1c3de1f76c73801ddf1a8ecb1c1c9c",
662
+ "shasum": ""
663
+ },
664
+ "require": {
665
+ "php": ">=5.3.3"
666
+ },
667
+ "require-dev": {
668
+ "symfony/expression-language": "~2.4",
669
+ "symfony/phpunit-bridge": "~2.7"
670
+ },
671
+ "time": "2015-07-22 10:08:40",
672
+ "type": "library",
673
+ "extra": {
674
+ "branch-alias": {
675
+ "dev-master": "2.6-dev"
676
+ }
677
+ },
678
+ "installation-source": "dist",
679
+ "autoload": {
680
+ "psr-0": {
681
+ "Symfony\\Component\\HttpFoundation\\": ""
682
+ },
683
+ "classmap": [
684
+ "Symfony/Component/HttpFoundation/Resources/stubs"
685
+ ]
686
+ },
687
+ "notification-url": "https://packagist.org/downloads/",
688
+ "license": [
689
+ "MIT"
690
+ ],
691
+ "authors": [
692
+ {
693
+ "name": "Fabien Potencier",
694
+ "email": "fabien@symfony.com"
695
+ },
696
+ {
697
+ "name": "Symfony Community",
698
+ "homepage": "https://symfony.com/contributors"
699
+ }
700
+ ],
701
+ "description": "Symfony HttpFoundation Component",
702
+ "homepage": "https://symfony.com"
703
+ },
704
+ {
705
+ "name": "symfony/event-dispatcher",
706
+ "version": "v2.6.11",
707
+ "version_normalized": "2.6.11.0",
708
+ "target-dir": "Symfony/Component/EventDispatcher",
709
+ "source": {
710
+ "type": "git",
711
+ "url": "https://github.com/symfony/event-dispatcher.git",
712
+ "reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02"
713
+ },
714
+ "dist": {
715
+ "type": "zip",
716
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/672593bc4b0043a0acf91903bb75a1c82d8f2e02",
717
+ "reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02",
718
+ "shasum": ""
719
+ },
720
+ "require": {
721
+ "php": ">=5.3.3"
722
+ },
723
+ "require-dev": {
724
+ "psr/log": "~1.0",
725
+ "symfony/config": "~2.0,>=2.0.5",
726
+ "symfony/dependency-injection": "~2.6",
727
+ "symfony/expression-language": "~2.6",
728
+ "symfony/phpunit-bridge": "~2.7",
729
+ "symfony/stopwatch": "~2.3"
730
+ },
731
+ "suggest": {
732
+ "symfony/dependency-injection": "",
733
+ "symfony/http-kernel": ""
734
+ },
735
+ "time": "2015-05-02 15:18:45",
736
+ "type": "library",
737
+ "extra": {
738
+ "branch-alias": {
739
+ "dev-master": "2.6-dev"
740
+ }
741
+ },
742
+ "installation-source": "dist",
743
+ "autoload": {
744
+ "psr-0": {
745
+ "Symfony\\Component\\EventDispatcher\\": ""
746
+ }
747
+ },
748
+ "notification-url": "https://packagist.org/downloads/",
749
+ "license": [
750
+ "MIT"
751
+ ],
752
+ "authors": [
753
+ {
754
+ "name": "Fabien Potencier",
755
+ "email": "fabien@symfony.com"
756
+ },
757
+ {
758
+ "name": "Symfony Community",
759
+ "homepage": "https://symfony.com/contributors"
760
+ }
761
+ ],
762
+ "description": "Symfony EventDispatcher Component",
763
+ "homepage": "https://symfony.com"
764
+ },
765
+ {
766
+ "name": "symfony/debug",
767
+ "version": "v2.7.5",
768
+ "version_normalized": "2.7.5.0",
769
+ "source": {
770
+ "type": "git",
771
+ "url": "https://github.com/symfony/debug.git",
772
+ "reference": "c79c361bca8e5ada6a47603875a3c964d03b67b1"
773
+ },
774
+ "dist": {
775
+ "type": "zip",
776
+ "url": "https://api.github.com/repos/symfony/debug/zipball/c79c361bca8e5ada6a47603875a3c964d03b67b1",
777
+ "reference": "c79c361bca8e5ada6a47603875a3c964d03b67b1",
778
+ "shasum": ""
779
+ },
780
+ "require": {
781
+ "php": ">=5.3.9",
782
+ "psr/log": "~1.0"
783
+ },
784
+ "conflict": {
785
+ "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
786
+ },
787
+ "require-dev": {
788
+ "symfony/class-loader": "~2.2",
789
+ "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2",
790
+ "symfony/phpunit-bridge": "~2.7"
791
+ },
792
+ "time": "2015-09-14 08:41:38",
793
+ "type": "library",
794
+ "extra": {
795
+ "branch-alias": {
796
+ "dev-master": "2.7-dev"
797
+ }
798
+ },
799
+ "installation-source": "dist",
800
+ "autoload": {
801
+ "psr-4": {
802
+ "Symfony\\Component\\Debug\\": ""
803
+ }
804
+ },
805
+ "notification-url": "https://packagist.org/downloads/",
806
+ "license": [
807
+ "MIT"
808
+ ],
809
+ "authors": [
810
+ {
811
+ "name": "Fabien Potencier",
812
+ "email": "fabien@symfony.com"
813
+ },
814
+ {
815
+ "name": "Symfony Community",
816
+ "homepage": "https://symfony.com/contributors"
817
+ }
818
+ ],
819
+ "description": "Symfony Debug Component",
820
+ "homepage": "https://symfony.com"
821
+ },
822
+ {
823
+ "name": "symfony/http-kernel",
824
+ "version": "v2.6.11",
825
+ "version_normalized": "2.6.11.0",
826
+ "target-dir": "Symfony/Component/HttpKernel",
827
+ "source": {
828
+ "type": "git",
829
+ "url": "https://github.com/symfony/http-kernel.git",
830
+ "reference": "a3f0ed713255c0400a2db38b3ed01989ef4b7322"
831
+ },
832
+ "dist": {
833
+ "type": "zip",
834
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/a3f0ed713255c0400a2db38b3ed01989ef4b7322",
835
+ "reference": "a3f0ed713255c0400a2db38b3ed01989ef4b7322",
836
+ "shasum": ""
837
+ },
838
+ "require": {
839
+ "php": ">=5.3.3",
840
+ "psr/log": "~1.0",
841
+ "symfony/debug": "~2.6,>=2.6.2",
842
+ "symfony/event-dispatcher": "~2.6,>=2.6.7",
843
+ "symfony/http-foundation": "~2.5,>=2.5.4"
844
+ },
845
+ "require-dev": {
846
+ "symfony/browser-kit": "~2.3",
847
+ "symfony/class-loader": "~2.1",
848
+ "symfony/config": "~2.0,>=2.0.5",
849
+ "symfony/console": "~2.3",
850
+ "symfony/css-selector": "~2.0,>=2.0.5",
851
+ "symfony/dependency-injection": "~2.2",
852
+ "symfony/dom-crawler": "~2.0,>=2.0.5",
853
+ "symfony/expression-language": "~2.4",
854
+ "symfony/finder": "~2.0,>=2.0.5",
855
+ "symfony/phpunit-bridge": "~2.7",
856
+ "symfony/process": "~2.0,>=2.0.5",
857
+ "symfony/routing": "~2.2",
858
+ "symfony/stopwatch": "~2.3",
859
+ "symfony/templating": "~2.2",
860
+ "symfony/translation": "~2.0,>=2.0.5",
861
+ "symfony/var-dumper": "~2.6"
862
+ },
863
+ "suggest": {
864
+ "symfony/browser-kit": "",
865
+ "symfony/class-loader": "",
866
+ "symfony/config": "",
867
+ "symfony/console": "",
868
+ "symfony/dependency-injection": "",
869
+ "symfony/finder": "",
870
+ "symfony/var-dumper": ""
871
+ },
872
+ "time": "2015-07-26 10:44:22",
873
+ "type": "library",
874
+ "extra": {
875
+ "branch-alias": {
876
+ "dev-master": "2.6-dev"
877
+ }
878
+ },
879
+ "installation-source": "dist",
880
+ "autoload": {
881
+ "psr-0": {
882
+ "Symfony\\Component\\HttpKernel\\": ""
883
+ }
884
+ },
885
+ "notification-url": "https://packagist.org/downloads/",
886
+ "license": [
887
+ "MIT"
888
+ ],
889
+ "authors": [
890
+ {
891
+ "name": "Fabien Potencier",
892
+ "email": "fabien@symfony.com"
893
+ },
894
+ {
895
+ "name": "Symfony Community",
896
+ "homepage": "https://symfony.com/contributors"
897
+ }
898
+ ],
899
+ "description": "Symfony HttpKernel Component",
900
+ "homepage": "https://symfony.com"
901
+ },
902
+ {
903
+ "name": "symfony/filesystem",
904
+ "version": "v2.7.5",
905
+ "version_normalized": "2.7.5.0",
906
+ "source": {
907
+ "type": "git",
908
+ "url": "https://github.com/symfony/filesystem.git",
909
+ "reference": "a17f8a17c20e8614c15b8e116e2f4bcde102cfab"
910
+ },
911
+ "dist": {
912
+ "type": "zip",
913
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/a17f8a17c20e8614c15b8e116e2f4bcde102cfab",
914
+ "reference": "a17f8a17c20e8614c15b8e116e2f4bcde102cfab",
915
+ "shasum": ""
916
+ },
917
+ "require": {
918
+ "php": ">=5.3.9"
919
+ },
920
+ "require-dev": {
921
+ "symfony/phpunit-bridge": "~2.7"
922
+ },
923
+ "time": "2015-09-09 17:42:36",
924
+ "type": "library",
925
+ "extra": {
926
+ "branch-alias": {
927
+ "dev-master": "2.7-dev"
928
+ }
929
+ },
930
+ "installation-source": "dist",
931
+ "autoload": {
932
+ "psr-4": {
933
+ "Symfony\\Component\\Filesystem\\": ""
934
+ }
935
+ },
936
+ "notification-url": "https://packagist.org/downloads/",
937
+ "license": [
938
+ "MIT"
939
+ ],
940
+ "authors": [
941
+ {
942
+ "name": "Fabien Potencier",
943
+ "email": "fabien@symfony.com"
944
+ },
945
+ {
946
+ "name": "Symfony Community",
947
+ "homepage": "https://symfony.com/contributors"
948
+ }
949
+ ],
950
+ "description": "Symfony Filesystem Component",
951
+ "homepage": "https://symfony.com"
952
+ },
953
+ {
954
+ "name": "expressly/php-common",
955
+ "version": "1.1.6",
956
+ "version_normalized": "1.1.6.0",
957
+ "source": {
958
+ "type": "git",
959
+ "url": "https://github.com/expressly/php-common.git",
960
+ "reference": "7fcf212fdcd4967b23ce087cf19a6fed440b1b52"
961
+ },
962
+ "dist": {
963
+ "type": "zip",
964
+ "url": "https://api.github.com/repos/expressly/php-common/zipball/7fcf212fdcd4967b23ce087cf19a6fed440b1b52",
965
+ "reference": "7fcf212fdcd4967b23ce087cf19a6fed440b1b52",
966
+ "shasum": ""
967
+ },
968
+ "require": {
969
+ "deralex/yaml-config-service-provider": "1.0.1",
970
+ "doctrine/collections": "1.3.0",
971
+ "kriswallsmith/buzz": "0.13",
972
+ "monolog/monolog": "1.13.1",
973
+ "php": ">=5.3.0",
974
+ "predis/predis": "1.0.1",
975
+ "silex/silex": "1.2.4",
976
+ "symfony/config": "2.6.7",
977
+ "symfony/yaml": "2.6.7"
978
+ },
979
+ "require-dev": {
980
+ "phpunit/phpunit": "4.6.6"
981
+ },
982
+ "time": "2015-09-25 12:59:26",
983
+ "type": "library",
984
+ "installation-source": "dist",
985
+ "autoload": {
986
+ "psr-4": {
987
+ "Expressly\\": "src/"
988
+ }
989
+ },
990
+ "license": [
991
+ "MIT"
992
+ ],
993
+ "authors": [
994
+ {
995
+ "name": "Sam Pratt",
996
+ "email": "sam@buyexpressly.com"
997
+ }
998
+ ],
999
+ "description": "Expressly common PHP library",
1000
+ "support": {
1001
+ "source": "https://github.com/expressly/php-common/tree/1.1.6",
1002
+ "issues": "https://github.com/expressly/php-common/issues"
1003
+ }
1004
+ }
1005
+ ]
app/code/community/Expressly/Expressly/vendor/deralex/yaml-config-service-provider/.gitignore ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Bootstrap
2
+ app/bootstrap*
3
+
4
+ # Symfony directories
5
+ vendor/*
6
+ */logs/*
7
+ */cache/*
8
+ web/uploads/*
9
+ web/bundles/*
10
+ bin/
11
+
12
+ # Configuration files
13
+ app/config/parameters.ini
14
+ app/config/parameters.yml
15
+
16
+ .idea/
17
+
app/code/community/Expressly/Expressly/vendor/deralex/yaml-config-service-provider/.travis.yml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ language: php
2
+
3
+ php:
4
+ - 5.3
5
+ - 5.4
6
+
7
+ before_script:
8
+ - curl -s http://getcomposer.org/installer | php
9
+ - php composer.phar install --dev
app/code/community/Expressly/Expressly/vendor/deralex/yaml-config-service-provider/README.md ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ YamlConfigServiceProvider
2
+ =========================
3
+
4
+ Service provider for Silex for using YAML configuration files.
5
+
6
+ [![Latest Stable Version](https://poser.pugx.org/deralex/yaml-config-service-provider/v/stable.png)](https://packagist.org/packages/deralex/yaml-config-service-provider)
7
+ [![Total Downloads](https://poser.pugx.org/deralex/yaml-config-service-provider/downloads.png)](https://packagist.org/packages/deralex/yaml-config-service-provider)
8
+
9
+ Installation
10
+ --------------
11
+
12
+ To use it add following line to your composer.json:
13
+
14
+ "require": {
15
+ ...
16
+ "deralex/yaml-config-service-provider": "1.0.x-dev"
17
+ ...
18
+ }
19
+
20
+
21
+ Usage
22
+ --------------
23
+ Include following line of code somewhere in your initial Silex file (index.php or whatever):
24
+
25
+ $app->register(new DerAlex\Silex\YamlConfigServiceProvider(PATH_TO_CONFIG));
26
+
27
+ Now you have access to all of your configuration variables through `$app['config']`.
28
+
29
+
30
+ Example
31
+ ---------------
32
+
33
+ config.yml:
34
+
35
+ database:
36
+ host: localhost
37
+ user: myuser
38
+ password: mypassword
39
+
40
+ index.php:
41
+
42
+ <?php
43
+ require_once __DIR__.'/../vendor/autoload.php';
44
+
45
+ $app = new Silex\Application();
46
+
47
+ // Considering the config.yml files is in the same directory as index.php
48
+ $app->register(new DerAlex\Silex\YamlConfigServiceProvider('config.yml'));
49
+
50
+ echo $app['config']['database']['host'];
51
+ ...
52
+
53
+ License
54
+ ----------------
55
+ Copyright (c) 2013 Alexander Kluth <contact@alexanderkluth.com>
56
+
57
+ Permission is hereby granted, free of charge, to any person obtaining a
58
+ copy of this software and associated documentation files (the "Software"),
59
+ to deal in the Software without restriction, including without limitation
60
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
61
+ and/or sell copies of the Software, and to permit persons to whom the
62
+ Software is furnished to do so, subject to the following conditions:
63
+
64
+ The above copyright notice and this permission notice shall be included in
65
+ all copies or substantial portions of the Software.
66
+
67
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
68
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
69
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
70
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
71
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
72
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
73
+ DEALINGS IN THE SOFTWARE.
app/code/community/Expressly/Expressly/vendor/deralex/yaml-config-service-provider/composer.json ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "deralex/yaml-config-service-provider",
3
+ "description": "Silex ServiceProvider for using YAML configuration files",
4
+ "keywords": ["silex"],
5
+ "license": "MIT",
6
+ "authors": [{
7
+ "name": "Alexander Kluth",
8
+ "email": "contact@alexanderkluth.com"
9
+ }],
10
+ "require": {
11
+ "silex/silex": ">=1.0 <=1.3",
12
+ "symfony/yaml": "~2.4"
13
+ },
14
+ "require-dev": {
15
+ "phpspec/phpspec": "2.0.*@dev"
16
+ },
17
+ "suggest": {
18
+ "symfony/yaml": "~2.4"
19
+ },
20
+ "autoload": {
21
+ "psr-0": { "DerAlex\\Silex": "src" }
22
+ },
23
+ "extra": {
24
+ "branch-alias": {
25
+ "dev-master": "1.0-dev"
26
+ }
27
+ },
28
+ "config": {
29
+ "bin-dir": "bin"
30
+ }
31
+ }
app/code/community/Expressly/Expressly/vendor/deralex/yaml-config-service-provider/composer.lock ADDED
@@ -0,0 +1,923 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_readme": [
3
+ "This file locks the dependencies of your project to a known state",
4
+ "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5
+ "This file is @generated automatically"
6
+ ],
7
+ "hash": "5e62b2e07f9b4eb0100dca5b7178454c",
8
+ "packages": [
9
+ {
10
+ "name": "pimple/pimple",
11
+ "version": "v1.1.1",
12
+ "source": {
13
+ "type": "git",
14
+ "url": "https://github.com/silexphp/Pimple.git",
15
+ "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d"
16
+ },
17
+ "dist": {
18
+ "type": "zip",
19
+ "url": "https://api.github.com/repos/silexphp/Pimple/zipball/2019c145fe393923f3441b23f29bbdfaa5c58c4d",
20
+ "reference": "2019c145fe393923f3441b23f29bbdfaa5c58c4d",
21
+ "shasum": ""
22
+ },
23
+ "require": {
24
+ "php": ">=5.3.0"
25
+ },
26
+ "type": "library",
27
+ "extra": {
28
+ "branch-alias": {
29
+ "dev-master": "1.1.x-dev"
30
+ }
31
+ },
32
+ "autoload": {
33
+ "psr-0": {
34
+ "Pimple": "lib/"
35
+ }
36
+ },
37
+ "notification-url": "https://packagist.org/downloads/",
38
+ "license": [
39
+ "MIT"
40
+ ],
41
+ "authors": [
42
+ {
43
+ "name": "Fabien Potencier",
44
+ "email": "fabien@symfony.com"
45
+ }
46
+ ],
47
+ "description": "Pimple is a simple Dependency Injection Container for PHP 5.3",
48
+ "homepage": "http://pimple.sensiolabs.org",
49
+ "keywords": [
50
+ "container",
51
+ "dependency injection"
52
+ ],
53
+ "time": "2013-11-22 08:30:29"
54
+ },
55
+ {
56
+ "name": "psr/log",
57
+ "version": "1.0.0",
58
+ "source": {
59
+ "type": "git",
60
+ "url": "https://github.com/php-fig/log.git",
61
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b"
62
+ },
63
+ "dist": {
64
+ "type": "zip",
65
+ "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b",
66
+ "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b",
67
+ "shasum": ""
68
+ },
69
+ "type": "library",
70
+ "autoload": {
71
+ "psr-0": {
72
+ "Psr\\Log\\": ""
73
+ }
74
+ },
75
+ "notification-url": "https://packagist.org/downloads/",
76
+ "license": [
77
+ "MIT"
78
+ ],
79
+ "authors": [
80
+ {
81
+ "name": "PHP-FIG",
82
+ "homepage": "http://www.php-fig.org/"
83
+ }
84
+ ],
85
+ "description": "Common interface for logging libraries",
86
+ "keywords": [
87
+ "log",
88
+ "psr",
89
+ "psr-3"
90
+ ],
91
+ "time": "2012-12-21 11:40:51"
92
+ },
93
+ {
94
+ "name": "silex/silex",
95
+ "version": "v1.2.3",
96
+ "source": {
97
+ "type": "git",
98
+ "url": "https://github.com/silexphp/Silex.git",
99
+ "reference": "57c98ea0cb47664096094912920951fde1f4631a"
100
+ },
101
+ "dist": {
102
+ "type": "zip",
103
+ "url": "https://api.github.com/repos/silexphp/Silex/zipball/57c98ea0cb47664096094912920951fde1f4631a",
104
+ "reference": "57c98ea0cb47664096094912920951fde1f4631a",
105
+ "shasum": ""
106
+ },
107
+ "require": {
108
+ "php": ">=5.3.3",
109
+ "pimple/pimple": "~1.0",
110
+ "symfony/event-dispatcher": "~2.3,<3.0",
111
+ "symfony/http-foundation": "~2.3,<3.0",
112
+ "symfony/http-kernel": "~2.3,<3.0",
113
+ "symfony/routing": "~2.3,<3.0"
114
+ },
115
+ "require-dev": {
116
+ "doctrine/dbal": "~2.2",
117
+ "monolog/monolog": "~1.4,>=1.4.1",
118
+ "swiftmailer/swiftmailer": "5.*",
119
+ "symfony/browser-kit": "~2.3,<3.0",
120
+ "symfony/config": "~2.3,<3.0",
121
+ "symfony/css-selector": "~2.3,<3.0",
122
+ "symfony/debug": "~2.3,<3.0",
123
+ "symfony/dom-crawler": "~2.3,<3.0",
124
+ "symfony/finder": "~2.3,<3.0",
125
+ "symfony/form": "~2.3,<3.0",
126
+ "symfony/locale": "~2.3,<3.0",
127
+ "symfony/monolog-bridge": "~2.3,<3.0",
128
+ "symfony/options-resolver": "~2.3,<3.0",
129
+ "symfony/process": "~2.3,<3.0",
130
+ "symfony/security": "~2.3,<3.0",
131
+ "symfony/serializer": "~2.3,<3.0",
132
+ "symfony/translation": "~2.3,<3.0",
133
+ "symfony/twig-bridge": "~2.3,<3.0",
134
+ "symfony/validator": "~2.3,<3.0",
135
+ "twig/twig": ">=1.8.0,<2.0-dev"
136
+ },
137
+ "suggest": {
138
+ "symfony/browser-kit": "~2.3",
139
+ "symfony/css-selector": "~2.3",
140
+ "symfony/dom-crawler": "~2.3",
141
+ "symfony/form": "~2.3"
142
+ },
143
+ "type": "library",
144
+ "extra": {
145
+ "branch-alias": {
146
+ "dev-master": "1.2.x-dev"
147
+ }
148
+ },
149
+ "autoload": {
150
+ "psr-0": {
151
+ "Silex": "src/"
152
+ }
153
+ },
154
+ "notification-url": "https://packagist.org/downloads/",
155
+ "license": [
156
+ "MIT"
157
+ ],
158
+ "authors": [
159
+ {
160
+ "name": "Fabien Potencier",
161
+ "email": "fabien@symfony.com"
162
+ },
163
+ {
164
+ "name": "Igor Wiedler",
165
+ "email": "igor@wiedler.ch"
166
+ }
167
+ ],
168
+ "description": "The PHP micro-framework based on the Symfony2 Components",
169
+ "homepage": "http://silex.sensiolabs.org",
170
+ "keywords": [
171
+ "microframework"
172
+ ],
173
+ "time": "2015-01-20 16:45:58"
174
+ },
175
+ {
176
+ "name": "symfony/debug",
177
+ "version": "v2.6.4",
178
+ "target-dir": "Symfony/Component/Debug",
179
+ "source": {
180
+ "type": "git",
181
+ "url": "https://github.com/symfony/Debug.git",
182
+ "reference": "150c80059c3ccf68f96a4fceb513eb6b41f23300"
183
+ },
184
+ "dist": {
185
+ "type": "zip",
186
+ "url": "https://api.github.com/repos/symfony/Debug/zipball/150c80059c3ccf68f96a4fceb513eb6b41f23300",
187
+ "reference": "150c80059c3ccf68f96a4fceb513eb6b41f23300",
188
+ "shasum": ""
189
+ },
190
+ "require": {
191
+ "php": ">=5.3.3",
192
+ "psr/log": "~1.0"
193
+ },
194
+ "conflict": {
195
+ "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
196
+ },
197
+ "require-dev": {
198
+ "symfony/class-loader": "~2.2",
199
+ "symfony/http-foundation": "~2.1",
200
+ "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2"
201
+ },
202
+ "suggest": {
203
+ "symfony/http-foundation": "",
204
+ "symfony/http-kernel": ""
205
+ },
206
+ "type": "library",
207
+ "extra": {
208
+ "branch-alias": {
209
+ "dev-master": "2.6-dev"
210
+ }
211
+ },
212
+ "autoload": {
213
+ "psr-0": {
214
+ "Symfony\\Component\\Debug\\": ""
215
+ }
216
+ },
217
+ "notification-url": "https://packagist.org/downloads/",
218
+ "license": [
219
+ "MIT"
220
+ ],
221
+ "authors": [
222
+ {
223
+ "name": "Symfony Community",
224
+ "homepage": "http://symfony.com/contributors"
225
+ },
226
+ {
227
+ "name": "Fabien Potencier",
228
+ "email": "fabien@symfony.com"
229
+ }
230
+ ],
231
+ "description": "Symfony Debug Component",
232
+ "homepage": "http://symfony.com",
233
+ "time": "2015-01-21 20:57:55"
234
+ },
235
+ {
236
+ "name": "symfony/event-dispatcher",
237
+ "version": "v2.6.4",
238
+ "target-dir": "Symfony/Component/EventDispatcher",
239
+ "source": {
240
+ "type": "git",
241
+ "url": "https://github.com/symfony/EventDispatcher.git",
242
+ "reference": "f75989f3ab2743a82fe0b03ded2598a2b1546813"
243
+ },
244
+ "dist": {
245
+ "type": "zip",
246
+ "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/f75989f3ab2743a82fe0b03ded2598a2b1546813",
247
+ "reference": "f75989f3ab2743a82fe0b03ded2598a2b1546813",
248
+ "shasum": ""
249
+ },
250
+ "require": {
251
+ "php": ">=5.3.3"
252
+ },
253
+ "require-dev": {
254
+ "psr/log": "~1.0",
255
+ "symfony/config": "~2.0,>=2.0.5",
256
+ "symfony/dependency-injection": "~2.6",
257
+ "symfony/expression-language": "~2.6",
258
+ "symfony/stopwatch": "~2.3"
259
+ },
260
+ "suggest": {
261
+ "symfony/dependency-injection": "",
262
+ "symfony/http-kernel": ""
263
+ },
264
+ "type": "library",
265
+ "extra": {
266
+ "branch-alias": {
267
+ "dev-master": "2.6-dev"
268
+ }
269
+ },
270
+ "autoload": {
271
+ "psr-0": {
272
+ "Symfony\\Component\\EventDispatcher\\": ""
273
+ }
274
+ },
275
+ "notification-url": "https://packagist.org/downloads/",
276
+ "license": [
277
+ "MIT"
278
+ ],
279
+ "authors": [
280
+ {
281
+ "name": "Symfony Community",
282
+ "homepage": "http://symfony.com/contributors"
283
+ },
284
+ {
285
+ "name": "Fabien Potencier",
286
+ "email": "fabien@symfony.com"
287
+ }
288
+ ],
289
+ "description": "Symfony EventDispatcher Component",
290
+ "homepage": "http://symfony.com",
291
+ "time": "2015-02-01 16:10:57"
292
+ },
293
+ {
294
+ "name": "symfony/http-foundation",
295
+ "version": "v2.6.4",
296
+ "target-dir": "Symfony/Component/HttpFoundation",
297
+ "source": {
298
+ "type": "git",
299
+ "url": "https://github.com/symfony/HttpFoundation.git",
300
+ "reference": "8fa63d614d56ccfe033e30411d90913cfc483ff6"
301
+ },
302
+ "dist": {
303
+ "type": "zip",
304
+ "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/8fa63d614d56ccfe033e30411d90913cfc483ff6",
305
+ "reference": "8fa63d614d56ccfe033e30411d90913cfc483ff6",
306
+ "shasum": ""
307
+ },
308
+ "require": {
309
+ "php": ">=5.3.3"
310
+ },
311
+ "require-dev": {
312
+ "symfony/expression-language": "~2.4"
313
+ },
314
+ "type": "library",
315
+ "extra": {
316
+ "branch-alias": {
317
+ "dev-master": "2.6-dev"
318
+ }
319
+ },
320
+ "autoload": {
321
+ "psr-0": {
322
+ "Symfony\\Component\\HttpFoundation\\": ""
323
+ },
324
+ "classmap": [
325
+ "Symfony/Component/HttpFoundation/Resources/stubs"
326
+ ]
327
+ },
328
+ "notification-url": "https://packagist.org/downloads/",
329
+ "license": [
330
+ "MIT"
331
+ ],
332
+ "authors": [
333
+ {
334
+ "name": "Symfony Community",
335
+ "homepage": "http://symfony.com/contributors"
336
+ },
337
+ {
338
+ "name": "Fabien Potencier",
339
+ "email": "fabien@symfony.com"
340
+ }
341
+ ],
342
+ "description": "Symfony HttpFoundation Component",
343
+ "homepage": "http://symfony.com",
344
+ "time": "2015-02-01 16:10:57"
345
+ },
346
+ {
347
+ "name": "symfony/http-kernel",
348
+ "version": "v2.6.4",
349
+ "target-dir": "Symfony/Component/HttpKernel",
350
+ "source": {
351
+ "type": "git",
352
+ "url": "https://github.com/symfony/HttpKernel.git",
353
+ "reference": "27abf3106d8bd08562070dd4e2438c279792c434"
354
+ },
355
+ "dist": {
356
+ "type": "zip",
357
+ "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/27abf3106d8bd08562070dd4e2438c279792c434",
358
+ "reference": "27abf3106d8bd08562070dd4e2438c279792c434",
359
+ "shasum": ""
360
+ },
361
+ "require": {
362
+ "php": ">=5.3.3",
363
+ "psr/log": "~1.0",
364
+ "symfony/debug": "~2.6,>=2.6.2",
365
+ "symfony/event-dispatcher": "~2.5.9|~2.6,>=2.6.2",
366
+ "symfony/http-foundation": "~2.5,>=2.5.4"
367
+ },
368
+ "require-dev": {
369
+ "symfony/browser-kit": "~2.3",
370
+ "symfony/class-loader": "~2.1",
371
+ "symfony/config": "~2.0,>=2.0.5",
372
+ "symfony/console": "~2.3",
373
+ "symfony/css-selector": "~2.0,>=2.0.5",
374
+ "symfony/dependency-injection": "~2.2",
375
+ "symfony/dom-crawler": "~2.0,>=2.0.5",
376
+ "symfony/expression-language": "~2.4",
377
+ "symfony/finder": "~2.0,>=2.0.5",
378
+ "symfony/process": "~2.0,>=2.0.5",
379
+ "symfony/routing": "~2.2",
380
+ "symfony/stopwatch": "~2.3",
381
+ "symfony/templating": "~2.2",
382
+ "symfony/translation": "~2.0,>=2.0.5",
383
+ "symfony/var-dumper": "~2.6"
384
+ },
385
+ "suggest": {
386
+ "symfony/browser-kit": "",
387
+ "symfony/class-loader": "",
388
+ "symfony/config": "",
389
+ "symfony/console": "",
390
+ "symfony/dependency-injection": "",
391
+ "symfony/finder": "",
392
+ "symfony/var-dumper": ""
393
+ },
394
+ "type": "library",
395
+ "extra": {
396
+ "branch-alias": {
397
+ "dev-master": "2.6-dev"
398
+ }
399
+ },
400
+ "autoload": {
401
+ "psr-0": {
402
+ "Symfony\\Component\\HttpKernel\\": ""
403
+ }
404
+ },
405
+ "notification-url": "https://packagist.org/downloads/",
406
+ "license": [
407
+ "MIT"
408
+ ],
409
+ "authors": [
410
+ {
411
+ "name": "Symfony Community",
412
+ "homepage": "http://symfony.com/contributors"
413
+ },
414
+ {
415
+ "name": "Fabien Potencier",
416
+ "email": "fabien@symfony.com"
417
+ }
418
+ ],
419
+ "description": "Symfony HttpKernel Component",
420
+ "homepage": "http://symfony.com",
421
+ "time": "2015-02-02 18:02:30"
422
+ },
423
+ {
424
+ "name": "symfony/routing",
425
+ "version": "v2.6.4",
426
+ "target-dir": "Symfony/Component/Routing",
427
+ "source": {
428
+ "type": "git",
429
+ "url": "https://github.com/symfony/Routing.git",
430
+ "reference": "bda1c3c67f2a33bbeabb1d321feaf626a0ca5698"
431
+ },
432
+ "dist": {
433
+ "type": "zip",
434
+ "url": "https://api.github.com/repos/symfony/Routing/zipball/bda1c3c67f2a33bbeabb1d321feaf626a0ca5698",
435
+ "reference": "bda1c3c67f2a33bbeabb1d321feaf626a0ca5698",
436
+ "shasum": ""
437
+ },
438
+ "require": {
439
+ "php": ">=5.3.3"
440
+ },
441
+ "require-dev": {
442
+ "doctrine/annotations": "~1.0",
443
+ "doctrine/common": "~2.2",
444
+ "psr/log": "~1.0",
445
+ "symfony/config": "~2.2",
446
+ "symfony/expression-language": "~2.4",
447
+ "symfony/http-foundation": "~2.3",
448
+ "symfony/yaml": "~2.0,>=2.0.5"
449
+ },
450
+ "suggest": {
451
+ "doctrine/annotations": "For using the annotation loader",
452
+ "symfony/config": "For using the all-in-one router or any loader",
453
+ "symfony/expression-language": "For using expression matching",
454
+ "symfony/yaml": "For using the YAML loader"
455
+ },
456
+ "type": "library",
457
+ "extra": {
458
+ "branch-alias": {
459
+ "dev-master": "2.6-dev"
460
+ }
461
+ },
462
+ "autoload": {
463
+ "psr-0": {
464
+ "Symfony\\Component\\Routing\\": ""
465
+ }
466
+ },
467
+ "notification-url": "https://packagist.org/downloads/",
468
+ "license": [
469
+ "MIT"
470
+ ],
471
+ "authors": [
472
+ {
473
+ "name": "Symfony Community",
474
+ "homepage": "http://symfony.com/contributors"
475
+ },
476
+ {
477
+ "name": "Fabien Potencier",
478
+ "email": "fabien@symfony.com"
479
+ }
480
+ ],
481
+ "description": "Symfony Routing Component",
482
+ "homepage": "http://symfony.com",
483
+ "keywords": [
484
+ "router",
485
+ "routing",
486
+ "uri",
487
+ "url"
488
+ ],
489
+ "time": "2015-01-15 12:15:12"
490
+ },
491
+ {
492
+ "name": "symfony/yaml",
493
+ "version": "v2.6.4",
494
+ "target-dir": "Symfony/Component/Yaml",
495
+ "source": {
496
+ "type": "git",
497
+ "url": "https://github.com/symfony/Yaml.git",
498
+ "reference": "60ed7751671113cf1ee7d7778e691642c2e9acd8"
499
+ },
500
+ "dist": {
501
+ "type": "zip",
502
+ "url": "https://api.github.com/repos/symfony/Yaml/zipball/60ed7751671113cf1ee7d7778e691642c2e9acd8",
503
+ "reference": "60ed7751671113cf1ee7d7778e691642c2e9acd8",
504
+ "shasum": ""
505
+ },
506
+ "require": {
507
+ "php": ">=5.3.3"
508
+ },
509
+ "type": "library",
510
+ "extra": {
511
+ "branch-alias": {
512
+ "dev-master": "2.6-dev"
513
+ }
514
+ },
515
+ "autoload": {
516
+ "psr-0": {
517
+ "Symfony\\Component\\Yaml\\": ""
518
+ }
519
+ },
520
+ "notification-url": "https://packagist.org/downloads/",
521
+ "license": [
522
+ "MIT"
523
+ ],
524
+ "authors": [
525
+ {
526
+ "name": "Symfony Community",
527
+ "homepage": "http://symfony.com/contributors"
528
+ },
529
+ {
530
+ "name": "Fabien Potencier",
531
+ "email": "fabien@symfony.com"
532
+ }
533
+ ],
534
+ "description": "Symfony Yaml Component",
535
+ "homepage": "http://symfony.com",
536
+ "time": "2015-01-25 04:39:26"
537
+ }
538
+ ],
539
+ "packages-dev": [
540
+ {
541
+ "name": "doctrine/instantiator",
542
+ "version": "1.0.4",
543
+ "source": {
544
+ "type": "git",
545
+ "url": "https://github.com/doctrine/instantiator.git",
546
+ "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119"
547
+ },
548
+ "dist": {
549
+ "type": "zip",
550
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119",
551
+ "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119",
552
+ "shasum": ""
553
+ },
554
+ "require": {
555
+ "php": ">=5.3,<8.0-DEV"
556
+ },
557
+ "require-dev": {
558
+ "athletic/athletic": "~0.1.8",
559
+ "ext-pdo": "*",
560
+ "ext-phar": "*",
561
+ "phpunit/phpunit": "~4.0",
562
+ "squizlabs/php_codesniffer": "2.0.*@ALPHA"
563
+ },
564
+ "type": "library",
565
+ "extra": {
566
+ "branch-alias": {
567
+ "dev-master": "1.0.x-dev"
568
+ }
569
+ },
570
+ "autoload": {
571
+ "psr-0": {
572
+ "Doctrine\\Instantiator\\": "src"
573
+ }
574
+ },
575
+ "notification-url": "https://packagist.org/downloads/",
576
+ "license": [
577
+ "MIT"
578
+ ],
579
+ "authors": [
580
+ {
581
+ "name": "Marco Pivetta",
582
+ "email": "ocramius@gmail.com",
583
+ "homepage": "http://ocramius.github.com/"
584
+ }
585
+ ],
586
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
587
+ "homepage": "https://github.com/doctrine/instantiator",
588
+ "keywords": [
589
+ "constructor",
590
+ "instantiate"
591
+ ],
592
+ "time": "2014-10-13 12:58:55"
593
+ },
594
+ {
595
+ "name": "phpdocumentor/reflection-docblock",
596
+ "version": "2.0.4",
597
+ "source": {
598
+ "type": "git",
599
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
600
+ "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
601
+ },
602
+ "dist": {
603
+ "type": "zip",
604
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
605
+ "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
606
+ "shasum": ""
607
+ },
608
+ "require": {
609
+ "php": ">=5.3.3"
610
+ },
611
+ "require-dev": {
612
+ "phpunit/phpunit": "~4.0"
613
+ },
614
+ "suggest": {
615
+ "dflydev/markdown": "~1.0",
616
+ "erusev/parsedown": "~1.0"
617
+ },
618
+ "type": "library",
619
+ "extra": {
620
+ "branch-alias": {
621
+ "dev-master": "2.0.x-dev"
622
+ }
623
+ },
624
+ "autoload": {
625
+ "psr-0": {
626
+ "phpDocumentor": [
627
+ "src/"
628
+ ]
629
+ }
630
+ },
631
+ "notification-url": "https://packagist.org/downloads/",
632
+ "license": [
633
+ "MIT"
634
+ ],
635
+ "authors": [
636
+ {
637
+ "name": "Mike van Riel",
638
+ "email": "mike.vanriel@naenius.com"
639
+ }
640
+ ],
641
+ "time": "2015-02-03 12:10:50"
642
+ },
643
+ {
644
+ "name": "phpspec/php-diff",
645
+ "version": "v1.0.2",
646
+ "source": {
647
+ "type": "git",
648
+ "url": "https://github.com/phpspec/php-diff.git",
649
+ "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a"
650
+ },
651
+ "dist": {
652
+ "type": "zip",
653
+ "url": "https://api.github.com/repos/phpspec/php-diff/zipball/30e103d19519fe678ae64a60d77884ef3d71b28a",
654
+ "reference": "30e103d19519fe678ae64a60d77884ef3d71b28a",
655
+ "shasum": ""
656
+ },
657
+ "type": "library",
658
+ "autoload": {
659
+ "psr-0": {
660
+ "Diff": "lib/"
661
+ }
662
+ },
663
+ "notification-url": "https://packagist.org/downloads/",
664
+ "license": [
665
+ "BSD-3-Clause"
666
+ ],
667
+ "authors": [
668
+ {
669
+ "name": "Chris Boulton",
670
+ "homepage": "http://github.com/chrisboulton",
671
+ "role": "Original developer"
672
+ }
673
+ ],
674
+ "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).",
675
+ "time": "2013-11-01 13:02:21"
676
+ },
677
+ {
678
+ "name": "phpspec/phpspec",
679
+ "version": "2.0.1",
680
+ "source": {
681
+ "type": "git",
682
+ "url": "https://github.com/phpspec/phpspec.git",
683
+ "reference": "61712147412cb647b6cb68b19833a60bfda759a1"
684
+ },
685
+ "dist": {
686
+ "type": "zip",
687
+ "url": "https://api.github.com/repos/phpspec/phpspec/zipball/61712147412cb647b6cb68b19833a60bfda759a1",
688
+ "reference": "61712147412cb647b6cb68b19833a60bfda759a1",
689
+ "shasum": ""
690
+ },
691
+ "require": {
692
+ "php": ">=5.3.3",
693
+ "phpspec/php-diff": "~1.0.0",
694
+ "phpspec/prophecy": "~1.1",
695
+ "symfony/console": "~2.1",
696
+ "symfony/event-dispatcher": "~2.1",
697
+ "symfony/finder": "~2.1",
698
+ "symfony/yaml": "~2.1"
699
+ },
700
+ "require-dev": {
701
+ "behat/behat": "~2.5",
702
+ "bossa/phpspec2-expect": "dev-master",
703
+ "symfony/filesystem": "~2.1"
704
+ },
705
+ "suggest": {
706
+ "phpspec/nyan-formatters": "~1.0 – Adds Nyan formatters"
707
+ },
708
+ "bin": [
709
+ "bin/phpspec"
710
+ ],
711
+ "type": "library",
712
+ "extra": {
713
+ "branch-alias": {
714
+ "dev-master": "2.0.x-dev"
715
+ }
716
+ },
717
+ "autoload": {
718
+ "psr-0": {
719
+ "PhpSpec": "src/"
720
+ }
721
+ },
722
+ "notification-url": "https://packagist.org/downloads/",
723
+ "license": [
724
+ "MIT"
725
+ ],
726
+ "authors": [
727
+ {
728
+ "name": "Konstantin Kudryashov",
729
+ "email": "ever.zet@gmail.com",
730
+ "homepage": "http://everzet.com"
731
+ },
732
+ {
733
+ "name": "Marcello Duarte",
734
+ "homepage": "http://marcelloduarte.net/"
735
+ }
736
+ ],
737
+ "description": "Specification-oriented BDD framework for PHP 5.3+",
738
+ "homepage": "http://phpspec.net/",
739
+ "keywords": [
740
+ "BDD",
741
+ "SpecBDD",
742
+ "TDD",
743
+ "spec",
744
+ "specification",
745
+ "testing",
746
+ "tests"
747
+ ],
748
+ "time": "2014-07-01 14:09:19"
749
+ },
750
+ {
751
+ "name": "phpspec/prophecy",
752
+ "version": "v1.3.1",
753
+ "source": {
754
+ "type": "git",
755
+ "url": "https://github.com/phpspec/prophecy.git",
756
+ "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9"
757
+ },
758
+ "dist": {
759
+ "type": "zip",
760
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/9ca52329bcdd1500de24427542577ebf3fc2f1c9",
761
+ "reference": "9ca52329bcdd1500de24427542577ebf3fc2f1c9",
762
+ "shasum": ""
763
+ },
764
+ "require": {
765
+ "doctrine/instantiator": "~1.0,>=1.0.2",
766
+ "phpdocumentor/reflection-docblock": "~2.0"
767
+ },
768
+ "require-dev": {
769
+ "phpspec/phpspec": "~2.0"
770
+ },
771
+ "type": "library",
772
+ "extra": {
773
+ "branch-alias": {
774
+ "dev-master": "1.2.x-dev"
775
+ }
776
+ },
777
+ "autoload": {
778
+ "psr-0": {
779
+ "Prophecy\\": "src/"
780
+ }
781
+ },
782
+ "notification-url": "https://packagist.org/downloads/",
783
+ "license": [
784
+ "MIT"
785
+ ],
786
+ "authors": [
787
+ {
788
+ "name": "Konstantin Kudryashov",
789
+ "email": "ever.zet@gmail.com",
790
+ "homepage": "http://everzet.com"
791
+ },
792
+ {
793
+ "name": "Marcello Duarte",
794
+ "email": "marcello.duarte@gmail.com"
795
+ }
796
+ ],
797
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
798
+ "homepage": "http://phpspec.org",
799
+ "keywords": [
800
+ "Double",
801
+ "Dummy",
802
+ "fake",
803
+ "mock",
804
+ "spy",
805
+ "stub"
806
+ ],
807
+ "time": "2014-11-17 16:23:49"
808
+ },
809
+ {
810
+ "name": "symfony/console",
811
+ "version": "v2.6.4",
812
+ "target-dir": "Symfony/Component/Console",
813
+ "source": {
814
+ "type": "git",
815
+ "url": "https://github.com/symfony/Console.git",
816
+ "reference": "e44154bfe3e41e8267d7a3794cd9da9a51cfac34"
817
+ },
818
+ "dist": {
819
+ "type": "zip",
820
+ "url": "https://api.github.com/repos/symfony/Console/zipball/e44154bfe3e41e8267d7a3794cd9da9a51cfac34",
821
+ "reference": "e44154bfe3e41e8267d7a3794cd9da9a51cfac34",
822
+ "shasum": ""
823
+ },
824
+ "require": {
825
+ "php": ">=5.3.3"
826
+ },
827
+ "require-dev": {
828
+ "psr/log": "~1.0",
829
+ "symfony/event-dispatcher": "~2.1",
830
+ "symfony/process": "~2.1"
831
+ },
832
+ "suggest": {
833
+ "psr/log": "For using the console logger",
834
+ "symfony/event-dispatcher": "",
835
+ "symfony/process": ""
836
+ },
837
+ "type": "library",
838
+ "extra": {
839
+ "branch-alias": {
840
+ "dev-master": "2.6-dev"
841
+ }
842
+ },
843
+ "autoload": {
844
+ "psr-0": {
845
+ "Symfony\\Component\\Console\\": ""
846
+ }
847
+ },
848
+ "notification-url": "https://packagist.org/downloads/",
849
+ "license": [
850
+ "MIT"
851
+ ],
852
+ "authors": [
853
+ {
854
+ "name": "Symfony Community",
855
+ "homepage": "http://symfony.com/contributors"
856
+ },
857
+ {
858
+ "name": "Fabien Potencier",
859
+ "email": "fabien@symfony.com"
860
+ }
861
+ ],
862
+ "description": "Symfony Console Component",
863
+ "homepage": "http://symfony.com",
864
+ "time": "2015-01-25 04:39:26"
865
+ },
866
+ {
867
+ "name": "symfony/finder",
868
+ "version": "v2.6.4",
869
+ "target-dir": "Symfony/Component/Finder",
870
+ "source": {
871
+ "type": "git",
872
+ "url": "https://github.com/symfony/Finder.git",
873
+ "reference": "16513333bca64186c01609961a2bb1b95b5e1355"
874
+ },
875
+ "dist": {
876
+ "type": "zip",
877
+ "url": "https://api.github.com/repos/symfony/Finder/zipball/16513333bca64186c01609961a2bb1b95b5e1355",
878
+ "reference": "16513333bca64186c01609961a2bb1b95b5e1355",
879
+ "shasum": ""
880
+ },
881
+ "require": {
882
+ "php": ">=5.3.3"
883
+ },
884
+ "type": "library",
885
+ "extra": {
886
+ "branch-alias": {
887
+ "dev-master": "2.6-dev"
888
+ }
889
+ },
890
+ "autoload": {
891
+ "psr-0": {
892
+ "Symfony\\Component\\Finder\\": ""
893
+ }
894
+ },
895
+ "notification-url": "https://packagist.org/downloads/",
896
+ "license": [
897
+ "MIT"
898
+ ],
899
+ "authors": [
900
+ {
901
+ "name": "Symfony Community",
902
+ "homepage": "http://symfony.com/contributors"
903
+ },
904
+ {
905
+ "name": "Fabien Potencier",
906
+ "email": "fabien@symfony.com"
907
+ }
908
+ ],
909
+ "description": "Symfony Finder Component",
910
+ "homepage": "http://symfony.com",
911
+ "time": "2015-01-03 08:01:59"
912
+ }
913
+ ],
914
+ "aliases": [],
915
+ "minimum-stability": "stable",
916
+ "stability-flags": {
917
+ "phpspec/phpspec": 20
918
+ },
919
+ "prefer-stable": false,
920
+ "prefer-lowest": false,
921
+ "platform": [],
922
+ "platform-dev": []
923
+ }
app/code/community/Expressly/Expressly/vendor/deralex/yaml-config-service-provider/spec/DerAlex/Silex/YamlConfigServiceProviderSpec.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace spec\DerAlex\Silex;
4
+
5
+ use PhpSpec\ObjectBehavior;
6
+ use Prophecy\Argument;
7
+
8
+ class YamlConfigServiceProviderSpec extends ObjectBehavior
9
+ {
10
+ function let()
11
+ {
12
+ $this->beConstructedWith(__DIR__ . '/../../Fixtures/config.yml');
13
+ }
14
+
15
+ function it_is_initializable()
16
+ {
17
+ $this->shouldHaveType('DerAlex\Silex\YamlConfigServiceProvider');
18
+ }
19
+ }
app/code/community/Expressly/Expressly/vendor/deralex/yaml-config-service-provider/spec/Fixtures/config.yml ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ database:
2
+ host: localhost
3
+ user: myuser
4
+ password: mypassword
app/code/community/Expressly/Expressly/vendor/deralex/yaml-config-service-provider/src/DerAlex/Silex/YamlConfigServiceProvider.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /******************************************************************************
3
+ * Copyright (c) 2013 Alexander Kluth <contact@alexanderkluth.com> *
4
+ * *
5
+ * Permission is hereby granted, free of charge, to any person obtaining a *
6
+ * copy of this software and associated documentation files (the "Software"), *
7
+ * to deal in the Software without restriction, including without limitation *
8
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, *
9
+ * and/or sell copies of the Software, and to permit persons to whom the *
10
+ * Software is furnished to do so, subject to the following conditions: *
11
+ * *
12
+ * The above copyright notice and this permission notice shall be included in *
13
+ * all copies or substantial portions of the Software. *
14
+ * *
15
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
16
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
17
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
18
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
19
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
20
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
21
+ * DEALINGS IN THE SOFTWARE. *
22
+ ******************************************************************************/
23
+ namespace DerAlex\Silex;
24
+
25
+ use Silex\Application;
26
+ use Silex\ServiceProviderInterface;
27
+ use Symfony\Component\Yaml\Yaml;
28
+
29
+
30
+ class YamlConfigServiceProvider implements ServiceProviderInterface
31
+ {
32
+ protected $file;
33
+
34
+ public function __construct($file) {
35
+ $this->file = $file;
36
+ }
37
+
38
+ public function register(Application $app) {
39
+ $config = Yaml::parse(file_get_contents($this->file));
40
+
41
+ if (is_array($config)) {
42
+ $this->importSearch($config, $app);
43
+
44
+ if (isset($app['config']) && is_array($app['config'])) {
45
+ $app['config'] = array_replace_recursive($app['config'], $config);
46
+ } else {
47
+ $app['config'] = $config;
48
+ }
49
+ }
50
+
51
+ }
52
+
53
+ /**
54
+ * Looks for import directives..
55
+ *
56
+ * @param array $config
57
+ * The result of Yaml::parse().
58
+ */
59
+ public function importSearch(&$config, $app) {
60
+ foreach ($config as $key => $value) {
61
+ if ($key == 'imports') {
62
+ foreach ($value as $resource) {
63
+ $base_dir = str_replace(basename($this->file), '', $this->file);
64
+ $new_config = new YamlConfigServiceProvider($base_dir . $resource['resource']);
65
+ $new_config->register($app);
66
+ }
67
+ unset($config['imports']);
68
+ }
69
+ }
70
+ }
71
+
72
+ public function boot(Application $app) {
73
+ }
74
+
75
+ public function getConfigFile() {
76
+ return $this->file;
77
+ }
78
+ }
79
+
app/code/community/Expressly/Expressly/vendor/doctrine/collections/.gitignore ADDED
@@ -0,0 +1 @@
 
1
+ vendor/
app/code/community/Expressly/Expressly/vendor/doctrine/collections/.travis.yml ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ language: php
2
+
3
+ php:
4
+ - 5.3
5
+ - 5.4
6
+ - 5.5
7
+ - 5.6
8
+ - 7.0
9
+ - hhvm
10
+ - hhvm-nightly
11
+
12
+ matrix:
13
+ fast_finish: true
14
+ allow_failures:
15
+ - php: 7.0
16
+
17
+ before_script:
18
+ - composer --prefer-source install
19
+
20
+ script:
21
+ - phpunit
app/code/community/Expressly/Expressly/vendor/doctrine/collections/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2006-2013 Doctrine Project
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
app/code/community/Expressly/Expressly/vendor/doctrine/collections/README.md ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Doctrine Collections
2
+
3
+ [![Build Status](https://travis-ci.org/doctrine/collections.svg?branch=master)](https://travis-ci.org/doctrine/collections)
4
+
5
+ Collections Abstraction library
6
+
7
+ ## Changelog
8
+
9
+ ### v1.3.0
10
+
11
+ * [Explicit casting of first and max results in criteria API](https://github.com/doctrine/collections/pull/26)
12
+ * [Keep keys when using `ArrayCollection#matching()` with sorting](https://github.com/doctrine/collections/pull/49)
13
+ * [Made `AbstractLazyCollection#$initialized` protected for extensibility](https://github.com/doctrine/collections/pull/52)
14
+
15
+ ### v1.2.0
16
+
17
+ * Add a new ``AbstractLazyCollection``
18
+
19
+ ### v1.1.0
20
+
21
+ * Deprecated ``Comparison::IS``, because it's only there for SQL semantics.
22
+ These are fixed in the ORM instead.
23
+ * Add ``Comparison::CONTAINS`` to perform partial string matches:
24
+
25
+ $criteria->andWhere($criteria->expr()->contains('property', 'Foo'));
app/code/community/Expressly/Expressly/vendor/doctrine/collections/composer.json ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "doctrine/collections",
3
+ "type": "library",
4
+ "description": "Collections Abstraction library",
5
+ "keywords": ["collections", "array", "iterator"],
6
+ "homepage": "http://www.doctrine-project.org",
7
+ "license": "MIT",
8
+ "authors": [
9
+ {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
10
+ {"name": "Roman Borschel", "email": "roman@code-factory.org"},
11
+ {"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
12
+ {"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
13
+ {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
14
+ ],
15
+ "require": {
16
+ "php": ">=5.3.2"
17
+ },
18
+ "require-dev": {
19
+ "phpunit/phpunit": "~4.0"
20
+ },
21
+ "autoload": {
22
+ "psr-0": { "Doctrine\\Common\\Collections\\": "lib/" }
23
+ },
24
+ "extra": {
25
+ "branch-alias": {
26
+ "dev-master": "1.2.x-dev"
27
+ }
28
+ }
29
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/AbstractLazyCollection.php ADDED
@@ -0,0 +1,343 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
+ *
15
+ * This software consists of voluntary contributions made by many individuals
16
+ * and is licensed under the MIT license. For more information, see
17
+ * <http://www.doctrine-project.org>.
18
+ */
19
+
20
+ namespace Doctrine\Common\Collections;
21
+
22
+ use Closure;
23
+
24
+ /**
25
+ * Lazy collection that is backed by a concrete collection
26
+ *
27
+ * @author Michaël Gallego <mic.gallego@gmail.com>
28
+ * @since 1.2
29
+ */
30
+ abstract class AbstractLazyCollection implements Collection
31
+ {
32
+ /**
33
+ * The backed collection to use
34
+ *
35
+ * @var Collection
36
+ */
37
+ protected $collection;
38
+
39
+ /**
40
+ * @var boolean
41
+ */
42
+ protected $initialized = false;
43
+
44
+ /**
45
+ * {@inheritDoc}
46
+ */
47
+ public function count()
48
+ {
49
+ $this->initialize();
50
+ return $this->collection->count();
51
+ }
52
+
53
+ /**
54
+ * {@inheritDoc}
55
+ */
56
+ public function add($element)
57
+ {
58
+ $this->initialize();
59
+ return $this->collection->add($element);
60
+ }
61
+
62
+ /**
63
+ * {@inheritDoc}
64
+ */
65
+ public function clear()
66
+ {
67
+ $this->initialize();
68
+ $this->collection->clear();
69
+ }
70
+
71
+ /**
72
+ * {@inheritDoc}
73
+ */
74
+ public function contains($element)
75
+ {
76
+ $this->initialize();
77
+ return $this->collection->contains($element);
78
+ }
79
+
80
+ /**
81
+ * {@inheritDoc}
82
+ */
83
+ public function isEmpty()
84
+ {
85
+ $this->initialize();
86
+ return $this->collection->isEmpty();
87
+ }
88
+
89
+ /**
90
+ * {@inheritDoc}
91
+ */
92
+ public function remove($key)
93
+ {
94
+ $this->initialize();
95
+ return $this->collection->remove($key);
96
+ }
97
+
98
+ /**
99
+ * {@inheritDoc}
100
+ */
101
+ public function removeElement($element)
102
+ {
103
+ $this->initialize();
104
+ return $this->collection->removeElement($element);
105
+ }
106
+
107
+ /**
108
+ * {@inheritDoc}
109
+ */
110
+ public function containsKey($key)
111
+ {
112
+ $this->initialize();
113
+ return $this->collection->containsKey($key);
114
+ }
115
+
116
+ /**
117
+ * {@inheritDoc}
118
+ */
119
+ public function get($key)
120
+ {
121
+ $this->initialize();
122
+ return $this->collection->get($key);
123
+ }
124
+
125
+ /**
126
+ * {@inheritDoc}
127
+ */
128
+ public function getKeys()
129
+ {
130
+ $this->initialize();
131
+ return $this->collection->getKeys();
132
+ }
133
+
134
+ /**
135
+ * {@inheritDoc}
136
+ */
137
+ public function getValues()
138
+ {
139
+ $this->initialize();
140
+ return $this->collection->getValues();
141
+ }
142
+
143
+ /**
144
+ * {@inheritDoc}
145
+ */
146
+ public function set($key, $value)
147
+ {
148
+ $this->initialize();
149
+ $this->collection->set($key, $value);
150
+ }
151
+
152
+ /**
153
+ * {@inheritDoc}
154
+ */
155
+ public function toArray()
156
+ {
157
+ $this->initialize();
158
+ return $this->collection->toArray();
159
+ }
160
+
161
+ /**
162
+ * {@inheritDoc}
163
+ */
164
+ public function first()
165
+ {
166
+ $this->initialize();
167
+ return $this->collection->first();
168
+ }
169
+
170
+ /**
171
+ * {@inheritDoc}
172
+ */
173
+ public function last()
174
+ {
175
+ $this->initialize();
176
+ return $this->collection->last();
177
+ }
178
+
179
+ /**
180
+ * {@inheritDoc}
181
+ */
182
+ public function key()
183
+ {
184
+ $this->initialize();
185
+ return $this->collection->key();
186
+ }
187
+
188
+ /**
189
+ * {@inheritDoc}
190
+ */
191
+ public function current()
192
+ {
193
+ $this->initialize();
194
+ return $this->collection->current();
195
+ }
196
+
197
+ /**
198
+ * {@inheritDoc}
199
+ */
200
+ public function next()
201
+ {
202
+ $this->initialize();
203
+ return $this->collection->next();
204
+ }
205
+
206
+ /**
207
+ * {@inheritDoc}
208
+ */
209
+ public function exists(Closure $p)
210
+ {
211
+ $this->initialize();
212
+ return $this->collection->exists($p);
213
+ }
214
+
215
+ /**
216
+ * {@inheritDoc}
217
+ */
218
+ public function filter(Closure $p)
219
+ {
220
+ $this->initialize();
221
+ return $this->collection->filter($p);
222
+ }
223
+
224
+ /**
225
+ * {@inheritDoc}
226
+ */
227
+ public function forAll(Closure $p)
228
+ {
229
+ $this->initialize();
230
+ return $this->collection->forAll($p);
231
+ }
232
+
233
+ /**
234
+ * {@inheritDoc}
235
+ */
236
+ public function map(Closure $func)
237
+ {
238
+ $this->initialize();
239
+ return $this->collection->map($func);
240
+ }
241
+
242
+ /**
243
+ * {@inheritDoc}
244
+ */
245
+ public function partition(Closure $p)
246
+ {
247
+ $this->initialize();
248
+ return $this->collection->partition($p);
249
+ }
250
+
251
+ /**
252
+ * {@inheritDoc}
253
+ */
254
+ public function indexOf($element)
255
+ {
256
+ $this->initialize();
257
+ return $this->collection->indexOf($element);
258
+ }
259
+
260
+ /**
261
+ * {@inheritDoc}
262
+ */
263
+ public function slice($offset, $length = null)
264
+ {
265
+ $this->initialize();
266
+ return $this->collection->slice($offset, $length);
267
+ }
268
+
269
+ /**
270
+ * {@inheritDoc}
271
+ */
272
+ public function getIterator()
273
+ {
274
+ $this->initialize();
275
+ return $this->collection->getIterator();
276
+ }
277
+
278
+ /**
279
+ * {@inheritDoc}
280
+ */
281
+ public function offsetExists($offset)
282
+ {
283
+ $this->initialize();
284
+ return $this->collection->offsetExists($offset);
285
+ }
286
+
287
+ /**
288
+ * {@inheritDoc}
289
+ */
290
+ public function offsetGet($offset)
291
+ {
292
+ $this->initialize();
293
+ return $this->collection->offsetGet($offset);
294
+ }
295
+
296
+ /**
297
+ * {@inheritDoc}
298
+ */
299
+ public function offsetSet($offset, $value)
300
+ {
301
+ $this->initialize();
302
+ $this->collection->offsetSet($offset, $value);
303
+ }
304
+
305
+ /**
306
+ * {@inheritDoc}
307
+ */
308
+ public function offsetUnset($offset)
309
+ {
310
+ $this->initialize();
311
+ $this->collection->offsetUnset($offset);
312
+ }
313
+
314
+ /**
315
+ * Is the lazy collection already initialized?
316
+ *
317
+ * @return bool
318
+ */
319
+ public function isInitialized()
320
+ {
321
+ return $this->initialized;
322
+ }
323
+
324
+ /**
325
+ * Initialize the collection
326
+ *
327
+ * @return void
328
+ */
329
+ protected function initialize()
330
+ {
331
+ if ( ! $this->initialized) {
332
+ $this->doInitialize();
333
+ $this->initialized = true;
334
+ }
335
+ }
336
+
337
+ /**
338
+ * Do the initialization logic
339
+ *
340
+ * @return void
341
+ */
342
+ abstract protected function doInitialize();
343
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php ADDED
@@ -0,0 +1,387 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
+ *
15
+ * This software consists of voluntary contributions made by many individuals
16
+ * and is licensed under the MIT license. For more information, see
17
+ * <http://www.doctrine-project.org>.
18
+ */
19
+
20
+ namespace Doctrine\Common\Collections;
21
+
22
+ use ArrayIterator;
23
+ use Closure;
24
+ use Doctrine\Common\Collections\Expr\ClosureExpressionVisitor;
25
+
26
+ /**
27
+ * An ArrayCollection is a Collection implementation that wraps a regular PHP array.
28
+ *
29
+ * @since 2.0
30
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
31
+ * @author Jonathan Wage <jonwage@gmail.com>
32
+ * @author Roman Borschel <roman@code-factory.org>
33
+ */
34
+ class ArrayCollection implements Collection, Selectable
35
+ {
36
+ /**
37
+ * An array containing the entries of this collection.
38
+ *
39
+ * @var array
40
+ */
41
+ private $elements;
42
+
43
+ /**
44
+ * Initializes a new ArrayCollection.
45
+ *
46
+ * @param array $elements
47
+ */
48
+ public function __construct(array $elements = array())
49
+ {
50
+ $this->elements = $elements;
51
+ }
52
+
53
+ /**
54
+ * {@inheritDoc}
55
+ */
56
+ public function toArray()
57
+ {
58
+ return $this->elements;
59
+ }
60
+
61
+ /**
62
+ * {@inheritDoc}
63
+ */
64
+ public function first()
65
+ {
66
+ return reset($this->elements);
67
+ }
68
+
69
+ /**
70
+ * {@inheritDoc}
71
+ */
72
+ public function last()
73
+ {
74
+ return end($this->elements);
75
+ }
76
+
77
+ /**
78
+ * {@inheritDoc}
79
+ */
80
+ public function key()
81
+ {
82
+ return key($this->elements);
83
+ }
84
+
85
+ /**
86
+ * {@inheritDoc}
87
+ */
88
+ public function next()
89
+ {
90
+ return next($this->elements);
91
+ }
92
+
93
+ /**
94
+ * {@inheritDoc}
95
+ */
96
+ public function current()
97
+ {
98
+ return current($this->elements);
99
+ }
100
+
101
+ /**
102
+ * {@inheritDoc}
103
+ */
104
+ public function remove($key)
105
+ {
106
+ if ( ! isset($this->elements[$key]) && ! array_key_exists($key, $this->elements)) {
107
+ return null;
108
+ }
109
+
110
+ $removed = $this->elements[$key];
111
+ unset($this->elements[$key]);
112
+
113
+ return $removed;
114
+ }
115
+
116
+ /**
117
+ * {@inheritDoc}
118
+ */
119
+ public function removeElement($element)
120
+ {
121
+ $key = array_search($element, $this->elements, true);
122
+
123
+ if ($key === false) {
124
+ return false;
125
+ }
126
+
127
+ unset($this->elements[$key]);
128
+
129
+ return true;
130
+ }
131
+
132
+ /**
133
+ * Required by interface ArrayAccess.
134
+ *
135
+ * {@inheritDoc}
136
+ */
137
+ public function offsetExists($offset)
138
+ {
139
+ return $this->containsKey($offset);
140
+ }
141
+
142
+ /**
143
+ * Required by interface ArrayAccess.
144
+ *
145
+ * {@inheritDoc}
146
+ */
147
+ public function offsetGet($offset)
148
+ {
149
+ return $this->get($offset);
150
+ }
151
+
152
+ /**
153
+ * Required by interface ArrayAccess.
154
+ *
155
+ * {@inheritDoc}
156
+ */
157
+ public function offsetSet($offset, $value)
158
+ {
159
+ if ( ! isset($offset)) {
160
+ return $this->add($value);
161
+ }
162
+
163
+ $this->set($offset, $value);
164
+ }
165
+
166
+ /**
167
+ * Required by interface ArrayAccess.
168
+ *
169
+ * {@inheritDoc}
170
+ */
171
+ public function offsetUnset($offset)
172
+ {
173
+ return $this->remove($offset);
174
+ }
175
+
176
+ /**
177
+ * {@inheritDoc}
178
+ */
179
+ public function containsKey($key)
180
+ {
181
+ return isset($this->elements[$key]) || array_key_exists($key, $this->elements);
182
+ }
183
+
184
+ /**
185
+ * {@inheritDoc}
186
+ */
187
+ public function contains($element)
188
+ {
189
+ return in_array($element, $this->elements, true);
190
+ }
191
+
192
+ /**
193
+ * {@inheritDoc}
194
+ */
195
+ public function exists(Closure $p)
196
+ {
197
+ foreach ($this->elements as $key => $element) {
198
+ if ($p($key, $element)) {
199
+ return true;
200
+ }
201
+ }
202
+
203
+ return false;
204
+ }
205
+
206
+ /**
207
+ * {@inheritDoc}
208
+ */
209
+ public function indexOf($element)
210
+ {
211
+ return array_search($element, $this->elements, true);
212
+ }
213
+
214
+ /**
215
+ * {@inheritDoc}
216
+ */
217
+ public function get($key)
218
+ {
219
+ return isset($this->elements[$key]) ? $this->elements[$key] : null;
220
+ }
221
+
222
+ /**
223
+ * {@inheritDoc}
224
+ */
225
+ public function getKeys()
226
+ {
227
+ return array_keys($this->elements);
228
+ }
229
+
230
+ /**
231
+ * {@inheritDoc}
232
+ */
233
+ public function getValues()
234
+ {
235
+ return array_values($this->elements);
236
+ }
237
+
238
+ /**
239
+ * {@inheritDoc}
240
+ */
241
+ public function count()
242
+ {
243
+ return count($this->elements);
244
+ }
245
+
246
+ /**
247
+ * {@inheritDoc}
248
+ */
249
+ public function set($key, $value)
250
+ {
251
+ $this->elements[$key] = $value;
252
+ }
253
+
254
+ /**
255
+ * {@inheritDoc}
256
+ */
257
+ public function add($value)
258
+ {
259
+ $this->elements[] = $value;
260
+
261
+ return true;
262
+ }
263
+
264
+ /**
265
+ * {@inheritDoc}
266
+ */
267
+ public function isEmpty()
268
+ {
269
+ return empty($this->elements);
270
+ }
271
+
272
+ /**
273
+ * Required by interface IteratorAggregate.
274
+ *
275
+ * {@inheritDoc}
276
+ */
277
+ public function getIterator()
278
+ {
279
+ return new ArrayIterator($this->elements);
280
+ }
281
+
282
+ /**
283
+ * {@inheritDoc}
284
+ */
285
+ public function map(Closure $func)
286
+ {
287
+ return new static(array_map($func, $this->elements));
288
+ }
289
+
290
+ /**
291
+ * {@inheritDoc}
292
+ */
293
+ public function filter(Closure $p)
294
+ {
295
+ return new static(array_filter($this->elements, $p));
296
+ }
297
+
298
+ /**
299
+ * {@inheritDoc}
300
+ */
301
+ public function forAll(Closure $p)
302
+ {
303
+ foreach ($this->elements as $key => $element) {
304
+ if ( ! $p($key, $element)) {
305
+ return false;
306
+ }
307
+ }
308
+
309
+ return true;
310
+ }
311
+
312
+ /**
313
+ * {@inheritDoc}
314
+ */
315
+ public function partition(Closure $p)
316
+ {
317
+ $matches = $noMatches = array();
318
+
319
+ foreach ($this->elements as $key => $element) {
320
+ if ($p($key, $element)) {
321
+ $matches[$key] = $element;
322
+ } else {
323
+ $noMatches[$key] = $element;
324
+ }
325
+ }
326
+
327
+ return array(new static($matches), new static($noMatches));
328
+ }
329
+
330
+ /**
331
+ * Returns a string representation of this object.
332
+ *
333
+ * @return string
334
+ */
335
+ public function __toString()
336
+ {
337
+ return __CLASS__ . '@' . spl_object_hash($this);
338
+ }
339
+
340
+ /**
341
+ * {@inheritDoc}
342
+ */
343
+ public function clear()
344
+ {
345
+ $this->elements = array();
346
+ }
347
+
348
+ /**
349
+ * {@inheritDoc}
350
+ */
351
+ public function slice($offset, $length = null)
352
+ {
353
+ return array_slice($this->elements, $offset, $length, true);
354
+ }
355
+
356
+ /**
357
+ * {@inheritDoc}
358
+ */
359
+ public function matching(Criteria $criteria)
360
+ {
361
+ $expr = $criteria->getWhereExpression();
362
+ $filtered = $this->elements;
363
+
364
+ if ($expr) {
365
+ $visitor = new ClosureExpressionVisitor();
366
+ $filter = $visitor->dispatch($expr);
367
+ $filtered = array_filter($filtered, $filter);
368
+ }
369
+
370
+ if ($orderings = $criteria->getOrderings()) {
371
+ foreach (array_reverse($orderings) as $field => $ordering) {
372
+ $next = ClosureExpressionVisitor::sortByField($field, $ordering == Criteria::DESC ? -1 : 1);
373
+ }
374
+
375
+ uasort($filtered, $next);
376
+ }
377
+
378
+ $offset = $criteria->getFirstResult();
379
+ $length = $criteria->getMaxResults();
380
+
381
+ if ($offset || $length) {
382
+ $filtered = array_slice($filtered, (int)$offset, $length);
383
+ }
384
+
385
+ return new static($filtered);
386
+ }
387
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Collection.php ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
+ *
15
+ * This software consists of voluntary contributions made by many individuals
16
+ * and is licensed under the MIT license. For more information, see
17
+ * <http://www.doctrine-project.org>.
18
+ */
19
+
20
+ namespace Doctrine\Common\Collections;
21
+
22
+ use ArrayAccess;
23
+ use Closure;
24
+ use Countable;
25
+ use IteratorAggregate;
26
+
27
+ /**
28
+ * The missing (SPL) Collection/Array/OrderedMap interface.
29
+ *
30
+ * A Collection resembles the nature of a regular PHP array. That is,
31
+ * it is essentially an <b>ordered map</b> that can also be used
32
+ * like a list.
33
+ *
34
+ * A Collection has an internal iterator just like a PHP array. In addition,
35
+ * a Collection can be iterated with external iterators, which is preferable.
36
+ * To use an external iterator simply use the foreach language construct to
37
+ * iterate over the collection (which calls {@link getIterator()} internally) or
38
+ * explicitly retrieve an iterator though {@link getIterator()} which can then be
39
+ * used to iterate over the collection.
40
+ * You can not rely on the internal iterator of the collection being at a certain
41
+ * position unless you explicitly positioned it before. Prefer iteration with
42
+ * external iterators.
43
+ *
44
+ * @since 2.0
45
+ * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
46
+ * @author Jonathan Wage <jonwage@gmail.com>
47
+ * @author Roman Borschel <roman@code-factory.org>
48
+ */
49
+ interface Collection extends Countable, IteratorAggregate, ArrayAccess
50
+ {
51
+ /**
52
+ * Adds an element at the end of the collection.
53
+ *
54
+ * @param mixed $element The element to add.
55
+ *
56
+ * @return boolean Always TRUE.
57
+ */
58
+ public function add($element);
59
+
60
+ /**
61
+ * Clears the collection, removing all elements.
62
+ *
63
+ * @return void
64
+ */
65
+ public function clear();
66
+
67
+ /**
68
+ * Checks whether an element is contained in the collection.
69
+ * This is an O(n) operation, where n is the size of the collection.
70
+ *
71
+ * @param mixed $element The element to search for.
72
+ *
73
+ * @return boolean TRUE if the collection contains the element, FALSE otherwise.
74
+ */
75
+ public function contains($element);
76
+
77
+ /**
78
+ * Checks whether the collection is empty (contains no elements).
79
+ *
80
+ * @return boolean TRUE if the collection is empty, FALSE otherwise.
81
+ */
82
+ public function isEmpty();
83
+
84
+ /**
85
+ * Removes the element at the specified index from the collection.
86
+ *
87
+ * @param string|integer $key The kex/index of the element to remove.
88
+ *
89
+ * @return mixed The removed element or NULL, if the collection did not contain the element.
90
+ */
91
+ public function remove($key);
92
+
93
+ /**
94
+ * Removes the specified element from the collection, if it is found.
95
+ *
96
+ * @param mixed $element The element to remove.
97
+ *
98
+ * @return boolean TRUE if this collection contained the specified element, FALSE otherwise.
99
+ */
100
+ public function removeElement($element);
101
+
102
+ /**
103
+ * Checks whether the collection contains an element with the specified key/index.
104
+ *
105
+ * @param string|integer $key The key/index to check for.
106
+ *
107
+ * @return boolean TRUE if the collection contains an element with the specified key/index,
108
+ * FALSE otherwise.
109
+ */
110
+ public function containsKey($key);
111
+
112
+ /**
113
+ * Gets the element at the specified key/index.
114
+ *
115
+ * @param string|integer $key The key/index of the element to retrieve.
116
+ *
117
+ * @return mixed
118
+ */
119
+ public function get($key);
120
+
121
+ /**
122
+ * Gets all keys/indices of the collection.
123
+ *
124
+ * @return array The keys/indices of the collection, in the order of the corresponding
125
+ * elements in the collection.
126
+ */
127
+ public function getKeys();
128
+
129
+ /**
130
+ * Gets all values of the collection.
131
+ *
132
+ * @return array The values of all elements in the collection, in the order they
133
+ * appear in the collection.
134
+ */
135
+ public function getValues();
136
+
137
+ /**
138
+ * Sets an element in the collection at the specified key/index.
139
+ *
140
+ * @param string|integer $key The key/index of the element to set.
141
+ * @param mixed $value The element to set.
142
+ *
143
+ * @return void
144
+ */
145
+ public function set($key, $value);
146
+
147
+ /**
148
+ * Gets a native PHP array representation of the collection.
149
+ *
150
+ * @return array
151
+ */
152
+ public function toArray();
153
+
154
+ /**
155
+ * Sets the internal iterator to the first element in the collection and returns this element.
156
+ *
157
+ * @return mixed
158
+ */
159
+ public function first();
160
+
161
+ /**
162
+ * Sets the internal iterator to the last element in the collection and returns this element.
163
+ *
164
+ * @return mixed
165
+ */
166
+ public function last();
167
+
168
+ /**
169
+ * Gets the key/index of the element at the current iterator position.
170
+ *
171
+ * @return int|string
172
+ */
173
+ public function key();
174
+
175
+ /**
176
+ * Gets the element of the collection at the current iterator position.
177
+ *
178
+ * @return mixed
179
+ */
180
+ public function current();
181
+
182
+ /**
183
+ * Moves the internal iterator position to the next element and returns this element.
184
+ *
185
+ * @return mixed
186
+ */
187
+ public function next();
188
+
189
+ /**
190
+ * Tests for the existence of an element that satisfies the given predicate.
191
+ *
192
+ * @param Closure $p The predicate.
193
+ *
194
+ * @return boolean TRUE if the predicate is TRUE for at least one element, FALSE otherwise.
195
+ */
196
+ public function exists(Closure $p);
197
+
198
+ /**
199
+ * Returns all the elements of this collection that satisfy the predicate p.
200
+ * The order of the elements is preserved.
201
+ *
202
+ * @param Closure $p The predicate used for filtering.
203
+ *
204
+ * @return Collection A collection with the results of the filter operation.
205
+ */
206
+ public function filter(Closure $p);
207
+
208
+ /**
209
+ * Tests whether the given predicate p holds for all elements of this collection.
210
+ *
211
+ * @param Closure $p The predicate.
212
+ *
213
+ * @return boolean TRUE, if the predicate yields TRUE for all elements, FALSE otherwise.
214
+ */
215
+ public function forAll(Closure $p);
216
+
217
+ /**
218
+ * Applies the given function to each element in the collection and returns
219
+ * a new collection with the elements returned by the function.
220
+ *
221
+ * @param Closure $func
222
+ *
223
+ * @return Collection
224
+ */
225
+ public function map(Closure $func);
226
+
227
+ /**
228
+ * Partitions this collection in two collections according to a predicate.
229
+ * Keys are preserved in the resulting collections.
230
+ *
231
+ * @param Closure $p The predicate on which to partition.
232
+ *
233
+ * @return array An array with two elements. The first element contains the collection
234
+ * of elements where the predicate returned TRUE, the second element
235
+ * contains the collection of elements where the predicate returned FALSE.
236
+ */
237
+ public function partition(Closure $p);
238
+
239
+ /**
240
+ * Gets the index/key of a given element. The comparison of two elements is strict,
241
+ * that means not only the value but also the type must match.
242
+ * For objects this means reference equality.
243
+ *
244
+ * @param mixed $element The element to search for.
245
+ *
246
+ * @return int|string|bool The key/index of the element or FALSE if the element was not found.
247
+ */
248
+ public function indexOf($element);
249
+
250
+ /**
251
+ * Extracts a slice of $length elements starting at position $offset from the Collection.
252
+ *
253
+ * If $length is null it returns all elements from $offset to the end of the Collection.
254
+ * Keys have to be preserved by this method. Calling this method will only return the
255
+ * selected slice and NOT change the elements contained in the collection slice is called on.
256
+ *
257
+ * @param int $offset The offset to start from.
258
+ * @param int|null $length The maximum number of elements to return, or null for no limit.
259
+ *
260
+ * @return array
261
+ */
262
+ public function slice($offset, $length = null);
263
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Criteria.php ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
+ *
15
+ * This software consists of voluntary contributions made by many individuals
16
+ * and is licensed under the MIT license. For more information, see
17
+ * <http://www.doctrine-project.org>.
18
+ */
19
+
20
+ namespace Doctrine\Common\Collections;
21
+
22
+ use Doctrine\Common\Collections\Expr\Expression;
23
+ use Doctrine\Common\Collections\Expr\CompositeExpression;
24
+
25
+ /**
26
+ * Criteria for filtering Selectable collections.
27
+ *
28
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
29
+ * @since 2.3
30
+ */
31
+ class Criteria
32
+ {
33
+ /**
34
+ * @var string
35
+ */
36
+ const ASC = 'ASC';
37
+
38
+ /**
39
+ * @var string
40
+ */
41
+ const DESC = 'DESC';
42
+
43
+ /**
44
+ * @var \Doctrine\Common\Collections\ExpressionBuilder|null
45
+ */
46
+ private static $expressionBuilder;
47
+
48
+ /**
49
+ * @var \Doctrine\Common\Collections\Expr\Expression|null
50
+ */
51
+ private $expression;
52
+
53
+ /**
54
+ * @var string[]
55
+ */
56
+ private $orderings = array();
57
+
58
+ /**
59
+ * @var int|null
60
+ */
61
+ private $firstResult;
62
+
63
+ /**
64
+ * @var int|null
65
+ */
66
+ private $maxResults;
67
+
68
+ /**
69
+ * Creates an instance of the class.
70
+ *
71
+ * @return Criteria
72
+ */
73
+ public static function create()
74
+ {
75
+ return new static();
76
+ }
77
+
78
+ /**
79
+ * Returns the expression builder.
80
+ *
81
+ * @return \Doctrine\Common\Collections\ExpressionBuilder
82
+ */
83
+ public static function expr()
84
+ {
85
+ if (self::$expressionBuilder === null) {
86
+ self::$expressionBuilder = new ExpressionBuilder();
87
+ }
88
+
89
+ return self::$expressionBuilder;
90
+ }
91
+
92
+ /**
93
+ * Construct a new Criteria.
94
+ *
95
+ * @param Expression $expression
96
+ * @param string[]|null $orderings
97
+ * @param int|null $firstResult
98
+ * @param int|null $maxResults
99
+ */
100
+ public function __construct(Expression $expression = null, array $orderings = null, $firstResult = null, $maxResults = null)
101
+ {
102
+ $this->expression = $expression;
103
+
104
+ $this->setFirstResult($firstResult);
105
+ $this->setMaxResults($maxResults);
106
+
107
+ if (null !== $orderings) {
108
+ $this->orderBy($orderings);
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Sets the where expression to evaluate when this Criteria is searched for.
114
+ *
115
+ * @param Expression $expression
116
+ *
117
+ * @return Criteria
118
+ */
119
+ public function where(Expression $expression)
120
+ {
121
+ $this->expression = $expression;
122
+
123
+ return $this;
124
+ }
125
+
126
+ /**
127
+ * Appends the where expression to evaluate when this Criteria is searched for
128
+ * using an AND with previous expression.
129
+ *
130
+ * @param Expression $expression
131
+ *
132
+ * @return Criteria
133
+ */
134
+ public function andWhere(Expression $expression)
135
+ {
136
+ if ($this->expression === null) {
137
+ return $this->where($expression);
138
+ }
139
+
140
+ $this->expression = new CompositeExpression(CompositeExpression::TYPE_AND, array(
141
+ $this->expression, $expression
142
+ ));
143
+
144
+ return $this;
145
+ }
146
+
147
+ /**
148
+ * Appends the where expression to evaluate when this Criteria is searched for
149
+ * using an OR with previous expression.
150
+ *
151
+ * @param Expression $expression
152
+ *
153
+ * @return Criteria
154
+ */
155
+ public function orWhere(Expression $expression)
156
+ {
157
+ if ($this->expression === null) {
158
+ return $this->where($expression);
159
+ }
160
+
161
+ $this->expression = new CompositeExpression(CompositeExpression::TYPE_OR, array(
162
+ $this->expression, $expression
163
+ ));
164
+
165
+ return $this;
166
+ }
167
+
168
+ /**
169
+ * Gets the expression attached to this Criteria.
170
+ *
171
+ * @return Expression|null
172
+ */
173
+ public function getWhereExpression()
174
+ {
175
+ return $this->expression;
176
+ }
177
+
178
+ /**
179
+ * Gets the current orderings of this Criteria.
180
+ *
181
+ * @return string[]
182
+ */
183
+ public function getOrderings()
184
+ {
185
+ return $this->orderings;
186
+ }
187
+
188
+ /**
189
+ * Sets the ordering of the result of this Criteria.
190
+ *
191
+ * Keys are field and values are the order, being either ASC or DESC.
192
+ *
193
+ * @see Criteria::ASC
194
+ * @see Criteria::DESC
195
+ *
196
+ * @param string[] $orderings
197
+ *
198
+ * @return Criteria
199
+ */
200
+ public function orderBy(array $orderings)
201
+ {
202
+ $this->orderings = array_map(
203
+ function ($ordering) {
204
+ return strtoupper($ordering) === Criteria::ASC ? Criteria::ASC : Criteria::DESC;
205
+ },
206
+ $orderings
207
+ );
208
+
209
+ return $this;
210
+ }
211
+
212
+ /**
213
+ * Gets the current first result option of this Criteria.
214
+ *
215
+ * @return int|null
216
+ */
217
+ public function getFirstResult()
218
+ {
219
+ return $this->firstResult;
220
+ }
221
+
222
+ /**
223
+ * Set the number of first result that this Criteria should return.
224
+ *
225
+ * @param int|null $firstResult The value to set.
226
+ *
227
+ * @return Criteria
228
+ */
229
+ public function setFirstResult($firstResult)
230
+ {
231
+ $this->firstResult = null === $firstResult ? null : (int) $firstResult;
232
+
233
+ return $this;
234
+ }
235
+
236
+ /**
237
+ * Gets maxResults.
238
+ *
239
+ * @return int|null
240
+ */
241
+ public function getMaxResults()
242
+ {
243
+ return $this->maxResults;
244
+ }
245
+
246
+ /**
247
+ * Sets maxResults.
248
+ *
249
+ * @param int|null $maxResults The value to set.
250
+ *
251
+ * @return Criteria
252
+ */
253
+ public function setMaxResults($maxResults)
254
+ {
255
+ $this->maxResults = null === $maxResults ? null : (int) $maxResults;
256
+
257
+ return $this;
258
+ }
259
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ClosureExpressionVisitor.php ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
+ *
15
+ * This software consists of voluntary contributions made by many individuals
16
+ * and is licensed under the MIT license. For more information, see
17
+ * <http://www.doctrine-project.org>.
18
+ */
19
+
20
+ namespace Doctrine\Common\Collections\Expr;
21
+
22
+ /**
23
+ * Walks an expression graph and turns it into a PHP closure.
24
+ *
25
+ * This closure can be used with {@Collection#filter()} and is used internally
26
+ * by {@ArrayCollection#select()}.
27
+ *
28
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
29
+ * @since 2.3
30
+ */
31
+ class ClosureExpressionVisitor extends ExpressionVisitor
32
+ {
33
+ /**
34
+ * Accesses the field of a given object. This field has to be public
35
+ * directly or indirectly (through an accessor get*, is*, or a magic
36
+ * method, __get, __call).
37
+ *
38
+ * @param object $object
39
+ * @param string $field
40
+ *
41
+ * @return mixed
42
+ */
43
+ public static function getObjectFieldValue($object, $field)
44
+ {
45
+ if (is_array($object)) {
46
+ return $object[$field];
47
+ }
48
+
49
+ $accessors = array('get', 'is');
50
+
51
+ foreach ($accessors as $accessor) {
52
+ $accessor .= $field;
53
+
54
+ if ( ! method_exists($object, $accessor)) {
55
+ continue;
56
+ }
57
+
58
+ return $object->$accessor();
59
+ }
60
+
61
+ // __call should be triggered for get.
62
+ $accessor = $accessors[0] . $field;
63
+
64
+ if (method_exists($object, '__call')) {
65
+ return $object->$accessor();
66
+ }
67
+
68
+ if ($object instanceof \ArrayAccess) {
69
+ return $object[$field];
70
+ }
71
+
72
+ return $object->$field;
73
+ }
74
+
75
+ /**
76
+ * Helper for sorting arrays of objects based on multiple fields + orientations.
77
+ *
78
+ * @param string $name
79
+ * @param int $orientation
80
+ * @param \Closure $next
81
+ *
82
+ * @return \Closure
83
+ */
84
+ public static function sortByField($name, $orientation = 1, \Closure $next = null)
85
+ {
86
+ if ( ! $next) {
87
+ $next = function() {
88
+ return 0;
89
+ };
90
+ }
91
+
92
+ return function ($a, $b) use ($name, $next, $orientation) {
93
+ $aValue = ClosureExpressionVisitor::getObjectFieldValue($a, $name);
94
+ $bValue = ClosureExpressionVisitor::getObjectFieldValue($b, $name);
95
+
96
+ if ($aValue === $bValue) {
97
+ return $next($a, $b);
98
+ }
99
+
100
+ return (($aValue > $bValue) ? 1 : -1) * $orientation;
101
+ };
102
+ }
103
+
104
+ /**
105
+ * {@inheritDoc}
106
+ */
107
+ public function walkComparison(Comparison $comparison)
108
+ {
109
+ $field = $comparison->getField();
110
+ $value = $comparison->getValue()->getValue(); // shortcut for walkValue()
111
+
112
+ switch ($comparison->getOperator()) {
113
+ case Comparison::EQ:
114
+ return function ($object) use ($field, $value) {
115
+ return ClosureExpressionVisitor::getObjectFieldValue($object, $field) === $value;
116
+ };
117
+
118
+ case Comparison::NEQ:
119
+ return function ($object) use ($field, $value) {
120
+ return ClosureExpressionVisitor::getObjectFieldValue($object, $field) !== $value;
121
+ };
122
+
123
+ case Comparison::LT:
124
+ return function ($object) use ($field, $value) {
125
+ return ClosureExpressionVisitor::getObjectFieldValue($object, $field) < $value;
126
+ };
127
+
128
+ case Comparison::LTE:
129
+ return function ($object) use ($field, $value) {
130
+ return ClosureExpressionVisitor::getObjectFieldValue($object, $field) <= $value;
131
+ };
132
+
133
+ case Comparison::GT:
134
+ return function ($object) use ($field, $value) {
135
+ return ClosureExpressionVisitor::getObjectFieldValue($object, $field) > $value;
136
+ };
137
+
138
+ case Comparison::GTE:
139
+ return function ($object) use ($field, $value) {
140
+ return ClosureExpressionVisitor::getObjectFieldValue($object, $field) >= $value;
141
+ };
142
+
143
+ case Comparison::IN:
144
+ return function ($object) use ($field, $value) {
145
+ return in_array(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value);
146
+ };
147
+
148
+ case Comparison::NIN:
149
+ return function ($object) use ($field, $value) {
150
+ return ! in_array(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value);
151
+ };
152
+
153
+ case Comparison::CONTAINS:
154
+ return function ($object) use ($field, $value) {
155
+ return false !== strpos(ClosureExpressionVisitor::getObjectFieldValue($object, $field), $value);
156
+ };
157
+
158
+ default:
159
+ throw new \RuntimeException("Unknown comparison operator: " . $comparison->getOperator());
160
+ }
161
+ }
162
+
163
+ /**
164
+ * {@inheritDoc}
165
+ */
166
+ public function walkValue(Value $value)
167
+ {
168
+ return $value->getValue();
169
+ }
170
+
171
+ /**
172
+ * {@inheritDoc}
173
+ */
174
+ public function walkCompositeExpression(CompositeExpression $expr)
175
+ {
176
+ $expressionList = array();
177
+
178
+ foreach ($expr->getExpressionList() as $child) {
179
+ $expressionList[] = $this->dispatch($child);
180
+ }
181
+
182
+ switch($expr->getType()) {
183
+ case CompositeExpression::TYPE_AND:
184
+ return $this->andExpressions($expressionList);
185
+
186
+ case CompositeExpression::TYPE_OR:
187
+ return $this->orExpressions($expressionList);
188
+
189
+ default:
190
+ throw new \RuntimeException("Unknown composite " . $expr->getType());
191
+ }
192
+ }
193
+
194
+ /**
195
+ * @param array $expressions
196
+ *
197
+ * @return callable
198
+ */
199
+ private function andExpressions($expressions)
200
+ {
201
+ return function ($object) use ($expressions) {
202
+ foreach ($expressions as $expression) {
203
+ if ( ! $expression($object)) {
204
+ return false;
205
+ }
206
+ }
207
+ return true;
208
+ };
209
+ }
210
+
211
+ /**
212
+ * @param array $expressions
213
+ *
214
+ * @return callable
215
+ */
216
+ private function orExpressions($expressions)
217
+ {
218
+ return function ($object) use ($expressions) {
219
+ foreach ($expressions as $expression) {
220
+ if ($expression($object)) {
221
+ return true;
222
+ }
223
+ }
224
+ return false;
225
+ };
226
+ }
227
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Comparison.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
+ *
15
+ * This software consists of voluntary contributions made by many individuals
16
+ * and is licensed under the MIT license. For more information, see
17
+ * <http://www.doctrine-project.org>.
18
+ */
19
+
20
+ namespace Doctrine\Common\Collections\Expr;
21
+
22
+ /**
23
+ * Comparison of a field with a value by the given operator.
24
+ *
25
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
26
+ * @since 2.3
27
+ */
28
+ class Comparison implements Expression
29
+ {
30
+ const EQ = '=';
31
+ const NEQ = '<>';
32
+ const LT = '<';
33
+ const LTE = '<=';
34
+ const GT = '>';
35
+ const GTE = '>=';
36
+ const IS = '='; // no difference with EQ
37
+ const IN = 'IN';
38
+ const NIN = 'NIN';
39
+ const CONTAINS = 'CONTAINS';
40
+
41
+ /**
42
+ * @var string
43
+ */
44
+ private $field;
45
+
46
+ /**
47
+ * @var string
48
+ */
49
+ private $op;
50
+
51
+ /**
52
+ * @var Value
53
+ */
54
+ private $value;
55
+
56
+ /**
57
+ * @param string $field
58
+ * @param string $operator
59
+ * @param mixed $value
60
+ */
61
+ public function __construct($field, $operator, $value)
62
+ {
63
+ if ( ! ($value instanceof Value)) {
64
+ $value = new Value($value);
65
+ }
66
+
67
+ $this->field = $field;
68
+ $this->op = $operator;
69
+ $this->value = $value;
70
+ }
71
+
72
+ /**
73
+ * @return string
74
+ */
75
+ public function getField()
76
+ {
77
+ return $this->field;
78
+ }
79
+
80
+ /**
81
+ * @return Value
82
+ */
83
+ public function getValue()
84
+ {
85
+ return $this->value;
86
+ }
87
+
88
+ /**
89
+ * @return string
90
+ */
91
+ public function getOperator()
92
+ {
93
+ return $this->op;
94
+ }
95
+
96
+ /**
97
+ * {@inheritDoc}
98
+ */
99
+ public function visit(ExpressionVisitor $visitor)
100
+ {
101
+ return $visitor->walkComparison($this);
102
+ }
103
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/CompositeExpression.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
+ *
15
+ * This software consists of voluntary contributions made by many individuals
16
+ * and is licensed under the MIT license. For more information, see
17
+ * <http://www.doctrine-project.org>.
18
+ */
19
+
20
+ namespace Doctrine\Common\Collections\Expr;
21
+
22
+ /**
23
+ * Expression of Expressions combined by AND or OR operation.
24
+ *
25
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
26
+ * @since 2.3
27
+ */
28
+ class CompositeExpression implements Expression
29
+ {
30
+ const TYPE_AND = 'AND';
31
+ const TYPE_OR = 'OR';
32
+
33
+ /**
34
+ * @var string
35
+ */
36
+ private $type;
37
+
38
+ /**
39
+ * @var Expression[]
40
+ */
41
+ private $expressions = array();
42
+
43
+ /**
44
+ * @param string $type
45
+ * @param array $expressions
46
+ *
47
+ * @throws \RuntimeException
48
+ */
49
+ public function __construct($type, array $expressions)
50
+ {
51
+ $this->type = $type;
52
+
53
+ foreach ($expressions as $expr) {
54
+ if ($expr instanceof Value) {
55
+ throw new \RuntimeException("Values are not supported expressions as children of and/or expressions.");
56
+ }
57
+ if ( ! ($expr instanceof Expression)) {
58
+ throw new \RuntimeException("No expression given to CompositeExpression.");
59
+ }
60
+
61
+ $this->expressions[] = $expr;
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Returns the list of expressions nested in this composite.
67
+ *
68
+ * @return Expression[]
69
+ */
70
+ public function getExpressionList()
71
+ {
72
+ return $this->expressions;
73
+ }
74
+
75
+ /**
76
+ * @return string
77
+ */
78
+ public function getType()
79
+ {
80
+ return $this->type;
81
+ }
82
+
83
+ /**
84
+ * {@inheritDoc}
85
+ */
86
+ public function visit(ExpressionVisitor $visitor)
87
+ {
88
+ return $visitor->walkCompositeExpression($this);
89
+ }
90
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Expression.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
+ *
15
+ * This software consists of voluntary contributions made by many individuals
16
+ * and is licensed under the MIT license. For more information, see
17
+ * <http://www.doctrine-project.org>.
18
+ */
19
+
20
+ namespace Doctrine\Common\Collections\Expr;
21
+
22
+ /**
23
+ * Expression for the {@link Selectable} interface.
24
+ *
25
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
26
+ */
27
+ interface Expression
28
+ {
29
+ /**
30
+ * @param ExpressionVisitor $visitor
31
+ *
32
+ * @return mixed
33
+ */
34
+ public function visit(ExpressionVisitor $visitor);
35
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/ExpressionVisitor.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
+ *
15
+ * This software consists of voluntary contributions made by many individuals
16
+ * and is licensed under the MIT license. For more information, see
17
+ * <http://www.doctrine-project.org>.
18
+ */
19
+
20
+ namespace Doctrine\Common\Collections\Expr;
21
+
22
+ /**
23
+ * An Expression visitor walks a graph of expressions and turns them into a
24
+ * query for the underlying implementation.
25
+ *
26
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
27
+ */
28
+ abstract class ExpressionVisitor
29
+ {
30
+ /**
31
+ * Converts a comparison expression into the target query language output.
32
+ *
33
+ * @param Comparison $comparison
34
+ *
35
+ * @return mixed
36
+ */
37
+ abstract public function walkComparison(Comparison $comparison);
38
+
39
+ /**
40
+ * Converts a value expression into the target query language part.
41
+ *
42
+ * @param Value $value
43
+ *
44
+ * @return mixed
45
+ */
46
+ abstract public function walkValue(Value $value);
47
+
48
+ /**
49
+ * Converts a composite expression into the target query language output.
50
+ *
51
+ * @param CompositeExpression $expr
52
+ *
53
+ * @return mixed
54
+ */
55
+ abstract public function walkCompositeExpression(CompositeExpression $expr);
56
+
57
+ /**
58
+ * Dispatches walking an expression to the appropriate handler.
59
+ *
60
+ * @param Expression $expr
61
+ *
62
+ * @return mixed
63
+ *
64
+ * @throws \RuntimeException
65
+ */
66
+ public function dispatch(Expression $expr)
67
+ {
68
+ switch (true) {
69
+ case ($expr instanceof Comparison):
70
+ return $this->walkComparison($expr);
71
+
72
+ case ($expr instanceof Value):
73
+ return $this->walkValue($expr);
74
+
75
+ case ($expr instanceof CompositeExpression):
76
+ return $this->walkCompositeExpression($expr);
77
+
78
+ default:
79
+ throw new \RuntimeException("Unknown Expression " . get_class($expr));
80
+ }
81
+ }
82
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Expr/Value.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
+ *
15
+ * This software consists of voluntary contributions made by many individuals
16
+ * and is licensed under the MIT license. For more information, see
17
+ * <http://www.doctrine-project.org>.
18
+ */
19
+
20
+ namespace Doctrine\Common\Collections\Expr;
21
+
22
+ class Value implements Expression
23
+ {
24
+ /**
25
+ * @var mixed
26
+ */
27
+ private $value;
28
+
29
+ /**
30
+ * @param mixed $value
31
+ */
32
+ public function __construct($value)
33
+ {
34
+ $this->value = $value;
35
+ }
36
+
37
+ /**
38
+ * @return mixed
39
+ */
40
+ public function getValue()
41
+ {
42
+ return $this->value;
43
+ }
44
+
45
+ /**
46
+ * {@inheritDoc}
47
+ */
48
+ public function visit(ExpressionVisitor $visitor)
49
+ {
50
+ return $visitor->walkValue($this);
51
+ }
52
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ExpressionBuilder.php ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
+ *
15
+ * This software consists of voluntary contributions made by many individuals
16
+ * and is licensed under the MIT license. For more information, see
17
+ * <http://www.doctrine-project.org>.
18
+ */
19
+
20
+ namespace Doctrine\Common\Collections;
21
+
22
+ use Doctrine\Common\Collections\Expr\Comparison;
23
+ use Doctrine\Common\Collections\Expr\CompositeExpression;
24
+ use Doctrine\Common\Collections\Expr\Value;
25
+
26
+ /**
27
+ * Builder for Expressions in the {@link Selectable} interface.
28
+ *
29
+ * Important Notice for interoperable code: You have to use scalar
30
+ * values only for comparisons, otherwise the behavior of the comparision
31
+ * may be different between implementations (Array vs ORM vs ODM).
32
+ *
33
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
34
+ * @since 2.3
35
+ */
36
+ class ExpressionBuilder
37
+ {
38
+ /**
39
+ * @param mixed $x
40
+ *
41
+ * @return CompositeExpression
42
+ */
43
+ public function andX($x = null)
44
+ {
45
+ return new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args());
46
+ }
47
+
48
+ /**
49
+ * @param mixed $x
50
+ *
51
+ * @return CompositeExpression
52
+ */
53
+ public function orX($x = null)
54
+ {
55
+ return new CompositeExpression(CompositeExpression::TYPE_OR, func_get_args());
56
+ }
57
+
58
+ /**
59
+ * @param string $field
60
+ * @param mixed $value
61
+ *
62
+ * @return Comparison
63
+ */
64
+ public function eq($field, $value)
65
+ {
66
+ return new Comparison($field, Comparison::EQ, new Value($value));
67
+ }
68
+
69
+ /**
70
+ * @param string $field
71
+ * @param mixed $value
72
+ *
73
+ * @return Comparison
74
+ */
75
+ public function gt($field, $value)
76
+ {
77
+ return new Comparison($field, Comparison::GT, new Value($value));
78
+ }
79
+
80
+ /**
81
+ * @param string $field
82
+ * @param mixed $value
83
+ *
84
+ * @return Comparison
85
+ */
86
+ public function lt($field, $value)
87
+ {
88
+ return new Comparison($field, Comparison::LT, new Value($value));
89
+ }
90
+
91
+ /**
92
+ * @param string $field
93
+ * @param mixed $value
94
+ *
95
+ * @return Comparison
96
+ */
97
+ public function gte($field, $value)
98
+ {
99
+ return new Comparison($field, Comparison::GTE, new Value($value));
100
+ }
101
+
102
+ /**
103
+ * @param string $field
104
+ * @param mixed $value
105
+ *
106
+ * @return Comparison
107
+ */
108
+ public function lte($field, $value)
109
+ {
110
+ return new Comparison($field, Comparison::LTE, new Value($value));
111
+ }
112
+
113
+ /**
114
+ * @param string $field
115
+ * @param mixed $value
116
+ *
117
+ * @return Comparison
118
+ */
119
+ public function neq($field, $value)
120
+ {
121
+ return new Comparison($field, Comparison::NEQ, new Value($value));
122
+ }
123
+
124
+ /**
125
+ * @param string $field
126
+ *
127
+ * @return Comparison
128
+ */
129
+ public function isNull($field)
130
+ {
131
+ return new Comparison($field, Comparison::EQ, new Value(null));
132
+ }
133
+
134
+ /**
135
+ * @param string $field
136
+ * @param mixed $values
137
+ *
138
+ * @return Comparison
139
+ */
140
+ public function in($field, array $values)
141
+ {
142
+ return new Comparison($field, Comparison::IN, new Value($values));
143
+ }
144
+
145
+ /**
146
+ * @param string $field
147
+ * @param mixed $values
148
+ *
149
+ * @return Comparison
150
+ */
151
+ public function notIn($field, array $values)
152
+ {
153
+ return new Comparison($field, Comparison::NIN, new Value($values));
154
+ }
155
+
156
+ /**
157
+ * @param string $field
158
+ * @param mixed $value
159
+ *
160
+ * @return Comparison
161
+ */
162
+ public function contains($field, $value)
163
+ {
164
+ return new Comparison($field, Comparison::CONTAINS, new Value($value));
165
+ }
166
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/lib/Doctrine/Common/Collections/Selectable.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
+ *
15
+ * This software consists of voluntary contributions made by many individuals
16
+ * and is licensed under the MIT license. For more information, see
17
+ * <http://www.doctrine-project.org>.
18
+ */
19
+
20
+ namespace Doctrine\Common\Collections;
21
+
22
+ /**
23
+ * Interface for collections that allow efficient filtering with an expression API.
24
+ *
25
+ * Goal of this interface is a backend independent method to fetch elements
26
+ * from a collections. {@link Expression} is crafted in a way that you can
27
+ * implement queries from both in-memory and database-backed collections.
28
+ *
29
+ * For database backed collections this allows very efficient access by
30
+ * utilizing the query APIs, for example SQL in the ORM. Applications using
31
+ * this API can implement efficient database access without having to ask the
32
+ * EntityManager or Repositories.
33
+ *
34
+ * @author Benjamin Eberlei <kontakt@beberlei.de>
35
+ * @since 2.3
36
+ */
37
+ interface Selectable
38
+ {
39
+ /**
40
+ * Selects all elements from a selectable that match the expression and
41
+ * returns a new collection containing these elements.
42
+ *
43
+ * @param Criteria $criteria
44
+ *
45
+ * @return Collection
46
+ */
47
+ public function matching(Criteria $criteria);
48
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/phpunit.xml.dist ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <phpunit backupGlobals="false"
4
+ backupStaticAttributes="false"
5
+ colors="true"
6
+ convertErrorsToExceptions="true"
7
+ convertNoticesToExceptions="true"
8
+ convertWarningsToExceptions="true"
9
+ processIsolation="false"
10
+ stopOnFailure="false"
11
+ syntaxCheck="false"
12
+ bootstrap="./tests/Doctrine/Tests/TestInit.php"
13
+ >
14
+ <testsuites>
15
+ <testsuite name="Doctrine Collections Test Suite">
16
+ <directory>./tests/Doctrine/</directory>
17
+ </testsuite>
18
+ </testsuites>
19
+
20
+ <filter>
21
+ <whitelist>
22
+ <directory>./lib/Doctrine/</directory>
23
+ </whitelist>
24
+ </filter>
25
+
26
+ <groups>
27
+ <exclude>
28
+ <group>performance</group>
29
+ </exclude>
30
+ </groups>
31
+ </phpunit>
app/code/community/Expressly/Expressly/vendor/doctrine/collections/tests/Doctrine/Tests/Common/Collections/AbstractLazyCollectionTest.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Doctrine\Tests\Common\Collections;
4
+
5
+ use Doctrine\Tests\LazyArrayCollection;
6
+
7
+ class AbstractLazyCollectionTest extends \PHPUnit_Framework_TestCase
8
+ {
9
+ public function testLazyCollection()
10
+ {
11
+ $collection = new LazyArrayCollection();
12
+
13
+ $this->assertFalse($collection->isInitialized());
14
+ $this->assertCount(3, $collection);
15
+
16
+ $collection->add('bar');
17
+ $this->assertTrue($collection->isInitialized());
18
+ $this->assertCount(4, $collection);
19
+ }
20
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/tests/Doctrine/Tests/Common/Collections/ArrayCollectionTest.php ADDED
@@ -0,0 +1,296 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
+ *
15
+ * This software consists of voluntary contributions made by many individuals
16
+ * and is licensed under the MIT license. For more information, see
17
+ * <http://www.doctrine-project.org>.
18
+ */
19
+
20
+ namespace Doctrine\Tests\Common\Collections;
21
+
22
+ use Doctrine\Common\Collections\ArrayCollection;
23
+ use Doctrine\Common\Collections\Criteria;
24
+
25
+ /**
26
+ * Tests for {@see \Doctrine\Common\Collections\ArrayCollection}
27
+ *
28
+ * @covers \Doctrine\Common\Collections\ArrayCollection
29
+ */
30
+ class ArrayCollectionTest extends \PHPUnit_Framework_TestCase
31
+ {
32
+ /**
33
+ * @dataProvider provideDifferentElements
34
+ */
35
+ public function testToArray($elements)
36
+ {
37
+ $collection = new ArrayCollection($elements);
38
+
39
+ $this->assertSame($elements, $collection->toArray());
40
+ }
41
+
42
+ /**
43
+ * @dataProvider provideDifferentElements
44
+ */
45
+ public function testFirst($elements)
46
+ {
47
+ $collection = new ArrayCollection($elements);
48
+ $this->assertSame(reset($elements), $collection->first());
49
+ }
50
+
51
+ /**
52
+ * @dataProvider provideDifferentElements
53
+ */
54
+ public function testLast($elements)
55
+ {
56
+ $collection = new ArrayCollection($elements);
57
+ $this->assertSame(end($elements), $collection->last());
58
+ }
59
+
60
+ /**
61
+ * @dataProvider provideDifferentElements
62
+ */
63
+ public function testKey($elements)
64
+ {
65
+ $collection = new ArrayCollection($elements);
66
+
67
+ $this->assertSame(key($elements), $collection->key());
68
+
69
+ next($elements);
70
+ $collection->next();
71
+
72
+ $this->assertSame(key($elements), $collection->key());
73
+ }
74
+
75
+ /**
76
+ * @dataProvider provideDifferentElements
77
+ */
78
+ public function testNext($elements)
79
+ {
80
+ $collection = new ArrayCollection($elements);
81
+
82
+ while (true) {
83
+ $collectionNext = $collection->next();
84
+ $arrayNext = next($elements);
85
+
86
+ if(!$collectionNext || !$arrayNext) {
87
+ break;
88
+ }
89
+
90
+ $this->assertSame($arrayNext, $collectionNext, "Returned value of ArrayCollection::next() and next() not match");
91
+ $this->assertSame(key($elements), $collection->key(), "Keys not match");
92
+ $this->assertSame(current($elements), $collection->current(), "Current values not match");
93
+ }
94
+ }
95
+
96
+ /**
97
+ * @dataProvider provideDifferentElements
98
+ */
99
+ public function testCurrent($elements)
100
+ {
101
+ $collection = new ArrayCollection($elements);
102
+
103
+ $this->assertSame(current($elements), $collection->current());
104
+
105
+ next($elements);
106
+ $collection->next();
107
+
108
+ $this->assertSame(current($elements), $collection->current());
109
+ }
110
+
111
+ /**
112
+ * @dataProvider provideDifferentElements
113
+ */
114
+ public function testGetKeys($elements)
115
+ {
116
+ $collection = new ArrayCollection($elements);
117
+
118
+ $this->assertSame(array_keys($elements), $collection->getKeys());
119
+ }
120
+
121
+ /**
122
+ * @dataProvider provideDifferentElements
123
+ */
124
+ public function testGetValues($elements)
125
+ {
126
+ $collection = new ArrayCollection($elements);
127
+
128
+ $this->assertSame(array_values($elements), $collection->getValues());
129
+ }
130
+
131
+ /**
132
+ * @dataProvider provideDifferentElements
133
+ */
134
+ public function testCount($elements)
135
+ {
136
+ $collection = new ArrayCollection($elements);
137
+
138
+ $this->assertSame(count($elements), $collection->count());
139
+ }
140
+
141
+ /**
142
+ * @dataProvider provideDifferentElements
143
+ */
144
+ public function testIterator($elements)
145
+ {
146
+ $collection = new ArrayCollection($elements);
147
+
148
+ $iterations = 0;
149
+ foreach($collection->getIterator() as $key => $item) {
150
+ $this->assertSame($elements[$key], $item, "Item {$key} not match");
151
+ $iterations++;
152
+ }
153
+
154
+ $this->assertEquals(count($elements), $iterations, "Number of iterations not match");
155
+ }
156
+
157
+ /**
158
+ * @return array
159
+ */
160
+ public function provideDifferentElements()
161
+ {
162
+ return array(
163
+ 'indexed' => array(array(1, 2, 3, 4, 5)),
164
+ 'associative' => array(array('A' => 'a', 'B' => 'b', 'C' => 'c')),
165
+ 'mixed' => array(array('A' => 'a', 1, 'B' => 'b', 2, 3)),
166
+ );
167
+ }
168
+
169
+ public function testRemove()
170
+ {
171
+ $elements = array(1, 'A' => 'a', 2, 'B' => 'b', 3);
172
+ $collection = new ArrayCollection($elements);
173
+
174
+ $this->assertEquals(1, $collection->remove(0));
175
+ unset($elements[0]);
176
+
177
+ $this->assertEquals(null, $collection->remove('non-existent'));
178
+ unset($elements['non-existent']);
179
+
180
+ $this->assertEquals(2, $collection->remove(1));
181
+ unset($elements[1]);
182
+
183
+ $this->assertEquals('a', $collection->remove('A'));
184
+ unset($elements['A']);
185
+
186
+ $this->assertEquals($elements, $collection->toArray());
187
+ }
188
+
189
+ public function testRemoveElement()
190
+ {
191
+ $elements = array(1, 'A' => 'a', 2, 'B' => 'b', 3, 'A2' => 'a', 'B2' => 'b');
192
+ $collection = new ArrayCollection($elements);
193
+
194
+ $this->assertTrue($collection->removeElement(1));
195
+ unset($elements[0]);
196
+
197
+ $this->assertFalse($collection->removeElement('non-existent'));
198
+
199
+ $this->assertTrue($collection->removeElement('a'));
200
+ unset($elements['A']);
201
+
202
+ $this->assertTrue($collection->removeElement('a'));
203
+ unset($elements['A2']);
204
+
205
+ $this->assertEquals($elements, $collection->toArray());
206
+ }
207
+
208
+ public function testContainsKey()
209
+ {
210
+ $elements = array(1, 'A' => 'a', 2, 'null' => null, 3, 'A2' => 'a', 'B2' => 'b');
211
+ $collection = new ArrayCollection($elements);
212
+
213
+ $this->assertTrue($collection->containsKey(0), "Contains index 0");
214
+ $this->assertTrue($collection->containsKey('A'), "Contains key \"A\"");
215
+ $this->assertTrue($collection->containsKey('null'), "Contains key \"null\", with value null");
216
+ $this->assertFalse($collection->containsKey('non-existent'), "Doesn't contain key");
217
+ }
218
+
219
+ public function testEmpty()
220
+ {
221
+ $collection = new ArrayCollection();
222
+ $this->assertTrue($collection->isEmpty(), "Empty collection");
223
+
224
+ $collection->add(1);
225
+ $this->assertFalse($collection->isEmpty(), "Not empty collection");
226
+ }
227
+
228
+ public function testContains()
229
+ {
230
+ $elements = array(1, 'A' => 'a', 2, 'null' => null, 3, 'A2' => 'a', 'zero' => 0);
231
+ $collection = new ArrayCollection($elements);
232
+
233
+ $this->assertTrue($collection->contains(0), "Contains Zero");
234
+ $this->assertTrue($collection->contains('a'), "Contains \"a\"");
235
+ $this->assertTrue($collection->contains(null), "Contains Null");
236
+ $this->assertFalse($collection->contains('non-existent'), "Doesn't contain an element");
237
+ }
238
+
239
+ public function testExists()
240
+ {
241
+ $elements = array(1, 'A' => 'a', 2, 'null' => null, 3, 'A2' => 'a', 'zero' => 0);
242
+ $collection = new ArrayCollection($elements);
243
+
244
+ $this->assertTrue($collection->exists(function($key, $element) {
245
+ return $key == 'A' && $element == 'a';
246
+ }), "Element exists");
247
+
248
+ $this->assertFalse($collection->exists(function($key, $element) {
249
+ return $key == 'non-existent' && $element == 'non-existent';
250
+ }), "Element not exists");
251
+ }
252
+
253
+ public function testIndexOf()
254
+ {
255
+ $elements = array(1, 'A' => 'a', 2, 'null' => null, 3, 'A2' => 'a', 'zero' => 0);
256
+ $collection = new ArrayCollection($elements);
257
+
258
+ $this->assertSame(array_search(2, $elements, true), $collection->indexOf(2), 'Index of 2');
259
+ $this->assertSame(array_search(null, $elements, true), $collection->indexOf(null), 'Index of null');
260
+ $this->assertSame(array_search('non-existent', $elements, true), $collection->indexOf('non-existent'), 'Index of non existent');
261
+ }
262
+
263
+ public function testGet()
264
+ {
265
+ $elements = array(1, 'A' => 'a', 2, 'null' => null, 3, 'A2' => 'a', 'zero' => 0);
266
+ $collection = new ArrayCollection($elements);
267
+
268
+ $this->assertSame(2, $collection->get(1), 'Get element by index');
269
+ $this->assertSame('a', $collection->get('A'), 'Get element by name');
270
+ $this->assertSame(null, $collection->get('non-existent'), 'Get non existent element');
271
+ }
272
+
273
+ public function testMatchingWithSortingPreservesyKeys()
274
+ {
275
+ $object1 = new \stdClass();
276
+ $object2 = new \stdClass();
277
+
278
+ $object1->sortField = 2;
279
+ $object2->sortField = 1;
280
+
281
+ $collection = new ArrayCollection(array(
282
+ 'object1' => $object1,
283
+ 'object2' => $object2,
284
+ ));
285
+
286
+ $this->assertSame(
287
+ array(
288
+ 'object2' => $object2,
289
+ 'object1' => $object1,
290
+ ),
291
+ $collection
292
+ ->matching(new Criteria(null, array('sortField' => Criteria::ASC)))
293
+ ->toArray()
294
+ );
295
+ }
296
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/tests/Doctrine/Tests/Common/Collections/ClosureExpressionVisitorTest.php ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
+ *
15
+ * This software consists of voluntary contributions made by many individuals
16
+ * and is licensed under the MIT license. For more information, see
17
+ * <http://www.doctrine-project.org>.
18
+ */
19
+
20
+ namespace Doctrine\Tests\Common\Collections;
21
+
22
+ use Doctrine\Common\Collections\Expr\ClosureExpressionVisitor;
23
+ use Doctrine\Common\Collections\ExpressionBuilder;
24
+
25
+ /**
26
+ * @group DDC-1637
27
+ */
28
+ class ClosureExpressionVisitorTest extends \PHPUnit_Framework_TestCase
29
+ {
30
+ /**
31
+ * @var ClosureExpressionVisitor
32
+ */
33
+ private $visitor;
34
+
35
+ /**
36
+ * @var ExpressionBuilder
37
+ */
38
+ private $builder;
39
+
40
+ protected function setUp()
41
+ {
42
+ $this->visitor = new ClosureExpressionVisitor();
43
+ $this->builder = new ExpressionBuilder();
44
+ }
45
+
46
+ public function testGetObjectFieldValueIsAccessor()
47
+ {
48
+ $object = new TestObject(1, 2, true);
49
+
50
+ $this->assertTrue($this->visitor->getObjectFieldValue($object, 'baz'));
51
+ }
52
+
53
+ public function testGetObjectFieldValueMagicCallMethod()
54
+ {
55
+ $object = new TestObject(1, 2, true, 3);
56
+
57
+ $this->assertEquals(3, $this->visitor->getObjectFieldValue($object, 'qux'));
58
+ }
59
+
60
+ public function testWalkEqualsComparison()
61
+ {
62
+ $closure = $this->visitor->walkComparison($this->builder->eq("foo", 1));
63
+
64
+ $this->assertTrue($closure(new TestObject(1)));
65
+ $this->assertFalse($closure(new TestObject(2)));
66
+ }
67
+
68
+ public function testWalkNotEqualsComparison()
69
+ {
70
+ $closure = $this->visitor->walkComparison($this->builder->neq("foo", 1));
71
+
72
+ $this->assertFalse($closure(new TestObject(1)));
73
+ $this->assertTrue($closure(new TestObject(2)));
74
+ }
75
+
76
+ public function testWalkLessThanComparison()
77
+ {
78
+ $closure = $this->visitor->walkComparison($this->builder->lt("foo", 1));
79
+
80
+ $this->assertFalse($closure(new TestObject(1)));
81
+ $this->assertTrue($closure(new TestObject(0)));
82
+ }
83
+
84
+ public function testWalkLessThanEqualsComparison()
85
+ {
86
+ $closure = $this->visitor->walkComparison($this->builder->lte("foo", 1));
87
+
88
+ $this->assertFalse($closure(new TestObject(2)));
89
+ $this->assertTrue($closure(new TestObject(1)));
90
+ $this->assertTrue($closure(new TestObject(0)));
91
+ }
92
+
93
+ public function testWalkGreaterThanEqualsComparison()
94
+ {
95
+ $closure = $this->visitor->walkComparison($this->builder->gte("foo", 1));
96
+
97
+ $this->assertTrue($closure(new TestObject(2)));
98
+ $this->assertTrue($closure(new TestObject(1)));
99
+ $this->assertFalse($closure(new TestObject(0)));
100
+ }
101
+
102
+ public function testWalkGreaterThanComparison()
103
+ {
104
+ $closure = $this->visitor->walkComparison($this->builder->gt("foo", 1));
105
+
106
+ $this->assertTrue($closure(new TestObject(2)));
107
+ $this->assertFalse($closure(new TestObject(1)));
108
+ $this->assertFalse($closure(new TestObject(0)));
109
+ }
110
+
111
+ public function testWalkInComparison()
112
+ {
113
+ $closure = $this->visitor->walkComparison($this->builder->in("foo", array(1, 2, 3)));
114
+
115
+ $this->assertTrue($closure(new TestObject(2)));
116
+ $this->assertTrue($closure(new TestObject(1)));
117
+ $this->assertFalse($closure(new TestObject(0)));
118
+ }
119
+
120
+ public function testWalkNotInComparison()
121
+ {
122
+ $closure = $this->visitor->walkComparison($this->builder->notIn("foo", array(1, 2, 3)));
123
+
124
+ $this->assertFalse($closure(new TestObject(1)));
125
+ $this->assertFalse($closure(new TestObject(2)));
126
+ $this->assertTrue($closure(new TestObject(0)));
127
+ $this->assertTrue($closure(new TestObject(4)));
128
+ }
129
+
130
+ public function testWalkContainsComparison()
131
+ {
132
+ $closure = $this->visitor->walkComparison($this->builder->contains('foo', 'hello'));
133
+
134
+ $this->assertTrue($closure(new TestObject('hello world')));
135
+ $this->assertFalse($closure(new TestObject('world')));
136
+ }
137
+
138
+ public function testWalkAndCompositeExpression()
139
+ {
140
+ $closure = $this->visitor->walkCompositeExpression(
141
+ $this->builder->andX(
142
+ $this->builder->eq("foo", 1),
143
+ $this->builder->eq("bar", 1)
144
+ )
145
+ );
146
+
147
+ $this->assertTrue($closure(new TestObject(1, 1)));
148
+ $this->assertFalse($closure(new TestObject(1, 0)));
149
+ $this->assertFalse($closure(new TestObject(0, 1)));
150
+ $this->assertFalse($closure(new TestObject(0, 0)));
151
+ }
152
+
153
+ public function testWalkOrCompositeExpression()
154
+ {
155
+ $closure = $this->visitor->walkCompositeExpression(
156
+ $this->builder->orX(
157
+ $this->builder->eq("foo", 1),
158
+ $this->builder->eq("bar", 1)
159
+ )
160
+ );
161
+
162
+ $this->assertTrue($closure(new TestObject(1, 1)));
163
+ $this->assertTrue($closure(new TestObject(1, 0)));
164
+ $this->assertTrue($closure(new TestObject(0, 1)));
165
+ $this->assertFalse($closure(new TestObject(0, 0)));
166
+ }
167
+
168
+ public function testSortByFieldAscending()
169
+ {
170
+ $objects = array(new TestObject("b"), new TestObject("a"), new TestObject("c"));
171
+ $sort = ClosureExpressionVisitor::sortByField("foo");
172
+
173
+ usort($objects, $sort);
174
+
175
+ $this->assertEquals("a", $objects[0]->getFoo());
176
+ $this->assertEquals("b", $objects[1]->getFoo());
177
+ $this->assertEquals("c", $objects[2]->getFoo());
178
+ }
179
+
180
+ public function testSortByFieldDescending()
181
+ {
182
+ $objects = array(new TestObject("b"), new TestObject("a"), new TestObject("c"));
183
+ $sort = ClosureExpressionVisitor::sortByField("foo", -1);
184
+
185
+ usort($objects, $sort);
186
+
187
+ $this->assertEquals("c", $objects[0]->getFoo());
188
+ $this->assertEquals("b", $objects[1]->getFoo());
189
+ $this->assertEquals("a", $objects[2]->getFoo());
190
+ }
191
+
192
+ public function testSortDelegate()
193
+ {
194
+ $objects = array(new TestObject("a", "c"), new TestObject("a", "b"), new TestObject("a", "a"));
195
+ $sort = ClosureExpressionVisitor::sortByField("bar", 1);
196
+ $sort = ClosureExpressionVisitor::sortByField("foo", 1, $sort);
197
+
198
+ usort($objects, $sort);
199
+
200
+ $this->assertEquals("a", $objects[0]->getBar());
201
+ $this->assertEquals("b", $objects[1]->getBar());
202
+ $this->assertEquals("c", $objects[2]->getBar());
203
+ }
204
+
205
+ public function testArrayComparison()
206
+ {
207
+ $closure = $this->visitor->walkComparison($this->builder->eq("foo", 42));
208
+
209
+ $this->assertTrue($closure(array('foo' => 42)));
210
+ }
211
+ }
212
+
213
+ class TestObject
214
+ {
215
+ private $foo;
216
+ private $bar;
217
+ private $baz;
218
+ private $qux;
219
+
220
+ public function __construct($foo = null, $bar = null, $baz = null, $qux = null)
221
+ {
222
+ $this->foo = $foo;
223
+ $this->bar = $bar;
224
+ $this->baz = $baz;
225
+ $this->qux = $qux;
226
+ }
227
+
228
+ public function __call($name, $arguments)
229
+ {
230
+ if ('getqux' === $name) {
231
+ return $this->qux;
232
+ }
233
+ }
234
+
235
+ public function getFoo()
236
+ {
237
+ return $this->foo;
238
+ }
239
+
240
+ public function getBar()
241
+ {
242
+ return $this->bar;
243
+ }
244
+
245
+ public function isBaz()
246
+ {
247
+ return $this->baz;
248
+ }
249
+ }
250
+
app/code/community/Expressly/Expressly/vendor/doctrine/collections/tests/Doctrine/Tests/Common/Collections/CollectionTest.php ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Doctrine\Tests\Common\Collections;
4
+
5
+ use Doctrine\Common\Collections\ArrayCollection;
6
+ use Doctrine\Common\Collections\Collection;
7
+ use Doctrine\Common\Collections\Criteria;
8
+
9
+ class CollectionTest extends \PHPUnit_Framework_TestCase
10
+ {
11
+ /**
12
+ * @var Collection
13
+ */
14
+ private $collection;
15
+
16
+ protected function setUp()
17
+ {
18
+ $this->collection = new ArrayCollection();
19
+ }
20
+
21
+ public function testIssetAndUnset()
22
+ {
23
+ $this->assertFalse(isset($this->collection[0]));
24
+ $this->collection->add('testing');
25
+ $this->assertTrue(isset($this->collection[0]));
26
+ unset($this->collection[0]);
27
+ $this->assertFalse(isset($this->collection[0]));
28
+ }
29
+
30
+ public function testToString()
31
+ {
32
+ $this->collection->add('testing');
33
+ $this->assertTrue(is_string((string) $this->collection));
34
+ }
35
+
36
+ public function testRemovingNonExistentEntryReturnsNull()
37
+ {
38
+ $this->assertEquals(null, $this->collection->remove('testing_does_not_exist'));
39
+ }
40
+
41
+ public function testExists()
42
+ {
43
+ $this->collection->add("one");
44
+ $this->collection->add("two");
45
+ $exists = $this->collection->exists(function($k, $e) { return $e == "one"; });
46
+ $this->assertTrue($exists);
47
+ $exists = $this->collection->exists(function($k, $e) { return $e == "other"; });
48
+ $this->assertFalse($exists);
49
+ }
50
+
51
+ public function testMap()
52
+ {
53
+ $this->collection->add(1);
54
+ $this->collection->add(2);
55
+ $res = $this->collection->map(function($e) { return $e * 2; });
56
+ $this->assertEquals(array(2, 4), $res->toArray());
57
+ }
58
+
59
+ public function testFilter()
60
+ {
61
+ $this->collection->add(1);
62
+ $this->collection->add("foo");
63
+ $this->collection->add(3);
64
+ $res = $this->collection->filter(function($e) { return is_numeric($e); });
65
+ $this->assertEquals(array(0 => 1, 2 => 3), $res->toArray());
66
+ }
67
+
68
+ public function testFirstAndLast()
69
+ {
70
+ $this->collection->add('one');
71
+ $this->collection->add('two');
72
+
73
+ $this->assertEquals($this->collection->first(), 'one');
74
+ $this->assertEquals($this->collection->last(), 'two');
75
+ }
76
+
77
+ public function testArrayAccess()
78
+ {
79
+ $this->collection[] = 'one';
80
+ $this->collection[] = 'two';
81
+
82
+ $this->assertEquals($this->collection[0], 'one');
83
+ $this->assertEquals($this->collection[1], 'two');
84
+
85
+ unset($this->collection[0]);
86
+ $this->assertEquals($this->collection->count(), 1);
87
+ }
88
+
89
+ public function testContainsKey()
90
+ {
91
+ $this->collection[5] = 'five';
92
+ $this->assertTrue($this->collection->containsKey(5));
93
+ }
94
+
95
+ public function testContains()
96
+ {
97
+ $this->collection[0] = 'test';
98
+ $this->assertTrue($this->collection->contains('test'));
99
+ }
100
+
101
+ public function testSearch()
102
+ {
103
+ $this->collection[0] = 'test';
104
+ $this->assertEquals(0, $this->collection->indexOf('test'));
105
+ }
106
+
107
+ public function testGet()
108
+ {
109
+ $this->collection[0] = 'test';
110
+ $this->assertEquals('test', $this->collection->get(0));
111
+ }
112
+
113
+ public function testGetKeys()
114
+ {
115
+ $this->collection[] = 'one';
116
+ $this->collection[] = 'two';
117
+ $this->assertEquals(array(0, 1), $this->collection->getKeys());
118
+ }
119
+
120
+ public function testGetValues()
121
+ {
122
+ $this->collection[] = 'one';
123
+ $this->collection[] = 'two';
124
+ $this->assertEquals(array('one', 'two'), $this->collection->getValues());
125
+ }
126
+
127
+ public function testCount()
128
+ {
129
+ $this->collection[] = 'one';
130
+ $this->collection[] = 'two';
131
+ $this->assertEquals($this->collection->count(), 2);
132
+ $this->assertEquals(count($this->collection), 2);
133
+ }
134
+
135
+ public function testForAll()
136
+ {
137
+ $this->collection[] = 'one';
138
+ $this->collection[] = 'two';
139
+ $this->assertEquals($this->collection->forAll(function($k, $e) { return is_string($e); }), true);
140
+ $this->assertEquals($this->collection->forAll(function($k, $e) { return is_array($e); }), false);
141
+ }
142
+
143
+ public function testPartition()
144
+ {
145
+ $this->collection[] = true;
146
+ $this->collection[] = false;
147
+ $partition = $this->collection->partition(function($k, $e) { return $e == true; });
148
+ $this->assertEquals($partition[0][0], true);
149
+ $this->assertEquals($partition[1][0], false);
150
+ }
151
+
152
+ public function testClear()
153
+ {
154
+ $this->collection[] = 'one';
155
+ $this->collection[] = 'two';
156
+ $this->collection->clear();
157
+ $this->assertEquals($this->collection->isEmpty(), true);
158
+ }
159
+
160
+ public function testRemove()
161
+ {
162
+ $this->collection[] = 'one';
163
+ $this->collection[] = 'two';
164
+ $el = $this->collection->remove(0);
165
+
166
+ $this->assertEquals('one', $el);
167
+ $this->assertEquals($this->collection->contains('one'), false);
168
+ $this->assertNull($this->collection->remove(0));
169
+ }
170
+
171
+ public function testRemoveElement()
172
+ {
173
+ $this->collection[] = 'one';
174
+ $this->collection[] = 'two';
175
+
176
+ $this->assertTrue($this->collection->removeElement('two'));
177
+ $this->assertFalse($this->collection->contains('two'));
178
+ $this->assertFalse($this->collection->removeElement('two'));
179
+ }
180
+
181
+ public function testSlice()
182
+ {
183
+ $this->collection[] = 'one';
184
+ $this->collection[] = 'two';
185
+ $this->collection[] = 'three';
186
+
187
+ $slice = $this->collection->slice(0, 1);
188
+ $this->assertInternalType('array', $slice);
189
+ $this->assertEquals(array('one'), $slice);
190
+
191
+ $slice = $this->collection->slice(1);
192
+ $this->assertEquals(array(1 => 'two', 2 => 'three'), $slice);
193
+
194
+ $slice = $this->collection->slice(1, 1);
195
+ $this->assertEquals(array(1 => 'two'), $slice);
196
+ }
197
+
198
+ public function fillMatchingFixture()
199
+ {
200
+ $std1 = new \stdClass();
201
+ $std1->foo = "bar";
202
+ $this->collection[] = $std1;
203
+
204
+ $std2 = new \stdClass();
205
+ $std2->foo = "baz";
206
+ $this->collection[] = $std2;
207
+ }
208
+
209
+ /**
210
+ * @group DDC-1637
211
+ */
212
+ public function testMatching()
213
+ {
214
+ $this->fillMatchingFixture();
215
+
216
+ $col = $this->collection->matching(new Criteria(Criteria::expr()->eq("foo", "bar")));
217
+ $this->assertInstanceOf('Doctrine\Common\Collections\Collection', $col);
218
+ $this->assertNotSame($col, $this->collection);
219
+ $this->assertEquals(1, count($col));
220
+ }
221
+
222
+ /**
223
+ * @group DDC-1637
224
+ */
225
+ public function testMatchingOrdering()
226
+ {
227
+ $this->fillMatchingFixture();
228
+
229
+ $col = $this->collection->matching(new Criteria(null, array('foo' => 'DESC')));
230
+
231
+ $this->assertInstanceOf('Doctrine\Common\Collections\Collection', $col);
232
+ $this->assertNotSame($col, $this->collection);
233
+ $this->assertEquals(2, count($col));
234
+ $this->assertEquals('baz', $col->first()->foo);
235
+ $this->assertEquals('bar', $col->last()->foo);
236
+ }
237
+
238
+ /**
239
+ * @group DDC-1637
240
+ */
241
+ public function testMatchingSlice()
242
+ {
243
+ $this->fillMatchingFixture();
244
+
245
+ $col = $this->collection->matching(new Criteria(null, null, 1, 1));
246
+
247
+ $this->assertInstanceOf('Doctrine\Common\Collections\Collection', $col);
248
+ $this->assertNotSame($col, $this->collection);
249
+ $this->assertEquals(1, count($col));
250
+ $this->assertEquals('baz', $col[0]->foo);
251
+ }
252
+
253
+ public function testCanRemoveNullValuesByKey()
254
+ {
255
+ $this->collection->add(null);
256
+ $this->collection->remove(0);
257
+ $this->assertTrue($this->collection->isEmpty());
258
+ }
259
+
260
+ public function testCanVerifyExistingKeysWithNullValues()
261
+ {
262
+ $this->collection->set('key', null);
263
+ $this->assertTrue($this->collection->containsKey('key'));
264
+ }
265
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/tests/Doctrine/Tests/Common/Collections/CriteriaTest.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Doctrine\Tests\Common\Collections;
4
+
5
+ use Doctrine\Common\Collections\Criteria;
6
+ use Doctrine\Common\Collections\Expr\Comparison;
7
+ use Doctrine\Common\Collections\Expr\CompositeExpression;
8
+
9
+ class CriteriaTest extends \PHPUnit_Framework_TestCase
10
+ {
11
+ public function testCreate()
12
+ {
13
+ $criteria = Criteria::create();
14
+
15
+ $this->assertInstanceOf('Doctrine\Common\Collections\Criteria', $criteria);
16
+ }
17
+
18
+ public function testConstructor()
19
+ {
20
+ $expr = new Comparison("field", "=", "value");
21
+ $criteria = new Criteria($expr, array("foo" => "ASC"), 10, 20);
22
+
23
+ $this->assertSame($expr, $criteria->getWhereExpression());
24
+ $this->assertEquals(array("foo" => "ASC"), $criteria->getOrderings());
25
+ $this->assertEquals(10, $criteria->getFirstResult());
26
+ $this->assertEquals(20, $criteria->getMaxResults());
27
+ }
28
+
29
+ public function testWhere()
30
+ {
31
+ $expr = new Comparison("field", "=", "value");
32
+ $criteria = new Criteria();
33
+
34
+ $criteria->where($expr);
35
+
36
+ $this->assertSame($expr, $criteria->getWhereExpression());
37
+ }
38
+
39
+ public function testAndWhere()
40
+ {
41
+ $expr = new Comparison("field", "=", "value");
42
+ $criteria = new Criteria();
43
+
44
+ $criteria->where($expr);
45
+ $expr = $criteria->getWhereExpression();
46
+ $criteria->andWhere($expr);
47
+
48
+ $where = $criteria->getWhereExpression();
49
+ $this->assertInstanceOf('Doctrine\Common\Collections\Expr\CompositeExpression', $where);
50
+
51
+ $this->assertEquals(CompositeExpression::TYPE_AND, $where->getType());
52
+ $this->assertSame(array($expr, $expr), $where->getExpressionList());
53
+ }
54
+
55
+ public function testOrWhere()
56
+ {
57
+ $expr = new Comparison("field", "=", "value");
58
+ $criteria = new Criteria();
59
+
60
+ $criteria->where($expr);
61
+ $expr = $criteria->getWhereExpression();
62
+ $criteria->orWhere($expr);
63
+
64
+ $where = $criteria->getWhereExpression();
65
+ $this->assertInstanceOf('Doctrine\Common\Collections\Expr\CompositeExpression', $where);
66
+
67
+ $this->assertEquals(CompositeExpression::TYPE_OR, $where->getType());
68
+ $this->assertSame(array($expr, $expr), $where->getExpressionList());
69
+ }
70
+
71
+ public function testOrderings()
72
+ {
73
+ $criteria = Criteria::create()
74
+ ->orderBy(array("foo" => "ASC"));
75
+
76
+ $this->assertEquals(array("foo" => "ASC"), $criteria->getOrderings());
77
+ }
78
+
79
+ public function testExpr()
80
+ {
81
+ $this->assertInstanceOf('Doctrine\Common\Collections\ExpressionBuilder', Criteria::expr());
82
+ }
83
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/tests/Doctrine/Tests/Common/Collections/ExpressionBuilderTest.php ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Doctrine\Tests\Common\Collections;
4
+
5
+ use Doctrine\Common\Collections\ExpressionBuilder;
6
+ use Doctrine\Common\Collections\Expr\Comparison;
7
+ use Doctrine\Common\Collections\Expr\CompositeExpression;
8
+
9
+ /**
10
+ * @group DDC-1637
11
+ */
12
+ class ExpressionBuilderTest extends \PHPUnit_Framework_TestCase
13
+ {
14
+ /**
15
+ * @var ExpressionBuilder
16
+ */
17
+ private $builder;
18
+
19
+ protected function setUp()
20
+ {
21
+ $this->builder = new ExpressionBuilder();
22
+ }
23
+
24
+ public function testAndX()
25
+ {
26
+ $expr = $this->builder->andX($this->builder->eq("a", "b"));
27
+
28
+ $this->assertInstanceOf('Doctrine\Common\Collections\Expr\CompositeExpression', $expr);
29
+ $this->assertEquals(CompositeExpression::TYPE_AND, $expr->getType());
30
+ }
31
+
32
+ public function testOrX()
33
+ {
34
+ $expr = $this->builder->orX($this->builder->eq("a", "b"));
35
+
36
+ $this->assertInstanceOf('Doctrine\Common\Collections\Expr\CompositeExpression', $expr);
37
+ $this->assertEquals(CompositeExpression::TYPE_OR, $expr->getType());
38
+ }
39
+
40
+ public function testInvalidAndXArgument()
41
+ {
42
+ $this->setExpectedException("RuntimeException");
43
+ $this->builder->andX("foo");
44
+ }
45
+
46
+ public function testEq()
47
+ {
48
+ $expr = $this->builder->eq("a", "b");
49
+
50
+ $this->assertInstanceOf('Doctrine\Common\Collections\Expr\Comparison', $expr);
51
+ $this->assertEquals(Comparison::EQ, $expr->getOperator());
52
+ }
53
+
54
+ public function testNeq()
55
+ {
56
+ $expr = $this->builder->neq("a", "b");
57
+
58
+ $this->assertInstanceOf('Doctrine\Common\Collections\Expr\Comparison', $expr);
59
+ $this->assertEquals(Comparison::NEQ, $expr->getOperator());
60
+ }
61
+
62
+ public function testLt()
63
+ {
64
+ $expr = $this->builder->lt("a", "b");
65
+
66
+ $this->assertInstanceOf('Doctrine\Common\Collections\Expr\Comparison', $expr);
67
+ $this->assertEquals(Comparison::LT, $expr->getOperator());
68
+ }
69
+
70
+ public function testGt()
71
+ {
72
+ $expr = $this->builder->gt("a", "b");
73
+
74
+ $this->assertInstanceOf('Doctrine\Common\Collections\Expr\Comparison', $expr);
75
+ $this->assertEquals(Comparison::GT, $expr->getOperator());
76
+ }
77
+
78
+ public function testGte()
79
+ {
80
+ $expr = $this->builder->gte("a", "b");
81
+
82
+ $this->assertInstanceOf('Doctrine\Common\Collections\Expr\Comparison', $expr);
83
+ $this->assertEquals(Comparison::GTE, $expr->getOperator());
84
+ }
85
+
86
+ public function testLte()
87
+ {
88
+ $expr = $this->builder->lte("a", "b");
89
+
90
+ $this->assertInstanceOf('Doctrine\Common\Collections\Expr\Comparison', $expr);
91
+ $this->assertEquals(Comparison::LTE, $expr->getOperator());
92
+ }
93
+
94
+ public function testIn()
95
+ {
96
+ $expr = $this->builder->in("a", array("b"));
97
+
98
+ $this->assertInstanceOf('Doctrine\Common\Collections\Expr\Comparison', $expr);
99
+ $this->assertEquals(Comparison::IN, $expr->getOperator());
100
+ }
101
+
102
+ public function testNotIn()
103
+ {
104
+ $expr = $this->builder->notIn("a", array("b"));
105
+
106
+ $this->assertInstanceOf('Doctrine\Common\Collections\Expr\Comparison', $expr);
107
+ $this->assertEquals(Comparison::NIN, $expr->getOperator());
108
+ }
109
+
110
+ public function testIsNull()
111
+ {
112
+ $expr = $this->builder->isNull("a");
113
+
114
+ $this->assertInstanceOf('Doctrine\Common\Collections\Expr\Comparison', $expr);
115
+ $this->assertEquals(Comparison::EQ, $expr->getOperator());
116
+ }
117
+
118
+ public function testContains()
119
+ {
120
+ $expr = $this->builder->contains("a", "b");
121
+
122
+ $this->assertInstanceOf('Doctrine\Common\Collections\Expr\Comparison', $expr);
123
+ $this->assertEquals(Comparison::CONTAINS, $expr->getOperator());
124
+ }
125
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/tests/Doctrine/Tests/LazyArrayCollection.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Doctrine\Tests;
4
+
5
+ use Doctrine\Common\Collections\AbstractLazyCollection;
6
+ use Doctrine\Common\Collections\ArrayCollection;
7
+
8
+ /**
9
+ * Simple lazy collection that used an ArrayCollection as backed collection
10
+ */
11
+ class LazyArrayCollection extends AbstractLazyCollection
12
+ {
13
+ /**
14
+ * Do the initialization logic
15
+ *
16
+ * @return void
17
+ */
18
+ protected function doInitialize()
19
+ {
20
+ $this->collection = new ArrayCollection(array('a', 'b', 'c'));
21
+ }
22
+ }
app/code/community/Expressly/Expressly/vendor/doctrine/collections/tests/Doctrine/Tests/TestInit.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file bootstraps the test environment.
4
+ */
5
+ namespace Doctrine\Tests;
6
+
7
+ error_reporting(E_ALL | E_STRICT);
8
+
9
+ // register silently failing autoloader
10
+ spl_autoload_register(function($class) {
11
+ if (0 === strpos($class, 'Doctrine\Tests\\')) {
12
+ $path = __DIR__.'/../../'.strtr($class, '\\', '/').'.php';
13
+ if (is_file($path) && is_readable($path)) {
14
+ require_once $path;
15
+
16
+ return true;
17
+ }
18
+ }
19
+ });
20
+
21
+ require_once __DIR__ . "/../../../vendor/autoload.php";
app/code/community/Expressly/Expressly/vendor/expressly/php-common/.gitignore ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .idea
2
+ vendor
3
+ node_modules
4
+ *.log
5
+ .sass-cache
6
+ .DS_Store
7
+ .DS_Store?
8
+ ._*
9
+ .Spotlight-V100
10
+ .Trashes
11
+ ehthumbs.db
12
+ Thumbs.db
13
+ composer.lock
app/code/community/Expressly/Expressly/vendor/expressly/php-common/.htaccess ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <IfModule mod_rewrite.c>
2
+ RewriteEngine On
3
+ RewriteCond %{REQUEST_FILENAME} !-f
4
+ RewriteRule ^(.*) src/Client.php [QSA,L]
5
+ </IfModule>
app/code/community/Expressly/Expressly/vendor/expressly/php-common/LICENSE ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 expressly
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
app/code/community/Expressly/Expressly/vendor/expressly/php-common/README.md ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Introduction
2
+ Common Expressly library. This library is written in Silex, with additional Symfony2 components, and Buzz to dispatch requests. All logic is handled by this library; child libraries should only wrap, and populate the existing functionality.
3
+
4
+ ## Style
5
+ All code must follow `PSR-1/PSR-2` style guidelines.
6
+
7
+ ## Requirements
8
+ - PHP 5.3+
9
+ - composer (to be bundled)
10
+ - Apache
11
+ - nginx (to be done by myself)
12
+
13
+ ## Installation
14
+ Basic installation:
15
+
16
+ - `git clone git@github.com:expressly/php-common.git`
17
+ - `composer install`
18
+ - `chmod -R 777 ./storage`
19
+
20
+ Or, require the git repository as a composer dependency to the child library.
21
+
22
+ There are a few sections of the library that must be populated, or overwritten for proper functionality.
23
+ Note: All references to an `$app` are directly linked to an instance of `Silex\Application`. This instance is returned from the `Expressly\Client`.
24
+
25
+ ### Database
26
+ As we require the storage of merchant preferences, some settings must be updated, or overwritten.
27
+ There is a Doctrine mapped fallback for `Expressly\Entity\Merchant` which utilizes default configuration values. If the eCommerce shop in question doesn't provide a database access API, the in-place fall-back is to be used.
28
+ The fallback will be used by default, configuration values must be updated. These values are located in `/src/Resources/config/config.yml`, and have a yaml structure of:
29
+
30
+ database:
31
+ driver: pdo_mysql
32
+ host: 127.0.0.1
33
+ dbname: expressly
34
+ user: root
35
+ password: ''
36
+
37
+ And
38
+
39
+ table:
40
+ merchant: expressly_preferences
41
+
42
+ To overwrite in PHP, use the following command as an example:
43
+
44
+ $app['config']['database']['dbname'] = 'expressly';
45
+
46
+ The following are to be saved in the merchants' database:
47
+ - Hostname
48
+ - Password (if not provided when calling `setPassword()`, a new password will be generated)
49
+ - Offer: whether to show offers, or not
50
+ - Redirect destination, if shop requires as such
51
+
52
+ ### Incoming Requests
53
+ Incoming request must be handled by the child library. The following requests will be received, and must be handled:
54
+
55
+ ping:
56
+ pattern: /expressly/api/ping
57
+ method: [GET]
58
+ event: utility.ping
59
+
60
+ customer migrate:
61
+ pattern: /expressly/api/user/{email}
62
+ method: [GET]
63
+ event: customer.migrate
64
+
65
+ customer update:
66
+ pattern: /expressly/api/user/{email}
67
+ method: [POST]
68
+ event: customer.update
69
+
70
+ customer reset:
71
+ pattern: /expressly/api/user/{email}/delete
72
+ method: [POST]
73
+ event: customer.reset
74
+
75
+ customer order:
76
+ pattern: /expressly/api/user/{email}/order
77
+ method: [GET]
78
+ event: customer.order
79
+
80
+
81
+ ### Outgoing Requests
82
+ All outgoing requests are sent via Buzz. These definitions are made in `/src/Resources/config/config.yml` in following structure:
83
+
84
+ external:
85
+ host: https://expresslyapp.com/api/v1
86
+ routes:
87
+ route_name:
88
+ method: METHOD
89
+ uri: /
90
+
91
+ All logic for outgoing events is handled by this library. Event are in place to dispatch requests, the incoming information must be populated. All available events definitions are located in `Expressly\Subscriber\*::getSubscribedEvents()`. To call these events, please repurpose the following:
92
+
93
+ $app['dispatcher']->dispatch('customer.migrate', new Expressly\Event\CustomerMigrateEvent($customer, $email, $reference));
94
+
95
+ ## Javascript
96
+ Using the respective shop's inclusion method, the `/src/Resources/js/expressly.js` file must be included on the page. Upon including the file, an AJAX request will be auto-executed to request the modal from our servers.
app/code/community/Expressly/Expressly/vendor/expressly/php-common/assets/js/expressly.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ // Expressly popup script
2
+ function init() {
3
+ return true;
4
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/assets/scss/default.scss ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ body,
2
+ html {
3
+ width: 100%;
4
+ height: 100%;
5
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/bootstrap/bootstrap.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $package = __DIR__ . '/../../../../vendor/autoload.php';
4
+ if (file_exists($package)) {
5
+ require $package;
6
+ } else {
7
+ require __DIR__ . '/../vendor/autoload.php';
8
+ }
9
+
10
+ use Expressly\Logger\DummyLogger;
11
+ use Monolog\Handler\RedisHandler;
12
+ use Monolog\Logger;
13
+ use Predis\Client;
14
+ use Silex\Provider\MonologServiceProvider;
15
+
16
+ $app = new Silex\Application();
17
+
18
+ require_once __DIR__ . '/config.php';
19
+
20
+ try {
21
+ $app->register(new MonologServiceProvider(), array(
22
+ 'monolog.level' => Logger::WARNING,
23
+ 'monolog.name' => $merchantType,
24
+ 'monolog.handler' => $app->share(function () {
25
+ // Configuration not being accessible anymore from $app directly after being instantiated.
26
+ return new RedisHandler(
27
+ new Client('tcp://internal.expresslyapp.com:6379'),
28
+ $_SERVER['HTTP_HOST'],
29
+ Logger::WARNING,
30
+ true
31
+ );
32
+ })
33
+ ));
34
+ } catch (\Exception $e) {
35
+ $app['logger'] = $app->share(function () {
36
+ return new DummyLogger();
37
+ });
38
+ }
39
+
40
+ require_once __DIR__ . '/database.php';
41
+ require_once __DIR__ . '/services.php';
42
+
43
+ return $app;
app/code/community/Expressly/Expressly/vendor/expressly/php-common/bootstrap/config.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $app->register(new DerAlex\Silex\YamlConfigServiceProvider(__DIR__ . '/../src/Resources/config/config.yml'));
4
+
5
+ // Overwrite default values with those passed in from Expressly\Client
6
+ $app['config'] = array_replace_recursive($app['config'], $config);
app/code/community/Expressly/Expressly/vendor/expressly/php-common/bootstrap/database.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ use Dflydev\Silex\Provider\DoctrineOrm\DoctrineOrmServiceProvider;
4
+ use Doctrine\Common\Annotations\AnnotationRegistry;
5
+ use Silex\Provider\DoctrineServiceProvider;
6
+
7
+ // DBAL
8
+ //$app->register(new DoctrineServiceProvider(), array(
9
+ // 'db.options' => $app['config']['database']
10
+ //));
11
+
12
+ $app->register(new \Expressly\ServiceProvider\DatabaseServiceProvider());
app/code/community/Expressly/Expressly/vendor/expressly/php-common/bootstrap/services.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // Register ServiceProviders
4
+ $app->register(new Expressly\ServiceProvider\VersionServiceProvider());
5
+ $app->register(new Expressly\ServiceProvider\ValidatorServiceProvider());
6
+ $app->register(new Expressly\ServiceProvider\ExternalRouteServiceProvider());
7
+ $app->register(new Expressly\ServiceProvider\MerchantServiceProvider());
8
+ $app->register(new Expressly\ServiceProvider\JavaScriptServiceProvider());
9
+ $app->register(new Expressly\ServiceProvider\CountryCodeServiceProvider());
10
+
11
+ // Register events
12
+ $app['dispatcher']->addSubscriber(new Expressly\Subscriber\CustomerMigrationSubscriber($app));
13
+ $app['dispatcher']->addSubscriber(new Expressly\Subscriber\MerchantSubscriber($app));
14
+ $app['dispatcher']->addSubscriber(new Expressly\Subscriber\BannerSubscriber($app));
15
+ $app['dispatcher']->addSubscriber(new Expressly\Subscriber\UtilitySubscriber($app));
app/code/community/Expressly/Expressly/vendor/expressly/php-common/composer.json ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "expressly/php-common",
3
+ "version": "1.1.6",
4
+ "type": "library",
5
+ "description": "Expressly common PHP library",
6
+ "require": {
7
+ "php": ">=5.3.0",
8
+ "silex/silex": "1.2.4",
9
+ "symfony/config": "2.6.7",
10
+ "symfony/yaml": "2.6.7",
11
+ "deralex/yaml-config-service-provider": "1.0.1",
12
+ "kriswallsmith/Buzz": "0.13",
13
+ "monolog/monolog": "1.13.1",
14
+ "doctrine/collections": "1.3.0",
15
+ "predis/predis": "1.0.1"
16
+ },
17
+ "license": "MIT",
18
+ "authors": [
19
+ {
20
+ "name": "Sam Pratt",
21
+ "email": "sam@buyexpressly.com"
22
+ }
23
+ ],
24
+ "require-dev": {
25
+ "phpunit/phpunit": "4.6.6"
26
+ },
27
+ "autoload": {
28
+ "psr-4": {
29
+ "Expressly\\": "src/"
30
+ }
31
+ }
32
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/gulpfile.js ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var gulp = require('gulp');
2
+ var uglify = require('gulp-uglify');
3
+ var sass = require('gulp-ruby-sass');
4
+ var prefix = require('gulp-autoprefixer');
5
+
6
+ gulp.task('default', ['css', 'js']);
7
+
8
+ gulp.task('css', function() {
9
+ return sass('./assets/scss/', { style: 'compressed' })
10
+ .pipe(prefix({
11
+ browsers: ['last 2 version'],
12
+ cascade: false
13
+ }))
14
+ .pipe(gulp.dest('./src/Resources/css'));
15
+ });
16
+
17
+ gulp.task('js', function() {
18
+ gulp.src('./assets/js/*.js')
19
+ .pipe(uglify())
20
+ .pipe(gulp.dest('./src/Resources/js'));
21
+ });
22
+
23
+ gulp.task('watch', ['css', 'js'], function() {
24
+ gulp.watch('./assets/scss/*.scss', ['css']);
25
+ gulp.watch('./assets/js/*.js', ['js']);
26
+ });
app/code/community/Expressly/Expressly/vendor/expressly/php-common/package.json ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "expressly-php-common",
3
+ "version": "1.0.0",
4
+ "description": "Expressly common PHP library",
5
+ "main": "gulpfile.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/expressly/php-common"
12
+ },
13
+ "keywords": [
14
+ "expressly"
15
+ ],
16
+ "author": "Sam Pratt <sam@buyexpressly.com>",
17
+ "license": "MIT",
18
+ "bugs": {
19
+ "url": "https://github.com/expressly/php-common/issues"
20
+ },
21
+ "homepage": "https://github.com/expressly/php-common",
22
+ "devDependencies": {
23
+ "gulp": "^3.8.11",
24
+ "gulp-autoprefixer": "^2.2.0",
25
+ "gulp-ruby-sass": "^1.0.5",
26
+ "gulp-uglify": "^1.2.0"
27
+ }
28
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/phpunit.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <phpunit backupGlobals="false"
3
+ backupStaticAttributes="false"
4
+ colors="true"
5
+ convertErrorsToExceptions="true"
6
+ convertNoticesToExceptions="true"
7
+ convertWarningsToExceptions="true"
8
+ processIsolation="false"
9
+ stopOnFailure="false"
10
+ syntaxCheck="false">
11
+ <testsuites>
12
+ <testsuite name="Expressly Common Test Suite">
13
+ <directory>./src/Tests/</directory>
14
+ </testsuite>
15
+ </testsuites>
16
+ <php>
17
+ <server name='HTTP_HOST' value='http://localhost' />
18
+ </php>
19
+ </phpunit>
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Client.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly;
4
+
5
+ use Silex\Application;
6
+
7
+ class Client
8
+ {
9
+ private $app;
10
+
11
+ public function __construct($merchantType, $config = array())
12
+ {
13
+ $this->app = require __DIR__ . '/../bootstrap/bootstrap.php';
14
+ }
15
+
16
+ public function getApp()
17
+ {
18
+ return $this->app;
19
+ }
20
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Address.php ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Entity;
4
+
5
+ class Address extends ArraySerializeable
6
+ {
7
+ const ADDRESS_BILLING = 'billing';
8
+ const ADDRESS_SHIPPING = 'shipping';
9
+ const ADDRESS_BOTH = 'both';
10
+
11
+ protected $firstName;
12
+ protected $lastName;
13
+ protected $address1;
14
+ protected $address2;
15
+ protected $city;
16
+ protected $companyName;
17
+ protected $zip;
18
+ protected $phone;
19
+ protected $alias;
20
+ protected $stateProvince;
21
+ protected $country;
22
+
23
+ public static function compare(Address $a, Address $b)
24
+ {
25
+ if ($a->toArray() == $b->toArray()) {
26
+ return true;
27
+ }
28
+
29
+ return false;
30
+ }
31
+
32
+ public function getFirstName()
33
+ {
34
+ return $this->firstName;
35
+ }
36
+
37
+ public function setFirstName($firstName)
38
+ {
39
+ $this->firstName = $firstName;
40
+
41
+ return $this;
42
+ }
43
+
44
+ public function getLastName()
45
+ {
46
+ return $this->lastName;
47
+ }
48
+
49
+ public function setLastName($lastName)
50
+ {
51
+ $this->lastName = $lastName;
52
+
53
+ return $this;
54
+ }
55
+
56
+ public function getAddress1()
57
+ {
58
+ return $this->address1;
59
+ }
60
+
61
+ public function setAddress1($addressLine)
62
+ {
63
+ $this->address1 = $addressLine;
64
+
65
+ return $this;
66
+ }
67
+
68
+ public function getAddress2()
69
+ {
70
+ return $this->address2;
71
+ }
72
+
73
+ public function setAddress2($addressLine)
74
+ {
75
+ $this->address2 = $addressLine;
76
+
77
+ return $this;
78
+ }
79
+
80
+ public function getCity()
81
+ {
82
+ return $this->city;
83
+ }
84
+
85
+ public function setCity($city)
86
+ {
87
+ $this->city = $city;
88
+
89
+ return $this;
90
+ }
91
+
92
+ public function getCompanyName()
93
+ {
94
+ return $this->companyName;
95
+ }
96
+
97
+ public function setCompanyName($companyName)
98
+ {
99
+ $this->companyName = $companyName;
100
+
101
+ return $this;
102
+ }
103
+
104
+ public function getZip()
105
+ {
106
+ return $this->zip;
107
+ }
108
+
109
+ public function setZip($zip)
110
+ {
111
+ $this->zip = $zip;
112
+
113
+ return $this;
114
+ }
115
+
116
+ public function setPhonePosition($phone)
117
+ {
118
+ $this->phone = (int)$phone;
119
+
120
+ return $this;
121
+ }
122
+
123
+ public function getPhonePosition()
124
+ {
125
+ return $this->phone;
126
+ }
127
+
128
+ public function getAlias()
129
+ {
130
+ return $this->alias;
131
+ }
132
+
133
+ public function setAlias($alias)
134
+ {
135
+ $this->alias = $alias;
136
+
137
+ return $this;
138
+ }
139
+
140
+ public function getStateProvince()
141
+ {
142
+ return $this->stateProvince;
143
+ }
144
+
145
+ public function setStateProvince($stateProvince)
146
+ {
147
+ $this->stateProvince = $stateProvince;
148
+
149
+ return $this;
150
+ }
151
+
152
+ public function getCountry()
153
+ {
154
+ return $this->country;
155
+ }
156
+
157
+ public function setCountry($country)
158
+ {
159
+ $this->country = $country;
160
+
161
+ return $this;
162
+ }
163
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/ArraySerializeable.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Entity;
4
+
5
+ use Doctrine\Common\Collections\ArrayCollection;
6
+
7
+ abstract class ArraySerializeable
8
+ {
9
+ public function toArray()
10
+ {
11
+ $data = get_object_vars($this);
12
+ $data = array_filter($data, function($item) {
13
+ return !is_null($item) && $item !== '';
14
+ });
15
+
16
+ array_walk_recursive($data, function (&$element) {
17
+ if ($element instanceof ArraySerializeable) {
18
+ $element = $element->toArray();
19
+ }
20
+ if ($element instanceof ArrayCollection) {
21
+ $element = $element->toArray();
22
+ array_walk($element, function (&$item) {
23
+ $item = $item->toArray();
24
+ });
25
+ }
26
+ });
27
+
28
+ return $data;
29
+ }
30
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Cart.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Entity;
4
+
5
+ class Cart
6
+ {
7
+ protected $productCode;
8
+ protected $coupon;
9
+
10
+ public function getProductCode()
11
+ {
12
+ return $this->productCode;
13
+ }
14
+
15
+ public function setProductCode($code)
16
+ {
17
+ $this->productCode = $code;
18
+
19
+ return $this;
20
+ }
21
+
22
+ public function getCoupon()
23
+ {
24
+ return $this->coupon;
25
+ }
26
+
27
+ public function setCoupon($coupon)
28
+ {
29
+ $this->coupon = $coupon;
30
+
31
+ return $this;
32
+
33
+ }
34
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Customer.php ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Entity;
4
+
5
+ use Doctrine\Common\Collections\ArrayCollection;
6
+
7
+ class Customer extends ArraySerializeable
8
+ {
9
+ const GENDER_MALE = 'M';
10
+ const GENDER_FEMALE = 'F';
11
+ const GENDER_TRANS = 'T';
12
+
13
+ protected $firstName;
14
+ protected $lastName;
15
+ protected $gender;
16
+ protected $billingAddress;
17
+ protected $shippingAddress;
18
+ protected $company;
19
+ protected $dob;
20
+ protected $taxNumber;
21
+ protected $onlinePresence;
22
+ protected $dateUpdated;
23
+ protected $dateLastOrder;
24
+ protected $numberOrdered;
25
+ protected $emails;
26
+ protected $phones;
27
+ protected $addresses;
28
+
29
+ public function __construct()
30
+ {
31
+ $this->onlinePresence = new ArrayCollection();
32
+ $this->emails = new ArrayCollection();
33
+ $this->phones = new ArrayCollection();
34
+ $this->addresses = new ArrayCollection();
35
+ }
36
+
37
+ public function setFirstName($firstName)
38
+ {
39
+ $this->firstName = $firstName;
40
+
41
+ return $this;
42
+ }
43
+
44
+ public function setLastName($lastName)
45
+ {
46
+ $this->lastName = $lastName;
47
+
48
+ return $this;
49
+ }
50
+
51
+ public function setGender($gender)
52
+ {
53
+ $this->gender = $gender;
54
+
55
+ return $this;
56
+ }
57
+
58
+ public function setCompany($company)
59
+ {
60
+ $this->company = $company;
61
+
62
+ return $this;
63
+ }
64
+
65
+ public function setBirthday(\DateTime $birthday)
66
+ {
67
+ $this->dob = $birthday->format('Y-m-d');
68
+
69
+ return $this;
70
+ }
71
+
72
+ public function setTaxNumber($taxNumber)
73
+ {
74
+ $this->taxNumber = $taxNumber;
75
+
76
+ return $this;
77
+ }
78
+
79
+ public function setDateUpdated(\DateTime $date)
80
+ {
81
+ $date->setTimezone(new \DateTimeZone('UTC'));
82
+ $this->dateUpdated = $date->format(\DateTime::ISO8601);
83
+
84
+ return $this;
85
+ }
86
+
87
+ public function setDateLastOrder(\DateTime $date)
88
+ {
89
+ $date->setTimezone(new \DateTimeZone('UTC'));
90
+ $this->dateLastOrder = $date->format(\DateTime::ISO8601);
91
+
92
+ return $this;
93
+ }
94
+
95
+ public function setNumberOrdered($number)
96
+ {
97
+ $this->numberOrdered = $number;
98
+
99
+ return $this;
100
+ }
101
+
102
+ public function addSocial(Social $social)
103
+ {
104
+ $this->onlinePresence->add($social);
105
+
106
+ return $this;
107
+ }
108
+
109
+ public function addEmail(Email $email)
110
+ {
111
+ $emails = $this->emails;
112
+ $exists = function ($index, $el) use ($emails, $email) {
113
+ if ($el->toArray() == $email->toArray()) {
114
+ return true;
115
+ }
116
+
117
+ return false;
118
+ };
119
+
120
+ if (!$this->emails->exists($exists)) {
121
+ $this->emails->add($email);
122
+ }
123
+
124
+ return $this;
125
+ }
126
+
127
+ public function getEmailIndex(Email $email)
128
+ {
129
+ $index = $this->emails->indexOf($email);
130
+
131
+ if (is_null($index)) {
132
+ $this->emails->map(function ($key, $el) use ($email, &$index) {
133
+ if ($el->toArray() == $email->toArray()) {
134
+ $index = $key;
135
+ }
136
+ });
137
+ }
138
+
139
+ return $index;
140
+ }
141
+
142
+ public function addPhone(Phone $phone)
143
+ {
144
+ $phones = $this->phones;
145
+ $exists = function ($index, $el) use ($phones, $phone) {
146
+ if ($el->toArray() == $phone->toArray()) {
147
+ return true;
148
+ }
149
+
150
+ return false;
151
+ };
152
+
153
+ if (!$this->phones->exists($exists)) {
154
+ $this->phones->add($phone);
155
+ }
156
+
157
+ return $this;
158
+ }
159
+
160
+ public function getPhoneIndex(Phone $phone)
161
+ {
162
+ $index = $this->phones->indexOf($phone);
163
+
164
+ if (is_null($index)) {
165
+ $this->phones->map(function ($key, $el) use ($phone, &$index) {
166
+ if ($el->toArray() == $phone->toArray()) {
167
+ $index = $key;
168
+ }
169
+ });
170
+ }
171
+
172
+ return $index;
173
+ }
174
+
175
+ public function addAddress(Address $address, $primary = false, $type = null)
176
+ {
177
+ $this->addresses->add($address);
178
+
179
+ if (!$primary) {
180
+ return $this;
181
+ }
182
+
183
+ $index = $this->addresses->indexOf($address);
184
+ if ($type == Address::ADDRESS_BILLING || $type == Address::ADDRESS_BOTH) {
185
+ $this->billingAddress = $index;
186
+ }
187
+ if ($type == Address::ADDRESS_SHIPPING || $type == Address::ADDRESS_BOTH) {
188
+ $this->shippingAddress = $index;
189
+ }
190
+
191
+ return $this;
192
+ }
193
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Email.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Entity;
4
+
5
+ class Email extends ArraySerializeable
6
+ {
7
+ protected $email;
8
+ protected $alias;
9
+
10
+ public function getEmail()
11
+ {
12
+ return $this->email;
13
+ }
14
+
15
+ public function setEmail($email)
16
+ {
17
+ $this->email = $email;
18
+
19
+ return $this;
20
+ }
21
+
22
+ public function getAlias()
23
+ {
24
+ return $this->alias;
25
+ }
26
+
27
+ public function setAlias($alias)
28
+ {
29
+ $this->alias = $alias;
30
+
31
+ return $this;
32
+ }
33
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Generic.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Entity;
4
+
5
+ class Generic extends ArraySerializeable
6
+ {
7
+ protected $field;
8
+ protected $value;
9
+
10
+ public function getField()
11
+ {
12
+ return $this->field;
13
+ }
14
+
15
+ public function setField($field)
16
+ {
17
+ $this->field = $field;
18
+
19
+ return $this;
20
+ }
21
+
22
+ public function getValue()
23
+ {
24
+ return $this->value;
25
+ }
26
+
27
+ public function setValue($value)
28
+ {
29
+ $this->value = $value;
30
+
31
+ return $this;
32
+ }
33
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Invoice.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Entity;
4
+
5
+ class Invoice extends ArraySerializeable
6
+ {
7
+ protected $email;
8
+ protected $orderCount = 0;
9
+ protected $preTaxTotal = 0.0;
10
+ protected $postTaxTotal = 0.0;
11
+ protected $tax = 0.0;
12
+ protected $orders = array();
13
+
14
+ public function setEmail($email)
15
+ {
16
+ $this->email = $email;
17
+
18
+ return $this;
19
+ }
20
+
21
+ public function addOrder(Order $order)
22
+ {
23
+ $this->orders[] = $order;
24
+
25
+ $this->orderCount++;
26
+ $this->preTaxTotal += $order->getPreTaxTotal();
27
+ $this->postTaxTotal += $order->getPostTaxTotal();
28
+ $this->tax += $order->getTax();
29
+
30
+ return $this;
31
+ }
32
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Merchant.php ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Entity;
4
+
5
+ class Merchant extends ArraySerializeable
6
+ {
7
+ protected $id;
8
+ protected $uuid;
9
+ protected $name;
10
+ protected $host;
11
+ protected $password;
12
+ protected $offer = true;
13
+ protected $destination;
14
+ protected $path;
15
+ protected $image;
16
+ protected $terms;
17
+ protected $policy;
18
+
19
+ public static function compare(Merchant $a, Merchant $b)
20
+ {
21
+ if ($a->getHost() != $b->getHost()) {
22
+ return false;
23
+ }
24
+
25
+ if ($a->getPassword() != $b->getPassword()) {
26
+ return false;
27
+ }
28
+
29
+ if ($a->getOffer() != $b->getOffer()) {
30
+ return false;
31
+ }
32
+
33
+ if ($a->getDestination() != $b->getDestination()) {
34
+ return false;
35
+ }
36
+
37
+ return true;
38
+ }
39
+
40
+ public function getHost()
41
+ {
42
+ return $this->host;
43
+ }
44
+
45
+ public function setHost($host)
46
+ {
47
+ $this->host = $host;
48
+
49
+ return $this;
50
+ }
51
+
52
+ public function getPassword()
53
+ {
54
+ return $this->password;
55
+ }
56
+
57
+ public function setPassword($password)
58
+ {
59
+ $this->password = $password;
60
+
61
+ return $this;
62
+ }
63
+
64
+ public function getOffer()
65
+ {
66
+ return (bool)$this->offer;
67
+ }
68
+
69
+ public function setOffer($offer)
70
+ {
71
+ $this->offer = (bool)$offer;
72
+
73
+ return $this;
74
+ }
75
+
76
+ public function getDestination()
77
+ {
78
+ return $this->destination;
79
+ }
80
+
81
+ public function setDestination($destination)
82
+ {
83
+ $this->destination = $destination;
84
+
85
+ return $this;
86
+ }
87
+
88
+ public function getUuid()
89
+ {
90
+ return $this->uuid;
91
+ }
92
+
93
+ public function setUuid($uuid)
94
+ {
95
+ $this->uuid = $uuid;
96
+
97
+ return $this;
98
+ }
99
+
100
+ public function getName()
101
+ {
102
+ return $this->name;
103
+ }
104
+
105
+ public function setName($name)
106
+ {
107
+ $this->name = $name;
108
+
109
+ return $this;
110
+ }
111
+
112
+ public function getId()
113
+ {
114
+ return $this->id;
115
+ }
116
+
117
+ public function setId($id)
118
+ {
119
+ $this->id = $id;
120
+
121
+ return $this;
122
+ }
123
+
124
+ public function getPath()
125
+ {
126
+ return $this->path;
127
+ }
128
+
129
+ public function setPath($path)
130
+ {
131
+ $this->path = $path;
132
+
133
+ return $this;
134
+ }
135
+
136
+ public function getEndpoint()
137
+ {
138
+ return $this->host . $this->path;
139
+ }
140
+
141
+ public function getImage()
142
+ {
143
+ return $this->image;
144
+ }
145
+
146
+ public function setImage($image)
147
+ {
148
+ $this->image = $image;
149
+
150
+ return $this;
151
+ }
152
+
153
+ public function getTerms()
154
+ {
155
+ return $this->terms;
156
+ }
157
+
158
+ public function setTerms($terms)
159
+ {
160
+ $this->terms = $terms;
161
+
162
+ return $this;
163
+ }
164
+
165
+ public function getPolicy()
166
+ {
167
+ return $this->policy;
168
+ }
169
+
170
+ public function setPolicy($policy)
171
+ {
172
+ $this->policy = $policy;
173
+
174
+ return $this;
175
+ }
176
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/MerchantType.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Entity;
4
+
5
+ class MerchantType
6
+ {
7
+ const PRESTASHOP = 'prestashop';
8
+ const MAGENTO = 'magento';
9
+ const OPENCART_1 = 'opencart1';
10
+ const OPENCART_2 = 'opencart2';
11
+ const WOOCOMMERCE = 'woocommerce';
12
+ const OSCOMMERCE_2 = 'oscommerce2';
13
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Meta.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Entity;
4
+
5
+ use Doctrine\Common\Collections\ArrayCollection;
6
+
7
+ class Meta extends ArraySerializeable
8
+ {
9
+ protected $locale;
10
+ protected $sender;
11
+ protected $issuerData;
12
+
13
+ public function __construct()
14
+ {
15
+ $this->setSender($_SERVER['SERVER_NAME']);
16
+ $this->issuerData = new ArrayCollection();
17
+ }
18
+
19
+ public function addIssuerData(Generic $data)
20
+ {
21
+ $this->issuerData->add($data);
22
+
23
+ return $this;
24
+ }
25
+
26
+ public function removeIssuerData(Generic $data)
27
+ {
28
+ $this->issuerData->removeElement($data);
29
+
30
+ return $this;
31
+ }
32
+
33
+ public function getLocale()
34
+ {
35
+ return $this->locale;
36
+ }
37
+
38
+ public function setLocale($locale)
39
+ {
40
+ $this->locale = $locale;
41
+
42
+ return $this;
43
+ }
44
+
45
+ public function getSender()
46
+ {
47
+ return $this->sender;
48
+ }
49
+
50
+ public function setSender($sender)
51
+ {
52
+ $this->sender = $sender;
53
+
54
+ return $this;
55
+ }
56
+
57
+ public function getIssuerData()
58
+ {
59
+ return $this->issuerData;
60
+ }
61
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Order.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Entity;
4
+
5
+ class Order extends ArraySerializeable
6
+ {
7
+ protected $id;
8
+ protected $date;
9
+ protected $itemCount;
10
+ protected $coupon;
11
+ protected $currency;
12
+ protected $preTaxTotal;
13
+ protected $postTaxTotal;
14
+ protected $tax;
15
+
16
+ public function setId($id)
17
+ {
18
+ $this->id = $id;
19
+
20
+ return $this;
21
+ }
22
+
23
+ public function setDate(\DateTime $date)
24
+ {
25
+ $date->setTimezone(new \DateTimeZone('UTC'));
26
+ $this->date = $date->format(\DateTime::ISO8601);
27
+
28
+ return $this;
29
+ }
30
+
31
+ public function setItemCount($itemCount)
32
+ {
33
+ $this->itemCount = (int)$itemCount;
34
+
35
+ return $this;
36
+ }
37
+
38
+ public function setCoupon($coupon)
39
+ {
40
+ $this->coupon = $coupon;
41
+
42
+ return $this;
43
+ }
44
+
45
+ public function setCurrency($currency)
46
+ {
47
+ $this->currency = $currency;
48
+
49
+ return $this;
50
+ }
51
+
52
+ public function setTotal($total, $tax = 0.0)
53
+ {
54
+ $this->preTaxTotal = (double)$total;
55
+ $this->tax = (double)$tax;
56
+ $this->postTaxTotal = (double)$total + (double)$tax;
57
+
58
+ return $this;
59
+ }
60
+
61
+ public function getPreTaxTotal()
62
+ {
63
+ return (double)$this->preTaxTotal;
64
+ }
65
+
66
+ public function getPostTaxTotal()
67
+ {
68
+ return (double)$this->postTaxTotal;
69
+ }
70
+
71
+ public function getTax()
72
+ {
73
+ return (double)$this->tax;
74
+ }
75
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Phone.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Entity;
4
+
5
+ class Phone extends ArraySerializeable
6
+ {
7
+ const PHONE_TYPE_MOBILE = 'M';
8
+ const PHONE_TYPE_HOME = 'L';
9
+
10
+ protected $type;
11
+ protected $number;
12
+ protected $countryCode;
13
+
14
+ public function getType()
15
+ {
16
+ return $this->type;
17
+ }
18
+
19
+ public function setType($type)
20
+ {
21
+ if ($type == self::PHONE_TYPE_HOME) {
22
+ $this->type = self::PHONE_TYPE_HOME;
23
+ }
24
+ if ($type == self::PHONE_TYPE_MOBILE) {
25
+ $this->type = self::PHONE_TYPE_MOBILE;
26
+ }
27
+
28
+ return $this;
29
+ }
30
+
31
+ public function getNumber()
32
+ {
33
+ return $this->number;
34
+ }
35
+
36
+ public function setNumber($number)
37
+ {
38
+ $this->number = $number;
39
+
40
+ return $this;
41
+ }
42
+
43
+ public function getCountryCode()
44
+ {
45
+ return $this->countryCode;
46
+ }
47
+
48
+ public function setCountryCode($code)
49
+ {
50
+ $this->countryCode = $code;
51
+
52
+ return $this;
53
+ }
54
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Route.php ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Entity;
4
+
5
+ use Buzz\Client\Curl;
6
+ use Buzz\Message\Request;
7
+ use Buzz\Message\RequestInterface;
8
+ use Buzz\Message\Response;
9
+ use Expressly\Exception\InvalidURIException;
10
+
11
+ class Route
12
+ {
13
+ private $host;
14
+ private $uri;
15
+ private $method;
16
+ private $parameters = array();
17
+ private $rules = array();
18
+ private $retries = 1;
19
+
20
+ const MAX_RETRIES = 3;
21
+
22
+ public function setParameters(Array $parameters)
23
+ {
24
+ $this->parameters = $parameters;
25
+
26
+ return $this;
27
+ }
28
+
29
+ public function process($callback = null)
30
+ {
31
+ $response = new Response();
32
+ $request = new Request($this->getMethod(), '/', $this->getURL());
33
+ $request->setProtocolVersion(1.1);
34
+ $request->addHeader('Content-Type: application/json');
35
+ $client = new Curl();
36
+ $client->setTimeout(5);
37
+ $client->setIgnoreErrors(true);
38
+
39
+ if (is_callable($callback)) {
40
+ // Add any additions to the Response
41
+ $callback($request);
42
+ }
43
+
44
+ $request->setContent(json_encode($request->getContent()));
45
+ $client->send($request, $response);
46
+
47
+ // To account for timeouts, retry up to MAX_RETRIES
48
+ $content = $response->getContent();
49
+ if ($response->isEmpty() && empty($content) && $this->retries <= self::MAX_RETRIES) {
50
+ $this->retries++;
51
+ $this->process($callback);
52
+ }
53
+
54
+ return $response;
55
+ }
56
+
57
+ public function getMethod()
58
+ {
59
+ return $this->method;
60
+ }
61
+
62
+ public function setMethod($method)
63
+ {
64
+ $this->method = RequestInterface::METHOD_GET;
65
+
66
+ $methods = array(
67
+ RequestInterface::METHOD_GET,
68
+ RequestInterface::METHOD_HEAD,
69
+ RequestInterface::METHOD_POST,
70
+ RequestInterface::METHOD_PUT,
71
+ RequestInterface::METHOD_DELETE,
72
+ RequestInterface::METHOD_PATCH
73
+ );
74
+
75
+ if (in_array($method, $methods)) {
76
+ $this->method = $method;
77
+ }
78
+
79
+ return $this;
80
+ }
81
+
82
+ public function getURL()
83
+ {
84
+ return $this->host . $this->getURI();
85
+ }
86
+
87
+ public function getURI()
88
+ {
89
+ if (empty($this->parameters)) {
90
+ if (!empty($this->rules)) {
91
+ throw new InvalidURIException(reset($this->rules)->getMessage());
92
+ }
93
+
94
+ return $this->uri;
95
+ }
96
+
97
+ $uri = $this->uri;
98
+ foreach ($this->parameters as $parameter => $value) {
99
+ if (isset($this->rules[$parameter]) && !$this->rules[$parameter]->validate($value)) {
100
+ throw new InvalidURIException($this->rules[$parameter]->getMessage());
101
+ }
102
+
103
+ $uri = str_replace("<$parameter>", $value, $uri);
104
+ }
105
+
106
+ return $uri;
107
+ }
108
+
109
+ public function setURI($uri)
110
+ {
111
+ $this->uri = $uri;
112
+
113
+ return $this;
114
+ }
115
+
116
+ public function setRules(Array $rules)
117
+ {
118
+ $this->rules = $rules;
119
+
120
+ return $this;
121
+ }
122
+
123
+ public function getHost()
124
+ {
125
+ return $this->host;
126
+ }
127
+
128
+ public function setHost($host)
129
+ {
130
+ $this->host = $host;
131
+
132
+ return $this;
133
+ }
134
+
135
+ public function __toString()
136
+ {
137
+ return (string)$this->getURL();
138
+ }
139
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Entity/Social.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Entity;
4
+
5
+ class Social extends Generic
6
+ {
7
+ const SOCIAL_WEBSITE = 'website';
8
+ const SOCIAL_FACEBOOK = 'facebook';
9
+ const SOCIAL_TWITTER = 'twitter';
10
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/AcknowledgeableEvent.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Event;
4
+
5
+ use Expressly\Entity\Merchant;
6
+
7
+ class AcknowledgeableEvent extends PasswordedEvent
8
+ {
9
+ private $acknowledge;
10
+
11
+ public function __construct(Merchant $merchant, $acknowledge)
12
+ {
13
+ parent::__construct($merchant);
14
+ $this->acknowledge = $acknowledge;
15
+ }
16
+
17
+ public function getAcknowledge()
18
+ {
19
+ return (bool)$this->acknowledge;
20
+ }
21
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/BannerEvent.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Event;
4
+
5
+ use Expressly\Entity\Merchant;
6
+
7
+ class BannerEvent extends PasswordedEvent
8
+ {
9
+ private $email;
10
+
11
+ public function __construct(Merchant $merchant, $email)
12
+ {
13
+ parent::__construct($merchant);
14
+ $this->email = $email;
15
+ }
16
+
17
+ public function getEmail()
18
+ {
19
+ return $this->email;
20
+ }
21
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/CustomerEvent.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Event;
4
+
5
+ use Expressly\Entity\Customer;
6
+ use Expressly\Entity\Merchant;
7
+
8
+ class CustomerEvent extends PasswordedEvent
9
+ {
10
+ protected $customer;
11
+
12
+ public function __construct(Merchant $merchant, Customer $customer)
13
+ {
14
+ parent::__construct($merchant);
15
+ $this->customer = $customer;
16
+ }
17
+
18
+ public function getCustomer()
19
+ {
20
+ return $this->customer;
21
+ }
22
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/CustomerMigrateEvent.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Event;
4
+
5
+ use Expressly\Entity\Merchant;
6
+
7
+ class CustomerMigrateEvent extends PasswordedEvent
8
+ {
9
+ const MIGRATED_CUSTOMER = 'migrated';
10
+ const EXISTING_CUSTOMER = 'existing_customer';
11
+ private $uuid;
12
+ private $status;
13
+
14
+ public function __construct(Merchant $merchant, $uuid, $status = self::MIGRATED_CUSTOMER)
15
+ {
16
+ parent::__construct($merchant);
17
+ $this->uuid = $uuid;
18
+ $this->status = $status;
19
+ }
20
+
21
+ public function getUuid()
22
+ {
23
+ return $this->uuid;
24
+ }
25
+
26
+ public function getStatus()
27
+ {
28
+ return $this->status;
29
+ }
30
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/CustomerUpdateEvent.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Event;
4
+
5
+ use Expressly\Entity\Merchant;
6
+
7
+ class CustomerUpdateEvent extends PasswordedEvent
8
+ {
9
+ private $updated;
10
+
11
+ public function __construct(Merchant $merchant, \DateTime $updated)
12
+ {
13
+ parent::__construct($merchant);
14
+ $this->updated = $updated;
15
+ }
16
+
17
+ public function getLastUpdated()
18
+ {
19
+ return $this->updated->getTimestamp();
20
+ }
21
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/MerchantEvent.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Event;
4
+
5
+ use Expressly\Entity\Merchant;
6
+
7
+ class MerchantEvent extends ResponseEvent
8
+ {
9
+ protected $merchant;
10
+
11
+ public function __construct(Merchant $merchant)
12
+ {
13
+ $this->merchant = $merchant;
14
+ }
15
+
16
+ public function getMerchant()
17
+ {
18
+ return $this->merchant;
19
+ }
20
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/MerchantUpdatePasswordEvent.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Event;
4
+
5
+ use Expressly\Entity\Merchant;
6
+
7
+ class MerchantUpdatePasswordEvent extends PasswordedEvent
8
+ {
9
+ private $oldPassword;
10
+
11
+ public function __construct(Merchant $merchant, $oldPassword)
12
+ {
13
+ parent::__construct($merchant);
14
+
15
+ $this->oldPassword = $oldPassword;
16
+ }
17
+
18
+ public function getToken()
19
+ {
20
+ return base64_encode(sprintf('%s:%s', $this->merchant->getUuid(), $this->getOldPassword()));
21
+ }
22
+
23
+ public function getOldPassword()
24
+ {
25
+ return $this->oldPassword;
26
+ }
27
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/OrderUpdateEvent.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Event;
4
+
5
+ use Expressly\Entity\Merchant;
6
+ use Expressly\Entity\Order;
7
+
8
+ class OrderUpdateEvent extends PasswordedEvent
9
+ {
10
+ protected $email;
11
+ protected $order;
12
+
13
+ public function __construct(Merchant $merchant, $email, Order $order)
14
+ {
15
+ parent::__construct($merchant);
16
+ $this->email = $email;
17
+ $this->order = $order;
18
+ }
19
+
20
+ public function getEmail()
21
+ {
22
+ return $this->email;
23
+ }
24
+
25
+ public function getorder()
26
+ {
27
+ return $this->order;
28
+ }
29
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/PasswordedEvent.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Event;
4
+
5
+ use Expressly\Entity\Merchant;
6
+
7
+ class PasswordedEvent extends MerchantEvent
8
+ {
9
+ public function __construct(Merchant $merchant)
10
+ {
11
+ parent::__construct($merchant);
12
+ }
13
+
14
+ public function getUuid()
15
+ {
16
+ return $this->merchant->getUuid();
17
+ }
18
+
19
+ public function getBasicHeader()
20
+ {
21
+ return "Authorization: Basic {$this->getToken()}";
22
+ }
23
+
24
+ public function getToken()
25
+ {
26
+ return base64_encode(sprintf('%s:%s', $this->merchant->getUuid(), $this->merchant->getPassword()));
27
+ }
28
+
29
+ public function getPassword()
30
+ {
31
+ return $this->getMerchant()->getPassword();
32
+ }
33
+
34
+ public function getMerchant()
35
+ {
36
+ return $this->merchant;
37
+ }
38
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Event/ResponseEvent.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Event;
4
+
5
+ use Buzz\Message\Response;
6
+ use Symfony\Component\EventDispatcher\Event;
7
+
8
+ class ResponseEvent extends Event
9
+ {
10
+ private $response;
11
+
12
+ public function getResponse()
13
+ {
14
+ return $this->response;
15
+ }
16
+
17
+ public function setResponse($response)
18
+ {
19
+ $this->response = $response;
20
+
21
+ return $this;
22
+ }
23
+
24
+ public function isSuccessful()
25
+ {
26
+ if (!$this->response instanceof Response) {
27
+ return false;
28
+ }
29
+
30
+ return $this->response->isSuccessful();
31
+ }
32
+
33
+ public function getContent()
34
+ {
35
+ if (!$this->response instanceof Response) {
36
+ return null;
37
+ }
38
+
39
+ $content = $this->response->getContent();
40
+ if (is_array($content)) {
41
+ return $content;
42
+ }
43
+
44
+ $json = json_decode($content, true);
45
+
46
+ return (json_last_error() == JSON_ERROR_NONE) ? $json : $content;
47
+ }
48
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Exception/ExceptionFormatter.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Exception;
4
+
5
+ class ExceptionFormatter
6
+ {
7
+ public static function format(\Exception $exception)
8
+ {
9
+ if ($exception instanceof GenericException) {
10
+ return (string)$exception;
11
+ }
12
+
13
+ return sprintf(
14
+ '%s-%s (%s::%u)',
15
+ get_class($exception),
16
+ $exception->getMessage(),
17
+ $exception->getFile(),
18
+ $exception->getLine()
19
+ );
20
+ }
21
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Exception/GenericException.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Exception;
4
+
5
+ class GenericException extends \Exception
6
+ {
7
+ public function __toString()
8
+ {
9
+ return (string)sprintf(
10
+ '%s-%s (%s::%u)',
11
+ __CLASS__,
12
+ $this->getMessage(),
13
+ $this->getFile(),
14
+ $this->getLine()
15
+ );
16
+ }
17
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Exception/InvalidURIException.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Exception;
4
+
5
+ class InvalidURIException extends GenericException
6
+ {
7
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Helper/BannerHelper.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Helper;
4
+
5
+ use Expressly\Event\BannerEvent;
6
+
7
+ class BannerHelper
8
+ {
9
+ public static function toHtml(BannerEvent $event)
10
+ {
11
+ $content = $event->getContent();
12
+
13
+ if (!is_array($content)) {
14
+ return '';
15
+ }
16
+
17
+ if (!array_key_exists('migrationLink', $content) || !array_key_exists('bannerImageUrl', $content)) {
18
+ return '';
19
+ }
20
+
21
+ return sprintf(
22
+ '<div class="expressly-banner"><a href="%s"><img src="%s"/></a>',
23
+ $content['migrationLink'],
24
+ $content['bannerImageUrl']
25
+ );
26
+ }
27
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Logger/DummyLogger.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Logger;
4
+
5
+ use Psr\Log\LoggerInterface;
6
+
7
+ class DummyLogger implements LoggerInterface
8
+ {
9
+ public function emergency($message, array $context = array())
10
+ {
11
+ }
12
+
13
+ public function alert($message, array $context = array())
14
+ {
15
+ }
16
+
17
+ public function critical($message, array $context = array())
18
+ {
19
+ }
20
+
21
+ public function error($message, array $context = array())
22
+ {
23
+ }
24
+
25
+ public function warning($message, array $context = array())
26
+ {
27
+ }
28
+
29
+ public function notice($message, array $context = array())
30
+ {
31
+ }
32
+
33
+ public function info($message, array $context = array())
34
+ {
35
+ }
36
+
37
+ public function debug($message, array $context = array())
38
+ {
39
+ }
40
+
41
+ public function log($level, $message, array $context = array())
42
+ {
43
+ }
44
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Presenter/BatchCustomerPresenter.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Presenter;
4
+
5
+ class BatchCustomerPresenter implements PresenterInterface
6
+ {
7
+ private $emails;
8
+
9
+ public function __construct(Array $emails)
10
+ {
11
+ if (empty($emails['existing'])) {
12
+ $emails['existing'] = array();
13
+ }
14
+ if (empty($emails['deleted'])) {
15
+ $emails['deleted'] = array();
16
+ }
17
+ if (empty($emails['pending'])) {
18
+ $emails['pending'] = array();
19
+ }
20
+ $this->emails = $emails;
21
+ }
22
+
23
+ public function toArray()
24
+ {
25
+ return array(
26
+ 'existing' => $this->emails['existing'],
27
+ 'deleted' => $this->emails['deleted'],
28
+ 'pending' => $this->emails['pending']
29
+ );
30
+ }
31
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Presenter/BatchInvoicePresenter.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Presenter;
4
+
5
+ use Expressly\Entity\Invoice;
6
+
7
+ class BatchInvoicePresenter implements PresenterInterface
8
+ {
9
+ private $invoices = array();
10
+
11
+ public function __construct(Array $invoices)
12
+ {
13
+ foreach ($invoices as $invoice) {
14
+ if ($invoice instanceof Invoice) {
15
+ $this->invoices[] = $invoice->toArray();
16
+ }
17
+ }
18
+ }
19
+
20
+ public function toArray()
21
+ {
22
+ return array(
23
+ 'invoices' => $this->invoices
24
+ );
25
+ }
26
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Presenter/CustomerMigratePresenter.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Presenter;
4
+
5
+ use Expressly\Entity\Customer;
6
+ use Expressly\Entity\Merchant;
7
+
8
+ class CustomerMigratePresenter implements PresenterInterface
9
+ {
10
+ private $merchant;
11
+ private $customer;
12
+ private $email;
13
+ private $reference;
14
+
15
+ public function __construct(Merchant $merchant, Customer $customer, $email, $reference, $locale = 'en')
16
+ {
17
+ $this->merchant = $merchant;
18
+ $this->customer = $customer;
19
+ $this->email = $email;
20
+ $this->reference = $reference;
21
+ $this->locale = $locale;
22
+ }
23
+
24
+ public function toArray()
25
+ {
26
+ return array(
27
+ 'meta' => array(
28
+ 'locale' => $this->locale,
29
+ 'issuerData' => array(
30
+ array(
31
+ 'field' => 'expressly_path',
32
+ 'value' => $this->merchant->getPath()
33
+ )
34
+ )
35
+ ),
36
+ 'data' => array(
37
+ 'email' => $this->email,
38
+ 'userReference' => $this->reference,
39
+ 'customerData' => $this->customer->toArray()
40
+ )
41
+ );
42
+ }
43
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Presenter/PingPresenter.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Presenter;
4
+
5
+ class PingPresenter
6
+ {
7
+ public function toArray()
8
+ {
9
+ return array(
10
+ 'expressly' => 'Stuff is happening!'
11
+ );
12
+ }
13
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Presenter/PresenterInterface.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Presenter;
4
+
5
+ interface PresenterInterface
6
+ {
7
+ public function toArray();
8
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Provider/ConfigProviderInterface.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Provider;
4
+
5
+ interface ConfigProviderInterface
6
+ {
7
+ public function __get($key);
8
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Provider/CountryCodeProvider.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Provider;
4
+
5
+ use Doctrine\Common\Collections\ArrayCollection;
6
+
7
+ class CountryCodeProvider
8
+ {
9
+ const COUNTRY_CODE_TYPE_ISO_2 = 'iso2';
10
+ const COUNTRY_CODE_TYPE_ISO_3 = 'iso3';
11
+ const COUNTRY_CODE_TYPE_ISO_M49 = 'm49';
12
+ private $countries;
13
+
14
+ public function __construct($countries)
15
+ {
16
+ $this->countries = new ArrayCollection();
17
+
18
+ foreach ($countries as $country) {
19
+ $this->countries->add($country);
20
+ }
21
+ }
22
+
23
+ public function getIso2($code)
24
+ {
25
+ $country = $this->getByCode($code);
26
+ return is_array($country) ? (string)$country[self::COUNTRY_CODE_TYPE_ISO_2] : false;
27
+ }
28
+
29
+ private function getByCode($code)
30
+ {
31
+ $type = $this->getCodeType($code);
32
+
33
+ if (!$type) {
34
+ return false;
35
+ }
36
+
37
+ return $this->countries->filter(function ($country) use ($type, $code) {
38
+ if ($country[$type] == $code) {
39
+ return true;
40
+ }
41
+
42
+ return false;
43
+ })->first();
44
+ }
45
+
46
+ private function getCodeType($code)
47
+ {
48
+ if (strlen($code) == 2) {
49
+ return self::COUNTRY_CODE_TYPE_ISO_2;
50
+ }
51
+
52
+ if (strlen($code) == 3) {
53
+ return (int)((string)$code) > 0 ? self::COUNTRY_CODE_TYPE_ISO_M49 : self::COUNTRY_CODE_TYPE_ISO_3;
54
+ }
55
+
56
+ return false;
57
+ }
58
+
59
+ public function getIso3($code)
60
+ {
61
+ $country = $this->getByCode($code);
62
+ return is_array($country) ? (string)$country[self::COUNTRY_CODE_TYPE_ISO_3] : false;
63
+ }
64
+
65
+ public function getM49($code)
66
+ {
67
+ $country = $this->getByCode($code);
68
+ return is_array($country) ? (string)$country[self::COUNTRY_CODE_TYPE_ISO_M49] : false;
69
+ }
70
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Provider/ExternalRouteProvider.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Provider;
4
+
5
+ use Doctrine\Common\Collections\ArrayCollection;
6
+ use Expressly\Entity\Route;
7
+ use Silex\Application;
8
+
9
+ class ExternalRouteProvider implements ConfigProviderInterface
10
+ {
11
+ private $routes;
12
+
13
+ public function __construct(Application $app, $hosts, $routes)
14
+ {
15
+ $this->routes = new ArrayCollection();
16
+
17
+
18
+ foreach ($routes as $key => $definition) {
19
+ $route = new Route();
20
+ $route->setHost($hosts[$definition['host']])
21
+ ->setURI($definition['uri'])
22
+ ->setMethod($definition['method']);
23
+
24
+ if (!empty($definition['validation'])) {
25
+ $validation = array();
26
+
27
+ foreach ($definition['validation'] as $parameter => $validatorKey) {
28
+ $validation[$parameter] = $app["{$validatorKey}.validator"];
29
+ }
30
+
31
+ $route->setRules($validation);
32
+ }
33
+
34
+ $this->routes->set($key, $route);
35
+ }
36
+ }
37
+
38
+ public function __get($key)
39
+ {
40
+ if ($this->routes->containsKey($key)) {
41
+ return $this->routes->get($key);
42
+ }
43
+
44
+ return null;
45
+ }
46
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Provider/JavaScriptProvider.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Provider;
4
+
5
+ class JavaScriptProvider
6
+ {
7
+ private $js;
8
+
9
+ public function __construct()
10
+ {
11
+ $this->js = scandir(__DIR__ . '/../Resources/js/');
12
+ }
13
+
14
+ public function getJs()
15
+ {
16
+ return $this->js;
17
+ }
18
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Provider/MerchantProvider.php ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Provider;
4
+
5
+ use Expressly\Entity\Merchant;
6
+ use Silex\Application;
7
+
8
+ class MerchantProvider implements MerchantProviderInterface
9
+ {
10
+ private $db;
11
+ private $logger;
12
+ private $table;
13
+ private $merchant;
14
+
15
+ public function __construct(Application $app, $config = array(), $table = null)
16
+ {
17
+ $this->db = $app['db'];
18
+ $this->logger = $app['logger'];
19
+ $this->table = !is_null($table) ? $table : $app['config']['table']['merchant'];
20
+ $this->merchant = new Merchant();
21
+ }
22
+
23
+ // private function firstOrCreate()
24
+ // {
25
+ // $merchant = new Merchant();
26
+ //
27
+ // try {
28
+ // $getQuery = sprintf('SELECT * FROM %s LIMIT 1', $this->table);
29
+ // $statement = $this->db->prepare($getQuery);
30
+ // $statement->execute();
31
+ //
32
+ // $result = $statement->fetch(\PDO::FETCH_ASSOC);
33
+ //
34
+ // if (empty($result)) {
35
+ // $merchant->setPassword(Merchant::createPassword());
36
+ // $password = $merchant->getPassword();
37
+ //
38
+ // $insertQuery = sprintf('INSERT INTO %s (`password`) VALUES (:password)', $this->table);
39
+ // $statement = $this->db->prepare($insertQuery);
40
+ // $statement->bindParam(':password', $password);
41
+ // $statement->execute();
42
+ //
43
+ // $result = $statement->fetch(\PDO::FETCH_ASSOC);
44
+ // }
45
+ //
46
+ // $merchant->setId($result['id'])
47
+ // ->setHost($result['host'])
48
+ // ->setPassword($result['password'])
49
+ // ->setOffer($result['offer'])
50
+ // ->setDestination($result['destination']);
51
+ // } catch (\PDOException $e) {
52
+ // $this->logger->addError($e);
53
+ // }
54
+ //
55
+ // return $merchant;
56
+ // }
57
+
58
+ public function getMerchant()
59
+ {
60
+ return $this->merchant;
61
+ }
62
+
63
+ public function setMerchant(Merchant $merchant)
64
+ {
65
+ if (!Merchant::compare($this->merchant, $merchant)) {
66
+ $this->save($merchant);
67
+ }
68
+
69
+ return $this;
70
+ }
71
+
72
+ private function save(Merchant $merchant)
73
+ {
74
+ if (empty($this->merchant)) {
75
+ return;
76
+ }
77
+
78
+ try {
79
+ $saveQuery = sprintf(
80
+ 'INSERT INTO %s (`id`, `uuid`, `shop_name`, `host`, `path`, `password`, `offer`, `destination`, `policy`, `terms`, `image`)
81
+ VALUES (:id, :uuid, :shop_name, :host, :path, :password, :offer, :destination, :policy, :terms, :image)
82
+ ON DUPLICATE KEY UPDATE `uuid`=VALUES(`uuid`), `name`=VALUES(`name`), `host`=VALUES(`host`), `path`=VALUES(`path`),
83
+ `password`=VALUES(`password`), `offer`=VALUES(`offer`), `destination`=VALUES(`destination`), `policy`=VALUES(`policy`),
84
+ `terms`=VALUES(`terms`), `image`=VALUES(`image`);',
85
+ $this->table
86
+ );
87
+ $statement = $this->db->prepare($saveQuery);
88
+ $statement->bindParam('id', $merchant->getId());
89
+ $statement->bindParam('uuid', $merchant->getUuid());
90
+ $statement->bindParam('shop_name', $merchant->getName());
91
+ $statement->bindParam('host', $merchant->getHost());
92
+ $statement->bindParam('path', $merchant->getPath());
93
+ $statement->bindParam('password', $merchant->getPassword());
94
+ $statement->bindParam('offer', $merchant->getOffer());
95
+ $statement->bindParam('destination', $merchant->getDestination());
96
+ $statement->bindParam('policy', $merchant->getPolicy());
97
+ $statement->bindParam('terms', $merchant->getTerms());
98
+ $statement->bindParam('image', $merchant->getImage());
99
+ $statement->execute();
100
+
101
+ $this->merchant = $merchant;
102
+ } catch (\PDOException $e) {
103
+ $this->logger->addError($e);
104
+ }
105
+ }
106
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Provider/MerchantProviderInterface.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Provider;
4
+
5
+ use Expressly\Entity\Merchant;
6
+
7
+ interface MerchantProviderInterface
8
+ {
9
+ public function setMerchant(Merchant $merchant);
10
+
11
+ public function getMerchant();
12
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Proxy/.gitkeep ADDED
File without changes
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/config/config.yml ADDED
@@ -0,0 +1,315 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ version: v1
2
+
3
+ database:
4
+ driver: mysql
5
+ host: 127.0.0.1
6
+ dbname: expressly
7
+ user: root
8
+ password: ''
9
+
10
+ table:
11
+ merchant: expressly_preferences
12
+
13
+ validators:
14
+ - { class: Expressly\Validator\UuidValidator, message: Plugin not registered; please register first. }
15
+ - { class: Expressly\Validator\EmailValidator, message: Invalid email address provided. }
16
+
17
+ external:
18
+ hosts:
19
+ default: https://prod.expresslyapp.com/api/v1
20
+ admin: https://prod.expresslyapp.com/api/admin
21
+ routes:
22
+ ping:
23
+ host: admin
24
+ method: GET
25
+ uri: /ping
26
+ customer_migrate_popup:
27
+ host: default
28
+ method: GET
29
+ uri: /migration/<uuid>
30
+ validation:
31
+ uuid: uuid_string
32
+ customer_migrate_data:
33
+ host: default
34
+ method: GET
35
+ uri: /migration/<uuid>/user
36
+ validation:
37
+ uuid: uuid_string
38
+ customer_migrate_success:
39
+ host: default
40
+ method: POST
41
+ uri: /migration/<uuid>/success
42
+ validation:
43
+ uuid: uuid_string
44
+ merchant_register:
45
+ host: default
46
+ method: POST
47
+ uri: /merchant/register
48
+ merchant_update:
49
+ host: default
50
+ method: POST
51
+ uri: /merchant/<uuid>/update
52
+ validation:
53
+ uuid: uuid_string
54
+ merchant_delete:
55
+ host: default
56
+ method: POST
57
+ uri: /merchant/<uuid>/uninstall
58
+ validation:
59
+ uuid: uuid_string
60
+ banner_request:
61
+ host: default
62
+ method: GET
63
+ uri: /banner/<uuid>?email=<email>
64
+ validation:
65
+ uuid: uuid_string
66
+ email: email
67
+
68
+ country_code:
69
+ - { iso2: 'AF', iso3: 'AFG', m49: '004' }
70
+ - { iso2: 'AX', iso3: 'ALA', m49: '248' }
71
+ - { iso2: 'AL', iso3: 'ALB', m49: '008' }
72
+ - { iso2: 'DZ', iso3: 'DZA', m49: '012' }
73
+ - { iso2: 'AS', iso3: 'ASM', m49: '016' }
74
+ - { iso2: 'AD', iso3: 'AND', m49: '020' }
75
+ - { iso2: 'AO', iso3: 'AGO', m49: '024' }
76
+ - { iso2: 'AI', iso3: 'AIA', m49: '660' }
77
+ - { iso2: 'AQ', iso3: 'ATA', m49: '010' }
78
+ - { iso2: 'AG', iso3: 'ATG', m49: '028' }
79
+ - { iso2: 'AR', iso3: 'ARG', m49: '032' }
80
+ - { iso2: 'AM', iso3: 'ARM', m49: '051' }
81
+ - { iso2: 'AW', iso3: 'ABW', m49: '533' }
82
+ - { iso2: 'AU', iso3: 'AUS', m49: '036' }
83
+ - { iso2: 'AT', iso3: 'AUT', m49: '040' }
84
+ - { iso2: 'AZ', iso3: 'AZE', m49: '031' }
85
+ - { iso2: 'BS', iso3: 'BHS', m49: '044' }
86
+ - { iso2: 'BH', iso3: 'BHR', m49: '048' }
87
+ - { iso2: 'BD', iso3: 'BGD', m49: '050' }
88
+ - { iso2: 'BB', iso3: 'BRB', m49: '052' }
89
+ - { iso2: 'BY', iso3: 'BLR', m49: '112' }
90
+ - { iso2: 'BE', iso3: 'BEL', m49: '056' }
91
+ - { iso2: 'BZ', iso3: 'BLZ', m49: '084' }
92
+ - { iso2: 'BJ', iso3: 'BEN', m49: '204' }
93
+ - { iso2: 'BM', iso3: 'BMU', m49: '060' }
94
+ - { iso2: 'BT', iso3: 'BTN', m49: '064' }
95
+ - { iso2: 'BO', iso3: 'BOL', m49: '068' }
96
+ - { iso2: 'BA', iso3: 'BIH', m49: '070' }
97
+ - { iso2: 'BW', iso3: 'BWA', m49: '072' }
98
+ - { iso2: 'BV', iso3: 'BVT', m49: '074' }
99
+ - { iso2: 'BR', iso3: 'BRA', m49: '076' }
100
+ - { iso2: 'VG', iso3: 'VGB', m49: '092' }
101
+ - { iso2: 'IO', iso3: 'IOT', m49: '086' }
102
+ - { iso2: 'BN', iso3: 'BRN', m49: '096' }
103
+ - { iso2: 'BG', iso3: 'BGR', m49: '100' }
104
+ - { iso2: 'BF', iso3: 'BFA', m49: '854' }
105
+ - { iso2: 'BI', iso3: 'BDI', m49: '108' }
106
+ - { iso2: 'KH', iso3: 'KHM', m49: '116' }
107
+ - { iso2: 'CM', iso3: 'CMR', m49: '120' }
108
+ - { iso2: 'CA', iso3: 'CAN', m49: '124' }
109
+ - { iso2: 'CV', iso3: 'CPV', m49: '132' }
110
+ - { iso2: 'KY', iso3: 'CYM', m49: '136' }
111
+ - { iso2: 'CF', iso3: 'CAF', m49: '140' }
112
+ - { iso2: 'TD', iso3: 'TCD', m49: '148' }
113
+ - { iso2: 'CL', iso3: 'CHL', m49: '152' }
114
+ - { iso2: 'CN', iso3: 'CHN', m49: '156' }
115
+ - { iso2: 'HK', iso3: 'HKG', m49: '344' }
116
+ - { iso2: 'MO', iso3: 'MAC', m49: '446' }
117
+ - { iso2: 'CX', iso3: 'CXR', m49: '162' }
118
+ - { iso2: 'CC', iso3: 'CCK', m49: '166' }
119
+ - { iso2: 'CO', iso3: 'COL', m49: '170' }
120
+ - { iso2: 'KM', iso3: 'COM', m49: '174' }
121
+ - { iso2: 'CG', iso3: 'COG', m49: '178' }
122
+ - { iso2: 'CD', iso3: 'COD', m49: '180' }
123
+ - { iso2: 'CK', iso3: 'COK', m49: '184' }
124
+ - { iso2: 'CR', iso3: 'CRI', m49: '188' }
125
+ - { iso2: 'CI', iso3: 'CIV', m49: '384' }
126
+ - { iso2: 'HR', iso3: 'HRV', m49: '191' }
127
+ - { iso2: 'CU', iso3: 'CUB', m49: '192' }
128
+ - { iso2: 'CY', iso3: 'CYP', m49: '196' }
129
+ - { iso2: 'CZ', iso3: 'CZE', m49: '203' }
130
+ - { iso2: 'DK', iso3: 'DNK', m49: '208' }
131
+ - { iso2: 'DJ', iso3: 'DJI', m49: '262' }
132
+ - { iso2: 'DM', iso3: 'DMA', m49: '212' }
133
+ - { iso2: 'DO', iso3: 'DOM', m49: '214' }
134
+ - { iso2: 'EC', iso3: 'ECU', m49: '218' }
135
+ - { iso2: 'EG', iso3: 'EGY', m49: '818' }
136
+ - { iso2: 'SV', iso3: 'SLV', m49: '222' }
137
+ - { iso2: 'GQ', iso3: 'GNQ', m49: '226' }
138
+ - { iso2: 'ER', iso3: 'ERI', m49: '232' }
139
+ - { iso2: 'EE', iso3: 'EST', m49: '233' }
140
+ - { iso2: 'ET', iso3: 'ETH', m49: '231' }
141
+ - { iso2: 'FK', iso3: 'FLK', m49: '238' }
142
+ - { iso2: 'FO', iso3: 'FRO', m49: '234' }
143
+ - { iso2: 'FJ', iso3: 'FJI', m49: '242' }
144
+ - { iso2: 'FI', iso3: 'FIN', m49: '246' }
145
+ - { iso2: 'FR', iso3: 'FRA', m49: '250' }
146
+ - { iso2: 'GF', iso3: 'GUF', m49: '254' }
147
+ - { iso2: 'PF', iso3: 'PYF', m49: '258' }
148
+ - { iso2: 'TF', iso3: 'ATF', m49: '260' }
149
+ - { iso2: 'GA', iso3: 'GAB', m49: '266' }
150
+ - { iso2: 'GM', iso3: 'GMB', m49: '270' }
151
+ - { iso2: 'GE', iso3: 'GEO', m49: '268' }
152
+ - { iso2: 'DE', iso3: 'DEU', m49: '276' }
153
+ - { iso2: 'GH', iso3: 'GHA', m49: '288' }
154
+ - { iso2: 'GI', iso3: 'GIB', m49: '292' }
155
+ - { iso2: 'GR', iso3: 'GRC', m49: '300' }
156
+ - { iso2: 'GL', iso3: 'GRL', m49: '304' }
157
+ - { iso2: 'GD', iso3: 'GRD', m49: '308' }
158
+ - { iso2: 'GP', iso3: 'GLP', m49: '312' }
159
+ - { iso2: 'GU', iso3: 'GUM', m49: '316' }
160
+ - { iso2: 'GT', iso3: 'GTM', m49: '320' }
161
+ - { iso2: 'GG', iso3: 'GGY', m49: '831' }
162
+ - { iso2: 'GN', iso3: 'GIN', m49: '324' }
163
+ - { iso2: 'GW', iso3: 'GNB', m49: '624' }
164
+ - { iso2: 'GY', iso3: 'GUY', m49: '328' }
165
+ - { iso2: 'HT', iso3: 'HTI', m49: '332' }
166
+ - { iso2: 'HM', iso3: 'HMD', m49: '334' }
167
+ - { iso2: 'VA', iso3: 'VAT', m49: '336' }
168
+ - { iso2: 'HN', iso3: 'HND', m49: '340' }
169
+ - { iso2: 'HU', iso3: 'HUN', m49: '348' }
170
+ - { iso2: 'IS', iso3: 'ISL', m49: '352' }
171
+ - { iso2: 'IN', iso3: 'IND', m49: '356' }
172
+ - { iso2: 'ID', iso3: 'IDN', m49: '360' }
173
+ - { iso2: 'IR', iso3: 'IRN', m49: '364' }
174
+ - { iso2: 'IQ', iso3: 'IRQ', m49: '368' }
175
+ - { iso2: 'IE', iso3: 'IRL', m49: '372' }
176
+ - { iso2: 'IM', iso3: 'IMN', m49: '833' }
177
+ - { iso2: 'IL', iso3: 'ISR', m49: '376' }
178
+ - { iso2: 'IT', iso3: 'ITA', m49: '380' }
179
+ - { iso2: 'JM', iso3: 'JAM', m49: '388' }
180
+ - { iso2: 'JP', iso3: 'JPN', m49: '392' }
181
+ - { iso2: 'JE', iso3: 'JEY', m49: '832' }
182
+ - { iso2: 'JO', iso3: 'JOR', m49: '400' }
183
+ - { iso2: 'KZ', iso3: 'KAZ', m49: '398' }
184
+ - { iso2: 'KE', iso3: 'KEN', m49: '404' }
185
+ - { iso2: 'KI', iso3: 'KIR', m49: '296' }
186
+ - { iso2: 'KP', iso3: 'PRK', m49: '408' }
187
+ - { iso2: 'KR', iso3: 'KOR', m49: '410' }
188
+ - { iso2: 'KW', iso3: 'KWT', m49: '414' }
189
+ - { iso2: 'KG', iso3: 'KGZ', m49: '417' }
190
+ - { iso2: 'LA', iso3: 'LAO', m49: '418' }
191
+ - { iso2: 'LV', iso3: 'LVA', m49: '428' }
192
+ - { iso2: 'LB', iso3: 'LBN', m49: '422' }
193
+ - { iso2: 'LS', iso3: 'LSO', m49: '426' }
194
+ - { iso2: 'LR', iso3: 'LBR', m49: '430' }
195
+ - { iso2: 'LY', iso3: 'LBY', m49: '434' }
196
+ - { iso2: 'LI', iso3: 'LIE', m49: '438' }
197
+ - { iso2: 'LT', iso3: 'LTU', m49: '440' }
198
+ - { iso2: 'LU', iso3: 'LUX', m49: '442' }
199
+ - { iso2: 'MK', iso3: 'MKD', m49: '807' }
200
+ - { iso2: 'MG', iso3: 'MDG', m49: '450' }
201
+ - { iso2: 'MW', iso3: 'MWI', m49: '454' }
202
+ - { iso2: 'MY', iso3: 'MYS', m49: '458' }
203
+ - { iso2: 'MV', iso3: 'MDV', m49: '462' }
204
+ - { iso2: 'ML', iso3: 'MLI', m49: '466' }
205
+ - { iso2: 'MT', iso3: 'MLT', m49: '470' }
206
+ - { iso2: 'MH', iso3: 'MHL', m49: '584' }
207
+ - { iso2: 'MQ', iso3: 'MTQ', m49: '474' }
208
+ - { iso2: 'MR', iso3: 'MRT', m49: '478' }
209
+ - { iso2: 'MU', iso3: 'MUS', m49: '480' }
210
+ - { iso2: 'YT', iso3: 'MYT', m49: '175' }
211
+ - { iso2: 'MX', iso3: 'MEX', m49: '484' }
212
+ - { iso2: 'FM', iso3: 'FSM', m49: '583' }
213
+ - { iso2: 'MD', iso3: 'MDA', m49: '498' }
214
+ - { iso2: 'MC', iso3: 'MCO', m49: '492' }
215
+ - { iso2: 'MN', iso3: 'MNG', m49: '496' }
216
+ - { iso2: 'ME', iso3: 'MNE', m49: '499' }
217
+ - { iso2: 'MS', iso3: 'MSR', m49: '500' }
218
+ - { iso2: 'MA', iso3: 'MAR', m49: '504' }
219
+ - { iso2: 'MZ', iso3: 'MOZ', m49: '508' }
220
+ - { iso2: 'MM', iso3: 'MMR', m49: '104' }
221
+ - { iso2: 'NA', iso3: 'NAM', m49: '516' }
222
+ - { iso2: 'NR', iso3: 'NRU', m49: '520' }
223
+ - { iso2: 'NP', iso3: 'NPL', m49: '524' }
224
+ - { iso2: 'NL', iso3: 'NLD', m49: '528' }
225
+ - { iso2: 'AN', iso3: 'ANT', m49: '530' }
226
+ - { iso2: 'NC', iso3: 'NCL', m49: '540' }
227
+ - { iso2: 'NZ', iso3: 'NZL', m49: '554' }
228
+ - { iso2: 'NI', iso3: 'NIC', m49: '558' }
229
+ - { iso2: 'NE', iso3: 'NER', m49: '562' }
230
+ - { iso2: 'NG', iso3: 'NGA', m49: '566' }
231
+ - { iso2: 'NU', iso3: 'NIU', m49: '570' }
232
+ - { iso2: 'NF', iso3: 'NFK', m49: '574' }
233
+ - { iso2: 'MP', iso3: 'MNP', m49: '580' }
234
+ - { iso2: 'NO', iso3: 'NOR', m49: '578' }
235
+ - { iso2: 'OM', iso3: 'OMN', m49: '512' }
236
+ - { iso2: 'PK', iso3: 'PAK', m49: '586' }
237
+ - { iso2: 'PW', iso3: 'PLW', m49: '585' }
238
+ - { iso2: 'PS', iso3: 'PSE', m49: '275' }
239
+ - { iso2: 'PA', iso3: 'PAN', m49: '591' }
240
+ - { iso2: 'PG', iso3: 'PNG', m49: '598' }
241
+ - { iso2: 'PY', iso3: 'PRY', m49: '600' }
242
+ - { iso2: 'PE', iso3: 'PER', m49: '604' }
243
+ - { iso2: 'PH', iso3: 'PHL', m49: '608' }
244
+ - { iso2: 'PN', iso3: 'PCN', m49: '612' }
245
+ - { iso2: 'PL', iso3: 'POL', m49: '616' }
246
+ - { iso2: 'PT', iso3: 'PRT', m49: '620' }
247
+ - { iso2: 'PR', iso3: 'PRI', m49: '630' }
248
+ - { iso2: 'QA', iso3: 'QAT', m49: '634' }
249
+ - { iso2: 'RE', iso3: 'REU', m49: '638' }
250
+ - { iso2: 'RO', iso3: 'ROU', m49: '642' }
251
+ - { iso2: 'RU', iso3: 'RUS', m49: '643' }
252
+ - { iso2: 'RW', iso3: 'RWA', m49: '646' }
253
+ - { iso2: 'BL', iso3: 'BLM', m49: '652' }
254
+ - { iso2: 'SH', iso3: 'SHN', m49: '654' }
255
+ - { iso2: 'KN', iso3: 'KNA', m49: '659' }
256
+ - { iso2: 'LC', iso3: 'LCA', m49: '662' }
257
+ - { iso2: 'MF', iso3: 'MAF', m49: '663' }
258
+ - { iso2: 'PM', iso3: 'SPM', m49: '666' }
259
+ - { iso2: 'VC', iso3: 'VCT', m49: '670' }
260
+ - { iso2: 'WS', iso3: 'WSM', m49: '882' }
261
+ - { iso2: 'SM', iso3: 'SMR', m49: '674' }
262
+ - { iso2: 'ST', iso3: 'STP', m49: '678' }
263
+ - { iso2: 'SA', iso3: 'SAU', m49: '682' }
264
+ - { iso2: 'SN', iso3: 'SEN', m49: '686' }
265
+ - { iso2: 'RS', iso3: 'SRB', m49: '688' }
266
+ - { iso2: 'SC', iso3: 'SYC', m49: '690' }
267
+ - { iso2: 'SL', iso3: 'SLE', m49: '694' }
268
+ - { iso2: 'SG', iso3: 'SGP', m49: '702' }
269
+ - { iso2: 'SK', iso3: 'SVK', m49: '703' }
270
+ - { iso2: 'SI', iso3: 'SVN', m49: '705' }
271
+ - { iso2: 'SB', iso3: 'SLB', m49: '090' }
272
+ - { iso2: 'SO', iso3: 'SOM', m49: '706' }
273
+ - { iso2: 'ZA', iso3: 'ZAF', m49: '710' }
274
+ - { iso2: 'GS', iso3: 'SGS', m49: '239' }
275
+ - { iso2: 'SS', iso3: 'SSD', m49: '728' }
276
+ - { iso2: 'ES', iso3: 'ESP', m49: '724' }
277
+ - { iso2: 'LK', iso3: 'LKA', m49: '144' }
278
+ - { iso2: 'SD', iso3: 'SDN', m49: '736' }
279
+ - { iso2: 'SR', iso3: 'SUR', m49: '740' }
280
+ - { iso2: 'SJ', iso3: 'SJM', m49: '744' }
281
+ - { iso2: 'SZ', iso3: 'SWZ', m49: '748' }
282
+ - { iso2: 'SE', iso3: 'SWE', m49: '752' }
283
+ - { iso2: 'CH', iso3: 'CHE', m49: '756' }
284
+ - { iso2: 'SY', iso3: 'SYR', m49: '760' }
285
+ - { iso2: 'TW', iso3: 'TWN', m49: '158' }
286
+ - { iso2: 'TJ', iso3: 'TJK', m49: '762' }
287
+ - { iso2: 'TZ', iso3: 'TZA', m49: '834' }
288
+ - { iso2: 'TH', iso3: 'THA', m49: '764' }
289
+ - { iso2: 'TL', iso3: 'TLS', m49: '626' }
290
+ - { iso2: 'TG', iso3: 'TGO', m49: '768' }
291
+ - { iso2: 'TK', iso3: 'TKL', m49: '772' }
292
+ - { iso2: 'TO', iso3: 'TON', m49: '776' }
293
+ - { iso2: 'TT', iso3: 'TTO', m49: '780' }
294
+ - { iso2: 'TN', iso3: 'TUN', m49: '788' }
295
+ - { iso2: 'TR', iso3: 'TUR', m49: '792' }
296
+ - { iso2: 'TM', iso3: 'TKM', m49: '795' }
297
+ - { iso2: 'TC', iso3: 'TCA', m49: '796' }
298
+ - { iso2: 'TV', iso3: 'TUV', m49: '798' }
299
+ - { iso2: 'UG', iso3: 'UGA', m49: '800' }
300
+ - { iso2: 'UA', iso3: 'UKR', m49: '804' }
301
+ - { iso2: 'AE', iso3: 'ARE', m49: '784' }
302
+ - { iso2: 'GB', iso3: 'GBR', m49: '826' }
303
+ - { iso2: 'US', iso3: 'USA', m49: '840' }
304
+ - { iso2: 'UM', iso3: 'UMI', m49: '581' }
305
+ - { iso2: 'UY', iso3: 'URY', m49: '858' }
306
+ - { iso2: 'UZ', iso3: 'UZB', m49: '860' }
307
+ - { iso2: 'VU', iso3: 'VUT', m49: '548' }
308
+ - { iso2: 'VE', iso3: 'VEN', m49: '862' }
309
+ - { iso2: 'VN', iso3: 'VNM', m49: '704' }
310
+ - { iso2: 'VI', iso3: 'VIR', m49: '850' }
311
+ - { iso2: 'WF', iso3: 'WLF', m49: '876' }
312
+ - { iso2: 'EH', iso3: 'ESH', m49: '732' }
313
+ - { iso2: 'YE', iso3: 'YEM', m49: '887' }
314
+ - { iso2: 'ZM', iso3: 'ZMB', m49: '894' }
315
+ - { iso2: 'ZW', iso3: 'ZWE', m49: '716' }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/css/default.css ADDED
@@ -0,0 +1 @@
 
1
+ body,html{width:100%;height:100%}
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/images/Logo_Blue_s.jpg ADDED
Binary file
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/images/cross.png ADDED
Binary file
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/images/tick.png ADDED
Binary file
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/js/expressly.js ADDED
@@ -0,0 +1 @@
 
1
+ function init(){return!0}
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/translations/de.yml ADDED
File without changes
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/translations/en.yml ADDED
File without changes
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/view/landing.html.twig ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once 'app/code/local/Expressly/Migrator/Helper/ExpresslyConfig.php';
3
+ $config = new ExpresslyConfig();
4
+ ?>
5
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
6
+ <html xmlns="http://www.w3.org/1999/xhtml">
7
+ <head>
8
+ <script>
9
+ // var baseUrl = {{ }};
10
+ // baseUrl can work as document.referer
11
+ // var isRedirectEnabled = <?php echo $config->isRedirectEnabled(); ?>;
12
+ // var isRedirectToLoginEnabled = <?php echo $config->isRedirectToLogin(); ?>;
13
+ // var redirectDestination = "<?php echo $config->getRedirectDestination(); ?>";
14
+ </script>
15
+ </head>
16
+ <body></body>
17
+ </html>
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Resources/view/offer.html.twig ADDED
File without changes
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/ServiceProvider/CountryCodeServiceProvider.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\ServiceProvider;
4
+
5
+ use Expressly\Provider\CountryCodeProvider;
6
+ use Silex\Application;
7
+ use Silex\ServiceProviderInterface;
8
+
9
+ class CountryCodeServiceProvider implements ServiceProviderInterface
10
+ {
11
+ public function register(Application $app)
12
+ {
13
+ $app['country_code.provider'] = new CountryCodeProvider($app['config']['country_code']);
14
+ }
15
+
16
+ public function boot(Application $app)
17
+ {
18
+ }
19
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/ServiceProvider/DatabaseServiceProvider.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\ServiceProvider;
4
+
5
+ use Silex\Application;
6
+ use Silex\ServiceProviderInterface;
7
+
8
+ class DatabaseServiceProvider implements ServiceProviderInterface
9
+ {
10
+ public function register(Application $app)
11
+ {
12
+ $app['db'] = $app->share(function ($app) {
13
+ $config = $app['config']['database'];
14
+ $dsn = sprintf('%s:dbname=%s;host=%s', $config['driver'], $config['dbname'], $config['host']);
15
+
16
+ return new \PDO($dsn, $config['user'], $config['password']);
17
+ });
18
+ }
19
+
20
+ public function boot(Application $app)
21
+ {
22
+ }
23
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/ServiceProvider/ExternalRouteServiceProvider.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\ServiceProvider;
4
+
5
+ use Expressly\Provider\ExternalRouteProvider;
6
+ use Silex\Application;
7
+ use Silex\ServiceProviderInterface;
8
+
9
+ class ExternalRouteServiceProvider implements ServiceProviderInterface
10
+ {
11
+ public function register(Application $app)
12
+ {
13
+ $app['external_route.provider'] = $app->share(function ($app) {
14
+ return new ExternalRouteProvider(
15
+ $app,
16
+ $app['config']['external']['hosts'],
17
+ $app['config']['external']['routes']
18
+ );
19
+ });
20
+ }
21
+
22
+ public function boot(Application $app)
23
+ {
24
+ }
25
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/ServiceProvider/JavaScriptServiceProvider.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\ServiceProvider;
4
+
5
+ use Expressly\Provider\JavaScriptProvider;
6
+ use Silex\Application;
7
+ use Silex\ServiceProviderInterface;
8
+
9
+ class JavaScriptServiceProvider implements ServiceProviderInterface
10
+ {
11
+ public function register(Application $app)
12
+ {
13
+ $app['js.provider'] = $app->share(function ($app) {
14
+ return new JavaScriptProvider();
15
+ });
16
+ }
17
+
18
+ public function boot(Application $app)
19
+ {
20
+ }
21
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/ServiceProvider/MerchantServiceProvider.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\ServiceProvider;
4
+
5
+ use Expressly\Provider\MerchantProvider;
6
+ use Silex\Application;
7
+ use Silex\ServiceProviderInterface;
8
+
9
+ class MerchantServiceProvider implements ServiceProviderInterface
10
+ {
11
+ public function register(Application $app)
12
+ {
13
+ $app['merchant.provider'] = $app->share(function ($app) {
14
+ return new MerchantProvider($app);
15
+ });
16
+ }
17
+
18
+ public function boot(Application $app)
19
+ {
20
+ }
21
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/ServiceProvider/ValidatorServiceProvider.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\ServiceProvider;
4
+
5
+ use Silex\Application;
6
+ use Silex\ServiceProviderInterface;
7
+
8
+ class ValidatorServiceProvider implements ServiceProviderInterface
9
+ {
10
+ public function register(Application $app)
11
+ {
12
+ foreach ($app['config']['validators'] as $definition) {
13
+ $validator = new $definition['class']($definition['message']);
14
+
15
+ $app["{$validator->getType()}.validator"] = $app->share(function () use ($validator) {
16
+ return $validator;
17
+ });
18
+ }
19
+ }
20
+
21
+ public function boot(Application $app)
22
+ {
23
+ }
24
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/ServiceProvider/VersionServiceProvider.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\ServiceProvider;
4
+
5
+ use Silex\Application;
6
+ use Silex\ServiceProviderInterface;
7
+
8
+ class VersionServiceProvider implements ServiceProviderInterface
9
+ {
10
+ public function register(Application $app)
11
+ {
12
+ $app['version'] = $app['config']['version'];
13
+ }
14
+
15
+ public function boot(Application $app)
16
+ {
17
+ }
18
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Subscriber/BannerSubscriber.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Subscriber;
4
+
5
+ use Expressly\Event\BannerEvent;
6
+ use Silex\Application;
7
+ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
8
+
9
+ class BannerSubscriber implements EventSubscriberInterface
10
+ {
11
+ private $app;
12
+ private $routeProvider;
13
+
14
+ const BANNER_REQUEST = 'banner.request';
15
+
16
+ public function __construct(Application $app)
17
+ {
18
+ $this->app = $app;
19
+ $this->routeProvider = $app['external_route.provider'];
20
+ }
21
+
22
+ public static function getSubscribedEvents()
23
+ {
24
+ return array(
25
+ self::BANNER_REQUEST => array('onRequest', 0)
26
+ );
27
+ }
28
+
29
+ public function onRequest(BannerEvent $event)
30
+ {
31
+ $route = $this->routeProvider->banner_request;
32
+ $route->setParameters(array(
33
+ 'uuid' => $event->getUuid(),
34
+ 'email' => $event->getEmail()
35
+ ));
36
+ $version = $this->app['version'];
37
+
38
+ $response = $route->process(function ($request) use ($event, $version) {
39
+ $request->addHeader($event->getBasicHeader());
40
+ });
41
+
42
+ $event->setResponse($response);
43
+ }
44
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Subscriber/CustomerMigrationSubscriber.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Subscriber;
4
+
5
+ use Expressly\Event\CustomerMigrateEvent;
6
+ use Silex\Application;
7
+ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
8
+
9
+ class CustomerMigrationSubscriber implements EventSubscriberInterface
10
+ {
11
+ private $app;
12
+ private $routeProvider;
13
+
14
+ const CUSTOMER_MIGRATE_POPUP = 'customer.migrate.popup';
15
+ const CUSTOMER_MIGRATE_DATA = 'customer.migrate.data';
16
+ const CUSTOMER_MIGRATE_SUCCESS = 'customer.migrate.success';
17
+
18
+ public function __construct(Application $app)
19
+ {
20
+ $this->app = $app;
21
+ $this->routeProvider = $this->app['external_route.provider'];
22
+ }
23
+
24
+ public static function getSubscribedEvents()
25
+ {
26
+ return array(
27
+ self::CUSTOMER_MIGRATE_POPUP => array('getPopup', 0),
28
+ self::CUSTOMER_MIGRATE_DATA => array('getData', 0),
29
+ self::CUSTOMER_MIGRATE_SUCCESS => array('onSuccess', 0)
30
+ );
31
+ }
32
+
33
+ /*
34
+ * Initial request of migrate customer request flow
35
+ * Returns JSON structured HTML to display to the user; requires user action to continue
36
+ */
37
+ public function getPopup(CustomerMigrateEvent $event)
38
+ {
39
+ $route = $this->routeProvider->customer_migrate_popup;
40
+ $route->setParameters(array(
41
+ 'uuid' => $event->getUuid()
42
+ ));
43
+
44
+ $response = $route->process(function ($request) use ($event) {
45
+ $request->addHeader($event->getBasicHeader());
46
+ });
47
+
48
+ $event->setResponse($response);
49
+ }
50
+
51
+ /*
52
+ * Secondary request of migrate customer request flow
53
+ * If user agrees to conditions: request cart, and coupon information
54
+ */
55
+ public function getData(CustomerMigrateEvent $event)
56
+ {
57
+ $route = $this->routeProvider->customer_migrate_data;
58
+ $route->setParameters(array(
59
+ 'uuid' => $event->getUuid()
60
+ ));
61
+
62
+ $response = $route->process(function ($request) use ($event) {
63
+ $request->addHeader($event->getBasicHeader());
64
+ });
65
+
66
+ $event->setResponse($response);
67
+ }
68
+
69
+ /*
70
+ * Additional third request to notify the application that we've added the user successfully
71
+ */
72
+ public function onSuccess(CustomerMigrateEvent $event)
73
+ {
74
+ $route = $this->routeProvider->customer_migrate_success;
75
+ $route->setParameters(array(
76
+ 'uuid' => $event->getUuid()
77
+ ));
78
+
79
+ $response = $route->process(function ($request) use ($event) {
80
+ $request->addHeader($event->getBasicHeader());
81
+
82
+ $request->setContent(array(
83
+ 'status' => $event->getStatus()
84
+ ));
85
+ });
86
+
87
+ $event->setResponse($response);
88
+ }
89
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Subscriber/MerchantSubscriber.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Subscriber;
4
+
5
+ use Expressly\Event\MerchantEvent;
6
+ use Expressly\Event\PasswordedEvent;
7
+ use Silex\Application;
8
+ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
9
+
10
+ class MerchantSubscriber implements EventSubscriberInterface
11
+ {
12
+ private $app;
13
+ private $routeProvider;
14
+
15
+ const MERCHANT_REGISTER = 'merchant.register';
16
+ const MERCHANT_UPDATE = 'merchant.update';
17
+ const MERCHANT_DELETE = 'merchant.delete';
18
+
19
+ public function __construct(Application $app)
20
+ {
21
+ $this->app = $app;
22
+ $this->routeProvider = $app['external_route.provider'];
23
+ }
24
+
25
+ public static function getSubscribedEvents()
26
+ {
27
+ return array(
28
+ self::MERCHANT_REGISTER => array('onRegister', 0),
29
+ self::MERCHANT_UPDATE => array('onUpdate', 0),
30
+ self::MERCHANT_DELETE => array('onDelete', 0)
31
+ );
32
+ }
33
+
34
+ public function onRegister(MerchantEvent $event)
35
+ {
36
+ $route = $this->routeProvider->merchant_register;
37
+ $version = $this->app['version'];
38
+
39
+ $response = $route->process(function ($request) use ($event, $version) {
40
+ $merchant = $event->getMerchant();
41
+
42
+ $request->setContent(array(
43
+ 'shopName' => $merchant->getName(),
44
+ 'shopUrl' => $merchant->getHost(),
45
+ 'apiBaseUrl' => $merchant->getEndpoint(),
46
+ 'shopImageUrl' => $merchant->getImage(),
47
+ 'termsAndConditionsUrl' => $merchant->getTerms(),
48
+ 'policyUrl' => $merchant->getPolicy(),
49
+ 'pluginVersion' => $version
50
+ ));
51
+ });
52
+
53
+ $event->setResponse($response);
54
+ }
55
+
56
+ public function onUpdate(PasswordedEvent $event)
57
+ {
58
+ $version = $this->app['version'];
59
+ $route = $this->routeProvider->merchant_update;
60
+ $route->setParameters(array(
61
+ 'uuid' => $event->getUuid()
62
+ ));
63
+
64
+ $response = $route->process(function ($request) use ($event, $version) {
65
+ $merchant = $event->getMerchant();
66
+
67
+ $request->addHeader($event->getBasicHeader());
68
+ $request->setContent(array(
69
+ 'shopName' => $merchant->getName(),
70
+ 'shopUrl' => $merchant->getHost(),
71
+ 'apiBaseUrl' => $merchant->getEndpoint(),
72
+ 'shopImageUrl' => $merchant->getImage(),
73
+ 'termsAndConditionsUrl' => $merchant->getTerms(),
74
+ 'policyUrl' => $merchant->getPolicy(),
75
+ 'pluginVersion' => $version
76
+ ));
77
+ });
78
+
79
+ $event->setResponse($response);
80
+ }
81
+
82
+ public function onDelete(PasswordedEvent $event)
83
+ {
84
+ $route = $this->routeProvider->merchant_delete;
85
+ $route->setParameters(array(
86
+ 'uuid' => $event->getUuid()
87
+ ));
88
+
89
+ $response = $route->process(function ($request) use ($event) {
90
+ $request->addHeader($event->getBasicHeader());
91
+ });
92
+
93
+ $event->setResponse($response);
94
+ }
95
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Subscriber/UtilitySubscriber.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Subscriber;
4
+
5
+ use Expressly\Event\ResponseEvent;
6
+ use Silex\Application;
7
+ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
8
+
9
+ class UtilitySubscriber implements EventSubscriberInterface
10
+ {
11
+ private $app;
12
+ private $routeProvider;
13
+
14
+ const UTILITY_PING = 'utility.ping';
15
+
16
+ public function __construct(Application $app)
17
+ {
18
+ $this->app = $app;
19
+ $this->routeProvider = $app['external_route.provider'];
20
+ }
21
+
22
+ public static function getSubscribedEvents()
23
+ {
24
+ return array(
25
+ self::UTILITY_PING => array('onPing', 0)
26
+ );
27
+ }
28
+
29
+ public function onPing(ResponseEvent $event)
30
+ {
31
+ $route = $this->routeProvider->ping;
32
+
33
+ $response = $route->process();
34
+
35
+ $event->setResponse($response);
36
+ }
37
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Tests/Helper/BannerHelperTest.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Test\Helper;
4
+
5
+ use Expressly\Entity\Merchant;
6
+ use Expressly\Helper\BannerHelper;
7
+
8
+ class BannerHelperTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ public function setUp()
11
+ {
12
+ require_once __DIR__ . '/../../../vendor/autoload.php';
13
+ }
14
+
15
+ public function testFailedEvent()
16
+ {
17
+ $bannerEvent = $this->getMockBuilder('Expressly\Event\BannerEvent')
18
+ ->setConstructorArgs(array(new Merchant(), 'test@email.com'))
19
+ ->getMock();
20
+
21
+ $bannerEvent
22
+ ->method('getContent')
23
+ ->willReturn(array());
24
+
25
+ $this->assertEmpty(BannerHelper::toHtml($bannerEvent));
26
+ }
27
+
28
+ public function testMissingMigrationLinkEven()
29
+ {
30
+ $bannerEvent = $this->getMockBuilder('Expressly\Event\BannerEvent')
31
+ ->setConstructorArgs(array(new Merchant(), 'test@email.com'))
32
+ ->getMock();
33
+
34
+ $bannerEvent
35
+ ->method('getContent')
36
+ ->willReturn(array('bannerImageUrl' => 'http://buyexpressly.com/assets/img/expressly-logo-sm-gray.png'));
37
+
38
+ $this->assertEmpty(BannerHelper::toHtml($bannerEvent));
39
+ }
40
+
41
+ public function testMissingBannerImageUrlEvent()
42
+ {
43
+ $bannerEvent = $this->getMockBuilder('Expressly\Event\BannerEvent')
44
+ ->setConstructorArgs(array(new Merchant(), 'test@email.com'))
45
+ ->getMock();
46
+
47
+ $bannerEvent
48
+ ->method('getContent')
49
+ ->willReturn(array('migrationLink' => 'http://buyexpressly.com/expressly/api/50602095-c390-4a8f-bc88-728d725b1410'));
50
+
51
+ $this->assertEmpty(BannerHelper::toHtml($bannerEvent));
52
+ }
53
+
54
+ public function testSuccessfulEvent()
55
+ {
56
+ $imageUrl = 'http://buyexpressly.com/assets/img/expressly-logo-sm-gray.png';
57
+ $migrationUrl = 'http://buyexpressly.com/expressly/api/50602095-c390-4a8f-bc88-728d725b1410';
58
+
59
+ $bannerEvent = $this->getMockBuilder('Expressly\Event\BannerEvent')
60
+ ->setConstructorArgs(array(new Merchant(), 'test@email.com'))
61
+ ->getMock();
62
+
63
+ $bannerEvent
64
+ ->method('getContent')
65
+ ->willReturn(array(
66
+ 'bannerImageUrl' => $imageUrl,
67
+ 'migrationLink' => $migrationUrl
68
+ ));
69
+
70
+ $this->assertEquals(
71
+ BannerHelper::toHtml($bannerEvent),
72
+ sprintf(
73
+ '<div class="expressly-banner"><a href="%s"><img src="%s"/></a>',
74
+ $migrationUrl,
75
+ $imageUrl
76
+ )
77
+ );
78
+ }
79
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Tests/Subscriber/BannerSubscriberTest.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Test\Subscriber;
4
+
5
+ use Expressly\Client;
6
+ use Expressly\Entity\Merchant;
7
+ use Expressly\Provider\ExternalRouteProvider;
8
+ use Expressly\Subscriber\BannerSubscriber;
9
+
10
+ class BannerSubscriberTest extends \PHPUnit_Framework_TestCase
11
+ {
12
+ protected $app;
13
+
14
+ public function setUp()
15
+ {
16
+ require_once __DIR__ . '/../../../vendor/autoload.php';
17
+
18
+ $client = new Client('phpunit', array('debug' => true));
19
+ $app = $client->getApp();
20
+ $app['external_route.provider'] = new ExternalRouteProvider(
21
+ $app,
22
+ array(
23
+ 'default' => 'http://localhost:8080/api/v1'
24
+ ),
25
+ array(
26
+ 'banner_request' => array(
27
+ 'host' => 'default',
28
+ 'method' => 'GET',
29
+ 'uri' => '/banner/<uuid>?email=<email>'
30
+ )
31
+ )
32
+ );
33
+
34
+ $this->app = $app;
35
+ }
36
+
37
+ public function tearDown()
38
+ {
39
+ $this->app = null;
40
+ }
41
+
42
+ public function testSubscribedEvents()
43
+ {
44
+ $this->assertTrue(
45
+ array_key_exists(
46
+ BannerSubscriber::BANNER_REQUEST,
47
+ BannerSubscriber::getSubscribedEvents()
48
+ )
49
+ );
50
+ }
51
+
52
+ public function testRequest()
53
+ {
54
+ $merchant = new Merchant();
55
+ $merchant
56
+ ->setUuid('50602095-c390-4a8f-bc88-728d725b1410')
57
+ ->setPassword('password');
58
+
59
+ $subscriber = $this->getMockBuilder('Expressly\Subscriber\BannerSubscriber')
60
+ ->setConstructorArgs(array($this->app))
61
+ ->getMock();
62
+
63
+ $bannerEvent = $this->getMockBuilder('Expressly\Event\BannerEvent')
64
+ ->setConstructorArgs(array($merchant, 'test@email.com'))
65
+ ->getMock();
66
+
67
+ $bannerEvent
68
+ ->method('isSuccessful')
69
+ ->willReturn(true);
70
+ $bannerEvent
71
+ ->method('getContent')
72
+ ->willReturn(array(
73
+ 'bannerImageUrl' => '',
74
+ 'migrationLink' => ''
75
+ ));
76
+
77
+ $subscriber->onRequest($bannerEvent);
78
+
79
+ $this->assertTrue($bannerEvent->isSuccessful());
80
+ $this->assertArrayHasKey('bannerImageUrl', $bannerEvent->getContent());
81
+ $this->assertArrayHasKey('migrationLink', $bannerEvent->getContent());
82
+ }
83
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Validator/EmailValidator.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Validator;
4
+
5
+ class EmailValidator implements ValidatorInterface
6
+ {
7
+ private $message;
8
+
9
+ public function __construct($message)
10
+ {
11
+ $this->message = $message;
12
+ }
13
+
14
+ public function validate($data)
15
+ {
16
+ if (!is_string($data)) {
17
+ return false;
18
+ }
19
+
20
+ if (filter_var($data, FILTER_VALIDATE_EMAIL)) {
21
+ return true;
22
+ }
23
+
24
+ return false;
25
+ }
26
+
27
+ public function getMessage()
28
+ {
29
+ return $this->message;
30
+ }
31
+
32
+ public function getType()
33
+ {
34
+ return 'email';
35
+ }
36
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Validator/UuidValidator.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Validator;
4
+
5
+ class UuidValidator implements ValidatorInterface
6
+ {
7
+ private $message;
8
+
9
+ public function __construct($message)
10
+ {
11
+ $this->message = $message;
12
+ }
13
+
14
+ public function validate($data)
15
+ {
16
+ if (!is_string($data)) {
17
+ return false;
18
+ }
19
+
20
+ if (preg_match('/^([\w]{8}-([\w]{4}-){3}[\w]{12})$/', $data) != false) {
21
+ return true;
22
+ }
23
+
24
+ return false;
25
+ }
26
+
27
+ public function getMessage()
28
+ {
29
+ return $this->message;
30
+ }
31
+
32
+ public function getType()
33
+ {
34
+ return 'uuid_string';
35
+ }
36
+ }
app/code/community/Expressly/Expressly/vendor/expressly/php-common/src/Validator/ValidatorInterface.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Expressly\Validator;
4
+
5
+ interface ValidatorInterface
6
+ {
7
+ public function validate($data);
8
+
9
+ public function getMessage();
10
+
11
+ public function getType();
12
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/.gitignore ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ bin
2
+ composer.lock
3
+ composer.phar
4
+ phpunit.xml
5
+ vendor
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/.travis.yml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ language: php
2
+
3
+ php:
4
+ - 5.4
5
+ - 5.5
6
+
7
+ env: TEST_SERVER="http://127.0.0.1:8080/server.php" TEST_PROXY="127.0.0.1:3128" PHP_FCGI_CHILDREN=10 PHP_FCGI_MAX_REQUESTS=10
8
+
9
+ before_install:
10
+ - echo "" | sudo add-apt-repository ppa:nginx/stable > /dev/null 2>&1
11
+ - sudo apt-get -qq update
12
+ - sudo apt-get -qq install nginx squid
13
+ - sudo stop squid3
14
+ - curl --version
15
+
16
+ before_script:
17
+ - sudo cp ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf.default ~/.phpenv/versions/$(phpenv version-name)/etc/php-fpm.conf
18
+ - echo "cgi.fix_pathinfo = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
19
+ - ~/.phpenv/versions/$(phpenv version-name)/sbin/php-fpm
20
+ - sudo nginx -p test -c etc/nginx.conf
21
+ - sudo squid3 -f test/etc/squid.conf
22
+ - composer self-update
23
+ - composer install --dev
24
+
25
+ script: ./bin/phpunit
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2010-2011 Kris Wallsmith
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/README.md ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [![Build Status](https://secure.travis-ci.org/kriswallsmith/Buzz.png?branch=master)](http://travis-ci.org/kriswallsmith/Buzz)
2
+
3
+ Buzz is a lightweight PHP 5.3 library for issuing HTTP requests.
4
+
5
+ ```php
6
+ <?php
7
+
8
+ $browser = new Buzz\Browser();
9
+ $response = $browser->get('http://www.google.com');
10
+
11
+ echo $browser->getLastRequest()."\n";
12
+ echo $response;
13
+ ```
14
+
15
+ You can also use the low-level HTTP classes directly.
16
+
17
+ ```php
18
+ <?php
19
+
20
+ $request = new Buzz\Message\Request('HEAD', '/', 'http://google.com');
21
+ $response = new Buzz\Message\Response();
22
+
23
+ $client = new Buzz\Client\FileGetContents();
24
+ $client->send($request, $response);
25
+
26
+ echo $request;
27
+ echo $response;
28
+ ```
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/composer.json ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "kriswallsmith/buzz",
3
+ "description": "Lightweight HTTP client",
4
+ "keywords": ["http client", "curl"],
5
+ "homepage": "https://github.com/kriswallsmith/Buzz",
6
+ "type": "library",
7
+ "license": "MIT",
8
+ "authors": [
9
+ {
10
+ "name": "Kris Wallsmith",
11
+ "email": "kris.wallsmith@gmail.com",
12
+ "homepage": "http://kriswallsmith.net/"
13
+ }
14
+ ],
15
+ "require": {
16
+ "php": ">=5.3.0"
17
+ },
18
+ "require-dev": {
19
+ "phpunit/phpunit": "3.7.*"
20
+ },
21
+ "suggest": {
22
+ "ext-curl": "*"
23
+ },
24
+ "config": {
25
+ "bin-dir": "bin"
26
+ },
27
+ "autoload": {
28
+ "psr-0": {
29
+ "Buzz": "lib/"
30
+ }
31
+ }
32
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Browser.php ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz;
4
+
5
+ use Buzz\Client\ClientInterface;
6
+ use Buzz\Client\FileGetContents;
7
+ use Buzz\Listener\ListenerChain;
8
+ use Buzz\Listener\ListenerInterface;
9
+ use Buzz\Message\Factory\Factory;
10
+ use Buzz\Message\Factory\FactoryInterface;
11
+ use Buzz\Message\MessageInterface;
12
+ use Buzz\Message\RequestInterface;
13
+ use Buzz\Util\Url;
14
+
15
+ class Browser
16
+ {
17
+ private $client;
18
+ private $factory;
19
+ private $listener;
20
+ private $lastRequest;
21
+ private $lastResponse;
22
+
23
+ public function __construct(ClientInterface $client = null, FactoryInterface $factory = null)
24
+ {
25
+ $this->client = $client ?: new FileGetContents();
26
+ $this->factory = $factory ?: new Factory();
27
+ }
28
+
29
+ public function get($url, $headers = array())
30
+ {
31
+ return $this->call($url, RequestInterface::METHOD_GET, $headers);
32
+ }
33
+
34
+ public function post($url, $headers = array(), $content = '')
35
+ {
36
+ return $this->call($url, RequestInterface::METHOD_POST, $headers, $content);
37
+ }
38
+
39
+ public function head($url, $headers = array())
40
+ {
41
+ return $this->call($url, RequestInterface::METHOD_HEAD, $headers);
42
+ }
43
+
44
+ public function patch($url, $headers = array(), $content = '')
45
+ {
46
+ return $this->call($url, RequestInterface::METHOD_PATCH, $headers, $content);
47
+ }
48
+
49
+ public function put($url, $headers = array(), $content = '')
50
+ {
51
+ return $this->call($url, RequestInterface::METHOD_PUT, $headers, $content);
52
+ }
53
+
54
+ public function delete($url, $headers = array(), $content = '')
55
+ {
56
+ return $this->call($url, RequestInterface::METHOD_DELETE, $headers, $content);
57
+ }
58
+
59
+ /**
60
+ * Sends a request.
61
+ *
62
+ * @param string $url The URL to call
63
+ * @param string $method The request method to use
64
+ * @param array $headers An array of request headers
65
+ * @param string $content The request content
66
+ *
67
+ * @return MessageInterface The response object
68
+ */
69
+ public function call($url, $method, $headers = array(), $content = '')
70
+ {
71
+ $request = $this->factory->createRequest($method);
72
+
73
+ if (!$url instanceof Url) {
74
+ $url = new Url($url);
75
+ }
76
+
77
+ $url->applyToRequest($request);
78
+
79
+ $request->addHeaders($headers);
80
+ $request->setContent($content);
81
+
82
+ return $this->send($request);
83
+ }
84
+
85
+ /**
86
+ * Sends a form request.
87
+ *
88
+ * @param string $url The URL to submit to
89
+ * @param array $fields An array of fields
90
+ * @param string $method The request method to use
91
+ * @param array $headers An array of request headers
92
+ *
93
+ * @return MessageInterface The response object
94
+ */
95
+ public function submit($url, array $fields, $method = RequestInterface::METHOD_POST, $headers = array())
96
+ {
97
+ $request = $this->factory->createFormRequest();
98
+
99
+ if (!$url instanceof Url) {
100
+ $url = new Url($url);
101
+ }
102
+
103
+ $url->applyToRequest($request);
104
+
105
+ $request->addHeaders($headers);
106
+ $request->setMethod($method);
107
+ $request->setFields($fields);
108
+
109
+ return $this->send($request);
110
+ }
111
+
112
+ /**
113
+ * Sends a request.
114
+ *
115
+ * @param RequestInterface $request A request object
116
+ * @param MessageInterface $response A response object
117
+ *
118
+ * @return MessageInterface The response
119
+ */
120
+ public function send(RequestInterface $request, MessageInterface $response = null)
121
+ {
122
+ if (null === $response) {
123
+ $response = $this->factory->createResponse();
124
+ }
125
+
126
+ if ($this->listener) {
127
+ $this->listener->preSend($request);
128
+ }
129
+
130
+ $this->client->send($request, $response);
131
+
132
+ $this->lastRequest = $request;
133
+ $this->lastResponse = $response;
134
+
135
+ if ($this->listener) {
136
+ $this->listener->postSend($request, $response);
137
+ }
138
+
139
+ return $response;
140
+ }
141
+
142
+ public function getLastRequest()
143
+ {
144
+ return $this->lastRequest;
145
+ }
146
+
147
+ public function getLastResponse()
148
+ {
149
+ return $this->lastResponse;
150
+ }
151
+
152
+ public function setClient(ClientInterface $client)
153
+ {
154
+ $this->client = $client;
155
+ }
156
+
157
+ public function getClient()
158
+ {
159
+ return $this->client;
160
+ }
161
+
162
+ public function setMessageFactory(FactoryInterface $factory)
163
+ {
164
+ $this->factory = $factory;
165
+ }
166
+
167
+ public function getMessageFactory()
168
+ {
169
+ return $this->factory;
170
+ }
171
+
172
+ public function setListener(ListenerInterface $listener)
173
+ {
174
+ $this->listener = $listener;
175
+ }
176
+
177
+ public function getListener()
178
+ {
179
+ return $this->listener;
180
+ }
181
+
182
+ public function addListener(ListenerInterface $listener)
183
+ {
184
+ if (!$this->listener) {
185
+ $this->listener = $listener;
186
+ } elseif ($this->listener instanceof ListenerChain) {
187
+ $this->listener->addListener($listener);
188
+ } else {
189
+ $this->listener = new ListenerChain(array(
190
+ $this->listener,
191
+ $listener,
192
+ ));
193
+ }
194
+ }
195
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Client/AbstractClient.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Client;
4
+
5
+ abstract class AbstractClient implements ClientInterface
6
+ {
7
+ protected $ignoreErrors = true;
8
+ protected $maxRedirects = 5;
9
+ protected $timeout = 5;
10
+ protected $verifyPeer = true;
11
+ protected $proxy;
12
+
13
+ public function setIgnoreErrors($ignoreErrors)
14
+ {
15
+ $this->ignoreErrors = $ignoreErrors;
16
+ }
17
+
18
+ public function getIgnoreErrors()
19
+ {
20
+ return $this->ignoreErrors;
21
+ }
22
+
23
+ public function setMaxRedirects($maxRedirects)
24
+ {
25
+ $this->maxRedirects = $maxRedirects;
26
+ }
27
+
28
+ public function getMaxRedirects()
29
+ {
30
+ return $this->maxRedirects;
31
+ }
32
+
33
+ public function setTimeout($timeout)
34
+ {
35
+ $this->timeout = $timeout;
36
+ }
37
+
38
+ public function getTimeout()
39
+ {
40
+ return $this->timeout;
41
+ }
42
+
43
+ public function setVerifyPeer($verifyPeer)
44
+ {
45
+ $this->verifyPeer = $verifyPeer;
46
+ }
47
+
48
+ public function getVerifyPeer()
49
+ {
50
+ return $this->verifyPeer;
51
+ }
52
+
53
+ public function setProxy($proxy)
54
+ {
55
+ $this->proxy = $proxy;
56
+ }
57
+
58
+ public function getProxy()
59
+ {
60
+ return $this->proxy;
61
+ }
62
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Client/AbstractCurl.php ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Client;
4
+
5
+ use Buzz\Message\Form\FormRequestInterface;
6
+ use Buzz\Message\Form\FormUploadInterface;
7
+ use Buzz\Message\MessageInterface;
8
+ use Buzz\Message\RequestInterface;
9
+ use Buzz\Exception\ClientException;
10
+
11
+ /**
12
+ * Base client class with helpers for working with cURL.
13
+ */
14
+ abstract class AbstractCurl extends AbstractClient
15
+ {
16
+ protected $options = array();
17
+
18
+ public function __construct()
19
+ {
20
+ if (defined('CURLOPT_PROTOCOLS')) {
21
+ $this->options = array(
22
+ CURLOPT_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS,
23
+ CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS,
24
+ );
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Creates a new cURL resource.
30
+ *
31
+ * @see curl_init()
32
+ *
33
+ * @return resource A new cURL resource
34
+ *
35
+ * @throws ClientException If unable to create a cURL resource
36
+ */
37
+ protected static function createCurlHandle()
38
+ {
39
+ if (false === $curl = curl_init()) {
40
+ throw new ClientException('Unable to create a new cURL handle');
41
+ }
42
+
43
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
44
+ curl_setopt($curl, CURLOPT_HEADER, true);
45
+
46
+ return $curl;
47
+ }
48
+
49
+ /**
50
+ * Populates a response object.
51
+ *
52
+ * @param resource $curl A cURL resource
53
+ * @param string $raw The raw response string
54
+ * @param MessageInterface $response The response object
55
+ */
56
+ protected static function populateResponse($curl, $raw, MessageInterface $response)
57
+ {
58
+ // fixes bug https://sourceforge.net/p/curl/bugs/1204/
59
+ $version = curl_version();
60
+ if (version_compare($version['version'], '7.30.0', '<')) {
61
+ $pos = strlen($raw) - curl_getinfo($curl, CURLINFO_SIZE_DOWNLOAD);
62
+ } else {
63
+ $pos = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
64
+ }
65
+
66
+ $response->setHeaders(static::getLastHeaders(rtrim(substr($raw, 0, $pos))));
67
+ $response->setContent(strlen($raw) > $pos ? substr($raw, $pos) : '');
68
+ }
69
+
70
+ /**
71
+ * Sets options on a cURL resource based on a request.
72
+ */
73
+ private static function setOptionsFromRequest($curl, RequestInterface $request)
74
+ {
75
+ $options = array(
76
+ CURLOPT_HTTP_VERSION => $request->getProtocolVersion() == 1.0 ? CURL_HTTP_VERSION_1_0 : CURL_HTTP_VERSION_1_1,
77
+ CURLOPT_CUSTOMREQUEST => $request->getMethod(),
78
+ CURLOPT_URL => $request->getHost().$request->getResource(),
79
+ CURLOPT_HTTPHEADER => $request->getHeaders(),
80
+ );
81
+
82
+ switch ($request->getMethod()) {
83
+ case RequestInterface::METHOD_HEAD:
84
+ $options[CURLOPT_NOBODY] = true;
85
+ break;
86
+
87
+ case RequestInterface::METHOD_GET:
88
+ $options[CURLOPT_HTTPGET] = true;
89
+ break;
90
+
91
+ case RequestInterface::METHOD_POST:
92
+ case RequestInterface::METHOD_PUT:
93
+ case RequestInterface::METHOD_DELETE:
94
+ case RequestInterface::METHOD_PATCH:
95
+ case RequestInterface::METHOD_OPTIONS:
96
+ $options[CURLOPT_POSTFIELDS] = $fields = static::getPostFields($request);
97
+
98
+ // remove the content-type header
99
+ if (is_array($fields)) {
100
+ $options[CURLOPT_HTTPHEADER] = array_filter($options[CURLOPT_HTTPHEADER], function($header) {
101
+ return 0 !== stripos($header, 'Content-Type: ');
102
+ });
103
+ }
104
+
105
+ break;
106
+ }
107
+
108
+ curl_setopt_array($curl, $options);
109
+ }
110
+
111
+ /**
112
+ * Returns a value for the CURLOPT_POSTFIELDS option.
113
+ *
114
+ * @return string|array A post fields value
115
+ */
116
+ private static function getPostFields(RequestInterface $request)
117
+ {
118
+ if (!$request instanceof FormRequestInterface) {
119
+ return $request->getContent();
120
+ }
121
+
122
+ $fields = $request->getFields();
123
+ $multipart = false;
124
+
125
+ foreach ($fields as $name => $value) {
126
+ if (!$value instanceof FormUploadInterface) {
127
+ continue;
128
+ }
129
+
130
+ if (!$file = $value->getFile()) {
131
+ return $request->getContent();
132
+ }
133
+
134
+ $multipart = true;
135
+
136
+ if (version_compare(PHP_VERSION, '5.5', '>=')) {
137
+ $curlFile = new \CURLFile($file);
138
+ if ($contentType = $value->getContentType()) {
139
+ $curlFile->setMimeType($contentType);
140
+ }
141
+
142
+ if (basename($file) != $value->getFilename()) {
143
+ $curlFile->setPostFilename($value->getFilename());
144
+ }
145
+
146
+ $fields[$name] = $curlFile;
147
+ } else {
148
+ // replace value with upload string
149
+ $fields[$name] = '@'.$file;
150
+
151
+ if ($contentType = $value->getContentType()) {
152
+ $fields[$name] .= ';type='.$contentType;
153
+ }
154
+ if (basename($file) != $value->getFilename()) {
155
+ $fields[$name] .= ';filename='.$value->getFilename();
156
+ }
157
+ }
158
+ }
159
+
160
+ return $multipart ? $fields : http_build_query($fields, '', '&');
161
+ }
162
+
163
+ /**
164
+ * A helper for getting the last set of headers.
165
+ *
166
+ * @param string $raw A string of many header chunks
167
+ *
168
+ * @return array An array of header lines
169
+ */
170
+ private static function getLastHeaders($raw)
171
+ {
172
+ $headers = array();
173
+ foreach (preg_split('/(\\r?\\n)/', $raw) as $header) {
174
+ if ($header) {
175
+ $headers[] = $header;
176
+ } else {
177
+ $headers = array();
178
+ }
179
+ }
180
+
181
+ return $headers;
182
+ }
183
+
184
+ /**
185
+ * Stashes a cURL option to be set on send, when the resource is created.
186
+ *
187
+ * If the supplied value it set to null the option will be removed.
188
+ *
189
+ * @param integer $option The option
190
+ * @param mixed $value The value
191
+ *
192
+ * @see curl_setopt()
193
+ */
194
+ public function setOption($option, $value)
195
+ {
196
+ if (null === $value) {
197
+ unset($this->options[$option]);
198
+ } else {
199
+ $this->options[$option] = $value;
200
+ }
201
+ }
202
+
203
+ /**
204
+ * Prepares a cURL resource to send a request.
205
+ */
206
+ protected function prepare($curl, RequestInterface $request, array $options = array())
207
+ {
208
+ static::setOptionsFromRequest($curl, $request);
209
+
210
+ // apply settings from client
211
+ if ($this->getTimeout() < 1) {
212
+ curl_setopt($curl, CURLOPT_TIMEOUT_MS, $this->getTimeout() * 1000);
213
+ } else {
214
+ curl_setopt($curl, CURLOPT_TIMEOUT, $this->getTimeout());
215
+ }
216
+
217
+ if ($this->proxy) {
218
+ curl_setopt($curl, CURLOPT_PROXY, $this->proxy);
219
+ }
220
+
221
+ $canFollow = !ini_get('safe_mode') && !ini_get('open_basedir');
222
+
223
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, $canFollow && $this->getMaxRedirects() > 0);
224
+ curl_setopt($curl, CURLOPT_MAXREDIRS, $canFollow ? $this->getMaxRedirects() : 0);
225
+ curl_setopt($curl, CURLOPT_FAILONERROR, !$this->getIgnoreErrors());
226
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, $this->getVerifyPeer());
227
+
228
+ // apply additional options
229
+ curl_setopt_array($curl, $options + $this->options);
230
+ }
231
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Client/AbstractStream.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Client;
4
+
5
+ use Buzz\Message\RequestInterface;
6
+
7
+ abstract class AbstractStream extends AbstractClient
8
+ {
9
+ /**
10
+ * Converts a request into an array for stream_context_create().
11
+ *
12
+ * @param RequestInterface $request A request object
13
+ *
14
+ * @return array An array for stream_context_create()
15
+ */
16
+ public function getStreamContextArray(RequestInterface $request)
17
+ {
18
+ $options = array(
19
+ 'http' => array(
20
+ // values from the request
21
+ 'method' => $request->getMethod(),
22
+ 'header' => implode("\r\n", $request->getHeaders()),
23
+ 'content' => $request->getContent(),
24
+ 'protocol_version' => $request->getProtocolVersion(),
25
+
26
+ // values from the current client
27
+ 'ignore_errors' => $this->getIgnoreErrors(),
28
+ 'follow_location' => $this->getMaxRedirects() > 0,
29
+ 'max_redirects' => $this->getMaxRedirects() + 1,
30
+ 'timeout' => $this->getTimeout(),
31
+ ),
32
+ 'ssl' => array(
33
+ 'verify_peer' => $this->getVerifyPeer(),
34
+ ),
35
+ );
36
+
37
+ if ($this->proxy) {
38
+ $options['http']['proxy'] = $this->proxy;
39
+ $options['http']['request_fulluri'] = true;
40
+ }
41
+
42
+ return $options;
43
+ }
44
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Client/BatchClientInterface.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Client;
4
+
5
+ use Buzz\Exception\ClientException;
6
+
7
+ /**
8
+ * A client capable of running batches of requests.
9
+ *
10
+ * The Countable implementation should return the number of queued requests.
11
+ */
12
+ interface BatchClientInterface extends ClientInterface, \Countable
13
+ {
14
+ /**
15
+ * Processes all queued requests.
16
+ *
17
+ * @throws ClientException If something goes wrong
18
+ */
19
+ public function flush();
20
+
21
+ /**
22
+ * Processes zero or more queued requests.
23
+ *
24
+ * @throws ClientException If something goes wrong
25
+ */
26
+ public function proceed();
27
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Client/ClientInterface.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Client;
4
+
5
+ use Buzz\Exception\ClientException;
6
+ use Buzz\Message\MessageInterface;
7
+ use Buzz\Message\RequestInterface;
8
+
9
+ interface ClientInterface
10
+ {
11
+ /**
12
+ * Populates the supplied response with the response for the supplied request.
13
+ *
14
+ * @param RequestInterface $request A request object
15
+ * @param MessageInterface $response A response object
16
+ *
17
+ * @throws ClientException If something goes wrong
18
+ */
19
+ public function send(RequestInterface $request, MessageInterface $response);
20
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Client/Curl.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Client;
4
+
5
+ use Buzz\Exception\RequestException;
6
+ use Buzz\Message\MessageInterface;
7
+ use Buzz\Message\RequestInterface;
8
+ use Buzz\Exception\LogicException;
9
+
10
+ class Curl extends AbstractCurl
11
+ {
12
+ private $lastCurl;
13
+
14
+ public function send(RequestInterface $request, MessageInterface $response, array $options = array())
15
+ {
16
+ if (is_resource($this->lastCurl)) {
17
+ curl_close($this->lastCurl);
18
+ }
19
+
20
+ $this->lastCurl = static::createCurlHandle();
21
+ $this->prepare($this->lastCurl, $request, $options);
22
+
23
+ $data = curl_exec($this->lastCurl);
24
+
25
+ if (false === $data) {
26
+ $errorMsg = curl_error($this->lastCurl);
27
+ $errorNo = curl_errno($this->lastCurl);
28
+
29
+ $e = new RequestException($errorMsg, $errorNo);
30
+ $e->setRequest($request);
31
+
32
+ throw $e;
33
+ }
34
+
35
+ static::populateResponse($this->lastCurl, $data, $response);
36
+ }
37
+
38
+ /**
39
+ * Introspects the last cURL request.
40
+ *
41
+ * @see curl_getinfo()
42
+ *
43
+ * @throws LogicException If there is no cURL resource
44
+ */
45
+ public function getInfo($opt = 0)
46
+ {
47
+ if (!is_resource($this->lastCurl)) {
48
+ throw new LogicException('There is no cURL resource');
49
+ }
50
+
51
+ return curl_getinfo($this->lastCurl, $opt);
52
+ }
53
+
54
+ public function __destruct()
55
+ {
56
+ if (is_resource($this->lastCurl)) {
57
+ curl_close($this->lastCurl);
58
+ }
59
+ }
60
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Client/FileGetContents.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Client;
4
+
5
+ use Buzz\Exception\RequestException;
6
+ use Buzz\Message\MessageInterface;
7
+ use Buzz\Message\RequestInterface;
8
+ use Buzz\Util\CookieJar;
9
+ use Buzz\Exception\ClientException;
10
+
11
+ class FileGetContents extends AbstractStream
12
+ {
13
+ /**
14
+ * @var CookieJar
15
+ */
16
+ protected $cookieJar;
17
+
18
+ /**
19
+ * @param CookieJar|null $cookieJar
20
+ */
21
+ public function __construct(CookieJar $cookieJar = null)
22
+ {
23
+ if ($cookieJar) {
24
+ $this->setCookieJar($cookieJar);
25
+ }
26
+ }
27
+
28
+ /**
29
+ * @param CookieJar $cookieJar
30
+ */
31
+ public function setCookieJar(CookieJar $cookieJar)
32
+ {
33
+ $this->cookieJar = $cookieJar;
34
+ }
35
+
36
+ /**
37
+ * @return CookieJar
38
+ */
39
+ public function getCookieJar()
40
+ {
41
+ return $this->cookieJar;
42
+ }
43
+
44
+ /**
45
+ * @see ClientInterface
46
+ *
47
+ * @throws ClientException If file_get_contents() fires an error
48
+ */
49
+ public function send(RequestInterface $request, MessageInterface $response)
50
+ {
51
+ if ($cookieJar = $this->getCookieJar()) {
52
+ $cookieJar->clearExpiredCookies();
53
+ $cookieJar->addCookieHeaders($request);
54
+ }
55
+
56
+ $context = stream_context_create($this->getStreamContextArray($request));
57
+ $url = $request->getHost().$request->getResource();
58
+
59
+ $level = error_reporting(0);
60
+ $content = file_get_contents($url, 0, $context);
61
+ error_reporting($level);
62
+ if (false === $content) {
63
+ $error = error_get_last();
64
+ $e = new RequestException($error['message']);
65
+ $e->setRequest($request);
66
+
67
+ throw $e;
68
+ }
69
+
70
+ $response->setHeaders($this->filterHeaders((array) $http_response_header));
71
+ $response->setContent($content);
72
+
73
+ if ($cookieJar) {
74
+ $cookieJar->processSetCookieHeaders($request, $response);
75
+ }
76
+ }
77
+
78
+ private function filterHeaders(array $headers)
79
+ {
80
+ $filtered = array();
81
+ foreach ($headers as $header) {
82
+ if (0 === stripos($header, 'http/')) {
83
+ $filtered = array();
84
+ }
85
+
86
+ $filtered[] = $header;
87
+ }
88
+
89
+ return $filtered;
90
+ }
91
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Client/MultiCurl.php ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Client;
4
+
5
+ use Buzz\Message\MessageInterface;
6
+ use Buzz\Message\RequestInterface;
7
+ use Buzz\Exception\ClientException;
8
+
9
+ class MultiCurl extends AbstractCurl implements BatchClientInterface
10
+ {
11
+ private $queue = array();
12
+ private $curlm;
13
+
14
+ /**
15
+ * Populates the supplied response with the response for the supplied request.
16
+ *
17
+ * The array of options will be passed to curl_setopt_array().
18
+ *
19
+ * If a "callback" option is supplied, its value will be called when the
20
+ * request completes. The callable should have the following signature:
21
+ *
22
+ * $callback = function($client, $request, $response, $options, $error) {
23
+ * if (!$error) {
24
+ * // success
25
+ * } else {
26
+ * // error ($error is one of the CURLE_* constants)
27
+ * }
28
+ * };
29
+ *
30
+ * @param RequestInterface $request A request object
31
+ * @param MessageInterface $response A response object
32
+ * @param array $options An array of options
33
+ */
34
+ public function send(RequestInterface $request, MessageInterface $response, array $options = array())
35
+ {
36
+ $this->queue[] = array($request, $response, $options);
37
+ }
38
+
39
+ public function count()
40
+ {
41
+ return count($this->queue);
42
+ }
43
+
44
+ public function flush()
45
+ {
46
+ while ($this->queue) {
47
+ $this->proceed();
48
+ }
49
+ }
50
+
51
+ public function proceed()
52
+ {
53
+ if (!$this->queue) {
54
+ return;
55
+ }
56
+
57
+ if (!$this->curlm && false === $this->curlm = curl_multi_init()) {
58
+ throw new ClientException('Unable to create a new cURL multi handle');
59
+ }
60
+
61
+ foreach (array_keys($this->queue) as $i) {
62
+ if (3 == count($this->queue[$i])) {
63
+ // prepare curl handle
64
+ list($request, , $options) = $this->queue[$i];
65
+ $curl = static::createCurlHandle();
66
+
67
+ // remove custom option
68
+ unset($options['callback']);
69
+
70
+ $this->prepare($curl, $request, $options);
71
+ $this->queue[$i][] = $curl;
72
+ curl_multi_add_handle($this->curlm, $curl);
73
+ }
74
+ }
75
+
76
+ // process outstanding perform
77
+ $active = null;
78
+ do {
79
+ $mrc = curl_multi_exec($this->curlm, $active);
80
+ } while ($active && CURLM_CALL_MULTI_PERFORM == $mrc);
81
+
82
+ // handle any completed requests
83
+ while ($done = curl_multi_info_read($this->curlm)) {
84
+ foreach (array_keys($this->queue) as $i) {
85
+ list($request, $response, $options, $curl) = $this->queue[$i];
86
+
87
+ if ($curl !== $done['handle']) {
88
+ continue;
89
+ }
90
+
91
+ // populate the response object
92
+ if (CURLE_OK === $done['result']) {
93
+ static::populateResponse($curl, curl_multi_getcontent($curl), $response);
94
+ }
95
+
96
+ // remove from queue
97
+ curl_multi_remove_handle($this->curlm, $curl);
98
+ curl_close($curl);
99
+ unset($this->queue[$i]);
100
+
101
+ // callback
102
+ if (isset($options['callback'])) {
103
+ call_user_func($options['callback'], $this, $request, $response, $options, $done['result']);
104
+ }
105
+ }
106
+ }
107
+
108
+ // cleanup
109
+ if (!$this->queue) {
110
+ curl_multi_close($this->curlm);
111
+ $this->curlm = null;
112
+ }
113
+ }
114
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Exception/ClientException.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Exception;
4
+
5
+ /**
6
+ * Thrown whenever a client process fails.
7
+ */
8
+ class ClientException extends RuntimeException
9
+ {
10
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Exception/ExceptionInterface.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Exception;
4
+
5
+ /**
6
+ * Marker interface to denote exceptions thrown from the Buzz context.
7
+ */
8
+ interface ExceptionInterface
9
+ {
10
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Exception/InvalidArgumentException.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Exception;
4
+
5
+ /**
6
+ * Thrown when an invalid argument is provided.
7
+ */
8
+ class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
9
+ {
10
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Exception/LogicException.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Exception;
4
+
5
+ /**
6
+ * Thrown whenever a required call-flow is not respected.
7
+ */
8
+ class LogicException extends \LogicException implements ExceptionInterface
9
+ {
10
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Exception/RequestException.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Exception;
4
+
5
+ use Buzz\Message\RequestInterface;
6
+
7
+ class RequestException extends ClientException
8
+ {
9
+ /**
10
+ * Request object
11
+ *
12
+ * @var RequestInterface
13
+ */
14
+ private $request;
15
+
16
+ /**
17
+ * @return RequestInterface
18
+ */
19
+ public function getRequest()
20
+ {
21
+ return $this->request;
22
+ }
23
+
24
+ /**
25
+ * @param RequestInterface $request
26
+ */
27
+ public function setRequest(RequestInterface $request)
28
+ {
29
+ $this->request = $request;
30
+ }
31
+
32
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Exception/RuntimeException.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Exception;
4
+
5
+ class RuntimeException extends \RuntimeException implements ExceptionInterface
6
+ {
7
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Listener/BasicAuthListener.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Listener;
4
+
5
+ use Buzz\Message\MessageInterface;
6
+ use Buzz\Message\RequestInterface;
7
+
8
+ class BasicAuthListener implements ListenerInterface
9
+ {
10
+ private $username;
11
+ private $password;
12
+
13
+ public function __construct($username, $password)
14
+ {
15
+ $this->username = $username;
16
+ $this->password = $password;
17
+ }
18
+
19
+ public function preSend(RequestInterface $request)
20
+ {
21
+ $request->addHeader('Authorization: Basic '.base64_encode($this->username.':'.$this->password));
22
+ }
23
+
24
+ public function postSend(RequestInterface $request, MessageInterface $response)
25
+ {
26
+ }
27
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Listener/CallbackListener.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Listener;
4
+
5
+ use Buzz\Message\MessageInterface;
6
+ use Buzz\Message\RequestInterface;
7
+ use Buzz\Exception\InvalidArgumentException;
8
+
9
+ class CallbackListener implements ListenerInterface
10
+ {
11
+ private $callable;
12
+
13
+ /**
14
+ * Constructor.
15
+ *
16
+ * The callback should expect either one or two arguments, depending on
17
+ * whether it is receiving a pre or post send notification.
18
+ *
19
+ * $listener = new CallbackListener(function($request, $response = null) {
20
+ * if ($response) {
21
+ * // postSend
22
+ * } else {
23
+ * // preSend
24
+ * }
25
+ * });
26
+ *
27
+ * @param mixed $callable A PHP callable
28
+ *
29
+ * @throws InvalidArgumentException If the argument is not callable
30
+ */
31
+ public function __construct($callable)
32
+ {
33
+ if (!is_callable($callable)) {
34
+ throw new InvalidArgumentException('The argument is not callable.');
35
+ }
36
+
37
+ $this->callable = $callable;
38
+ }
39
+
40
+ public function preSend(RequestInterface $request)
41
+ {
42
+ call_user_func($this->callable, $request);
43
+ }
44
+
45
+ public function postSend(RequestInterface $request, MessageInterface $response)
46
+ {
47
+ call_user_func($this->callable, $request, $response);
48
+ }
49
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Listener/History/Entry.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Listener\History;
4
+
5
+ use Buzz\Message\MessageInterface;
6
+ use Buzz\Message\RequestInterface;
7
+
8
+ class Entry
9
+ {
10
+ private $request;
11
+ private $response;
12
+ private $duration;
13
+
14
+ /**
15
+ * Constructor.
16
+ *
17
+ * @param RequestInterface $request The request
18
+ * @param MessageInterface $response The response
19
+ * @param integer $duration The duration in seconds
20
+ */
21
+ public function __construct(RequestInterface $request, MessageInterface $response, $duration = null)
22
+ {
23
+ $this->request = $request;
24
+ $this->response = $response;
25
+ $this->duration = $duration;
26
+ }
27
+
28
+ public function getRequest()
29
+ {
30
+ return $this->request;
31
+ }
32
+
33
+ public function getResponse()
34
+ {
35
+ return $this->response;
36
+ }
37
+
38
+ public function getDuration()
39
+ {
40
+ return $this->duration;
41
+ }
42
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Listener/History/Journal.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Listener\History;
4
+
5
+ use Buzz\Message\MessageInterface;
6
+ use Buzz\Message\RequestInterface;
7
+
8
+ class Journal implements \Countable, \IteratorAggregate
9
+ {
10
+ private $entries = array();
11
+ private $limit = 10;
12
+
13
+ /**
14
+ * Records an entry in the journal.
15
+ *
16
+ * @param RequestInterface $request The request
17
+ * @param MessageInterface $response The response
18
+ * @param integer $duration The duration in seconds
19
+ */
20
+ public function record(RequestInterface $request, MessageInterface $response, $duration = null)
21
+ {
22
+ $this->addEntry(new Entry($request, $response, $duration));
23
+ }
24
+
25
+ public function addEntry(Entry $entry)
26
+ {
27
+ array_push($this->entries, $entry);
28
+ $this->entries = array_slice($this->entries, $this->getLimit() * -1);
29
+ end($this->entries);
30
+ }
31
+
32
+ public function getEntries()
33
+ {
34
+ return $this->entries;
35
+ }
36
+
37
+ public function getLast()
38
+ {
39
+ return end($this->entries);
40
+ }
41
+
42
+ public function getLastRequest()
43
+ {
44
+ return $this->getLast()->getRequest();
45
+ }
46
+
47
+ public function getLastResponse()
48
+ {
49
+ return $this->getLast()->getResponse();
50
+ }
51
+
52
+ public function clear()
53
+ {
54
+ $this->entries = array();
55
+ }
56
+
57
+ public function count()
58
+ {
59
+ return count($this->entries);
60
+ }
61
+
62
+ public function setLimit($limit)
63
+ {
64
+ $this->limit = $limit;
65
+ }
66
+
67
+ public function getLimit()
68
+ {
69
+ return $this->limit;
70
+ }
71
+
72
+ public function getIterator()
73
+ {
74
+ return new \ArrayIterator(array_reverse($this->entries));
75
+ }
76
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Listener/HistoryListener.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Listener;
4
+
5
+ use Buzz\Listener\History\Journal;
6
+ use Buzz\Message\MessageInterface;
7
+ use Buzz\Message\RequestInterface;
8
+
9
+ class HistoryListener implements ListenerInterface
10
+ {
11
+ private $journal;
12
+ private $startTime;
13
+
14
+ public function __construct(Journal $journal)
15
+ {
16
+ $this->journal = $journal;
17
+ }
18
+
19
+ public function getJournal()
20
+ {
21
+ return $this->journal;
22
+ }
23
+
24
+ public function preSend(RequestInterface $request)
25
+ {
26
+ $this->startTime = microtime(true);
27
+ }
28
+
29
+ public function postSend(RequestInterface $request, MessageInterface $response)
30
+ {
31
+ $this->journal->record($request, $response, microtime(true) - $this->startTime);
32
+ }
33
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Listener/ListenerChain.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Listener;
4
+
5
+ use Buzz\Message\MessageInterface;
6
+ use Buzz\Message\RequestInterface;
7
+
8
+ class ListenerChain implements ListenerInterface
9
+ {
10
+ private $listeners;
11
+
12
+ public function __construct(array $listeners = array())
13
+ {
14
+ $this->listeners = $listeners;
15
+ }
16
+
17
+ public function addListener(ListenerInterface $listener)
18
+ {
19
+ $this->listeners[] = $listener;
20
+ }
21
+
22
+ public function getListeners()
23
+ {
24
+ return $this->listeners;
25
+ }
26
+
27
+ public function preSend(RequestInterface $request)
28
+ {
29
+ foreach ($this->listeners as $listener) {
30
+ $listener->preSend($request);
31
+ }
32
+ }
33
+
34
+ public function postSend(RequestInterface $request, MessageInterface $response)
35
+ {
36
+ foreach ($this->listeners as $listener) {
37
+ $listener->postSend($request, $response);
38
+ }
39
+ }
40
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Listener/ListenerInterface.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Listener;
4
+
5
+ use Buzz\Message\MessageInterface;
6
+ use Buzz\Message\RequestInterface;
7
+
8
+ interface ListenerInterface
9
+ {
10
+ public function preSend(RequestInterface $request);
11
+ public function postSend(RequestInterface $request, MessageInterface $response);
12
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Listener/LoggerListener.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Listener;
4
+
5
+ use Buzz\Message\MessageInterface;
6
+ use Buzz\Message\RequestInterface;
7
+ use Buzz\Exception\InvalidArgumentException;
8
+
9
+ class LoggerListener implements ListenerInterface
10
+ {
11
+ private $logger;
12
+ private $prefix;
13
+ private $startTime;
14
+
15
+ public function __construct($logger, $prefix = null)
16
+ {
17
+ if (!is_callable($logger)) {
18
+ throw new InvalidArgumentException('The logger must be a callable.');
19
+ }
20
+
21
+ $this->logger = $logger;
22
+ $this->prefix = $prefix;
23
+ }
24
+
25
+ public function preSend(RequestInterface $request)
26
+ {
27
+ $this->startTime = microtime(true);
28
+ }
29
+
30
+ public function postSend(RequestInterface $request, MessageInterface $response)
31
+ {
32
+ $seconds = microtime(true) - $this->startTime;
33
+
34
+ call_user_func($this->logger, sprintf('%sSent "%s %s%s" in %dms', $this->prefix, $request->getMethod(), $request->getHost(), $request->getResource(), round($seconds * 1000)));
35
+ }
36
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/AbstractMessage.php ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Message;
4
+
5
+ abstract class AbstractMessage implements MessageInterface
6
+ {
7
+ private $headers = array();
8
+ private $content;
9
+
10
+ /**
11
+ * Returns the value of a header.
12
+ *
13
+ * @param string $name
14
+ * @param string|boolean $glue Glue for implode, or false to return an array
15
+ *
16
+ * @return string|array|null
17
+ */
18
+ public function getHeader($name, $glue = "\r\n")
19
+ {
20
+ $needle = $name.':';
21
+
22
+ $values = array();
23
+ foreach ($this->getHeaders() as $header) {
24
+ if (0 === stripos($header, $needle)) {
25
+ $values[] = trim(substr($header, strlen($needle)));
26
+ }
27
+ }
28
+
29
+ if (false === $glue) {
30
+ return $values;
31
+ } else {
32
+ return count($values) ? implode($glue, $values) : null;
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Returns a header's attributes.
38
+ *
39
+ * @param string $name A header name
40
+ *
41
+ * @return array An associative array of attributes
42
+ */
43
+ public function getHeaderAttributes($name)
44
+ {
45
+ $attributes = array();
46
+ foreach ($this->getHeader($name, false) as $header) {
47
+ if (false !== strpos($header, ';')) {
48
+ // remove header value
49
+ list(, $header) = explode(';', $header, 2);
50
+
51
+ // loop through attribute key=value pairs
52
+ foreach (array_map('trim', explode(';', trim($header))) as $pair) {
53
+ list($key, $value) = explode('=', $pair);
54
+ $attributes[$key] = $value;
55
+ }
56
+ }
57
+ }
58
+
59
+ return $attributes;
60
+ }
61
+
62
+ /**
63
+ * Returns the value of a particular header attribute.
64
+ *
65
+ * @param string $header A header name
66
+ * @param string $attribute An attribute name
67
+ *
68
+ * @return string|null The value of the attribute or null if it isn't set
69
+ */
70
+ public function getHeaderAttribute($header, $attribute)
71
+ {
72
+ $attributes = $this->getHeaderAttributes($header);
73
+
74
+ if (isset($attributes[$attribute])) {
75
+ return $attributes[$attribute];
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Returns the current message as a DOMDocument.
81
+ *
82
+ * @return \DOMDocument
83
+ */
84
+ public function toDomDocument()
85
+ {
86
+ $revert = libxml_use_internal_errors(true);
87
+
88
+ $document = new \DOMDocument('1.0', $this->getHeaderAttribute('Content-Type', 'charset') ?: 'UTF-8');
89
+ if (0 === strpos($this->getHeader('Content-Type'), 'text/xml')) {
90
+ $document->loadXML($this->getContent());
91
+ } else {
92
+ $document->loadHTML($this->getContent());
93
+ }
94
+
95
+ libxml_use_internal_errors($revert);
96
+
97
+ return $document;
98
+ }
99
+
100
+ public function setHeaders(array $headers)
101
+ {
102
+ $this->headers = $this->flattenHeaders($headers);
103
+ }
104
+
105
+ public function addHeader($header)
106
+ {
107
+ $this->headers[] = $header;
108
+ }
109
+
110
+ public function addHeaders(array $headers)
111
+ {
112
+ $this->headers = array_merge($this->headers, $this->flattenHeaders($headers));
113
+ }
114
+
115
+ public function getHeaders()
116
+ {
117
+ return $this->headers;
118
+ }
119
+
120
+ public function setContent($content)
121
+ {
122
+ $this->content = $content;
123
+ }
124
+
125
+ public function getContent()
126
+ {
127
+ return $this->content;
128
+ }
129
+
130
+ public function __toString()
131
+ {
132
+ $string = implode("\r\n", $this->getHeaders())."\r\n";
133
+
134
+ if ($content = $this->getContent()) {
135
+ $string .= "\r\n$content\r\n";
136
+ }
137
+
138
+ return $string;
139
+ }
140
+
141
+ protected function flattenHeaders(array $headers)
142
+ {
143
+ $flattened = array();
144
+ foreach ($headers as $key => $header) {
145
+ if (is_int($key)) {
146
+ $flattened[] = $header;
147
+ } else {
148
+ $flattened[] = $key.': '.$header;
149
+ }
150
+ }
151
+
152
+ return $flattened;
153
+ }
154
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/Factory/Factory.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Message\Factory;
4
+
5
+ use Buzz\Message\Form\FormRequest;
6
+ use Buzz\Message\Request;
7
+ use Buzz\Message\RequestInterface;
8
+ use Buzz\Message\Response;
9
+
10
+ class Factory implements FactoryInterface
11
+ {
12
+ public function createRequest($method = RequestInterface::METHOD_GET, $resource = '/', $host = null)
13
+ {
14
+ return new Request($method, $resource, $host);
15
+ }
16
+
17
+ public function createFormRequest($method = RequestInterface::METHOD_POST, $resource = '/', $host = null)
18
+ {
19
+ return new FormRequest($method, $resource, $host);
20
+ }
21
+
22
+ public function createResponse()
23
+ {
24
+ return new Response();
25
+ }
26
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/Factory/FactoryInterface.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Message\Factory;
4
+
5
+ use Buzz\Message\RequestInterface;
6
+
7
+ interface FactoryInterface
8
+ {
9
+ public function createRequest($method = RequestInterface::METHOD_GET, $resource = '/', $host = null);
10
+ public function createFormRequest($method = RequestInterface::METHOD_POST, $resource = '/', $host = null);
11
+ public function createResponse();
12
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/Form/FormRequest.php ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Message\Form;
4
+
5
+ use Buzz\Message\Request;
6
+ use Buzz\Exception\LogicException;
7
+
8
+ /**
9
+ * FormRequest.
10
+ *
11
+ * $request = new FormRequest();
12
+ * $request->setField('user[name]', 'Kris Wallsmith');
13
+ * $request->setField('user[image]', new FormUpload('/path/to/image.jpg'));
14
+ *
15
+ * @author Marc Weistroff <marc.weistroff@sensio.com>
16
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
17
+ */
18
+ class FormRequest extends Request implements FormRequestInterface
19
+ {
20
+ private $fields = array();
21
+ private $boundary;
22
+
23
+ /**
24
+ * Constructor.
25
+ *
26
+ * Defaults to POST rather than GET.
27
+ */
28
+ public function __construct($method = self::METHOD_POST, $resource = '/', $host = null)
29
+ {
30
+ parent::__construct($method, $resource, $host);
31
+ }
32
+
33
+ /**
34
+ * Sets the value of a form field.
35
+ *
36
+ * If the value is an array it will be flattened and one field value will
37
+ * be added for each leaf.
38
+ */
39
+ public function setField($name, $value)
40
+ {
41
+ if (is_array($value)) {
42
+ $this->addFields(array($name => $value));
43
+
44
+ return;
45
+ }
46
+
47
+ if ('[]' == substr($name, -2)) {
48
+ $this->fields[substr($name, 0, -2)][] = $value;
49
+ } else {
50
+ $this->fields[$name] = $value;
51
+ }
52
+ }
53
+
54
+ public function addFields(array $fields)
55
+ {
56
+ foreach ($this->flattenArray($fields) as $name => $value) {
57
+ $this->setField($name, $value);
58
+ }
59
+ }
60
+
61
+ public function setFields(array $fields)
62
+ {
63
+ $this->fields = array();
64
+ $this->addFields($fields);
65
+ }
66
+
67
+ public function getFields()
68
+ {
69
+ return $this->fields;
70
+ }
71
+
72
+ public function getResource()
73
+ {
74
+ $resource = parent::getResource();
75
+
76
+ if (!$this->isSafe() || !$this->fields) {
77
+ return $resource;
78
+ }
79
+
80
+ // append the query string
81
+ $resource .= false === strpos($resource, '?') ? '?' : '&';
82
+ $resource .= http_build_query($this->fields);
83
+
84
+ return $resource;
85
+ }
86
+
87
+ public function setContent($content)
88
+ {
89
+ throw new \BadMethodCallException('It is not permitted to set the content.');
90
+ }
91
+
92
+ public function getHeaders()
93
+ {
94
+ $headers = parent::getHeaders();
95
+
96
+ if ($this->isSafe()) {
97
+ return $headers;
98
+ }
99
+
100
+ if ($this->isMultipart()) {
101
+ $headers[] = 'Content-Type: multipart/form-data; boundary='.$this->getBoundary();
102
+ } else {
103
+ $headers[] = 'Content-Type: application/x-www-form-urlencoded';
104
+ }
105
+
106
+ return $headers;
107
+ }
108
+
109
+ public function getContent()
110
+ {
111
+ if ($this->isSafe()) {
112
+ return;
113
+ }
114
+
115
+ if (!$this->isMultipart()) {
116
+ return http_build_query($this->fields);
117
+ }
118
+
119
+ $content = '';
120
+
121
+ foreach ($this->fields as $name => $values) {
122
+ $content .= '--'.$this->getBoundary()."\r\n";
123
+ if ($values instanceof FormUploadInterface) {
124
+ if (!$values->getFilename()) {
125
+ throw new LogicException(sprintf('Form upload at "%s" does not include a filename.', $name));
126
+ }
127
+
128
+ $values->setName($name);
129
+ $content .= (string) $values;
130
+ } else {
131
+ foreach (is_array($values) ? $values : array($values) as $value) {
132
+ $content .= "Content-Disposition: form-data; name=\"$name\"\r\n";
133
+ $content .= "\r\n";
134
+ $content .= $value."\r\n";
135
+ }
136
+ }
137
+ }
138
+
139
+ $content .= '--'.$this->getBoundary().'--';
140
+
141
+ return $content;
142
+ }
143
+
144
+ // private
145
+
146
+ private function flattenArray(array $values, $prefix = '', $format = '%s')
147
+ {
148
+ $flat = array();
149
+
150
+ foreach ($values as $name => $value) {
151
+ $flatName = $prefix.sprintf($format, $name);
152
+
153
+ if (is_array($value)) {
154
+ $flat += $this->flattenArray($value, $flatName, '[%s]');
155
+ } else {
156
+ $flat[$flatName] = $value;
157
+ }
158
+ }
159
+
160
+ return $flat;
161
+ }
162
+
163
+ private function isSafe()
164
+ {
165
+ return in_array($this->getMethod(), array(self::METHOD_GET, self::METHOD_HEAD));
166
+ }
167
+
168
+ private function isMultipart()
169
+ {
170
+ foreach ($this->fields as $name => $value) {
171
+ if (is_object($value) && $value instanceof FormUploadInterface) {
172
+ return true;
173
+ }
174
+ }
175
+
176
+ return false;
177
+ }
178
+
179
+ private function getBoundary()
180
+ {
181
+ if (!$this->boundary) {
182
+ $this->boundary = sha1(rand(11111, 99999).time().uniqid());
183
+ }
184
+
185
+ return $this->boundary;
186
+ }
187
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/Form/FormRequestInterface.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Message\Form;
4
+
5
+ use Buzz\Message\RequestInterface;
6
+
7
+ /**
8
+ * An HTTP request message sent by a web form.
9
+ *
10
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
11
+ */
12
+ interface FormRequestInterface extends RequestInterface
13
+ {
14
+ /**
15
+ * Returns an array of field names and values.
16
+ *
17
+ * @return array A array of names and values
18
+ */
19
+ public function getFields();
20
+
21
+ /**
22
+ * Sets the form fields for the current request.
23
+ *
24
+ * @param array $fields An array of field names and values
25
+ */
26
+ public function setFields(array $fields);
27
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/Form/FormUpload.php ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Message\Form;
4
+
5
+ use Buzz\Message\AbstractMessage;
6
+
7
+ class FormUpload extends AbstractMessage implements FormUploadInterface
8
+ {
9
+ private $name;
10
+ private $filename;
11
+ private $contentType;
12
+ private $file;
13
+
14
+ public function __construct($file = null, $contentType = null)
15
+ {
16
+ if ($file) {
17
+ $this->loadContent($file);
18
+ }
19
+
20
+ $this->contentType = $contentType;
21
+ }
22
+
23
+ public function getName()
24
+ {
25
+ return $this->name;
26
+ }
27
+
28
+ public function setName($name)
29
+ {
30
+ $this->name = $name;
31
+ }
32
+
33
+ public function getFilename()
34
+ {
35
+ if ($this->filename) {
36
+ return $this->filename;
37
+ } elseif ($this->file) {
38
+ return basename($this->file);
39
+ }
40
+ }
41
+
42
+ public function setFilename($filename)
43
+ {
44
+ $this->filename = $filename;
45
+ }
46
+
47
+ public function getContentType()
48
+ {
49
+ return $this->contentType ?: $this->detectContentType() ?: 'application/octet-stream';
50
+ }
51
+
52
+ public function setContentType($contentType)
53
+ {
54
+ $this->contentType = $contentType;
55
+ }
56
+
57
+ /**
58
+ * Prepends Content-Disposition and Content-Type headers.
59
+ */
60
+ public function getHeaders()
61
+ {
62
+ $headers = array('Content-Disposition: form-data');
63
+
64
+ if ($name = $this->getName()) {
65
+ $headers[0] .= sprintf('; name="%s"', $name);
66
+ }
67
+
68
+ if ($filename = $this->getFilename()) {
69
+ $headers[0] .= sprintf('; filename="%s"', $filename);
70
+ }
71
+
72
+ if ($contentType = $this->getContentType()) {
73
+ $headers[] = 'Content-Type: '.$contentType;
74
+ }
75
+
76
+ return array_merge($headers, parent::getHeaders());
77
+ }
78
+
79
+ /**
80
+ * Loads the content from a file.
81
+ */
82
+ public function loadContent($file)
83
+ {
84
+ $this->file = $file;
85
+
86
+ parent::setContent(null);
87
+ }
88
+
89
+ public function setContent($content)
90
+ {
91
+ parent::setContent($content);
92
+
93
+ $this->file = null;
94
+ }
95
+
96
+ public function getFile()
97
+ {
98
+ return $this->file;
99
+ }
100
+
101
+ public function getContent()
102
+ {
103
+ return $this->file ? file_get_contents($this->file) : parent::getContent();
104
+ }
105
+
106
+ // private
107
+
108
+ private function detectContentType()
109
+ {
110
+ if (!class_exists('finfo', false)) {
111
+ return false;
112
+ }
113
+
114
+ $finfo = new \finfo(FILEINFO_MIME_TYPE);
115
+
116
+ return $this->file ? $finfo->file($this->file) : $finfo->buffer(parent::getContent());
117
+ }
118
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/Form/FormUploadInterface.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Message\Form;
4
+
5
+ use Buzz\Message\MessageInterface;
6
+
7
+ interface FormUploadInterface extends MessageInterface
8
+ {
9
+ public function setName($name);
10
+ public function getFile();
11
+ public function getFilename();
12
+ public function getContentType();
13
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/MessageInterface.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Message;
4
+
5
+ /**
6
+ * An HTTP message.
7
+ *
8
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
9
+ */
10
+ interface MessageInterface
11
+ {
12
+ /**
13
+ * Returns a header value.
14
+ *
15
+ * @param string $name A header name
16
+ * @param string|boolean $glue Glue for implode, or false to return an array
17
+ *
18
+ * @return string|array|null The header value(s)
19
+ */
20
+ public function getHeader($name, $glue = "\r\n");
21
+
22
+ /**
23
+ * Returns an array of header lines.
24
+ *
25
+ * @return array An array of header lines (integer indexes, e.g. ["Header: value"])
26
+ */
27
+ public function getHeaders();
28
+
29
+ /**
30
+ * Sets all headers on the current message.
31
+ *
32
+ * Headers can be complete ["Header: value"] pairs or an associative array ["Header" => "value"]
33
+ *
34
+ * @param array $headers An array of header lines
35
+ */
36
+ public function setHeaders(array $headers);
37
+
38
+ /**
39
+ * Adds a header to this message.
40
+ *
41
+ * @param string $header A header line
42
+ */
43
+ public function addHeader($header);
44
+
45
+ /**
46
+ * Adds a set of headers to this message.
47
+ *
48
+ * Headers can be complete ["Header: value"] pairs or an associative array ["Header" => "value"]
49
+ *
50
+ * @param array $headers Headers
51
+ */
52
+ public function addHeaders(array $headers);
53
+
54
+ /**
55
+ * Returns the content of the message.
56
+ *
57
+ * @return string The message content
58
+ */
59
+ public function getContent();
60
+
61
+ /**
62
+ * Sets the content of the message.
63
+ *
64
+ * @param string $content The message content
65
+ */
66
+ public function setContent($content);
67
+
68
+ /**
69
+ * Returns the message document.
70
+ *
71
+ * @return string The message
72
+ */
73
+ public function __toString();
74
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/Request.php ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Message;
4
+
5
+ use Buzz\Util\Url;
6
+
7
+ class Request extends AbstractMessage implements RequestInterface
8
+ {
9
+ private $method;
10
+ private $resource;
11
+ private $host;
12
+ private $protocolVersion = 1.0;
13
+
14
+ /**
15
+ * Constructor.
16
+ *
17
+ * @param string $method
18
+ * @param string $resource
19
+ * @param string $host
20
+ */
21
+ public function __construct($method = self::METHOD_GET, $resource = '/', $host = null)
22
+ {
23
+ $this->method = strtoupper($method);
24
+ $this->resource = $resource;
25
+ $this->host = $host;
26
+ }
27
+
28
+ public function setHeaders(array $headers)
29
+ {
30
+ parent::setHeaders(array());
31
+
32
+ foreach ($this->flattenHeaders($headers) as $header) {
33
+ $this->addHeader($header);
34
+ }
35
+ }
36
+
37
+ public function addHeader($header)
38
+ {
39
+ if (0 === stripos(substr($header, -8), 'HTTP/1.') && 3 == count($parts = explode(' ', $header))) {
40
+ list($method, $resource, $protocolVersion) = $parts;
41
+
42
+ $this->setMethod($method);
43
+ $this->setResource($resource);
44
+ $this->setProtocolVersion((float) substr($protocolVersion, 5));
45
+ } else {
46
+ parent::addHeader($header);
47
+ }
48
+ }
49
+
50
+ public function setMethod($method)
51
+ {
52
+ $this->method = strtoupper($method);
53
+ }
54
+
55
+ public function getMethod()
56
+ {
57
+ return $this->method;
58
+ }
59
+
60
+ public function setResource($resource)
61
+ {
62
+ $this->resource = $resource;
63
+ }
64
+
65
+ public function getResource()
66
+ {
67
+ return $this->resource;
68
+ }
69
+
70
+ public function setHost($host)
71
+ {
72
+ $this->host = $host;
73
+ }
74
+
75
+ public function getHost()
76
+ {
77
+ return $this->host;
78
+ }
79
+
80
+ public function setProtocolVersion($protocolVersion)
81
+ {
82
+ $this->protocolVersion = $protocolVersion;
83
+ }
84
+
85
+ public function getProtocolVersion()
86
+ {
87
+ return $this->protocolVersion;
88
+ }
89
+
90
+ /**
91
+ * A convenience method for getting the full URL of the current request.
92
+ *
93
+ * @return string
94
+ */
95
+ public function getUrl()
96
+ {
97
+ return $this->getHost().$this->getResource();
98
+ }
99
+
100
+ /**
101
+ * A convenience method for populating the current request from a URL.
102
+ *
103
+ * @param Url|string $url An URL
104
+ */
105
+ public function fromUrl($url)
106
+ {
107
+ if (!$url instanceof Url) {
108
+ $url = new Url($url);
109
+ }
110
+
111
+ $url->applyToRequest($this);
112
+ }
113
+
114
+ /**
115
+ * Returns true if the current request is secure.
116
+ *
117
+ * @return boolean
118
+ */
119
+ public function isSecure()
120
+ {
121
+ return 'https' == parse_url($this->getHost(), PHP_URL_SCHEME);
122
+ }
123
+
124
+ /**
125
+ * Merges cookie headers on the way out.
126
+ */
127
+ public function getHeaders()
128
+ {
129
+ return $this->mergeCookieHeaders(parent::getHeaders());
130
+ }
131
+
132
+ /**
133
+ * Returns a string representation of the current request.
134
+ *
135
+ * @return string
136
+ */
137
+ public function __toString()
138
+ {
139
+ $string = sprintf("%s %s HTTP/%.1f\r\n", $this->getMethod(), $this->getResource(), $this->getProtocolVersion());
140
+
141
+ if ($host = $this->getHost()) {
142
+ $string .= 'Host: '.$host."\r\n";
143
+ }
144
+
145
+ if ($parent = trim(parent::__toString())) {
146
+ $string .= $parent."\r\n";
147
+ }
148
+
149
+ return $string;
150
+ }
151
+
152
+ // private
153
+
154
+ private function mergeCookieHeaders(array $headers)
155
+ {
156
+ $cookieHeader = null;
157
+ $needle = 'Cookie:';
158
+
159
+ foreach ($headers as $i => $header) {
160
+ if (0 !== stripos($header, $needle)) {
161
+ continue;
162
+ }
163
+
164
+ if (null === $cookieHeader) {
165
+ $cookieHeader = $i;
166
+ } else {
167
+ $headers[$cookieHeader] .= '; '.trim(substr($header, strlen($needle)));
168
+ unset($headers[$i]);
169
+ }
170
+ }
171
+
172
+ return array_values($headers);
173
+ }
174
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/RequestInterface.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Message;
4
+
5
+ /**
6
+ * An HTTP request message.
7
+ *
8
+ * @author Kris Wallsmith <kris.wallsmith@gmail.com>
9
+ */
10
+ interface RequestInterface extends MessageInterface
11
+ {
12
+ const METHOD_OPTIONS = 'OPTIONS';
13
+ const METHOD_GET = 'GET';
14
+ const METHOD_HEAD = 'HEAD';
15
+ const METHOD_POST = 'POST';
16
+ const METHOD_PUT = 'PUT';
17
+ const METHOD_DELETE = 'DELETE';
18
+ const METHOD_PATCH = 'PATCH';
19
+
20
+ /**
21
+ * Returns the HTTP method of the current request.
22
+ *
23
+ * @return string An HTTP method
24
+ */
25
+ public function getMethod();
26
+
27
+ /**
28
+ * Sets the HTTP method of the current request.
29
+ *
30
+ * @param string $method The request method
31
+ */
32
+ public function setMethod($method);
33
+
34
+ /**
35
+ * Returns the resource portion of the request line.
36
+ *
37
+ * @return string The resource requested
38
+ */
39
+ public function getResource();
40
+
41
+ /**
42
+ * Sets the resource for the current request.
43
+ *
44
+ * @param string $resource The resource being requested
45
+ */
46
+ public function setResource($resource);
47
+
48
+ /**
49
+ * Returns the protocol version of the current request.
50
+ *
51
+ * @return float The protocol version
52
+ */
53
+ public function getProtocolVersion();
54
+
55
+ /**
56
+ * Returns the value of the host header.
57
+ *
58
+ * @return string|null The host
59
+ */
60
+ public function getHost();
61
+
62
+ /**
63
+ * Sets the host for the current request.
64
+ *
65
+ * @param string $host The host
66
+ */
67
+ public function setHost($host);
68
+
69
+ /**
70
+ * Checks if the current request is secure.
71
+ *
72
+ * @return Boolean True if the request is secure
73
+ */
74
+ public function isSecure();
75
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Message/Response.php ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Message;
4
+
5
+ class Response extends AbstractMessage
6
+ {
7
+ private $protocolVersion;
8
+ private $statusCode;
9
+ private $reasonPhrase;
10
+
11
+ /**
12
+ * Returns the protocol version of the current response.
13
+ *
14
+ * @return float
15
+ */
16
+ public function getProtocolVersion()
17
+ {
18
+ if (null === $this->protocolVersion) {
19
+ $this->parseStatusLine();
20
+ }
21
+
22
+ return $this->protocolVersion ?: null;
23
+ }
24
+
25
+ /**
26
+ * Returns the status code of the current response.
27
+ *
28
+ * @return integer
29
+ */
30
+ public function getStatusCode()
31
+ {
32
+ if (null === $this->statusCode) {
33
+ $this->parseStatusLine();
34
+ }
35
+
36
+ return $this->statusCode ?: null;
37
+ }
38
+
39
+ /**
40
+ * Returns the reason phrase for the current response.
41
+ *
42
+ * @return string
43
+ */
44
+ public function getReasonPhrase()
45
+ {
46
+ if (null === $this->reasonPhrase) {
47
+ $this->parseStatusLine();
48
+ }
49
+
50
+ return $this->reasonPhrase ?: null;
51
+ }
52
+
53
+ public function setHeaders(array $headers)
54
+ {
55
+ parent::setHeaders($headers);
56
+
57
+ $this->resetStatusLine();
58
+ }
59
+
60
+ public function addHeader($header)
61
+ {
62
+ parent::addHeader($header);
63
+
64
+ $this->resetStatusLine();
65
+ }
66
+
67
+ public function addHeaders(array $headers)
68
+ {
69
+ parent::addHeaders($headers);
70
+
71
+ $this->resetStatusLine();
72
+ }
73
+
74
+ /**
75
+ * Is response invalid?
76
+ *
77
+ * @return Boolean
78
+ */
79
+ public function isInvalid()
80
+ {
81
+ return $this->getStatusCode() < 100 || $this->getStatusCode() >= 600;
82
+ }
83
+
84
+ /**
85
+ * Is response informative?
86
+ *
87
+ * @return Boolean
88
+ */
89
+ public function isInformational()
90
+ {
91
+ return $this->getStatusCode() >= 100 && $this->getStatusCode() < 200;
92
+ }
93
+
94
+ /**
95
+ * Is response successful?
96
+ *
97
+ * @return Boolean
98
+ */
99
+ public function isSuccessful()
100
+ {
101
+ return $this->getStatusCode() >= 200 && $this->getStatusCode() < 300;
102
+ }
103
+
104
+ /**
105
+ * Is the response a redirect?
106
+ *
107
+ * @return Boolean
108
+ */
109
+ public function isRedirection()
110
+ {
111
+ return $this->getStatusCode() >= 300 && $this->getStatusCode() < 400;
112
+ }
113
+
114
+ /**
115
+ * Is there a client error?
116
+ *
117
+ * @return Boolean
118
+ */
119
+ public function isClientError()
120
+ {
121
+ return $this->getStatusCode() >= 400 && $this->getStatusCode() < 500;
122
+ }
123
+
124
+ /**
125
+ * Was there a server side error?
126
+ *
127
+ * @return Boolean
128
+ */
129
+ public function isServerError()
130
+ {
131
+ return $this->getStatusCode() >= 500 && $this->getStatusCode() < 600;
132
+ }
133
+
134
+ /**
135
+ * Is the response OK?
136
+ *
137
+ * @return Boolean
138
+ */
139
+ public function isOk()
140
+ {
141
+ return 200 === $this->getStatusCode();
142
+ }
143
+
144
+ /**
145
+ * Is the reponse forbidden?
146
+ *
147
+ * @return Boolean
148
+ */
149
+ public function isForbidden()
150
+ {
151
+ return 403 === $this->getStatusCode();
152
+ }
153
+
154
+ /**
155
+ * Is the response a not found error?
156
+ *
157
+ * @return Boolean
158
+ */
159
+ public function isNotFound()
160
+ {
161
+ return 404 === $this->getStatusCode();
162
+ }
163
+
164
+ /**
165
+ * Is the response empty?
166
+ *
167
+ * @return Boolean
168
+ */
169
+ public function isEmpty()
170
+ {
171
+ return in_array($this->getStatusCode(), array(201, 204, 304));
172
+ }
173
+
174
+ // private
175
+
176
+ private function parseStatusLine()
177
+ {
178
+ $headers = $this->getHeaders();
179
+
180
+ if (isset($headers[0]) && 3 == count($parts = explode(' ', $headers[0], 3))) {
181
+ $this->protocolVersion = (float) substr($parts[0], 5);
182
+ $this->statusCode = (integer) $parts[1];
183
+ $this->reasonPhrase = $parts[2];
184
+ } else {
185
+ $this->protocolVersion = $this->statusCode = $this->reasonPhrase = false;
186
+ }
187
+ }
188
+
189
+ private function resetStatusLine()
190
+ {
191
+ $this->protocolVersion = $this->statusCode = $this->reasonPhrase = null;
192
+ }
193
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Util/Cookie.php ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Util;
4
+
5
+ use Buzz\Message\RequestInterface;
6
+
7
+ class Cookie
8
+ {
9
+ const ATTR_DOMAIN = 'domain';
10
+ const ATTR_PATH = 'path';
11
+ const ATTR_SECURE = 'secure';
12
+ const ATTR_MAX_AGE = 'max-age';
13
+ const ATTR_EXPIRES = 'expires';
14
+
15
+ protected $name;
16
+ protected $value;
17
+ protected $attributes = array();
18
+ protected $createdAt;
19
+
20
+ /**
21
+ * Constructor.
22
+ */
23
+ public function __construct()
24
+ {
25
+ $this->createdAt = time();
26
+ }
27
+
28
+ /**
29
+ * Returns true if the current cookie matches the supplied request.
30
+ *
31
+ * @return boolean
32
+ */
33
+ public function matchesRequest(RequestInterface $request)
34
+ {
35
+ // domain
36
+ if (!$this->matchesDomain(parse_url($request->getHost(), PHP_URL_HOST))) {
37
+ return false;
38
+ }
39
+
40
+ // path
41
+ if (!$this->matchesPath($request->getResource())) {
42
+ return false;
43
+ }
44
+
45
+ // secure
46
+ if ($this->hasAttribute(static::ATTR_SECURE) && !$request->isSecure()) {
47
+ return false;
48
+ }
49
+
50
+ return true;
51
+ }
52
+
53
+ /**
54
+ * Returns true of the current cookie has expired.
55
+ *
56
+ * Checks the max-age and expires attributes.
57
+ *
58
+ * @return boolean Whether the current cookie has expired
59
+ */
60
+ public function isExpired()
61
+ {
62
+ $maxAge = $this->getAttribute(static::ATTR_MAX_AGE);
63
+ if ($maxAge && time() - $this->getCreatedAt() > $maxAge) {
64
+ return true;
65
+ }
66
+
67
+ $expires = $this->getAttribute(static::ATTR_EXPIRES);
68
+ if ($expires && strtotime($expires) < time()) {
69
+ return true;
70
+ }
71
+
72
+ return false;
73
+ }
74
+
75
+ /**
76
+ * Returns true if the current cookie matches the supplied domain.
77
+ *
78
+ * @param string $domain A domain hostname
79
+ *
80
+ * @return boolean
81
+ */
82
+ public function matchesDomain($domain)
83
+ {
84
+ $cookieDomain = $this->getAttribute(static::ATTR_DOMAIN);
85
+
86
+ if (0 === strpos($cookieDomain, '.')) {
87
+ $pattern = '/\b'.preg_quote(substr($cookieDomain, 1), '/').'$/i';
88
+
89
+ return (boolean) preg_match($pattern, $domain);
90
+ } else {
91
+ return 0 == strcasecmp($cookieDomain, $domain);
92
+ }
93
+ }
94
+
95
+ /**
96
+ * Returns true if the current cookie matches the supplied path.
97
+ *
98
+ * @param string $path A path
99
+ *
100
+ * @return boolean
101
+ */
102
+ public function matchesPath($path)
103
+ {
104
+ $needle = $this->getAttribute(static::ATTR_PATH);
105
+
106
+ return null === $needle || 0 === strpos($path, $needle);
107
+ }
108
+
109
+ /**
110
+ * Populates the current cookie with data from the supplied Set-Cookie header.
111
+ *
112
+ * @param string $header A Set-Cookie header
113
+ * @param string $issuingDomain The domain that issued the header
114
+ */
115
+ public function fromSetCookieHeader($header, $issuingDomain)
116
+ {
117
+ list($this->name, $header) = explode('=', $header, 2);
118
+ if (false === strpos($header, ';')) {
119
+ $this->value = $header;
120
+ $header = null;
121
+ } else {
122
+ list($this->value, $header) = explode(';', $header, 2);
123
+ }
124
+
125
+ $this->clearAttributes();
126
+ foreach (array_map('trim', explode(';', trim($header))) as $pair) {
127
+ if (false === strpos($pair, '=')) {
128
+ $name = $pair;
129
+ $value = null;
130
+ } else {
131
+ list($name, $value) = explode('=', $pair);
132
+ }
133
+
134
+ $this->setAttribute($name, $value);
135
+ }
136
+
137
+ if (!$this->getAttribute(static::ATTR_DOMAIN)) {
138
+ $this->setAttribute(static::ATTR_DOMAIN, $issuingDomain);
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Formats a Cookie header for the current cookie.
144
+ *
145
+ * @return string An HTTP request Cookie header
146
+ */
147
+ public function toCookieHeader()
148
+ {
149
+ return 'Cookie: '.$this->getName().'='.$this->getValue();
150
+ }
151
+
152
+ public function setName($name)
153
+ {
154
+ $this->name = $name;
155
+ }
156
+
157
+ public function getName()
158
+ {
159
+ return $this->name;
160
+ }
161
+
162
+ public function setValue($value)
163
+ {
164
+ $this->value = $value;
165
+ }
166
+
167
+ public function getValue()
168
+ {
169
+ return $this->value;
170
+ }
171
+
172
+ public function setAttributes(array $attributes)
173
+ {
174
+ // attributes are case insensitive
175
+ $this->attributes = array_change_key_case($attributes);
176
+ }
177
+
178
+ public function setAttribute($name, $value)
179
+ {
180
+ $this->attributes[strtolower($name)] = $value;
181
+ }
182
+
183
+ public function getAttributes()
184
+ {
185
+ return $this->attributes;
186
+ }
187
+
188
+ public function getAttribute($name)
189
+ {
190
+ $name = strtolower($name);
191
+
192
+ if (isset($this->attributes[$name])) {
193
+ return $this->attributes[$name];
194
+ }
195
+ }
196
+
197
+ public function hasAttribute($name)
198
+ {
199
+ return array_key_exists($name, $this->attributes);
200
+ }
201
+
202
+ public function clearAttributes()
203
+ {
204
+ $this->setAttributes(array());
205
+ }
206
+
207
+ public function setCreatedAt($createdAt)
208
+ {
209
+ $this->createdAt = $createdAt;
210
+ }
211
+
212
+ public function getCreatedAt()
213
+ {
214
+ return $this->createdAt;
215
+ }
216
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Util/CookieJar.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Util;
4
+
5
+ use Buzz\Message\MessageInterface;
6
+ use Buzz\Message\RequestInterface;
7
+
8
+ class CookieJar
9
+ {
10
+ protected $cookies = array();
11
+
12
+ public function setCookies($cookies)
13
+ {
14
+ $this->cookies = array();
15
+ foreach ($cookies as $cookie) {
16
+ $this->addCookie($cookie);
17
+ }
18
+ }
19
+
20
+ public function getCookies()
21
+ {
22
+ return $this->cookies;
23
+ }
24
+
25
+ /**
26
+ * Adds a cookie to the current cookie jar.
27
+ *
28
+ * @param Cookie $cookie A cookie object
29
+ */
30
+ public function addCookie(Cookie $cookie)
31
+ {
32
+ $this->cookies[] = $cookie;
33
+ }
34
+
35
+ /**
36
+ * Adds Cookie headers to the supplied request.
37
+ *
38
+ * @param RequestInterface $request A request object
39
+ */
40
+ public function addCookieHeaders(RequestInterface $request)
41
+ {
42
+ foreach ($this->cookies as $cookie) {
43
+ if ($cookie->matchesRequest($request)) {
44
+ $request->addHeader($cookie->toCookieHeader());
45
+ }
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Processes Set-Cookie headers from a request/response pair.
51
+ *
52
+ * @param RequestInterface $request A request object
53
+ * @param MessageInterface $response A response object
54
+ */
55
+ public function processSetCookieHeaders(RequestInterface $request, MessageInterface $response)
56
+ {
57
+ foreach ($response->getHeader('Set-Cookie', false) as $header) {
58
+ $cookie = new Cookie();
59
+ $cookie->fromSetCookieHeader($header, parse_url($request->getHost(), PHP_URL_HOST));
60
+
61
+ $this->addCookie($cookie);
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Removes expired cookies.
67
+ */
68
+ public function clearExpiredCookies()
69
+ {
70
+ foreach ($this->cookies as $i => $cookie) {
71
+ if ($cookie->isExpired()) {
72
+ unset($this->cookies[$i]);
73
+ }
74
+ }
75
+
76
+ // reset array keys
77
+ $this->cookies = array_values($this->cookies);
78
+ }
79
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/lib/Buzz/Util/Url.php ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Util;
4
+
5
+ use Buzz\Message\RequestInterface;
6
+ use Buzz\Exception\InvalidArgumentException;
7
+
8
+ class Url
9
+ {
10
+ private static $defaultPorts = array(
11
+ 'http' => 80,
12
+ 'https' => 443,
13
+ );
14
+
15
+ private $url;
16
+ private $components;
17
+
18
+ /**
19
+ * Constructor.
20
+ *
21
+ * @param string $url The URL
22
+ *
23
+ * @throws InvalidArgumentException If the URL is invalid
24
+ */
25
+ public function __construct($url)
26
+ {
27
+ $components = parse_url($url);
28
+
29
+ if (false === $components) {
30
+ throw new InvalidArgumentException(sprintf('The URL "%s" is invalid.', $url));
31
+ }
32
+
33
+ // support scheme-less URLs
34
+ if (!isset($components['host']) && isset($components['path'])) {
35
+ $pos = strpos($components['path'], '/');
36
+ if (false === $pos) {
37
+ $components['host'] = $components['path'];
38
+ unset($components['path']);
39
+ } elseif (0 !== $pos) {
40
+ list($host, $path) = explode('/', $components['path'], 2);
41
+ $components['host'] = $host;
42
+ $components['path'] = '/'.$path;
43
+ }
44
+ }
45
+
46
+ // default port
47
+ if (isset($components['scheme']) && !isset($components['port']) && isset(self::$defaultPorts[$components['scheme']])) {
48
+ $components['port'] = self::$defaultPorts[$components['scheme']];
49
+ }
50
+
51
+ $this->url = $url;
52
+ $this->components = $components;
53
+ }
54
+
55
+ public function getScheme()
56
+ {
57
+ return $this->parseUrl('scheme');
58
+ }
59
+
60
+ public function getHostname()
61
+ {
62
+ return $this->parseUrl('host');
63
+ }
64
+
65
+ public function getPort()
66
+ {
67
+ return $this->parseUrl('port');
68
+ }
69
+
70
+ public function getUser()
71
+ {
72
+ return $this->parseUrl('user');
73
+ }
74
+
75
+ public function getPassword()
76
+ {
77
+ return $this->parseUrl('pass');
78
+ }
79
+
80
+ public function getPath()
81
+ {
82
+ return $this->parseUrl('path');
83
+ }
84
+
85
+ public function getQueryString()
86
+ {
87
+ return $this->parseUrl('query');
88
+ }
89
+
90
+ public function getFragment()
91
+ {
92
+ return $this->parseUrl('fragment');
93
+ }
94
+
95
+ /**
96
+ * Returns a host string that combines scheme, hostname and port.
97
+ *
98
+ * @return string A host value for an HTTP message
99
+ */
100
+ public function getHost()
101
+ {
102
+ if ($hostname = $this->parseUrl('host')) {
103
+ $host = $scheme = $this->parseUrl('scheme', 'http');
104
+ $host .= '://';
105
+ $host .= $hostname;
106
+
107
+ $port = $this->parseUrl('port');
108
+ if ($port && (!isset(self::$defaultPorts[$scheme]) || self::$defaultPorts[$scheme] != $port)) {
109
+ $host .= ':'.$port;
110
+ }
111
+
112
+ return $host;
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Returns a resource string that combines path and query string.
118
+ *
119
+ * @return string A resource value for an HTTP message
120
+ */
121
+ public function getResource()
122
+ {
123
+ $resource = $this->parseUrl('path', '/');
124
+
125
+ if ($query = $this->parseUrl('query')) {
126
+ $resource .= '?'.$query;
127
+ }
128
+
129
+ return $resource;
130
+ }
131
+
132
+ /**
133
+ * Returns a formatted URL.
134
+ */
135
+ public function format($pattern)
136
+ {
137
+ static $map = array(
138
+ 's' => 'getScheme',
139
+ 'u' => 'getUser',
140
+ 'a' => 'getPassword',
141
+ 'h' => 'getHostname',
142
+ 'o' => 'getPort',
143
+ 'p' => 'getPath',
144
+ 'q' => 'getQueryString',
145
+ 'f' => 'getFragment',
146
+ 'H' => 'getHost',
147
+ 'R' => 'getResource',
148
+ );
149
+
150
+ $url = '';
151
+
152
+ $parts = str_split($pattern);
153
+ while ($part = current($parts)) {
154
+ if (isset($map[$part])) {
155
+ $method = $map[$part];
156
+ $url .= $this->$method();
157
+ } elseif ('\\' == $part) {
158
+ $url .= next($parts);
159
+ } elseif (!ctype_alpha($part)) {
160
+ $url .= $part;
161
+ } else {
162
+ throw new InvalidArgumentException(sprintf('The format character "%s" is invalid.', $part));
163
+ }
164
+
165
+ next($parts);
166
+ }
167
+
168
+ return $url;
169
+ }
170
+
171
+ /**
172
+ * Applies the current URL to the supplied request.
173
+ */
174
+ public function applyToRequest(RequestInterface $request)
175
+ {
176
+ $request->setResource($this->getResource());
177
+ $request->setHost($this->getHost());
178
+ }
179
+
180
+ private function parseUrl($component = null, $default = null)
181
+ {
182
+ if (null === $component) {
183
+ return $this->components;
184
+ } elseif (isset($this->components[$component])) {
185
+ return $this->components[$component];
186
+ } else {
187
+ return $default;
188
+ }
189
+ }
190
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/phpunit.xml.dist ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <phpunit backupGlobals="false" bootstrap="vendor/autoload.php" colors="true">
4
+ <testsuites>
5
+ <testsuite name="Buzz Test Suite">
6
+ <directory suffix="Test.php">./test/Buzz/</directory>
7
+ </testsuite>
8
+ </testsuites>
9
+
10
+ <php>
11
+ <!-- <server name="TEST_SERVER" value="http://localhost/buzz/test/server.php" /> -->
12
+ <!-- <server name="TEST_PROXY" value="localhost:3128" /> -->
13
+ </php>
14
+
15
+ <filter>
16
+ <whitelist>
17
+ <directory suffix=".php">./lib/Buzz/</directory>
18
+ </whitelist>
19
+ </filter>
20
+ </phpunit>
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/BrowserTest.php ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test;
4
+
5
+ use Buzz\Browser;
6
+
7
+ class BrowserTest extends \PHPUnit_Framework_TestCase
8
+ {
9
+ private $client;
10
+ private $factory;
11
+ private $browser;
12
+
13
+ protected function setUp()
14
+ {
15
+ $this->client = $this->getMock('Buzz\Client\ClientInterface');
16
+ $this->factory = $this->getMock('Buzz\Message\Factory\FactoryInterface');
17
+
18
+ $this->browser = new Browser($this->client, $this->factory);
19
+ }
20
+
21
+ /**
22
+ * @dataProvider provideMethods
23
+ */
24
+ public function testBasicMethods($method, $content)
25
+ {
26
+ $request = $this->getMock('Buzz\Message\RequestInterface');
27
+ $response = $this->getMock('Buzz\Message\MessageInterface');
28
+ $headers = array('X-Foo: bar');
29
+
30
+ $this->factory->expects($this->once())
31
+ ->method('createRequest')
32
+ ->with(strtoupper($method))
33
+ ->will($this->returnValue($request));
34
+ $request->expects($this->once())
35
+ ->method('setHost')
36
+ ->with('http://google.com');
37
+ $request->expects($this->once())
38
+ ->method('setResource')
39
+ ->with('/');
40
+ $request->expects($this->once())
41
+ ->method('addHeaders')
42
+ ->with($headers);
43
+ $request->expects($this->once())
44
+ ->method('setContent')
45
+ ->with($content);
46
+ $this->factory->expects($this->once())
47
+ ->method('createResponse')
48
+ ->will($this->returnValue($response));
49
+ $this->client->expects($this->once())
50
+ ->method('send')
51
+ ->with($request, $response);
52
+
53
+ $actual = $this->browser->$method('http://google.com/', $headers, $content);
54
+
55
+ $this->assertSame($response, $actual);
56
+ }
57
+
58
+ public function provideMethods()
59
+ {
60
+ return array(
61
+ array('get', ''),
62
+ array('head', ''),
63
+ array('post', 'content'),
64
+ array('put', 'content'),
65
+ array('delete', 'content'),
66
+ );
67
+ }
68
+
69
+ public function testSubmit()
70
+ {
71
+ $request = $this->getMock('Buzz\Message\Form\FormRequestInterface');
72
+ $response = $this->getMock('Buzz\Message\MessageInterface');
73
+ $headers = array('X-Foo: bar');
74
+
75
+ $this->factory->expects($this->once())
76
+ ->method('createFormRequest')
77
+ ->will($this->returnValue($request));
78
+ $request->expects($this->once())
79
+ ->method('setMethod')
80
+ ->with('PUT');
81
+ $request->expects($this->once())
82
+ ->method('setHost')
83
+ ->with('http://google.com');
84
+ $request->expects($this->once())
85
+ ->method('setResource')
86
+ ->with('/');
87
+ $request->expects($this->once())
88
+ ->method('addHeaders')
89
+ ->with($headers);
90
+ $request->expects($this->once())
91
+ ->method('setFields')
92
+ ->with(array('foo' => 'bar', 'bar' => 'foo'));
93
+ $this->factory->expects($this->once())
94
+ ->method('createResponse')
95
+ ->will($this->returnValue($response));
96
+ $this->client->expects($this->once())
97
+ ->method('send')
98
+ ->with($request, $response);
99
+
100
+ $actual = $this->browser->submit('http://google.com', array('foo' => 'bar', 'bar' => 'foo'), 'PUT', $headers);
101
+
102
+ $this->assertSame($response, $actual);
103
+ }
104
+
105
+ public function testListener()
106
+ {
107
+ $listener = $this->getMock('Buzz\Listener\ListenerInterface');
108
+ $request = $this->getMock('Buzz\Message\RequestInterface');
109
+ $response = $this->getMock('Buzz\Message\MessageInterface');
110
+
111
+ $listener->expects($this->once())
112
+ ->method('preSend')
113
+ ->with($request);
114
+ $listener->expects($this->once())
115
+ ->method('postSend')
116
+ ->with($request, $response);
117
+
118
+ $this->browser->setListener($listener);
119
+ $this->assertSame($listener, $this->browser->getListener());
120
+
121
+ $this->browser->send($request, $response);
122
+ }
123
+
124
+ public function testLastMessages()
125
+ {
126
+ $request = $this->getMock('Buzz\Message\RequestInterface');
127
+ $response = $this->getMock('Buzz\Message\MessageInterface');
128
+
129
+ $this->browser->send($request, $response);
130
+
131
+ $this->assertSame($request, $this->browser->getLastRequest());
132
+ $this->assertSame($response, $this->browser->getLastResponse());
133
+ }
134
+
135
+ public function testClientMethods()
136
+ {
137
+ $client = $this->getMock('Buzz\Client\ClientInterface');
138
+ $this->browser->setClient($client);
139
+ $this->assertSame($client, $this->browser->getClient());
140
+ }
141
+
142
+ public function testFactoryMethods()
143
+ {
144
+ $factory = $this->getMock('Buzz\Message\Factory\FactoryInterface');
145
+ $this->browser->setMessageFactory($factory);
146
+ $this->assertSame($factory, $this->browser->getMessageFactory());
147
+ }
148
+
149
+ public function testAddFirstListener()
150
+ {
151
+ $listener = $this->getMock('Buzz\Listener\ListenerInterface');
152
+ $this->browser->addListener($listener);
153
+ $this->assertEquals($listener, $this->browser->getListener());
154
+ }
155
+
156
+ public function testAddSecondListener()
157
+ {
158
+ $listener = $this->getMock('Buzz\Listener\ListenerInterface');
159
+
160
+ $this->browser->addListener($listener);
161
+ $this->browser->addListener($listener);
162
+
163
+ $listenerChain = $this->browser->getListener();
164
+
165
+ $this->assertInstanceOf('Buzz\Listener\ListenerChain', $listenerChain);
166
+ $this->assertEquals(2, count($listenerChain->getListeners()));
167
+ }
168
+
169
+ public function testAddThirdListener()
170
+ {
171
+ $listener = $this->getMock('Buzz\Listener\ListenerInterface');
172
+
173
+ $this->browser->addListener($listener);
174
+ $this->browser->addListener($listener);
175
+ $this->browser->addListener($listener);
176
+
177
+ $listenerChain = $this->browser->getListener();
178
+
179
+ $this->assertInstanceOf('Buzz\Listener\ListenerChain', $listenerChain);
180
+ $this->assertEquals(3, count($listenerChain->getListeners()));
181
+ }
182
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Client/AbstractStreamTest.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Client;
4
+
5
+ use Buzz\Client\AbstractStream;
6
+ use Buzz\Message\Request;
7
+ use Buzz\Message\RequestInterface;
8
+ use Buzz\Message\MessageInterface;
9
+
10
+ class StreamClient extends AbstractStream
11
+ {
12
+ public function send(RequestInterface $request, MessageInterface $response)
13
+ {
14
+ }
15
+ }
16
+
17
+ class AbstractStreamTest extends \PHPUnit_Framework_TestCase
18
+ {
19
+ public function testConvertsARequestToAContextArray()
20
+ {
21
+ $request = new Request('POST', '/resource/123', 'http://example.com');
22
+ $request->addHeader('Content-Type: application/x-www-form-urlencoded');
23
+ $request->addHeader('Content-Length: 15');
24
+ $request->setContent('foo=bar&bar=baz');
25
+
26
+ $client = new StreamClient();
27
+ $client->setMaxRedirects(5);
28
+ $client->setIgnoreErrors(false);
29
+ $client->setTimeout(10);
30
+ $expected = array(
31
+ 'http' => array(
32
+ 'method' => 'POST',
33
+ 'header' => "Content-Type: application/x-www-form-urlencoded\r\nContent-Length: 15",
34
+ 'content' => 'foo=bar&bar=baz',
35
+ 'protocol_version' => 1.0,
36
+ 'ignore_errors' => false,
37
+ 'follow_location' => true,
38
+ 'max_redirects' => 6,
39
+ 'timeout' => 10,
40
+ ),
41
+ 'ssl' => array(
42
+ 'verify_peer' => true,
43
+ ),
44
+ );
45
+
46
+ $this->assertEquals($expected, $client->getStreamContextArray($request));
47
+
48
+ $client->setVerifyPeer(true);
49
+ $expected['ssl']['verify_peer'] = true;
50
+ $this->assertEquals($expected, $client->getStreamContextArray($request));
51
+
52
+ $client->setMaxRedirects(0);
53
+ $expected['http']['follow_location'] = false;
54
+ $expected['http']['max_redirects'] = 1;
55
+ $this->assertEquals($expected, $client->getStreamContextArray($request));
56
+ }
57
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Client/ClientTest.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Client;
4
+
5
+ use Buzz\Message;
6
+
7
+ class ClientTest extends \PHPUnit_Framework_TestCase
8
+ {
9
+ /**
10
+ * @dataProvider provideInvalidHosts
11
+ */
12
+ public function testSendToInvalidUrl($host, $client)
13
+ {
14
+ $this->setExpectedException('Buzz\\Exception\\ClientException');
15
+
16
+ $request = new Message\Request();
17
+ $request->fromUrl('http://'.$host.':12345');
18
+
19
+ $response = new Message\Response();
20
+
21
+ $client = new $client();
22
+ $client->setTimeout(0.05);
23
+ $client->send($request, $response);
24
+ }
25
+
26
+ public function provideInvalidHosts()
27
+ {
28
+ return array(
29
+ array('invalid_domain', 'Buzz\\Client\\Curl'),
30
+ array('invalid_domain.buzz', 'Buzz\\Client\\Curl'),
31
+
32
+ array('invalid_domain', 'Buzz\\Client\\FileGetContents'),
33
+ array('invalid_domain.buzz', 'Buzz\\Client\\FileGetContents'),
34
+ );
35
+ }
36
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Client/FunctionalTest.php ADDED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Client;
4
+
5
+ use Buzz\Client\BatchClientInterface;
6
+ use Buzz\Client\ClientInterface;
7
+ use Buzz\Client\Curl;
8
+ use Buzz\Client\FileGetContents;
9
+ use Buzz\Client\MultiCurl;
10
+ use Buzz\Message\Form\FormRequest;
11
+ use Buzz\Message\Form\FormUpload;
12
+ use Buzz\Message\Request;
13
+ use Buzz\Message\RequestInterface;
14
+ use Buzz\Message\Response;
15
+
16
+ class FunctionalTest extends \PHPUnit_Framework_TestCase
17
+ {
18
+ protected function setUp()
19
+ {
20
+ if (!isset($_SERVER['TEST_SERVER'])) {
21
+ $this->markTestSkipped('The test server is not configured.');
22
+ }
23
+ }
24
+
25
+ /**
26
+ * @dataProvider provideClientAndMethod
27
+ */
28
+ public function testRequestMethods($client, $method)
29
+ {
30
+ $request = new Request($method);
31
+ $request->fromUrl($_SERVER['TEST_SERVER']);
32
+ $request->setContent('test');
33
+ $response = $this->send($client, $request);
34
+
35
+ $data = json_decode($response->getContent(), true);
36
+
37
+ $this->assertEquals($method, $data['SERVER']['REQUEST_METHOD']);
38
+ }
39
+
40
+ /**
41
+ * @dataProvider provideClient
42
+ */
43
+ public function testGetContentType($client)
44
+ {
45
+ $request = new Request();
46
+ $request->fromUrl($_SERVER['TEST_SERVER']);
47
+ $response = $this->send($client, $request);
48
+
49
+ $data = json_decode($response->getContent(), true);
50
+
51
+ $this->assertArrayNotHasKey('CONTENT_TYPE', $data['SERVER']);
52
+ }
53
+
54
+ /**
55
+ * @dataProvider provideClient
56
+ */
57
+ public function testFormPost($client)
58
+ {
59
+ $request = new FormRequest();
60
+ $request->fromUrl($_SERVER['TEST_SERVER']);
61
+ $request->setField('company[name]', 'Google');
62
+ $response = $this->send($client, $request);
63
+
64
+ $data = json_decode($response->getContent(), true);
65
+
66
+ $this->assertStringStartsWith('application/x-www-form-urlencoded', $data['SERVER']['CONTENT_TYPE']);
67
+ $this->assertEquals('Google', $data['POST']['company']['name']);
68
+ }
69
+
70
+ /**
71
+ * @dataProvider provideClient
72
+ */
73
+ public function testFormGet($client)
74
+ {
75
+ $request = new FormRequest(FormRequest::METHOD_GET);
76
+ $request->fromUrl($_SERVER['TEST_SERVER']);
77
+ $request->setField('search[query]', 'cats');
78
+ $response = $this->send($client, $request);
79
+
80
+ $data = json_decode($response->getContent(), true);
81
+
82
+ $this->assertArrayNotHasKey('CONTENT_TYPE', $data['SERVER']);
83
+ $this->assertEquals('cats', $data['GET']['search']['query']);
84
+ }
85
+
86
+ /**
87
+ * @dataProvider provideClientAndUpload
88
+ */
89
+ public function testFileUpload($client, $upload)
90
+ {
91
+ $request = new FormRequest();
92
+ $request->fromUrl($_SERVER['TEST_SERVER']);
93
+ $request->setField('company[name]', 'Google');
94
+ $request->setField('company[logo]', $upload);
95
+ $response = $this->send($client, $request);
96
+
97
+ $data = json_decode($response->getContent(), true);
98
+
99
+ $this->assertStringStartsWith('multipart/form-data', $data['SERVER']['CONTENT_TYPE']);
100
+ $this->assertEquals('Google', $data['POST']['company']['name']);
101
+ $this->assertEquals('google.png', $data['FILES']['company']['name']['logo']);
102
+ }
103
+
104
+ /**
105
+ * @dataProvider provideClient
106
+ */
107
+ public function testJsonPayload($client)
108
+ {
109
+ $request = new Request(RequestInterface::METHOD_POST);
110
+ $request->fromUrl($_SERVER['TEST_SERVER']);
111
+ $request->addHeader('Content-Type: application/json');
112
+ $request->setContent(json_encode(array('foo' => 'bar')));
113
+ $response = $this->send($client, $request);
114
+
115
+ $data = json_decode($response->getContent(), true);
116
+
117
+ $this->assertEquals('application/json', $data['SERVER']['CONTENT_TYPE']);
118
+ $this->assertEquals('{"foo":"bar"}', $data['INPUT']);
119
+ }
120
+
121
+ /**
122
+ * @dataProvider provideClient
123
+ */
124
+ public function testConsecutiveRequests($client)
125
+ {
126
+ // request 1
127
+ $request = new Request(RequestInterface::METHOD_PUT);
128
+ $request->fromUrl($_SERVER['TEST_SERVER']);
129
+ $request->addHeader('Content-Type: application/json');
130
+ $request->setContent(json_encode(array('foo' => 'bar')));
131
+ $response = $this->send($client, $request);
132
+
133
+ $data = json_decode($response->getContent(), true);
134
+
135
+ $this->assertEquals('PUT', $data['SERVER']['REQUEST_METHOD']);
136
+ $this->assertEquals('application/json', $data['SERVER']['CONTENT_TYPE']);
137
+ $this->assertEquals('{"foo":"bar"}', $data['INPUT']);
138
+
139
+ // request 2
140
+ $request = new Request(RequestInterface::METHOD_GET);
141
+ $request->fromUrl($_SERVER['TEST_SERVER']);
142
+ $response = $this->send($client, $request);
143
+
144
+ $data = json_decode($response->getContent(), true);
145
+
146
+ $this->assertEquals('GET', $data['SERVER']['REQUEST_METHOD']);
147
+ $this->assertEmpty($data['INPUT']);
148
+ }
149
+
150
+ /**
151
+ * @dataProvider provideClient
152
+ */
153
+ public function testPlus($client)
154
+ {
155
+ $request = new FormRequest();
156
+ $request->fromUrl($_SERVER['TEST_SERVER']);
157
+ $request->setField('math', '1+1=2');
158
+ $response = $this->send($client, $request);
159
+
160
+ $data = json_decode($response->getContent(), true);
161
+ parse_str($data['INPUT'], $fields);
162
+
163
+ $this->assertEquals(array('math' => '1+1=2'), $fields);
164
+ }
165
+
166
+ /**
167
+ * @dataProvider provideClient
168
+ */
169
+ public function testRedirectedResponse($client)
170
+ {
171
+ $request = new Request();
172
+ $request->fromUrl($_SERVER['TEST_SERVER'].'?redirect_to='.$_SERVER['TEST_SERVER']);
173
+ $response = $this->send($client, $request);
174
+
175
+ $headers = $response->getHeaders();
176
+ $this->assertContains('200', $headers[0]);
177
+ }
178
+
179
+ /**
180
+ * @dataProvider provideClient
181
+ */
182
+ public function testProxy($client)
183
+ {
184
+ if (!isset($_SERVER['TEST_PROXY'])) {
185
+ $this->markTestSkipped('The proxy server is not configured.');
186
+ }
187
+
188
+ $client->setProxy($_SERVER['TEST_PROXY']);
189
+
190
+ $request = new Request();
191
+ $request->fromUrl($_SERVER['TEST_SERVER']);
192
+ $response = $this->send($client, $request);
193
+
194
+ $data = json_decode($response->getContent(), true);
195
+ $this->assertArrayHasKey('HTTP_VIA', $data['SERVER']);
196
+ }
197
+
198
+ /**
199
+ * @expectedException RuntimeException
200
+ * @expectedExceptionMessage Protocol pop3 not supported or disabled in libcurl
201
+ */
202
+ public function testRedirectedToForbiddenProtocol()
203
+ {
204
+ $client = new Curl();
205
+ $request = new Request();
206
+ $request->fromUrl($_SERVER['TEST_SERVER'].'?redirect_to=pop3://localhost/');
207
+ $response = $this->send($client, $request);
208
+ }
209
+
210
+ public function testMultiCurlExecutesRequestsConcurently()
211
+ {
212
+ $client = new MultiCurl();
213
+ $client->setTimeout(10);
214
+
215
+ $calls = array();
216
+ $callback = function($client, $request, $response, $options, $error) use(&$calls) {
217
+ $calls[] = func_get_args();
218
+ };
219
+
220
+ for ($i = 3; $i > 0; $i--) {
221
+ $request = new Request();
222
+ $request->fromUrl($_SERVER['TEST_SERVER'].'?delay='.$i);
223
+ $client->send($request, new Response(), array('callback' => $callback));
224
+ }
225
+
226
+ $client->flush();
227
+ $this->assertCount(3, $calls);
228
+ }
229
+
230
+ public function provideClient()
231
+ {
232
+ return array(
233
+ array(new Curl()),
234
+ array(new FileGetContents()),
235
+ array(new MultiCurl()),
236
+ );
237
+ }
238
+
239
+ public function provideClientAndMethod()
240
+ {
241
+ // HEAD is intentionally omitted
242
+ // http://stackoverflow.com/questions/2603104/does-mod-php-honor-head-requests-properly
243
+
244
+ $methods = array('GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS');
245
+ $clients = $this->provideClient();
246
+
247
+ $data = array();
248
+ foreach ($clients as $client) {
249
+ foreach ($methods as $method) {
250
+ $data[] = array($client[0], $method);
251
+ }
252
+ }
253
+
254
+ return $data;
255
+ }
256
+
257
+ public function provideClientAndUpload()
258
+ {
259
+ $stringUpload = new FormUpload();
260
+ $stringUpload->setFilename('google.png');
261
+ $stringUpload->setContent(file_get_contents(__DIR__.'/../Message/Fixtures/google.png'));
262
+
263
+ $uploads = array($stringUpload, new FormUpload(__DIR__.'/../Message/Fixtures/google.png'));
264
+ $clients = $this->provideClient();
265
+
266
+ $data = array();
267
+ foreach ($clients as $client) {
268
+ foreach ($uploads as $upload) {
269
+ $data[] = array($client[0], $upload);
270
+ }
271
+ }
272
+
273
+ return $data;
274
+ }
275
+
276
+ private function send(ClientInterface $client, RequestInterface $request)
277
+ {
278
+ $response = new Response();
279
+ $client->send($request, $response);
280
+
281
+ if ($client instanceof BatchClientInterface) {
282
+ $client->flush();
283
+ }
284
+
285
+ return $response;
286
+ }
287
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Listener/BasicAuthListenerTest.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Listener;
4
+
5
+ use Buzz\Listener\BasicAuthListener;
6
+ use Buzz\Message;
7
+
8
+ class BasicAuthListenerTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ public function testBasicAuthHeader()
11
+ {
12
+ $request = new Message\Request();
13
+ $this->assertEmpty($request->getHeader('Authorization'));
14
+
15
+ $listener = new BasicAuthListener('foo', 'bar');
16
+ $listener->preSend($request);
17
+
18
+ $this->assertEquals('Basic '.base64_encode('foo:bar'), $request->getHeader('Authorization'));
19
+ }
20
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Listener/CallbackListenerTest.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Listener;
4
+
5
+ use Buzz\Listener\CallbackListener;
6
+ use Buzz\Message;
7
+
8
+ class CallbackListenerTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ public function testCallback()
11
+ {
12
+ $calls = array();
13
+ $listener = new CallbackListener(function() use (& $calls) {
14
+ $calls[] = func_get_args();
15
+ });
16
+
17
+ $request = new Message\Request();
18
+ $response = new Message\Response();
19
+
20
+ $listener->preSend($request);
21
+ $listener->postSend($request, $response);
22
+
23
+ $this->assertEquals(array(
24
+ array($request),
25
+ array($request, $response),
26
+ ), $calls);
27
+ }
28
+
29
+ public function testInvalidCallback()
30
+ {
31
+ $this->setExpectedException('Buzz\Exception\InvalidArgumentException');
32
+ $listener = new CallbackListener(array(1, 2, 3));
33
+ }
34
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Listener/History/EntryTest.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\History;
4
+
5
+ use Buzz\Listener\History\Entry;
6
+ use Buzz\Message;
7
+
8
+ class EntryTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ public function testDuration()
11
+ {
12
+ $entry = new Entry(new Message\Request(), new Message\Response(), 123);
13
+ $this->assertEquals(123, $entry->getDuration());
14
+ }
15
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Listener/History/JournalTest.php ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\History;
4
+
5
+ use Buzz\Listener\History\Journal;
6
+ use Buzz\Message;
7
+
8
+ class JournalTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ protected $request1;
11
+ protected $request2;
12
+ protected $request3;
13
+
14
+ protected $response1;
15
+ protected $response2;
16
+ protected $response3;
17
+
18
+ protected function setUp()
19
+ {
20
+ $this->request1 = new Message\Request();
21
+ $this->request1->setContent('request1');
22
+ $this->request2 = new Message\Request();
23
+ $this->request2->setContent('request2');
24
+ $this->request3 = new Message\Request();
25
+ $this->request3->setContent('request3');
26
+
27
+ $this->response1 = new Message\Response();
28
+ $this->response1->setContent('response1');
29
+ $this->response2 = new Message\Response();
30
+ $this->response2->setContent('response2');
31
+ $this->response3 = new Message\Response();
32
+ $this->response3->setContent('response3');
33
+ }
34
+
35
+ protected function tearDown()
36
+ {
37
+ $this->request1 = null;
38
+ $this->request2 = null;
39
+ $this->request3 = null;
40
+
41
+ $this->response1 = null;
42
+ $this->response2 = null;
43
+ $this->response3 = null;
44
+ }
45
+
46
+ public function testRecordEnforcesLimit()
47
+ {
48
+ $journal = new Journal();
49
+ $journal->setLimit(2);
50
+
51
+ $journal->record($this->request1, $this->response1);
52
+ $journal->record($this->request2, $this->response2);
53
+ $journal->record($this->request3, $this->response3);
54
+
55
+ $this->assertEquals(2, count($journal));
56
+ }
57
+
58
+ public function testGetLastReturnsTheLastEntry()
59
+ {
60
+ $journal = new Journal();
61
+
62
+ $journal->record($this->request1, $this->response1);
63
+ $journal->record($this->request2, $this->response2);
64
+
65
+ $this->assertEquals($this->request2, $journal->getLast()->getRequest());
66
+
67
+ return $journal;
68
+ }
69
+
70
+ /**
71
+ * @depends testGetLastReturnsTheLastEntry
72
+ */
73
+ public function testGetLastRequestReturnsTheLastRequest(Journal $journal)
74
+ {
75
+ $this->assertEquals($this->request2, $journal->getLastRequest());
76
+ }
77
+
78
+ /**
79
+ * @depends testGetLastReturnsTheLastEntry
80
+ */
81
+ public function testGetLastResponseReturnsTheLastResponse(Journal $journal)
82
+ {
83
+ $this->assertEquals($this->response2, $journal->getLastResponse());
84
+ }
85
+
86
+ /**
87
+ * @depends testGetLastReturnsTheLastEntry
88
+ */
89
+ public function testClearRemovesEntries(Journal $journal)
90
+ {
91
+ $journal->clear();
92
+ $this->assertEquals(0, count($journal));
93
+ }
94
+
95
+ /**
96
+ * @depends testGetLastReturnsTheLastEntry
97
+ */
98
+ public function testForeachIteratesReversedEntries(Journal $journal)
99
+ {
100
+ $requests = array($this->request2, $this->request1);
101
+ $responses = array($this->response2, $this->response1);
102
+
103
+ foreach ($journal as $index => $entry) {
104
+ $this->assertEquals($requests[$index], $entry->getRequest());
105
+ $this->assertEquals($responses[$index], $entry->getResponse());
106
+ }
107
+ }
108
+
109
+ /**
110
+ * @depends testGetLastReturnsTheLastEntry
111
+ */
112
+ public function testDuration()
113
+ {
114
+ $journal = new Journal();
115
+ $journal->record($this->request1, $this->response1, 100);
116
+
117
+ $this->assertEquals($journal->getLast()->getDuration(), 100);
118
+ }
119
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Listener/HistoryListenerTest.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Listener;
4
+
5
+ use Buzz\Listener\HistoryListener;
6
+ use Buzz\Message;
7
+
8
+ class HistoryListenerTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ private $journal;
11
+ private $listener;
12
+
13
+ protected function setUp()
14
+ {
15
+ $this->journal = $this->getMockBuilder('Buzz\Listener\History\Journal')
16
+ ->disableOriginalConstructor()
17
+ ->getMock();
18
+
19
+ $this->listener = new HistoryListener($this->journal);
20
+ }
21
+
22
+ public function testHistory()
23
+ {
24
+ $request = new Message\Request();
25
+ $response = new Message\Response();
26
+
27
+ $this->journal->expects($this->once())
28
+ ->method('record')
29
+ ->with($request, $response, $this->isType('float'));
30
+
31
+ $this->listener->preSend($request);
32
+ $this->listener->postSend($request, $response);
33
+ }
34
+
35
+ public function testGetter()
36
+ {
37
+ $this->assertSame($this->journal, $this->listener->getJournal());
38
+ }
39
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Listener/ListenerChainTest.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Listener;
4
+
5
+ use Buzz\Listener\ListenerChain;
6
+ use Buzz\Message;
7
+
8
+ class ListenerChainTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ public function testListeners()
11
+ {
12
+ $listener = new ListenerChain(array($this->getMock('Buzz\Listener\ListenerInterface')));
13
+ $this->assertEquals(1, count($listener->getListeners()));
14
+
15
+ $listener->addListener($this->getMock('Buzz\Listener\ListenerInterface'));
16
+ $this->assertEquals(2, count($listener->getListeners()));
17
+ }
18
+
19
+ public function testChain()
20
+ {
21
+ $delegate = $this->getMock('Buzz\Listener\ListenerInterface');
22
+ $request = new Message\Request();
23
+ $response = new Message\Response();
24
+
25
+ $delegate->expects($this->once())
26
+ ->method('preSend')
27
+ ->with($request);
28
+ $delegate->expects($this->once())
29
+ ->method('postSend')
30
+ ->with($request, $response);
31
+
32
+ $listener = new ListenerChain(array($delegate));
33
+ $listener->preSend($request);
34
+ $listener->postSend($request, $response);
35
+ }
36
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Listener/LoggerListenerTest.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Listener;
4
+
5
+ use Buzz\Listener\LoggerListener;
6
+ use Buzz\Message;
7
+
8
+ class LoggerListenerTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ public function testLogger()
11
+ {
12
+ $test = $this;
13
+ $logger = function($line) use ($test) {
14
+ $test->assertRegExp('~^Sent "GET http://google.com/" in \d+ms$~', $line);
15
+ };
16
+
17
+ $request = new Message\Request();
18
+ $request->fromUrl('http://google.com/');
19
+ $response = new Message\Response();
20
+
21
+ $listener = new LoggerListener($logger);
22
+ $listener->preSend($request);
23
+ $listener->postSend($request, $response);
24
+ }
25
+
26
+ public function testInvalidLogger()
27
+ {
28
+ $this->setExpectedException('Buzz\Exception\InvalidArgumentException');
29
+ $listener = new LoggerListener(array(1, 2, 3));
30
+ }
31
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Message/AbstractMessageTest.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Message;
4
+
5
+ use Buzz\Message\AbstractMessage;
6
+
7
+ class Message extends AbstractMessage
8
+ {
9
+ }
10
+
11
+ class AbstractMessageTest extends \PHPUnit_Framework_TestCase
12
+ {
13
+ public function testGetHeaderGluesHeadersTogether()
14
+ {
15
+ $message = new Message();
16
+ $message->addHeader('X-My-Header: foo');
17
+ $message->addHeader('X-My-Header: bar');
18
+
19
+ $this->assertEquals('foo'."\r\n".'bar', $message->getHeader('X-My-Header'));
20
+ $this->assertEquals('foo,bar', $message->getHeader('X-My-Header', ','));
21
+ $this->assertEquals(array('foo', 'bar'), $message->getHeader('X-My-Header', false));
22
+ }
23
+
24
+ public function testGetHeaderReturnsNullIfHeaderDoesNotExist()
25
+ {
26
+ $message = new Message();
27
+
28
+ $this->assertNull($message->getHeader('X-Nonexistant'));
29
+ }
30
+
31
+ public function testGetHeaderIsCaseInsensitive()
32
+ {
33
+ $message = new Message();
34
+ $message->addHeader('X-zomg: test');
35
+
36
+ $this->assertEquals('test', $message->getHeader('X-ZOMG'));
37
+ }
38
+
39
+ public function testToStringFormatsTheMessage()
40
+ {
41
+ $message = new Message();
42
+ $message->addHeader('Foo: Bar');
43
+ $message->setContent('==CONTENT==');
44
+
45
+ $expected = "Foo: Bar\r\n\r\n==CONTENT==\r\n";
46
+
47
+ $this->assertEquals($expected, (string) $message);
48
+ }
49
+
50
+ public function testGetHeaderAttributesReturnsHeaderAttributes()
51
+ {
52
+ $message = new Message();
53
+ $message->addHeader('Content-Type: text/xml; charset=utf8');
54
+
55
+ $this->assertEquals('utf8', $message->getHeaderAttribute('Content-Type', 'charset'));
56
+ }
57
+
58
+ public function testGetNotFoundHeaderAttribute()
59
+ {
60
+ $message = new Message();
61
+ $this->assertNull($message->getHeaderAttribute('Content-Type', 'charset'));
62
+ }
63
+
64
+ public function testAddHeaders()
65
+ {
66
+ $message = new Message();
67
+ $message->addHeaders(array('Content-Type: text/xml; charset=utf8', 'Foo' => 'test'));
68
+ $message->addHeaders(array('Test' => 'foo', 'Foo' => 'test'));
69
+
70
+ $expected = array('Content-Type: text/xml; charset=utf8', 'Foo: test', 'Test: foo', 'Foo: test');
71
+ $this->assertEquals($expected, $message->getHeaders());
72
+ }
73
+
74
+ public function testSetHeaders()
75
+ {
76
+ $message = new Message();
77
+ $message->setHeaders(array('Content-Type: text/xml; charset=utf8', 'Foo' => 'test'));
78
+ $message->setHeaders(array('Test: foo', 'Foo' => 'test'));
79
+
80
+ $expected = array('Test: foo', 'Foo: test');
81
+ $this->assertEquals($expected, $message->getHeaders());
82
+ }
83
+
84
+ public function testToDomDocumentWithContentTypeTextXmlReturnsDomDocument()
85
+ {
86
+ $message = new Message();
87
+
88
+ $message->setHeaders(array('Content-Type: text/xml'));
89
+ $message->setContent('<foo><bar></bar></foo>');
90
+ $this->assertInstanceOf('DOMDocument', $message->toDomDocument());
91
+ }
92
+
93
+ public function testToDomDocumentWithContentTypeTextHtmlReturnsDomDocument()
94
+ {
95
+ $message = new Message();
96
+
97
+ $message->setHeaders(array('Content-Type: text/html'));
98
+ $message->setContent('<foo><bar></bar></foo>');
99
+ $this->assertInstanceOf('DOMDocument', $message->toDomDocument());
100
+ }
101
+
102
+ public function testToDomDocumentWithContentTypeTextXmlReturnsXmlString()
103
+ {
104
+ $message = new Message();
105
+ $expected = <<<XML
106
+ <?xml version="1.0"?>
107
+ <foo><bar/></foo>
108
+
109
+ XML;
110
+
111
+ $message->setHeaders(array('Content-Type: text/xml'));
112
+ $message->setContent('<foo><bar></bar></foo>');
113
+ $this->assertEquals($expected, $message->toDomDocument()->saveXML());
114
+ }
115
+
116
+ public function testToDomDocumentWithContentTypeTextHTMLReturnsHTMLString()
117
+ {
118
+ $message = new Message();
119
+ $expected = <<<HTML
120
+ <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
121
+ <html><body><foo><bar></bar></foo></body></html>
122
+
123
+ HTML;
124
+
125
+ $message->setHeaders(array('Content-Type: text/html'));
126
+ $message->setContent('<foo><bar></bar></foo>');
127
+ $this->assertEquals($expected, $message->toDomDocument()->saveHTML());
128
+ }
129
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Message/FactoryTest.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Message;
4
+
5
+ use Buzz\Message\Factory\Factory;
6
+ use Buzz\Message\Request;
7
+ use Buzz\Message\RequestInterface;
8
+
9
+ class FactoryTest extends \PHPUnit_Framework_TestCase
10
+ {
11
+ private $factory;
12
+
13
+ protected function setUp()
14
+ {
15
+ $this->factory = new Factory();
16
+ }
17
+
18
+ public function testCreateRequestDefaults()
19
+ {
20
+ $request = $this->factory->createRequest();
21
+
22
+ $this->assertInstanceOf('Buzz\Message\Request', $request);
23
+ $this->assertEquals(RequestInterface::METHOD_GET, $request->getMethod());
24
+ $this->assertEquals('/', $request->getResource());
25
+ $this->assertNull($request->getHost());
26
+ }
27
+
28
+ public function testCreateRequestArguments()
29
+ {
30
+ $request = $this->factory->createRequest(RequestInterface::METHOD_POST, '/foo', 'http://example.com');
31
+
32
+ $this->assertEquals(RequestInterface::METHOD_POST, $request->getMethod());
33
+ $this->assertEquals('/foo', $request->getResource());
34
+ $this->assertEquals('http://example.com', $request->getHost());
35
+ }
36
+
37
+ public function testCreateFormRequestDefaults()
38
+ {
39
+ $request = $this->factory->createFormRequest();
40
+
41
+ $this->assertInstanceOf('Buzz\Message\Form\FormRequest', $request);
42
+ $this->assertEquals(RequestInterface::METHOD_POST, $request->getMethod());
43
+ $this->assertEquals('/', $request->getResource());
44
+ $this->assertNull($request->getHost());
45
+ }
46
+
47
+ public function testCreateFormRequestArguments()
48
+ {
49
+ $request = $this->factory->createFormRequest(RequestInterface::METHOD_PUT, '/foo', 'http://example.com');
50
+
51
+ $this->assertInstanceOf('Buzz\Message\Form\FormRequest', $request);
52
+ $this->assertEquals(RequestInterface::METHOD_PUT, $request->getMethod());
53
+ $this->assertEquals('/foo', $request->getResource());
54
+ $this->assertEquals('http://example.com', $request->getHost());
55
+ }
56
+
57
+ public function testCreateResponse()
58
+ {
59
+ $this->assertInstanceOf('Buzz\Message\Response', $this->factory->createResponse());
60
+ }
61
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Message/Fixtures/google.png ADDED
Binary file
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Message/FormRequestTest.php ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Message;
4
+
5
+ use Buzz\Message\Form\FormRequest;
6
+ use Buzz\Message\Form\FormUpload;
7
+
8
+ /**
9
+ * FormRequestTest
10
+ *
11
+ * @author Marc Weistroff <marc.weistroff@sensio.com>
12
+ */
13
+ class FormRequestTest extends \PHPUnit_Framework_TestCase
14
+ {
15
+ public function testGetContentGeneratesContent()
16
+ {
17
+ $message = new FormRequest();
18
+ $message->setField('foo', 'bar');
19
+ $message->setField('bar', 'foo');
20
+
21
+ $expected = "foo=bar&bar=foo";
22
+ $this->assertEquals($expected, $message->getContent());
23
+ }
24
+
25
+ public function testAddDataAddsData()
26
+ {
27
+ $message = new FormRequest();
28
+ $message->setField('foo', 'bar');
29
+
30
+ $this->assertEquals(array('foo' => 'bar'), $message->getFields());
31
+ }
32
+
33
+ /**
34
+ * @expectedException \BadMethodCallException
35
+ */
36
+ public function testSetContentIsNotPermitted()
37
+ {
38
+ $message = new FormRequest();
39
+ $message->setContent('foobar');
40
+ }
41
+
42
+ public function testSetFields()
43
+ {
44
+ $request = new FormRequest();
45
+ $request->setFields(array('foo' => 'bar'));
46
+ $this->assertEquals(array('foo' => 'bar'), $request->getFields());
47
+ }
48
+
49
+ public function testContentType()
50
+ {
51
+ $request = new FormRequest();
52
+ $this->assertEquals('application/x-www-form-urlencoded', $request->getHeader('Content-Type'));
53
+ }
54
+
55
+ public function testDeepArray()
56
+ {
57
+ $request = new FormRequest();
58
+ $request->setField('person', array('fname' => 'John', 'lname' => 'Doe'));
59
+
60
+ $this->assertEquals('person%5Bfname%5D=John&person%5Blname%5D=Doe', $request->getContent());
61
+ }
62
+
63
+ public function testFieldPush()
64
+ {
65
+ $request = new FormRequest();
66
+ $request->setField('colors[]', 'red');
67
+ $request->setField('colors[]', 'blue');
68
+
69
+ $this->assertEquals('colors%5B0%5D=red&colors%5B1%5D=blue', $request->getContent());
70
+ }
71
+
72
+ public function testMultipartHeaders()
73
+ {
74
+ $request = new FormRequest();
75
+ $request->setField('foo', array('bar' => new FormUpload()));
76
+
77
+ $headers = $request->getHeaders();
78
+
79
+ $this->assertStringStartsWith('Content-Type: multipart/form-data; boundary=', $headers[0]);
80
+ }
81
+
82
+ public function testMultipartContent()
83
+ {
84
+ $upload = new FormUpload();
85
+ $upload->setFilename('image.jpg');
86
+ $upload->setContent('foobar');
87
+
88
+ $request = new FormRequest();
89
+ $request->setField('user[name]', 'Kris');
90
+ $request->setField('user[image]', $upload);
91
+
92
+ $content = $request->getContent();
93
+
94
+ $this->assertContains("Content-Disposition: form-data; name=\"user[name]\"\r\n\r\nKris\r\n", $content);
95
+ $this->assertContains("Content-Disposition: form-data; name=\"user[image]\"; filename=\"image.jpg\"\r\nContent-Type: text/plain\r\n\r\nfoobar\r\n", $content);
96
+ }
97
+
98
+ public function testFilenamelessUpload()
99
+ {
100
+ $this->setExpectedException('LogicException');
101
+
102
+ $upload = new FormUpload();
103
+ $upload->setContent('foobar');
104
+
105
+ $request = new FormRequest();
106
+ $request->setField('user[name]', 'Kris');
107
+ $request->setField('user[image]', $upload);
108
+
109
+ $content = $request->getContent();
110
+ }
111
+
112
+ public function testGetRequest()
113
+ {
114
+ $request = new FormRequest(FormRequest::METHOD_GET, '/search');
115
+ $request->setField('q', 'cats');
116
+
117
+ $this->assertEquals('/search?q=cats', $request->getResource());
118
+ $this->assertEmpty($request->getContent());
119
+ }
120
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Message/FormUploadTest.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Message;
4
+
5
+ use Buzz\Message\Form\FormUpload;
6
+
7
+ class FormUploadTest extends \PHPUnit_Framework_TestCase
8
+ {
9
+ public function testStringContent()
10
+ {
11
+ $upload = new FormUpload();
12
+ $upload->setName('company[logo]');
13
+ $upload->setFilename('google.png');
14
+ $upload->setContent(file_get_contents(__DIR__.'/Fixtures/google.png'));
15
+
16
+ $this->assertEquals(array(
17
+ 'Content-Disposition: form-data; name="company[logo]"; filename="google.png"',
18
+ 'Content-Type: image/png',
19
+ ), $upload->getHeaders());
20
+ }
21
+
22
+ public function testFileContent()
23
+ {
24
+ $upload = new FormUpload(__DIR__.'/Fixtures/google.png');
25
+ $upload->setName('company[logo]');
26
+
27
+ $this->assertEquals(array(
28
+ 'Content-Disposition: form-data; name="company[logo]"; filename="google.png"',
29
+ 'Content-Type: image/png',
30
+ ), $upload->getHeaders());
31
+ }
32
+
33
+ public function testContentType()
34
+ {
35
+ $upload = new FormUpload(__DIR__.'/Fixtures/google.png');
36
+ $upload->setName('company[logo]');
37
+ $upload->setContentType('foo/bar');
38
+
39
+ $this->assertEquals(array(
40
+ 'Content-Disposition: form-data; name="company[logo]"; filename="google.png"',
41
+ 'Content-Type: foo/bar',
42
+ ), $upload->getHeaders());
43
+ }
44
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Message/RequestTest.php ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Message;
4
+
5
+ use Buzz\Message\Request;
6
+
7
+ class RequestTest extends \PHPUnit_Framework_TestCase
8
+ {
9
+ public function testConstructorSetsMethodResourceAndHost()
10
+ {
11
+ $request = new Request('HEAD', '/resource/123', 'http://example.com');
12
+
13
+ $this->assertEquals('HEAD', $request->getMethod());
14
+ $this->assertEquals('/resource/123', $request->getResource());
15
+ $this->assertEquals('http://example.com', $request->getHost());
16
+ }
17
+
18
+ public function testGetUrlFormatsAUrl()
19
+ {
20
+ $request = new Request();
21
+ $request->setHost('http://example.com');
22
+ $request->setResource('/resource/123');
23
+
24
+ $this->assertEquals('http://example.com/resource/123', $request->getUrl());
25
+ }
26
+
27
+ public function testFromUrlSetsRequestValues()
28
+ {
29
+ $request = new Request();
30
+ $request->fromUrl('http://example.com/resource/123?foo=bar#foobar');
31
+
32
+ $this->assertEquals('http://example.com', $request->getHost());
33
+ $this->assertEquals('/resource/123?foo=bar', $request->getResource());
34
+ }
35
+
36
+ public function testFromUrlSetsADefaultResource()
37
+ {
38
+ $request = new Request();
39
+ $request->fromUrl('http://example.com');
40
+
41
+ $this->assertEquals('/', $request->getResource());
42
+
43
+ $request = new Request();
44
+ $request->fromUrl('http://example.com?foo=bar');
45
+
46
+ $this->assertEquals('/?foo=bar', $request->getResource());
47
+ }
48
+
49
+ public function testFromUrlSetsADefaultScheme()
50
+ {
51
+ $request = new Request();
52
+ $request->fromUrl('example.com/foo/bar');
53
+
54
+ $this->assertEquals('http://example.com', $request->getHost());
55
+ $this->assertEquals('/foo/bar', $request->getResource());
56
+ }
57
+
58
+ public function testFromUrlLeaveHostEmptyIfNoneIsProvided()
59
+ {
60
+ $request = new Request();
61
+ $request->fromUrl('/foo');
62
+
63
+ $this->assertNull($request->getHost());
64
+ }
65
+
66
+ public function testFromUrlAcceptsPort()
67
+ {
68
+ $request = new Request();
69
+ $request->fromUrl('http://localhost:3000/foo');
70
+
71
+ $this->assertEquals('http://localhost:3000', $request->getHost());
72
+ $this->assertEquals('/foo', $request->getResource());
73
+ }
74
+
75
+ public function testFromUrlRejectsInvalidUrl()
76
+ {
77
+ $this->setExpectedException('InvalidArgumentException');
78
+
79
+ // port number is too high
80
+ $request = new Request();
81
+ $request->fromUrl('http://localhost:123456');
82
+ }
83
+
84
+ public function testIsSecureChecksScheme()
85
+ {
86
+ $request = new Request('GET', '/resource/123', 'http://example.com');
87
+ $this->assertFalse($request->isSecure());
88
+
89
+ $request = new Request('GET', '/resource/123', 'https://example.com');
90
+ $this->assertTrue($request->isSecure());
91
+ }
92
+
93
+ public function testToStringFormatsTheRequest()
94
+ {
95
+ $request = new Request('POST', '/resource/123', 'http://example.com');
96
+ $request->setProtocolVersion(1.1);
97
+ $request->addHeader('Content-Type: application/x-www-form-urlencoded');
98
+ $request->setContent('foo=bar&bar=baz');
99
+
100
+ $expected = "POST /resource/123 HTTP/1.1\r\n";
101
+ $expected .= "Host: http://example.com\r\n";
102
+ $expected .= "Content-Type: application/x-www-form-urlencoded\r\n";
103
+ $expected .= "\r\n";
104
+ $expected .= "foo=bar&bar=baz\r\n";
105
+
106
+ $this->assertEquals($expected, (string) $request);
107
+ }
108
+
109
+ public function testMethodIsAlwaysUppercased()
110
+ {
111
+ $request = new Request('post', '/resource/123', 'http://example.com');
112
+
113
+ $this->assertEquals('POST', $request->getMethod());
114
+ }
115
+
116
+ public function testSetMethod()
117
+ {
118
+ $request = new Request();
119
+ $request->setMethod('get');
120
+ $this->assertEquals('GET', $request->getMethod());
121
+ }
122
+
123
+ public function testCookieMerge()
124
+ {
125
+ $request = new Request();
126
+ $request->addHeader('Cookie: foo=bar');
127
+ $request->addHeader('Content-Type: text/plain');
128
+ $request->addHeader('Cookie: bar=foo');
129
+
130
+ $this->assertEquals(array(
131
+ 'Cookie: foo=bar; bar=foo',
132
+ 'Content-Type: text/plain',
133
+ ), $request->getHeaders());
134
+
135
+ $expected = "GET / HTTP/1.0\r\n";
136
+ $expected .= "Cookie: foo=bar; bar=foo\r\n";
137
+ $expected .= "Content-Type: text/plain\r\n";
138
+
139
+ $this->assertEquals($expected, (string) $request);
140
+ }
141
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Message/ResponseTest.php ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Message;
4
+
5
+ use Buzz\Message\Response;
6
+
7
+ class ResponseTest extends \PHPUnit_Framework_TestCase
8
+ {
9
+ public function testGetProtocolVersionReturnsTheProtocolVersion()
10
+ {
11
+ $response = new Response();
12
+
13
+ $this->assertNull($response->getProtocolVersion());
14
+
15
+ $response->addHeader('HTTP/1.0 200 OK');
16
+
17
+ $this->assertEquals(1.0, $response->getProtocolVersion());
18
+ }
19
+
20
+ public function testGetStatusCodeReturnsTheStatusCode()
21
+ {
22
+ $response = new Response();
23
+
24
+ $this->assertNull($response->getStatusCode());
25
+
26
+ $response->addHeader('HTTP/1.0 200 OK');
27
+
28
+ $this->assertEquals(200, $response->getStatusCode());
29
+ }
30
+
31
+ public function testGetReasonPhraseReturnsTheReasonPhrase()
32
+ {
33
+ $response = new Response();
34
+
35
+ $this->assertEquals($response->getReasonPhrase(), null);
36
+
37
+ $response->addHeader('HTTP/1.0 200 OK');
38
+
39
+ $this->assertEquals('OK', $response->getReasonPhrase());
40
+ }
41
+
42
+ public function testGetReasonPhraseReturnsAMultiwordReasonPhrase()
43
+ {
44
+ $response = new Response();
45
+
46
+ $this->assertNull($response->getReasonPhrase());
47
+
48
+ $response->addHeader('HTTP/1.0 500 Internal Server Error');
49
+
50
+ $this->assertEquals('Internal Server Error', $response->getReasonPhrase());
51
+ }
52
+
53
+ public function testAddHeadersResetsStatusLine()
54
+ {
55
+ $response = new Response();
56
+ $this->assertNull($response->getStatusCode());
57
+ $response->addHeaders(array('HTTP/1.0 200 OK'));
58
+ $this->assertEquals(200, $response->getStatusCode());
59
+ }
60
+
61
+ /**
62
+ * @dataProvider statusProvider
63
+ *
64
+ *
65
+ */
66
+ public function testIssers($code, $method, $expected)
67
+ {
68
+ $response = new Response();
69
+ $response->addHeaders(array('HTTP/1.0 '.$code.' Status'));
70
+ $this->assertEquals($expected, $response->{$method}());
71
+ }
72
+
73
+ public function statusProvider()
74
+ {
75
+ return array(
76
+ array(50, 'isInvalid', true),
77
+ array(700, 'isInvalid', true),
78
+ array(100, 'isInvalid', false),
79
+
80
+ array(100, 'isInformational', true),
81
+ array(199, 'isInformational', true),
82
+ array(200, 'isInformational', false),
83
+
84
+ array(200, 'isSuccessful', true),
85
+ array(299, 'isSuccessful', true),
86
+ array(300, 'isSuccessful', false),
87
+
88
+ array(301, 'isRedirection', true),
89
+ array(302, 'isRedirection', true),
90
+ array(400, 'isRedirection', false),
91
+
92
+ array(404, 'isClientError', true),
93
+ array(401, 'isClientError', true),
94
+ array(500, 'isClientError', false),
95
+
96
+ array(500, 'isServerError', true),
97
+ array(400, 'isServerError', false),
98
+
99
+ array(200, 'isOk', true),
100
+ array(201, 'isOk', false),
101
+
102
+ array(403, 'isForbidden', true),
103
+ array(404, 'isForbidden', false),
104
+
105
+ array(404, 'isNotFound', true),
106
+ array(403, 'isNotFound', false),
107
+
108
+ array(201, 'isEmpty', true),
109
+ array(204, 'isEmpty', true),
110
+ array(304, 'isEmpty', true),
111
+ array(203, 'isEmpty', false),
112
+ );
113
+ }
114
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Util/CookieJarTest.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Cookie;
4
+
5
+ use Buzz\Util\Cookie;
6
+ use Buzz\Util\CookieJar;
7
+ use Buzz\Message;
8
+
9
+ class CookieJarTest extends \PHPUnit_Framework_TestCase
10
+ {
11
+ public function testProcessSetCookieHeadersSetsCookies()
12
+ {
13
+ $request = new Message\Request();
14
+ $request->setHost('http://www.example.com');
15
+
16
+ $response = new Message\Response();
17
+ $response->addHeader('Set-Cookie: SESSION2=qwerty');
18
+ $response->addHeader('Set-Cookie: SESSION1=asdf');
19
+
20
+ $jar = new CookieJar();
21
+ $jar->processSetCookieHeaders($request, $response);
22
+
23
+ $cookies = $jar->getCookies();
24
+
25
+ $this->assertEquals(2, count($cookies));
26
+ foreach ($cookies as $cookie) {
27
+ $this->assertEquals('www.example.com', $cookie->getAttribute(Cookie::ATTR_DOMAIN));
28
+ $this->assertTrue(in_array($cookie->getName(), array('SESSION1', 'SESSION2')));
29
+ }
30
+ }
31
+
32
+ public function testAddCookieHeadersAddsCookieHeaders()
33
+ {
34
+ $request = new Message\Request();
35
+ $request->setHost('http://www.example.com');
36
+
37
+ $cookie = new Cookie();
38
+ $cookie->setName('SESSION');
39
+ $cookie->setValue('asdf');
40
+ $cookie->setAttribute(Cookie::ATTR_DOMAIN, '.example.com');
41
+
42
+ $jar = new CookieJar();
43
+ $jar->setCookies(array($cookie));
44
+ $jar->addCookieHeaders($request);
45
+
46
+ $this->assertEquals('SESSION=asdf', $request->getHeader('Cookie'));
47
+ }
48
+
49
+ public function testClearExpiredCookiesRemovesExpiredCookies()
50
+ {
51
+ $cookie = new Cookie();
52
+ $cookie->setName('SESSION');
53
+ $cookie->setValue('asdf');
54
+ $cookie->setAttribute(Cookie::ATTR_EXPIRES, 'Fri, 01-Dec-1999 00:00:00 GMT');
55
+
56
+ $jar = new CookieJar();
57
+ $jar->addCookie($cookie);
58
+ $jar->clearExpiredCookies();
59
+
60
+ $this->assertEquals(0, count($jar->getCookies()));
61
+
62
+ $cookie = new Cookie();
63
+ $cookie->setName('SESSION');
64
+ $cookie->setValue('asdf');
65
+ $cookie->setAttribute(Cookie::ATTR_MAX_AGE, '-60');
66
+
67
+ $jar = new CookieJar();
68
+ $jar->addCookie($cookie);
69
+ $jar->clearExpiredCookies();
70
+
71
+ $this->assertEquals(0, count($jar->getCookies()));
72
+ }
73
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Util/CookieTest.php ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Cookie;
4
+
5
+ use Buzz\Util\Cookie;
6
+ use Buzz\Message;
7
+
8
+ class CookieTest extends \PHPUnit_Framework_TestCase
9
+ {
10
+ public function testFromSetCookieHeaderSetsCookieAttributes()
11
+ {
12
+ $cookie = new Cookie();
13
+ $cookie->fromSetCookieHeader('SESSION=asdf; expires='.date('r', strtotime('2000-01-01 00:00:00')).'; path=/; domain=.example.com; secure', 'www.example.com');
14
+
15
+ $this->assertEquals('SESSION', $cookie->getName());
16
+ $this->assertEquals('asdf', $cookie->getValue());
17
+ $this->assertEquals(array(
18
+ 'expires' => date('r', strtotime('2000-01-01 00:00:00')),
19
+ 'path' => '/',
20
+ 'domain' => '.example.com',
21
+ 'secure' => null,
22
+ ), $cookie->getAttributes());
23
+ }
24
+
25
+ public function testFromSetCookieHeaderFallsBackToIssuingDomain()
26
+ {
27
+ $cookie = new Cookie();
28
+ $cookie->fromSetCookieHeader('SESSION=asdf', 'example.com');
29
+
30
+ $this->assertEquals('example.com', $cookie->getAttribute(Cookie::ATTR_DOMAIN));
31
+ }
32
+
33
+ public function testToCookieHeaderFormatsACookieHeader()
34
+ {
35
+ $cookie = new Cookie();
36
+ $cookie->setName('SESSION');
37
+ $cookie->setValue('asdf');
38
+
39
+ $this->assertEquals('Cookie: SESSION=asdf', $cookie->toCookieHeader());
40
+ }
41
+
42
+ public function testMatchesDomainMatchesSimpleDomains()
43
+ {
44
+ $cookie = new Cookie();
45
+ $cookie->setAttribute('domain', 'nytimes.com');
46
+
47
+ $this->assertTrue($cookie->matchesDomain('nytimes.com'));
48
+ $this->assertFalse($cookie->matchesDomain('google.com'));
49
+ }
50
+
51
+ public function testMatchesDomainMatchesSubdomains()
52
+ {
53
+ $cookie = new Cookie();
54
+ $cookie->setAttribute('domain', '.nytimes.com');
55
+
56
+ $this->assertTrue($cookie->matchesDomain('nytimes.com'));
57
+ $this->assertTrue($cookie->matchesDomain('blogs.nytimes.com'));
58
+ $this->assertFalse($cookie->matchesDomain('google.com'));
59
+ }
60
+
61
+ public function testIsExpiredChecksMaxAge()
62
+ {
63
+ $cookie = new Cookie();
64
+ $cookie->setAttribute('max-age', 60);
65
+
66
+ $this->assertFalse($cookie->isExpired());
67
+
68
+ $cookie = new Cookie();
69
+ $cookie->setCreatedAt(strtotime('-1 hour'));
70
+ $cookie->setAttribute('max-age', 60);
71
+
72
+ $this->assertTrue($cookie->isExpired());
73
+ }
74
+
75
+ public function testIsExpiredChecksExpires()
76
+ {
77
+ $cookie = new Cookie();
78
+ $cookie->setAttribute('expires', date('r', strtotime('+1 week')));
79
+
80
+ $this->assertFalse($cookie->isExpired());
81
+
82
+ $cookie = new Cookie();
83
+ $cookie->setAttribute('expires', date('r', strtotime('-1 month')));
84
+
85
+ $this->assertTrue($cookie->isExpired());
86
+ }
87
+
88
+ public function testMatchesPathChecksPath()
89
+ {
90
+ $cookie = new Cookie();
91
+ $cookie->setAttribute('path', '/resource');
92
+
93
+ $this->assertTrue($cookie->matchesPath('/resource/123'));
94
+ $this->assertFalse($cookie->matchesPath('/login'));
95
+
96
+ $cookie = new Cookie();
97
+ $this->assertTrue($cookie->matchesPath('/resource/123'));
98
+ }
99
+
100
+ public function testMatchesRequestChecksDomain()
101
+ {
102
+ $request = new Message\Request();
103
+ $request->setHost('http://example.com');
104
+
105
+ $cookie = new Cookie();
106
+ $cookie->setAttribute(Cookie::ATTR_DOMAIN, 'example.com');
107
+
108
+ $this->assertTrue($cookie->matchesRequest($request));
109
+
110
+ $cookie = new Cookie();
111
+ $cookie->setAttribute(Cookie::ATTR_DOMAIN, 'foo.com');
112
+
113
+ $this->assertFalse($cookie->matchesRequest($request));
114
+ }
115
+
116
+ public function testMatchesRequestChecksPath()
117
+ {
118
+ $request = new Message\Request();
119
+ $request->setHost('http://example.com');
120
+ $request->setResource('/foo/bar');
121
+
122
+ $cookie = new Cookie();
123
+ $cookie->setAttribute(Cookie::ATTR_DOMAIN, 'example.com');
124
+ $cookie->setAttribute(Cookie::ATTR_PATH, '/foo');
125
+
126
+ $this->assertTrue($cookie->matchesRequest($request));
127
+
128
+ $cookie = new Cookie();
129
+ $cookie->setAttribute(Cookie::ATTR_DOMAIN, 'example.com');
130
+ $cookie->setAttribute(Cookie::ATTR_PATH, '/foo/bar/baz');
131
+
132
+ $this->assertFalse($cookie->matchesRequest($request));
133
+ }
134
+
135
+ public function testMatchesRequestChecksSecureAttribute()
136
+ {
137
+ $request = new Message\Request();
138
+ $request->setHost('https://example.com');
139
+
140
+ $cookie = new Cookie();
141
+ $cookie->setAttribute(Cookie::ATTR_DOMAIN, 'example.com');
142
+ $cookie->setAttribute(Cookie::ATTR_SECURE, null);
143
+
144
+ $this->assertTrue($cookie->matchesRequest($request));
145
+
146
+ $request = new Message\Request();
147
+ $request->setHost('http://example.com');
148
+
149
+ $this->assertFalse($cookie->matchesRequest($request));
150
+ }
151
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/Buzz/Test/Util/UrlTest.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Buzz\Test\Util;
4
+
5
+ use Buzz\Util\Url;
6
+
7
+ class UrlTest extends \PHPUnit_Framework_TestCase
8
+ {
9
+ /**
10
+ * @dataProvider provideUrlAndHost
11
+ */
12
+ public function testGetHost($urlStr, $host, $resource)
13
+ {
14
+ $url = new Url($urlStr);
15
+ $this->assertEquals($host, $url->getHost());
16
+ $this->assertEquals($resource, $url->getResource());
17
+ }
18
+
19
+ public function provideUrlAndHost()
20
+ {
21
+ return array(
22
+ array('https://example.com/resource/123?foo=bar#foobar', 'https://example.com', '/resource/123?foo=bar'),
23
+ array('http://example.com', 'http://example.com', '/'),
24
+ array('http://example.com?foo=bar', 'http://example.com', '/?foo=bar'),
25
+ array('example.com/foo/bar', 'http://example.com', '/foo/bar'),
26
+ array('/foo', null, '/foo'),
27
+ array('http://localhost:3000/foo', 'http://localhost:3000', '/foo'),
28
+ );
29
+ }
30
+
31
+ public function testInvalidUrl()
32
+ {
33
+ $this->setExpectedException('InvalidArgumentException');
34
+ new Url('http://localhost:123456');
35
+ }
36
+
37
+ /**
38
+ * @dataProvider providePattern
39
+ */
40
+ public function testFormat($input, $pattern, $expected)
41
+ {
42
+ $url = new Url($input);
43
+ $this->assertEquals($expected, $url->format($pattern));
44
+ }
45
+
46
+ public function providePattern()
47
+ {
48
+ $full = 'http://foo:bar@example.com:123/asdf?tweedle=dee#dum';
49
+ $host = 'example.com';
50
+
51
+ return array(
52
+ array($full, 's://u:a@h:op?q#f', 'http://foo:bar@example.com:123/asdf?tweedle=dee#dum'),
53
+ array($full, 'HR', 'http://example.com:123/asdf?tweedle=dee'),
54
+ array($host, 'HR', 'http://example.com/'),
55
+ );
56
+ }
57
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/etc/nginx.conf ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ events {
2
+ worker_connections 1024;
3
+ }
4
+
5
+ http {
6
+ keepalive_timeout 65;
7
+
8
+ fastcgi_connect_timeout 60;
9
+ fastcgi_send_timeout 180;
10
+ fastcgi_read_timeout 180;
11
+ fastcgi_buffer_size 32k;
12
+ fastcgi_buffers 16 16k;
13
+ fastcgi_intercept_errors on;
14
+
15
+ upstream php {
16
+ server 127.0.0.1:9000;
17
+ }
18
+
19
+ access_log /var/log/nginx/access.log;
20
+ error_log /var/log/nginx/error.log;
21
+
22
+ server {
23
+ listen 8080 default_server;
24
+ server_name .localhost;
25
+
26
+ charset utf-8;
27
+
28
+ root .;
29
+
30
+ location ~ \.php$ {
31
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
32
+
33
+ fastcgi_param QUERY_STRING $query_string;
34
+ fastcgi_param REQUEST_METHOD $request_method;
35
+ fastcgi_param CONTENT_TYPE $content_type if_not_empty;
36
+
37
+ fastcgi_param CONTENT_LENGTH $content_length;
38
+
39
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
40
+ fastcgi_param SCRIPT_NAME $fastcgi_script_name;
41
+ fastcgi_param REQUEST_URI $request_uri;
42
+ fastcgi_param DOCUMENT_URI $document_uri;
43
+ fastcgi_param DOCUMENT_ROOT $document_root;
44
+ fastcgi_param SERVER_PROTOCOL $server_protocol;
45
+
46
+ fastcgi_pass php;
47
+ }
48
+ }
49
+ }
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/etc/squid.conf ADDED
@@ -0,0 +1,2 @@
 
 
1
+ http_access allow all
2
+ http_port 3128
app/code/community/Expressly/Expressly/vendor/kriswallsmith/buzz/test/server.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (isset($_GET['redirect_to'])) {
4
+ header('Location: '.$_GET['redirect_to']);
5
+ die;
6
+ }
7
+
8
+ if (isset($_GET['delay'])) {
9
+ sleep($_GET['delay']);
10
+ }
11
+
12
+ echo json_encode(array(
13
+ 'SERVER' => $_SERVER,
14
+ 'GET' => $_GET,
15
+ 'POST' => $_POST,
16
+ 'FILES' => $_FILES,
17
+ 'INPUT' => file_get_contents('php://input'),
18
+ ));
app/code/community/Expressly/Expressly/vendor/monolog/monolog/.php_cs ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $finder = Symfony\CS\Finder\DefaultFinder::create()
4
+ ->files()
5
+ ->name('*.php')
6
+ ->in(__DIR__.'/src')
7
+ ->in(__DIR__.'/tests')
8
+ ;
9
+
10
+ return Symfony\CS\Config\Config::create()
11
+ ->fixers(array(
12
+ 'psr0', 'encoding', 'short_tag', 'braces', 'elseif', 'eof_ending', 'function_declaration', 'indentation', 'line_after_namespace', 'linefeed', 'lowercase_constants', 'lowercase_keywords', 'multiple_use', 'php_closing_tag', 'trailing_spaces', 'visibility', 'duplicate_semicolon', 'extra_empty_lines', 'include', 'namespace_no_leading_whitespace', 'object_operator', 'operators_spaces', 'phpdoc_params', 'return', 'single_array_no_trailing_comma', 'spaces_cast', 'standardize_not_equal', 'ternary_spaces', 'unused_use', 'whitespacy_lines',
13
+ ))
14
+ ->finder($finder)
15
+ ;
app/code/community/Expressly/Expressly/vendor/monolog/monolog/CHANGELOG.mdown ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ### 1.13.1 (2015-03-09)
2
+
3
+ * Fixed regression in HipChat requiring a new token to be created
4
+
5
+ ### 1.13.0 (2015-03-05)
6
+
7
+ * Added Registry::hasLogger to check for the presence of a logger instance
8
+ * Added context.user support to RavenHandler
9
+ * Added HipChat API v2 support in the HipChatHandler
10
+ * Added NativeMailerHandler::addParameter to pass params to the mail() process
11
+ * Added context data to SlackHandler when $includeContextAndExtra is true
12
+ * Added ability to customize the Swift_Message per-email in SwiftMailerHandler
13
+ * Fixed SwiftMailerHandler to lazily create message instances if a callback is provided
14
+ * Fixed serialization of INF and NaN values in Normalizer and LineFormatter
15
+
16
+ ### 1.12.0 (2014-12-29)
17
+
18
+ * Break: HandlerInterface::isHandling now receives a partial record containing only a level key. This was always the intent and does not break any Monolog handler but is strictly speaking a BC break and you should check if you relied on any other field in your own handlers.
19
+ * Added PsrHandler to forward records to another PSR-3 logger
20
+ * Added SamplingHandler to wrap around a handler and include only every Nth record
21
+ * Added MongoDBFormatter to support better storage with MongoDBHandler (it must be enabled manually for now)
22
+ * Added exception codes in the output of most formatters
23
+ * Added LineFormatter::includeStacktraces to enable exception stack traces in logs (uses more than one line)
24
+ * Added $useShortAttachment to SlackHandler to minify attachment size and $includeExtra to append extra data
25
+ * Added $host to HipChatHandler for users of private instances
26
+ * Added $transactionName to NewRelicHandler and support for a transaction_name context value
27
+ * Fixed MandrillHandler to avoid outputing API call responses
28
+ * Fixed some non-standard behaviors in SyslogUdpHandler
29
+
30
+ ### 1.11.0 (2014-09-30)
31
+
32
+ * Break: The NewRelicHandler extra and context data are now prefixed with extra_ and context_ to avoid clashes. Watch out if you have scripts reading those from the API and rely on names
33
+ * Added WhatFailureGroupHandler to suppress any exception coming from the wrapped handlers and avoid chain failures if a logging service fails
34
+ * Added MandrillHandler to send emails via the Mandrillapp.com API
35
+ * Added SlackHandler to log records to a Slack.com account
36
+ * Added FleepHookHandler to log records to a Fleep.io account
37
+ * Added LogglyHandler::addTag to allow adding tags to an existing handler
38
+ * Added $ignoreEmptyContextAndExtra to LineFormatter to avoid empty [] at the end
39
+ * Added $useLocking to StreamHandler and RotatingFileHandler to enable flock() while writing
40
+ * Added support for PhpAmqpLib in the AmqpHandler
41
+ * Added FingersCrossedHandler::clear and BufferHandler::clear to reset them between batches in long running jobs
42
+ * Added support for adding extra fields from $_SERVER in the WebProcessor
43
+ * Fixed support for non-string values in PrsLogMessageProcessor
44
+ * Fixed SwiftMailer messages being sent with the wrong date in long running scripts
45
+ * Fixed minor PHP 5.6 compatibility issues
46
+ * Fixed BufferHandler::close being called twice
47
+
48
+ ### 1.10.0 (2014-06-04)
49
+
50
+ * Added Logger::getHandlers() and Logger::getProcessors() methods
51
+ * Added $passthruLevel argument to FingersCrossedHandler to let it always pass some records through even if the trigger level is not reached
52
+ * Added support for extra data in NewRelicHandler
53
+ * Added $expandNewlines flag to the ErrorLogHandler to create multiple log entries when a message has multiple lines
54
+
55
+ ### 1.9.1 (2014-04-24)
56
+
57
+ * Fixed regression in RotatingFileHandler file permissions
58
+ * Fixed initialization of the BufferHandler to make sure it gets flushed after receiving records
59
+ * Fixed ChromePHPHandler and FirePHPHandler's activation strategies to be more conservative
60
+
61
+ ### 1.9.0 (2014-04-20)
62
+
63
+ * Added LogEntriesHandler to send logs to a LogEntries account
64
+ * Added $filePermissions to tweak file mode on StreamHandler and RotatingFileHandler
65
+ * Added $useFormatting flag to MemoryProcessor to make it send raw data in bytes
66
+ * Added support for table formatting in FirePHPHandler via the table context key
67
+ * Added a TagProcessor to add tags to records, and support for tags in RavenHandler
68
+ * Added $appendNewline flag to the JsonFormatter to enable using it when logging to files
69
+ * Added sound support to the PushoverHandler
70
+ * Fixed multi-threading support in StreamHandler
71
+ * Fixed empty headers issue when ChromePHPHandler received no records
72
+ * Fixed default format of the ErrorLogHandler
73
+
74
+ ### 1.8.0 (2014-03-23)
75
+
76
+ * Break: the LineFormatter now strips newlines by default because this was a bug, set $allowInlineLineBreaks to true if you need them
77
+ * Added BrowserConsoleHandler to send logs to any browser's console via console.log() injection in the output
78
+ * Added FilterHandler to filter records and only allow those of a given list of levels through to the wrapped handler
79
+ * Added FlowdockHandler to send logs to a Flowdock account
80
+ * Added RollbarHandler to send logs to a Rollbar account
81
+ * Added HtmlFormatter to send prettier log emails with colors for each log level
82
+ * Added GitProcessor to add the current branch/commit to extra record data
83
+ * Added a Monolog\Registry class to allow easier global access to pre-configured loggers
84
+ * Added support for the new official graylog2/gelf-php lib for GelfHandler, upgrade if you can by replacing the mlehner/gelf-php requirement
85
+ * Added support for HHVM
86
+ * Added support for Loggly batch uploads
87
+ * Added support for tweaking the content type and encoding in NativeMailerHandler
88
+ * Added $skipClassesPartials to tweak the ignored classes in the IntrospectionProcessor
89
+ * Fixed batch request support in GelfHandler
90
+
91
+ ### 1.7.0 (2013-11-14)
92
+
93
+ * Added ElasticSearchHandler to send logs to an Elastic Search server
94
+ * Added DynamoDbHandler and ScalarFormatter to send logs to Amazon's Dynamo DB
95
+ * Added SyslogUdpHandler to send logs to a remote syslogd server
96
+ * Added LogglyHandler to send logs to a Loggly account
97
+ * Added $level to IntrospectionProcessor so it only adds backtraces when needed
98
+ * Added $version to LogstashFormatter to allow using the new v1 Logstash format
99
+ * Added $appName to NewRelicHandler
100
+ * Added configuration of Pushover notification retries/expiry
101
+ * Added $maxColumnWidth to NativeMailerHandler to change the 70 chars default
102
+ * Added chainability to most setters for all handlers
103
+ * Fixed RavenHandler batch processing so it takes the message from the record with highest priority
104
+ * Fixed HipChatHandler batch processing so it sends all messages at once
105
+ * Fixed issues with eAccelerator
106
+ * Fixed and improved many small things
107
+
108
+ ### 1.6.0 (2013-07-29)
109
+
110
+ * Added HipChatHandler to send logs to a HipChat chat room
111
+ * Added ErrorLogHandler to send logs to PHP's error_log function
112
+ * Added NewRelicHandler to send logs to NewRelic's service
113
+ * Added Monolog\ErrorHandler helper class to register a Logger as exception/error/fatal handler
114
+ * Added ChannelLevelActivationStrategy for the FingersCrossedHandler to customize levels by channel
115
+ * Added stack traces output when normalizing exceptions (json output & co)
116
+ * Added Monolog\Logger::API constant (currently 1)
117
+ * Added support for ChromePHP's v4.0 extension
118
+ * Added support for message priorities in PushoverHandler, see $highPriorityLevel and $emergencyLevel
119
+ * Added support for sending messages to multiple users at once with the PushoverHandler
120
+ * Fixed RavenHandler's support for batch sending of messages (when behind a Buffer or FingersCrossedHandler)
121
+ * Fixed normalization of Traversables with very large data sets, only the first 1000 items are shown now
122
+ * Fixed issue in RotatingFileHandler when an open_basedir restriction is active
123
+ * Fixed minor issues in RavenHandler and bumped the API to Raven 0.5.0
124
+ * Fixed SyslogHandler issue when many were used concurrently with different facilities
125
+
126
+ ### 1.5.0 (2013-04-23)
127
+
128
+ * Added ProcessIdProcessor to inject the PID in log records
129
+ * Added UidProcessor to inject a unique identifier to all log records of one request/run
130
+ * Added support for previous exceptions in the LineFormatter exception serialization
131
+ * Added Monolog\Logger::getLevels() to get all available levels
132
+ * Fixed ChromePHPHandler so it avoids sending headers larger than Chrome can handle
133
+
134
+ ### 1.4.1 (2013-04-01)
135
+
136
+ * Fixed exception formatting in the LineFormatter to be more minimalistic
137
+ * Fixed RavenHandler's handling of context/extra data, requires Raven client >0.1.0
138
+ * Fixed log rotation in RotatingFileHandler to work with long running scripts spanning multiple days
139
+ * Fixed WebProcessor array access so it checks for data presence
140
+ * Fixed Buffer, Group and FingersCrossed handlers to make use of their processors
141
+
142
+ ### 1.4.0 (2013-02-13)
143
+
144
+ * Added RedisHandler to log to Redis via the Predis library or the phpredis extension
145
+ * Added ZendMonitorHandler to log to the Zend Server monitor
146
+ * Added the possibility to pass arrays of handlers and processors directly in the Logger constructor
147
+ * Added `$useSSL` option to the PushoverHandler which is enabled by default
148
+ * Fixed ChromePHPHandler and FirePHPHandler issue when multiple instances are used simultaneously
149
+ * Fixed header injection capability in the NativeMailHandler
150
+
151
+ ### 1.3.1 (2013-01-11)
152
+
153
+ * Fixed LogstashFormatter to be usable with stream handlers
154
+ * Fixed GelfMessageFormatter levels on Windows
155
+
156
+ ### 1.3.0 (2013-01-08)
157
+
158
+ * Added PSR-3 compliance, the `Monolog\Logger` class is now an instance of `Psr\Log\LoggerInterface`
159
+ * Added PsrLogMessageProcessor that you can selectively enable for full PSR-3 compliance
160
+ * Added LogstashFormatter (combine with SocketHandler or StreamHandler to send logs to Logstash)
161
+ * Added PushoverHandler to send mobile notifications
162
+ * Added CouchDBHandler and DoctrineCouchDBHandler
163
+ * Added RavenHandler to send data to Sentry servers
164
+ * Added support for the new MongoClient class in MongoDBHandler
165
+ * Added microsecond precision to log records' timestamps
166
+ * Added `$flushOnOverflow` param to BufferHandler to flush by batches instead of losing
167
+ the oldest entries
168
+ * Fixed normalization of objects with cyclic references
169
+
170
+ ### 1.2.1 (2012-08-29)
171
+
172
+ * Added new $logopts arg to SyslogHandler to provide custom openlog options
173
+ * Fixed fatal error in SyslogHandler
174
+
175
+ ### 1.2.0 (2012-08-18)
176
+
177
+ * Added AmqpHandler (for use with AMQP servers)
178
+ * Added CubeHandler
179
+ * Added NativeMailerHandler::addHeader() to send custom headers in mails
180
+ * Added the possibility to specify more than one recipient in NativeMailerHandler
181
+ * Added the possibility to specify float timeouts in SocketHandler
182
+ * Added NOTICE and EMERGENCY levels to conform with RFC 5424
183
+ * Fixed the log records to use the php default timezone instead of UTC
184
+ * Fixed BufferHandler not being flushed properly on PHP fatal errors
185
+ * Fixed normalization of exotic resource types
186
+ * Fixed the default format of the SyslogHandler to avoid duplicating datetimes in syslog
187
+
188
+ ### 1.1.0 (2012-04-23)
189
+
190
+ * Added Monolog\Logger::isHandling() to check if a handler will
191
+ handle the given log level
192
+ * Added ChromePHPHandler
193
+ * Added MongoDBHandler
194
+ * Added GelfHandler (for use with Graylog2 servers)
195
+ * Added SocketHandler (for use with syslog-ng for example)
196
+ * Added NormalizerFormatter
197
+ * Added the possibility to change the activation strategy of the FingersCrossedHandler
198
+ * Added possibility to show microseconds in logs
199
+ * Added `server` and `referer` to WebProcessor output
200
+
201
+ ### 1.0.2 (2011-10-24)
202
+
203
+ * Fixed bug in IE with large response headers and FirePHPHandler
204
+
205
+ ### 1.0.1 (2011-08-25)
206
+
207
+ * Added MemoryPeakUsageProcessor and MemoryUsageProcessor
208
+ * Added Monolog\Logger::getName() to get a logger's channel name
209
+
210
+ ### 1.0.0 (2011-07-06)
211
+
212
+ * Added IntrospectionProcessor to get info from where the logger was called
213
+ * Fixed WebProcessor in CLI
214
+
215
+ ### 1.0.0-RC1 (2011-07-01)
216
+
217
+ * Initial release
app/code/community/Expressly/Expressly/vendor/monolog/monolog/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2011-2014 Jordi Boggiano
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
app/code/community/Expressly/Expressly/vendor/monolog/monolog/README.mdown ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Monolog - Logging for PHP 5.3+ [![Build Status](https://secure.travis-ci.org/Seldaek/monolog.png)](http://travis-ci.org/Seldaek/monolog)
2
+ ==============================
3
+
4
+ [![Total Downloads](https://poser.pugx.org/monolog/monolog/downloads.png)](https://packagist.org/packages/monolog/monolog)
5
+ [![Latest Stable Version](https://poser.pugx.org/monolog/monolog/v/stable.png)](https://packagist.org/packages/monolog/monolog)
6
+ [![Reference Status](https://www.versioneye.com/php/monolog:monolog/reference_badge.svg)](https://www.versioneye.com/php/monolog:monolog/references)
7
+
8
+
9
+ Monolog sends your logs to files, sockets, inboxes, databases and various
10
+ web services. See the complete list of handlers below. Special handlers
11
+ allow you to build advanced logging strategies.
12
+
13
+ This library implements the [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
14
+ interface that you can type-hint against in your own libraries to keep
15
+ a maximum of interoperability. You can also use it in your applications to
16
+ make sure you can always use another compatible logger at a later time.
17
+ As of 1.11.0 Monolog public APIs will also accept PSR-3 log levels.
18
+ Internally Monolog still uses its own level scheme since it predates PSR-3.
19
+
20
+ Usage
21
+ -----
22
+
23
+ Install the latest version with `composer require monolog/monolog`
24
+
25
+ ```php
26
+ <?php
27
+
28
+ use Monolog\Logger;
29
+ use Monolog\Handler\StreamHandler;
30
+
31
+ // create a log channel
32
+ $log = new Logger('name');
33
+ $log->pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING));
34
+
35
+ // add records to the log
36
+ $log->addWarning('Foo');
37
+ $log->addError('Bar');
38
+ ```
39
+
40
+ Core Concepts
41
+ -------------
42
+
43
+ Every `Logger` instance has a channel (name) and a stack of handlers. Whenever
44
+ you add a record to the logger, it traverses the handler stack. Each handler
45
+ decides whether it fully handled the record, and if so, the propagation of the
46
+ record ends there.
47
+
48
+ This allows for flexible logging setups, for example having a `StreamHandler` at
49
+ the bottom of the stack that will log anything to disk, and on top of that add
50
+ a `MailHandler` that will send emails only when an error message is logged.
51
+ Handlers also have a `$bubble` property which defines whether they block the
52
+ record or not if they handled it. In this example, setting the `MailHandler`'s
53
+ `$bubble` argument to false means that records handled by the `MailHandler` will
54
+ not propagate to the `StreamHandler` anymore.
55
+
56
+ You can create many `Logger`s, each defining a channel (e.g.: db, request,
57
+ router, ..) and each of them combining various handlers, which can be shared
58
+ or not. The channel is reflected in the logs and allows you to easily see or
59
+ filter records.
60
+
61
+ Each Handler also has a Formatter, a default one with settings that make sense
62
+ will be created if you don't set one. The formatters normalize and format
63
+ incoming records so that they can be used by the handlers to output useful
64
+ information.
65
+
66
+ Custom severity levels are not available. Only the eight
67
+ [RFC 5424](http://tools.ietf.org/html/rfc5424) levels (debug, info, notice,
68
+ warning, error, critical, alert, emergency) are present for basic filtering
69
+ purposes, but for sorting and other use cases that would require
70
+ flexibility, you should add Processors to the Logger that can add extra
71
+ information (tags, user ip, ..) to the records before they are handled.
72
+
73
+ Log Levels
74
+ ----------
75
+
76
+ Monolog supports the logging levels described by [RFC 5424](http://tools.ietf.org/html/rfc5424).
77
+
78
+ - **DEBUG** (100): Detailed debug information.
79
+
80
+ - **INFO** (200): Interesting events. Examples: User logs in, SQL logs.
81
+
82
+ - **NOTICE** (250): Normal but significant events.
83
+
84
+ - **WARNING** (300): Exceptional occurrences that are not errors. Examples:
85
+ Use of deprecated APIs, poor use of an API, undesirable things that are not
86
+ necessarily wrong.
87
+
88
+ - **ERROR** (400): Runtime errors that do not require immediate action but
89
+ should typically be logged and monitored.
90
+
91
+ - **CRITICAL** (500): Critical conditions. Example: Application component
92
+ unavailable, unexpected exception.
93
+
94
+ - **ALERT** (550): Action must be taken immediately. Example: Entire website
95
+ down, database unavailable, etc. This should trigger the SMS alerts and wake
96
+ you up.
97
+
98
+ - **EMERGENCY** (600): Emergency: system is unusable.
99
+
100
+ Docs
101
+ ====
102
+
103
+ **See the `doc` directory for more detailed documentation.
104
+ The following is only a list of all parts that come with Monolog.**
105
+
106
+ Handlers
107
+ --------
108
+
109
+ ### Log to files and syslog
110
+
111
+ - _StreamHandler_: Logs records into any PHP stream, use this for log files.
112
+ - _RotatingFileHandler_: Logs records to a file and creates one logfile per day.
113
+ It will also delete files older than `$maxFiles`. You should use
114
+ [logrotate](http://linuxcommand.org/man_pages/logrotate8.html) for high profile
115
+ setups though, this is just meant as a quick and dirty solution.
116
+ - _SyslogHandler_: Logs records to the syslog.
117
+ - _ErrorLogHandler_: Logs records to PHP's
118
+ [`error_log()`](http://docs.php.net/manual/en/function.error-log.php) function.
119
+
120
+ ### Send alerts and emails
121
+
122
+ - _NativeMailerHandler_: Sends emails using PHP's
123
+ [`mail()`](http://php.net/manual/en/function.mail.php) function.
124
+ - _SwiftMailerHandler_: Sends emails using a [`Swift_Mailer`](http://swiftmailer.org/) instance.
125
+ - _PushoverHandler_: Sends mobile notifications via the [Pushover](https://www.pushover.net/) API.
126
+ - _HipChatHandler_: Logs records to a [HipChat](http://hipchat.com) chat room using its API.
127
+ - _FlowdockHandler_: Logs records to a [Flowdock](https://www.flowdock.com/) account.
128
+ - _SlackHandler_: Logs records to a [Slack](https://www.slack.com/) account.
129
+ - _MandrillHandler_: Sends emails via the Mandrill API using a [`Swift_Message`](http://swiftmailer.org/) instance.
130
+ - _FleepHookHandler_: Logs records to a [Fleep](https://fleep.io/) conversation using Webhooks.
131
+
132
+ ### Log specific servers and networked logging
133
+
134
+ - _SocketHandler_: Logs records to [sockets](http://php.net/fsockopen), use this
135
+ for UNIX and TCP sockets. See an [example](https://github.com/Seldaek/monolog/blob/master/doc/sockets.md).
136
+ - _AmqpHandler_: Logs records to an [amqp](http://www.amqp.org/) compatible
137
+ server. Requires the [php-amqp](http://pecl.php.net/package/amqp) extension (1.0+).
138
+ - _GelfHandler_: Logs records to a [Graylog2](http://www.graylog2.org) server.
139
+ - _CubeHandler_: Logs records to a [Cube](http://square.github.com/cube/) server.
140
+ - _RavenHandler_: Logs records to a [Sentry](http://getsentry.com/) server using
141
+ [raven](https://packagist.org/packages/raven/raven).
142
+ - _ZendMonitorHandler_: Logs records to the Zend Monitor present in Zend Server.
143
+ - _NewRelicHandler_: Logs records to a [NewRelic](http://newrelic.com/) application.
144
+ - _LogglyHandler_: Logs records to a [Loggly](http://www.loggly.com/) account.
145
+ - _RollbarHandler_: Logs records to a [Rollbar](https://rollbar.com/) account.
146
+ - _SyslogUdpHandler_: Logs records to a remote [Syslogd](http://www.rsyslog.com/) server.
147
+ - _LogEntriesHandler_: Logs records to a [LogEntries](http://logentries.com/) account.
148
+
149
+ ### Logging in development
150
+
151
+ - _FirePHPHandler_: Handler for [FirePHP](http://www.firephp.org/), providing
152
+ inline `console` messages within [FireBug](http://getfirebug.com/).
153
+ - _ChromePHPHandler_: Handler for [ChromePHP](http://www.chromephp.com/), providing
154
+ inline `console` messages within Chrome.
155
+ - _BrowserConsoleHandler_: Handler to send logs to browser's Javascript `console` with
156
+ no browser extension required. Most browsers supporting `console` API are supported.
157
+
158
+ ### Log to databases
159
+
160
+ - _RedisHandler_: Logs records to a [redis](http://redis.io) server.
161
+ - _MongoDBHandler_: Handler to write records in MongoDB via a
162
+ [Mongo](http://pecl.php.net/package/mongo) extension connection.
163
+ - _CouchDBHandler_: Logs records to a CouchDB server.
164
+ - _DoctrineCouchDBHandler_: Logs records to a CouchDB server via the Doctrine CouchDB ODM.
165
+ - _ElasticSearchHandler_: Logs records to an Elastic Search server.
166
+ - _DynamoDbHandler_: Logs records to a DynamoDB table with the [AWS SDK](https://github.com/aws/aws-sdk-php).
167
+
168
+ ### Wrappers / Special Handlers
169
+
170
+ - _FingersCrossedHandler_: A very interesting wrapper. It takes a logger as
171
+ parameter and will accumulate log records of all levels until a record
172
+ exceeds the defined severity level. At which point it delivers all records,
173
+ including those of lower severity, to the handler it wraps. This means that
174
+ until an error actually happens you will not see anything in your logs, but
175
+ when it happens you will have the full information, including debug and info
176
+ records. This provides you with all the information you need, but only when
177
+ you need it.
178
+ - _WhatFailureGroupHandler_: This handler extends the _GroupHandler_ ignoring
179
+ exceptions raised by each child handler. This allows you to ignore issues
180
+ where a remote tcp connection may have died but you do not want your entire
181
+ application to crash and may wish to continue to log to other handlers.
182
+ - _BufferHandler_: This handler will buffer all the log records it receives
183
+ until `close()` is called at which point it will call `handleBatch()` on the
184
+ handler it wraps with all the log messages at once. This is very useful to
185
+ send an email with all records at once for example instead of having one mail
186
+ for every log record.
187
+ - _GroupHandler_: This handler groups other handlers. Every record received is
188
+ sent to all the handlers it is configured with.
189
+ - _FilterHandler_: This handler only lets records of the given levels through
190
+ to the wrapped handler.
191
+ - _SamplingHandler_: Wraps around another handler and lets you sample records
192
+ if you only want to store some of them.
193
+ - _NullHandler_: Any record it can handle will be thrown away. This can be used
194
+ to put on top of an existing handler stack to disable it temporarily.
195
+ - _PsrHandler_: Can be used to forward log records to an existing PSR-3 logger
196
+ - _TestHandler_: Used for testing, it records everything that is sent to it and
197
+ has accessors to read out the information.
198
+
199
+ Formatters
200
+ ----------
201
+
202
+ - _LineFormatter_: Formats a log record into a one-line string.
203
+ - _HtmlFormatter_: Used to format log records into a human readable html table, mainly suitable for emails.
204
+ - _NormalizerFormatter_: Normalizes objects/resources down to strings so a record can easily be serialized/encoded.
205
+ - _ScalarFormatter_: Used to format log records into an associative array of scalar values.
206
+ - _JsonFormatter_: Encodes a log record into json.
207
+ - _WildfireFormatter_: Used to format log records into the Wildfire/FirePHP protocol, only useful for the FirePHPHandler.
208
+ - _ChromePHPFormatter_: Used to format log records into the ChromePHP format, only useful for the ChromePHPHandler.
209
+ - _GelfMessageFormatter_: Used to format log records into Gelf message instances, only useful for the GelfHandler.
210
+ - _LogstashFormatter_: Used to format log records into [logstash](http://logstash.net/) event json, useful for any handler listed under inputs [here](http://logstash.net/docs/latest).
211
+ - _ElasticaFormatter_: Used to format log records into an Elastica\Document object, only useful for the ElasticSearchHandler.
212
+ - _LogglyFormatter_: Used to format log records into Loggly messages, only useful for the LogglyHandler.
213
+ - _FlowdockFormatter_: Used to format log records into Flowdock messages, only useful for the FlowdockHandler.
214
+ - _MongoDBFormatter_: Converts \DateTime instances to \MongoDate and objects recursively to arrays, only useful with the MongoDBHandler.
215
+
216
+ Processors
217
+ ----------
218
+
219
+ - _IntrospectionProcessor_: Adds the line/file/class/method from which the log call originated.
220
+ - _WebProcessor_: Adds the current request URI, request method and client IP to a log record.
221
+ - _MemoryUsageProcessor_: Adds the current memory usage to a log record.
222
+ - _MemoryPeakUsageProcessor_: Adds the peak memory usage to a log record.
223
+ - _ProcessIdProcessor_: Adds the process id to a log record.
224
+ - _UidProcessor_: Adds a unique identifier to a log record.
225
+ - _GitProcessor_: Adds the current git branch and commit to a log record.
226
+ - _TagProcessor_: Adds an array of predefined tags to a log record.
227
+
228
+ Utilities
229
+ ---------
230
+
231
+ - _Registry_: The `Monolog\Registry` class lets you configure global loggers that you
232
+ can then statically access from anywhere. It is not really a best practice but can
233
+ help in some older codebases or for ease of use.
234
+ - _ErrorHandler_: The `Monolog\ErrorHandler` class allows you to easily register
235
+ a Logger instance as an exception handler, error handler or fatal error handler.
236
+ - _ErrorLevelActivationStrategy_: Activates a FingersCrossedHandler when a certain log
237
+ level is reached.
238
+ - _ChannelLevelActivationStrategy_: Activates a FingersCrossedHandler when a certain
239
+ log level is reached, depending on which channel received the log record.
240
+
241
+ Third Party Packages
242
+ --------------------
243
+
244
+ Third party handlers, formatters and processors are
245
+ [listed in the wiki](https://github.com/Seldaek/monolog/wiki/Third-Party-Packages). You
246
+ can also add your own there if you publish one.
247
+
248
+ About
249
+ =====
250
+
251
+ Requirements
252
+ ------------
253
+
254
+ - Monolog works with PHP 5.3 or above, and is also tested to work with HHVM.
255
+
256
+ Submitting bugs and feature requests
257
+ ------------------------------------
258
+
259
+ Bugs and feature request are tracked on [GitHub](https://github.com/Seldaek/monolog/issues)
260
+
261
+ Frameworks Integration
262
+ ----------------------
263
+
264
+ - Frameworks and libraries using [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
265
+ can be used very easily with Monolog since it implements the interface.
266
+ - [Symfony2](http://symfony.com) comes out of the box with Monolog.
267
+ - [Silex](http://silex.sensiolabs.org/) comes out of the box with Monolog.
268
+ - [Laravel 4 & 5](http://laravel.com/) come out of the box with Monolog.
269
+ - [PPI](http://www.ppi.io/) comes out of the box with Monolog.
270
+ - [CakePHP](http://cakephp.org/) is usable with Monolog via the [cakephp-monolog](https://github.com/jadb/cakephp-monolog) plugin.
271
+ - [Slim](http://www.slimframework.com/) is usable with Monolog via the [Slim-Monolog](https://github.com/Flynsarmy/Slim-Monolog) log writer.
272
+ - [XOOPS 2.6](http://xoops.org/) comes out of the box with Monolog.
273
+ - [Aura.Web_Project](https://github.com/auraphp/Aura.Web_Project) comes out of the box with Monolog.
274
+ - [Nette Framework](http://nette.org/en/) can be used with Monolog via [Kdyby/Monolog](https://github.com/Kdyby/Monolog) extension.
275
+ - [Proton Micro Framework](https://github.com/alexbilbie/Proton) comes out of the box with Monolog.
276
+
277
+ Author
278
+ ------
279
+
280
+ Jordi Boggiano - <j.boggiano@seld.be> - <http://twitter.com/seldaek><br />
281
+ See also the list of [contributors](https://github.com/Seldaek/monolog/contributors) which participated in this project.
282
+
283
+ License
284
+ -------
285
+
286
+ Monolog is licensed under the MIT License - see the `LICENSE` file for details
287
+
288
+ Acknowledgements
289
+ ----------------
290
+
291
+ This library is heavily inspired by Python's [Logbook](http://packages.python.org/Logbook/)
292
+ library, although most concepts have been adjusted to fit to the PHP world.
app/code/community/Expressly/Expressly/vendor/monolog/monolog/composer.json ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "monolog/monolog",
3
+ "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
4
+ "keywords": ["log", "logging", "psr-3"],
5
+ "homepage": "http://github.com/Seldaek/monolog",
6
+ "type": "library",
7
+ "license": "MIT",
8
+ "authors": [
9
+ {
10
+ "name": "Jordi Boggiano",
11
+ "email": "j.boggiano@seld.be",
12
+ "homepage": "http://seld.be"
13
+ }
14
+ ],
15
+ "require": {
16
+ "php": ">=5.3.0",
17
+ "psr/log": "~1.0"
18
+ },
19
+ "require-dev": {
20
+ "phpunit/phpunit": "~4.0",
21
+ "graylog2/gelf-php": "~1.0",
22
+ "raven/raven": "~0.5",
23
+ "ruflin/elastica": "0.90.*",
24
+ "doctrine/couchdb": "~1.0@dev",
25
+ "aws/aws-sdk-php": "~2.4, >2.4.8",
26
+ "videlalvaro/php-amqplib": "~2.4",
27
+ "swiftmailer/swiftmailer": "~5.3"
28
+ },
29
+ "suggest": {
30
+ "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
31
+ "raven/raven": "Allow sending log messages to a Sentry server",
32
+ "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
33
+ "ruflin/elastica": "Allow sending log messages to an Elastic Search server",
34
+ "videlalvaro/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
35
+ "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
36
+ "ext-mongo": "Allow sending log messages to a MongoDB server",
37
+ "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
38
+ "rollbar/rollbar": "Allow sending log messages to Rollbar"
39
+ },
40
+ "autoload": {
41
+ "psr-4": {"Monolog\\": "src/Monolog"}
42
+ },
43
+ "provide": {
44
+ "psr/log-implementation": "1.0.0"
45
+ },
46
+ "extra": {
47
+ "branch-alias": {
48
+ "dev-master": "1.13.x-dev"
49
+ }
50
+ },
51
+ "scripts": {
52
+ "test": "phpunit"
53
+ }
54
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/doc/extending.md ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Extending Monolog
2
+ =================
3
+
4
+ Monolog is fully extensible, allowing you to adapt your logger to your needs.
5
+
6
+ Writing your own handler
7
+ ------------------------
8
+
9
+ Monolog provides many built-in handlers. But if the one you need does not
10
+ exist, you can write it and use it in your logger. The only requirement is
11
+ to implement `Monolog\Handler\HandlerInterface`.
12
+
13
+ Let's write a PDOHandler to log records to a database. We will extend the
14
+ abstract class provided by Monolog to keep things DRY.
15
+
16
+ ```php
17
+ <?php
18
+
19
+ use Monolog\Logger;
20
+ use Monolog\Handler\AbstractProcessingHandler;
21
+
22
+ class PDOHandler extends AbstractProcessingHandler
23
+ {
24
+ private $initialized = false;
25
+ private $pdo;
26
+ private $statement;
27
+
28
+ public function __construct(PDO $pdo, $level = Logger::DEBUG, $bubble = true)
29
+ {
30
+ $this->pdo = $pdo;
31
+ parent::__construct($level, $bubble);
32
+ }
33
+
34
+ protected function write(array $record)
35
+ {
36
+ if (!$this->initialized) {
37
+ $this->initialize();
38
+ }
39
+
40
+ $this->statement->execute(array(
41
+ 'channel' => $record['channel'],
42
+ 'level' => $record['level'],
43
+ 'message' => $record['formatted'],
44
+ 'time' => $record['datetime']->format('U'),
45
+ ));
46
+ }
47
+
48
+ private function initialize()
49
+ {
50
+ $this->pdo->exec(
51
+ 'CREATE TABLE IF NOT EXISTS monolog '
52
+ .'(channel VARCHAR(255), level INTEGER, message LONGTEXT, time INTEGER UNSIGNED)'
53
+ );
54
+ $this->statement = $this->pdo->prepare(
55
+ 'INSERT INTO monolog (channel, level, message, time) VALUES (:channel, :level, :message, :time)'
56
+ );
57
+
58
+ $this->initialized = true;
59
+ }
60
+ }
61
+ ```
62
+
63
+ You can now use this handler in your logger:
64
+
65
+ ```php
66
+ <?php
67
+
68
+ $logger->pushHandler(new PDOHandler(new PDO('sqlite:logs.sqlite')));
69
+
70
+ // You can now use your logger
71
+ $logger->addInfo('My logger is now ready');
72
+ ```
73
+
74
+ The `Monolog\Handler\AbstractProcessingHandler` class provides most of the
75
+ logic needed for the handler, including the use of processors and the formatting
76
+ of the record (which is why we use ``$record['formatted']`` instead of ``$record['message']``).
app/code/community/Expressly/Expressly/vendor/monolog/monolog/doc/sockets.md ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Sockets Handler
2
+ ===============
3
+
4
+ This handler allows you to write your logs to sockets using [fsockopen](http://php.net/fsockopen)
5
+ or [pfsockopen](http://php.net/pfsockopen).
6
+
7
+ Persistent sockets are mainly useful in web environments where you gain some performance not closing/opening
8
+ the connections between requests.
9
+
10
+ Basic Example
11
+ -------------
12
+
13
+ ```php
14
+ <?php
15
+
16
+ use Monolog\Logger;
17
+ use Monolog\Handler\SocketHandler;
18
+
19
+ // Create the logger
20
+ $logger = new Logger('my_logger');
21
+
22
+ // Create the handler
23
+ $handler = new SocketHandler('unix:///var/log/httpd_app_log.socket');
24
+ $handler->setPersistent(true);
25
+
26
+ // Now add the handler
27
+ $logger->pushHandler($handler, Logger::DEBUG);
28
+
29
+ // You can now use your logger
30
+ $logger->addInfo('My logger is now ready');
31
+
32
+ ```
33
+
34
+ In this example, using syslog-ng, you should see the log on the log server:
35
+
36
+ cweb1 [2012-02-26 00:12:03] my_logger.INFO: My logger is now ready [] []
37
+
app/code/community/Expressly/Expressly/vendor/monolog/monolog/doc/usage.md ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Using Monolog
2
+ =============
3
+
4
+ Installation
5
+ ------------
6
+
7
+ Monolog is available on Packagist ([monolog/monolog](http://packagist.org/packages/monolog/monolog))
8
+ and as such installable via [Composer](http://getcomposer.org/).
9
+
10
+ ```bash
11
+ php composer.phar require monolog/monolog
12
+ ```
13
+
14
+ If you do not use Composer, you can grab the code from GitHub, and use any
15
+ PSR-0 compatible autoloader (e.g. the [Symfony2 ClassLoader component](https://github.com/symfony/ClassLoader))
16
+ to load Monolog classes.
17
+
18
+ Configuring a logger
19
+ --------------------
20
+
21
+ Here is a basic setup to log to a file and to firephp on the DEBUG level:
22
+
23
+ ```php
24
+ <?php
25
+
26
+ use Monolog\Logger;
27
+ use Monolog\Handler\StreamHandler;
28
+ use Monolog\Handler\FirePHPHandler;
29
+
30
+ // Create the logger
31
+ $logger = new Logger('my_logger');
32
+ // Now add some handlers
33
+ $logger->pushHandler(new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG));
34
+ $logger->pushHandler(new FirePHPHandler());
35
+
36
+ // You can now use your logger
37
+ $logger->addInfo('My logger is now ready');
38
+ ```
39
+
40
+ Let's explain it. The first step is to create the logger instance which will
41
+ be used in your code. The argument is a channel name, which is useful when
42
+ you use several loggers (see below for more details about it).
43
+
44
+ The logger itself does not know how to handle a record. It delegates it to
45
+ some handlers. The code above registers two handlers in the stack to allow
46
+ handling records in two different ways.
47
+
48
+ Note that the FirePHPHandler is called first as it is added on top of the
49
+ stack. This allows you to temporarily add a logger with bubbling disabled if
50
+ you want to override other configured loggers.
51
+
52
+ Adding extra data in the records
53
+ --------------------------------
54
+
55
+ Monolog provides two different ways to add extra informations along the simple
56
+ textual message.
57
+
58
+ ### Using the logging context
59
+
60
+ The first way is the context, allowing to pass an array of data along the
61
+ record:
62
+
63
+ ```php
64
+ <?php
65
+
66
+ $logger->addInfo('Adding a new user', array('username' => 'Seldaek'));
67
+ ```
68
+
69
+ Simple handlers (like the StreamHandler for instance) will simply format
70
+ the array to a string but richer handlers can take advantage of the context
71
+ (FirePHP is able to display arrays in pretty way for instance).
72
+
73
+ ### Using processors
74
+
75
+ The second way is to add extra data for all records by using a processor.
76
+ Processors can be any callable. They will get the record as parameter and
77
+ must return it after having eventually changed the `extra` part of it. Let's
78
+ write a processor adding some dummy data in the record:
79
+
80
+ ```php
81
+ <?php
82
+
83
+ $logger->pushProcessor(function ($record) {
84
+ $record['extra']['dummy'] = 'Hello world!';
85
+
86
+ return $record;
87
+ });
88
+ ```
89
+
90
+ Monolog provides some built-in processors that can be used in your project.
91
+ Look at the [README file](https://github.com/Seldaek/monolog/blob/master/README.mdown) for the list.
92
+
93
+ > Tip: processors can also be registered on a specific handler instead of
94
+ the logger to apply only for this handler.
95
+
96
+ Leveraging channels
97
+ -------------------
98
+
99
+ Channels are a great way to identify to which part of the application a record
100
+ is related. This is useful in big applications (and is leveraged by
101
+ MonologBundle in Symfony2).
102
+
103
+ Picture two loggers sharing a handler that writes to a single log file.
104
+ Channels would allow you to identify the logger that issued every record.
105
+ You can easily grep through the log files filtering this or that channel.
106
+
107
+ ```php
108
+ <?php
109
+
110
+ use Monolog\Logger;
111
+ use Monolog\Handler\StreamHandler;
112
+ use Monolog\Handler\FirePHPHandler;
113
+
114
+ // Create some handlers
115
+ $stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG);
116
+ $firephp = new FirePHPHandler();
117
+
118
+ // Create the main logger of the app
119
+ $logger = new Logger('my_logger');
120
+ $logger->pushHandler($stream);
121
+ $logger->pushHandler($firephp);
122
+
123
+ // Create a logger for the security-related stuff with a different channel
124
+ $securityLogger = new Logger('security');
125
+ $securityLogger->pushHandler($stream);
126
+ $securityLogger->pushHandler($firephp);
127
+ ```
128
+
129
+ Customizing log format
130
+ ----------------------
131
+
132
+ In Monolog it's easy to customize the format of the logs written into files,
133
+ sockets, mails, databases and other handlers. Most of the handlers use the
134
+
135
+ ```php
136
+ $record['formatted']
137
+ ```
138
+
139
+ value to be automatically put into the log device. This value depends on the
140
+ formatter settings. You can choose between predefined formatter classes or
141
+ write your own (e.g. a multiline text file for human-readable output).
142
+
143
+ To configure a predefined formatter class, just set it as the handler's field:
144
+
145
+ ```php
146
+ // the default date format is "Y-m-d H:i:s"
147
+ $dateFormat = "Y n j, g:i a";
148
+ // the default output format is "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"
149
+ $output = "%datetime% > %level_name% > %message% %context% %extra%\n";
150
+ // finally, create a formatter
151
+ $formatter = new LineFormatter($output, $dateFormat);
152
+
153
+ // Create a handler
154
+ $stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG);
155
+ $stream->setFormatter($formatter);
156
+ // bind it to a logger object
157
+ $securityLogger = new Logger('security');
158
+ $securityLogger->pushHandler($stream);
159
+ ```
160
+
161
+ You may also reuse the same formatter between multiple handlers and share those
162
+ handlers between multiple loggers.
app/code/community/Expressly/Expressly/vendor/monolog/monolog/phpunit.xml.dist ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <phpunit bootstrap="tests/bootstrap.php" colors="true">
4
+ <testsuites>
5
+ <testsuite name="Monolog Test Suite">
6
+ <directory>tests/Monolog/</directory>
7
+ </testsuite>
8
+ </testsuites>
9
+
10
+ <filter>
11
+ <whitelist>
12
+ <directory suffix=".php">src/Monolog/</directory>
13
+ </whitelist>
14
+ </filter>
15
+ </phpunit>
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/ErrorHandler.php ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog;
13
+
14
+ use Psr\Log\LoggerInterface;
15
+ use Psr\Log\LogLevel;
16
+
17
+ /**
18
+ * Monolog error handler
19
+ *
20
+ * A facility to enable logging of runtime errors, exceptions and fatal errors.
21
+ *
22
+ * Quick setup: <code>ErrorHandler::register($logger);</code>
23
+ *
24
+ * @author Jordi Boggiano <j.boggiano@seld.be>
25
+ */
26
+ class ErrorHandler
27
+ {
28
+ private $logger;
29
+
30
+ private $previousExceptionHandler;
31
+ private $uncaughtExceptionLevel;
32
+
33
+ private $previousErrorHandler;
34
+ private $errorLevelMap;
35
+
36
+ private $fatalLevel;
37
+ private $reservedMemory;
38
+ private static $fatalErrors = array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR);
39
+
40
+ public function __construct(LoggerInterface $logger)
41
+ {
42
+ $this->logger = $logger;
43
+ }
44
+
45
+ /**
46
+ * Registers a new ErrorHandler for a given Logger
47
+ *
48
+ * By default it will handle errors, exceptions and fatal errors
49
+ *
50
+ * @param LoggerInterface $logger
51
+ * @param array|false $errorLevelMap an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling
52
+ * @param int|false $exceptionLevel a LogLevel::* constant, or false to disable exception handling
53
+ * @param int|false $fatalLevel a LogLevel::* constant, or false to disable fatal error handling
54
+ * @return ErrorHandler
55
+ */
56
+ public static function register(LoggerInterface $logger, $errorLevelMap = array(), $exceptionLevel = null, $fatalLevel = null)
57
+ {
58
+ $handler = new static($logger);
59
+ if ($errorLevelMap !== false) {
60
+ $handler->registerErrorHandler($errorLevelMap);
61
+ }
62
+ if ($exceptionLevel !== false) {
63
+ $handler->registerExceptionHandler($exceptionLevel);
64
+ }
65
+ if ($fatalLevel !== false) {
66
+ $handler->registerFatalHandler($fatalLevel);
67
+ }
68
+
69
+ return $handler;
70
+ }
71
+
72
+ public function registerExceptionHandler($level = null, $callPrevious = true)
73
+ {
74
+ $prev = set_exception_handler(array($this, 'handleException'));
75
+ $this->uncaughtExceptionLevel = $level;
76
+ if ($callPrevious && $prev) {
77
+ $this->previousExceptionHandler = $prev;
78
+ }
79
+ }
80
+
81
+ public function registerErrorHandler(array $levelMap = array(), $callPrevious = true, $errorTypes = -1)
82
+ {
83
+ $prev = set_error_handler(array($this, 'handleError'), $errorTypes);
84
+ $this->errorLevelMap = array_replace($this->defaultErrorLevelMap(), $levelMap);
85
+ if ($callPrevious) {
86
+ $this->previousErrorHandler = $prev ?: true;
87
+ }
88
+ }
89
+
90
+ public function registerFatalHandler($level = null, $reservedMemorySize = 20)
91
+ {
92
+ register_shutdown_function(array($this, 'handleFatalError'));
93
+
94
+ $this->reservedMemory = str_repeat(' ', 1024 * $reservedMemorySize);
95
+ $this->fatalLevel = $level;
96
+ }
97
+
98
+ protected function defaultErrorLevelMap()
99
+ {
100
+ return array(
101
+ E_ERROR => LogLevel::CRITICAL,
102
+ E_WARNING => LogLevel::WARNING,
103
+ E_PARSE => LogLevel::ALERT,
104
+ E_NOTICE => LogLevel::NOTICE,
105
+ E_CORE_ERROR => LogLevel::CRITICAL,
106
+ E_CORE_WARNING => LogLevel::WARNING,
107
+ E_COMPILE_ERROR => LogLevel::ALERT,
108
+ E_COMPILE_WARNING => LogLevel::WARNING,
109
+ E_USER_ERROR => LogLevel::ERROR,
110
+ E_USER_WARNING => LogLevel::WARNING,
111
+ E_USER_NOTICE => LogLevel::NOTICE,
112
+ E_STRICT => LogLevel::NOTICE,
113
+ E_RECOVERABLE_ERROR => LogLevel::ERROR,
114
+ E_DEPRECATED => LogLevel::NOTICE,
115
+ E_USER_DEPRECATED => LogLevel::NOTICE,
116
+ );
117
+ }
118
+
119
+ /**
120
+ * @private
121
+ */
122
+ public function handleException(\Exception $e)
123
+ {
124
+ $this->logger->log(
125
+ $this->uncaughtExceptionLevel === null ? LogLevel::ERROR : $this->uncaughtExceptionLevel,
126
+ sprintf('Uncaught Exception %s: "%s" at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()),
127
+ array('exception' => $e)
128
+ );
129
+
130
+ if ($this->previousExceptionHandler) {
131
+ call_user_func($this->previousExceptionHandler, $e);
132
+ }
133
+ }
134
+
135
+ /**
136
+ * @private
137
+ */
138
+ public function handleError($code, $message, $file = '', $line = 0, $context = array())
139
+ {
140
+ if (!(error_reporting() & $code)) {
141
+ return;
142
+ }
143
+
144
+ $level = isset($this->errorLevelMap[$code]) ? $this->errorLevelMap[$code] : LogLevel::CRITICAL;
145
+ $this->logger->log($level, self::codeToString($code).': '.$message, array('code' => $code, 'message' => $message, 'file' => $file, 'line' => $line));
146
+
147
+ if ($this->previousErrorHandler === true) {
148
+ return false;
149
+ } elseif ($this->previousErrorHandler) {
150
+ return call_user_func($this->previousErrorHandler, $code, $message, $file, $line, $context);
151
+ }
152
+ }
153
+
154
+ /**
155
+ * @private
156
+ */
157
+ public function handleFatalError()
158
+ {
159
+ $this->reservedMemory = null;
160
+
161
+ $lastError = error_get_last();
162
+ if ($lastError && in_array($lastError['type'], self::$fatalErrors)) {
163
+ $this->logger->log(
164
+ $this->fatalLevel === null ? LogLevel::ALERT : $this->fatalLevel,
165
+ 'Fatal Error ('.self::codeToString($lastError['type']).'): '.$lastError['message'],
166
+ array('code' => $lastError['type'], 'message' => $lastError['message'], 'file' => $lastError['file'], 'line' => $lastError['line'])
167
+ );
168
+ }
169
+ }
170
+
171
+ private static function codeToString($code)
172
+ {
173
+ switch ($code) {
174
+ case E_ERROR:
175
+ return 'E_ERROR';
176
+ case E_WARNING:
177
+ return 'E_WARNING';
178
+ case E_PARSE:
179
+ return 'E_PARSE';
180
+ case E_NOTICE:
181
+ return 'E_NOTICE';
182
+ case E_CORE_ERROR:
183
+ return 'E_CORE_ERROR';
184
+ case E_CORE_WARNING:
185
+ return 'E_CORE_WARNING';
186
+ case E_COMPILE_ERROR:
187
+ return 'E_COMPILE_ERROR';
188
+ case E_COMPILE_WARNING:
189
+ return 'E_COMPILE_WARNING';
190
+ case E_USER_ERROR:
191
+ return 'E_USER_ERROR';
192
+ case E_USER_WARNING:
193
+ return 'E_USER_WARNING';
194
+ case E_USER_NOTICE:
195
+ return 'E_USER_NOTICE';
196
+ case E_STRICT:
197
+ return 'E_STRICT';
198
+ case E_RECOVERABLE_ERROR:
199
+ return 'E_RECOVERABLE_ERROR';
200
+ case E_DEPRECATED:
201
+ return 'E_DEPRECATED';
202
+ case E_USER_DEPRECATED:
203
+ return 'E_USER_DEPRECATED';
204
+ }
205
+
206
+ return 'Unknown PHP error';
207
+ }
208
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/ChromePHPFormatter.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Formats a log message according to the ChromePHP array format
18
+ *
19
+ * @author Christophe Coevoet <stof@notk.org>
20
+ */
21
+ class ChromePHPFormatter implements FormatterInterface
22
+ {
23
+ /**
24
+ * Translates Monolog log levels to Wildfire levels.
25
+ */
26
+ private $logLevels = array(
27
+ Logger::DEBUG => 'log',
28
+ Logger::INFO => 'info',
29
+ Logger::NOTICE => 'info',
30
+ Logger::WARNING => 'warn',
31
+ Logger::ERROR => 'error',
32
+ Logger::CRITICAL => 'error',
33
+ Logger::ALERT => 'error',
34
+ Logger::EMERGENCY => 'error',
35
+ );
36
+
37
+ /**
38
+ * {@inheritdoc}
39
+ */
40
+ public function format(array $record)
41
+ {
42
+ // Retrieve the line and file if set and remove them from the formatted extra
43
+ $backtrace = 'unknown';
44
+ if (isset($record['extra']['file']) && isset($record['extra']['line'])) {
45
+ $backtrace = $record['extra']['file'].' : '.$record['extra']['line'];
46
+ unset($record['extra']['file']);
47
+ unset($record['extra']['line']);
48
+ }
49
+
50
+ $message = array('message' => $record['message']);
51
+ if ($record['context']) {
52
+ $message['context'] = $record['context'];
53
+ }
54
+ if ($record['extra']) {
55
+ $message['extra'] = $record['extra'];
56
+ }
57
+ if (count($message) === 1) {
58
+ $message = reset($message);
59
+ }
60
+
61
+ return array(
62
+ $record['channel'],
63
+ $message,
64
+ $backtrace,
65
+ $this->logLevels[$record['level']],
66
+ );
67
+ }
68
+
69
+ public function formatBatch(array $records)
70
+ {
71
+ $formatted = array();
72
+
73
+ foreach ($records as $record) {
74
+ $formatted[] = $this->format($record);
75
+ }
76
+
77
+ return $formatted;
78
+ }
79
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/ElasticaFormatter.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ use Elastica\Document;
15
+
16
+ /**
17
+ * Format a log message into an Elastica Document
18
+ *
19
+ * @author Jelle Vink <jelle.vink@gmail.com>
20
+ */
21
+ class ElasticaFormatter extends NormalizerFormatter
22
+ {
23
+ /**
24
+ * @var string Elastic search index name
25
+ */
26
+ protected $index;
27
+
28
+ /**
29
+ * @var string Elastic search document type
30
+ */
31
+ protected $type;
32
+
33
+ /**
34
+ * @param string $index Elastic Search index name
35
+ * @param string $type Elastic Search document type
36
+ */
37
+ public function __construct($index, $type)
38
+ {
39
+ parent::__construct(\DateTime::ISO8601);
40
+ $this->index = $index;
41
+ $this->type = $type;
42
+ }
43
+
44
+ /**
45
+ * {@inheritdoc}
46
+ */
47
+ public function format(array $record)
48
+ {
49
+ $record = parent::format($record);
50
+
51
+ return $this->getDocument($record);
52
+ }
53
+
54
+ /**
55
+ * Getter index
56
+ * @return string
57
+ */
58
+ public function getIndex()
59
+ {
60
+ return $this->index;
61
+ }
62
+
63
+ /**
64
+ * Getter type
65
+ * @return string
66
+ */
67
+ public function getType()
68
+ {
69
+ return $this->type;
70
+ }
71
+
72
+ /**
73
+ * Convert a log message into an Elastica Document
74
+ *
75
+ * @param array $record Log message
76
+ * @return Document
77
+ */
78
+ protected function getDocument($record)
79
+ {
80
+ $document = new Document();
81
+ $document->setData($record);
82
+ $document->setType($this->type);
83
+ $document->setIndex($this->index);
84
+
85
+ return $document;
86
+ }
87
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/FlowdockFormatter.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ /**
15
+ * formats the record to be used in the FlowdockHandler
16
+ *
17
+ * @author Dominik Liebler <liebler.dominik@gmail.com>
18
+ */
19
+ class FlowdockFormatter implements FormatterInterface
20
+ {
21
+ /**
22
+ * @var string
23
+ */
24
+ private $source;
25
+
26
+ /**
27
+ * @var string
28
+ */
29
+ private $sourceEmail;
30
+
31
+ /**
32
+ * @param string $source
33
+ * @param string $sourceEmail
34
+ */
35
+ public function __construct($source, $sourceEmail)
36
+ {
37
+ $this->source = $source;
38
+ $this->sourceEmail = $sourceEmail;
39
+ }
40
+
41
+ /**
42
+ * {@inheritdoc}
43
+ */
44
+ public function format(array $record)
45
+ {
46
+ $tags = array(
47
+ '#logs',
48
+ '#' . strtolower($record['level_name']),
49
+ '#' . $record['channel'],
50
+ );
51
+
52
+ foreach ($record['extra'] as $value) {
53
+ $tags[] = '#' . $value;
54
+ }
55
+
56
+ $subject = sprintf(
57
+ 'in %s: %s - %s',
58
+ $this->source,
59
+ $record['level_name'],
60
+ $this->getShortMessage($record['message'])
61
+ );
62
+
63
+ $record['flowdock'] = array(
64
+ 'source' => $this->source,
65
+ 'from_address' => $this->sourceEmail,
66
+ 'subject' => $subject,
67
+ 'content' => $record['message'],
68
+ 'tags' => $tags,
69
+ 'project' => $this->source,
70
+ );
71
+
72
+ return $record;
73
+ }
74
+
75
+ /**
76
+ * {@inheritdoc}
77
+ */
78
+ public function formatBatch(array $records)
79
+ {
80
+ $formatted = array();
81
+
82
+ foreach ($records as $record) {
83
+ $formatted[] = $this->format($record);
84
+ }
85
+
86
+ return $formatted;
87
+ }
88
+
89
+ /**
90
+ * @param string $message
91
+ *
92
+ * @return string
93
+ */
94
+ public function getShortMessage($message)
95
+ {
96
+ $maxLength = 45;
97
+
98
+ if (strlen($message) > $maxLength) {
99
+ $message = substr($message, 0, $maxLength - 4) . ' ...';
100
+ }
101
+
102
+ return $message;
103
+ }
104
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ /**
15
+ * Interface for formatters
16
+ *
17
+ * @author Jordi Boggiano <j.boggiano@seld.be>
18
+ */
19
+ interface FormatterInterface
20
+ {
21
+ /**
22
+ * Formats a log record.
23
+ *
24
+ * @param array $record A record to format
25
+ * @return mixed The formatted record
26
+ */
27
+ public function format(array $record);
28
+
29
+ /**
30
+ * Formats a set of log records.
31
+ *
32
+ * @param array $records A set of records to format
33
+ * @return mixed The formatted set of records
34
+ */
35
+ public function formatBatch(array $records);
36
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/GelfMessageFormatter.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ use Monolog\Logger;
15
+ use Gelf\Message;
16
+
17
+ /**
18
+ * Serializes a log message to GELF
19
+ * @see http://www.graylog2.org/about/gelf
20
+ *
21
+ * @author Matt Lehner <mlehner@gmail.com>
22
+ */
23
+ class GelfMessageFormatter extends NormalizerFormatter
24
+ {
25
+ /**
26
+ * @var string the name of the system for the Gelf log message
27
+ */
28
+ protected $systemName;
29
+
30
+ /**
31
+ * @var string a prefix for 'extra' fields from the Monolog record (optional)
32
+ */
33
+ protected $extraPrefix;
34
+
35
+ /**
36
+ * @var string a prefix for 'context' fields from the Monolog record (optional)
37
+ */
38
+ protected $contextPrefix;
39
+
40
+ /**
41
+ * Translates Monolog log levels to Graylog2 log priorities.
42
+ */
43
+ private $logLevels = array(
44
+ Logger::DEBUG => 7,
45
+ Logger::INFO => 6,
46
+ Logger::NOTICE => 5,
47
+ Logger::WARNING => 4,
48
+ Logger::ERROR => 3,
49
+ Logger::CRITICAL => 2,
50
+ Logger::ALERT => 1,
51
+ Logger::EMERGENCY => 0,
52
+ );
53
+
54
+ public function __construct($systemName = null, $extraPrefix = null, $contextPrefix = 'ctxt_')
55
+ {
56
+ parent::__construct('U.u');
57
+
58
+ $this->systemName = $systemName ?: gethostname();
59
+
60
+ $this->extraPrefix = $extraPrefix;
61
+ $this->contextPrefix = $contextPrefix;
62
+ }
63
+
64
+ /**
65
+ * {@inheritdoc}
66
+ */
67
+ public function format(array $record)
68
+ {
69
+ $record = parent::format($record);
70
+
71
+ if (!isset($record['datetime'], $record['message'], $record['level'])) {
72
+ throw new \InvalidArgumentException('The record should at least contain datetime, message and level keys, '.var_export($record, true).' given');
73
+ }
74
+
75
+ $message = new Message();
76
+ $message
77
+ ->setTimestamp($record['datetime'])
78
+ ->setShortMessage((string) $record['message'])
79
+ ->setHost($this->systemName)
80
+ ->setLevel($this->logLevels[$record['level']]);
81
+
82
+ if (isset($record['channel'])) {
83
+ $message->setFacility($record['channel']);
84
+ }
85
+ if (isset($record['extra']['line'])) {
86
+ $message->setLine($record['extra']['line']);
87
+ unset($record['extra']['line']);
88
+ }
89
+ if (isset($record['extra']['file'])) {
90
+ $message->setFile($record['extra']['file']);
91
+ unset($record['extra']['file']);
92
+ }
93
+
94
+ foreach ($record['extra'] as $key => $val) {
95
+ $message->setAdditional($this->extraPrefix . $key, is_scalar($val) ? $val : $this->toJson($val));
96
+ }
97
+
98
+ foreach ($record['context'] as $key => $val) {
99
+ $message->setAdditional($this->contextPrefix . $key, is_scalar($val) ? $val : $this->toJson($val));
100
+ }
101
+
102
+ if (null === $message->getFile() && isset($record['context']['exception']['file'])) {
103
+ if (preg_match("/^(.+):([0-9]+)$/", $record['context']['exception']['file'], $matches)) {
104
+ $message->setFile($matches[1]);
105
+ $message->setLine($matches[2]);
106
+ }
107
+ }
108
+
109
+ return $message;
110
+ }
111
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/HtmlFormatter.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file is part of the Monolog package.
4
+ *
5
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
6
+ *
7
+ * For the full copyright and license information, please view the LICENSE
8
+ * file that was distributed with this source code.
9
+ */
10
+
11
+ namespace Monolog\Formatter;
12
+
13
+ use Monolog\Logger;
14
+
15
+ /**
16
+ * Formats incoming records into an HTML table
17
+ *
18
+ * This is especially useful for html email logging
19
+ *
20
+ * @author Tiago Brito <tlfbrito@gmail.com>
21
+ */
22
+ class HtmlFormatter extends NormalizerFormatter
23
+ {
24
+ /**
25
+ * Translates Monolog log levels to html color priorities.
26
+ */
27
+ private $logLevels = array(
28
+ Logger::DEBUG => '#cccccc',
29
+ Logger::INFO => '#468847',
30
+ Logger::NOTICE => '#3a87ad',
31
+ Logger::WARNING => '#c09853',
32
+ Logger::ERROR => '#f0ad4e',
33
+ Logger::CRITICAL => '#FF7708',
34
+ Logger::ALERT => '#C12A19',
35
+ Logger::EMERGENCY => '#000000',
36
+ );
37
+
38
+ /**
39
+ * @param string $dateFormat The format of the timestamp: one supported by DateTime::format
40
+ */
41
+ public function __construct($dateFormat = null)
42
+ {
43
+ parent::__construct($dateFormat);
44
+ }
45
+
46
+ /**
47
+ * Creates an HTML table row
48
+ *
49
+ * @param string $th Row header content
50
+ * @param string $td Row standard cell content
51
+ * @param bool $escapeTd false if td content must not be html escaped
52
+ * @return string
53
+ */
54
+ private function addRow($th, $td = ' ', $escapeTd = true)
55
+ {
56
+ $th = htmlspecialchars($th, ENT_NOQUOTES, 'UTF-8');
57
+ if ($escapeTd) {
58
+ $td = '<pre>'.htmlspecialchars($td, ENT_NOQUOTES, 'UTF-8').'</pre>';
59
+ }
60
+
61
+ return "<tr style=\"padding: 4px;spacing: 0;text-align: left;\">\n<th style=\"background: #cccccc\" width=\"100px\">$th:</th>\n<td style=\"padding: 4px;spacing: 0;text-align: left;background: #eeeeee\">".$td."</td>\n</tr>";
62
+ }
63
+
64
+ /**
65
+ * Create a HTML h1 tag
66
+ *
67
+ * @param string $title Text to be in the h1
68
+ * @param integer $level Error level
69
+ * @return string
70
+ */
71
+ private function addTitle($title, $level)
72
+ {
73
+ $title = htmlspecialchars($title, ENT_NOQUOTES, 'UTF-8');
74
+
75
+ return '<h1 style="background: '.$this->logLevels[$level].';color: #ffffff;padding: 5px;" class="monolog-output">'.$title.'</h1>';
76
+ }
77
+ /**
78
+ * Formats a log record.
79
+ *
80
+ * @param array $record A record to format
81
+ * @return mixed The formatted record
82
+ */
83
+ public function format(array $record)
84
+ {
85
+ $output = $this->addTitle($record['level_name'], $record['level']);
86
+ $output .= '<table cellspacing="1" width="100%" class="monolog-output">';
87
+
88
+ $output .= $this->addRow('Message', (string) $record['message']);
89
+ $output .= $this->addRow('Time', $record['datetime']->format($this->dateFormat));
90
+ $output .= $this->addRow('Channel', $record['channel']);
91
+ if ($record['context']) {
92
+ $embeddedTable = '<table cellspacing="1" width="100%">';
93
+ foreach ($record['context'] as $key => $value) {
94
+ $embeddedTable .= $this->addRow($key, $this->convertToString($value));
95
+ }
96
+ $embeddedTable .= '</table>';
97
+ $output .= $this->addRow('Context', $embeddedTable, false);
98
+ }
99
+ if ($record['extra']) {
100
+ $embeddedTable = '<table cellspacing="1" width="100%">';
101
+ foreach ($record['extra'] as $key => $value) {
102
+ $embeddedTable .= $this->addRow($key, $this->convertToString($value));
103
+ }
104
+ $embeddedTable .= '</table>';
105
+ $output .= $this->addRow('Extra', $embeddedTable, false);
106
+ }
107
+
108
+ return $output.'</table>';
109
+ }
110
+
111
+ /**
112
+ * Formats a set of log records.
113
+ *
114
+ * @param array $records A set of records to format
115
+ * @return mixed The formatted set of records
116
+ */
117
+ public function formatBatch(array $records)
118
+ {
119
+ $message = '';
120
+ foreach ($records as $record) {
121
+ $message .= $this->format($record);
122
+ }
123
+
124
+ return $message;
125
+ }
126
+
127
+ protected function convertToString($data)
128
+ {
129
+ if (null === $data || is_scalar($data)) {
130
+ return (string) $data;
131
+ }
132
+
133
+ $data = $this->normalize($data);
134
+ if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
135
+ return json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
136
+ }
137
+
138
+ return str_replace('\\/', '/', json_encode($data));
139
+ }
140
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ /**
15
+ * Encodes whatever record data is passed to it as json
16
+ *
17
+ * This can be useful to log to databases or remote APIs
18
+ *
19
+ * @author Jordi Boggiano <j.boggiano@seld.be>
20
+ */
21
+ class JsonFormatter implements FormatterInterface
22
+ {
23
+ const BATCH_MODE_JSON = 1;
24
+ const BATCH_MODE_NEWLINES = 2;
25
+
26
+ protected $batchMode;
27
+ protected $appendNewline;
28
+
29
+ /**
30
+ * @param int $batchMode
31
+ */
32
+ public function __construct($batchMode = self::BATCH_MODE_JSON, $appendNewline = true)
33
+ {
34
+ $this->batchMode = $batchMode;
35
+ $this->appendNewline = $appendNewline;
36
+ }
37
+
38
+ /**
39
+ * The batch mode option configures the formatting style for
40
+ * multiple records. By default, multiple records will be
41
+ * formatted as a JSON-encoded array. However, for
42
+ * compatibility with some API endpoints, alternative styles
43
+ * are available.
44
+ *
45
+ * @return int
46
+ */
47
+ public function getBatchMode()
48
+ {
49
+ return $this->batchMode;
50
+ }
51
+
52
+ /**
53
+ * True if newlines are appended to every formatted record
54
+ *
55
+ * @return bool
56
+ */
57
+ public function isAppendingNewlines()
58
+ {
59
+ return $this->appendNewline;
60
+ }
61
+
62
+ /**
63
+ * {@inheritdoc}
64
+ */
65
+ public function format(array $record)
66
+ {
67
+ return json_encode($record) . ($this->appendNewline ? "\n" : '');
68
+ }
69
+
70
+ /**
71
+ * {@inheritdoc}
72
+ */
73
+ public function formatBatch(array $records)
74
+ {
75
+ switch ($this->batchMode) {
76
+ case static::BATCH_MODE_NEWLINES:
77
+ return $this->formatBatchNewlines($records);
78
+
79
+ case static::BATCH_MODE_JSON:
80
+ default:
81
+ return $this->formatBatchJson($records);
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Return a JSON-encoded array of records.
87
+ *
88
+ * @param array $records
89
+ * @return string
90
+ */
91
+ protected function formatBatchJson(array $records)
92
+ {
93
+ return json_encode($records);
94
+ }
95
+
96
+ /**
97
+ * Use new lines to separate records instead of a
98
+ * JSON-encoded array.
99
+ *
100
+ * @param array $records
101
+ * @return string
102
+ */
103
+ protected function formatBatchNewlines(array $records)
104
+ {
105
+ $instance = $this;
106
+
107
+ $oldNewline = $this->appendNewline;
108
+ $this->appendNewline = false;
109
+ array_walk($records, function (&$value, $key) use ($instance) {
110
+ $value = $instance->format($value);
111
+ });
112
+ $this->appendNewline = $oldNewline;
113
+
114
+ return implode("\n", $records);
115
+ }
116
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ use Exception;
15
+
16
+ /**
17
+ * Formats incoming records into a one-line string
18
+ *
19
+ * This is especially useful for logging to files
20
+ *
21
+ * @author Jordi Boggiano <j.boggiano@seld.be>
22
+ * @author Christophe Coevoet <stof@notk.org>
23
+ */
24
+ class LineFormatter extends NormalizerFormatter
25
+ {
26
+ const SIMPLE_FORMAT = "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n";
27
+
28
+ protected $format;
29
+ protected $allowInlineLineBreaks;
30
+ protected $ignoreEmptyContextAndExtra;
31
+ protected $includeStacktraces;
32
+
33
+ /**
34
+ * @param string $format The format of the message
35
+ * @param string $dateFormat The format of the timestamp: one supported by DateTime::format
36
+ * @param bool $allowInlineLineBreaks Whether to allow inline line breaks in log entries
37
+ * @param bool $ignoreEmptyContextAndExtra
38
+ */
39
+ public function __construct($format = null, $dateFormat = null, $allowInlineLineBreaks = false, $ignoreEmptyContextAndExtra = false)
40
+ {
41
+ $this->format = $format ?: static::SIMPLE_FORMAT;
42
+ $this->allowInlineLineBreaks = $allowInlineLineBreaks;
43
+ $this->ignoreEmptyContextAndExtra = $ignoreEmptyContextAndExtra;
44
+ parent::__construct($dateFormat);
45
+ }
46
+
47
+ public function includeStacktraces($include = true)
48
+ {
49
+ $this->includeStacktraces = $include;
50
+ if ($this->includeStacktraces) {
51
+ $this->allowInlineLineBreaks = true;
52
+ }
53
+ }
54
+
55
+ public function allowInlineLineBreaks($allow = true)
56
+ {
57
+ $this->allowInlineLineBreaks = $allow;
58
+ }
59
+
60
+ public function ignoreEmptyContextAndExtra($ignore = true)
61
+ {
62
+ $this->ignoreEmptyContextAndExtra = $ignore;
63
+ }
64
+
65
+ /**
66
+ * {@inheritdoc}
67
+ */
68
+ public function format(array $record)
69
+ {
70
+ $vars = parent::format($record);
71
+
72
+ $output = $this->format;
73
+
74
+ foreach ($vars['extra'] as $var => $val) {
75
+ if (false !== strpos($output, '%extra.'.$var.'%')) {
76
+ $output = str_replace('%extra.'.$var.'%', $this->stringify($val), $output);
77
+ unset($vars['extra'][$var]);
78
+ }
79
+ }
80
+
81
+ if ($this->ignoreEmptyContextAndExtra) {
82
+ if (empty($vars['context'])) {
83
+ unset($vars['context']);
84
+ $output = str_replace('%context%', '', $output);
85
+ }
86
+
87
+ if (empty($vars['extra'])) {
88
+ unset($vars['extra']);
89
+ $output = str_replace('%extra%', '', $output);
90
+ }
91
+ }
92
+
93
+ foreach ($vars as $var => $val) {
94
+ if (false !== strpos($output, '%'.$var.'%')) {
95
+ $output = str_replace('%'.$var.'%', $this->stringify($val), $output);
96
+ }
97
+ }
98
+
99
+ return $output;
100
+ }
101
+
102
+ public function formatBatch(array $records)
103
+ {
104
+ $message = '';
105
+ foreach ($records as $record) {
106
+ $message .= $this->format($record);
107
+ }
108
+
109
+ return $message;
110
+ }
111
+
112
+ public function stringify($value)
113
+ {
114
+ return $this->replaceNewlines($this->convertToString($value));
115
+ }
116
+
117
+ protected function normalizeException(Exception $e)
118
+ {
119
+ $previousText = '';
120
+ if ($previous = $e->getPrevious()) {
121
+ do {
122
+ $previousText .= ', '.get_class($previous).'(code: '.$previous->getCode().'): '.$previous->getMessage().' at '.$previous->getFile().':'.$previous->getLine();
123
+ } while ($previous = $previous->getPrevious());
124
+ }
125
+
126
+ $str = '[object] ('.get_class($e).'(code: '.$e->getCode().'): '.$e->getMessage().' at '.$e->getFile().':'.$e->getLine().$previousText.')';
127
+ if ($this->includeStacktraces) {
128
+ $str .= "\n[stacktrace]\n".$e->getTraceAsString();
129
+ }
130
+
131
+ return $str;
132
+ }
133
+
134
+ protected function convertToString($data)
135
+ {
136
+ if (null === $data || is_bool($data)) {
137
+ return var_export($data, true);
138
+ }
139
+
140
+ if (is_scalar($data)) {
141
+ return (string) $data;
142
+ }
143
+
144
+ if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
145
+ return $this->toJson($data, true);
146
+ }
147
+
148
+ return str_replace('\\/', '/', @json_encode($data));
149
+ }
150
+
151
+ protected function replaceNewlines($str)
152
+ {
153
+ if ($this->allowInlineLineBreaks) {
154
+ return $str;
155
+ }
156
+
157
+ return strtr($str, array("\r\n" => ' ', "\r" => ' ', "\n" => ' '));
158
+ }
159
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/LogglyFormatter.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ /**
15
+ * Encodes message information into JSON in a format compatible with Loggly.
16
+ *
17
+ * @author Adam Pancutt <adam@pancutt.com>
18
+ */
19
+ class LogglyFormatter extends JsonFormatter
20
+ {
21
+ /**
22
+ * Overrides the default batch mode to new lines for compatibility with the
23
+ * Loggly bulk API.
24
+ *
25
+ * @param integer $batchMode
26
+ */
27
+ public function __construct($batchMode = self::BATCH_MODE_NEWLINES, $appendNewline = false)
28
+ {
29
+ parent::__construct($batchMode, $appendNewline);
30
+ }
31
+
32
+ /**
33
+ * Appends the 'timestamp' parameter for indexing by Loggly.
34
+ *
35
+ * @see https://www.loggly.com/docs/automated-parsing/#json
36
+ * @see \Monolog\Formatter\JsonFormatter::format()
37
+ */
38
+ public function format(array $record)
39
+ {
40
+ if (isset($record["datetime"]) && ($record["datetime"] instanceof \DateTime)) {
41
+ $record["timestamp"] = $record["datetime"]->format("Y-m-d\TH:i:s.uO");
42
+ // TODO 2.0 unset the 'datetime' parameter, retained for BC
43
+ }
44
+
45
+ return parent::format($record);
46
+ }
47
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/LogstashFormatter.php ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ /**
15
+ * Serializes a log message to Logstash Event Format
16
+ *
17
+ * @see http://logstash.net/
18
+ * @see https://github.com/logstash/logstash/blob/master/lib/logstash/event.rb
19
+ *
20
+ * @author Tim Mower <timothy.mower@gmail.com>
21
+ */
22
+ class LogstashFormatter extends NormalizerFormatter
23
+ {
24
+ const V0 = 0;
25
+ const V1 = 1;
26
+
27
+ /**
28
+ * @var string the name of the system for the Logstash log message, used to fill the @source field
29
+ */
30
+ protected $systemName;
31
+
32
+ /**
33
+ * @var string an application name for the Logstash log message, used to fill the @type field
34
+ */
35
+ protected $applicationName;
36
+
37
+ /**
38
+ * @var string a prefix for 'extra' fields from the Monolog record (optional)
39
+ */
40
+ protected $extraPrefix;
41
+
42
+ /**
43
+ * @var string a prefix for 'context' fields from the Monolog record (optional)
44
+ */
45
+ protected $contextPrefix;
46
+
47
+ /**
48
+ * @var integer logstash format version to use
49
+ */
50
+ protected $version;
51
+
52
+ /**
53
+ * @param string $applicationName the application that sends the data, used as the "type" field of logstash
54
+ * @param string $systemName the system/machine name, used as the "source" field of logstash, defaults to the hostname of the machine
55
+ * @param string $extraPrefix prefix for extra keys inside logstash "fields"
56
+ * @param string $contextPrefix prefix for context keys inside logstash "fields", defaults to ctxt_
57
+ */
58
+ public function __construct($applicationName, $systemName = null, $extraPrefix = null, $contextPrefix = 'ctxt_', $version = self::V0)
59
+ {
60
+ // logstash requires a ISO 8601 format date with optional millisecond precision.
61
+ parent::__construct('Y-m-d\TH:i:s.uP');
62
+
63
+ $this->systemName = $systemName ?: gethostname();
64
+ $this->applicationName = $applicationName;
65
+ $this->extraPrefix = $extraPrefix;
66
+ $this->contextPrefix = $contextPrefix;
67
+ $this->version = $version;
68
+ }
69
+
70
+ /**
71
+ * {@inheritdoc}
72
+ */
73
+ public function format(array $record)
74
+ {
75
+ $record = parent::format($record);
76
+
77
+ if ($this->version === self::V1) {
78
+ $message = $this->formatV1($record);
79
+ } else {
80
+ $message = $this->formatV0($record);
81
+ }
82
+
83
+ return $this->toJson($message) . "\n";
84
+ }
85
+
86
+ protected function formatV0(array $record)
87
+ {
88
+ if (empty($record['datetime'])) {
89
+ $record['datetime'] = gmdate('c');
90
+ }
91
+ $message = array(
92
+ '@timestamp' => $record['datetime'],
93
+ '@source' => $this->systemName,
94
+ '@fields' => array()
95
+ );
96
+ if (isset($record['message'])) {
97
+ $message['@message'] = $record['message'];
98
+ }
99
+ if (isset($record['channel'])) {
100
+ $message['@tags'] = array($record['channel']);
101
+ $message['@fields']['channel'] = $record['channel'];
102
+ }
103
+ if (isset($record['level'])) {
104
+ $message['@fields']['level'] = $record['level'];
105
+ }
106
+ if ($this->applicationName) {
107
+ $message['@type'] = $this->applicationName;
108
+ }
109
+ if (isset($record['extra']['server'])) {
110
+ $message['@source_host'] = $record['extra']['server'];
111
+ }
112
+ if (isset($record['extra']['url'])) {
113
+ $message['@source_path'] = $record['extra']['url'];
114
+ }
115
+ if (!empty($record['extra'])) {
116
+ foreach ($record['extra'] as $key => $val) {
117
+ $message['@fields'][$this->extraPrefix . $key] = $val;
118
+ }
119
+ }
120
+ if (!empty($record['context'])) {
121
+ foreach ($record['context'] as $key => $val) {
122
+ $message['@fields'][$this->contextPrefix . $key] = $val;
123
+ }
124
+ }
125
+
126
+ return $message;
127
+ }
128
+
129
+ protected function formatV1(array $record)
130
+ {
131
+ if (empty($record['datetime'])) {
132
+ $record['datetime'] = gmdate('c');
133
+ }
134
+ $message = array(
135
+ '@timestamp' => $record['datetime'],
136
+ '@version' => 1,
137
+ 'host' => $this->systemName,
138
+ );
139
+ if (isset($record['message'])) {
140
+ $message['message'] = $record['message'];
141
+ }
142
+ if (isset($record['channel'])) {
143
+ $message['type'] = $record['channel'];
144
+ $message['channel'] = $record['channel'];
145
+ }
146
+ if (isset($record['level_name'])) {
147
+ $message['level'] = $record['level_name'];
148
+ }
149
+ if ($this->applicationName) {
150
+ $message['type'] = $this->applicationName;
151
+ }
152
+ if (!empty($record['extra'])) {
153
+ foreach ($record['extra'] as $key => $val) {
154
+ $message[$this->extraPrefix . $key] = $val;
155
+ }
156
+ }
157
+ if (!empty($record['context'])) {
158
+ foreach ($record['context'] as $key => $val) {
159
+ $message[$this->contextPrefix . $key] = $val;
160
+ }
161
+ }
162
+
163
+ return $message;
164
+ }
165
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/MongoDBFormatter.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ /**
15
+ * Formats a record for use with the MongoDBHandler.
16
+ *
17
+ * @author Florian Plattner <me@florianplattner.de>
18
+ */
19
+ class MongoDBFormatter implements FormatterInterface
20
+ {
21
+ private $exceptionTraceAsString;
22
+ private $maxNestingLevel;
23
+
24
+ /**
25
+ * @param int $maxNestingLevel 0 means infinite nesting, the $record itself is level 1, $record['context'] is 2
26
+ * @param bool $exceptionTraceAsString set to false to log exception traces as a sub documents instead of strings
27
+ */
28
+ public function __construct($maxNestingLevel = 3, $exceptionTraceAsString = true)
29
+ {
30
+ $this->maxNestingLevel = max($maxNestingLevel, 0);
31
+ $this->exceptionTraceAsString = (bool) $exceptionTraceAsString;
32
+ }
33
+
34
+ /**
35
+ * {@inheritDoc}
36
+ */
37
+ public function format(array $record)
38
+ {
39
+ return $this->formatArray($record);
40
+ }
41
+
42
+ /**
43
+ * {@inheritDoc}
44
+ */
45
+ public function formatBatch(array $records)
46
+ {
47
+ foreach ($records as $key => $record) {
48
+ $records[$key] = $this->format($record);
49
+ }
50
+
51
+ return $records;
52
+ }
53
+
54
+ protected function formatArray(array $record, $nestingLevel = 0)
55
+ {
56
+ if ($this->maxNestingLevel == 0 || $nestingLevel <= $this->maxNestingLevel) {
57
+ foreach ($record as $name => $value) {
58
+ if ($value instanceof \DateTime) {
59
+ $record[$name] = $this->formatDate($value, $nestingLevel + 1);
60
+ } elseif ($value instanceof \Exception) {
61
+ $record[$name] = $this->formatException($value, $nestingLevel + 1);
62
+ } elseif (is_array($value)) {
63
+ $record[$name] = $this->formatArray($value, $nestingLevel + 1);
64
+ } elseif (is_object($value)) {
65
+ $record[$name] = $this->formatObject($value, $nestingLevel + 1);
66
+ }
67
+ }
68
+ } else {
69
+ $record = '[...]';
70
+ }
71
+
72
+ return $record;
73
+ }
74
+
75
+ protected function formatObject($value, $nestingLevel)
76
+ {
77
+ $objectVars = get_object_vars($value);
78
+ $objectVars['class'] = get_class($value);
79
+
80
+ return $this->formatArray($objectVars, $nestingLevel);
81
+ }
82
+
83
+ protected function formatException(\Exception $exception, $nestingLevel)
84
+ {
85
+ $formattedException = array(
86
+ 'class' => get_class($exception),
87
+ 'message' => $exception->getMessage(),
88
+ 'code' => $exception->getCode(),
89
+ 'file' => $exception->getFile() . ':' . $exception->getLine(),
90
+ );
91
+
92
+ if ($this->exceptionTraceAsString === true) {
93
+ $formattedException['trace'] = $exception->getTraceAsString();
94
+ } else {
95
+ $formattedException['trace'] = $exception->getTrace();
96
+ }
97
+
98
+ return $this->formatArray($formattedException, $nestingLevel);
99
+ }
100
+
101
+ protected function formatDate(\DateTime $value, $nestingLevel)
102
+ {
103
+ return new \MongoDate($value->getTimestamp());
104
+ }
105
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ use Exception;
15
+
16
+ /**
17
+ * Normalizes incoming records to remove objects/resources so it's easier to dump to various targets
18
+ *
19
+ * @author Jordi Boggiano <j.boggiano@seld.be>
20
+ */
21
+ class NormalizerFormatter implements FormatterInterface
22
+ {
23
+ const SIMPLE_DATE = "Y-m-d H:i:s";
24
+
25
+ protected $dateFormat;
26
+
27
+ /**
28
+ * @param string $dateFormat The format of the timestamp: one supported by DateTime::format
29
+ */
30
+ public function __construct($dateFormat = null)
31
+ {
32
+ $this->dateFormat = $dateFormat ?: static::SIMPLE_DATE;
33
+ if (!function_exists('json_encode')) {
34
+ throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s NormalizerFormatter');
35
+ }
36
+ }
37
+
38
+ /**
39
+ * {@inheritdoc}
40
+ */
41
+ public function format(array $record)
42
+ {
43
+ return $this->normalize($record);
44
+ }
45
+
46
+ /**
47
+ * {@inheritdoc}
48
+ */
49
+ public function formatBatch(array $records)
50
+ {
51
+ foreach ($records as $key => $record) {
52
+ $records[$key] = $this->format($record);
53
+ }
54
+
55
+ return $records;
56
+ }
57
+
58
+ protected function normalize($data)
59
+ {
60
+ if (null === $data || is_scalar($data)) {
61
+ if (is_float($data)) {
62
+ if (is_infinite($data)) {
63
+ return ($data > 0 ? '' : '-') . 'INF';
64
+ }
65
+ if (is_nan($data)) {
66
+ return 'NaN';
67
+ }
68
+ }
69
+
70
+ return $data;
71
+ }
72
+
73
+ if (is_array($data) || $data instanceof \Traversable) {
74
+ $normalized = array();
75
+
76
+ $count = 1;
77
+ foreach ($data as $key => $value) {
78
+ if ($count++ >= 1000) {
79
+ $normalized['...'] = 'Over 1000 items, aborting normalization';
80
+ break;
81
+ }
82
+ $normalized[$key] = $this->normalize($value);
83
+ }
84
+
85
+ return $normalized;
86
+ }
87
+
88
+ if ($data instanceof \DateTime) {
89
+ return $data->format($this->dateFormat);
90
+ }
91
+
92
+ if (is_object($data)) {
93
+ if ($data instanceof Exception) {
94
+ return $this->normalizeException($data);
95
+ }
96
+
97
+ return sprintf("[object] (%s: %s)", get_class($data), $this->toJson($data, true));
98
+ }
99
+
100
+ if (is_resource($data)) {
101
+ return '[resource]';
102
+ }
103
+
104
+ return '[unknown('.gettype($data).')]';
105
+ }
106
+
107
+ protected function normalizeException(Exception $e)
108
+ {
109
+ $data = array(
110
+ 'class' => get_class($e),
111
+ 'message' => $e->getMessage(),
112
+ 'code' => $e->getCode(),
113
+ 'file' => $e->getFile().':'.$e->getLine(),
114
+ );
115
+
116
+ $trace = $e->getTrace();
117
+ foreach ($trace as $frame) {
118
+ if (isset($frame['file'])) {
119
+ $data['trace'][] = $frame['file'].':'.$frame['line'];
120
+ } else {
121
+ // We should again normalize the frames, because it might contain invalid items
122
+ $data['trace'][] = $this->toJson($this->normalize($frame), true);
123
+ }
124
+ }
125
+
126
+ if ($previous = $e->getPrevious()) {
127
+ $data['previous'] = $this->normalizeException($previous);
128
+ }
129
+
130
+ return $data;
131
+ }
132
+
133
+ protected function toJson($data, $ignoreErrors = false)
134
+ {
135
+ // suppress json_encode errors since it's twitchy with some inputs
136
+ if ($ignoreErrors) {
137
+ if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
138
+ return @json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
139
+ }
140
+
141
+ return @json_encode($data);
142
+ }
143
+
144
+ if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
145
+ return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
146
+ }
147
+
148
+ return json_encode($data);
149
+ }
150
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/ScalarFormatter.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ /**
15
+ * Formats data into an associative array of scalar values.
16
+ * Objects and arrays will be JSON encoded.
17
+ *
18
+ * @author Andrew Lawson <adlawson@gmail.com>
19
+ */
20
+ class ScalarFormatter extends NormalizerFormatter
21
+ {
22
+ /**
23
+ * {@inheritdoc}
24
+ */
25
+ public function format(array $record)
26
+ {
27
+ foreach ($record as $key => $value) {
28
+ $record[$key] = $this->normalizeValue($value);
29
+ }
30
+
31
+ return $record;
32
+ }
33
+
34
+ /**
35
+ * @param mixed $value
36
+ * @return mixed
37
+ */
38
+ protected function normalizeValue($value)
39
+ {
40
+ $normalized = $this->normalize($value);
41
+
42
+ if (is_array($normalized) || is_object($normalized)) {
43
+ return $this->toJson($normalized, true);
44
+ }
45
+
46
+ return $normalized;
47
+ }
48
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Formatter/WildfireFormatter.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Serializes a log message according to Wildfire's header requirements
18
+ *
19
+ * @author Eric Clemmons (@ericclemmons) <eric@uxdriven.com>
20
+ * @author Christophe Coevoet <stof@notk.org>
21
+ * @author Kirill chEbba Chebunin <iam@chebba.org>
22
+ */
23
+ class WildfireFormatter extends NormalizerFormatter
24
+ {
25
+ const TABLE = 'table';
26
+
27
+ /**
28
+ * Translates Monolog log levels to Wildfire levels.
29
+ */
30
+ private $logLevels = array(
31
+ Logger::DEBUG => 'LOG',
32
+ Logger::INFO => 'INFO',
33
+ Logger::NOTICE => 'INFO',
34
+ Logger::WARNING => 'WARN',
35
+ Logger::ERROR => 'ERROR',
36
+ Logger::CRITICAL => 'ERROR',
37
+ Logger::ALERT => 'ERROR',
38
+ Logger::EMERGENCY => 'ERROR',
39
+ );
40
+
41
+ /**
42
+ * {@inheritdoc}
43
+ */
44
+ public function format(array $record)
45
+ {
46
+ // Retrieve the line and file if set and remove them from the formatted extra
47
+ $file = $line = '';
48
+ if (isset($record['extra']['file'])) {
49
+ $file = $record['extra']['file'];
50
+ unset($record['extra']['file']);
51
+ }
52
+ if (isset($record['extra']['line'])) {
53
+ $line = $record['extra']['line'];
54
+ unset($record['extra']['line']);
55
+ }
56
+
57
+ $record = $this->normalize($record);
58
+ $message = array('message' => $record['message']);
59
+ $handleError = false;
60
+ if ($record['context']) {
61
+ $message['context'] = $record['context'];
62
+ $handleError = true;
63
+ }
64
+ if ($record['extra']) {
65
+ $message['extra'] = $record['extra'];
66
+ $handleError = true;
67
+ }
68
+ if (count($message) === 1) {
69
+ $message = reset($message);
70
+ }
71
+
72
+ if (isset($record['context'][self::TABLE])) {
73
+ $type = 'TABLE';
74
+ $label = $record['channel'] .': '. $record['message'];
75
+ $message = $record['context'][self::TABLE];
76
+ } else {
77
+ $type = $this->logLevels[$record['level']];
78
+ $label = $record['channel'];
79
+ }
80
+
81
+ // Create JSON object describing the appearance of the message in the console
82
+ $json = $this->toJson(array(
83
+ array(
84
+ 'Type' => $type,
85
+ 'File' => $file,
86
+ 'Line' => $line,
87
+ 'Label' => $label,
88
+ ),
89
+ $message,
90
+ ), $handleError);
91
+
92
+ // The message itself is a serialization of the above JSON object + it's length
93
+ return sprintf(
94
+ '%s|%s|',
95
+ strlen($json),
96
+ $json
97
+ );
98
+ }
99
+
100
+ public function formatBatch(array $records)
101
+ {
102
+ throw new \BadMethodCallException('Batch formatting does not make sense for the WildfireFormatter');
103
+ }
104
+
105
+ protected function normalize($data)
106
+ {
107
+ if (is_object($data) && !$data instanceof \DateTime) {
108
+ return $data;
109
+ }
110
+
111
+ return parent::normalize($data);
112
+ }
113
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+ use Monolog\Formatter\FormatterInterface;
16
+ use Monolog\Formatter\LineFormatter;
17
+
18
+ /**
19
+ * Base Handler class providing the Handler structure
20
+ *
21
+ * @author Jordi Boggiano <j.boggiano@seld.be>
22
+ */
23
+ abstract class AbstractHandler implements HandlerInterface
24
+ {
25
+ protected $level = Logger::DEBUG;
26
+ protected $bubble = true;
27
+
28
+ /**
29
+ * @var FormatterInterface
30
+ */
31
+ protected $formatter;
32
+ protected $processors = array();
33
+
34
+ /**
35
+ * @param integer $level The minimum logging level at which this handler will be triggered
36
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
37
+ */
38
+ public function __construct($level = Logger::DEBUG, $bubble = true)
39
+ {
40
+ $this->setLevel($level);
41
+ $this->bubble = $bubble;
42
+ }
43
+
44
+ /**
45
+ * {@inheritdoc}
46
+ */
47
+ public function isHandling(array $record)
48
+ {
49
+ return $record['level'] >= $this->level;
50
+ }
51
+
52
+ /**
53
+ * {@inheritdoc}
54
+ */
55
+ public function handleBatch(array $records)
56
+ {
57
+ foreach ($records as $record) {
58
+ $this->handle($record);
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Closes the handler.
64
+ *
65
+ * This will be called automatically when the object is destroyed
66
+ */
67
+ public function close()
68
+ {
69
+ }
70
+
71
+ /**
72
+ * {@inheritdoc}
73
+ */
74
+ public function pushProcessor($callback)
75
+ {
76
+ if (!is_callable($callback)) {
77
+ throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given');
78
+ }
79
+ array_unshift($this->processors, $callback);
80
+
81
+ return $this;
82
+ }
83
+
84
+ /**
85
+ * {@inheritdoc}
86
+ */
87
+ public function popProcessor()
88
+ {
89
+ if (!$this->processors) {
90
+ throw new \LogicException('You tried to pop from an empty processor stack.');
91
+ }
92
+
93
+ return array_shift($this->processors);
94
+ }
95
+
96
+ /**
97
+ * {@inheritdoc}
98
+ */
99
+ public function setFormatter(FormatterInterface $formatter)
100
+ {
101
+ $this->formatter = $formatter;
102
+
103
+ return $this;
104
+ }
105
+
106
+ /**
107
+ * {@inheritdoc}
108
+ */
109
+ public function getFormatter()
110
+ {
111
+ if (!$this->formatter) {
112
+ $this->formatter = $this->getDefaultFormatter();
113
+ }
114
+
115
+ return $this->formatter;
116
+ }
117
+
118
+ /**
119
+ * Sets minimum logging level at which this handler will be triggered.
120
+ *
121
+ * @param integer $level
122
+ * @return self
123
+ */
124
+ public function setLevel($level)
125
+ {
126
+ $this->level = Logger::toMonologLevel($level);
127
+
128
+ return $this;
129
+ }
130
+
131
+ /**
132
+ * Gets minimum logging level at which this handler will be triggered.
133
+ *
134
+ * @return integer
135
+ */
136
+ public function getLevel()
137
+ {
138
+ return $this->level;
139
+ }
140
+
141
+ /**
142
+ * Sets the bubbling behavior.
143
+ *
144
+ * @param Boolean $bubble true means that this handler allows bubbling.
145
+ * false means that bubbling is not permitted.
146
+ * @return self
147
+ */
148
+ public function setBubble($bubble)
149
+ {
150
+ $this->bubble = $bubble;
151
+
152
+ return $this;
153
+ }
154
+
155
+ /**
156
+ * Gets the bubbling behavior.
157
+ *
158
+ * @return Boolean true means that this handler allows bubbling.
159
+ * false means that bubbling is not permitted.
160
+ */
161
+ public function getBubble()
162
+ {
163
+ return $this->bubble;
164
+ }
165
+
166
+ public function __destruct()
167
+ {
168
+ try {
169
+ $this->close();
170
+ } catch (\Exception $e) {
171
+ // do nothing
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Gets the default formatter.
177
+ *
178
+ * @return FormatterInterface
179
+ */
180
+ protected function getDefaultFormatter()
181
+ {
182
+ return new LineFormatter();
183
+ }
184
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ /**
15
+ * Base Handler class providing the Handler structure
16
+ *
17
+ * Classes extending it should (in most cases) only implement write($record)
18
+ *
19
+ * @author Jordi Boggiano <j.boggiano@seld.be>
20
+ * @author Christophe Coevoet <stof@notk.org>
21
+ */
22
+ abstract class AbstractProcessingHandler extends AbstractHandler
23
+ {
24
+ /**
25
+ * {@inheritdoc}
26
+ */
27
+ public function handle(array $record)
28
+ {
29
+ if (!$this->isHandling($record)) {
30
+ return false;
31
+ }
32
+
33
+ $record = $this->processRecord($record);
34
+
35
+ $record['formatted'] = $this->getFormatter()->format($record);
36
+
37
+ $this->write($record);
38
+
39
+ return false === $this->bubble;
40
+ }
41
+
42
+ /**
43
+ * Writes the record down to the log of the implementing handler
44
+ *
45
+ * @param array $record
46
+ * @return void
47
+ */
48
+ abstract protected function write(array $record);
49
+
50
+ /**
51
+ * Processes a record.
52
+ *
53
+ * @param array $record
54
+ * @return array
55
+ */
56
+ protected function processRecord(array $record)
57
+ {
58
+ if ($this->processors) {
59
+ foreach ($this->processors as $processor) {
60
+ $record = call_user_func($processor, $record);
61
+ }
62
+ }
63
+
64
+ return $record;
65
+ }
66
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+ use Monolog\Formatter\LineFormatter;
16
+
17
+ /**
18
+ * Common syslog functionality
19
+ */
20
+ abstract class AbstractSyslogHandler extends AbstractProcessingHandler
21
+ {
22
+ protected $facility;
23
+
24
+ /**
25
+ * Translates Monolog log levels to syslog log priorities.
26
+ */
27
+ protected $logLevels = array(
28
+ Logger::DEBUG => LOG_DEBUG,
29
+ Logger::INFO => LOG_INFO,
30
+ Logger::NOTICE => LOG_NOTICE,
31
+ Logger::WARNING => LOG_WARNING,
32
+ Logger::ERROR => LOG_ERR,
33
+ Logger::CRITICAL => LOG_CRIT,
34
+ Logger::ALERT => LOG_ALERT,
35
+ Logger::EMERGENCY => LOG_EMERG,
36
+ );
37
+
38
+ /**
39
+ * List of valid log facility names.
40
+ */
41
+ protected $facilities = array(
42
+ 'auth' => LOG_AUTH,
43
+ 'authpriv' => LOG_AUTHPRIV,
44
+ 'cron' => LOG_CRON,
45
+ 'daemon' => LOG_DAEMON,
46
+ 'kern' => LOG_KERN,
47
+ 'lpr' => LOG_LPR,
48
+ 'mail' => LOG_MAIL,
49
+ 'news' => LOG_NEWS,
50
+ 'syslog' => LOG_SYSLOG,
51
+ 'user' => LOG_USER,
52
+ 'uucp' => LOG_UUCP,
53
+ );
54
+
55
+ /**
56
+ * @param mixed $facility
57
+ * @param integer $level The minimum logging level at which this handler will be triggered
58
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
59
+ */
60
+ public function __construct($facility = LOG_USER, $level = Logger::DEBUG, $bubble = true)
61
+ {
62
+ parent::__construct($level, $bubble);
63
+
64
+ if (!defined('PHP_WINDOWS_VERSION_BUILD')) {
65
+ $this->facilities['local0'] = LOG_LOCAL0;
66
+ $this->facilities['local1'] = LOG_LOCAL1;
67
+ $this->facilities['local2'] = LOG_LOCAL2;
68
+ $this->facilities['local3'] = LOG_LOCAL3;
69
+ $this->facilities['local4'] = LOG_LOCAL4;
70
+ $this->facilities['local5'] = LOG_LOCAL5;
71
+ $this->facilities['local6'] = LOG_LOCAL6;
72
+ $this->facilities['local7'] = LOG_LOCAL7;
73
+ }
74
+
75
+ // convert textual description of facility to syslog constant
76
+ if (array_key_exists(strtolower($facility), $this->facilities)) {
77
+ $facility = $this->facilities[strtolower($facility)];
78
+ } elseif (!in_array($facility, array_values($this->facilities), true)) {
79
+ throw new \UnexpectedValueException('Unknown facility value "'.$facility.'" given');
80
+ }
81
+
82
+ $this->facility = $facility;
83
+ }
84
+
85
+ /**
86
+ * {@inheritdoc}
87
+ */
88
+ protected function getDefaultFormatter()
89
+ {
90
+ return new LineFormatter('%channel%.%level_name%: %message% %context% %extra%');
91
+ }
92
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+ use Monolog\Formatter\JsonFormatter;
16
+ use PhpAmqpLib\Message\AMQPMessage;
17
+ use PhpAmqpLib\Channel\AMQPChannel;
18
+ use AMQPExchange;
19
+
20
+ class AmqpHandler extends AbstractProcessingHandler
21
+ {
22
+ /**
23
+ * @var AMQPExchange|AMQPChannel $exchange
24
+ */
25
+ protected $exchange;
26
+
27
+ /**
28
+ * @var string
29
+ */
30
+ protected $exchangeName;
31
+
32
+ /**
33
+ * @param AMQPExchange|AMQPChannel $exchange AMQPExchange (php AMQP ext) or PHP AMQP lib channel, ready for use
34
+ * @param string $exchangeName
35
+ * @param int $level
36
+ * @param bool $bubble Whether the messages that are handled can bubble up the stack or not
37
+ */
38
+ public function __construct($exchange, $exchangeName = 'log', $level = Logger::DEBUG, $bubble = true)
39
+ {
40
+ if ($exchange instanceof AMQPExchange) {
41
+ $exchange->setName($exchangeName);
42
+ } elseif ($exchange instanceof AMQPChannel) {
43
+ $this->exchangeName = $exchangeName;
44
+ } else {
45
+ throw new \InvalidArgumentException('PhpAmqpLib\Channel\AMQPChannel or AMQPExchange instance required');
46
+ }
47
+ $this->exchange = $exchange;
48
+
49
+ parent::__construct($level, $bubble);
50
+ }
51
+
52
+ /**
53
+ * {@inheritDoc}
54
+ */
55
+ protected function write(array $record)
56
+ {
57
+ $data = $record["formatted"];
58
+
59
+ $routingKey = sprintf(
60
+ '%s.%s',
61
+ // TODO 2.0 remove substr call
62
+ substr($record['level_name'], 0, 4),
63
+ $record['channel']
64
+ );
65
+
66
+ if ($this->exchange instanceof AMQPExchange) {
67
+ $this->exchange->publish(
68
+ $data,
69
+ strtolower($routingKey),
70
+ 0,
71
+ array(
72
+ 'delivery_mode' => 2,
73
+ 'Content-type' => 'application/json'
74
+ )
75
+ );
76
+ } else {
77
+ $this->exchange->basic_publish(
78
+ new AMQPMessage(
79
+ (string) $data,
80
+ array(
81
+ 'delivery_mode' => 2,
82
+ 'content_type' => 'application/json'
83
+ )
84
+ ),
85
+ $this->exchangeName,
86
+ strtolower($routingKey)
87
+ );
88
+ }
89
+ }
90
+
91
+ /**
92
+ * {@inheritDoc}
93
+ */
94
+ protected function getDefaultFormatter()
95
+ {
96
+ return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false);
97
+ }
98
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/BrowserConsoleHandler.php ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Formatter\LineFormatter;
15
+
16
+ /**
17
+ * Handler sending logs to browser's javascript console with no browser extension required
18
+ *
19
+ * @author Olivier Poitrey <rs@dailymotion.com>
20
+ */
21
+ class BrowserConsoleHandler extends AbstractProcessingHandler
22
+ {
23
+ protected static $initialized = false;
24
+ protected static $records = array();
25
+
26
+ /**
27
+ * {@inheritDoc}
28
+ *
29
+ * Formatted output may contain some formatting markers to be transferred to `console.log` using the %c format.
30
+ *
31
+ * Example of formatted string:
32
+ *
33
+ * You can do [[blue text]]{color: blue} or [[green background]]{background-color: green; color: white}
34
+ *
35
+ */
36
+ protected function getDefaultFormatter()
37
+ {
38
+ return new LineFormatter('[[%channel%]]{macro: autolabel} [[%level_name%]]{font-weight: bold} %message%');
39
+ }
40
+
41
+ /**
42
+ * {@inheritDoc}
43
+ */
44
+ protected function write(array $record)
45
+ {
46
+ // Accumulate records
47
+ self::$records[] = $record;
48
+
49
+ // Register shutdown handler if not already done
50
+ if (PHP_SAPI !== 'cli' && !self::$initialized) {
51
+ self::$initialized = true;
52
+ register_shutdown_function(array('Monolog\Handler\BrowserConsoleHandler', 'send'));
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Convert records to javascript console commands and send it to the browser.
58
+ * This method is automatically called on PHP shutdown if output is HTML.
59
+ */
60
+ public static function send()
61
+ {
62
+ // Check content type
63
+ foreach (headers_list() as $header) {
64
+ if (stripos($header, 'content-type:') === 0) {
65
+ if (stripos($header, 'text/html') === false) {
66
+ // This handler only works with HTML outputs
67
+ return;
68
+ }
69
+ break;
70
+ }
71
+ }
72
+
73
+ if (count(self::$records)) {
74
+ echo '<script>' . self::generateScript() . '</script>';
75
+ self::reset();
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Forget all logged records
81
+ */
82
+ public static function reset()
83
+ {
84
+ self::$records = array();
85
+ }
86
+
87
+ private static function generateScript()
88
+ {
89
+ $script = array();
90
+ foreach (self::$records as $record) {
91
+ $context = self::dump('Context', $record['context']);
92
+ $extra = self::dump('Extra', $record['extra']);
93
+
94
+ if (empty($context) && empty($extra)) {
95
+ $script[] = self::call_array('log', self::handleStyles($record['formatted']));
96
+ } else {
97
+ $script = array_merge($script,
98
+ array(self::call_array('groupCollapsed', self::handleStyles($record['formatted']))),
99
+ $context,
100
+ $extra,
101
+ array(self::call('groupEnd'))
102
+ );
103
+ }
104
+ }
105
+
106
+ return "(function (c) {if (c && c.groupCollapsed) {\n" . implode("\n", $script) . "\n}})(console);";
107
+ }
108
+
109
+ private static function handleStyles($formatted)
110
+ {
111
+ $args = array(self::quote('font-weight: normal'));
112
+ $format = '%c' . $formatted;
113
+ preg_match_all('/\[\[(.*?)\]\]\{([^}]*)\}/s', $format, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
114
+
115
+ foreach (array_reverse($matches) as $match) {
116
+ $args[] = self::quote(self::handleCustomStyles($match[2][0], $match[1][0]));
117
+ $args[] = '"font-weight: normal"';
118
+
119
+ $pos = $match[0][1];
120
+ $format = substr($format, 0, $pos) . '%c' . $match[1][0] . '%c' . substr($format, $pos + strlen($match[0][0]));
121
+ }
122
+
123
+ array_unshift($args, self::quote($format));
124
+
125
+ return $args;
126
+ }
127
+
128
+ private static function handleCustomStyles($style, $string)
129
+ {
130
+ static $colors = array('blue', 'green', 'red', 'magenta', 'orange', 'black', 'grey');
131
+ static $labels = array();
132
+
133
+ return preg_replace_callback('/macro\s*:(.*?)(?:;|$)/', function ($m) use ($string, &$colors, &$labels) {
134
+ if (trim($m[1]) === 'autolabel') {
135
+ // Format the string as a label with consistent auto assigned background color
136
+ if (!isset($labels[$string])) {
137
+ $labels[$string] = $colors[count($labels) % count($colors)];
138
+ }
139
+ $color = $labels[$string];
140
+
141
+ return "background-color: $color; color: white; border-radius: 3px; padding: 0 2px 0 2px";
142
+ }
143
+
144
+ return $m[1];
145
+ }, $style);
146
+ }
147
+
148
+ private static function dump($title, array $dict)
149
+ {
150
+ $script = array();
151
+ $dict = array_filter($dict);
152
+ if (empty($dict)) {
153
+ return $script;
154
+ }
155
+ $script[] = self::call('log', self::quote('%c%s'), self::quote('font-weight: bold'), self::quote($title));
156
+ foreach ($dict as $key => $value) {
157
+ $value = json_encode($value);
158
+ if (empty($value)) {
159
+ $value = self::quote('');
160
+ }
161
+ $script[] = self::call('log', self::quote('%s: %o'), self::quote($key), $value);
162
+ }
163
+
164
+ return $script;
165
+ }
166
+
167
+ private static function quote($arg)
168
+ {
169
+ return '"' . addcslashes($arg, "\"\n") . '"';
170
+ }
171
+
172
+ private static function call()
173
+ {
174
+ $args = func_get_args();
175
+ $method = array_shift($args);
176
+
177
+ return self::call_array($method, $args);
178
+ }
179
+
180
+ private static function call_array($method, array $args)
181
+ {
182
+ return 'c.' . $method . '(' . implode(', ', $args) . ');';
183
+ }
184
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Buffers all records until closing the handler and then pass them as batch.
18
+ *
19
+ * This is useful for a MailHandler to send only one mail per request instead of
20
+ * sending one per log message.
21
+ *
22
+ * @author Christophe Coevoet <stof@notk.org>
23
+ */
24
+ class BufferHandler extends AbstractHandler
25
+ {
26
+ protected $handler;
27
+ protected $bufferSize = 0;
28
+ protected $bufferLimit;
29
+ protected $flushOnOverflow;
30
+ protected $buffer = array();
31
+ protected $initialized = false;
32
+
33
+ /**
34
+ * @param HandlerInterface $handler Handler.
35
+ * @param integer $bufferLimit How many entries should be buffered at most, beyond that the oldest items are removed from the buffer.
36
+ * @param integer $level The minimum logging level at which this handler will be triggered
37
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
38
+ * @param Boolean $flushOnOverflow If true, the buffer is flushed when the max size has been reached, by default oldest entries are discarded
39
+ */
40
+ public function __construct(HandlerInterface $handler, $bufferLimit = 0, $level = Logger::DEBUG, $bubble = true, $flushOnOverflow = false)
41
+ {
42
+ parent::__construct($level, $bubble);
43
+ $this->handler = $handler;
44
+ $this->bufferLimit = (int) $bufferLimit;
45
+ $this->flushOnOverflow = $flushOnOverflow;
46
+ }
47
+
48
+ /**
49
+ * {@inheritdoc}
50
+ */
51
+ public function handle(array $record)
52
+ {
53
+ if ($record['level'] < $this->level) {
54
+ return false;
55
+ }
56
+
57
+ if (!$this->initialized) {
58
+ // __destructor() doesn't get called on Fatal errors
59
+ register_shutdown_function(array($this, 'close'));
60
+ $this->initialized = true;
61
+ }
62
+
63
+ if ($this->bufferLimit > 0 && $this->bufferSize === $this->bufferLimit) {
64
+ if ($this->flushOnOverflow) {
65
+ $this->flush();
66
+ } else {
67
+ array_shift($this->buffer);
68
+ $this->bufferSize--;
69
+ }
70
+ }
71
+
72
+ if ($this->processors) {
73
+ foreach ($this->processors as $processor) {
74
+ $record = call_user_func($processor, $record);
75
+ }
76
+ }
77
+
78
+ $this->buffer[] = $record;
79
+ $this->bufferSize++;
80
+
81
+ return false === $this->bubble;
82
+ }
83
+
84
+ public function flush()
85
+ {
86
+ if ($this->bufferSize === 0) {
87
+ return;
88
+ }
89
+
90
+ $this->handler->handleBatch($this->buffer);
91
+ $this->clear();
92
+ }
93
+
94
+ public function __destruct()
95
+ {
96
+ // suppress the parent behavior since we already have register_shutdown_function()
97
+ // to call close(), and the reference contained there will prevent this from being
98
+ // GC'd until the end of the request
99
+ }
100
+
101
+ /**
102
+ * {@inheritdoc}
103
+ */
104
+ public function close()
105
+ {
106
+ $this->flush();
107
+ }
108
+
109
+ /**
110
+ * Clears the buffer without flushing any messages down to the wrapped handler.
111
+ */
112
+ public function clear()
113
+ {
114
+ $this->bufferSize = 0;
115
+ $this->buffer = array();
116
+ }
117
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Formatter\ChromePHPFormatter;
15
+ use Monolog\Logger;
16
+
17
+ /**
18
+ * Handler sending logs to the ChromePHP extension (http://www.chromephp.com/)
19
+ *
20
+ * @author Christophe Coevoet <stof@notk.org>
21
+ */
22
+ class ChromePHPHandler extends AbstractProcessingHandler
23
+ {
24
+ /**
25
+ * Version of the extension
26
+ */
27
+ const VERSION = '4.0';
28
+
29
+ /**
30
+ * Header name
31
+ */
32
+ const HEADER_NAME = 'X-ChromeLogger-Data';
33
+
34
+ protected static $initialized = false;
35
+
36
+ /**
37
+ * Tracks whether we sent too much data
38
+ *
39
+ * Chrome limits the headers to 256KB, so when we sent 240KB we stop sending
40
+ *
41
+ * @var Boolean
42
+ */
43
+ protected static $overflowed = false;
44
+
45
+ protected static $json = array(
46
+ 'version' => self::VERSION,
47
+ 'columns' => array('label', 'log', 'backtrace', 'type'),
48
+ 'rows' => array(),
49
+ );
50
+
51
+ protected static $sendHeaders = true;
52
+
53
+ /**
54
+ * @param integer $level The minimum logging level at which this handler will be triggered
55
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
56
+ */
57
+ public function __construct($level = Logger::DEBUG, $bubble = true)
58
+ {
59
+ parent::__construct($level, $bubble);
60
+ if (!function_exists('json_encode')) {
61
+ throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s ChromePHPHandler');
62
+ }
63
+ }
64
+
65
+ /**
66
+ * {@inheritdoc}
67
+ */
68
+ public function handleBatch(array $records)
69
+ {
70
+ $messages = array();
71
+
72
+ foreach ($records as $record) {
73
+ if ($record['level'] < $this->level) {
74
+ continue;
75
+ }
76
+ $messages[] = $this->processRecord($record);
77
+ }
78
+
79
+ if (!empty($messages)) {
80
+ $messages = $this->getFormatter()->formatBatch($messages);
81
+ self::$json['rows'] = array_merge(self::$json['rows'], $messages);
82
+ $this->send();
83
+ }
84
+ }
85
+
86
+ /**
87
+ * {@inheritDoc}
88
+ */
89
+ protected function getDefaultFormatter()
90
+ {
91
+ return new ChromePHPFormatter();
92
+ }
93
+
94
+ /**
95
+ * Creates & sends header for a record
96
+ *
97
+ * @see sendHeader()
98
+ * @see send()
99
+ * @param array $record
100
+ */
101
+ protected function write(array $record)
102
+ {
103
+ self::$json['rows'][] = $record['formatted'];
104
+
105
+ $this->send();
106
+ }
107
+
108
+ /**
109
+ * Sends the log header
110
+ *
111
+ * @see sendHeader()
112
+ */
113
+ protected function send()
114
+ {
115
+ if (self::$overflowed || !self::$sendHeaders) {
116
+ return;
117
+ }
118
+
119
+ if (!self::$initialized) {
120
+ self::$initialized = true;
121
+
122
+ self::$sendHeaders = $this->headersAccepted();
123
+ if (!self::$sendHeaders) {
124
+ return;
125
+ }
126
+
127
+ self::$json['request_uri'] = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
128
+ }
129
+
130
+ $json = @json_encode(self::$json);
131
+ $data = base64_encode(utf8_encode($json));
132
+ if (strlen($data) > 240*1024) {
133
+ self::$overflowed = true;
134
+
135
+ $record = array(
136
+ 'message' => 'Incomplete logs, chrome header size limit reached',
137
+ 'context' => array(),
138
+ 'level' => Logger::WARNING,
139
+ 'level_name' => Logger::getLevelName(Logger::WARNING),
140
+ 'channel' => 'monolog',
141
+ 'datetime' => new \DateTime(),
142
+ 'extra' => array(),
143
+ );
144
+ self::$json['rows'][count(self::$json['rows']) - 1] = $this->getFormatter()->format($record);
145
+ $json = @json_encode(self::$json);
146
+ $data = base64_encode(utf8_encode($json));
147
+ }
148
+
149
+ if (trim($data) !== '') {
150
+ $this->sendHeader(self::HEADER_NAME, $data);
151
+ }
152
+ }
153
+
154
+ /**
155
+ * Send header string to the client
156
+ *
157
+ * @param string $header
158
+ * @param string $content
159
+ */
160
+ protected function sendHeader($header, $content)
161
+ {
162
+ if (!headers_sent() && self::$sendHeaders) {
163
+ header(sprintf('%s: %s', $header, $content));
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Verifies if the headers are accepted by the current user agent
169
+ *
170
+ * @return Boolean
171
+ */
172
+ protected function headersAccepted()
173
+ {
174
+ if (empty($_SERVER['HTTP_USER_AGENT'])) {
175
+ return false;
176
+ }
177
+
178
+ return preg_match('{\bChrome/\d+[\.\d+]*\b}', $_SERVER['HTTP_USER_AGENT']);
179
+ }
180
+
181
+ /**
182
+ * BC getter for the sendHeaders property that has been made static
183
+ */
184
+ public function __get($property)
185
+ {
186
+ if ('sendHeaders' !== $property) {
187
+ throw new \InvalidArgumentException('Undefined property '.$property);
188
+ }
189
+
190
+ return static::$sendHeaders;
191
+ }
192
+
193
+ /**
194
+ * BC setter for the sendHeaders property that has been made static
195
+ */
196
+ public function __set($property, $value)
197
+ {
198
+ if ('sendHeaders' !== $property) {
199
+ throw new \InvalidArgumentException('Undefined property '.$property);
200
+ }
201
+
202
+ static::$sendHeaders = $value;
203
+ }
204
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Formatter\JsonFormatter;
15
+ use Monolog\Logger;
16
+
17
+ /**
18
+ * CouchDB handler
19
+ *
20
+ * @author Markus Bachmann <markus.bachmann@bachi.biz>
21
+ */
22
+ class CouchDBHandler extends AbstractProcessingHandler
23
+ {
24
+ private $options;
25
+
26
+ public function __construct(array $options = array(), $level = Logger::DEBUG, $bubble = true)
27
+ {
28
+ $this->options = array_merge(array(
29
+ 'host' => 'localhost',
30
+ 'port' => 5984,
31
+ 'dbname' => 'logger',
32
+ 'username' => null,
33
+ 'password' => null,
34
+ ), $options);
35
+
36
+ parent::__construct($level, $bubble);
37
+ }
38
+
39
+ /**
40
+ * {@inheritDoc}
41
+ */
42
+ protected function write(array $record)
43
+ {
44
+ $basicAuth = null;
45
+ if ($this->options['username']) {
46
+ $basicAuth = sprintf('%s:%s@', $this->options['username'], $this->options['password']);
47
+ }
48
+
49
+ $url = 'http://'.$basicAuth.$this->options['host'].':'.$this->options['port'].'/'.$this->options['dbname'];
50
+ $context = stream_context_create(array(
51
+ 'http' => array(
52
+ 'method' => 'POST',
53
+ 'content' => $record['formatted'],
54
+ 'ignore_errors' => true,
55
+ 'max_redirects' => 0,
56
+ 'header' => 'Content-type: application/json',
57
+ )
58
+ ));
59
+
60
+ if (false === @file_get_contents($url, null, $context)) {
61
+ throw new \RuntimeException(sprintf('Could not connect to %s', $url));
62
+ }
63
+ }
64
+
65
+ /**
66
+ * {@inheritDoc}
67
+ */
68
+ protected function getDefaultFormatter()
69
+ {
70
+ return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false);
71
+ }
72
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/CubeHandler.php ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Logs to Cube.
18
+ *
19
+ * @link http://square.github.com/cube/
20
+ * @author Wan Chen <kami@kamisama.me>
21
+ */
22
+ class CubeHandler extends AbstractProcessingHandler
23
+ {
24
+ private $udpConnection = null;
25
+ private $httpConnection = null;
26
+ private $scheme = null;
27
+ private $host = null;
28
+ private $port = null;
29
+ private $acceptedSchemes = array('http', 'udp');
30
+
31
+ /**
32
+ * Create a Cube handler
33
+ *
34
+ * @throws UnexpectedValueException when given url is not a valid url.
35
+ * A valid url must consists of three parts : protocol://host:port
36
+ * Only valid protocol used by Cube are http and udp
37
+ */
38
+ public function __construct($url, $level = Logger::DEBUG, $bubble = true)
39
+ {
40
+ $urlInfos = parse_url($url);
41
+
42
+ if (!isset($urlInfos['scheme']) || !isset($urlInfos['host']) || !isset($urlInfos['port'])) {
43
+ throw new \UnexpectedValueException('URL "'.$url.'" is not valid');
44
+ }
45
+
46
+ if (!in_array($urlInfos['scheme'], $this->acceptedSchemes)) {
47
+ throw new \UnexpectedValueException(
48
+ 'Invalid protocol (' . $urlInfos['scheme'] . ').'
49
+ . ' Valid options are ' . implode(', ', $this->acceptedSchemes));
50
+ }
51
+
52
+ $this->scheme = $urlInfos['scheme'];
53
+ $this->host = $urlInfos['host'];
54
+ $this->port = $urlInfos['port'];
55
+
56
+ parent::__construct($level, $bubble);
57
+ }
58
+
59
+ /**
60
+ * Establish a connection to an UDP socket
61
+ *
62
+ * @throws LogicException when unable to connect to the socket
63
+ */
64
+ protected function connectUdp()
65
+ {
66
+ if (!extension_loaded('sockets')) {
67
+ throw new MissingExtensionException('The sockets extension is required to use udp URLs with the CubeHandler');
68
+ }
69
+
70
+ $this->udpConnection = socket_create(AF_INET, SOCK_DGRAM, 0);
71
+ if (!$this->udpConnection) {
72
+ throw new \LogicException('Unable to create a socket');
73
+ }
74
+
75
+ if (!socket_connect($this->udpConnection, $this->host, $this->port)) {
76
+ throw new \LogicException('Unable to connect to the socket at ' . $this->host . ':' . $this->port);
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Establish a connection to a http server
82
+ */
83
+ protected function connectHttp()
84
+ {
85
+ if (!extension_loaded('curl')) {
86
+ throw new \LogicException('The curl extension is needed to use http URLs with the CubeHandler');
87
+ }
88
+
89
+ $this->httpConnection = curl_init('http://'.$this->host.':'.$this->port.'/1.0/event/put');
90
+
91
+ if (!$this->httpConnection) {
92
+ throw new \LogicException('Unable to connect to ' . $this->host . ':' . $this->port);
93
+ }
94
+
95
+ curl_setopt($this->httpConnection, CURLOPT_CUSTOMREQUEST, "POST");
96
+ curl_setopt($this->httpConnection, CURLOPT_RETURNTRANSFER, true);
97
+ }
98
+
99
+ /**
100
+ * {@inheritdoc}
101
+ */
102
+ protected function write(array $record)
103
+ {
104
+ $date = $record['datetime'];
105
+
106
+ $data = array('time' => $date->format('Y-m-d\TH:i:s.uO'));
107
+ unset($record['datetime']);
108
+
109
+ if (isset($record['context']['type'])) {
110
+ $data['type'] = $record['context']['type'];
111
+ unset($record['context']['type']);
112
+ } else {
113
+ $data['type'] = $record['channel'];
114
+ }
115
+
116
+ $data['data'] = $record['context'];
117
+ $data['data']['level'] = $record['level'];
118
+
119
+ $this->{'write'.$this->scheme}(json_encode($data));
120
+ }
121
+
122
+ private function writeUdp($data)
123
+ {
124
+ if (!$this->udpConnection) {
125
+ $this->connectUdp();
126
+ }
127
+
128
+ socket_send($this->udpConnection, $data, strlen($data), 0);
129
+ }
130
+
131
+ private function writeHttp($data)
132
+ {
133
+ if (!$this->httpConnection) {
134
+ $this->connectHttp();
135
+ }
136
+
137
+ curl_setopt($this->httpConnection, CURLOPT_POSTFIELDS, '['.$data.']');
138
+ curl_setopt($this->httpConnection, CURLOPT_HTTPHEADER, array(
139
+ 'Content-Type: application/json',
140
+ 'Content-Length: ' . strlen('['.$data.']'))
141
+ );
142
+
143
+ return curl_exec($this->httpConnection);
144
+ }
145
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+ use Monolog\Formatter\NormalizerFormatter;
16
+ use Doctrine\CouchDB\CouchDBClient;
17
+
18
+ /**
19
+ * CouchDB handler for Doctrine CouchDB ODM
20
+ *
21
+ * @author Markus Bachmann <markus.bachmann@bachi.biz>
22
+ */
23
+ class DoctrineCouchDBHandler extends AbstractProcessingHandler
24
+ {
25
+ private $client;
26
+
27
+ public function __construct(CouchDBClient $client, $level = Logger::DEBUG, $bubble = true)
28
+ {
29
+ $this->client = $client;
30
+ parent::__construct($level, $bubble);
31
+ }
32
+
33
+ /**
34
+ * {@inheritDoc}
35
+ */
36
+ protected function write(array $record)
37
+ {
38
+ $this->client->postDocument($record['formatted']);
39
+ }
40
+
41
+ protected function getDefaultFormatter()
42
+ {
43
+ return new NormalizerFormatter;
44
+ }
45
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/DynamoDbHandler.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Aws\Common\Aws;
15
+ use Aws\DynamoDb\DynamoDbClient;
16
+ use Monolog\Formatter\ScalarFormatter;
17
+ use Monolog\Logger;
18
+
19
+ /**
20
+ * Amazon DynamoDB handler (http://aws.amazon.com/dynamodb/)
21
+ *
22
+ * @link https://github.com/aws/aws-sdk-php/
23
+ * @author Andrew Lawson <adlawson@gmail.com>
24
+ */
25
+ class DynamoDbHandler extends AbstractProcessingHandler
26
+ {
27
+ const DATE_FORMAT = 'Y-m-d\TH:i:s.uO';
28
+
29
+ /**
30
+ * @var DynamoDbClient
31
+ */
32
+ protected $client;
33
+
34
+ /**
35
+ * @var string
36
+ */
37
+ protected $table;
38
+
39
+ /**
40
+ * @param DynamoDbClient $client
41
+ * @param string $table
42
+ * @param integer $level
43
+ * @param boolean $bubble
44
+ */
45
+ public function __construct(DynamoDbClient $client, $table, $level = Logger::DEBUG, $bubble = true)
46
+ {
47
+ if (!defined('Aws\Common\Aws::VERSION') || version_compare('3.0', Aws::VERSION, '<=')) {
48
+ throw new \RuntimeException('The DynamoDbHandler is only known to work with the AWS SDK 2.x releases');
49
+ }
50
+
51
+ $this->client = $client;
52
+ $this->table = $table;
53
+
54
+ parent::__construct($level, $bubble);
55
+ }
56
+
57
+ /**
58
+ * {@inheritdoc}
59
+ */
60
+ protected function write(array $record)
61
+ {
62
+ $filtered = $this->filterEmptyFields($record['formatted']);
63
+ $formatted = $this->client->formatAttributes($filtered);
64
+
65
+ $this->client->putItem(array(
66
+ 'TableName' => $this->table,
67
+ 'Item' => $formatted
68
+ ));
69
+ }
70
+
71
+ /**
72
+ * @param array $record
73
+ * @return array
74
+ */
75
+ protected function filterEmptyFields(array $record)
76
+ {
77
+ return array_filter($record, function ($value) {
78
+ return !empty($value) || false === $value || 0 === $value;
79
+ });
80
+ }
81
+
82
+ /**
83
+ * {@inheritdoc}
84
+ */
85
+ protected function getDefaultFormatter()
86
+ {
87
+ return new ScalarFormatter(self::DATE_FORMAT);
88
+ }
89
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/ElasticSearchHandler.php ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Formatter\FormatterInterface;
15
+ use Monolog\Formatter\ElasticaFormatter;
16
+ use Monolog\Logger;
17
+ use Elastica\Client;
18
+ use Elastica\Exception\ExceptionInterface;
19
+
20
+ /**
21
+ * Elastic Search handler
22
+ *
23
+ * Usage example:
24
+ *
25
+ * $client = new \Elastica\Client();
26
+ * $options = array(
27
+ * 'index' => 'elastic_index_name',
28
+ * 'type' => 'elastic_doc_type',
29
+ * );
30
+ * $handler = new ElasticSearchHandler($client, $options);
31
+ * $log = new Logger('application');
32
+ * $log->pushHandler($handler);
33
+ *
34
+ * @author Jelle Vink <jelle.vink@gmail.com>
35
+ */
36
+ class ElasticSearchHandler extends AbstractProcessingHandler
37
+ {
38
+ /**
39
+ * @var Client
40
+ */
41
+ protected $client;
42
+
43
+ /**
44
+ * @var array Handler config options
45
+ */
46
+ protected $options = array();
47
+
48
+ /**
49
+ * @param Client $client Elastica Client object
50
+ * @param array $options Handler configuration
51
+ * @param integer $level The minimum logging level at which this handler will be triggered
52
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
53
+ */
54
+ public function __construct(Client $client, array $options = array(), $level = Logger::DEBUG, $bubble = true)
55
+ {
56
+ parent::__construct($level, $bubble);
57
+ $this->client = $client;
58
+ $this->options = array_merge(
59
+ array(
60
+ 'index' => 'monolog', // Elastic index name
61
+ 'type' => 'record', // Elastic document type
62
+ 'ignore_error' => false, // Suppress Elastica exceptions
63
+ ),
64
+ $options
65
+ );
66
+ }
67
+
68
+ /**
69
+ * {@inheritDoc}
70
+ */
71
+ protected function write(array $record)
72
+ {
73
+ $this->bulkSend(array($record['formatted']));
74
+ }
75
+
76
+ /**
77
+ * {@inheritdoc}
78
+ */
79
+ public function setFormatter(FormatterInterface $formatter)
80
+ {
81
+ if ($formatter instanceof ElasticaFormatter) {
82
+ return parent::setFormatter($formatter);
83
+ }
84
+ throw new \InvalidArgumentException('ElasticSearchHandler is only compatible with ElasticaFormatter');
85
+ }
86
+
87
+ /**
88
+ * Getter options
89
+ * @return array
90
+ */
91
+ public function getOptions()
92
+ {
93
+ return $this->options;
94
+ }
95
+
96
+ /**
97
+ * {@inheritDoc}
98
+ */
99
+ protected function getDefaultFormatter()
100
+ {
101
+ return new ElasticaFormatter($this->options['index'], $this->options['type']);
102
+ }
103
+
104
+ /**
105
+ * {@inheritdoc}
106
+ */
107
+ public function handleBatch(array $records)
108
+ {
109
+ $documents = $this->getFormatter()->formatBatch($records);
110
+ $this->bulkSend($documents);
111
+ }
112
+
113
+ /**
114
+ * Use Elasticsearch bulk API to send list of documents
115
+ * @param array $documents
116
+ * @throws \RuntimeException
117
+ */
118
+ protected function bulkSend(array $documents)
119
+ {
120
+ try {
121
+ $this->client->addDocuments($documents);
122
+ } catch (ExceptionInterface $e) {
123
+ if (!$this->options['ignore_error']) {
124
+ throw new \RuntimeException("Error sending messages to Elasticsearch", 0, $e);
125
+ }
126
+ }
127
+ }
128
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Formatter\LineFormatter;
15
+ use Monolog\Logger;
16
+
17
+ /**
18
+ * Stores to PHP error_log() handler.
19
+ *
20
+ * @author Elan Ruusamäe <glen@delfi.ee>
21
+ */
22
+ class ErrorLogHandler extends AbstractProcessingHandler
23
+ {
24
+ const OPERATING_SYSTEM = 0;
25
+ const SAPI = 4;
26
+
27
+ protected $messageType;
28
+ protected $expandNewlines;
29
+
30
+ /**
31
+ * @param integer $messageType Says where the error should go.
32
+ * @param integer $level The minimum logging level at which this handler will be triggered
33
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
34
+ * @param Boolean $expandNewlines If set to true, newlines in the message will be expanded to be take multiple log entries
35
+ */
36
+ public function __construct($messageType = self::OPERATING_SYSTEM, $level = Logger::DEBUG, $bubble = true, $expandNewlines = false)
37
+ {
38
+ parent::__construct($level, $bubble);
39
+
40
+ if (false === in_array($messageType, self::getAvailableTypes())) {
41
+ $message = sprintf('The given message type "%s" is not supported', print_r($messageType, true));
42
+ throw new \InvalidArgumentException($message);
43
+ }
44
+
45
+ $this->messageType = $messageType;
46
+ $this->expandNewlines = $expandNewlines;
47
+ }
48
+
49
+ /**
50
+ * @return array With all available types
51
+ */
52
+ public static function getAvailableTypes()
53
+ {
54
+ return array(
55
+ self::OPERATING_SYSTEM,
56
+ self::SAPI,
57
+ );
58
+ }
59
+
60
+ /**
61
+ * {@inheritDoc}
62
+ */
63
+ protected function getDefaultFormatter()
64
+ {
65
+ return new LineFormatter('[%datetime%] %channel%.%level_name%: %message% %context% %extra%');
66
+ }
67
+
68
+ /**
69
+ * {@inheritdoc}
70
+ */
71
+ protected function write(array $record)
72
+ {
73
+ if ($this->expandNewlines) {
74
+ $lines = preg_split('{[\r\n]+}', (string) $record['formatted']);
75
+ foreach ($lines as $line) {
76
+ error_log($line, $this->messageType);
77
+ }
78
+ } else {
79
+ error_log((string) $record['formatted'], $this->messageType);
80
+ }
81
+ }
82
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/FilterHandler.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Simple handler wrapper that filters records based on a list of levels
18
+ *
19
+ * It can be configured with an exact list of levels to allow, or a min/max level.
20
+ *
21
+ * @author Hennadiy Verkh
22
+ * @author Jordi Boggiano <j.boggiano@seld.be>
23
+ */
24
+ class FilterHandler extends AbstractHandler
25
+ {
26
+ /**
27
+ * Handler or factory callable($record, $this)
28
+ *
29
+ * @var callable|\Monolog\Handler\HandlerInterface
30
+ */
31
+ protected $handler;
32
+
33
+ /**
34
+ * Minimum level for logs that are passes to handler
35
+ *
36
+ * @var int[]
37
+ */
38
+ protected $acceptedLevels;
39
+
40
+ /**
41
+ * Whether the messages that are handled can bubble up the stack or not
42
+ *
43
+ * @var Boolean
44
+ */
45
+ protected $bubble;
46
+
47
+ /**
48
+ * @param callable|HandlerInterface $handler Handler or factory callable($record, $this).
49
+ * @param int|array $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided
50
+ * @param int $maxLevel Maximum level to accept, only used if $minLevelOrList is not an array
51
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
52
+ */
53
+ public function __construct($handler, $minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY, $bubble = true)
54
+ {
55
+ $this->handler = $handler;
56
+ $this->bubble = $bubble;
57
+ $this->setAcceptedLevels($minLevelOrList, $maxLevel);
58
+
59
+ if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) {
60
+ throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object");
61
+ }
62
+ }
63
+
64
+ /**
65
+ * @return array
66
+ */
67
+ public function getAcceptedLevels()
68
+ {
69
+ return array_flip($this->acceptedLevels);
70
+ }
71
+
72
+ /**
73
+ * @param int|array $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided
74
+ * @param int $maxLevel Maximum level to accept, only used if $minLevelOrList is not an array
75
+ */
76
+ public function setAcceptedLevels($minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY)
77
+ {
78
+ if (is_array($minLevelOrList)) {
79
+ $acceptedLevels = array_map('Monolog\Logger::toMonologLevel', $minLevelOrList);
80
+ } else {
81
+ $minLevelOrList = Logger::toMonologLevel($minLevelOrList);
82
+ $maxLevel = Logger::toMonologLevel($maxLevel);
83
+ $acceptedLevels = array_values(array_filter(Logger::getLevels(), function ($level) use ($minLevelOrList, $maxLevel) {
84
+ return $level >= $minLevelOrList && $level <= $maxLevel;
85
+ }));
86
+ }
87
+ $this->acceptedLevels = array_flip($acceptedLevels);
88
+ }
89
+
90
+ /**
91
+ * {@inheritdoc}
92
+ */
93
+ public function isHandling(array $record)
94
+ {
95
+ return isset($this->acceptedLevels[$record['level']]);
96
+ }
97
+
98
+ /**
99
+ * {@inheritdoc}
100
+ */
101
+ public function handle(array $record)
102
+ {
103
+ if (!$this->isHandling($record)) {
104
+ return false;
105
+ }
106
+
107
+ // The same logic as in FingersCrossedHandler
108
+ if (!$this->handler instanceof HandlerInterface) {
109
+ $this->handler = call_user_func($this->handler, $record, $this);
110
+ if (!$this->handler instanceof HandlerInterface) {
111
+ throw new \RuntimeException("The factory callable should return a HandlerInterface");
112
+ }
113
+ }
114
+
115
+ if ($this->processors) {
116
+ foreach ($this->processors as $processor) {
117
+ $record = call_user_func($processor, $record);
118
+ }
119
+ }
120
+
121
+ $this->handler->handle($record);
122
+
123
+ return false === $this->bubble;
124
+ }
125
+
126
+ /**
127
+ * {@inheritdoc}
128
+ */
129
+ public function handleBatch(array $records)
130
+ {
131
+ $filtered = array();
132
+ foreach ($records as $record) {
133
+ if ($this->isHandling($record)) {
134
+ $filtered[] = $record;
135
+ }
136
+ }
137
+
138
+ $this->handler->handleBatch($filtered);
139
+ }
140
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ActivationStrategyInterface.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler\FingersCrossed;
13
+
14
+ /**
15
+ * Interface for activation strategies for the FingersCrossedHandler.
16
+ *
17
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
18
+ */
19
+ interface ActivationStrategyInterface
20
+ {
21
+ /**
22
+ * Returns whether the given record activates the handler.
23
+ *
24
+ * @param array $record
25
+ * @return Boolean
26
+ */
27
+ public function isHandlerActivated(array $record);
28
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ChannelLevelActivationStrategy.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler\FingersCrossed;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Channel and Error level based monolog activation strategy. Allows to trigger activation
18
+ * based on level per channel. e.g. trigger activation on level 'ERROR' by default, except
19
+ * for records of the 'sql' channel; those should trigger activation on level 'WARN'.
20
+ *
21
+ * Example:
22
+ *
23
+ * <code>
24
+ * $activationStrategy = new ChannelLevelActivationStrategy(
25
+ * Logger::CRITICAL,
26
+ * array(
27
+ * 'request' => Logger::ALERT,
28
+ * 'sensitive' => Logger::ERROR,
29
+ * )
30
+ * );
31
+ * $handler = new FingersCrossedHandler(new StreamHandler('php://stderr'), $activationStrategy);
32
+ * </code>
33
+ *
34
+ * @author Mike Meessen <netmikey@gmail.com>
35
+ */
36
+ class ChannelLevelActivationStrategy implements ActivationStrategyInterface
37
+ {
38
+ private $defaultActionLevel;
39
+ private $channelToActionLevel;
40
+
41
+ /**
42
+ * @param int $defaultActionLevel The default action level to be used if the record's category doesn't match any
43
+ * @param array $channelToActionLevel An array that maps channel names to action levels.
44
+ */
45
+ public function __construct($defaultActionLevel, $channelToActionLevel = array())
46
+ {
47
+ $this->defaultActionLevel = Logger::toMonologLevel($defaultActionLevel);
48
+ $this->channelToActionLevel = array_map('Monolog\Logger::toMonologLevel', $channelToActionLevel);
49
+ }
50
+
51
+ public function isHandlerActivated(array $record)
52
+ {
53
+ if (isset($this->channelToActionLevel[$record['channel']])) {
54
+ return $record['level'] >= $this->channelToActionLevel[$record['channel']];
55
+ }
56
+
57
+ return $record['level'] >= $this->defaultActionLevel;
58
+ }
59
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossed/ErrorLevelActivationStrategy.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler\FingersCrossed;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Error level based activation strategy.
18
+ *
19
+ * @author Johannes M. Schmitt <schmittjoh@gmail.com>
20
+ */
21
+ class ErrorLevelActivationStrategy implements ActivationStrategyInterface
22
+ {
23
+ private $actionLevel;
24
+
25
+ public function __construct($actionLevel)
26
+ {
27
+ $this->actionLevel = Logger::toMonologLevel($actionLevel);
28
+ }
29
+
30
+ public function isHandlerActivated(array $record)
31
+ {
32
+ return $record['level'] >= $this->actionLevel;
33
+ }
34
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
15
+ use Monolog\Handler\FingersCrossed\ActivationStrategyInterface;
16
+ use Monolog\Logger;
17
+
18
+ /**
19
+ * Buffers all records until a certain level is reached
20
+ *
21
+ * The advantage of this approach is that you don't get any clutter in your log files.
22
+ * Only requests which actually trigger an error (or whatever your actionLevel is) will be
23
+ * in the logs, but they will contain all records, not only those above the level threshold.
24
+ *
25
+ * You can find the various activation strategies in the
26
+ * Monolog\Handler\FingersCrossed\ namespace.
27
+ *
28
+ * @author Jordi Boggiano <j.boggiano@seld.be>
29
+ */
30
+ class FingersCrossedHandler extends AbstractHandler
31
+ {
32
+ protected $handler;
33
+ protected $activationStrategy;
34
+ protected $buffering = true;
35
+ protected $bufferSize;
36
+ protected $buffer = array();
37
+ protected $stopBuffering;
38
+ protected $passthruLevel;
39
+
40
+ /**
41
+ * @param callable|HandlerInterface $handler Handler or factory callable($record, $fingersCrossedHandler).
42
+ * @param int|ActivationStrategyInterface $activationStrategy Strategy which determines when this handler takes action
43
+ * @param int $bufferSize How many entries should be buffered at most, beyond that the oldest items are removed from the buffer.
44
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
45
+ * @param Boolean $stopBuffering Whether the handler should stop buffering after being triggered (default true)
46
+ * @param int $passthruLevel Minimum level to always flush to handler on close, even if strategy not triggered
47
+ */
48
+ public function __construct($handler, $activationStrategy = null, $bufferSize = 0, $bubble = true, $stopBuffering = true, $passthruLevel = null)
49
+ {
50
+ if (null === $activationStrategy) {
51
+ $activationStrategy = new ErrorLevelActivationStrategy(Logger::WARNING);
52
+ }
53
+
54
+ // convert simple int activationStrategy to an object
55
+ if (!$activationStrategy instanceof ActivationStrategyInterface) {
56
+ $activationStrategy = new ErrorLevelActivationStrategy($activationStrategy);
57
+ }
58
+
59
+ $this->handler = $handler;
60
+ $this->activationStrategy = $activationStrategy;
61
+ $this->bufferSize = $bufferSize;
62
+ $this->bubble = $bubble;
63
+ $this->stopBuffering = $stopBuffering;
64
+ $this->passthruLevel = $passthruLevel;
65
+
66
+ if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) {
67
+ throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object");
68
+ }
69
+ }
70
+
71
+ /**
72
+ * {@inheritdoc}
73
+ */
74
+ public function isHandling(array $record)
75
+ {
76
+ return true;
77
+ }
78
+
79
+ /**
80
+ * {@inheritdoc}
81
+ */
82
+ public function handle(array $record)
83
+ {
84
+ if ($this->processors) {
85
+ foreach ($this->processors as $processor) {
86
+ $record = call_user_func($processor, $record);
87
+ }
88
+ }
89
+
90
+ if ($this->buffering) {
91
+ $this->buffer[] = $record;
92
+ if ($this->bufferSize > 0 && count($this->buffer) > $this->bufferSize) {
93
+ array_shift($this->buffer);
94
+ }
95
+ if ($this->activationStrategy->isHandlerActivated($record)) {
96
+ if ($this->stopBuffering) {
97
+ $this->buffering = false;
98
+ }
99
+ if (!$this->handler instanceof HandlerInterface) {
100
+ $this->handler = call_user_func($this->handler, $record, $this);
101
+ if (!$this->handler instanceof HandlerInterface) {
102
+ throw new \RuntimeException("The factory callable should return a HandlerInterface");
103
+ }
104
+ }
105
+ $this->handler->handleBatch($this->buffer);
106
+ $this->buffer = array();
107
+ }
108
+ } else {
109
+ $this->handler->handle($record);
110
+ }
111
+
112
+ return false === $this->bubble;
113
+ }
114
+
115
+ /**
116
+ * {@inheritdoc}
117
+ */
118
+ public function close()
119
+ {
120
+ if (null !== $this->passthruLevel) {
121
+ $level = $this->passthruLevel;
122
+ $this->buffer = array_filter($this->buffer, function ($record) use ($level) {
123
+ return $record['level'] >= $level;
124
+ });
125
+ if (count($this->buffer) > 0) {
126
+ $this->handler->handleBatch($this->buffer);
127
+ $this->buffer = array();
128
+ }
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Resets the state of the handler. Stops forwarding records to the wrapped handler.
134
+ */
135
+ public function reset()
136
+ {
137
+ $this->buffering = true;
138
+ }
139
+
140
+ /**
141
+ * Clears the buffer without flushing any messages down to the wrapped handler.
142
+ *
143
+ * It also resets the handler to its initial buffering state.
144
+ */
145
+ public function clear()
146
+ {
147
+ $this->buffer = array();
148
+ $this->reset();
149
+ }
150
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Formatter\WildfireFormatter;
15
+
16
+ /**
17
+ * Simple FirePHP Handler (http://www.firephp.org/), which uses the Wildfire protocol.
18
+ *
19
+ * @author Eric Clemmons (@ericclemmons) <eric@uxdriven.com>
20
+ */
21
+ class FirePHPHandler extends AbstractProcessingHandler
22
+ {
23
+ /**
24
+ * WildFire JSON header message format
25
+ */
26
+ const PROTOCOL_URI = 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2';
27
+
28
+ /**
29
+ * FirePHP structure for parsing messages & their presentation
30
+ */
31
+ const STRUCTURE_URI = 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1';
32
+
33
+ /**
34
+ * Must reference a "known" plugin, otherwise headers won't display in FirePHP
35
+ */
36
+ const PLUGIN_URI = 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3';
37
+
38
+ /**
39
+ * Header prefix for Wildfire to recognize & parse headers
40
+ */
41
+ const HEADER_PREFIX = 'X-Wf';
42
+
43
+ /**
44
+ * Whether or not Wildfire vendor-specific headers have been generated & sent yet
45
+ */
46
+ protected static $initialized = false;
47
+
48
+ /**
49
+ * Shared static message index between potentially multiple handlers
50
+ * @var int
51
+ */
52
+ protected static $messageIndex = 1;
53
+
54
+ protected static $sendHeaders = true;
55
+
56
+ /**
57
+ * Base header creation function used by init headers & record headers
58
+ *
59
+ * @param array $meta Wildfire Plugin, Protocol & Structure Indexes
60
+ * @param string $message Log message
61
+ * @return array Complete header string ready for the client as key and message as value
62
+ */
63
+ protected function createHeader(array $meta, $message)
64
+ {
65
+ $header = sprintf('%s-%s', self::HEADER_PREFIX, join('-', $meta));
66
+
67
+ return array($header => $message);
68
+ }
69
+
70
+ /**
71
+ * Creates message header from record
72
+ *
73
+ * @see createHeader()
74
+ * @param array $record
75
+ * @return string
76
+ */
77
+ protected function createRecordHeader(array $record)
78
+ {
79
+ // Wildfire is extensible to support multiple protocols & plugins in a single request,
80
+ // but we're not taking advantage of that (yet), so we're using "1" for simplicity's sake.
81
+ return $this->createHeader(
82
+ array(1, 1, 1, self::$messageIndex++),
83
+ $record['formatted']
84
+ );
85
+ }
86
+
87
+ /**
88
+ * {@inheritDoc}
89
+ */
90
+ protected function getDefaultFormatter()
91
+ {
92
+ return new WildfireFormatter();
93
+ }
94
+
95
+ /**
96
+ * Wildfire initialization headers to enable message parsing
97
+ *
98
+ * @see createHeader()
99
+ * @see sendHeader()
100
+ * @return array
101
+ */
102
+ protected function getInitHeaders()
103
+ {
104
+ // Initial payload consists of required headers for Wildfire
105
+ return array_merge(
106
+ $this->createHeader(array('Protocol', 1), self::PROTOCOL_URI),
107
+ $this->createHeader(array(1, 'Structure', 1), self::STRUCTURE_URI),
108
+ $this->createHeader(array(1, 'Plugin', 1), self::PLUGIN_URI)
109
+ );
110
+ }
111
+
112
+ /**
113
+ * Send header string to the client
114
+ *
115
+ * @param string $header
116
+ * @param string $content
117
+ */
118
+ protected function sendHeader($header, $content)
119
+ {
120
+ if (!headers_sent() && self::$sendHeaders) {
121
+ header(sprintf('%s: %s', $header, $content));
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Creates & sends header for a record, ensuring init headers have been sent prior
127
+ *
128
+ * @see sendHeader()
129
+ * @see sendInitHeaders()
130
+ * @param array $record
131
+ */
132
+ protected function write(array $record)
133
+ {
134
+ if (!self::$sendHeaders) {
135
+ return;
136
+ }
137
+
138
+ // WildFire-specific headers must be sent prior to any messages
139
+ if (!self::$initialized) {
140
+ self::$initialized = true;
141
+
142
+ self::$sendHeaders = $this->headersAccepted();
143
+ if (!self::$sendHeaders) {
144
+ return;
145
+ }
146
+
147
+ foreach ($this->getInitHeaders() as $header => $content) {
148
+ $this->sendHeader($header, $content);
149
+ }
150
+ }
151
+
152
+ $header = $this->createRecordHeader($record);
153
+ if (trim(current($header)) !== '') {
154
+ $this->sendHeader(key($header), current($header));
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Verifies if the headers are accepted by the current user agent
160
+ *
161
+ * @return Boolean
162
+ */
163
+ protected function headersAccepted()
164
+ {
165
+ if (!empty($_SERVER['HTTP_USER_AGENT']) && preg_match('{\bFirePHP/\d+\.\d+\b}', $_SERVER['HTTP_USER_AGENT'])) {
166
+ return true;
167
+ }
168
+
169
+ return isset($_SERVER['HTTP_X_FIREPHP_VERSION']);
170
+ }
171
+
172
+ /**
173
+ * BC getter for the sendHeaders property that has been made static
174
+ */
175
+ public function __get($property)
176
+ {
177
+ if ('sendHeaders' !== $property) {
178
+ throw new \InvalidArgumentException('Undefined property '.$property);
179
+ }
180
+
181
+ return static::$sendHeaders;
182
+ }
183
+
184
+ /**
185
+ * BC setter for the sendHeaders property that has been made static
186
+ */
187
+ public function __set($property, $value)
188
+ {
189
+ if ('sendHeaders' !== $property) {
190
+ throw new \InvalidArgumentException('Undefined property '.$property);
191
+ }
192
+
193
+ static::$sendHeaders = $value;
194
+ }
195
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/FleepHookHandler.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Formatter\LineFormatter;
15
+ use Monolog\Logger;
16
+
17
+ /**
18
+ * Sends logs to Fleep.io using Webhook integrations
19
+ *
20
+ * You'll need a Fleep.io account to use this handler.
21
+ *
22
+ * @see https://fleep.io/integrations/webhooks/ Fleep Webhooks Documentation
23
+ * @author Ando Roots <ando@sqroot.eu>
24
+ */
25
+ class FleepHookHandler extends SocketHandler
26
+ {
27
+ const FLEEP_HOST = 'fleep.io';
28
+
29
+ const FLEEP_HOOK_URI = '/hook/';
30
+
31
+ /**
32
+ * @var string Webhook token (specifies the conversation where logs are sent)
33
+ */
34
+ protected $token;
35
+
36
+ /**
37
+ * Construct a new Fleep.io Handler.
38
+ *
39
+ * For instructions on how to create a new web hook in your conversations
40
+ * see https://fleep.io/integrations/webhooks/
41
+ *
42
+ * @param string $token Webhook token
43
+ * @param bool|int $level The minimum logging level at which this handler will be triggered
44
+ * @param bool $bubble Whether the messages that are handled can bubble up the stack or not
45
+ * @throws MissingExtensionException
46
+ */
47
+ public function __construct($token, $level = Logger::DEBUG, $bubble = true)
48
+ {
49
+ if (!extension_loaded('openssl')) {
50
+ throw new MissingExtensionException('The OpenSSL PHP extension is required to use the FleepHookHandler');
51
+ }
52
+
53
+ $this->token = $token;
54
+
55
+ $connectionString = 'ssl://' . self::FLEEP_HOST . ':443';
56
+ parent::__construct($connectionString, $level, $bubble);
57
+ }
58
+
59
+ /**
60
+ * Returns the default formatter to use with this handler
61
+ *
62
+ * Overloaded to remove empty context and extra arrays from the end of the log message.
63
+ *
64
+ * @return LineFormatter
65
+ */
66
+ protected function getDefaultFormatter()
67
+ {
68
+ return new LineFormatter(null, null, true, true);
69
+ }
70
+
71
+ /**
72
+ * Handles a log record
73
+ *
74
+ * @param array $record
75
+ */
76
+ public function write(array $record)
77
+ {
78
+ parent::write($record);
79
+ $this->closeSocket();
80
+ }
81
+
82
+ /**
83
+ * {@inheritdoc}
84
+ *
85
+ * @param array $record
86
+ * @return string
87
+ */
88
+ protected function generateDataStream($record)
89
+ {
90
+ $content = $this->buildContent($record);
91
+
92
+ return $this->buildHeader($content) . $content;
93
+ }
94
+
95
+ /**
96
+ * Builds the header of the API Call
97
+ *
98
+ * @param string $content
99
+ * @return string
100
+ */
101
+ private function buildHeader($content)
102
+ {
103
+ $header = "POST " . self::FLEEP_HOOK_URI . $this->token . " HTTP/1.1\r\n";
104
+ $header .= "Host: " . self::FLEEP_HOST . "\r\n";
105
+ $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
106
+ $header .= "Content-Length: " . strlen($content) . "\r\n";
107
+ $header .= "\r\n";
108
+
109
+ return $header;
110
+ }
111
+
112
+ /**
113
+ * Builds the body of API call
114
+ *
115
+ * @param array $record
116
+ * @return string
117
+ */
118
+ private function buildContent($record)
119
+ {
120
+ $dataArray = array(
121
+ 'message' => $record['formatted']
122
+ );
123
+
124
+ return http_build_query($dataArray);
125
+ }
126
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Sends notifications through the Flowdock push API
18
+ *
19
+ * This must be configured with a FlowdockFormatter instance via setFormatter()
20
+ *
21
+ * Notes:
22
+ * API token - Flowdock API token
23
+ *
24
+ * @author Dominik Liebler <liebler.dominik@gmail.com>
25
+ * @see https://www.flowdock.com/api/push
26
+ */
27
+ class FlowdockHandler extends SocketHandler
28
+ {
29
+ /**
30
+ * @var string
31
+ */
32
+ protected $apiToken;
33
+
34
+ /**
35
+ * @param string $apiToken
36
+ * @param bool|int $level The minimum logging level at which this handler will be triggered
37
+ * @param bool $bubble Whether the messages that are handled can bubble up the stack or not
38
+ *
39
+ * @throws MissingExtensionException if OpenSSL is missing
40
+ */
41
+ public function __construct($apiToken, $level = Logger::DEBUG, $bubble = true)
42
+ {
43
+ if (!extension_loaded('openssl')) {
44
+ throw new MissingExtensionException('The OpenSSL PHP extension is required to use the FlowdockHandler');
45
+ }
46
+
47
+ parent::__construct('ssl://api.flowdock.com:443', $level, $bubble);
48
+ $this->apiToken = $apiToken;
49
+ }
50
+
51
+ /**
52
+ * {@inheritdoc}
53
+ *
54
+ * @param array $record
55
+ */
56
+ protected function write(array $record)
57
+ {
58
+ parent::write($record);
59
+
60
+ $this->closeSocket();
61
+ }
62
+
63
+ /**
64
+ * {@inheritdoc}
65
+ *
66
+ * @param array $record
67
+ * @return string
68
+ */
69
+ protected function generateDataStream($record)
70
+ {
71
+ $content = $this->buildContent($record);
72
+
73
+ return $this->buildHeader($content) . $content;
74
+ }
75
+
76
+ /**
77
+ * Builds the body of API call
78
+ *
79
+ * @param array $record
80
+ * @return string
81
+ */
82
+ private function buildContent($record)
83
+ {
84
+ return json_encode($record['formatted']['flowdock']);
85
+ }
86
+
87
+ /**
88
+ * Builds the header of the API Call
89
+ *
90
+ * @param string $content
91
+ * @return string
92
+ */
93
+ private function buildHeader($content)
94
+ {
95
+ $header = "POST /v1/messages/team_inbox/" . $this->apiToken . " HTTP/1.1\r\n";
96
+ $header .= "Host: api.flowdock.com\r\n";
97
+ $header .= "Content-Type: application/json\r\n";
98
+ $header .= "Content-Length: " . strlen($content) . "\r\n";
99
+ $header .= "\r\n";
100
+
101
+ return $header;
102
+ }
103
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/GelfHandler.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Gelf\IMessagePublisher;
15
+ use Gelf\PublisherInterface;
16
+ use InvalidArgumentException;
17
+ use Monolog\Logger;
18
+ use Monolog\Formatter\GelfMessageFormatter;
19
+
20
+ /**
21
+ * Handler to send messages to a Graylog2 (http://www.graylog2.org) server
22
+ *
23
+ * @author Matt Lehner <mlehner@gmail.com>
24
+ * @author Benjamin Zikarsky <benjamin@zikarsky.de>
25
+ */
26
+ class GelfHandler extends AbstractProcessingHandler
27
+ {
28
+ /**
29
+ * @var Publisher the publisher object that sends the message to the server
30
+ */
31
+ protected $publisher;
32
+
33
+ /**
34
+ * @param PublisherInterface|IMessagePublisher $publisher a publisher object
35
+ * @param integer $level The minimum logging level at which this handler will be triggered
36
+ * @param boolean $bubble Whether the messages that are handled can bubble up the stack or not
37
+ */
38
+ public function __construct($publisher, $level = Logger::DEBUG, $bubble = true)
39
+ {
40
+ parent::__construct($level, $bubble);
41
+
42
+ if (!$publisher instanceof IMessagePublisher && !$publisher instanceof PublisherInterface) {
43
+ throw new InvalidArgumentException("Invalid publisher, expected a Gelf\IMessagePublisher or Gelf\PublisherInterface instance");
44
+ }
45
+
46
+ $this->publisher = $publisher;
47
+ }
48
+
49
+ /**
50
+ * {@inheritdoc}
51
+ */
52
+ public function close()
53
+ {
54
+ $this->publisher = null;
55
+ }
56
+
57
+ /**
58
+ * {@inheritdoc}
59
+ */
60
+ protected function write(array $record)
61
+ {
62
+ $this->publisher->publish($record['formatted']);
63
+ }
64
+
65
+ /**
66
+ * {@inheritDoc}
67
+ */
68
+ protected function getDefaultFormatter()
69
+ {
70
+ return new GelfMessageFormatter();
71
+ }
72
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ /**
15
+ * Forwards records to multiple handlers
16
+ *
17
+ * @author Lenar Lõhmus <lenar@city.ee>
18
+ */
19
+ class GroupHandler extends AbstractHandler
20
+ {
21
+ protected $handlers;
22
+
23
+ /**
24
+ * @param array $handlers Array of Handlers.
25
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
26
+ */
27
+ public function __construct(array $handlers, $bubble = true)
28
+ {
29
+ foreach ($handlers as $handler) {
30
+ if (!$handler instanceof HandlerInterface) {
31
+ throw new \InvalidArgumentException('The first argument of the GroupHandler must be an array of HandlerInterface instances.');
32
+ }
33
+ }
34
+
35
+ $this->handlers = $handlers;
36
+ $this->bubble = $bubble;
37
+ }
38
+
39
+ /**
40
+ * {@inheritdoc}
41
+ */
42
+ public function isHandling(array $record)
43
+ {
44
+ foreach ($this->handlers as $handler) {
45
+ if ($handler->isHandling($record)) {
46
+ return true;
47
+ }
48
+ }
49
+
50
+ return false;
51
+ }
52
+
53
+ /**
54
+ * {@inheritdoc}
55
+ */
56
+ public function handle(array $record)
57
+ {
58
+ if ($this->processors) {
59
+ foreach ($this->processors as $processor) {
60
+ $record = call_user_func($processor, $record);
61
+ }
62
+ }
63
+
64
+ foreach ($this->handlers as $handler) {
65
+ $handler->handle($record);
66
+ }
67
+
68
+ return false === $this->bubble;
69
+ }
70
+
71
+ /**
72
+ * {@inheritdoc}
73
+ */
74
+ public function handleBatch(array $records)
75
+ {
76
+ foreach ($this->handlers as $handler) {
77
+ $handler->handleBatch($records);
78
+ }
79
+ }
80
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Formatter\FormatterInterface;
15
+
16
+ /**
17
+ * Interface that all Monolog Handlers must implement
18
+ *
19
+ * @author Jordi Boggiano <j.boggiano@seld.be>
20
+ */
21
+ interface HandlerInterface
22
+ {
23
+ /**
24
+ * Checks whether the given record will be handled by this handler.
25
+ *
26
+ * This is mostly done for performance reasons, to avoid calling processors for nothing.
27
+ *
28
+ * Handlers should still check the record levels within handle(), returning false in isHandling()
29
+ * is no guarantee that handle() will not be called, and isHandling() might not be called
30
+ * for a given record.
31
+ *
32
+ * @param array $record Partial log record containing only a level key
33
+ *
34
+ * @return Boolean
35
+ */
36
+ public function isHandling(array $record);
37
+
38
+ /**
39
+ * Handles a record.
40
+ *
41
+ * All records may be passed to this method, and the handler should discard
42
+ * those that it does not want to handle.
43
+ *
44
+ * The return value of this function controls the bubbling process of the handler stack.
45
+ * Unless the bubbling is interrupted (by returning true), the Logger class will keep on
46
+ * calling further handlers in the stack with a given log record.
47
+ *
48
+ * @param array $record The record to handle
49
+ * @return Boolean true means that this handler handled the record, and that bubbling is not permitted.
50
+ * false means the record was either not processed or that this handler allows bubbling.
51
+ */
52
+ public function handle(array $record);
53
+
54
+ /**
55
+ * Handles a set of records at once.
56
+ *
57
+ * @param array $records The records to handle (an array of record arrays)
58
+ */
59
+ public function handleBatch(array $records);
60
+
61
+ /**
62
+ * Adds a processor in the stack.
63
+ *
64
+ * @param callable $callback
65
+ * @return self
66
+ */
67
+ public function pushProcessor($callback);
68
+
69
+ /**
70
+ * Removes the processor on top of the stack and returns it.
71
+ *
72
+ * @return callable
73
+ */
74
+ public function popProcessor();
75
+
76
+ /**
77
+ * Sets the formatter.
78
+ *
79
+ * @param FormatterInterface $formatter
80
+ * @return self
81
+ */
82
+ public function setFormatter(FormatterInterface $formatter);
83
+
84
+ /**
85
+ * Gets the formatter.
86
+ *
87
+ * @return FormatterInterface
88
+ */
89
+ public function getFormatter();
90
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/HipChatHandler.php ADDED
@@ -0,0 +1,306 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Sends notifications through the hipchat api to a hipchat room
18
+ *
19
+ * Notes:
20
+ * API token - HipChat API token
21
+ * Room - HipChat Room Id or name, where messages are sent
22
+ * Name - Name used to send the message (from)
23
+ * notify - Should the message trigger a notification in the clients
24
+ *
25
+ * @author Rafael Dohms <rafael@doh.ms>
26
+ * @see https://www.hipchat.com/docs/api
27
+ */
28
+ class HipChatHandler extends SocketHandler
29
+ {
30
+ /**
31
+ * The maximum allowed length for the name used in the "from" field.
32
+ */
33
+ const MAXIMUM_NAME_LENGTH = 15;
34
+
35
+ /**
36
+ * The maximum allowed length for the message.
37
+ */
38
+ const MAXIMUM_MESSAGE_LENGTH = 9500;
39
+
40
+ /**
41
+ * @var string
42
+ */
43
+ private $token;
44
+
45
+ /**
46
+ * @var string
47
+ */
48
+ private $room;
49
+
50
+ /**
51
+ * @var string
52
+ */
53
+ private $name;
54
+
55
+ /**
56
+ * @var bool
57
+ */
58
+ private $notify;
59
+
60
+ /**
61
+ * @var string
62
+ */
63
+ private $format;
64
+
65
+ /**
66
+ * @var string
67
+ */
68
+ private $host;
69
+
70
+ /**
71
+ * @param string $token HipChat API Token
72
+ * @param string $room The room that should be alerted of the message (Id or Name)
73
+ * @param string $name Name used in the "from" field
74
+ * @param bool $notify Trigger a notification in clients or not
75
+ * @param int $level The minimum logging level at which this handler will be triggered
76
+ * @param bool $bubble Whether the messages that are handled can bubble up the stack or not
77
+ * @param bool $useSSL Whether to connect via SSL.
78
+ * @param string $format The format of the messages (default to text, can be set to html if you have html in the messages)
79
+ * @param string $host The HipChat server hostname.
80
+ */
81
+ public function __construct($token, $room, $name = 'Monolog', $notify = false, $level = Logger::CRITICAL, $bubble = true, $useSSL = true, $format = 'text', $host = 'api.hipchat.com')
82
+ {
83
+ if (!$this->validateStringLength($name, static::MAXIMUM_NAME_LENGTH)) {
84
+ throw new \InvalidArgumentException('The supplied name is too long. HipChat\'s v1 API supports names up to 15 UTF-8 characters.');
85
+ }
86
+
87
+ $connectionString = $useSSL ? 'ssl://'.$host.':443' : $host.':80';
88
+ parent::__construct($connectionString, $level, $bubble);
89
+
90
+ $this->token = $token;
91
+ $this->name = $name;
92
+ $this->notify = $notify;
93
+ $this->room = $room;
94
+ $this->format = $format;
95
+ $this->host = $host;
96
+ }
97
+
98
+ /**
99
+ * {@inheritdoc}
100
+ *
101
+ * @param array $record
102
+ * @return string
103
+ */
104
+ protected function generateDataStream($record)
105
+ {
106
+ $content = $this->buildContent($record);
107
+
108
+ return $this->buildHeader($content) . $content;
109
+ }
110
+
111
+ /**
112
+ * Builds the body of API call
113
+ *
114
+ * @param array $record
115
+ * @return string
116
+ */
117
+ private function buildContent($record)
118
+ {
119
+ $dataArray = array(
120
+ 'from' => $this->name,
121
+ 'room_id' => $this->room,
122
+ 'notify' => $this->notify,
123
+ 'message' => $record['formatted'],
124
+ 'message_format' => $this->format,
125
+ 'color' => $this->getAlertColor($record['level']),
126
+ );
127
+
128
+ return http_build_query($dataArray);
129
+ }
130
+
131
+ /**
132
+ * Builds the header of the API Call
133
+ *
134
+ * @param string $content
135
+ * @return string
136
+ */
137
+ private function buildHeader($content)
138
+ {
139
+ $header = "POST /v1/rooms/message?format=json&auth_token=".$this->token." HTTP/1.1\r\n";
140
+ $header .= "Host: {$this->host}\r\n";
141
+ $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
142
+ $header .= "Content-Length: " . strlen($content) . "\r\n";
143
+ $header .= "\r\n";
144
+
145
+ return $header;
146
+ }
147
+
148
+ /**
149
+ * Assigns a color to each level of log records.
150
+ *
151
+ * @param integer $level
152
+ * @return string
153
+ */
154
+ protected function getAlertColor($level)
155
+ {
156
+ switch (true) {
157
+ case $level >= Logger::ERROR:
158
+ return 'red';
159
+ case $level >= Logger::WARNING:
160
+ return 'yellow';
161
+ case $level >= Logger::INFO:
162
+ return 'green';
163
+ case $level == Logger::DEBUG:
164
+ return 'gray';
165
+ default:
166
+ return 'yellow';
167
+ }
168
+ }
169
+
170
+ /**
171
+ * {@inheritdoc}
172
+ *
173
+ * @param array $record
174
+ */
175
+ protected function write(array $record)
176
+ {
177
+ parent::write($record);
178
+ $this->closeSocket();
179
+ }
180
+
181
+ /**
182
+ * {@inheritdoc}
183
+ */
184
+ public function handleBatch(array $records)
185
+ {
186
+ if (count($records) == 0) {
187
+ return true;
188
+ }
189
+
190
+ $batchRecords = $this->combineRecords($records);
191
+
192
+ $handled = false;
193
+ foreach ($batchRecords as $batchRecord) {
194
+ if ($this->isHandling($batchRecord)) {
195
+ $this->write($batchRecord);
196
+ $handled = true;
197
+ }
198
+ }
199
+
200
+ if (!$handled) {
201
+ return false;
202
+ }
203
+
204
+ return false === $this->bubble;
205
+ }
206
+
207
+ /**
208
+ * Combines multiple records into one. Error level of the combined record
209
+ * will be the highest level from the given records. Datetime will be taken
210
+ * from the first record.
211
+ *
212
+ * @param $records
213
+ * @return array
214
+ */
215
+ private function combineRecords($records)
216
+ {
217
+ $batchRecord = null;
218
+ $batchRecords = array();
219
+ $messages = array();
220
+ $formattedMessages = array();
221
+ $level = 0;
222
+ $levelName = null;
223
+ $datetime = null;
224
+
225
+ foreach ($records as $record) {
226
+ $record = $this->processRecord($record);
227
+
228
+ if ($record['level'] > $level) {
229
+ $level = $record['level'];
230
+ $levelName = $record['level_name'];
231
+ }
232
+
233
+ if (null === $datetime) {
234
+ $datetime = $record['datetime'];
235
+ }
236
+
237
+ $messages[] = $record['message'];
238
+ $messageStr = implode(PHP_EOL, $messages);
239
+ $formattedMessages[] = $this->getFormatter()->format($record);
240
+ $formattedMessageStr = implode('', $formattedMessages);
241
+
242
+ $batchRecord = array(
243
+ 'message' => $messageStr,
244
+ 'formatted' => $formattedMessageStr,
245
+ 'context' => array(),
246
+ 'extra' => array(),
247
+ );
248
+
249
+ if (!$this->validateStringLength($batchRecord['formatted'], static::MAXIMUM_MESSAGE_LENGTH)) {
250
+ // Pop the last message and implode the remaining messages
251
+ $lastMessage = array_pop($messages);
252
+ $lastFormattedMessage = array_pop($formattedMessages);
253
+ $batchRecord['message'] = implode(PHP_EOL, $messages);
254
+ $batchRecord['formatted'] = implode('', $formattedMessages);
255
+
256
+ $batchRecords[] = $batchRecord;
257
+ $messages = array($lastMessage);
258
+ $formattedMessages = array($lastFormattedMessage);
259
+
260
+ $batchRecord = null;
261
+ }
262
+ }
263
+
264
+ if (null !== $batchRecord) {
265
+ $batchRecords[] = $batchRecord;
266
+ }
267
+
268
+ // Set the max level and datetime for all records
269
+ foreach ($batchRecords as &$batchRecord) {
270
+ $batchRecord = array_merge(
271
+ $batchRecord,
272
+ array(
273
+ 'level' => $level,
274
+ 'level_name' => $levelName,
275
+ 'datetime' => $datetime
276
+ )
277
+ );
278
+ }
279
+
280
+ return $batchRecords;
281
+ }
282
+
283
+ /**
284
+ * Validates the length of a string.
285
+ *
286
+ * If the `mb_strlen()` function is available, it will use that, as HipChat
287
+ * allows UTF-8 characters. Otherwise, it will fall back to `strlen()`.
288
+ *
289
+ * Note that this might cause false failures in the specific case of using
290
+ * a valid name with less than 16 characters, but 16 or more bytes, on a
291
+ * system where `mb_strlen()` is unavailable.
292
+ *
293
+ * @param string $str
294
+ * @param int $length
295
+ *
296
+ * @return bool
297
+ */
298
+ private function validateStringLength($str, $length)
299
+ {
300
+ if (function_exists('mb_strlen')) {
301
+ return (mb_strlen($str) <= $length);
302
+ }
303
+
304
+ return (strlen($str) <= $length);
305
+ }
306
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * @author Robert Kaufmann III <rok3@rok3.me>
18
+ */
19
+ class LogEntriesHandler extends SocketHandler
20
+ {
21
+ /**
22
+ * @var string
23
+ */
24
+ protected $logToken;
25
+
26
+ /**
27
+ * @param string $token Log token supplied by LogEntries
28
+ * @param boolean $useSSL Whether or not SSL encryption should be used.
29
+ * @param int $level The minimum logging level to trigger this handler
30
+ * @param boolean $bubble Whether or not messages that are handled should bubble up the stack.
31
+ *
32
+ * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing
33
+ */
34
+ public function __construct($token, $useSSL = true, $level = Logger::DEBUG, $bubble = true)
35
+ {
36
+ if ($useSSL && !extension_loaded('openssl')) {
37
+ throw new MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for LogEntriesHandler');
38
+ }
39
+
40
+ $endpoint = $useSSL ? 'ssl://data.logentries.com:443' : 'data.logentries.com:80';
41
+ parent::__construct($endpoint, $level, $bubble);
42
+ $this->logToken = $token;
43
+ }
44
+
45
+ /**
46
+ * {@inheritdoc}
47
+ *
48
+ * @param array $record
49
+ * @return string
50
+ */
51
+ protected function generateDataStream($record)
52
+ {
53
+ return $this->logToken . ' ' . $record['formatted'];
54
+ }
55
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/LogglyHandler.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+ use Monolog\Formatter\LogglyFormatter;
16
+
17
+ /**
18
+ * Sends errors to Loggly.
19
+ *
20
+ * @author Przemek Sobstel <przemek@sobstel.org>
21
+ * @author Adam Pancutt <adam@pancutt.com>
22
+ */
23
+ class LogglyHandler extends AbstractProcessingHandler
24
+ {
25
+ const HOST = 'logs-01.loggly.com';
26
+ const ENDPOINT_SINGLE = 'inputs';
27
+ const ENDPOINT_BATCH = 'bulk';
28
+
29
+ protected $token;
30
+
31
+ protected $tag;
32
+
33
+ public function __construct($token, $level = Logger::DEBUG, $bubble = true)
34
+ {
35
+ if (!extension_loaded('curl')) {
36
+ throw new \LogicException('The curl extension is needed to use the LogglyHandler');
37
+ }
38
+
39
+ $this->token = $token;
40
+
41
+ parent::__construct($level, $bubble);
42
+ }
43
+
44
+ public function setTag($tag)
45
+ {
46
+ $this->tag = $tag;
47
+ }
48
+
49
+ public function addTag($tag)
50
+ {
51
+ $this->tag = (strlen($this->tag) > 0) ? $this->tag .','. $tag : $tag;
52
+ }
53
+
54
+ protected function write(array $record)
55
+ {
56
+ $this->send($record["formatted"], self::ENDPOINT_SINGLE);
57
+ }
58
+
59
+ public function handleBatch(array $records)
60
+ {
61
+ $level = $this->level;
62
+
63
+ $records = array_filter($records, function ($record) use ($level) {
64
+ return ($record['level'] >= $level);
65
+ });
66
+
67
+ if ($records) {
68
+ $this->send($this->getFormatter()->formatBatch($records), self::ENDPOINT_BATCH);
69
+ }
70
+ }
71
+
72
+ protected function send($data, $endpoint)
73
+ {
74
+ $url = sprintf("https://%s/%s/%s/", self::HOST, $endpoint, $this->token);
75
+
76
+ $headers = array('Content-Type: application/json');
77
+
78
+ if ($this->tag) {
79
+ $headers[] = "X-LOGGLY-TAG: {$this->tag}";
80
+ }
81
+
82
+ $ch = curl_init();
83
+
84
+ curl_setopt($ch, CURLOPT_URL, $url);
85
+ curl_setopt($ch, CURLOPT_POST, true);
86
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
87
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
88
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
89
+
90
+ curl_exec($ch);
91
+ curl_close($ch);
92
+ }
93
+
94
+ protected function getDefaultFormatter()
95
+ {
96
+ return new LogglyFormatter();
97
+ }
98
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/MailHandler.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ /**
15
+ * Base class for all mail handlers
16
+ *
17
+ * @author Gyula Sallai
18
+ */
19
+ abstract class MailHandler extends AbstractProcessingHandler
20
+ {
21
+ /**
22
+ * {@inheritdoc}
23
+ */
24
+ public function handleBatch(array $records)
25
+ {
26
+ $messages = array();
27
+
28
+ foreach ($records as $record) {
29
+ if ($record['level'] < $this->level) {
30
+ continue;
31
+ }
32
+ $messages[] = $this->processRecord($record);
33
+ }
34
+
35
+ if (!empty($messages)) {
36
+ $this->send((string) $this->getFormatter()->formatBatch($messages), $messages);
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Send a mail with the given content
42
+ *
43
+ * @param string $content formatted email body to be sent
44
+ * @param array $records the array of log records that formed this content
45
+ */
46
+ abstract protected function send($content, array $records);
47
+
48
+ /**
49
+ * {@inheritdoc}
50
+ */
51
+ protected function write(array $record)
52
+ {
53
+ $this->send((string) $record['formatted'], array($record));
54
+ }
55
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/MandrillHandler.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * MandrillHandler uses cURL to send the emails to the Mandrill API
18
+ *
19
+ * @author Adam Nicholson <adamnicholson10@gmail.com>
20
+ */
21
+ class MandrillHandler extends MailHandler
22
+ {
23
+ protected $client;
24
+ protected $message;
25
+
26
+ /**
27
+ * @param string $apiKey A valid Mandrill API key
28
+ * @param callable|\Swift_Message $message An example message for real messages, only the body will be replaced
29
+ * @param integer $level The minimum logging level at which this handler will be triggered
30
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
31
+ */
32
+ public function __construct($apiKey, $message, $level = Logger::ERROR, $bubble = true)
33
+ {
34
+ parent::__construct($level, $bubble);
35
+
36
+ if (!$message instanceof \Swift_Message && is_callable($message)) {
37
+ $message = call_user_func($message);
38
+ }
39
+ if (!$message instanceof \Swift_Message) {
40
+ throw new \InvalidArgumentException('You must provide either a Swift_Message instance or a callable returning it');
41
+ }
42
+ $this->message = $message;
43
+ $this->apiKey = $apiKey;
44
+ }
45
+
46
+ /**
47
+ * {@inheritdoc}
48
+ */
49
+ protected function send($content, array $records)
50
+ {
51
+ $message = clone $this->message;
52
+ $message->setBody($content);
53
+ $message->setDate(time());
54
+
55
+ $ch = curl_init();
56
+
57
+ curl_setopt($ch, CURLOPT_URL, 'https://mandrillapp.com/api/1.0/messages/send-raw.json');
58
+ curl_setopt($ch, CURLOPT_POST, 1);
59
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
60
+ curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
61
+ 'key' => $this->apiKey,
62
+ 'raw_message' => (string) $message,
63
+ 'async' => false,
64
+ )));
65
+
66
+ curl_exec($ch);
67
+ curl_close($ch);
68
+ }
69
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ /**
15
+ * Exception can be thrown if an extension for an handler is missing
16
+ *
17
+ * @author Christian Bergau <cbergau86@gmail.com>
18
+ */
19
+ class MissingExtensionException extends \Exception
20
+ {
21
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+ use Monolog\Formatter\NormalizerFormatter;
16
+
17
+ /**
18
+ * Logs to a MongoDB database.
19
+ *
20
+ * usage example:
21
+ *
22
+ * $log = new Logger('application');
23
+ * $mongodb = new MongoDBHandler(new \Mongo("mongodb://localhost:27017"), "logs", "prod");
24
+ * $log->pushHandler($mongodb);
25
+ *
26
+ * @author Thomas Tourlourat <thomas@tourlourat.com>
27
+ */
28
+ class MongoDBHandler extends AbstractProcessingHandler
29
+ {
30
+ protected $mongoCollection;
31
+
32
+ public function __construct($mongo, $database, $collection, $level = Logger::DEBUG, $bubble = true)
33
+ {
34
+ if (!($mongo instanceof \MongoClient || $mongo instanceof \Mongo)) {
35
+ throw new \InvalidArgumentException('MongoClient or Mongo instance required');
36
+ }
37
+
38
+ $this->mongoCollection = $mongo->selectCollection($database, $collection);
39
+
40
+ parent::__construct($level, $bubble);
41
+ }
42
+
43
+ protected function write(array $record)
44
+ {
45
+ $this->mongoCollection->save($record["formatted"]);
46
+ }
47
+
48
+ /**
49
+ * {@inheritDoc}
50
+ */
51
+ protected function getDefaultFormatter()
52
+ {
53
+ return new NormalizerFormatter();
54
+ }
55
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * NativeMailerHandler uses the mail() function to send the emails
18
+ *
19
+ * @author Christophe Coevoet <stof@notk.org>
20
+ * @author Mark Garrett <mark@moderndeveloperllc.com>
21
+ */
22
+ class NativeMailerHandler extends MailHandler
23
+ {
24
+ /**
25
+ * The email addresses to which the message will be sent
26
+ * @var array
27
+ */
28
+ protected $to;
29
+
30
+ /**
31
+ * The subject of the email
32
+ * @var string
33
+ */
34
+ protected $subject;
35
+
36
+ /**
37
+ * Optional headers for the message
38
+ * @var array
39
+ */
40
+ protected $headers = array();
41
+
42
+ /**
43
+ * Optional parameters for the message
44
+ * @var array
45
+ */
46
+ protected $parameters = array();
47
+
48
+ /**
49
+ * The wordwrap length for the message
50
+ * @var integer
51
+ */
52
+ protected $maxColumnWidth;
53
+
54
+ /**
55
+ * The Content-type for the message
56
+ * @var string
57
+ */
58
+ protected $contentType = 'text/plain';
59
+
60
+ /**
61
+ * The encoding for the message
62
+ * @var string
63
+ */
64
+ protected $encoding = 'utf-8';
65
+
66
+ /**
67
+ * @param string|array $to The receiver of the mail
68
+ * @param string $subject The subject of the mail
69
+ * @param string $from The sender of the mail
70
+ * @param integer $level The minimum logging level at which this handler will be triggered
71
+ * @param boolean $bubble Whether the messages that are handled can bubble up the stack or not
72
+ * @param int $maxColumnWidth The maximum column width that the message lines will have
73
+ */
74
+ public function __construct($to, $subject, $from, $level = Logger::ERROR, $bubble = true, $maxColumnWidth = 70)
75
+ {
76
+ parent::__construct($level, $bubble);
77
+ $this->to = is_array($to) ? $to : array($to);
78
+ $this->subject = $subject;
79
+ $this->addHeader(sprintf('From: %s', $from));
80
+ $this->maxColumnWidth = $maxColumnWidth;
81
+ }
82
+
83
+ /**
84
+ * Add headers to the message
85
+ *
86
+ * @param string|array $headers Custom added headers
87
+ * @return self
88
+ */
89
+ public function addHeader($headers)
90
+ {
91
+ foreach ((array) $headers as $header) {
92
+ if (strpos($header, "\n") !== false || strpos($header, "\r") !== false) {
93
+ throw new \InvalidArgumentException('Headers can not contain newline characters for security reasons');
94
+ }
95
+ $this->headers[] = $header;
96
+ }
97
+
98
+ return $this;
99
+ }
100
+
101
+ /**
102
+ * Add parameters to the message
103
+ *
104
+ * @param string|array $parameters Custom added parameters
105
+ * @return self
106
+ */
107
+ public function addParameter($parameters)
108
+ {
109
+ $this->parameters = array_merge($this->parameters, (array) $parameters);
110
+
111
+ return $this;
112
+ }
113
+
114
+ /**
115
+ * {@inheritdoc}
116
+ */
117
+ protected function send($content, array $records)
118
+ {
119
+ $content = wordwrap($content, $this->maxColumnWidth);
120
+ $headers = ltrim(implode("\r\n", $this->headers) . "\r\n", "\r\n");
121
+ $headers .= 'Content-type: ' . $this->getContentType() . '; charset=' . $this->getEncoding() . "\r\n";
122
+ if ($this->getContentType() == 'text/html' && false === strpos($headers, 'MIME-Version:')) {
123
+ $headers .= 'MIME-Version: 1.0' . "\r\n";
124
+ }
125
+ foreach ($this->to as $to) {
126
+ mail($to, $this->subject, $content, $headers, implode(' ', $this->parameters));
127
+ }
128
+ }
129
+
130
+ /**
131
+ * @return string $contentType
132
+ */
133
+ public function getContentType()
134
+ {
135
+ return $this->contentType;
136
+ }
137
+
138
+ /**
139
+ * @return string $encoding
140
+ */
141
+ public function getEncoding()
142
+ {
143
+ return $this->encoding;
144
+ }
145
+
146
+ /**
147
+ * @param string $contentType The content type of the email - Defaults to text/plain. Use text/html for HTML
148
+ * messages.
149
+ * @return self
150
+ */
151
+ public function setContentType($contentType)
152
+ {
153
+ if (strpos($contentType, "\n") !== false || strpos($contentType, "\r") !== false) {
154
+ throw new \InvalidArgumentException('The content type can not contain newline characters to prevent email header injection');
155
+ }
156
+
157
+ $this->contentType = $contentType;
158
+
159
+ return $this;
160
+ }
161
+
162
+ /**
163
+ * @param string $encoding
164
+ * @return self
165
+ */
166
+ public function setEncoding($encoding)
167
+ {
168
+ if (strpos($encoding, "\n") !== false || strpos($encoding, "\r") !== false) {
169
+ throw new \InvalidArgumentException('The encoding can not contain newline characters to prevent email header injection');
170
+ }
171
+
172
+ $this->encoding = $encoding;
173
+
174
+ return $this;
175
+ }
176
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Class to record a log on a NewRelic application.
18
+ * Enabling New Relic High Security mode may prevent capture of useful information.
19
+ *
20
+ * @see https://docs.newrelic.com/docs/agents/php-agent
21
+ * @see https://docs.newrelic.com/docs/accounts-partnerships/accounts/security/high-security
22
+ */
23
+ class NewRelicHandler extends AbstractProcessingHandler
24
+ {
25
+ /**
26
+ * Name of the New Relic application that will receive logs from this handler.
27
+ *
28
+ * @var string
29
+ */
30
+ protected $appName;
31
+
32
+ /**
33
+ * Name of the current transaction
34
+ *
35
+ * @var string
36
+ */
37
+ protected $transactionName;
38
+
39
+ /**
40
+ * Some context and extra data is passed into the handler as arrays of values. Do we send them as is
41
+ * (useful if we are using the API), or explode them for display on the NewRelic RPM website?
42
+ *
43
+ * @var boolean
44
+ */
45
+ protected $explodeArrays;
46
+
47
+ /**
48
+ * {@inheritDoc}
49
+ *
50
+ * @param string $appName
51
+ * @param boolean $explodeArrays
52
+ * @param string $transactionName
53
+ */
54
+ public function __construct(
55
+ $level = Logger::ERROR,
56
+ $bubble = true,
57
+ $appName = null,
58
+ $explodeArrays = false,
59
+ $transactionName = null
60
+ ) {
61
+ parent::__construct($level, $bubble);
62
+
63
+ $this->appName = $appName;
64
+ $this->explodeArrays = $explodeArrays;
65
+ $this->transactionName = $transactionName;
66
+ }
67
+
68
+ /**
69
+ * {@inheritDoc}
70
+ */
71
+ protected function write(array $record)
72
+ {
73
+ if (!$this->isNewRelicEnabled()) {
74
+ throw new MissingExtensionException('The newrelic PHP extension is required to use the NewRelicHandler');
75
+ }
76
+
77
+ if ($appName = $this->getAppName($record['context'])) {
78
+ $this->setNewRelicAppName($appName);
79
+ }
80
+
81
+ if ($transactionName = $this->getTransactionName($record['context'])) {
82
+ $this->setNewRelicTransactionName($transactionName);
83
+ unset($record['context']['transaction_name']);
84
+ }
85
+
86
+ if (isset($record['context']['exception']) && $record['context']['exception'] instanceof \Exception) {
87
+ newrelic_notice_error($record['message'], $record['context']['exception']);
88
+ unset($record['context']['exception']);
89
+ } else {
90
+ newrelic_notice_error($record['message']);
91
+ }
92
+
93
+ foreach ($record['context'] as $key => $parameter) {
94
+ if (is_array($parameter) && $this->explodeArrays) {
95
+ foreach ($parameter as $paramKey => $paramValue) {
96
+ newrelic_add_custom_parameter('context_' . $key . '_' . $paramKey, $paramValue);
97
+ }
98
+ } else {
99
+ newrelic_add_custom_parameter('context_' . $key, $parameter);
100
+ }
101
+ }
102
+
103
+ foreach ($record['extra'] as $key => $parameter) {
104
+ if (is_array($parameter) && $this->explodeArrays) {
105
+ foreach ($parameter as $paramKey => $paramValue) {
106
+ newrelic_add_custom_parameter('extra_' . $key . '_' . $paramKey, $paramValue);
107
+ }
108
+ } else {
109
+ newrelic_add_custom_parameter('extra_' . $key, $parameter);
110
+ }
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Checks whether the NewRelic extension is enabled in the system.
116
+ *
117
+ * @return bool
118
+ */
119
+ protected function isNewRelicEnabled()
120
+ {
121
+ return extension_loaded('newrelic');
122
+ }
123
+
124
+ /**
125
+ * Returns the appname where this log should be sent. Each log can override the default appname, set in this
126
+ * handler's constructor, by providing the appname in it's context.
127
+ *
128
+ * @param array $context
129
+ * @return null|string
130
+ */
131
+ protected function getAppName(array $context)
132
+ {
133
+ if (isset($context['appname'])) {
134
+ return $context['appname'];
135
+ }
136
+
137
+ return $this->appName;
138
+ }
139
+
140
+ /**
141
+ * Returns the name of the current transaction. Each log can override the default transaction name, set in this
142
+ * handler's constructor, by providing the transaction_name in it's context
143
+ *
144
+ * @param array $context
145
+ *
146
+ * @return null|string
147
+ */
148
+ protected function getTransactionName(array $context)
149
+ {
150
+ if (isset($context['transaction_name'])) {
151
+ return $context['transaction_name'];
152
+ }
153
+
154
+ return $this->transactionName;
155
+ }
156
+
157
+ /**
158
+ * Sets the NewRelic application that should receive this log.
159
+ *
160
+ * @param string $appName
161
+ */
162
+ protected function setNewRelicAppName($appName)
163
+ {
164
+ newrelic_set_appname($appName);
165
+ }
166
+
167
+ /**
168
+ * Overwrites the name of the current transaction
169
+ *
170
+ * @param $transactionName
171
+ */
172
+ protected function setNewRelicTransactionName($transactionName)
173
+ {
174
+ newrelic_name_transaction($transactionName);
175
+ }
176
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Blackhole
18
+ *
19
+ * Any record it can handle will be thrown away. This can be used
20
+ * to put on top of an existing stack to override it temporarily.
21
+ *
22
+ * @author Jordi Boggiano <j.boggiano@seld.be>
23
+ */
24
+ class NullHandler extends AbstractHandler
25
+ {
26
+ /**
27
+ * @param integer $level The minimum logging level at which this handler will be triggered
28
+ */
29
+ public function __construct($level = Logger::DEBUG)
30
+ {
31
+ parent::__construct($level, false);
32
+ }
33
+
34
+ /**
35
+ * {@inheritdoc}
36
+ */
37
+ public function handle(array $record)
38
+ {
39
+ if ($record['level'] < $this->level) {
40
+ return false;
41
+ }
42
+
43
+ return true;
44
+ }
45
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/PsrHandler.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+ use Psr\Log\LoggerInterface;
16
+
17
+ /**
18
+ * Proxies log messages to an existing PSR-3 compliant logger.
19
+ *
20
+ * @author Michael Moussa <michael.moussa@gmail.com>
21
+ */
22
+ class PsrHandler extends AbstractHandler
23
+ {
24
+ /**
25
+ * PSR-3 compliant logger
26
+ *
27
+ * @var LoggerInterface
28
+ */
29
+ protected $logger;
30
+
31
+ /**
32
+ * @param LoggerInterface $logger The underlying PSR-3 compliant logger to which messages will be proxied
33
+ * @param int $level The minimum logging level at which this handler will be triggered
34
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
35
+ */
36
+ public function __construct(LoggerInterface $logger, $level = Logger::DEBUG, $bubble = true)
37
+ {
38
+ parent::__construct($level, $bubble);
39
+
40
+ $this->logger = $logger;
41
+ }
42
+
43
+ /**
44
+ * {@inheritDoc}
45
+ */
46
+ public function handle(array $record)
47
+ {
48
+ if (!$this->isHandling($record)) {
49
+ return false;
50
+ }
51
+
52
+ $this->logger->log(strtolower($record['level_name']), $record['message'], $record['context']);
53
+
54
+ return false === $this->bubble;
55
+ }
56
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/PushoverHandler.php ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Sends notifications through the pushover api to mobile phones
18
+ *
19
+ * @author Sebastian Göttschkes <sebastian.goettschkes@googlemail.com>
20
+ * @see https://www.pushover.net/api
21
+ */
22
+ class PushoverHandler extends SocketHandler
23
+ {
24
+ private $token;
25
+ private $users;
26
+ private $title;
27
+ private $user;
28
+ private $retry;
29
+ private $expire;
30
+
31
+ private $highPriorityLevel;
32
+ private $emergencyLevel;
33
+
34
+ /**
35
+ * All parameters that can be sent to Pushover
36
+ * @see https://pushover.net/api
37
+ * @var array
38
+ */
39
+ private $parameterNames = array(
40
+ 'token' => true,
41
+ 'user' => true,
42
+ 'message' => true,
43
+ 'device' => true,
44
+ 'title' => true,
45
+ 'url' => true,
46
+ 'url_title' => true,
47
+ 'priority' => true,
48
+ 'timestamp' => true,
49
+ 'sound' => true,
50
+ 'retry' => true,
51
+ 'expire' => true,
52
+ 'callback' => true,
53
+ );
54
+
55
+ /**
56
+ * Sounds the api supports by default
57
+ * @see https://pushover.net/api#sounds
58
+ * @var array
59
+ */
60
+ private $sounds = array(
61
+ 'pushover', 'bike', 'bugle', 'cashregister', 'classical', 'cosmic', 'falling', 'gamelan', 'incoming',
62
+ 'intermission', 'magic', 'mechanical', 'pianobar', 'siren', 'spacealarm', 'tugboat', 'alien', 'climb',
63
+ 'persistent', 'echo', 'updown', 'none',
64
+ );
65
+
66
+ /**
67
+ * @param string $token Pushover api token
68
+ * @param string|array $users Pushover user id or array of ids the message will be sent to
69
+ * @param string $title Title sent to the Pushover API
70
+ * @param integer $level The minimum logging level at which this handler will be triggered
71
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
72
+ * @param Boolean $useSSL Whether to connect via SSL. Required when pushing messages to users that are not
73
+ * the pushover.net app owner. OpenSSL is required for this option.
74
+ * @param integer $highPriorityLevel The minimum logging level at which this handler will start
75
+ * sending "high priority" requests to the Pushover API
76
+ * @param integer $emergencyLevel The minimum logging level at which this handler will start
77
+ * sending "emergency" requests to the Pushover API
78
+ * @param integer $retry The retry parameter specifies how often (in seconds) the Pushover servers will send the same notification to the user.
79
+ * @param integer $expire The expire parameter specifies how many seconds your notification will continue to be retried for (every retry seconds).
80
+ */
81
+ public function __construct($token, $users, $title = null, $level = Logger::CRITICAL, $bubble = true, $useSSL = true, $highPriorityLevel = Logger::CRITICAL, $emergencyLevel = Logger::EMERGENCY, $retry = 30, $expire = 25200)
82
+ {
83
+ $connectionString = $useSSL ? 'ssl://api.pushover.net:443' : 'api.pushover.net:80';
84
+ parent::__construct($connectionString, $level, $bubble);
85
+
86
+ $this->token = $token;
87
+ $this->users = (array) $users;
88
+ $this->title = $title ?: gethostname();
89
+ $this->highPriorityLevel = Logger::toMonologLevel($highPriorityLevel);
90
+ $this->emergencyLevel = Logger::toMonologLevel($emergencyLevel);
91
+ $this->retry = $retry;
92
+ $this->expire = $expire;
93
+ }
94
+
95
+ protected function generateDataStream($record)
96
+ {
97
+ $content = $this->buildContent($record);
98
+
99
+ return $this->buildHeader($content) . $content;
100
+ }
101
+
102
+ private function buildContent($record)
103
+ {
104
+ // Pushover has a limit of 512 characters on title and message combined.
105
+ $maxMessageLength = 512 - strlen($this->title);
106
+ $message = substr($record['message'], 0, $maxMessageLength);
107
+ $timestamp = $record['datetime']->getTimestamp();
108
+
109
+ $dataArray = array(
110
+ 'token' => $this->token,
111
+ 'user' => $this->user,
112
+ 'message' => $message,
113
+ 'title' => $this->title,
114
+ 'timestamp' => $timestamp
115
+ );
116
+
117
+ if (isset($record['level']) && $record['level'] >= $this->emergencyLevel) {
118
+ $dataArray['priority'] = 2;
119
+ $dataArray['retry'] = $this->retry;
120
+ $dataArray['expire'] = $this->expire;
121
+ } elseif (isset($record['level']) && $record['level'] >= $this->highPriorityLevel) {
122
+ $dataArray['priority'] = 1;
123
+ }
124
+
125
+ // First determine the available parameters
126
+ $context = array_intersect_key($record['context'], $this->parameterNames);
127
+ $extra = array_intersect_key($record['extra'], $this->parameterNames);
128
+
129
+ // Least important info should be merged with subsequent info
130
+ $dataArray = array_merge($extra, $context, $dataArray);
131
+
132
+ // Only pass sounds that are supported by the API
133
+ if (isset($dataArray['sound']) && !in_array($dataArray['sound'], $this->sounds)) {
134
+ unset($dataArray['sound']);
135
+ }
136
+
137
+ return http_build_query($dataArray);
138
+ }
139
+
140
+ private function buildHeader($content)
141
+ {
142
+ $header = "POST /1/messages.json HTTP/1.1\r\n";
143
+ $header .= "Host: api.pushover.net\r\n";
144
+ $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
145
+ $header .= "Content-Length: " . strlen($content) . "\r\n";
146
+ $header .= "\r\n";
147
+
148
+ return $header;
149
+ }
150
+
151
+ protected function write(array $record)
152
+ {
153
+ foreach ($this->users as $user) {
154
+ $this->user = $user;
155
+
156
+ parent::write($record);
157
+ $this->closeSocket();
158
+ }
159
+
160
+ $this->user = null;
161
+ }
162
+
163
+ public function setHighPriorityLevel($value)
164
+ {
165
+ $this->highPriorityLevel = $value;
166
+ }
167
+
168
+ public function setEmergencyLevel($value)
169
+ {
170
+ $this->emergencyLevel = $value;
171
+ }
172
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/RavenHandler.php ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Formatter\LineFormatter;
15
+ use Monolog\Formatter\FormatterInterface;
16
+ use Monolog\Logger;
17
+ use Raven_Client;
18
+
19
+ /**
20
+ * Handler to send messages to a Sentry (https://github.com/getsentry/sentry) server
21
+ * using raven-php (https://github.com/getsentry/raven-php)
22
+ *
23
+ * @author Marc Abramowitz <marc@marc-abramowitz.com>
24
+ */
25
+ class RavenHandler extends AbstractProcessingHandler
26
+ {
27
+ /**
28
+ * Translates Monolog log levels to Raven log levels.
29
+ */
30
+ private $logLevels = array(
31
+ Logger::DEBUG => Raven_Client::DEBUG,
32
+ Logger::INFO => Raven_Client::INFO,
33
+ Logger::NOTICE => Raven_Client::INFO,
34
+ Logger::WARNING => Raven_Client::WARNING,
35
+ Logger::ERROR => Raven_Client::ERROR,
36
+ Logger::CRITICAL => Raven_Client::FATAL,
37
+ Logger::ALERT => Raven_Client::FATAL,
38
+ Logger::EMERGENCY => Raven_Client::FATAL,
39
+ );
40
+
41
+ /**
42
+ * @var Raven_Client the client object that sends the message to the server
43
+ */
44
+ protected $ravenClient;
45
+
46
+ /**
47
+ * @var LineFormatter The formatter to use for the logs generated via handleBatch()
48
+ */
49
+ protected $batchFormatter;
50
+
51
+ /**
52
+ * @param Raven_Client $ravenClient
53
+ * @param integer $level The minimum logging level at which this handler will be triggered
54
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
55
+ */
56
+ public function __construct(Raven_Client $ravenClient, $level = Logger::DEBUG, $bubble = true)
57
+ {
58
+ parent::__construct($level, $bubble);
59
+
60
+ $this->ravenClient = $ravenClient;
61
+ }
62
+
63
+ /**
64
+ * {@inheritdoc}
65
+ */
66
+ public function handleBatch(array $records)
67
+ {
68
+ $level = $this->level;
69
+
70
+ // filter records based on their level
71
+ $records = array_filter($records, function ($record) use ($level) {
72
+ return $record['level'] >= $level;
73
+ });
74
+
75
+ if (!$records) {
76
+ return;
77
+ }
78
+
79
+ // the record with the highest severity is the "main" one
80
+ $record = array_reduce($records, function ($highest, $record) {
81
+ if ($record['level'] >= $highest['level']) {
82
+ return $record;
83
+ }
84
+
85
+ return $highest;
86
+ });
87
+
88
+ // the other ones are added as a context item
89
+ $logs = array();
90
+ foreach ($records as $r) {
91
+ $logs[] = $this->processRecord($r);
92
+ }
93
+
94
+ if ($logs) {
95
+ $record['context']['logs'] = (string) $this->getBatchFormatter()->formatBatch($logs);
96
+ }
97
+
98
+ $this->handle($record);
99
+ }
100
+
101
+ /**
102
+ * Sets the formatter for the logs generated by handleBatch().
103
+ *
104
+ * @param FormatterInterface $formatter
105
+ */
106
+ public function setBatchFormatter(FormatterInterface $formatter)
107
+ {
108
+ $this->batchFormatter = $formatter;
109
+ }
110
+
111
+ /**
112
+ * Gets the formatter for the logs generated by handleBatch().
113
+ *
114
+ * @return FormatterInterface
115
+ */
116
+ public function getBatchFormatter()
117
+ {
118
+ if (!$this->batchFormatter) {
119
+ $this->batchFormatter = $this->getDefaultBatchFormatter();
120
+ }
121
+
122
+ return $this->batchFormatter;
123
+ }
124
+
125
+ /**
126
+ * {@inheritdoc}
127
+ */
128
+ protected function write(array $record)
129
+ {
130
+ // ensures user context is empty
131
+ $this->ravenClient->user_context(null);
132
+ $options = array();
133
+ $options['level'] = $this->logLevels[$record['level']];
134
+ $options['tags'] = array();
135
+ if (!empty($record['extra']['tags'])) {
136
+ $options['tags'] = array_merge($options['tags'], $record['extra']['tags']);
137
+ unset($record['extra']['tags']);
138
+ }
139
+ if (!empty($record['context']['tags'])) {
140
+ $options['tags'] = array_merge($options['tags'], $record['context']['tags']);
141
+ unset($record['context']['tags']);
142
+ }
143
+ if (!empty($record['context']['logger'])) {
144
+ $options['logger'] = $record['context']['logger'];
145
+ unset($record['context']['logger']);
146
+ } else {
147
+ $options['logger'] = $record['channel'];
148
+ }
149
+ if (!empty($record['context'])) {
150
+ $options['extra']['context'] = $record['context'];
151
+ if (!empty($record['context']['user'])) {
152
+ $this->ravenClient->user_context($record['context']['user']);
153
+ unset($options['extra']['context']['user']);
154
+ }
155
+ }
156
+ if (!empty($record['extra'])) {
157
+ $options['extra']['extra'] = $record['extra'];
158
+ }
159
+
160
+ if (isset($record['context']['exception']) && $record['context']['exception'] instanceof \Exception) {
161
+ $options['extra']['message'] = $record['formatted'];
162
+ $this->ravenClient->captureException($record['context']['exception'], $options);
163
+
164
+ return;
165
+ }
166
+
167
+ $this->ravenClient->captureMessage($record['formatted'], array(), $options);
168
+ }
169
+
170
+ /**
171
+ * {@inheritDoc}
172
+ */
173
+ protected function getDefaultFormatter()
174
+ {
175
+ return new LineFormatter('[%channel%] %message%');
176
+ }
177
+
178
+ /**
179
+ * Gets the default formatter for the logs generated by handleBatch().
180
+ *
181
+ * @return FormatterInterface
182
+ */
183
+ protected function getDefaultBatchFormatter()
184
+ {
185
+ return new LineFormatter();
186
+ }
187
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+ use Monolog\Formatter\LineFormatter;
16
+
17
+ /**
18
+ * Logs to a Redis key using rpush
19
+ *
20
+ * usage example:
21
+ *
22
+ * $log = new Logger('application');
23
+ * $redis = new RedisHandler(new Predis\Client("tcp://localhost:6379"), "logs", "prod");
24
+ * $log->pushHandler($redis);
25
+ *
26
+ * @author Thomas Tourlourat <thomas@tourlourat.com>
27
+ */
28
+ class RedisHandler extends AbstractProcessingHandler
29
+ {
30
+ private $redisClient;
31
+ private $redisKey;
32
+
33
+ # redis instance, key to use
34
+ public function __construct($redis, $key, $level = Logger::DEBUG, $bubble = true)
35
+ {
36
+ if (!(($redis instanceof \Predis\Client) || ($redis instanceof \Redis))) {
37
+ throw new \InvalidArgumentException('Predis\Client or Redis instance required');
38
+ }
39
+
40
+ $this->redisClient = $redis;
41
+ $this->redisKey = $key;
42
+
43
+ parent::__construct($level, $bubble);
44
+ }
45
+
46
+ protected function write(array $record)
47
+ {
48
+ $this->redisClient->rpush($this->redisKey, $record["formatted"]);
49
+ }
50
+
51
+ /**
52
+ * {@inheritDoc}
53
+ */
54
+ protected function getDefaultFormatter()
55
+ {
56
+ return new LineFormatter();
57
+ }
58
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use RollbarNotifier;
15
+ use Exception;
16
+ use Monolog\Logger;
17
+
18
+ /**
19
+ * Sends errors to Rollbar
20
+ *
21
+ * @author Paul Statezny <paulstatezny@gmail.com>
22
+ */
23
+ class RollbarHandler extends AbstractProcessingHandler
24
+ {
25
+ /**
26
+ * Rollbar notifier
27
+ *
28
+ * @var RollbarNotifier
29
+ */
30
+ protected $rollbarNotifier;
31
+
32
+ /**
33
+ * @param RollbarNotifier $rollbarNotifier RollbarNotifier object constructed with valid token
34
+ * @param integer $level The minimum logging level at which this handler will be triggered
35
+ * @param boolean $bubble Whether the messages that are handled can bubble up the stack or not
36
+ */
37
+ public function __construct(RollbarNotifier $rollbarNotifier, $level = Logger::ERROR, $bubble = true)
38
+ {
39
+ $this->rollbarNotifier = $rollbarNotifier;
40
+
41
+ parent::__construct($level, $bubble);
42
+ }
43
+
44
+ /**
45
+ * {@inheritdoc}
46
+ */
47
+ protected function write(array $record)
48
+ {
49
+ if (isset($record['context']['exception']) && $record['context']['exception'] instanceof Exception) {
50
+ $this->rollbarNotifier->report_exception($record['context']['exception']);
51
+ } else {
52
+ $extraData = array(
53
+ 'level' => $record['level'],
54
+ 'channel' => $record['channel'],
55
+ 'datetime' => $record['datetime']->format('U'),
56
+ );
57
+
58
+ $this->rollbarNotifier->report_message(
59
+ $record['message'],
60
+ $record['level_name'],
61
+ array_merge($record['context'], $record['extra'], $extraData)
62
+ );
63
+ }
64
+ }
65
+
66
+ /**
67
+ * {@inheritdoc}
68
+ */
69
+ public function close()
70
+ {
71
+ $this->rollbarNotifier->flush();
72
+ }
73
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Stores logs to files that are rotated every day and a limited number of files are kept.
18
+ *
19
+ * This rotation is only intended to be used as a workaround. Using logrotate to
20
+ * handle the rotation is strongly encouraged when you can use it.
21
+ *
22
+ * @author Christophe Coevoet <stof@notk.org>
23
+ * @author Jordi Boggiano <j.boggiano@seld.be>
24
+ */
25
+ class RotatingFileHandler extends StreamHandler
26
+ {
27
+ protected $filename;
28
+ protected $maxFiles;
29
+ protected $mustRotate;
30
+ protected $nextRotation;
31
+ protected $filenameFormat;
32
+ protected $dateFormat;
33
+
34
+ /**
35
+ * @param string $filename
36
+ * @param integer $maxFiles The maximal amount of files to keep (0 means unlimited)
37
+ * @param integer $level The minimum logging level at which this handler will be triggered
38
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
39
+ * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write)
40
+ * @param Boolean $useLocking Try to lock log file before doing any writes
41
+ */
42
+ public function __construct($filename, $maxFiles = 0, $level = Logger::DEBUG, $bubble = true, $filePermission = null, $useLocking = false)
43
+ {
44
+ $this->filename = $filename;
45
+ $this->maxFiles = (int) $maxFiles;
46
+ $this->nextRotation = new \DateTime('tomorrow');
47
+ $this->filenameFormat = '{filename}-{date}';
48
+ $this->dateFormat = 'Y-m-d';
49
+
50
+ parent::__construct($this->getTimedFilename(), $level, $bubble, $filePermission, $useLocking);
51
+ }
52
+
53
+ /**
54
+ * {@inheritdoc}
55
+ */
56
+ public function close()
57
+ {
58
+ parent::close();
59
+
60
+ if (true === $this->mustRotate) {
61
+ $this->rotate();
62
+ }
63
+ }
64
+
65
+ public function setFilenameFormat($filenameFormat, $dateFormat)
66
+ {
67
+ $this->filenameFormat = $filenameFormat;
68
+ $this->dateFormat = $dateFormat;
69
+ $this->url = $this->getTimedFilename();
70
+ $this->close();
71
+ }
72
+
73
+ /**
74
+ * {@inheritdoc}
75
+ */
76
+ protected function write(array $record)
77
+ {
78
+ // on the first record written, if the log is new, we should rotate (once per day)
79
+ if (null === $this->mustRotate) {
80
+ $this->mustRotate = !file_exists($this->url);
81
+ }
82
+
83
+ if ($this->nextRotation < $record['datetime']) {
84
+ $this->mustRotate = true;
85
+ $this->close();
86
+ }
87
+
88
+ parent::write($record);
89
+ }
90
+
91
+ /**
92
+ * Rotates the files.
93
+ */
94
+ protected function rotate()
95
+ {
96
+ // update filename
97
+ $this->url = $this->getTimedFilename();
98
+ $this->nextRotation = new \DateTime('tomorrow');
99
+
100
+ // skip GC of old logs if files are unlimited
101
+ if (0 === $this->maxFiles) {
102
+ return;
103
+ }
104
+
105
+ $logFiles = glob($this->getGlobPattern());
106
+ if ($this->maxFiles >= count($logFiles)) {
107
+ // no files to remove
108
+ return;
109
+ }
110
+
111
+ // Sorting the files by name to remove the older ones
112
+ usort($logFiles, function ($a, $b) {
113
+ return strcmp($b, $a);
114
+ });
115
+
116
+ foreach (array_slice($logFiles, $this->maxFiles) as $file) {
117
+ if (is_writable($file)) {
118
+ unlink($file);
119
+ }
120
+ }
121
+ }
122
+
123
+ protected function getTimedFilename()
124
+ {
125
+ $fileInfo = pathinfo($this->filename);
126
+ $timedFilename = str_replace(
127
+ array('{filename}', '{date}'),
128
+ array($fileInfo['filename'], date($this->dateFormat)),
129
+ $fileInfo['dirname'] . '/' . $this->filenameFormat
130
+ );
131
+
132
+ if (!empty($fileInfo['extension'])) {
133
+ $timedFilename .= '.'.$fileInfo['extension'];
134
+ }
135
+
136
+ return $timedFilename;
137
+ }
138
+
139
+ protected function getGlobPattern()
140
+ {
141
+ $fileInfo = pathinfo($this->filename);
142
+ $glob = str_replace(
143
+ array('{filename}', '{date}'),
144
+ array($fileInfo['filename'], '*'),
145
+ $fileInfo['dirname'] . '/' . $this->filenameFormat
146
+ );
147
+ if (!empty($fileInfo['extension'])) {
148
+ $glob .= '.'.$fileInfo['extension'];
149
+ }
150
+
151
+ return $glob;
152
+ }
153
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/SamplingHandler.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ /**
15
+ * Sampling handler
16
+ *
17
+ * A sampled event stream can be useful for logging high frequency events in
18
+ * a production environment where you only need an idea of what is happening
19
+ * and are not concerned with capturing every occurrence. Since the decision to
20
+ * handle or not handle a particular event is determined randomly, the
21
+ * resulting sampled log is not guaranteed to contain 1/N of the events that
22
+ * occurred in the application, but based on the Law of large numbers, it will
23
+ * tend to be close to this ratio with a large number of attempts.
24
+ *
25
+ * @author Bryan Davis <bd808@wikimedia.org>
26
+ * @author Kunal Mehta <legoktm@gmail.com>
27
+ */
28
+ class SamplingHandler extends AbstractHandler
29
+ {
30
+ /**
31
+ * @var callable|HandlerInterface $handler
32
+ */
33
+ protected $handler;
34
+
35
+ /**
36
+ * @var int $factor
37
+ */
38
+ protected $factor;
39
+
40
+ /**
41
+ * @param callable|HandlerInterface $handler Handler or factory callable($record, $fingersCrossedHandler).
42
+ * @param int $factor Sample factor
43
+ */
44
+ public function __construct($handler, $factor)
45
+ {
46
+ parent::__construct();
47
+ $this->handler = $handler;
48
+ $this->factor = $factor;
49
+
50
+ if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) {
51
+ throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object");
52
+ }
53
+ }
54
+
55
+ public function isHandling(array $record)
56
+ {
57
+ return $this->handler->isHandling($record);
58
+ }
59
+
60
+ public function handle(array $record)
61
+ {
62
+ if ($this->isHandling($record) && mt_rand(1, $this->factor) === 1) {
63
+ // The same logic as in FingersCrossedHandler
64
+ if (!$this->handler instanceof HandlerInterface) {
65
+ $this->handler = call_user_func($this->handler, $record, $this);
66
+ if (!$this->handler instanceof HandlerInterface) {
67
+ throw new \RuntimeException("The factory callable should return a HandlerInterface");
68
+ }
69
+ }
70
+
71
+ if ($this->processors) {
72
+ foreach ($this->processors as $processor) {
73
+ $record = call_user_func($processor, $record);
74
+ }
75
+ }
76
+
77
+ $this->handler->handle($record);
78
+ }
79
+
80
+ return false === $this->bubble;
81
+ }
82
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php ADDED
@@ -0,0 +1,280 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+ use Monolog\Formatter\LineFormatter;
16
+
17
+ /**
18
+ * Sends notifications through Slack API
19
+ *
20
+ * @author Greg Kedzierski <greg@gregkedzierski.com>
21
+ * @see https://api.slack.com/
22
+ */
23
+ class SlackHandler extends SocketHandler
24
+ {
25
+ /**
26
+ * Slack API token
27
+ * @var string
28
+ */
29
+ private $token;
30
+
31
+ /**
32
+ * Slack channel (encoded ID or name)
33
+ * @var string
34
+ */
35
+ private $channel;
36
+
37
+ /**
38
+ * Name of a bot
39
+ * @var string
40
+ */
41
+ private $username;
42
+
43
+ /**
44
+ * Emoji icon name
45
+ * @var string
46
+ */
47
+ private $iconEmoji;
48
+
49
+ /**
50
+ * Whether the message should be added to Slack as attachment (plain text otherwise)
51
+ * @var bool
52
+ */
53
+ private $useAttachment;
54
+
55
+ /**
56
+ * Whether the the context/extra messages added to Slack as attachments are in a short style
57
+ * @var bool
58
+ */
59
+ private $useShortAttachment;
60
+
61
+ /**
62
+ * Whether the attachment should include context and extra data
63
+ * @var bool
64
+ */
65
+ private $includeContextAndExtra;
66
+
67
+ /**
68
+ * @var LineFormatter
69
+ */
70
+ private $lineFormatter;
71
+
72
+ /**
73
+ * @param string $token Slack API token
74
+ * @param string $channel Slack channel (encoded ID or name)
75
+ * @param string $username Name of a bot
76
+ * @param bool $useAttachment Whether the message should be added to Slack as attachment (plain text otherwise)
77
+ * @param string|null $iconEmoji The emoji name to use (or null)
78
+ * @param int $level The minimum logging level at which this handler will be triggered
79
+ * @param bool $bubble Whether the messages that are handled can bubble up the stack or not
80
+ * @param bool $useShortAttachment Whether the the context/extra messages added to Slack as attachments are in a short style
81
+ * @param bool $includeContextAndExtra Whether the attachment should include context and extra data
82
+ */
83
+ public function __construct($token, $channel, $username = 'Monolog', $useAttachment = true, $iconEmoji = null, $level = Logger::CRITICAL, $bubble = true, $useShortAttachment = false, $includeContextAndExtra = false)
84
+ {
85
+ if (!extension_loaded('openssl')) {
86
+ throw new MissingExtensionException('The OpenSSL PHP extension is required to use the SlackHandler');
87
+ }
88
+
89
+ parent::__construct('ssl://slack.com:443', $level, $bubble);
90
+
91
+ $this->token = $token;
92
+ $this->channel = $channel;
93
+ $this->username = $username;
94
+ $this->iconEmoji = trim($iconEmoji, ':');
95
+ $this->useAttachment = $useAttachment;
96
+ $this->useShortAttachment = $useShortAttachment;
97
+ $this->includeContextAndExtra = $includeContextAndExtra;
98
+ if ($this->includeContextAndExtra) {
99
+ $this->lineFormatter = new LineFormatter;
100
+ }
101
+ }
102
+
103
+ /**
104
+ * {@inheritdoc}
105
+ *
106
+ * @param array $record
107
+ * @return string
108
+ */
109
+ protected function generateDataStream($record)
110
+ {
111
+ $content = $this->buildContent($record);
112
+
113
+ return $this->buildHeader($content) . $content;
114
+ }
115
+
116
+ /**
117
+ * Builds the body of API call
118
+ *
119
+ * @param array $record
120
+ * @return string
121
+ */
122
+ private function buildContent($record)
123
+ {
124
+ $dataArray = array(
125
+ 'token' => $this->token,
126
+ 'channel' => $this->channel,
127
+ 'username' => $this->username,
128
+ 'text' => '',
129
+ 'attachments' => array()
130
+ );
131
+
132
+ if ($this->useAttachment) {
133
+ $attachment = array(
134
+ 'fallback' => $record['message'],
135
+ 'color' => $this->getAttachmentColor($record['level'])
136
+ );
137
+
138
+ if ($this->useShortAttachment) {
139
+ $attachment['fields'] = array(
140
+ array(
141
+ 'title' => $record['level_name'],
142
+ 'value' => $record['message'],
143
+ 'short' => false
144
+ )
145
+ );
146
+ } else {
147
+ $attachment['fields'] = array(
148
+ array(
149
+ 'title' => 'Message',
150
+ 'value' => $record['message'],
151
+ 'short' => false
152
+ ),
153
+ array(
154
+ 'title' => 'Level',
155
+ 'value' => $record['level_name'],
156
+ 'short' => true
157
+ )
158
+ );
159
+ }
160
+
161
+ if ($this->includeContextAndExtra) {
162
+ if (!empty($record['extra'])) {
163
+ if ($this->useShortAttachment) {
164
+ $attachment['fields'][] = array(
165
+ 'title' => "Extra",
166
+ 'value' => $this->stringify($record['extra']),
167
+ 'short' => $this->useShortAttachment
168
+ );
169
+ } else {
170
+ // Add all extra fields as individual fields in attachment
171
+ foreach ($record['extra'] as $var => $val) {
172
+ $attachment['fields'][] = array(
173
+ 'title' => $var,
174
+ 'value' => $val,
175
+ 'short' => $this->useShortAttachment
176
+ );
177
+ }
178
+ }
179
+ }
180
+
181
+ if (!empty($record['context'])) {
182
+ if ($this->useShortAttachment) {
183
+ $attachment['fields'][] = array(
184
+ 'title' => "Context",
185
+ 'value' => $this->stringify($record['context']),
186
+ 'short' => $this->useShortAttachment
187
+ );
188
+ } else {
189
+ // Add all context fields as individual fields in attachment
190
+ foreach ($record['context'] as $var => $val) {
191
+ $attachment['fields'][] = array(
192
+ 'title' => $var,
193
+ 'value' => $val,
194
+ 'short' => $this->useShortAttachment
195
+ );
196
+ }
197
+ }
198
+ }
199
+ }
200
+
201
+ $dataArray['attachments'] = json_encode(array($attachment));
202
+ } else {
203
+ $dataArray['text'] = $record['message'];
204
+ }
205
+
206
+ if ($this->iconEmoji) {
207
+ $dataArray['icon_emoji'] = ":{$this->iconEmoji}:";
208
+ }
209
+
210
+ return http_build_query($dataArray);
211
+ }
212
+
213
+ /**
214
+ * Builds the header of the API Call
215
+ *
216
+ * @param string $content
217
+ * @return string
218
+ */
219
+ private function buildHeader($content)
220
+ {
221
+ $header = "POST /api/chat.postMessage HTTP/1.1\r\n";
222
+ $header .= "Host: slack.com\r\n";
223
+ $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
224
+ $header .= "Content-Length: " . strlen($content) . "\r\n";
225
+ $header .= "\r\n";
226
+
227
+ return $header;
228
+ }
229
+
230
+ /**
231
+ * {@inheritdoc}
232
+ *
233
+ * @param array $record
234
+ */
235
+ protected function write(array $record)
236
+ {
237
+ parent::write($record);
238
+ $this->closeSocket();
239
+ }
240
+
241
+ /**
242
+ * Returned a Slack message attachment color associated with
243
+ * provided level.
244
+ *
245
+ * @param int $level
246
+ * @return string
247
+ */
248
+ protected function getAttachmentColor($level)
249
+ {
250
+ switch (true) {
251
+ case $level >= Logger::ERROR:
252
+ return 'danger';
253
+ case $level >= Logger::WARNING:
254
+ return 'warning';
255
+ case $level >= Logger::INFO:
256
+ return 'good';
257
+ default:
258
+ return '#e3e4e6';
259
+ }
260
+ }
261
+
262
+ /**
263
+ * Stringifies an array of key/value pairs to be used in attachment fields
264
+ *
265
+ * @param array $fields
266
+ * @access protected
267
+ * @return string
268
+ */
269
+ protected function stringify($fields)
270
+ {
271
+ $string = '';
272
+ foreach ($fields as $var => $val) {
273
+ $string .= $var.': '.$this->lineFormatter->stringify($val)." | ";
274
+ }
275
+
276
+ $string = rtrim($string, " |");
277
+
278
+ return $string;
279
+ }
280
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Stores to any socket - uses fsockopen() or pfsockopen().
18
+ *
19
+ * @author Pablo de Leon Belloc <pablolb@gmail.com>
20
+ * @see http://php.net/manual/en/function.fsockopen.php
21
+ */
22
+ class SocketHandler extends AbstractProcessingHandler
23
+ {
24
+ private $connectionString;
25
+ private $connectionTimeout;
26
+ private $resource;
27
+ private $timeout = 0;
28
+ private $persistent = false;
29
+ private $errno;
30
+ private $errstr;
31
+
32
+ /**
33
+ * @param string $connectionString Socket connection string
34
+ * @param integer $level The minimum logging level at which this handler will be triggered
35
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
36
+ */
37
+ public function __construct($connectionString, $level = Logger::DEBUG, $bubble = true)
38
+ {
39
+ parent::__construct($level, $bubble);
40
+ $this->connectionString = $connectionString;
41
+ $this->connectionTimeout = (float) ini_get('default_socket_timeout');
42
+ }
43
+
44
+ /**
45
+ * Connect (if necessary) and write to the socket
46
+ *
47
+ * @param array $record
48
+ *
49
+ * @throws \UnexpectedValueException
50
+ * @throws \RuntimeException
51
+ */
52
+ protected function write(array $record)
53
+ {
54
+ $this->connectIfNotConnected();
55
+ $data = $this->generateDataStream($record);
56
+ $this->writeToSocket($data);
57
+ }
58
+
59
+ /**
60
+ * We will not close a PersistentSocket instance so it can be reused in other requests.
61
+ */
62
+ public function close()
63
+ {
64
+ if (!$this->isPersistent()) {
65
+ $this->closeSocket();
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Close socket, if open
71
+ */
72
+ public function closeSocket()
73
+ {
74
+ if (is_resource($this->resource)) {
75
+ fclose($this->resource);
76
+ $this->resource = null;
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Set socket connection to nbe persistent. It only has effect before the connection is initiated.
82
+ *
83
+ * @param type $boolean
84
+ */
85
+ public function setPersistent($boolean)
86
+ {
87
+ $this->persistent = (boolean) $boolean;
88
+ }
89
+
90
+ /**
91
+ * Set connection timeout. Only has effect before we connect.
92
+ *
93
+ * @param float $seconds
94
+ *
95
+ * @see http://php.net/manual/en/function.fsockopen.php
96
+ */
97
+ public function setConnectionTimeout($seconds)
98
+ {
99
+ $this->validateTimeout($seconds);
100
+ $this->connectionTimeout = (float) $seconds;
101
+ }
102
+
103
+ /**
104
+ * Set write timeout. Only has effect before we connect.
105
+ *
106
+ * @param float $seconds
107
+ *
108
+ * @see http://php.net/manual/en/function.stream-set-timeout.php
109
+ */
110
+ public function setTimeout($seconds)
111
+ {
112
+ $this->validateTimeout($seconds);
113
+ $this->timeout = (float) $seconds;
114
+ }
115
+
116
+ /**
117
+ * Get current connection string
118
+ *
119
+ * @return string
120
+ */
121
+ public function getConnectionString()
122
+ {
123
+ return $this->connectionString;
124
+ }
125
+
126
+ /**
127
+ * Get persistent setting
128
+ *
129
+ * @return boolean
130
+ */
131
+ public function isPersistent()
132
+ {
133
+ return $this->persistent;
134
+ }
135
+
136
+ /**
137
+ * Get current connection timeout setting
138
+ *
139
+ * @return float
140
+ */
141
+ public function getConnectionTimeout()
142
+ {
143
+ return $this->connectionTimeout;
144
+ }
145
+
146
+ /**
147
+ * Get current in-transfer timeout
148
+ *
149
+ * @return float
150
+ */
151
+ public function getTimeout()
152
+ {
153
+ return $this->timeout;
154
+ }
155
+
156
+ /**
157
+ * Check to see if the socket is currently available.
158
+ *
159
+ * UDP might appear to be connected but might fail when writing. See http://php.net/fsockopen for details.
160
+ *
161
+ * @return boolean
162
+ */
163
+ public function isConnected()
164
+ {
165
+ return is_resource($this->resource)
166
+ && !feof($this->resource); // on TCP - other party can close connection.
167
+ }
168
+
169
+ /**
170
+ * Wrapper to allow mocking
171
+ */
172
+ protected function pfsockopen()
173
+ {
174
+ return @pfsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout);
175
+ }
176
+
177
+ /**
178
+ * Wrapper to allow mocking
179
+ */
180
+ protected function fsockopen()
181
+ {
182
+ return @fsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout);
183
+ }
184
+
185
+ /**
186
+ * Wrapper to allow mocking
187
+ *
188
+ * @see http://php.net/manual/en/function.stream-set-timeout.php
189
+ */
190
+ protected function streamSetTimeout()
191
+ {
192
+ $seconds = floor($this->timeout);
193
+ $microseconds = round(($this->timeout - $seconds)*1e6);
194
+
195
+ return stream_set_timeout($this->resource, $seconds, $microseconds);
196
+ }
197
+
198
+ /**
199
+ * Wrapper to allow mocking
200
+ */
201
+ protected function fwrite($data)
202
+ {
203
+ return @fwrite($this->resource, $data);
204
+ }
205
+
206
+ /**
207
+ * Wrapper to allow mocking
208
+ */
209
+ protected function streamGetMetadata()
210
+ {
211
+ return stream_get_meta_data($this->resource);
212
+ }
213
+
214
+ private function validateTimeout($value)
215
+ {
216
+ $ok = filter_var($value, FILTER_VALIDATE_FLOAT);
217
+ if ($ok === false || $value < 0) {
218
+ throw new \InvalidArgumentException("Timeout must be 0 or a positive float (got $value)");
219
+ }
220
+ }
221
+
222
+ private function connectIfNotConnected()
223
+ {
224
+ if ($this->isConnected()) {
225
+ return;
226
+ }
227
+ $this->connect();
228
+ }
229
+
230
+ protected function generateDataStream($record)
231
+ {
232
+ return (string) $record['formatted'];
233
+ }
234
+
235
+ private function connect()
236
+ {
237
+ $this->createSocketResource();
238
+ $this->setSocketTimeout();
239
+ }
240
+
241
+ private function createSocketResource()
242
+ {
243
+ if ($this->isPersistent()) {
244
+ $resource = $this->pfsockopen();
245
+ } else {
246
+ $resource = $this->fsockopen();
247
+ }
248
+ if (!$resource) {
249
+ throw new \UnexpectedValueException("Failed connecting to $this->connectionString ($this->errno: $this->errstr)");
250
+ }
251
+ $this->resource = $resource;
252
+ }
253
+
254
+ private function setSocketTimeout()
255
+ {
256
+ if (!$this->streamSetTimeout()) {
257
+ throw new \UnexpectedValueException("Failed setting timeout with stream_set_timeout()");
258
+ }
259
+ }
260
+
261
+ private function writeToSocket($data)
262
+ {
263
+ $length = strlen($data);
264
+ $sent = 0;
265
+ while ($this->isConnected() && $sent < $length) {
266
+ if (0 == $sent) {
267
+ $chunk = $this->fwrite($data);
268
+ } else {
269
+ $chunk = $this->fwrite(substr($data, $sent));
270
+ }
271
+ if ($chunk === false) {
272
+ throw new \RuntimeException("Could not write to socket");
273
+ }
274
+ $sent += $chunk;
275
+ $socketInfo = $this->streamGetMetadata();
276
+ if ($socketInfo['timed_out']) {
277
+ throw new \RuntimeException("Write timed-out");
278
+ }
279
+ }
280
+ if (!$this->isConnected() && $sent < $length) {
281
+ throw new \RuntimeException("End-of-file reached, probably we got disconnected (sent $sent of $length)");
282
+ }
283
+ }
284
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Stores to any stream resource
18
+ *
19
+ * Can be used to store into php://stderr, remote and local files, etc.
20
+ *
21
+ * @author Jordi Boggiano <j.boggiano@seld.be>
22
+ */
23
+ class StreamHandler extends AbstractProcessingHandler
24
+ {
25
+ protected $stream;
26
+ protected $url;
27
+ private $errorMessage;
28
+ protected $filePermission;
29
+ protected $useLocking;
30
+
31
+ /**
32
+ * @param resource|string $stream
33
+ * @param integer $level The minimum logging level at which this handler will be triggered
34
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
35
+ * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write)
36
+ * @param Boolean $useLocking Try to lock log file before doing any writes
37
+ *
38
+ * @throws \InvalidArgumentException If stream is not a resource or string
39
+ */
40
+ public function __construct($stream, $level = Logger::DEBUG, $bubble = true, $filePermission = null, $useLocking = false)
41
+ {
42
+ parent::__construct($level, $bubble);
43
+ if (is_resource($stream)) {
44
+ $this->stream = $stream;
45
+ } elseif (is_string($stream)) {
46
+ $this->url = $stream;
47
+ } else {
48
+ throw new \InvalidArgumentException('A stream must either be a resource or a string.');
49
+ }
50
+
51
+ $this->filePermission = $filePermission;
52
+ $this->useLocking = $useLocking;
53
+ }
54
+
55
+ /**
56
+ * {@inheritdoc}
57
+ */
58
+ public function close()
59
+ {
60
+ if (is_resource($this->stream)) {
61
+ fclose($this->stream);
62
+ }
63
+ $this->stream = null;
64
+ }
65
+
66
+ /**
67
+ * {@inheritdoc}
68
+ */
69
+ protected function write(array $record)
70
+ {
71
+ if (!is_resource($this->stream)) {
72
+ if (!$this->url) {
73
+ throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().');
74
+ }
75
+ $this->errorMessage = null;
76
+ set_error_handler(array($this, 'customErrorHandler'));
77
+ $this->stream = fopen($this->url, 'a');
78
+ if ($this->filePermission !== null) {
79
+ @chmod($this->url, $this->filePermission);
80
+ }
81
+ restore_error_handler();
82
+ if (!is_resource($this->stream)) {
83
+ $this->stream = null;
84
+ throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: '.$this->errorMessage, $this->url));
85
+ }
86
+ }
87
+
88
+ if ($this->useLocking) {
89
+ // ignoring errors here, there's not much we can do about them
90
+ flock($this->stream, LOCK_EX);
91
+ }
92
+
93
+ fwrite($this->stream, (string) $record['formatted']);
94
+
95
+ if ($this->useLocking) {
96
+ flock($this->stream, LOCK_UN);
97
+ }
98
+ }
99
+
100
+ private function customErrorHandler($code, $msg)
101
+ {
102
+ $this->errorMessage = preg_replace('{^fopen\(.*?\): }', '', $msg);
103
+ }
104
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/SwiftMailerHandler.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * SwiftMailerHandler uses Swift_Mailer to send the emails
18
+ *
19
+ * @author Gyula Sallai
20
+ */
21
+ class SwiftMailerHandler extends MailHandler
22
+ {
23
+ protected $mailer;
24
+ private $messageTemplate;
25
+
26
+ /**
27
+ * @param \Swift_Mailer $mailer The mailer to use
28
+ * @param callable|\Swift_Message $message An example message for real messages, only the body will be replaced
29
+ * @param integer $level The minimum logging level at which this handler will be triggered
30
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
31
+ */
32
+ public function __construct(\Swift_Mailer $mailer, $message, $level = Logger::ERROR, $bubble = true)
33
+ {
34
+ parent::__construct($level, $bubble);
35
+
36
+ $this->mailer = $mailer;
37
+ $this->messageTemplate = $message;
38
+ }
39
+
40
+ /**
41
+ * {@inheritdoc}
42
+ */
43
+ protected function send($content, array $records)
44
+ {
45
+ $this->mailer->send($this->buildMessage($content, $records));
46
+ }
47
+
48
+ /**
49
+ * Creates instance of Swift_Message to be sent
50
+ *
51
+ * @param string $content formatted email body to be sent
52
+ * @param array $records Log records that formed the content
53
+ * @return \Swift_Message
54
+ */
55
+ protected function buildMessage($content, array $records)
56
+ {
57
+ $message = null;
58
+ if ($this->messageTemplate instanceof \Swift_Message) {
59
+ $message = clone $this->messageTemplate;
60
+ } else if (is_callable($this->messageTemplate)) {
61
+ $message = call_user_func($this->messageTemplate, $content, $records);
62
+ }
63
+
64
+ if (!$message instanceof \Swift_Message) {
65
+ throw new \InvalidArgumentException('Could not resolve message as instance of Swift_Message or a callable returning it');
66
+ }
67
+
68
+ $message->setBody($content);
69
+ $message->setDate(time());
70
+
71
+ return $message;
72
+ }
73
+
74
+ /**
75
+ * BC getter, to be removed in 2.0
76
+ */
77
+ public function __get($name)
78
+ {
79
+ if ($name === 'message') {
80
+ trigger_error('SwiftMailerHandler->message is deprecated, use ->buildMessage() instead to retrieve the message', E_USER_DEPRECATED);
81
+
82
+ return $this->buildMessage(null, array());
83
+ }
84
+
85
+ throw new \InvalidArgumentException('Invalid property '.$name);
86
+ }
87
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Logs to syslog service.
18
+ *
19
+ * usage example:
20
+ *
21
+ * $log = new Logger('application');
22
+ * $syslog = new SyslogHandler('myfacility', 'local6');
23
+ * $formatter = new LineFormatter("%channel%.%level_name%: %message% %extra%");
24
+ * $syslog->setFormatter($formatter);
25
+ * $log->pushHandler($syslog);
26
+ *
27
+ * @author Sven Paulus <sven@karlsruhe.org>
28
+ */
29
+ class SyslogHandler extends AbstractSyslogHandler
30
+ {
31
+ protected $ident;
32
+ protected $logopts;
33
+
34
+ /**
35
+ * @param string $ident
36
+ * @param mixed $facility
37
+ * @param integer $level The minimum logging level at which this handler will be triggered
38
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
39
+ * @param int $logopts Option flags for the openlog() call, defaults to LOG_PID
40
+ */
41
+ public function __construct($ident, $facility = LOG_USER, $level = Logger::DEBUG, $bubble = true, $logopts = LOG_PID)
42
+ {
43
+ parent::__construct($facility, $level, $bubble);
44
+
45
+ $this->ident = $ident;
46
+ $this->logopts = $logopts;
47
+ }
48
+
49
+ /**
50
+ * {@inheritdoc}
51
+ */
52
+ public function close()
53
+ {
54
+ closelog();
55
+ }
56
+
57
+ /**
58
+ * {@inheritdoc}
59
+ */
60
+ protected function write(array $record)
61
+ {
62
+ if (!openlog($this->ident, $this->logopts, $this->facility)) {
63
+ throw new \LogicException('Can\'t open syslog for ident "'.$this->ident.'" and facility "'.$this->facility.'"');
64
+ }
65
+ syslog($this->logLevels[$record['level']], (string) $record['formatted']);
66
+ }
67
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdp/UdpSocket.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler\SyslogUdp;
13
+
14
+ class UdpSocket
15
+ {
16
+ const DATAGRAM_MAX_LENGTH = 65023;
17
+
18
+ public function __construct($ip, $port = 514)
19
+ {
20
+ $this->ip = $ip;
21
+ $this->port = $port;
22
+ $this->socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
23
+ }
24
+
25
+ public function write($line, $header = "")
26
+ {
27
+ $this->send($this->assembleMessage($line, $header));
28
+ }
29
+
30
+ public function close()
31
+ {
32
+ socket_close($this->socket);
33
+ }
34
+
35
+ protected function send($chunk)
36
+ {
37
+ socket_sendto($this->socket, $chunk, strlen($chunk), $flags = 0, $this->ip, $this->port);
38
+ }
39
+
40
+ protected function assembleMessage($line, $header)
41
+ {
42
+ $chunkSize = self::DATAGRAM_MAX_LENGTH - strlen($header);
43
+
44
+ return $header . substr($line, 0, $chunkSize);
45
+ }
46
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+ use Monolog\Handler\SyslogUdp\UdpSocket;
16
+
17
+ /**
18
+ * A Handler for logging to a remote syslogd server.
19
+ *
20
+ * @author Jesper Skovgaard Nielsen <nulpunkt@gmail.com>
21
+ */
22
+ class SyslogUdpHandler extends AbstractSyslogHandler
23
+ {
24
+ /**
25
+ * @param string $host
26
+ * @param int $port
27
+ * @param mixed $facility
28
+ * @param integer $level The minimum logging level at which this handler will be triggered
29
+ * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
30
+ */
31
+ public function __construct($host, $port = 514, $facility = LOG_USER, $level = Logger::DEBUG, $bubble = true)
32
+ {
33
+ parent::__construct($facility, $level, $bubble);
34
+
35
+ $this->socket = new UdpSocket($host, $port ?: 514);
36
+ }
37
+
38
+ protected function write(array $record)
39
+ {
40
+ $lines = $this->splitMessageIntoLines($record['formatted']);
41
+
42
+ $header = $this->makeCommonSyslogHeader($this->logLevels[$record['level']]);
43
+
44
+ foreach ($lines as $line) {
45
+ $this->socket->write($line, $header);
46
+ }
47
+ }
48
+
49
+ public function close()
50
+ {
51
+ $this->socket->close();
52
+ }
53
+
54
+ private function splitMessageIntoLines($message)
55
+ {
56
+ if (is_array($message)) {
57
+ $message = implode("\n", $message);
58
+ }
59
+
60
+ return preg_split('/$\R?^/m', $message);
61
+ }
62
+
63
+ /**
64
+ * Make common syslog header (see rfc5424)
65
+ */
66
+ protected function makeCommonSyslogHeader($severity)
67
+ {
68
+ $priority = $severity + $this->facility;
69
+
70
+ return "<$priority>1 ";
71
+ }
72
+
73
+ /**
74
+ * Inject your own socket, mainly used for testing
75
+ */
76
+ public function setSocket($socket)
77
+ {
78
+ $this->socket = $socket;
79
+ }
80
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Used for testing purposes.
18
+ *
19
+ * It records all records and gives you access to them for verification.
20
+ *
21
+ * @author Jordi Boggiano <j.boggiano@seld.be>
22
+ */
23
+ class TestHandler extends AbstractProcessingHandler
24
+ {
25
+ protected $records = array();
26
+ protected $recordsByLevel = array();
27
+
28
+ public function getRecords()
29
+ {
30
+ return $this->records;
31
+ }
32
+
33
+ public function hasEmergency($record)
34
+ {
35
+ return $this->hasRecord($record, Logger::EMERGENCY);
36
+ }
37
+
38
+ public function hasAlert($record)
39
+ {
40
+ return $this->hasRecord($record, Logger::ALERT);
41
+ }
42
+
43
+ public function hasCritical($record)
44
+ {
45
+ return $this->hasRecord($record, Logger::CRITICAL);
46
+ }
47
+
48
+ public function hasError($record)
49
+ {
50
+ return $this->hasRecord($record, Logger::ERROR);
51
+ }
52
+
53
+ public function hasWarning($record)
54
+ {
55
+ return $this->hasRecord($record, Logger::WARNING);
56
+ }
57
+
58
+ public function hasNotice($record)
59
+ {
60
+ return $this->hasRecord($record, Logger::NOTICE);
61
+ }
62
+
63
+ public function hasInfo($record)
64
+ {
65
+ return $this->hasRecord($record, Logger::INFO);
66
+ }
67
+
68
+ public function hasDebug($record)
69
+ {
70
+ return $this->hasRecord($record, Logger::DEBUG);
71
+ }
72
+
73
+ public function hasEmergencyRecords()
74
+ {
75
+ return isset($this->recordsByLevel[Logger::EMERGENCY]);
76
+ }
77
+
78
+ public function hasAlertRecords()
79
+ {
80
+ return isset($this->recordsByLevel[Logger::ALERT]);
81
+ }
82
+
83
+ public function hasCriticalRecords()
84
+ {
85
+ return isset($this->recordsByLevel[Logger::CRITICAL]);
86
+ }
87
+
88
+ public function hasErrorRecords()
89
+ {
90
+ return isset($this->recordsByLevel[Logger::ERROR]);
91
+ }
92
+
93
+ public function hasWarningRecords()
94
+ {
95
+ return isset($this->recordsByLevel[Logger::WARNING]);
96
+ }
97
+
98
+ public function hasNoticeRecords()
99
+ {
100
+ return isset($this->recordsByLevel[Logger::NOTICE]);
101
+ }
102
+
103
+ public function hasInfoRecords()
104
+ {
105
+ return isset($this->recordsByLevel[Logger::INFO]);
106
+ }
107
+
108
+ public function hasDebugRecords()
109
+ {
110
+ return isset($this->recordsByLevel[Logger::DEBUG]);
111
+ }
112
+
113
+ protected function hasRecord($record, $level)
114
+ {
115
+ if (!isset($this->recordsByLevel[$level])) {
116
+ return false;
117
+ }
118
+
119
+ if (is_array($record)) {
120
+ $record = $record['message'];
121
+ }
122
+
123
+ foreach ($this->recordsByLevel[$level] as $rec) {
124
+ if ($rec['message'] === $record) {
125
+ return true;
126
+ }
127
+ }
128
+
129
+ return false;
130
+ }
131
+
132
+ /**
133
+ * {@inheritdoc}
134
+ */
135
+ protected function write(array $record)
136
+ {
137
+ $this->recordsByLevel[$record['level']][] = $record;
138
+ $this->records[] = $record;
139
+ }
140
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ /**
15
+ * Forwards records to multiple handlers suppressing failures of each handler
16
+ * and continuing through to give every handler a chance to succeed.
17
+ *
18
+ * @author Craig D'Amelio <craig@damelio.ca>
19
+ */
20
+ class WhatFailureGroupHandler extends GroupHandler
21
+ {
22
+ /**
23
+ * {@inheritdoc}
24
+ */
25
+ public function handle(array $record)
26
+ {
27
+ if ($this->processors) {
28
+ foreach ($this->processors as $processor) {
29
+ $record = call_user_func($processor, $record);
30
+ }
31
+ }
32
+
33
+ foreach ($this->handlers as $handler) {
34
+ try {
35
+ $handler->handle($record);
36
+ } catch (\Exception $e) {
37
+ // What failure?
38
+ }
39
+ }
40
+
41
+ return false === $this->bubble;
42
+ }
43
+
44
+ /**
45
+ * {@inheritdoc}
46
+ */
47
+ public function handleBatch(array $records)
48
+ {
49
+ foreach ($this->handlers as $handler) {
50
+ try {
51
+ $handler->handleBatch($records);
52
+ } catch (\Exception $e) {
53
+ // What failure?
54
+ }
55
+ }
56
+ }
57
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * This file is part of the Monolog package.
4
+ *
5
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
6
+ *
7
+ * For the full copyright and license information, please view the LICENSE
8
+ * file that was distributed with this source code.
9
+ */
10
+
11
+ namespace Monolog\Handler;
12
+
13
+ use Monolog\Formatter\NormalizerFormatter;
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Handler sending logs to Zend Monitor
18
+ *
19
+ * @author Christian Bergau <cbergau86@gmail.com>
20
+ */
21
+ class ZendMonitorHandler extends AbstractProcessingHandler
22
+ {
23
+ /**
24
+ * Monolog level / ZendMonitor Custom Event priority map
25
+ *
26
+ * @var array
27
+ */
28
+ protected $levelMap = array(
29
+ Logger::DEBUG => 1,
30
+ Logger::INFO => 2,
31
+ Logger::NOTICE => 3,
32
+ Logger::WARNING => 4,
33
+ Logger::ERROR => 5,
34
+ Logger::CRITICAL => 6,
35
+ Logger::ALERT => 7,
36
+ Logger::EMERGENCY => 0,
37
+ );
38
+
39
+ /**
40
+ * Construct
41
+ *
42
+ * @param int $level
43
+ * @param bool $bubble
44
+ * @throws MissingExtensionException
45
+ */
46
+ public function __construct($level = Logger::DEBUG, $bubble = true)
47
+ {
48
+ if (!function_exists('zend_monitor_custom_event')) {
49
+ throw new MissingExtensionException('You must have Zend Server installed in order to use this handler');
50
+ }
51
+ parent::__construct($level, $bubble);
52
+ }
53
+
54
+ /**
55
+ * {@inheritdoc}
56
+ */
57
+ protected function write(array $record)
58
+ {
59
+ $this->writeZendMonitorCustomEvent(
60
+ $this->levelMap[$record['level']],
61
+ $record['message'],
62
+ $record['formatted']
63
+ );
64
+ }
65
+
66
+ /**
67
+ * Write a record to Zend Monitor
68
+ *
69
+ * @param int $level
70
+ * @param string $message
71
+ * @param array $formatted
72
+ */
73
+ protected function writeZendMonitorCustomEvent($level, $message, $formatted)
74
+ {
75
+ zend_monitor_custom_event($level, $message, $formatted);
76
+ }
77
+
78
+ /**
79
+ * {@inheritdoc}
80
+ */
81
+ public function getDefaultFormatter()
82
+ {
83
+ return new NormalizerFormatter();
84
+ }
85
+
86
+ /**
87
+ * Get the level map
88
+ *
89
+ * @return array
90
+ */
91
+ public function getLevelMap()
92
+ {
93
+ return $this->levelMap;
94
+ }
95
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Logger.php ADDED
@@ -0,0 +1,615 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog;
13
+
14
+ use Monolog\Handler\HandlerInterface;
15
+ use Monolog\Handler\StreamHandler;
16
+ use Psr\Log\LoggerInterface;
17
+ use Psr\Log\InvalidArgumentException;
18
+
19
+ /**
20
+ * Monolog log channel
21
+ *
22
+ * It contains a stack of Handlers and a stack of Processors,
23
+ * and uses them to store records that are added to it.
24
+ *
25
+ * @author Jordi Boggiano <j.boggiano@seld.be>
26
+ */
27
+ class Logger implements LoggerInterface
28
+ {
29
+ /**
30
+ * Detailed debug information
31
+ */
32
+ const DEBUG = 100;
33
+
34
+ /**
35
+ * Interesting events
36
+ *
37
+ * Examples: User logs in, SQL logs.
38
+ */
39
+ const INFO = 200;
40
+
41
+ /**
42
+ * Uncommon events
43
+ */
44
+ const NOTICE = 250;
45
+
46
+ /**
47
+ * Exceptional occurrences that are not errors
48
+ *
49
+ * Examples: Use of deprecated APIs, poor use of an API,
50
+ * undesirable things that are not necessarily wrong.
51
+ */
52
+ const WARNING = 300;
53
+
54
+ /**
55
+ * Runtime errors
56
+ */
57
+ const ERROR = 400;
58
+
59
+ /**
60
+ * Critical conditions
61
+ *
62
+ * Example: Application component unavailable, unexpected exception.
63
+ */
64
+ const CRITICAL = 500;
65
+
66
+ /**
67
+ * Action must be taken immediately
68
+ *
69
+ * Example: Entire website down, database unavailable, etc.
70
+ * This should trigger the SMS alerts and wake you up.
71
+ */
72
+ const ALERT = 550;
73
+
74
+ /**
75
+ * Urgent alert.
76
+ */
77
+ const EMERGENCY = 600;
78
+
79
+ /**
80
+ * Monolog API version
81
+ *
82
+ * This is only bumped when API breaks are done and should
83
+ * follow the major version of the library
84
+ *
85
+ * @var int
86
+ */
87
+ const API = 1;
88
+
89
+ /**
90
+ * Logging levels from syslog protocol defined in RFC 5424
91
+ *
92
+ * @var array $levels Logging levels
93
+ */
94
+ protected static $levels = array(
95
+ 100 => 'DEBUG',
96
+ 200 => 'INFO',
97
+ 250 => 'NOTICE',
98
+ 300 => 'WARNING',
99
+ 400 => 'ERROR',
100
+ 500 => 'CRITICAL',
101
+ 550 => 'ALERT',
102
+ 600 => 'EMERGENCY',
103
+ );
104
+
105
+ /**
106
+ * @var \DateTimeZone
107
+ */
108
+ protected static $timezone;
109
+
110
+ /**
111
+ * @var string
112
+ */
113
+ protected $name;
114
+
115
+ /**
116
+ * The handler stack
117
+ *
118
+ * @var HandlerInterface[]
119
+ */
120
+ protected $handlers;
121
+
122
+ /**
123
+ * Processors that will process all log records
124
+ *
125
+ * To process records of a single handler instead, add the processor on that specific handler
126
+ *
127
+ * @var callable[]
128
+ */
129
+ protected $processors;
130
+
131
+ /**
132
+ * @param string $name The logging channel
133
+ * @param HandlerInterface[] $handlers Optional stack of handlers, the first one in the array is called first, etc.
134
+ * @param callable[] $processors Optional array of processors
135
+ */
136
+ public function __construct($name, array $handlers = array(), array $processors = array())
137
+ {
138
+ $this->name = $name;
139
+ $this->handlers = $handlers;
140
+ $this->processors = $processors;
141
+ }
142
+
143
+ /**
144
+ * @return string
145
+ */
146
+ public function getName()
147
+ {
148
+ return $this->name;
149
+ }
150
+
151
+ /**
152
+ * Pushes a handler on to the stack.
153
+ *
154
+ * @param HandlerInterface $handler
155
+ */
156
+ public function pushHandler(HandlerInterface $handler)
157
+ {
158
+ array_unshift($this->handlers, $handler);
159
+ }
160
+
161
+ /**
162
+ * Pops a handler from the stack
163
+ *
164
+ * @return HandlerInterface
165
+ */
166
+ public function popHandler()
167
+ {
168
+ if (!$this->handlers) {
169
+ throw new \LogicException('You tried to pop from an empty handler stack.');
170
+ }
171
+
172
+ return array_shift($this->handlers);
173
+ }
174
+
175
+ /**
176
+ * @return HandlerInterface[]
177
+ */
178
+ public function getHandlers()
179
+ {
180
+ return $this->handlers;
181
+ }
182
+
183
+ /**
184
+ * Adds a processor on to the stack.
185
+ *
186
+ * @param callable $callback
187
+ */
188
+ public function pushProcessor($callback)
189
+ {
190
+ if (!is_callable($callback)) {
191
+ throw new \InvalidArgumentException('Processors must be valid callables (callback or object with an __invoke method), '.var_export($callback, true).' given');
192
+ }
193
+ array_unshift($this->processors, $callback);
194
+ }
195
+
196
+ /**
197
+ * Removes the processor on top of the stack and returns it.
198
+ *
199
+ * @return callable
200
+ */
201
+ public function popProcessor()
202
+ {
203
+ if (!$this->processors) {
204
+ throw new \LogicException('You tried to pop from an empty processor stack.');
205
+ }
206
+
207
+ return array_shift($this->processors);
208
+ }
209
+
210
+ /**
211
+ * @return callable[]
212
+ */
213
+ public function getProcessors()
214
+ {
215
+ return $this->processors;
216
+ }
217
+
218
+ /**
219
+ * Adds a log record.
220
+ *
221
+ * @param integer $level The logging level
222
+ * @param string $message The log message
223
+ * @param array $context The log context
224
+ * @return Boolean Whether the record has been processed
225
+ */
226
+ public function addRecord($level, $message, array $context = array())
227
+ {
228
+ if (!$this->handlers) {
229
+ $this->pushHandler(new StreamHandler('php://stderr', static::DEBUG));
230
+ }
231
+
232
+ $levelName = static::getLevelName($level);
233
+
234
+ // check if any handler will handle this message so we can return early and save cycles
235
+ $handlerKey = null;
236
+ foreach ($this->handlers as $key => $handler) {
237
+ if ($handler->isHandling(array('level' => $level))) {
238
+ $handlerKey = $key;
239
+ break;
240
+ }
241
+ }
242
+
243
+ if (null === $handlerKey) {
244
+ return false;
245
+ }
246
+
247
+ if (!static::$timezone) {
248
+ static::$timezone = new \DateTimeZone(date_default_timezone_get() ?: 'UTC');
249
+ }
250
+
251
+ $record = array(
252
+ 'message' => (string) $message,
253
+ 'context' => $context,
254
+ 'level' => $level,
255
+ 'level_name' => $levelName,
256
+ 'channel' => $this->name,
257
+ 'datetime' => \DateTime::createFromFormat('U.u', sprintf('%.6F', microtime(true)), static::$timezone)->setTimezone(static::$timezone),
258
+ 'extra' => array(),
259
+ );
260
+
261
+ foreach ($this->processors as $processor) {
262
+ $record = call_user_func($processor, $record);
263
+ }
264
+ while (isset($this->handlers[$handlerKey]) &&
265
+ false === $this->handlers[$handlerKey]->handle($record)) {
266
+ $handlerKey++;
267
+ }
268
+
269
+ return true;
270
+ }
271
+
272
+ /**
273
+ * Adds a log record at the DEBUG level.
274
+ *
275
+ * @param string $message The log message
276
+ * @param array $context The log context
277
+ * @return Boolean Whether the record has been processed
278
+ */
279
+ public function addDebug($message, array $context = array())
280
+ {
281
+ return $this->addRecord(static::DEBUG, $message, $context);
282
+ }
283
+
284
+ /**
285
+ * Adds a log record at the INFO level.
286
+ *
287
+ * @param string $message The log message
288
+ * @param array $context The log context
289
+ * @return Boolean Whether the record has been processed
290
+ */
291
+ public function addInfo($message, array $context = array())
292
+ {
293
+ return $this->addRecord(static::INFO, $message, $context);
294
+ }
295
+
296
+ /**
297
+ * Adds a log record at the NOTICE level.
298
+ *
299
+ * @param string $message The log message
300
+ * @param array $context The log context
301
+ * @return Boolean Whether the record has been processed
302
+ */
303
+ public function addNotice($message, array $context = array())
304
+ {
305
+ return $this->addRecord(static::NOTICE, $message, $context);
306
+ }
307
+
308
+ /**
309
+ * Adds a log record at the WARNING level.
310
+ *
311
+ * @param string $message The log message
312
+ * @param array $context The log context
313
+ * @return Boolean Whether the record has been processed
314
+ */
315
+ public function addWarning($message, array $context = array())
316
+ {
317
+ return $this->addRecord(static::WARNING, $message, $context);
318
+ }
319
+
320
+ /**
321
+ * Adds a log record at the ERROR level.
322
+ *
323
+ * @param string $message The log message
324
+ * @param array $context The log context
325
+ * @return Boolean Whether the record has been processed
326
+ */
327
+ public function addError($message, array $context = array())
328
+ {
329
+ return $this->addRecord(static::ERROR, $message, $context);
330
+ }
331
+
332
+ /**
333
+ * Adds a log record at the CRITICAL level.
334
+ *
335
+ * @param string $message The log message
336
+ * @param array $context The log context
337
+ * @return Boolean Whether the record has been processed
338
+ */
339
+ public function addCritical($message, array $context = array())
340
+ {
341
+ return $this->addRecord(static::CRITICAL, $message, $context);
342
+ }
343
+
344
+ /**
345
+ * Adds a log record at the ALERT level.
346
+ *
347
+ * @param string $message The log message
348
+ * @param array $context The log context
349
+ * @return Boolean Whether the record has been processed
350
+ */
351
+ public function addAlert($message, array $context = array())
352
+ {
353
+ return $this->addRecord(static::ALERT, $message, $context);
354
+ }
355
+
356
+ /**
357
+ * Adds a log record at the EMERGENCY level.
358
+ *
359
+ * @param string $message The log message
360
+ * @param array $context The log context
361
+ * @return Boolean Whether the record has been processed
362
+ */
363
+ public function addEmergency($message, array $context = array())
364
+ {
365
+ return $this->addRecord(static::EMERGENCY, $message, $context);
366
+ }
367
+
368
+ /**
369
+ * Gets all supported logging levels.
370
+ *
371
+ * @return array Assoc array with human-readable level names => level codes.
372
+ */
373
+ public static function getLevels()
374
+ {
375
+ return array_flip(static::$levels);
376
+ }
377
+
378
+ /**
379
+ * Gets the name of the logging level.
380
+ *
381
+ * @param integer $level
382
+ * @return string
383
+ */
384
+ public static function getLevelName($level)
385
+ {
386
+ if (!isset(static::$levels[$level])) {
387
+ throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels)));
388
+ }
389
+
390
+ return static::$levels[$level];
391
+ }
392
+
393
+ /**
394
+ * Converts PSR-3 levels to Monolog ones if necessary
395
+ *
396
+ * @param string|int Level number (monolog) or name (PSR-3)
397
+ * @return int
398
+ */
399
+ public static function toMonologLevel($level)
400
+ {
401
+ if (is_string($level) && defined(__CLASS__.'::'.strtoupper($level))) {
402
+ return constant(__CLASS__.'::'.strtoupper($level));
403
+ }
404
+
405
+ return $level;
406
+ }
407
+
408
+ /**
409
+ * Checks whether the Logger has a handler that listens on the given level
410
+ *
411
+ * @param integer $level
412
+ * @return Boolean
413
+ */
414
+ public function isHandling($level)
415
+ {
416
+ $record = array(
417
+ 'level' => $level,
418
+ );
419
+
420
+ foreach ($this->handlers as $handler) {
421
+ if ($handler->isHandling($record)) {
422
+ return true;
423
+ }
424
+ }
425
+
426
+ return false;
427
+ }
428
+
429
+ /**
430
+ * Adds a log record at an arbitrary level.
431
+ *
432
+ * This method allows for compatibility with common interfaces.
433
+ *
434
+ * @param mixed $level The log level
435
+ * @param string $message The log message
436
+ * @param array $context The log context
437
+ * @return Boolean Whether the record has been processed
438
+ */
439
+ public function log($level, $message, array $context = array())
440
+ {
441
+ if (is_string($level) && defined(__CLASS__.'::'.strtoupper($level))) {
442
+ $level = constant(__CLASS__.'::'.strtoupper($level));
443
+ }
444
+
445
+ return $this->addRecord($level, $message, $context);
446
+ }
447
+
448
+ /**
449
+ * Adds a log record at the DEBUG level.
450
+ *
451
+ * This method allows for compatibility with common interfaces.
452
+ *
453
+ * @param string $message The log message
454
+ * @param array $context The log context
455
+ * @return Boolean Whether the record has been processed
456
+ */
457
+ public function debug($message, array $context = array())
458
+ {
459
+ return $this->addRecord(static::DEBUG, $message, $context);
460
+ }
461
+
462
+ /**
463
+ * Adds a log record at the INFO level.
464
+ *
465
+ * This method allows for compatibility with common interfaces.
466
+ *
467
+ * @param string $message The log message
468
+ * @param array $context The log context
469
+ * @return Boolean Whether the record has been processed
470
+ */
471
+ public function info($message, array $context = array())
472
+ {
473
+ return $this->addRecord(static::INFO, $message, $context);
474
+ }
475
+
476
+ /**
477
+ * Adds a log record at the NOTICE level.
478
+ *
479
+ * This method allows for compatibility with common interfaces.
480
+ *
481
+ * @param string $message The log message
482
+ * @param array $context The log context
483
+ * @return Boolean Whether the record has been processed
484
+ */
485
+ public function notice($message, array $context = array())
486
+ {
487
+ return $this->addRecord(static::NOTICE, $message, $context);
488
+ }
489
+
490
+ /**
491
+ * Adds a log record at the WARNING level.
492
+ *
493
+ * This method allows for compatibility with common interfaces.
494
+ *
495
+ * @param string $message The log message
496
+ * @param array $context The log context
497
+ * @return Boolean Whether the record has been processed
498
+ */
499
+ public function warn($message, array $context = array())
500
+ {
501
+ return $this->addRecord(static::WARNING, $message, $context);
502
+ }
503
+
504
+ /**
505
+ * Adds a log record at the WARNING level.
506
+ *
507
+ * This method allows for compatibility with common interfaces.
508
+ *
509
+ * @param string $message The log message
510
+ * @param array $context The log context
511
+ * @return Boolean Whether the record has been processed
512
+ */
513
+ public function warning($message, array $context = array())
514
+ {
515
+ return $this->addRecord(static::WARNING, $message, $context);
516
+ }
517
+
518
+ /**
519
+ * Adds a log record at the ERROR level.
520
+ *
521
+ * This method allows for compatibility with common interfaces.
522
+ *
523
+ * @param string $message The log message
524
+ * @param array $context The log context
525
+ * @return Boolean Whether the record has been processed
526
+ */
527
+ public function err($message, array $context = array())
528
+ {
529
+ return $this->addRecord(static::ERROR, $message, $context);
530
+ }
531
+
532
+ /**
533
+ * Adds a log record at the ERROR level.
534
+ *
535
+ * This method allows for compatibility with common interfaces.
536
+ *
537
+ * @param string $message The log message
538
+ * @param array $context The log context
539
+ * @return Boolean Whether the record has been processed
540
+ */
541
+ public function error($message, array $context = array())
542
+ {
543
+ return $this->addRecord(static::ERROR, $message, $context);
544
+ }
545
+
546
+ /**
547
+ * Adds a log record at the CRITICAL level.
548
+ *
549
+ * This method allows for compatibility with common interfaces.
550
+ *
551
+ * @param string $message The log message
552
+ * @param array $context The log context
553
+ * @return Boolean Whether the record has been processed
554
+ */
555
+ public function crit($message, array $context = array())
556
+ {
557
+ return $this->addRecord(static::CRITICAL, $message, $context);
558
+ }
559
+
560
+ /**
561
+ * Adds a log record at the CRITICAL level.
562
+ *
563
+ * This method allows for compatibility with common interfaces.
564
+ *
565
+ * @param string $message The log message
566
+ * @param array $context The log context
567
+ * @return Boolean Whether the record has been processed
568
+ */
569
+ public function critical($message, array $context = array())
570
+ {
571
+ return $this->addRecord(static::CRITICAL, $message, $context);
572
+ }
573
+
574
+ /**
575
+ * Adds a log record at the ALERT level.
576
+ *
577
+ * This method allows for compatibility with common interfaces.
578
+ *
579
+ * @param string $message The log message
580
+ * @param array $context The log context
581
+ * @return Boolean Whether the record has been processed
582
+ */
583
+ public function alert($message, array $context = array())
584
+ {
585
+ return $this->addRecord(static::ALERT, $message, $context);
586
+ }
587
+
588
+ /**
589
+ * Adds a log record at the EMERGENCY level.
590
+ *
591
+ * This method allows for compatibility with common interfaces.
592
+ *
593
+ * @param string $message The log message
594
+ * @param array $context The log context
595
+ * @return Boolean Whether the record has been processed
596
+ */
597
+ public function emerg($message, array $context = array())
598
+ {
599
+ return $this->addRecord(static::EMERGENCY, $message, $context);
600
+ }
601
+
602
+ /**
603
+ * Adds a log record at the EMERGENCY level.
604
+ *
605
+ * This method allows for compatibility with common interfaces.
606
+ *
607
+ * @param string $message The log message
608
+ * @param array $context The log context
609
+ * @return Boolean Whether the record has been processed
610
+ */
611
+ public function emergency($message, array $context = array())
612
+ {
613
+ return $this->addRecord(static::EMERGENCY, $message, $context);
614
+ }
615
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/GitProcessor.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Processor;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Injects Git branch and Git commit SHA in all records
18
+ *
19
+ * @author Nick Otter
20
+ * @author Jordi Boggiano <j.boggiano@seld.be>
21
+ */
22
+ class GitProcessor
23
+ {
24
+ private $level;
25
+ private static $cache;
26
+
27
+ public function __construct($level = Logger::DEBUG)
28
+ {
29
+ $this->level = Logger::toMonologLevel($level);
30
+ }
31
+
32
+ /**
33
+ * @param array $record
34
+ * @return array
35
+ */
36
+ public function __invoke(array $record)
37
+ {
38
+ // return if the level is not high enough
39
+ if ($record['level'] < $this->level) {
40
+ return $record;
41
+ }
42
+
43
+ $record['extra']['git'] = self::getGitInfo();
44
+
45
+ return $record;
46
+ }
47
+
48
+ private static function getGitInfo()
49
+ {
50
+ if (self::$cache) {
51
+ return self::$cache;
52
+ }
53
+
54
+ $branches = `git branch -v --no-abbrev`;
55
+ if (preg_match('{^\* (.+?)\s+([a-f0-9]{40})(?:\s|$)}m', $branches, $matches)) {
56
+ return self::$cache = array(
57
+ 'branch' => $matches[1],
58
+ 'commit' => $matches[2],
59
+ );
60
+ }
61
+
62
+ return self::$cache = array();
63
+ }
64
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Processor;
13
+
14
+ use Monolog\Logger;
15
+
16
+ /**
17
+ * Injects line/file:class/function where the log message came from
18
+ *
19
+ * Warning: This only works if the handler processes the logs directly.
20
+ * If you put the processor on a handler that is behind a FingersCrossedHandler
21
+ * for example, the processor will only be called once the trigger level is reached,
22
+ * and all the log records will have the same file/line/.. data from the call that
23
+ * triggered the FingersCrossedHandler.
24
+ *
25
+ * @author Jordi Boggiano <j.boggiano@seld.be>
26
+ */
27
+ class IntrospectionProcessor
28
+ {
29
+ private $level;
30
+
31
+ private $skipClassesPartials;
32
+
33
+ public function __construct($level = Logger::DEBUG, array $skipClassesPartials = array('Monolog\\'))
34
+ {
35
+ $this->level = Logger::toMonologLevel($level);
36
+ $this->skipClassesPartials = $skipClassesPartials;
37
+ }
38
+
39
+ /**
40
+ * @param array $record
41
+ * @return array
42
+ */
43
+ public function __invoke(array $record)
44
+ {
45
+ // return if the level is not high enough
46
+ if ($record['level'] < $this->level) {
47
+ return $record;
48
+ }
49
+
50
+ $trace = debug_backtrace();
51
+
52
+ // skip first since it's always the current method
53
+ array_shift($trace);
54
+ // the call_user_func call is also skipped
55
+ array_shift($trace);
56
+
57
+ $i = 0;
58
+
59
+ while (isset($trace[$i]['class'])) {
60
+ foreach ($this->skipClassesPartials as $part) {
61
+ if (strpos($trace[$i]['class'], $part) !== false) {
62
+ $i++;
63
+ continue 2;
64
+ }
65
+ }
66
+ break;
67
+ }
68
+
69
+ // we should have the call source now
70
+ $record['extra'] = array_merge(
71
+ $record['extra'],
72
+ array(
73
+ 'file' => isset($trace[$i-1]['file']) ? $trace[$i-1]['file'] : null,
74
+ 'line' => isset($trace[$i-1]['line']) ? $trace[$i-1]['line'] : null,
75
+ 'class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : null,
76
+ 'function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : null,
77
+ )
78
+ );
79
+
80
+ return $record;
81
+ }
82
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Processor;
13
+
14
+ /**
15
+ * Injects memory_get_peak_usage in all records
16
+ *
17
+ * @see Monolog\Processor\MemoryProcessor::__construct() for options
18
+ * @author Rob Jensen
19
+ */
20
+ class MemoryPeakUsageProcessor extends MemoryProcessor
21
+ {
22
+ /**
23
+ * @param array $record
24
+ * @return array
25
+ */
26
+ public function __invoke(array $record)
27
+ {
28
+ $bytes = memory_get_peak_usage($this->realUsage);
29
+ $formatted = $this->formatBytes($bytes);
30
+
31
+ $record['extra'] = array_merge(
32
+ $record['extra'],
33
+ array(
34
+ 'memory_peak_usage' => $formatted,
35
+ )
36
+ );
37
+
38
+ return $record;
39
+ }
40
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Processor;
13
+
14
+ /**
15
+ * Some methods that are common for all memory processors
16
+ *
17
+ * @author Rob Jensen
18
+ */
19
+ abstract class MemoryProcessor
20
+ {
21
+ /**
22
+ * @var boolean If true, get the real size of memory allocated from system. Else, only the memory used by emalloc() is reported.
23
+ */
24
+ protected $realUsage;
25
+
26
+ /**
27
+ * @var boolean If true, then format memory size to human readable string (MB, KB, B depending on size)
28
+ */
29
+ protected $useFormatting;
30
+
31
+ /**
32
+ * @param boolean $realUsage Set this to true to get the real size of memory allocated from system.
33
+ * @param boolean $useFormatting If true, then format memory size to human readable string (MB, KB, B depending on size)
34
+ */
35
+ public function __construct($realUsage = true, $useFormatting = true)
36
+ {
37
+ $this->realUsage = (boolean) $realUsage;
38
+ $this->useFormatting = (boolean) $useFormatting;
39
+ }
40
+
41
+ /**
42
+ * Formats bytes into a human readable string if $this->useFormatting is true, otherwise return $bytes as is
43
+ *
44
+ * @param int $bytes
45
+ * @return string|int Formatted string if $this->useFormatting is true, otherwise return $bytes as is
46
+ */
47
+ protected function formatBytes($bytes)
48
+ {
49
+ $bytes = (int) $bytes;
50
+
51
+ if (!$this->useFormatting) {
52
+ return $bytes;
53
+ }
54
+
55
+ if ($bytes > 1024*1024) {
56
+ return round($bytes/1024/1024, 2).' MB';
57
+ } elseif ($bytes > 1024) {
58
+ return round($bytes/1024, 2).' KB';
59
+ }
60
+
61
+ return $bytes . ' B';
62
+ }
63
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Processor;
13
+
14
+ /**
15
+ * Injects memory_get_usage in all records
16
+ *
17
+ * @see Monolog\Processor\MemoryProcessor::__construct() for options
18
+ * @author Rob Jensen
19
+ */
20
+ class MemoryUsageProcessor extends MemoryProcessor
21
+ {
22
+ /**
23
+ * @param array $record
24
+ * @return array
25
+ */
26
+ public function __invoke(array $record)
27
+ {
28
+ $bytes = memory_get_usage($this->realUsage);
29
+ $formatted = $this->formatBytes($bytes);
30
+
31
+ $record['extra'] = array_merge(
32
+ $record['extra'],
33
+ array(
34
+ 'memory_usage' => $formatted,
35
+ )
36
+ );
37
+
38
+ return $record;
39
+ }
40
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Processor;
13
+
14
+ /**
15
+ * Adds value of getmypid into records
16
+ *
17
+ * @author Andreas Hörnicke
18
+ */
19
+ class ProcessIdProcessor
20
+ {
21
+ /**
22
+ * @param array $record
23
+ * @return array
24
+ */
25
+ public function __invoke(array $record)
26
+ {
27
+ $record['extra']['process_id'] = getmypid();
28
+
29
+ return $record;
30
+ }
31
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Processor;
13
+
14
+ /**
15
+ * Processes a record's message according to PSR-3 rules
16
+ *
17
+ * It replaces {foo} with the value from $context['foo']
18
+ *
19
+ * @author Jordi Boggiano <j.boggiano@seld.be>
20
+ */
21
+ class PsrLogMessageProcessor
22
+ {
23
+ /**
24
+ * @param array $record
25
+ * @return array
26
+ */
27
+ public function __invoke(array $record)
28
+ {
29
+ if (false === strpos($record['message'], '{')) {
30
+ return $record;
31
+ }
32
+
33
+ $replacements = array();
34
+ foreach ($record['context'] as $key => $val) {
35
+ if (is_null($val) || is_scalar($val) || (is_object($val) && method_exists($val, "__toString"))) {
36
+ $replacements['{'.$key.'}'] = $val;
37
+ } elseif (is_object($val)) {
38
+ $replacements['{'.$key.'}'] = '[object '.get_class($val).']';
39
+ } else {
40
+ $replacements['{'.$key.'}'] = '['.gettype($val).']';
41
+ }
42
+ }
43
+
44
+ $record['message'] = strtr($record['message'], $replacements);
45
+
46
+ return $record;
47
+ }
48
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Processor;
13
+
14
+ /**
15
+ * Adds a tags array into record
16
+ *
17
+ * @author Martijn Riemers
18
+ */
19
+ class TagProcessor
20
+ {
21
+ private $tags;
22
+
23
+ public function __construct(array $tags = array())
24
+ {
25
+ $this->tags = $tags;
26
+ }
27
+
28
+ public function __invoke(array $record)
29
+ {
30
+ $record['extra']['tags'] = $this->tags;
31
+
32
+ return $record;
33
+ }
34
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Processor;
13
+
14
+ /**
15
+ * Adds a unique identifier into records
16
+ *
17
+ * @author Simon Mönch <sm@webfactory.de>
18
+ */
19
+ class UidProcessor
20
+ {
21
+ private $uid;
22
+
23
+ public function __construct($length = 7)
24
+ {
25
+ if (!is_int($length) || $length > 32 || $length < 1) {
26
+ throw new \InvalidArgumentException('The uid length must be an integer between 1 and 32');
27
+ }
28
+
29
+ $this->uid = substr(hash('md5', uniqid('', true)), 0, $length);
30
+ }
31
+
32
+ public function __invoke(array $record)
33
+ {
34
+ $record['extra']['uid'] = $this->uid;
35
+
36
+ return $record;
37
+ }
38
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Processor;
13
+
14
+ /**
15
+ * Injects url/method and remote IP of the current web request in all records
16
+ *
17
+ * @author Jordi Boggiano <j.boggiano@seld.be>
18
+ */
19
+ class WebProcessor
20
+ {
21
+ /**
22
+ * @var array|\ArrayAccess
23
+ */
24
+ protected $serverData;
25
+
26
+ /**
27
+ * @var array
28
+ */
29
+ protected $extraFields = array(
30
+ 'url' => 'REQUEST_URI',
31
+ 'ip' => 'REMOTE_ADDR',
32
+ 'http_method' => 'REQUEST_METHOD',
33
+ 'server' => 'SERVER_NAME',
34
+ 'referrer' => 'HTTP_REFERER',
35
+ );
36
+
37
+ /**
38
+ * @param array|\ArrayAccess $serverData Array or object w/ ArrayAccess that provides access to the $_SERVER data
39
+ * @param array|null $extraFields Extra field names to be added (all available by default)
40
+ */
41
+ public function __construct($serverData = null, array $extraFields = null)
42
+ {
43
+ if (null === $serverData) {
44
+ $this->serverData = &$_SERVER;
45
+ } elseif (is_array($serverData) || $serverData instanceof \ArrayAccess) {
46
+ $this->serverData = $serverData;
47
+ } else {
48
+ throw new \UnexpectedValueException('$serverData must be an array or object implementing ArrayAccess.');
49
+ }
50
+
51
+ if (null !== $extraFields) {
52
+ foreach (array_keys($this->extraFields) as $fieldName) {
53
+ if (!in_array($fieldName, $extraFields)) {
54
+ unset($this->extraFields[$fieldName]);
55
+ }
56
+ }
57
+ }
58
+ }
59
+
60
+ /**
61
+ * @param array $record
62
+ * @return array
63
+ */
64
+ public function __invoke(array $record)
65
+ {
66
+ // skip processing if for some reason request data
67
+ // is not present (CLI or wonky SAPIs)
68
+ if (!isset($this->serverData['REQUEST_URI'])) {
69
+ return $record;
70
+ }
71
+
72
+ $record['extra'] = $this->appendExtraFields($record['extra']);
73
+
74
+ return $record;
75
+ }
76
+
77
+ /**
78
+ * @param string $extraName
79
+ * @param string $serverName
80
+ * @return $this
81
+ */
82
+ public function addExtraField($extraName, $serverName)
83
+ {
84
+ $this->extraFields[$extraName] = $serverName;
85
+
86
+ return $this;
87
+ }
88
+
89
+ /**
90
+ * @param array $extra
91
+ * @return array
92
+ */
93
+ private function appendExtraFields(array $extra)
94
+ {
95
+ foreach ($this->extraFields as $extraName => $serverName) {
96
+ $extra[$extraName] = isset($this->serverData[$serverName]) ? $this->serverData[$serverName] : null;
97
+ }
98
+
99
+ if (isset($this->serverData['UNIQUE_ID'])) {
100
+ $extra['unique_id'] = $this->serverData['UNIQUE_ID'];
101
+ }
102
+
103
+ return $extra;
104
+ }
105
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/src/Monolog/Registry.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog;
13
+
14
+ use InvalidArgumentException;
15
+
16
+ /**
17
+ * Monolog log registry
18
+ *
19
+ * Allows to get `Logger` instances in the global scope
20
+ * via static method calls on this class.
21
+ *
22
+ * <code>
23
+ * $application = new Monolog\Logger('application');
24
+ * $api = new Monolog\Logger('api');
25
+ *
26
+ * Monolog\Registry::addLogger($application);
27
+ * Monolog\Registry::addLogger($api);
28
+ *
29
+ * function testLogger()
30
+ * {
31
+ * Monolog\Registry::api()->addError('Sent to $api Logger instance');
32
+ * Monolog\Registry::application()->addError('Sent to $application Logger instance');
33
+ * }
34
+ * </code>
35
+ *
36
+ * @author Tomas Tatarko <tomas@tatarko.sk>
37
+ */
38
+ class Registry
39
+ {
40
+ /**
41
+ * List of all loggers in the registry (ba named indexes)
42
+ *
43
+ * @var Logger[]
44
+ */
45
+ private static $loggers = array();
46
+
47
+ /**
48
+ * Adds new logging channel to the registry
49
+ *
50
+ * @param Logger $logger Instance of the logging channel
51
+ * @param string|null $name Name of the logging channel ($logger->getName() by default)
52
+ * @param boolean $overwrite Overwrite instance in the registry if the given name already exists?
53
+ * @throws \InvalidArgumentException If $overwrite set to false and named Logger instance already exists
54
+ */
55
+ public static function addLogger(Logger $logger, $name = null, $overwrite = false)
56
+ {
57
+ $name = $name ?: $logger->getName();
58
+
59
+ if (isset(self::$loggers[$name]) && !$overwrite) {
60
+ throw new InvalidArgumentException('Logger with the given name already exists');
61
+ }
62
+
63
+ self::$loggers[$name] = $logger;
64
+ }
65
+
66
+ /**
67
+ * Checks if such logging channel exists by name or instance
68
+ *
69
+ * @param string|Logger $logger Name or logger instance
70
+ */
71
+ public static function hasLogger($logger)
72
+ {
73
+ if ($logger instanceof Logger) {
74
+ $index = array_search($logger, self::$loggers, true);
75
+
76
+ return false !== $index;
77
+ } else {
78
+ return isset(self::$loggers[$logger]);
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Removes instance from registry by name or instance
84
+ *
85
+ * @param string|Logger $logger Name or logger instance
86
+ */
87
+ public static function removeLogger($logger)
88
+ {
89
+ if ($logger instanceof Logger) {
90
+ if (false !== ($idx = array_search($logger, self::$loggers, true))) {
91
+ unset(self::$loggers[$idx]);
92
+ }
93
+ } else {
94
+ unset(self::$loggers[$logger]);
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Clears the registry
100
+ */
101
+ public static function clear()
102
+ {
103
+ self::$loggers = array();
104
+ }
105
+
106
+ /**
107
+ * Gets Logger instance from the registry
108
+ *
109
+ * @param string $name Name of the requested Logger instance
110
+ * @return Logger Requested instance of Logger
111
+ * @throws \InvalidArgumentException If named Logger instance is not in the registry
112
+ */
113
+ public static function getInstance($name)
114
+ {
115
+ if (!isset(self::$loggers[$name])) {
116
+ throw new InvalidArgumentException(sprintf('Requested "%s" logger instance is not in the registry', $name));
117
+ }
118
+
119
+ return self::$loggers[$name];
120
+ }
121
+
122
+ /**
123
+ * Gets Logger instance from the registry via static method call
124
+ *
125
+ * @param string $name Name of the requested Logger instance
126
+ * @param array $arguments Arguments passed to static method call
127
+ * @return Logger Requested instance of Logger
128
+ * @throws \InvalidArgumentException If named Logger instance is not in the registry
129
+ */
130
+ public static function __callStatic($name, $arguments)
131
+ {
132
+ return self::getInstance($name);
133
+ }
134
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/ErrorHandlerTest.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog;
13
+
14
+ use Monolog\Handler\TestHandler;
15
+
16
+ class ErrorHandlerTest extends \PHPUnit_Framework_TestCase
17
+ {
18
+ public function testHandleError()
19
+ {
20
+ $logger = new Logger('test', array($handler = new TestHandler));
21
+ $errHandler = new ErrorHandler($logger);
22
+
23
+ $errHandler->registerErrorHandler(array(E_USER_NOTICE => Logger::EMERGENCY), false);
24
+ trigger_error('Foo', E_USER_ERROR);
25
+ $this->assertCount(1, $handler->getRecords());
26
+ $this->assertTrue($handler->hasErrorRecords());
27
+ trigger_error('Foo', E_USER_NOTICE);
28
+ $this->assertCount(2, $handler->getRecords());
29
+ $this->assertTrue($handler->hasEmergencyRecords());
30
+ }
31
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/ChromePHPFormatterTest.php ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ use Monolog\Logger;
15
+
16
+ class ChromePHPFormatterTest extends \PHPUnit_Framework_TestCase
17
+ {
18
+ /**
19
+ * @covers Monolog\Formatter\ChromePHPFormatter::format
20
+ */
21
+ public function testDefaultFormat()
22
+ {
23
+ $formatter = new ChromePHPFormatter();
24
+ $record = array(
25
+ 'level' => Logger::ERROR,
26
+ 'level_name' => 'ERROR',
27
+ 'channel' => 'meh',
28
+ 'context' => array('from' => 'logger'),
29
+ 'datetime' => new \DateTime("@0"),
30
+ 'extra' => array('ip' => '127.0.0.1'),
31
+ 'message' => 'log',
32
+ );
33
+
34
+ $message = $formatter->format($record);
35
+
36
+ $this->assertEquals(
37
+ array(
38
+ 'meh',
39
+ array(
40
+ 'message' => 'log',
41
+ 'context' => array('from' => 'logger'),
42
+ 'extra' => array('ip' => '127.0.0.1'),
43
+ ),
44
+ 'unknown',
45
+ 'error'
46
+ ),
47
+ $message
48
+ );
49
+ }
50
+
51
+ /**
52
+ * @covers Monolog\Formatter\ChromePHPFormatter::format
53
+ */
54
+ public function testFormatWithFileAndLine()
55
+ {
56
+ $formatter = new ChromePHPFormatter();
57
+ $record = array(
58
+ 'level' => Logger::CRITICAL,
59
+ 'level_name' => 'CRITICAL',
60
+ 'channel' => 'meh',
61
+ 'context' => array('from' => 'logger'),
62
+ 'datetime' => new \DateTime("@0"),
63
+ 'extra' => array('ip' => '127.0.0.1', 'file' => 'test', 'line' => 14),
64
+ 'message' => 'log',
65
+ );
66
+
67
+ $message = $formatter->format($record);
68
+
69
+ $this->assertEquals(
70
+ array(
71
+ 'meh',
72
+ array(
73
+ 'message' => 'log',
74
+ 'context' => array('from' => 'logger'),
75
+ 'extra' => array('ip' => '127.0.0.1'),
76
+ ),
77
+ 'test : 14',
78
+ 'error'
79
+ ),
80
+ $message
81
+ );
82
+ }
83
+
84
+ /**
85
+ * @covers Monolog\Formatter\ChromePHPFormatter::format
86
+ */
87
+ public function testFormatWithoutContext()
88
+ {
89
+ $formatter = new ChromePHPFormatter();
90
+ $record = array(
91
+ 'level' => Logger::DEBUG,
92
+ 'level_name' => 'DEBUG',
93
+ 'channel' => 'meh',
94
+ 'context' => array(),
95
+ 'datetime' => new \DateTime("@0"),
96
+ 'extra' => array(),
97
+ 'message' => 'log',
98
+ );
99
+
100
+ $message = $formatter->format($record);
101
+
102
+ $this->assertEquals(
103
+ array(
104
+ 'meh',
105
+ 'log',
106
+ 'unknown',
107
+ 'log'
108
+ ),
109
+ $message
110
+ );
111
+ }
112
+
113
+ /**
114
+ * @covers Monolog\Formatter\ChromePHPFormatter::formatBatch
115
+ */
116
+ public function testBatchFormatThrowException()
117
+ {
118
+ $formatter = new ChromePHPFormatter();
119
+ $records = array(
120
+ array(
121
+ 'level' => Logger::INFO,
122
+ 'level_name' => 'INFO',
123
+ 'channel' => 'meh',
124
+ 'context' => array(),
125
+ 'datetime' => new \DateTime("@0"),
126
+ 'extra' => array(),
127
+ 'message' => 'log',
128
+ ),
129
+ array(
130
+ 'level' => Logger::WARNING,
131
+ 'level_name' => 'WARNING',
132
+ 'channel' => 'foo',
133
+ 'context' => array(),
134
+ 'datetime' => new \DateTime("@0"),
135
+ 'extra' => array(),
136
+ 'message' => 'log2',
137
+ ),
138
+ );
139
+
140
+ $this->assertEquals(
141
+ array(
142
+ array(
143
+ 'meh',
144
+ 'log',
145
+ 'unknown',
146
+ 'info'
147
+ ),
148
+ array(
149
+ 'foo',
150
+ 'log2',
151
+ 'unknown',
152
+ 'warn'
153
+ ),
154
+ ),
155
+ $formatter->formatBatch($records)
156
+ );
157
+ }
158
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/ElasticaFormatterTest.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ use Monolog\Logger;
15
+
16
+ class ElasticaFormatterTest extends \PHPUnit_Framework_TestCase
17
+ {
18
+ public function setUp()
19
+ {
20
+ if (!class_exists("Elastica\Document")) {
21
+ $this->markTestSkipped("ruflin/elastica not installed");
22
+ }
23
+ }
24
+
25
+ /**
26
+ * @covers Monolog\Formatter\ElasticaFormatter::__construct
27
+ * @covers Monolog\Formatter\ElasticaFormatter::format
28
+ * @covers Monolog\Formatter\ElasticaFormatter::getDocument
29
+ */
30
+ public function testFormat()
31
+ {
32
+ // test log message
33
+ $msg = array(
34
+ 'level' => Logger::ERROR,
35
+ 'level_name' => 'ERROR',
36
+ 'channel' => 'meh',
37
+ 'context' => array('foo' => 7, 'bar', 'class' => new \stdClass),
38
+ 'datetime' => new \DateTime("@0"),
39
+ 'extra' => array(),
40
+ 'message' => 'log',
41
+ );
42
+
43
+ // expected values
44
+ $expected = $msg;
45
+ $expected['datetime'] = '1970-01-01T00:00:00+0000';
46
+ $expected['context'] = array(
47
+ 'class' => '[object] (stdClass: {})',
48
+ 'foo' => 7,
49
+ 0 => 'bar',
50
+ );
51
+
52
+ // format log message
53
+ $formatter = new ElasticaFormatter('my_index', 'doc_type');
54
+ $doc = $formatter->format($msg);
55
+ $this->assertInstanceOf('Elastica\Document', $doc);
56
+
57
+ // Document parameters
58
+ $params = $doc->getParams();
59
+ $this->assertEquals('my_index', $params['_index']);
60
+ $this->assertEquals('doc_type', $params['_type']);
61
+
62
+ // Document data values
63
+ $data = $doc->getData();
64
+ foreach (array_keys($expected) as $key) {
65
+ $this->assertEquals($expected[$key], $data[$key]);
66
+ }
67
+ }
68
+
69
+ /**
70
+ * @covers Monolog\Formatter\ElasticaFormatter::getIndex
71
+ * @covers Monolog\Formatter\ElasticaFormatter::getType
72
+ */
73
+ public function testGetters()
74
+ {
75
+ $formatter = new ElasticaFormatter('my_index', 'doc_type');
76
+ $this->assertEquals('my_index', $formatter->getIndex());
77
+ $this->assertEquals('doc_type', $formatter->getType());
78
+ }
79
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/FlowdockFormatterTest.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ use Monolog\Logger;
15
+ use Monolog\TestCase;
16
+
17
+ class FlowdockFormatterTest extends TestCase
18
+ {
19
+ /**
20
+ * @covers Monolog\Formatter\FlowdockFormatter::format
21
+ */
22
+ public function testFormat()
23
+ {
24
+ $formatter = new FlowdockFormatter('test_source', 'source@test.com');
25
+ $record = $this->getRecord();
26
+
27
+ $expected = array(
28
+ 'source' => 'test_source',
29
+ 'from_address' => 'source@test.com',
30
+ 'subject' => 'in test_source: WARNING - test',
31
+ 'content' => 'test',
32
+ 'tags' => array('#logs', '#warning', '#test'),
33
+ 'project' => 'test_source',
34
+ );
35
+ $formatted = $formatter->format($record);
36
+
37
+ $this->assertEquals($expected, $formatted['flowdock']);
38
+ }
39
+
40
+ /**
41
+ * @ covers Monolog\Formatter\FlowdockFormatter::formatBatch
42
+ */
43
+ public function testFormatBatch()
44
+ {
45
+ $formatter = new FlowdockFormatter('test_source', 'source@test.com');
46
+ $records = array(
47
+ $this->getRecord(Logger::WARNING),
48
+ $this->getRecord(Logger::DEBUG),
49
+ );
50
+ $formatted = $formatter->formatBatch($records);
51
+
52
+ $this->assertArrayHasKey('flowdock', $formatted[0]);
53
+ $this->assertArrayHasKey('flowdock', $formatted[1]);
54
+ }
55
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/GelfMessageFormatterTest.php ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ use Monolog\Logger;
15
+
16
+ class GelfMessageFormatterTest extends \PHPUnit_Framework_TestCase
17
+ {
18
+ public function setUp()
19
+ {
20
+ if (!class_exists('\Gelf\Message')) {
21
+ $this->markTestSkipped("graylog2/gelf-php or mlehner/gelf-php is not installed");
22
+ }
23
+ }
24
+
25
+ /**
26
+ * @covers Monolog\Formatter\GelfMessageFormatter::format
27
+ */
28
+ public function testDefaultFormatter()
29
+ {
30
+ $formatter = new GelfMessageFormatter();
31
+ $record = array(
32
+ 'level' => Logger::ERROR,
33
+ 'level_name' => 'ERROR',
34
+ 'channel' => 'meh',
35
+ 'context' => array(),
36
+ 'datetime' => new \DateTime("@0"),
37
+ 'extra' => array(),
38
+ 'message' => 'log',
39
+ );
40
+
41
+ $message = $formatter->format($record);
42
+
43
+ $this->assertInstanceOf('Gelf\Message', $message);
44
+ $this->assertEquals(0, $message->getTimestamp());
45
+ $this->assertEquals('log', $message->getShortMessage());
46
+ $this->assertEquals('meh', $message->getFacility());
47
+ $this->assertEquals(null, $message->getLine());
48
+ $this->assertEquals(null, $message->getFile());
49
+ $this->assertEquals($this->isLegacy() ? 3 : 'error', $message->getLevel());
50
+ $this->assertNotEmpty($message->getHost());
51
+
52
+ $formatter = new GelfMessageFormatter('mysystem');
53
+
54
+ $message = $formatter->format($record);
55
+
56
+ $this->assertInstanceOf('Gelf\Message', $message);
57
+ $this->assertEquals('mysystem', $message->getHost());
58
+ }
59
+
60
+ /**
61
+ * @covers Monolog\Formatter\GelfMessageFormatter::format
62
+ */
63
+ public function testFormatWithFileAndLine()
64
+ {
65
+ $formatter = new GelfMessageFormatter();
66
+ $record = array(
67
+ 'level' => Logger::ERROR,
68
+ 'level_name' => 'ERROR',
69
+ 'channel' => 'meh',
70
+ 'context' => array('from' => 'logger'),
71
+ 'datetime' => new \DateTime("@0"),
72
+ 'extra' => array('file' => 'test', 'line' => 14),
73
+ 'message' => 'log',
74
+ );
75
+
76
+ $message = $formatter->format($record);
77
+
78
+ $this->assertInstanceOf('Gelf\Message', $message);
79
+ $this->assertEquals('test', $message->getFile());
80
+ $this->assertEquals(14, $message->getLine());
81
+ }
82
+
83
+ /**
84
+ * @covers Monolog\Formatter\GelfMessageFormatter::format
85
+ * @expectedException InvalidArgumentException
86
+ */
87
+ public function testFormatInvalidFails()
88
+ {
89
+ $formatter = new GelfMessageFormatter();
90
+ $record = array(
91
+ 'level' => Logger::ERROR,
92
+ 'level_name' => 'ERROR',
93
+ );
94
+
95
+ $formatter->format($record);
96
+ }
97
+
98
+ /**
99
+ * @covers Monolog\Formatter\GelfMessageFormatter::format
100
+ */
101
+ public function testFormatWithContext()
102
+ {
103
+ $formatter = new GelfMessageFormatter();
104
+ $record = array(
105
+ 'level' => Logger::ERROR,
106
+ 'level_name' => 'ERROR',
107
+ 'channel' => 'meh',
108
+ 'context' => array('from' => 'logger'),
109
+ 'datetime' => new \DateTime("@0"),
110
+ 'extra' => array('key' => 'pair'),
111
+ 'message' => 'log'
112
+ );
113
+
114
+ $message = $formatter->format($record);
115
+
116
+ $this->assertInstanceOf('Gelf\Message', $message);
117
+
118
+ $message_array = $message->toArray();
119
+
120
+ $this->assertArrayHasKey('_ctxt_from', $message_array);
121
+ $this->assertEquals('logger', $message_array['_ctxt_from']);
122
+
123
+ // Test with extraPrefix
124
+ $formatter = new GelfMessageFormatter(null, null, 'CTX');
125
+ $message = $formatter->format($record);
126
+
127
+ $this->assertInstanceOf('Gelf\Message', $message);
128
+
129
+ $message_array = $message->toArray();
130
+
131
+ $this->assertArrayHasKey('_CTXfrom', $message_array);
132
+ $this->assertEquals('logger', $message_array['_CTXfrom']);
133
+ }
134
+
135
+ /**
136
+ * @covers Monolog\Formatter\GelfMessageFormatter::format
137
+ */
138
+ public function testFormatWithContextContainingException()
139
+ {
140
+ $formatter = new GelfMessageFormatter();
141
+ $record = array(
142
+ 'level' => Logger::ERROR,
143
+ 'level_name' => 'ERROR',
144
+ 'channel' => 'meh',
145
+ 'context' => array('from' => 'logger', 'exception' => array(
146
+ 'class' => '\Exception',
147
+ 'file' => '/some/file/in/dir.php:56',
148
+ 'trace' => array('/some/file/1.php:23', '/some/file/2.php:3')
149
+ )),
150
+ 'datetime' => new \DateTime("@0"),
151
+ 'extra' => array(),
152
+ 'message' => 'log'
153
+ );
154
+
155
+ $message = $formatter->format($record);
156
+
157
+ $this->assertInstanceOf('Gelf\Message', $message);
158
+
159
+ $this->assertEquals("/some/file/in/dir.php", $message->getFile());
160
+ $this->assertEquals("56", $message->getLine());
161
+ }
162
+
163
+ /**
164
+ * @covers Monolog\Formatter\GelfMessageFormatter::format
165
+ */
166
+ public function testFormatWithExtra()
167
+ {
168
+ $formatter = new GelfMessageFormatter();
169
+ $record = array(
170
+ 'level' => Logger::ERROR,
171
+ 'level_name' => 'ERROR',
172
+ 'channel' => 'meh',
173
+ 'context' => array('from' => 'logger'),
174
+ 'datetime' => new \DateTime("@0"),
175
+ 'extra' => array('key' => 'pair'),
176
+ 'message' => 'log'
177
+ );
178
+
179
+ $message = $formatter->format($record);
180
+
181
+ $this->assertInstanceOf('Gelf\Message', $message);
182
+
183
+ $message_array = $message->toArray();
184
+
185
+ $this->assertArrayHasKey('_key', $message_array);
186
+ $this->assertEquals('pair', $message_array['_key']);
187
+
188
+ // Test with extraPrefix
189
+ $formatter = new GelfMessageFormatter(null, 'EXT');
190
+ $message = $formatter->format($record);
191
+
192
+ $this->assertInstanceOf('Gelf\Message', $message);
193
+
194
+ $message_array = $message->toArray();
195
+
196
+ $this->assertArrayHasKey('_EXTkey', $message_array);
197
+ $this->assertEquals('pair', $message_array['_EXTkey']);
198
+ }
199
+
200
+ private function isLegacy()
201
+ {
202
+ return interface_exists('\Gelf\IMessagePublisher');
203
+ }
204
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/JsonFormatterTest.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ use Monolog\Logger;
15
+ use Monolog\TestCase;
16
+
17
+ class JsonFormatterTest extends TestCase
18
+ {
19
+ /**
20
+ * @covers Monolog\Formatter\JsonFormatter::__construct
21
+ * @covers Monolog\Formatter\JsonFormatter::getBatchMode
22
+ * @covers Monolog\Formatter\JsonFormatter::isAppendingNewlines
23
+ */
24
+ public function testConstruct()
25
+ {
26
+ $formatter = new JsonFormatter();
27
+ $this->assertEquals(JsonFormatter::BATCH_MODE_JSON, $formatter->getBatchMode());
28
+ $this->assertEquals(true, $formatter->isAppendingNewlines());
29
+ $formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_NEWLINES, false);
30
+ $this->assertEquals(JsonFormatter::BATCH_MODE_NEWLINES, $formatter->getBatchMode());
31
+ $this->assertEquals(false, $formatter->isAppendingNewlines());
32
+ }
33
+
34
+ /**
35
+ * @covers Monolog\Formatter\JsonFormatter::format
36
+ */
37
+ public function testFormat()
38
+ {
39
+ $formatter = new JsonFormatter();
40
+ $record = $this->getRecord();
41
+ $this->assertEquals(json_encode($record)."\n", $formatter->format($record));
42
+
43
+ $formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false);
44
+ $record = $this->getRecord();
45
+ $this->assertEquals(json_encode($record), $formatter->format($record));
46
+ }
47
+
48
+ /**
49
+ * @covers Monolog\Formatter\JsonFormatter::formatBatch
50
+ * @covers Monolog\Formatter\JsonFormatter::formatBatchJson
51
+ */
52
+ public function testFormatBatch()
53
+ {
54
+ $formatter = new JsonFormatter();
55
+ $records = array(
56
+ $this->getRecord(Logger::WARNING),
57
+ $this->getRecord(Logger::DEBUG),
58
+ );
59
+ $this->assertEquals(json_encode($records), $formatter->formatBatch($records));
60
+ }
61
+
62
+ /**
63
+ * @covers Monolog\Formatter\JsonFormatter::formatBatch
64
+ * @covers Monolog\Formatter\JsonFormatter::formatBatchNewlines
65
+ */
66
+ public function testFormatBatchNewlines()
67
+ {
68
+ $formatter = new JsonFormatter(JsonFormatter::BATCH_MODE_NEWLINES);
69
+ $records = $expected = array(
70
+ $this->getRecord(Logger::WARNING),
71
+ $this->getRecord(Logger::DEBUG),
72
+ );
73
+ array_walk($expected, function (&$value, $key) {
74
+ $value = json_encode($value);
75
+ });
76
+ $this->assertEquals(implode("\n", $expected), $formatter->formatBatch($records));
77
+ }
78
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/LineFormatterTest.php ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ /**
15
+ * @covers Monolog\Formatter\LineFormatter
16
+ */
17
+ class LineFormatterTest extends \PHPUnit_Framework_TestCase
18
+ {
19
+ public function testDefFormatWithString()
20
+ {
21
+ $formatter = new LineFormatter(null, 'Y-m-d');
22
+ $message = $formatter->format(array(
23
+ 'level_name' => 'WARNING',
24
+ 'channel' => 'log',
25
+ 'context' => array(),
26
+ 'message' => 'foo',
27
+ 'datetime' => new \DateTime,
28
+ 'extra' => array(),
29
+ ));
30
+ $this->assertEquals('['.date('Y-m-d').'] log.WARNING: foo [] []'."\n", $message);
31
+ }
32
+
33
+ public function testDefFormatWithArrayContext()
34
+ {
35
+ $formatter = new LineFormatter(null, 'Y-m-d');
36
+ $message = $formatter->format(array(
37
+ 'level_name' => 'ERROR',
38
+ 'channel' => 'meh',
39
+ 'message' => 'foo',
40
+ 'datetime' => new \DateTime,
41
+ 'extra' => array(),
42
+ 'context' => array(
43
+ 'foo' => 'bar',
44
+ 'baz' => 'qux',
45
+ 'bool' => false,
46
+ 'null' => null,
47
+ )
48
+ ));
49
+ $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: foo {"foo":"bar","baz":"qux","bool":false,"null":null} []'."\n", $message);
50
+ }
51
+
52
+ public function testDefFormatExtras()
53
+ {
54
+ $formatter = new LineFormatter(null, 'Y-m-d');
55
+ $message = $formatter->format(array(
56
+ 'level_name' => 'ERROR',
57
+ 'channel' => 'meh',
58
+ 'context' => array(),
59
+ 'datetime' => new \DateTime,
60
+ 'extra' => array('ip' => '127.0.0.1'),
61
+ 'message' => 'log',
62
+ ));
63
+ $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: log [] {"ip":"127.0.0.1"}'."\n", $message);
64
+ }
65
+
66
+ public function testFormatExtras()
67
+ {
68
+ $formatter = new LineFormatter("[%datetime%] %channel%.%level_name%: %message% %context% %extra.file% %extra%\n", 'Y-m-d');
69
+ $message = $formatter->format(array(
70
+ 'level_name' => 'ERROR',
71
+ 'channel' => 'meh',
72
+ 'context' => array(),
73
+ 'datetime' => new \DateTime,
74
+ 'extra' => array('ip' => '127.0.0.1', 'file' => 'test'),
75
+ 'message' => 'log',
76
+ ));
77
+ $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: log [] test {"ip":"127.0.0.1"}'."\n", $message);
78
+ }
79
+
80
+ public function testContextAndExtraOptionallyNotShownIfEmpty()
81
+ {
82
+ $formatter = new LineFormatter(null, 'Y-m-d', false, true);
83
+ $message = $formatter->format(array(
84
+ 'level_name' => 'ERROR',
85
+ 'channel' => 'meh',
86
+ 'context' => array(),
87
+ 'datetime' => new \DateTime,
88
+ 'extra' => array(),
89
+ 'message' => 'log',
90
+ ));
91
+ $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: log '."\n", $message);
92
+ }
93
+
94
+ public function testDefFormatWithObject()
95
+ {
96
+ $formatter = new LineFormatter(null, 'Y-m-d');
97
+ $message = $formatter->format(array(
98
+ 'level_name' => 'ERROR',
99
+ 'channel' => 'meh',
100
+ 'context' => array(),
101
+ 'datetime' => new \DateTime,
102
+ 'extra' => array('foo' => new TestFoo, 'bar' => new TestBar, 'baz' => array(), 'res' => fopen('php://memory', 'rb')),
103
+ 'message' => 'foobar',
104
+ ));
105
+
106
+ $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: foobar [] {"foo":"[object] (Monolog\\\\Formatter\\\\TestFoo: {\\"foo\\":\\"foo\\"})","bar":"[object] (Monolog\\\\Formatter\\\\TestBar: {})","baz":[],"res":"[resource]"}'."\n", $message);
107
+ }
108
+
109
+ public function testDefFormatWithException()
110
+ {
111
+ $formatter = new LineFormatter(null, 'Y-m-d');
112
+ $message = $formatter->format(array(
113
+ 'level_name' => 'CRITICAL',
114
+ 'channel' => 'core',
115
+ 'context' => array('exception' => new \RuntimeException('Foo')),
116
+ 'datetime' => new \DateTime,
117
+ 'extra' => array(),
118
+ 'message' => 'foobar',
119
+ ));
120
+
121
+ $path = str_replace('\\/', '/', json_encode(__FILE__));
122
+
123
+ $this->assertEquals('['.date('Y-m-d').'] core.CRITICAL: foobar {"exception":"[object] (RuntimeException(code: 0): Foo at '.substr($path, 1, -1).':'.(__LINE__-8).')"} []'."\n", $message);
124
+ }
125
+
126
+ public function testDefFormatWithPreviousException()
127
+ {
128
+ $formatter = new LineFormatter(null, 'Y-m-d');
129
+ $previous = new \LogicException('Wut?');
130
+ $message = $formatter->format(array(
131
+ 'level_name' => 'CRITICAL',
132
+ 'channel' => 'core',
133
+ 'context' => array('exception' => new \RuntimeException('Foo', 0, $previous)),
134
+ 'datetime' => new \DateTime,
135
+ 'extra' => array(),
136
+ 'message' => 'foobar',
137
+ ));
138
+
139
+ $path = str_replace('\\/', '/', json_encode(__FILE__));
140
+
141
+ $this->assertEquals('['.date('Y-m-d').'] core.CRITICAL: foobar {"exception":"[object] (RuntimeException(code: 0): Foo at '.substr($path, 1, -1).':'.(__LINE__-8).', LogicException(code: 0): Wut? at '.substr($path, 1, -1).':'.(__LINE__-12).')"} []'."\n", $message);
142
+ }
143
+
144
+ public function testBatchFormat()
145
+ {
146
+ $formatter = new LineFormatter(null, 'Y-m-d');
147
+ $message = $formatter->formatBatch(array(
148
+ array(
149
+ 'level_name' => 'CRITICAL',
150
+ 'channel' => 'test',
151
+ 'message' => 'bar',
152
+ 'context' => array(),
153
+ 'datetime' => new \DateTime,
154
+ 'extra' => array(),
155
+ ),
156
+ array(
157
+ 'level_name' => 'WARNING',
158
+ 'channel' => 'log',
159
+ 'message' => 'foo',
160
+ 'context' => array(),
161
+ 'datetime' => new \DateTime,
162
+ 'extra' => array(),
163
+ ),
164
+ ));
165
+ $this->assertEquals('['.date('Y-m-d').'] test.CRITICAL: bar [] []'."\n".'['.date('Y-m-d').'] log.WARNING: foo [] []'."\n", $message);
166
+ }
167
+
168
+ public function testFormatShouldStripInlineLineBreaks()
169
+ {
170
+ $formatter = new LineFormatter(null, 'Y-m-d');
171
+ $message = $formatter->format(
172
+ array(
173
+ 'message' => "foo\nbar",
174
+ 'context' => array(),
175
+ 'extra' => array(),
176
+ )
177
+ );
178
+
179
+ $this->assertRegExp('/foo bar/', $message);
180
+ }
181
+
182
+ public function testFormatShouldNotStripInlineLineBreaksWhenFlagIsSet()
183
+ {
184
+ $formatter = new LineFormatter(null, 'Y-m-d', true);
185
+ $message = $formatter->format(
186
+ array(
187
+ 'message' => "foo\nbar",
188
+ 'context' => array(),
189
+ 'extra' => array(),
190
+ )
191
+ );
192
+
193
+ $this->assertRegExp('/foo\nbar/', $message);
194
+ }
195
+ }
196
+
197
+ class TestFoo
198
+ {
199
+ public $foo = 'foo';
200
+ }
201
+
202
+ class TestBar
203
+ {
204
+ public function __toString()
205
+ {
206
+ return 'bar';
207
+ }
208
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/LogglyFormatterTest.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ use Monolog\TestCase;
15
+
16
+ class LogglyFormatterTest extends TestCase
17
+ {
18
+ /**
19
+ * @covers Monolog\Formatter\LogglyFormatter::__construct
20
+ */
21
+ public function testConstruct()
22
+ {
23
+ $formatter = new LogglyFormatter();
24
+ $this->assertEquals(LogglyFormatter::BATCH_MODE_NEWLINES, $formatter->getBatchMode());
25
+ $formatter = new LogglyFormatter(LogglyFormatter::BATCH_MODE_JSON);
26
+ $this->assertEquals(LogglyFormatter::BATCH_MODE_JSON, $formatter->getBatchMode());
27
+ }
28
+
29
+ /**
30
+ * @covers Monolog\Formatter\LogglyFormatter::format
31
+ */
32
+ public function testFormat()
33
+ {
34
+ $formatter = new LogglyFormatter();
35
+ $record = $this->getRecord();
36
+ $formatted_decoded = json_decode($formatter->format($record), true);
37
+ $this->assertArrayHasKey("timestamp", $formatted_decoded);
38
+ $this->assertEquals(new \DateTime($formatted_decoded["timestamp"]), $record["datetime"]);
39
+ }
40
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/LogstashFormatterTest.php ADDED
@@ -0,0 +1,289 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ use Monolog\Logger;
15
+
16
+ class LogstashFormatterTest extends \PHPUnit_Framework_TestCase
17
+ {
18
+ /**
19
+ * @covers Monolog\Formatter\LogstashFormatter::format
20
+ */
21
+ public function testDefaultFormatter()
22
+ {
23
+ $formatter = new LogstashFormatter('test', 'hostname');
24
+ $record = array(
25
+ 'level' => Logger::ERROR,
26
+ 'level_name' => 'ERROR',
27
+ 'channel' => 'meh',
28
+ 'context' => array(),
29
+ 'datetime' => new \DateTime("@0"),
30
+ 'extra' => array(),
31
+ 'message' => 'log',
32
+ );
33
+
34
+ $message = json_decode($formatter->format($record), true);
35
+
36
+ $this->assertEquals("1970-01-01T00:00:00.000000+00:00", $message['@timestamp']);
37
+ $this->assertEquals('log', $message['@message']);
38
+ $this->assertEquals('meh', $message['@fields']['channel']);
39
+ $this->assertContains('meh', $message['@tags']);
40
+ $this->assertEquals(Logger::ERROR, $message['@fields']['level']);
41
+ $this->assertEquals('test', $message['@type']);
42
+ $this->assertEquals('hostname', $message['@source']);
43
+
44
+ $formatter = new LogstashFormatter('mysystem');
45
+
46
+ $message = json_decode($formatter->format($record), true);
47
+
48
+ $this->assertEquals('mysystem', $message['@type']);
49
+ }
50
+
51
+ /**
52
+ * @covers Monolog\Formatter\LogstashFormatter::format
53
+ */
54
+ public function testFormatWithFileAndLine()
55
+ {
56
+ $formatter = new LogstashFormatter('test');
57
+ $record = array(
58
+ 'level' => Logger::ERROR,
59
+ 'level_name' => 'ERROR',
60
+ 'channel' => 'meh',
61
+ 'context' => array('from' => 'logger'),
62
+ 'datetime' => new \DateTime("@0"),
63
+ 'extra' => array('file' => 'test', 'line' => 14),
64
+ 'message' => 'log',
65
+ );
66
+
67
+ $message = json_decode($formatter->format($record), true);
68
+
69
+ $this->assertEquals('test', $message['@fields']['file']);
70
+ $this->assertEquals(14, $message['@fields']['line']);
71
+ }
72
+
73
+ /**
74
+ * @covers Monolog\Formatter\LogstashFormatter::format
75
+ */
76
+ public function testFormatWithContext()
77
+ {
78
+ $formatter = new LogstashFormatter('test');
79
+ $record = array(
80
+ 'level' => Logger::ERROR,
81
+ 'level_name' => 'ERROR',
82
+ 'channel' => 'meh',
83
+ 'context' => array('from' => 'logger'),
84
+ 'datetime' => new \DateTime("@0"),
85
+ 'extra' => array('key' => 'pair'),
86
+ 'message' => 'log'
87
+ );
88
+
89
+ $message = json_decode($formatter->format($record), true);
90
+
91
+ $message_array = $message['@fields'];
92
+
93
+ $this->assertArrayHasKey('ctxt_from', $message_array);
94
+ $this->assertEquals('logger', $message_array['ctxt_from']);
95
+
96
+ // Test with extraPrefix
97
+ $formatter = new LogstashFormatter('test', null, null, 'CTX');
98
+ $message = json_decode($formatter->format($record), true);
99
+
100
+ $message_array = $message['@fields'];
101
+
102
+ $this->assertArrayHasKey('CTXfrom', $message_array);
103
+ $this->assertEquals('logger', $message_array['CTXfrom']);
104
+ }
105
+
106
+ /**
107
+ * @covers Monolog\Formatter\LogstashFormatter::format
108
+ */
109
+ public function testFormatWithExtra()
110
+ {
111
+ $formatter = new LogstashFormatter('test');
112
+ $record = array(
113
+ 'level' => Logger::ERROR,
114
+ 'level_name' => 'ERROR',
115
+ 'channel' => 'meh',
116
+ 'context' => array('from' => 'logger'),
117
+ 'datetime' => new \DateTime("@0"),
118
+ 'extra' => array('key' => 'pair'),
119
+ 'message' => 'log'
120
+ );
121
+
122
+ $message = json_decode($formatter->format($record), true);
123
+
124
+ $message_array = $message['@fields'];
125
+
126
+ $this->assertArrayHasKey('key', $message_array);
127
+ $this->assertEquals('pair', $message_array['key']);
128
+
129
+ // Test with extraPrefix
130
+ $formatter = new LogstashFormatter('test', null, 'EXT');
131
+ $message = json_decode($formatter->format($record), true);
132
+
133
+ $message_array = $message['@fields'];
134
+
135
+ $this->assertArrayHasKey('EXTkey', $message_array);
136
+ $this->assertEquals('pair', $message_array['EXTkey']);
137
+ }
138
+
139
+ public function testFormatWithApplicationName()
140
+ {
141
+ $formatter = new LogstashFormatter('app', 'test');
142
+ $record = array(
143
+ 'level' => Logger::ERROR,
144
+ 'level_name' => 'ERROR',
145
+ 'channel' => 'meh',
146
+ 'context' => array('from' => 'logger'),
147
+ 'datetime' => new \DateTime("@0"),
148
+ 'extra' => array('key' => 'pair'),
149
+ 'message' => 'log'
150
+ );
151
+
152
+ $message = json_decode($formatter->format($record), true);
153
+
154
+ $this->assertArrayHasKey('@type', $message);
155
+ $this->assertEquals('app', $message['@type']);
156
+ }
157
+
158
+ /**
159
+ * @covers Monolog\Formatter\LogstashFormatter::format
160
+ */
161
+ public function testDefaultFormatterV1()
162
+ {
163
+ $formatter = new LogstashFormatter('test', 'hostname', null, 'ctxt_', LogstashFormatter::V1);
164
+ $record = array(
165
+ 'level' => Logger::ERROR,
166
+ 'level_name' => 'ERROR',
167
+ 'channel' => 'meh',
168
+ 'context' => array(),
169
+ 'datetime' => new \DateTime("@0"),
170
+ 'extra' => array(),
171
+ 'message' => 'log',
172
+ );
173
+
174
+ $message = json_decode($formatter->format($record), true);
175
+
176
+ $this->assertEquals("1970-01-01T00:00:00.000000+00:00", $message['@timestamp']);
177
+ $this->assertEquals("1", $message['@version']);
178
+ $this->assertEquals('log', $message['message']);
179
+ $this->assertEquals('meh', $message['channel']);
180
+ $this->assertEquals('ERROR', $message['level']);
181
+ $this->assertEquals('test', $message['type']);
182
+ $this->assertEquals('hostname', $message['host']);
183
+
184
+ $formatter = new LogstashFormatter('mysystem', null, null, 'ctxt_', LogstashFormatter::V1);
185
+
186
+ $message = json_decode($formatter->format($record), true);
187
+
188
+ $this->assertEquals('mysystem', $message['type']);
189
+ }
190
+
191
+ /**
192
+ * @covers Monolog\Formatter\LogstashFormatter::format
193
+ */
194
+ public function testFormatWithFileAndLineV1()
195
+ {
196
+ $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1);
197
+ $record = array(
198
+ 'level' => Logger::ERROR,
199
+ 'level_name' => 'ERROR',
200
+ 'channel' => 'meh',
201
+ 'context' => array('from' => 'logger'),
202
+ 'datetime' => new \DateTime("@0"),
203
+ 'extra' => array('file' => 'test', 'line' => 14),
204
+ 'message' => 'log',
205
+ );
206
+
207
+ $message = json_decode($formatter->format($record), true);
208
+
209
+ $this->assertEquals('test', $message['file']);
210
+ $this->assertEquals(14, $message['line']);
211
+ }
212
+
213
+ /**
214
+ * @covers Monolog\Formatter\LogstashFormatter::format
215
+ */
216
+ public function testFormatWithContextV1()
217
+ {
218
+ $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1);
219
+ $record = array(
220
+ 'level' => Logger::ERROR,
221
+ 'level_name' => 'ERROR',
222
+ 'channel' => 'meh',
223
+ 'context' => array('from' => 'logger'),
224
+ 'datetime' => new \DateTime("@0"),
225
+ 'extra' => array('key' => 'pair'),
226
+ 'message' => 'log'
227
+ );
228
+
229
+ $message = json_decode($formatter->format($record), true);
230
+
231
+ $this->assertArrayHasKey('ctxt_from', $message);
232
+ $this->assertEquals('logger', $message['ctxt_from']);
233
+
234
+ // Test with extraPrefix
235
+ $formatter = new LogstashFormatter('test', null, null, 'CTX', LogstashFormatter::V1);
236
+ $message = json_decode($formatter->format($record), true);
237
+
238
+ $this->assertArrayHasKey('CTXfrom', $message);
239
+ $this->assertEquals('logger', $message['CTXfrom']);
240
+ }
241
+
242
+ /**
243
+ * @covers Monolog\Formatter\LogstashFormatter::format
244
+ */
245
+ public function testFormatWithExtraV1()
246
+ {
247
+ $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1);
248
+ $record = array(
249
+ 'level' => Logger::ERROR,
250
+ 'level_name' => 'ERROR',
251
+ 'channel' => 'meh',
252
+ 'context' => array('from' => 'logger'),
253
+ 'datetime' => new \DateTime("@0"),
254
+ 'extra' => array('key' => 'pair'),
255
+ 'message' => 'log'
256
+ );
257
+
258
+ $message = json_decode($formatter->format($record), true);
259
+
260
+ $this->assertArrayHasKey('key', $message);
261
+ $this->assertEquals('pair', $message['key']);
262
+
263
+ // Test with extraPrefix
264
+ $formatter = new LogstashFormatter('test', null, 'EXT', 'ctxt_', LogstashFormatter::V1);
265
+ $message = json_decode($formatter->format($record), true);
266
+
267
+ $this->assertArrayHasKey('EXTkey', $message);
268
+ $this->assertEquals('pair', $message['EXTkey']);
269
+ }
270
+
271
+ public function testFormatWithApplicationNameV1()
272
+ {
273
+ $formatter = new LogstashFormatter('app', 'test', null, 'ctxt_', LogstashFormatter::V1);
274
+ $record = array(
275
+ 'level' => Logger::ERROR,
276
+ 'level_name' => 'ERROR',
277
+ 'channel' => 'meh',
278
+ 'context' => array('from' => 'logger'),
279
+ 'datetime' => new \DateTime("@0"),
280
+ 'extra' => array('key' => 'pair'),
281
+ 'message' => 'log'
282
+ );
283
+
284
+ $message = json_decode($formatter->format($record), true);
285
+
286
+ $this->assertArrayHasKey('type', $message);
287
+ $this->assertEquals('app', $message['type']);
288
+ }
289
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/MongoDBFormatterTest.php ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Monolog\Formatter;
4
+
5
+ use Monolog\Logger;
6
+
7
+ /**
8
+ * @author Florian Plattner <me@florianplattner.de>
9
+ */
10
+ class MongoDBFormatterTest extends \PHPUnit_Framework_TestCase
11
+ {
12
+ public function setUp()
13
+ {
14
+ if (!class_exists('MongoDate')) {
15
+ $this->markTestSkipped('mongo extension not installed');
16
+ }
17
+ }
18
+
19
+ public function constructArgumentProvider()
20
+ {
21
+ return array(
22
+ array(1, true, 1, true),
23
+ array(0, false, 0, false),
24
+ );
25
+ }
26
+
27
+ /**
28
+ * @param $traceDepth
29
+ * @param $traceAsString
30
+ * @param $expectedTraceDepth
31
+ * @param $expectedTraceAsString
32
+ *
33
+ * @dataProvider constructArgumentProvider
34
+ */
35
+ public function testConstruct($traceDepth, $traceAsString, $expectedTraceDepth, $expectedTraceAsString)
36
+ {
37
+ $formatter = new MongoDBFormatter($traceDepth, $traceAsString);
38
+
39
+ $reflTrace = new \ReflectionProperty($formatter, 'exceptionTraceAsString');
40
+ $reflTrace->setAccessible(true);
41
+ $this->assertEquals($expectedTraceAsString, $reflTrace->getValue($formatter));
42
+
43
+ $reflDepth = new\ReflectionProperty($formatter, 'maxNestingLevel');
44
+ $reflDepth->setAccessible(true);
45
+ $this->assertEquals($expectedTraceDepth, $reflDepth->getValue($formatter));
46
+ }
47
+
48
+ public function testSimpleFormat()
49
+ {
50
+ $record = array(
51
+ 'message' => 'some log message',
52
+ 'context' => array(),
53
+ 'level' => Logger::WARNING,
54
+ 'level_name' => Logger::getLevelName(Logger::WARNING),
55
+ 'channel' => 'test',
56
+ 'datetime' => new \DateTime('2014-02-01 00:00:00'),
57
+ 'extra' => array(),
58
+ );
59
+
60
+ $formatter = new MongoDBFormatter();
61
+ $formattedRecord = $formatter->format($record);
62
+
63
+ $this->assertCount(7, $formattedRecord);
64
+ $this->assertEquals('some log message', $formattedRecord['message']);
65
+ $this->assertEquals(array(), $formattedRecord['context']);
66
+ $this->assertEquals(Logger::WARNING, $formattedRecord['level']);
67
+ $this->assertEquals(Logger::getLevelName(Logger::WARNING), $formattedRecord['level_name']);
68
+ $this->assertEquals('test', $formattedRecord['channel']);
69
+ $this->assertInstanceOf('\MongoDate', $formattedRecord['datetime']);
70
+ $this->assertEquals('0.00000000 1391212800', $formattedRecord['datetime']->__toString());
71
+ $this->assertEquals(array(), $formattedRecord['extra']);
72
+ }
73
+
74
+ public function testRecursiveFormat()
75
+ {
76
+ $someObject = new \stdClass();
77
+ $someObject->foo = 'something';
78
+ $someObject->bar = 'stuff';
79
+
80
+ $record = array(
81
+ 'message' => 'some log message',
82
+ 'context' => array(
83
+ 'stuff' => new \DateTime('2014-02-01 02:31:33'),
84
+ 'some_object' => $someObject,
85
+ 'context_string' => 'some string',
86
+ 'context_int' => 123456,
87
+ 'except' => new \Exception('exception message', 987),
88
+ ),
89
+ 'level' => Logger::WARNING,
90
+ 'level_name' => Logger::getLevelName(Logger::WARNING),
91
+ 'channel' => 'test',
92
+ 'datetime' => new \DateTime('2014-02-01 00:00:00'),
93
+ 'extra' => array(),
94
+ );
95
+
96
+ $formatter = new MongoDBFormatter();
97
+ $formattedRecord = $formatter->format($record);
98
+
99
+ $this->assertCount(5, $formattedRecord['context']);
100
+ $this->assertInstanceOf('\MongoDate', $formattedRecord['context']['stuff']);
101
+ $this->assertEquals('0.00000000 1391221893', $formattedRecord['context']['stuff']->__toString());
102
+ $this->assertEquals(
103
+ array(
104
+ 'foo' => 'something',
105
+ 'bar' => 'stuff',
106
+ 'class' => 'stdClass',
107
+ ),
108
+ $formattedRecord['context']['some_object']
109
+ );
110
+ $this->assertEquals('some string', $formattedRecord['context']['context_string']);
111
+ $this->assertEquals(123456, $formattedRecord['context']['context_int']);
112
+
113
+ $this->assertCount(5, $formattedRecord['context']['except']);
114
+ $this->assertEquals('exception message', $formattedRecord['context']['except']['message']);
115
+ $this->assertEquals(987, $formattedRecord['context']['except']['code']);
116
+ $this->assertInternalType('string', $formattedRecord['context']['except']['file']);
117
+ $this->assertInternalType('integer', $formattedRecord['context']['except']['code']);
118
+ $this->assertInternalType('string', $formattedRecord['context']['except']['trace']);
119
+ $this->assertEquals('Exception', $formattedRecord['context']['except']['class']);
120
+ }
121
+
122
+ public function testFormatDepthArray()
123
+ {
124
+ $record = array(
125
+ 'message' => 'some log message',
126
+ 'context' => array(
127
+ 'nest2' => array(
128
+ 'property' => 'anything',
129
+ 'nest3' => array(
130
+ 'nest4' => 'value',
131
+ 'property' => 'nothing'
132
+ )
133
+ )
134
+ ),
135
+ 'level' => Logger::WARNING,
136
+ 'level_name' => Logger::getLevelName(Logger::WARNING),
137
+ 'channel' => 'test',
138
+ 'datetime' => new \DateTime('2014-02-01 00:00:00'),
139
+ 'extra' => array(),
140
+ );
141
+
142
+ $formatter = new MongoDBFormatter(2);
143
+ $formattedResult = $formatter->format($record);
144
+
145
+ $this->assertEquals(
146
+ array(
147
+ 'nest2' => array(
148
+ 'property' => 'anything',
149
+ 'nest3' => '[...]',
150
+ )
151
+ ),
152
+ $formattedResult['context']
153
+ );
154
+ }
155
+
156
+ public function testFormatDepthArrayInfiniteNesting()
157
+ {
158
+ $record = array(
159
+ 'message' => 'some log message',
160
+ 'context' => array(
161
+ 'nest2' => array(
162
+ 'property' => 'something',
163
+ 'nest3' => array(
164
+ 'property' => 'anything',
165
+ 'nest4' => array(
166
+ 'property' => 'nothing',
167
+ ),
168
+ )
169
+ )
170
+ ),
171
+ 'level' => Logger::WARNING,
172
+ 'level_name' => Logger::getLevelName(Logger::WARNING),
173
+ 'channel' => 'test',
174
+ 'datetime' => new \DateTime('2014-02-01 00:00:00'),
175
+ 'extra' => array(),
176
+ );
177
+
178
+ $formatter = new MongoDBFormatter(0);
179
+ $formattedResult = $formatter->format($record);
180
+
181
+ $this->assertEquals(
182
+ array(
183
+ 'nest2' => array(
184
+ 'property' => 'something',
185
+ 'nest3' => array(
186
+ 'property' => 'anything',
187
+ 'nest4' => array(
188
+ 'property' => 'nothing',
189
+ )
190
+ ),
191
+ )
192
+ ),
193
+ $formattedResult['context']
194
+ );
195
+ }
196
+
197
+ public function testFormatDepthObjects()
198
+ {
199
+ $someObject = new \stdClass();
200
+ $someObject->property = 'anything';
201
+ $someObject->nest3 = new \stdClass();
202
+ $someObject->nest3->property = 'nothing';
203
+ $someObject->nest3->nest4 = 'invisible';
204
+
205
+ $record = array(
206
+ 'message' => 'some log message',
207
+ 'context' => array(
208
+ 'nest2' => $someObject
209
+ ),
210
+ 'level' => Logger::WARNING,
211
+ 'level_name' => Logger::getLevelName(Logger::WARNING),
212
+ 'channel' => 'test',
213
+ 'datetime' => new \DateTime('2014-02-01 00:00:00'),
214
+ 'extra' => array(),
215
+ );
216
+
217
+ $formatter = new MongoDBFormatter(2, true);
218
+ $formattedResult = $formatter->format($record);
219
+
220
+ $this->assertEquals(
221
+ array(
222
+ 'nest2' => array(
223
+ 'property' => 'anything',
224
+ 'nest3' => '[...]',
225
+ 'class' => 'stdClass',
226
+ ),
227
+ ),
228
+ $formattedResult['context']
229
+ );
230
+ }
231
+
232
+ public function testFormatDepthException()
233
+ {
234
+ $record = array(
235
+ 'message' => 'some log message',
236
+ 'context' => array(
237
+ 'nest2' => new \Exception('exception message', 987),
238
+ ),
239
+ 'level' => Logger::WARNING,
240
+ 'level_name' => Logger::getLevelName(Logger::WARNING),
241
+ 'channel' => 'test',
242
+ 'datetime' => new \DateTime('2014-02-01 00:00:00'),
243
+ 'extra' => array(),
244
+ );
245
+
246
+ $formatter = new MongoDBFormatter(2, false);
247
+ $formattedRecord = $formatter->format($record);
248
+
249
+ $this->assertEquals('exception message', $formattedRecord['context']['nest2']['message']);
250
+ $this->assertEquals(987, $formattedRecord['context']['nest2']['code']);
251
+ $this->assertEquals('[...]', $formattedRecord['context']['nest2']['trace']);
252
+ }
253
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/NormalizerFormatterTest.php ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ /**
15
+ * @covers Monolog\Formatter\NormalizerFormatter
16
+ */
17
+ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase
18
+ {
19
+ public function testFormat()
20
+ {
21
+ $formatter = new NormalizerFormatter('Y-m-d');
22
+ $formatted = $formatter->format(array(
23
+ 'level_name' => 'ERROR',
24
+ 'channel' => 'meh',
25
+ 'message' => 'foo',
26
+ 'datetime' => new \DateTime,
27
+ 'extra' => array('foo' => new TestFooNorm, 'bar' => new TestBarNorm, 'baz' => array(), 'res' => fopen('php://memory', 'rb')),
28
+ 'context' => array(
29
+ 'foo' => 'bar',
30
+ 'baz' => 'qux',
31
+ 'inf' => INF,
32
+ '-inf' => -INF,
33
+ 'nan' => acos(4),
34
+ ),
35
+ ));
36
+
37
+ $this->assertEquals(array(
38
+ 'level_name' => 'ERROR',
39
+ 'channel' => 'meh',
40
+ 'message' => 'foo',
41
+ 'datetime' => date('Y-m-d'),
42
+ 'extra' => array(
43
+ 'foo' => '[object] (Monolog\\Formatter\\TestFooNorm: {"foo":"foo"})',
44
+ 'bar' => '[object] (Monolog\\Formatter\\TestBarNorm: {})',
45
+ 'baz' => array(),
46
+ 'res' => '[resource]',
47
+ ),
48
+ 'context' => array(
49
+ 'foo' => 'bar',
50
+ 'baz' => 'qux',
51
+ 'inf' => 'INF',
52
+ '-inf' => '-INF',
53
+ 'nan' => 'NaN',
54
+ )
55
+ ), $formatted);
56
+ }
57
+
58
+ public function testFormatExceptions()
59
+ {
60
+ $formatter = new NormalizerFormatter('Y-m-d');
61
+ $e = new \LogicException('bar');
62
+ $e2 = new \RuntimeException('foo', 0, $e);
63
+ $formatted = $formatter->format(array(
64
+ 'exception' => $e2,
65
+ ));
66
+
67
+ $this->assertGreaterThan(5, count($formatted['exception']['trace']));
68
+ $this->assertTrue(isset($formatted['exception']['previous']));
69
+ unset($formatted['exception']['trace'], $formatted['exception']['previous']);
70
+
71
+ $this->assertEquals(array(
72
+ 'exception' => array(
73
+ 'class' => get_class($e2),
74
+ 'message' => $e2->getMessage(),
75
+ 'code' => $e2->getCode(),
76
+ 'file' => $e2->getFile().':'.$e2->getLine(),
77
+ )
78
+ ), $formatted);
79
+ }
80
+
81
+ public function testBatchFormat()
82
+ {
83
+ $formatter = new NormalizerFormatter('Y-m-d');
84
+ $formatted = $formatter->formatBatch(array(
85
+ array(
86
+ 'level_name' => 'CRITICAL',
87
+ 'channel' => 'test',
88
+ 'message' => 'bar',
89
+ 'context' => array(),
90
+ 'datetime' => new \DateTime,
91
+ 'extra' => array(),
92
+ ),
93
+ array(
94
+ 'level_name' => 'WARNING',
95
+ 'channel' => 'log',
96
+ 'message' => 'foo',
97
+ 'context' => array(),
98
+ 'datetime' => new \DateTime,
99
+ 'extra' => array(),
100
+ ),
101
+ ));
102
+ $this->assertEquals(array(
103
+ array(
104
+ 'level_name' => 'CRITICAL',
105
+ 'channel' => 'test',
106
+ 'message' => 'bar',
107
+ 'context' => array(),
108
+ 'datetime' => date('Y-m-d'),
109
+ 'extra' => array(),
110
+ ),
111
+ array(
112
+ 'level_name' => 'WARNING',
113
+ 'channel' => 'log',
114
+ 'message' => 'foo',
115
+ 'context' => array(),
116
+ 'datetime' => date('Y-m-d'),
117
+ 'extra' => array(),
118
+ ),
119
+ ), $formatted);
120
+ }
121
+
122
+ /**
123
+ * Test issue #137
124
+ */
125
+ public function testIgnoresRecursiveObjectReferences()
126
+ {
127
+ // set up the recursion
128
+ $foo = new \stdClass();
129
+ $bar = new \stdClass();
130
+
131
+ $foo->bar = $bar;
132
+ $bar->foo = $foo;
133
+
134
+ // set an error handler to assert that the error is not raised anymore
135
+ $that = $this;
136
+ set_error_handler(function ($level, $message, $file, $line, $context) use ($that) {
137
+ if (error_reporting() & $level) {
138
+ restore_error_handler();
139
+ $that->fail("$message should not be raised");
140
+ }
141
+ });
142
+
143
+ $formatter = new NormalizerFormatter();
144
+ $reflMethod = new \ReflectionMethod($formatter, 'toJson');
145
+ $reflMethod->setAccessible(true);
146
+ $res = $reflMethod->invoke($formatter, array($foo, $bar), true);
147
+
148
+ restore_error_handler();
149
+
150
+ $this->assertEquals(@json_encode(array($foo, $bar)), $res);
151
+ }
152
+
153
+ public function testIgnoresInvalidTypes()
154
+ {
155
+ // set up the recursion
156
+ $resource = fopen(__FILE__, 'r');
157
+
158
+ // set an error handler to assert that the error is not raised anymore
159
+ $that = $this;
160
+ set_error_handler(function ($level, $message, $file, $line, $context) use ($that) {
161
+ if (error_reporting() & $level) {
162
+ restore_error_handler();
163
+ $that->fail("$message should not be raised");
164
+ }
165
+ });
166
+
167
+ $formatter = new NormalizerFormatter();
168
+ $reflMethod = new \ReflectionMethod($formatter, 'toJson');
169
+ $reflMethod->setAccessible(true);
170
+ $res = $reflMethod->invoke($formatter, array($resource), true);
171
+
172
+ restore_error_handler();
173
+
174
+ $this->assertEquals(@json_encode(array($resource)), $res);
175
+ }
176
+
177
+ public function testExceptionTraceWithArgs()
178
+ {
179
+ if (defined('HHVM_VERSION')) {
180
+ $this->markTestSkipped('Not supported in HHVM since it detects errors differently');
181
+ }
182
+
183
+ // This happens i.e. in React promises or Guzzle streams where stream wrappers are registered
184
+ // and no file or line are included in the trace because it's treated as internal function
185
+ set_error_handler(function ($errno, $errstr, $errfile, $errline) {
186
+ throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
187
+ });
188
+
189
+ try {
190
+ // This will contain $resource and $wrappedResource as arguments in the trace item
191
+ $resource = fopen('php://memory', 'rw+');
192
+ fwrite($resource, 'test_resource');
193
+ $wrappedResource = new TestStreamFoo($resource);
194
+ // Just do something stupid with a resource/wrapped resource as argument
195
+ array_keys($wrappedResource);
196
+ } catch (\Exception $e) {
197
+ restore_error_handler();
198
+ }
199
+
200
+ $formatter = new NormalizerFormatter();
201
+ $record = array('context' => array('exception' => $e));
202
+ $result = $formatter->format($record);
203
+
204
+ $this->assertRegExp(
205
+ '%"resource":"\[resource\]"%',
206
+ $result['context']['exception']['trace'][0]
207
+ );
208
+
209
+ if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
210
+ $pattern = '%"wrappedResource":"\[object\] \(Monolog\\\\\\\\Formatter\\\\\\\\TestStreamFoo: \)"%';
211
+ } else {
212
+ $pattern = '%\\\\"resource\\\\":null%';
213
+ }
214
+
215
+ // Tests that the wrapped resource is ignored while encoding, only works for PHP <= 5.4
216
+ $this->assertRegExp(
217
+ $pattern,
218
+ $result['context']['exception']['trace'][0]
219
+ );
220
+ }
221
+ }
222
+
223
+ class TestFooNorm
224
+ {
225
+ public $foo = 'foo';
226
+ }
227
+
228
+ class TestBarNorm
229
+ {
230
+ public function __toString()
231
+ {
232
+ return 'bar';
233
+ }
234
+ }
235
+
236
+ class TestStreamFoo
237
+ {
238
+ public $foo;
239
+ public $resource;
240
+
241
+ public function __construct($resource)
242
+ {
243
+ $this->resource = $resource;
244
+ $this->foo = 'BAR';
245
+ }
246
+
247
+ public function __toString()
248
+ {
249
+ fseek($this->resource, 0);
250
+
251
+ return $this->foo . ' - ' . (string) stream_get_contents($this->resource);
252
+ }
253
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/ScalarFormatterTest.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Monolog\Formatter;
3
+
4
+ class ScalarFormatterTest extends \PHPUnit_Framework_TestCase
5
+ {
6
+ public function setUp()
7
+ {
8
+ $this->formatter = new ScalarFormatter();
9
+ }
10
+
11
+ public function buildTrace(\Exception $e)
12
+ {
13
+ $data = array();
14
+ $trace = $e->getTrace();
15
+ foreach ($trace as $frame) {
16
+ if (isset($frame['file'])) {
17
+ $data[] = $frame['file'].':'.$frame['line'];
18
+ } else {
19
+ $data[] = json_encode($frame);
20
+ }
21
+ }
22
+
23
+ return $data;
24
+ }
25
+
26
+ public function encodeJson($data)
27
+ {
28
+ if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
29
+ return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
30
+ }
31
+
32
+ return json_encode($data);
33
+ }
34
+
35
+ public function testFormat()
36
+ {
37
+ $exception = new \Exception('foo');
38
+ $formatted = $this->formatter->format(array(
39
+ 'foo' => 'string',
40
+ 'bar' => 1,
41
+ 'baz' => false,
42
+ 'bam' => array(1, 2, 3),
43
+ 'bat' => array('foo' => 'bar'),
44
+ 'bap' => \DateTime::createFromFormat(\DateTime::ISO8601, '1970-01-01T00:00:00+0000'),
45
+ 'ban' => $exception
46
+ ));
47
+
48
+ $this->assertSame(array(
49
+ 'foo' => 'string',
50
+ 'bar' => 1,
51
+ 'baz' => false,
52
+ 'bam' => $this->encodeJson(array(1, 2, 3)),
53
+ 'bat' => $this->encodeJson(array('foo' => 'bar')),
54
+ 'bap' => '1970-01-01 00:00:00',
55
+ 'ban' => $this->encodeJson(array(
56
+ 'class' => get_class($exception),
57
+ 'message' => $exception->getMessage(),
58
+ 'code' => $exception->getCode(),
59
+ 'file' => $exception->getFile() . ':' . $exception->getLine(),
60
+ 'trace' => $this->buildTrace($exception)
61
+ ))
62
+ ), $formatted);
63
+ }
64
+
65
+ public function testFormatWithErrorContext()
66
+ {
67
+ $context = array('file' => 'foo', 'line' => 1);
68
+ $formatted = $this->formatter->format(array(
69
+ 'context' => $context
70
+ ));
71
+
72
+ $this->assertSame(array(
73
+ 'context' => $this->encodeJson($context)
74
+ ), $formatted);
75
+ }
76
+
77
+ public function testFormatWithExceptionContext()
78
+ {
79
+ $exception = new \Exception('foo');
80
+ $formatted = $this->formatter->format(array(
81
+ 'context' => array(
82
+ 'exception' => $exception
83
+ )
84
+ ));
85
+
86
+ $this->assertSame(array(
87
+ 'context' => $this->encodeJson(array(
88
+ 'exception' => array(
89
+ 'class' => get_class($exception),
90
+ 'message' => $exception->getMessage(),
91
+ 'code' => $exception->getCode(),
92
+ 'file' => $exception->getFile() . ':' . $exception->getLine(),
93
+ 'trace' => $this->buildTrace($exception)
94
+ )
95
+ ))
96
+ ), $formatted);
97
+ }
98
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Formatter/WildfireFormatterTest.php ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Formatter;
13
+
14
+ use Monolog\Logger;
15
+
16
+ class WildfireFormatterTest extends \PHPUnit_Framework_TestCase
17
+ {
18
+ /**
19
+ * @covers Monolog\Formatter\WildfireFormatter::format
20
+ */
21
+ public function testDefaultFormat()
22
+ {
23
+ $wildfire = new WildfireFormatter();
24
+ $record = array(
25
+ 'level' => Logger::ERROR,
26
+ 'level_name' => 'ERROR',
27
+ 'channel' => 'meh',
28
+ 'context' => array('from' => 'logger'),
29
+ 'datetime' => new \DateTime("@0"),
30
+ 'extra' => array('ip' => '127.0.0.1'),
31
+ 'message' => 'log',
32
+ );
33
+
34
+ $message = $wildfire->format($record);
35
+
36
+ $this->assertEquals(
37
+ '125|[{"Type":"ERROR","File":"","Line":"","Label":"meh"},'
38
+ .'{"message":"log","context":{"from":"logger"},"extra":{"ip":"127.0.0.1"}}]|',
39
+ $message
40
+ );
41
+ }
42
+
43
+ /**
44
+ * @covers Monolog\Formatter\WildfireFormatter::format
45
+ */
46
+ public function testFormatWithFileAndLine()
47
+ {
48
+ $wildfire = new WildfireFormatter();
49
+ $record = array(
50
+ 'level' => Logger::ERROR,
51
+ 'level_name' => 'ERROR',
52
+ 'channel' => 'meh',
53
+ 'context' => array('from' => 'logger'),
54
+ 'datetime' => new \DateTime("@0"),
55
+ 'extra' => array('ip' => '127.0.0.1', 'file' => 'test', 'line' => 14),
56
+ 'message' => 'log',
57
+ );
58
+
59
+ $message = $wildfire->format($record);
60
+
61
+ $this->assertEquals(
62
+ '129|[{"Type":"ERROR","File":"test","Line":14,"Label":"meh"},'
63
+ .'{"message":"log","context":{"from":"logger"},"extra":{"ip":"127.0.0.1"}}]|',
64
+ $message
65
+ );
66
+ }
67
+
68
+ /**
69
+ * @covers Monolog\Formatter\WildfireFormatter::format
70
+ */
71
+ public function testFormatWithoutContext()
72
+ {
73
+ $wildfire = new WildfireFormatter();
74
+ $record = array(
75
+ 'level' => Logger::ERROR,
76
+ 'level_name' => 'ERROR',
77
+ 'channel' => 'meh',
78
+ 'context' => array(),
79
+ 'datetime' => new \DateTime("@0"),
80
+ 'extra' => array(),
81
+ 'message' => 'log',
82
+ );
83
+
84
+ $message = $wildfire->format($record);
85
+
86
+ $this->assertEquals(
87
+ '58|[{"Type":"ERROR","File":"","Line":"","Label":"meh"},"log"]|',
88
+ $message
89
+ );
90
+ }
91
+
92
+ /**
93
+ * @covers Monolog\Formatter\WildfireFormatter::formatBatch
94
+ * @expectedException BadMethodCallException
95
+ */
96
+ public function testBatchFormatThrowException()
97
+ {
98
+ $wildfire = new WildfireFormatter();
99
+ $record = array(
100
+ 'level' => Logger::ERROR,
101
+ 'level_name' => 'ERROR',
102
+ 'channel' => 'meh',
103
+ 'context' => array(),
104
+ 'datetime' => new \DateTime("@0"),
105
+ 'extra' => array(),
106
+ 'message' => 'log',
107
+ );
108
+
109
+ $wildfire->formatBatch(array($record));
110
+ }
111
+
112
+ /**
113
+ * @covers Monolog\Formatter\WildfireFormatter::format
114
+ */
115
+ public function testTableFormat()
116
+ {
117
+ $wildfire = new WildfireFormatter();
118
+ $record = array(
119
+ 'level' => Logger::ERROR,
120
+ 'level_name' => 'ERROR',
121
+ 'channel' => 'table-channel',
122
+ 'context' => array(
123
+ WildfireFormatter::TABLE => array(
124
+ array('col1', 'col2', 'col3'),
125
+ array('val1', 'val2', 'val3'),
126
+ array('foo1', 'foo2', 'foo3'),
127
+ array('bar1', 'bar2', 'bar3'),
128
+ ),
129
+ ),
130
+ 'datetime' => new \DateTime("@0"),
131
+ 'extra' => array(),
132
+ 'message' => 'table-message',
133
+ );
134
+
135
+ $message = $wildfire->format($record);
136
+
137
+ $this->assertEquals(
138
+ '171|[{"Type":"TABLE","File":"","Line":"","Label":"table-channel: table-message"},[["col1","col2","col3"],["val1","val2","val3"],["foo1","foo2","foo3"],["bar1","bar2","bar3"]]]|',
139
+ $message
140
+ );
141
+ }
142
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/AbstractHandlerTest.php ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+ use Monolog\Formatter\LineFormatter;
17
+ use Monolog\Processor\WebProcessor;
18
+
19
+ class AbstractHandlerTest extends TestCase
20
+ {
21
+ /**
22
+ * @covers Monolog\Handler\AbstractHandler::__construct
23
+ * @covers Monolog\Handler\AbstractHandler::getLevel
24
+ * @covers Monolog\Handler\AbstractHandler::setLevel
25
+ * @covers Monolog\Handler\AbstractHandler::getBubble
26
+ * @covers Monolog\Handler\AbstractHandler::setBubble
27
+ * @covers Monolog\Handler\AbstractHandler::getFormatter
28
+ * @covers Monolog\Handler\AbstractHandler::setFormatter
29
+ */
30
+ public function testConstructAndGetSet()
31
+ {
32
+ $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', array(Logger::WARNING, false));
33
+ $this->assertEquals(Logger::WARNING, $handler->getLevel());
34
+ $this->assertEquals(false, $handler->getBubble());
35
+
36
+ $handler->setLevel(Logger::ERROR);
37
+ $handler->setBubble(true);
38
+ $handler->setFormatter($formatter = new LineFormatter);
39
+ $this->assertEquals(Logger::ERROR, $handler->getLevel());
40
+ $this->assertEquals(true, $handler->getBubble());
41
+ $this->assertSame($formatter, $handler->getFormatter());
42
+ }
43
+
44
+ /**
45
+ * @covers Monolog\Handler\AbstractHandler::handleBatch
46
+ */
47
+ public function testHandleBatch()
48
+ {
49
+ $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler');
50
+ $handler->expects($this->exactly(2))
51
+ ->method('handle');
52
+ $handler->handleBatch(array($this->getRecord(), $this->getRecord()));
53
+ }
54
+
55
+ /**
56
+ * @covers Monolog\Handler\AbstractHandler::isHandling
57
+ */
58
+ public function testIsHandling()
59
+ {
60
+ $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', array(Logger::WARNING, false));
61
+ $this->assertTrue($handler->isHandling($this->getRecord()));
62
+ $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG)));
63
+ }
64
+
65
+ /**
66
+ * @covers Monolog\Handler\AbstractHandler::__construct
67
+ */
68
+ public function testHandlesPsrStyleLevels()
69
+ {
70
+ $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler', array('warning', false));
71
+ $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG)));
72
+ $handler->setLevel('debug');
73
+ $this->assertTrue($handler->isHandling($this->getRecord(Logger::DEBUG)));
74
+ }
75
+
76
+ /**
77
+ * @covers Monolog\Handler\AbstractHandler::getFormatter
78
+ * @covers Monolog\Handler\AbstractHandler::getDefaultFormatter
79
+ */
80
+ public function testGetFormatterInitializesDefault()
81
+ {
82
+ $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler');
83
+ $this->assertInstanceOf('Monolog\Formatter\LineFormatter', $handler->getFormatter());
84
+ }
85
+
86
+ /**
87
+ * @covers Monolog\Handler\AbstractHandler::pushProcessor
88
+ * @covers Monolog\Handler\AbstractHandler::popProcessor
89
+ * @expectedException LogicException
90
+ */
91
+ public function testPushPopProcessor()
92
+ {
93
+ $logger = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler');
94
+ $processor1 = new WebProcessor;
95
+ $processor2 = new WebProcessor;
96
+
97
+ $logger->pushProcessor($processor1);
98
+ $logger->pushProcessor($processor2);
99
+
100
+ $this->assertEquals($processor2, $logger->popProcessor());
101
+ $this->assertEquals($processor1, $logger->popProcessor());
102
+ $logger->popProcessor();
103
+ }
104
+
105
+ /**
106
+ * @covers Monolog\Handler\AbstractHandler::pushProcessor
107
+ * @expectedException InvalidArgumentException
108
+ */
109
+ public function testPushProcessorWithNonCallable()
110
+ {
111
+ $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractHandler');
112
+
113
+ $handler->pushProcessor(new \stdClass());
114
+ }
115
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/AbstractProcessingHandlerTest.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+ use Monolog\Processor\WebProcessor;
17
+
18
+ class AbstractProcessingHandlerTest extends TestCase
19
+ {
20
+ /**
21
+ * @covers Monolog\Handler\AbstractProcessingHandler::handle
22
+ */
23
+ public function testHandleLowerLevelMessage()
24
+ {
25
+ $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::WARNING, true));
26
+ $this->assertFalse($handler->handle($this->getRecord(Logger::DEBUG)));
27
+ }
28
+
29
+ /**
30
+ * @covers Monolog\Handler\AbstractProcessingHandler::handle
31
+ */
32
+ public function testHandleBubbling()
33
+ {
34
+ $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::DEBUG, true));
35
+ $this->assertFalse($handler->handle($this->getRecord()));
36
+ }
37
+
38
+ /**
39
+ * @covers Monolog\Handler\AbstractProcessingHandler::handle
40
+ */
41
+ public function testHandleNotBubbling()
42
+ {
43
+ $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::DEBUG, false));
44
+ $this->assertTrue($handler->handle($this->getRecord()));
45
+ }
46
+
47
+ /**
48
+ * @covers Monolog\Handler\AbstractProcessingHandler::handle
49
+ */
50
+ public function testHandleIsFalseWhenNotHandled()
51
+ {
52
+ $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler', array(Logger::WARNING, false));
53
+ $this->assertTrue($handler->handle($this->getRecord()));
54
+ $this->assertFalse($handler->handle($this->getRecord(Logger::DEBUG)));
55
+ }
56
+
57
+ /**
58
+ * @covers Monolog\Handler\AbstractProcessingHandler::processRecord
59
+ */
60
+ public function testProcessRecord()
61
+ {
62
+ $handler = $this->getMockForAbstractClass('Monolog\Handler\AbstractProcessingHandler');
63
+ $handler->pushProcessor(new WebProcessor(array(
64
+ 'REQUEST_URI' => '',
65
+ 'REQUEST_METHOD' => '',
66
+ 'REMOTE_ADDR' => '',
67
+ 'SERVER_NAME' => '',
68
+ 'UNIQUE_ID' => '',
69
+ )));
70
+ $handledRecord = null;
71
+ $handler->expects($this->once())
72
+ ->method('write')
73
+ ->will($this->returnCallback(function ($record) use (&$handledRecord) {
74
+ $handledRecord = $record;
75
+ }))
76
+ ;
77
+ $handler->handle($this->getRecord());
78
+ $this->assertEquals(6, count($handledRecord['extra']));
79
+ }
80
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/AmqpHandlerTest.php ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+ use PhpAmqpLib\Message\AMQPMessage;
17
+ use PhpAmqpLib\Channel\AMQPChannel;
18
+ use PhpAmqpLib\Connection\AMQPConnection;
19
+
20
+ /**
21
+ * @covers Monolog\Handler\RotatingFileHandler
22
+ */
23
+ class AmqpHandlerTest extends TestCase
24
+ {
25
+ public function testHandleAmqpExt()
26
+ {
27
+ if (!class_exists('AMQPConnection') || !class_exists('AMQPExchange')) {
28
+ $this->markTestSkipped("amqp-php not installed");
29
+ }
30
+
31
+ if (!class_exists('AMQPChannel')) {
32
+ $this->markTestSkipped("Please update AMQP to version >= 1.0");
33
+ }
34
+
35
+ $messages = array();
36
+
37
+ $exchange = $this->getMock('AMQPExchange', array('publish', 'setName'), array(), '', false);
38
+ $exchange->expects($this->once())
39
+ ->method('setName')
40
+ ->with('log')
41
+ ;
42
+ $exchange->expects($this->any())
43
+ ->method('publish')
44
+ ->will($this->returnCallback(function ($message, $routing_key, $flags = 0, $attributes = array()) use (&$messages) {
45
+ $messages[] = array($message, $routing_key, $flags, $attributes);
46
+ }))
47
+ ;
48
+
49
+ $handler = new AmqpHandler($exchange, 'log');
50
+
51
+ $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
52
+
53
+ $expected = array(
54
+ array(
55
+ 'message' => 'test',
56
+ 'context' => array(
57
+ 'data' => array(),
58
+ 'foo' => 34,
59
+ ),
60
+ 'level' => 300,
61
+ 'level_name' => 'WARNING',
62
+ 'channel' => 'test',
63
+ 'extra' => array(),
64
+ ),
65
+ 'warn.test',
66
+ 0,
67
+ array(
68
+ 'delivery_mode' => 2,
69
+ 'Content-type' => 'application/json'
70
+ )
71
+ );
72
+
73
+ $handler->handle($record);
74
+
75
+ $this->assertCount(1, $messages);
76
+ $messages[0][0] = json_decode($messages[0][0], true);
77
+ unset($messages[0][0]['datetime']);
78
+ $this->assertEquals($expected, $messages[0]);
79
+ }
80
+
81
+ public function testHandlePhpAmqpLib()
82
+ {
83
+ if (!class_exists('PhpAmqpLib\Connection\AMQPConnection')) {
84
+ $this->markTestSkipped("php-amqplib not installed");
85
+ }
86
+
87
+ $messages = array();
88
+
89
+ $exchange = $this->getMock('PhpAmqpLib\Channel\AMQPChannel', array('basic_publish', '__destruct'), array(), '', false);
90
+
91
+ $exchange->expects($this->any())
92
+ ->method('basic_publish')
93
+ ->will($this->returnCallback(function (AMQPMessage $msg, $exchange = "", $routing_key = "", $mandatory = false, $immediate = false, $ticket = null) use (&$messages) {
94
+ $messages[] = array($msg, $exchange, $routing_key, $mandatory, $immediate, $ticket);
95
+ }))
96
+ ;
97
+
98
+ $handler = new AmqpHandler($exchange, 'log');
99
+
100
+ $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
101
+
102
+ $expected = array(
103
+ array(
104
+ 'message' => 'test',
105
+ 'context' => array(
106
+ 'data' => array(),
107
+ 'foo' => 34,
108
+ ),
109
+ 'level' => 300,
110
+ 'level_name' => 'WARNING',
111
+ 'channel' => 'test',
112
+ 'extra' => array(),
113
+ ),
114
+ 'log',
115
+ 'warn.test',
116
+ false,
117
+ false,
118
+ null,
119
+ array(
120
+ 'delivery_mode' => 2,
121
+ 'content_type' => 'application/json'
122
+ )
123
+ );
124
+
125
+ $handler->handle($record);
126
+
127
+ $this->assertCount(1, $messages);
128
+
129
+ /* @var $msg AMQPMessage */
130
+ $msg = $messages[0][0];
131
+ $messages[0][0] = json_decode($msg->body, true);
132
+ $messages[0][] = $msg->get_properties();
133
+ unset($messages[0][0]['datetime']);
134
+
135
+ $this->assertEquals($expected, $messages[0]);
136
+ }
137
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/BrowserConsoleHandlerTest.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+
17
+ /**
18
+ * @covers Monolog\Handler\BrowserConsoleHandlerTest
19
+ */
20
+ class BrowserConsoleHandlerTest extends TestCase
21
+ {
22
+ protected function setUp()
23
+ {
24
+ BrowserConsoleHandler::reset();
25
+ }
26
+
27
+ protected function generateScript()
28
+ {
29
+ $reflMethod = new \ReflectionMethod('Monolog\Handler\BrowserConsoleHandler', 'generateScript');
30
+ $reflMethod->setAccessible(true);
31
+
32
+ return $reflMethod->invoke(null);
33
+ }
34
+
35
+ public function testStyling()
36
+ {
37
+ $handler = new BrowserConsoleHandler();
38
+ $handler->setFormatter($this->getIdentityFormatter());
39
+
40
+ $handler->handle($this->getRecord(Logger::DEBUG, 'foo[[bar]]{color: red}'));
41
+
42
+ $expected = <<<EOF
43
+ (function (c) {if (c && c.groupCollapsed) {
44
+ c.log("%cfoo%cbar%c", "font-weight: normal", "color: red", "font-weight: normal");
45
+ }})(console);
46
+ EOF;
47
+
48
+ $this->assertEquals($expected, $this->generateScript());
49
+ }
50
+
51
+ public function testEscaping()
52
+ {
53
+ $handler = new BrowserConsoleHandler();
54
+ $handler->setFormatter($this->getIdentityFormatter());
55
+
56
+ $handler->handle($this->getRecord(Logger::DEBUG, "[foo] [[\"bar\n[baz]\"]]{color: red}"));
57
+
58
+ $expected = <<<EOF
59
+ (function (c) {if (c && c.groupCollapsed) {
60
+ c.log("%c[foo] %c\"bar\\n[baz]\"%c", "font-weight: normal", "color: red", "font-weight: normal");
61
+ }})(console);
62
+ EOF;
63
+
64
+ $this->assertEquals($expected, $this->generateScript());
65
+ }
66
+
67
+ public function testAutolabel()
68
+ {
69
+ $handler = new BrowserConsoleHandler();
70
+ $handler->setFormatter($this->getIdentityFormatter());
71
+
72
+ $handler->handle($this->getRecord(Logger::DEBUG, '[[foo]]{macro: autolabel}'));
73
+ $handler->handle($this->getRecord(Logger::DEBUG, '[[bar]]{macro: autolabel}'));
74
+ $handler->handle($this->getRecord(Logger::DEBUG, '[[foo]]{macro: autolabel}'));
75
+
76
+ $expected = <<<EOF
77
+ (function (c) {if (c && c.groupCollapsed) {
78
+ c.log("%c%cfoo%c", "font-weight: normal", "background-color: blue; color: white; border-radius: 3px; padding: 0 2px 0 2px", "font-weight: normal");
79
+ c.log("%c%cbar%c", "font-weight: normal", "background-color: green; color: white; border-radius: 3px; padding: 0 2px 0 2px", "font-weight: normal");
80
+ c.log("%c%cfoo%c", "font-weight: normal", "background-color: blue; color: white; border-radius: 3px; padding: 0 2px 0 2px", "font-weight: normal");
81
+ }})(console);
82
+ EOF;
83
+
84
+ $this->assertEquals($expected, $this->generateScript());
85
+ }
86
+
87
+ public function testContext()
88
+ {
89
+ $handler = new BrowserConsoleHandler();
90
+ $handler->setFormatter($this->getIdentityFormatter());
91
+
92
+ $handler->handle($this->getRecord(Logger::DEBUG, 'test', array('foo' => 'bar')));
93
+
94
+ $expected = <<<EOF
95
+ (function (c) {if (c && c.groupCollapsed) {
96
+ c.groupCollapsed("%ctest", "font-weight: normal");
97
+ c.log("%c%s", "font-weight: bold", "Context");
98
+ c.log("%s: %o", "foo", "bar");
99
+ c.groupEnd();
100
+ }})(console);
101
+ EOF;
102
+
103
+ $this->assertEquals($expected, $this->generateScript());
104
+ }
105
+
106
+ public function testConcurrentHandlers()
107
+ {
108
+ $handler1 = new BrowserConsoleHandler();
109
+ $handler1->setFormatter($this->getIdentityFormatter());
110
+
111
+ $handler2 = new BrowserConsoleHandler();
112
+ $handler2->setFormatter($this->getIdentityFormatter());
113
+
114
+ $handler1->handle($this->getRecord(Logger::DEBUG, 'test1'));
115
+ $handler2->handle($this->getRecord(Logger::DEBUG, 'test2'));
116
+ $handler1->handle($this->getRecord(Logger::DEBUG, 'test3'));
117
+ $handler2->handle($this->getRecord(Logger::DEBUG, 'test4'));
118
+
119
+ $expected = <<<EOF
120
+ (function (c) {if (c && c.groupCollapsed) {
121
+ c.log("%ctest1", "font-weight: normal");
122
+ c.log("%ctest2", "font-weight: normal");
123
+ c.log("%ctest3", "font-weight: normal");
124
+ c.log("%ctest4", "font-weight: normal");
125
+ }})(console);
126
+ EOF;
127
+
128
+ $this->assertEquals($expected, $this->generateScript());
129
+ }
130
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/BufferHandlerTest.php ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+
17
+ class BufferHandlerTest extends TestCase
18
+ {
19
+ private $shutdownCheckHandler;
20
+
21
+ /**
22
+ * @covers Monolog\Handler\BufferHandler::__construct
23
+ * @covers Monolog\Handler\BufferHandler::handle
24
+ * @covers Monolog\Handler\BufferHandler::close
25
+ */
26
+ public function testHandleBuffers()
27
+ {
28
+ $test = new TestHandler();
29
+ $handler = new BufferHandler($test);
30
+ $handler->handle($this->getRecord(Logger::DEBUG));
31
+ $handler->handle($this->getRecord(Logger::INFO));
32
+ $this->assertFalse($test->hasDebugRecords());
33
+ $this->assertFalse($test->hasInfoRecords());
34
+ $handler->close();
35
+ $this->assertTrue($test->hasInfoRecords());
36
+ $this->assertTrue(count($test->getRecords()) === 2);
37
+ }
38
+
39
+ /**
40
+ * @covers Monolog\Handler\BufferHandler::close
41
+ * @covers Monolog\Handler\BufferHandler::flush
42
+ */
43
+ public function testPropagatesRecordsAtEndOfRequest()
44
+ {
45
+ $test = new TestHandler();
46
+ $handler = new BufferHandler($test);
47
+ $handler->handle($this->getRecord(Logger::WARNING));
48
+ $handler->handle($this->getRecord(Logger::DEBUG));
49
+ $this->shutdownCheckHandler = $test;
50
+ register_shutdown_function(array($this, 'checkPropagation'));
51
+ }
52
+
53
+ public function checkPropagation()
54
+ {
55
+ if (!$this->shutdownCheckHandler->hasWarningRecords() || !$this->shutdownCheckHandler->hasDebugRecords()) {
56
+ echo '!!! BufferHandlerTest::testPropagatesRecordsAtEndOfRequest failed to verify that the messages have been propagated' . PHP_EOL;
57
+ exit(1);
58
+ }
59
+ }
60
+
61
+ /**
62
+ * @covers Monolog\Handler\BufferHandler::handle
63
+ */
64
+ public function testHandleBufferLimit()
65
+ {
66
+ $test = new TestHandler();
67
+ $handler = new BufferHandler($test, 2);
68
+ $handler->handle($this->getRecord(Logger::DEBUG));
69
+ $handler->handle($this->getRecord(Logger::DEBUG));
70
+ $handler->handle($this->getRecord(Logger::INFO));
71
+ $handler->handle($this->getRecord(Logger::WARNING));
72
+ $handler->close();
73
+ $this->assertTrue($test->hasWarningRecords());
74
+ $this->assertTrue($test->hasInfoRecords());
75
+ $this->assertFalse($test->hasDebugRecords());
76
+ }
77
+
78
+ /**
79
+ * @covers Monolog\Handler\BufferHandler::handle
80
+ */
81
+ public function testHandleBufferLimitWithFlushOnOverflow()
82
+ {
83
+ $test = new TestHandler();
84
+ $handler = new BufferHandler($test, 3, Logger::DEBUG, true, true);
85
+
86
+ // send two records
87
+ $handler->handle($this->getRecord(Logger::DEBUG));
88
+ $handler->handle($this->getRecord(Logger::DEBUG));
89
+ $handler->handle($this->getRecord(Logger::DEBUG));
90
+ $this->assertFalse($test->hasDebugRecords());
91
+ $this->assertCount(0, $test->getRecords());
92
+
93
+ // overflow
94
+ $handler->handle($this->getRecord(Logger::INFO));
95
+ $this->assertTrue($test->hasDebugRecords());
96
+ $this->assertCount(3, $test->getRecords());
97
+
98
+ // should buffer again
99
+ $handler->handle($this->getRecord(Logger::WARNING));
100
+ $this->assertCount(3, $test->getRecords());
101
+
102
+ $handler->close();
103
+ $this->assertCount(5, $test->getRecords());
104
+ $this->assertTrue($test->hasWarningRecords());
105
+ $this->assertTrue($test->hasInfoRecords());
106
+ }
107
+
108
+ /**
109
+ * @covers Monolog\Handler\BufferHandler::handle
110
+ */
111
+ public function testHandleLevel()
112
+ {
113
+ $test = new TestHandler();
114
+ $handler = new BufferHandler($test, 0, Logger::INFO);
115
+ $handler->handle($this->getRecord(Logger::DEBUG));
116
+ $handler->handle($this->getRecord(Logger::INFO));
117
+ $handler->handle($this->getRecord(Logger::WARNING));
118
+ $handler->handle($this->getRecord(Logger::DEBUG));
119
+ $handler->close();
120
+ $this->assertTrue($test->hasWarningRecords());
121
+ $this->assertTrue($test->hasInfoRecords());
122
+ $this->assertFalse($test->hasDebugRecords());
123
+ }
124
+
125
+ /**
126
+ * @covers Monolog\Handler\BufferHandler::flush
127
+ */
128
+ public function testFlush()
129
+ {
130
+ $test = new TestHandler();
131
+ $handler = new BufferHandler($test, 0);
132
+ $handler->handle($this->getRecord(Logger::DEBUG));
133
+ $handler->handle($this->getRecord(Logger::INFO));
134
+ $handler->flush();
135
+ $this->assertTrue($test->hasInfoRecords());
136
+ $this->assertTrue($test->hasDebugRecords());
137
+ $this->assertFalse($test->hasWarningRecords());
138
+ }
139
+
140
+ /**
141
+ * @covers Monolog\Handler\BufferHandler::handle
142
+ */
143
+ public function testHandleUsesProcessors()
144
+ {
145
+ $test = new TestHandler();
146
+ $handler = new BufferHandler($test);
147
+ $handler->pushProcessor(function ($record) {
148
+ $record['extra']['foo'] = true;
149
+
150
+ return $record;
151
+ });
152
+ $handler->handle($this->getRecord(Logger::WARNING));
153
+ $handler->flush();
154
+ $this->assertTrue($test->hasWarningRecords());
155
+ $records = $test->getRecords();
156
+ $this->assertTrue($records[0]['extra']['foo']);
157
+ }
158
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/ChromePHPHandlerTest.php ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+
17
+ /**
18
+ * @covers Monolog\Handler\ChromePHPHandler
19
+ */
20
+ class ChromePHPHandlerTest extends TestCase
21
+ {
22
+ protected function setUp()
23
+ {
24
+ TestChromePHPHandler::reset();
25
+ $_SERVER['HTTP_USER_AGENT'] = 'Monolog Test; Chrome/1.0';
26
+ }
27
+
28
+ public function testHeaders()
29
+ {
30
+ $handler = new TestChromePHPHandler();
31
+ $handler->setFormatter($this->getIdentityFormatter());
32
+ $handler->handle($this->getRecord(Logger::DEBUG));
33
+ $handler->handle($this->getRecord(Logger::WARNING));
34
+
35
+ $expected = array(
36
+ 'X-ChromeLogger-Data' => base64_encode(utf8_encode(json_encode(array(
37
+ 'version' => ChromePHPHandler::VERSION,
38
+ 'columns' => array('label', 'log', 'backtrace', 'type'),
39
+ 'rows' => array(
40
+ 'test',
41
+ 'test',
42
+ ),
43
+ 'request_uri' => '',
44
+ ))))
45
+ );
46
+
47
+ $this->assertEquals($expected, $handler->getHeaders());
48
+ }
49
+
50
+ public function testHeadersOverflow()
51
+ {
52
+ $handler = new TestChromePHPHandler();
53
+ $handler->handle($this->getRecord(Logger::DEBUG));
54
+ $handler->handle($this->getRecord(Logger::WARNING, str_repeat('a', 150*1024)));
55
+
56
+ // overflow chrome headers limit
57
+ $handler->handle($this->getRecord(Logger::WARNING, str_repeat('a', 100*1024)));
58
+
59
+ $expected = array(
60
+ 'X-ChromeLogger-Data' => base64_encode(utf8_encode(json_encode(array(
61
+ 'version' => ChromePHPHandler::VERSION,
62
+ 'columns' => array('label', 'log', 'backtrace', 'type'),
63
+ 'rows' => array(
64
+ array(
65
+ 'test',
66
+ 'test',
67
+ 'unknown',
68
+ 'log',
69
+ ),
70
+ array(
71
+ 'test',
72
+ str_repeat('a', 150*1024),
73
+ 'unknown',
74
+ 'warn',
75
+ ),
76
+ array(
77
+ 'monolog',
78
+ 'Incomplete logs, chrome header size limit reached',
79
+ 'unknown',
80
+ 'warn',
81
+ ),
82
+ ),
83
+ 'request_uri' => '',
84
+ ))))
85
+ );
86
+
87
+ $this->assertEquals($expected, $handler->getHeaders());
88
+ }
89
+
90
+ public function testConcurrentHandlers()
91
+ {
92
+ $handler = new TestChromePHPHandler();
93
+ $handler->setFormatter($this->getIdentityFormatter());
94
+ $handler->handle($this->getRecord(Logger::DEBUG));
95
+ $handler->handle($this->getRecord(Logger::WARNING));
96
+
97
+ $handler2 = new TestChromePHPHandler();
98
+ $handler2->setFormatter($this->getIdentityFormatter());
99
+ $handler2->handle($this->getRecord(Logger::DEBUG));
100
+ $handler2->handle($this->getRecord(Logger::WARNING));
101
+
102
+ $expected = array(
103
+ 'X-ChromeLogger-Data' => base64_encode(utf8_encode(json_encode(array(
104
+ 'version' => ChromePHPHandler::VERSION,
105
+ 'columns' => array('label', 'log', 'backtrace', 'type'),
106
+ 'rows' => array(
107
+ 'test',
108
+ 'test',
109
+ 'test',
110
+ 'test',
111
+ ),
112
+ 'request_uri' => '',
113
+ ))))
114
+ );
115
+
116
+ $this->assertEquals($expected, $handler2->getHeaders());
117
+ }
118
+ }
119
+
120
+ class TestChromePHPHandler extends ChromePHPHandler
121
+ {
122
+ protected $headers = array();
123
+
124
+ public static function reset()
125
+ {
126
+ self::$initialized = false;
127
+ self::$overflowed = false;
128
+ self::$sendHeaders = true;
129
+ self::$json['rows'] = array();
130
+ }
131
+
132
+ protected function sendHeader($header, $content)
133
+ {
134
+ $this->headers[$header] = $content;
135
+ }
136
+
137
+ public function getHeaders()
138
+ {
139
+ return $this->headers;
140
+ }
141
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/CouchDBHandlerTest.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+
17
+ class CouchDBHandlerTest extends TestCase
18
+ {
19
+ public function testHandle()
20
+ {
21
+ $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
22
+
23
+ $expected = array(
24
+ 'message' => 'test',
25
+ 'context' => array('data' => '[object] (stdClass: {})', 'foo' => 34),
26
+ 'level' => Logger::WARNING,
27
+ 'level_name' => 'WARNING',
28
+ 'channel' => 'test',
29
+ 'datetime' => $record['datetime']->format('Y-m-d H:i:s'),
30
+ 'extra' => array(),
31
+ );
32
+
33
+ $handler = new CouchDBHandler();
34
+
35
+ try {
36
+ $handler->handle($record);
37
+ } catch (\RuntimeException $e) {
38
+ $this->markTestSkipped('Could not connect to couchdb server on http://localhost:5984');
39
+ }
40
+ }
41
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+
17
+ class DoctrineCouchDBHandlerTest extends TestCase
18
+ {
19
+ protected function setup()
20
+ {
21
+ if (!class_exists('Doctrine\CouchDB\CouchDBClient')) {
22
+ $this->markTestSkipped('The "doctrine/couchdb" package is not installed');
23
+ }
24
+ }
25
+
26
+ public function testHandle()
27
+ {
28
+ $client = $this->getMockBuilder('Doctrine\\CouchDB\\CouchDBClient')
29
+ ->setMethods(array('postDocument'))
30
+ ->disableOriginalConstructor()
31
+ ->getMock();
32
+
33
+ $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
34
+
35
+ $expected = array(
36
+ 'message' => 'test',
37
+ 'context' => array('data' => '[object] (stdClass: {})', 'foo' => 34),
38
+ 'level' => Logger::WARNING,
39
+ 'level_name' => 'WARNING',
40
+ 'channel' => 'test',
41
+ 'datetime' => $record['datetime']->format('Y-m-d H:i:s'),
42
+ 'extra' => array(),
43
+ );
44
+
45
+ $client->expects($this->once())
46
+ ->method('postDocument')
47
+ ->with($expected);
48
+
49
+ $handler = new DoctrineCouchDBHandler($client);
50
+ $handler->handle($record);
51
+ }
52
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/DynamoDbHandlerTest.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+
16
+ class DynamoDbHandlerTest extends TestCase
17
+ {
18
+ public function setUp()
19
+ {
20
+ if (!class_exists('Aws\DynamoDb\DynamoDbClient')) {
21
+ $this->markTestSkipped('aws/aws-sdk-php not installed');
22
+ }
23
+
24
+ $this->client = $this->getMockBuilder('Aws\DynamoDb\DynamoDbClient')
25
+ ->setMethods(array('formatAttributes', '__call'))
26
+ ->disableOriginalConstructor()->getMock();
27
+ }
28
+
29
+ public function testConstruct()
30
+ {
31
+ $this->assertInstanceOf('Monolog\Handler\DynamoDbHandler', new DynamoDbHandler($this->client, 'foo'));
32
+ }
33
+
34
+ public function testInterface()
35
+ {
36
+ $this->assertInstanceOf('Monolog\Handler\HandlerInterface', new DynamoDbHandler($this->client, 'foo'));
37
+ }
38
+
39
+ public function testGetFormatter()
40
+ {
41
+ $handler = new DynamoDbHandler($this->client, 'foo');
42
+ $this->assertInstanceOf('Monolog\Formatter\ScalarFormatter', $handler->getFormatter());
43
+ }
44
+
45
+ public function testHandle()
46
+ {
47
+ $record = $this->getRecord();
48
+ $formatter = $this->getMock('Monolog\Formatter\FormatterInterface');
49
+ $formatted = array('foo' => 1, 'bar' => 2);
50
+ $handler = new DynamoDbHandler($this->client, 'foo');
51
+ $handler->setFormatter($formatter);
52
+
53
+ $formatter
54
+ ->expects($this->once())
55
+ ->method('format')
56
+ ->with($record)
57
+ ->will($this->returnValue($formatted));
58
+ $this->client
59
+ ->expects($this->once())
60
+ ->method('formatAttributes')
61
+ ->with($this->isType('array'))
62
+ ->will($this->returnValue($formatted));
63
+ $this->client
64
+ ->expects($this->once())
65
+ ->method('__call')
66
+ ->with('putItem', array(array(
67
+ 'TableName' => 'foo',
68
+ 'Item' => $formatted
69
+ )));
70
+
71
+ $handler->handle($record);
72
+ }
73
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/ElasticSearchHandlerTest.php ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Formatter\ElasticaFormatter;
15
+ use Monolog\Formatter\NormalizerFormatter;
16
+ use Monolog\TestCase;
17
+ use Monolog\Logger;
18
+ use Elastica\Client;
19
+ use Elastica\Request;
20
+ use Elastica\Response;
21
+
22
+ class ElasticSearchHandlerTest extends TestCase
23
+ {
24
+ /**
25
+ * @var Client mock
26
+ */
27
+ protected $client;
28
+
29
+ /**
30
+ * @var array Default handler options
31
+ */
32
+ protected $options = array(
33
+ 'index' => 'my_index',
34
+ 'type' => 'doc_type',
35
+ );
36
+
37
+ public function setUp()
38
+ {
39
+ // Elastica lib required
40
+ if (!class_exists("Elastica\Client")) {
41
+ $this->markTestSkipped("ruflin/elastica not installed");
42
+ }
43
+
44
+ // base mock Elastica Client object
45
+ $this->client = $this->getMockBuilder('Elastica\Client')
46
+ ->setMethods(array('addDocuments'))
47
+ ->disableOriginalConstructor()
48
+ ->getMock();
49
+ }
50
+
51
+ /**
52
+ * @covers Monolog\Handler\ElasticSearchHandler::write
53
+ * @covers Monolog\Handler\ElasticSearchHandler::handleBatch
54
+ * @covers Monolog\Handler\ElasticSearchHandler::bulkSend
55
+ * @covers Monolog\Handler\ElasticSearchHandler::getDefaultFormatter
56
+ */
57
+ public function testHandle()
58
+ {
59
+ // log message
60
+ $msg = array(
61
+ 'level' => Logger::ERROR,
62
+ 'level_name' => 'ERROR',
63
+ 'channel' => 'meh',
64
+ 'context' => array('foo' => 7, 'bar', 'class' => new \stdClass),
65
+ 'datetime' => new \DateTime("@0"),
66
+ 'extra' => array(),
67
+ 'message' => 'log',
68
+ );
69
+
70
+ // format expected result
71
+ $formatter = new ElasticaFormatter($this->options['index'], $this->options['type']);
72
+ $expected = array($formatter->format($msg));
73
+
74
+ // setup ES client mock
75
+ $this->client->expects($this->any())
76
+ ->method('addDocuments')
77
+ ->with($expected);
78
+
79
+ // perform tests
80
+ $handler = new ElasticSearchHandler($this->client, $this->options);
81
+ $handler->handle($msg);
82
+ $handler->handleBatch(array($msg));
83
+ }
84
+
85
+ /**
86
+ * @covers Monolog\Handler\ElasticSearchHandler::setFormatter
87
+ */
88
+ public function testSetFormatter()
89
+ {
90
+ $handler = new ElasticSearchHandler($this->client);
91
+ $formatter = new ElasticaFormatter('index_new', 'type_new');
92
+ $handler->setFormatter($formatter);
93
+ $this->assertInstanceOf('Monolog\Formatter\ElasticaFormatter', $handler->getFormatter());
94
+ $this->assertEquals('index_new', $handler->getFormatter()->getIndex());
95
+ $this->assertEquals('type_new', $handler->getFormatter()->getType());
96
+ }
97
+
98
+ /**
99
+ * @covers Monolog\Handler\ElasticSearchHandler::setFormatter
100
+ * @expectedException InvalidArgumentException
101
+ * @expectedExceptionMessage ElasticSearchHandler is only compatible with ElasticaFormatter
102
+ */
103
+ public function testSetFormatterInvalid()
104
+ {
105
+ $handler = new ElasticSearchHandler($this->client);
106
+ $formatter = new NormalizerFormatter();
107
+ $handler->setFormatter($formatter);
108
+ }
109
+
110
+ /**
111
+ * @covers Monolog\Handler\ElasticSearchHandler::__construct
112
+ * @covers Monolog\Handler\ElasticSearchHandler::getOptions
113
+ */
114
+ public function testOptions()
115
+ {
116
+ $expected = array(
117
+ 'index' => $this->options['index'],
118
+ 'type' => $this->options['type'],
119
+ 'ignore_error' => false,
120
+ );
121
+ $handler = new ElasticSearchHandler($this->client, $this->options);
122
+ $this->assertEquals($expected, $handler->getOptions());
123
+ }
124
+
125
+ /**
126
+ * @covers Monolog\Handler\ElasticSearchHandler::bulkSend
127
+ * @dataProvider providerTestConnectionErrors
128
+ */
129
+ public function testConnectionErrors($ignore, $expectedError)
130
+ {
131
+ $clientOpts = array('host' => '127.0.0.1', 'port' => 1);
132
+ $client = new Client($clientOpts);
133
+ $handlerOpts = array('ignore_error' => $ignore);
134
+ $handler = new ElasticSearchHandler($client, $handlerOpts);
135
+
136
+ if ($expectedError) {
137
+ $this->setExpectedException($expectedError[0], $expectedError[1]);
138
+ $handler->handle($this->getRecord());
139
+ } else {
140
+ $this->assertFalse($handler->handle($this->getRecord()));
141
+ }
142
+ }
143
+
144
+ /**
145
+ * @return array
146
+ */
147
+ public function providerTestConnectionErrors()
148
+ {
149
+ return array(
150
+ array(false, array('RuntimeException', 'Error sending messages to Elasticsearch')),
151
+ array(true, false),
152
+ );
153
+ }
154
+
155
+ /**
156
+ * Integration test using localhost Elastic Search server
157
+ *
158
+ * @covers Monolog\Handler\ElasticSearchHandler::__construct
159
+ * @covers Monolog\Handler\ElasticSearchHandler::handleBatch
160
+ * @covers Monolog\Handler\ElasticSearchHandler::bulkSend
161
+ * @covers Monolog\Handler\ElasticSearchHandler::getDefaultFormatter
162
+ */
163
+ public function testHandleIntegration()
164
+ {
165
+ $msg = array(
166
+ 'level' => Logger::ERROR,
167
+ 'level_name' => 'ERROR',
168
+ 'channel' => 'meh',
169
+ 'context' => array('foo' => 7, 'bar', 'class' => new \stdClass),
170
+ 'datetime' => new \DateTime("@0"),
171
+ 'extra' => array(),
172
+ 'message' => 'log',
173
+ );
174
+
175
+ $expected = $msg;
176
+ $expected['datetime'] = $msg['datetime']->format(\DateTime::ISO8601);
177
+ $expected['context'] = array(
178
+ 'class' => '[object] (stdClass: {})',
179
+ 'foo' => 7,
180
+ 0 => 'bar',
181
+ );
182
+
183
+ $client = new Client();
184
+ $handler = new ElasticSearchHandler($client, $this->options);
185
+ try {
186
+ $handler->handleBatch(array($msg));
187
+ } catch (\RuntimeException $e) {
188
+ $this->markTestSkipped("Cannot connect to Elastic Search server on localhost");
189
+ }
190
+
191
+ // check document id from ES server response
192
+ $documentId = $this->getCreatedDocId($client->getLastResponse());
193
+ $this->assertNotEmpty($documentId, 'No elastic document id received');
194
+
195
+ // retrieve document source from ES and validate
196
+ $document = $this->getDocSourceFromElastic(
197
+ $client,
198
+ $this->options['index'],
199
+ $this->options['type'],
200
+ $documentId
201
+ );
202
+ $this->assertEquals($expected, $document);
203
+
204
+ // remove test index from ES
205
+ $client->request("/{$this->options['index']}", Request::DELETE);
206
+ }
207
+
208
+ /**
209
+ * Return last created document id from ES response
210
+ * @param Response $response Elastica Response object
211
+ * @return string|null
212
+ */
213
+ protected function getCreatedDocId(Response $response)
214
+ {
215
+ $data = $response->getData();
216
+ if (!empty($data['items'][0]['create']['_id'])) {
217
+ return $data['items'][0]['create']['_id'];
218
+ }
219
+ }
220
+
221
+ /**
222
+ * Retrieve document by id from Elasticsearch
223
+ * @param Client $client Elastica client
224
+ * @param string $index
225
+ * @param string $type
226
+ * @param string $documentId
227
+ * @return array
228
+ */
229
+ protected function getDocSourceFromElastic(Client $client, $index, $type, $documentId)
230
+ {
231
+ $resp = $client->request("/{$index}/{$type}/{$documentId}", Request::GET);
232
+ $data = $resp->getData();
233
+ if (!empty($data['_source'])) {
234
+ return $data['_source'];
235
+ }
236
+
237
+ return array();
238
+ }
239
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/ErrorLogHandlerTest.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+ use Monolog\Formatter\LineFormatter;
17
+
18
+ function error_log()
19
+ {
20
+ $GLOBALS['error_log'][] = func_get_args();
21
+ }
22
+
23
+ class ErrorLogHandlerTest extends TestCase
24
+ {
25
+ protected function setUp()
26
+ {
27
+ $GLOBALS['error_log'] = array();
28
+ }
29
+
30
+ /**
31
+ * @covers Monolog\Handler\ErrorLogHandler::__construct
32
+ * @expectedException InvalidArgumentException
33
+ * @expectedExceptionMessage The given message type "42" is not supported
34
+ */
35
+ public function testShouldNotAcceptAnInvalidTypeOnContructor()
36
+ {
37
+ new ErrorLogHandler(42);
38
+ }
39
+
40
+ /**
41
+ * @covers Monolog\Handler\ErrorLogHandler::write
42
+ */
43
+ public function testShouldLogMessagesUsingErrorLogFuncion()
44
+ {
45
+ $type = ErrorLogHandler::OPERATING_SYSTEM;
46
+ $handler = new ErrorLogHandler($type);
47
+ $handler->setFormatter(new LineFormatter('%channel%.%level_name%: %message% %context% %extra%', null, true));
48
+ $handler->handle($this->getRecord(Logger::ERROR, "Foo\nBar\r\n\r\nBaz"));
49
+
50
+ $this->assertSame("test.ERROR: Foo\nBar\r\n\r\nBaz [] []", $GLOBALS['error_log'][0][0]);
51
+ $this->assertSame($GLOBALS['error_log'][0][1], $type);
52
+
53
+ $handler = new ErrorLogHandler($type, Logger::DEBUG, true, true);
54
+ $handler->setFormatter(new LineFormatter(null, null, true));
55
+ $handler->handle($this->getRecord(Logger::ERROR, "Foo\nBar\r\n\r\nBaz"));
56
+
57
+ $this->assertStringMatchesFormat('[%s] test.ERROR: Foo', $GLOBALS['error_log'][1][0]);
58
+ $this->assertSame($GLOBALS['error_log'][1][1], $type);
59
+
60
+ $this->assertStringMatchesFormat('Bar', $GLOBALS['error_log'][2][0]);
61
+ $this->assertSame($GLOBALS['error_log'][2][1], $type);
62
+
63
+ $this->assertStringMatchesFormat('Baz [] []', $GLOBALS['error_log'][3][0]);
64
+ $this->assertSame($GLOBALS['error_log'][3][1], $type);
65
+ }
66
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/FilterHandlerTest.php ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+ use Monolog\TestCase;
16
+
17
+ class FilterHandlerTest extends TestCase
18
+ {
19
+ /**
20
+ * @covers Monolog\Handler\FilterHandler::isHandling
21
+ */
22
+ public function testIsHandling()
23
+ {
24
+ $test = new TestHandler();
25
+ $handler = new FilterHandler($test, Logger::INFO, Logger::NOTICE);
26
+ $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG)));
27
+ $this->assertTrue($handler->isHandling($this->getRecord(Logger::INFO)));
28
+ $this->assertTrue($handler->isHandling($this->getRecord(Logger::NOTICE)));
29
+ $this->assertFalse($handler->isHandling($this->getRecord(Logger::WARNING)));
30
+ $this->assertFalse($handler->isHandling($this->getRecord(Logger::ERROR)));
31
+ $this->assertFalse($handler->isHandling($this->getRecord(Logger::CRITICAL)));
32
+ $this->assertFalse($handler->isHandling($this->getRecord(Logger::ALERT)));
33
+ $this->assertFalse($handler->isHandling($this->getRecord(Logger::EMERGENCY)));
34
+ }
35
+
36
+ /**
37
+ * @covers Monolog\Handler\FilterHandler::handle
38
+ * @covers Monolog\Handler\FilterHandler::setAcceptedLevels
39
+ * @covers Monolog\Handler\FilterHandler::isHandling
40
+ */
41
+ public function testHandleProcessOnlyNeededLevels()
42
+ {
43
+ $test = new TestHandler();
44
+ $handler = new FilterHandler($test, Logger::INFO, Logger::NOTICE);
45
+
46
+ $handler->handle($this->getRecord(Logger::DEBUG));
47
+ $this->assertFalse($test->hasDebugRecords());
48
+
49
+ $handler->handle($this->getRecord(Logger::INFO));
50
+ $this->assertTrue($test->hasInfoRecords());
51
+ $handler->handle($this->getRecord(Logger::NOTICE));
52
+ $this->assertTrue($test->hasNoticeRecords());
53
+
54
+ $handler->handle($this->getRecord(Logger::WARNING));
55
+ $this->assertFalse($test->hasWarningRecords());
56
+ $handler->handle($this->getRecord(Logger::ERROR));
57
+ $this->assertFalse($test->hasErrorRecords());
58
+ $handler->handle($this->getRecord(Logger::CRITICAL));
59
+ $this->assertFalse($test->hasCriticalRecords());
60
+ $handler->handle($this->getRecord(Logger::ALERT));
61
+ $this->assertFalse($test->hasAlertRecords());
62
+ $handler->handle($this->getRecord(Logger::EMERGENCY));
63
+ $this->assertFalse($test->hasEmergencyRecords());
64
+
65
+ $test = new TestHandler();
66
+ $handler = new FilterHandler($test, array(Logger::INFO, Logger::ERROR));
67
+
68
+ $handler->handle($this->getRecord(Logger::DEBUG));
69
+ $this->assertFalse($test->hasDebugRecords());
70
+ $handler->handle($this->getRecord(Logger::INFO));
71
+ $this->assertTrue($test->hasInfoRecords());
72
+ $handler->handle($this->getRecord(Logger::NOTICE));
73
+ $this->assertFalse($test->hasNoticeRecords());
74
+ $handler->handle($this->getRecord(Logger::ERROR));
75
+ $this->assertTrue($test->hasErrorRecords());
76
+ $handler->handle($this->getRecord(Logger::CRITICAL));
77
+ $this->assertFalse($test->hasCriticalRecords());
78
+ }
79
+
80
+ /**
81
+ * @covers Monolog\Handler\FilterHandler::setAcceptedLevels
82
+ * @covers Monolog\Handler\FilterHandler::getAcceptedLevels
83
+ */
84
+ public function testAcceptedLevelApi()
85
+ {
86
+ $test = new TestHandler();
87
+ $handler = new FilterHandler($test);
88
+
89
+ $levels = array(Logger::INFO, Logger::ERROR);
90
+ $handler->setAcceptedLevels($levels);
91
+ $this->assertSame($levels, $handler->getAcceptedLevels());
92
+
93
+ $handler->setAcceptedLevels(array('info', 'error'));
94
+ $this->assertSame($levels, $handler->getAcceptedLevels());
95
+
96
+ $levels = array(Logger::CRITICAL, Logger::ALERT, Logger::EMERGENCY);
97
+ $handler->setAcceptedLevels(Logger::CRITICAL, Logger::EMERGENCY);
98
+ $this->assertSame($levels, $handler->getAcceptedLevels());
99
+
100
+ $handler->setAcceptedLevels('critical', 'emergency');
101
+ $this->assertSame($levels, $handler->getAcceptedLevels());
102
+ }
103
+
104
+ /**
105
+ * @covers Monolog\Handler\FilterHandler::handle
106
+ */
107
+ public function testHandleUsesProcessors()
108
+ {
109
+ $test = new TestHandler();
110
+ $handler = new FilterHandler($test, Logger::DEBUG, Logger::EMERGENCY);
111
+ $handler->pushProcessor(
112
+ function ($record) {
113
+ $record['extra']['foo'] = true;
114
+
115
+ return $record;
116
+ }
117
+ );
118
+ $handler->handle($this->getRecord(Logger::WARNING));
119
+ $this->assertTrue($test->hasWarningRecords());
120
+ $records = $test->getRecords();
121
+ $this->assertTrue($records[0]['extra']['foo']);
122
+ }
123
+
124
+ /**
125
+ * @covers Monolog\Handler\FilterHandler::handle
126
+ */
127
+ public function testHandleRespectsBubble()
128
+ {
129
+ $test = new TestHandler();
130
+
131
+ $handler = new FilterHandler($test, Logger::INFO, Logger::NOTICE, false);
132
+ $this->assertTrue($handler->handle($this->getRecord(Logger::INFO)));
133
+ $this->assertFalse($handler->handle($this->getRecord(Logger::WARNING)));
134
+
135
+ $handler = new FilterHandler($test, Logger::INFO, Logger::NOTICE, true);
136
+ $this->assertFalse($handler->handle($this->getRecord(Logger::INFO)));
137
+ $this->assertFalse($handler->handle($this->getRecord(Logger::WARNING)));
138
+ }
139
+
140
+ /**
141
+ * @covers Monolog\Handler\FilterHandler::handle
142
+ */
143
+ public function testHandleWithCallback()
144
+ {
145
+ $test = new TestHandler();
146
+ $handler = new FilterHandler(
147
+ function ($record, $handler) use ($test) {
148
+ return $test;
149
+ }, Logger::INFO, Logger::NOTICE, false
150
+ );
151
+ $handler->handle($this->getRecord(Logger::DEBUG));
152
+ $handler->handle($this->getRecord(Logger::INFO));
153
+ $this->assertFalse($test->hasDebugRecords());
154
+ $this->assertTrue($test->hasInfoRecords());
155
+ }
156
+
157
+ /**
158
+ * @covers Monolog\Handler\FilterHandler::handle
159
+ * @expectedException \RuntimeException
160
+ */
161
+ public function testHandleWithBadCallbackThrowsException()
162
+ {
163
+ $handler = new FilterHandler(
164
+ function ($record, $handler) {
165
+ return 'foo';
166
+ }
167
+ );
168
+ $handler->handle($this->getRecord(Logger::WARNING));
169
+ }
170
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/FingersCrossedHandlerTest.php ADDED
@@ -0,0 +1,240 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+ use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
17
+ use Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy;
18
+
19
+ class FingersCrossedHandlerTest extends TestCase
20
+ {
21
+ /**
22
+ * @covers Monolog\Handler\FingersCrossedHandler::__construct
23
+ * @covers Monolog\Handler\FingersCrossedHandler::handle
24
+ */
25
+ public function testHandleBuffers()
26
+ {
27
+ $test = new TestHandler();
28
+ $handler = new FingersCrossedHandler($test);
29
+ $handler->handle($this->getRecord(Logger::DEBUG));
30
+ $handler->handle($this->getRecord(Logger::INFO));
31
+ $this->assertFalse($test->hasDebugRecords());
32
+ $this->assertFalse($test->hasInfoRecords());
33
+ $handler->handle($this->getRecord(Logger::WARNING));
34
+ $handler->close();
35
+ $this->assertTrue($test->hasInfoRecords());
36
+ $this->assertTrue(count($test->getRecords()) === 3);
37
+ }
38
+
39
+ /**
40
+ * @covers Monolog\Handler\FingersCrossedHandler::handle
41
+ */
42
+ public function testHandleStopsBufferingAfterTrigger()
43
+ {
44
+ $test = new TestHandler();
45
+ $handler = new FingersCrossedHandler($test);
46
+ $handler->handle($this->getRecord(Logger::WARNING));
47
+ $handler->handle($this->getRecord(Logger::DEBUG));
48
+ $handler->close();
49
+ $this->assertTrue($test->hasWarningRecords());
50
+ $this->assertTrue($test->hasDebugRecords());
51
+ }
52
+
53
+ /**
54
+ * @covers Monolog\Handler\FingersCrossedHandler::handle
55
+ * @covers Monolog\Handler\FingersCrossedHandler::reset
56
+ */
57
+ public function testHandleRestartBufferingAfterReset()
58
+ {
59
+ $test = new TestHandler();
60
+ $handler = new FingersCrossedHandler($test);
61
+ $handler->handle($this->getRecord(Logger::WARNING));
62
+ $handler->handle($this->getRecord(Logger::DEBUG));
63
+ $handler->reset();
64
+ $handler->handle($this->getRecord(Logger::INFO));
65
+ $handler->close();
66
+ $this->assertTrue($test->hasWarningRecords());
67
+ $this->assertTrue($test->hasDebugRecords());
68
+ $this->assertFalse($test->hasInfoRecords());
69
+ }
70
+
71
+ /**
72
+ * @covers Monolog\Handler\FingersCrossedHandler::handle
73
+ */
74
+ public function testHandleRestartBufferingAfterBeingTriggeredWhenStopBufferingIsDisabled()
75
+ {
76
+ $test = new TestHandler();
77
+ $handler = new FingersCrossedHandler($test, Logger::WARNING, 0, false, false);
78
+ $handler->handle($this->getRecord(Logger::DEBUG));
79
+ $handler->handle($this->getRecord(Logger::WARNING));
80
+ $handler->handle($this->getRecord(Logger::INFO));
81
+ $handler->close();
82
+ $this->assertTrue($test->hasWarningRecords());
83
+ $this->assertTrue($test->hasDebugRecords());
84
+ $this->assertFalse($test->hasInfoRecords());
85
+ }
86
+
87
+ /**
88
+ * @covers Monolog\Handler\FingersCrossedHandler::handle
89
+ */
90
+ public function testHandleBufferLimit()
91
+ {
92
+ $test = new TestHandler();
93
+ $handler = new FingersCrossedHandler($test, Logger::WARNING, 2);
94
+ $handler->handle($this->getRecord(Logger::DEBUG));
95
+ $handler->handle($this->getRecord(Logger::DEBUG));
96
+ $handler->handle($this->getRecord(Logger::INFO));
97
+ $handler->handle($this->getRecord(Logger::WARNING));
98
+ $this->assertTrue($test->hasWarningRecords());
99
+ $this->assertTrue($test->hasInfoRecords());
100
+ $this->assertFalse($test->hasDebugRecords());
101
+ }
102
+
103
+ /**
104
+ * @covers Monolog\Handler\FingersCrossedHandler::handle
105
+ */
106
+ public function testHandleWithCallback()
107
+ {
108
+ $test = new TestHandler();
109
+ $handler = new FingersCrossedHandler(function ($record, $handler) use ($test) {
110
+ return $test;
111
+ });
112
+ $handler->handle($this->getRecord(Logger::DEBUG));
113
+ $handler->handle($this->getRecord(Logger::INFO));
114
+ $this->assertFalse($test->hasDebugRecords());
115
+ $this->assertFalse($test->hasInfoRecords());
116
+ $handler->handle($this->getRecord(Logger::WARNING));
117
+ $this->assertTrue($test->hasInfoRecords());
118
+ $this->assertTrue(count($test->getRecords()) === 3);
119
+ }
120
+
121
+ /**
122
+ * @covers Monolog\Handler\FingersCrossedHandler::handle
123
+ * @expectedException RuntimeException
124
+ */
125
+ public function testHandleWithBadCallbackThrowsException()
126
+ {
127
+ $handler = new FingersCrossedHandler(function ($record, $handler) {
128
+ return 'foo';
129
+ });
130
+ $handler->handle($this->getRecord(Logger::WARNING));
131
+ }
132
+
133
+ /**
134
+ * @covers Monolog\Handler\FingersCrossedHandler::isHandling
135
+ */
136
+ public function testIsHandlingAlways()
137
+ {
138
+ $test = new TestHandler();
139
+ $handler = new FingersCrossedHandler($test, Logger::ERROR);
140
+ $this->assertTrue($handler->isHandling($this->getRecord(Logger::DEBUG)));
141
+ }
142
+
143
+ /**
144
+ * @covers Monolog\Handler\FingersCrossedHandler::__construct
145
+ * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::__construct
146
+ * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::isHandlerActivated
147
+ */
148
+ public function testErrorLevelActivationStrategy()
149
+ {
150
+ $test = new TestHandler();
151
+ $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy(Logger::WARNING));
152
+ $handler->handle($this->getRecord(Logger::DEBUG));
153
+ $this->assertFalse($test->hasDebugRecords());
154
+ $handler->handle($this->getRecord(Logger::WARNING));
155
+ $this->assertTrue($test->hasDebugRecords());
156
+ $this->assertTrue($test->hasWarningRecords());
157
+ }
158
+
159
+ /**
160
+ * @covers Monolog\Handler\FingersCrossedHandler::__construct
161
+ * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::__construct
162
+ * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::isHandlerActivated
163
+ */
164
+ public function testErrorLevelActivationStrategyWithPsrLevel()
165
+ {
166
+ $test = new TestHandler();
167
+ $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy('warning'));
168
+ $handler->handle($this->getRecord(Logger::DEBUG));
169
+ $this->assertFalse($test->hasDebugRecords());
170
+ $handler->handle($this->getRecord(Logger::WARNING));
171
+ $this->assertTrue($test->hasDebugRecords());
172
+ $this->assertTrue($test->hasWarningRecords());
173
+ }
174
+
175
+ /**
176
+ * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::__construct
177
+ * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::isHandlerActivated
178
+ */
179
+ public function testChannelLevelActivationStrategy()
180
+ {
181
+ $test = new TestHandler();
182
+ $handler = new FingersCrossedHandler($test, new ChannelLevelActivationStrategy(Logger::ERROR, array('othertest' => Logger::DEBUG)));
183
+ $handler->handle($this->getRecord(Logger::WARNING));
184
+ $this->assertFalse($test->hasWarningRecords());
185
+ $record = $this->getRecord(Logger::DEBUG);
186
+ $record['channel'] = 'othertest';
187
+ $handler->handle($record);
188
+ $this->assertTrue($test->hasDebugRecords());
189
+ $this->assertTrue($test->hasWarningRecords());
190
+ }
191
+
192
+ /**
193
+ * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::__construct
194
+ * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::isHandlerActivated
195
+ */
196
+ public function testChannelLevelActivationStrategyWithPsrLevels()
197
+ {
198
+ $test = new TestHandler();
199
+ $handler = new FingersCrossedHandler($test, new ChannelLevelActivationStrategy('error', array('othertest' => 'debug')));
200
+ $handler->handle($this->getRecord(Logger::WARNING));
201
+ $this->assertFalse($test->hasWarningRecords());
202
+ $record = $this->getRecord(Logger::DEBUG);
203
+ $record['channel'] = 'othertest';
204
+ $handler->handle($record);
205
+ $this->assertTrue($test->hasDebugRecords());
206
+ $this->assertTrue($test->hasWarningRecords());
207
+ }
208
+
209
+ /**
210
+ * @covers Monolog\Handler\FingersCrossedHandler::handle
211
+ */
212
+ public function testHandleUsesProcessors()
213
+ {
214
+ $test = new TestHandler();
215
+ $handler = new FingersCrossedHandler($test, Logger::INFO);
216
+ $handler->pushProcessor(function ($record) {
217
+ $record['extra']['foo'] = true;
218
+
219
+ return $record;
220
+ });
221
+ $handler->handle($this->getRecord(Logger::WARNING));
222
+ $this->assertTrue($test->hasWarningRecords());
223
+ $records = $test->getRecords();
224
+ $this->assertTrue($records[0]['extra']['foo']);
225
+ }
226
+
227
+ /**
228
+ * @covers Monolog\Handler\FingersCrossedHandler::close
229
+ */
230
+ public function testPassthruOnClose()
231
+ {
232
+ $test = new TestHandler();
233
+ $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy(Logger::WARNING), 0, true, true, Logger::INFO);
234
+ $handler->handle($this->getRecord(Logger::DEBUG));
235
+ $handler->handle($this->getRecord(Logger::INFO));
236
+ $handler->close();
237
+ $this->assertFalse($test->hasDebugRecords());
238
+ $this->assertTrue($test->hasInfoRecords());
239
+ }
240
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/FirePHPHandlerTest.php ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+
17
+ /**
18
+ * @covers Monolog\Handler\FirePHPHandler
19
+ */
20
+ class FirePHPHandlerTest extends TestCase
21
+ {
22
+ public function setUp()
23
+ {
24
+ TestFirePHPHandler::reset();
25
+ $_SERVER['HTTP_USER_AGENT'] = 'Monolog Test; FirePHP/1.0';
26
+ }
27
+
28
+ public function testHeaders()
29
+ {
30
+ $handler = new TestFirePHPHandler;
31
+ $handler->setFormatter($this->getIdentityFormatter());
32
+ $handler->handle($this->getRecord(Logger::DEBUG));
33
+ $handler->handle($this->getRecord(Logger::WARNING));
34
+
35
+ $expected = array(
36
+ 'X-Wf-Protocol-1' => 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2',
37
+ 'X-Wf-1-Structure-1' => 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1',
38
+ 'X-Wf-1-Plugin-1' => 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3',
39
+ 'X-Wf-1-1-1-1' => 'test',
40
+ 'X-Wf-1-1-1-2' => 'test',
41
+ );
42
+
43
+ $this->assertEquals($expected, $handler->getHeaders());
44
+ }
45
+
46
+ public function testConcurrentHandlers()
47
+ {
48
+ $handler = new TestFirePHPHandler;
49
+ $handler->setFormatter($this->getIdentityFormatter());
50
+ $handler->handle($this->getRecord(Logger::DEBUG));
51
+ $handler->handle($this->getRecord(Logger::WARNING));
52
+
53
+ $handler2 = new TestFirePHPHandler;
54
+ $handler2->setFormatter($this->getIdentityFormatter());
55
+ $handler2->handle($this->getRecord(Logger::DEBUG));
56
+ $handler2->handle($this->getRecord(Logger::WARNING));
57
+
58
+ $expected = array(
59
+ 'X-Wf-Protocol-1' => 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2',
60
+ 'X-Wf-1-Structure-1' => 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1',
61
+ 'X-Wf-1-Plugin-1' => 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3',
62
+ 'X-Wf-1-1-1-1' => 'test',
63
+ 'X-Wf-1-1-1-2' => 'test',
64
+ );
65
+
66
+ $expected2 = array(
67
+ 'X-Wf-1-1-1-3' => 'test',
68
+ 'X-Wf-1-1-1-4' => 'test',
69
+ );
70
+
71
+ $this->assertEquals($expected, $handler->getHeaders());
72
+ $this->assertEquals($expected2, $handler2->getHeaders());
73
+ }
74
+ }
75
+
76
+ class TestFirePHPHandler extends FirePHPHandler
77
+ {
78
+ protected $headers = array();
79
+
80
+ public static function reset()
81
+ {
82
+ self::$initialized = false;
83
+ self::$sendHeaders = true;
84
+ self::$messageIndex = 1;
85
+ }
86
+
87
+ protected function sendHeader($header, $content)
88
+ {
89
+ $this->headers[$header] = $content;
90
+ }
91
+
92
+ public function getHeaders()
93
+ {
94
+ return $this->headers;
95
+ }
96
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/Fixtures/.gitkeep ADDED
File without changes
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/FleepHookHandlerTest.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Formatter\LineFormatter;
15
+ use Monolog\Logger;
16
+ use Monolog\TestCase;
17
+
18
+ /**
19
+ * @coversDefaultClass \Monolog\Handler\FleepHookHandler
20
+ */
21
+ class FleepHookHandlerTest extends TestCase
22
+ {
23
+ /**
24
+ * Default token to use in tests
25
+ */
26
+ const TOKEN = '123abc';
27
+
28
+ /**
29
+ * @var FleepHookHandler
30
+ */
31
+ private $handler;
32
+
33
+ public function setUp()
34
+ {
35
+ parent::setUp();
36
+
37
+ if (!extension_loaded('openssl')) {
38
+ $this->markTestSkipped('This test requires openssl extension to run');
39
+ }
40
+
41
+ // Create instances of the handler and logger for convenience
42
+ $this->handler = new FleepHookHandler(self::TOKEN);
43
+ }
44
+
45
+ /**
46
+ * @covers ::__construct
47
+ */
48
+ public function testConstructorSetsExpectedDefaults()
49
+ {
50
+ $this->assertEquals(Logger::DEBUG, $this->handler->getLevel());
51
+ $this->assertEquals(true, $this->handler->getBubble());
52
+ }
53
+
54
+ /**
55
+ * @covers ::getDefaultFormatter
56
+ */
57
+ public function testHandlerUsesLineFormatterWhichIgnoresEmptyArrays()
58
+ {
59
+ $record = array(
60
+ 'message' => 'msg',
61
+ 'context' => array(),
62
+ 'level' => Logger::DEBUG,
63
+ 'level_name' => Logger::getLevelName(Logger::DEBUG),
64
+ 'channel' => 'channel',
65
+ 'datetime' => new \DateTime(),
66
+ 'extra' => array(),
67
+ );
68
+
69
+ $expectedFormatter = new LineFormatter(null, null, true, true);
70
+ $expected = $expectedFormatter->format($record);
71
+
72
+ $handlerFormatter = $this->handler->getFormatter();
73
+ $actual = $handlerFormatter->format($record);
74
+
75
+ $this->assertEquals($expected, $actual, 'Empty context and extra arrays should not be rendered');
76
+ }
77
+
78
+ /**
79
+ * @covers ::__construct
80
+ */
81
+ public function testConnectionStringisConstructedCorrectly()
82
+ {
83
+ $this->assertEquals('ssl://' . FleepHookHandler::FLEEP_HOST . ':443', $this->handler->getConnectionString());
84
+ }
85
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/FlowdockHandlerTest.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Formatter\FlowdockFormatter;
15
+ use Monolog\TestCase;
16
+ use Monolog\Logger;
17
+
18
+ /**
19
+ * @author Dominik Liebler <liebler.dominik@gmail.com>
20
+ * @see https://www.hipchat.com/docs/api
21
+ */
22
+ class FlowdockHandlerTest extends TestCase
23
+ {
24
+ /**
25
+ * @var resource
26
+ */
27
+ private $res;
28
+
29
+ /**
30
+ * @var FlowdockHandler
31
+ */
32
+ private $handler;
33
+
34
+ public function setUp()
35
+ {
36
+ if (!extension_loaded('openssl')) {
37
+ $this->markTestSkipped('This test requires openssl to run');
38
+ }
39
+ }
40
+
41
+ public function testWriteHeader()
42
+ {
43
+ $this->createHandler();
44
+ $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
45
+ fseek($this->res, 0);
46
+ $content = fread($this->res, 1024);
47
+
48
+ $this->assertRegexp('/POST \/v1\/messages\/team_inbox\/.* HTTP\/1.1\\r\\nHost: api.flowdock.com\\r\\nContent-Type: application\/json\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content);
49
+
50
+ return $content;
51
+ }
52
+
53
+ /**
54
+ * @depends testWriteHeader
55
+ */
56
+ public function testWriteContent($content)
57
+ {
58
+ $this->assertRegexp('/"source":"test_source"/', $content);
59
+ $this->assertRegexp('/"from_address":"source@test\.com"/', $content);
60
+ }
61
+
62
+ private function createHandler($token = 'myToken')
63
+ {
64
+ $constructorArgs = array($token, Logger::DEBUG);
65
+ $this->res = fopen('php://memory', 'a');
66
+ $this->handler = $this->getMock(
67
+ '\Monolog\Handler\FlowdockHandler',
68
+ array('fsockopen', 'streamSetTimeout', 'closeSocket'),
69
+ $constructorArgs
70
+ );
71
+
72
+ $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString');
73
+ $reflectionProperty->setAccessible(true);
74
+ $reflectionProperty->setValue($this->handler, 'localhost:1234');
75
+
76
+ $this->handler->expects($this->any())
77
+ ->method('fsockopen')
78
+ ->will($this->returnValue($this->res));
79
+ $this->handler->expects($this->any())
80
+ ->method('streamSetTimeout')
81
+ ->will($this->returnValue(true));
82
+ $this->handler->expects($this->any())
83
+ ->method('closeSocket')
84
+ ->will($this->returnValue(true));
85
+
86
+ $this->handler->setFormatter(new FlowdockFormatter('test_source', 'source@test.com'));
87
+ }
88
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerLegacyTest.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Gelf\Message;
15
+ use Monolog\TestCase;
16
+ use Monolog\Logger;
17
+ use Monolog\Formatter\GelfMessageFormatter;
18
+
19
+ class GelfHandlerLegacyTest extends TestCase
20
+ {
21
+ public function setUp()
22
+ {
23
+ if (!class_exists('Gelf\MessagePublisher') || !class_exists('Gelf\Message')) {
24
+ $this->markTestSkipped("mlehner/gelf-php not installed");
25
+ }
26
+
27
+ require_once __DIR__ . '/GelfMockMessagePublisher.php';
28
+ }
29
+
30
+ /**
31
+ * @covers Monolog\Handler\GelfHandler::__construct
32
+ */
33
+ public function testConstruct()
34
+ {
35
+ $handler = new GelfHandler($this->getMessagePublisher());
36
+ $this->assertInstanceOf('Monolog\Handler\GelfHandler', $handler);
37
+ }
38
+
39
+ protected function getHandler($messagePublisher)
40
+ {
41
+ $handler = new GelfHandler($messagePublisher);
42
+
43
+ return $handler;
44
+ }
45
+
46
+ protected function getMessagePublisher()
47
+ {
48
+ return new GelfMockMessagePublisher('localhost');
49
+ }
50
+
51
+ public function testDebug()
52
+ {
53
+ $messagePublisher = $this->getMessagePublisher();
54
+ $handler = $this->getHandler($messagePublisher);
55
+
56
+ $record = $this->getRecord(Logger::DEBUG, "A test debug message");
57
+ $handler->handle($record);
58
+
59
+ $this->assertEquals(7, $messagePublisher->lastMessage->getLevel());
60
+ $this->assertEquals('test', $messagePublisher->lastMessage->getFacility());
61
+ $this->assertEquals($record['message'], $messagePublisher->lastMessage->getShortMessage());
62
+ $this->assertEquals(null, $messagePublisher->lastMessage->getFullMessage());
63
+ }
64
+
65
+ public function testWarning()
66
+ {
67
+ $messagePublisher = $this->getMessagePublisher();
68
+ $handler = $this->getHandler($messagePublisher);
69
+
70
+ $record = $this->getRecord(Logger::WARNING, "A test warning message");
71
+ $handler->handle($record);
72
+
73
+ $this->assertEquals(4, $messagePublisher->lastMessage->getLevel());
74
+ $this->assertEquals('test', $messagePublisher->lastMessage->getFacility());
75
+ $this->assertEquals($record['message'], $messagePublisher->lastMessage->getShortMessage());
76
+ $this->assertEquals(null, $messagePublisher->lastMessage->getFullMessage());
77
+ }
78
+
79
+ public function testInjectedGelfMessageFormatter()
80
+ {
81
+ $messagePublisher = $this->getMessagePublisher();
82
+ $handler = $this->getHandler($messagePublisher);
83
+
84
+ $handler->setFormatter(new GelfMessageFormatter('mysystem', 'EXT', 'CTX'));
85
+
86
+ $record = $this->getRecord(Logger::WARNING, "A test warning message");
87
+ $record['extra']['blarg'] = 'yep';
88
+ $record['context']['from'] = 'logger';
89
+ $handler->handle($record);
90
+
91
+ $this->assertEquals('mysystem', $messagePublisher->lastMessage->getHost());
92
+ $this->assertArrayHasKey('_EXTblarg', $messagePublisher->lastMessage->toArray());
93
+ $this->assertArrayHasKey('_CTXfrom', $messagePublisher->lastMessage->toArray());
94
+ }
95
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerTest.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Gelf\Message;
15
+ use Monolog\TestCase;
16
+ use Monolog\Logger;
17
+ use Monolog\Formatter\GelfMessageFormatter;
18
+
19
+ class GelfHandlerTest extends TestCase
20
+ {
21
+ public function setUp()
22
+ {
23
+ if (!class_exists('Gelf\Publisher') || !class_exists('Gelf\Message')) {
24
+ $this->markTestSkipped("graylog2/gelf-php not installed");
25
+ }
26
+ }
27
+
28
+ /**
29
+ * @covers Monolog\Handler\GelfHandler::__construct
30
+ */
31
+ public function testConstruct()
32
+ {
33
+ $handler = new GelfHandler($this->getMessagePublisher());
34
+ $this->assertInstanceOf('Monolog\Handler\GelfHandler', $handler);
35
+ }
36
+
37
+ protected function getHandler($messagePublisher)
38
+ {
39
+ $handler = new GelfHandler($messagePublisher);
40
+
41
+ return $handler;
42
+ }
43
+
44
+ protected function getMessagePublisher()
45
+ {
46
+ return $this->getMock('Gelf\Publisher', array('publish'), array(), '', false);
47
+ }
48
+
49
+ public function testDebug()
50
+ {
51
+ $record = $this->getRecord(Logger::DEBUG, "A test debug message");
52
+ $expectedMessage = new Message();
53
+ $expectedMessage
54
+ ->setLevel(7)
55
+ ->setFacility("test")
56
+ ->setShortMessage($record['message'])
57
+ ->setTimestamp($record['datetime'])
58
+ ;
59
+
60
+ $messagePublisher = $this->getMessagePublisher();
61
+ $messagePublisher->expects($this->once())
62
+ ->method('publish')
63
+ ->with($expectedMessage);
64
+
65
+ $handler = $this->getHandler($messagePublisher);
66
+
67
+ $handler->handle($record);
68
+ }
69
+
70
+ public function testWarning()
71
+ {
72
+ $record = $this->getRecord(Logger::WARNING, "A test warning message");
73
+ $expectedMessage = new Message();
74
+ $expectedMessage
75
+ ->setLevel(4)
76
+ ->setFacility("test")
77
+ ->setShortMessage($record['message'])
78
+ ->setTimestamp($record['datetime'])
79
+ ;
80
+
81
+ $messagePublisher = $this->getMessagePublisher();
82
+ $messagePublisher->expects($this->once())
83
+ ->method('publish')
84
+ ->with($expectedMessage);
85
+
86
+ $handler = $this->getHandler($messagePublisher);
87
+
88
+ $handler->handle($record);
89
+ }
90
+
91
+ public function testInjectedGelfMessageFormatter()
92
+ {
93
+ $record = $this->getRecord(Logger::WARNING, "A test warning message");
94
+ $record['extra']['blarg'] = 'yep';
95
+ $record['context']['from'] = 'logger';
96
+
97
+ $expectedMessage = new Message();
98
+ $expectedMessage
99
+ ->setLevel(4)
100
+ ->setFacility("test")
101
+ ->setHost("mysystem")
102
+ ->setShortMessage($record['message'])
103
+ ->setTimestamp($record['datetime'])
104
+ ->setAdditional("EXTblarg", 'yep')
105
+ ->setAdditional("CTXfrom", 'logger')
106
+ ;
107
+
108
+ $messagePublisher = $this->getMessagePublisher();
109
+ $messagePublisher->expects($this->once())
110
+ ->method('publish')
111
+ ->with($expectedMessage);
112
+
113
+ $handler = $this->getHandler($messagePublisher);
114
+ $handler->setFormatter(new GelfMessageFormatter('mysystem', 'EXT', 'CTX'));
115
+ $handler->handle($record);
116
+ }
117
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/GelfMockMessagePublisher.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Gelf\MessagePublisher;
15
+ use Gelf\Message;
16
+
17
+ class GelfMockMessagePublisher extends MessagePublisher
18
+ {
19
+ public function publish(Message $message)
20
+ {
21
+ $this->lastMessage = $message;
22
+ }
23
+
24
+ public $lastMessage = null;
25
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/GroupHandlerTest.php ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+
17
+ class GroupHandlerTest extends TestCase
18
+ {
19
+ /**
20
+ * @covers Monolog\Handler\GroupHandler::__construct
21
+ * @expectedException InvalidArgumentException
22
+ */
23
+ public function testConstructorOnlyTakesHandler()
24
+ {
25
+ new GroupHandler(array(new TestHandler(), "foo"));
26
+ }
27
+
28
+ /**
29
+ * @covers Monolog\Handler\GroupHandler::__construct
30
+ * @covers Monolog\Handler\GroupHandler::handle
31
+ */
32
+ public function testHandle()
33
+ {
34
+ $testHandlers = array(new TestHandler(), new TestHandler());
35
+ $handler = new GroupHandler($testHandlers);
36
+ $handler->handle($this->getRecord(Logger::DEBUG));
37
+ $handler->handle($this->getRecord(Logger::INFO));
38
+ foreach ($testHandlers as $test) {
39
+ $this->assertTrue($test->hasDebugRecords());
40
+ $this->assertTrue($test->hasInfoRecords());
41
+ $this->assertTrue(count($test->getRecords()) === 2);
42
+ }
43
+ }
44
+
45
+ /**
46
+ * @covers Monolog\Handler\GroupHandler::handleBatch
47
+ */
48
+ public function testHandleBatch()
49
+ {
50
+ $testHandlers = array(new TestHandler(), new TestHandler());
51
+ $handler = new GroupHandler($testHandlers);
52
+ $handler->handleBatch(array($this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO)));
53
+ foreach ($testHandlers as $test) {
54
+ $this->assertTrue($test->hasDebugRecords());
55
+ $this->assertTrue($test->hasInfoRecords());
56
+ $this->assertTrue(count($test->getRecords()) === 2);
57
+ }
58
+ }
59
+
60
+ /**
61
+ * @covers Monolog\Handler\GroupHandler::isHandling
62
+ */
63
+ public function testIsHandling()
64
+ {
65
+ $testHandlers = array(new TestHandler(Logger::ERROR), new TestHandler(Logger::WARNING));
66
+ $handler = new GroupHandler($testHandlers);
67
+ $this->assertTrue($handler->isHandling($this->getRecord(Logger::ERROR)));
68
+ $this->assertTrue($handler->isHandling($this->getRecord(Logger::WARNING)));
69
+ $this->assertFalse($handler->isHandling($this->getRecord(Logger::DEBUG)));
70
+ }
71
+
72
+ /**
73
+ * @covers Monolog\Handler\GroupHandler::handle
74
+ */
75
+ public function testHandleUsesProcessors()
76
+ {
77
+ $test = new TestHandler();
78
+ $handler = new GroupHandler(array($test));
79
+ $handler->pushProcessor(function ($record) {
80
+ $record['extra']['foo'] = true;
81
+
82
+ return $record;
83
+ });
84
+ $handler->handle($this->getRecord(Logger::WARNING));
85
+ $this->assertTrue($test->hasWarningRecords());
86
+ $records = $test->getRecords();
87
+ $this->assertTrue($records[0]['extra']['foo']);
88
+ }
89
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/HipChatHandlerTest.php ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+
17
+ /**
18
+ * @author Rafael Dohms <rafael@doh.ms>
19
+ * @see https://www.hipchat.com/docs/api
20
+ */
21
+ class HipChatHandlerTest extends TestCase
22
+ {
23
+ private $res;
24
+ private $handler;
25
+
26
+ public function testWriteHeader()
27
+ {
28
+ $this->createHandler();
29
+ $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
30
+ fseek($this->res, 0);
31
+ $content = fread($this->res, 1024);
32
+
33
+ $this->assertRegexp('/POST \/v1\/rooms\/message\?format=json&auth_token=.* HTTP\/1.1\\r\\nHost: api.hipchat.com\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content);
34
+
35
+ return $content;
36
+ }
37
+
38
+ public function testWriteCustomHostHeader()
39
+ {
40
+ $this->createHandler('myToken', 'room1', 'Monolog', false, 'hipchat.foo.bar');
41
+ $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
42
+ fseek($this->res, 0);
43
+ $content = fread($this->res, 1024);
44
+
45
+ $this->assertRegexp('/POST \/v1\/rooms\/message\?format=json&auth_token=.* HTTP\/1.1\\r\\nHost: hipchat.foo.bar\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content);
46
+
47
+ return $content;
48
+ }
49
+
50
+ /**
51
+ * @depends testWriteHeader
52
+ */
53
+ public function testWriteContent($content)
54
+ {
55
+ $this->assertRegexp('/from=Monolog&room_id=room1&notify=0&message=test1&message_format=text&color=red$/', $content);
56
+ }
57
+
58
+ public function testWriteWithComplexMessage()
59
+ {
60
+ $this->createHandler();
61
+ $this->handler->handle($this->getRecord(Logger::CRITICAL, 'Backup of database "example" finished in 16 minutes.'));
62
+ fseek($this->res, 0);
63
+ $content = fread($this->res, 1024);
64
+
65
+ $this->assertRegexp('/message=Backup\+of\+database\+%22example%22\+finished\+in\+16\+minutes\./', $content);
66
+ }
67
+
68
+ /**
69
+ * @dataProvider provideLevelColors
70
+ */
71
+ public function testWriteWithErrorLevelsAndColors($level, $expectedColor)
72
+ {
73
+ $this->createHandler();
74
+ $this->handler->handle($this->getRecord($level, 'Backup of database "example" finished in 16 minutes.'));
75
+ fseek($this->res, 0);
76
+ $content = fread($this->res, 1024);
77
+
78
+ $this->assertRegexp('/color='.$expectedColor.'/', $content);
79
+ }
80
+
81
+ public function provideLevelColors()
82
+ {
83
+ return array(
84
+ array(Logger::DEBUG, 'gray'),
85
+ array(Logger::INFO, 'green'),
86
+ array(Logger::WARNING, 'yellow'),
87
+ array(Logger::ERROR, 'red'),
88
+ array(Logger::CRITICAL, 'red'),
89
+ array(Logger::ALERT, 'red'),
90
+ array(Logger::EMERGENCY,'red'),
91
+ array(Logger::NOTICE, 'green'),
92
+ );
93
+ }
94
+
95
+ /**
96
+ * @dataProvider provideBatchRecords
97
+ */
98
+ public function testHandleBatch($records, $expectedColor)
99
+ {
100
+ $this->createHandler();
101
+
102
+ $this->handler->handleBatch($records);
103
+
104
+ fseek($this->res, 0);
105
+ $content = fread($this->res, 1024);
106
+
107
+ $this->assertRegexp('/color='.$expectedColor.'/', $content);
108
+ }
109
+
110
+ public function provideBatchRecords()
111
+ {
112
+ return array(
113
+ array(
114
+ array(
115
+ array('level' => Logger::WARNING, 'message' => 'Oh bugger!', 'level_name' => 'warning', 'datetime' => new \DateTime()),
116
+ array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()),
117
+ array('level' => Logger::CRITICAL, 'message' => 'Everything is broken!', 'level_name' => 'critical', 'datetime' => new \DateTime())
118
+ ),
119
+ 'red',
120
+ ),
121
+ array(
122
+ array(
123
+ array('level' => Logger::WARNING, 'message' => 'Oh bugger!', 'level_name' => 'warning', 'datetime' => new \DateTime()),
124
+ array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()),
125
+ ),
126
+ 'yellow',
127
+ ),
128
+ array(
129
+ array(
130
+ array('level' => Logger::DEBUG, 'message' => 'Just debugging.', 'level_name' => 'debug', 'datetime' => new \DateTime()),
131
+ array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()),
132
+ ),
133
+ 'green',
134
+ ),
135
+ array(
136
+ array(
137
+ array('level' => Logger::DEBUG, 'message' => 'Just debugging.', 'level_name' => 'debug', 'datetime' => new \DateTime()),
138
+ ),
139
+ 'gray',
140
+ ),
141
+ );
142
+ }
143
+
144
+ private function createHandler($token = 'myToken', $room = 'room1', $name = 'Monolog', $notify = false, $host = 'api.hipchat.com')
145
+ {
146
+ $constructorArgs = array($token, $room, $name, $notify, Logger::DEBUG, true, true, 'text', $host);
147
+ $this->res = fopen('php://memory', 'a');
148
+ $this->handler = $this->getMock(
149
+ '\Monolog\Handler\HipChatHandler',
150
+ array('fsockopen', 'streamSetTimeout', 'closeSocket'),
151
+ $constructorArgs
152
+ );
153
+
154
+ $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString');
155
+ $reflectionProperty->setAccessible(true);
156
+ $reflectionProperty->setValue($this->handler, 'localhost:1234');
157
+
158
+ $this->handler->expects($this->any())
159
+ ->method('fsockopen')
160
+ ->will($this->returnValue($this->res));
161
+ $this->handler->expects($this->any())
162
+ ->method('streamSetTimeout')
163
+ ->will($this->returnValue(true));
164
+ $this->handler->expects($this->any())
165
+ ->method('closeSocket')
166
+ ->will($this->returnValue(true));
167
+
168
+ $this->handler->setFormatter($this->getIdentityFormatter());
169
+ }
170
+
171
+ /**
172
+ * @expectedException InvalidArgumentException
173
+ */
174
+ public function testCreateWithTooLongName()
175
+ {
176
+ $hipChatHandler = new \Monolog\Handler\HipChatHandler('token', 'room', 'SixteenCharsHere');
177
+ }
178
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/LogEntriesHandlerTest.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+
17
+ /**
18
+ * @author Robert Kaufmann III <rok3@rok3.me>
19
+ */
20
+ class LogEntriesHandlerTest extends TestCase
21
+ {
22
+ /**
23
+ * @var resource
24
+ */
25
+ private $res;
26
+
27
+ /**
28
+ * @var LogEntriesHandler
29
+ */
30
+ private $handler;
31
+
32
+ public function testWriteContent()
33
+ {
34
+ $this->createHandler();
35
+ $this->handler->handle($this->getRecord(Logger::CRITICAL, 'Critical write test'));
36
+
37
+ fseek($this->res, 0);
38
+ $content = fread($this->res, 1024);
39
+
40
+ $this->assertRegexp('/testToken \[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] test.CRITICAL: Critical write test/', $content);
41
+ }
42
+
43
+ public function testWriteBatchContent()
44
+ {
45
+ $records = array(
46
+ $this->getRecord(),
47
+ $this->getRecord(),
48
+ $this->getRecord()
49
+ );
50
+ $this->createHandler();
51
+ $this->handler->handleBatch($records);
52
+
53
+ fseek($this->res, 0);
54
+ $content = fread($this->res, 1024);
55
+
56
+ $this->assertRegexp('/(testToken \[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\] .* \[\] \[\]\n){3}/', $content);
57
+ }
58
+
59
+ private function createHandler()
60
+ {
61
+ $useSSL = extension_loaded('openssl');
62
+ $args = array('testToken', $useSSL, Logger::DEBUG, true);
63
+ $this->res = fopen('php://memory', 'a');
64
+ $this->handler = $this->getMock(
65
+ '\Monolog\Handler\LogEntriesHandler',
66
+ array('fsockopen', 'streamSetTimeout', 'closeSocket'),
67
+ $args
68
+ );
69
+
70
+ $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString');
71
+ $reflectionProperty->setAccessible(true);
72
+ $reflectionProperty->setValue($this->handler, 'localhost:1234');
73
+
74
+ $this->handler->expects($this->any())
75
+ ->method('fsockopen')
76
+ ->will($this->returnValue($this->res));
77
+ $this->handler->expects($this->any())
78
+ ->method('streamSetTimeout')
79
+ ->will($this->returnValue(true));
80
+ $this->handler->expects($this->any())
81
+ ->method('closeSocket')
82
+ ->will($this->returnValue(true));
83
+ }
84
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/MailHandlerTest.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\Logger;
15
+ use Monolog\TestCase;
16
+
17
+ class MailHandlerTest extends TestCase
18
+ {
19
+ /**
20
+ * @covers Monolog\Handler\MailHandler::handleBatch
21
+ */
22
+ public function testHandleBatch()
23
+ {
24
+ $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
25
+ $formatter->expects($this->once())
26
+ ->method('formatBatch'); // Each record is formatted
27
+
28
+ $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler');
29
+ $handler->expects($this->once())
30
+ ->method('send');
31
+ $handler->expects($this->never())
32
+ ->method('write'); // write is for individual records
33
+
34
+ $handler->setFormatter($formatter);
35
+
36
+ $handler->handleBatch($this->getMultipleRecords());
37
+ }
38
+
39
+ /**
40
+ * @covers Monolog\Handler\MailHandler::handleBatch
41
+ */
42
+ public function testHandleBatchNotSendsMailIfMessagesAreBelowLevel()
43
+ {
44
+ $records = array(
45
+ $this->getRecord(Logger::DEBUG, 'debug message 1'),
46
+ $this->getRecord(Logger::DEBUG, 'debug message 2'),
47
+ $this->getRecord(Logger::INFO, 'information'),
48
+ );
49
+
50
+ $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler');
51
+ $handler->expects($this->never())
52
+ ->method('send');
53
+ $handler->setLevel(Logger::ERROR);
54
+
55
+ $handler->handleBatch($records);
56
+ }
57
+
58
+ /**
59
+ * @covers Monolog\Handler\MailHandler::write
60
+ */
61
+ public function testHandle()
62
+ {
63
+ $handler = $this->getMockForAbstractClass('Monolog\\Handler\\MailHandler');
64
+
65
+ $record = $this->getRecord();
66
+ $records = array($record);
67
+ $records[0]['formatted'] = '['.$record['datetime']->format('Y-m-d H:i:s').'] test.WARNING: test [] []'."\n";
68
+
69
+ $handler->expects($this->once())
70
+ ->method('send')
71
+ ->with($records[0]['formatted'], $records);
72
+
73
+ $handler->handle($record);
74
+ }
75
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/MockRavenClient.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Raven_Client;
15
+
16
+ class MockRavenClient extends Raven_Client
17
+ {
18
+ public function capture($data, $stack, $vars = null)
19
+ {
20
+ $this->lastData = $data;
21
+ $this->lastStack = $stack;
22
+ }
23
+
24
+ public $lastData;
25
+ public $lastStack;
26
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/MongoDBHandlerTest.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+
17
+ class MongoDBHandlerTest extends TestCase
18
+ {
19
+ /**
20
+ * @expectedException InvalidArgumentException
21
+ */
22
+ public function testConstructorShouldThrowExceptionForInvalidMongo()
23
+ {
24
+ new MongoDBHandler(new \stdClass(), 'DB', 'Collection');
25
+ }
26
+
27
+ public function testHandle()
28
+ {
29
+ $mongo = $this->getMock('Mongo', array('selectCollection'), array(), '', false);
30
+ $collection = $this->getMock('stdClass', array('save'));
31
+
32
+ $mongo->expects($this->once())
33
+ ->method('selectCollection')
34
+ ->with('DB', 'Collection')
35
+ ->will($this->returnValue($collection));
36
+
37
+ $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
38
+
39
+ $expected = array(
40
+ 'message' => 'test',
41
+ 'context' => array('data' => '[object] (stdClass: {})', 'foo' => 34),
42
+ 'level' => Logger::WARNING,
43
+ 'level_name' => 'WARNING',
44
+ 'channel' => 'test',
45
+ 'datetime' => $record['datetime']->format('Y-m-d H:i:s'),
46
+ 'extra' => array(),
47
+ );
48
+
49
+ $collection->expects($this->once())
50
+ ->method('save')
51
+ ->with($expected);
52
+
53
+ $handler = new MongoDBHandler($mongo, 'DB', 'Collection');
54
+ $handler->handle($record);
55
+ }
56
+ }
57
+
58
+ if (!class_exists('Mongo')) {
59
+ class Mongo
60
+ {
61
+ public function selectCollection()
62
+ {
63
+ }
64
+ }
65
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/NativeMailerHandlerTest.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+
16
+ class NativeMailerHandlerTest extends TestCase
17
+ {
18
+ /**
19
+ * @expectedException InvalidArgumentException
20
+ */
21
+ public function testConstructorHeaderInjection()
22
+ {
23
+ $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', "receiver@example.org\r\nFrom: faked@attacker.org");
24
+ }
25
+
26
+ /**
27
+ * @expectedException InvalidArgumentException
28
+ */
29
+ public function testSetterHeaderInjection()
30
+ {
31
+ $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org');
32
+ $mailer->addHeader("Content-Type: text/html\r\nFrom: faked@attacker.org");
33
+ }
34
+
35
+ /**
36
+ * @expectedException InvalidArgumentException
37
+ */
38
+ public function testSetterArrayHeaderInjection()
39
+ {
40
+ $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org');
41
+ $mailer->addHeader(array("Content-Type: text/html\r\nFrom: faked@attacker.org"));
42
+ }
43
+
44
+ /**
45
+ * @expectedException InvalidArgumentException
46
+ */
47
+ public function testSetterContentTypeInjection()
48
+ {
49
+ $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org');
50
+ $mailer->setContentType("text/html\r\nFrom: faked@attacker.org");
51
+ }
52
+
53
+ /**
54
+ * @expectedException InvalidArgumentException
55
+ */
56
+ public function testSetterEncodingInjection()
57
+ {
58
+ $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org');
59
+ $mailer->setEncoding("utf-8\r\nFrom: faked@attacker.org");
60
+ }
61
+ }
app/code/community/Expressly/Expressly/vendor/monolog/monolog/tests/Monolog/Handler/NewRelicHandlerTest.php ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Monolog\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+
17
+ class NewRelicHandlerTest extends TestCase
18
+ {
19
+ public static $appname;
20
+ public static $customParameters;
21
+ public static $transactionName;
22
+
23
+ public function setUp()
24
+ {
25
+ self::$appname = null;
26
+ self::$customParameters = array();
27
+ self::$transactionName = null;
28
+ }
29
+
30
+ /**
31
+ * @expectedException Monolog\Handler\MissingExtensionException
32
+ */
33
+ public function testThehandlerThrowsAnExceptionIfTheNRExtensionIsNotLoaded()
34
+ {
35
+ $handler = new StubNewRelicHandlerWithoutExtension();
36
+ $handler->handle($this->getRecord(Logger::ERROR));
37
+ }
38
+
39
+ public function testThehandlerCanHandleTheRecord()
40
+ {
41
+ $handler = new StubNewRelicHandler();
42
+ $handler->handle($this->getRecord(Logger::ERROR));
43
+ }
44
+
45
+ public function testThehandlerCanAdd