Constant Contact Forms - Version 1.4.0

Version Description

  • Added: Various styling options during the form building process.
  • Added: Initial Akismet integration to help aid with spam submissions.
  • Added: Clear form fields after successful AJAX-based form submissions.
  • Added: Clear success/error message after small delay, for AJAX-based form submissions.
  • Added: WordPress action hooks before and after form output. Useful to add your own output for a given form.
  • Added: Compatibility with "Call To Action" plugin.
  • Added: Include custom field labels in email notifications.
  • Added: Ability to customize who receives email notifications, per form.
  • Added: Frontend form submit button disabled if hidden honeypot field has changed.
  • Fixed: Consistently applied ctct_process_form_success filter to AJAX form submission success messages.
  • Fixed: Prevent errors with Constant Contact social links and array_merge issues.
  • Fixed: Prevent errors with array_key_exists() and the ctct_get_settings_option function.
  • Fixed: Wording around associated lists for a form, in the WordPress admin.
  • Fixed: Removed .gitignore files from /vendor folders.
  • Fixed: Prevent potential PHP warnings and notices in various areas.
  • Updated: Better support for emailing notifications to multiple recipiants.
  • Updated: Better disabling of submit button during AJAX-based submissions.
  • Updated: Tightened up form builder screen to not use so much space.
Download this release

Release Info

Developer constantcontact
Plugin Icon 128x128 Constant Contact Forms
Version 1.4.0
Comparing to
See all releases

Code changes from version 1.3.7 to 1.4.0

Files changed (241) hide show
  1. assets/css/admin-forms.css +0 -449
  2. assets/css/admin-global-no-connection.css +0 -307
  3. assets/css/admin-notices.css +0 -50
  4. assets/css/admin-pages.css +0 -351
  5. assets/css/admin-style.css +1307 -0
  6. assets/css/oath.css +0 -84
  7. assets/css/style.css +50 -1
  8. assets/css/style.min.css +1 -1
  9. assets/images/oval.min.svg +1 -0
  10. assets/js/ctct-plugin-frontend.js +55 -12
  11. assets/js/ctct-plugin-frontend.min.js +1 -1
  12. assets/js/ctct-plugin-frontend/validation.js +55 -12
  13. assets/sass/_admin-forms.scss +210 -0
  14. assets/sass/{admin-global-no-connection.scss → _admin-global-no-connection.scss} +0 -3
  15. assets/sass/{admin-notices.scss → _admin-notices.scss} +0 -0
  16. assets/sass/{admin-pages.scss → _admin-pages.scss} +0 -3
  17. assets/sass/_forms.scss +8 -3
  18. assets/sass/_inputs.scss +38 -0
  19. assets/sass/{oath.scss → _oath.scss} +0 -3
  20. assets/sass/admin-forms.scss +0 -123
  21. assets/sass/admin-style.scss +13 -0
  22. constant-contact-forms.php +38 -3
  23. includes/class-admin-pages.php +1 -15
  24. includes/class-admin.php +10 -2
  25. includes/class-api.php +2 -2
  26. includes/class-builder-fields.php +211 -10
  27. includes/class-builder.php +1 -1
  28. includes/class-check.php +1 -1
  29. includes/class-connect.php +1 -10
  30. includes/class-cpts.php +1 -1
  31. includes/class-display-shortcode.php +8 -8
  32. includes/class-display.php +555 -159
  33. includes/class-lists.php +40 -24
  34. includes/class-logging.php +2 -2
  35. includes/class-mail.php +63 -17
  36. includes/class-notifications.php +1 -6
  37. includes/class-process-form.php +18 -3
  38. includes/class-settings.php +45 -11
  39. includes/class-user-customizations.php +29 -0
  40. includes/compatibility.php +39 -0
  41. includes/helper-functions.php +210 -3
  42. languages/constant-contact-forms.pot +320 -202
  43. readme.txt +25 -4
  44. vendor/constantcontact/constantcontact/.gitignore +25 -0
  45. vendor/constantcontact/constantcontact/.travis.yml +20 -0
  46. vendor/constantcontact/constantcontact/constantcontact/phpunit.xml +0 -8
  47. vendor/constantcontact/constantcontact/constantcontact/test/Auth/CtctOAuth2UnitTest.php +0 -140
  48. vendor/constantcontact/constantcontact/constantcontact/test/Json/Account/get_account_info.json +0 -21
  49. vendor/constantcontact/constantcontact/constantcontact/test/Json/Account/get_verified_email_addresses.json +0 -6
  50. vendor/constantcontact/constantcontact/constantcontact/test/Json/Activities/get_activities.json +0 -52
  51. vendor/constantcontact/constantcontact/constantcontact/test/Json/Activities/get_activity.json +0 -24
  52. vendor/constantcontact/constantcontact/constantcontact/test/Json/Activities/post_add_contacts.json +0 -6
  53. vendor/constantcontact/constantcontact/constantcontact/test/Json/Activities/post_clear_lists.json +0 -6
  54. vendor/constantcontact/constantcontact/constantcontact/test/Json/Activities/post_export_contacts.json +0 -6
  55. vendor/constantcontact/constantcontact/constantcontact/test/Json/Activities/post_remove_contacts_from_lists.json +0 -6
  56. vendor/constantcontact/constantcontact/constantcontact/test/Json/Auth/get_access_token.json +0 -5
  57. vendor/constantcontact/constantcontact/constantcontact/test/Json/Auth/token_info.json +0 -5
  58. vendor/constantcontact/constantcontact/constantcontact/test/Json/Campaigns/get_campaign.json +0 -63
  59. vendor/constantcontact/constantcontact/constantcontact/test/Json/Campaigns/get_campaigns.json +0 -57
  60. vendor/constantcontact/constantcontact/constantcontact/test/Json/Campaigns/get_preview.json +0 -7
  61. vendor/constantcontact/constantcontact/constantcontact/test/Json/Campaigns/get_schedule.json +0 -4
  62. vendor/constantcontact/constantcontact/constantcontact/test/Json/Campaigns/get_schedules.json +0 -10
  63. vendor/constantcontact/constantcontact/constantcontact/test/Json/Campaigns/post_test_send.json +0 -7
  64. vendor/constantcontact/constantcontact/constantcontact/test/Json/Contacts/get_contact.json +0 -63
  65. vendor/constantcontact/constantcontact/constantcontact/test/Json/Contacts/get_contacts.json +0 -111
  66. vendor/constantcontact/constantcontact/constantcontact/test/Json/Contacts/get_contacts_no_next.json +0 -108
  67. vendor/constantcontact/constantcontact/constantcontact/test/Json/JsonLoader.php +0 -177
  68. vendor/constantcontact/constantcontact/constantcontact/test/Json/Library/get_file_upload_status.json +0 -7
  69. vendor/constantcontact/constantcontact/constantcontact/test/Json/Library/get_library_file.json +0 -22
  70. vendor/constantcontact/constantcontact/constantcontact/test/Json/Library/get_library_files.json +0 -29
  71. vendor/constantcontact/constantcontact/constantcontact/test/Json/Library/get_library_folder.json +0 -27
  72. vendor/constantcontact/constantcontact/constantcontact/test/Json/Library/get_library_folders.json +0 -34
  73. vendor/constantcontact/constantcontact/constantcontact/test/Json/Lists/get_list.json +0 -7
  74. vendor/constantcontact/constantcontact/constantcontact/test/Json/Lists/get_lists.json +0 -16
  75. vendor/constantcontact/constantcontact/constantcontact/test/Json/Tracking/get_bounces.json +0 -29
  76. vendor/constantcontact/constantcontact/constantcontact/test/Json/Tracking/get_clicks.json +0 -25
  77. vendor/constantcontact/constantcontact/constantcontact/test/Json/Tracking/get_forwards.json +0 -23
  78. vendor/constantcontact/constantcontact/constantcontact/test/Json/Tracking/get_opens.json +0 -23
  79. vendor/constantcontact/constantcontact/constantcontact/test/Json/Tracking/get_opt_outs.json +0 -27
  80. vendor/constantcontact/constantcontact/constantcontact/test/Json/Tracking/get_sends.json +0 -30
  81. vendor/constantcontact/constantcontact/constantcontact/test/Json/Tracking/get_summary.json +0 -9
  82. vendor/constantcontact/constantcontact/constantcontact/test/Services/AccountServiceUnitTest.php +0 -62
  83. vendor/constantcontact/constantcontact/constantcontact/test/Services/ActivityServiceUnitTest.php +0 -119
  84. vendor/constantcontact/constantcontact/constantcontact/test/Services/CampaignScheduleServiceUnitTest.php +0 -113
  85. vendor/constantcontact/constantcontact/constantcontact/test/Services/CampaignTrackingServiceUnitTest.php +0 -203
  86. vendor/constantcontact/constantcontact/constantcontact/test/Services/ContactServiceUnitTest.php +0 -353
  87. vendor/constantcontact/constantcontact/constantcontact/test/Services/ContactTrackingServiceUnitTest.php +0 -185
  88. vendor/constantcontact/constantcontact/constantcontact/test/Services/EmailCampaignServiceUnitTest.php +0 -291
  89. vendor/constantcontact/constantcontact/constantcontact/test/Services/LibraryServiceUnitTest.php +0 -195
  90. vendor/constantcontact/constantcontact/constantcontact/test/Services/ListServiceUnitTest.php +0 -143
  91. vendor/constantcontact/constantcontact/constantcontact/test/bootstrap.php +0 -9
  92. vendor/constantcontact/guzzlehttp/ringphp/docs/Makefile +0 -153
  93. vendor/constantcontact/guzzlehttp/ringphp/docs/client_handlers.rst +0 -173
  94. vendor/constantcontact/guzzlehttp/ringphp/docs/client_middleware.rst +0 -165
  95. vendor/constantcontact/guzzlehttp/ringphp/docs/conf.py +0 -23
  96. vendor/constantcontact/guzzlehttp/ringphp/docs/futures.rst +0 -164
  97. vendor/constantcontact/guzzlehttp/ringphp/docs/index.rst +0 -50
  98. vendor/constantcontact/guzzlehttp/ringphp/docs/requirements.txt +0 -1
  99. vendor/constantcontact/guzzlehttp/ringphp/docs/spec.rst +0 -311
  100. vendor/constantcontact/guzzlehttp/ringphp/docs/testing.rst +0 -74
  101. vendor/constantcontact/guzzlehttp/ringphp/phpunit.xml.dist +0 -14
  102. vendor/constantcontact/guzzlehttp/ringphp/tests/Client/CurlFactoryTest.php +0 -821
  103. vendor/constantcontact/guzzlehttp/ringphp/tests/Client/CurlHandlerTest.php +0 -96
  104. vendor/constantcontact/guzzlehttp/ringphp/tests/Client/CurlMultiHandlerTest.php +0 -165
  105. vendor/constantcontact/guzzlehttp/ringphp/tests/Client/MiddlewareTest.php +0 -65
  106. vendor/constantcontact/guzzlehttp/ringphp/tests/Client/MockHandlerTest.php +0 -86
  107. vendor/constantcontact/guzzlehttp/ringphp/tests/Client/Server.php +0 -183
  108. vendor/constantcontact/guzzlehttp/ringphp/tests/Client/StreamHandlerTest.php +0 -480
  109. vendor/constantcontact/guzzlehttp/ringphp/tests/Client/server.js +0 -241
  110. vendor/constantcontact/guzzlehttp/ringphp/tests/CoreTest.php +0 -336
  111. vendor/constantcontact/guzzlehttp/ringphp/tests/Future/CompletedFutureArrayTest.php +0 -21
  112. vendor/constantcontact/guzzlehttp/ringphp/tests/Future/CompletedFutureValueTest.php +0 -46
  113. vendor/constantcontact/guzzlehttp/ringphp/tests/Future/FutureArrayTest.php +0 -56
  114. vendor/constantcontact/guzzlehttp/ringphp/tests/Future/FutureValueTest.php +0 -109
  115. vendor/constantcontact/guzzlehttp/ringphp/tests/bootstrap.php +0 -11
  116. vendor/constantcontact/guzzlehttp/streams/phpunit.xml.dist +0 -17
  117. vendor/constantcontact/guzzlehttp/streams/tests/AppendStreamTest.php +0 -178
  118. vendor/constantcontact/guzzlehttp/streams/tests/AsyncReadStreamTest.php +0 -186
  119. vendor/constantcontact/guzzlehttp/streams/tests/BufferStreamTest.php +0 -69
  120. vendor/constantcontact/guzzlehttp/streams/tests/CachingStreamTest.php +0 -136
  121. vendor/constantcontact/guzzlehttp/streams/tests/DroppingStreamTest.php +0 -26
  122. vendor/constantcontact/guzzlehttp/streams/tests/Exception/SeekExceptionTest.php +0 -16
  123. vendor/constantcontact/guzzlehttp/streams/tests/FnStreamTest.php +0 -89
  124. vendor/constantcontact/guzzlehttp/streams/tests/GuzzleStreamWrapperTest.php +0 -99
  125. vendor/constantcontact/guzzlehttp/streams/tests/InflateStreamTest.php +0 -16
  126. vendor/constantcontact/guzzlehttp/streams/tests/LazyOpenStreamTest.php +0 -64
  127. vendor/constantcontact/guzzlehttp/streams/tests/LimitStreamTest.php +0 -133
  128. vendor/constantcontact/guzzlehttp/streams/tests/NoSeekStreamTest.php +0 -41
  129. vendor/constantcontact/guzzlehttp/streams/tests/NullStreamTest.php +0 -39
  130. vendor/constantcontact/guzzlehttp/streams/tests/PumpStreamTest.php +0 -77
  131. vendor/constantcontact/guzzlehttp/streams/tests/StreamDecoratorTraitTest.php +0 -147
  132. vendor/constantcontact/guzzlehttp/streams/tests/StreamTest.php +0 -252
  133. vendor/constantcontact/guzzlehttp/streams/tests/UtilsTest.php +0 -155
  134. vendor/constantcontact/react/promise/phpunit.xml.dist +0 -25
  135. vendor/constantcontact/react/promise/tests/DeferredTest.php +0 -42
  136. vendor/constantcontact/react/promise/tests/FulfilledPromiseTest.php +0 -50
  137. vendor/constantcontact/react/promise/tests/FunctionAllTest.php +0 -97
  138. vendor/constantcontact/react/promise/tests/FunctionAnyTest.php +0 -116
  139. vendor/constantcontact/react/promise/tests/FunctionCheckTypehintTest.php +0 -118
  140. vendor/constantcontact/react/promise/tests/FunctionMapTest.php +0 -125
  141. vendor/constantcontact/react/promise/tests/FunctionRaceTest.php +0 -122
  142. vendor/constantcontact/react/promise/tests/FunctionReduceTest.php +0 -290
  143. vendor/constantcontact/react/promise/tests/FunctionRejectTest.php +0 -64
  144. vendor/constantcontact/react/promise/tests/FunctionResolveTest.php +0 -102
  145. vendor/constantcontact/react/promise/tests/FunctionSomeTest.php +0 -126
  146. vendor/constantcontact/react/promise/tests/LazyPromiseTest.php +0 -107
  147. vendor/constantcontact/react/promise/tests/PromiseAdapter/CallbackPromiseAdapter.php +0 -40
  148. vendor/constantcontact/react/promise/tests/PromiseAdapter/PromiseAdapterInterface.php +0 -14
  149. vendor/constantcontact/react/promise/tests/PromiseTest.php +0 -116
  150. vendor/constantcontact/react/promise/tests/PromiseTest/CancelTestTrait.php +0 -206
  151. vendor/constantcontact/react/promise/tests/PromiseTest/FullTestTrait.php +0 -15
  152. vendor/constantcontact/react/promise/tests/PromiseTest/NotifyTestTrait.php +0 -336
  153. vendor/constantcontact/react/promise/tests/PromiseTest/PromiseFulfilledTestTrait.php +0 -351
  154. vendor/constantcontact/react/promise/tests/PromiseTest/PromisePendingTestTrait.php +0 -68
  155. vendor/constantcontact/react/promise/tests/PromiseTest/PromiseRejectedTestTrait.php +0 -492
  156. vendor/constantcontact/react/promise/tests/PromiseTest/PromiseSettledTestTrait.php +0 -86
  157. vendor/constantcontact/react/promise/tests/PromiseTest/RejectTestTrait.php +0 -368
  158. vendor/constantcontact/react/promise/tests/PromiseTest/ResolveTestTrait.php +0 -263
  159. vendor/constantcontact/react/promise/tests/RejectedPromiseTest.php +0 -50
  160. vendor/constantcontact/react/promise/tests/Stub/CallableStub.php +0 -10
  161. vendor/constantcontact/react/promise/tests/TestCase.php +0 -41
  162. vendor/constantcontact/react/promise/tests/bootstrap.php +0 -7
  163. vendor/monolog/monolog/{CHANGELOG.mdown → CHANGELOG.md} +25 -0
  164. vendor/monolog/monolog/{README.mdown → README.md} +0 -0
  165. vendor/monolog/monolog/doc/01-usage.md +0 -231
  166. vendor/monolog/monolog/doc/02-handlers-formatters-processors.md +0 -155
  167. vendor/monolog/monolog/doc/03-utilities.md +0 -13
  168. vendor/monolog/monolog/doc/04-extending.md +0 -76
  169. vendor/monolog/monolog/doc/sockets.md +0 -39
  170. vendor/monolog/monolog/phpunit.xml.dist +0 -19
  171. vendor/monolog/monolog/src/Monolog/Handler/Slack/SlackRecord.php +294 -0
  172. vendor/monolog/monolog/src/Monolog/Handler/SlackWebhookHandler.php +115 -0
  173. vendor/monolog/monolog/src/Monolog/Handler/SlackbotHandler.php +80 -0
  174. vendor/monolog/monolog/src/Monolog/Processor/MercurialProcessor.php +63 -0
  175. vendor/monolog/monolog/tests/Monolog/ErrorHandlerTest.php +0 -31
  176. vendor/monolog/monolog/tests/Monolog/Formatter/ChromePHPFormatterTest.php +0 -158
  177. vendor/monolog/monolog/tests/Monolog/Formatter/ElasticaFormatterTest.php +0 -79
  178. vendor/monolog/monolog/tests/Monolog/Formatter/FlowdockFormatterTest.php +0 -55
  179. vendor/monolog/monolog/tests/Monolog/Formatter/FluentdFormatterTest.php +0 -62
  180. vendor/monolog/monolog/tests/Monolog/Formatter/GelfMessageFormatterTest.php +0 -234
  181. vendor/monolog/monolog/tests/Monolog/Formatter/JsonFormatterTest.php +0 -122
  182. vendor/monolog/monolog/tests/Monolog/Formatter/LineFormatterTest.php +0 -222
  183. vendor/monolog/monolog/tests/Monolog/Formatter/LogglyFormatterTest.php +0 -40
  184. vendor/monolog/monolog/tests/Monolog/Formatter/LogstashFormatterTest.php +0 -333
  185. vendor/monolog/monolog/tests/Monolog/Formatter/MongoDBFormatterTest.php +0 -262
  186. vendor/monolog/monolog/tests/Monolog/Formatter/NormalizerFormatterTest.php +0 -405
  187. vendor/monolog/monolog/tests/Monolog/Formatter/ScalarFormatterTest.php +0 -110
  188. vendor/monolog/monolog/tests/Monolog/Formatter/WildfireFormatterTest.php +0 -142
  189. vendor/monolog/monolog/tests/Monolog/Handler/AbstractHandlerTest.php +0 -115
  190. vendor/monolog/monolog/tests/Monolog/Handler/AbstractProcessingHandlerTest.php +0 -80
  191. vendor/monolog/monolog/tests/Monolog/Handler/AmqpHandlerTest.php +0 -136
  192. vendor/monolog/monolog/tests/Monolog/Handler/BrowserConsoleHandlerTest.php +0 -130
  193. vendor/monolog/monolog/tests/Monolog/Handler/BufferHandlerTest.php +0 -158
  194. vendor/monolog/monolog/tests/Monolog/Handler/ChromePHPHandlerTest.php +0 -141
  195. vendor/monolog/monolog/tests/Monolog/Handler/CouchDBHandlerTest.php +0 -31
  196. vendor/monolog/monolog/tests/Monolog/Handler/DeduplicationHandlerTest.php +0 -165
  197. vendor/monolog/monolog/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php +0 -52
  198. vendor/monolog/monolog/tests/Monolog/Handler/DynamoDbHandlerTest.php +0 -75
  199. vendor/monolog/monolog/tests/Monolog/Handler/ElasticSearchHandlerTest.php +0 -239
  200. vendor/monolog/monolog/tests/Monolog/Handler/ErrorLogHandlerTest.php +0 -66
  201. vendor/monolog/monolog/tests/Monolog/Handler/FilterHandlerTest.php +0 -170
  202. vendor/monolog/monolog/tests/Monolog/Handler/FingersCrossedHandlerTest.php +0 -279
  203. vendor/monolog/monolog/tests/Monolog/Handler/FirePHPHandlerTest.php +0 -96
  204. vendor/monolog/monolog/tests/Monolog/Handler/Fixtures/.gitkeep +0 -0
  205. vendor/monolog/monolog/tests/Monolog/Handler/FleepHookHandlerTest.php +0 -85
  206. vendor/monolog/monolog/tests/Monolog/Handler/FlowdockHandlerTest.php +0 -88
  207. vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerLegacyTest.php +0 -95
  208. vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerTest.php +0 -117
  209. vendor/monolog/monolog/tests/Monolog/Handler/GelfMockMessagePublisher.php +0 -25
  210. vendor/monolog/monolog/tests/Monolog/Handler/GroupHandlerTest.php +0 -112
  211. vendor/monolog/monolog/tests/Monolog/Handler/HandlerWrapperTest.php +0 -130
  212. vendor/monolog/monolog/tests/Monolog/Handler/HipChatHandlerTest.php +0 -279
  213. vendor/monolog/monolog/tests/Monolog/Handler/LogEntriesHandlerTest.php +0 -84
  214. vendor/monolog/monolog/tests/Monolog/Handler/MailHandlerTest.php +0 -75
  215. vendor/monolog/monolog/tests/Monolog/Handler/MockRavenClient.php +0 -27
  216. vendor/monolog/monolog/tests/Monolog/Handler/MongoDBHandlerTest.php +0 -65
  217. vendor/monolog/monolog/tests/Monolog/Handler/NativeMailerHandlerTest.php +0 -111
  218. vendor/monolog/monolog/tests/Monolog/Handler/NewRelicHandlerTest.php +0 -200
  219. vendor/monolog/monolog/tests/Monolog/Handler/NullHandlerTest.php +0 -33
  220. vendor/monolog/monolog/tests/Monolog/Handler/PHPConsoleHandlerTest.php +0 -273
  221. vendor/monolog/monolog/tests/Monolog/Handler/PsrHandlerTest.php +0 -50
  222. vendor/monolog/monolog/tests/Monolog/Handler/PushoverHandlerTest.php +0 -141
  223. vendor/monolog/monolog/tests/Monolog/Handler/RavenHandlerTest.php +0 -227
  224. vendor/monolog/monolog/tests/Monolog/Handler/RedisHandlerTest.php +0 -127
  225. vendor/monolog/monolog/tests/Monolog/Handler/RollbarHandlerTest.php +84 -0
  226. vendor/monolog/monolog/tests/Monolog/Handler/RotatingFileHandlerTest.php +0 -211
  227. vendor/monolog/monolog/tests/Monolog/Handler/SamplingHandlerTest.php +0 -33
  228. vendor/monolog/monolog/tests/Monolog/Handler/Slack/SlackRecordTest.php +387 -0
  229. vendor/monolog/monolog/tests/Monolog/Handler/SlackHandlerTest.php +0 -151
  230. vendor/monolog/monolog/tests/Monolog/Handler/SlackWebhookHandlerTest.php +107 -0
  231. vendor/monolog/monolog/tests/Monolog/Handler/SlackbotHandlerTest.php +47 -0
  232. vendor/monolog/monolog/tests/Monolog/Handler/SocketHandlerTest.php +0 -309
  233. vendor/monolog/monolog/tests/Monolog/Handler/StreamHandlerTest.php +0 -184
  234. vendor/monolog/monolog/tests/Monolog/Handler/SwiftMailerHandlerTest.php +0 -113
  235. vendor/monolog/monolog/tests/Monolog/Handler/SyslogHandlerTest.php +0 -44
  236. vendor/monolog/monolog/tests/Monolog/Handler/SyslogUdpHandlerTest.php +0 -49
  237. vendor/monolog/monolog/tests/Monolog/Handler/TestHandlerTest.php +0 -66
  238. vendor/monolog/monolog/tests/Monolog/Handler/UdpSocketTest.php +0 -64
  239. vendor/monolog/monolog/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php +0 -121
  240. vendor/monolog/monolog/tests/Monolog/Handler/ZendMonitorHandlerTest.php +0 -69
  241. vendor/monolog/monolog/tests/Monolog/LoggerTest.php +0 -383
assets/css/admin-forms.css DELETED
@@ -1,449 +0,0 @@
1
- .ctct-modal {
2
- -moz-osx-font-smoothing: grayscale;
3
- -webkit-font-smoothing: antialiased;
4
- background-color: rgba(0, 0, 0, 0.3);
5
- bottom: 0;
6
- display: none;
7
- left: 0;
8
- overflow: hidden;
9
- position: fixed;
10
- right: 0;
11
- top: 0;
12
- z-index: 9999;
13
- }
14
-
15
- .ctct-modal:after {
16
- clear: both;
17
- content: "";
18
- display: table;
19
- }
20
-
21
- .ctct-modal h2 {
22
- color: #fff;
23
- font-size: 28px;
24
- font-weight: 400;
25
- line-height: 1.2;
26
- margin: 0;
27
- }
28
-
29
- .ctct-modal h3 {
30
- color: #005990;
31
- font-size: 18px;
32
- line-height: 1.2;
33
- margin-bottom: 15px;
34
- margin-top: 10px;
35
- }
36
-
37
- .ctct-modal p {
38
- color: #555555;
39
- font-size: 14.7px;
40
- }
41
-
42
- .ctct-modal.ctct-modal-open {
43
- display: block;
44
- overflow-x: hidden;
45
- overflow-y: auto;
46
- }
47
-
48
- .ctct-modal .ctct-modal-dialog {
49
- left: 50%;
50
- position: absolute;
51
- top: 50%;
52
- transform: translate(-50%, -50%);
53
- width: 100%;
54
- max-width: 720px;
55
- }
56
-
57
- @media screen and (max-width: 1024px) {
58
- .ctct-modal .ctct-modal-dialog {
59
- max-width: 75%;
60
- }
61
- }
62
-
63
- @media screen and (max-width: 782px) {
64
- .ctct-modal .ctct-modal-dialog {
65
- left: 7.5%;
66
- top: 15%;
67
- transform: translate(0, 0);
68
- margin-bottom: 15%;
69
- max-width: 85%;
70
- }
71
- }
72
-
73
- .ctct-modal .ctct-modal-content {
74
- background-clip: padding-box;
75
- background-color: #ffffff;
76
- border-radius: 8px;
77
- box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.4);
78
- outline: 0;
79
- padding: rem(10);
80
- position: relative;
81
- }
82
-
83
- .ctct-modal .ctct-modal-content .ctct-modal-header {
84
- background: #88C5E2 url(../images/cc-modal-bg.png) 50% 50% no-repeat;
85
- border-top-left-radius: 8px;
86
- border-top-right-radius: 8px;
87
- padding: 65px 20px 40px;
88
- text-align: center;
89
- }
90
-
91
- .ctct-modal .ctct-modal-content .ctct-modal-header p {
92
- color: #fff;
93
- font-size: 16px;
94
- margin-bottom: 0;
95
- }
96
-
97
- .ctct-modal .ctct-modal-content .ctct-modal-header p .displayed-shortcode {
98
- color: #333333;
99
- }
100
-
101
- .ctct-modal .ctct-modal-content .ctct-modal-header .ctct-logo img {
102
- max-width: 75%;
103
- }
104
-
105
- .ctct-modal .ctct-modal-content .ctct-modal-header .ctct-modal-close {
106
- color: #ffffff;
107
- cursor: pointer;
108
- font-size: 26px;
109
- height: 16px;
110
- line-height: 0;
111
- margin: 0;
112
- outline: none;
113
- padding: 0;
114
- padding: 0;
115
- position: absolute;
116
- right: 10px;
117
- text-decoration: none;
118
- top: 18px;
119
- width: 16px;
120
- }
121
-
122
- .ctct-modal .ctct-modal-content .ctct-modal-header .ctct-modal-close:after {
123
- clear: both;
124
- content: "";
125
- display: table;
126
- }
127
-
128
- .ctct-modal .ctct-modal-content .ctct-modal-footer {
129
- background-color: #EFEFEE;
130
- border-bottom-left-radius: 8px;
131
- border-bottom-right-radius: 8px;
132
- border-top: 3px solid #fff;
133
- padding: 15px 15px 18px;
134
- text-align: center;
135
- }
136
-
137
- .ctct-modal .ctct-modal-content .ctct-modal-footer p {
138
- margin: 0;
139
- font-size: 16px;
140
- }
141
-
142
- .ctct-modal .ctct-modal-content .ctct-modal-footer a {
143
- color: #0078C3;
144
- text-decoration: underline;
145
- }
146
-
147
- .ctct-modal .ctct-modal-content .ctct-modal-footer.ctct-modal-footer-privacy a {
148
- text-decoration: none;
149
- }
150
-
151
- .ctct-modal .ctct-modal-content .ctct-modal-footer .button {
152
- border-radius: 4px;
153
- color: #fff;
154
- font-size: 16px;
155
- font-weight: 600;
156
- height: auto;
157
- line-height: 1;
158
- margin-bottom: 10px;
159
- min-width: 180px;
160
- padding: 14px 30px;
161
- }
162
-
163
- .ctct-modal .ctct-modal-content .ctct-modal-footer .button.no-bg {
164
- border: none;
165
- box-shadow: none;
166
- color: #0078C3;
167
- }
168
-
169
- .ctct-modal .ctct-modal-content .ctct-modal-footer .button.button-orange {
170
- background-color: #FFA901;
171
- border: 1px solid #cd8800;
172
- }
173
-
174
- .ctct-modal .ctct-modal-content .ctct-modal-footer .button.button-orange:hover, .ctct-modal .ctct-modal-content .ctct-modal-footer .button.button-orange:focus {
175
- background-color: #cd8800;
176
- }
177
-
178
- .ctct-modal .ctct-modal-content .ctct-modal-footer .button.button-blue {
179
- background-color: #0078C3;
180
- border: 1px solid #005990;
181
- }
182
-
183
- .ctct-modal .ctct-modal-content .ctct-modal-footer .button.button-blue:hover, .ctct-modal .ctct-modal-content .ctct-modal-footer .button.button-blue:focus {
184
- background-color: #005990;
185
- }
186
-
187
- .ctct-modal .ctct-modal-content .ctct-modal-body {
188
- padding: 15px;
189
- position: relative;
190
- }
191
-
192
- .ctct-modal .ctct-modal-content .ctct-modal-body:after {
193
- clear: both;
194
- content: "";
195
- display: table;
196
- }
197
-
198
- .ctct-modal .ctct-modal-content .ctct-modal-body.ctct-privacy-modal-body {
199
- overflow: scroll;
200
- height: 350px;
201
- }
202
-
203
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left,
204
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right {
205
- float: left;
206
- padding: 15px 50px 15px;
207
- text-align: center;
208
- width: 50%;
209
- box-sizing: border-box;
210
- }
211
-
212
- @media screen and (max-width: 782px) {
213
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left,
214
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right {
215
- width: 100%;
216
- float: none;
217
- }
218
- }
219
-
220
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left img.ctct-modal-flare,
221
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left svg.ctct-modal-flare,
222
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right img.ctct-modal-flare,
223
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right svg.ctct-modal-flare {
224
- max-width: 120px;
225
- height: auto;
226
- }
227
-
228
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left p,
229
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right p {
230
- max-width: 90%;
231
- margin: 0 auto 25px;
232
- }
233
-
234
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left p.small,
235
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right p.small {
236
- line-height: 1;
237
- margin: 0;
238
- max-width: 100%;
239
- }
240
-
241
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left small,
242
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right small {
243
- font-style: italic;
244
- }
245
-
246
- .ctct-modal .ctct-modal-content .ctct-modal-body .now-what {
247
- text-align: center;
248
- }
249
-
250
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left {
251
- border-right: 1px solid #EFEFEE;
252
- }
253
-
254
- @media screen and (max-width: 782px) {
255
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left {
256
- border-bottom: 1px solid #EFEFEE;
257
- border-right: 0;
258
- }
259
- }
260
-
261
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right {
262
- border-left: 2px solid #EFEFEE;
263
- }
264
-
265
- @media screen and (max-width: 782px) {
266
- .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right {
267
- border-top: 1px solid #EFEFEE;
268
- border-left: 0;
269
- }
270
- }
271
-
272
- .ctct-modal .ctct-modal-content .ctct-modal-body.ctct-custom-textarea .ctct-modal-left {
273
- border: none;
274
- padding-left: 15px;
275
- text-align: left;
276
- }
277
-
278
- .ctct-modal .ctct-modal-content .ctct-modal-body.ctct-custom-textarea .ctct-modal-right {
279
- border: none;
280
- padding: 15px;
281
- }
282
-
283
- .ctct-modal .ctct-modal-content .ctct-modal-body.ctct-custom-textarea .ctct-modal-right img {
284
- max-width: 100%;
285
- }
286
-
287
- .ctct-modal .ctct-modal-content .ctct-modal-body .button {
288
- border-radius: 4px;
289
- color: #fff;
290
- font-size: 16px;
291
- font-weight: 600;
292
- height: auto;
293
- line-height: 1;
294
- margin-bottom: 10px;
295
- min-width: 180px;
296
- padding: 14px 30px;
297
- }
298
-
299
- .ctct-modal .ctct-modal-content .ctct-modal-body .button.button-orange {
300
- background-color: #FFA901;
301
- border: 1px solid #cd8800;
302
- }
303
-
304
- .ctct-modal .ctct-modal-content .ctct-modal-body .button.button-orange:hover, .ctct-modal .ctct-modal-content .ctct-modal-body .button.button-orange:focus {
305
- background-color: #cd8800;
306
- }
307
-
308
- .ctct-modal .ctct-modal-content .ctct-modal-body .button.button-blue {
309
- background-color: #0078C3;
310
- border: 1px solid #005990;
311
- }
312
-
313
- .ctct-modal .ctct-modal-content .ctct-modal-body .button.button-blue:hover, .ctct-modal .ctct-modal-content .ctct-modal-body .button.button-blue:focus {
314
- background-color: #005990;
315
- }
316
-
317
- .post-type-ctct_forms .misc-pub-section.misc-pub-visibility, .post-type-ctct_forms .misc-pub-section.misc-pub-curtime {
318
- display: none;
319
- }
320
-
321
- body.post-type-ctct_lists .misc-pub-post-status {
322
- display: none;
323
- }
324
-
325
- body.post-type-ctct_forms #titlediv #title {
326
- height: 2.7em;
327
- }
328
-
329
- .ctct-admin-title-details {
330
- font-size: .6em;
331
- vertical-align: middle;
332
- display: block;
333
- line-height: 2em;
334
- }
335
-
336
- #cmb2-metabox-ctct_1_optin_metabox .cmb2-id--ctct-opt-in-instructions,
337
- #cmb2-metabox-ctct_1_optin_metabox .cmb2-id--ctct-opt-in {
338
- display: none;
339
- }
340
-
341
- #ctct_0_description_metabox #custom_fields_group_repeat .cmb-field-list .cmb-row:not(:last-of-type),
342
- #ctct_1_optin_metabox #custom_fields_group_repeat .cmb-field-list .cmb-row:not(:last-of-type),
343
- #ctct_2_fields_metabox #custom_fields_group_repeat .cmb-field-list .cmb-row:not(:last-of-type) {
344
- border-bottom: none;
345
- padding-bottom: 0.1em;
346
- }
347
-
348
- #ctct_0_description_metabox #custom_fields_group_repeat .required,
349
- #ctct_1_optin_metabox #custom_fields_group_repeat .required,
350
- #ctct_2_fields_metabox #custom_fields_group_repeat .required {
351
- padding-bottom: 0.1em;
352
- padding-top: 0.1em;
353
- }
354
-
355
- #ctct_0_description_metabox #default_fields_group_repeat .cmb-field-list > .cmb-row,
356
- #ctct_1_optin_metabox #default_fields_group_repeat .cmb-field-list > .cmb-row,
357
- #ctct_2_fields_metabox #default_fields_group_repeat .cmb-field-list > .cmb-row {
358
- padding-top: 0.5em;
359
- }
360
-
361
- #ctct_0_description_metabox #default_fields_group_repeat .cmb-field-list > .cmb-row:not(:last-of-type),
362
- #ctct_1_optin_metabox #default_fields_group_repeat .cmb-field-list > .cmb-row:not(:last-of-type),
363
- #ctct_2_fields_metabox #default_fields_group_repeat .cmb-field-list > .cmb-row:not(:last-of-type) {
364
- padding-bottom: 0.1em;
365
- border-bottom: 1px solid #e9e9e9 !important;
366
- }
367
-
368
- #ctct_0_description_metabox .cmb-repeat-group-wrap .cmb-repeatable-grouping,
369
- #ctct_1_optin_metabox .cmb-repeat-group-wrap .cmb-repeatable-grouping,
370
- #ctct_2_fields_metabox .cmb-repeat-group-wrap .cmb-repeatable-grouping {
371
- margin: 0 0 1.5em 0;
372
- }
373
-
374
- #ctct_0_description_metabox .cmb-repeat-group-wrap .cmb-repeatable-grouping .cmb-row,
375
- #ctct_1_optin_metabox .cmb-repeat-group-wrap .cmb-repeatable-grouping .cmb-row,
376
- #ctct_2_fields_metabox .cmb-repeat-group-wrap .cmb-repeatable-grouping .cmb-row {
377
- margin: 0 0 0 0.3em;
378
- }
379
-
380
- #ctct_0_description_metabox .postbox-container .cmb-remove-field-row,
381
- #ctct_1_optin_metabox .postbox-container .cmb-remove-field-row,
382
- #ctct_2_fields_metabox .postbox-container .cmb-remove-field-row {
383
- padding-top: 0.8em;
384
- padding-bottom: 0.8em;
385
- }
386
-
387
- #ctct_0_description_metabox .cmb-repeat-group-wrap,
388
- #ctct_1_optin_metabox .cmb-repeat-group-wrap,
389
- #ctct_2_fields_metabox .cmb-repeat-group-wrap {
390
- padding: 0 !important;
391
- }
392
-
393
- #ctct_0_description_metabox .cmb-repeat-group-wrap .cmb-repeat-group-field,
394
- #ctct_1_optin_metabox .cmb-repeat-group-wrap .cmb-repeat-group-field,
395
- #ctct_2_fields_metabox .cmb-repeat-group-wrap .cmb-repeat-group-field {
396
- padding-top: 0.2em;
397
- }
398
-
399
- #ctct_0_description_metabox button.cmb-add-group-row,
400
- #ctct_1_optin_metabox button.cmb-add-group-row,
401
- #ctct_2_fields_metabox button.cmb-add-group-row {
402
- color: white !important;
403
- background: #008ec2 !important;
404
- border-color: #006799 !important;
405
- }
406
-
407
- #ctct_0_description_metabox .cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row,
408
- #ctct_1_optin_metabox .cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row,
409
- #ctct_2_fields_metabox .cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row {
410
- top: .3em;
411
- }
412
-
413
- #ctct_0_description_metabox button.cmb-remove-group-row,
414
- #ctct_1_optin_metabox button.cmb-remove-group-row,
415
- #ctct_2_fields_metabox button.cmb-remove-group-row {
416
- background: #ffdfa3 !important;
417
- }
418
-
419
- #ctct_0_description_metabox button.cmb-remove-group-row,
420
- #ctct_1_optin_metabox button.cmb-remove-group-row,
421
- #ctct_2_fields_metabox button.cmb-remove-group-row {
422
- display: none;
423
- }
424
-
425
- #ctct_0_description_metabox h3.cmb-group-title.cmbhandle-title,
426
- #ctct_1_optin_metabox h3.cmb-group-title.cmbhandle-title,
427
- #ctct_2_fields_metabox h3.cmb-group-title.cmbhandle-title {
428
- padding-left: 1em;
429
- }
430
-
431
- #ctct_1_optin_metabox .cmb-row {
432
- border-bottom: none;
433
- }
434
-
435
- #ctct_1_optin_metabox .cmb2-id--ctct-list {
436
- padding-bottom: 0.5em;
437
- }
438
-
439
- #ctct_1_optin_metabox .cmb-th {
440
- width: 25%;
441
- }
442
-
443
- #ctct_1_optin_metabox .cmb-th + .cmb-td {
444
- width: 70%;
445
- }
446
-
447
- #ctct_option_metabox_settings span.cmb2-metabox-description {
448
- color: #444444;
449
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/admin-global-no-connection.css DELETED
@@ -1,307 +0,0 @@
1
- #adminmenu .wp-submenu a[href="edit.php?post_type=ctct_forms&page=ctct_options_connect"] {
2
- color: #3ad182;
3
- }
4
-
5
- .ctct_options_connect {
6
- box-sizing: border-box;
7
- padding: 70px;
8
- text-align: center;
9
- width: 100%;
10
- }
11
-
12
- .ctct_options_connect hr {
13
- margin-bottom: 45px;
14
- }
15
-
16
- @media screen and (max-width: 782px) {
17
- .ctct_options_connect {
18
- padding: 30px 30px 0;
19
- margin-left: -10px;
20
- }
21
- }
22
-
23
- .ctct_options_connect .ctct-call-to-action {
24
- margin-bottom: 45px;
25
- overflow: hidden;
26
- text-align: left;
27
- width: 100%;
28
- }
29
-
30
- .ctct_options_connect .ctct-call-to-action p {
31
- float: left;
32
- margin: 0;
33
- }
34
-
35
- .ctct_options_connect .ctct-call-to-action a {
36
- float: right;
37
- text-align: center;
38
- }
39
-
40
- @media screen and (max-width: 782px) {
41
- .ctct_options_connect .ctct-call-to-action a {
42
- float: none;
43
- }
44
- }
45
-
46
- .ctct_options_connect .ctct-call-to-action .ctct-call-to-action-text a {
47
- float: none;
48
- }
49
-
50
- .ctct_options_connect .ctct-call-to-action .ctct-call-to-action-text small {
51
- line-height: 1.2px;
52
- }
53
-
54
- .ctct_options_connect .ctct-call-to-action #subbox {
55
- height: 40px;
56
- margin: 15px 0;
57
- width: 50%;
58
- }
59
-
60
- .ctct_options_connect .ctct-call-to-action #subbutton {
61
- color: #0078C3;
62
- float: right;
63
- }
64
-
65
- @media screen and (max-width: 782px) {
66
- .ctct_options_connect .ctct-call-to-action #subbutton {
67
- float: none;
68
- }
69
- }
70
-
71
- .ctct_options_connect img {
72
- width: 100%;
73
- max-width: 400px;
74
- height: auto;
75
- }
76
-
77
- .ctct_options_connect h3 {
78
- color: #005990;
79
- font-size: 20px;
80
- line-height: 1.2;
81
- margin-bottom: 10px;
82
- margin-top: 10px;
83
- }
84
-
85
- .ctct_options_connect p {
86
- color: #606d78;
87
- font-size: 14.7px;
88
- margin: 0;
89
- }
90
-
91
- .ctct_options_connect p.ctct-description {
92
- font-size: 16px;
93
- margin-bottom: 50px;
94
- margin-top: 5px;
95
- }
96
-
97
- .ctct_options_connect p.small {
98
- color: #747e88;
99
- font-size: 13.3px;
100
- margin: 15px auto 0;
101
- }
102
-
103
- @media screen and (max-width: 782px) {
104
- .ctct_options_connect p.small {
105
- max-width: 100%;
106
- }
107
- }
108
-
109
- .ctct_options_connect .ctct-body {
110
- margin: 0 auto;
111
- max-width: 75%;
112
- overflow-y: hidden;
113
- position: relative;
114
- }
115
-
116
- .ctct_options_connect .ctct-body:after {
117
- clear: both;
118
- content: "";
119
- display: table;
120
- }
121
-
122
- .ctct_options_connect .ctct-body .ctct-call-to-action-text {
123
- float: left;
124
- width: 75%;
125
- }
126
-
127
- @media screen and (max-width: 782px) {
128
- .ctct_options_connect .ctct-body .ctct-call-to-action-text {
129
- width: 100%;
130
- }
131
- }
132
-
133
- .ctct_options_connect .ctct-body .ctct-call-to-action-text h3 {
134
- margin-top: 0;
135
- }
136
-
137
- .ctct_options_connect .ctct-body .clear {
138
- width: 100%;
139
- clear: both;
140
- height: 0;
141
- }
142
-
143
- .ctct_options_connect .ctct-body .left,
144
- .ctct_options_connect .ctct-body .right {
145
- box-sizing: border-box;
146
- box-sizing: border-box;
147
- float: left;
148
- margin-bottom: -500px;
149
- padding: 15px 0px 520px;
150
- text-align: center;
151
- width: 50%;
152
- }
153
-
154
- @media screen and (max-width: 782px) {
155
- .ctct_options_connect .ctct-body .left,
156
- .ctct_options_connect .ctct-body .right {
157
- float: none;
158
- margin-bottom: 0;
159
- padding: 15px 0;
160
- width: 100%;
161
- }
162
- }
163
-
164
- .ctct_options_connect .ctct-body .left img.flare,
165
- .ctct_options_connect .ctct-body .left svg.flare,
166
- .ctct_options_connect .ctct-body .right img.flare,
167
- .ctct_options_connect .ctct-body .right svg.flare {
168
- width: 180px;
169
- height: auto;
170
- }
171
-
172
- .ctct_options_connect .ctct-body .left {
173
- border-right: 1px solid #ddd;
174
- padding-right: 70px;
175
- }
176
-
177
- @media screen and (max-width: 782px) {
178
- .ctct_options_connect .ctct-body .left {
179
- border-bottom: 1px solid #ddd;
180
- border-right: 0;
181
- padding-bottom: 30px;
182
- padding-right: 0;
183
- }
184
- }
185
-
186
- .ctct_options_connect .ctct-body .left p {
187
- max-width: 220px;
188
- margin: 0 auto 25px;
189
- }
190
-
191
- @media screen and (max-width: 782px) {
192
- .ctct_options_connect .ctct-body .left p {
193
- max-width: 100%;
194
- }
195
- }
196
-
197
- .ctct_options_connect .ctct-body .right {
198
- padding-left: 70px;
199
- }
200
-
201
- @media screen and (max-width: 782px) {
202
- .ctct_options_connect .ctct-body .right {
203
- padding-left: 0;
204
- padding-top: 30px;
205
- }
206
- }
207
-
208
- .ctct_options_connect .ctct-body .right p {
209
- display: block;
210
- max-width: 350px;
211
- margin: 0 auto 25px;
212
- }
213
-
214
- @media screen and (max-width: 782px) {
215
- .ctct_options_connect .ctct-body .right p {
216
- max-width: 100%;
217
- }
218
- }
219
-
220
- .ctct_options_connect .ctct-body .button {
221
- border-radius: 4px;
222
- color: #fff;
223
- font-size: 16px;
224
- font-weight: 600;
225
- height: auto;
226
- line-height: 1;
227
- margin-bottom: 10px;
228
- min-width: 180px;
229
- padding: 14px 30px;
230
- }
231
-
232
- .ctct_options_connect .ctct-body .button.button-orange {
233
- background-color: #FFA901;
234
- border: 1px solid #cd8800;
235
- }
236
-
237
- .ctct_options_connect .ctct-body .button.button-orange:hover, .ctct_options_connect .ctct-body .button.button-orange:focus {
238
- background-color: #cd8800;
239
- }
240
-
241
- .ctct_options_connect .ctct-body .button.button-blue {
242
- background-color: #0078C3;
243
- border: 1px solid #005990;
244
- }
245
-
246
- .ctct_options_connect .ctct-body .button.button-blue:hover, .ctct_options_connect .ctct-body .button.button-blue:focus {
247
- background-color: #005990;
248
- }
249
-
250
- .ctct_options_connect .ctct-body .ctct-connected .ctct-connected-next-step {
251
- margin-bottom: 40px;
252
- }
253
-
254
- .ctct_options_connect .ctct-body .ctct-connected .ctct-connected-next-step h3 {
255
- color: #2ECC40;
256
- }
257
-
258
- .ctct_options_connect .ctct-body .ctct-connected .ctct-disconnect-text {
259
- float: left;
260
- margin-bottom: 50px;
261
- overflow: hidden;
262
- text-align: left;
263
- }
264
-
265
- .ctct_options_connect .ctct-body .ctct-connected form {
266
- float: right;
267
- }
268
-
269
- .ctct_options_connect .ctct-body .ctct-connected .button {
270
- color: #0078C3;
271
- }
272
-
273
- .ctct_options_connect .ctct-body .ctct-connected .button.button-blue {
274
- color: #fff;
275
- }
276
-
277
- .ctct_options_connect .ctct-body .ctct-connected .ctct-connected-next-step {
278
- clear: both;
279
- }
280
-
281
- .ctct_options_connect .ctct-body .ctct-connected .ctct-connect-ga-optin {
282
- margin-top: 15px;
283
- }
284
-
285
- @media screen and (max-width: 782px) {
286
- .ctct_options_connect .ctct-body .ctct-connected .ctct-disconnect-text {
287
- float: none;
288
- text-align: center;
289
- }
290
- .ctct_options_connect .ctct-body .ctct-connected form {
291
- float: none;
292
- }
293
- }
294
-
295
- .error {
296
- background: none !important;
297
- border-left: 1px solid #FF4136 !important;
298
- border-radius: 3px;
299
- border: 1px solid #FF4136;
300
- box-shadow: none !important;
301
- display: inline-block;
302
- margin: 0 0 20px 0 !important;
303
- }
304
-
305
- .error p {
306
- color: #FF4136 !important;
307
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/admin-notices.css DELETED
@@ -1,50 +0,0 @@
1
- .updated.ctct-admin-notice,
2
- .error.ctct-admin-notice {
3
- padding: 1em 38px 1em 1em;
4
- position: relative;
5
- }
6
-
7
- a.ctct-notice-dismiss {
8
- text-decoration: none;
9
- }
10
-
11
- #ctct-admin-notice-activation {
12
- padding: 1em 1em 0 1em;
13
- }
14
-
15
- #ctct-admin-notice-activation .ctct-notice-intro {
16
- max-width: 600px;
17
- line-height: 1.5em;
18
- }
19
-
20
- #ctct-admin-notice-activation .ctct-notice-button,
21
- #ctct-admin-notice-activation .ctct-notice-button:active {
22
- vertical-align: middle;
23
- margin: .5em;
24
- }
25
-
26
- .ctct-admin-notice {
27
- overflow: hidden;
28
- }
29
-
30
- .ctct-admin-notice.updated {
31
- border-left-color: #1a5285;
32
- }
33
-
34
- .ctct-admin-notice > div {
35
- float: left;
36
- }
37
-
38
- .ctct-admin-notice .admin-notice-message {
39
- margin-left: 15px;
40
- width: 80%;
41
- }
42
-
43
- .ctct-admin-notice .admin-notice-message h4 {
44
- color: #1a5285;
45
- margin: 0 0 10px;
46
- }
47
-
48
- .ctct-admin-notice .admin-notice-message > div {
49
- float: left;
50
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/admin-pages.css DELETED
@@ -1,351 +0,0 @@
1
- .constant-contact-about {
2
- padding: 15px;
3
- }
4
-
5
- @media screen and (max-width: 782px) {
6
- .constant-contact-about {
7
- padding: 0;
8
- }
9
- }
10
-
11
- .constant-contact-about .ctct-section {
12
- margin-bottom: 50px;
13
- }
14
-
15
- .constant-contact-about h1.about-header {
16
- color: #1a5285;
17
- font-size: 26px;
18
- margin: 0 0 15px 0;
19
- }
20
-
21
- .constant-contact-about h3 {
22
- padding: 20px 0;
23
- }
24
-
25
- .constant-contact-about p {
26
- font-size: 16px;
27
- font-weight: 300;
28
- color: #333333;
29
- }
30
-
31
- .constant-contact-about .clear {
32
- width: 100%;
33
- clear: both;
34
- height: 0;
35
- }
36
-
37
- .constant-contact-about .button {
38
- border-radius: 4px;
39
- color: #fff;
40
- font-size: 16px;
41
- font-weight: 600;
42
- height: auto;
43
- line-height: 1;
44
- margin-bottom: 10px;
45
- min-width: 180px;
46
- padding: 14px 30px;
47
- text-align: center;
48
- }
49
-
50
- .constant-contact-about .button.button-orange {
51
- background-color: #FFA901;
52
- border: 1px solid #cd8800;
53
- }
54
-
55
- .constant-contact-about .button.button-orange:hover, .constant-contact-about .button.button-orange:focus {
56
- background-color: #cd8800;
57
- }
58
-
59
- .constant-contact-about .button.button-blue {
60
- background-color: #0078C3;
61
- border: 1px solid #005990;
62
- }
63
-
64
- .constant-contact-about .button.button-blue:hover, .constant-contact-about .button.button-blue:focus {
65
- background-color: #005990;
66
- }
67
-
68
- .constant-contact-about .about-text {
69
- margin: 0 50px 0 0;
70
- }
71
-
72
- @media screen and (max-width: 482px) {
73
- .constant-contact-about .about-text {
74
- margiun: 0;
75
- }
76
- }
77
-
78
- .constant-contact-about .feature-section.two-col > div {
79
- width: 49%;
80
- float: left;
81
- }
82
-
83
- .constant-contact-about .headline-feature {
84
- max-width: 90%;
85
- }
86
-
87
- @media screen and (max-width: 782px) {
88
- .constant-contact-about .headline-feature {
89
- max-width: 100%;
90
- }
91
- }
92
-
93
- .constant-contact-about .headline-feature p {
94
- margin-bottom: 0;
95
- }
96
-
97
- .constant-contact-about .headline-feature h5 {
98
- font-weight: 300;
99
- color: #747e88;
100
- font-style: italic;
101
- }
102
-
103
- .constant-contact-about .headline-title, .constant-contact-about .c-text {
104
- text-align: center;
105
- }
106
-
107
- .constant-contact-about .featured-image {
108
- min-height: 150px;
109
- position: relative;
110
- }
111
-
112
- .constant-contact-about .fff-img {
113
- height: 315px;
114
- margin: 20px;
115
- overflow: hidden;
116
- max-width: 720px;
117
- }
118
-
119
- .constant-contact-about .introduction {
120
- padding: 20px 0;
121
- }
122
-
123
- .constant-contact-about .featured-title {
124
- color: white;
125
- font-size: 2em;
126
- font-weight: bold;
127
- margin: 0 auto;
128
- position: absolute;
129
- text-align: center;
130
- text-shadow: 0 0 15px #000;
131
- top: 80px;
132
- width: 100%;
133
- }
134
-
135
- @media screen and (max-width: 482px) {
136
- .constant-contact-about .featured-title {
137
- color: #1a5285;
138
- font-size: 26px;
139
- line-height: 28px;
140
- margin-top: 15px;
141
- position: relative;
142
- text-shadow: none;
143
- top: 0;
144
- }
145
- }
146
-
147
- .constant-contact-about .featured-introduction {
148
- color: white;
149
- font-size: 1.2em;
150
- margin: 0 auto;
151
- position: absolute;
152
- text-align: center;
153
- text-shadow: 0 0 15px #000;
154
- top: 120px;
155
- width: 100%;
156
- }
157
-
158
- @media screen and (max-width: 482px) {
159
- .constant-contact-about .featured-introduction {
160
- color: #1a5285;
161
- line-height: 1;
162
- margin-top: 15px;
163
- position: relative;
164
- text-shadow: none;
165
- top: 0;
166
- }
167
- }
168
-
169
- .constant-contact-about .hide-overflow {
170
- overflow: hidden;
171
- position: relative;
172
- }
173
-
174
- .constant-contact-about .hide-overflow hr {
175
- margin-top: 30px;
176
- }
177
-
178
- .constant-contact-about .hide-overflow h2 {
179
- font-weight: 400;
180
- font-size: 16px;
181
- color: #1a5285;
182
- text-align: left;
183
- margin-top: 30px;
184
- }
185
-
186
- .constant-contact-about .left-side {
187
- float: left;
188
- box-sizing: border-box;
189
- padding-right: 160px;
190
- }
191
-
192
- @media screen and (max-width: 482px) {
193
- .constant-contact-about .left-side {
194
- padding-right: 0;
195
- }
196
- }
197
-
198
- .constant-contact-about .plugin-badge {
199
- float: right;
200
- max-height: 180px;
201
- max-width: 160px;
202
- margin-left: 40px;
203
- }
204
-
205
- @media screen and (max-width: 482px) {
206
- .constant-contact-about .plugin-badge {
207
- display: none;
208
- }
209
- }
210
-
211
- .constant-contact-about .feature-image {
212
- text-align: center;
213
- }
214
-
215
- .cc-a-block {
216
- margin: 0 auto;
217
- max-width: 90%;
218
- padding: 50px 0;
219
- text-align: center;
220
- }
221
-
222
- .cc-a-block:after {
223
- clear: both;
224
- content: "";
225
- display: table;
226
- }
227
-
228
- @media screen and (max-width: 482px) {
229
- .cc-a-block {
230
- padding: 25px 0;
231
- }
232
- }
233
-
234
- .cc-a-block h3 {
235
- color: #1a5285;
236
- font-size: 21px;
237
- font-weight: 300;
238
- height: 63px;
239
- margin: 0 auto;
240
- max-width: 70%;
241
- }
242
-
243
- @media screen and (max-width: 782px) {
244
- .cc-a-block h3 {
245
- height: auto;
246
- max-width: 100%;
247
- }
248
- }
249
-
250
- .cc-a-block .left,
251
- .cc-a-block .right {
252
- float: left;
253
- width: 50%;
254
- }
255
-
256
- .cc-a-block .left:after,
257
- .cc-a-block .right:after {
258
- clear: both;
259
- content: "";
260
- display: table;
261
- }
262
-
263
- @media screen and (max-width: 482px) {
264
- .cc-a-block .left,
265
- .cc-a-block .right {
266
- width: 100%;
267
- float: none;
268
- }
269
- }
270
-
271
- .cc-a-block .left .ad-1,
272
- .cc-a-block .left .ad-2,
273
- .cc-a-block .right .ad-1,
274
- .cc-a-block .right .ad-2 {
275
- width: 90%;
276
- }
277
-
278
- @media screen and (max-width: 482px) {
279
- .cc-a-block .left .ad-1,
280
- .cc-a-block .left .ad-2,
281
- .cc-a-block .right .ad-1,
282
- .cc-a-block .right .ad-2 {
283
- width: 100%;
284
- float: none;
285
- }
286
- }
287
-
288
- .cc-a-block .left .ad-1 img,
289
- .cc-a-block .left .ad-2 img,
290
- .cc-a-block .right .ad-1 img,
291
- .cc-a-block .right .ad-2 img {
292
- width: 100%;
293
- height: auto;
294
- }
295
-
296
- .cc-a-block .left .ad-1,
297
- .cc-a-block .right .ad-1 {
298
- float: left;
299
- }
300
-
301
- .cc-a-block .left .ad-1 h3,
302
- .cc-a-block .right .ad-1 h3 {
303
- padding-top: 35px;
304
- height: 47px;
305
- }
306
-
307
- .cc-a-block .left .ad-2,
308
- .cc-a-block .right .ad-2 {
309
- float: right;
310
- }
311
-
312
- .ctct-bonus-points {
313
- list-style: circle;
314
- padding-left: 50px;
315
- font-size: 16px;
316
- font-weight: 300;
317
- color: #2b5e8c;
318
- }
319
-
320
- .section-try-us .ctct-bonus-points {
321
- margin-bottom: 50px;
322
- }
323
-
324
- .section-try-us a.button {
325
- margin-right: 40px;
326
- }
327
-
328
- .section-try-us a.ctct-connect {
329
- font-weight: bold;
330
- }
331
-
332
- .section-marketing-tips #subbox {
333
- height: 40px;
334
- width: 50%;
335
- }
336
-
337
- #cmb2-metabox-ctct_option_metabox_settings .regular-text {
338
- width: 500px;
339
- }
340
-
341
- .cmb2-options-page #ctct_option_metabox_settings .cmb2-metabox > .cmb-row {
342
- background: transparent;
343
- border: none;
344
- box-shadow: none;
345
- }
346
-
347
- .ctct-body #ctct_error_logs {
348
- height: 400px;
349
- resize: vertical;
350
- width: 100%;
351
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/admin-style.css ADDED
@@ -0,0 +1,1307 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .ctct-modal {
2
+ -moz-osx-font-smoothing: grayscale;
3
+ -webkit-font-smoothing: antialiased;
4
+ background-color: rgba(0, 0, 0, 0.3);
5
+ bottom: 0;
6
+ display: none;
7
+ left: 0;
8
+ overflow: hidden;
9
+ position: fixed;
10
+ right: 0;
11
+ top: 0;
12
+ z-index: 9999;
13
+ }
14
+
15
+ .ctct-modal:after {
16
+ clear: both;
17
+ content: "";
18
+ display: table;
19
+ }
20
+
21
+ .ctct-modal h2 {
22
+ color: #fff;
23
+ font-size: 28px;
24
+ font-weight: 400;
25
+ line-height: 1.2;
26
+ margin: 0;
27
+ }
28
+
29
+ .ctct-modal h3 {
30
+ color: #005990;
31
+ font-size: 18px;
32
+ line-height: 1.2;
33
+ margin-bottom: 15px;
34
+ margin-top: 10px;
35
+ }
36
+
37
+ .ctct-modal p {
38
+ color: #555555;
39
+ font-size: 14.7px;
40
+ }
41
+
42
+ .ctct-modal.ctct-modal-open {
43
+ display: block;
44
+ overflow-x: hidden;
45
+ overflow-y: auto;
46
+ }
47
+
48
+ .ctct-modal .ctct-modal-dialog {
49
+ left: 50%;
50
+ position: absolute;
51
+ top: 50%;
52
+ transform: translate(-50%, -50%);
53
+ width: 100%;
54
+ max-width: 720px;
55
+ }
56
+
57
+ @media screen and (max-width: 1024px) {
58
+ .ctct-modal .ctct-modal-dialog {
59
+ max-width: 75%;
60
+ }
61
+ }
62
+
63
+ @media screen and (max-width: 782px) {
64
+ .ctct-modal .ctct-modal-dialog {
65
+ left: 7.5%;
66
+ top: 15%;
67
+ transform: translate(0, 0);
68
+ margin-bottom: 15%;
69
+ max-width: 85%;
70
+ }
71
+ }
72
+
73
+ .ctct-modal .ctct-modal-content {
74
+ background-clip: padding-box;
75
+ background-color: #ffffff;
76
+ border-radius: 8px;
77
+ box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.4);
78
+ outline: 0;
79
+ padding: rem(10);
80
+ position: relative;
81
+ }
82
+
83
+ .ctct-modal .ctct-modal-content .ctct-modal-header {
84
+ background: #88C5E2 url(../images/cc-modal-bg.png) 50% 50% no-repeat;
85
+ border-top-left-radius: 8px;
86
+ border-top-right-radius: 8px;
87
+ padding: 65px 20px 40px;
88
+ text-align: center;
89
+ }
90
+
91
+ .ctct-modal .ctct-modal-content .ctct-modal-header p {
92
+ color: #fff;
93
+ font-size: 16px;
94
+ margin-bottom: 0;
95
+ }
96
+
97
+ .ctct-modal .ctct-modal-content .ctct-modal-header p .displayed-shortcode {
98
+ color: #333333;
99
+ }
100
+
101
+ .ctct-modal .ctct-modal-content .ctct-modal-header .ctct-logo img {
102
+ max-width: 75%;
103
+ }
104
+
105
+ .ctct-modal .ctct-modal-content .ctct-modal-header .ctct-modal-close {
106
+ color: #ffffff;
107
+ cursor: pointer;
108
+ font-size: 26px;
109
+ height: 16px;
110
+ line-height: 0;
111
+ margin: 0;
112
+ outline: none;
113
+ padding: 0;
114
+ padding: 0;
115
+ position: absolute;
116
+ right: 10px;
117
+ text-decoration: none;
118
+ top: 18px;
119
+ width: 16px;
120
+ }
121
+
122
+ .ctct-modal .ctct-modal-content .ctct-modal-header .ctct-modal-close:after {
123
+ clear: both;
124
+ content: "";
125
+ display: table;
126
+ }
127
+
128
+ .ctct-modal .ctct-modal-content .ctct-modal-footer {
129
+ background-color: #EFEFEE;
130
+ border-bottom-left-radius: 8px;
131
+ border-bottom-right-radius: 8px;
132
+ border-top: 3px solid #fff;
133
+ padding: 15px 15px 18px;
134
+ text-align: center;
135
+ }
136
+
137
+ .ctct-modal .ctct-modal-content .ctct-modal-footer p {
138
+ margin: 0;
139
+ font-size: 16px;
140
+ }
141
+
142
+ .ctct-modal .ctct-modal-content .ctct-modal-footer a {
143
+ color: #0078C3;
144
+ text-decoration: underline;
145
+ }
146
+
147
+ .ctct-modal .ctct-modal-content .ctct-modal-footer.ctct-modal-footer-privacy a {
148
+ text-decoration: none;
149
+ }
150
+
151
+ .ctct-modal .ctct-modal-content .ctct-modal-footer .button {
152
+ border-radius: 4px;
153
+ color: #fff;
154
+ font-size: 16px;
155
+ font-weight: 600;
156
+ height: auto;
157
+ line-height: 1;
158
+ margin-bottom: 10px;
159
+ min-width: 180px;
160
+ padding: 14px 30px;
161
+ }
162
+
163
+ .ctct-modal .ctct-modal-content .ctct-modal-footer .button.no-bg {
164
+ border: none;
165
+ box-shadow: none;
166
+ color: #0078C3;
167
+ }
168
+
169
+ .ctct-modal .ctct-modal-content .ctct-modal-footer .button.button-orange {
170
+ background-color: #FFA901;
171
+ border: 1px solid #cd8800;
172
+ }
173
+
174
+ .ctct-modal .ctct-modal-content .ctct-modal-footer .button.button-orange:hover, .ctct-modal .ctct-modal-content .ctct-modal-footer .button.button-orange:focus {
175
+ background-color: #cd8800;
176
+ }
177
+
178
+ .ctct-modal .ctct-modal-content .ctct-modal-footer .button.button-blue {
179
+ background-color: #0078C3;
180
+ border: 1px solid #005990;
181
+ }
182
+
183
+ .ctct-modal .ctct-modal-content .ctct-modal-footer .button.button-blue:hover, .ctct-modal .ctct-modal-content .ctct-modal-footer .button.button-blue:focus {
184
+ background-color: #005990;
185
+ }
186
+
187
+ .ctct-modal .ctct-modal-content .ctct-modal-body {
188
+ padding: 15px;
189
+ position: relative;
190
+ }
191
+
192
+ .ctct-modal .ctct-modal-content .ctct-modal-body:after {
193
+ clear: both;
194
+ content: "";
195
+ display: table;
196
+ }
197
+
198
+ .ctct-modal .ctct-modal-content .ctct-modal-body.ctct-privacy-modal-body {
199
+ overflow: scroll;
200
+ height: 350px;
201
+ }
202
+
203
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left,
204
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right {
205
+ float: left;
206
+ padding: 15px 50px 15px;
207
+ text-align: center;
208
+ width: 50%;
209
+ box-sizing: border-box;
210
+ }
211
+
212
+ @media screen and (max-width: 782px) {
213
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left,
214
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right {
215
+ width: 100%;
216
+ float: none;
217
+ }
218
+ }
219
+
220
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left img.ctct-modal-flare,
221
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left svg.ctct-modal-flare,
222
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right img.ctct-modal-flare,
223
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right svg.ctct-modal-flare {
224
+ max-width: 120px;
225
+ height: auto;
226
+ }
227
+
228
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left p,
229
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right p {
230
+ max-width: 90%;
231
+ margin: 0 auto 25px;
232
+ }
233
+
234
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left p.small,
235
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right p.small {
236
+ line-height: 1;
237
+ margin: 0;
238
+ max-width: 100%;
239
+ }
240
+
241
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left small,
242
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right small {
243
+ font-style: italic;
244
+ }
245
+
246
+ .ctct-modal .ctct-modal-content .ctct-modal-body .now-what {
247
+ text-align: center;
248
+ }
249
+
250
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left {
251
+ border-right: 1px solid #EFEFEE;
252
+ }
253
+
254
+ @media screen and (max-width: 782px) {
255
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-left {
256
+ border-bottom: 1px solid #EFEFEE;
257
+ border-right: 0;
258
+ }
259
+ }
260
+
261
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right {
262
+ border-left: 2px solid #EFEFEE;
263
+ }
264
+
265
+ @media screen and (max-width: 782px) {
266
+ .ctct-modal .ctct-modal-content .ctct-modal-body .ctct-modal-right {
267
+ border-top: 1px solid #EFEFEE;
268
+ border-left: 0;
269
+ }
270
+ }
271
+
272
+ .ctct-modal .ctct-modal-content .ctct-modal-body.ctct-custom-textarea .ctct-modal-left {
273
+ border: none;
274
+ padding-left: 15px;
275
+ text-align: left;
276
+ }
277
+
278
+ .ctct-modal .ctct-modal-content .ctct-modal-body.ctct-custom-textarea .ctct-modal-right {
279
+ border: none;
280
+ padding: 15px;
281
+ }
282
+
283
+ .ctct-modal .ctct-modal-content .ctct-modal-body.ctct-custom-textarea .ctct-modal-right img {
284
+ max-width: 100%;
285
+ }
286
+
287
+ .ctct-modal .ctct-modal-content .ctct-modal-body .button {
288
+ border-radius: 4px;
289
+ color: #fff;
290
+ font-size: 16px;
291
+ font-weight: 600;
292
+ height: auto;
293
+ line-height: 1;
294
+ margin-bottom: 10px;
295
+ min-width: 180px;
296
+ padding: 14px 30px;
297
+ }
298
+
299
+ .ctct-modal .ctct-modal-content .ctct-modal-body .button.button-orange {
300
+ background-color: #FFA901;
301
+ border: 1px solid #cd8800;
302
+ }
303
+
304
+ .ctct-modal .ctct-modal-content .ctct-modal-body .button.button-orange:hover, .ctct-modal .ctct-modal-content .ctct-modal-body .button.button-orange:focus {
305
+ background-color: #cd8800;
306
+ }
307
+
308
+ .ctct-modal .ctct-modal-content .ctct-modal-body .button.button-blue {
309
+ background-color: #0078C3;
310
+ border: 1px solid #005990;
311
+ }
312
+
313
+ .ctct-modal .ctct-modal-content .ctct-modal-body .button.button-blue:hover, .ctct-modal .ctct-modal-content .ctct-modal-body .button.button-blue:focus {
314
+ background-color: #005990;
315
+ }
316
+
317
+ .post-type-ctct_forms .misc-pub-section.misc-pub-visibility, .post-type-ctct_forms .misc-pub-section.misc-pub-curtime {
318
+ display: none;
319
+ }
320
+
321
+ body.post-type-ctct_lists .misc-pub-post-status {
322
+ display: none;
323
+ }
324
+
325
+ body.post-type-ctct_forms #titlediv #title {
326
+ height: 2.7em;
327
+ }
328
+
329
+ .ctct-admin-title-details {
330
+ font-size: .6em;
331
+ vertical-align: middle;
332
+ display: block;
333
+ line-height: 2em;
334
+ }
335
+
336
+ #cmb2-metabox-ctct_1_optin_metabox .cmb2-id--ctct-opt-in-instructions,
337
+ #cmb2-metabox-ctct_1_optin_metabox .cmb2-id--ctct-opt-in {
338
+ display: none;
339
+ }
340
+
341
+ #ctct_0_list_metabox .cmb-row,
342
+ #ctct_1_custom_form_css_metabox .cmb-row,
343
+ #ctct_1_custom_input_css_metabox .cmb-row {
344
+ padding-bottom: 0;
345
+ }
346
+
347
+ #cmb2-metabox-ctct_2_fields_metabox .cmb2-id--ctct-title {
348
+ padding: .8em 0 1em;
349
+ }
350
+
351
+ #ctct_1_custom_form_css_metabox .cmb2-id-form-title-title {
352
+ padding: .8em 0 1em;
353
+ }
354
+
355
+ #ctct_0_description_metabox #custom_fields_group_repeat .cmb-field-list .cmb-row:not(:last-of-type),
356
+ #ctct_1_optin_metabox #custom_fields_group_repeat .cmb-field-list .cmb-row:not(:last-of-type),
357
+ #ctct_2_fields_metabox #custom_fields_group_repeat .cmb-field-list .cmb-row:not(:last-of-type) {
358
+ border-bottom: none;
359
+ padding-bottom: 0.1em;
360
+ }
361
+
362
+ #ctct_0_description_metabox #custom_fields_group_repeat .required,
363
+ #ctct_1_optin_metabox #custom_fields_group_repeat .required,
364
+ #ctct_2_fields_metabox #custom_fields_group_repeat .required {
365
+ padding-bottom: 0.1em;
366
+ padding-top: 0.1em;
367
+ }
368
+
369
+ #ctct_0_description_metabox #default_fields_group_repeat .cmb-field-list > .cmb-row,
370
+ #ctct_1_optin_metabox #default_fields_group_repeat .cmb-field-list > .cmb-row,
371
+ #ctct_2_fields_metabox #default_fields_group_repeat .cmb-field-list > .cmb-row {
372
+ padding-top: 0.5em;
373
+ }
374
+
375
+ #ctct_0_description_metabox #default_fields_group_repeat .cmb-field-list > .cmb-row:not(:last-of-type),
376
+ #ctct_1_optin_metabox #default_fields_group_repeat .cmb-field-list > .cmb-row:not(:last-of-type),
377
+ #ctct_2_fields_metabox #default_fields_group_repeat .cmb-field-list > .cmb-row:not(:last-of-type) {
378
+ padding-bottom: 0.1em;
379
+ border-bottom: 1px solid #e9e9e9 !important;
380
+ }
381
+
382
+ #ctct_0_description_metabox .cmb-repeat-group-wrap,
383
+ #ctct_1_optin_metabox .cmb-repeat-group-wrap,
384
+ #ctct_2_fields_metabox .cmb-repeat-group-wrap {
385
+ padding: 0 !important;
386
+ }
387
+
388
+ #ctct_0_description_metabox .cmb-repeat-group-wrap .cmb-repeatable-grouping,
389
+ #ctct_1_optin_metabox .cmb-repeat-group-wrap .cmb-repeatable-grouping,
390
+ #ctct_2_fields_metabox .cmb-repeat-group-wrap .cmb-repeatable-grouping {
391
+ margin: 0 0 1.5em 0;
392
+ }
393
+
394
+ #ctct_0_description_metabox .cmb-repeat-group-wrap .cmb-repeatable-grouping .cmb-row,
395
+ #ctct_1_optin_metabox .cmb-repeat-group-wrap .cmb-repeatable-grouping .cmb-row,
396
+ #ctct_2_fields_metabox .cmb-repeat-group-wrap .cmb-repeatable-grouping .cmb-row {
397
+ margin: 0 0 0 0.3em;
398
+ }
399
+
400
+ #ctct_0_description_metabox .cmb-repeat-group-wrap .cmb-repeat-group-field,
401
+ #ctct_1_optin_metabox .cmb-repeat-group-wrap .cmb-repeat-group-field,
402
+ #ctct_2_fields_metabox .cmb-repeat-group-wrap .cmb-repeat-group-field {
403
+ padding-top: 0.2em;
404
+ }
405
+
406
+ #ctct_0_description_metabox .postbox-container .cmb-remove-field-row,
407
+ #ctct_1_optin_metabox .postbox-container .cmb-remove-field-row,
408
+ #ctct_2_fields_metabox .postbox-container .cmb-remove-field-row {
409
+ padding-top: 0.8em;
410
+ padding-bottom: 0.8em;
411
+ }
412
+
413
+ #ctct_0_description_metabox button.cmb-add-group-row,
414
+ #ctct_1_optin_metabox button.cmb-add-group-row,
415
+ #ctct_2_fields_metabox button.cmb-add-group-row {
416
+ color: white !important;
417
+ background: #008ec2 !important;
418
+ border-color: #006799 !important;
419
+ }
420
+
421
+ #ctct_0_description_metabox button.cmb-remove-group-row,
422
+ #ctct_1_optin_metabox button.cmb-remove-group-row,
423
+ #ctct_2_fields_metabox button.cmb-remove-group-row {
424
+ background: #ffdfa3 !important;
425
+ display: none;
426
+ }
427
+
428
+ #ctct_0_description_metabox .cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row,
429
+ #ctct_1_optin_metabox .cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row,
430
+ #ctct_2_fields_metabox .cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row {
431
+ top: .3em;
432
+ }
433
+
434
+ #ctct_0_description_metabox h3.cmb-group-title.cmbhandle-title,
435
+ #ctct_1_optin_metabox h3.cmb-group-title.cmbhandle-title,
436
+ #ctct_2_fields_metabox h3.cmb-group-title.cmbhandle-title {
437
+ padding-left: 1em;
438
+ }
439
+
440
+ #ctct_1_optin_metabox .cmb-row {
441
+ border-bottom: none;
442
+ padding: .5em 0px;
443
+ }
444
+
445
+ #ctct_1_optin_metabox .cmb2-id--ctct-list {
446
+ padding-bottom: 0.5em;
447
+ }
448
+
449
+ #ctct_1_optin_metabox .cmb-th {
450
+ width: 25%;
451
+ }
452
+
453
+ #ctct_1_optin_metabox .cmb-th + .cmb-td {
454
+ width: 70%;
455
+ }
456
+
457
+ #ctct_option_metabox_settings span.cmb2-metabox-description {
458
+ color: #444444;
459
+ }
460
+
461
+ #cmb2-metabox-email_settings .cmb-row,
462
+ #cmb2-metabox-ctct_2_generated_metabox .cmb-row,
463
+ #cmb2-metabox-ctct_1_custom_input_css_metabox .cmb-row {
464
+ padding-bottom: 0px !important;
465
+ }
466
+
467
+ #side-sortables #ctct_1_custom_form_css_metabox .cmb-row {
468
+ padding: 0.5em 0 0 0;
469
+ }
470
+
471
+ #side-sortables #ctct_1_custom_form_css_metabox .cmb-th {
472
+ padding-bottom: 0;
473
+ }
474
+
475
+ #side-sortables #ctct_1_custom_form_css_metabox .cmb-type-title {
476
+ border-bottom: none;
477
+ }
478
+
479
+ #side-sortables #ctct_1_custom_form_css_metabox .cmb2-id--ctct-form-title-font-size,
480
+ #side-sortables #ctct_1_custom_form_css_metabox .cmb2-id--ctct-form-description-font-size {
481
+ border-bottom: none;
482
+ margin-bottom: 0;
483
+ }
484
+
485
+ #side-sortables #ctct_1_custom_input_css_metabox .cmb2-id-form-padding-title {
486
+ border-bottom: 0;
487
+ padding-bottom: 0;
488
+ }
489
+
490
+ #side-sortables #ctct_1_custom_input_css_metabox .cmb2-id--ctct-input-margin-top,
491
+ #side-sortables #ctct_1_custom_input_css_metabox .cmb2-id--ctct-input-margin-right {
492
+ margin-bottom: 0;
493
+ margin-top: 0;
494
+ padding-bottom: 0;
495
+ padding-top: 0;
496
+ }
497
+
498
+ #side-sortables #ctct_1_custom_input_css_metabox .cmb2-id--ctct-form-label-placement {
499
+ padding-bottom: 0;
500
+ margin-bottom: 0;
501
+ }
502
+
503
+ #side-sortables #ctct_1_custom_input_css_metabox .cmb-type-text-small {
504
+ border-bottom: none;
505
+ float: left;
506
+ width: 50%;
507
+ }
508
+
509
+ #side-sortables #ctct_1_custom_input_css_metabox .cmb-type-text-small .cmb-th {
510
+ padding-bottom: 0;
511
+ }
512
+
513
+ #adminmenu .wp-submenu a[href="edit.php?post_type=ctct_forms&page=ctct_options_connect"] {
514
+ color: #3ad182;
515
+ }
516
+
517
+ .ctct_options_connect {
518
+ box-sizing: border-box;
519
+ padding: 70px;
520
+ text-align: center;
521
+ width: 100%;
522
+ }
523
+
524
+ .ctct_options_connect hr {
525
+ margin-bottom: 45px;
526
+ }
527
+
528
+ @media screen and (max-width: 782px) {
529
+ .ctct_options_connect {
530
+ padding: 30px 30px 0;
531
+ margin-left: -10px;
532
+ }
533
+ }
534
+
535
+ .ctct_options_connect .ctct-call-to-action {
536
+ margin-bottom: 45px;
537
+ overflow: hidden;
538
+ text-align: left;
539
+ width: 100%;
540
+ }
541
+
542
+ .ctct_options_connect .ctct-call-to-action p {
543
+ float: left;
544
+ margin: 0;
545
+ }
546
+
547
+ .ctct_options_connect .ctct-call-to-action a {
548
+ float: right;
549
+ text-align: center;
550
+ }
551
+
552
+ @media screen and (max-width: 782px) {
553
+ .ctct_options_connect .ctct-call-to-action a {
554
+ float: none;
555
+ }
556
+ }
557
+
558
+ .ctct_options_connect .ctct-call-to-action .ctct-call-to-action-text a {
559
+ float: none;
560
+ }
561
+
562
+ .ctct_options_connect .ctct-call-to-action .ctct-call-to-action-text small {
563
+ line-height: 1.2px;
564
+ }
565
+
566
+ .ctct_options_connect .ctct-call-to-action #subbox {
567
+ height: 40px;
568
+ margin: 15px 0;
569
+ width: 50%;
570
+ }
571
+
572
+ .ctct_options_connect .ctct-call-to-action #subbutton {
573
+ color: #0078C3;
574
+ float: right;
575
+ }
576
+
577
+ @media screen and (max-width: 782px) {
578
+ .ctct_options_connect .ctct-call-to-action #subbutton {
579
+ float: none;
580
+ }
581
+ }
582
+
583
+ .ctct_options_connect img {
584
+ width: 100%;
585
+ max-width: 400px;
586
+ height: auto;
587
+ }
588
+
589
+ .ctct_options_connect h3 {
590
+ color: #005990;
591
+ font-size: 20px;
592
+ line-height: 1.2;
593
+ margin-bottom: 10px;
594
+ margin-top: 10px;
595
+ }
596
+
597
+ .ctct_options_connect p {
598
+ color: #606d78;
599
+ font-size: 14.7px;
600
+ margin: 0;
601
+ }
602
+
603
+ .ctct_options_connect p.ctct-description {
604
+ font-size: 16px;
605
+ margin-bottom: 50px;
606
+ margin-top: 5px;
607
+ }
608
+
609
+ .ctct_options_connect p.small {
610
+ color: #747e88;
611
+ font-size: 13.3px;
612
+ margin: 15px auto 0;
613
+ }
614
+
615
+ @media screen and (max-width: 782px) {
616
+ .ctct_options_connect p.small {
617
+ max-width: 100%;
618
+ }
619
+ }
620
+
621
+ .ctct_options_connect .ctct-body {
622
+ margin: 0 auto;
623
+ max-width: 75%;
624
+ overflow-y: hidden;
625
+ position: relative;
626
+ }
627
+
628
+ .ctct_options_connect .ctct-body:after {
629
+ clear: both;
630
+ content: "";
631
+ display: table;
632
+ }
633
+
634
+ .ctct_options_connect .ctct-body .ctct-call-to-action-text {
635
+ float: left;
636
+ width: 75%;
637
+ }
638
+
639
+ @media screen and (max-width: 782px) {
640
+ .ctct_options_connect .ctct-body .ctct-call-to-action-text {
641
+ width: 100%;
642
+ }
643
+ }
644
+
645
+ .ctct_options_connect .ctct-body .ctct-call-to-action-text h3 {
646
+ margin-top: 0;
647
+ }
648
+
649
+ .ctct_options_connect .ctct-body .clear {
650
+ width: 100%;
651
+ clear: both;
652
+ height: 0;
653
+ }
654
+
655
+ .ctct_options_connect .ctct-body .left,
656
+ .ctct_options_connect .ctct-body .right {
657
+ box-sizing: border-box;
658
+ box-sizing: border-box;
659
+ float: left;
660
+ margin-bottom: -500px;
661
+ padding: 15px 0px 520px;
662
+ text-align: center;
663
+ width: 50%;
664
+ }
665
+
666
+ @media screen and (max-width: 782px) {
667
+ .ctct_options_connect .ctct-body .left,
668
+ .ctct_options_connect .ctct-body .right {
669
+ float: none;
670
+ margin-bottom: 0;
671
+ padding: 15px 0;
672
+ width: 100%;
673
+ }
674
+ }
675
+
676
+ .ctct_options_connect .ctct-body .left img.flare,
677
+ .ctct_options_connect .ctct-body .left svg.flare,
678
+ .ctct_options_connect .ctct-body .right img.flare,
679
+ .ctct_options_connect .ctct-body .right svg.flare {
680
+ width: 180px;
681
+ height: auto;
682
+ }
683
+
684
+ .ctct_options_connect .ctct-body .left {
685
+ border-right: 1px solid #ddd;
686
+ padding-right: 70px;
687
+ }
688
+
689
+ @media screen and (max-width: 782px) {
690
+ .ctct_options_connect .ctct-body .left {
691
+ border-bottom: 1px solid #ddd;
692
+ border-right: 0;
693
+ padding-bottom: 30px;
694
+ padding-right: 0;
695
+ }
696
+ }
697
+
698
+ .ctct_options_connect .ctct-body .left p {
699
+ max-width: 220px;
700
+ margin: 0 auto 25px;
701
+ }
702
+
703
+ @media screen and (max-width: 782px) {
704
+ .ctct_options_connect .ctct-body .left p {
705
+ max-width: 100%;
706
+ }
707
+ }
708
+
709
+ .ctct_options_connect .ctct-body .right {
710
+ padding-left: 70px;
711
+ }
712
+
713
+ @media screen and (max-width: 782px) {
714
+ .ctct_options_connect .ctct-body .right {
715
+ padding-left: 0;
716
+ padding-top: 30px;
717
+ }
718
+ }
719
+
720
+ .ctct_options_connect .ctct-body .right p {
721
+ display: block;
722
+ max-width: 350px;
723
+ margin: 0 auto 25px;
724
+ }
725
+
726
+ @media screen and (max-width: 782px) {
727
+ .ctct_options_connect .ctct-body .right p {
728
+ max-width: 100%;
729
+ }
730
+ }
731
+
732
+ .ctct_options_connect .ctct-body .button {
733
+ border-radius: 4px;
734
+ color: #fff;
735
+ font-size: 16px;
736
+ font-weight: 600;
737
+ height: auto;
738
+ line-height: 1;
739
+ margin-bottom: 10px;
740
+ min-width: 180px;
741
+ padding: 14px 30px;
742
+ }
743
+
744
+ .ctct_options_connect .ctct-body .button.button-orange {
745
+ background-color: #FFA901;
746
+ border: 1px solid #cd8800;
747
+ }
748
+
749
+ .ctct_options_connect .ctct-body .button.button-orange:hover, .ctct_options_connect .ctct-body .button.button-orange:focus {
750
+ background-color: #cd8800;
751
+ }
752
+
753
+ .ctct_options_connect .ctct-body .button.button-blue {
754
+ background-color: #0078C3;
755
+ border: 1px solid #005990;
756
+ }
757
+
758
+ .ctct_options_connect .ctct-body .button.button-blue:hover, .ctct_options_connect .ctct-body .button.button-blue:focus {
759
+ background-color: #005990;
760
+ }
761
+
762
+ .ctct_options_connect .ctct-body .ctct-connected .ctct-connected-next-step {
763
+ margin-bottom: 40px;
764
+ }
765
+
766
+ .ctct_options_connect .ctct-body .ctct-connected .ctct-connected-next-step h3 {
767
+ color: #2ECC40;
768
+ }
769
+
770
+ .ctct_options_connect .ctct-body .ctct-connected .ctct-disconnect-text {
771
+ float: left;
772
+ margin-bottom: 50px;
773
+ overflow: hidden;
774
+ text-align: left;
775
+ }
776
+
777
+ .ctct_options_connect .ctct-body .ctct-connected form {
778
+ float: right;
779
+ }
780
+
781
+ .ctct_options_connect .ctct-body .ctct-connected .button {
782
+ color: #0078C3;
783
+ }
784
+
785
+ .ctct_options_connect .ctct-body .ctct-connected .button.button-blue {
786
+ color: #fff;
787
+ }
788
+
789
+ .ctct_options_connect .ctct-body .ctct-connected .ctct-connected-next-step {
790
+ clear: both;
791
+ }
792
+
793
+ .ctct_options_connect .ctct-body .ctct-connected .ctct-connect-ga-optin {
794
+ margin-top: 15px;
795
+ }
796
+
797
+ @media screen and (max-width: 782px) {
798
+ .ctct_options_connect .ctct-body .ctct-connected .ctct-disconnect-text {
799
+ float: none;
800
+ text-align: center;
801
+ }
802
+ .ctct_options_connect .ctct-body .ctct-connected form {
803
+ float: none;
804
+ }
805
+ }
806
+
807
+ .error {
808
+ background: none !important;
809
+ border-left: 1px solid #FF4136 !important;
810
+ border-radius: 3px;
811
+ border: 1px solid #FF4136;
812
+ box-shadow: none !important;
813
+ display: inline-block;
814
+ margin: 0 0 20px 0 !important;
815
+ }
816
+
817
+ .error p {
818
+ color: #FF4136 !important;
819
+ }
820
+
821
+ .updated.ctct-admin-notice,
822
+ .error.ctct-admin-notice {
823
+ padding: 1em 38px 1em 1em;
824
+ position: relative;
825
+ }
826
+
827
+ a.ctct-notice-dismiss {
828
+ text-decoration: none;
829
+ }
830
+
831
+ #ctct-admin-notice-activation {
832
+ padding: 1em 1em 0 1em;
833
+ }
834
+
835
+ #ctct-admin-notice-activation .ctct-notice-intro {
836
+ max-width: 600px;
837
+ line-height: 1.5em;
838
+ }
839
+
840
+ #ctct-admin-notice-activation .ctct-notice-button,
841
+ #ctct-admin-notice-activation .ctct-notice-button:active {
842
+ vertical-align: middle;
843
+ margin: .5em;
844
+ }
845
+
846
+ .ctct-admin-notice {
847
+ overflow: hidden;
848
+ }
849
+
850
+ .ctct-admin-notice.updated {
851
+ border-left-color: #1a5285;
852
+ }
853
+
854
+ .ctct-admin-notice > div {
855
+ float: left;
856
+ }
857
+
858
+ .ctct-admin-notice .admin-notice-message {
859
+ margin-left: 15px;
860
+ width: 80%;
861
+ }
862
+
863
+ .ctct-admin-notice .admin-notice-message h4 {
864
+ color: #1a5285;
865
+ margin: 0 0 10px;
866
+ }
867
+
868
+ .ctct-admin-notice .admin-notice-message > div {
869
+ float: left;
870
+ }
871
+
872
+ .constant-contact-about {
873
+ padding: 15px;
874
+ }
875
+
876
+ @media screen and (max-width: 782px) {
877
+ .constant-contact-about {
878
+ padding: 0;
879
+ }
880
+ }
881
+
882
+ .constant-contact-about .ctct-section {
883
+ margin-bottom: 50px;
884
+ }
885
+
886
+ .constant-contact-about h1.about-header {
887
+ color: #1a5285;
888
+ font-size: 26px;
889
+ margin: 0 0 15px 0;
890
+ }
891
+
892
+ .constant-contact-about h3 {
893
+ padding: 20px 0;
894
+ }
895
+
896
+ .constant-contact-about p {
897
+ font-size: 16px;
898
+ font-weight: 300;
899
+ color: #333333;
900
+ }
901
+
902
+ .constant-contact-about .clear {
903
+ width: 100%;
904
+ clear: both;
905
+ height: 0;
906
+ }
907
+
908
+ .constant-contact-about .button {
909
+ border-radius: 4px;
910
+ color: #fff;
911
+ font-size: 16px;
912
+ font-weight: 600;
913
+ height: auto;
914
+ line-height: 1;
915
+ margin-bottom: 10px;
916
+ min-width: 180px;
917
+ padding: 14px 30px;
918
+ text-align: center;
919
+ }
920
+
921
+ .constant-contact-about .button.button-orange {
922
+ background-color: #FFA901;
923
+ border: 1px solid #cd8800;
924
+ }
925
+
926
+ .constant-contact-about .button.button-orange:hover, .constant-contact-about .button.button-orange:focus {
927
+ background-color: #cd8800;
928
+ }
929
+
930
+ .constant-contact-about .button.button-blue {
931
+ background-color: #0078C3;
932
+ border: 1px solid #005990;
933
+ }
934
+
935
+ .constant-contact-about .button.button-blue:hover, .constant-contact-about .button.button-blue:focus {
936
+ background-color: #005990;
937
+ }
938
+
939
+ .constant-contact-about .about-text {
940
+ margin: 0 50px 0 0;
941
+ }
942
+
943
+ @media screen and (max-width: 482px) {
944
+ .constant-contact-about .about-text {
945
+ margiun: 0;
946
+ }
947
+ }
948
+
949
+ .constant-contact-about .feature-section.two-col > div {
950
+ width: 49%;
951
+ float: left;
952
+ }
953
+
954
+ .constant-contact-about .headline-feature {
955
+ max-width: 90%;
956
+ }
957
+
958
+ @media screen and (max-width: 782px) {
959
+ .constant-contact-about .headline-feature {
960
+ max-width: 100%;
961
+ }
962
+ }
963
+
964
+ .constant-contact-about .headline-feature p {
965
+ margin-bottom: 0;
966
+ }
967
+
968
+ .constant-contact-about .headline-feature h5 {
969
+ font-weight: 300;
970
+ color: #747e88;
971
+ font-style: italic;
972
+ }
973
+
974
+ .constant-contact-about .headline-title, .constant-contact-about .c-text {
975
+ text-align: center;
976
+ }
977
+
978
+ .constant-contact-about .featured-image {
979
+ min-height: 150px;
980
+ position: relative;
981
+ }
982
+
983
+ .constant-contact-about .fff-img {
984
+ height: 315px;
985
+ margin: 20px;
986
+ overflow: hidden;
987
+ max-width: 720px;
988
+ }
989
+
990
+ .constant-contact-about .introduction {
991
+ padding: 20px 0;
992
+ }
993
+
994
+ .constant-contact-about .featured-title {
995
+ color: white;
996
+ font-size: 2em;
997
+ font-weight: bold;
998
+ margin: 0 auto;
999
+ position: absolute;
1000
+ text-align: center;
1001
+ text-shadow: 0 0 15px #000;
1002
+ top: 80px;
1003
+ width: 100%;
1004
+ }
1005
+
1006
+ @media screen and (max-width: 482px) {
1007
+ .constant-contact-about .featured-title {
1008
+ color: #1a5285;
1009
+ font-size: 26px;
1010
+ line-height: 28px;
1011
+ margin-top: 15px;
1012
+ position: relative;
1013
+ text-shadow: none;
1014
+ top: 0;
1015
+ }
1016
+ }
1017
+
1018
+ .constant-contact-about .featured-introduction {
1019
+ color: white;
1020
+ font-size: 1.2em;
1021
+ margin: 0 auto;
1022
+ position: absolute;
1023
+ text-align: center;
1024
+ text-shadow: 0 0 15px #000;
1025
+ top: 120px;
1026
+ width: 100%;
1027
+ }
1028
+
1029
+ @media screen and (max-width: 482px) {
1030
+ .constant-contact-about .featured-introduction {
1031
+ color: #1a5285;
1032
+ line-height: 1;
1033
+ margin-top: 15px;
1034
+ position: relative;
1035
+ text-shadow: none;
1036
+ top: 0;
1037
+ }
1038
+ }
1039
+
1040
+ .constant-contact-about .hide-overflow {
1041
+ overflow: hidden;
1042
+ position: relative;
1043
+ }
1044
+
1045
+ .constant-contact-about .hide-overflow hr {
1046
+ margin-top: 30px;
1047
+ }
1048
+
1049
+ .constant-contact-about .hide-overflow h2 {
1050
+ font-weight: 400;
1051
+ font-size: 16px;
1052
+ color: #1a5285;
1053
+ text-align: left;
1054
+ margin-top: 30px;
1055
+ }
1056
+
1057
+ .constant-contact-about .left-side {
1058
+ float: left;
1059
+ box-sizing: border-box;
1060
+ padding-right: 160px;
1061
+ }
1062
+
1063
+ @media screen and (max-width: 482px) {
1064
+ .constant-contact-about .left-side {
1065
+ padding-right: 0;
1066
+ }
1067
+ }
1068
+
1069
+ .constant-contact-about .plugin-badge {
1070
+ float: right;
1071
+ max-height: 180px;
1072
+ max-width: 160px;
1073
+ margin-left: 40px;
1074
+ }
1075
+
1076
+ @media screen and (max-width: 482px) {
1077
+ .constant-contact-about .plugin-badge {
1078
+ display: none;
1079
+ }
1080
+ }
1081
+
1082
+ .constant-contact-about .feature-image {
1083
+ text-align: center;
1084
+ }
1085
+
1086
+ .cc-a-block {
1087
+ margin: 0 auto;
1088
+ max-width: 90%;
1089
+ padding: 50px 0;
1090
+ text-align: center;
1091
+ }
1092
+
1093
+ .cc-a-block:after {
1094
+ clear: both;
1095
+ content: "";
1096
+ display: table;
1097
+ }
1098
+
1099
+ @media screen and (max-width: 482px) {
1100
+ .cc-a-block {
1101
+ padding: 25px 0;
1102
+ }
1103
+ }
1104
+
1105
+ .cc-a-block h3 {
1106
+ color: #1a5285;
1107
+ font-size: 21px;
1108
+ font-weight: 300;
1109
+ height: 63px;
1110
+ margin: 0 auto;
1111
+ max-width: 70%;
1112
+ }
1113
+
1114
+ @media screen and (max-width: 782px) {
1115
+ .cc-a-block h3 {
1116
+ height: auto;
1117
+ max-width: 100%;
1118
+ }
1119
+ }
1120
+
1121
+ .cc-a-block .left,
1122
+ .cc-a-block .right {
1123
+ float: left;
1124
+ width: 50%;
1125
+ }
1126
+
1127
+ .cc-a-block .left:after,
1128
+ .cc-a-block .right:after {
1129
+ clear: both;
1130
+ content: "";
1131
+ display: table;
1132
+ }
1133
+
1134
+ @media screen and (max-width: 482px) {
1135
+ .cc-a-block .left,
1136
+ .cc-a-block .right {
1137
+ width: 100%;
1138
+ float: none;
1139
+ }
1140
+ }
1141
+
1142
+ .cc-a-block .left .ad-1,
1143
+ .cc-a-block .left .ad-2,
1144
+ .cc-a-block .right .ad-1,
1145
+ .cc-a-block .right .ad-2 {
1146
+ width: 90%;
1147
+ }
1148
+
1149
+ @media screen and (max-width: 482px) {
1150
+ .cc-a-block .left .ad-1,
1151
+ .cc-a-block .left .ad-2,
1152
+ .cc-a-block .right .ad-1,
1153
+ .cc-a-block .right .ad-2 {
1154
+ width: 100%;
1155
+ float: none;
1156
+ }
1157
+ }
1158
+
1159
+ .cc-a-block .left .ad-1 img,
1160
+ .cc-a-block .left .ad-2 img,
1161
+ .cc-a-block .right .ad-1 img,
1162
+ .cc-a-block .right .ad-2 img {
1163
+ width: 100%;
1164
+ height: auto;
1165
+ }
1166
+
1167
+ .cc-a-block .left .ad-1,
1168
+ .cc-a-block .right .ad-1 {
1169
+ float: left;
1170
+ }
1171
+
1172
+ .cc-a-block .left .ad-1 h3,
1173
+ .cc-a-block .right .ad-1 h3 {
1174
+ padding-top: 35px;
1175
+ height: 47px;
1176
+ }
1177
+
1178
+ .cc-a-block .left .ad-2,
1179
+ .cc-a-block .right .ad-2 {
1180
+ float: right;
1181
+ }
1182
+
1183
+ .ctct-bonus-points {
1184
+ list-style: circle;
1185
+ padding-left: 50px;
1186
+ font-size: 16px;
1187
+ font-weight: 300;
1188
+ color: #2b5e8c;
1189
+ }
1190
+
1191
+ .section-try-us .ctct-bonus-points {
1192
+ margin-bottom: 50px;
1193
+ }
1194
+
1195
+ .section-try-us a.button {
1196
+ margin-right: 40px;
1197
+ }
1198
+
1199
+ .section-try-us a.ctct-connect {
1200
+ font-weight: bold;
1201
+ }
1202
+
1203
+ .section-marketing-tips #subbox {
1204
+ height: 40px;
1205
+ width: 50%;
1206
+ }
1207
+
1208
+ #cmb2-metabox-ctct_option_metabox_settings .regular-text {
1209
+ width: 500px;
1210
+ }
1211
+
1212
+ .cmb2-options-page #ctct_option_metabox_settings .cmb2-metabox > .cmb-row {
1213
+ background: transparent;
1214
+ border: none;
1215
+ box-shadow: none;
1216
+ }
1217
+
1218
+ .ctct-body #ctct_error_logs {
1219
+ height: 400px;
1220
+ resize: vertical;
1221
+ width: 100%;
1222
+ }
1223
+
1224
+ .ctct-logo {
1225
+ max-width: 400px;
1226
+ }
1227
+
1228
+ .ctct_options_connect {
1229
+ box-sizing: border-box;
1230
+ padding: 70px;
1231
+ text-align: center;
1232
+ width: 100%;
1233
+ }
1234
+
1235
+ @media screen and (max-width: 782px) {
1236
+ .ctct_options_connect {
1237
+ padding: 30px 30px 0;
1238
+ margin-left: -10px;
1239
+ }
1240
+ }
1241
+
1242
+ .ctct_options_connect img {
1243
+ width: 100%;
1244
+ max-width: 400px;
1245
+ height: auto;
1246
+ }
1247
+
1248
+ .ctct_options_connect p {
1249
+ color: #606d78;
1250
+ font-size: 16px;
1251
+ }
1252
+
1253
+ .ctct_options_connect .ctct-description {
1254
+ text-align: left;
1255
+ }
1256
+
1257
+ .ctct_options_connect .ctct-body {
1258
+ margin: 0 auto;
1259
+ max-width: 75%;
1260
+ overflow-y: hidden;
1261
+ padding: 0 15px;
1262
+ position: relative;
1263
+ }
1264
+
1265
+ .ctct_options_connect .ctct-body:after {
1266
+ clear: both;
1267
+ content: "";
1268
+ display: table;
1269
+ }
1270
+
1271
+ .ctct_options_connect .ctct-body .notice {
1272
+ background: none;
1273
+ border-left: none;
1274
+ box-shadow: none;
1275
+ margin: 0 0 20px 0;
1276
+ padding: 0;
1277
+ }
1278
+
1279
+ .ctct_options_connect .ctct-body .button {
1280
+ border-radius: 4px;
1281
+ color: #fff;
1282
+ font-size: 16px;
1283
+ font-weight: 600;
1284
+ height: auto;
1285
+ line-height: 1;
1286
+ margin-bottom: 10px;
1287
+ min-width: 180px;
1288
+ padding: 14px 30px;
1289
+ }
1290
+
1291
+ .ctct_options_connect .ctct-body .button.button-orange {
1292
+ background-color: #FFA901;
1293
+ border: 1px solid #cd8800;
1294
+ }
1295
+
1296
+ .ctct_options_connect .ctct-body .button.button-orange:hover, .ctct_options_connect .ctct-body .button.button-orange:focus {
1297
+ background-color: #cd8800;
1298
+ }
1299
+
1300
+ .ctct_options_connect .ctct-body .button.button-blue {
1301
+ background-color: #0078C3;
1302
+ border: 1px solid #005990;
1303
+ }
1304
+
1305
+ .ctct_options_connect .ctct-body .button.button-blue:hover, .ctct_options_connect .ctct-body .button.button-blue:focus {
1306
+ background-color: #005990;
1307
+ }
assets/css/oath.css DELETED
@@ -1,84 +0,0 @@
1
- .ctct-logo {
2
- max-width: 400px;
3
- }
4
-
5
- .ctct_options_connect {
6
- box-sizing: border-box;
7
- padding: 70px;
8
- text-align: center;
9
- width: 100%;
10
- }
11
-
12
- @media screen and (max-width: 782px) {
13
- .ctct_options_connect {
14
- padding: 30px 30px 0;
15
- margin-left: -10px;
16
- }
17
- }
18
-
19
- .ctct_options_connect img {
20
- width: 100%;
21
- max-width: 400px;
22
- height: auto;
23
- }
24
-
25
- .ctct_options_connect p {
26
- color: #606d78;
27
- font-size: 16px;
28
- }
29
-
30
- .ctct_options_connect .ctct-description {
31
- text-align: left;
32
- }
33
-
34
- .ctct_options_connect .ctct-body {
35
- margin: 0 auto;
36
- max-width: 75%;
37
- overflow-y: hidden;
38
- padding: 0 15px;
39
- position: relative;
40
- }
41
-
42
- .ctct_options_connect .ctct-body:after {
43
- clear: both;
44
- content: "";
45
- display: table;
46
- }
47
-
48
- .ctct_options_connect .ctct-body .notice {
49
- background: none;
50
- border-left: none;
51
- box-shadow: none;
52
- margin: 0 0 20px 0;
53
- padding: 0;
54
- }
55
-
56
- .ctct_options_connect .ctct-body .button {
57
- border-radius: 4px;
58
- color: #fff;
59
- font-size: 16px;
60
- font-weight: 600;
61
- height: auto;
62
- line-height: 1;
63
- margin-bottom: 10px;
64
- min-width: 180px;
65
- padding: 14px 30px;
66
- }
67
-
68
- .ctct_options_connect .ctct-body .button.button-orange {
69
- background-color: #FFA901;
70
- border: 1px solid #cd8800;
71
- }
72
-
73
- .ctct_options_connect .ctct-body .button.button-orange:hover, .ctct_options_connect .ctct-body .button.button-orange:focus {
74
- background-color: #cd8800;
75
- }
76
-
77
- .ctct_options_connect .ctct-body .button.button-blue {
78
- background-color: #0078C3;
79
- border: 1px solid #005990;
80
- }
81
-
82
- .ctct_options_connect .ctct-body .button.button-blue:hover, .ctct_options_connect .ctct-body .button.button-blue:focus {
83
- background-color: #005990;
84
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/style.css CHANGED
@@ -58,6 +58,36 @@
58
  padding-left: 40px;
59
  }
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  .ctct-form-wrapper #ctct_usage {
62
  position: absolute;
63
  overflow: hidden;
@@ -69,12 +99,31 @@
69
  padding: 0px;
70
  }
71
 
 
 
 
 
 
 
 
 
 
72
  .ctct-form-wrapper .ctct-form:after {
73
  clear: both;
74
  content: "";
75
  display: table;
76
  }
77
 
 
 
 
 
 
 
 
 
 
 
78
  .ctct-form-wrapper .ctct-form abbr {
79
  border: none;
80
  color: #FF4136;
@@ -131,4 +180,4 @@
131
  }
132
  }
133
 
134
- /*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0eWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtFQUNFLGlCQUFpQjtDQUNsQjs7QUFFRDtFQUNFLGtCQUFrQjtFQUNsQixhQUFhO0NBQ2Q7O0FBRUQ7RUFDRSwwQ0FBMEM7RUFDMUMsc0JBQXNCO0VBQ3RCLGVBQWU7Q0FDaEI7O0FBRUQ7RUFDRSwwQ0FBMEM7RUFDMUMsc0JBQXNCO0VBQ3RCLGVBQWU7Q0FDaEI7O0FBRUQ7RUFDRSxnQkFBZ0I7Q0FDakI7O0FBRUQ7RUFDRSxzQkFBc0I7Q0FDdkI7O0FBbUNEO0VBQ0UsOERBQThEO0VBQzlELDZCQUE2QjtFQUM3QixzQkFBc0I7RUFDdEIsc0JBQXNCO0VBQ3RCLG1CQUFtQjtDQUNwQjs7QUFFRDtFQUNFLHVEQUF1RDtFQUN2RCwwQ0FBMEM7RUFDMUMsNkJBQTZCO0VBQzdCLHNCQUFzQjtFQUN0QixzQkFBc0I7RUFDdEIsbUJBQW1CO0NBQ3BCOztBQUVEO0VBQ0Usa0JBQWtCO0VBQ2xCLG1CQUFtQjtDQUNwQjs7QUFFRDtFQUNFLHVEQUF1RDtFQUN2RCwwQ0FBMEM7RUFDMUMsNkJBQTZCO0VBQzdCLHNCQUFzQjtFQUN0QixzQkFBc0I7RUFDdEIsbUJBQW1CO0NBQ3BCOztBQUVEO0VBQ0UsbUJBQW1CO0VBQ25CLGlCQUFpQjtFQUNqQiwrQkFBK0I7RUFDL0IsWUFBWTtFQUNaLFdBQVc7RUFDWCxhQUFhO0VBQ2IsaUJBQWlCO0VBQ2pCLGFBQWE7Q0FDZDs7QUFFRDtFQUNFLFlBQVk7RUFDWixZQUFZO0VBQ1osZUFBZTtDQUNoQjs7QUFFRDtFQUNFLGFBQWE7RUFDYixlQUFlO0VBQ2YsaUJBQWlCO0NBQ2xCOztBQUVEO0VBQ0UsWUFBWTtFQUNaLGlCQUFpQjtDQUNsQjs7QUFFRDtFQUNFLGVBQWU7Q0FDaEI7O0FBRUQ7RUFDRSxnQkFBZ0I7Q0FDakI7O0FBRUQ7RUFDRSxZQUFZO0NBQ2I7O0FBdEdEOztFQUNFO0lBQ0UsWUFBWTtJQUNaLGlCQUFpQjtJQUNqQixXQUFXO0dBQ1o7O0VBQ0Q7SUFDRSxnQkFBZ0I7R0FDakI7O0VBSUQ7SUFDRSxZQUFZO0lBQ1osaUJBQWlCO0lBQ2pCLFdBQVc7R0FDWjs7RUFDRDtJQUNFLGdCQUFnQjtHQUNqQjs7RUFJRDtJQUNFLFlBQVk7SUFDWixpQkFBaUI7SUFDakIsV0FBVztHQUNaOztFQUNEO0lBQ0UsZ0JBQWdCO0dBQ2pCO0NBckJGIiwiZmlsZSI6InN0eWxlLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIi5jdGN0LWZvcm0td3JhcHBlciAuY3RjdC1idXR0b24ge1xuICBmb250LXNpemU6IDAuOWVtO1xufVxuXG4uY3RjdC1mb3JtLXdyYXBwZXIgLmN0Y3QtbWVzc2FnZSB7XG4gIGJvcmRlcjogMXB4IHNvbGlkO1xuICBwYWRkaW5nOiAxZW07XG59XG5cbi5jdGN0LWZvcm0td3JhcHBlciAuZXJyb3Ige1xuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgNjUsIDU0LCAwLjAyKTtcbiAgYm9yZGVyLWNvbG9yOiAjRkY0MTM2O1xuICBjb2xvcjogI2NmMGIwMDtcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyIC5zdWNjZXNzIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSg0NiwgMjA0LCA2NCwgMC4wMik7XG4gIGJvcmRlci1jb2xvcjogIzJFQ0M0MDtcbiAgY29sb3I6ICMxYjc5MjY7XG59XG5cbi5jdGN0LWZvcm0td3JhcHBlciAuY3RjdC1mb3JtLWZpZWxkIHtcbiAgbWFyZ2luOiAwIDAgMWVtO1xufVxuXG4uY3RjdC1mb3JtLXdyYXBwZXIgLmN0Y3QtZmllbGQtaW5saW5lIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xufVxuXG5AbWVkaWEgKG1pbi13aWR0aDogOTkycHgpIHtcbiAgLmN0Y3QtZm9ybS13cmFwcGVyIC5jdGN0LWZpZWxkLWhhbGYge1xuICAgIGZsb2F0OiBsZWZ0O1xuICAgIG1hcmdpbi1yaWdodDogMiU7XG4gICAgd2lkdGg6IDQ4JTtcbiAgfVxuICAuY3RjdC1mb3JtLXdyYXBwZXIgLmN0Y3QtZmllbGQtaGFsZjpsYXN0LW9mLXR5cGUge1xuICAgIG1hcmdpbi1yaWdodDogMDtcbiAgfVxufVxuXG5AbWVkaWEgKG1pbi13aWR0aDogOTkycHgpIHtcbiAgLmN0Y3QtZm9ybS13cmFwcGVyIC5jdGN0LWZpZWxkLXRoaXJkIHtcbiAgICBmbG9hdDogbGVmdDtcbiAgICBtYXJnaW4tcmlnaHQ6IDIlO1xuICAgIHdpZHRoOiAzMiU7XG4gIH1cbiAgLmN0Y3QtZm9ybS13cmFwcGVyIC5jdGN0LWZpZWxkLXRoaXJkOmxhc3Qtb2YtdHlwZSB7XG4gICAgbWFyZ2luLXJpZ2h0OiAwO1xuICB9XG59XG5cbkBtZWRpYSAobWluLXdpZHRoOiA5OTJweCkge1xuICAuY3RjdC1mb3JtLXdyYXBwZXIgLmN0Y3QtZmllbGQtZm91cnRoIHtcbiAgICBmbG9hdDogbGVmdDtcbiAgICBtYXJnaW4tcmlnaHQ6IDIlO1xuICAgIHdpZHRoOiAyNCU7XG4gIH1cbiAgLmN0Y3QtZm9ybS13cmFwcGVyIC5jdGN0LWZpZWxkLWZvdXJ0aDpsYXN0LW9mLXR5cGUge1xuICAgIG1hcmdpbi1yaWdodDogMDtcbiAgfVxufVxuXG4uY3RjdC1mb3JtLXdyYXBwZXIgaW5wdXRbdHlwZT1cInRleHRcIl06cmVxdWlyZWQ6dmFsaWQsIC5jdGN0LWZvcm0td3JhcHBlciBpbnB1dFt0eXBlPVwiZW1haWxcIl06cmVxdWlyZWQ6dmFsaWQsIC5jdGN0LWZvcm0td3JhcHBlciBpbnB1dFt0eXBlPVwicGFzc3dvcmRcIl06cmVxdWlyZWQ6dmFsaWQsIC5jdGN0LWZvcm0td3JhcHBlciBpbnB1dFt0eXBlPVwidGVsXCJdOnJlcXVpcmVkOnZhbGlkLCAuY3RjdC1mb3JtLXdyYXBwZXIgaW5wdXRbdHlwZT1cIm51bWJlclwiXTpyZXF1aXJlZDp2YWxpZCB7XG4gIGJhY2tncm91bmQ6IHdoaXRlIHVybChcIi4uL2ltYWdlcy9jaGVja19jaXJjbGUuc3ZnXCIpIG5vLXJlcGVhdDtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogOHB4IDUwJTtcbiAgYmFja2dyb3VuZC1zaXplOiAyNHB4O1xuICBib3JkZXItY29sb3I6ICMyRUNDNDA7XG4gIHBhZGRpbmctbGVmdDogNDBweDtcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyIGlucHV0W3R5cGU9XCJ0ZXh0XCJdOnJlcXVpcmVkLmN0Y3QtaW52YWxpZCwgLmN0Y3QtZm9ybS13cmFwcGVyIGlucHV0W3R5cGU9XCJ0ZXh0XCJdLmN0Y3QtaW52YWxpZCwgLmN0Y3QtZm9ybS13cmFwcGVyIGlucHV0W3R5cGU9XCJlbWFpbFwiXTpyZXF1aXJlZC5jdGN0LWludmFsaWQsIC5jdGN0LWZvcm0td3JhcHBlciBpbnB1dFt0eXBlPVwiZW1haWxcIl0uY3RjdC1pbnZhbGlkLCAuY3RjdC1mb3JtLXdyYXBwZXIgaW5wdXRbdHlwZT1cInBhc3N3b3JkXCJdOnJlcXVpcmVkLmN0Y3QtaW52YWxpZCwgLmN0Y3QtZm9ybS13cmFwcGVyIGlucHV0W3R5cGU9XCJwYXNzd29yZFwiXS5jdGN0LWludmFsaWQsIC5jdGN0LWZvcm0td3JhcHBlciBpbnB1dFt0eXBlPVwidGVsXCJdOnJlcXVpcmVkLmN0Y3QtaW52YWxpZCwgLmN0Y3QtZm9ybS13cmFwcGVyIGlucHV0W3R5cGU9XCJ0ZWxcIl0uY3RjdC1pbnZhbGlkLCAuY3RjdC1mb3JtLXdyYXBwZXIgaW5wdXRbdHlwZT1cIm51bWJlclwiXTpyZXF1aXJlZC5jdGN0LWludmFsaWQsIC5jdGN0LWZvcm0td3JhcHBlciBpbnB1dFt0eXBlPVwibnVtYmVyXCJdLmN0Y3QtaW52YWxpZCB7XG4gIGJhY2tncm91bmQ6IHdoaXRlIHVybChcIi4uL2ltYWdlcy9lcnJvci5zdmdcIikgbm8tcmVwZWF0O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgNjUsIDU0LCAwLjAyKTtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogOHB4IDUwJTtcbiAgYmFja2dyb3VuZC1zaXplOiAyNHB4O1xuICBib3JkZXItY29sb3I6ICNGRjQxMzY7XG4gIHBhZGRpbmctbGVmdDogNDBweDtcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyIC5jdGN0LWZpZWxkLWVycm9yIHtcbiAgZm9udC1zaXplOiAwLjg1ZW07XG4gIGZvbnQtc3R5bGU6IGl0YWxpYztcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyIGlucHV0LmN0Y3QtaW52YWxpZCB7XG4gIGJhY2tncm91bmQ6IHdoaXRlIHVybChcIi4uL2ltYWdlcy9lcnJvci5zdmdcIikgbm8tcmVwZWF0O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgNjUsIDU0LCAwLjAyKTtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogOHB4IDUwJTtcbiAgYmFja2dyb3VuZC1zaXplOiAyNHB4O1xuICBib3JkZXItY29sb3I6ICNGRjQxMzY7XG4gIHBhZGRpbmctbGVmdDogNDBweDtcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyICNjdGN0X3VzYWdlIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICBjbGlwOiByZWN0KDBweCwgMHB4LCAwcHgsIDBweCk7XG4gIGhlaWdodDogMXB4O1xuICB3aWR0aDogMXB4O1xuICBtYXJnaW46IC0xcHg7XG4gIGJvcmRlcjogMHB4IG5vbmU7XG4gIHBhZGRpbmc6IDBweDtcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyIC5jdGN0LWZvcm06YWZ0ZXIge1xuICBjbGVhcjogYm90aDtcbiAgY29udGVudDogXCJcIjtcbiAgZGlzcGxheTogdGFibGU7XG59XG5cbi5jdGN0LWZvcm0td3JhcHBlciAuY3RjdC1mb3JtIGFiYnIge1xuICBib3JkZXI6IG5vbmU7XG4gIGNvbG9yOiAjRkY0MTM2O1xuICBmb250LXNpemU6IDAuOWVtO1xufVxuXG4uY3RjdC1mb3JtLXdyYXBwZXIgLmN0Y3QtaW5wdXQtY29udGFpbmVyIGxhYmVsIHtcbiAgY29sb3I6ICNhYWE7XG4gIGZvbnQtc2l6ZTogMC44ZW07XG59XG5cbi5jdGN0LWZvcm0td3JhcHBlciAuY3RjdC1maWVsZC1lcnJvciB7XG4gIGNvbG9yOiAjRkY0MTM2O1xufVxuXG4uY3RjdC1mb3JtLXdyYXBwZXIgLmN0Y3Qtc3VibWl0IHtcbiAgY3Vyc29yOiBwb2ludGVyO1xufVxuXG4uY3RjdC10d2VudHlmb3VydGVlbiAuY3RjdC1mb3JtLWZpZWxkIGlucHV0IHtcbiAgd2lkdGg6IDEwMCU7XG59XG4iXX0= */
58
  padding-left: 40px;
59
  }
60
 
61
+ .ctct-form-wrapper input.ctct-label-left,
62
+ .ctct-form-wrapper textarea.ctct-label-left {
63
+ display: inline-block;
64
+ width: 75%;
65
+ }
66
+
67
+ .ctct-form-wrapper span.ctct-label-left {
68
+ display: inline-block;
69
+ margin-right: 5%;
70
+ width: 20%;
71
+ }
72
+
73
+ .ctct-form-wrapper input.ctct-label-right,
74
+ .ctct-form-wrapper textarea.ctct-label-right {
75
+ display: inline-block;
76
+ margin-right: 5%;
77
+ width: 75%;
78
+ }
79
+
80
+ .ctct-form-wrapper span.ctct-label-right {
81
+ display: inline-block;
82
+ width: 20%;
83
+ }
84
+
85
+ .ctct-form-wrapper span.ctct-label-hidden {
86
+ left: -9999px !important;
87
+ position: absolute !important;
88
+ top: -9999px !important;
89
+ }
90
+
91
  .ctct-form-wrapper #ctct_usage {
92
  position: absolute;
93
  overflow: hidden;
99
  padding: 0px;
100
  }
101
 
102
+ .ctct-form-wrapper #ctct-submitted:disabled {
103
+ background-image: url("../images/oval.min.svg");
104
+ background-position: center;
105
+ background-repeat: no-repeat;
106
+ color: transparent;
107
+ cursor: wait;
108
+ opacity: 0.3;
109
+ }
110
+
111
  .ctct-form-wrapper .ctct-form:after {
112
  clear: both;
113
  content: "";
114
  display: table;
115
  }
116
 
117
+ .ctct-form-wrapper .ctct-form .ctct-label-top label,
118
+ .ctct-form-wrapper .ctct-form .ctct-label-bottom label {
119
+ display: block;
120
+ }
121
+
122
+ .ctct-form-wrapper .ctct-form .ctct-label-left label,
123
+ .ctct-form-wrapper .ctct-form .ctct-label-right label {
124
+ display: inline-block;
125
+ }
126
+
127
  .ctct-form-wrapper .ctct-form abbr {
128
  border: none;
129
  color: #FF4136;
180
  }
181
  }
182
 
183
+ /*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0eWxlLmNzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtFQUNFLGlCQUFpQjtDQUNsQjs7QUFFRDtFQUNFLGtCQUFrQjtFQUNsQixhQUFhO0NBQ2Q7O0FBRUQ7RUFDRSwwQ0FBMEM7RUFDMUMsc0JBQXNCO0VBQ3RCLGVBQWU7Q0FDaEI7O0FBRUQ7RUFDRSwwQ0FBMEM7RUFDMUMsc0JBQXNCO0VBQ3RCLGVBQWU7Q0FDaEI7O0FBRUQ7RUFDRSxnQkFBZ0I7Q0FDakI7O0FBRUQ7RUFDRSxzQkFBc0I7Q0FDdkI7O0FBbUNEO0VBQ0UsOERBQThEO0VBQzlELDZCQUE2QjtFQUM3QixzQkFBc0I7RUFDdEIsc0JBQXNCO0VBQ3RCLG1CQUFtQjtDQUNwQjs7QUFFRDtFQUNFLHVEQUF1RDtFQUN2RCwwQ0FBMEM7RUFDMUMsNkJBQTZCO0VBQzdCLHNCQUFzQjtFQUN0QixzQkFBc0I7RUFDdEIsbUJBQW1CO0NBQ3BCOztBQUVEO0VBQ0Usa0JBQWtCO0VBQ2xCLG1CQUFtQjtDQUNwQjs7QUFFRDtFQUNFLHVEQUF1RDtFQUN2RCwwQ0FBMEM7RUFDMUMsNkJBQTZCO0VBQzdCLHNCQUFzQjtFQUN0QixzQkFBc0I7RUFDdEIsbUJBQW1CO0NBQ3BCOztBQUVEOztFQUVFLHNCQUFzQjtFQUN0QixXQUFXO0NBQ1o7O0FBRUQ7RUFDRSxzQkFBc0I7RUFDdEIsaUJBQWlCO0VBQ2pCLFdBQVc7Q0FDWjs7QUFFRDs7RUFFRSxzQkFBc0I7RUFDdEIsaUJBQWlCO0VBQ2pCLFdBQVc7Q0FDWjs7QUFFRDtFQUNFLHNCQUFzQjtFQUN0QixXQUFXO0NBQ1o7O0FBRUQ7RUFDRSx5QkFBeUI7RUFDekIsOEJBQThCO0VBQzlCLHdCQUF3QjtDQUN6Qjs7QUFFRDtFQUNFLG1CQUFtQjtFQUNuQixpQkFBaUI7RUFDakIsK0JBQStCO0VBQy9CLFlBQVk7RUFDWixXQUFXO0VBQ1gsYUFBYTtFQUNiLGlCQUFpQjtFQUNqQixhQUFhO0NBQ2Q7O0FBRUQ7RUFDRSxnREFBZ0Q7RUFDaEQsNEJBQTRCO0VBQzVCLDZCQUE2QjtFQUM3QixtQkFBbUI7RUFDbkIsYUFBYTtFQUNiLGFBQWE7Q0FDZDs7QUFFRDtFQUNFLFlBQVk7RUFDWixZQUFZO0VBQ1osZUFBZTtDQUNoQjs7QUFFRDs7RUFFRSxlQUFlO0NBQ2hCOztBQUVEOztFQUVFLHNCQUFzQjtDQUN2Qjs7QUFFRDtFQUNFLGFBQWE7RUFDYixlQUFlO0VBQ2YsaUJBQWlCO0NBQ2xCOztBQUVEO0VBQ0UsWUFBWTtFQUNaLGlCQUFpQjtDQUNsQjs7QUFFRDtFQUNFLGVBQWU7Q0FDaEI7O0FBRUQ7RUFDRSxnQkFBZ0I7Q0FDakI7O0FBRUQ7RUFDRSxZQUFZO0NBQ2I7O0FBdkpEOztFQUNFO0lBQ0UsWUFBWTtJQUNaLGlCQUFpQjtJQUNqQixXQUFXO0dBQ1o7O0VBQ0Q7SUFDRSxnQkFBZ0I7R0FDakI7O0VBSUQ7SUFDRSxZQUFZO0lBQ1osaUJBQWlCO0lBQ2pCLFdBQVc7R0FDWjs7RUFDRDtJQUNFLGdCQUFnQjtHQUNqQjs7RUFJRDtJQUNFLFlBQVk7SUFDWixpQkFBaUI7SUFDakIsV0FBVztHQUNaOztFQUNEO0lBQ0UsZ0JBQWdCO0dBQ2pCO0NBckJGIiwiZmlsZSI6InN0eWxlLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIi5jdGN0LWZvcm0td3JhcHBlciAuY3RjdC1idXR0b24ge1xuICBmb250LXNpemU6IDAuOWVtO1xufVxuXG4uY3RjdC1mb3JtLXdyYXBwZXIgLmN0Y3QtbWVzc2FnZSB7XG4gIGJvcmRlcjogMXB4IHNvbGlkO1xuICBwYWRkaW5nOiAxZW07XG59XG5cbi5jdGN0LWZvcm0td3JhcHBlciAuZXJyb3Ige1xuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgNjUsIDU0LCAwLjAyKTtcbiAgYm9yZGVyLWNvbG9yOiAjRkY0MTM2O1xuICBjb2xvcjogI2NmMGIwMDtcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyIC5zdWNjZXNzIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSg0NiwgMjA0LCA2NCwgMC4wMik7XG4gIGJvcmRlci1jb2xvcjogIzJFQ0M0MDtcbiAgY29sb3I6ICMxYjc5MjY7XG59XG5cbi5jdGN0LWZvcm0td3JhcHBlciAuY3RjdC1mb3JtLWZpZWxkIHtcbiAgbWFyZ2luOiAwIDAgMWVtO1xufVxuXG4uY3RjdC1mb3JtLXdyYXBwZXIgLmN0Y3QtZmllbGQtaW5saW5lIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xufVxuXG5AbWVkaWEgKG1pbi13aWR0aDogOTkycHgpIHtcbiAgLmN0Y3QtZm9ybS13cmFwcGVyIC5jdGN0LWZpZWxkLWhhbGYge1xuICAgIGZsb2F0OiBsZWZ0O1xuICAgIG1hcmdpbi1yaWdodDogMiU7XG4gICAgd2lkdGg6IDQ4JTtcbiAgfVxuICAuY3RjdC1mb3JtLXdyYXBwZXIgLmN0Y3QtZmllbGQtaGFsZjpsYXN0LW9mLXR5cGUge1xuICAgIG1hcmdpbi1yaWdodDogMDtcbiAgfVxufVxuXG5AbWVkaWEgKG1pbi13aWR0aDogOTkycHgpIHtcbiAgLmN0Y3QtZm9ybS13cmFwcGVyIC5jdGN0LWZpZWxkLXRoaXJkIHtcbiAgICBmbG9hdDogbGVmdDtcbiAgICBtYXJnaW4tcmlnaHQ6IDIlO1xuICAgIHdpZHRoOiAzMiU7XG4gIH1cbiAgLmN0Y3QtZm9ybS13cmFwcGVyIC5jdGN0LWZpZWxkLXRoaXJkOmxhc3Qtb2YtdHlwZSB7XG4gICAgbWFyZ2luLXJpZ2h0OiAwO1xuICB9XG59XG5cbkBtZWRpYSAobWluLXdpZHRoOiA5OTJweCkge1xuICAuY3RjdC1mb3JtLXdyYXBwZXIgLmN0Y3QtZmllbGQtZm91cnRoIHtcbiAgICBmbG9hdDogbGVmdDtcbiAgICBtYXJnaW4tcmlnaHQ6IDIlO1xuICAgIHdpZHRoOiAyNCU7XG4gIH1cbiAgLmN0Y3QtZm9ybS13cmFwcGVyIC5jdGN0LWZpZWxkLWZvdXJ0aDpsYXN0LW9mLXR5cGUge1xuICAgIG1hcmdpbi1yaWdodDogMDtcbiAgfVxufVxuXG4uY3RjdC1mb3JtLXdyYXBwZXIgaW5wdXRbdHlwZT1cInRleHRcIl06cmVxdWlyZWQ6dmFsaWQsIC5jdGN0LWZvcm0td3JhcHBlciBpbnB1dFt0eXBlPVwiZW1haWxcIl06cmVxdWlyZWQ6dmFsaWQsIC5jdGN0LWZvcm0td3JhcHBlciBpbnB1dFt0eXBlPVwicGFzc3dvcmRcIl06cmVxdWlyZWQ6dmFsaWQsIC5jdGN0LWZvcm0td3JhcHBlciBpbnB1dFt0eXBlPVwidGVsXCJdOnJlcXVpcmVkOnZhbGlkLCAuY3RjdC1mb3JtLXdyYXBwZXIgaW5wdXRbdHlwZT1cIm51bWJlclwiXTpyZXF1aXJlZDp2YWxpZCB7XG4gIGJhY2tncm91bmQ6IHdoaXRlIHVybChcIi4uL2ltYWdlcy9jaGVja19jaXJjbGUuc3ZnXCIpIG5vLXJlcGVhdDtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogOHB4IDUwJTtcbiAgYmFja2dyb3VuZC1zaXplOiAyNHB4O1xuICBib3JkZXItY29sb3I6ICMyRUNDNDA7XG4gIHBhZGRpbmctbGVmdDogNDBweDtcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyIGlucHV0W3R5cGU9XCJ0ZXh0XCJdOnJlcXVpcmVkLmN0Y3QtaW52YWxpZCwgLmN0Y3QtZm9ybS13cmFwcGVyIGlucHV0W3R5cGU9XCJ0ZXh0XCJdLmN0Y3QtaW52YWxpZCwgLmN0Y3QtZm9ybS13cmFwcGVyIGlucHV0W3R5cGU9XCJlbWFpbFwiXTpyZXF1aXJlZC5jdGN0LWludmFsaWQsIC5jdGN0LWZvcm0td3JhcHBlciBpbnB1dFt0eXBlPVwiZW1haWxcIl0uY3RjdC1pbnZhbGlkLCAuY3RjdC1mb3JtLXdyYXBwZXIgaW5wdXRbdHlwZT1cInBhc3N3b3JkXCJdOnJlcXVpcmVkLmN0Y3QtaW52YWxpZCwgLmN0Y3QtZm9ybS13cmFwcGVyIGlucHV0W3R5cGU9XCJwYXNzd29yZFwiXS5jdGN0LWludmFsaWQsIC5jdGN0LWZvcm0td3JhcHBlciBpbnB1dFt0eXBlPVwidGVsXCJdOnJlcXVpcmVkLmN0Y3QtaW52YWxpZCwgLmN0Y3QtZm9ybS13cmFwcGVyIGlucHV0W3R5cGU9XCJ0ZWxcIl0uY3RjdC1pbnZhbGlkLCAuY3RjdC1mb3JtLXdyYXBwZXIgaW5wdXRbdHlwZT1cIm51bWJlclwiXTpyZXF1aXJlZC5jdGN0LWludmFsaWQsIC5jdGN0LWZvcm0td3JhcHBlciBpbnB1dFt0eXBlPVwibnVtYmVyXCJdLmN0Y3QtaW52YWxpZCB7XG4gIGJhY2tncm91bmQ6IHdoaXRlIHVybChcIi4uL2ltYWdlcy9lcnJvci5zdmdcIikgbm8tcmVwZWF0O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgNjUsIDU0LCAwLjAyKTtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogOHB4IDUwJTtcbiAgYmFja2dyb3VuZC1zaXplOiAyNHB4O1xuICBib3JkZXItY29sb3I6ICNGRjQxMzY7XG4gIHBhZGRpbmctbGVmdDogNDBweDtcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyIC5jdGN0LWZpZWxkLWVycm9yIHtcbiAgZm9udC1zaXplOiAwLjg1ZW07XG4gIGZvbnQtc3R5bGU6IGl0YWxpYztcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyIGlucHV0LmN0Y3QtaW52YWxpZCB7XG4gIGJhY2tncm91bmQ6IHdoaXRlIHVybChcIi4uL2ltYWdlcy9lcnJvci5zdmdcIikgbm8tcmVwZWF0O1xuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDI1NSwgNjUsIDU0LCAwLjAyKTtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogOHB4IDUwJTtcbiAgYmFja2dyb3VuZC1zaXplOiAyNHB4O1xuICBib3JkZXItY29sb3I6ICNGRjQxMzY7XG4gIHBhZGRpbmctbGVmdDogNDBweDtcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyIGlucHV0LmN0Y3QtbGFiZWwtbGVmdCxcbi5jdGN0LWZvcm0td3JhcHBlciB0ZXh0YXJlYS5jdGN0LWxhYmVsLWxlZnQge1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIHdpZHRoOiA3NSU7XG59XG5cbi5jdGN0LWZvcm0td3JhcHBlciBzcGFuLmN0Y3QtbGFiZWwtbGVmdCB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgbWFyZ2luLXJpZ2h0OiA1JTtcbiAgd2lkdGg6IDIwJTtcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyIGlucHV0LmN0Y3QtbGFiZWwtcmlnaHQsXG4uY3RjdC1mb3JtLXdyYXBwZXIgdGV4dGFyZWEuY3RjdC1sYWJlbC1yaWdodCB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgbWFyZ2luLXJpZ2h0OiA1JTtcbiAgd2lkdGg6IDc1JTtcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyIHNwYW4uY3RjdC1sYWJlbC1yaWdodCB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgd2lkdGg6IDIwJTtcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyIHNwYW4uY3RjdC1sYWJlbC1oaWRkZW4ge1xuICBsZWZ0OiAtOTk5OXB4ICFpbXBvcnRhbnQ7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZSAhaW1wb3J0YW50O1xuICB0b3A6IC05OTk5cHggIWltcG9ydGFudDtcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyICNjdGN0X3VzYWdlIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBvdmVyZmxvdzogaGlkZGVuO1xuICBjbGlwOiByZWN0KDBweCwgMHB4LCAwcHgsIDBweCk7XG4gIGhlaWdodDogMXB4O1xuICB3aWR0aDogMXB4O1xuICBtYXJnaW46IC0xcHg7XG4gIGJvcmRlcjogMHB4IG5vbmU7XG4gIHBhZGRpbmc6IDBweDtcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyICNjdGN0LXN1Ym1pdHRlZDpkaXNhYmxlZCB7XG4gIGJhY2tncm91bmQtaW1hZ2U6IHVybChcIi4uL2ltYWdlcy9vdmFsLm1pbi5zdmdcIik7XG4gIGJhY2tncm91bmQtcG9zaXRpb246IGNlbnRlcjtcbiAgYmFja2dyb3VuZC1yZXBlYXQ6IG5vLXJlcGVhdDtcbiAgY29sb3I6IHRyYW5zcGFyZW50O1xuICBjdXJzb3I6IHdhaXQ7XG4gIG9wYWNpdHk6IDAuMztcbn1cblxuLmN0Y3QtZm9ybS13cmFwcGVyIC5jdGN0LWZvcm06YWZ0ZXIge1xuICBjbGVhcjogYm90aDtcbiAgY29udGVudDogXCJcIjtcbiAgZGlzcGxheTogdGFibGU7XG59XG5cbi5jdGN0LWZvcm0td3JhcHBlciAuY3RjdC1mb3JtIC5jdGN0LWxhYmVsLXRvcCBsYWJlbCxcbi5jdGN0LWZvcm0td3JhcHBlciAuY3RjdC1mb3JtIC5jdGN0LWxhYmVsLWJvdHRvbSBsYWJlbCB7XG4gIGRpc3BsYXk6IGJsb2NrO1xufVxuXG4uY3RjdC1mb3JtLXdyYXBwZXIgLmN0Y3QtZm9ybSAuY3RjdC1sYWJlbC1sZWZ0IGxhYmVsLFxuLmN0Y3QtZm9ybS13cmFwcGVyIC5jdGN0LWZvcm0gLmN0Y3QtbGFiZWwtcmlnaHQgbGFiZWwge1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG59XG5cbi5jdGN0LWZvcm0td3JhcHBlciAuY3RjdC1mb3JtIGFiYnIge1xuICBib3JkZXI6IG5vbmU7XG4gIGNvbG9yOiAjRkY0MTM2O1xuICBmb250LXNpemU6IDAuOWVtO1xufVxuXG4uY3RjdC1mb3JtLXdyYXBwZXIgLmN0Y3QtaW5wdXQtY29udGFpbmVyIGxhYmVsIHtcbiAgY29sb3I6ICNhYWE7XG4gIGZvbnQtc2l6ZTogMC44ZW07XG59XG5cbi5jdGN0LWZvcm0td3JhcHBlciAuY3RjdC1maWVsZC1lcnJvciB7XG4gIGNvbG9yOiAjRkY0MTM2O1xufVxuXG4uY3RjdC1mb3JtLXdyYXBwZXIgLmN0Y3Qtc3VibWl0IHtcbiAgY3Vyc29yOiBwb2ludGVyO1xufVxuXG4uY3RjdC10d2VudHlmb3VydGVlbiAuY3RjdC1mb3JtLWZpZWxkIGlucHV0IHtcbiAgd2lkdGg6IDEwMCU7XG59XG4iXX0= */
assets/css/style.min.css CHANGED
@@ -1 +1 @@
1
- .ctct-form-wrapper .ctct-button{font-size:.9em}.ctct-form-wrapper .ctct-message{border:1px solid;padding:1em}.ctct-form-wrapper .error{background-color:rgba(255,65,54,.02);border-color:#ff4136;color:#cf0b00}.ctct-form-wrapper .success{background-color:rgba(46,204,64,.02);border-color:#2ecc40;color:#1b7926}.ctct-form-wrapper .ctct-form-field{margin:0 0 1em}.ctct-form-wrapper .ctct-field-inline{display:inline-block}.ctct-form-wrapper input[type=email]:required:valid,.ctct-form-wrapper input[type=number]:required:valid,.ctct-form-wrapper input[type=password]:required:valid,.ctct-form-wrapper input[type=tel]:required:valid,.ctct-form-wrapper input[type=text]:required:valid{background:#fff url(../images/check_circle.svg) no-repeat;background-position:8px 50%;background-size:24px;border-color:#2ecc40;padding-left:40px}.ctct-form-wrapper input[type=email].ctct-invalid,.ctct-form-wrapper input[type=email]:required.ctct-invalid,.ctct-form-wrapper input[type=number].ctct-invalid,.ctct-form-wrapper input[type=number]:required.ctct-invalid,.ctct-form-wrapper input[type=password].ctct-invalid,.ctct-form-wrapper input[type=password]:required.ctct-invalid,.ctct-form-wrapper input[type=tel].ctct-invalid,.ctct-form-wrapper input[type=tel]:required.ctct-invalid,.ctct-form-wrapper input[type=text].ctct-invalid,.ctct-form-wrapper input[type=text]:required.ctct-invalid{background:#fff url(../images/error.svg) no-repeat;background-color:rgba(255,65,54,.02);background-position:8px 50%;background-size:24px;border-color:#ff4136;padding-left:40px}.ctct-form-wrapper .ctct-field-error{font-size:.85em;font-style:italic}.ctct-form-wrapper input.ctct-invalid{background:#fff url(../images/error.svg) no-repeat;background-color:rgba(255,65,54,.02);background-position:8px 50%;background-size:24px;border-color:#ff4136;padding-left:40px}.ctct-form-wrapper #ctct_usage{position:absolute;overflow:hidden;clip:rect(0,0,0,0);height:1px;width:1px;margin:-1px;border:0 none;padding:0}.ctct-form-wrapper .ctct-form:after{clear:both;content:"";display:table}.ctct-form-wrapper .ctct-form abbr{border:none;color:#ff4136;font-size:.9em}.ctct-form-wrapper .ctct-input-container label{color:#aaa;font-size:.8em}.ctct-form-wrapper .ctct-field-error{color:#ff4136}.ctct-form-wrapper .ctct-submit{cursor:pointer}.ctct-twentyfourteen .ctct-form-field input{width:100%}@media (min-width:992px){.ctct-form-wrapper .ctct-field-half{float:left;margin-right:2%;width:48%}.ctct-form-wrapper .ctct-field-half:last-of-type{margin-right:0}.ctct-form-wrapper .ctct-field-third{float:left;margin-right:2%;width:32%}.ctct-form-wrapper .ctct-field-third:last-of-type{margin-right:0}.ctct-form-wrapper .ctct-field-fourth{float:left;margin-right:2%;width:24%}.ctct-form-wrapper .ctct-field-fourth:last-of-type{margin-right:0}}
1
+ .ctct-form-wrapper .ctct-button{font-size:.9em}.ctct-form-wrapper .ctct-message{border:1px solid;padding:1em}.ctct-form-wrapper .error{background-color:rgba(255,65,54,.02);border-color:#ff4136;color:#cf0b00}.ctct-form-wrapper .success{background-color:rgba(46,204,64,.02);border-color:#2ecc40;color:#1b7926}.ctct-form-wrapper .ctct-form-field{margin:0 0 1em}.ctct-form-wrapper .ctct-field-inline{display:inline-block}.ctct-form-wrapper input[type=email]:required:valid,.ctct-form-wrapper input[type=number]:required:valid,.ctct-form-wrapper input[type=password]:required:valid,.ctct-form-wrapper input[type=tel]:required:valid,.ctct-form-wrapper input[type=text]:required:valid{background:#fff url(../images/check_circle.svg) no-repeat;background-position:8px 50%;background-size:24px;border-color:#2ecc40;padding-left:40px}.ctct-form-wrapper input[type=email].ctct-invalid,.ctct-form-wrapper input[type=email]:required.ctct-invalid,.ctct-form-wrapper input[type=number].ctct-invalid,.ctct-form-wrapper input[type=number]:required.ctct-invalid,.ctct-form-wrapper input[type=password].ctct-invalid,.ctct-form-wrapper input[type=password]:required.ctct-invalid,.ctct-form-wrapper input[type=tel].ctct-invalid,.ctct-form-wrapper input[type=tel]:required.ctct-invalid,.ctct-form-wrapper input[type=text].ctct-invalid,.ctct-form-wrapper input[type=text]:required.ctct-invalid{background:#fff url(../images/error.svg) no-repeat;background-color:rgba(255,65,54,.02);background-position:8px 50%;background-size:24px;border-color:#ff4136;padding-left:40px}.ctct-form-wrapper .ctct-field-error{font-size:.85em;font-style:italic}.ctct-form-wrapper input.ctct-invalid{background:#fff url(../images/error.svg) no-repeat;background-color:rgba(255,65,54,.02);background-position:8px 50%;background-size:24px;border-color:#ff4136;padding-left:40px}.ctct-form-wrapper input.ctct-label-left,.ctct-form-wrapper textarea.ctct-label-left{display:inline-block;width:75%}.ctct-form-wrapper span.ctct-label-left{display:inline-block;margin-right:5%;width:20%}.ctct-form-wrapper input.ctct-label-right,.ctct-form-wrapper textarea.ctct-label-right{display:inline-block;margin-right:5%;width:75%}.ctct-form-wrapper span.ctct-label-right{display:inline-block;width:20%}.ctct-form-wrapper span.ctct-label-hidden{left:-9999px!important;position:absolute!important;top:-9999px!important}.ctct-form-wrapper #ctct_usage{position:absolute;overflow:hidden;clip:rect(0,0,0,0);height:1px;width:1px;margin:-1px;border:0 none;padding:0}.ctct-form-wrapper #ctct-submitted:disabled{background-image:url(../images/oval.min.svg);background-position:50%;background-repeat:no-repeat;color:transparent;cursor:wait;opacity:.3}.ctct-form-wrapper .ctct-form:after{clear:both;content:"";display:table}.ctct-form-wrapper .ctct-form .ctct-label-bottom label,.ctct-form-wrapper .ctct-form .ctct-label-top label{display:block}.ctct-form-wrapper .ctct-form .ctct-label-left label,.ctct-form-wrapper .ctct-form .ctct-label-right label{display:inline-block}.ctct-form-wrapper .ctct-form abbr{border:none;color:#ff4136;font-size:.9em}.ctct-form-wrapper .ctct-input-container label{color:#aaa;font-size:.8em}.ctct-form-wrapper .ctct-field-error{color:#ff4136}.ctct-form-wrapper .ctct-submit{cursor:pointer}.ctct-twentyfourteen .ctct-form-field input{width:100%}@media (min-width:992px){.ctct-form-wrapper .ctct-field-half{float:left;margin-right:2%;width:48%}.ctct-form-wrapper .ctct-field-half:last-of-type{margin-right:0}.ctct-form-wrapper .ctct-field-third{float:left;margin-right:2%;width:32%}.ctct-form-wrapper .ctct-field-third:last-of-type{margin-right:0}.ctct-form-wrapper .ctct-field-fourth{float:left;margin-right:2%;width:24%}.ctct-form-wrapper .ctct-field-fourth:last-of-type{margin-right:0}}
assets/images/oval.min.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg width="38" height="38" xmlns="http://www.w3.org/2000/svg" stroke="#fff"><g transform="translate(1 1)" stroke-width="2" fill="none" fill-rule="evenodd"><circle stroke-opacity=".5" cx="18" cy="18" r="18"/><path d="M36 18c0-9.94-8.06-18-18-18"><animateTransform attributeName="transform" type="rotate" from="0 18 18" to="360 18 18" dur="1s" repeatCount="indefinite"/></path></g></svg>
assets/js/ctct-plugin-frontend.js CHANGED
@@ -31,15 +31,15 @@ window.CTCTSupport = {};
31
  that.cache();
32
  that.bindEvents();
33
  that.removePlaceholder();
34
- }
35
 
36
  that.removePlaceholder = function() {
37
  $( '.ctct-form-field input,textarea' ).focus( function() {
38
- $( this ).data( 'placeholder', $( this ).attr( 'placeholder' ) ).attr( 'placeholder','' );
39
  }).blur( function() {
40
  $( this ).attr( 'placeholder', $( this ).data( 'placeholder' ) );
41
  });
42
- }
43
 
44
  // Cache all the things.
45
  that.cache = function() {
@@ -47,13 +47,22 @@ window.CTCTSupport = {};
47
  window: $( window ),
48
  body: $( 'body' ),
49
  form: '.ctct-form-wrapper form',
 
 
50
  };
 
51
  that.timeout = null;
52
- }
53
 
54
  that.setAllInputsValid = function() {
55
  $( that.$c.form + ' .ctct-invalid' ).removeClass( 'ctct-invalid' );
56
- }
 
 
 
 
 
 
57
 
58
  that.processError = function( error ) {
59
 
@@ -62,11 +71,27 @@ window.CTCTSupport = {};
62
  $( '#' + error.id ).addClass( 'ctct-invalid' );
63
  }
64
 
65
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
  // Combine all events.
68
  that.bindEvents = function() {
69
  $( that.$c.form ).on( 'click', 'input[type=submit]', function(e) {
 
70
  if ('on' === $('.ctct-form').attr('data-doajax')) {
71
  var $form_id = $(this).closest('.ctct-form-wrapper').attr('id');
72
  var form_id_selector = '';
@@ -87,19 +112,32 @@ window.CTCTSupport = {};
87
  clearTimeout(that.timeout);
88
 
89
  that.timeout = setTimeout(function () {
 
90
  $.post(
91
  ajaxurl,
92
  {
93
  'action': 'ctct_process_form',
94
- 'data' : $(form_id_selector + 'form').serialize(),
95
  },
96
  function (response) {
97
-
98
- // Make sure we got the 'status' attribut in our response
99
  if (typeof( response.status ) !== 'undefined') {
100
 
101
- if ('success' == response.status) {
102
- $(form_id_selector+'.ctct-form').before('<p class="ctct-message ' + response.status + '">' + response.message + '</p>');
 
 
 
 
 
 
 
 
 
 
 
 
103
  } else {
104
  // Here we'll want to disable the submit button and
105
  // add some error classes
@@ -117,7 +155,12 @@ window.CTCTSupport = {};
117
  }, 500)
118
  }
119
  });
120
- }
 
 
 
 
 
121
 
122
  // Engage!
123
  $( that.init );
31
  that.cache();
32
  that.bindEvents();
33
  that.removePlaceholder();
34
+ };
35
 
36
  that.removePlaceholder = function() {
37
  $( '.ctct-form-field input,textarea' ).focus( function() {
38
+ $( this ).data( 'placeholder', $( this ).attr( 'placeholder' ) ).attr( 'placeholder', '' );
39
  }).blur( function() {
40
  $( this ).attr( 'placeholder', $( this ).data( 'placeholder' ) );
41
  });
42
+ };
43
 
44
  // Cache all the things.
45
  that.cache = function() {
47
  window: $( window ),
48
  body: $( 'body' ),
49
  form: '.ctct-form-wrapper form',
50
+ honeypot: $( '#ctct_usage_field' ),
51
+ submitButton: $( '.ctct-form-wrapper form input[type=submit]' )
52
  };
53
+
54
  that.timeout = null;
55
+ };
56
 
57
  that.setAllInputsValid = function() {
58
  $( that.$c.form + ' .ctct-invalid' ).removeClass( 'ctct-invalid' );
59
+ };
60
+
61
+ that.clearFormInputs = function (form_id_selector) {
62
+ var submitted_form = $(form_id_selector + ' form');
63
+ // jQuery doesn't have a native reset function so the [0] will convert to a JavaScript object.
64
+ submitted_form[0].reset();
65
+ };
66
 
67
  that.processError = function( error ) {
68
 
71
  $( '#' + error.id ).addClass( 'ctct-invalid' );
72
  }
73
 
74
+ };
75
+
76
+ /**
77
+ * Check the value of the hidden honeypot field.
78
+ * If there is anything in it, disable the form submission button.
79
+ */
80
+ that.checkHoneypot = function() {
81
+ var honeypot_length = that.$c.honeypot.val().length;
82
+
83
+ // If there is text in the honeypot, disable the submit button
84
+ if( honeypot_length > 0 ) {
85
+ that.$c.submitButton.attr( 'disabled', 'disabled' );
86
+ } else {
87
+ that.$c.submitButton.attr( 'disabled', false );
88
+ }
89
+ };
90
 
91
  // Combine all events.
92
  that.bindEvents = function() {
93
  $( that.$c.form ).on( 'click', 'input[type=submit]', function(e) {
94
+
95
  if ('on' === $('.ctct-form').attr('data-doajax')) {
96
  var $form_id = $(this).closest('.ctct-form-wrapper').attr('id');
97
  var form_id_selector = '';
112
  clearTimeout(that.timeout);
113
 
114
  that.timeout = setTimeout(function () {
115
+ $('#ctct-submitted').prop('disabled', true);
116
  $.post(
117
  ajaxurl,
118
  {
119
  'action': 'ctct_process_form',
120
+ 'data' : $(form_id_selector + 'form').serialize()
121
  },
122
  function (response) {
123
+ $('#ctct-submitted').prop('disabled', false);
124
+ // Make sure we got the 'status' attribute in our response
125
  if (typeof( response.status ) !== 'undefined') {
126
 
127
+ if ( 'success' === response.status ) {
128
+ // Add a timestamp to the message so that we only remove this message and not all at once.
129
+ var time_class = 'message-time-' + $.now();
130
+
131
+ var message_class = 'ctct-message ' + response.status + ' ' + time_class;
132
+ $(form_id_selector+'.ctct-form').before('<p class="' + message_class + '">' + response.message + '</p>');
133
+
134
+ if ( '' !== form_id_selector ) {
135
+ that.clearFormInputs( form_id_selector );
136
+ }
137
+ // Set a 5 second timeout to remove the added success message.
138
+ setTimeout( function() {
139
+ $( '.' + time_class ).fadeOut('slow');
140
+ }, 5000 );
141
  } else {
142
  // Here we'll want to disable the submit button and
143
  // add some error classes
155
  }, 500)
156
  }
157
  });
158
+
159
+ // Look for any changes on the honeypot input field.
160
+ $( that.$c.honeypot ).on( 'change keyup', function( e ) {
161
+ that.checkHoneypot();
162
+ });
163
+ };
164
 
165
  // Engage!
166
  $( that.init );
assets/js/ctct-plugin-frontend.min.js CHANGED
@@ -1 +1 @@
1
- !function(t,e){function c(){return e("#ctct-submitted").attr("disabled","disabled")}function o(){return e("#ctct-submitted").attr("disabled",null)}e(document).ready(function(){e("#ctct-submitted").on("click",function(){setTimeout(function(){c(),setTimeout(o,3e3)},100)})})}(window,jQuery),window.CTCTSupport={},function(t,e,c){c.init=function(){c.cache(),c.bindEvents(),c.removePlaceholder()},c.removePlaceholder=function(){e(".ctct-form-field input,textarea").focus(function(){e(this).data("placeholder",e(this).attr("placeholder")).attr("placeholder","")}).blur(function(){e(this).attr("placeholder",e(this).data("placeholder"))})},c.cache=function(){c.$c={window:e(t),body:e("body"),form:".ctct-form-wrapper form"},c.timeout=null},c.setAllInputsValid=function(){e(c.$c.form+" .ctct-invalid").removeClass("ctct-invalid")},c.processError=function(t){"undefined"!=typeof t.id&&e("#"+t.id).addClass("ctct-invalid")},c.bindEvents=function(){e(c.$c.form).on("click","input[type=submit]",function(t){if("on"===e(".ctct-form").attr("data-doajax")){var o=e(this).closest(".ctct-form-wrapper").attr("id"),i="";""!=o&&(i="#"+o+" ");var n=!0;if(e.each(e(i+".ctct-form [required]"),function(t,e){e.checkValidity()===!1&&(n=!1)}),!1===n)return;t.preventDefault(),clearTimeout(c.timeout),c.timeout=setTimeout(function(){e.post(ajaxurl,{action:"ctct_process_form",data:e(i+"form").serialize()},function(t){"undefined"!=typeof t.status&&("success"==t.status?e(i+".ctct-form").before('<p class="ctct-message '+t.status+'">'+t.message+"</p>"):"undefined"!=typeof t.errors?(c.setAllInputsValid(),t.errors.forEach(c.processError)):e(i+".ctct-form").before('<p class="ctct-message '+t.status+'">'+t.message+"</p>"))})},500)}})},e(c.init)}(window,jQuery,window.CTCTSupport);
1
+ !function(t,e){function c(){return e("#ctct-submitted").attr("disabled","disabled")}function o(){return e("#ctct-submitted").attr("disabled",null)}e(document).ready(function(){e("#ctct-submitted").on("click",function(){setTimeout(function(){c(),setTimeout(o,3e3)},100)})})}(window,jQuery),window.CTCTSupport={},function(t,e,c){c.init=function(){c.cache(),c.bindEvents(),c.removePlaceholder()},c.removePlaceholder=function(){e(".ctct-form-field input,textarea").focus(function(){e(this).data("placeholder",e(this).attr("placeholder")).attr("placeholder","")}).blur(function(){e(this).attr("placeholder",e(this).data("placeholder"))})},c.cache=function(){c.$c={window:e(t),body:e("body"),form:".ctct-form-wrapper form",honeypot:e("#ctct_usage_field"),submitButton:e(".ctct-form-wrapper form input[type=submit]")},c.timeout=null},c.setAllInputsValid=function(){e(c.$c.form+" .ctct-invalid").removeClass("ctct-invalid")},c.clearFormInputs=function(t){var c=e(t+" form");c[0].reset()},c.processError=function(t){"undefined"!=typeof t.id&&e("#"+t.id).addClass("ctct-invalid")},c.checkHoneypot=function(){var t=c.$c.honeypot.val().length;t>0?c.$c.submitButton.attr("disabled","disabled"):c.$c.submitButton.attr("disabled",!1)},c.bindEvents=function(){e(c.$c.form).on("click","input[type=submit]",function(t){if("on"===e(".ctct-form").attr("data-doajax")){var o=e(this).closest(".ctct-form-wrapper").attr("id"),i="";""!=o&&(i="#"+o+" ");var n=!0;if(e.each(e(i+".ctct-form [required]"),function(t,e){e.checkValidity()===!1&&(n=!1)}),!1===n)return;t.preventDefault(),clearTimeout(c.timeout),c.timeout=setTimeout(function(){e("#ctct-submitted").prop("disabled",!0),e.post(ajaxurl,{action:"ctct_process_form",data:e(i+"form").serialize()},function(t){if(e("#ctct-submitted").prop("disabled",!1),"undefined"!=typeof t.status)if("success"===t.status){var o="message-time-"+e.now(),n="ctct-message "+t.status+" "+o;e(i+".ctct-form").before('<p class="'+n+'">'+t.message+"</p>"),""!==i&&c.clearFormInputs(i),setTimeout(function(){e("."+o).fadeOut("slow")},5e3)}else"undefined"!=typeof t.errors?(c.setAllInputsValid(),t.errors.forEach(c.processError)):e(i+".ctct-form").before('<p class="ctct-message '+t.status+'">'+t.message+"</p>")})},500)}}),e(c.$c.honeypot).on("change keyup",function(t){c.checkHoneypot()})},e(c.init)}(window,jQuery,window.CTCTSupport);
assets/js/ctct-plugin-frontend/validation.js CHANGED
@@ -6,15 +6,15 @@ window.CTCTSupport = {};
6
  that.cache();
7
  that.bindEvents();
8
  that.removePlaceholder();
9
- }
10
 
11
  that.removePlaceholder = function() {
12
  $( '.ctct-form-field input,textarea' ).focus( function() {
13
- $( this ).data( 'placeholder', $( this ).attr( 'placeholder' ) ).attr( 'placeholder','' );
14
  }).blur( function() {
15
  $( this ).attr( 'placeholder', $( this ).data( 'placeholder' ) );
16
  });
17
- }
18
 
19
  // Cache all the things.
20
  that.cache = function() {
@@ -22,13 +22,22 @@ window.CTCTSupport = {};
22
  window: $( window ),
23
  body: $( 'body' ),
24
  form: '.ctct-form-wrapper form',
 
 
25
  };
 
26
  that.timeout = null;
27
- }
28
 
29
  that.setAllInputsValid = function() {
30
  $( that.$c.form + ' .ctct-invalid' ).removeClass( 'ctct-invalid' );
31
- }
 
 
 
 
 
 
32
 
33
  that.processError = function( error ) {
34
 
@@ -37,11 +46,27 @@ window.CTCTSupport = {};
37
  $( '#' + error.id ).addClass( 'ctct-invalid' );
38
  }
39
 
40
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
  // Combine all events.
43
  that.bindEvents = function() {
44
  $( that.$c.form ).on( 'click', 'input[type=submit]', function(e) {
 
45
  if ('on' === $('.ctct-form').attr('data-doajax')) {
46
  var $form_id = $(this).closest('.ctct-form-wrapper').attr('id');
47
  var form_id_selector = '';
@@ -62,19 +87,32 @@ window.CTCTSupport = {};
62
  clearTimeout(that.timeout);
63
 
64
  that.timeout = setTimeout(function () {
 
65
  $.post(
66
  ajaxurl,
67
  {
68
  'action': 'ctct_process_form',
69
- 'data' : $(form_id_selector + 'form').serialize(),
70
  },
71
  function (response) {
72
-
73
- // Make sure we got the 'status' attribut in our response
74
  if (typeof( response.status ) !== 'undefined') {
75
 
76
- if ('success' == response.status) {
77
- $(form_id_selector+'.ctct-form').before('<p class="ctct-message ' + response.status + '">' + response.message + '</p>');
 
 
 
 
 
 
 
 
 
 
 
 
78
  } else {
79
  // Here we'll want to disable the submit button and
80
  // add some error classes
@@ -92,7 +130,12 @@ window.CTCTSupport = {};
92
  }, 500)
93
  }
94
  });
95
- }
 
 
 
 
 
96
 
97
  // Engage!
98
  $( that.init );
6
  that.cache();
7
  that.bindEvents();
8
  that.removePlaceholder();
9
+ };
10
 
11
  that.removePlaceholder = function() {
12
  $( '.ctct-form-field input,textarea' ).focus( function() {
13
+ $( this ).data( 'placeholder', $( this ).attr( 'placeholder' ) ).attr( 'placeholder', '' );
14
  }).blur( function() {
15
  $( this ).attr( 'placeholder', $( this ).data( 'placeholder' ) );
16
  });
17
+ };
18
 
19
  // Cache all the things.
20
  that.cache = function() {
22
  window: $( window ),
23
  body: $( 'body' ),
24
  form: '.ctct-form-wrapper form',
25
+ honeypot: $( '#ctct_usage_field' ),
26
+ submitButton: $( '.ctct-form-wrapper form input[type=submit]' )
27
  };
28
+
29
  that.timeout = null;
30
+ };
31
 
32
  that.setAllInputsValid = function() {
33
  $( that.$c.form + ' .ctct-invalid' ).removeClass( 'ctct-invalid' );
34
+ };
35
+
36
+ that.clearFormInputs = function (form_id_selector) {
37
+ var submitted_form = $(form_id_selector + ' form');
38
+ // jQuery doesn't have a native reset function so the [0] will convert to a JavaScript object.
39
+ submitted_form[0].reset();
40
+ };
41
 
42
  that.processError = function( error ) {
43
 
46
  $( '#' + error.id ).addClass( 'ctct-invalid' );
47
  }
48
 
49
+ };
50
+
51
+ /**
52
+ * Check the value of the hidden honeypot field.
53
+ * If there is anything in it, disable the form submission button.
54
+ */
55
+ that.checkHoneypot = function() {
56
+ var honeypot_length = that.$c.honeypot.val().length;
57
+
58
+ // If there is text in the honeypot, disable the submit button
59
+ if( honeypot_length > 0 ) {
60
+ that.$c.submitButton.attr( 'disabled', 'disabled' );
61
+ } else {
62
+ that.$c.submitButton.attr( 'disabled', false );
63
+ }
64
+ };
65
 
66
  // Combine all events.
67
  that.bindEvents = function() {
68
  $( that.$c.form ).on( 'click', 'input[type=submit]', function(e) {
69
+
70
  if ('on' === $('.ctct-form').attr('data-doajax')) {
71
  var $form_id = $(this).closest('.ctct-form-wrapper').attr('id');
72
  var form_id_selector = '';
87
  clearTimeout(that.timeout);
88
 
89
  that.timeout = setTimeout(function () {
90
+ $('#ctct-submitted').prop('disabled', true);
91
  $.post(
92
  ajaxurl,
93
  {
94
  'action': 'ctct_process_form',
95
+ 'data' : $(form_id_selector + 'form').serialize()
96
  },
97
  function (response) {
98
+ $('#ctct-submitted').prop('disabled', false);
99
+ // Make sure we got the 'status' attribute in our response
100
  if (typeof( response.status ) !== 'undefined') {
101
 
102
+ if ( 'success' === response.status ) {
103
+ // Add a timestamp to the message so that we only remove this message and not all at once.
104
+ var time_class = 'message-time-' + $.now();
105
+
106
+ var message_class = 'ctct-message ' + response.status + ' ' + time_class;
107
+ $(form_id_selector+'.ctct-form').before('<p class="' + message_class + '">' + response.message + '</p>');
108
+
109
+ if ( '' !== form_id_selector ) {
110
+ that.clearFormInputs( form_id_selector );
111
+ }
112
+ // Set a 5 second timeout to remove the added success message.
113
+ setTimeout( function() {
114
+ $( '.' + time_class ).fadeOut('slow');
115
+ }, 5000 );
116
  } else {
117
  // Here we'll want to disable the submit button and
118
  // add some error classes
130
  }, 500)
131
  }
132
  });
133
+
134
+ // Look for any changes on the honeypot input field.
135
+ $( that.$c.honeypot ).on( 'change keyup', function( e ) {
136
+ that.checkHoneypot();
137
+ });
138
+ };
139
 
140
  // Engage!
141
  $( that.init );
assets/sass/_admin-forms.scss ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .post-type-ctct_forms {
2
+ .misc-pub-section {
3
+ &.misc-pub-visibility,
4
+ &.misc-pub-curtime {
5
+ display: none;
6
+ }
7
+ }
8
+ }
9
+
10
+ body.post-type-ctct_lists .misc-pub-post-status {
11
+ display: none;
12
+ }
13
+
14
+ body.post-type-ctct_forms #titlediv #title {
15
+ height: 2.7em;
16
+ }
17
+
18
+ .ctct-admin-title-details {
19
+ font-size: .6em;
20
+ vertical-align: middle;
21
+ display: block;
22
+ line-height: 2em;
23
+ }
24
+
25
+ #cmb2-metabox-ctct_1_optin_metabox {
26
+ .cmb2-id--ctct-opt-in-instructions,
27
+ .cmb2-id--ctct-opt-in {
28
+ display: none;
29
+ }
30
+
31
+ }
32
+
33
+ #ctct_0_list_metabox,
34
+ #ctct_1_custom_form_css_metabox,
35
+ #ctct_1_custom_input_css_metabox {
36
+ .cmb-row {
37
+ padding-bottom: 0;
38
+ }
39
+ }
40
+
41
+ #cmb2-metabox-ctct_2_fields_metabox {
42
+ .cmb2-id--ctct-title {
43
+ padding: .8em 0 1em;
44
+ }
45
+ }
46
+
47
+ #ctct_1_custom_form_css_metabox {
48
+ .cmb2-id-form-title-title {
49
+ padding: .8em 0 1em;
50
+ }
51
+ }
52
+
53
+ #ctct_0_description_metabox,
54
+ #ctct_1_optin_metabox,
55
+ #ctct_2_fields_metabox {
56
+
57
+ #custom_fields_group_repeat {
58
+ .cmb-field-list .cmb-row:not(:last-of-type) {
59
+ border-bottom: none;
60
+ padding-bottom: 0.1em;
61
+ }
62
+ .required {
63
+ padding-bottom: 0.1em;
64
+ padding-top: 0.1em;
65
+ }
66
+ }
67
+
68
+ #default_fields_group_repeat {
69
+ .cmb-field-list {
70
+ & > .cmb-row {
71
+ padding-top: 0.5em;
72
+
73
+ &:not(:last-of-type) {
74
+ padding-bottom: 0.1em;
75
+ border-bottom: 1px solid #e9e9e9 !important;
76
+ }
77
+ }
78
+ }
79
+ }
80
+
81
+ .cmb-repeat-group-wrap {
82
+ padding: 0 !important;
83
+
84
+ .cmb-repeatable-grouping {
85
+ margin: 0 0 1.5em 0;
86
+
87
+ .cmb-row {
88
+ margin: 0 0 0 0.3em;
89
+ }
90
+ }
91
+
92
+ .cmb-repeat-group-field {
93
+ padding-top: 0.2em;
94
+ }
95
+ }
96
+
97
+ .postbox-container .cmb-remove-field-row {
98
+ padding-top: 0.8em;
99
+ padding-bottom: 0.8em;
100
+ }
101
+
102
+ button {
103
+ &.cmb-add-group-row {
104
+ color: white !important;
105
+ background: #008ec2 !important;
106
+ border-color: #006799 !important;
107
+ }
108
+ &.cmb-remove-group-row {
109
+ background: #ffdfa3 !important;
110
+ display: none;
111
+ }
112
+ }
113
+
114
+ .cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row {
115
+ top: .3em;
116
+ }
117
+
118
+ h3.cmb-group-title.cmbhandle-title {
119
+ padding-left: 1em;
120
+ }
121
+ }
122
+
123
+ #ctct_1_optin_metabox {
124
+
125
+ .cmb-row {
126
+ border-bottom: none;
127
+ padding: .5em 0px;
128
+ }
129
+
130
+ .cmb2-id--ctct-list {
131
+ padding-bottom: 0.5em;
132
+ }
133
+
134
+ .cmb-th {
135
+ width: 25%;
136
+ }
137
+
138
+ .cmb-th + .cmb-td {
139
+ width: 70%;
140
+ }
141
+ }
142
+
143
+ #ctct_option_metabox_settings {
144
+ span.cmb2-metabox-description {
145
+ color: rgb(68, 68, 68);
146
+ }
147
+ }
148
+
149
+ #cmb2-metabox-email_settings,
150
+ #cmb2-metabox-ctct_2_generated_metabox,
151
+ #cmb2-metabox-ctct_1_custom_input_css_metabox {
152
+ .cmb-row {
153
+ padding-bottom: 0px !important;
154
+ }
155
+ }
156
+
157
+ #side-sortables {
158
+
159
+ #ctct_1_custom_form_css_metabox {
160
+
161
+ .cmb-row {
162
+ padding: 0.5em 0 0 0;
163
+ } // .cmb-row
164
+
165
+ .cmb-th {
166
+ padding-bottom: 0;
167
+ } // .cmb-th
168
+
169
+ .cmb-type-title {
170
+ border-bottom: none;
171
+ } // .cmb-type-title
172
+
173
+ .cmb2-id--ctct-form-title-font-size,
174
+ .cmb2-id--ctct-form-description-font-size {
175
+ border-bottom: none;
176
+ margin-bottom: 0;
177
+ } // .cmb2-id--ctct-form-title-font-size
178
+
179
+ } // #ctct_1_custom_form_css_metabox
180
+
181
+ #ctct_1_custom_input_css_metabox {
182
+ .cmb2-id-form-padding-title {
183
+ border-bottom: 0;
184
+ padding-bottom: 0;
185
+ } // .cmb2-id-form-padding-title
186
+
187
+ .cmb2-id--ctct-input-margin-top,
188
+ .cmb2-id--ctct-input-margin-right {
189
+ margin-bottom: 0;
190
+ margin-top: 0;
191
+ padding-bottom: 0;
192
+ padding-top: 0;
193
+ } // .cmb2-id--ctct-input-margin-top, .cmb2-id--ctct-input-margin-right
194
+
195
+ .cmb2-id--ctct-form-label-placement {
196
+ padding-bottom: 0;
197
+ margin-bottom: 0;
198
+ } // .cmb2-id--ctct-form-label-placement
199
+
200
+ .cmb-type-text-small {
201
+ border-bottom: none;
202
+ float: left;
203
+ width: 50%;
204
+
205
+ .cmb-th {
206
+ padding-bottom: 0;
207
+ } // .cmb-th
208
+ } // .cmb-type-text-small
209
+ } // #ctct_1_custom_input_css_metabox
210
+ } // #side-sortables
assets/sass/{admin-global-no-connection.scss → _admin-global-no-connection.scss} RENAMED
@@ -1,6 +1,3 @@
1
- @import 'variables';
2
- @import 'mixins';
3
-
4
  #adminmenu .wp-submenu a[href="edit.php?post_type=ctct_forms&page=ctct_options_connect"] {
5
  color: rgb(58, 209, 130);
6
  }
 
 
 
1
  #adminmenu .wp-submenu a[href="edit.php?post_type=ctct_forms&page=ctct_options_connect"] {
2
  color: rgb(58, 209, 130);
3
  }
assets/sass/{admin-notices.scss → _admin-notices.scss} RENAMED
File without changes
assets/sass/{admin-pages.scss → _admin-pages.scss} RENAMED
@@ -1,6 +1,3 @@
1
- @import 'variables';
2
- @import 'mixins';
3
-
4
  //--------------------------------------------------------------
5
  // About Page
6
  //--------------------------------------------------------------
 
 
 
1
  //--------------------------------------------------------------
2
  // About Page
3
  //--------------------------------------------------------------
assets/sass/_forms.scss CHANGED
@@ -6,9 +6,14 @@
6
  .ctct-form {
7
  @include clearfix;
8
 
9
- label {
10
-
11
- } // <label>
 
 
 
 
 
12
 
13
  abbr {
14
  border: none;
6
  .ctct-form {
7
  @include clearfix;
8
 
9
+ .ctct-label-top label,
10
+ .ctct-label-bottom label {
11
+ display: block;
12
+ }
13
+ .ctct-label-left label,
14
+ .ctct-label-right label {
15
+ display: inline-block;
16
+ }
17
 
18
  abbr {
19
  border: none;
assets/sass/_inputs.scss CHANGED
@@ -49,6 +49,36 @@
49
  padding-left: 40px;
50
  }
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  #ctct_usage {
53
  position: absolute;
54
  overflow: hidden;
@@ -59,4 +89,12 @@
59
  border: 0px none;
60
  padding: 0px;
61
  }
 
 
 
 
 
 
 
 
62
  }
49
  padding-left: 40px;
50
  }
51
 
52
+ input.ctct-label-left,
53
+ textarea.ctct-label-left {
54
+ display: inline-block;
55
+ width: 75%;
56
+ } // input.ctct-label-left, textarea.ctct-label-left
57
+
58
+ span.ctct-label-left {
59
+ display: inline-block;
60
+ margin-right: 5%;
61
+ width: 20%;
62
+ } // span.ctct-label-left
63
+
64
+ input.ctct-label-right,
65
+ textarea.ctct-label-right {
66
+ display: inline-block;
67
+ margin-right: 5%;
68
+ width: 75%;
69
+ } // input.ctct-label-right, textarea.ctct-label-right
70
+
71
+ span.ctct-label-right {
72
+ display: inline-block;
73
+ width: 20%;
74
+ } // span.ctct-label-right
75
+
76
+ span.ctct-label-hidden {
77
+ left: -9999px !important;
78
+ position: absolute !important;
79
+ top: -9999px !important;
80
+ } // span.ctct-label-hidden
81
+
82
  #ctct_usage {
83
  position: absolute;
84
  overflow: hidden;
89
  border: 0px none;
90
  padding: 0px;
91
  }
92
+ #ctct-submitted:disabled {
93
+ background-image: url('../images/oval.min.svg');
94
+ background-position: center;
95
+ background-repeat: no-repeat;
96
+ color: transparent;
97
+ cursor: wait;
98
+ opacity: 0.3;
99
+ }
100
  }
assets/sass/{oath.scss → _oath.scss} RENAMED
@@ -1,6 +1,3 @@
1
- @import 'variables';
2
- @import 'mixins';
3
-
4
  //--------------------------------------------------------------
5
  // Disconnect Page
6
  //--------------------------------------------------------------
 
 
 
1
  //--------------------------------------------------------------
2
  // Disconnect Page
3
  //--------------------------------------------------------------
assets/sass/admin-forms.scss DELETED
@@ -1,123 +0,0 @@
1
- @import 'variables';
2
- @import 'mixins';
3
- @import 'modal';
4
-
5
-
6
- .post-type-ctct_forms .misc-pub-section {
7
- &.misc-pub-visibility,
8
- &.misc-pub-curtime {
9
- display: none;
10
- }
11
- }
12
-
13
- body.post-type-ctct_lists .misc-pub-post-status {
14
- display: none;
15
- }
16
-
17
- body.post-type-ctct_forms #titlediv #title {
18
- height: 2.7em;
19
- }
20
-
21
- .ctct-admin-title-details {
22
- font-size: .6em;
23
- vertical-align: middle;
24
- display: block;
25
- line-height: 2em;
26
- }
27
-
28
- #cmb2-metabox-ctct_1_optin_metabox .cmb2-id--ctct-opt-in-instructions,
29
- #cmb2-metabox-ctct_1_optin_metabox .cmb2-id--ctct-opt-in {
30
- display: none;
31
- }
32
-
33
- #ctct_0_description_metabox,
34
- #ctct_1_optin_metabox,
35
- #ctct_2_fields_metabox {
36
-
37
- #custom_fields_group_repeat .cmb-field-list .cmb-row:not(:last-of-type) {
38
- border-bottom: none;
39
- padding-bottom: 0.1em;
40
- }
41
-
42
- #custom_fields_group_repeat .required {
43
- padding-bottom: 0.1em;
44
- padding-top: 0.1em;
45
- }
46
-
47
- #default_fields_group_repeat .cmb-field-list > .cmb-row {
48
- padding-top: 0.5em;
49
- }
50
-
51
- #default_fields_group_repeat .cmb-field-list > .cmb-row:not(:last-of-type) {
52
- padding-bottom: 0.1em;
53
- border-bottom: 1px solid #e9e9e9 !important;
54
- }
55
-
56
- .cmb-repeat-group-wrap .cmb-repeatable-grouping {
57
- margin: 0 0 1.5em 0;
58
- }
59
-
60
- .cmb-repeat-group-wrap .cmb-repeatable-grouping .cmb-row {
61
- margin: 0 0 0 0.3em;
62
- }
63
-
64
- .postbox-container .cmb-remove-field-row {
65
- padding-top: 0.8em;
66
- padding-bottom: 0.8em;
67
- }
68
-
69
- .cmb-repeat-group-wrap {
70
- padding: 0 !important;
71
- }
72
-
73
- .cmb-repeat-group-wrap .cmb-repeat-group-field {
74
- padding-top: 0.2em;
75
- }
76
-
77
- button.cmb-add-group-row {
78
- color: white !important;
79
- background: #008ec2 !important;
80
- border-color: #006799 !important;
81
- }
82
-
83
- .cmb2-metabox button.dashicons-before.dashicons-no-alt.cmb-remove-group-row {
84
- top: .3em;
85
- }
86
-
87
- button.cmb-remove-group-row {
88
- background: #ffdfa3 !important;
89
- }
90
-
91
- button.cmb-remove-group-row {
92
- display: none;
93
- }
94
-
95
- h3.cmb-group-title.cmbhandle-title {
96
- padding-left: 1em;
97
- }
98
- }
99
-
100
- #ctct_1_optin_metabox {
101
-
102
- .cmb-row {
103
- border-bottom: none;
104
- }
105
-
106
- .cmb2-id--ctct-list {
107
- padding-bottom: 0.5em;
108
- }
109
-
110
- .cmb-th {
111
- width: 25%;
112
- }
113
-
114
- .cmb-th + .cmb-td {
115
- width: 70%;
116
- }
117
- }
118
-
119
- #ctct_option_metabox_settings {
120
- span.cmb2-metabox-description {
121
- color: rgb(68, 68, 68);
122
- }
123
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/sass/admin-style.scss ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //--------------------------------------------------------------
2
+ // Let's import all the things - admin-style.css
3
+ //--------------------------------------------------------------
4
+
5
+ @import "variables";
6
+ @import "mixins";
7
+ @import 'modal';
8
+
9
+ @import "admin-forms";
10
+ @import "admin-global-no-connection";
11
+ @import "admin-notices";
12
+ @import "admin-pages";
13
+ @import "oath";
constant-contact-forms.php CHANGED
@@ -12,7 +12,7 @@
12
  * Plugin Name: Constant Contact Forms for WordPress
13
  * Plugin URI: https://www.constantcontact.com
14
  * Description: Be a better marketer. All it takes is Constant Contact email marketing.
15
- * Version: 1.3.7
16
  * Author: Constant Contact
17
  * Author URI: https://www.constantcontact.com/index?pn=miwordpress
18
  * License: GPLv3
@@ -77,7 +77,7 @@ class Constant_Contact {
77
  * @since 1.0.0
78
  * @var string
79
  */
80
- const VERSION = '1.3.7';
81
 
82
  /**
83
  * URL of plugin directory.
@@ -379,6 +379,9 @@ class Constant_Contact {
379
 
380
  // Include our helper functions function for end-users.
381
  self::include_file( 'helper-functions', false );
 
 
 
382
  }
383
 
384
  /**
@@ -455,10 +458,14 @@ class Constant_Contact {
455
  // Allow shortcodes in widgets for our plugin.
456
  add_filter( 'widget_text', 'do_shortcode' );
457
 
 
 
 
458
  if ( is_admin() ) {
459
  add_action( 'wp_ajax_ctct_dismiss_first_modal', array( $this, 'ajax_save_clear_first_form' ) );
460
  add_action( 'wp_ajax_nopriv_ctct_dismiss_first_modal', array( $this, 'ajax_save_clear_first_form' ) );
461
  }
 
462
  }
463
 
464
  /**
@@ -598,7 +605,7 @@ class Constant_Contact {
598
 
599
  if ( isset( $_POST['action'] ) && 'ctct_dismiss_first_modal' === $_POST['action'] ) {
600
  // Save our dismiss for the first form modal.
601
- update_option( 'ctct_first_form_modal_dismissed', time() );
602
  }
603
  wp_die();
604
  }
@@ -767,6 +774,34 @@ class Constant_Contact {
767
  return $classes;
768
  }
769
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
770
  /**
771
  * Determine if we are in a Constant Contact area.
772
  *
12
  * Plugin Name: Constant Contact Forms for WordPress
13
  * Plugin URI: https://www.constantcontact.com
14
  * Description: Be a better marketer. All it takes is Constant Contact email marketing.
15
+ * Version: 1.4.0
16
  * Author: Constant Contact
17
  * Author URI: https://www.constantcontact.com/index?pn=miwordpress
18
  * License: GPLv3
77
  * @since 1.0.0
78
  * @var string
79
  */
80
+ const VERSION = '1.4.0';
81
 
82
  /**
83
  * URL of plugin directory.
379
 
380
  // Include our helper functions function for end-users.
381
  self::include_file( 'helper-functions', false );
382
+
383
+ // Include compatibility fixes to address conflicts with other plug-ins.
384
+ self::include_file( 'compatibility', false );
385
  }
386
 
387
  /**
458
  // Allow shortcodes in widgets for our plugin.
459
  add_filter( 'widget_text', 'do_shortcode' );
460
 
461
+ add_action( 'admin_enqueue_scripts', array( $this, 'register_admin_assets' ), 1 );
462
+ add_action( 'wp_enqueue_scripts', array( $this, 'register_front_assets' ), 1 );
463
+
464
  if ( is_admin() ) {
465
  add_action( 'wp_ajax_ctct_dismiss_first_modal', array( $this, 'ajax_save_clear_first_form' ) );
466
  add_action( 'wp_ajax_nopriv_ctct_dismiss_first_modal', array( $this, 'ajax_save_clear_first_form' ) );
467
  }
468
+
469
  }
470
 
471
  /**
605
 
606
  if ( isset( $_POST['action'] ) && 'ctct_dismiss_first_modal' === $_POST['action'] ) {
607
  // Save our dismiss for the first form modal.
608
+ update_option( 'ctct_first_form_modal_dismissed', current_time( 'timestamp' ) );
609
  }
610
  wp_die();
611
  }
774
  return $classes;
775
  }
776
 
777
+ /**
778
+ * Register our admin styles.
779
+ *
780
+ * @since 1.4.0
781
+ */
782
+ public function register_admin_assets() {
783
+ wp_register_style(
784
+ 'constant-contact-forms-admin',
785
+ $this->url() . 'assets/css/admin-style.css',
786
+ array(),
787
+ self::VERSION
788
+ );
789
+ }
790
+
791
+ /**
792
+ * Register our frontend styles.
793
+ *
794
+ * @since 1.4.0
795
+ */
796
+ public function register_front_assets() {
797
+ wp_register_style(
798
+ 'ctct_form_styles',
799
+ $this->url() . 'assets/css/style.css',
800
+ array(),
801
+ self::VERSION
802
+ );
803
+ }
804
+
805
  /**
806
  * Determine if we are in a Constant Contact area.
807
  *
includes/class-admin-pages.php CHANGED
@@ -49,21 +49,7 @@ class ConstantContact_Admin_Pages {
49
  * @since 1.0.0
50
  */
51
  public function styles() {
52
-
53
- wp_enqueue_style(
54
- 'constant-contact-forms',
55
- constant_contact()->url() . 'assets/css/admin-forms.css',
56
- array(),
57
- Constant_Contact::VERSION
58
- );
59
-
60
- wp_enqueue_style(
61
- 'constant_contact_admin_pages',
62
- constant_contact()->url() . 'assets/css/admin-pages.css',
63
- array(),
64
- Constant_Contact::VERSION
65
- );
66
-
67
  wp_enqueue_script( 'ctct_form' );
68
  }
69
 
49
  * @since 1.0.0
50
  */
51
  public function styles() {
52
+ wp_enqueue_style( 'constant-contact-forms-admin' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  wp_enqueue_script( 'ctct_form' );
54
  }
55
 
includes/class-admin.php CHANGED
@@ -290,7 +290,7 @@ class ConstantContact_Admin {
290
  get_the_title( $list->ID )
291
  );
292
  } else {
293
- esc_html_e( 'No associated form', 'constant-contact-forms' );
294
  }
295
  break;
296
  }
@@ -352,6 +352,13 @@ class ConstantContact_Admin {
352
  * @return array
353
  */
354
  public function add_social_links( $links ) {
 
 
 
 
 
 
 
355
  // Get Twitter share link.
356
  $twitter_cta = __( 'Check out the official WordPress plugin from @constantcontact :', 'constant-contact-forms' );
357
 
@@ -501,12 +508,13 @@ class ConstantContact_Admin {
501
  *
502
  * @since 1.3.0
503
  *
504
- * @param string $list_id Constant Contact list ID value
505
  * @return mixed
506
  */
507
  public function get_associated_list_by_id( $list_id ) {
508
  global $wpdb;
509
  $sql = "SELECT p.ID FROM $wpdb->posts as p INNER JOIN $wpdb->postmeta as pm on p.ID = pm.post_id WHERE pm.meta_key = '_ctct_list_id' AND pm.meta_value = %s";
 
510
  $rs = $wpdb->get_results(
511
  $wpdb->prepare( $sql, $list_id )
512
  );
290
  get_the_title( $list->ID )
291
  );
292
  } else {
293
+ esc_html_e( 'No associated list', 'constant-contact-forms' );
294
  }
295
  break;
296
  }
352
  * @return array
353
  */
354
  public function add_social_links( $links ) {
355
+
356
+ // No code beyond this point can account for a non-array value for this passed parameter,
357
+ // so let's just return early.
358
+ if ( ! is_array( $links ) ) {
359
+ return $links;
360
+ }
361
+
362
  // Get Twitter share link.
363
  $twitter_cta = __( 'Check out the official WordPress plugin from @constantcontact :', 'constant-contact-forms' );
364
 
508
  *
509
  * @since 1.3.0
510
  *
511
+ * @param string $list_id Constant Contact list ID value.
512
  * @return mixed
513
  */
514
  public function get_associated_list_by_id( $list_id ) {
515
  global $wpdb;
516
  $sql = "SELECT p.ID FROM $wpdb->posts as p INNER JOIN $wpdb->postmeta as pm on p.ID = pm.post_id WHERE pm.meta_key = '_ctct_list_id' AND pm.meta_value = %s";
517
+
518
  $rs = $wpdb->get_results(
519
  $wpdb->prepare( $sql, $list_id )
520
  );
includes/class-api.php CHANGED
@@ -827,8 +827,8 @@ class ConstantContact_API {
827
  }
828
 
829
  $disclosure = array(
830
- 'name' => empty( $account_info->organization_name ) ? ctct_get_settings_option( '_ctct_disclose_name' ) : $account_info->organization_name,
831
- 'address' => ctct_get_settings_option( '_ctct_disclose_address' ),
832
  );
833
 
834
  // Bail if we don't have a name.
827
  }
828
 
829
  $disclosure = array(
830
+ 'name' => empty( $account_info->organization_name ) ? ctct_get_settings_option( '_ctct_disclose_name', '' ) : $account_info->organization_name,
831
+ 'address' => ctct_get_settings_option( '_ctct_disclose_address', '' ),
832
  );
833
 
834
  // Bail if we don't have a name.
includes/class-builder-fields.php CHANGED
@@ -77,8 +77,11 @@ class ConstantContact_Builder_Fields {
77
  add_action( 'cmb2_admin_init', array( $this, 'description_metabox' ) );
78
  add_action( 'cmb2_admin_init', array( $this, 'constant_contact_list_metabox' ) );
79
  add_action( 'cmb2_admin_init', array( $this, 'opt_ins_metabox' ) );
80
- add_action( 'cmb2_admin_init', array( $this, 'fields_metabox' ) );
81
  add_action( 'cmb2_admin_init', array( $this, 'generated_shortcode' ) );
 
 
 
 
82
  add_filter( 'cmb2_override__ctct_generated_shortcode_meta_save', '__return_empty_string' );
83
  }
84
 
@@ -177,9 +180,9 @@ class ConstantContact_Builder_Fields {
177
  ) );
178
 
179
  $options_metabox->add_field( array(
180
- 'name' => esc_html__( 'Submission behavior', 'constant-contact-forms' ),
181
- 'type' => 'title',
182
- 'id' => 'submission_behavior_title',
183
  'after' => '<hr/>',
184
  ) );
185
 
@@ -198,13 +201,181 @@ class ConstantContact_Builder_Fields {
198
  'description' => __( 'Enable form submission without a page refresh. This option overrides the Redirect URL choice above.', 'constant-contact-forms' ),
199
  ) );
200
 
201
-
202
-
203
  if ( constant_contact()->api->is_connected() ) {
204
  $this->show_optin_connected_fields( $options_metabox );
205
  }
206
  }
207
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  /**
209
  * Helper method to show our connected optin fields.
210
  *
@@ -299,11 +470,11 @@ class ConstantContact_Builder_Fields {
299
  $business_name ? ( $business_name ) : __( 'Your Business Name', 'constant-contact-forms' );
300
 
301
  $options_metabox->add_field( array(
302
- 'name' => __( 'Opt-in Affirmation', 'constant-contact-forms' ),
303
- 'id' => $this->prefix . 'opt_in_instructions',
304
- 'type' => 'textarea_small',
305
  // translators: placeholder has a business name from Constant Contact.
306
- 'default' => sprintf( __( 'Example: Yes, I would like to receive emails from %s. (You can unsubscribe anytime)', 'constant-contact-forms' ), $business_name ),
307
  ) );
308
  }
309
 
@@ -511,4 +682,34 @@ class ConstantContact_Builder_Fields {
511
  ),
512
  ) );
513
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
514
  }
77
  add_action( 'cmb2_admin_init', array( $this, 'description_metabox' ) );
78
  add_action( 'cmb2_admin_init', array( $this, 'constant_contact_list_metabox' ) );
79
  add_action( 'cmb2_admin_init', array( $this, 'opt_ins_metabox' ) );
 
80
  add_action( 'cmb2_admin_init', array( $this, 'generated_shortcode' ) );
81
+ add_action( 'cmb2_admin_init', array( $this, 'email_settings' ) );
82
+ add_action( 'cmb2_admin_init', array( $this, 'custom_form_css_metabox' ) );
83
+ add_action( 'cmb2_admin_init', array( $this, 'custom_input_css_metabox' ) );
84
+ add_action( 'cmb2_admin_init', array( $this, 'fields_metabox' ) );
85
  add_filter( 'cmb2_override__ctct_generated_shortcode_meta_save', '__return_empty_string' );
86
  }
87
 
180
  ) );
181
 
182
  $options_metabox->add_field( array(
183
+ 'name' => esc_html__( 'Submission behavior', 'constant-contact-forms' ),
184
+ 'type' => 'title',
185
+ 'id' => 'submission_behavior_title',
186
  'after' => '<hr/>',
187
  ) );
188
 
201
  'description' => __( 'Enable form submission without a page refresh. This option overrides the Redirect URL choice above.', 'constant-contact-forms' ),
202
  ) );
203
 
 
 
204
  if ( constant_contact()->api->is_connected() ) {
205
  $this->show_optin_connected_fields( $options_metabox );
206
  }
207
  }
208
 
209
+ /**
210
+ * Metabox for user to set custom CSS for a form.
211
+ *
212
+ * @since 1.4.0
213
+ */
214
+ public function custom_form_css_metabox() {
215
+ $custom_css_metabox = new_cmb2_box( array(
216
+ 'id' => 'ctct_1_custom_form_css_metabox',
217
+ 'title' => __( 'Form Design', 'constant-contact-forms' ),
218
+ 'object_types' => array( 'ctct_forms' ),
219
+ 'context' => 'side',
220
+ 'priority' => 'low',
221
+ ) );
222
+
223
+ $custom_css_metabox->add_field( array(
224
+ 'name' => __( 'Background Color', 'constant-contact-forms' ),
225
+ 'id' => $this->prefix . 'form_background_color',
226
+ 'type' => 'colorpicker',
227
+ 'description' => esc_html__(
228
+ 'Applies to the whole form.',
229
+ 'constant-contact-forms'
230
+ ),
231
+ ) );
232
+
233
+ $custom_css_metabox->add_field( array(
234
+ 'name' => esc_html__( 'Form Description', 'constant-contact-forms' ),
235
+ 'type' => 'title',
236
+ 'id' => 'form-description-title',
237
+ ) );
238
+
239
+ $custom_css_metabox->add_field( array(
240
+ 'name' => __( 'Font Size', 'constant-contact-forms' ),
241
+ 'id' => $this->prefix . 'form_description_font_size',
242
+ 'type' => 'select',
243
+ 'show_option_none' => 'Default',
244
+ 'options_cb' => 'constant_contact_get_font_dropdown_sizes',
245
+ ) );
246
+
247
+ $custom_css_metabox->add_field( array(
248
+ 'name' => __( 'Font Color', 'constant-contact-forms' ),
249
+ 'id' => $this->prefix . 'form_description_color',
250
+ 'type' => 'colorpicker',
251
+ ) );
252
+
253
+ $custom_css_metabox->add_field( array(
254
+ 'name' => esc_html__( 'Form Submit Button', 'constant-contact-forms' ),
255
+ 'type' => 'title',
256
+ 'id' => 'form-submit-button-title',
257
+ ) );
258
+
259
+ $custom_css_metabox->add_field( array(
260
+ 'name' => __( 'Font Size', 'constant-contact-forms' ),
261
+ 'id' => $this->prefix . 'form_submit_button_font_size',
262
+ 'type' => 'select',
263
+ 'show_option_none' => 'Default',
264
+ 'options_cb' => 'constant_contact_get_font_dropdown_sizes',
265
+ ) );
266
+
267
+ $custom_css_metabox->add_field( array(
268
+ 'name' => __( 'Font Color', 'constant-contact-forms' ),
269
+ 'id' => $this->prefix . 'form_submit_button_text_color',
270
+ 'type' => 'colorpicker',
271
+ 'description' => esc_html__(
272
+ 'Choose a color for the submit button text.',
273
+ 'constant-contact-forms'
274
+ ),
275
+ ) );
276
+
277
+ $custom_css_metabox->add_field( array(
278
+ 'name' => __( 'Background Color', 'constant-contact-forms' ),
279
+ 'id' => $this->prefix . 'form_submit_button_background_color',
280
+ 'type' => 'colorpicker',
281
+ 'description' => esc_html__(
282
+ 'Choose a color for the submit button background.',
283
+ 'constant-contact-forms'
284
+ ),
285
+ ) );
286
+ }
287
+
288
+ /**
289
+ * Metabox for user to set custom CSS for a form.
290
+ *
291
+ * @since 1.4.0
292
+ */
293
+ public function custom_input_css_metabox() {
294
+ $custom_css_metabox = new_cmb2_box( array(
295
+ 'id' => 'ctct_1_custom_input_css_metabox',
296
+ 'title' => __( 'Input Design', 'constant-contact-forms' ),
297
+ 'object_types' => array( 'ctct_forms' ),
298
+ 'context' => 'side',
299
+ 'priority' => 'low',
300
+ ) );
301
+
302
+ $custom_css_metabox->add_field( array(
303
+ 'name' => esc_html__( 'Form Padding', 'constant-contact-forms' ),
304
+ 'type' => 'title',
305
+ 'id' => 'form-padding-title',
306
+ 'description' => esc_html__(
307
+ 'Enter padding values in number of pixels. Padding will be applied to four sides of the form.',
308
+ 'constant-contact-form' ),
309
+ ) );
310
+
311
+ $custom_css_metabox->add_field( array(
312
+ 'name' => __( 'Top', 'constant-contact-forms' ),
313
+ 'id' => $this->prefix . 'form_padding_top',
314
+ 'type' => 'text_small',
315
+ 'show_names' => true,
316
+ 'attributes' => array(
317
+ 'type' => 'number',
318
+ ),
319
+ ) );
320
+
321
+ $custom_css_metabox->add_field( array(
322
+ 'name' => __( 'Right', 'constant-contact-forms' ),
323
+ 'id' => $this->prefix . 'form_padding_right',
324
+ 'type' => 'text_small',
325
+ 'show_names' => true,
326
+ 'attributes' => array(
327
+ 'type' => 'number',
328
+ ),
329
+ ) );
330
+
331
+ $custom_css_metabox->add_field( array(
332
+ 'name' => __( 'Bottom', 'constant-contact-forms' ),
333
+ 'id' => $this->prefix . 'form_padding_bottom',
334
+ 'type' => 'text_small',
335
+ 'show_names' => true,
336
+ 'attributes' => array(
337
+ 'type' => 'number',
338
+ ),
339
+ ) );
340
+
341
+ $custom_css_metabox->add_field( array(
342
+ 'name' => __( 'Left', 'constant-contact-forms' ),
343
+ 'id' => $this->prefix . 'form_padding_left',
344
+ 'type' => 'text_small',
345
+ 'show_names' => true,
346
+ 'attributes' => array(
347
+ 'type' => 'number',
348
+ ),
349
+ ) );
350
+
351
+ $custom_css_metabox->add_field( array(
352
+ 'name' => __( 'Custom Classes', 'constant-contact-forms' ),
353
+ 'id' => $this->prefix . 'input_custom_classes',
354
+ 'type' => 'text',
355
+ 'description' => esc_html__(
356
+ 'Set custom CSS class(es) for inputs. Separate multiple classes with spaces.',
357
+ 'constant-contact-forms'
358
+ ),
359
+ ) );
360
+
361
+ $custom_css_metabox->add_field( array(
362
+ 'name' => __( 'Label Placement', 'constant-contact-forms' ),
363
+ 'id' => $this->prefix . 'form_label_placement',
364
+ 'type' => 'select',
365
+ 'show_option_none' => 'Global',
366
+ 'options' => array(
367
+ 'top' => 'Top',
368
+ 'left' => 'Left',
369
+ 'bottom' => 'Bottom',
370
+ 'right' => 'Right',
371
+ ),
372
+ 'description' => esc_html__(
373
+ 'Set the position for labels for inputs.',
374
+ 'constant-contact-forms'
375
+ ),
376
+ ) );
377
+ }
378
+
379
  /**
380
  * Helper method to show our connected optin fields.
381
  *
470
  $business_name ? ( $business_name ) : __( 'Your Business Name', 'constant-contact-forms' );
471
 
472
  $options_metabox->add_field( array(
473
+ 'name' => __( 'Opt-in Affirmation', 'constant-contact-forms' ),
474
+ 'id' => $this->prefix . 'opt_in_instructions',
475
+ 'type' => 'textarea_small',
476
  // translators: placeholder has a business name from Constant Contact.
477
+ 'default' => sprintf( __( 'Example: Yes, I would like to receive emails from %s. (You can unsubscribe anytime)', 'constant-contact-forms' ), $business_name ),
478
  ) );
479
  }
480
 
682
  ),
683
  ) );
684
  }
685
+
686
+ /**
687
+ * Add a metabox for customizing destination email for a given form.
688
+ *
689
+ * @since 1.4.0
690
+ */
691
+ public function email_settings() {
692
+
693
+ $email_settings = new_cmb2_box( array(
694
+ 'id' => 'email_settings',
695
+ 'title' => esc_html__( 'Email settings', 'constant-contact-forms' ),
696
+ 'object_types' => array( 'ctct_forms' ),
697
+ 'context' => 'side',
698
+ 'priority' => 'low',
699
+ ) );
700
+
701
+ $email_settings->add_field( array(
702
+ 'name' => esc_html__( 'Email destination', 'constant-contact-forms' ),
703
+ 'desc' => esc_html__( 'Who should receive email notifications for this form. Separate multiple emails by a comma. Leave blank to default to admin email.', 'constant-contact-forms' ),
704
+ 'id' => $this->prefix . 'email_settings',
705
+ 'type' => 'text_medium',
706
+ ) );
707
+
708
+ $email_settings->add_field( array(
709
+ 'name' => esc_html__( 'Disable email notifications for this form?', 'constant-contact-forms' ),
710
+ 'desc' => esc_html__( 'Check this option to disable emails for this Constant Contact Forms form.', 'constant-contact-forms' ),
711
+ 'id' => $this->prefix . 'disable_emails_for_form',
712
+ 'type' => 'checkbox',
713
+ ) );
714
+ }
715
  }
includes/class-builder.php CHANGED
@@ -117,7 +117,7 @@ class ConstantContact_Builder {
117
  public function add_form_css() {
118
 
119
  // Let's style this thing
120
- wp_enqueue_style( 'constant-contact-forms' );
121
  }
122
 
123
  /**
117
  public function add_form_css() {
118
 
119
  // Let's style this thing
120
+ wp_enqueue_style( 'constant-contact-forms-admin' );
121
  }
122
 
123
  /**
includes/class-check.php CHANGED
@@ -162,7 +162,7 @@ class ConstantContact_Check {
162
 
163
  if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) {
164
  // translators: placeholder will be a timestamp for the current time.
165
- return sprintf( __( 'The DISABLE_WP_CRON constant is set to true as of %s. WP-Cron is disabled and will not run.', 'constant-contact-forms' ), current_time( 'm/d/Y g:i:s a' ) );
166
  }
167
 
168
  if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) {
162
 
163
  if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) {
164
  // translators: placeholder will be a timestamp for the current time.
165
+ return sprintf( __( 'The DISABLE_WP_CRON constant is set to true as of %s. WP-Cron is disabled and will not run.', 'constant-contact-forms' ), current_time( 'm/d/Y g:i:s a' ) ); // Both uses of current_time like this are valid.
166
  }
167
 
168
  if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) {
includes/class-connect.php CHANGED
@@ -158,20 +158,11 @@ class ConstantContact_Connect {
158
  */
159
  public function admin_page_display() {
160
 
161
- wp_register_style(
162
- 'constant_contact_admin_global_no_connection',
163
- constant_contact()->url() . 'assets/css/admin-global-no-connection.css',
164
- array(),
165
- Constant_Contact::VERSION
166
- );
167
-
168
- wp_enqueue_style( 'constant_contact_admin_global_no_connection' );
169
-
170
  if ( ! current_user_can( 'manage_options' ) ) {
171
  return false;
172
  }
173
 
174
- wp_enqueue_style( 'constant-contact-oath', constant_contact()->url() . 'assets/css/oath.css' );
175
 
176
  wp_localize_script( 'ctct_form', 'ctct_texts', array( 'disconnectconfirm' => __( 'Are you sure you want to disconnect?', 'constant-contact-forms' ) ) );
177
 
158
  */
159
  public function admin_page_display() {
160
 
 
 
 
 
 
 
 
 
 
161
  if ( ! current_user_can( 'manage_options' ) ) {
162
  return false;
163
  }
164
 
165
+ wp_enqueue_style( 'constant-contact-forms-admin' );
166
 
167
  wp_localize_script( 'ctct_form', 'ctct_texts', array( 'disconnectconfirm' => __( 'Are you sure you want to disconnect?', 'constant-contact-forms' ) ) );
168
 
includes/class-cpts.php CHANGED
@@ -307,7 +307,7 @@ class ConstantContact_CPTS {
307
  $title = ( $form->post_title ) ? $form->post_title : __( 'No title', 'constant-contact-forms' );
308
 
309
  // Get the last modified time in human text.
310
- $last_modified = human_time_diff( strtotime( $form->post_modified ), time() );
311
 
312
  // Build up our title for the shortcode form admin.
313
  $title = sprintf(
307
  $title = ( $form->post_title ) ? $form->post_title : __( 'No title', 'constant-contact-forms' );
308
 
309
  // Get the last modified time in human text.
310
+ $last_modified = human_time_diff( strtotime( $form->post_modified ), current_time( 'timestamp' ) );
311
 
312
  // Build up our title for the shortcode form admin.
313
  $title = sprintf(
includes/class-display-shortcode.php CHANGED
@@ -44,7 +44,7 @@ class ConstantContact_Display_Shortcode {
44
  }
45
 
46
  /**
47
- * Acts as a wrapper so our shortcode class doesnt have to do this.
48
  *
49
  * @since 1.0.0
50
  *
@@ -71,7 +71,7 @@ class ConstantContact_Display_Shortcode {
71
  */
72
  public function get_form( $form_id ) {
73
 
74
- // sanity check it
75
  $form_id = absint( $form_id );
76
  if ( ! $form_id ) {
77
  return '';
@@ -145,11 +145,11 @@ class ConstantContact_Display_Shortcode {
145
  * @param array $custom_fields Custom fields to parse through.
146
  * @param array $full_data Array of full data.
147
  * @param int $form_id Form ID.
148
- * @return string Form field markup.
149
  */
150
  public function get_field_values( $custom_fields, $full_data, $form_id ) {
151
 
152
- // Get all our data from our fields, while we unserialize them
153
  $fields = $this->generate_field_values_for_fields( maybe_unserialize( $custom_fields ) );
154
 
155
  // Now that we've finished checking all of our form fields, we'll
@@ -158,10 +158,10 @@ class ConstantContact_Display_Shortcode {
158
  $fields['options']['form_id'] = $form_id;
159
  }
160
 
161
- // add in our form description, if we have one
162
  $fields['options']['description'] = $this->get_nested_value_from_data( '_ctct_description', $full_data );
163
 
164
- // Get our optin data
165
  $fields['options']['optin'] = $this->generate_optin_data( $full_data );
166
 
167
  return $fields;
@@ -188,7 +188,7 @@ class ConstantContact_Display_Shortcode {
188
  // Loop through each of our fields.
189
  foreach ( $custom_fields as $key => $value ) {
190
 
191
- // Make sure we have the parts of our array that we expect
192
  if ( ! isset( $custom_fields ) || ! isset( $custom_fields[ $key ] ) ) {
193
  continue;
194
  }
@@ -203,7 +203,7 @@ class ConstantContact_Display_Shortcode {
203
  // Set our field description, if we can.
204
  $fields = $this->set_field( '_ctct_field_desc', 'description', $key, $fields, $custom_fields );
205
 
206
- // Set our field requirement, if we can. We do this by casting the results of our two checks to a boolean
207
  $fields['fields'][ $key ]['required'] = (
208
  isset( $custom_fields[ $key ]['_ctct_required_field'] ) &&
209
  'on' === $custom_fields[ $key ]['_ctct_required_field']
44
  }
45
 
46
  /**
47
+ * Acts as a wrapper so our shortcode class doesn't have to do this.
48
  *
49
  * @since 1.0.0
50
  *
71
  */
72
  public function get_form( $form_id ) {
73
 
74
+ // Sanity check it.
75
  $form_id = absint( $form_id );
76
  if ( ! $form_id ) {
77
  return '';
145
  * @param array $custom_fields Custom fields to parse through.
146
  * @param array $full_data Array of full data.
147
  * @param int $form_id Form ID.
148
+ * @return array Form field markup.
149
  */
150
  public function get_field_values( $custom_fields, $full_data, $form_id ) {
151
 
152
+ // Get all our data from our fields, while we unserialize them.
153
  $fields = $this->generate_field_values_for_fields( maybe_unserialize( $custom_fields ) );
154
 
155
  // Now that we've finished checking all of our form fields, we'll
158
  $fields['options']['form_id'] = $form_id;
159
  }
160
 
161
+ // add in our form description, if we have one.
162
  $fields['options']['description'] = $this->get_nested_value_from_data( '_ctct_description', $full_data );
163
 
164
+ // Get our optin data.
165
  $fields['options']['optin'] = $this->generate_optin_data( $full_data );
166
 
167
  return $fields;
188
  // Loop through each of our fields.
189
  foreach ( $custom_fields as $key => $value ) {
190
 
191
+ // Make sure we have the parts of our array that we expect.
192
  if ( ! isset( $custom_fields ) || ! isset( $custom_fields[ $key ] ) ) {
193
  continue;
194
  }
203
  // Set our field description, if we can.
204
  $fields = $this->set_field( '_ctct_field_desc', 'description', $key, $fields, $custom_fields );
205
 
206
+ // Set our field requirement, if we can. We do this by casting the results of our two checks to a boolean.
207
  $fields['fields'][ $key ]['required'] = (
208
  isset( $custom_fields[ $key ]['_ctct_required_field'] ) &&
209
  'on' === $custom_fields[ $key ]['_ctct_required_field']
includes/class-display.php CHANGED
@@ -21,6 +21,22 @@ class ConstantContact_Display {
21
  */
22
  protected $plugin = null;
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  /**
25
  * Constructor.
26
  *
@@ -30,18 +46,21 @@ class ConstantContact_Display {
30
  */
31
  public function __construct( $plugin ) {
32
  $this->plugin = $plugin;
 
 
33
  }
34
 
35
  /**
36
  * Scripts.
37
  *
38
  * @since 1.0.0
 
39
  *
40
  * @param bool $enqueue Set true to enqueue the scripts after registering.
41
  */
42
  public function scripts( $enqueue = false ) {
43
 
44
- $debug = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG === true ? true : false;
45
  $suffix = ( true === $debug ) ? '' : '.min';
46
 
47
  wp_register_script(
@@ -52,29 +71,131 @@ class ConstantContact_Display {
52
  true
53
  );
54
 
55
- if ( $enqueue ) {
56
- wp_enqueue_script( 'ctct_frontend_forms' );
57
- }
58
  }
59
 
60
  /**
61
- * Register and (maybe) enqueue styles.
62
  *
63
  * @since 1.0.0
 
64
  *
65
  * @param bool $enqueue Set true to enqueue the scripts after registering.
66
  */
67
  public function styles( $enqueue = false ) {
68
- wp_register_style(
69
- 'ctct_form_styles',
70
- constant_contact()->url() . 'assets/css/style.css',
71
- array(),
72
- Constant_Contact::VERSION
 
 
 
 
 
 
 
 
 
73
  );
74
 
75
- if ( $enqueue ) {
76
- wp_enqueue_style( 'ctct_form_styles' );
 
 
 
77
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  }
79
 
80
  /**
@@ -93,14 +214,8 @@ class ConstantContact_Display {
93
  return '';
94
  }
95
 
96
- // Enqueue some things.
97
- if ( ! $skip_styles ) {
98
- $this->styles( true );
99
- $this->scripts( true );
100
- } else {
101
- $this->scripts();
102
- }
103
-
104
  $return = '';
105
  $form_err_display = '';
106
  $error_message = false;
@@ -120,7 +235,7 @@ class ConstantContact_Display {
120
  // Check to see if we got a response, and if it has the fields we expect.
121
  if ( $response && isset( $response['message'] ) && isset( $response['status'] ) ) {
122
 
123
- // If we were succesful, then display success message.
124
  if ( 'success' === $response['status'] ) {
125
 
126
  // If we were successful, we'll return here so we don't display the entire form again.
@@ -129,9 +244,9 @@ class ConstantContact_Display {
129
  } else {
130
 
131
  // If we didn't get a success message, then we want to error.
132
- // We already checked for a messsage response, but we'll force the
133
  // status to error if we're not here.
134
- $status = 'error';
135
  $error_message = trim( $response['message'] );
136
  }
137
  }
@@ -159,9 +274,37 @@ class ConstantContact_Display {
159
  $form_action = apply_filters( 'constant_contact_front_form_action', '', $form_id );
160
  $should_do_ajax = get_post_meta( $form_id, '_ctct_do_ajax', true );
161
  $do_ajax = ( 'on' === $should_do_ajax ) ? $should_do_ajax : 'off';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163
  // Build out our form.
164
- $return .= '<form class="ctct-form ctct-form-' . $form_id . '" id="' . $rf_id . '" data-doajax="' . esc_attr( $do_ajax ) . '" action="' . esc_attr( $form_action ) . '" method="post">';
 
 
 
 
165
 
166
  // If we have errors, display them.
167
  $return .= $form_err_display;
@@ -194,6 +337,18 @@ class ConstantContact_Display {
194
 
195
  $return .= '</form>';
196
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  $return .= '<script type="text/javascript">';
198
  $return .= 'var ajaxurl = "' . esc_url( admin_url( 'admin-ajax.php' ) ) . '";';
199
  $return .= '</script>';
@@ -286,8 +441,8 @@ class ConstantContact_Display {
286
  public function build_form_fields( $form_data, $old_values, $req_errors ) {
287
 
288
  // Start our wrapper return var.
289
- $return = '';
290
- $form_id = 0;
291
 
292
  // Check to see if we have a form ID for the form, and display our description.
293
  if ( isset( $form_data['options'] ) && isset( $form_data['options']['form_id'] ) ) {
@@ -295,16 +450,21 @@ class ConstantContact_Display {
295
  // Get our description.
296
  $desc = isset( $form_data['options']['description'] ) ? $form_data['options']['description'] : '';
297
 
298
- // Clean our form ID.
299
- $form_id = absint( $form_data['options']['form_id'] );
300
-
301
- // Add in our Description.
302
  $return .= $this->description( $desc, $form_id );
 
303
  }
304
 
305
- // Loop through each of our form fields and output it.
306
- foreach ( $form_data['fields'] as $key => $value ) {
307
- $return .= $this->field( $value, $old_values, $req_errors, $form_id );
 
 
 
 
 
 
 
308
  }
309
 
310
  // Check to see if we have an opt-in for the form, and display it.
@@ -335,7 +495,7 @@ class ConstantContact_Display {
335
 
336
  public function build_recaptcha() {
337
  // If we've reached this point, we know we have our keys.
338
- $site_key = ctct_get_settings_option( '_ctct_recaptcha_site_key' );
339
 
340
  /**
341
  * Filters the language code to be used with Google reCAPTCHA.
@@ -360,7 +520,19 @@ class ConstantContact_Display {
360
  }
361
 
362
  public function build_timestamp() {
363
- return '<input type="hidden" name="ctct_time" value="' . time() . '" />';
 
 
 
 
 
 
 
 
 
 
 
 
364
  }
365
 
366
  /**
@@ -383,14 +555,16 @@ class ConstantContact_Display {
383
  * Wrapper for single field display.
384
  *
385
  * @since 1.0.0
 
386
  *
387
- * @param array $field Field data.
388
- * @param array $old_values Original values.
389
- * @param array $req_errors Errors.
390
- * @param int $form_id Current form ID.
 
391
  * @return string HTML markup
392
  */
393
- public function field( $field, $old_values = array(), $req_errors = array(), $form_id = 0 ) {
394
 
395
  // If we don't have a name or a mapping, it will be hard to do things.
396
  if ( ! isset( $field['name'] ) || ! isset( $field['map_to'] ) ) {
@@ -398,20 +572,21 @@ class ConstantContact_Display {
398
  }
399
 
400
  $field = wp_parse_args( $field, array(
401
- 'name' => '',
402
- 'map_to' => '',
403
- 'type' => '',
404
- 'description' => '',
405
- 'required' => false,
 
406
  ) );
407
 
408
  // Check all our data points.
409
- $name = sanitize_text_field( $field['name'] );
410
- $map = sanitize_text_field( $field['map_to'] );
411
- $desc = sanitize_text_field( isset( $field['description'] ) ? $field['description'] : '' );
412
- $type = sanitize_text_field( isset( $field['type'] ) ? $field['type'] : 'text_field' );
413
- $value = sanitize_text_field( isset( $field['value'] ) ? $field['value'] : false );
414
- $req = isset( $field['required'] ) ? $field['required'] : false;
415
 
416
  // We may have more than one of the same field in our array.
417
  // this makes sure we keep them unique when processing them.
@@ -439,7 +614,7 @@ class ConstantContact_Display {
439
 
440
  // Based on the error type, display an error.
441
  if ( 'invalid' === $error['error'] ) {
442
- $field_error .= __( 'Error: Please correct your entry.', 'constant-contact-forms' );
443
  } else {
444
  $field_error .= __( ' Error: Please fill out this field.', 'constant-contact-forms' );
445
  }
@@ -464,13 +639,13 @@ class ConstantContact_Display {
464
  case 'company':
465
  case 'website':
466
  case 'text_field':
467
- return $this->input( 'text', $name, $map, $value, $desc, $req, false, $field_error, $form_id );
468
  break;
469
  case 'custom_text_area':
470
- return $this->textarea( $name, $map, $value, $desc, $req, $field_error, 'maxlength="500"' );
471
  break;
472
  case 'email':
473
- return $this->input( 'email', $name, $map, $value, $desc, $req, false, $field_error );
474
  break;
475
  case 'hidden':
476
  return $this->input( 'hidden', $name, $map, $value, $desc, $req );
@@ -482,7 +657,7 @@ class ConstantContact_Display {
482
  return $this->input( 'submit', $name, $map, $value, $desc, $req, false, $field_error );
483
  break;
484
  case 'address':
485
- return $this->address( $name, $map, $value, $desc, $req, $field_error );
486
  break;
487
  case 'anniversery':
488
  case 'birthday':
@@ -502,7 +677,7 @@ class ConstantContact_Display {
502
  *
503
  * @param string|array $value Field value.
504
  * @param string $map Map value.
505
- * @param array $field Array of fields
506
  * @param array $submitted_vals Array of submitted values.
507
  * @return string Submitted value.
508
  */
@@ -591,6 +766,36 @@ class ConstantContact_Display {
591
  return '<p class="ctct-message ' . esc_attr( $type ) . '">' . esc_attr( $message ) . '</p>';
592
  }
593
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
594
  /**
595
  * Helper method to display form description.
596
  *
@@ -602,7 +807,8 @@ class ConstantContact_Display {
602
  */
603
  public function description( $desc = '', $form_id = false ) {
604
 
605
- $display = '';
 
606
 
607
  // If we have the permissions, also display an edit link.
608
  if ( current_user_can( 'edit_posts' ) && $form_id ) {
@@ -616,7 +822,7 @@ class ConstantContact_Display {
616
  }
617
  }
618
 
619
- return '<span class="ctct-form-description">' . wpautop( wp_kses_post( $desc ) ) . '</span>' . $display;
620
  }
621
 
622
  /**
@@ -624,32 +830,16 @@ class ConstantContact_Display {
624
  *
625
  * @since 1.0.0
626
  *
627
- * @param string $type Type of field.
628
- * @param string $name Name / id of field.
629
- * @param string $f_id Field ID.
630
- * @param string $label Label text for field.
631
- * @param boolean $req If this field required.
632
- * @param boolean $use_label Whether or not to use label.
633
  * @return string HTML markup.
634
  */
635
  public function field_top( $type = '', $name = '', $f_id = '', $label = '', $req = false, $use_label = true ) {
636
 
637
- // Set blank defaults for required info.
638
- $req_label = '';
639
-
640
- // If this is required, we output the HMTL5 required att.
641
- if ( $req ) {
642
-
643
- /**
644
- * Filters the markup used for the required indicator.
645
- *
646
- * @since 1.0.0
647
- *
648
- * @param string $value An `<abbr>` tag with an asterisk indicating required status.
649
- */
650
- $req_label = apply_filters( 'constant_contact_required_label', '<abbr title="required">*</abbr>' );
651
- }
652
-
653
  $classes = array(
654
  'ctct-form-field',
655
  'ctct-form-field-' . $type,
@@ -661,13 +851,6 @@ class ConstantContact_Display {
661
  // Start building our return markup.
662
  $markup = '<p class="' . implode( ' ', $classes ) . '">';
663
 
664
- // Allow skipping label, also don't show for submit buttons.
665
- if ( $use_label && ( 'submit' !== $type ) && ( 'hidden' !== $type ) ) {
666
-
667
- // Our field label will be the form name + required asterisk + our label.
668
- $markup .= $this->get_label( $f_id, $name . ' ' . $req_label );
669
- }
670
-
671
  // If we're not on submit or hidden, but still doing label on bottom,
672
  // then output a container div.
673
  if ( ! $use_label ) {
@@ -703,6 +886,40 @@ class ConstantContact_Display {
703
  return $markup . '</p>';
704
  }
705
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
706
  /**
707
  * Helper method to get form label.
708
  *
@@ -721,32 +938,67 @@ class ConstantContact_Display {
721
  *
722
  * @since 1.0.0
723
  *
724
- * @param string $type Type of form field.
725
- * @param string $name ID of form field.
726
- * @param string $id ID attribute value.
727
- * @param string $value pre-filled value.
728
- * @param string $label label text for inpug.
729
- * @param boolean $req If field required.
730
- * @param boolean $f_only If we only return the field itself, with no label.
731
- * @param boolean $field_error Field error.
732
- * @param int $form_id Current form ID.
 
733
  * @return string HTML markup for field.
734
  */
735
- public function input( $type = 'text', $name = '', $id = '', $value = '', $label = '', $req = false, $f_only = false, $field_error = false, $form_id = 0 ) {
736
 
737
  // Sanitize our stuff / set values.
738
- $name = sanitize_text_field( $name );
739
- $f_id = sanitize_title( $id );
740
- $type = sanitize_text_field( $type );
741
- $value = sanitize_text_field( $value );
742
- $label = sanitize_text_field( $label );
 
 
 
 
 
 
 
 
 
743
  $req_text = $req ? 'required' : '';
744
 
745
  // Start our markup.
746
  $markup = $this->field_top( $type, $name, $f_id, $label, $req );
747
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
748
  // Provide some CSS class(es).
749
- $classes = array( 'ctct-' . esc_attr( $type ) );
 
 
 
 
 
750
 
751
  /**
752
  * Filter to add classes for the rendering input.
@@ -766,12 +1018,10 @@ class ConstantContact_Display {
766
  * @param bool $value Whether or not to truncate. Default false.
767
  */
768
  $truncate_max_length = apply_filters( 'constant_contact_include_custom_field_label', false, $form_id );
769
- $max_length = '';
770
  if ( false !== strpos( $id, 'custom___' ) ) {
771
  $max_length = ( $truncate_max_length ) ? $this->get_max_length_attr( $name ) : $this->get_max_length_attr();
772
  }
773
- // Set our field as as seprate var, because we allow for only returning that.
774
- $field = '<input ' . $req_text . ' type="' . $type . '" name="' . $f_id . '" id="' . $f_id . '" value="' . $value . '" ' . $max_length . ' placeholder="' . $label . '" ';
775
 
776
  // If we have an error.
777
  if ( $field_error ) {
@@ -779,16 +1029,35 @@ class ConstantContact_Display {
779
  $classes[] = 'ctct-invalid';
780
  }
781
 
 
782
  // Append classes to our field.
783
  if ( count( $classes ) ) {
784
- $field .= 'class="' . implode( ' ', $classes ) . '"';
785
  }
786
 
787
  // Finish the markup for our field itself.
788
- $field .= '/>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
789
 
790
- // Add our field to our markup.
791
- $markup .= $field;
 
 
 
792
 
793
  // If we got an error, add it to the bottom label.
794
  if ( $field_error ) {
@@ -839,7 +1108,7 @@ class ConstantContact_Display {
839
  */
840
  $classes = apply_filters( 'constant_contact_input_classes', $classes, $type );
841
 
842
- $markup = $this->field_top( $type, $name, $f_id, $label, false, false );
843
  $markup .= '<input type="' . $type . '" name="' . $f_id . '" id="' . $f_id . '" value="' . $value . '" class="' . implode( ' ', $classes ) . '" />';
844
  $markup .= $this->field_bottom( $name, ' ' . $label );
845
 
@@ -959,7 +1228,7 @@ class ConstantContact_Display {
959
  // If we aren't showing the field, then we default our checkbox to checked.
960
  $checked = $show ? '' : 'checked';
961
 
962
- $markup = $this->field_top( 'checkbox', 'ctct-opt-in', 'ctct-opt-in', $label, false, false );
963
  $markup .= '<input type="checkbox" ' . $checked . ' name="ctct-opt-in" id="ctct-opt-in" class="ctct-checkbox ctct-opt-in" value="' . $value . '" />';
964
  $markup .= $this->field_bottom( 'ctct-opt-in', ' ' . wp_kses_post( $label ), false );
965
 
@@ -971,15 +1240,16 @@ class ConstantContact_Display {
971
  *
972
  * @since 1.0.0
973
  *
974
- * @param string $name Name of fields.
975
- * @param string $f_id Form ID name.
976
- * @param array $value Values of each field.
977
- * @param string $desc Label of field.
978
- * @param boolean $req Whether or not required.
979
- * @param string $field_error Field error value.
 
980
  * @return string field HTML markup.
981
  */
982
- public function address( $name = '', $f_id = '', $value = array(), $desc = '', $req = false, $field_error = '' ) {
983
 
984
  // Set up our text strings.
985
  $street = __( 'Street Address', 'constant-contact-forms' );
@@ -1002,37 +1272,149 @@ class ConstantContact_Display {
1002
  *
1003
  * @param string $value An `<abbr>` tag with an asterisk indicating required status.
1004
  */
1005
- $req_label = $req ? ' ' . apply_filters( 'constant_contact_required_label', '<abbr title="required">*</abbr>' ) : '';
1006
- $req_class = $req ? ' ctct-form-field-required ' : '';
1007
- $req = $req ? ' required ' : '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1008
 
1009
- // Build our field.
1010
- $return = '<fieldset class="ctct-address">';
1011
- $return .= ' <legend>' . esc_attr( $name ) . '</legend>';
1012
- $return .= ' <div class="ctct-form-field ctct-field-full address-line-1' . $req_class . '">';
1013
- $return .= ' <label for="street_' . esc_attr( $f_id ) . '">' . esc_attr( $street ) . $req_label . '</label>';
1014
- $return .= ' <input ' . $req . 'type="text" class="ctct-text ctct-address-street" name="street_' . esc_attr( $f_id ) . '" id="street_' . esc_attr( $f_id ) . '" value="' . esc_attr( $v_street ) . '">';
1015
- $return .= ' </div>';
 
 
 
 
 
 
 
1016
  // Address Line 2 is not required, note the missing $req inclusion.
1017
- $return .= ' <div class="ctct-form-field ctct-field-full address-line-2' . $req_class . '" id="input_2_1_2_container">';
1018
- $return .= ' <label for="line_2_' . esc_attr( $f_id ) . '">' . esc_attr( $line_2 ) . '</label>';
1019
- $return .= ' <input type="text" class="ctct-text ctct-address-line-2" name="line_2_' . esc_attr( $f_id ) . '" id="line_2_' . esc_attr( $f_id ) . '" value="' . esc_attr( $v_line_2 ) . '">';
1020
- $return .= ' </div>';
1021
- $return .= ' <div class="ctct-form-field ctct-field-third address-city' . $req_class . '" id="input_2_1_3_container">';
1022
- $return .= ' <label for="city_' . esc_attr( $f_id ) . '">' . esc_attr( $city ) . $req_label . '</label>';
1023
- $return .= ' <input ' . $req . 'type="text" class="ctct-text ctct-address-city" name="city_' . esc_attr( $f_id ) . '" id="city_' . esc_attr( $f_id ) . '" value="' . esc_attr( $v_city ) . '">';
1024
- $return .= ' </div>';
1025
- $return .= ' <div class="ctct-form-field ctct-field-third address-state' . $req_class . '" id="input_2_1_4_container">';
1026
- $return .= ' <label for="state_' . esc_attr( $f_id ) . '">' . esc_attr( $state ) . $req_label . '</label>';
1027
- $return .= ' <input ' . $req . 'type="text" class="ctct-text ctct-address-state" name="state_' . esc_attr( $f_id ) . '" id="state_' . esc_attr( $f_id ) . '" value="' . esc_attr( $v_state ) . '">';
1028
- $return .= ' </div>';
1029
- $return .= ' <div class="ctct-form-field ctct-field-third address-zip' . $req_class . '" id="input_2_1_5_container">';
1030
- $return .= ' <label for="zip_' . esc_attr( $f_id ) . '">' . esc_attr( $zip ) . $req_label . '</label>';
1031
- $return .= ' <input ' . $req . 'type="text" class="ctct-text ctct-address-zip" name="zip_' . esc_attr( $f_id ) . '" id="zip_' . esc_attr( $f_id ) . '" value="' . esc_attr( $v_zip ) . '">';
1032
- $return .= ' </div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1033
  $return .= '</fieldset>';
1034
 
1035
- return $return;
 
 
 
 
 
 
 
 
 
 
 
 
 
1036
  }
1037
 
1038
  /**
@@ -1256,23 +1638,28 @@ class ConstantContact_Display {
1256
  *
1257
  * @since 1.0.0
1258
  *
1259
- * @param string $name Name of field.
1260
- * @param string $map ID of field.
1261
- * @param string $value Previous value of field.
1262
- * @param string $desc Description/label of field.
1263
- * @param boolean $req If is required.
1264
- * @param string $field_error Error from field.
1265
- * @param string $extra_attrs Extra attributes to append.
 
1266
  * @return string HTML markup.
1267
  */
1268
- public function textarea( $name = '', $map = '', $value = '', $desc = '', $req = false, $field_error = '', $extra_attrs = '' ) {
 
 
 
1269
 
1270
- $classes = array( 'ctct-form-field' );
1271
  // Set our required text.
1272
  $req_text = $req ? 'required' : '';
1273
  if ( $req ) {
1274
  $classes[] = 'ctct-form-field-required';
1275
  }
 
 
1276
 
1277
  // If required, get our label.
1278
  $req_label = '';
@@ -1288,9 +1675,16 @@ class ConstantContact_Display {
1288
  $req_label = apply_filters( 'constant_contact_required_label', '<abbr title="required">*</abbr>' );
1289
  }
1290
 
1291
- $return = '<p class="' . implode( ' ', $classes ) . '"><label for="' . esc_attr( $map ) . '">' . esc_attr( $name ) . ' ' . $req_label . '</label>';
1292
- $return .= '<textarea class="ctct-textarea" ' . $req_text . ' name="' . esc_attr( $map ) . '" placeholder="' . esc_attr( $desc ) . '" ' . $extra_attrs . '>' . esc_html( $value ) . '</textarea>';
 
1293
 
 
 
 
 
 
 
1294
  if ( $field_error ) {
1295
  $return .= '<span class="ctct-field-error"><label for="' . esc_attr( $map ) . '">' . esc_attr( __( 'Error: Please correct your entry.', 'constant-contact-forms' ) ) . '</label></span>';
1296
  }
@@ -1299,7 +1693,7 @@ class ConstantContact_Display {
1299
  }
1300
 
1301
  /**
1302
- * Maybe display the disclourse notice.
1303
  *
1304
  * @since 1.0.0
1305
  *
@@ -1381,5 +1775,7 @@ class ConstantContact_Display {
1381
  }
1382
  return 'maxlength="' . $length . '"';
1383
  }
 
 
1384
  }
1385
 
21
  */
22
  protected $plugin = null;
23
 
24
+ /**
25
+ * The global custom styles.
26
+ *
27
+ * @since 1.4.0
28
+ * @var array
29
+ */
30
+ protected $global_form_styles = array();
31
+
32
+ /**
33
+ * Styles set for a particular form.
34
+ *
35
+ * @since 1.4.0
36
+ * @var array
37
+ */
38
+ protected $specific_form_styles = array();
39
+
40
  /**
41
  * Constructor.
42
  *
46
  */
47
  public function __construct( $plugin ) {
48
  $this->plugin = $plugin;
49
+ add_action( 'wp_enqueue_scripts', array( $this, 'scripts' ) );
50
+ add_action( 'wp_enqueue_scripts', array( $this, 'styles' ) );
51
  }
52
 
53
  /**
54
  * Scripts.
55
  *
56
  * @since 1.0.0
57
+ * @since 1.4.0 Deprecated parameter.
58
  *
59
  * @param bool $enqueue Set true to enqueue the scripts after registering.
60
  */
61
  public function scripts( $enqueue = false ) {
62
 
63
+ $debug = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG === true ? true : false;
64
  $suffix = ( true === $debug ) ? '' : '.min';
65
 
66
  wp_register_script(
71
  true
72
  );
73
 
74
+ wp_enqueue_script( 'ctct_frontend_forms' );
 
 
75
  }
76
 
77
  /**
78
+ * Enqueue styles.
79
  *
80
  * @since 1.0.0
81
+ * @since 1.4.0 Deprecated parameter.
82
  *
83
  * @param bool $enqueue Set true to enqueue the scripts after registering.
84
  */
85
  public function styles( $enqueue = false ) {
86
+ wp_enqueue_style( 'ctct_form_styles' );
87
+ }
88
+
89
+ /**
90
+ * Retrieve the styles set globally for forms.
91
+ *
92
+ * @since 1.4.0
93
+ * @author Scott Tirrell
94
+ */
95
+ public function set_global_form_css() {
96
+
97
+ $defaults = array(
98
+ 'global_form_classes' => '',
99
+ 'global_label_placement' => '',
100
  );
101
 
102
+ $global_form_css = array();
103
+
104
+ $global_form_classes = ctct_get_settings_option( '_ctct_form_custom_classes' );
105
+ if ( $global_form_classes ) {
106
+ $global_form_css['global_form_classes'] = $global_form_classes;
107
  }
108
+
109
+ $global_label_placement = ctct_get_settings_option( 'ctct_form_label_placement' );
110
+ if ( $global_label_placement ) {
111
+ $global_form_css['global_label_placement'] = $global_label_placement;
112
+ }
113
+
114
+ $this->global_form_styles = wp_parse_args( $global_form_css, $defaults );
115
+
116
+ }
117
+
118
+ /**
119
+ * Retrieve the styles set for a specific form.
120
+ *
121
+ * @param int $form_id The id of the form.
122
+ *
123
+ * @since 1.4.0
124
+ * @author Scott Tirrell
125
+ */
126
+ public function set_specific_form_css( $form_id ) {
127
+ $defaults = array(
128
+ 'form_background_color' => '',
129
+ 'form_description_font_size' => '',
130
+ 'form_description_color' => '',
131
+ 'form_submit_button_font_size' => '',
132
+ 'form_submit_button_text_color' => '',
133
+ 'form_submit_button_background_color' => '',
134
+ 'form_padding_top' => '',
135
+ 'form_padding_right' => '',
136
+ 'form_padding_bottom' => '',
137
+ 'form_padding_left' => '',
138
+ 'input_custom_classes' => '',
139
+ );
140
+
141
+ $specific_form_css = array();
142
+
143
+ $ctct_form_background_color = get_post_meta( $form_id, '_ctct_form_background_color', true );
144
+ if ( ! empty( $ctct_form_background_color ) ) {
145
+ $specific_form_css['form_background_color'] = "background-color: {$ctct_form_background_color};";
146
+ }
147
+
148
+ $ctct_form_description_font_size = get_post_meta( $form_id, '_ctct_form_description_font_size', true );
149
+ if ( ! empty( $ctct_form_description_font_size ) ) {
150
+ $specific_form_css['form_description_font_size'] = "font-size: {$ctct_form_description_font_size};";
151
+ }
152
+
153
+ $ctct_form_description_color = get_post_meta( $form_id, '_ctct_form_description_color', true );
154
+ if ( ! empty( $ctct_form_description_color ) ) {
155
+ $specific_form_css['form_description_color'] = "color: {$ctct_form_description_color};";
156
+ }
157
+
158
+ $ctct_form_submit_button_font_size = get_post_meta( $form_id, '_ctct_form_submit_button_font_size', true );
159
+ if ( ! empty( $ctct_form_submit_button_font_size ) ) {
160
+ $specific_form_css['form_submit_button_font_size'] = "font-size: {$ctct_form_submit_button_font_size};";
161
+ }
162
+
163
+ $ctct_form_submit_button_text_color = get_post_meta( $form_id, '_ctct_form_submit_button_text_color', true );
164
+ if ( ! empty( $ctct_form_submit_button_text_color ) ) {
165
+ $specific_form_css['form_submit_button_text_color'] = "color: {$ctct_form_submit_button_text_color};";
166
+ }
167
+
168
+ $ctct_form_submit_button_background_color = get_post_meta( $form_id, '_ctct_form_submit_button_background_color', true );
169
+ if ( ! empty( $ctct_form_submit_button_background_color ) ) {
170
+ $specific_form_css['form_submit_button_background_color'] = "background-color: {$ctct_form_submit_button_background_color};";
171
+ }
172
+
173
+ $ctct_form_padding_top = get_post_meta( $form_id, '_ctct_form_padding_top', true );
174
+ if ( ! empty( $ctct_form_padding_top ) ) {
175
+ $specific_form_css['form_padding_top'] = "padding-top: {$ctct_form_padding_top}px;";
176
+ }
177
+
178
+ $ctct_form_padding_right = get_post_meta( $form_id, '_ctct_form_padding_right', true );
179
+ if ( ! empty( $ctct_form_padding_right ) ) {
180
+ $specific_form_css['form_padding_right'] = "padding-right: {$ctct_form_padding_right}px;";
181
+ }
182
+
183
+ $ctct_form_padding_bottom = get_post_meta( $form_id, '_ctct_form_padding_bottom', true );
184
+ if ( ! empty( $ctct_form_padding_bottom ) ) {
185
+ $specific_form_css['form_padding_bottom'] = "padding-bottom: {$ctct_form_padding_bottom}px;";
186
+ }
187
+
188
+ $ctct_form_padding_left = get_post_meta( $form_id, '_ctct_form_padding_left', true );
189
+ if ( ! empty( $ctct_form_padding_left ) ) {
190
+ $specific_form_css['form_padding_left'] = "padding-left: {$ctct_form_padding_left}px;";
191
+ }
192
+
193
+ $ctct_input_custom_classes = get_post_meta( $form_id, '_ctct_input_custom_classes', true );
194
+ if ( ! empty( $ctct_input_custom_classes ) ) {
195
+ $specific_form_css['input_custom_classes'] = esc_attr( $ctct_input_custom_classes );
196
+ }
197
+
198
+ $this->specific_form_styles = wp_parse_args( $specific_form_css, $defaults );
199
  }
200
 
201
  /**
214
  return '';
215
  }
216
 
217
+ $this->set_global_form_css();
218
+ $this->set_specific_form_css( $form_id );
 
 
 
 
 
 
219
  $return = '';
220
  $form_err_display = '';
221
  $error_message = false;
235
  // Check to see if we got a response, and if it has the fields we expect.
236
  if ( $response && isset( $response['message'] ) && isset( $response['status'] ) ) {
237
 
238
+ // If we were successful, then display success message.
239
  if ( 'success' === $response['status'] ) {
240
 
241
  // If we were successful, we'll return here so we don't display the entire form again.
244
  } else {
245
 
246
  // If we didn't get a success message, then we want to error.
247
+ // We already checked for a message response, but we'll force the
248
  // status to error if we're not here.
249
+ $status = 'error';
250
  $error_message = trim( $response['message'] );
251
  }
252
  }
274
  $form_action = apply_filters( 'constant_contact_front_form_action', '', $form_id );
275
  $should_do_ajax = get_post_meta( $form_id, '_ctct_do_ajax', true );
276
  $do_ajax = ( 'on' === $should_do_ajax ) ? $should_do_ajax : 'off';
277
+ $form_classes = 'ctct-form ctct-form-' . $form_id;
278
+ $form_classes .= $this->build_custom_form_classes();
279
+
280
+ $form_styles = '';
281
+ if ( ! empty( $this->specific_form_styles['form_background_color'] ) ) {
282
+ $form_styles = $this->specific_form_styles['form_background_color'];
283
+ }
284
+
285
+ foreach( ['bottom','left','right','top'] as $pos ) {
286
+ $form_styles .= $this->specific_form_styles[ 'form_padding_' . $pos ];
287
+ }
288
+
289
+ // Add action before form for custom actions.
290
+ ob_start();
291
+ /**
292
+ * Fires before the start of the form tag.
293
+ *
294
+ * @since 1.4.0
295
+ *
296
+ * @param int $form_id Current form ID.
297
+ */
298
+ do_action( 'ctct_before_form', $form_id );
299
+ $return .= ob_get_contents();
300
+ ob_end_clean();
301
 
302
  // Build out our form.
303
+ $return .= '<form class="' . esc_attr( $form_classes ) . '" id="' . $rf_id . '" ';
304
+ $return .= 'data-doajax="' . esc_attr( $do_ajax ) . '" ';
305
+ $return .= 'style="' . esc_attr( $form_styles ) . '" ';
306
+ $return .= 'action="' . esc_attr( $form_action ) . '" ';
307
+ $return .= 'method="post">';
308
 
309
  // If we have errors, display them.
310
  $return .= $form_err_display;
337
 
338
  $return .= '</form>';
339
 
340
+ ob_start();
341
+ /**
342
+ * Fires after the end of the form tag.
343
+ *
344
+ * @since 1.4.0
345
+ *
346
+ * @param int $form_id Current form ID.
347
+ */
348
+ do_action( 'ctct_after_form', $form_id );
349
+ $return .= ob_get_contents();
350
+ ob_end_clean();
351
+
352
  $return .= '<script type="text/javascript">';
353
  $return .= 'var ajaxurl = "' . esc_url( admin_url( 'admin-ajax.php' ) ) . '";';
354
  $return .= '</script>';
441
  public function build_form_fields( $form_data, $old_values, $req_errors ) {
442
 
443
  // Start our wrapper return var.
444
+ $return = '';
445
+ $form_id = absint( $form_data['options']['form_id'] );
446
 
447
  // Check to see if we have a form ID for the form, and display our description.
448
  if ( isset( $form_data['options'] ) && isset( $form_data['options']['form_id'] ) ) {
450
  // Get our description.
451
  $desc = isset( $form_data['options']['description'] ) ? $form_data['options']['description'] : '';
452
 
453
+ // Get our Description.
 
 
 
454
  $return .= $this->description( $desc, $form_id );
455
+
456
  }
457
 
458
+ $label_placement = constant_contact_get_css_customization( $form_id, '_ctct_form_label_placement' );
459
+ if ( empty( $label_placement ) ) {
460
+ $label_placement = 'top';
461
+ }
462
+
463
+ if ( isset( $form_data['fields'] ) && is_array( $form_data['fields'] ) ) {
464
+ // Loop through each of our form fields and output it.
465
+ foreach ( $form_data['fields'] as $key => $value ) {
466
+ $return .= $this->field( $value, $old_values, $req_errors, $form_id, $label_placement );
467
+ }
468
  }
469
 
470
  // Check to see if we have an opt-in for the form, and display it.
495
 
496
  public function build_recaptcha() {
497
  // If we've reached this point, we know we have our keys.
498
+ $site_key = ctct_get_settings_option( '_ctct_recaptcha_site_key', '' );
499
 
500
  /**
501
  * Filters the language code to be used with Google reCAPTCHA.
520
  }
521
 
522
  public function build_timestamp() {
523
+ return '<input type="hidden" name="ctct_time" value="' . current_time( 'timestamp' ) . '" />';
524
+ }
525
+
526
+ public function build_custom_form_classes() {
527
+ $custom = '';
528
+ if ( ! empty( $this->global_form_styles['global_form_classes'] ) ) {
529
+ $custom .= ' ' . esc_attr( $this->global_form_styles['global_form_classes'] );
530
+ }
531
+ if ( ! empty( $this->specific_form_styles['input_custom_classes'] ) ) {
532
+ $custom .= ' ' . esc_attr( $this->specific_form_styles['input_custom_classes'] );
533
+ }
534
+
535
+ return $custom;
536
  }
537
 
538
  /**
555
  * Wrapper for single field display.
556
  *
557
  * @since 1.0.0
558
+ * @since 1.4.0 Added label placement parameter.
559
  *
560
+ * @param array $field Field data.
561
+ * @param array $old_values Original values.
562
+ * @param array $req_errors Errors.
563
+ * @param int $form_id Current form ID.
564
+ * @param string $label_placement Label placement location.
565
  * @return string HTML markup
566
  */
567
+ public function field( $field, $old_values = array(), $req_errors = array(), $form_id = 0, $label_placement = 'top' ) {
568
 
569
  // If we don't have a name or a mapping, it will be hard to do things.
570
  if ( ! isset( $field['name'] ) || ! isset( $field['map_to'] ) ) {
572
  }
573
 
574
  $field = wp_parse_args( $field, array(
575
+ 'name' => '',
576
+ 'map_to' => '',
577
+ 'type' => '',
578
+ 'description' => '',
579
+ 'field_custom_css' => array(),
580
+ 'required' => false,
581
  ) );
582
 
583
  // Check all our data points.
584
+ $name = sanitize_text_field( $field['name'] );
585
+ $map = sanitize_text_field( $field['map_to'] );
586
+ $desc = sanitize_text_field( isset( $field['description'] ) ? $field['description'] : '' );
587
+ $type = sanitize_text_field( isset( $field['type'] ) ? $field['type'] : 'text_field' );
588
+ $value = sanitize_text_field( isset( $field['value'] ) ? $field['value'] : false );
589
+ $req = isset( $field['required'] ) ? $field['required'] : false;
590
 
591
  // We may have more than one of the same field in our array.
592
  // this makes sure we keep them unique when processing them.
614
 
615
  // Based on the error type, display an error.
616
  if ( 'invalid' === $error['error'] ) {
617
+ $field_error .= __( 'Error: Please correct your entry.', 'constant-contact-forms' );
618
  } else {
619
  $field_error .= __( ' Error: Please fill out this field.', 'constant-contact-forms' );
620
  }
639
  case 'company':
640
  case 'website':
641
  case 'text_field':
642
+ return $this->input( 'text', $name, $map, $value, $desc, $req, false, $field_error, $form_id, $label_placement );
643
  break;
644
  case 'custom_text_area':
645
+ return $this->textarea( $name, $map, $value, $desc, $req, $field_error, 'maxlength="500"', $label_placement );
646
  break;
647
  case 'email':
648
+ return $this->input( 'email', $name, $map, $value, $desc, $req, false, $field_error, $form_id, $label_placement );
649
  break;
650
  case 'hidden':
651
  return $this->input( 'hidden', $name, $map, $value, $desc, $req );
657
  return $this->input( 'submit', $name, $map, $value, $desc, $req, false, $field_error );
658
  break;
659
  case 'address':
660
+ return $this->address( $name, $map, $value, $desc, $req, $field_error, $label_placement );
661
  break;
662
  case 'anniversery':
663
  case 'birthday':
677
  *
678
  * @param string|array $value Field value.
679
  * @param string $map Map value.
680
+ * @param array $field Array of fields.
681
  * @param array $submitted_vals Array of submitted values.
682
  * @return string Submitted value.
683
  */
766
  return '<p class="ctct-message ' . esc_attr( $type ) . '">' . esc_attr( $message ) . '</p>';
767
  }
768
 
769
+ /**
770
+ * Get an inline style tag to use for the form's description.
771
+ *
772
+ * @author Scott Tirrell
773
+ * @since 1.4.0
774
+ *
775
+ * @return string The inline style tag for the form's description.
776
+ */
777
+ public function get_description_inline_styles() {
778
+ $inline_style = '';
779
+ $styles = array();
780
+
781
+ // Set any custom CSS for the form description.
782
+ $specific_form_styles = $this->specific_form_styles;
783
+
784
+ if ( ! empty( $specific_form_styles['form_description_font_size'] ) ) {
785
+ $styles[] = $specific_form_styles['form_description_font_size'];
786
+ }
787
+
788
+ if ( ! empty( $specific_form_styles['form_description_color'] ) ) {
789
+ $styles[] = $specific_form_styles['form_description_color'];
790
+ }
791
+
792
+ if ( ! empty( $styles ) ) {
793
+ $inline_style = 'style="' . esc_attr( implode( ' ', $styles ) ) . '"';
794
+ }
795
+
796
+ return $inline_style;
797
+ }
798
+
799
  /**
800
  * Helper method to display form description.
801
  *
807
  */
808
  public function description( $desc = '', $form_id = false ) {
809
 
810
+ $display = '';
811
+ $inline_style = $this->get_description_inline_styles();
812
 
813
  // If we have the permissions, also display an edit link.
814
  if ( current_user_can( 'edit_posts' ) && $form_id ) {
822
  }
823
  }
824
 
825
+ return '<span class="ctct-form-description" ' . $inline_style . '>' . wpautop( wp_kses_post( $desc ) ) . '</span>' . $display;
826
  }
827
 
828
  /**
830
  *
831
  * @since 1.0.0
832
  *
833
+ * @param string $type Type of field.
834
+ * @param string $name Name / id of field.
835
+ * @param string $f_id Field ID.
836
+ * @param string $label Label text for field.
837
+ * @param boolean $req If this field required.
838
+ * @param boolean $use_label Whether or not to use label.
839
  * @return string HTML markup.
840
  */
841
  public function field_top( $type = '', $name = '', $f_id = '', $label = '', $req = false, $use_label = true ) {
842
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
843
  $classes = array(
844
  'ctct-form-field',
845
  'ctct-form-field-' . $type,
851
  // Start building our return markup.
852
  $markup = '<p class="' . implode( ' ', $classes ) . '">';
853
 
 
 
 
 
 
 
 
854
  // If we're not on submit or hidden, but still doing label on bottom,
855
  // then output a container div.
856
  if ( ! $use_label ) {
886
  return $markup . '</p>';
887
  }
888
 
889
+ /**
890
+ * Get inline styles for the form's submit button.
891
+ *
892
+ * @since 1.4.0
893
+ * @author Scott Tirrell
894
+ *
895
+ * @return string
896
+ */
897
+ public function get_submit_inline_styles() {
898
+ $inline_style = '';
899
+ $styles = array();
900
+
901
+ // Set any custom CSS for the form submit button.
902
+ $specific_form_styles = $this->specific_form_styles;
903
+
904
+ if ( ! empty( $specific_form_styles['form_submit_button_font_size'] ) ) {
905
+ $styles[] = $specific_form_styles['form_submit_button_font_size'];
906
+ }
907
+
908
+ if ( ! empty( $specific_form_styles['form_submit_button_text_color'] ) ) {
909
+ $styles[] = $specific_form_styles['form_submit_button_text_color'];
910
+ }
911
+
912
+ if ( ! empty( $specific_form_styles['form_submit_button_background_color'] ) ) {
913
+ $styles[] = $specific_form_styles['form_submit_button_background_color'];
914
+ }
915
+
916
+ if ( ! empty( $styles ) ) {
917
+ $inline_style = 'style="' . esc_attr( implode( ' ', $styles ) ) . '"';
918
+ }
919
+
920
+ return $inline_style;
921
+ }
922
+
923
  /**
924
  * Helper method to get form label.
925
  *
938
  *
939
  * @since 1.0.0
940
  *
941
+ * @param string $type Type of form field.
942
+ * @param string $name ID of form field.
943
+ * @param string $id ID attribute value.
944
+ * @param string $value pre-filled value.
945
+ * @param string $label label text for input.
946
+ * @param boolean $req If field required.
947
+ * @param boolean $f_only If we only return the field itself, with no label.
948
+ * @param boolean $field_error Field error.
949
+ * @param int $form_id Current form ID.
950
+ * @param string $label_placement Where to place the label.
951
  * @return string HTML markup for field.
952
  */
953
+ public function input( $type = 'text', $name = '', $id = '', $value = '', $label = '', $req = false, $f_only = false, $field_error = false, $form_id = 0, $label_placement = '' ) {
954
 
955
  // Sanitize our stuff / set values.
956
+ $name = sanitize_text_field( $name );
957
+ $f_id = sanitize_title( $id );
958
+ $input_inline_styles = '';
959
+ $label_placement_class = 'ctct-label-' . $label_placement;
960
+ $specific_form_styles = $this->specific_form_styles;
961
+
962
+ // Use different styles for submit button.
963
+ if ( 'submit' === $type ) {
964
+ $input_inline_styles = $this->get_submit_inline_styles();
965
+ }
966
+
967
+ $type = sanitize_text_field( $type );
968
+ $value = sanitize_text_field( $value );
969
+ $label = sanitize_text_field( $label );
970
  $req_text = $req ? 'required' : '';
971
 
972
  // Start our markup.
973
  $markup = $this->field_top( $type, $name, $f_id, $label, $req );
974
 
975
+ // Set blank defaults for required info.
976
+ $req_label = '';
977
+ // If this is required, we output the HMTL5 required att.
978
+ if ( $req ) {
979
+
980
+ /**
981
+ * Filters the markup used for the required indicator.
982
+ *
983
+ * @since 1.0.0
984
+ *
985
+ * @param string $value An `<abbr>` tag with an asterisk indicating required status.
986
+ */
987
+ $req_label = apply_filters( 'constant_contact_required_label', '<abbr title="required">*</abbr>' );
988
+ }
989
+ if ( ( 'top' === $label_placement || 'left' === $label_placement || 'hidden' === $label_placement ) && ( 'submit' !== $type ) && ( 'hidden' !== $type ) ) {
990
+ $markup .= '<span class="' . $label_placement_class . '">';
991
+ $markup .= $this->get_label( $f_id, $name . ' ' . $req_label );
992
+ $markup .= '</span>';
993
+ }
994
+
995
  // Provide some CSS class(es).
996
+ $classes = array( 'ctct-' . esc_attr( $type ) );
997
+ $classes[] = $label_placement_class;
998
+ if ( ! empty( $specific_form_styles['input_custom_classes'] ) ) {
999
+ $custom_input_classes = explode( ' ', $specific_form_styles['input_custom_classes'] );
1000
+ $classes = array_merge( $classes, $custom_input_classes );
1001
+ }
1002
 
1003
  /**
1004
  * Filter to add classes for the rendering input.
1018
  * @param bool $value Whether or not to truncate. Default false.
1019
  */
1020
  $truncate_max_length = apply_filters( 'constant_contact_include_custom_field_label', false, $form_id );
1021
+ $max_length = '';
1022
  if ( false !== strpos( $id, 'custom___' ) ) {
1023
  $max_length = ( $truncate_max_length ) ? $this->get_max_length_attr( $name ) : $this->get_max_length_attr();
1024
  }
 
 
1025
 
1026
  // If we have an error.
1027
  if ( $field_error ) {
1029
  $classes[] = 'ctct-invalid';
1030
  }
1031
 
1032
+ $class_attr = '';
1033
  // Append classes to our field.
1034
  if ( count( $classes ) ) {
1035
+ $class_attr = 'class="' . implode( ' ', $classes ) . '"';
1036
  }
1037
 
1038
  // Finish the markup for our field itself.
1039
+ $field = '<input %s type="%s" name="%s" id="%s" %s value="%s" %s placeholder="%s" %s />';
1040
+ $markup .= sprintf(
1041
+ $field,
1042
+ $req_text,
1043
+ $type,
1044
+ $f_id,
1045
+ $f_id,
1046
+ $input_inline_styles,
1047
+ $value,
1048
+ $max_length,
1049
+ $label,
1050
+ $class_attr
1051
+ );
1052
+ // Reassign because if we want "field only", like for hidden inputs, we need to
1053
+ // still pass a value that went through sprintf().
1054
+ $field = $markup;
1055
 
1056
+ if ( ( 'bottom' === $label_placement || 'right' === $label_placement ) && ( 'submit' !== $type ) && ( 'hidden' !== $type ) ) {
1057
+ $markup .= '<span class="' . $label_placement_class . '">';
1058
+ $markup .= $this->get_label( $f_id, $name . ' ' . $req_label );
1059
+ $markup .= '</span>';
1060
+ }
1061
 
1062
  // If we got an error, add it to the bottom label.
1063
  if ( $field_error ) {
1108
  */
1109
  $classes = apply_filters( 'constant_contact_input_classes', $classes, $type );
1110
 
1111
+ $markup = $this->field_top( $type, $name, $f_id, $label, false, false );
1112
  $markup .= '<input type="' . $type . '" name="' . $f_id . '" id="' . $f_id . '" value="' . $value . '" class="' . implode( ' ', $classes ) . '" />';
1113
  $markup .= $this->field_bottom( $name, ' ' . $label );
1114
 
1228
  // If we aren't showing the field, then we default our checkbox to checked.
1229
  $checked = $show ? '' : 'checked';
1230
 
1231
+ $markup = $this->field_top( 'checkbox', 'ctct-opt-in', 'ctct-opt-in', $label, false, false );
1232
  $markup .= '<input type="checkbox" ' . $checked . ' name="ctct-opt-in" id="ctct-opt-in" class="ctct-checkbox ctct-opt-in" value="' . $value . '" />';
1233
  $markup .= $this->field_bottom( 'ctct-opt-in', ' ' . wp_kses_post( $label ), false );
1234
 
1240
  *
1241
  * @since 1.0.0
1242
  *
1243
+ * @param string $name Name of fields.
1244
+ * @param string $f_id Form ID name.
1245
+ * @param array $value Values of each field.
1246
+ * @param string $desc Label of field.
1247
+ * @param boolean $req Whether or not required.
1248
+ * @param string $field_error Field error value.
1249
+ * @param string $label_placement Where to put the label.
1250
  * @return string field HTML markup.
1251
  */
1252
+ public function address( $name = '', $f_id = '', $value = array(), $desc = '', $req = false, $field_error = '', $label_placement = 'top' ) {
1253
 
1254
  // Set up our text strings.
1255
  $street = __( 'Street Address', 'constant-contact-forms' );
1272
  *
1273
  * @param string $value An `<abbr>` tag with an asterisk indicating required status.
1274
  */
1275
+ $req_label = $req ? ' ' . apply_filters( 'constant_contact_required_label', '<abbr title="required">*</abbr>' ) : '';
1276
+ $req_class = $req ? ' ctct-form-field-required ' : '';
1277
+ $req = $req ? ' required ' : '';
1278
+ $label_placement_class = 'ctct-label-' . $label_placement;
1279
+
1280
+ $label_street1 = sprintf(
1281
+ '<span class="%s"><label for="street_%s">%s</label></span>',
1282
+ esc_attr( $label_placement_class ),
1283
+ esc_attr( $f_id ),
1284
+ esc_attr( $street ) . $req_label
1285
+ );
1286
+ $input_street1 = sprintf(
1287
+ '<input %stype="text" class="ctct-text ctct-address-street %s" name="street_%s" id="street_%s" value="%s">',
1288
+ $req,
1289
+ esc_attr( $label_placement_class ),
1290
+ esc_attr( $f_id ),
1291
+ esc_attr( $f_id ),
1292
+ esc_attr( $v_street )
1293
+ );
1294
 
1295
+ $input_street1_whole = '';
1296
+ if ( 'top' === $label_placement || 'left' === $label_placement || 'hidden' === $label_placement ) {
1297
+ $input_street1_whole = $label_street1 . $input_street1;
1298
+ }
1299
+ if ( 'bottom' === $label_placement || 'right' === $label_placement ) {
1300
+ $input_street1_whole = $input_street1 . $label_street1;
1301
+ }
1302
+
1303
+ $label_street2 = sprintf(
1304
+ '<span class="%s"><label for="line_2_%s">%s</label></span>',
1305
+ $label_placement_class,
1306
+ esc_attr( $f_id ),
1307
+ esc_attr( $line_2 )
1308
+ );
1309
  // Address Line 2 is not required, note the missing $req inclusion.
1310
+ $input_street2 = sprintf(
1311
+ '<input type="text" class="ctct-text ctct-address-line-2 %s" name="line_2_%s" id="line_2_%s" value="%s">',
1312
+ esc_attr( $label_placement_class ),
1313
+ esc_attr( $f_id ),
1314
+ esc_attr( $f_id ),
1315
+ esc_attr( $v_line_2 )
1316
+ );
1317
+
1318
+ $input_street2_whole = '';
1319
+ if ( 'top' === $label_placement || 'left' === $label_placement || 'hidden' === $label_placement ) {
1320
+ $input_street2_whole = $label_street2 . $input_street2;
1321
+ }
1322
+ if ( 'bottom' === $label_placement || 'right' === $label_placement ) {
1323
+ $input_street2_whole = $input_street2 . $label_street2;
1324
+ }
1325
+
1326
+ $label_city = sprintf(
1327
+ '<span class="%s"><label for="city_%s">%s</label></span>',
1328
+ $label_placement_class,
1329
+ esc_attr( $f_id ),
1330
+ esc_attr( $city ) . $req_label
1331
+ );
1332
+ $input_city = sprintf(
1333
+ '<input %stype="text" class="ctct-text ctct-address-city %s" name="city_%s" id="city_%s" value="%s">',
1334
+ $req,
1335
+ esc_attr( $label_placement_class ),
1336
+ esc_attr( $f_id ),
1337
+ esc_attr( $f_id ),
1338
+ esc_attr( $v_city )
1339
+ );
1340
+
1341
+ $input_city_whole = '';
1342
+ if ( 'top' === $label_placement || 'left' === $label_placement || 'hidden' === $label_placement ) {
1343
+ $input_city_whole = $label_city . $input_city;
1344
+ }
1345
+ if ( 'bottom' === $label_placement || 'right' === $label_placement ) {
1346
+ $input_city_whole = $input_city . $label_city;
1347
+ }
1348
+
1349
+ $label_state = sprintf(
1350
+ '<span class="%s"><label for="state_%s">%s</label></span>',
1351
+ $label_placement_class,
1352
+ esc_attr( $f_id ),
1353
+ esc_attr( $state ) . $req_label
1354
+ );
1355
+ $input_state = sprintf(
1356
+ '<input %stype="text" class="ctct-text ctct-address-state %s" name="state_%s" id="state_%s" value="%s">',
1357
+ $req,
1358
+ esc_attr( $label_placement_class ),
1359
+ esc_attr( $f_id ),
1360
+ esc_attr( $f_id ),
1361
+ esc_attr( $v_state )
1362
+ );
1363
+
1364
+ $input_state_whole = '';
1365
+ if ( 'top' === $label_placement || 'left' === $label_placement || 'hidden' === $label_placement ) {
1366
+ $input_state_whole = $label_state . $input_state;
1367
+ }
1368
+ if ( 'bottom' === $label_placement || 'right' === $label_placement ) {
1369
+ $input_state_whole = $input_state . $label_state;
1370
+ }
1371
+
1372
+ $label_zip = sprintf(
1373
+ '<span class="%s"><label for="zip_%s">%s</label></span>',
1374
+ $label_placement_class,
1375
+ esc_attr( $f_id ),
1376
+ esc_attr( $zip ) . $req_label
1377
+ );
1378
+ $input_zip = sprintf(
1379
+ '<input %stype="text" class="ctct-text ctct-address-zip %s" name="zip_%s" id="zip_%s" value="%s">',
1380
+ $req,
1381
+ esc_attr( $label_placement_class ),
1382
+ esc_attr( $f_id ),
1383
+ esc_attr( $f_id ),
1384
+ esc_attr( $v_zip )
1385
+ );
1386
+
1387
+ $input_zip_whole = '';
1388
+ if ( 'top' === $label_placement || 'left' === $label_placement || 'hidden' === $label_placement ) {
1389
+ $input_zip_whole = $label_zip . $input_zip;
1390
+ }
1391
+ if ( 'bottom' === $label_placement || 'right' === $label_placement ) {
1392
+ $input_zip_whole = $input_zip . $label_zip;
1393
+ }
1394
+
1395
+ // Build our field.
1396
+ $return = '<fieldset class="ctct-address"><legend>%s</legend>';
1397
+ $return .= '<div class="ctct-form-field ctct-field-full address-line-1%s">%s</div>';
1398
+ $return .= '<div class="ctct-form-field ctct-field-full address-line-2%s" id="input_2_1_2_container">%s</div>';
1399
+ $return .= '<div class="ctct-form-field ctct-field-third address-city%s" id="input_2_1_3_container">%s</div>';
1400
+ $return .= '<div class="ctct-form-field ctct-field-third address-state%s" id="input_2_1_4_container">%s</div>';
1401
+ $return .= '<div class="ctct-form-field ctct-field-third address-zip%s" id="input_2_1_5_container">%s</div>';
1402
  $return .= '</fieldset>';
1403
 
1404
+ return sprintf(
1405
+ $return,
1406
+ esc_html( $name ),
1407
+ $req_class,
1408
+ $input_street1_whole,
1409
+ $req_class,
1410
+ $input_street2_whole,
1411
+ $req_class,
1412
+ $input_city_whole,
1413
+ $req_class,
1414
+ $input_state_whole,
1415
+ $req_class,
1416
+ $input_zip_whole
1417
+ );
1418
  }
1419
 
1420
  /**
1638
  *
1639
  * @since 1.0.0
1640
  *
1641
+ * @param string $name Name of field.
1642
+ * @param string $map ID of field.
1643
+ * @param string $value Previous value of field.
1644
+ * @param string $desc Description/label of field.
1645
+ * @param boolean $req If is required.
1646
+ * @param string $field_error Error from field.
1647
+ * @param string $extra_attrs Extra attributes to append.
1648
+ * @param string $label_placement Where to place the label.
1649
  * @return string HTML markup.
1650
  */
1651
+ public function textarea( $name = '', $map = '', $value = '', $desc = '', $req = false, $field_error = '', $extra_attrs = '', $label_placement = 'top' ) {
1652
+
1653
+ $classes = array( 'ctct-form-field' );
1654
+ $textarea_classes = array( 'ctct-textarea' );
1655
 
 
1656
  // Set our required text.
1657
  $req_text = $req ? 'required' : '';
1658
  if ( $req ) {
1659
  $classes[] = 'ctct-form-field-required';
1660
  }
1661
+ $label_placement_class = 'ctct-label-' . $label_placement;
1662
+ $textarea_classes[] = $label_placement_class;
1663
 
1664
  // If required, get our label.
1665
  $req_label = '';
1675
  $req_label = apply_filters( 'constant_contact_required_label', '<abbr title="required">*</abbr>' );
1676
  }
1677
 
1678
+ $return = '<p class="' . implode( ' ', $classes ) . '">';
1679
+ $label = '<span class="' . $label_placement_class . '"><label for="' . esc_attr( $map ) . '">' . esc_attr( $name ) . ' ' . $req_label . '</label></span>';
1680
+ $textarea = '<textarea class="' . esc_attr( implode( ' ', $textarea_classes ) ) . '" ' . $req_text . ' name="' . esc_attr( $map ) . '" placeholder="' . esc_attr( $desc ) . '" ' . $extra_attrs . '>' . esc_html( $value ) . '</textarea>';
1681
 
1682
+ if ( 'top' === $label_placement || 'left' === $label_placement || 'hidden' === $label_placement ) {
1683
+ $return .= $label . $textarea;
1684
+ }
1685
+ if ( 'right' === $label_placement || 'bottom' === $label_placement ) {
1686
+ $return .= $textarea . $label;
1687
+ }
1688
  if ( $field_error ) {
1689
  $return .= '<span class="ctct-field-error"><label for="' . esc_attr( $map ) . '">' . esc_attr( __( 'Error: Please correct your entry.', 'constant-contact-forms' ) ) . '</label></span>';
1690
  }
1693
  }
1694
 
1695
  /**
1696
+ * Maybe display the disclosure notice.
1697
  *
1698
  * @since 1.0.0
1699
  *
1775
  }
1776
  return 'maxlength="' . $length . '"';
1777
  }
1778
+
1779
+
1780
  }
1781
 
includes/class-lists.php CHANGED
@@ -51,9 +51,6 @@ class ConstantContact_Lists {
51
  add_action( 'save_post_ctct_lists', array( $this, 'save_or_update_list' ), 10, 1 );
52
  add_action( 'transition_post_status', array( $this, 'post_status_transition' ), 11, 3 );
53
 
54
- // Show duplicate notices for lists.
55
- add_action( 'admin_notices', array( $this, 'show_duplicate_list_message' ) );
56
-
57
  // On deletion, verify the list is handled correctly.
58
  add_action( 'wp_trash_post', array( $this, 'delete_list' ) );
59
 
@@ -67,6 +64,8 @@ class ConstantContact_Lists {
67
 
68
  // Remove quick edit.
69
  add_filter( 'post_row_actions', array( $this, 'remove_quick_edit_from_lists' ) );
 
 
70
  }
71
 
72
  /**
@@ -177,7 +176,7 @@ class ConstantContact_Lists {
177
  * @since 1.0.0
178
  */
179
  public function add_form_css() {
180
- wp_enqueue_style( 'constant-contact-forms' );
181
  }
182
 
183
  /**
@@ -206,7 +205,7 @@ class ConstantContact_Lists {
206
  //
207
  // Currently, the rate limit for this is a refresh every 2 minutes. This can be filtered to be
208
  // less or more time.
209
- $last_synced = get_option( 'constant_contact_lists_last_synced', time() - DAY_IN_SECONDS );
210
 
211
  /**
212
  * Filters the rate limit to use for syncing lists.
@@ -220,7 +219,7 @@ class ConstantContact_Lists {
220
  // If our last synced time plus our rate limit is less than or equal to right now,
221
  // then we don't want to refresh. If we refreshed less than 15 minutes ago, we do not want to
222
  // redo it. Also allow forcing a bypass of this check.
223
- if ( ( ! $force ) && ( $last_synced + $sync_rate_limit_time ) >= time() ) {
224
  return;
225
  }
226
 
@@ -383,7 +382,7 @@ class ConstantContact_Lists {
383
  }
384
 
385
  // Update our last synced option to prevent doing this too often.
386
- update_option( 'constant_contact_lists_last_synced', time() );
387
 
388
  /**
389
  * Hook when a ctct list is updated.
@@ -476,7 +475,7 @@ class ConstantContact_Lists {
476
  $this->sync_lists( true );
477
 
478
  // Set our last synced time to now, so we don't re-add our new/removed list right away.
479
- update_option( 'constant_contact_lists_last_synced', time() );
480
 
481
  return $return;
482
 
@@ -803,12 +802,11 @@ class ConstantContact_Lists {
803
  }
804
 
805
  /**
806
- * Hooked into admin_notices, show our duplicate list message if we have one.
807
  *
808
- * @since 1.0.0
809
  */
810
- public function show_duplicate_list_message() {
811
-
812
  // Make sure we're on the correct page.
813
  global $pagenow, $post;
814
  if ( $pagenow || ( ! in_array( $pagenow, array( 'post.php' ), true ) ) ) {
@@ -825,14 +823,20 @@ class ConstantContact_Lists {
825
  get_post_meta( $post->ID, 'ctct_duplicate_list', true )
826
  ) {
827
 
828
- // Add our output ( I know, gross inline CSS )
829
- // @todo Remove inline CSS.
830
- ?>
831
- <div class="notice notice-error">
832
- <p><?php esc_attr_e( 'You already have a list with that name.', 'constant-contact-forms' ); ?></p>
833
- </div>
834
- <style>
835
- #title {
 
 
 
 
 
 
836
  background: url( "<?php echo esc_url_raw( $this->plugin->url . 'assets/images/error.svg' ); ?>" ) no-repeat;
837
  background-color: fade-out( #FF4136, 0.98);
838
  background-position: 8px 50%;
@@ -840,9 +844,21 @@ class ConstantContact_Lists {
840
  border-color: #FF4136;
841
  padding-left: 40px;
842
  }
843
- </style>
844
- <?php
845
- }
 
 
 
 
 
 
 
 
 
 
 
 
846
  }
847
 
848
  /**
@@ -879,7 +895,7 @@ class ConstantContact_Lists {
879
  current_user_can( 'manage_options' )
880
  ) {
881
  // Force our last updated time to be in the past, so we trigger the auto-refresh
882
- update_option( 'constant_contact_lists_last_synced', time() - HOUR_IN_SECONDS );
883
 
884
  // Get our url with our custom query args removed
885
  $url = remove_query_arg( array( 'ctct_resyncing', 'ctct_list_sync' ) );
51
  add_action( 'save_post_ctct_lists', array( $this, 'save_or_update_list' ), 10, 1 );
52
  add_action( 'transition_post_status', array( $this, 'post_status_transition' ), 11, 3 );
53
 
 
 
 
54
  // On deletion, verify the list is handled correctly.
55
  add_action( 'wp_trash_post', array( $this, 'delete_list' ) );
56
 
64
 
65
  // Remove quick edit.
66
  add_filter( 'post_row_actions', array( $this, 'remove_quick_edit_from_lists' ) );
67
+
68
+ add_action( 'admin_init', array( $this, 'maybe_display_duplicate_list_error' ) );
69
  }
70
 
71
  /**
176
  * @since 1.0.0
177
  */
178
  public function add_form_css() {
179
+ wp_enqueue_style( 'constant-contact-forms-admin' );
180
  }
181
 
182
  /**
205
  //
206
  // Currently, the rate limit for this is a refresh every 2 minutes. This can be filtered to be
207
  // less or more time.
208
+ $last_synced = get_option( 'constant_contact_lists_last_synced', current_time( 'timestamp' ) - DAY_IN_SECONDS );
209
 
210
  /**
211
  * Filters the rate limit to use for syncing lists.
219
  // If our last synced time plus our rate limit is less than or equal to right now,
220
  // then we don't want to refresh. If we refreshed less than 15 minutes ago, we do not want to
221
  // redo it. Also allow forcing a bypass of this check.
222
+ if ( ( ! $force ) && ( $last_synced + $sync_rate_limit_time ) >= current_time( 'timestamp' ) ) {
223
  return;
224
  }
225
 
382
  }
383
 
384
  // Update our last synced option to prevent doing this too often.
385
+ update_option( 'constant_contact_lists_last_synced', current_time( 'timestamp' ) );
386
 
387
  /**
388
  * Hook when a ctct list is updated.
475
  $this->sync_lists( true );
476
 
477
  // Set our last synced time to now, so we don't re-add our new/removed list right away.
478
+ update_option( 'constant_contact_lists_last_synced', current_time( 'timestamp' ) );
479
 
480
  return $return;
481
 
802
  }
803
 
804
  /**
805
+ * Maybe show some information about duplicate list errors.
806
  *
807
+ * @since 1.4.0
808
  */
809
+ public function maybe_display_duplicate_list_error() {
 
810
  // Make sure we're on the correct page.
811
  global $pagenow, $post;
812
  if ( $pagenow || ( ! in_array( $pagenow, array( 'post.php' ), true ) ) ) {
823
  get_post_meta( $post->ID, 'ctct_duplicate_list', true )
824
  ) {
825
 
826
+ add_action( 'admin_head', array( $this, 'list_css' ) );
827
+ add_action( 'admin_notices', array( $this, 'show_duplicate_list_message' ) );
828
+ }
829
+ }
830
+
831
+ /**
832
+ * Output some embedded CSS for our error.
833
+ *
834
+ * @since 1.4.0
835
+ */
836
+ public function list_css() {
837
+ ?>
838
+ <style>
839
+ .post-type-ctct_lists #titlediv #title {
840
  background: url( "<?php echo esc_url_raw( $this->plugin->url . 'assets/images/error.svg' ); ?>" ) no-repeat;
841
  background-color: fade-out( #FF4136, 0.98);
842
  background-position: 8px 50%;
844
  border-color: #FF4136;
845
  padding-left: 40px;
846
  }
847
+ </style>
848
+ <?php
849
+ }
850
+
851
+ /**
852
+ * Hooked into admin_notices, show our duplicate list message if we have one.
853
+ *
854
+ * @since 1.0.0
855
+ */
856
+ public function show_duplicate_list_message() {
857
+ ?>
858
+ <div class="notice notice-error">
859
+ <p><?php esc_attr_e( 'You already have a list with that name.', 'constant-contact-forms' ); ?></p>
860
+ </div>
861
+ <?php
862
  }
863
 
864
  /**
895
  current_user_can( 'manage_options' )
896
  ) {
897
  // Force our last updated time to be in the past, so we trigger the auto-refresh
898
+ update_option( 'constant_contact_lists_last_synced', current_time( 'timestamp' ) - HOUR_IN_SECONDS );
899
 
900
  // Get our url with our custom query args removed
901
  $url = remove_query_arg( array( 'ctct_resyncing', 'ctct_list_sync' ) );
includes/class-logging.php CHANGED
@@ -94,7 +94,7 @@ class ConstantContact_Logging {
94
  */
95
  public function add_options_page() {
96
 
97
- $debugging_enabled = ctct_get_settings_option( '_ctct_logging' );
98
 
99
  if ( 'on' !== $debugging_enabled ) {
100
  return;
@@ -123,7 +123,7 @@ class ConstantContact_Logging {
123
  */
124
  public function admin_page_display() {
125
 
126
- wp_enqueue_style( 'constant-contact-oath', constant_contact()->url() . 'assets/css/oath.css' );
127
 
128
  ?>
129
  <div class="wrap <?php echo esc_attr( $this->key ); ?>">
94
  */
95
  public function add_options_page() {
96
 
97
+ $debugging_enabled = ctct_get_settings_option( '_ctct_logging', '' );
98
 
99
  if ( 'on' !== $debugging_enabled ) {
100
  return;
123
  */
124
  public function admin_page_display() {
125
 
126
+ wp_enqueue_style( 'constant-contact-forms-admin' );
127
 
128
  ?>
129
  <div class="wrap <?php echo esc_attr( $this->key ); ?>">
includes/class-mail.php CHANGED
@@ -80,7 +80,7 @@ class ConstantContact_Mail {
80
  * @param int $schedule_delay The time to add to `time()` for the event.
81
  */
82
  $schedule_delay = apply_filters( 'constant_contact_opt_in_delay', MINUTE_IN_SECONDS );
83
- wp_schedule_single_event( time() + absint( $schedule_delay ), 'ctct_schedule_form_opt_in', array( $values ) );
84
  }
85
  }
86
 
@@ -95,14 +95,14 @@ class ConstantContact_Mail {
95
  $values = constant_contact()->process_form->pretty_values( $values );
96
 
97
  // Format them.
98
- $email_values = $this->format_values_for_email( $values );
99
  $was_forced = false; // Set a value regardless of status.
100
 
101
  // Increment our counter for processed form entries.
102
  constant_contact()->process_form->increment_processed_form_count();
103
 
104
  // Skip sending e-mail if we're connected, the site owner has opted out of notification emails, and the user has opted in
105
- if ( constant_contact()->api->is_connected() && 'on' === ctct_get_settings_option( '_ctct_disable_email_notifications' ) ) {
106
  if ( $add_to_opt_in ) {
107
  return true;
108
  }
@@ -119,7 +119,7 @@ class ConstantContact_Mail {
119
  // Checks if we have a list
120
  if (
121
  ( ! constant_contact()->api->is_connected() || empty( $has_list ) ) &&
122
- ( 'on' === ctct_get_settings_option( '_ctct_disable_email_notifications' ) )
123
  ) { // If we're not connected or have no list set AND we've disabled. Override.
124
 
125
  $submission_details['list-available'] = 'no';
@@ -129,14 +129,14 @@ class ConstantContact_Mail {
129
  if (
130
  ! empty( $_POST['ctct_must_opt_in'] ) &&
131
  empty( $opt_in_details ) &&
132
- ( 'on' === ctct_get_settings_option( '_ctct_disable_email_notifications' ) )
133
  ) {
134
  $submission_details['opted-in'] = 'no';
135
  $was_forced = true;
136
  }
137
 
138
  // Send the mail.
139
- return $this->mail( $this->get_email(), $email_values, $submission_details, $was_forced );
140
  }
141
 
142
  /**
@@ -188,23 +188,36 @@ class ConstantContact_Mail {
188
  * Formats values for email.
189
  *
190
  * @since 1.0.0
 
191
  *
192
- * @param array $pretty_vals Values to format.
 
193
  * @return string HTML content for email.
194
  */
195
- public function format_values_for_email( $pretty_vals ) {
196
 
197
  $return = '';
 
 
 
198
  foreach ( $pretty_vals as $val ) {
199
 
200
  $label = isset( $val['orig_key'] ) ? $val['orig_key'] : false;
201
 
202
- if ( $label ) {
 
 
 
 
 
 
203
  // Break out our unique key.
204
  $label = explode( '___', $label );
205
 
206
  // Uppercase and format to be human readable.
207
  $label = ucwords( str_replace( '_', ' ', $label[0] ) );
 
 
208
  }
209
  $value = isset( $val['post'] ) ? $val['post'] : '&nbsp;';
210
 
@@ -218,10 +231,13 @@ class ConstantContact_Mail {
218
  * Get the email address to send to.
219
  *
220
  * @since 1.0.0
 
 
 
221
  *
222
  * @return string Email address to send to.
223
  */
224
- public function get_email() {
225
 
226
  $email = get_option( 'admin_email' );
227
 
@@ -229,10 +245,12 @@ class ConstantContact_Mail {
229
  * Filters the email to send Constant Contact Forms admin emails to.
230
  *
231
  * @since 1.3.0
 
232
  *
233
  * @param string $email Email address to send to. Default admin_email option.
 
234
  */
235
- return apply_filters( 'constant_contact_destination_email', $email );
236
  }
237
 
238
  /**
@@ -258,8 +276,28 @@ class ConstantContact_Mail {
258
  $screen = get_current_screen();
259
  }
260
 
261
- $mail_key = md5( "{$destination_email}:{$content}:" . ( isset( $screen->id ) ? $screen->id : '' ) );
262
- $partial_email = $this->get_email_part( $destination_email );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
 
264
  // If we already have sent this e-mail, don't send it again.
265
  if ( $last_sent === $mail_key ) {
@@ -278,10 +316,18 @@ class ConstantContact_Mail {
278
  return true;
279
  }
280
 
281
- // If we didn't get passed in a sanitized email, we know something is
282
- // wonky here, so bail out.
283
- if ( sanitize_email( $destination_email ) !== $destination_email ) {
284
- return false;
 
 
 
 
 
 
 
 
285
  }
286
 
287
  // Filter to allow sending HTML for our message body.
80
  * @param int $schedule_delay The time to add to `time()` for the event.
81
  */
82
  $schedule_delay = apply_filters( 'constant_contact_opt_in_delay', MINUTE_IN_SECONDS );
83
+ wp_schedule_single_event( current_time( 'timestamp' ) + absint( $schedule_delay ), 'ctct_schedule_form_opt_in', array( $values ) );
84
  }
85
  }
86
 
95
  $values = constant_contact()->process_form->pretty_values( $values );
96
 
97
  // Format them.
98
+ $email_values = $this->format_values_for_email( $values, $submission_details['form_id'] );
99
  $was_forced = false; // Set a value regardless of status.
100
 
101
  // Increment our counter for processed form entries.
102
  constant_contact()->process_form->increment_processed_form_count();
103
 
104
  // Skip sending e-mail if we're connected, the site owner has opted out of notification emails, and the user has opted in
105
+ if ( constant_contact()->api->is_connected() && constant_contact_emails_disabled( $submission_details['form_id'] ) ) {
106
  if ( $add_to_opt_in ) {
107
  return true;
108
  }
119
  // Checks if we have a list
120
  if (
121
  ( ! constant_contact()->api->is_connected() || empty( $has_list ) ) &&
122
+ ( constant_contact_emails_disabled( $submission_details['form_id'] ) )
123
  ) { // If we're not connected or have no list set AND we've disabled. Override.
124
 
125
  $submission_details['list-available'] = 'no';
129
  if (
130
  ! empty( $_POST['ctct_must_opt_in'] ) &&
131
  empty( $opt_in_details ) &&
132
+ ( constant_contact_emails_disabled( $submission_details['form_id'] ) )
133
  ) {
134
  $submission_details['opted-in'] = 'no';
135
  $was_forced = true;
136
  }
137
 
138
  // Send the mail.
139
+ return $this->mail( $this->get_email( $submission_details['form_id'] ), $email_values, $submission_details, $was_forced );
140
  }
141
 
142
  /**
188
  * Formats values for email.
189
  *
190
  * @since 1.0.0
191
+ * @since 1.4.0 Added form_id parameter.
192
  *
193
+ * @param array $pretty_vals Values to format.
194
+ * @param string $form_id Form ID being submitted to.
195
  * @return string HTML content for email.
196
  */
197
+ public function format_values_for_email( $pretty_vals, $form_id ) {
198
 
199
  $return = '';
200
+
201
+ // Retrieve our original label to send with API request.
202
+ $original_field_data = $this->plugin->process_form->get_original_fields( $form_id );
203
  foreach ( $pretty_vals as $val ) {
204
 
205
  $label = isset( $val['orig_key'] ) ? $val['orig_key'] : false;
206
 
207
+ $custom_field_name = '';
208
+ if ( false !== strpos( $label, 'custom___' ) ) {
209
+ $custom_field = ( $original_field_data[ $val['orig_key'] ] );
210
+ $custom_field_name .= $custom_field['name'];
211
+ }
212
+
213
+ if ( $label && empty( $custom_field_name ) ) {
214
  // Break out our unique key.
215
  $label = explode( '___', $label );
216
 
217
  // Uppercase and format to be human readable.
218
  $label = ucwords( str_replace( '_', ' ', $label[0] ) );
219
+ } else {
220
+ $label = $custom_field_name;
221
  }
222
  $value = isset( $val['post'] ) ? $val['post'] : '&nbsp;';
223
 
231
  * Get the email address to send to.
232
  *
233
  * @since 1.0.0
234
+ * @since 1.4.0 Added form ID parameter.
235
+ *
236
+ * @param string $form_id Current form ID being submitted to.
237
  *
238
  * @return string Email address to send to.
239
  */
240
+ public function get_email( $form_id ) {
241
 
242
  $email = get_option( 'admin_email' );
243
 
245
  * Filters the email to send Constant Contact Forms admin emails to.
246
  *
247
  * @since 1.3.0
248
+ * @since 1.4.0 Added form ID parameter.
249
  *
250
  * @param string $email Email address to send to. Default admin_email option.
251
+ * @param string $form_id Current form ID being submitted to.
252
  */
253
+ return apply_filters( 'constant_contact_destination_email', $email, $form_id );
254
  }
255
 
256
  /**
276
  $screen = get_current_screen();
277
  }
278
 
279
+ if ( is_array( $destination_email ) ) {
280
+ $temp_destination_email = implode( ',', $destination_email );
281
+ } else {
282
+ $temp_destination_email = $destination_email;
283
+ }
284
+ // Implode for the sake of $mail_key and md5 usage.
285
+ $mail_key = md5( "{$temp_destination_email}:{$content}:" . ( isset( $screen->id ) ? $screen->id : '' ) );
286
+
287
+ if ( is_array( $destination_email ) ) {
288
+ $partial_email = array_map( array( $this, 'get_email_part' ), $destination_email );
289
+ $partial_email = implode( ',', $partial_email );
290
+ } else {
291
+ if ( false !== strpos( $destination_email, ',' ) ) {
292
+ // Use trim to handle cases of ", "
293
+ $partials = array_map( 'trim', explode( ',', $destination_email ) );
294
+ // Collect our parts and re-implode.
295
+ $partial_email = array_map( array( $this, 'get_email_part' ), $partials );
296
+ $partial_email = implode( ',', $partial_email );
297
+ } else {
298
+ $partial_email = $this->get_email_part( $destination_email );
299
+ }
300
+ }
301
 
302
  // If we already have sent this e-mail, don't send it again.
303
  if ( $last_sent === $mail_key ) {
316
  return true;
317
  }
318
 
319
+ if ( is_array( $destination_email ) ) {
320
+ $destination_email = array_map( 'sanitize_email', $destination_email );
321
+ $destination_email = implode( ',', $destination_email );
322
+ } else {
323
+ if ( false !== strpos( $destination_email, ',' ) ) {
324
+ // Use trim to handle cases of ", "
325
+ $partials = array_map( 'trim', explode( ',', $destination_email ) );
326
+ $partials = array_map( 'sanitize_email', $partials );
327
+ $destination_email = implode( ',', $partials );
328
+ } else {
329
+ $destination_email = sanitize_email( $destination_email );
330
+ }
331
  }
332
 
333
  // Filter to allow sending HTML for our message body.
includes/class-notifications.php CHANGED
@@ -395,12 +395,7 @@ class ConstantContact_Notifications {
395
  // If we haven't shown styles yet, enqueue em.
396
  if ( ! $have_styles ) {
397
 
398
- wp_enqueue_style(
399
- 'constant-contact-admin-notices',
400
- constant_contact()->url() . 'assets/css/admin-notices.css',
401
- array(),
402
- Constant_Contact::VERSION
403
- );
404
 
405
  $have_styles = true;
406
  }
395
  // If we haven't shown styles yet, enqueue em.
396
  if ( ! $have_styles ) {
397
 
398
+ wp_enqueue_style( 'constant-contact-forms-admin' );
 
 
 
 
 
399
 
400
  $have_styles = true;
401
  }
includes/class-process-form.php CHANGED
@@ -115,7 +115,11 @@ class ConstantContact_Process_Form {
115
  switch ( $status ) {
116
 
117
  case 'success':
118
- $message = __( 'Your information has been submitted.', 'constant-contact-forms' );
 
 
 
 
119
  break;
120
 
121
  // Generic error.
@@ -211,7 +215,7 @@ class ConstantContact_Process_Form {
211
  }
212
 
213
  if ( isset( $data['g-recaptcha-response'] ) ) {
214
- $secret = ctct_get_settings_option( '_ctct_recaptcha_secret_key' );
215
  $method = null;
216
  if ( ! ini_get( 'allow_url_fopen' ) ) {
217
  $method = new \ReCaptcha\RequestMethod\CurlPost();
@@ -222,7 +226,6 @@ class ConstantContact_Process_Form {
222
 
223
  if ( ! $resp->isSuccess() ) {
224
  constant_contact_maybe_log_it( 'reCAPTCHA', 'Failed to verify with Google reCAPTCHA', array( $resp->getErrorCodes() ) );
225
- // @todo Utilize the error message(s) that come back from Google, if any.
226
  return array(
227
  'status' => 'named_error',
228
  'error' => __( 'Failed reCAPTCHA check', 'constant-contact-forms' ),
@@ -676,6 +679,9 @@ class ConstantContact_Process_Form {
676
  * Filters the message for the successful processed form.
677
  *
678
  * @since 1.3.0
 
 
 
679
  */
680
  $message = apply_filters( 'ctct_process_form_success', __( 'Your information has been submitted.', 'constant-contact-forms' ), $form_id );
681
  break;
@@ -722,6 +728,15 @@ class ConstantContact_Process_Form {
722
  update_option( 'ctct-processed-forms', $count );
723
  }
724
 
 
 
 
 
 
 
 
 
 
725
  public function has_all_required_fields( $form_id, $form_data ) {
726
  $original = $this->get_original_fields( $form_id );
727
 
115
  switch ( $status ) {
116
 
117
  case 'success':
118
+
119
+ /** This filter is documented in includes/class-process-form.php */
120
+ $message = apply_filters( 'ctct_process_form_success',
121
+ __( 'Your information has been submitted.', 'constant-contact-forms' ),
122
+ intval( $json_data['ctct-id'] ) );
123
  break;
124
 
125
  // Generic error.
215
  }
216
 
217
  if ( isset( $data['g-recaptcha-response'] ) ) {
218
+ $secret = ctct_get_settings_option( '_ctct_recaptcha_secret_key', '' );
219
  $method = null;
220
  if ( ! ini_get( 'allow_url_fopen' ) ) {
221
  $method = new \ReCaptcha\RequestMethod\CurlPost();
226
 
227
  if ( ! $resp->isSuccess() ) {
228
  constant_contact_maybe_log_it( 'reCAPTCHA', 'Failed to verify with Google reCAPTCHA', array( $resp->getErrorCodes() ) );
 
229
  return array(
230
  'status' => 'named_error',
231
  'error' => __( 'Failed reCAPTCHA check', 'constant-contact-forms' ),
679
  * Filters the message for the successful processed form.
680
  *
681
  * @since 1.3.0
682
+ *
683
+ * @param string $value Success message.
684
+ * @param string/int $form_id ID of the Constant Contact form being submitted to.
685
  */
686
  $message = apply_filters( 'ctct_process_form_success', __( 'Your information has been submitted.', 'constant-contact-forms' ), $form_id );
687
  break;
728
  update_option( 'ctct-processed-forms', $count );
729
  }
730
 
731
+ /**
732
+ * Check if we have all the required fields for a given form.
733
+ *
734
+ * @since 1.3.5
735
+ *
736
+ * @param int $form_id
737
+ * @param array $form_data
738
+ * @return bool
739
+ */
740
  public function has_all_required_fields( $form_id, $form_data ) {
741
  $original = $this->get_original_fields( $form_id );
742
 
includes/class-settings.php CHANGED
@@ -149,7 +149,7 @@ class ConstantContact_Settings {
149
  * @since 1.0.0
150
  */
151
  public function scripts() {
152
- wp_enqueue_style( 'constant-contact-forms' );
153
  }
154
 
155
  /**
@@ -352,16 +352,50 @@ class ConstantContact_Settings {
352
  '<div class="discover-recaptcha">' . __( 'Learn more and get an <a href="https://www.google.com/recaptcha/intro/" target="_blank">API site key</a>', 'constant-contact-forms' ) . '</div>'
353
  );
354
  $cmb->add_field( array(
355
- 'name' => esc_html__( 'Site Key', 'constant-contact-forms' ),
356
- 'id' => '_ctct_recaptcha_site_key',
357
- 'type' => 'text',
358
  'before_row' => $before_recaptcha,
359
  ) );
360
 
361
  $cmb->add_field( array(
362
- 'name' => esc_html__( 'Secret Key', 'constant-contact-forms' ),
363
- 'id' => '_ctct_recaptcha_secret_key',
364
- 'type' => 'text',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
365
  ) );
366
 
367
  $before_debugging = sprintf(
@@ -413,7 +447,7 @@ class ConstantContact_Settings {
413
  public function check_if_optin_should_show( $type ) {
414
 
415
  // Get all our settings.
416
- $available_areas = ctct_get_settings_option( '_ctct_optin_forms' );
417
 
418
  // If our settings aren't an array, bail out.
419
  if ( ! is_array( $available_areas ) ) {
@@ -479,8 +513,8 @@ class ConstantContact_Settings {
479
  }
480
 
481
  // Get our label, based on our settings if they're available.
482
- $saved_label = ctct_get_settings_option( '_ctct_optin_label' );
483
- $list = ctct_get_settings_option( '_ctct_optin_list' );
484
 
485
  // Otherwise, use our default.
486
  $label = $saved_label ? $saved_label : esc_html__( 'Sign up to our newsletter.', 'constant-contact-forms' );
@@ -847,7 +881,7 @@ function ctct_get_settings_option( $key = '', $default = null ) {
847
 
848
  if ( 'all' === $key ) {
849
  $val = $opts;
850
- } elseif ( array_key_exists( $key, $opts ) && false !== $opts[ $key ] ) {
851
  $val = $opts[ $key ];
852
  }
853
 
149
  * @since 1.0.0
150
  */
151
  public function scripts() {
152
+ wp_enqueue_style( 'constant-contact-forms-admin' );
153
  }
154
 
155
  /**
352
  '<div class="discover-recaptcha">' . __( 'Learn more and get an <a href="https://www.google.com/recaptcha/intro/" target="_blank">API site key</a>', 'constant-contact-forms' ) . '</div>'
353
  );
354
  $cmb->add_field( array(
355
+ 'name' => esc_html__( 'Site Key', 'constant-contact-forms' ),
356
+ 'id' => '_ctct_recaptcha_site_key',
357
+ 'type' => 'text',
358
  'before_row' => $before_recaptcha,
359
  ) );
360
 
361
  $cmb->add_field( array(
362
+ 'name' => esc_html__( 'Secret Key', 'constant-contact-forms' ),
363
+ 'id' => '_ctct_recaptcha_secret_key',
364
+ 'type' => 'text',
365
+ ) );
366
+
367
+ $before_global_css = sprintf(
368
+ '<hr /><h2>%s</h2>',
369
+ esc_html__( 'Global Form CSS Settings', 'constant-contact-forms' )
370
+ );
371
+
372
+ $cmb->add_field( array(
373
+ 'name' => esc_html__( 'CSS Classes', 'constant-contact_forms' ),
374
+ 'id' => '_ctct_form_custom_classes',
375
+ 'type' => 'text',
376
+ 'description' => esc_html__(
377
+ 'Provide custom classes for the form separated by a single space.',
378
+ 'constant-contact-forms'
379
+ ),
380
+ 'before_row' => $before_global_css,
381
+ ) );
382
+
383
+ $cmb->add_field( array(
384
+ 'name' => esc_html__( 'Label Placement' ),
385
+ 'id' => '_ctct_form_label_placement',
386
+ 'type' => 'select',
387
+ 'default' => 'top',
388
+ 'show_option_none' => false,
389
+ 'options' => array(
390
+ 'top' => 'Top',
391
+ 'left' => 'Left',
392
+ 'right' => 'Right',
393
+ 'hidden' => 'Hidden',
394
+ ),
395
+ 'description' => esc_html__(
396
+ 'Choose the position for the labels of the form elements.',
397
+ 'constant-contact-forms'
398
+ ),
399
  ) );
400
 
401
  $before_debugging = sprintf(
447
  public function check_if_optin_should_show( $type ) {
448
 
449
  // Get all our settings.
450
+ $available_areas = ctct_get_settings_option( '_ctct_optin_forms', [] );
451
 
452
  // If our settings aren't an array, bail out.
453
  if ( ! is_array( $available_areas ) ) {
513
  }
514
 
515
  // Get our label, based on our settings if they're available.
516
+ $saved_label = ctct_get_settings_option( '_ctct_optin_label', '' );
517
+ $list = ctct_get_settings_option( '_ctct_optin_list', '' );
518
 
519
  // Otherwise, use our default.
520
  $label = $saved_label ? $saved_label : esc_html__( 'Sign up to our newsletter.', 'constant-contact-forms' );
881
 
882
  if ( 'all' === $key ) {
883
  $val = $opts;
884
+ } elseif ( is_array( $opts ) && array_key_exists( $key, $opts ) && false !== $opts[ $key ] ) {
885
  $val = $opts[ $key ];
886
  }
887
 
includes/class-user-customizations.php CHANGED
@@ -38,6 +38,7 @@ class ConstantContact_User_Customizations {
38
  public function hooks() {
39
  add_filter( 'ctct_process_form_success', array( $this, 'process_form_success' ), 10, 2 );
40
  add_filter( 'constant_contact_front_form_action', array( $this, 'custom_redirect' ), 10, 2 );
 
41
  }
42
 
43
  /**
@@ -75,4 +76,32 @@ class ConstantContact_User_Customizations {
75
 
76
  return constant_contact_clean_url( $custom );
77
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  }
38
  public function hooks() {
39
  add_filter( 'ctct_process_form_success', array( $this, 'process_form_success' ), 10, 2 );
40
  add_filter( 'constant_contact_front_form_action', array( $this, 'custom_redirect' ), 10, 2 );
41
+ add_filter( 'constant_contact_destination_email', array( $this, 'custom_email' ), 10, 2 );
42
  }
43
 
44
  /**
76
 
77
  return constant_contact_clean_url( $custom );
78
  }
79
+
80
+ /**
81
+ * Conditionally return a custom email destination value to our mail filter.
82
+ *
83
+ * @since 1.4.0
84
+ *
85
+ * @param $form_id
86
+ * @return mixed|string
87
+ */
88
+ public function custom_email( $destination_email, $form_id ) {
89
+ $custom_email = get_post_meta( $form_id, '_ctct_email_destination', true );
90
+
91
+ if ( empty( $custom_email ) ) {
92
+ return $destination_email;
93
+ }
94
+
95
+ // @todo Potentially using this type of code in many places in 1.4.0. Worthy of a helper function.
96
+ if ( false !== strpos( $custom_email, ',' ) ) {
97
+ // Use trim to handle cases of ", "
98
+ $partials = array_map( 'trim', explode( ',', $custom_email ) );
99
+ $partials = array_map( 'sanitize_email', $partials );
100
+ $custom_email = implode( ',', $partials );
101
+ } else {
102
+ $custom_email = sanitize_email( $custom_email );
103
+ }
104
+
105
+ return $custom_email;
106
+ }
107
  }
includes/compatibility.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Fixes for compatibility issues with other plug-ins.
4
+ *
5
+ * @package ConstantContact
6
+ * @author Constant Contact
7
+ * @since NEXT
8
+ */
9
+
10
+ /**
11
+ * Add the Constant Contact post type to an array of excluded post types.
12
+ *
13
+ * @since NEXT
14
+ *
15
+ * @param array $excluded The post types to exclude.
16
+ * @return array
17
+ */
18
+ function constant_contact_exclude_ctct_forms( $excluded ) {
19
+ $excluded[] = 'ctct_forms';
20
+ return $excluded;
21
+ }
22
+
23
+ // If the WordPress Calls to Action plug-in is installed, exclude our post type to conflict.
24
+ add_filter( 'cta_excluded_post_types', 'constant_contact_exclude_ctct_forms' );
25
+
26
+ /**
27
+ * Ignore the field added by Popup Maker from being processed by Constant Contact.
28
+ *
29
+ * @since 1.4.0
30
+ *
31
+ * @param array $ignored The array of fields that Constant Contact should ignore.
32
+ * @return array
33
+ */
34
+ function constant_contact_exclude_pum( $ignored ) {
35
+ $ignored[] = 'pum_form_popup_id';
36
+
37
+ return $ignored;
38
+ }
39
+ add_filter( 'constant_contact_ignored_post_form_values', 'constant_contact_exclude_pum' );
includes/helper-functions.php CHANGED
@@ -228,7 +228,7 @@ function constant_contact_review_ajax_handler() {
228
  switch ( $action ) {
229
  case 'dismissed':
230
  $dismissed = get_option( 'ctct-review-dismissed', array() );
231
- $dismissed['time'] = time();
232
  if ( empty( $dismissed['count'] ) ) {
233
  $dismissed['count'] = '1';
234
  } elseif ( isset( $dismissed['count'] ) && '2' === $dismissed['count'] ) {
@@ -313,7 +313,7 @@ function constant_contact_has_redirect_uri( $form_id = 0 ) {
313
  * @return bool
314
  */
315
  function constant_contact_check_timestamps( $maybe_spam, $data ) {
316
- $current = time();
317
  $difference = $current - $data['ctct_time'];
318
  if ( $difference <= 5 ) {
319
  return true;
@@ -351,7 +351,7 @@ function constant_contact_clean_url( $url = '' ) {
351
  * @return bool
352
  */
353
  function constant_contact_debugging_enabled() {
354
- $debugging_enabled = ctct_get_settings_option( '_ctct_logging' );
355
 
356
  return (
357
  ( defined( 'CONSTANT_CONTACT_DEBUG_MAIL' ) && CONSTANT_CONTACT_DEBUG_MAIL ) ||
@@ -383,3 +383,210 @@ function constant_contact_maybe_log_it( $log_name, $error, $extra_data = '' ) {
383
  // Log status of error.
384
  $logger->addInfo( $error, $extra );
385
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  switch ( $action ) {
229
  case 'dismissed':
230
  $dismissed = get_option( 'ctct-review-dismissed', array() );
231
+ $dismissed['time'] = current_time( 'timestamp' );
232
  if ( empty( $dismissed['count'] ) ) {
233
  $dismissed['count'] = '1';
234
  } elseif ( isset( $dismissed['count'] ) && '2' === $dismissed['count'] ) {
313
  * @return bool
314
  */
315
  function constant_contact_check_timestamps( $maybe_spam, $data ) {
316
+ $current = current_time( 'timestamp' );
317
  $difference = $current - $data['ctct_time'];
318
  if ( $difference <= 5 ) {
319
  return true;
351
  * @return bool
352
  */
353
  function constant_contact_debugging_enabled() {
354
+ $debugging_enabled = ctct_get_settings_option( '_ctct_logging', '' );
355
 
356
  return (
357
  ( defined( 'CONSTANT_CONTACT_DEBUG_MAIL' ) && CONSTANT_CONTACT_DEBUG_MAIL ) ||
383
  // Log status of error.
384
  $logger->addInfo( $error, $extra );
385
  }
386
+
387
+ /**
388
+ * Check spam through Akismet.
389
+ * It will build Akismet query string and call Akismet API.
390
+ * Akismet response return 'true' for spam submission.
391
+ *
392
+ * Akismet integration props to GiveWP. We appreciate the initial work.
393
+ *
394
+ * @since 1.4.0
395
+ *
396
+ * @param bool $is_spam Current status of the submission.
397
+ * @param array $data Array of submission data.
398
+ * @return bool
399
+ */
400
+ function constant_contact_akismet( $is_spam, $data ) {
401
+
402
+ // Bail out, If spam.
403
+ if ( $is_spam ) {
404
+ return $is_spam;
405
+ }
406
+
407
+ $email = false;
408
+ $fname = $lname = $name = '';
409
+ foreach ( $data as $key => $value ) {
410
+ if ( 'email' === substr( $key, 0, 5 ) ) {
411
+ $email = $value;
412
+ }
413
+ if ( 'first_name' === substr( $key, 0, 10 ) ) {
414
+ $fname = $value;
415
+ }
416
+ if ( 'last_name' === substr( $key, 0, 9 ) ) {
417
+ $lname = $value;
418
+ }
419
+ }
420
+
421
+ if ( $fname ) {
422
+ $name = $fname;
423
+ }
424
+ if ( $lname ) {
425
+ $name .= ' ' . $lname;
426
+ }
427
+
428
+ // Bail out, if Akismet key not exist.
429
+ if ( ! constant_contact_check_akismet_key() ) {
430
+ return $is_spam;
431
+ }
432
+
433
+ // Build args array.
434
+ $args = array();
435
+
436
+ $args['comment_author'] = $name;
437
+ $args['comment_author_email'] = $email;
438
+ $args['blog'] = get_option( 'home' );
439
+ $args['blog_lang'] = get_locale();
440
+ $args['blog_charset'] = get_option( 'blog_charset' );
441
+ $args['user_ip'] = $_SERVER['REMOTE_ADDR'];
442
+ $args['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
443
+ $args['referrer'] = $_SERVER['HTTP_REFERER'];
444
+ $args['comment_type'] = 'contact-form';
445
+
446
+ $ignore = array( 'HTTP_COOKIE', 'HTTP_COOKIE2', 'PHP_AUTH_PW' );
447
+
448
+ foreach ( $_SERVER as $key => $value ) {
449
+ if ( ! in_array( $key, (array) $ignore ) ) {
450
+ $args[ "{$key}" ] = $value;
451
+ }
452
+ }
453
+
454
+ // It will return Akismet spam detect API response.
455
+ $is_spam = constant_contact_akismet_spam_check( $args );
456
+
457
+ return $is_spam;
458
+ }
459
+ add_filter( 'constant_contact_maybe_spam', 'constant_contact_akismet', 10, 2 );
460
+
461
+ /**
462
+ * Check Akismet API Key.
463
+ *
464
+ * @since 1.4.0
465
+ *
466
+ * @return bool
467
+ */
468
+ function constant_contact_check_akismet_key() {
469
+ if ( is_callable( array( 'Akismet', 'get_api_key' ) ) ) { // Akismet v3.0
470
+ return (bool) Akismet::get_api_key();
471
+ }
472
+
473
+ if ( function_exists( 'akismet_get_key' ) ) {
474
+ return (bool) akismet_get_key();
475
+ }
476
+
477
+ return false;
478
+ }
479
+
480
+ /**
481
+ * Detect spam through Akismet Comment API.
482
+ *
483
+ * @since 1.4.0
484
+ *
485
+ * @param array $args
486
+ * @return bool|mixed
487
+ */
488
+ function constant_contact_akismet_spam_check( $args ) {
489
+ global $akismet_api_host, $akismet_api_port;
490
+
491
+ $spam = false;
492
+ $query_string = http_build_query( $args );
493
+
494
+ if ( is_callable( array( 'Akismet', 'http_post' ) ) ) { // Akismet v3.0
495
+ $response = Akismet::http_post( $query_string, 'comment-check' );
496
+ } else {
497
+ $response = akismet_http_post( $query_string, $akismet_api_host,
498
+ '/1.1/comment-check', $akismet_api_port );
499
+ }
500
+
501
+ // It's spam if response status is true.
502
+ if ( 'true' === $response[1] ) {
503
+ $spam = true;
504
+ }
505
+
506
+ return $spam;
507
+ }
508
+
509
+ /**
510
+ * Check whether or not emails should be disabled.
511
+ *
512
+ * @since 1.4.0
513
+ *
514
+ * @param int $form_id Current form ID being submitted to.
515
+ *
516
+ * @return mixed|void
517
+ */
518
+ function constant_contact_emails_disabled( $form_id = 0 ) {
519
+
520
+ // Assume we can.
521
+ $disabled = false;
522
+
523
+ // Check for a setting for the form itself.
524
+ $form_disabled = get_post_meta( $form_id, '_ctct_disable_emails_for_form', true );
525
+ if ( 'on' === $form_disabled ) {
526
+ $disabled = true;
527
+ }
528
+
529
+ // Check for our global setting.
530
+ $global_form_disabled = ctct_get_settings_option( '_ctct_disable_email_notifications', '' );
531
+ if ( 'on' === $global_form_disabled ) {
532
+ $disabled = true;
533
+ }
534
+
535
+ /**
536
+ * Filters whether or not emails should be disabled.
537
+ *
538
+ * @since 1.4.0
539
+ *
540
+ * @param bool $disabled Whether or not emails are disabled.
541
+ * @param int $form_id Form ID being submitted to.
542
+ */
543
+ return apply_filters( 'constant_contact_emails_disabled', $disabled, $form_id );
544
+ }
545
+
546
+ /**
547
+ * Get a list of font sizes to use in a dropdown menu for user customization.
548
+ *
549
+ * @since 1.4.0
550
+ *
551
+ * @return array The font sizes to use in a dropdown.
552
+ */
553
+ function constant_contact_get_font_dropdown_sizes() {
554
+ return array(
555
+ '12px' => '12 pixels',
556
+ '13px' => '13 pixels',
557
+ '14px' => '14 pixels',
558
+ '15px' => '15 pixels',
559
+ '16px' => '16 pixels',
560
+ '17px' => '17 pixels',
561
+ '18px' => '18 pixels',
562
+ '19px' => '19 pixels',
563
+ '20px' => '20 pixels',
564
+ );
565
+ }
566
+
567
+ /**
568
+ * Retrieve a CSS customization setting for a given form.
569
+ *
570
+ * Provide the post meta key or global setting key to retrieve.
571
+ *
572
+ * @since 1.4.0
573
+ *
574
+ * @param int $form_id Form ID to fetch data for.
575
+ * @param string $customization_key Key to fetch value for.
576
+ * @return string.
577
+ */
578
+ function constant_contact_get_css_customization( $form_id, $customization_key = '' ) {
579
+
580
+ $form_id = absint( $form_id );
581
+ $form_css = get_post_meta( $form_id );
582
+
583
+ if ( is_array( $form_css ) && array_key_exists( $customization_key, $form_css ) ) {
584
+ if ( ! empty( $form_css[ $customization_key ][0] ) ) {
585
+ return $form_css[ $customization_key ][0];
586
+ }
587
+ }
588
+
589
+ $global_setting = ctct_get_settings_option( $customization_key );
590
+
591
+ return ( ! empty( $global_setting ) ) ? $global_setting : '';
592
+ }
languages/constant-contact-forms.pot CHANGED
@@ -3,7 +3,7 @@ msgid ""
3
  msgstr ""
4
  "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
5
  "Project-Id-Version: Constant Contact Forms for WordPress\n"
6
- "POT-Creation-Date: 2018-05-01 16:12-0500\n"
7
  "PO-Revision-Date: 2017-01-12 14:46-0600\n"
8
  "Last-Translator: Michael Beckwith <michael.d.beckwith@gmail.com>\n"
9
  "Language-Team: Constant Contact\n"
@@ -29,162 +29,162 @@ msgstr ""
29
  msgid "Constant Contact"
30
  msgstr ""
31
 
32
- #: constant-contact-forms.php:390
33
  msgid ""
34
  "Constant Contact Forms requires PHP 5.4 or higher. Your hosting provider or "
35
  "website administrator should be able to assist in updating your PHP version."
36
  msgstr ""
37
 
38
- #: constant-contact-forms.php:718
39
  msgid "Error loading license."
40
  msgstr ""
41
 
42
- #: includes/class-admin-pages.php:88
43
  msgid "This is a sample help header"
44
  msgstr ""
45
 
46
- #: includes/class-admin-pages.php:89
47
  msgid "This is some sample help text."
48
  msgstr ""
49
 
50
- #: includes/class-admin-pages.php:92
51
  msgid "This is another sample header"
52
  msgstr ""
53
 
54
- #: includes/class-admin-pages.php:93
55
  msgid "This is also some sample help text."
56
  msgstr ""
57
 
58
- #: includes/class-admin-pages.php:116
59
  msgid "Is this a sample question?"
60
  msgstr ""
61
 
62
- #: includes/class-admin-pages.php:117
63
  msgid "This is a sample answer"
64
  msgstr ""
65
 
66
- #: includes/class-admin-pages.php:120
67
  msgid "This is also a sample question"
68
  msgstr ""
69
 
70
- #: includes/class-admin-pages.php:121
71
  msgid "This is another sample answer"
72
  msgstr ""
73
 
74
- #: includes/class-admin-pages.php:134
75
  msgid "Help / FAQ"
76
  msgstr ""
77
 
78
- #: includes/class-admin-pages.php:141
79
  msgid "Help"
80
  msgstr ""
81
 
82
- #: includes/class-admin-pages.php:175
83
  msgid "FAQ"
84
  msgstr ""
85
 
86
- #: includes/class-admin-pages.php:239
87
  #: includes/class-notification-content.php:53
88
  msgid "Constant Contact Forms"
89
  msgstr ""
90
 
91
- #: includes/class-admin-pages.php:241
92
  msgid ""
93
  "This plugin makes it fast and easy to capture all kinds of visitor "
94
  "information right from your WordPress site—even if you don't have a Constant "
95
  "Contact account."
96
  msgstr ""
97
 
98
- #: includes/class-admin-pages.php:244
99
  msgid ""
100
  "Whether you're looking to collect email addresses, contact info, or visitor "
101
  "feedback, you can customize your forms with data fields that work best for "
102
  "you."
103
  msgstr ""
104
 
105
- #: includes/class-admin-pages.php:247
106
  msgid ""
107
  "Quickly create different types of forms that are clear, simple, and mobile-"
108
  "optimized."
109
  msgstr ""
110
 
111
- #: includes/class-admin-pages.php:248
112
  msgid ""
113
  "Choose forms that automatically select the theme and style of your WordPress "
114
  "site."
115
  msgstr ""
116
 
117
- #: includes/class-admin-pages.php:249
118
  msgid ""
119
  "Customize the form data fields, so you can tailor the type of information "
120
  "you collect."
121
  msgstr ""
122
 
123
- #: includes/class-admin-pages.php:256
124
  msgid "Collecting email addresses with the plugin?"
125
  msgstr ""
126
 
127
- #: includes/class-admin-pages.php:257
128
  msgid "Turn those contacts into customers."
129
  msgstr ""
130
 
131
- #: includes/class-admin-pages.php:260
132
  msgid ""
133
  "Nurture your new contacts with a Constant Contact email marketing account "
134
  "even after they've left your website. Sign up for a 60-day trial account* "
135
  "and you can:"
136
  msgstr ""
137
 
138
- #: includes/class-admin-pages.php:263
139
  msgid "Seamlessly add new contacts to mailing lists."
140
  msgstr ""
141
 
142
- #: includes/class-admin-pages.php:264
143
  msgid "Create and send professional emails."
144
  msgstr ""
145
 
146
- #: includes/class-admin-pages.php:265
147
  msgid "Get expert marketing help and support."
148
  msgstr ""
149
 
150
- #: includes/class-admin-pages.php:270 includes/class-connect.php:263
151
  msgid "Try us Free"
152
  msgstr ""
153
 
154
- #: includes/class-admin-pages.php:273
155
  msgid "Already have a Constant Contact account?"
156
  msgstr ""
157
 
158
- #: includes/class-admin-pages.php:275
159
  msgid "Connect the plugin."
160
  msgstr ""
161
 
162
- #: includes/class-admin-pages.php:279
163
  msgid ""
164
  "NOTE: You can use the Constant Contact Form plugin without a Constant "
165
  "Contact account. All information collected by the forms will be individually "
166
  "emailed to your site admin."
167
  msgstr ""
168
 
169
- #: includes/class-admin-pages.php:286 includes/class-connect.php:281
170
  msgid "Sign Up"
171
  msgstr ""
172
 
173
- #: includes/class-admin-pages.php:287 includes/class-connect.php:269
174
  msgid "Email marketing tips delivered to your inbox."
175
  msgstr ""
176
 
177
- #: includes/class-admin-pages.php:288 includes/class-connect.php:270
178
  msgid ""
179
  "Ready to grow with email marketing? Subscribe now for the latest tips and "
180
  "industry best practices to create great-looking emails that work."
181
  msgstr ""
182
 
183
- #: includes/class-admin-pages.php:289 includes/class-connect.php:271
184
  msgid "Enter your email address"
185
  msgstr ""
186
 
187
- #: includes/class-admin-pages.php:296 includes/class-connect.php:278
188
  #, php-format
189
  msgid ""
190
  "By submitting this form, you agree to receive periodic product announcements "
@@ -193,15 +193,15 @@ msgid ""
193
  "email. Constant Contact, Inc, 1601 Trapelo Road, Waltham, MA 02451, %s"
194
  msgstr ""
195
 
196
- #: includes/class-admin-pages.php:306
197
  msgid "Powerful Email Marketing, Made Simple."
198
  msgstr ""
199
 
200
- #: includes/class-admin-pages.php:309
201
  msgid "Create professional emails that bring customers to your door"
202
  msgstr ""
203
 
204
- #: includes/class-admin-pages.php:313
205
  msgid ""
206
  "Email marketing is good for your business. $44-back-for-every-$1-spent kind "
207
  "of good.* And with the Constant Contact for WordPress plugin, you can "
@@ -209,64 +209,64 @@ msgid ""
209
  "visitors long after they've left."
210
  msgstr ""
211
 
212
- #: includes/class-admin-pages.php:317
213
  msgid "GPLv3 license"
214
  msgstr ""
215
 
216
- #: includes/class-admin-pages.php:321
217
  #, php-format
218
  msgid "This software is released under a modified %s."
219
  msgstr ""
220
 
221
- #: includes/class-admin-pages.php:327
222
  msgid "*Direct Marketing Association 2013 Statistical Fact Book"
223
  msgstr ""
224
 
225
- #: includes/class-admin-pages.php:335
226
  msgid "Easily Add Forms"
227
  msgstr ""
228
 
229
- #: includes/class-admin-pages.php:338
230
  msgctxt "add forms alt text"
231
  msgid "add forms screenshot"
232
  msgstr ""
233
 
234
- #: includes/class-admin-pages.php:341
235
  msgid ""
236
  "Create forms that automatically select the theme and styling of your "
237
  "WordPress site for a perfect match. "
238
  msgstr ""
239
 
240
- #: includes/class-admin-pages.php:347
241
  msgid "Stay Connected With Your WordPress Visitors"
242
  msgstr ""
243
 
244
- #: includes/class-admin-pages.php:350
245
  msgctxt "stay connected alt text"
246
  msgid "stay connected screenshot"
247
  msgstr ""
248
 
249
- #: includes/class-admin-pages.php:353
250
  msgid ""
251
  "Form completions from site visitors are conveniently added to your Constant "
252
  "Contact email list."
253
  msgstr ""
254
 
255
- #: includes/class-admin-pages.php:373
256
  msgid "Constant Contact Forms - License"
257
  msgstr ""
258
 
259
  #: includes/class-admin.php:116 includes/class-admin.php:117
260
- #: includes/class-admin.php:359
261
  msgid "About"
262
  msgstr ""
263
 
264
  #: includes/class-admin.php:125 includes/class-admin.php:126
265
- #: includes/class-admin.php:360
266
  msgid "License"
267
  msgstr ""
268
 
269
- #: includes/class-admin.php:210 includes/class-settings.php:697
270
  msgid "Settings updated."
271
  msgstr ""
272
 
@@ -274,7 +274,7 @@ msgstr ""
274
  msgid "Description"
275
  msgstr ""
276
 
277
- #: includes/class-admin.php:249 includes/class-builder-fields.php:496
278
  msgid "Shortcode"
279
  msgstr ""
280
 
@@ -283,7 +283,7 @@ msgid "Associated List"
283
  msgstr ""
284
 
285
  #: includes/class-admin.php:293
286
- msgid "No associated form"
287
  msgstr ""
288
 
289
  #: includes/class-admin.php:309
@@ -294,23 +294,23 @@ msgstr ""
294
  msgid "None available"
295
  msgstr ""
296
 
297
- #: includes/class-admin.php:356
298
  msgid "Check out the official WordPress plugin from @constantcontact :"
299
  msgstr ""
300
 
301
- #: includes/class-admin.php:372
302
  msgid "Spread the word!"
303
  msgstr ""
304
 
305
- #: includes/class-admin.php:448
306
  msgid "You have unsaved changes."
307
  msgstr ""
308
 
309
- #: includes/class-admin.php:449
310
  msgid "move up"
311
  msgstr ""
312
 
313
- #: includes/class-admin.php:450
314
  msgid "move down"
315
  msgstr ""
316
 
@@ -328,23 +328,23 @@ msgid ""
328
  "new token."
329
  msgstr ""
330
 
331
- #: includes/class-builder-fields.php:92
332
  msgid "Constant Contact List"
333
  msgstr ""
334
 
335
- #: includes/class-builder-fields.php:107 includes/class-settings.php:301
336
  msgid "Add subscribers to"
337
  msgstr ""
338
 
339
- #: includes/class-builder-fields.php:110
340
  msgid "No List Selected"
341
  msgstr ""
342
 
343
- #: includes/class-builder-fields.php:130
344
  msgid "Form Description"
345
  msgstr ""
346
 
347
- #: includes/class-builder-fields.php:138
348
  msgid ""
349
  "This message will display above the form fields, so use it as an opportunity "
350
  "to pitch your email list. Tell visitors why they should subscribe to your "
@@ -352,241 +352,343 @@ msgid ""
352
  "coupons, and more."
353
  msgstr ""
354
 
355
- #: includes/class-builder-fields.php:158
356
  msgid "Form Options"
357
  msgstr ""
358
 
359
- #: includes/class-builder-fields.php:166
360
  msgid "Button text"
361
  msgstr ""
362
 
363
- #: includes/class-builder-fields.php:169
364
  msgid "Sign up"
365
  msgstr ""
366
 
367
- #: includes/class-builder-fields.php:173
368
  msgid "Success message"
369
  msgstr ""
370
 
371
- #: includes/class-builder-fields.php:176
372
  msgid "Your information has been submitted"
373
  msgstr ""
374
 
375
- #: includes/class-builder-fields.php:180
376
  msgid "Submission behavior"
377
  msgstr ""
378
 
379
- #: includes/class-builder-fields.php:187
380
  msgid "Redirect URL"
381
  msgstr ""
382
 
383
- #: includes/class-builder-fields.php:190
384
  msgid "Leave blank to keep users on the current page."
385
  msgstr ""
386
 
387
- #: includes/class-builder-fields.php:195
388
  msgid "No page refresh"
389
  msgstr ""
390
 
391
- #: includes/class-builder-fields.php:198
392
  msgid ""
393
  "Enable form submission without a page refresh. This option overrides the "
394
  "Redirect URL choice above."
395
  msgstr ""
396
 
397
- #: includes/class-builder-fields.php:220
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
398
  msgid ""
399
  "Enabling this option will require users to check a box to be added to your "
400
  "list."
401
  msgstr ""
402
 
403
- #: includes/class-builder-fields.php:226
404
  msgid "Learn more"
405
  msgstr ""
406
 
407
- #: includes/class-builder-fields.php:231
408
  msgid "Email opt-in"
409
  msgstr ""
410
 
411
- #: includes/class-builder-fields.php:254
412
  msgid "Enable email subscriber opt-in"
413
  msgstr ""
414
 
415
- #: includes/class-builder-fields.php:256
416
  msgid "Adds an opt-in to the bottom of your form."
417
  msgstr ""
418
 
419
- #: includes/class-builder-fields.php:276
420
  msgid "Add a checkbox so subscribers can opt-in to your email list."
421
  msgstr ""
422
 
423
- #: includes/class-builder-fields.php:278
424
  msgid "(For use with Contact Us form)"
425
  msgstr ""
426
 
427
- #: includes/class-builder-fields.php:281
428
  msgid "Opt-in checkbox"
429
  msgstr ""
430
 
431
- #: includes/class-builder-fields.php:299
432
  msgid "Your Business Name"
433
  msgstr ""
434
 
435
- #: includes/class-builder-fields.php:302 includes/class-settings.php:322
436
  msgid "Opt-in Affirmation"
437
  msgstr ""
438
 
439
- #: includes/class-builder-fields.php:306
440
  #, php-format
441
  msgid ""
442
  "Example: Yes, I would like to receive emails from %s. (You can unsubscribe "
443
  "anytime)"
444
  msgstr ""
445
 
446
- #: includes/class-builder-fields.php:322
447
  msgid "Form Fields"
448
  msgstr ""
449
 
450
- #: includes/class-builder-fields.php:331
451
  msgid "Add Fields"
452
  msgstr ""
453
 
454
- #: includes/class-builder-fields.php:337
455
  msgid ""
456
  "Create a field for each piece of information you want to collect. Good "
457
  "basics include email address, first name, and last name."
458
  msgstr ""
459
 
460
- #: includes/class-builder-fields.php:348
461
  msgid "Field {#}"
462
  msgstr ""
463
 
464
- #: includes/class-builder-fields.php:349
465
  msgid "Add Another Field"
466
  msgstr ""
467
 
468
- #: includes/class-builder-fields.php:350
469
  msgid "Remove Field"
470
  msgstr ""
471
 
472
- #: includes/class-builder-fields.php:362
473
  msgid "A brief description of this field (optional)"
474
  msgstr ""
475
 
476
- #: includes/class-builder-fields.php:367
477
  msgid "Email (required)"
478
  msgstr ""
479
 
480
- #: includes/class-builder-fields.php:368
481
  msgid "c.contact@example.com"
482
  msgstr ""
483
 
484
- #: includes/class-builder-fields.php:371
485
  msgid "First Name"
486
  msgstr ""
487
 
488
- #: includes/class-builder-fields.php:372
489
  msgid "John"
490
  msgstr ""
491
 
492
- #: includes/class-builder-fields.php:375
493
  msgid "Last Name"
494
  msgstr ""
495
 
496
- #: includes/class-builder-fields.php:376
497
  msgid "Smith"
498
  msgstr ""
499
 
500
- #: includes/class-builder-fields.php:379
501
  msgid "Phone Number"
502
  msgstr ""
503
 
504
- #: includes/class-builder-fields.php:380
505
  msgid "(555) 272-3342"
506
  msgstr ""
507
 
508
- #: includes/class-builder-fields.php:383
509
  msgid "Address"
510
  msgstr ""
511
 
512
- #: includes/class-builder-fields.php:384
513
  msgid "4115 S. Main Rd."
514
  msgstr ""
515
 
516
- #: includes/class-builder-fields.php:387
517
  msgid "Job Title"
518
  msgstr ""
519
 
520
- #: includes/class-builder-fields.php:388
521
  msgid "Project Manager"
522
  msgstr ""
523
 
524
- #: includes/class-builder-fields.php:391
525
  msgid "Company"
526
  msgstr ""
527
 
528
- #: includes/class-builder-fields.php:392
529
  msgid "Acme Manufacturing"
530
  msgstr ""
531
 
532
- #: includes/class-builder-fields.php:395
533
  msgid "Website"
534
  msgstr ""
535
 
536
- #: includes/class-builder-fields.php:396
537
  msgid "http://www.example.com"
538
  msgstr ""
539
 
540
- #: includes/class-builder-fields.php:411
541
  msgid "Custom Text Field"
542
  msgstr ""
543
 
544
- #: includes/class-builder-fields.php:412
545
  msgid "A custom text field"
546
  msgstr ""
547
 
548
- #: includes/class-builder-fields.php:415
549
  msgid "Custom Text Area"
550
  msgstr ""
551
 
552
- #: includes/class-builder-fields.php:416
553
  msgid "A large custom text field"
554
  msgstr ""
555
 
556
- #: includes/class-builder-fields.php:451
557
  msgid "Select a Field"
558
  msgstr ""
559
 
560
- #: includes/class-builder-fields.php:462
561
  msgid "Field Label"
562
  msgstr ""
563
 
564
- #: includes/class-builder-fields.php:465
565
  msgid "Email"
566
  msgstr ""
567
 
568
- #: includes/class-builder-fields.php:470
569
  msgid "Field Description"
570
  msgstr ""
571
 
572
- #: includes/class-builder-fields.php:474
573
  msgid "Ex: Enter email address"
574
  msgstr ""
575
 
576
- #: includes/class-builder-fields.php:480
577
  msgid "Required"
578
  msgstr ""
579
 
580
- #: includes/class-builder-fields.php:504
581
  msgid "Shortcode to use"
582
  msgstr ""
583
 
584
- #: includes/class-builder-fields.php:507
585
  msgid ""
586
  "Shortcode to embed - <em><small>You can copy and paste this in a post to "
587
  "display your form.</small></em>"
588
  msgstr ""
589
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
590
  #: includes/class-builder.php:200
591
  msgid "Please add an email field to continue."
592
  msgstr ""
@@ -646,7 +748,7 @@ msgid ""
646
  msgstr ""
647
 
648
  #: includes/class-builder.php:360 includes/class-builder.php:361
649
- #: includes/class-connect.php:253
650
  msgid "Connect Plugin"
651
  msgstr ""
652
 
@@ -727,7 +829,7 @@ msgstr ""
727
  msgid "Cron spawn ok"
728
  msgstr ""
729
 
730
- #: includes/class-connect.php:133 includes/class-connect.php:196
731
  msgid "Disconnect"
732
  msgstr ""
733
 
@@ -735,34 +837,34 @@ msgstr ""
735
  msgid "Connect Now"
736
  msgstr ""
737
 
738
- #: includes/class-connect.php:176
739
  msgid "Are you sure you want to disconnect?"
740
  msgstr ""
741
 
742
- #: includes/class-connect.php:181 includes/class-logging.php:130
743
  #: includes/class-notification-content.php:109
744
  #: includes/class-notification-content.php:139 includes/class-optin.php:129
745
- #: includes/class-settings.php:781
746
  msgid "Constant Contact logo"
747
  msgstr ""
748
 
749
- #: includes/class-connect.php:188
750
  msgid "Account connected."
751
  msgstr ""
752
 
753
- #: includes/class-connect.php:190
754
  msgid "Plugin connected to Constant Contact."
755
  msgstr ""
756
 
757
- #: includes/class-connect.php:202
758
  msgid "Your account is connected! Now, add a new form."
759
  msgstr ""
760
 
761
- #: includes/class-connect.php:210
762
  msgid "Please help to improve this plugin."
763
  msgstr ""
764
 
765
- #: includes/class-connect.php:213
766
  #, php-format
767
  msgid ""
768
  "Allow Constant Contact to use Google Analytics&trade; to track your usage "
@@ -770,52 +872,52 @@ msgid ""
770
  "Settings page. See our %s."
771
  msgstr ""
772
 
773
- #: includes/class-connect.php:213
774
  msgid "Privacy Statement"
775
  msgstr ""
776
 
777
- #: includes/class-connect.php:215
778
  msgid "Allow"
779
  msgstr ""
780
 
781
- #: includes/class-connect.php:216 includes/class-notification-content.php:148
782
  msgid "Dismiss"
783
  msgstr ""
784
 
785
- #: includes/class-connect.php:228
786
  msgid "There was an error connecting your account. Please try again."
787
  msgstr ""
788
 
789
- #: includes/class-connect.php:234
790
  msgid ""
791
  "Get the most out of this plugin &mdash; use it with an active Constant "
792
  "Contact account. By connecting to an account, you'll be able to engage "
793
  "visitors through email marketing and turn more of them into customers."
794
  msgstr ""
795
 
796
- #: includes/class-connect.php:239
797
  msgid "Connect your Constant Contact account."
798
  msgstr ""
799
 
800
- #: includes/class-connect.php:240
801
  msgid "By connecting, you authorize this plugin to access your account."
802
  msgstr ""
803
 
804
- #: includes/class-connect.php:260
805
  msgid "No Constant Contact account? Try us out."
806
  msgstr ""
807
 
808
- #: includes/class-connect.php:261
809
  msgid ""
810
  "Create professional emails so you can nurture great relationships with new "
811
  "contacts even after they leave your website. Sign up for a free 60-day trial."
812
  msgstr ""
813
 
814
- #: includes/class-connect.php:286
815
  msgid "NOTE: "
816
  msgstr ""
817
 
818
- #: includes/class-connect.php:286
819
  msgid ""
820
  "It's possible to use the plugin without connecting to a Constant Contact "
821
  "account. In this case, all information collected by the forms will be "
@@ -856,7 +958,7 @@ msgstr ""
856
  msgid "New Form"
857
  msgstr ""
858
 
859
- #: includes/class-cpts.php:70 includes/class-display.php:615
860
  msgid "Edit Form"
861
  msgstr ""
862
 
@@ -1087,103 +1189,103 @@ msgstr ""
1087
  msgid "%1$s (last modified %2$s ago)"
1088
  msgstr ""
1089
 
1090
- #: includes/class-display.php:330
1091
  msgid "Constant Contact Use."
1092
  msgstr ""
1093
 
1094
- #: includes/class-display.php:442 includes/class-display.php:1295
1095
  msgid "Error: Please correct your entry."
1096
  msgstr ""
1097
 
1098
- #: includes/class-display.php:444
1099
  msgid " Error: Please fill out this field."
1100
  msgstr ""
1101
 
1102
- #: includes/class-display.php:870
1103
  msgid "Send"
1104
  msgstr ""
1105
 
1106
- #: includes/class-display.php:985
1107
  msgid "Street Address"
1108
  msgstr ""
1109
 
1110
- #: includes/class-display.php:986
1111
  msgid "Address Line 2"
1112
  msgstr ""
1113
 
1114
- #: includes/class-display.php:987
1115
  msgid "City"
1116
  msgstr ""
1117
 
1118
- #: includes/class-display.php:988
1119
  msgid "State"
1120
  msgstr ""
1121
 
1122
- #: includes/class-display.php:989
1123
  msgid "ZIP Code"
1124
  msgstr ""
1125
 
1126
- #: includes/class-display.php:1054
1127
  msgid "Month"
1128
  msgstr ""
1129
 
1130
- #: includes/class-display.php:1055
1131
  msgid "Day"
1132
  msgstr ""
1133
 
1134
- #: includes/class-display.php:1056
1135
  msgid "Year"
1136
  msgstr ""
1137
 
1138
- #: includes/class-display.php:1180
1139
  msgid "January"
1140
  msgstr ""
1141
 
1142
- #: includes/class-display.php:1181
1143
  msgid "February"
1144
  msgstr ""
1145
 
1146
- #: includes/class-display.php:1182
1147
  msgid "March"
1148
  msgstr ""
1149
 
1150
- #: includes/class-display.php:1183
1151
  msgid "April"
1152
  msgstr ""
1153
 
1154
- #: includes/class-display.php:1184
1155
  msgid "May"
1156
  msgstr ""
1157
 
1158
- #: includes/class-display.php:1185
1159
  msgid "June"
1160
  msgstr ""
1161
 
1162
- #: includes/class-display.php:1186
1163
  msgid "July "
1164
  msgstr ""
1165
 
1166
- #: includes/class-display.php:1187
1167
  msgid "August"
1168
  msgstr ""
1169
 
1170
- #: includes/class-display.php:1188
1171
  msgid "September"
1172
  msgstr ""
1173
 
1174
- #: includes/class-display.php:1189
1175
  msgid "October"
1176
  msgstr ""
1177
 
1178
- #: includes/class-display.php:1190
1179
  msgid "November"
1180
  msgstr ""
1181
 
1182
- #: includes/class-display.php:1191
1183
  msgid "December"
1184
  msgstr ""
1185
 
1186
- #: includes/class-display.php:1362
1187
  #, php-format
1188
  msgid ""
1189
  "By submitting this form, you are consenting to receive marketing emails "
@@ -1191,23 +1293,23 @@ msgid ""
1191
  "the SafeUnsubscribe&reg; link, found at the bottom of every email. %s"
1192
  msgstr ""
1193
 
1194
- #: includes/class-display.php:1368
1195
  msgid "Emails are serviced by Constant Contact"
1196
  msgstr ""
1197
 
1198
- #: includes/class-lists.php:81
1199
  msgid "List Information"
1200
  msgstr ""
1201
 
1202
- #: includes/class-lists.php:171
1203
  msgid "List information will populate upon saving."
1204
  msgstr ""
1205
 
1206
- #: includes/class-lists.php:832
1207
  msgid "You already have a list with that name."
1208
  msgstr ""
1209
 
1210
- #: includes/class-lists.php:862
1211
  msgid "Sync Lists with Constant Contact"
1212
  msgstr ""
1213
 
@@ -1255,24 +1357,24 @@ msgstr ""
1255
  msgid "Delete logs"
1256
  msgstr ""
1257
 
1258
- #: includes/class-mail.php:269
1259
  #, php-format
1260
  msgid "Duplicate send mail for: %1$s and: %2$s"
1261
  msgstr ""
1262
 
1263
- #: includes/class-mail.php:293
1264
  msgid "Your Constant Contact Forms plugin has captured new information."
1265
  msgstr ""
1266
 
1267
- #: includes/class-mail.php:297
1268
  msgid "Form title: "
1269
  msgstr ""
1270
 
1271
- #: includes/class-mail.php:298
1272
  msgid "Form information: "
1273
  msgstr ""
1274
 
1275
- #: includes/class-mail.php:304
1276
  #, php-format
1277
  msgid ""
1278
  "Email marketing is a great way to stay connected and engage with visitors "
@@ -1280,30 +1382,30 @@ msgid ""
1280
  "pn=miwordpress%s to sign up for a Free Trial."
1281
  msgstr ""
1282
 
1283
- #: includes/class-mail.php:341
1284
  msgid "Constant Contact Forms Notification"
1285
  msgstr ""
1286
 
1287
- #: includes/class-mail.php:429
1288
  #, php-format
1289
  msgid ""
1290
  "%sNote:%s You have disabled admin email notifications under the plugin "
1291
  "settings, but are receiving this email because of the following reason."
1292
  msgstr ""
1293
 
1294
- #: includes/class-mail.php:452
1295
  msgid "Submitted to Constant Contact:"
1296
  msgstr ""
1297
 
1298
- #: includes/class-mail.php:458
1299
  msgid "NO (Constant Contact list not selected for this form)"
1300
  msgstr ""
1301
 
1302
- #: includes/class-mail.php:464
1303
  msgid "NO (User did not select the Email Opt-in checkbox)"
1304
  msgstr ""
1305
 
1306
- #: includes/class-mail.php:464
1307
  msgid ""
1308
  "You can disable this under Form options. Email Opt-in isn't required to add "
1309
  "subscribers into your account"
@@ -1362,55 +1464,55 @@ msgid ""
1362
  "implement via <a href=\"%s\">Settings</a>"
1363
  msgstr ""
1364
 
1365
- #: includes/class-notifications.php:420
1366
  msgid "Dismiss this notice."
1367
  msgstr ""
1368
 
1369
- #: includes/class-optin.php:137 includes/class-settings.php:789
1370
  msgid "Agree"
1371
  msgstr ""
1372
 
1373
- #: includes/class-optin.php:138 includes/class-settings.php:790
1374
  msgid "Disagree"
1375
  msgstr ""
1376
 
1377
- #: includes/class-process-form.php:107 includes/class-process-form.php:660
1378
  msgid "There was an error sending your form."
1379
  msgstr ""
1380
 
1381
- #: includes/class-process-form.php:118 includes/class-process-form.php:680
1382
  msgid "Your information has been submitted."
1383
  msgstr ""
1384
 
1385
- #: includes/class-process-form.php:135 includes/class-process-form.php:256
1386
- #: includes/class-process-form.php:697
1387
  msgid ""
1388
  "We had trouble processing your submission. Please review your entries and "
1389
  "try again."
1390
  msgstr ""
1391
 
1392
- #: includes/class-process-form.php:186
1393
  msgid "No Constant Contact Forms form ID provided"
1394
  msgstr ""
1395
 
1396
- #: includes/class-process-form.php:194
1397
  msgid "No form verify value provided"
1398
  msgstr ""
1399
 
1400
- #: includes/class-process-form.php:202 includes/class-process-form.php:244
1401
  msgid "We do no think you are human"
1402
  msgstr ""
1403
 
1404
- #: includes/class-process-form.php:209
1405
  msgid "Please properly fill out all required fields"
1406
  msgstr ""
1407
 
1408
- #: includes/class-process-form.php:228
1409
  msgid "Failed reCAPTCHA check"
1410
  msgstr ""
1411
 
1412
- #: includes/class-process-form.php:265 includes/class-process-form.php:274
1413
- #: includes/class-process-form.php:283
1414
  msgid ""
1415
  "We had trouble processing your submission. Make sure you haven't changed the "
1416
  "required Form ID and try again."
@@ -1507,32 +1609,48 @@ msgid "Secret Key"
1507
  msgstr ""
1508
 
1509
  #: includes/class-settings.php:369
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1510
  msgid "Support"
1511
  msgstr ""
1512
 
1513
- #: includes/class-settings.php:372
1514
  msgid "Enable logging for debugging purposes."
1515
  msgstr ""
1516
 
1517
- #: includes/class-settings.php:373
1518
  msgid ""
1519
  "This option will turn on some logging functionality that can be used to "
1520
  "deduce sources of issues with the use of Constant Contact Forms plugin."
1521
  msgstr ""
1522
 
1523
- #: includes/class-settings.php:391
1524
  msgid "Add a checkbox to the comment field in your posts"
1525
  msgstr ""
1526
 
1527
- #: includes/class-settings.php:392
1528
  msgid "Add a checkbox to the main WordPress login page"
1529
  msgstr ""
1530
 
1531
- #: includes/class-settings.php:397
1532
  msgid "Add a checkbox to the WordPress user registration page"
1533
  msgstr ""
1534
 
1535
- #: includes/class-settings.php:486
1536
  msgid "Sign up to our newsletter."
1537
  msgstr ""
1538
 
3
  msgstr ""
4
  "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
5
  "Project-Id-Version: Constant Contact Forms for WordPress\n"
6
+ "POT-Creation-Date: 2018-07-27 11:19-0500\n"
7
  "PO-Revision-Date: 2017-01-12 14:46-0600\n"
8
  "Last-Translator: Michael Beckwith <michael.d.beckwith@gmail.com>\n"
9
  "Language-Team: Constant Contact\n"
29
  msgid "Constant Contact"
30
  msgstr ""
31
 
32
+ #: constant-contact-forms.php:393
33
  msgid ""
34
  "Constant Contact Forms requires PHP 5.4 or higher. Your hosting provider or "
35
  "website administrator should be able to assist in updating your PHP version."
36
  msgstr ""
37
 
38
+ #: constant-contact-forms.php:725
39
  msgid "Error loading license."
40
  msgstr ""
41
 
42
+ #: includes/class-admin-pages.php:74
43
  msgid "This is a sample help header"
44
  msgstr ""
45
 
46
+ #: includes/class-admin-pages.php:75
47
  msgid "This is some sample help text."
48
  msgstr ""
49
 
50
+ #: includes/class-admin-pages.php:78
51
  msgid "This is another sample header"
52
  msgstr ""
53
 
54
+ #: includes/class-admin-pages.php:79
55
  msgid "This is also some sample help text."
56
  msgstr ""
57
 
58
+ #: includes/class-admin-pages.php:102
59
  msgid "Is this a sample question?"
60
  msgstr ""
61
 
62
+ #: includes/class-admin-pages.php:103
63
  msgid "This is a sample answer"
64
  msgstr ""
65
 
66
+ #: includes/class-admin-pages.php:106
67
  msgid "This is also a sample question"
68
  msgstr ""
69
 
70
+ #: includes/class-admin-pages.php:107
71
  msgid "This is another sample answer"
72
  msgstr ""
73
 
74
+ #: includes/class-admin-pages.php:120
75
  msgid "Help / FAQ"
76
  msgstr ""
77
 
78
+ #: includes/class-admin-pages.php:127
79
  msgid "Help"
80
  msgstr ""
81
 
82
+ #: includes/class-admin-pages.php:161
83
  msgid "FAQ"
84
  msgstr ""
85
 
86
+ #: includes/class-admin-pages.php:225
87
  #: includes/class-notification-content.php:53
88
  msgid "Constant Contact Forms"
89
  msgstr ""
90
 
91
+ #: includes/class-admin-pages.php:227
92
  msgid ""
93
  "This plugin makes it fast and easy to capture all kinds of visitor "
94
  "information right from your WordPress site—even if you don't have a Constant "
95
  "Contact account."
96
  msgstr ""
97
 
98
+ #: includes/class-admin-pages.php:230
99
  msgid ""
100
  "Whether you're looking to collect email addresses, contact info, or visitor "
101
  "feedback, you can customize your forms with data fields that work best for "
102
  "you."
103
  msgstr ""
104
 
105
+ #: includes/class-admin-pages.php:233
106
  msgid ""
107
  "Quickly create different types of forms that are clear, simple, and mobile-"
108
  "optimized."
109
  msgstr ""
110
 
111
+ #: includes/class-admin-pages.php:234
112
  msgid ""
113
  "Choose forms that automatically select the theme and style of your WordPress "
114
  "site."
115
  msgstr ""
116
 
117
+ #: includes/class-admin-pages.php:235
118
  msgid ""
119
  "Customize the form data fields, so you can tailor the type of information "
120
  "you collect."
121
  msgstr ""
122
 
123
+ #: includes/class-admin-pages.php:242
124
  msgid "Collecting email addresses with the plugin?"
125
  msgstr ""
126
 
127
+ #: includes/class-admin-pages.php:243
128
  msgid "Turn those contacts into customers."
129
  msgstr ""
130
 
131
+ #: includes/class-admin-pages.php:246
132
  msgid ""
133
  "Nurture your new contacts with a Constant Contact email marketing account "
134
  "even after they've left your website. Sign up for a 60-day trial account* "
135
  "and you can:"
136
  msgstr ""
137
 
138
+ #: includes/class-admin-pages.php:249
139
  msgid "Seamlessly add new contacts to mailing lists."
140
  msgstr ""
141
 
142
+ #: includes/class-admin-pages.php:250
143
  msgid "Create and send professional emails."
144
  msgstr ""
145
 
146
+ #: includes/class-admin-pages.php:251
147
  msgid "Get expert marketing help and support."
148
  msgstr ""
149
 
150
+ #: includes/class-admin-pages.php:256 includes/class-connect.php:254
151
  msgid "Try us Free"
152
  msgstr ""
153
 
154
+ #: includes/class-admin-pages.php:259
155
  msgid "Already have a Constant Contact account?"
156
  msgstr ""
157
 
158
+ #: includes/class-admin-pages.php:261
159
  msgid "Connect the plugin."
160
  msgstr ""
161
 
162
+ #: includes/class-admin-pages.php:265
163
  msgid ""
164
  "NOTE: You can use the Constant Contact Form plugin without a Constant "
165
  "Contact account. All information collected by the forms will be individually "
166
  "emailed to your site admin."
167
  msgstr ""
168
 
169
+ #: includes/class-admin-pages.php:272 includes/class-connect.php:272
170
  msgid "Sign Up"
171
  msgstr ""
172
 
173
+ #: includes/class-admin-pages.php:273 includes/class-connect.php:260
174
  msgid "Email marketing tips delivered to your inbox."
175
  msgstr ""
176
 
177
+ #: includes/class-admin-pages.php:274 includes/class-connect.php:261
178
  msgid ""
179
  "Ready to grow with email marketing? Subscribe now for the latest tips and "
180
  "industry best practices to create great-looking emails that work."
181
  msgstr ""
182
 
183
+ #: includes/class-admin-pages.php:275 includes/class-connect.php:262
184
  msgid "Enter your email address"
185
  msgstr ""
186
 
187
+ #: includes/class-admin-pages.php:282 includes/class-connect.php:269
188
  #, php-format
189
  msgid ""
190
  "By submitting this form, you agree to receive periodic product announcements "
193
  "email. Constant Contact, Inc, 1601 Trapelo Road, Waltham, MA 02451, %s"
194
  msgstr ""
195
 
196
+ #: includes/class-admin-pages.php:292
197
  msgid "Powerful Email Marketing, Made Simple."
198
  msgstr ""
199
 
200
+ #: includes/class-admin-pages.php:295
201
  msgid "Create professional emails that bring customers to your door"
202
  msgstr ""
203
 
204
+ #: includes/class-admin-pages.php:299
205
  msgid ""
206
  "Email marketing is good for your business. $44-back-for-every-$1-spent kind "
207
  "of good.* And with the Constant Contact for WordPress plugin, you can "
209
  "visitors long after they've left."
210
  msgstr ""
211
 
212
+ #: includes/class-admin-pages.php:303
213
  msgid "GPLv3 license"
214
  msgstr ""
215
 
216
+ #: includes/class-admin-pages.php:307
217
  #, php-format
218
  msgid "This software is released under a modified %s."
219
  msgstr ""
220
 
221
+ #: includes/class-admin-pages.php:313
222
  msgid "*Direct Marketing Association 2013 Statistical Fact Book"
223
  msgstr ""
224
 
225
+ #: includes/class-admin-pages.php:321
226
  msgid "Easily Add Forms"
227
  msgstr ""
228
 
229
+ #: includes/class-admin-pages.php:324
230
  msgctxt "add forms alt text"
231
  msgid "add forms screenshot"
232
  msgstr ""
233
 
234
+ #: includes/class-admin-pages.php:327
235
  msgid ""
236
  "Create forms that automatically select the theme and styling of your "
237
  "WordPress site for a perfect match. "
238
  msgstr ""
239
 
240
+ #: includes/class-admin-pages.php:333
241
  msgid "Stay Connected With Your WordPress Visitors"
242
  msgstr ""
243
 
244
+ #: includes/class-admin-pages.php:336
245
  msgctxt "stay connected alt text"
246
  msgid "stay connected screenshot"
247
  msgstr ""
248
 
249
+ #: includes/class-admin-pages.php:339
250
  msgid ""
251
  "Form completions from site visitors are conveniently added to your Constant "
252
  "Contact email list."
253
  msgstr ""
254
 
255
+ #: includes/class-admin-pages.php:359
256
  msgid "Constant Contact Forms - License"
257
  msgstr ""
258
 
259
  #: includes/class-admin.php:116 includes/class-admin.php:117
260
+ #: includes/class-admin.php:366
261
  msgid "About"
262
  msgstr ""
263
 
264
  #: includes/class-admin.php:125 includes/class-admin.php:126
265
+ #: includes/class-admin.php:367
266
  msgid "License"
267
  msgstr ""
268
 
269
+ #: includes/class-admin.php:210 includes/class-settings.php:731
270
  msgid "Settings updated."
271
  msgstr ""
272
 
274
  msgid "Description"
275
  msgstr ""
276
 
277
+ #: includes/class-admin.php:249 includes/class-builder-fields.php:667
278
  msgid "Shortcode"
279
  msgstr ""
280
 
283
  msgstr ""
284
 
285
  #: includes/class-admin.php:293
286
+ msgid "No associated list"
287
  msgstr ""
288
 
289
  #: includes/class-admin.php:309
294
  msgid "None available"
295
  msgstr ""
296
 
297
+ #: includes/class-admin.php:363
298
  msgid "Check out the official WordPress plugin from @constantcontact :"
299
  msgstr ""
300
 
301
+ #: includes/class-admin.php:379
302
  msgid "Spread the word!"
303
  msgstr ""
304
 
305
+ #: includes/class-admin.php:455
306
  msgid "You have unsaved changes."
307
  msgstr ""
308
 
309
+ #: includes/class-admin.php:456
310
  msgid "move up"
311
  msgstr ""
312
 
313
+ #: includes/class-admin.php:457
314
  msgid "move down"
315
  msgstr ""
316
 
328
  "new token."
329
  msgstr ""
330
 
331
+ #: includes/class-builder-fields.php:95
332
  msgid "Constant Contact List"
333
  msgstr ""
334
 
335
+ #: includes/class-builder-fields.php:110 includes/class-settings.php:301
336
  msgid "Add subscribers to"
337
  msgstr ""
338
 
339
+ #: includes/class-builder-fields.php:113
340
  msgid "No List Selected"
341
  msgstr ""
342
 
343
+ #: includes/class-builder-fields.php:133 includes/class-builder-fields.php:234
344
  msgid "Form Description"
345
  msgstr ""
346
 
347
+ #: includes/class-builder-fields.php:141
348
  msgid ""
349
  "This message will display above the form fields, so use it as an opportunity "
350
  "to pitch your email list. Tell visitors why they should subscribe to your "
352
  "coupons, and more."
353
  msgstr ""
354
 
355
+ #: includes/class-builder-fields.php:161
356
  msgid "Form Options"
357
  msgstr ""
358
 
359
+ #: includes/class-builder-fields.php:169
360
  msgid "Button text"
361
  msgstr ""
362
 
363
+ #: includes/class-builder-fields.php:172
364
  msgid "Sign up"
365
  msgstr ""
366
 
367
+ #: includes/class-builder-fields.php:176
368
  msgid "Success message"
369
  msgstr ""
370
 
371
+ #: includes/class-builder-fields.php:179
372
  msgid "Your information has been submitted"
373
  msgstr ""
374
 
375
+ #: includes/class-builder-fields.php:183
376
  msgid "Submission behavior"
377
  msgstr ""
378
 
379
+ #: includes/class-builder-fields.php:190
380
  msgid "Redirect URL"
381
  msgstr ""
382
 
383
+ #: includes/class-builder-fields.php:193
384
  msgid "Leave blank to keep users on the current page."
385
  msgstr ""
386
 
387
+ #: includes/class-builder-fields.php:198
388
  msgid "No page refresh"
389
  msgstr ""
390
 
391
+ #: includes/class-builder-fields.php:201
392
  msgid ""
393
  "Enable form submission without a page refresh. This option overrides the "
394
  "Redirect URL choice above."
395
  msgstr ""
396
 
397
+ #: includes/class-builder-fields.php:217
398
+ msgid "Form Design"
399
+ msgstr ""
400
+
401
+ #: includes/class-builder-fields.php:224 includes/class-builder-fields.php:278
402
+ msgid "Background Color"
403
+ msgstr ""
404
+
405
+ #: includes/class-builder-fields.php:228
406
+ msgid "Applies to the whole form."
407
+ msgstr ""
408
+
409
+ #: includes/class-builder-fields.php:240 includes/class-builder-fields.php:260
410
+ msgid "Font Size"
411
+ msgstr ""
412
+
413
+ #: includes/class-builder-fields.php:248 includes/class-builder-fields.php:268
414
+ msgid "Font Color"
415
+ msgstr ""
416
+
417
+ #: includes/class-builder-fields.php:254
418
+ msgid "Form Submit Button"
419
+ msgstr ""
420
+
421
+ #: includes/class-builder-fields.php:272
422
+ msgid "Choose a color for the submit button text."
423
+ msgstr ""
424
+
425
+ #: includes/class-builder-fields.php:282
426
+ msgid "Choose a color for the submit button background."
427
+ msgstr ""
428
+
429
+ #: includes/class-builder-fields.php:296
430
+ msgid "Input Design"
431
+ msgstr ""
432
+
433
+ #: includes/class-builder-fields.php:303
434
+ msgid "Form Padding"
435
+ msgstr ""
436
+
437
+ #: includes/class-builder-fields.php:307
438
+ msgid ""
439
+ "Enter padding values in number of pixels. Padding will be applied to four "
440
+ "sides of the form."
441
+ msgstr ""
442
+
443
+ #: includes/class-builder-fields.php:312
444
+ msgid "Top"
445
+ msgstr ""
446
+
447
+ #: includes/class-builder-fields.php:322
448
+ msgid "Right"
449
+ msgstr ""
450
+
451
+ #: includes/class-builder-fields.php:332
452
+ msgid "Bottom"
453
+ msgstr ""
454
+
455
+ #: includes/class-builder-fields.php:342
456
+ msgid "Left"
457
+ msgstr ""
458
+
459
+ #: includes/class-builder-fields.php:352
460
+ msgid "Custom Classes"
461
+ msgstr ""
462
+
463
+ #: includes/class-builder-fields.php:356
464
+ msgid ""
465
+ "Set custom CSS class(es) for inputs. Separate multiple classes with spaces."
466
+ msgstr ""
467
+
468
+ #: includes/class-builder-fields.php:362 includes/class-settings.php:384
469
+ msgid "Label Placement"
470
+ msgstr ""
471
+
472
+ #: includes/class-builder-fields.php:373
473
+ msgid "Set the position for labels for inputs."
474
+ msgstr ""
475
+
476
+ #: includes/class-builder-fields.php:391
477
  msgid ""
478
  "Enabling this option will require users to check a box to be added to your "
479
  "list."
480
  msgstr ""
481
 
482
+ #: includes/class-builder-fields.php:397
483
  msgid "Learn more"
484
  msgstr ""
485
 
486
+ #: includes/class-builder-fields.php:402
487
  msgid "Email opt-in"
488
  msgstr ""
489
 
490
+ #: includes/class-builder-fields.php:425
491
  msgid "Enable email subscriber opt-in"
492
  msgstr ""
493
 
494
+ #: includes/class-builder-fields.php:427
495
  msgid "Adds an opt-in to the bottom of your form."
496
  msgstr ""
497
 
498
+ #: includes/class-builder-fields.php:447
499
  msgid "Add a checkbox so subscribers can opt-in to your email list."
500
  msgstr ""
501
 
502
+ #: includes/class-builder-fields.php:449
503
  msgid "(For use with Contact Us form)"
504
  msgstr ""
505
 
506
+ #: includes/class-builder-fields.php:452
507
  msgid "Opt-in checkbox"
508
  msgstr ""
509
 
510
+ #: includes/class-builder-fields.php:470
511
  msgid "Your Business Name"
512
  msgstr ""
513
 
514
+ #: includes/class-builder-fields.php:473 includes/class-settings.php:322
515
  msgid "Opt-in Affirmation"
516
  msgstr ""
517
 
518
+ #: includes/class-builder-fields.php:477
519
  #, php-format
520
  msgid ""
521
  "Example: Yes, I would like to receive emails from %s. (You can unsubscribe "
522
  "anytime)"
523
  msgstr ""
524
 
525
+ #: includes/class-builder-fields.php:493
526
  msgid "Form Fields"
527
  msgstr ""
528
 
529
+ #: includes/class-builder-fields.php:502
530
  msgid "Add Fields"
531
  msgstr ""
532
 
533
+ #: includes/class-builder-fields.php:508
534
  msgid ""
535
  "Create a field for each piece of information you want to collect. Good "
536
  "basics include email address, first name, and last name."
537
  msgstr ""
538
 
539
+ #: includes/class-builder-fields.php:519
540
  msgid "Field {#}"
541
  msgstr ""
542
 
543
+ #: includes/class-builder-fields.php:520
544
  msgid "Add Another Field"
545
  msgstr ""
546
 
547
+ #: includes/class-builder-fields.php:521
548
  msgid "Remove Field"
549
  msgstr ""
550
 
551
+ #: includes/class-builder-fields.php:533
552
  msgid "A brief description of this field (optional)"
553
  msgstr ""
554
 
555
+ #: includes/class-builder-fields.php:538
556
  msgid "Email (required)"
557
  msgstr ""
558
 
559
+ #: includes/class-builder-fields.php:539
560
  msgid "c.contact@example.com"
561
  msgstr ""
562
 
563
+ #: includes/class-builder-fields.php:542
564
  msgid "First Name"
565
  msgstr ""
566
 
567
+ #: includes/class-builder-fields.php:543
568
  msgid "John"
569
  msgstr ""
570
 
571
+ #: includes/class-builder-fields.php:546
572
  msgid "Last Name"
573
  msgstr ""
574
 
575
+ #: includes/class-builder-fields.php:547
576
  msgid "Smith"
577
  msgstr ""
578
 
579
+ #: includes/class-builder-fields.php:550
580
  msgid "Phone Number"
581
  msgstr ""
582
 
583
+ #: includes/class-builder-fields.php:551
584
  msgid "(555) 272-3342"
585
  msgstr ""
586
 
587
+ #: includes/class-builder-fields.php:554
588
  msgid "Address"
589
  msgstr ""
590
 
591
+ #: includes/class-builder-fields.php:555
592
  msgid "4115 S. Main Rd."
593
  msgstr ""
594
 
595
+ #: includes/class-builder-fields.php:558
596
  msgid "Job Title"
597
  msgstr ""
598
 
599
+ #: includes/class-builder-fields.php:559
600
  msgid "Project Manager"
601
  msgstr ""
602
 
603
+ #: includes/class-builder-fields.php:562
604
  msgid "Company"
605
  msgstr ""
606
 
607
+ #: includes/class-builder-fields.php:563
608
  msgid "Acme Manufacturing"
609
  msgstr ""
610
 
611
+ #: includes/class-builder-fields.php:566
612
  msgid "Website"
613
  msgstr ""
614
 
615
+ #: includes/class-builder-fields.php:567
616
  msgid "http://www.example.com"
617
  msgstr ""
618
 
619
+ #: includes/class-builder-fields.php:582
620
  msgid "Custom Text Field"
621
  msgstr ""
622
 
623
+ #: includes/class-builder-fields.php:583
624
  msgid "A custom text field"
625
  msgstr ""
626
 
627
+ #: includes/class-builder-fields.php:586
628
  msgid "Custom Text Area"
629
  msgstr ""
630
 
631
+ #: includes/class-builder-fields.php:587
632
  msgid "A large custom text field"
633
  msgstr ""
634
 
635
+ #: includes/class-builder-fields.php:622
636
  msgid "Select a Field"
637
  msgstr ""
638
 
639
+ #: includes/class-builder-fields.php:633
640
  msgid "Field Label"
641
  msgstr ""
642
 
643
+ #: includes/class-builder-fields.php:636
644
  msgid "Email"
645
  msgstr ""
646
 
647
+ #: includes/class-builder-fields.php:641
648
  msgid "Field Description"
649
  msgstr ""
650
 
651
+ #: includes/class-builder-fields.php:645
652
  msgid "Ex: Enter email address"
653
  msgstr ""
654
 
655
+ #: includes/class-builder-fields.php:651
656
  msgid "Required"
657
  msgstr ""
658
 
659
+ #: includes/class-builder-fields.php:675
660
  msgid "Shortcode to use"
661
  msgstr ""
662
 
663
+ #: includes/class-builder-fields.php:678
664
  msgid ""
665
  "Shortcode to embed - <em><small>You can copy and paste this in a post to "
666
  "display your form.</small></em>"
667
  msgstr ""
668
 
669
+ #: includes/class-builder-fields.php:695
670
+ msgid "Email settings"
671
+ msgstr ""
672
+
673
+ #: includes/class-builder-fields.php:702
674
+ msgid "Email destination"
675
+ msgstr ""
676
+
677
+ #: includes/class-builder-fields.php:703
678
+ msgid ""
679
+ "Who should receive email notifications for this form. Separate multiple "
680
+ "emails by a comma. Leave blank to default to admin email."
681
+ msgstr ""
682
+
683
+ #: includes/class-builder-fields.php:709
684
+ msgid "Disable email notifications for this form?"
685
+ msgstr ""
686
+
687
+ #: includes/class-builder-fields.php:710
688
+ msgid ""
689
+ "Check this option to disable emails for this Constant Contact Forms form."
690
+ msgstr ""
691
+
692
  #: includes/class-builder.php:200
693
  msgid "Please add an email field to continue."
694
  msgstr ""
748
  msgstr ""
749
 
750
  #: includes/class-builder.php:360 includes/class-builder.php:361
751
+ #: includes/class-connect.php:244
752
  msgid "Connect Plugin"
753
  msgstr ""
754
 
829
  msgid "Cron spawn ok"
830
  msgstr ""
831
 
832
+ #: includes/class-connect.php:133 includes/class-connect.php:187
833
  msgid "Disconnect"
834
  msgstr ""
835
 
837
  msgid "Connect Now"
838
  msgstr ""
839
 
840
+ #: includes/class-connect.php:167
841
  msgid "Are you sure you want to disconnect?"
842
  msgstr ""
843
 
844
+ #: includes/class-connect.php:172 includes/class-logging.php:130
845
  #: includes/class-notification-content.php:109
846
  #: includes/class-notification-content.php:139 includes/class-optin.php:129
847
+ #: includes/class-settings.php:815
848
  msgid "Constant Contact logo"
849
  msgstr ""
850
 
851
+ #: includes/class-connect.php:179
852
  msgid "Account connected."
853
  msgstr ""
854
 
855
+ #: includes/class-connect.php:181
856
  msgid "Plugin connected to Constant Contact."
857
  msgstr ""
858
 
859
+ #: includes/class-connect.php:193
860
  msgid "Your account is connected! Now, add a new form."
861
  msgstr ""
862
 
863
+ #: includes/class-connect.php:201
864
  msgid "Please help to improve this plugin."
865
  msgstr ""
866
 
867
+ #: includes/class-connect.php:204
868
  #, php-format
869
  msgid ""
870
  "Allow Constant Contact to use Google Analytics&trade; to track your usage "
872
  "Settings page. See our %s."
873
  msgstr ""
874
 
875
+ #: includes/class-connect.php:204
876
  msgid "Privacy Statement"
877
  msgstr ""
878
 
879
+ #: includes/class-connect.php:206
880
  msgid "Allow"
881
  msgstr ""
882
 
883
+ #: includes/class-connect.php:207 includes/class-notification-content.php:148
884
  msgid "Dismiss"
885
  msgstr ""
886
 
887
+ #: includes/class-connect.php:219
888
  msgid "There was an error connecting your account. Please try again."
889
  msgstr ""
890
 
891
+ #: includes/class-connect.php:225
892
  msgid ""
893
  "Get the most out of this plugin &mdash; use it with an active Constant "
894
  "Contact account. By connecting to an account, you'll be able to engage "
895
  "visitors through email marketing and turn more of them into customers."
896
  msgstr ""
897
 
898
+ #: includes/class-connect.php:230
899
  msgid "Connect your Constant Contact account."
900
  msgstr ""
901
 
902
+ #: includes/class-connect.php:231
903
  msgid "By connecting, you authorize this plugin to access your account."
904
  msgstr ""
905
 
906
+ #: includes/class-connect.php:251
907
  msgid "No Constant Contact account? Try us out."
908
  msgstr ""
909
 
910
+ #: includes/class-connect.php:252
911
  msgid ""
912
  "Create professional emails so you can nurture great relationships with new "
913
  "contacts even after they leave your website. Sign up for a free 60-day trial."
914
  msgstr ""
915
 
916
+ #: includes/class-connect.php:277
917
  msgid "NOTE: "
918
  msgstr ""
919
 
920
+ #: includes/class-connect.php:277
921
  msgid ""
922
  "It's possible to use the plugin without connecting to a Constant Contact "
923
  "account. In this case, all information collected by the forms will be "
958
  msgid "New Form"
959
  msgstr ""
960
 
961
+ #: includes/class-cpts.php:70 includes/class-display.php:821
962
  msgid "Edit Form"
963
  msgstr ""
964
 
1189
  msgid "%1$s (last modified %2$s ago)"
1190
  msgstr ""
1191
 
1192
+ #: includes/class-display.php:490
1193
  msgid "Constant Contact Use."
1194
  msgstr ""
1195
 
1196
+ #: includes/class-display.php:617 includes/class-display.php:1689
1197
  msgid "Error: Please correct your entry."
1198
  msgstr ""
1199
 
1200
+ #: includes/class-display.php:619
1201
  msgid " Error: Please fill out this field."
1202
  msgstr ""
1203
 
1204
+ #: includes/class-display.php:1139
1205
  msgid "Send"
1206
  msgstr ""
1207
 
1208
+ #: includes/class-display.php:1255
1209
  msgid "Street Address"
1210
  msgstr ""
1211
 
1212
+ #: includes/class-display.php:1256
1213
  msgid "Address Line 2"
1214
  msgstr ""
1215
 
1216
+ #: includes/class-display.php:1257
1217
  msgid "City"
1218
  msgstr ""
1219
 
1220
+ #: includes/class-display.php:1258
1221
  msgid "State"
1222
  msgstr ""
1223
 
1224
+ #: includes/class-display.php:1259
1225
  msgid "ZIP Code"
1226
  msgstr ""
1227
 
1228
+ #: includes/class-display.php:1436
1229
  msgid "Month"
1230
  msgstr ""
1231
 
1232
+ #: includes/class-display.php:1437
1233
  msgid "Day"
1234
  msgstr ""
1235
 
1236
+ #: includes/class-display.php:1438
1237
  msgid "Year"
1238
  msgstr ""
1239
 
1240
+ #: includes/class-display.php:1562
1241
  msgid "January"
1242
  msgstr ""
1243
 
1244
+ #: includes/class-display.php:1563
1245
  msgid "February"
1246
  msgstr ""
1247
 
1248
+ #: includes/class-display.php:1564
1249
  msgid "March"
1250
  msgstr ""
1251
 
1252
+ #: includes/class-display.php:1565
1253
  msgid "April"
1254
  msgstr ""
1255
 
1256
+ #: includes/class-display.php:1566
1257
  msgid "May"
1258
  msgstr ""
1259
 
1260
+ #: includes/class-display.php:1567
1261
  msgid "June"
1262
  msgstr ""
1263
 
1264
+ #: includes/class-display.php:1568
1265
  msgid "July "
1266
  msgstr ""
1267
 
1268
+ #: includes/class-display.php:1569
1269
  msgid "August"
1270
  msgstr ""
1271
 
1272
+ #: includes/class-display.php:1570
1273
  msgid "September"
1274
  msgstr ""
1275
 
1276
+ #: includes/class-display.php:1571
1277
  msgid "October"
1278
  msgstr ""
1279
 
1280
+ #: includes/class-display.php:1572
1281
  msgid "November"
1282
  msgstr ""
1283
 
1284
+ #: includes/class-display.php:1573
1285
  msgid "December"
1286
  msgstr ""
1287
 
1288
+ #: includes/class-display.php:1756
1289
  #, php-format
1290
  msgid ""
1291
  "By submitting this form, you are consenting to receive marketing emails "
1293
  "the SafeUnsubscribe&reg; link, found at the bottom of every email. %s"
1294
  msgstr ""
1295
 
1296
+ #: includes/class-display.php:1762
1297
  msgid "Emails are serviced by Constant Contact"
1298
  msgstr ""
1299
 
1300
+ #: includes/class-lists.php:80
1301
  msgid "List Information"
1302
  msgstr ""
1303
 
1304
+ #: includes/class-lists.php:170
1305
  msgid "List information will populate upon saving."
1306
  msgstr ""
1307
 
1308
+ #: includes/class-lists.php:859
1309
  msgid "You already have a list with that name."
1310
  msgstr ""
1311
 
1312
+ #: includes/class-lists.php:878
1313
  msgid "Sync Lists with Constant Contact"
1314
  msgstr ""
1315
 
1357
  msgid "Delete logs"
1358
  msgstr ""
1359
 
1360
+ #: includes/class-mail.php:307
1361
  #, php-format
1362
  msgid "Duplicate send mail for: %1$s and: %2$s"
1363
  msgstr ""
1364
 
1365
+ #: includes/class-mail.php:339
1366
  msgid "Your Constant Contact Forms plugin has captured new information."
1367
  msgstr ""
1368
 
1369
+ #: includes/class-mail.php:343
1370
  msgid "Form title: "
1371
  msgstr ""
1372
 
1373
+ #: includes/class-mail.php:344
1374
  msgid "Form information: "
1375
  msgstr ""
1376
 
1377
+ #: includes/class-mail.php:350
1378
  #, php-format
1379
  msgid ""
1380
  "Email marketing is a great way to stay connected and engage with visitors "
1382
  "pn=miwordpress%s to sign up for a Free Trial."
1383
  msgstr ""
1384
 
1385
+ #: includes/class-mail.php:387
1386
  msgid "Constant Contact Forms Notification"
1387
  msgstr ""
1388
 
1389
+ #: includes/class-mail.php:475
1390
  #, php-format
1391
  msgid ""
1392
  "%sNote:%s You have disabled admin email notifications under the plugin "
1393
  "settings, but are receiving this email because of the following reason."
1394
  msgstr ""
1395
 
1396
+ #: includes/class-mail.php:498
1397
  msgid "Submitted to Constant Contact:"
1398
  msgstr ""
1399
 
1400
+ #: includes/class-mail.php:504
1401
  msgid "NO (Constant Contact list not selected for this form)"
1402
  msgstr ""
1403
 
1404
+ #: includes/class-mail.php:510
1405
  msgid "NO (User did not select the Email Opt-in checkbox)"
1406
  msgstr ""
1407
 
1408
+ #: includes/class-mail.php:510
1409
  msgid ""
1410
  "You can disable this under Form options. Email Opt-in isn't required to add "
1411
  "subscribers into your account"
1464
  "implement via <a href=\"%s\">Settings</a>"
1465
  msgstr ""
1466
 
1467
+ #: includes/class-notifications.php:415
1468
  msgid "Dismiss this notice."
1469
  msgstr ""
1470
 
1471
+ #: includes/class-optin.php:137 includes/class-settings.php:823
1472
  msgid "Agree"
1473
  msgstr ""
1474
 
1475
+ #: includes/class-optin.php:138 includes/class-settings.php:824
1476
  msgid "Disagree"
1477
  msgstr ""
1478
 
1479
+ #: includes/class-process-form.php:107 includes/class-process-form.php:663
1480
  msgid "There was an error sending your form."
1481
  msgstr ""
1482
 
1483
+ #: includes/class-process-form.php:121 includes/class-process-form.php:686
1484
  msgid "Your information has been submitted."
1485
  msgstr ""
1486
 
1487
+ #: includes/class-process-form.php:139 includes/class-process-form.php:259
1488
+ #: includes/class-process-form.php:703
1489
  msgid ""
1490
  "We had trouble processing your submission. Please review your entries and "
1491
  "try again."
1492
  msgstr ""
1493
 
1494
+ #: includes/class-process-form.php:190
1495
  msgid "No Constant Contact Forms form ID provided"
1496
  msgstr ""
1497
 
1498
+ #: includes/class-process-form.php:198
1499
  msgid "No form verify value provided"
1500
  msgstr ""
1501
 
1502
+ #: includes/class-process-form.php:206 includes/class-process-form.php:247
1503
  msgid "We do no think you are human"
1504
  msgstr ""
1505
 
1506
+ #: includes/class-process-form.php:213
1507
  msgid "Please properly fill out all required fields"
1508
  msgstr ""
1509
 
1510
+ #: includes/class-process-form.php:231
1511
  msgid "Failed reCAPTCHA check"
1512
  msgstr ""
1513
 
1514
+ #: includes/class-process-form.php:268 includes/class-process-form.php:277
1515
+ #: includes/class-process-form.php:286
1516
  msgid ""
1517
  "We had trouble processing your submission. Make sure you haven't changed the "
1518
  "required Form ID and try again."
1609
  msgstr ""
1610
 
1611
  #: includes/class-settings.php:369
1612
+ msgid "Global Form CSS Settings"
1613
+ msgstr ""
1614
+
1615
+ #: includes/class-settings.php:373
1616
+ msgid "CSS Classes"
1617
+ msgstr ""
1618
+
1619
+ #: includes/class-settings.php:377
1620
+ msgid "Provide custom classes for the form separated by a single space."
1621
+ msgstr ""
1622
+
1623
+ #: includes/class-settings.php:396
1624
+ msgid "Choose the position for the labels of the form elements."
1625
+ msgstr ""
1626
+
1627
+ #: includes/class-settings.php:403
1628
  msgid "Support"
1629
  msgstr ""
1630
 
1631
+ #: includes/class-settings.php:406
1632
  msgid "Enable logging for debugging purposes."
1633
  msgstr ""
1634
 
1635
+ #: includes/class-settings.php:407
1636
  msgid ""
1637
  "This option will turn on some logging functionality that can be used to "
1638
  "deduce sources of issues with the use of Constant Contact Forms plugin."
1639
  msgstr ""
1640
 
1641
+ #: includes/class-settings.php:425
1642
  msgid "Add a checkbox to the comment field in your posts"
1643
  msgstr ""
1644
 
1645
+ #: includes/class-settings.php:426
1646
  msgid "Add a checkbox to the main WordPress login page"
1647
  msgstr ""
1648
 
1649
+ #: includes/class-settings.php:431
1650
  msgid "Add a checkbox to the WordPress user registration page"
1651
  msgstr ""
1652
 
1653
+ #: includes/class-settings.php:520
1654
  msgid "Sign up to our newsletter."
1655
  msgstr ""
1656
 
readme.txt CHANGED
@@ -2,10 +2,10 @@
2
  Contributors: constantcontact
3
  Tags: capture, contacts, constant contact, constant contact form, constant contact newsletter, constant contact official, contact forms, email, form, forms, marketing, mobile, newsletter, opt-in, plugin, signup, subscribe, subscription, widget
4
  Requires at least: 4.0.0
5
- Tested up to: 4.9.4
6
- Stable tag: 1.3.7
7
- License: GPLv2
8
- License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
  Requires PHP: 5.4
10
 
11
  The official Constant Contact plugin adds a contact form to your WordPress site to quickly capture information from visitors.
@@ -34,6 +34,27 @@ BONUS: If you have a Constant Contact account, all new email addresses that you
34
  5. Basic Form
35
 
36
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  = 1.3.7 =
38
  * Added: Logging functionality to help aid with debugging and the plugin not working as needed or expected.
39
  * Added: Passed form ID to filters related to including labels for custom fields.
2
  Contributors: constantcontact
3
  Tags: capture, contacts, constant contact, constant contact form, constant contact newsletter, constant contact official, contact forms, email, form, forms, marketing, mobile, newsletter, opt-in, plugin, signup, subscribe, subscription, widget
4
  Requires at least: 4.0.0
5
+ Tested up to: 4.9.7
6
+ Stable tag: 1.4.0
7
+ License: GPLv3
8
+ License URI: http://www.gnu.org/licenses/gpl-3.0.html
9
  Requires PHP: 5.4
10
 
11
  The official Constant Contact plugin adds a contact form to your WordPress site to quickly capture information from visitors.
34
  5. Basic Form
35
 
36
  == Changelog ==
37
+
38
+ = 1.4.0 =
39
+ * Added: Various styling options during the form building process.
40
+ * Added: Initial Akismet integration to help aid with spam submissions.
41
+ * Added: Clear form fields after successful AJAX-based form submissions.
42
+ * Added: Clear success/error message after small delay, for AJAX-based form submissions.
43
+ * Added: WordPress action hooks before and after form output. Useful to add your own output for a given form.
44
+ * Added: Compatibility with "Call To Action" plugin.
45
+ * Added: Include custom field labels in email notifications.
46
+ * Added: Ability to customize who receives email notifications, per form.
47
+ * Added: Frontend form submit button disabled if hidden honeypot field has changed.
48
+ * Fixed: Consistently applied ctct_process_form_success filter to AJAX form submission success messages.
49
+ * Fixed: Prevent errors with Constant Contact social links and array_merge issues.
50
+ * Fixed: Prevent errors with array_key_exists() and the ctct_get_settings_option function.
51
+ * Fixed: Wording around associated lists for a form, in the WordPress admin.
52
+ * Fixed: Removed .gitignore files from /vendor folders.
53
+ * Fixed: Prevent potential PHP warnings and notices in various areas.
54
+ * Updated: Better support for emailing notifications to multiple recipiants.
55
+ * Updated: Better disabling of submit button during AJAX-based submissions.
56
+ * Updated: Tightened up form builder screen to not use so much space.
57
+
58
  = 1.3.7 =
59
  * Added: Logging functionality to help aid with debugging and the plugin not working as needed or expected.
60
  * Added: Passed form ID to filters related to including labels for custom fields.
vendor/constantcontact/constantcontact/.gitignore ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Created by .gitignore support plugin (hsz.mobi)
2
+
3
+ ## Directory-based project format
4
+ .idea/
5
+ /*.iml
6
+
7
+ ## File-based project format
8
+ *.ipr
9
+ *.iws
10
+
11
+ ## Additional for IntelliJ
12
+ out/
13
+
14
+ # generated by mpeltonen/sbt-idea plugin
15
+ .idea_modules/
16
+
17
+ # generated by JIRA plugin
18
+ atlassian-ide-plugin.xml
19
+
20
+ ### Composer template
21
+ composer.lock
22
+ composer.phar
23
+ vendor/
24
+
25
+ devFile.php
vendor/constantcontact/constantcontact/.travis.yml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ language: php
2
+
3
+ php:
4
+ - 5.4
5
+ - 5.5
6
+ - 5.6
7
+ - hhvm
8
+
9
+ env:
10
+ - GUZZLE_VERSION="5.1.0"
11
+
12
+ before_script: composer install
13
+
14
+ install:
15
+ - composer require guzzlehttp/guzzle:${GUZZLE_VERSION}
16
+
17
+ matrix:
18
+ allow_failures:
19
+ - php: hhvm
20
+ fast_finish: true
vendor/constantcontact/constantcontact/constantcontact/phpunit.xml DELETED
@@ -1,8 +0,0 @@
1
- <phpunit bootstrap="test/bootstrap.php">
2
- <testsuites>
3
- <testsuite name="UnitTests">
4
- <directory>test/Services</directory>
5
- <directory>test/Auth</directory>
6
- </testsuite>
7
- </testsuites>
8
- </phpunit>
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Auth/CtctOAuth2UnitTest.php DELETED
@@ -1,140 +0,0 @@
1
- <?php
2
-
3
- use Ctct\Auth\CtctOAuth2;
4
- use Ctct\Util\Config;
5
- use GuzzleHttp\Client;
6
- use GuzzleHttp\Message\Response;
7
- use GuzzleHttp\Stream\Stream;
8
- use GuzzleHttp\Subscriber\Mock;
9
-
10
- class CtctOAuth2UnitTest extends PHPUnit_Framework_TestCase
11
- {
12
- /**
13
- * @var Client
14
- */
15
- private static $client;
16
-
17
- /**
18
- * @var CtctOAuth2
19
- */
20
- private $ctctOAuth2;
21
-
22
- private $apiKey = "apiKey";
23
- private $clientSecret = "clientSecret";
24
- private $redirectUri = "redirectUri";
25
-
26
- public static function setUpBeforeClass()
27
- {
28
- self::$client = new Client();
29
- $tokenInfoStream = Stream::factory(JsonLoader::getTokenInfoJson());
30
- $accessTokenStream = Stream::factory(JsonLoader::getAccessTokenJson());
31
- $mock = new Mock([
32
- new Response(200, array(), $tokenInfoStream),
33
- new Response(200, array(), $accessTokenStream)
34
- ]);
35
- self::$client->getEmitter()->attach($mock);
36
- }
37
-
38
- public function setUp()
39
- {
40
- $this->ctctOAuth2 = new CtctOAuth2($this->apiKey, $this->clientSecret, $this->redirectUri);
41
- }
42
-
43
- public function testGetTokenInfo()
44
- {
45
- $response = self::$client->post('/');
46
-
47
- $token = $response->json();
48
-
49
- $this->assertEquals("f98b207c-ta99b-4938-b523-3cc2895f5420", $token['client_id']);
50
- $this->assertEquals("ctcttest", $token['user_name']);
51
- $this->assertEquals("315110295", $token['expires_in']);
52
- }
53
-
54
- public function testGetAccessToken()
55
- {
56
- $response = self::$client->post('/');
57
-
58
- $token = $response->json();
59
-
60
- $this->assertEquals("v6574b42-a5bc-4574-a87f-5c9d1202e316", $token['access_token']);
61
- $this->assertEquals("308874923", $token['expires_in']);
62
- $this->assertEquals("Bearer", $token['token_type']);
63
- }
64
-
65
- /**
66
- * @dataProvider authorizationUrlProvider
67
- */
68
- public function testGetAuthorizationUrl($server, $expectedResponse)
69
- {
70
- $this->assertEquals($expectedResponse, $this->ctctOAuth2->getAuthorizationUrl($server));
71
- }
72
-
73
- public function testGetAuthorizationUrlServer()
74
- {
75
- $authUrl = $this->ctctOAuth2->getAuthorizationUrl();
76
- $baseUrl = Config::get('auth.base_url') . Config::get('auth.authorization_endpoint');
77
- $params = array(
78
- 'response_type' => 'code',
79
- 'client_id' => $this->apiKey,
80
- 'redirect_uri' => $this->redirectUri
81
- );
82
- $expectedUrl = $baseUrl . '?' . http_build_query($params);
83
- $this->assertEquals($expectedUrl, $authUrl);
84
- }
85
-
86
- public function testGetAuthorizationUrlClient()
87
- {
88
- $authUrl = $this->ctctOAuth2->getAuthorizationUrl(false);
89
- $baseUrl = Config::get('auth.base_url') . Config::get('auth.authorization_endpoint');
90
- $params = array(
91
- 'response_type' => 'token',
92
- 'client_id' => $this->apiKey,
93
- 'redirect_uri' => $this->redirectUri
94
- );
95
- $expectedUrl = $baseUrl . '?' . http_build_query($params);
96
- $this->assertEquals($expectedUrl, $authUrl);
97
- }
98
-
99
- public function testGetAuthorizationUrlServerWithState()
100
- {
101
- $state = 'this is my state';
102
- $authUrl = $this->ctctOAuth2->getAuthorizationUrl(true, $state);
103
- $baseUrl = Config::get('auth.base_url') . Config::get('auth.authorization_endpoint');
104
- $params = array(
105
- 'response_type' => 'code',
106
- 'client_id' => $this->apiKey,
107
- 'redirect_uri' => $this->redirectUri,
108
- 'state' => $state
109
- );
110
- $expectedUrl = $baseUrl . '?' . http_build_query($params, '', '&', PHP_QUERY_RFC3986);
111
- $this->assertEquals($expectedUrl, $authUrl);
112
- }
113
-
114
- public function testGetAuthorizationUrlClientWithState()
115
- {
116
- $state = 'this is my state';
117
- $authUrl = $this->ctctOAuth2->getAuthorizationUrl(false, $state);
118
- $baseUrl = Config::get('auth.base_url') . Config::get('auth.authorization_endpoint');
119
- $params = array(
120
- 'response_type' => 'token',
121
- 'client_id' => $this->apiKey,
122
- 'redirect_uri' => $this->redirectUri,
123
- 'state' => $state
124
- );
125
- $expectedUrl = $baseUrl . '?' . http_build_query($params, '', '&', PHP_QUERY_RFC3986);
126
- $this->assertEquals($expectedUrl, $authUrl);
127
- }
128
-
129
- public function authorizationUrlProvider()
130
- {
131
- $requestParams = "&client_id=apiKey&redirect_uri=redirectUri";
132
- $serverParams = "?response_type=" . Config::get('auth.response_type_code') . $requestParams;
133
- $clientParams = "?response_type=" . Config::get('auth.response_type_token') . $requestParams;
134
-
135
- return array(
136
- array(true, Config::get('auth.base_url') . Config::get('auth.authorization_endpoint') . $serverParams),
137
- array(false, Config::get('auth.base_url') . Config::get('auth.authorization_endpoint') . $clientParams)
138
- );
139
- }
140
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Account/get_account_info.json DELETED
@@ -1,21 +0,0 @@
1
- {
2
- "website":"http://www.example.com",
3
- "organization_name":"My Company",
4
- "time_zone":"US/Eastern",
5
- "first_name":"Mary Jane",
6
- "last_name":"Doe",
7
- "email":"mjdoe@example.com",
8
- "phone":"5555555555",
9
- "company_logo":"https://ih.constantcontact.com/fs137/1100371573368/img/90.jpg",
10
- "country_code":"US",
11
- "state_code":"MA",
12
- "organization_addresses":[
13
- {
14
- "city": "Anytown",
15
- "line1":"123 Maple Street",
16
- "postal_code":"11111",
17
- "country_code":"US",
18
- "state_code":"MA"
19
- }
20
- ]
21
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Account/get_verified_email_addresses.json DELETED
@@ -1,6 +0,0 @@
1
- [
2
- {
3
- "email_address": "test123@roving.com",
4
- "status": "CONFIRMED"
5
- }
6
- ]
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Activities/get_activities.json DELETED
@@ -1,52 +0,0 @@
1
- [
2
- {
3
- "id": "a07e1ikxwuphd4nwjxl",
4
- "type": "EXPORT_CONTACTS",
5
- "status": "COMPLETE",
6
- "start_date": "2013-02-13T15:57:03.627Z",
7
- "finish_date": "2013-02-13T15:57:03.649Z",
8
- "created_date": "2013-02-13T15:56:14.697Z",
9
- "error_count": 0,
10
- "contact_count": 0
11
- },
12
- {
13
- "id": "a07e1ikxwuohd4ni3no",
14
- "type": "EXPORT_CONTACTS",
15
- "status": "COMPLETE",
16
- "start_date": "2013-02-13T15:45:02.959Z",
17
- "finish_date": "2013-02-13T15:45:03.146Z",
18
- "created_date": "2013-02-13T15:45:00.420Z",
19
- "error_count": 0,
20
- "contact_count": 0
21
- },
22
- {
23
- "id": "a07e1ikxyomhd4la0o9",
24
- "type": "REMOVE_CONTACTS_FROM_LISTS",
25
- "status": "COMPLETE",
26
- "start_date": "2013-02-13T14:43:01.635Z",
27
- "finish_date": "2013-02-13T14:43:01.662Z",
28
- "created_date": "2013-02-13T14:42:44.073Z",
29
- "error_count": 2,
30
- "contact_count": 2
31
- },
32
- {
33
- "id": "a07e1ikxwujhd4j5dpm",
34
- "type": "CLEAR_CONTACTS_FROM_LISTS",
35
- "status": "COMPLETE",
36
- "start_date": "2013-02-13T13:44:01.186Z",
37
- "finish_date": "2013-02-13T13:44:03.330Z",
38
- "created_date": "2013-02-13T13:43:08.458Z",
39
- "error_count": 0,
40
- "contact_count": 352
41
- },
42
- {
43
- "id": "a07e1ikqlv6hcxbe11w",
44
- "type": "REMOVE_CONTACTS_FROM_LISTS",
45
- "status": "COMPLETE",
46
- "start_date": "2013-02-08T12:31:56.472Z",
47
- "finish_date": "2013-02-08T12:31:56.525Z",
48
- "created_date": "2013-02-08T12:31:31.796Z",
49
- "error_count": 2,
50
- "contact_count": 2
51
- }
52
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Activities/get_activity.json DELETED
@@ -1,24 +0,0 @@
1
- {
2
- "id": "a07e1ikxyomhd4la0o9",
3
- "type": "REMOVE_CONTACTS_FROM_LISTS",
4
- "status": "COMPLETE",
5
- "errors": [
6
- {
7
- "message": "test@roving.com (not found in subscriber list)",
8
- "line_number": 0,
9
- "email_address": ""
10
- },
11
- {
12
- "message": "test1@roving.com (not found in subscriber list)",
13
- "line_number": 0,
14
- "email_address": ""
15
- }
16
- ],
17
- "warnings": [],
18
- "file_name": "",
19
- "start_date": "2013-02-13T14:43:01.635Z",
20
- "finish_date": "2013-02-13T14:43:01.662Z",
21
- "created_date": "2013-02-13T14:42:44.073Z",
22
- "error_count": 2,
23
- "contact_count": 2
24
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Activities/post_add_contacts.json DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "id": "a07e1il69qzhdby44ro",
3
- "type": "ADD_CONTACTS",
4
- "error_count": 0,
5
- "contact_count": 1
6
- }
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Activities/post_clear_lists.json DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "id": "a07e1il69fwhd7uan9h",
3
- "type": "CLEAR_CONTACTS_FROM_LISTS",
4
- "error_count": 0,
5
- "contact_count": 0
6
- }
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Activities/post_export_contacts.json DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "id": "a07e1i5nqamhcfeuu0h",
3
- "type": "EXPORT_CONTACTS",
4
- "error_count": 0,
5
- "contacts_count": 0
6
- }
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Activities/post_remove_contacts_from_lists.json DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "id": "a07e1i5nqamhcfeuu0h",
3
- "type": "REMOVE_CONTACTS_FROM_LISTS",
4
- "error_count": 0,
5
- "contacts_count": 0
6
- }
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Auth/get_access_token.json DELETED
@@ -1,5 +0,0 @@
1
- {
2
- "access_token": "v6574b42-a5bc-4574-a87f-5c9d1202e316",
3
- "expires_in": "308874923",
4
- "token_type": "Bearer"
5
- }
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Auth/token_info.json DELETED
@@ -1,5 +0,0 @@
1
- {
2
- "client_id": "f98b207c-ta99b-4938-b523-3cc2895f5420",
3
- "user_name": "ctcttest",
4
- "expires_in": "315110295"
5
- }
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Campaigns/get_campaign.json DELETED
@@ -1,63 +0,0 @@
1
- {
2
- "id": "1100394165290",
3
- "name": "CampaignName-05965ddb-12d2-43e5-b8f3-0c22ca487c3a",
4
- "subject": "CampaignSubject",
5
- "status": "SENT",
6
- "from_name": "From WSPI",
7
- "from_email": "wiz-20121206130519@l1.snoopy.roving.com",
8
- "reply_to_email": "wiz-20121206130519@l1.snoopy.roving.com",
9
- "template_type": "CUSTOM",
10
- "created_date": "2012-12-06T18:06:05.255Z",
11
- "last_edit_date": "2012-12-06T18:06:05.255Z",
12
- "last_run_date": "2012-12-06T18:06:40.342Z",
13
- "is_permission_reminder_enabled": false,
14
- "permission_reminder_text": "",
15
- "permalink_url": "http://www.constantcontact.com",
16
- "is_view_as_webpage_enabled": false,
17
- "view_as_web_page_text": "Having trouble viewing this email?",
18
- "view_as_web_page_link_text": "Click Here",
19
- "greeting_salutations": "Hi",
20
- "greeting_name": "FIRST_NAME",
21
- "greeting_string": "",
22
- "email_content": "<html><body>Hi <a href=\"http://www.constantcontact.com\">Visit ConstantContact.com!</a> </body></html>",
23
- "text_content": "<text>Something to test</text>",
24
- "email_content_format": "HTML",
25
- "style_sheet": "",
26
- "message_footer": {
27
- "city": "Waltham",
28
- "state": "MA",
29
- "country": "US",
30
- "organization_name": "WSPIOrgName",
31
- "address_line_1": "1601 Trapelo RD",
32
- "address_line_2": "suite 2",
33
- "address_line_3": "box 4",
34
- "international_state": "",
35
- "postal_code": "02451",
36
- "include_forward_email": true,
37
- "forward_email_link_text": "WSPIForwardThisEmail",
38
- "include_subscribe_link": true,
39
- "subscribe_link_text": "WSPISubscribeLinkText"
40
- },
41
- "tracking_summary": {
42
- "sends": 15,
43
- "opens": 10,
44
- "clicks": 10,
45
- "forwards": 3,
46
- "unsubscribes": 2,
47
- "bounces": 18,
48
- "spam_count": 1
49
- },
50
- "is_visible_in_ui": false,
51
- "sent_to_contact_lists": [
52
- {
53
- "id": 3
54
- }
55
- ],
56
- "click_through_details": [
57
- {
58
- "url": "http://www.constantcontact.com",
59
- "url_uid": "1100394163874",
60
- "click_count": 10
61
- }
62
- ]
63
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Campaigns/get_campaigns.json DELETED
@@ -1,57 +0,0 @@
1
- {
2
- "meta": {
3
- "pagination": {
4
- "next_link": "/v2/emailcampaigns?next=cGFnZU51bT0yJnBhZ2VTaXplPTM"
5
- }
6
- },
7
- "results": [
8
- {
9
- "id": "1100371240640",
10
- "name": "Email Created 2012/11/29, 4:13 PM",
11
- "status": "SENT",
12
- "modified_date": "2012-11-29T16:15:17.468Z"
13
- },
14
- {
15
- "id": "1100368835463",
16
- "name": "CampaignNdddasdsdme2",
17
- "status": "DRAFT",
18
- "modified_date": "2012-10-16T16:14:34.221Z"
19
- },
20
- {
21
- "id": "1100368834956",
22
- "name": "CampaignNasdsdme2",
23
- "status": "DRAFT",
24
- "modified_date": "2012-10-16T15:44:45.341Z"
25
- },
26
- {
27
- "id": "1100368605465",
28
- "name": "CampaignName2dddfdf",
29
- "status": "DRAFT",
30
- "modified_date": "2012-10-10T12:34:33.702Z"
31
- },
32
- {
33
- "id": "1100368605462",
34
- "name": "CampaignName2dfdf",
35
- "status": "DRAFT",
36
- "modified_date": "2012-10-10T12:33:39.402Z"
37
- },
38
- {
39
- "id": "1100367933663",
40
- "name": "CampaignName-cfd9b733-a4a3-40b0-ab92-8ad66d954c7f",
41
- "status": "DRAFT",
42
- "modified_date": "2012-09-25T18:29:43.259Z"
43
- },
44
- {
45
- "id": "1100367567199",
46
- "name": "u8cf32jeirb2",
47
- "status": "DRAFT",
48
- "modified_date": "2012-09-19T14:03:06.774Z"
49
- },
50
- {
51
- "id": "1100367567187",
52
- "name": "6qgk3d0opqgb",
53
- "status": "DRAFT",
54
- "modified_date": "2012-09-19T13:54:15.316Z"
55
- }
56
- ]
57
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Campaigns/get_preview.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "subject":"Subject Test",
3
- "from_email":"myemail@example.com",
4
- "reply_to_email":"myemail@example.com",
5
- "preview_email_content":"<head ><meta /></head><body><center><table bgcolor=\"#ffffff\" id=\"VWPLINK\" width=\"595\"><tr><td style=\"font-size: 8pt; font-family: Verdana, Arial, Helvetica, sans-serif; color: #000000;\" width=\"100%\">View this message as a web page\n<a >Click here\n</a></td></tr></table></center><center ><table bgcolor=\"#ffffff\" width=\"595\" ><tr ><td width=\"100%\" ><font color=\"#000000\" face=\"verdana,arial\" size=\"1\" ><div >As a reminder, you're receiving this email because you have expressed an interest in MyCompany. Don't forget to add from_email@example.com to your address book so we'll be sure to land in your inbox! You may unsubscribe if you no longer wish to receive our emails. <div >&nbsp;</div><div >You may <a >unsubscribe</a> if you no longer wish to receive our emails.</div></div></font></td></tr></table></center><img /><p>This is text of the email message.</p><br />\n<table bgcolor=\"#ffffff\" padding=\"0\" width=\"100%\" ><tr align=\"center\" ><td ><table bgcolor=\"#ffffff\" width=\"595\" ><tr ><td colspan=\"2\" ><font face=\"tahoma,sans-serif\" size=\"1\" ><b ><a >Click here to forward this message</a></b></font><br />\n<br />\n</td></tr>\n<tr ><td ><FooterContent ><a ><img /></a></FooterContent></td><td align=\"right\" ><font face=\"tahoma,sans-serif\" size=\"1\" ><FooterLogo ><a ><img /></a></FooterLogo></font>\n</td>\n</tr><tr ><td colspan=\"2\" ><font face=\"tahoma,sans-serif\" size=\"1\" ><FooterContent ><div >This email was sent to {Email Address} by <a >rmarcucella@constantcontact.com</a> <span style=\"color: #bababa;\" > | </span> &nbsp; </div>\n<div ><a >Update Profile/Email Address</a> <span style=\"color: #bababa;\" >|</span> Instant removal with <a >SafeUnsubscribe</a>&trade; <span style=\"color: #bababa;\" >|</span> <a >Privacy Policy</a>.</div></FooterContent></font>\n</td>\n</tr>\n<tr ><td colspan=\"2\" ><font face=\"tahoma,sans-serif\" size=\"1\" ><br />My Organization | 123 Maple Street | Suite 1 | Anytown | MA | 01444</font>\n</td>\n</tr>\n</table>\n</td>\n</tr>\n</table>\n<br />\n&lt;/body&gt;",
6
- "preview_text_content":"View this message as a web page\nClick here\nhttp://campaign.r20.l1.constantcontact.com/render?ca=025eff86-6378-4f53-9301-5897ecf50b30&c={Contact Id}&ch={Contact Id}\n\nAs a reminder, you're receiving this email because you have expressed an interest in MyCompany. Don't forget to add from_email@example.com to your address book so we'll be sure to land in your inbox! You may unsubscribe if you no longer wish to receive our emails. You may unsubscribe\nhttp://visitor.l1.constantcontact.com/do?p=un&m=001JZtDyxcvPiye1EthMqSLGA%3D%3D&ch={Contact Id}&ca=025eff86-6378-4f53-9301-5897ecf50b30\n if you no longer wish to receive our emails.\n------------------------------------------------------------\nThis is the text of the email message.\n\nClick here to forward this message\nhttp://ui.l1.constantcontact.com/sa/fwtf.jsp?llr=cqmhk9aab&m=1100394770946&ea=rmarcucella%40constantcontact.com&a=1100400205633\n\n\n\n\n\nThis email was sent to {Email Address} by rmarcucella@constantcontact.com.\n\nUpdate Profile/Email Address\nhttp://visitor.l1.constantcontact.com/do?p=oo&m=001JZtDyxcvPiye1EthMqSLGA%3D%3D&ch={Contact Id}&ca=025eff86-6378-4f53-9301-5897ecf50b30\n\n\nInstant removal with SafeUnsubscribe(TM)\nhttp://visitor.l1.constantcontact.com/do?p=un&m=001JZtDyxcvPiye1EthMqSLGA%3D%3D&ch={Contact Id}&ca=025eff86-6378-4f53-9301-5897ecf50b30\n\n\nPrivacy Policy:\nhttp://ui.l1.constantcontact.com/roving/CCPrivacyPolicy.jsp\n\n\n\n\n\nOnline Marketing by\nhttp://img.l1.constantcontact.com/letters/images/cc-logo-color-sm.gif\nhttp://www.constantcontact.com\n\n\n\nMy Organization | 123 Maple Street | Suite 1 | Anytown | MA | 01444\n\n\n\n\n\n\n\n\n"
7
- }
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Campaigns/get_schedule.json DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "id": 1,
3
- "scheduled_date": "2012-12-16T11:07:43.626Z"
4
- }
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Campaigns/get_schedules.json DELETED
@@ -1,10 +0,0 @@
1
- [
2
- {
3
- "id": 1,
4
- "scheduled_date": "2012-12-16T11:07:43.626Z"
5
- },
6
- {
7
- "id": 2,
8
- "scheduled_date": "2012-12-17T11:08:00.000Z"
9
- }
10
- ]
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Campaigns/post_test_send.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "format": "HTML",
3
- "personal_message": "oh hai there",
4
- "email_addresses": [
5
- "test@roving.com"
6
- ]
7
- }
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Contacts/get_contact.json DELETED
@@ -1,63 +0,0 @@
1
- {
2
- "id": 238,
3
- "status": "ACTIVE",
4
- "fax": "555-1212",
5
- "addresses": [
6
- {
7
- "line1": "1601 Trapelo Rd",
8
- "line2": "Suite 329",
9
- "line3": "Line 3",
10
- "city": "Waltham",
11
- "address_type": "PERSONAL",
12
- "state_code": "MA",
13
- "country_code": "us",
14
- "postal_code": "01720",
15
- "sub_postal_code": "7885"
16
- }
17
- ],
18
- "notes": [
19
- {
20
- "id": 1,
21
- "note": "Here are some cool notes to add",
22
- "created_date": "2012-12-03T17:09:22.702Z"
23
- }
24
- ],
25
- "confirmed": false,
26
- "lists": [
27
- {
28
- "id": 9,
29
- "status": "ACTIVE"
30
- }
31
- ],
32
- "source": "API",
33
- "email_addresses": [
34
- {
35
- "status": "ACTIVE",
36
- "confirm_status": "NO_CONFIRMATION_REQUIRED",
37
- "opt_in_source": "ACTION_BY_VISITOR",
38
- "opt_in_date": "2012-09-17T14:40:41.271Z",
39
- "opt_out_date": "2012-03-29T14:59:25.427Z",
40
- "email_address": "john+smith@gmail.com"
41
- }
42
- ],
43
- "prefix_name": "Mr.",
44
- "first_name": "John",
45
- "last_name": "Smith",
46
- "job_title": "Software Engineer",
47
- "company_name": "Constant Contact",
48
- "home_phone": "555-1212",
49
- "work_phone": "555-1213",
50
- "cell_phone": "555-1214",
51
- "custom_fields": [
52
- {
53
- "name": "CustomField1",
54
- "value": "3/28/2011 11:09 AM EDT"
55
- },
56
- {
57
- "name": "CustomField2",
58
- "value": "Site owner"
59
- }
60
- ],
61
- "source_details": "69f9d72b-0a5e-479d-b844-722b1da9595f",
62
- "source_is_url": false
63
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Contacts/get_contacts.json DELETED
@@ -1,111 +0,0 @@
1
- {
2
- "meta": {
3
- "pagination": {
4
- "next_link": "/v2/contacts?next=c3RhcnRBdD0zJmxpbWl0PTI"
5
- }
6
- },
7
- "results": [
8
- {
9
- "id": 230,
10
- "status": "REMOVED",
11
- "fax": "",
12
- "addresses": [
13
- {
14
- "line1": "Addr1",
15
- "line2": "",
16
- "line3": "",
17
- "city": "Boston",
18
- "address_type": "PERSONAL",
19
- "state_code": "MA",
20
- "country_code": "us",
21
- "postal_code": "00112",
22
- "sub_postal_code": ""
23
- },
24
- {
25
- "line1": "",
26
- "line2": "",
27
- "line3": "",
28
- "city": "",
29
- "address_type": "BUSINESS",
30
- "state_code": "",
31
- "country_code": "",
32
- "postal_code": "",
33
- "sub_postal_code": ""
34
- }
35
- ],
36
- "notes": [],
37
- "confirmed": false,
38
- "lists": [],
39
- "source": "",
40
- "email_addresses": [
41
- {
42
- "status": "REMOVED",
43
- "confirm_status": "NO_CONFIRMATION_REQUIRED",
44
- "opt_in_source": "ACTION_BY_VISITOR",
45
- "opt_in_date": "2012-05-29T16:26:36.915Z",
46
- "opt_out_date": "2012-06-18T13:13:46.974Z",
47
- "email_address": "test@roving.com"
48
- }
49
- ],
50
- "prefix_name": "",
51
- "first_name": "",
52
- "last_name": "",
53
- "job_title": "",
54
- "department_name": "",
55
- "company_name": "",
56
- "custom_fields": [],
57
- "source_details": "",
58
- "action_by": "ACTION_BY_VISITOR"
59
- },
60
- {
61
- "id": 231,
62
- "status": "ACTIVE",
63
- "fax": "",
64
- "addresses": [
65
- {
66
- "line1": "Suite 101",
67
- "line2": "line2",
68
- "line3": "line3",
69
- "city": "Brookfield",
70
- "address_type": "PERSONAL",
71
- "state_code": "WI",
72
- "country_code": "us",
73
- "postal_code": "53027",
74
- "sub_postal_code": ""
75
- }
76
- ],
77
- "notes": [],
78
- "confirmed": false,
79
- "lists": [
80
- {
81
- "id": 1,
82
- "status": "ACTIVE"
83
- }
84
- ],
85
- "source": "",
86
- "email_addresses": [
87
- {
88
- "status": "ACTIVE",
89
- "confirm_status": "NO_CONFIRMATION_REQUIRED",
90
- "opt_in_source": "ACTION_BY_OWNER",
91
- "opt_in_date": "2012-06-22T10:29:09.976Z",
92
- "opt_out_date": "",
93
- "email_address": "anothertest@roving.com"
94
- }
95
- ],
96
- "prefix_name": "",
97
- "first_name": "Jimmy",
98
- "last_name": "Roving",
99
- "job_title": "Bear Tamer",
100
- "department_name": "Animals",
101
- "company_name": "Animal Trainer Pro",
102
- "custom_fields": [
103
- {
104
- "name": "CustomField1",
105
- "value": "1"
106
- }
107
- ],
108
- "source_details": "details"
109
- }
110
- ]
111
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Contacts/get_contacts_no_next.json DELETED
@@ -1,108 +0,0 @@
1
- {
2
- "meta": {
3
- "pagination": {}
4
- },
5
- "results": [
6
- {
7
- "id": 230,
8
- "status": "REMOVED",
9
- "fax": "",
10
- "addresses": [
11
- {
12
- "line1": "Addr1",
13
- "line2": "",
14
- "line3": "",
15
- "city": "Boston",
16
- "address_type": "PERSONAL",
17
- "state_code": "MA",
18
- "country_code": "us",
19
- "postal_code": "00112",
20
- "sub_postal_code": ""
21
- },
22
- {
23
- "line1": "",
24
- "line2": "",
25
- "line3": "",
26
- "city": "",
27
- "address_type": "BUSINESS",
28
- "state_code": "",
29
- "country_code": "",
30
- "postal_code": "",
31
- "sub_postal_code": ""
32
- }
33
- ],
34
- "notes": [],
35
- "confirmed": false,
36
- "lists": [],
37
- "source": "",
38
- "email_addresses": [
39
- {
40
- "status": "REMOVED",
41
- "confirm_status": "NO_CONFIRMATION_REQUIRED",
42
- "opt_in_source": "ACTION_BY_VISITOR",
43
- "opt_in_date": "2012-05-29T16:26:36.915Z",
44
- "opt_out_date": "2012-06-18T13:13:46.974Z",
45
- "email_address": "test@roving.com"
46
- }
47
- ],
48
- "prefix_name": "",
49
- "first_name": "",
50
- "last_name": "",
51
- "job_title": "",
52
- "department_name": "",
53
- "company_name": "",
54
- "custom_fields": [],
55
- "source_details": ""
56
- },
57
- {
58
- "id": 231,
59
- "status": "ACTIVE",
60
- "fax": "",
61
- "addresses": [
62
- {
63
- "line1": "Suite 101",
64
- "line2": "line2",
65
- "line3": "line3",
66
- "city": "Brookfield",
67
- "address_type": "PERSONAL",
68
- "state_code": "WI",
69
- "country_code": "us",
70
- "postal_code": "53027",
71
- "sub_postal_code": ""
72
- }
73
- ],
74
- "notes": [],
75
- "confirmed": false,
76
- "lists": [
77
- {
78
- "id": 1,
79
- "status": "ACTIVE"
80
- }
81
- ],
82
- "source": "",
83
- "email_addresses": [
84
- {
85
- "status": "ACTIVE",
86
- "confirm_status": "NO_CONFIRMATION_REQUIRED",
87
- "opt_in_source": "ACTION_BY_OWNER",
88
- "opt_in_date": "2012-06-22T10:29:09.976Z",
89
- "opt_out_date": "",
90
- "email_address": "anothertest@roving.com"
91
- }
92
- ],
93
- "prefix_name": "",
94
- "first_name": "Jimmy",
95
- "last_name": "Roving",
96
- "job_title": "Bear Tamer",
97
- "department_name": "Animals",
98
- "company_name": "Animal Trainer Pro",
99
- "custom_fields": [
100
- {
101
- "name": "CustomField1",
102
- "value": "1"
103
- }
104
- ],
105
- "source_details": "details"
106
- }
107
- ]
108
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/JsonLoader.php DELETED
@@ -1,177 +0,0 @@
1
- <?php
2
-
3
- class JsonLoader
4
- {
5
- const CONTACTS_FOLDER = "/Contacts";
6
- const LISTS_FOLDER = "/Lists";
7
- const CAMPAIGNS_FOLDER = "/Campaigns";
8
- const CAMPAIGN_TRACKING_FOLDER = "/Tracking";
9
- const ACTIVITIES_FOLDER = "/Activities";
10
- const ACCOUNT_FOLDER = "/Account";
11
- const AUTH_FOLDER = "/Auth";
12
- const LIBRARY_FOLDER = "/Library";
13
-
14
- public static function getTokenInfoJson()
15
- {
16
- return file_get_contents(__DIR__ . self::AUTH_FOLDER . "/token_info.json");
17
- }
18
-
19
- public static function getAccessTokenJson()
20
- {
21
- return file_get_contents(__DIR__ . self::AUTH_FOLDER . "/get_access_token.json");
22
- }
23
-
24
- public static function getVerifiedAddressesJson()
25
- {
26
- return file_get_contents(__DIR__ . self::ACCOUNT_FOLDER . "/get_verified_email_addresses.json");
27
- }
28
-
29
- public static function getAccountInfoJson()
30
- {
31
- return file_get_contents(__DIR__ . self::ACCOUNT_FOLDER . "/get_account_info.json");
32
- }
33
-
34
- public static function getLibraryFileJson()
35
- {
36
- return file_get_contents(__DIR__ . self::LIBRARY_FOLDER . "/get_library_file.json");
37
- }
38
-
39
- public static function getLibraryFilesJson()
40
- {
41
- return file_get_contents(__DIR__ . self::LIBRARY_FOLDER . "/get_library_files.json");
42
- }
43
-
44
- public static function getLibraryFolderJson()
45
- {
46
- return file_get_contents(__DIR__ . self::LIBRARY_FOLDER . "/get_library_folder.json");
47
- }
48
-
49
- public static function getLibraryFoldersJson()
50
- {
51
- return file_get_contents(__DIR__ . self::LIBRARY_FOLDER . "/get_library_folders.json");
52
- }
53
-
54
- public static function getFileUploadStatusJson()
55
- {
56
- return file_get_contents(__DIR__ . self::LIBRARY_FOLDER . "/get_file_upload_status.json");
57
- }
58
-
59
- public static function getContactJson()
60
- {
61
- return file_get_contents(__DIR__ . self::CONTACTS_FOLDER . "/get_contact.json");
62
- }
63
-
64
- public static function getContactsJson()
65
- {
66
- return file_get_contents(__DIR__ . self::CONTACTS_FOLDER . "/get_contacts.json");
67
- }
68
-
69
- public static function getContactsNoNextJson()
70
- {
71
- return file_get_contents(__DIR__ . self::CONTACTS_FOLDER . "/get_contacts_no_next.json");
72
- }
73
-
74
- public static function getListsJson()
75
- {
76
- return file_get_contents(__DIR__ . self::LISTS_FOLDER . "/get_lists.json");
77
- }
78
-
79
- public static function getListJson()
80
- {
81
- return file_get_contents(__DIR__ . self::LISTS_FOLDER . "/get_list.json");
82
- }
83
-
84
- public static function getCampaignJson()
85
- {
86
- return file_get_contents(__DIR__ . self::CAMPAIGNS_FOLDER . "/get_campaign.json");
87
- }
88
-
89
- public static function getCampaignsJson()
90
- {
91
- return file_get_contents(__DIR__ . self::CAMPAIGNS_FOLDER . "/get_campaigns.json");
92
- }
93
-
94
- public static function getCampaignScheduleJson()
95
- {
96
- return file_get_contents(__DIR__ . self::CAMPAIGNS_FOLDER . "/get_schedule.json");
97
- }
98
-
99
- public static function getCampaignSchedulesJson()
100
- {
101
- return file_get_contents(__DIR__ . self::CAMPAIGNS_FOLDER . "/get_schedules.json");
102
- }
103
-
104
- public static function getTestSendJson()
105
- {
106
- return file_get_contents(__DIR__ . self::CAMPAIGNS_FOLDER . "/post_test_send.json");
107
- }
108
-
109
- public static function getPreviewJson() {
110
- return file_get_contents(__DIR__ . self::CAMPAIGNS_FOLDER . "/get_preview.json");
111
- }
112
-
113
- public static function getClicks()
114
- {
115
- return file_get_contents(__DIR__ . self::CAMPAIGN_TRACKING_FOLDER . "/get_clicks.json");
116
- }
117
-
118
- public static function getBounces()
119
- {
120
- return file_get_contents(__DIR__ . self::CAMPAIGN_TRACKING_FOLDER . "/get_bounces.json");
121
- }
122
-
123
- public static function getForwards()
124
- {
125
- return file_get_contents(__DIR__ . self::CAMPAIGN_TRACKING_FOLDER . "/get_forwards.json");
126
- }
127
-
128
- public static function getOptOuts()
129
- {
130
- return file_get_contents(__DIR__ . self::CAMPAIGN_TRACKING_FOLDER . "/get_opt_outs.json");
131
- }
132
-
133
- public static function getSends()
134
- {
135
- return file_get_contents(__DIR__ . self::CAMPAIGN_TRACKING_FOLDER . "/get_sends.json");
136
- }
137
-
138
- public static function getOpens()
139
- {
140
- return file_get_contents(__DIR__ . self::CAMPAIGN_TRACKING_FOLDER . "/get_opens.json");
141
- }
142
-
143
- public static function getSummary()
144
- {
145
- return file_get_contents(__DIR__ . self::CAMPAIGN_TRACKING_FOLDER . "/get_summary.json");
146
- }
147
-
148
- public static function getActivities()
149
- {
150
- return file_get_contents(__DIR__ . self::ACTIVITIES_FOLDER . "/get_activities.json");
151
- }
152
-
153
- public static function getActivity()
154
- {
155
- return file_get_contents(__DIR__ . self::ACTIVITIES_FOLDER . "/get_activity.json");
156
- }
157
-
158
- public static function getClearListsActivity()
159
- {
160
- return file_get_contents(__DIR__ . self::ACTIVITIES_FOLDER . "/post_clear_lists.json");
161
- }
162
-
163
- public static function getExportContactsActivity()
164
- {
165
- return file_get_contents(__DIR__ . self::ACTIVITIES_FOLDER . "/post_export_contacts.json");
166
- }
167
-
168
- public static function getRemoveContactsFromListsActivity()
169
- {
170
- return file_get_contents(__DIR__ . self::ACTIVITIES_FOLDER . "/post_remove_contacts_from_lists.json");
171
- }
172
-
173
- public static function getAddContactsActivity()
174
- {
175
- return file_get_contents(__DIR__ . self::ACTIVITIES_FOLDER . "/post_add_contacts.json");
176
- }
177
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Library/get_file_upload_status.json DELETED
@@ -1,7 +0,0 @@
1
- [
2
- {
3
- "file_id": "9",
4
- "status": "Active",
5
- "description":"Active"
6
- }
7
- ]
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Library/get_library_file.json DELETED
@@ -1,22 +0,0 @@
1
- {
2
- "name": "IMG_0261.JPG",
3
- "id": "4",
4
- "description": "chocolates",
5
- "folder": "Images",
6
- "height": 600,
7
- "width": 800,
8
- "size": 68825,
9
- "url": "https://origin.ih.l1.constantcontact.com/fs115/1100310339939/img/4.jpg",
10
- "source": "MyComputer",
11
- "status": "Active",
12
- "thumbnail": {
13
- "url": "https://origin.ih.l1.constantcontact.com/fs115/1100310339939/img/4.jpg",
14
- "height": 150,
15
- "width": 200
16
- },
17
- "created_date": "2013-06-19T11:36:43.000-04:00",
18
- "modified_date": "2013-08-23T12:54:17.000-04:00",
19
- "folder_id": null,
20
- "is_image": true,
21
- "file_type": "JPG"
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Library/get_library_files.json DELETED
@@ -1,29 +0,0 @@
1
- {
2
- "meta": {
3
- "pagination": {
4
- "next_link": "/v2/library/files?next=c023cmNlPUFsbCUiUmZzZXQ9MTgyIcV5cGU9QWxsJmxpbWl0PTE"
5
- }
6
- },
7
- "results": [{
8
- "name": "Test_card.png",
9
- "id": "182",
10
- "description": "descriptionssss",
11
- "folder": "Images",
12
- "height": 360,
13
- "width": 640,
14
- "size": 26271,
15
- "url": "https://mlsvc01-prod.s3.amazonaws.com/489270ef001/d738eefc-8e8e-4a69-8e7d-8e7217d22a0a.png",
16
- "source": "MyComputer",
17
- "status": "Active",
18
- "thumbnail": {
19
- "url": "https://mlsvc01-prod.s3.amazonaws.com/489270ef001/d738eefc-8e8e-4a69-8e7d-8e7217d22a0a.png",
20
- "height": 112,
21
- "width": 200
22
- },
23
- "created_date": "2015-01-09T00:14:08.000-05:00",
24
- "modified_date": "2015-01-09T00:14:08.000-05:00",
25
- "folder_id": null,
26
- "is_image": true,
27
- "file_type": "PNG"
28
- }]
29
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Library/get_library_folder.json DELETED
@@ -1,27 +0,0 @@
1
- {
2
- "id": "-5",
3
- "name": "Folder",
4
- "level": 1,
5
- "children": [{
6
- "id": "-7",
7
- "name": "SubFolder",
8
- "level": 2,
9
- "children": [],
10
- "item_count": 0,
11
- "parent_id": "-5",
12
- "modified_date": "2014-08-04T11:40:36.000-04:00",
13
- "created_date": "2014-08-04T11:40:36.000-04:00"
14
- }, {
15
- "id": "-6",
16
- "name": "Sub-Folder",
17
- "level": 2,
18
- "children": [],
19
- "item_count": 0,
20
- "parent_id": "-5",
21
- "modified_date": "2014-08-04T11:40:42.000-04:00",
22
- "created_date": "2014-08-04T11:40:27.000-04:00"
23
- }],
24
- "item_count": 3,
25
- "modified_date": "2013-09-09T14:25:44.000-04:00",
26
- "created_date": "2013-09-09T14:25:44.000-04:00"
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Library/get_library_folders.json DELETED
@@ -1,34 +0,0 @@
1
- {
2
- "meta": {
3
- "pagination": {
4
- "next_link": "/v2/library/folders?next=b2Zmc1V0PTzmbGltaJE9Mo"
5
- }
6
- },
7
- "results": [{
8
- "id": "-5",
9
- "name": "Folder",
10
- "level": 1,
11
- "children": [{
12
- "id": "-7",
13
- "name": "SubFolder",
14
- "level": 2,
15
- "children": [],
16
- "item_count": 0,
17
- "parent_id": "-5",
18
- "modified_date": "2014-08-04T11:40:36.000-04:00",
19
- "created_date": "2014-08-04T11:40:36.000-04:00"
20
- }, {
21
- "id": "-6",
22
- "name": "Sub-Folder",
23
- "level": 2,
24
- "children": [],
25
- "item_count": 0,
26
- "parent_id": "-5",
27
- "modified_date": "2014-08-04T11:40:42.000-04:00",
28
- "created_date": "2014-08-04T11:40:27.000-04:00"
29
- }],
30
- "item_count": 3,
31
- "modified_date": "2013-09-09T14:25:44.000-04:00",
32
- "created_date": "2013-09-09T14:25:44.000-04:00"
33
- }]
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Lists/get_list.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "id": 6,
3
- "name": "Test List 4",
4
- "status": "HIDDEN",
5
- "contact_count": 19,
6
- "opt_in_default": false
7
- }
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Lists/get_lists.json DELETED
@@ -1,16 +0,0 @@
1
- [
2
- {
3
- "id": 1,
4
- "name": "General Interest",
5
- "status": "ACTIVE",
6
- "contact_count": 17,
7
- "opt_in_default": false
8
- },
9
- {
10
- "id": 3,
11
- "name": "mod_Test List 1",
12
- "status": "HIDDEN",
13
- "contact_count": 18,
14
- "opt_in_default": false
15
- }
16
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Tracking/get_bounces.json DELETED
@@ -1,29 +0,0 @@
1
- {
2
- "meta": {
3
- "pagination": {
4
- "next_link": "/v2/emailcampaigns/1100394165290/tracking/bounces?next=bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA"
5
- }
6
- },
7
- "results": [
8
- {
9
- "activity_type": "EMAIL_BOUNCE",
10
- "campaign_id": 1100394165290,
11
- "contact_id": "2",
12
- "email_address": "wizpie9dedde9dd27644bdb3d9be134b7294f71354817123188401000@snoopy.roving.com",
13
- "bounce_code": "B",
14
- "bounce_description": "Non-existent address",
15
- "bounce_message": "",
16
- "bounce_date": "2012-12-06T13:05:24.844Z"
17
- },
18
- {
19
- "activity_type": "EMAIL_BOUNCE",
20
- "campaign_id": 1100394165290,
21
- "contact_id": "3",
22
- "email_address": "wizpief9ed91eb16d84ecf84bd90317fceffdb1354817123188144000@snoopy.roving.com",
23
- "bounce_code": "B",
24
- "bounce_description": "Non-existent address",
25
- "bounce_message": "",
26
- "bounce_date": "2012-12-06T13:05:24.845Z"
27
- }
28
- ]
29
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Tracking/get_clicks.json DELETED
@@ -1,25 +0,0 @@
1
- {
2
- "meta": {
3
- "pagination": {
4
- "next_link": "/v2/emailcampaigns/1100394165290/tracking/clicks?next=bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA"
5
- }
6
- },
7
- "results": [
8
- {
9
- "activity_type": "EMAIL_CLICK",
10
- "campaign_id": 1100394165290,
11
- "contact_id": "69",
12
- "email_address": "wizpie00375ca0a11346a89aea4b8f5991d0d91354817217769892000@snoopy.roving.com",
13
- "link_id": 0,
14
- "click_date": "2012-12-06T13:07:01.701Z"
15
- },
16
- {
17
- "activity_type": "EMAIL_CLICK",
18
- "campaign_id": 1100394165290,
19
- "contact_id": "68",
20
- "email_address": "wizpiebfb0852b90d44412892276b68b949b7a1354817217770057000@snoopy.roving.com",
21
- "link_id": 0,
22
- "click_date": "2012-12-06T13:07:01.599Z"
23
- }
24
- ]
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Tracking/get_forwards.json DELETED
@@ -1,23 +0,0 @@
1
- {
2
- "meta": {
3
- "pagination": {
4
- "next_link": "/v2/emailcampaigns/1100394165290/tracking/forwards?next=bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA"
5
- }
6
- },
7
- "results": [
8
- {
9
- "activity_type": "EMAIL_FORWARD",
10
- "campaign_id": 1100394165290,
11
- "contact_id": "74",
12
- "email_address": "wizpie2ca3455df5c34a26806f519f01f8a22e1354817223114268000@snoopy.roving.com",
13
- "forward_date": "2012-12-06T13:07:06.810Z"
14
- },
15
- {
16
- "activity_type": "EMAIL_FORWARD",
17
- "campaign_id": 1100394165290,
18
- "contact_id": "74",
19
- "email_address": "wizpie2ca3455df5c34a26806f519f01f8a22e1354817223114268000@snoopy.roving.com",
20
- "forward_date": "2012-12-06T13:07:06.701Z"
21
- }
22
- ]
23
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Tracking/get_opens.json DELETED
@@ -1,23 +0,0 @@
1
- {
2
- "meta": {
3
- "pagination": {
4
- "next_link": "/v2/emailcampaigns/1100394165290/tracking/opens?next=bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA"
5
- }
6
- },
7
- "results": [
8
- {
9
- "activity_type": "EMAIL_OPEN",
10
- "campaign_id": 1100394165290,
11
- "contact_id": "86",
12
- "email_address": "wizpie9e19a6d35ec249efa8fc3085721aa61d1354817227762990000@snoopy.roving.com",
13
- "open_date": "2012-12-06T13:07:11.839Z"
14
- },
15
- {
16
- "activity_type": "EMAIL_OPEN",
17
- "campaign_id": 1100394165290,
18
- "contact_id": "85",
19
- "email_address": "wizpie5b9fc124727546eeb8123d646acdb77d1354817227763138000@snoopy.roving.com",
20
- "open_date": "2012-12-06T13:07:11.729Z"
21
- }
22
- ]
23
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Tracking/get_opt_outs.json DELETED
@@ -1,27 +0,0 @@
1
- {
2
- "meta": {
3
- "pagination": {
4
- "next_link": "/v2/emailcampaigns/1100394165290/tracking/unsubscribes?next=bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA"
5
- }
6
- },
7
- "results": [
8
- {
9
- "activity_type": "EMAIL_UNSUBSCRIBE",
10
- "campaign_id": 1100394165290,
11
- "contact_id": "58",
12
- "email_address": "wizpieabd7817c1d0d4f08bb05f16f6681221c1354817211855027000@snoopy.roving.com",
13
- "unsubscribe_date": "2012-12-06T13:06:53.440Z",
14
- "unsubscribe_source": "ACTION_BY_CUSTOMER",
15
- "unsubscribe_reason": ""
16
- },
17
- {
18
- "activity_type": "EMAIL_UNSUBSCRIBE",
19
- "campaign_id": 1100394165290,
20
- "contact_id": "57",
21
- "email_address": "wizpiebf0717c7ce95455fb7fa9bbfb1812a4e1354817211855058000@snoopy.roving.com",
22
- "unsubscribe_date": "2012-12-06T13:06:53.333Z",
23
- "unsubscribe_source": "ACTION_BY_CUSTOMER",
24
- "unsubscribe_reason": ""
25
- }
26
- ]
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Tracking/get_sends.json DELETED
@@ -1,30 +0,0 @@
1
- {
2
- "meta": {
3
- "pagination": {
4
- "next_link": "/v2/emailcampaigns/1100394165290/tracking/sends?next=bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA"
5
- }
6
- },
7
- "results": [
8
- {
9
- "activity_type": "EMAIL_SEND",
10
- "campaign_id": 1100394165290,
11
- "contact_id": "55",
12
- "email_address": "wizpiea298d1c2500b4f2d8294300de4b29fe31354817207606824000@snoopy.roving.com",
13
- "send_date": "2012-12-06T18:06:50.650Z"
14
- },
15
- {
16
- "activity_type": "EMAIL_SEND",
17
- "campaign_id": 1100394165290,
18
- "contact_id": "56",
19
- "email_address": "wizpie0d703ea133b1451c951c105aeb3190741354817207606848000@snoopy.roving.com",
20
- "send_date": "2012-12-06T18:06:50.533Z"
21
- },
22
- {
23
- "activity_type": "EMAIL_SEND",
24
- "campaign_id": 1100394165290,
25
- "contact_id": "53",
26
- "email_address": "wizpie10262bf020494ad89b298d45a89b10b61354817207606880000@snoopy.roving.com",
27
- "send_date": "2012-12-06T18:06:50.430Z"
28
- }
29
- ]
30
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Json/Tracking/get_summary.json DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "sends": 15,
3
- "opens": 10,
4
- "clicks": 10,
5
- "forwards": 3,
6
- "unsubscribes": 2,
7
- "bounces": 18,
8
- "campaign_id": 1100394165290
9
- }
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Services/AccountServiceUnitTest.php DELETED
@@ -1,62 +0,0 @@
1
- <?php
2
-
3
- use Ctct\Components\Account\AccountInfo;
4
- use Ctct\Components\Account\VerifiedEmailAddress;
5
- use GuzzleHttp\Client;
6
- use GuzzleHttp\Subscriber\Mock;
7
- use GuzzleHttp\Stream\Stream;
8
- use GuzzleHttp\Message\Response;
9
-
10
- class AccountServiceUnitTest extends PHPUnit_Framework_TestCase
11
- {
12
- /**
13
- * @var Client
14
- */
15
- private static $client;
16
-
17
- public static function setUpBeforeClass()
18
- {
19
- self::$client = new Client();
20
- $verifiedAddressStream = Stream::factory(JsonLoader::getVerifiedAddressesJson());
21
- $accountInfoStream = Stream::factory(JsonLoader::getAccountInfoJson());
22
- $mock = new Mock([
23
- new Response(200, array(), $verifiedAddressStream),
24
- new Response(200, array(), $accountInfoStream)
25
- ]);
26
- self::$client->getEmitter()->attach($mock);
27
- }
28
-
29
- public function testGetVerifiedAddresses() {
30
- $response = self::$client->get('/');
31
- $verifiedAddresses = array();
32
- foreach ($response->json() as $verifiedAddress) {
33
- $verifiedAddresses[] = VerifiedEmailAddress::create($verifiedAddress);
34
- }
35
-
36
- foreach ($verifiedAddresses as $verifiedAddress) {
37
- $this->assertInstanceOf('Ctct\Components\Account\VerifiedEmailAddress', $verifiedAddress);
38
- $this->assertEquals("test123@roving.com", $verifiedAddress->email_address);
39
- $this->assertEquals("CONFIRMED", $verifiedAddress->status);
40
- }
41
- }
42
-
43
- public function testGetAccountInfo()
44
- {
45
- $response = self::$client->get('/');
46
- $result = AccountInfo::create($response->json());
47
-
48
- $this->assertInstanceOf('Ctct\Components\Account\AccountInfo', $result);
49
- $this->assertEquals("http://www.example.com", $result->website);
50
- $this->assertEquals("My Company", $result->organization_name);
51
- $this->assertEquals("http://www.example.com", $result->website);
52
- $this->assertEquals("My Company", $result->organization_name);
53
- $this->assertEquals("US/Eastern", $result->time_zone);
54
- $this->assertEquals("Mary Jane", $result->first_name);
55
- $this->assertEquals("Doe", $result->last_name);
56
- $this->assertEquals("mjdoe@example.com", $result->email);
57
- $this->assertEquals("5555555555", $result->phone);
58
- $this->assertEquals("https://ih.constantcontact.com/fs137/1100371573368/img/90.jpg", $result->company_logo);
59
- $this->assertEquals("US", $result->country_code);
60
- $this->assertEquals("MA", $result->state_code);
61
- }
62
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Services/ActivityServiceUnitTest.php DELETED
@@ -1,119 +0,0 @@
1
- <?php
2
- use Ctct\Components\Activities\Activity;
3
- use GuzzleHttp\Client;
4
- use GuzzleHttp\Subscriber\Mock;
5
- use GuzzleHttp\Stream\Stream;
6
- use GuzzleHttp\Message\Response;
7
-
8
- class ActivityServiceUnitTest extends PHPUnit_Framework_TestCase
9
- {
10
- /**
11
- * @var Client
12
- */
13
- private static $client;
14
-
15
- public static function setUpBeforeClass()
16
- {
17
- self::$client = new Client();
18
- $activityStream = Stream::factory(JsonLoader::getActivity());
19
- $activitiesStream = Stream::factory(JsonLoader::getActivities());
20
- $clearListActivityStream = Stream::factory(JsonLoader::getClearListsActivity());
21
- $exportActivityStream = Stream::factory(JsonLoader::getExportContactsActivity());
22
- $removeContactsFromListStream = Stream::factory(JsonLoader::getRemoveContactsFromListsActivity());
23
- $addContactsStream = Stream::factory(JsonLoader::getAddContactsActivity());
24
- $mock = new Mock([
25
- new Response(200, array(), $activityStream),
26
- new Response(200, array(), $activitiesStream),
27
- new Response(201, array(), $clearListActivityStream),
28
- new Response(201, array(), $exportActivityStream),
29
- new Response(201, array(), $removeContactsFromListStream),
30
- new Response(201, array(), $addContactsStream)
31
- ]);
32
- self::$client->getEmitter()->attach($mock);
33
- }
34
-
35
- public function testGetActivity()
36
- {
37
- $response = self::$client->get('/');
38
-
39
- $activity = Activity::create($response->json());
40
- $this->assertInstanceOf('Ctct\Components\Activities\Activity', $activity);
41
- $this->assertEquals("a07e1ikxyomhd4la0o9", $activity->id);
42
- $this->assertEquals("REMOVE_CONTACTS_FROM_LISTS", $activity->type);
43
- $this->assertEquals("COMPLETE", $activity->status);
44
- $this->assertEquals("2013-02-13T14:43:01.635Z", $activity->start_date);
45
- $this->assertEquals("2013-02-13T14:43:01.662Z", $activity->finish_date);
46
- $this->assertEquals("2013-02-13T14:42:44.073Z", $activity->created_date);
47
- $this->assertEquals(2, $activity->error_count);
48
- $this->assertEquals(2, $activity->contact_count);
49
- $this->assertEquals("test@roving.com (not found in subscriber list)", $activity->errors[0]->message);
50
- $this->assertEquals(0, $activity->errors[0]->line_number);
51
- }
52
-
53
- public function testGetActivities()
54
- {
55
- $response = self::$client->get('/');
56
- $activities = array();
57
- foreach ($response->json() as $activityResponse) {
58
- $activities[] = Activity::create($activityResponse);
59
- }
60
- $activity = $activities[0];
61
- $this->assertInstanceOf('Ctct\Components\Activities\Activity', $activity);
62
- $this->assertEquals("a07e1ikxwuphd4nwjxl", $activity->id);
63
- $this->assertEquals("EXPORT_CONTACTS", $activity->type);
64
- $this->assertEquals("COMPLETE", $activity->status);
65
- $this->assertEquals("2013-02-13T15:57:03.627Z", $activity->start_date);
66
- $this->assertEquals("2013-02-13T15:57:03.649Z", $activity->finish_date);
67
- $this->assertEquals("2013-02-13T15:56:14.697Z", $activity->created_date);
68
- $this->assertEquals(0, $activity->error_count);
69
- $this->assertEquals(0, $activity->contact_count);
70
- }
71
-
72
- public function testAddClearListsActivity()
73
- {
74
- $response = self::$client->post('/');
75
-
76
- $activity = Activity::create($response->json());
77
- $this->assertInstanceOf('Ctct\Components\Activities\Activity', $activity);
78
- $this->assertEquals("a07e1il69fwhd7uan9h", $activity->id);
79
- $this->assertEquals("CLEAR_CONTACTS_FROM_LISTS", $activity->type);
80
- $this->assertEquals(0, $activity->error_count);
81
- $this->assertEquals(0, $activity->contact_count);
82
- }
83
-
84
- public function testAddExportContactsActivity()
85
- {
86
- $response = self::$client->post('/');
87
-
88
- $activity = Activity::create($response->json());
89
- $this->assertInstanceOf('Ctct\Components\Activities\Activity', $activity);
90
- $this->assertEquals("a07e1i5nqamhcfeuu0h", $activity->id);
91
- $this->assertEquals("EXPORT_CONTACTS", $activity->type);
92
- $this->assertEquals(0, $activity->error_count);
93
- $this->assertEquals(0, $activity->contact_count);
94
- }
95
-
96
- public function testAddRemoveContactsFromListsActivity()
97
- {
98
- $response = self::$client->post('/');
99
-
100
- $activity = Activity::create($response->json());
101
- $this->assertInstanceOf('Ctct\Components\Activities\Activity', $activity);
102
- $this->assertEquals("a07e1i5nqamhcfeuu0h", $activity->id);
103
- $this->assertEquals("REMOVE_CONTACTS_FROM_LISTS", $activity->type);
104
- $this->assertEquals(0, $activity->error_count);
105
- $this->assertEquals(0, $activity->contact_count);
106
- }
107
-
108
- public function testAddCreateContactsActivity()
109
- {
110
- $response = self::$client->post('/');
111
-
112
- $activity = Activity::create($response->json());
113
- $this->assertInstanceOf('Ctct\Components\Activities\Activity', $activity);
114
- $this->assertEquals("a07e1il69qzhdby44ro", $activity->id);
115
- $this->assertEquals("ADD_CONTACTS", $activity->type);
116
- $this->assertEquals(0, $activity->error_count);
117
- $this->assertEquals(1, $activity->contact_count);
118
- }
119
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Services/CampaignScheduleServiceUnitTest.php DELETED
@@ -1,113 +0,0 @@
1
- <?php
2
-
3
- use Ctct\Components\EmailMarketing\Schedule;
4
- use Ctct\Components\EmailMarketing\TestSend;
5
-
6
- use GuzzleHttp\Client;
7
- use GuzzleHttp\Exception\ClientException;
8
- use GuzzleHttp\Subscriber\Mock;
9
- use GuzzleHttp\Stream\Stream;
10
- use GuzzleHttp\Message\Response;
11
-
12
- class CampaignScheduleServiceUnitTest extends PHPUnit_Framework_TestCase
13
- {
14
- /**
15
- * @var Client
16
- */
17
- private static $client;
18
-
19
- public static function setUpBeforeClass()
20
- {
21
- self::$client = new Client();
22
- $schedulesStream = Stream::factory(JsonLoader::getCampaignSchedulesJson());
23
- $scheduleStream = Stream::factory(JsonLoader::getCampaignScheduleJson());
24
- $testSendStream = Stream::factory(JsonLoader::getTestSendJson());
25
- $mock = new Mock([
26
- new Response(200, array(), $schedulesStream),
27
- new Response(200, array(), $scheduleStream),
28
- new Response(201, array(), $scheduleStream),
29
- new Response(200, array(), $scheduleStream),
30
- new Response(204, array()),
31
- new Response(400, array()),
32
- new Response(200, array(), $testSendStream)
33
- ]);
34
- self::$client->getEmitter()->attach($mock);
35
- }
36
-
37
- public function testGetSchedules()
38
- {
39
- $response = self::$client->get('/');
40
-
41
- $schedules = array();
42
- foreach ($response->json() as $responseSchedule) {
43
- $schedules[] = $responseSchedule;
44
- }
45
-
46
- $schedule1 = Schedule::create($schedules[0]);
47
- $this->assertInstanceOf('Ctct\Components\EmailMarketing\Schedule', $schedule1);
48
- $this->assertEquals(1, $schedule1->id);
49
- $this->assertEquals("2012-12-16T11:07:43.626Z", $schedule1->scheduled_date);
50
-
51
- $schedule2 = Schedule::create($schedules[1]);
52
- $this->assertEquals(2, $schedule2->id);
53
- $this->assertEquals("2012-12-17T11:08:00.000Z", $schedule2->scheduled_date);
54
- }
55
-
56
- public function testGetSchedule()
57
- {
58
- $response = self::$client->get('/');
59
-
60
- $schedule = Schedule::create($response->json());
61
- $this->assertInstanceOf('Ctct\Components\EmailMarketing\Schedule', $schedule);
62
- $this->assertEquals(1, $schedule->id);
63
- $this->assertEquals("2012-12-16T11:07:43.626Z", $schedule->scheduled_date);
64
- }
65
-
66
- public function testAddSchedule()
67
- {
68
- $response = self::$client->post('/');
69
-
70
- $createdSchedule = Schedule::create($response->json());
71
- $this->assertInstanceOf('Ctct\Components\EmailMarketing\Schedule', $createdSchedule);
72
- $this->assertEquals(1, $createdSchedule->id);
73
- $this->assertEquals("2012-12-16T11:07:43.626Z", $createdSchedule->scheduled_date);
74
- }
75
-
76
- public function testUpdateSchedule()
77
- {
78
- $response = self::$client->put('/');
79
-
80
- $updatedSchedule = Schedule::create($response->json());
81
- $this->assertInstanceOf('Ctct\Components\EmailMarketing\Schedule', $updatedSchedule);
82
- $this->assertEquals(1, $updatedSchedule->id);
83
- $this->assertEquals("2012-12-16T11:07:43.626Z", $updatedSchedule->scheduled_date);
84
- }
85
-
86
- public function testDeleteSchedule()
87
- {
88
- $response = self::$client->delete('/');
89
-
90
- $this->assertEquals(204, $response->getStatusCode());
91
- }
92
-
93
- public function testDeleteScheduleFailed()
94
- {
95
- try {
96
- self::$client->delete('/');
97
- $this->fail("Call did not fail");
98
- } catch (ClientException $e) {
99
- $this->assertEquals(400, $e->getCode());
100
- }
101
- }
102
-
103
- public function testSendTest()
104
- {
105
- $response = self::$client->post('/');
106
-
107
- $testSend = TestSend::create($response->json());
108
- $this->assertInstanceOf('Ctct\Components\EmailMarketing\TestSend', $testSend);
109
- $this->assertEquals("HTML", $testSend->format);
110
- $this->assertEquals("oh hai there", $testSend->personal_message);
111
- $this->assertEquals("test@roving.com", $testSend->email_addresses[0]);
112
- }
113
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Services/CampaignTrackingServiceUnitTest.php DELETED
@@ -1,203 +0,0 @@
1
- <?php
2
-
3
- use Ctct\Components\ResultSet;
4
- use Ctct\Components\Tracking\BounceActivity;
5
- use Ctct\Components\Tracking\ClickActivity;
6
- use Ctct\Components\Tracking\ForwardActivity;
7
- use Ctct\Components\Tracking\OpenActivity;
8
- use Ctct\Components\Tracking\SendActivity;
9
- use Ctct\Components\Tracking\TrackingSummary;
10
- use Ctct\Components\Tracking\UnsubscribeActivity;
11
-
12
- use GuzzleHttp\Client;
13
- use GuzzleHttp\Subscriber\Mock;
14
- use GuzzleHttp\Stream\Stream;
15
- use GuzzleHttp\Message\Response;
16
-
17
- class CampaignTrackingServiceUnitTest extends PHPUnit_Framework_TestCase
18
- {
19
- /**
20
- * @var Client
21
- */
22
- private static $client;
23
-
24
- public static function setUpBeforeClass()
25
- {
26
- self::$client = new Client();
27
- $bouncesStream = Stream::factory(JsonLoader::getBounces());
28
- $clicksStream = Stream::factory(JsonLoader::getClicks());
29
- $forwardsStream = Stream::factory(JsonLoader::getForwards());
30
- $unsubscribesStream = Stream::factory(JsonLoader::getOptOuts());
31
- $sendsStream = Stream::factory(JsonLoader::getSends());
32
- $opensStream = Stream::factory(JsonLoader::getOpens());
33
- $summaryStream = Stream::factory(JsonLoader::getSummary());
34
- $mock = new Mock([
35
- new Response(200, array(), $bouncesStream),
36
- new Response(200, array(), $clicksStream),
37
- new Response(200, array(), $forwardsStream),
38
- new Response(200, array(), $unsubscribesStream),
39
- new Response(200, array(), $sendsStream),
40
- new Response(200, array(), $opensStream),
41
- new Response(200, array(), $summaryStream)
42
- ]);
43
- self::$client->getEmitter()->attach($mock);
44
- }
45
-
46
- public function testGetBounces()
47
- {
48
- $response = self::$client->get('/');
49
-
50
- $responseJson = $response->json();
51
- $resultSet = new ResultSet($responseJson['results'], $responseJson['meta']);
52
-
53
- $bounceActivity = BounceActivity::create($resultSet->results[0]);
54
-
55
- $this->assertInstanceOf('Ctct\Components\ResultSet', $resultSet);
56
- $this->assertInstanceOf('Ctct\Components\Tracking\BounceActivity', $bounceActivity);
57
- $this->assertEquals("bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA", $resultSet->next);
58
- $this->assertEquals("EMAIL_BOUNCE", $bounceActivity->activity_type);
59
- $this->assertEquals(1100394165290, $bounceActivity->campaign_id);
60
- $this->assertEquals("2", $bounceActivity->contact_id);
61
- $this->assertEquals(
62
- "wizpie9dedde9dd27644bdb3d9be134b7294f71354817123188401000@snoopy.roving.com",
63
- $bounceActivity->email_address
64
- );
65
-
66
- $this->assertEquals("B", $bounceActivity->bounce_code);
67
- $this->assertEquals("Non-existent address", $bounceActivity->bounce_description);
68
- $this->assertEquals("", $bounceActivity->bounce_message);
69
- $this->assertEquals("2012-12-06T13:05:24.844Z", $bounceActivity->bounce_date);
70
- }
71
-
72
- public function testGetClicks()
73
- {
74
- $response = self::$client->get('/');
75
-
76
- $responseJson = $response->json();
77
- $resultSet = new ResultSet($responseJson['results'], $responseJson['meta']);
78
-
79
- $clickActivity = ClickActivity::create($resultSet->results[0]);
80
-
81
- $this->assertInstanceOf('Ctct\Components\ResultSet', $resultSet);
82
- $this->assertInstanceOf('Ctct\Components\Tracking\ClickActivity', $clickActivity);
83
- $this->assertEquals("bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA", $resultSet->next);
84
- $this->assertEquals("EMAIL_CLICK", $clickActivity->activity_type);
85
- $this->assertEquals(1100394165290, $clickActivity->campaign_id);
86
- $this->assertEquals("69", $clickActivity->contact_id);
87
- $this->assertEquals(
88
- "wizpie00375ca0a11346a89aea4b8f5991d0d91354817217769892000@snoopy.roving.com",
89
- $clickActivity->email_address
90
- );
91
-
92
- $this->assertEquals(0, $clickActivity->link_id);
93
- $this->assertEquals("2012-12-06T13:07:01.701Z", $clickActivity->click_date);
94
- }
95
-
96
- public function testGetForwards()
97
- {
98
- $response = self::$client->get('/');
99
-
100
- $responseJson = $response->json();
101
- $resultSet = new ResultSet($responseJson['results'], $responseJson['meta']);
102
-
103
- $forwardActivity = ForwardActivity::create($resultSet->results[0]);
104
-
105
- $this->assertInstanceOf('Ctct\Components\ResultSet', $resultSet);
106
- $this->assertInstanceOf('Ctct\Components\Tracking\ForwardActivity', $forwardActivity);
107
- $this->assertEquals("bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA", $resultSet->next);
108
- $this->assertEquals("EMAIL_FORWARD", $forwardActivity->activity_type);
109
- $this->assertEquals(1100394165290, $forwardActivity->campaign_id);
110
- $this->assertEquals("74", $forwardActivity->contact_id);
111
- $this->assertEquals(
112
- "wizpie2ca3455df5c34a26806f519f01f8a22e1354817223114268000@snoopy.roving.com",
113
- $forwardActivity->email_address
114
- );
115
-
116
- $this->assertEquals("2012-12-06T13:07:06.810Z", $forwardActivity->forward_date);
117
- }
118
-
119
- public function testGetUnsubscribes()
120
- {
121
- $response = self::$client->get('/');
122
-
123
- $responseJson = $response->json();
124
- $resultSet = new ResultSet($responseJson['results'], $responseJson['meta']);
125
-
126
- $unsubscribeActivity = UnsubscribeActivity::create($resultSet->results[0]);
127
-
128
- $this->assertInstanceOf('Ctct\Components\ResultSet', $resultSet);
129
- $this->assertInstanceOf('Ctct\Components\Tracking\UnsubscribeActivity', $unsubscribeActivity);
130
- $this->assertEquals("bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA", $resultSet->next);
131
- $this->assertEquals("EMAIL_UNSUBSCRIBE", $unsubscribeActivity->activity_type);
132
- $this->assertEquals(1100394165290, $unsubscribeActivity->campaign_id);
133
- $this->assertEquals("58", $unsubscribeActivity->contact_id);
134
- $this->assertEquals(
135
- "wizpieabd7817c1d0d4f08bb05f16f6681221c1354817211855027000@snoopy.roving.com",
136
- $unsubscribeActivity->email_address
137
- );
138
-
139
- $this->assertEquals("2012-12-06T13:06:53.440Z", $unsubscribeActivity->unsubscribe_date);
140
- $this->assertEquals("ACTION_BY_CUSTOMER", $unsubscribeActivity->unsubscribe_source);
141
- $this->assertEquals("", $unsubscribeActivity->unsubscribe_reason);
142
- }
143
-
144
- public function testGetSends()
145
- {
146
- $response = self::$client->get('/');
147
-
148
- $responseJson = $response->json();
149
- $resultSet = new ResultSet($responseJson['results'], $responseJson['meta']);
150
-
151
- $sendActivity = SendActivity::create($resultSet->results[0]);
152
-
153
- $this->assertInstanceOf('Ctct\Components\ResultSet', $resultSet);
154
- $this->assertInstanceOf('Ctct\Components\Tracking\SendActivity', $sendActivity);
155
- $this->assertEquals("bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA", $resultSet->next);
156
- $this->assertEquals("EMAIL_SEND", $sendActivity->activity_type);
157
- $this->assertEquals(1100394165290, $sendActivity->campaign_id);
158
- $this->assertEquals("55", $sendActivity->contact_id);
159
- $this->assertEquals(
160
- "wizpiea298d1c2500b4f2d8294300de4b29fe31354817207606824000@snoopy.roving.com",
161
- $sendActivity->email_address
162
- );
163
-
164
- $this->assertEquals("2012-12-06T18:06:50.650Z", $sendActivity->send_date);
165
- }
166
-
167
- public function testGetOpens()
168
- {
169
- $response = self::$client->get('/');
170
-
171
- $responseJson = $response->json();
172
- $resultSet = new ResultSet($responseJson['results'], $responseJson['meta']);
173
-
174
- $openActivity = OpenActivity::create($resultSet->results[0]);
175
-
176
- $this->assertInstanceOf('Ctct\Components\ResultSet', $resultSet);
177
- $this->assertInstanceOf('Ctct\Components\Tracking\OpenActivity', $openActivity);
178
- $this->assertEquals("bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA", $resultSet->next);
179
- $this->assertEquals("EMAIL_OPEN", $openActivity->activity_type);
180
- $this->assertEquals(1100394165290, $openActivity->campaign_id);
181
- $this->assertEquals("86", $openActivity->contact_id);
182
- $this->assertEquals(
183
- "wizpie9e19a6d35ec249efa8fc3085721aa61d1354817227762990000@snoopy.roving.com",
184
- $openActivity->email_address
185
- );
186
-
187
- $this->assertEquals("2012-12-06T13:07:11.839Z", $openActivity->open_date);
188
- }
189
-
190
- public function testGetSummary()
191
- {
192
- $response = self::$client->get('/');
193
-
194
- $summary = TrackingSummary::create($response->json());
195
- $this->assertInstanceOf('Ctct\Components\Tracking\TrackingSummary', $summary);
196
- $this->assertEquals(15, $summary->sends);
197
- $this->assertEquals(10, $summary->opens);
198
- $this->assertEquals(10, $summary->clicks);
199
- $this->assertEquals(3, $summary->forwards);
200
- $this->assertEquals(2, $summary->unsubscribes);
201
- $this->assertEquals(18, $summary->bounces);
202
- }
203
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Services/ContactServiceUnitTest.php DELETED
@@ -1,353 +0,0 @@
1
- <?php
2
-
3
- use Ctct\Components\ResultSet;
4
- use Ctct\Components\Contacts\Contact;
5
-
6
- use GuzzleHttp\Client;
7
- use GuzzleHttp\Exception\ClientException;
8
- use GuzzleHttp\Subscriber\Mock;
9
- use GuzzleHttp\Stream\Stream;
10
- use GuzzleHttp\Message\Response;
11
-
12
- class ContactServiceUnitTest extends PHPUnit_Framework_TestCase
13
- {
14
- /**
15
- * @var Client
16
- */
17
- private static $client;
18
-
19
- public static function setUpBeforeClass()
20
- {
21
- self::$client = new Client();
22
- $contactsStream = Stream::factory(JsonLoader::getContactsJson());
23
- $contactsNoNextStream = Stream::factory(JsonLoader::getContactsNoNextJson());
24
- $contactStream = Stream::factory(JsonLoader::getContactJson());
25
- $mock = new Mock([
26
- new Response(200, array(), $contactsStream),
27
- new Response(200, array(), $contactsNoNextStream),
28
- new Response(200, array(), $contactStream),
29
- new Response(201, array(), $contactStream),
30
- new Response(204, array()),
31
- new Response(400, array()),
32
- new Response(200, array(), $contactStream)
33
- ]);
34
- self::$client->getEmitter()->attach($mock);
35
- }
36
-
37
- public function testGetContacts()
38
- {
39
- $response = self::$client->get('/')->json();
40
- $result = new ResultSet($response['results'], $response['meta']);
41
-
42
- $this->assertInstanceOf('Ctct\Components\ResultSet', $result);
43
- $this->assertEquals('c3RhcnRBdD0zJmxpbWl0PTI', $result->next);
44
-
45
- $contact = Contact::create($result->results[1]);
46
- $this->assertInstanceOf('Ctct\Components\Contacts\Contact', $contact);
47
- $this->assertEquals(231, $contact->id);
48
- $this->assertEquals("ACTIVE", $contact->status);
49
- $this->assertEquals("", $contact->fax);
50
- $this->assertEquals("", $contact->prefix_name);
51
- $this->assertEquals("Jimmy", $contact->first_name);
52
- $this->assertEquals("Roving", $contact->last_name);
53
- $this->assertEquals("Bear Tamer", $contact->job_title);
54
- $this->assertEquals("Animal Trainer Pro", $contact->company_name);
55
- $this->assertEquals("details", $contact->source_details);
56
- $this->assertEquals(false, $contact->confirmed);
57
- $this->assertEquals("", $contact->source);
58
-
59
- // custom fields
60
- $customField = $contact->custom_fields[0];
61
- $this->assertEquals("CustomField1", $customField->name);
62
- $this->assertInstanceOf('Ctct\Components\Contacts\CustomField', $customField);
63
- $this->assertEquals("1", $customField->value);
64
-
65
- //addresses
66
- $address = $contact->addresses[0];
67
- $this->assertInstanceOf('Ctct\Components\Contacts\Address', $address);
68
- $this->assertEquals("Suite 101", $address->line1);
69
- $this->assertEquals("line2", $address->line2);
70
- $this->assertEquals("line3", $address->line3);
71
- $this->assertEquals("Brookfield", $address->city);
72
- $this->assertEquals("PERSONAL", $address->address_type);
73
- $this->assertEquals("WI", $address->state_code);
74
- $this->assertEquals("us", $address->country_code);
75
- $this->assertEquals("53027", $address->postal_code);
76
- $this->assertEquals("", $address->sub_postal_code);
77
-
78
- //notes
79
- $this->assertEquals(0, count($contact->notes));
80
-
81
- //lists
82
- $this->assertEquals(1, $contact->lists[0]->id);
83
- $this->assertEquals("ACTIVE", $contact->lists[0]->status);
84
-
85
- // EmailAddress
86
- $emailAddress = $contact->email_addresses[0];
87
- $this->assertInstanceOf('Ctct\Components\Contacts\EmailAddress', $emailAddress);
88
- $this->assertEquals("ACTIVE", $emailAddress->status);
89
- $this->assertEquals("NO_CONFIRMATION_REQUIRED", $emailAddress->confirm_status);
90
- $this->assertEquals("ACTION_BY_OWNER", $emailAddress->opt_in_source);
91
- $this->assertEquals("2012-06-22T10:29:09.976Z", $emailAddress->opt_in_date);
92
- $this->assertEquals("", $emailAddress->opt_out_date);
93
- $this->assertEquals("anothertest@roving.com", $emailAddress->email_address);
94
- }
95
-
96
- public function testGetContactsNoNextLink()
97
- {
98
- $response = self::$client->get('/')->json();
99
- $result = new ResultSet($response['results'], $response['meta']);
100
-
101
- $this->assertInstanceOf('Ctct\Components\ResultSet', $result);
102
- $this->assertEquals(null, $result->next);
103
-
104
- $contact = Contact::create($result->results[1]);
105
- $this->assertInstanceOf('Ctct\Components\Contacts\Contact', $contact);
106
- $this->assertEquals(231, $contact->id);
107
- $this->assertEquals("ACTIVE", $contact->status);
108
- $this->assertEquals("", $contact->fax);
109
- $this->assertEquals("", $contact->prefix_name);
110
- $this->assertEquals("Jimmy", $contact->first_name);
111
- $this->assertEquals("Roving", $contact->last_name);
112
- $this->assertEquals("Bear Tamer", $contact->job_title);
113
- $this->assertEquals("Animal Trainer Pro", $contact->company_name);
114
- $this->assertEquals("details", $contact->source_details);
115
- $this->assertEquals(false, $contact->confirmed);
116
- $this->assertEquals("", $contact->source);
117
-
118
- // custom fields
119
- $customField = $contact->custom_fields[0];
120
- $this->assertEquals("CustomField1", $customField->name);
121
- $this->assertInstanceOf('Ctct\Components\Contacts\CustomField', $customField);
122
- $this->assertEquals("1", $customField->value);
123
-
124
- //addresses
125
- $address = $contact->addresses[0];
126
- $this->assertInstanceOf('Ctct\Components\Contacts\Address', $address);
127
- $this->assertEquals("Suite 101", $address->line1);
128
- $this->assertEquals("line2", $address->line2);
129
- $this->assertEquals("line3", $address->line3);
130
- $this->assertEquals("Brookfield", $address->city);
131
- $this->assertEquals("PERSONAL", $address->address_type);
132
- $this->assertEquals("WI", $address->state_code);
133
- $this->assertEquals("us", $address->country_code);
134
- $this->assertEquals("53027", $address->postal_code);
135
- $this->assertEquals("", $address->sub_postal_code);
136
-
137
- //notes
138
- $this->assertEquals(0, count($contact->notes));
139
-
140
- //lists
141
- $this->assertEquals(1, $contact->lists[0]->id);
142
- $this->assertEquals("ACTIVE", $contact->lists[0]->status);
143
-
144
- // EmailAddress
145
- $emailAddress = $contact->email_addresses[0];
146
- $this->assertInstanceOf('Ctct\Components\Contacts\EmailAddress', $emailAddress);
147
- $this->assertEquals("ACTIVE", $emailAddress->status);
148
- $this->assertEquals("NO_CONFIRMATION_REQUIRED", $emailAddress->confirm_status);
149
- $this->assertEquals("ACTION_BY_OWNER", $emailAddress->opt_in_source);
150
- $this->assertEquals("2012-06-22T10:29:09.976Z", $emailAddress->opt_in_date);
151
- $this->assertEquals("", $emailAddress->opt_out_date);
152
- $this->assertEquals("anothertest@roving.com", $emailAddress->email_address);
153
- }
154
-
155
- public function testGetContact()
156
- {
157
- $response = self::$client->get('/');
158
-
159
- $contact = Contact::create($response->json());
160
- $this->assertInstanceOf('Ctct\Components\Contacts\Contact', $contact);
161
- $this->assertEquals(238, $contact->id);
162
- $this->assertEquals("ACTIVE", $contact->status);
163
- $this->assertEquals("555-1212", $contact->fax);
164
- $this->assertEquals("Mr.", $contact->prefix_name);
165
- $this->assertEquals("John", $contact->first_name);
166
- $this->assertEquals("Smith", $contact->last_name);
167
- $this->assertEquals("Software Engineer", $contact->job_title);
168
- $this->assertEquals("Constant Contact", $contact->company_name);
169
- $this->assertEquals("555-1212", $contact->home_phone);
170
- $this->assertEquals("555-1213", $contact->work_phone);
171
- $this->assertEquals("555-1214", $contact->cell_phone);
172
- $this->assertEquals("69f9d72b-0a5e-479d-b844-722b1da9595f", $contact->source_details);
173
- $this->assertEquals(false, $contact->confirmed);
174
- $this->assertEquals("API", $contact->source);
175
-
176
- // custom fields
177
- $this->assertInstanceOf('Ctct\Components\Contacts\CustomField', $contact->custom_fields[0]);
178
- $this->assertEquals("CustomField1", $contact->custom_fields[0]->name);
179
- $this->assertEquals("3/28/2011 11:09 AM EDT", $contact->custom_fields[0]->value);
180
- $this->assertEquals("CustomField2", $contact->custom_fields[1]->name);
181
- $this->assertEquals("Site owner", $contact->custom_fields[1]->value);
182
-
183
- //addresses
184
- $this->assertInstanceOf('Ctct\Components\Contacts\Address', $contact->addresses[0]);
185
- $this->assertEquals("1601 Trapelo Rd", $contact->addresses[0]->line1);
186
- $this->assertEquals("Suite 329", $contact->addresses[0]->line2);
187
- $this->assertEquals("Line 3", $contact->addresses[0]->line3);
188
- $this->assertEquals("Waltham", $contact->addresses[0]->city);
189
- $this->assertEquals("PERSONAL", $contact->addresses[0]->address_type);
190
- $this->assertEquals("MA", $contact->addresses[0]->state_code);
191
- $this->assertEquals("us", $contact->addresses[0]->country_code);
192
- $this->assertEquals("01720", $contact->addresses[0]->postal_code);
193
- $this->assertEquals("7885", $contact->addresses[0]->sub_postal_code);
194
-
195
- //notes
196
- $this->assertInstanceOf('Ctct\Components\Contacts\Note', $contact->notes[0]);
197
- $this->assertEquals(1, $contact->notes[0]->id);
198
- $this->assertEquals("Here are some cool notes to add", $contact->notes[0]->note);
199
- $this->assertEquals("2012-12-03T17:09:22.702Z", $contact->notes[0]->created_date);
200
-
201
- //lists
202
- $this->assertInstanceOf('Ctct\Components\Contacts\ContactList', $contact->lists[0]);
203
- $this->assertEquals(9, $contact->lists[0]->id);
204
- $this->assertEquals("ACTIVE", $contact->lists[0]->status);
205
-
206
- // EmailAddress
207
- $this->assertInstanceOf('Ctct\Components\Contacts\EmailAddress', $contact->email_addresses[0]);
208
- $this->assertEquals("ACTIVE", $contact->email_addresses[0]->status);
209
- $this->assertEquals("NO_CONFIRMATION_REQUIRED", $contact->email_addresses[0]->confirm_status);
210
- $this->assertEquals("ACTION_BY_VISITOR", $contact->email_addresses[0]->opt_in_source);
211
- $this->assertEquals("2012-09-17T14:40:41.271Z", $contact->email_addresses[0]->opt_in_date);
212
- $this->assertEquals("2012-03-29T14:59:25.427Z", $contact->email_addresses[0]->opt_out_date);
213
- $this->assertEquals("john+smith@gmail.com", $contact->email_addresses[0]->email_address);
214
- }
215
-
216
- public function testAddContact()
217
- {
218
- $response = self::$client->post('/');
219
-
220
- $contact = Contact::create($response->json());
221
- $this->assertInstanceOf('Ctct\Components\Contacts\Contact', $contact);
222
- $this->assertEquals(238, $contact->id);
223
- $this->assertEquals("ACTIVE", $contact->status);
224
- $this->assertEquals("555-1212", $contact->fax);
225
- $this->assertEquals("Mr.", $contact->prefix_name);
226
- $this->assertEquals("John", $contact->first_name);
227
- $this->assertEquals("Smith", $contact->last_name);
228
- $this->assertEquals("Software Engineer", $contact->job_title);
229
- $this->assertEquals("Constant Contact", $contact->company_name);
230
- $this->assertEquals("555-1212", $contact->home_phone);
231
- $this->assertEquals("555-1213", $contact->work_phone);
232
- $this->assertEquals("555-1214", $contact->cell_phone);
233
- $this->assertEquals("69f9d72b-0a5e-479d-b844-722b1da9595f", $contact->source_details);
234
- $this->assertEquals(false, $contact->confirmed);
235
- $this->assertEquals("API", $contact->source);
236
-
237
- // custom fields
238
- $this->assertInstanceOf('Ctct\Components\Contacts\CustomField', $contact->custom_fields[0]);
239
- $this->assertEquals("CustomField1", $contact->custom_fields[0]->name);
240
- $this->assertEquals("3/28/2011 11:09 AM EDT", $contact->custom_fields[0]->value);
241
- $this->assertEquals("CustomField2", $contact->custom_fields[1]->name);
242
- $this->assertEquals("Site owner", $contact->custom_fields[1]->value);
243
-
244
- //addresses
245
- $this->assertInstanceOf('Ctct\Components\Contacts\Address', $contact->addresses[0]);
246
- $this->assertEquals("1601 Trapelo Rd", $contact->addresses[0]->line1);
247
- $this->assertEquals("Suite 329", $contact->addresses[0]->line2);
248
- $this->assertEquals("Line 3", $contact->addresses[0]->line3);
249
- $this->assertEquals("Waltham", $contact->addresses[0]->city);
250
- $this->assertEquals("PERSONAL", $contact->addresses[0]->address_type);
251
- $this->assertEquals("MA", $contact->addresses[0]->state_code);
252
- $this->assertEquals("us", $contact->addresses[0]->country_code);
253
- $this->assertEquals("01720", $contact->addresses[0]->postal_code);
254
- $this->assertEquals("7885", $contact->addresses[0]->sub_postal_code);
255
-
256
- //notes
257
- $this->assertInstanceOf('Ctct\Components\Contacts\Note', $contact->notes[0]);
258
- $this->assertEquals(1, $contact->notes[0]->id);
259
- $this->assertEquals("Here are some cool notes to add", $contact->notes[0]->note);
260
- $this->assertEquals("2012-12-03T17:09:22.702Z", $contact->notes[0]->created_date);
261
-
262
- //lists
263
- $this->assertInstanceOf('Ctct\Components\Contacts\ContactList', $contact->lists[0]);
264
- $this->assertEquals(9, $contact->lists[0]->id);
265
- $this->assertEquals("ACTIVE", $contact->lists[0]->status);
266
-
267
- // EmailAddress
268
- $this->assertInstanceOf('Ctct\Components\Contacts\EmailAddress', $contact->email_addresses[0]);
269
- $this->assertEquals("ACTIVE", $contact->email_addresses[0]->status);
270
- $this->assertEquals("NO_CONFIRMATION_REQUIRED", $contact->email_addresses[0]->confirm_status);
271
- $this->assertEquals("ACTION_BY_VISITOR", $contact->email_addresses[0]->opt_in_source);
272
- $this->assertEquals("2012-09-17T14:40:41.271Z", $contact->email_addresses[0]->opt_in_date);
273
- $this->assertEquals("2012-03-29T14:59:25.427Z", $contact->email_addresses[0]->opt_out_date);
274
- $this->assertEquals("john+smith@gmail.com", $contact->email_addresses[0]->email_address);
275
- }
276
-
277
- public function testDeleteContact()
278
- {
279
- $response = self::$client->delete('/');
280
-
281
- $this->assertEquals(204, $response->getStatusCode());
282
- }
283
-
284
- public function testDeleteContactFailed() {
285
- try {
286
- self::$client->delete('/');
287
- $this->fail("Delete call didn't fail");
288
- } catch (ClientException $e) {
289
- $this->assertEquals(400, $e->getCode());
290
- }
291
- }
292
-
293
- public function testUpdateContact()
294
- {
295
- $response = self::$client->put('/');
296
-
297
- $contact = Contact::create($response->json());
298
- $this->assertInstanceOf('Ctct\Components\Contacts\Contact', $contact);
299
- $this->assertEquals(238, $contact->id);
300
- $this->assertEquals("ACTIVE", $contact->status);
301
- $this->assertEquals("555-1212", $contact->fax);
302
- $this->assertEquals("Mr.", $contact->prefix_name);
303
- $this->assertEquals("John", $contact->first_name);
304
- $this->assertEquals("Smith", $contact->last_name);
305
- $this->assertEquals("Software Engineer", $contact->job_title);
306
- $this->assertEquals("Constant Contact", $contact->company_name);
307
- $this->assertEquals("555-1212", $contact->home_phone);
308
- $this->assertEquals("555-1213", $contact->work_phone);
309
- $this->assertEquals("555-1214", $contact->cell_phone);
310
- $this->assertEquals("69f9d72b-0a5e-479d-b844-722b1da9595f", $contact->source_details);
311
- $this->assertEquals(false, $contact->confirmed);
312
- $this->assertEquals("API", $contact->source);
313
-
314
- // custom fields
315
- $this->assertInstanceOf('Ctct\Components\Contacts\CustomField', $contact->custom_fields[0]);
316
- $this->assertEquals("CustomField1", $contact->custom_fields[0]->name);
317
- $this->assertEquals("3/28/2011 11:09 AM EDT", $contact->custom_fields[0]->value);
318
- $this->assertEquals("CustomField2", $contact->custom_fields[1]->name);
319
- $this->assertEquals("Site owner", $contact->custom_fields[1]->value);
320
-
321
- //addresses
322
- $this->assertInstanceOf('Ctct\Components\Contacts\Address', $contact->addresses[0]);
323
- $this->assertEquals("1601 Trapelo Rd", $contact->addresses[0]->line1);
324
- $this->assertEquals("Suite 329", $contact->addresses[0]->line2);
325
- $this->assertEquals("Line 3", $contact->addresses[0]->line3);
326
- $this->assertEquals("Waltham", $contact->addresses[0]->city);
327
- $this->assertEquals("PERSONAL", $contact->addresses[0]->address_type);
328
- $this->assertEquals("MA", $contact->addresses[0]->state_code);
329
- $this->assertEquals("us", $contact->addresses[0]->country_code);
330
- $this->assertEquals("01720", $contact->addresses[0]->postal_code);
331
- $this->assertEquals("7885", $contact->addresses[0]->sub_postal_code);
332
-
333
- //notes
334
- $this->assertInstanceOf('Ctct\Components\Contacts\Note', $contact->notes[0]);
335
- $this->assertEquals(1, $contact->notes[0]->id);
336
- $this->assertEquals("Here are some cool notes to add", $contact->notes[0]->note);
337
- $this->assertEquals("2012-12-03T17:09:22.702Z", $contact->notes[0]->created_date);
338
-
339
- //lists
340
- $this->assertInstanceOf('Ctct\Components\Contacts\ContactList', $contact->lists[0]);
341
- $this->assertEquals(9, $contact->lists[0]->id);
342
- $this->assertEquals("ACTIVE", $contact->lists[0]->status);
343
-
344
- // EmailAddress
345
- $this->assertInstanceOf('Ctct\Components\Contacts\EmailAddress', $contact->email_addresses[0]);
346
- $this->assertEquals("ACTIVE", $contact->email_addresses[0]->status);
347
- $this->assertEquals("NO_CONFIRMATION_REQUIRED", $contact->email_addresses[0]->confirm_status);
348
- $this->assertEquals("ACTION_BY_VISITOR", $contact->email_addresses[0]->opt_in_source);
349
- $this->assertEquals("2012-09-17T14:40:41.271Z", $contact->email_addresses[0]->opt_in_date);
350
- $this->assertEquals("2012-03-29T14:59:25.427Z", $contact->email_addresses[0]->opt_out_date);
351
- $this->assertEquals("john+smith@gmail.com", $contact->email_addresses[0]->email_address);
352
- }
353
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Services/ContactTrackingServiceUnitTest.php DELETED
@@ -1,185 +0,0 @@
1
- <?php
2
-
3
- use Ctct\Components\ResultSet;
4
- use Ctct\Components\Tracking\BounceActivity;
5
- use Ctct\Components\Tracking\ClickActivity;
6
- use Ctct\Components\Tracking\ForwardActivity;
7
- use Ctct\Components\Tracking\UnsubscribeActivity;
8
- use Ctct\Components\Tracking\SendActivity;
9
- use Ctct\Components\Tracking\OpenActivity;
10
- use Ctct\Components\Tracking\TrackingSummary;
11
-
12
- use GuzzleHttp\Client;
13
- use GuzzleHttp\Subscriber\Mock;
14
- use GuzzleHttp\Stream\Stream;
15
- use GuzzleHttp\Message\Response;
16
-
17
- class ContactTrackingServiceUnitTest extends PHPUnit_Framework_TestCase
18
- {
19
- /**
20
- * @var Client
21
- */
22
- private static $client;
23
-
24
- public static function setUpBeforeClass()
25
- {
26
- self::$client = new Client();
27
- $getBouncesStream = Stream::factory(JsonLoader::getBounces());
28
- $getClicksStream = Stream::factory(JsonLoader::getClicks());
29
- $getForwardsStream = Stream::factory(JsonLoader::getForwards());
30
- $getUnsubscribesStream = Stream::factory(JsonLoader::getOptOuts());
31
- $getSendsStream = Stream::factory(JsonLoader::getSends());
32
- $getOpensStream = Stream::factory(JsonLoader::getOpens());
33
- $getSummaryStream = Stream::factory(JsonLoader::getSummary());
34
- $mock = new Mock([
35
- new Response(200, array(), $getBouncesStream),
36
- new Response(200, array(), $getClicksStream),
37
- new Response(200, array(), $getForwardsStream),
38
- new Response(200, array(), $getUnsubscribesStream),
39
- new Response(200, array(), $getSendsStream),
40
- new Response(200, array(), $getOpensStream),
41
- new Response(200, array(), $getSummaryStream)
42
- ]);
43
- self::$client->getEmitter()->attach($mock);
44
- }
45
-
46
- public function testGetBounces()
47
- {
48
- $response = self::$client->get('/')->json();
49
-
50
- $resultSet = new ResultSet($response['results'], $response['meta']);
51
- $bounceActivity = BounceActivity::create($resultSet->results[0]);
52
- $this->assertInstanceOf('Ctct\Components\ResultSet', $resultSet);
53
- $this->assertInstanceOf('Ctct\Components\Tracking\BounceActivity', $bounceActivity);
54
- $this->assertEquals("bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA", $resultSet->next);
55
- $this->assertEquals("EMAIL_BOUNCE", $bounceActivity->activity_type);
56
- $this->assertEquals(1100394165290, $bounceActivity->campaign_id);
57
- $this->assertEquals("2", $bounceActivity->contact_id);
58
- $this->assertEquals(
59
- "wizpie9dedde9dd27644bdb3d9be134b7294f71354817123188401000@snoopy.roving.com",
60
- $bounceActivity->email_address
61
- );
62
-
63
- $this->assertEquals("B", $bounceActivity->bounce_code);
64
- $this->assertEquals("Non-existent address", $bounceActivity->bounce_description);
65
- $this->assertEquals("", $bounceActivity->bounce_message);
66
- $this->assertEquals("2012-12-06T13:05:24.844Z", $bounceActivity->bounce_date);
67
- }
68
-
69
- public function testGetClicks()
70
- {
71
- $response = self::$client->get('/')->json();
72
-
73
- $resultSet = new ResultSet($response['results'], $response['meta']);
74
- $clickActivity = ClickActivity::create($resultSet->results[0]);
75
- $this->assertInstanceOf('Ctct\Components\ResultSet', $resultSet);
76
- $this->assertInstanceOf('Ctct\Components\Tracking\ClickActivity', $clickActivity);
77
- $this->assertEquals("bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA", $resultSet->next);
78
- $this->assertEquals("EMAIL_CLICK", $clickActivity->activity_type);
79
- $this->assertEquals(1100394165290, $clickActivity->campaign_id);
80
- $this->assertEquals("69", $clickActivity->contact_id);
81
- $this->assertEquals(
82
- "wizpie00375ca0a11346a89aea4b8f5991d0d91354817217769892000@snoopy.roving.com",
83
- $clickActivity->email_address
84
- );
85
-
86
- $this->assertEquals(0, $clickActivity->link_id);
87
- $this->assertEquals("2012-12-06T13:07:01.701Z", $clickActivity->click_date);
88
- }
89
-
90
- public function testGetForwards()
91
- {
92
- $response = self::$client->get('/')->json();
93
-
94
- $resultSet = new ResultSet($response['results'], $response['meta']);
95
- $forwardActivity = ForwardActivity::create($resultSet->results[0]);
96
- $this->assertInstanceOf('Ctct\Components\ResultSet', $resultSet);
97
- $this->assertInstanceOf('Ctct\Components\Tracking\ForwardActivity', $forwardActivity);
98
- $this->assertEquals("bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA", $resultSet->next);
99
- $this->assertEquals("EMAIL_FORWARD", $forwardActivity->activity_type);
100
- $this->assertEquals(1100394165290, $forwardActivity->campaign_id);
101
- $this->assertEquals("74", $forwardActivity->contact_id);
102
- $this->assertEquals(
103
- "wizpie2ca3455df5c34a26806f519f01f8a22e1354817223114268000@snoopy.roving.com",
104
- $forwardActivity->email_address
105
- );
106
-
107
- $this->assertEquals("2012-12-06T13:07:06.810Z", $forwardActivity->forward_date);
108
- }
109
-
110
- public function testGetUnsubscribes()
111
- {
112
- $response = self::$client->get('/')->json();
113
-
114
- $resultSet = new ResultSet($response['results'], $response['meta']);
115
- $unsubscribeActivity = UnsubscribeActivity::create($resultSet->results[0]);
116
- $this->assertInstanceOf('Ctct\Components\ResultSet', $resultSet);
117
- $this->assertInstanceOf('Ctct\Components\Tracking\UnsubscribeActivity', $unsubscribeActivity);
118
- $this->assertEquals("bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA", $resultSet->next);
119
- $this->assertEquals("EMAIL_UNSUBSCRIBE", $unsubscribeActivity->activity_type);
120
- $this->assertEquals(1100394165290, $unsubscribeActivity->campaign_id);
121
- $this->assertEquals("58", $unsubscribeActivity->contact_id);
122
- $this->assertEquals(
123
- "wizpieabd7817c1d0d4f08bb05f16f6681221c1354817211855027000@snoopy.roving.com",
124
- $unsubscribeActivity->email_address
125
- );
126
-
127
- $this->assertEquals("2012-12-06T13:06:53.440Z", $unsubscribeActivity->unsubscribe_date);
128
- $this->assertEquals("ACTION_BY_CUSTOMER", $unsubscribeActivity->unsubscribe_source);
129
- $this->assertEquals("", $unsubscribeActivity->unsubscribe_reason);
130
- }
131
-
132
- public function testGetSends()
133
- {
134
- $response = self::$client->get('/')->json();
135
-
136
- $resultSet = new ResultSet($response['results'], $response['meta']);
137
- $sendActivity = SendActivity::create($resultSet->results[0]);
138
- $this->assertInstanceOf('Ctct\Components\ResultSet', $resultSet);
139
- $this->assertInstanceOf('Ctct\Components\Tracking\SendActivity', $sendActivity);
140
- $this->assertEquals("bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA", $resultSet->next);
141
- $this->assertEquals("EMAIL_SEND", $sendActivity->activity_type);
142
- $this->assertEquals(1100394165290, $sendActivity->campaign_id);
143
- $this->assertEquals("55", $sendActivity->contact_id);
144
- $this->assertEquals(
145
- "wizpiea298d1c2500b4f2d8294300de4b29fe31354817207606824000@snoopy.roving.com",
146
- $sendActivity->email_address
147
- );
148
-
149
- $this->assertEquals("2012-12-06T18:06:50.650Z", $sendActivity->send_date);
150
- }
151
-
152
- public function testGetOpens()
153
- {
154
- $response = self::$client->get('/')->json();
155
-
156
- $resultSet = new ResultSet($response['results'], $response['meta']);
157
- $openActivity = OpenActivity::create($resultSet->results[0]);
158
- $this->assertInstanceOf('Ctct\Components\ResultSet', $resultSet);
159
- $this->assertInstanceOf('Ctct\Components\Tracking\OpenActivity', $openActivity);
160
- $this->assertEquals("bGltaXQ9MyZuZXh0PTEzNTQ4MTcyMTA0MzA", $resultSet->next);
161
- $this->assertEquals("EMAIL_OPEN", $openActivity->activity_type);
162
- $this->assertEquals(1100394165290, $openActivity->campaign_id);
163
- $this->assertEquals("86", $openActivity->contact_id);
164
- $this->assertEquals(
165
- "wizpie9e19a6d35ec249efa8fc3085721aa61d1354817227762990000@snoopy.roving.com",
166
- $openActivity->email_address
167
- );
168
-
169
- $this->assertEquals("2012-12-06T13:07:11.839Z", $openActivity->open_date);
170
- }
171
-
172
- public function testGetSummary()
173
- {
174
- $response = self::$client->get('/');
175
-
176
- $summary = TrackingSummary::create($response->json());
177
- $this->assertInstanceOf('Ctct\Components\Tracking\TrackingSummary', $summary);
178
- $this->assertEquals(15, $summary->sends);
179
- $this->assertEquals(10, $summary->opens);
180
- $this->assertEquals(10, $summary->clicks);
181
- $this->assertEquals(3, $summary->forwards);
182
- $this->assertEquals(2, $summary->unsubscribes);
183
- $this->assertEquals(18, $summary->bounces);
184
- }
185
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Services/EmailCampaignServiceUnitTest.php DELETED
@@ -1,291 +0,0 @@
1
- <?php
2
-
3
- use Ctct\Components\ResultSet;
4
- use Ctct\Components\EmailMarketing\Campaign;
5
- use Ctct\Components\EmailMarketing\CampaignPreview;
6
-
7
- use GuzzleHttp\Client;
8
- use GuzzleHttp\Exception\ClientException;
9
- use GuzzleHttp\Subscriber\Mock;
10
- use GuzzleHttp\Stream\Stream;
11
- use GuzzleHttp\Message\Response;
12
-
13
- class EmailMarketingServiceUnitTest extends PHPUnit_Framework_TestCase
14
- {
15
- /**
16
- * @var Client
17
- */
18
- private static $client;
19
-
20
- public static function setUpBeforeClass()
21
- {
22
- self::$client = new Client();
23
- $getCampaignsStream = Stream::factory(JsonLoader::getCampaignsJson());
24
- $getCampaignStream = Stream::factory(JsonLoader::getCampaignJson());
25
- $getPreviewStream = Stream::factory(JsonLoader::getPreviewJson());
26
- $mock = new Mock([
27
- new Response(200, array(), $getCampaignsStream),
28
- new Response(204, array()),
29
- new Response(400, array()),
30
- new Response(200, array(), $getCampaignStream),
31
- new Response(201, array(), $getCampaignStream),
32
- new Response(200, array(), $getCampaignStream),
33
- new Response(200, array(), $getPreviewStream)
34
- ]);
35
- self::$client->getEmitter()->attach($mock);
36
- }
37
-
38
- public function testGetCampaigns()
39
- {
40
- $response = self::$client->get('/')->json();
41
- $result = new ResultSet($response['results'], $response['meta']);
42
- $campaigns = array();
43
- foreach ($result->results as $campaign) {
44
- $campaigns[] = Campaign::create($campaign);
45
- }
46
-
47
- $this->assertInstanceOf('Ctct\Components\ResultSet', $result);
48
- $this->assertInstanceOf('Ctct\Components\EmailMarketing\Campaign', $campaigns[0]);
49
- $this->assertEquals("cGFnZU51bT0yJnBhZ2VTaXplPTM", $result->next);
50
- $this->assertEquals("1100371240640", $campaigns[0]->id);
51
- $this->assertEquals("Email Created 2012/11/29, 4:13 PM", $campaigns[0]->name);
52
- $this->assertEquals("SENT", $campaigns[0]->status);
53
- $this->assertEquals("2012-11-29T16:15:17.468Z", $campaigns[0]->modified_date);
54
-
55
- $this->assertEquals("1100368835463", $campaigns[1]->id);
56
- $this->assertEquals("CampaignNdddasdsdme2", $campaigns[1]->name);
57
- $this->assertEquals("DRAFT", $campaigns[1]->status);
58
- $this->assertEquals("2012-10-16T16:14:34.221Z", $campaigns[1]->modified_date);
59
- }
60
-
61
- public function testDeleteCampaign()
62
- {
63
- $response = self::$client->delete('/');
64
- $this->assertEquals(204, $response->getStatusCode());
65
- }
66
-
67
- public function testDeleteCampaignFailed()
68
- {
69
- try {
70
- self::$client->delete('/');
71
- $this->fail("Delete did not fail");
72
- } catch (ClientException $e) {
73
- $this->assertEquals(400, $e->getCode());
74
- }
75
- }
76
-
77
- public function testGetCampaign()
78
- {
79
- $response = self::$client->get('/');
80
-
81
- $campaign = Campaign::create($response->json());
82
- $this->assertInstanceOf('Ctct\Components\EmailMarketing\Campaign', $campaign);
83
- $this->assertEquals("1100394165290", $campaign->id);
84
- $this->assertEquals("CampaignName-05965ddb-12d2-43e5-b8f3-0c22ca487c3a", $campaign->name);
85
- $this->assertEquals("CampaignSubject", $campaign->subject);
86
- $this->assertEquals("SENT", $campaign->status);
87
- $this->assertEquals("From WSPI", $campaign->from_name);
88
- $this->assertEquals("wiz-20121206130519@l1.snoopy.roving.com", $campaign->from_email);
89
- $this->assertEquals("wiz-20121206130519@l1.snoopy.roving.com", $campaign->reply_to_email);
90
- $this->assertEquals("CUSTOM", $campaign->template_type);
91
- $this->assertEquals("2012-12-06T18:06:05.255Z", $campaign->created_date);
92
- $this->assertEquals("2012-12-06T18:06:40.342Z", $campaign->last_run_date);
93
- $this->assertEquals(false, $campaign->is_permission_reminder_enabled);
94
- $this->assertEquals("", $campaign->permission_reminder_text);
95
- $this->assertEquals(false, $campaign->is_view_as_webpage_enabled);
96
- $this->assertEquals("Having trouble viewing this email?", $campaign->view_as_web_page_text);
97
- $this->assertEquals("Click Here", $campaign->view_as_web_page_link_text);
98
- $this->assertEquals("Hi", $campaign->greeting_salutations);
99
- $this->assertEquals("FIRST_NAME", $campaign->greeting_name);
100
- $this->assertEquals("", $campaign->greeting_string);
101
- $this->assertEquals("http://www.constantcontact.com", $campaign->permalink_url);
102
-
103
- $this->assertEquals(
104
- "<html><body>Hi <a href=\"http://www.constantcontact.com\">Visit ConstantContact.com!</a> </body></html>",
105
- $campaign->email_content
106
- );
107
- $this->assertEqualS("HTML", $campaign->email_content_format);
108
- $this->assertEquals("", $campaign->style_sheet);
109
- $this->assertEquals("<text>Something to test</text>", $campaign->text_content);
110
-
111
- // message footer
112
- $this->assertEquals("Waltham", $campaign->message_footer->city);
113
- $this->assertEquals("MA", $campaign->message_footer->state);
114
- $this->assertEquals("US", $campaign->message_footer->country);
115
- $this->assertEquals("WSPIOrgName", $campaign->message_footer->organization_name);
116
- $this->assertEquals("1601 Trapelo RD", $campaign->message_footer->address_line_1);
117
- $this->assertEquals("suite 2", $campaign->message_footer->address_line_2);
118
- $this->assertEquals("box 4", $campaign->message_footer->address_line_3);
119
- $this->assertEquals("", $campaign->message_footer->international_state);
120
- $this->assertEquals("02451", $campaign->message_footer->postal_code);
121
- $this->assertEquals(true, $campaign->message_footer->include_forward_email);
122
- $this->assertEquals("WSPIForwardThisEmail", $campaign->message_footer->forward_email_link_text);
123
- $this->assertEquals(true, $campaign->message_footer->include_subscribe_link);
124
- $this->assertEquals("WSPISubscribeLinkText", $campaign->message_footer->subscribe_link_text);
125
-
126
- // tracking summary
127
- $this->assertEquals(15, $campaign->tracking_summary->sends);
128
- $this->assertEquals(10, $campaign->tracking_summary->opens);
129
- $this->assertEquals(10, $campaign->tracking_summary->clicks);
130
- $this->assertEquals(3, $campaign->tracking_summary->forwards);
131
- $this->assertEquals(2, $campaign->tracking_summary->unsubscribes);
132
- $this->assertEquals(18, $campaign->tracking_summary->bounces);
133
- $this->assertEquals(1, $campaign->tracking_summary->spam_count);
134
-
135
- // sent to contact lists
136
- $this->assertEquals(1, count($campaign->sent_to_contact_lists));
137
- $this->assertEquals(3, $campaign->sent_to_contact_lists[0]->id);
138
-
139
- //click through details
140
- $this->assertEquals("http://www.constantcontact.com", $campaign->click_through_details[0]->url);
141
- $this->assertEquals("1100394163874", $campaign->click_through_details[0]->url_uid);
142
- $this->assertEquals(10, $campaign->click_through_details[0]->click_count);
143
- }
144
-
145
- public function testAddCampaign()
146
- {
147
- $response = self::$client->post('/');
148
-
149
- $campaign = Campaign::create($response->json());
150
- $this->assertInstanceOf('Ctct\Components\EmailMarketing\Campaign', $campaign);
151
- $this->assertEquals("1100394165290", $campaign->id);
152
- $this->assertEquals("CampaignName-05965ddb-12d2-43e5-b8f3-0c22ca487c3a", $campaign->name);
153
- $this->assertEquals("CampaignSubject", $campaign->subject);
154
- $this->assertEquals("SENT", $campaign->status);
155
- $this->assertEquals("From WSPI", $campaign->from_name);
156
- $this->assertEquals("wiz-20121206130519@l1.snoopy.roving.com", $campaign->from_email);
157
- $this->assertEquals("wiz-20121206130519@l1.snoopy.roving.com", $campaign->reply_to_email);
158
- $this->assertEquals("CUSTOM", $campaign->template_type);
159
- $this->assertEquals("2012-12-06T18:06:05.255Z", $campaign->created_date);
160
- $this->assertEquals("2012-12-06T18:06:40.342Z", $campaign->last_run_date);
161
- $this->assertEquals(false, $campaign->is_permission_reminder_enabled);
162
- $this->assertEquals("", $campaign->permission_reminder_text);
163
- $this->assertEquals(false, $campaign->is_view_as_webpage_enabled);
164
- $this->assertEquals("Having trouble viewing this email?", $campaign->view_as_web_page_text);
165
- $this->assertEquals("Click Here", $campaign->view_as_web_page_link_text);
166
- $this->assertEquals("Hi", $campaign->greeting_salutations);
167
- $this->assertEquals("FIRST_NAME", $campaign->greeting_name);
168
- $this->assertEquals("", $campaign->greeting_string);
169
-
170
- $this->assertEquals(
171
- "<html><body>Hi <a href=\"http://www.constantcontact.com\">Visit ConstantContact.com!</a> </body></html>",
172
- $campaign->email_content
173
- );
174
-
175
- $this->assertEqualS("HTML", $campaign->email_content_format);
176
- $this->assertEquals("", $campaign->style_sheet);
177
- $this->assertEquals("<text>Something to test</text>", $campaign->text_content);
178
-
179
- // message footer
180
- $this->assertEquals("Waltham", $campaign->message_footer->city);
181
- $this->assertEquals("MA", $campaign->message_footer->state);
182
- $this->assertEquals("US", $campaign->message_footer->country);
183
- $this->assertEquals("WSPIOrgName", $campaign->message_footer->organization_name);
184
- $this->assertEquals("1601 Trapelo RD", $campaign->message_footer->address_line_1);
185
- $this->assertEquals("suite 2", $campaign->message_footer->address_line_2);
186
- $this->assertEquals("box 4", $campaign->message_footer->address_line_3);
187
- $this->assertEquals("", $campaign->message_footer->international_state);
188
- $this->assertEquals("02451", $campaign->message_footer->postal_code);
189
- $this->assertEquals(true, $campaign->message_footer->include_forward_email);
190
- $this->assertEquals("WSPIForwardThisEmail", $campaign->message_footer->forward_email_link_text);
191
- $this->assertEquals(true, $campaign->message_footer->include_subscribe_link);
192
- $this->assertEquals("WSPISubscribeLinkText", $campaign->message_footer->subscribe_link_text);
193
-
194
- // tracking summary
195
- $this->assertEquals(15, $campaign->tracking_summary->sends);
196
- $this->assertEquals(10, $campaign->tracking_summary->opens);
197
- $this->assertEquals(10, $campaign->tracking_summary->clicks);
198
- $this->assertEquals(3, $campaign->tracking_summary->forwards);
199
- $this->assertEquals(2, $campaign->tracking_summary->unsubscribes);
200
- $this->assertEquals(18, $campaign->tracking_summary->bounces);
201
-
202
- // sent to contact lists
203
- $this->assertEquals(1, count($campaign->sent_to_contact_lists));
204
- $this->assertEquals(3, $campaign->sent_to_contact_lists[0]->id);
205
-
206
- //click through details
207
- $this->assertEquals("http://www.constantcontact.com", $campaign->click_through_details[0]->url);
208
- $this->assertEquals("1100394163874", $campaign->click_through_details[0]->url_uid);
209
- $this->assertEquals(10, $campaign->click_through_details[0]->click_count);
210
- }
211
-
212
- public function testUpdateCampaign()
213
- {
214
- $response = self::$client->put('/');
215
-
216
- $campaign = Campaign::create($response->json());
217
- $this->assertInstanceOf('Ctct\Components\EmailMarketing\Campaign', $campaign);
218
- $this->assertEquals("1100394165290", $campaign->id);
219
- $this->assertEquals("CampaignName-05965ddb-12d2-43e5-b8f3-0c22ca487c3a", $campaign->name);
220
- $this->assertEquals("CampaignSubject", $campaign->subject);
221
- $this->assertEquals("SENT", $campaign->status);
222
- $this->assertEquals("From WSPI", $campaign->from_name);
223
- $this->assertEquals("wiz-20121206130519@l1.snoopy.roving.com", $campaign->from_email);
224
- $this->assertEquals("wiz-20121206130519@l1.snoopy.roving.com", $campaign->reply_to_email);
225
- $this->assertEquals("CUSTOM", $campaign->template_type);
226
- $this->assertEquals("2012-12-06T18:06:05.255Z", $campaign->created_date);
227
- $this->assertEquals("2012-12-06T18:06:40.342Z", $campaign->last_run_date);
228
- $this->assertEquals(false, $campaign->is_permission_reminder_enabled);
229
- $this->assertEquals("", $campaign->permission_reminder_text);
230
- $this->assertEquals(false, $campaign->is_view_as_webpage_enabled);
231
- $this->assertEquals("Having trouble viewing this email?", $campaign->view_as_web_page_text);
232
- $this->assertEquals("Click Here", $campaign->view_as_web_page_link_text);
233
- $this->assertEquals("Hi", $campaign->greeting_salutations);
234
- $this->assertEquals("FIRST_NAME", $campaign->greeting_name);
235
- $this->assertEquals("", $campaign->greeting_string);
236
-
237
- $this->assertEquals(
238
- "<html><body>Hi <a href=\"http://www.constantcontact.com\">Visit ConstantContact.com!</a> </body></html>",
239
- $campaign->email_content
240
- );
241
-
242
- $this->assertEquals("HTML", $campaign->email_content_format);
243
- $this->assertEquals("", $campaign->style_sheet);
244
- $this->assertEquals("<text>Something to test</text>", $campaign->text_content);
245
-
246
- // message footer
247
- $this->assertEquals("Waltham", $campaign->message_footer->city);
248
- $this->assertEquals("MA", $campaign->message_footer->state);
249
- $this->assertEquals("US", $campaign->message_footer->country);
250
- $this->assertEquals("WSPIOrgName", $campaign->message_footer->organization_name);
251
- $this->assertEquals("1601 Trapelo RD", $campaign->message_footer->address_line_1);
252
- $this->assertEquals("suite 2", $campaign->message_footer->address_line_2);
253
- $this->assertEquals("box 4", $campaign->message_footer->address_line_3);
254
- $this->assertEquals("", $campaign->message_footer->international_state);
255
- $this->assertEquals("02451", $campaign->message_footer->postal_code);
256
- $this->assertEquals(true, $campaign->message_footer->include_forward_email);
257
- $this->assertEquals("WSPIForwardThisEmail", $campaign->message_footer->forward_email_link_text);
258
- $this->assertEquals(true, $campaign->message_footer->include_subscribe_link);
259
- $this->assertEquals("WSPISubscribeLinkText", $campaign->message_footer->subscribe_link_text);
260
-
261
- // tracking summary
262
- $this->assertEquals(15, $campaign->tracking_summary->sends);
263
- $this->assertEquals(10, $campaign->tracking_summary->opens);
264
- $this->assertEquals(10, $campaign->tracking_summary->clicks);
265
- $this->assertEquals(3, $campaign->tracking_summary->forwards);
266
- $this->assertEquals(2, $campaign->tracking_summary->unsubscribes);
267
- $this->assertEquals(18, $campaign->tracking_summary->bounces);
268
-
269
- // sent to contact lists
270
- $this->assertEquals(1, count($campaign->sent_to_contact_lists));
271
- $this->assertEquals(3, $campaign->sent_to_contact_lists[0]->id);
272
-
273
- //click through details
274
- $this->assertEquals("http://www.constantcontact.com", $campaign->click_through_details[0]->url);
275
- $this->assertEquals("1100394163874", $campaign->click_through_details[0]->url_uid);
276
- $this->assertEquals(10, $campaign->click_through_details[0]->click_count);
277
- }
278
-
279
- public function testGetPreview() {
280
- $response = self::$client->get('/');
281
-
282
- $preview = CampaignPreview::create($response->json());
283
- $this->assertEquals("Subject Test", $preview->subject);
284
- $this->assertEquals("myemail@example.com", $preview->fromEmail);
285
- $this->assertEquals("myemail@example.com", $preview->replyToEmail);
286
- $htmlContent = "<head ><meta /></head><body><center><table bgcolor=\"#ffffff\" id=\"VWPLINK\" width=\"595\"><tr><td style=\"font-size: 8pt; font-family: Verdana, Arial, Helvetica, sans-serif; color: #000000;\" width=\"100%\">View this message as a web page\n<a >Click here\n</a></td></tr></table></center><center ><table bgcolor=\"#ffffff\" width=\"595\" ><tr ><td width=\"100%\" ><font color=\"#000000\" face=\"verdana,arial\" size=\"1\" ><div >As a reminder, you're receiving this email because you have expressed an interest in MyCompany. Don't forget to add from_email@example.com to your address book so we'll be sure to land in your inbox! You may unsubscribe if you no longer wish to receive our emails. <div >&nbsp;</div><div >You may <a >unsubscribe</a> if you no longer wish to receive our emails.</div></div></font></td></tr></table></center><img /><p>This is text of the email message.</p><br />\n<table bgcolor=\"#ffffff\" padding=\"0\" width=\"100%\" ><tr align=\"center\" ><td ><table bgcolor=\"#ffffff\" width=\"595\" ><tr ><td colspan=\"2\" ><font face=\"tahoma,sans-serif\" size=\"1\" ><b ><a >Click here to forward this message</a></b></font><br />\n<br />\n</td></tr>\n<tr ><td ><FooterContent ><a ><img /></a></FooterContent></td><td align=\"right\" ><font face=\"tahoma,sans-serif\" size=\"1\" ><FooterLogo ><a ><img /></a></FooterLogo></font>\n</td>\n</tr><tr ><td colspan=\"2\" ><font face=\"tahoma,sans-serif\" size=\"1\" ><FooterContent ><div >This email was sent to {Email Address} by <a >rmarcucella@constantcontact.com</a> <span style=\"color: #bababa;\" > | </span> &nbsp; </div>\n<div ><a >Update Profile/Email Address</a> <span style=\"color: #bababa;\" >|</span> Instant removal with <a >SafeUnsubscribe</a>&trade; <span style=\"color: #bababa;\" >|</span> <a >Privacy Policy</a>.</div></FooterContent></font>\n</td>\n</tr>\n<tr ><td colspan=\"2\" ><font face=\"tahoma,sans-serif\" size=\"1\" ><br />My Organization | 123 Maple Street | Suite 1 | Anytown | MA | 01444</font>\n</td>\n</tr>\n</table>\n</td>\n</tr>\n</table>\n<br />\n&lt;/body&gt;";
287
- $this->assertEquals($htmlContent, $preview->htmlContent);
288
- $textContent = "View this message as a web page\nClick here\nhttp://campaign.r20.l1.constantcontact.com/render?ca=025eff86-6378-4f53-9301-5897ecf50b30&c={Contact Id}&ch={Contact Id}\n\nAs a reminder, you're receiving this email because you have expressed an interest in MyCompany. Don't forget to add from_email@example.com to your address book so we'll be sure to land in your inbox! You may unsubscribe if you no longer wish to receive our emails. You may unsubscribe\nhttp://visitor.l1.constantcontact.com/do?p=un&m=001JZtDyxcvPiye1EthMqSLGA%3D%3D&ch={Contact Id}&ca=025eff86-6378-4f53-9301-5897ecf50b30\n if you no longer wish to receive our emails.\n------------------------------------------------------------\nThis is the text of the email message.\n\nClick here to forward this message\nhttp://ui.l1.constantcontact.com/sa/fwtf.jsp?llr=cqmhk9aab&m=1100394770946&ea=rmarcucella%40constantcontact.com&a=1100400205633\n\n\n\n\n\nThis email was sent to {Email Address} by rmarcucella@constantcontact.com.\n\nUpdate Profile/Email Address\nhttp://visitor.l1.constantcontact.com/do?p=oo&m=001JZtDyxcvPiye1EthMqSLGA%3D%3D&ch={Contact Id}&ca=025eff86-6378-4f53-9301-5897ecf50b30\n\n\nInstant removal with SafeUnsubscribe(TM)\nhttp://visitor.l1.constantcontact.com/do?p=un&m=001JZtDyxcvPiye1EthMqSLGA%3D%3D&ch={Contact Id}&ca=025eff86-6378-4f53-9301-5897ecf50b30\n\n\nPrivacy Policy:\nhttp://ui.l1.constantcontact.com/roving/CCPrivacyPolicy.jsp\n\n\n\n\n\nOnline Marketing by\nhttp://img.l1.constantcontact.com/letters/images/cc-logo-color-sm.gif\nhttp://www.constantcontact.com\n\n\n\nMy Organization | 123 Maple Street | Suite 1 | Anytown | MA | 01444\n\n\n\n\n\n\n\n\n";
289
- $this->assertEquals($textContent, $preview->textContent);
290
- }
291
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Services/LibraryServiceUnitTest.php DELETED
@@ -1,195 +0,0 @@
1
- <?php
2
-
3
- use Ctct\Components\ResultSet;
4
- use Ctct\Components\Library\File;
5
- use Ctct\Components\Library\Folder;
6
- use Ctct\Components\Library\FileUploadStatus;
7
-
8
- use GuzzleHttp\Client;
9
- use GuzzleHttp\Subscriber\Mock;
10
- use GuzzleHttp\Stream\Stream;
11
- use GuzzleHttp\Message\Response;
12
-
13
- class LibraryServiceUnitTest extends PHPUnit_Framework_TestCase
14
- {
15
- /**
16
- * @var Client
17
- */
18
- private static $client;
19
-
20
- public static function setUpBeforeClass()
21
- {
22
- self::$client = new Client();
23
- $getFileStream = Stream::factory(JsonLoader::getLibraryFileJson());
24
- $getFilesStream = Stream::factory(JsonLoader::getLibraryFilesJson());
25
- $getFolderStream = Stream::factory(JsonLoader::getLibraryFolderJson());
26
- $getFoldersStream = Stream::factory(JsonLoader::getLibraryFoldersJson());
27
- $getFileUploadStream = Stream::factory(JsonLoader::getFileUploadStatusJson());
28
- $mock = new Mock([
29
- new Response(200, array(), $getFileStream),
30
- new Response(200, array(), $getFilesStream),
31
- new Response(200, array(), $getFolderStream),
32
- new Response(200, array(), $getFoldersStream),
33
- new Response(201, array("Id" => 1)),
34
- new Response(200, array(), $getFileUploadStream)
35
- ]);
36
- self::$client->getEmitter()->attach($mock);
37
- }
38
-
39
- public function testGetLibraryFile()
40
- {
41
- $response = self::$client->get('/');
42
-
43
- $file = File::create($response->json());
44
- $this->assertInstanceOf('Ctct\Components\Library\File', $file);
45
- $this->assertEquals("IMG_0261.JPG", $file->name);
46
- $this->assertEquals("4", $file->id);
47
- $this->assertEquals("chocolates", $file->description);
48
- $this->assertEquals("Images", $file->folder);
49
- $this->assertEquals(600, $file->height);
50
- $this->assertEquals(800, $file->width);
51
- $this->assertEquals(68825, $file->size);
52
- $this->assertEquals("https://origin.ih.l1.constantcontact.com/fs115/1100310339939/img/4.jpg", $file->url);
53
- $this->assertEquals("MyComputer", $file->source);
54
- $this->assertEquals("Active", $file->status);
55
-
56
- $this->assertInstanceOf('Ctct\Components\Library\Thumbnail', $file->thumbnail);
57
- $this->assertEquals("https://origin.ih.l1.constantcontact.com/fs115/1100310339939/img/4.jpg", $file->thumbnail->url);
58
- $this->assertEquals(200, $file->thumbnail->width);
59
- $this->assertEquals(150, $file->thumbnail->height);
60
-
61
- $this->assertEquals("2013-06-19T11:36:43.000-04:00", $file->created_date);
62
- $this->assertEquals("2013-08-23T12:54:17.000-04:00", $file->modified_date);
63
- $this->assertEquals(null, $file->folder_id);
64
- $this->assertEquals(true, $file->is_image);
65
- $this->assertEquals("JPG", $file->type);
66
- }
67
-
68
- public function testGetLibraryFiles()
69
- {
70
- $response = self::$client->get('/')->json();
71
-
72
- $result = new ResultSet($response['results'], $response['meta']);
73
- $files = array();
74
- foreach ($result->results as $file) {
75
- $files[] = File::create($file);
76
- }
77
-
78
- $this->assertInstanceOf('Ctct\Components\ResultSet', $result);
79
- $this->assertEquals('c023cmNlPUFsbCUiUmZzZXQ9MTgyIcV5cGU9QWxsJmxpbWl0PTE', $result->next);
80
- $this->assertInstanceOf('Ctct\Components\Library\File', $files[0]);
81
- $this->assertEquals("Test_card.png", $files[0]->name);
82
- $this->assertEquals("182", $files[0]->id);
83
- $this->assertEquals("descriptionssss", $files[0]->description);
84
- $this->assertEquals("Images", $files[0]->folder);
85
- $this->assertEquals(360, $files[0]->height);
86
- $this->assertEquals(640, $files[0]->width);
87
- $this->assertEquals(26271, $files[0]->size);
88
- $this->assertEquals("https://mlsvc01-prod.s3.amazonaws.com/489270ef001/d738eefc-8e8e-4a69-8e7d-8e7217d22a0a.png", $files[0]->url);
89
- $this->assertEquals("MyComputer", $files[0]->source);
90
- $this->assertEquals("Active", $files[0]->status);
91
-
92
- $this->assertInstanceOf('Ctct\Components\Library\Thumbnail', $files[0]->thumbnail);
93
- $this->assertEquals("https://mlsvc01-prod.s3.amazonaws.com/489270ef001/d738eefc-8e8e-4a69-8e7d-8e7217d22a0a.png", $files[0]->thumbnail->url);
94
- $this->assertEquals(112, $files[0]->thumbnail->height);
95
- $this->assertEquals(200, $files[0]->thumbnail->width);
96
-
97
- $this->assertEquals("2015-01-09T00:14:08.000-05:00", $files[0]->created_date);
98
- $this->assertEquals("2015-01-09T00:14:08.000-05:00", $files[0]->modified_date);
99
- $this->assertEquals(null, $files[0]->folder_id);
100
- $this->assertEquals(true, $files[0]->is_image);
101
- $this->assertEquals("PNG", $files[0]->file_type);
102
- }
103
-
104
- public function testGetLibraryFolder()
105
- {
106
- $response = self::$client->get('/');
107
-
108
- $folder = Folder::create($response->json());
109
- $this->assertInstanceOf('Ctct\Components\Library\Folder', $folder);
110
- $this->assertEquals("-5", $folder->id);
111
- $this->assertEquals("Folder", $folder->name);
112
- $this->assertEquals(1, $folder->level);
113
-
114
- $childrenCount = 0;
115
- foreach ($folder->children as $child) {
116
- $this->assertInstanceOf('Ctct\Components\Library\Folder', $child);
117
- $childrenCount++;
118
- }
119
- $this->assertEquals(2, $childrenCount);
120
- $this->assertEquals("-7", $folder->children[0]->id);
121
- $this->assertEquals("SubFolder", $folder->children[0]->name);
122
- $this->assertEquals(2, $folder->children[0]->level);
123
- $this->assertEquals(null, $folder->children[0]->children);
124
- $this->assertEquals(0, $folder->children[0]->item_count);
125
- $this->assertEquals("-5", $folder->children[0]->parent_id);
126
- $this->assertEquals("2014-08-04T11:40:36.000-04:00", $folder->children[0]->modified_date);
127
- $this->assertEquals("2014-08-04T11:40:36.000-04:00", $folder->children[0]->created_date);
128
-
129
- $this->assertEquals(3, $folder->item_count);
130
- $this->assertEquals("2013-09-09T14:25:44.000-04:00", $folder->modified_date);
131
- $this->assertEquals("2013-09-09T14:25:44.000-04:00", $folder->created_date);
132
- }
133
-
134
- public function testGetLibraryFolders()
135
- {
136
- $response = self::$client->get('/')->json();
137
-
138
- $result = new ResultSet($response['results'], $response['meta']);
139
- $folders = array();
140
- foreach ($result->results as $folder) {
141
- $folders[] = Folder::create($folder);
142
- }
143
-
144
- $this->assertInstanceOf('Ctct\Components\ResultSet', $result);
145
- $this->assertEquals("b2Zmc1V0PTzmbGltaJE9Mo", $result->next);
146
- $this->assertInstanceOf('Ctct\Components\Library\Folder', $folders[0]);
147
- $this->assertEquals("-5", $folders[0]->id);
148
- $this->assertEquals("Folder", $folders[0]->name);
149
- $this->assertEquals(1, $folders[0]->level);
150
-
151
- $childrenCount = 0;
152
- foreach ($folders[0]->children as $child) {
153
- $this->assertInstanceOf('Ctct\Components\Library\Folder', $child);
154
- $childrenCount++;
155
- }
156
- $this->assertEquals(2, $childrenCount);
157
- $this->assertEquals("-7", $folders[0]->children[0]->id);
158
- $this->assertEquals("SubFolder", $folders[0]->children[0]->name);
159
- $this->assertEquals(2, $folders[0]->children[0]->level);
160
- $this->assertEquals(null, $folders[0]->children[0]->children);
161
- $this->assertEquals(0, $folders[0]->children[0]->item_count);
162
- $this->assertEquals("-5", $folders[0]->children[0]->parent_id);
163
- $this->assertEquals("2014-08-04T11:40:36.000-04:00", $folders[0]->children[0]->modified_date);
164
- $this->assertEquals("2014-08-04T11:40:36.000-04:00", $folders[0]->children[0]->created_date);
165
-
166
- $this->assertEquals(3, $folders[0]->item_count);
167
- $this->assertEquals("2013-09-09T14:25:44.000-04:00", $folders[0]->modified_date);
168
- $this->assertEquals("2013-09-09T14:25:44.000-04:00", $folders[0]->created_date);
169
- }
170
-
171
- public function testUploadFile()
172
- {
173
- $response = self::$client->post('/');
174
-
175
- $id = $response->getHeader("Id");
176
- $code = $response->getStatusCode();
177
- $this->assertEquals("1", $id);
178
- $this->assertEquals(201, $code);
179
- }
180
-
181
- public function testGetFileUploadStatus()
182
- {
183
- $response = self::$client->get('/');
184
-
185
- $statuses = array();
186
- foreach ($response->json() as $result) {
187
- $statuses[] = FileUploadStatus::create($result);
188
- }
189
-
190
- $fileUploadStatus = $statuses[0];
191
- $this->assertEquals("9", $fileUploadStatus->file_id);
192
- $this->assertEquals("Active", $fileUploadStatus->description);
193
- $this->assertEquals("Active", $fileUploadStatus->status);
194
- }
195
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/Services/ListServiceUnitTest.php DELETED
@@ -1,143 +0,0 @@
1
- <?php
2
-
3
- use Ctct\Components\ResultSet;
4
- use Ctct\Components\Contacts\Contact;
5
- use Ctct\Components\Contacts\ContactList;
6
-
7
- use GuzzleHttp\Client;
8
- use GuzzleHttp\Subscriber\Mock;
9
- use GuzzleHttp\Stream\Stream;
10
- use GuzzleHttp\Message\Response;
11
-
12
- class ListServiceUnitTest extends PHPUnit_Framework_TestCase
13
- {
14
- /**
15
- * @var Client
16
- */
17
- private static $client;
18
-
19
- public static function setUpBeforeClass()
20
- {
21
- self::$client = new Client();
22
- $getListsStream = Stream::factory(JsonLoader::getListsJson());
23
- $getListStream = Stream::factory(JsonLoader::getListJson());
24
- $getContactsStream = Stream::factory(JsonLoader::getContactsJson());
25
- $mock = new Mock([
26
- new Response(200, array(), $getListsStream),
27
- new Response(200, array(), $getListStream),
28
- new Response(201, array(), $getListStream),
29
- new Response(200, array(), $getListStream),
30
- new Response(200, array(), $getContactsStream)
31
- ]);
32
- self::$client->getEmitter()->attach($mock);
33
- }
34
-
35
- public function testGetLists()
36
- {
37
- $response = self::$client->get('/');
38
-
39
- $lists = array();
40
- foreach ($response->json() as $list) {
41
- $lists[] = ContactList::create($list);
42
- }
43
- $this->assertInstanceOf('Ctct\Components\Contacts\ContactList', $lists[0]);
44
- $this->assertEquals(1, $lists[0]->id);
45
- $this->assertEquals("General Interest", $lists[0]->name);
46
- $this->assertEquals("ACTIVE", $lists[0]->status);
47
- $this->assertEquals(17, $lists[0]->contact_count);
48
-
49
- $this->assertEquals(3, $lists[1]->id);
50
- $this->assertEquals("mod_Test List 1", $lists[1]->name);
51
- $this->assertEquals("HIDDEN", $lists[1]->status);
52
- $this->assertEquals(18, $lists[1]->contact_count);
53
- }
54
-
55
- public function testGetList()
56
- {
57
- $response = self::$client->get('/');
58
- $list = ContactList::create($response->json());
59
- $this->assertInstanceOf('Ctct\Components\Contacts\ContactList', $list);
60
- $this->assertEquals(6, $list->id);
61
- $this->assertEquals("Test List 4", $list->name);
62
- $this->assertEquals("HIDDEN", $list->status);
63
- $this->assertEquals(19, $list->contact_count);
64
- }
65
-
66
- public function testAddList()
67
- {
68
- $response = self::$client->post('/');
69
- $list = ContactList::create($response->json());
70
- $this->assertInstanceOf('Ctct\Components\Contacts\ContactList', $list);
71
- $this->assertEquals(6, $list->id);
72
- $this->assertEquals("Test List 4", $list->name);
73
- $this->assertEquals("HIDDEN", $list->status);
74
- $this->assertEquals(19, $list->contact_count);
75
- }
76
-
77
- public function testUpdateList()
78
- {
79
- $response = self::$client->put('/');
80
- $list = ContactList::create($response->json());
81
- $this->assertInstanceOf('Ctct\Components\Contacts\ContactList', $list);
82
- $this->assertEquals(6, $list->id);
83
- $this->assertEquals("Test List 4", $list->name);
84
- $this->assertEquals("HIDDEN", $list->status);
85
- $this->assertEquals(19, $list->contact_count);
86
- }
87
-
88
- public function testGetContactsFromList()
89
- {
90
- $response = self::$client->get('/')->json();
91
- $result = new ResultSet($response['results'], $response['meta']);
92
- $this->assertInstanceOf('Ctct\Components\ResultSet', $result);
93
-
94
- $contact = Contact::create($result->results[1]);
95
-
96
- $this->assertInstanceOf('Ctct\Components\Contacts\Contact', $contact);
97
- $this->assertEquals(231, $contact->id);
98
- $this->assertEquals("ACTIVE", $contact->status);
99
- $this->assertEquals("", $contact->fax);
100
- $this->assertEquals("", $contact->prefix_name);
101
- $this->assertEquals("Jimmy", $contact->first_name);
102
- $this->assertEquals("Roving", $contact->last_name);
103
- $this->assertEquals("Bear Tamer", $contact->job_title);
104
- $this->assertEquals("Animal Trainer Pro", $contact->company_name);
105
- $this->assertEquals("details", $contact->source_details);
106
- $this->assertEquals(false, $contact->confirmed);
107
- $this->assertEquals("", $contact->source);
108
-
109
- // custom fields
110
- $this->assertInstanceOf('Ctct\Components\Contacts\CustomField', $contact->custom_fields[0]);
111
- $this->assertEquals("CustomField1", $contact->custom_fields[0]->name);
112
- $this->assertEquals("1", $contact->custom_fields[0]->value);
113
-
114
- //addresses
115
- $this->assertInstanceOf('Ctct\Components\Contacts\Address', $contact->addresses[0]);
116
- $this->assertEquals("Suite 101", $contact->addresses[0]->line1);
117
- $this->assertEquals("line2", $contact->addresses[0]->line2);
118
- $this->assertEquals("line3", $contact->addresses[0]->line3);
119
- $this->assertEquals("Brookfield", $contact->addresses[0]->city);
120
- $this->assertEquals("PERSONAL", $contact->addresses[0]->address_type);
121
- $this->assertEquals("WI", $contact->addresses[0]->state_code);
122
- $this->assertEquals("us", $contact->addresses[0]->country_code);
123
- $this->assertEquals("53027", $contact->addresses[0]->postal_code);
124
- $this->assertEquals("", $contact->addresses[0]->sub_postal_code);
125
-
126
- //notes
127
- $this->assertEquals(0, count($contact->notes));
128
-
129
- //lists
130
- $this->assertInstanceOf('Ctct\Components\Contacts\ContactList', $contact->lists[0]);
131
- $this->assertEquals(1, $contact->lists[0]->id);
132
- $this->assertEquals("ACTIVE", $contact->lists[0]->status);
133
-
134
- // EmailAddress
135
- $this->assertInstanceOf('Ctct\Components\Contacts\EmailAddress', $contact->email_addresses[0]);
136
- $this->assertEquals("ACTIVE", $contact->email_addresses[0]->status);
137
- $this->assertEquals("NO_CONFIRMATION_REQUIRED", $contact->email_addresses[0]->confirm_status);
138
- $this->assertEquals("ACTION_BY_OWNER", $contact->email_addresses[0]->opt_in_source);
139
- $this->assertEquals("2012-06-22T10:29:09.976Z", $contact->email_addresses[0]->opt_in_date);
140
- $this->assertEquals("", $contact->email_addresses[0]->opt_out_date);
141
- $this->assertEquals("anothertest@roving.com", $contact->email_addresses[0]->email_address);
142
- }
143
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/constantcontact/constantcontact/test/bootstrap.php DELETED
@@ -1,9 +0,0 @@
1
- <?php
2
- // autoloader for the SDK
3
- require_once(realpath(dirname(__FILE__) . '/../') . "/src/Ctct/autoload.php");
4
-
5
- // load the JsonLoader
6
- require_once(__DIR__ . "/Json/JsonLoader.php");
7
-
8
- // autoload composer dependencies
9
- require_once(realpath(dirname(__FILE__) . '/../') . "/vendor/autoload.php");
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/docs/Makefile DELETED
@@ -1,153 +0,0 @@
1
- # Makefile for Sphinx documentation
2
- #
3
-
4
- # You can set these variables from the command line.
5
- SPHINXOPTS =
6
- SPHINXBUILD = sphinx-build
7
- PAPER =
8
- BUILDDIR = _build
9
-
10
- # Internal variables.
11
- PAPEROPT_a4 = -D latex_paper_size=a4
12
- PAPEROPT_letter = -D latex_paper_size=letter
13
- ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
14
- # the i18n builder cannot share the environment and doctrees with the others
15
- I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
16
-
17
- .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
18
-
19
- help:
20
- @echo "Please use \`make <target>' where <target> is one of"
21
- @echo " html to make standalone HTML files"
22
- @echo " dirhtml to make HTML files named index.html in directories"
23
- @echo " singlehtml to make a single large HTML file"
24
- @echo " pickle to make pickle files"
25
- @echo " json to make JSON files"
26
- @echo " htmlhelp to make HTML files and a HTML help project"
27
- @echo " qthelp to make HTML files and a qthelp project"
28
- @echo " devhelp to make HTML files and a Devhelp project"
29
- @echo " epub to make an epub"
30
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
31
- @echo " latexpdf to make LaTeX files and run them through pdflatex"
32
- @echo " text to make text files"
33
- @echo " man to make manual pages"
34
- @echo " texinfo to make Texinfo files"
35
- @echo " info to make Texinfo files and run them through makeinfo"
36
- @echo " gettext to make PO message catalogs"
37
- @echo " changes to make an overview of all changed/added/deprecated items"
38
- @echo " linkcheck to check all external links for integrity"
39
- @echo " doctest to run all doctests embedded in the documentation (if enabled)"
40
-
41
- clean:
42
- -rm -rf $(BUILDDIR)/*
43
-
44
- html:
45
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
46
- @echo
47
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
48
-
49
- dirhtml:
50
- $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
51
- @echo
52
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
53
-
54
- singlehtml:
55
- $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
56
- @echo
57
- @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
58
-
59
- pickle:
60
- $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
61
- @echo
62
- @echo "Build finished; now you can process the pickle files."
63
-
64
- json:
65
- $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
66
- @echo
67
- @echo "Build finished; now you can process the JSON files."
68
-
69
- htmlhelp:
70
- $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
71
- @echo
72
- @echo "Build finished; now you can run HTML Help Workshop with the" \
73
- ".hhp project file in $(BUILDDIR)/htmlhelp."
74
-
75
- qthelp:
76
- $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
77
- @echo
78
- @echo "Build finished; now you can run "qcollectiongenerator" with the" \
79
- ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
80
- @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/GuzzleRing.qhcp"
81
- @echo "To view the help file:"
82
- @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/GuzzleRing.qhc"
83
-
84
- devhelp:
85
- $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
86
- @echo
87
- @echo "Build finished."
88
- @echo "To view the help file:"
89
- @echo "# mkdir -p $$HOME/.local/share/devhelp/GuzzleRing"
90
- @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/GuzzleRing"
91
- @echo "# devhelp"
92
-
93
- epub:
94
- $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
95
- @echo
96
- @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
97
-
98
- latex:
99
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
100
- @echo
101
- @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
102
- @echo "Run \`make' in that directory to run these through (pdf)latex" \
103
- "(use \`make latexpdf' here to do that automatically)."
104
-
105
- latexpdf:
106
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
107
- @echo "Running LaTeX files through pdflatex..."
108
- $(MAKE) -C $(BUILDDIR)/latex all-pdf
109
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
110
-
111
- text:
112
- $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
113
- @echo
114
- @echo "Build finished. The text files are in $(BUILDDIR)/text."
115
-
116
- man:
117
- $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
118
- @echo
119
- @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
120
-
121
- texinfo:
122
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
123
- @echo
124
- @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
125
- @echo "Run \`make' in that directory to run these through makeinfo" \
126
- "(use \`make info' here to do that automatically)."
127
-
128
- info:
129
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
130
- @echo "Running Texinfo files through makeinfo..."
131
- make -C $(BUILDDIR)/texinfo info
132
- @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
133
-
134
- gettext:
135
- $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
136
- @echo
137
- @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
138
-
139
- changes:
140
- $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
141
- @echo
142
- @echo "The overview file is in $(BUILDDIR)/changes."
143
-
144
- linkcheck:
145
- $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
146
- @echo
147
- @echo "Link check complete; look for any errors in the above output " \
148
- "or in $(BUILDDIR)/linkcheck/output.txt."
149
-
150
- doctest:
151
- $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
152
- @echo "Testing of doctests in the sources finished, look at the " \
153
- "results in $(BUILDDIR)/doctest/output.txt."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/docs/client_handlers.rst DELETED
@@ -1,173 +0,0 @@
1
- ===============
2
- Client Handlers
3
- ===============
4
-
5
- Client handlers accept a request array and return a future response array that
6
- can be used synchronously as an array or asynchronously using a promise.
7
-
8
- Built-In Handlers
9
- -----------------
10
-
11
- RingPHP comes with three built-in client handlers.
12
-
13
- Stream Handler
14
- ~~~~~~~~~~~~~~
15
-
16
- The ``GuzzleHttp\Ring\Client\StreamHandler`` uses PHP's
17
- `http stream wrapper <http://php.net/manual/en/wrappers.http.php>`_ to send
18
- requests.
19
-
20
- .. note::
21
-
22
- This handler cannot send requests concurrently.
23
-
24
- You can provide an associative array of custom stream context options to the
25
- StreamHandler using the ``stream_context`` key of the ``client`` request
26
- option.
27
-
28
- .. code-block:: php
29
-
30
- use GuzzleHttp\Ring\Client\StreamHandler;
31
-
32
- $response = $handler([
33
- 'http_method' => 'GET',
34
- 'uri' => '/',
35
- 'headers' => ['host' => ['httpbin.org']],
36
- 'client' => [
37
- 'stream_context' => [
38
- 'http' => [
39
- 'request_fulluri' => true,
40
- 'method' => 'HEAD'
41
- ],
42
- 'socket' => [
43
- 'bindto' => '127.0.0.1:0'
44
- ],
45
- 'ssl' => [
46
- 'verify_peer' => false
47
- ]
48
- ]
49
- ]
50
- ]);
51
-
52
- // Even though it's already completed, you can still use a promise
53
- $response->then(function ($response) {
54
- echo $response['status']; // 200
55
- });
56
-
57
- // Or access the response using the future interface
58
- echo $response['status']; // 200
59
-
60
- cURL Handler
61
- ~~~~~~~~~~~~
62
-
63
- The ``GuzzleHttp\Ring\Client\CurlHandler`` can be used with PHP 5.5+ to send
64
- requests using cURL easy handles. This handler is great for sending requests
65
- one at a time because the execute and select loop is implemented in C code
66
- which executes faster and consumes less memory than using PHP's
67
- ``curl_multi_*`` interface.
68
-
69
- .. note::
70
-
71
- This handler cannot send requests concurrently.
72
-
73
- When using the CurlHandler, custom curl options can be specified as an
74
- associative array of `cURL option constants <http://php.net/manual/en/curl.constants.php>`_
75
- mapping to values in the ``client`` option of a requst using the **curl** key.
76
-
77
- .. code-block:: php
78
-
79
- use GuzzleHttp\Ring\Client\CurlHandler;
80
-
81
- $handler = new CurlHandler();
82
-
83
- $request = [
84
- 'http_method' => 'GET',
85
- 'headers' => ['host' => [Server::$host]],
86
- 'client' => ['curl' => [CURLOPT_LOW_SPEED_LIMIT => 10]]
87
- ];
88
-
89
- $response = $handler($request);
90
-
91
- // The response can be used directly as an array.
92
- echo $response['status']; // 200
93
-
94
- // Or, it can be used as a promise (that has already fulfilled).
95
- $response->then(function ($response) {
96
- echo $response['status']; // 200
97
- });
98
-
99
- cURL Multi Handler
100
- ~~~~~~~~~~~~~~~~~~
101
-
102
- The ``GuzzleHttp\Ring\Client\CurlMultiHandler`` transfers requests using
103
- cURL's `multi API <http://curl.haxx.se/libcurl/c/libcurl-multi.html>`_. The
104
- ``CurlMultiHandler`` is great for sending requests concurrently.
105
-
106
- .. code-block:: php
107
-
108
- use GuzzleHttp\Ring\Client\CurlMultiHandler;
109
-
110
- $handler = new CurlMultiHandler();
111
-
112
- $request = [
113
- 'http_method' => 'GET',
114
- 'headers' => ['host' => [Server::$host]]
115
- ];
116
-
117
- // this call returns a future array immediately.
118
- $response = $handler($request);
119
-
120
- // Ideally, you should use the promise API to not block.
121
- $response
122
- ->then(function ($response) {
123
- // Got the response at some point in the future
124
- echo $response['status']; // 200
125
- // Don't break the chain
126
- return $response;
127
- })->then(function ($response) {
128
- // ...
129
- });
130
-
131
- // If you really need to block, then you can use the response as an
132
- // associative array. This will block until it has completed.
133
- echo $response['status']; // 200
134
-
135
- Just like the ``CurlHandler``, the ``CurlMultiHandler`` accepts custom curl
136
- option in the ``curl`` key of the ``client`` request option.
137
-
138
- Mock Handler
139
- ~~~~~~~~~~~~
140
-
141
- The ``GuzzleHttp\Ring\Client\MockHandler`` is used to return mock responses.
142
- When constructed, the handler can be configured to return the same response
143
- array over and over, a future response, or a the evaluation of a callback
144
- function.
145
-
146
- .. code-block:: php
147
-
148
- use GuzzleHttp\Ring\Client\MockHandler;
149
-
150
- // Return a canned response.
151
- $mock = new MockHandler(['status' => 200]);
152
- $response = $mock([]);
153
- assert(200 == $response['status']);
154
- assert([] == $response['headers']);
155
-
156
- Implementing Handlers
157
- ---------------------
158
-
159
- Client handlers are just PHP callables (functions or classes that have the
160
- ``__invoke`` magic method). The callable accepts a request array and MUST
161
- return an instance of ``GuzzleHttp\Ring\Future\FutureArrayInterface`` so that
162
- the response can be used by both blocking and non-blocking consumers.
163
-
164
- Handlers need to follow a few simple rules:
165
-
166
- 1. Do not throw exceptions. If an error is encountered, return an array that
167
- contains the ``error`` key that maps to an ``\Exception`` value.
168
- 2. If the request has a ``delay`` client option, then the handler should only
169
- send the request after the specified delay time in seconds. Blocking
170
- handlers may find it convenient to just let the
171
- ``GuzzleHttp\Ring\Core::doSleep($request)`` function handle this for them.
172
- 3. Always return an instance of ``GuzzleHttp\Ring\Future\FutureArrayInterface``.
173
- 4. Complete any outstanding requests when the handler is destructed.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/docs/client_middleware.rst DELETED
@@ -1,165 +0,0 @@
1
- =================
2
- Client Middleware
3
- =================
4
-
5
- Middleware intercepts requests before they are sent over the wire and can be
6
- used to add functionality to handlers.
7
-
8
- Modifying Requests
9
- ------------------
10
-
11
- Let's say you wanted to modify requests before they are sent over the wire
12
- so that they always add specific headers. This can be accomplished by creating
13
- a function that accepts a handler and returns a new function that adds the
14
- composed behavior.
15
-
16
- .. code-block:: php
17
-
18
- use GuzzleHttp\Ring\Client\CurlHandler;
19
-
20
- $handler = new CurlHandler();
21
-
22
- $addHeaderHandler = function (callable $handler, array $headers = []) {
23
- return function (array $request) use ($handler, $headers) {
24
- // Add our custom headers
25
- foreach ($headers as $key => $value) {
26
- $request['headers'][$key] = $value;
27
- }
28
-
29
- // Send the request using the handler and return the response.
30
- return $handler($request);
31
- }
32
- };
33
-
34
- // Create a new handler that adds headers to each request.
35
- $handler = $addHeaderHandler($handler, [
36
- 'X-AddMe' => 'hello',
37
- 'Authorization' => 'Basic xyz'
38
- ]);
39
-
40
- $response = $handler([
41
- 'http_method' => 'GET',
42
- 'headers' => ['Host' => ['httpbin.org']]
43
- ]);
44
-
45
- Modifying Responses
46
- -------------------
47
-
48
- You can change a response as it's returned from a middleware. Remember that
49
- responses returned from an handler (including middleware) must implement
50
- ``GuzzleHttp\Ring\Future\FutureArrayInterface``. In order to be a good citizen,
51
- you should not expect that the responses returned through your middleware will
52
- be completed synchronously. Instead, you should use the
53
- ``GuzzleHttp\Ring\Core::proxy()`` function to modify the response when the
54
- underlying promise is resolved. This function is a helper function that makes it
55
- easy to create a new instance of ``FutureArrayInterface`` that wraps an existing
56
- ``FutureArrayInterface`` object.
57
-
58
- Let's say you wanted to add headers to a response as they are returned from
59
- your middleware, but you want to make sure you aren't causing future
60
- responses to be dereferenced right away. You can achieve this by modifying the
61
- incoming request and using the ``Core::proxy`` function.
62
-
63
- .. code-block:: php
64
-
65
- use GuzzleHttp\Ring\Core;
66
- use GuzzleHttp\Ring\Client\CurlHandler;
67
-
68
- $handler = new CurlHandler();
69
-
70
- $responseHeaderHandler = function (callable $handler, array $headers) {
71
- return function (array $request) use ($handler, $headers) {
72
- // Send the request using the wrapped handler.
73
- return Core::proxy($handler($request), function ($response) use ($headers) {
74
- // Add the headers to the response when it is available.
75
- foreach ($headers as $key => $value) {
76
- $response['headers'][$key] = (array) $value;
77
- }
78
- // Note that you can return a regular response array when using
79
- // the proxy method.
80
- return $response;
81
- });
82
- }
83
- };
84
-
85
- // Create a new handler that adds headers to each response.
86
- $handler = $responseHeaderHandler($handler, ['X-Header' => 'hello!']);
87
-
88
- $response = $handler([
89
- 'http_method' => 'GET',
90
- 'headers' => ['Host' => ['httpbin.org']]
91
- ]);
92
-
93
- assert($response['headers']['X-Header'] == 'hello!');
94
-
95
- Built-In Middleware
96
- -------------------
97
-
98
- RingPHP comes with a few basic client middlewares that modify requests
99
- and responses.
100
-
101
- Streaming Middleware
102
- ~~~~~~~~~~~~~~~~~~~~
103
-
104
- If you want to send all requests with the ``streaming`` option to a specific
105
- handler but other requests to a different handler, then use the streaming
106
- middleware.
107
-
108
- .. code-block:: php
109
-
110
- use GuzzleHttp\Ring\Client\CurlHandler;
111
- use GuzzleHttp\Ring\Client\StreamHandler;
112
- use GuzzleHttp\Ring\Client\Middleware;
113
-
114
- $defaultHandler = new CurlHandler();
115
- $streamingHandler = new StreamHandler();
116
- $streamingHandler = Middleware::wrapStreaming(
117
- $defaultHandler,
118
- $streamingHandler
119
- );
120
-
121
- // Send the request using the streaming handler.
122
- $response = $streamingHandler([
123
- 'http_method' => 'GET',
124
- 'headers' => ['Host' => ['www.google.com']],
125
- 'stream' => true
126
- ]);
127
-
128
- // Send the request using the default handler.
129
- $response = $streamingHandler([
130
- 'http_method' => 'GET',
131
- 'headers' => ['Host' => ['www.google.com']]
132
- ]);
133
-
134
- Future Middleware
135
- ~~~~~~~~~~~~~~~~~
136
-
137
- If you want to send all requests with the ``future`` option to a specific
138
- handler but other requests to a different handler, then use the future
139
- middleware.
140
-
141
- .. code-block:: php
142
-
143
- use GuzzleHttp\Ring\Client\CurlHandler;
144
- use GuzzleHttp\Ring\Client\CurlMultiHandler;
145
- use GuzzleHttp\Ring\Client\Middleware;
146
-
147
- $defaultHandler = new CurlHandler();
148
- $futureHandler = new CurlMultiHandler();
149
- $futureHandler = Middleware::wrapFuture(
150
- $defaultHandler,
151
- $futureHandler
152
- );
153
-
154
- // Send the request using the blocking CurlHandler.
155
- $response = $futureHandler([
156
- 'http_method' => 'GET',
157
- 'headers' => ['Host' => ['www.google.com']]
158
- ]);
159
-
160
- // Send the request using the non-blocking CurlMultiHandler.
161
- $response = $futureHandler([
162
- 'http_method' => 'GET',
163
- 'headers' => ['Host' => ['www.google.com']],
164
- 'future' => true
165
- ]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/docs/conf.py DELETED
@@ -1,23 +0,0 @@
1
- import sys, os
2
- import sphinx_rtd_theme
3
- from sphinx.highlighting import lexers
4
- from pygments.lexers.web import PhpLexer
5
-
6
-
7
- lexers['php'] = PhpLexer(startinline=True, linenos=1)
8
- lexers['php-annotations'] = PhpLexer(startinline=True, linenos=1)
9
- primary_domain = 'php'
10
-
11
- extensions = []
12
- templates_path = ['_templates']
13
- source_suffix = '.rst'
14
- master_doc = 'index'
15
- project = u'RingPHP'
16
- copyright = u'2014, Michael Dowling'
17
- version = '1.0.0-alpha'
18
- exclude_patterns = ['_build']
19
-
20
- html_title = "RingPHP"
21
- html_short_title = "RingPHP"
22
- html_theme = "sphinx_rtd_theme"
23
- html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/docs/futures.rst DELETED
@@ -1,164 +0,0 @@
1
- =======
2
- Futures
3
- =======
4
-
5
- Futures represent a computation that may have not yet completed. RingPHP
6
- uses hybrid of futures and promises to provide a consistent API that can be
7
- used for both blocking and non-blocking consumers.
8
-
9
- Promises
10
- --------
11
-
12
- You can get the result of a future when it is ready using the promise interface
13
- of a future. Futures expose a promise API via a ``then()`` method that utilizes
14
- `React's promise library <https://github.com/reactphp/promise>`_. You should
15
- use this API when you do not wish to block.
16
-
17
- .. code-block:: php
18
-
19
- use GuzzleHttp\Ring\Client\CurlMultiHandler;
20
-
21
- $request = [
22
- 'http_method' => 'GET',
23
- 'uri' => '/',
24
- 'headers' => ['host' => ['httpbin.org']]
25
- ];
26
-
27
- $response = $handler($request);
28
-
29
- // Use the then() method to use the promise API of the future.
30
- $response->then(function ($response) {
31
- echo $response['status'];
32
- });
33
-
34
- You can get the promise used by a future, an instance of
35
- ``React\Promise\PromiseInterface``, by calling the ``promise()`` method.
36
-
37
- .. code-block:: php
38
-
39
- $response = $handler($request);
40
- $promise = $response->promise();
41
- $promise->then(function ($response) {
42
- echo $response['status'];
43
- });
44
-
45
- This promise value can be used with React's
46
- `aggregate promise functions <https://github.com/reactphp/promise#functions>`_.
47
-
48
- Waiting
49
- -------
50
-
51
- You can wait on a future to complete and retrieve the value, or *dereference*
52
- the future, using the ``wait()`` method. Calling the ``wait()`` method of a
53
- future will block until the result is available. The result is then returned or
54
- an exception is thrown if and exception was encountered while waiting on the
55
- the result. Subsequent calls to dereference a future will return the previously
56
- completed result or throw the previously encountered exception. Futures can be
57
- cancelled, which stops the computation if possible.
58
-
59
- .. code-block:: php
60
-
61
- use GuzzleHttp\Ring\Client\CurlMultiHandler;
62
-
63
- $response = $handler([
64
- 'http_method' => 'GET',
65
- 'uri' => '/',
66
- 'headers' => ['host' => ['httpbin.org']]
67
- ]);
68
-
69
- // You can explicitly call block to wait on a result.
70
- $realizedResponse = $response->wait();
71
-
72
- // Future responses can be used like a regular PHP array.
73
- echo $response['status'];
74
-
75
- In addition to explicitly calling the ``wait()`` function, using a future like
76
- a normal value will implicitly trigger the ``wait()`` function.
77
-
78
- Future Responses
79
- ----------------
80
-
81
- RingPHP uses futures to return asynchronous responses immediately. Client
82
- handlers always return future responses that implement
83
- ``GuzzleHttp\Ring\Future\ArrayFutureInterface``. These future responses act
84
- just like normal PHP associative arrays for blocking access and provide a
85
- promise interface for non-blocking access.
86
-
87
- .. code-block:: php
88
-
89
- use GuzzleHttp\Ring\Client\CurlMultiHandler;
90
-
91
- $handler = new CurlMultiHandler();
92
-
93
- $request = [
94
- 'http_method' => 'GET',
95
- 'uri' => '/',
96
- 'headers' => ['Host' => ['www.google.com']]
97
- ];
98
-
99
- $response = $handler($request);
100
-
101
- // Use the promise API for non-blocking access to the response. The actual
102
- // response value will be delivered to the promise.
103
- $response->then(function ($response) {
104
- echo $response['status'];
105
- });
106
-
107
- // You can wait (block) until the future is completed.
108
- $response->wait();
109
-
110
- // This will implicitly call wait(), and will block too!
111
- $response['status'];
112
-
113
- .. important::
114
-
115
- Futures that are not completed by the time the underlying handler is
116
- destructed will be completed when the handler is shutting down.
117
-
118
- Cancelling
119
- ----------
120
-
121
- Futures can be cancelled if they have not already been dereferenced.
122
-
123
- RingPHP futures are typically implemented with the
124
- ``GuzzleHttp\Ring\Future\BaseFutureTrait``. This trait provides the cancellation
125
- functionality that should be common to most implementations. Cancelling a
126
- future response will try to prevent the request from sending over the wire.
127
-
128
- When a future is cancelled, the cancellation function is invoked and performs
129
- the actual work needed to cancel the request from sending if possible
130
- (e.g., telling an event loop to stop sending a request or to close a socket).
131
- If no cancellation function is provided, then a request cannot be cancelled. If
132
- a cancel function is provided, then it should accept the future as an argument
133
- and return true if the future was successfully cancelled or false if it could
134
- not be cancelled.
135
-
136
- Wrapping an existing Promise
137
- ----------------------------
138
-
139
- You can easily create a future from any existing promise using the
140
- ``GuzzleHttp\Ring\Future\FutureValue`` class. This class's constructor
141
- accepts a promise as the first argument, a wait function as the second
142
- argument, and a cancellation function as the third argument. The dereference
143
- function is used to force the promise to resolve (for example, manually ticking
144
- an event loop). The cancel function is optional and is used to tell the thing
145
- that created the promise that it can stop computing the result (for example,
146
- telling an event loop to stop transferring a request).
147
-
148
- .. code-block:: php
149
-
150
- use GuzzleHttp\Ring\Future\FutureValue;
151
- use React\Promise\Deferred;
152
-
153
- $deferred = new Deferred();
154
- $promise = $deferred->promise();
155
-
156
- $f = new FutureValue(
157
- $promise,
158
- function () use ($deferred) {
159
- // This function is responsible for blocking and resolving the
160
- // promise. Here we pass in a reference to the deferred so that
161
- // it can be resolved or rejected.
162
- $deferred->resolve('foo');
163
- }
164
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/docs/index.rst DELETED
@@ -1,50 +0,0 @@
1
- =======
2
- RingPHP
3
- =======
4
-
5
- Provides a simple API and specification that abstracts away the details of HTTP
6
- into a single PHP function. RingPHP be used to power HTTP clients and servers
7
- through a PHP function that accepts a request hash and returns a response hash
8
- that is fulfilled using a `promise <https://github.com/reactphp/promise>`_,
9
- allowing RingPHP to support both synchronous and asynchronous workflows.
10
-
11
- By abstracting the implementation details of different HTTP clients and
12
- servers, RingPHP allows you to utilize pluggable HTTP clients and servers
13
- without tying your application to a specific implementation.
14
-
15
- .. toctree::
16
- :maxdepth: 2
17
-
18
- spec
19
- futures
20
- client_middleware
21
- client_handlers
22
- testing
23
-
24
- .. code-block:: php
25
-
26
- <?php
27
- require 'vendor/autoload.php';
28
-
29
- use GuzzleHttp\Ring\Client\CurlHandler;
30
-
31
- $handler = new CurlHandler();
32
- $response = $handler([
33
- 'http_method' => 'GET',
34
- 'uri' => '/',
35
- 'headers' => [
36
- 'host' => ['www.google.com'],
37
- 'x-foo' => ['baz']
38
- ]
39
- ]);
40
-
41
- $response->then(function (array $response) {
42
- echo $response['status'];
43
- });
44
-
45
- $response->wait();
46
-
47
- RingPHP is inspired by Clojure's `Ring <https://github.com/ring-clojure/ring>`_,
48
- which, in turn, was inspired by Python's WSGI and Ruby's Rack. RingPHP is
49
- utilized as the handler layer in `Guzzle <http://guzzlephp.org>`_ 5.0+ to send
50
- HTTP requests.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/docs/requirements.txt DELETED
@@ -1 +0,0 @@
1
- sphinx_rtd_theme
 
vendor/constantcontact/guzzlehttp/ringphp/docs/spec.rst DELETED
@@ -1,311 +0,0 @@
1
- =============
2
- Specification
3
- =============
4
-
5
- RingPHP applications consist of handlers, requests, responses, and
6
- middleware.
7
-
8
- Handlers
9
- --------
10
-
11
- Handlers are implemented as a PHP ``callable`` that accept a request array
12
- and return a response array (``GuzzleHttp\Ring\Future\FutureArrayInterface``).
13
-
14
- For example:
15
-
16
- .. code-block:: php
17
-
18
- use GuzzleHttp\Ring\Future\CompletedFutureArray;
19
-
20
- $mockHandler = function (array $request) {
21
- return new CompletedFutureArray([
22
- 'status' => 200,
23
- 'headers' => ['X-Foo' => ['Bar']],
24
- 'body' => 'Hello!'
25
- ]);
26
- };
27
-
28
- This handler returns the same response each time it is invoked. All RingPHP
29
- handlers must return a ``GuzzleHttp\Ring\Future\FutureArrayInterface``. Use
30
- ``GuzzleHttp\Ring\Future\CompletedFutureArray`` when returning a response that
31
- has already completed.
32
-
33
- Requests
34
- --------
35
-
36
- A request array is a PHP associative array that contains the configuration
37
- settings need to send a request.
38
-
39
- .. code-block:: php
40
-
41
- $request = [
42
- 'http_method' => 'GET',
43
- 'scheme' => 'http',
44
- 'uri' => '/',
45
- 'body' => 'hello!',
46
- 'client' => ['timeout' => 1.0],
47
- 'headers' => [
48
- 'host' => ['httpbin.org'],
49
- 'X-Foo' => ['baz', 'bar']
50
- ]
51
- ];
52
-
53
- The request array contains the following key value pairs:
54
-
55
- request_method
56
- (string, required) The HTTP request method, must be all caps corresponding
57
- to a HTTP request method, such as ``GET`` or ``POST``.
58
-
59
- scheme
60
- (string) The transport protocol, must be one of ``http`` or ``https``.
61
- Defaults to ``http``.
62
-
63
- uri
64
- (string, required) The request URI excluding the query string. Must
65
- start with "/".
66
-
67
- query_string
68
- (string) The query string, if present (e.g., ``foo=bar``).
69
-
70
- version
71
- (string) HTTP protocol version. Defaults to ``1.1``.
72
-
73
- headers
74
- (required, array) Associative array of headers. Each key represents the
75
- header name. Each value contains an array of strings where each entry of
76
- the array SHOULD be sent over the wire on a separate header line.
77
-
78
- body
79
- (string, fopen resource, ``Iterator``, ``GuzzleHttp\Stream\StreamInterface``)
80
- The body of the request, if present. Can be a string, resource returned
81
- from fopen, an ``Iterator`` that yields chunks of data, an object that
82
- implemented ``__toString``, or a ``GuzzleHttp\Stream\StreamInterface``.
83
-
84
- future
85
- (bool, string) Controls the asynchronous behavior of a response.
86
-
87
- Set to ``true`` or omit the ``future`` option to *request* that a request
88
- will be completed asynchronously. Keep in mind that your request might not
89
- necessarily be completed asynchronously based on the handler you are using.
90
- Set the ``future`` option to ``false`` to request that a synchronous
91
- response be provided.
92
-
93
- You can provide a string value to specify fine-tuned future behaviors that
94
- may be specific to the underlying handlers you are using. There are,
95
- however, some common future options that handlers should implement if
96
- possible.
97
-
98
- lazy
99
- Requests that the handler does not open and send the request
100
- immediately, but rather only opens and sends the request once the
101
- future is dereferenced. This option is often useful for sending a large
102
- number of requests concurrently to allow handlers to take better
103
- advantage of non-blocking transfers by first building up a pool of
104
- requests.
105
-
106
- If an handler does not implement or understand a provided string value,
107
- then the request MUST be treated as if the user provided ``true`` rather
108
- than the string value.
109
-
110
- Future responses created by asynchronous handlers MUST attempt to complete
111
- any outstanding future responses when they are destructed. Asynchronous
112
- handlers MAY choose to automatically complete responses when the number
113
- of outstanding requests reaches an handler-specific threshold.
114
-
115
- Client Specific Options
116
- ~~~~~~~~~~~~~~~~~~~~~~~
117
-
118
- The following options are only used in ring client handlers.
119
-
120
- .. _client-options:
121
-
122
- client
123
- (array) Associative array of client specific transfer options. The
124
- ``client`` request key value pair can contain the following keys:
125
-
126
- cert
127
- (string, array) Set to a string to specify the path to a file
128
- containing a PEM formatted SSL client side certificate. If a password
129
- is required, then set ``cert`` to an array containing the path to the
130
- PEM file in the first array element followed by the certificate
131
- password in the second array element.
132
-
133
- connect_timeout
134
- (float) Float describing the number of seconds to wait while trying to
135
- connect to a server. Use ``0`` to wait indefinitely (the default
136
- behavior).
137
-
138
- debug
139
- (bool, fopen() resource) Set to true or set to a PHP stream returned by
140
- fopen() to enable debug output with the handler used to send a request.
141
- If set to ``true``, the output is written to PHP's STDOUT. If a PHP
142
- ``fopen`` resource handle is provided, the output is written to the
143
- stream.
144
-
145
- "Debug output" is handler specific: different handlers will yield
146
- different output and various various level of detail. For example, when
147
- using cURL to transfer requests, cURL's `CURLOPT_VERBOSE <http://curl.haxx.se/libcurl/c/CURLOPT_VERBOSE.html>`_
148
- will be used. When using the PHP stream wrapper, `stream notifications <http://php.net/manual/en/function.stream-notification-callback.php>`_
149
- will be emitted.
150
-
151
- decode_content
152
- (bool) Specify whether or not ``Content-Encoding`` responses
153
- (gzip, deflate, etc.) are automatically decoded. Set to ``true`` to
154
- automatically decode encoded responses. Set to ``false`` to not decode
155
- responses. By default, content is *not* decoded automatically.
156
-
157
- delay
158
- (int) The number of milliseconds to delay before sending the request.
159
- This is often used for delaying before retrying a request. Handlers
160
- SHOULD implement this if possible, but it is not a strict requirement.
161
-
162
- progress
163
- (function) Defines a function to invoke when transfer progress is made.
164
- The function accepts the following arguments:
165
-
166
- 1. The total number of bytes expected to be downloaded
167
- 2. The number of bytes downloaded so far
168
- 3. The number of bytes expected to be uploaded
169
- 4. The number of bytes uploaded so far
170
-
171
- proxy
172
- (string, array) Pass a string to specify an HTTP proxy, or an
173
- associative array to specify different proxies for different protocols
174
- where the scheme is the key and the value is the proxy address.
175
-
176
- .. code-block:: php
177
-
178
- $request = [
179
- 'http_method' => 'GET',
180
- 'headers' => ['host' => ['httpbin.org']],
181
- 'client' => [
182
- // Use different proxies for different URI schemes.
183
- 'proxy' => [
184
- 'http' => 'http://proxy.example.com:5100',
185
- 'https' => 'https://proxy.example.com:6100'
186
- ]
187
- ]
188
- ];
189
-
190
- ssl_key
191
- (string, array) Specify the path to a file containing a private SSL key
192
- in PEM format. If a password is required, then set to an array
193
- containing the path to the SSL key in the first array element followed
194
- by the password required for the certificate in the second element.
195
-
196
- save_to
197
- (string, fopen resource, ``GuzzleHttp\Stream\StreamInterface``)
198
- Specifies where the body of the response is downloaded. Pass a string to
199
- open a local file on disk and save the output to the file. Pass an fopen
200
- resource to save the output to a PHP stream resource. Pass a
201
- ``GuzzleHttp\Stream\StreamInterface`` to save the output to a Guzzle
202
- StreamInterface. Omitting this option will typically save the body of a
203
- response to a PHP temp stream.
204
-
205
- stream
206
- (bool) Set to true to stream a response rather than download it all
207
- up-front. This option will only be utilized when the corresponding
208
- handler supports it.
209
-
210
- timeout
211
- (float) Float describing the timeout of the request in seconds. Use 0 to
212
- wait indefinitely (the default behavior).
213
-
214
- verify
215
- (bool, string) Describes the SSL certificate verification behavior of a
216
- request. Set to true to enable SSL certificate verification using the
217
- system CA bundle when available (the default). Set to false to disable
218
- certificate verification (this is insecure!). Set to a string to provide
219
- the path to a CA bundle on disk to enable verification using a custom
220
- certificate.
221
-
222
- version
223
- (string) HTTP protocol version to use with the request.
224
-
225
- Server Specific Options
226
- ~~~~~~~~~~~~~~~~~~~~~~~
227
-
228
- The following options are only used in ring server handlers.
229
-
230
- server_port
231
- (integer) The port on which the request is being handled. This is only
232
- used with ring servers, and is required.
233
-
234
- server_name
235
- (string) The resolved server name, or the server IP address. Required when
236
- using a Ring server.
237
-
238
- remote_addr
239
- (string) The IP address of the client or the last proxy that sent the
240
- request. Required when using a Ring server.
241
-
242
- Responses
243
- ---------
244
-
245
- A response is an array-like object that implements
246
- ``GuzzleHttp\Ring\Future\FutureArrayInterface``. Responses contain the
247
- following key value pairs:
248
-
249
- body
250
- (string, fopen resource, ``Iterator``, ``GuzzleHttp\Stream\StreamInterface``)
251
- The body of the response, if present. Can be a string, resource returned
252
- from fopen, an ``Iterator`` that yields chunks of data, an object that
253
- implemented ``__toString``, or a ``GuzzleHttp\Stream\StreamInterface``.
254
-
255
- effective_url
256
- (string) The URL that returned the resulting response.
257
-
258
- error
259
- (``\Exception``) Contains an exception describing any errors that were
260
- encountered during the transfer.
261
-
262
- headers
263
- (Required, array) Associative array of headers. Each key represents the
264
- header name. Each value contains an array of strings where each entry of
265
- the array is a header line. The headers array MAY be an empty array in the
266
- event an error occurred before a response was received.
267
-
268
- reason
269
- (string) Optional reason phrase. This option should be provided when the
270
- reason phrase does not match the typical reason phrase associated with the
271
- ``status`` code. See `RFC 7231 <http://tools.ietf.org/html/rfc7231#section-6.1>`_
272
- for a list of HTTP reason phrases mapped to status codes.
273
-
274
- status
275
- (Required, integer) The HTTP status code. The status code MAY be set to
276
- ``null`` in the event an error occurred before a response was received
277
- (e.g., a networking error).
278
-
279
- transfer_stats
280
- (array) Provides an associative array of arbitrary transfer statistics if
281
- provided by the underlying handler.
282
-
283
- version
284
- (string) HTTP protocol version. Defaults to ``1.1``.
285
-
286
- Middleware
287
- ----------
288
-
289
- Ring middleware augments the functionality of handlers by invoking them in the
290
- process of generating responses. Middleware is typically implemented as a
291
- higher-order function that takes one or more handlers as arguments followed by
292
- an optional associative array of options as the last argument, returning a new
293
- handler with the desired compound behavior.
294
-
295
- Here's an example of a middleware that adds a Content-Type header to each
296
- request.
297
-
298
- .. code-block:: php
299
-
300
- use GuzzleHttp\Ring\Client\CurlHandler;
301
- use GuzzleHttp\Ring\Core;
302
-
303
- $contentTypeHandler = function(callable $handler, $contentType) {
304
- return function (array $request) use ($handler, $contentType) {
305
- return $handler(Core::setHeader('Content-Type', $contentType));
306
- };
307
- };
308
-
309
- $baseHandler = new CurlHandler();
310
- $wrappedHandler = $contentTypeHandler($baseHandler, 'text/html');
311
- $response = $wrappedHandler([/** request hash **/]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/docs/testing.rst DELETED
@@ -1,74 +0,0 @@
1
- =======
2
- Testing
3
- =======
4
-
5
- RingPHP tests client handlers using `PHPUnit <https://phpunit.de/>`_ and a
6
- built-in node.js web server.
7
-
8
- Running Tests
9
- -------------
10
-
11
- First, install the dependencies using `Composer <https://getcomposer.org>`_.
12
-
13
- composer.phar install
14
-
15
- Next, run the unit tests using ``Make``.
16
-
17
- make test
18
-
19
- The tests are also run on Travis-CI on each commit: https://travis-ci.org/guzzle/guzzle-ring
20
-
21
- Test Server
22
- -----------
23
-
24
- Testing client handlers usually involves actually sending HTTP requests.
25
- RingPHP provides a node.js web server that returns canned responses and
26
- keep a list of the requests that have been received. The server can then
27
- be queried to get a list of the requests that were sent by the client so that
28
- you can ensure that the client serialized and transferred requests as intended.
29
-
30
- The server keeps a list of queued responses and returns responses that are
31
- popped off of the queue as HTTP requests are received. When there are not
32
- more responses to serve, the server returns a 500 error response.
33
-
34
- The test server uses the ``GuzzleHttp\Tests\Ring\Client\Server`` class to
35
- control the server.
36
-
37
- .. code-block:: php
38
-
39
- use GuzzleHttp\Ring\Client\StreamHandler;
40
- use GuzzleHttp\Tests\Ring\Client\Server;
41
-
42
- // First return a 200 followed by a 404 response.
43
- Server::enqueue([
44
- ['status' => 200],
45
- ['status' => 404]
46
- ]);
47
-
48
- $handler = new StreamHandler();
49
-
50
- $response = $handler([
51
- 'http_method' => 'GET',
52
- 'headers' => ['host' => [Server::$host]],
53
- 'uri' => '/'
54
- ]);
55
-
56
- assert(200 == $response['status']);
57
-
58
- $response = $handler([
59
- 'http_method' => 'HEAD',
60
- 'headers' => ['host' => [Server::$host]],
61
- 'uri' => '/'
62
- ]);
63
-
64
- assert(404 == $response['status']);
65
-
66
- After requests have been sent, you can get a list of the requests as they
67
- were sent over the wire to ensure they were sent correctly.
68
-
69
- .. code-block:: php
70
-
71
- $received = Server::received();
72
-
73
- assert('GET' == $received[0]['http_method']);
74
- assert('HEAD' == $received[1]['http_method']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/phpunit.xml.dist DELETED
@@ -1,14 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <phpunit bootstrap="./tests/bootstrap.php"
3
- colors="true">
4
- <testsuites>
5
- <testsuite>
6
- <directory>tests</directory>
7
- </testsuite>
8
- </testsuites>
9
- <filter>
10
- <whitelist>
11
- <directory suffix=".php">src</directory>
12
- </whitelist>
13
- </filter>
14
- </phpunit>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/tests/Client/CurlFactoryTest.php DELETED
@@ -1,821 +0,0 @@
1
- <?php
2
- // Override curl_setopt_array() to get the last set curl options
3
- namespace GuzzleHttp\Ring\Client {
4
- function curl_setopt_array($handle, array $options) {
5
- if (!empty($_SERVER['curl_test'])) {
6
- $_SERVER['_curl'] = $options;
7
- } else {
8
- unset($_SERVER['_curl']);
9
- }
10
- \curl_setopt_array($handle, $options);
11
- }
12
- }
13
-
14
- namespace GuzzleHttp\Tests\Ring\Client {
15
-
16
- use GuzzleHttp\Ring\Client\CurlFactory;
17
- use GuzzleHttp\Ring\Client\CurlMultiHandler;
18
- use GuzzleHttp\Ring\Client\MockHandler;
19
- use GuzzleHttp\Ring\Core;
20
- use GuzzleHttp\Stream\FnStream;
21
- use GuzzleHttp\Stream\NoSeekStream;
22
- use GuzzleHttp\Stream\Stream;
23
-
24
- class CurlFactoryTest extends \PHPUnit_Framework_TestCase
25
- {
26
- public static function setUpBeforeClass()
27
- {
28
- $_SERVER['curl_test'] = true;
29
- unset($_SERVER['_curl']);
30
- }
31
-
32
- public static function tearDownAfterClass()
33
- {
34
- unset($_SERVER['_curl'], $_SERVER['curl_test']);
35
- }
36
-
37
- public function testCreatesCurlHandle()
38
- {
39
- Server::flush();
40
- Server::enqueue([[
41
- 'status' => 200,
42
- 'headers' => [
43
- 'Foo' => ['Bar'],
44
- 'Baz' => ['bam'],
45
- 'Content-Length' => [2],
46
- ],
47
- 'body' => 'hi',
48
- ]]);
49
-
50
- $stream = Stream::factory();
51
-
52
- $request = [
53
- 'http_method' => 'PUT',
54
- 'headers' => [
55
- 'host' => [Server::$url],
56
- 'Hi' => [' 123'],
57
- ],
58
- 'body' => 'testing',
59
- 'client' => ['save_to' => $stream],
60
- ];
61
-
62
- $f = new CurlFactory();
63
- $result = $f($request);
64
- $this->assertInternalType('array', $result);
65
- $this->assertCount(3, $result);
66
- $this->assertInternalType('resource', $result[0]);
67
- $this->assertInternalType('array', $result[1]);
68
- $this->assertSame($stream, $result[2]);
69
- curl_close($result[0]);
70
-
71
- $this->assertEquals('PUT', $_SERVER['_curl'][CURLOPT_CUSTOMREQUEST]);
72
- $this->assertEquals(
73
- 'http://http://127.0.0.1:8125/',
74
- $_SERVER['_curl'][CURLOPT_URL]
75
- );
76
- // Sends via post fields when the request is small enough
77
- $this->assertEquals('testing', $_SERVER['_curl'][CURLOPT_POSTFIELDS]);
78
- $this->assertEquals(0, $_SERVER['_curl'][CURLOPT_RETURNTRANSFER]);
79
- $this->assertEquals(0, $_SERVER['_curl'][CURLOPT_HEADER]);
80
- $this->assertEquals(150, $_SERVER['_curl'][CURLOPT_CONNECTTIMEOUT]);
81
- $this->assertInstanceOf('Closure', $_SERVER['_curl'][CURLOPT_HEADERFUNCTION]);
82
-
83
- if (defined('CURLOPT_PROTOCOLS')) {
84
- $this->assertEquals(
85
- CURLPROTO_HTTP | CURLPROTO_HTTPS,
86
- $_SERVER['_curl'][CURLOPT_PROTOCOLS]
87
- );
88
- }
89
-
90
- $this->assertContains('Expect:', $_SERVER['_curl'][CURLOPT_HTTPHEADER]);
91
- $this->assertContains('Accept:', $_SERVER['_curl'][CURLOPT_HTTPHEADER]);
92
- $this->assertContains('Content-Type:', $_SERVER['_curl'][CURLOPT_HTTPHEADER]);
93
- $this->assertContains('Hi: 123', $_SERVER['_curl'][CURLOPT_HTTPHEADER]);
94
- $this->assertContains('host: http://127.0.0.1:8125/', $_SERVER['_curl'][CURLOPT_HTTPHEADER]);
95
- }
96
-
97
- public function testSendsHeadRequests()
98
- {
99
- Server::flush();
100
- Server::enqueue([['status' => 200]]);
101
- $a = new CurlMultiHandler();
102
- $response = $a([
103
- 'http_method' => 'HEAD',
104
- 'headers' => ['host' => [Server::$host]],
105
- ]);
106
- $response->wait();
107
- $this->assertEquals(true, $_SERVER['_curl'][CURLOPT_NOBODY]);
108
- $checks = [CURLOPT_WRITEFUNCTION, CURLOPT_READFUNCTION, CURLOPT_FILE, CURLOPT_INFILE];
109
- foreach ($checks as $check) {
110
- $this->assertArrayNotHasKey($check, $_SERVER['_curl']);
111
- }
112
- $this->assertEquals('HEAD', Server::received()[0]['http_method']);
113
- }
114
-
115
- public function testCanAddCustomCurlOptions()
116
- {
117
- Server::flush();
118
- Server::enqueue([['status' => 200]]);
119
- $a = new CurlMultiHandler();
120
- $a([
121
- 'http_method' => 'GET',
122
- 'headers' => ['host' => [Server::$host]],
123
- 'client' => ['curl' => [CURLOPT_LOW_SPEED_LIMIT => 10]],
124
- ]);
125
- $this->assertEquals(10, $_SERVER['_curl'][CURLOPT_LOW_SPEED_LIMIT]);
126
- }
127
-
128
- /**
129
- * @expectedException \InvalidArgumentException
130
- * @expectedExceptionMessage SSL CA bundle not found: /does/not/exist
131
- */
132
- public function testValidatesVerify()
133
- {
134
- $f = new CurlFactory();
135
- $f([
136
- 'http_method' => 'GET',
137
- 'headers' => ['host' => ['foo.com']],
138
- 'client' => ['verify' => '/does/not/exist'],
139
- ]);
140
- }
141
-
142
- public function testCanSetVerifyToFile()
143
- {
144
- $f = new CurlFactory();
145
- $f([
146
- 'http_method' => 'GET',
147
- 'headers' => ['host' => ['foo.com']],
148
- 'client' => ['verify' => __FILE__],
149
- ]);
150
- $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_CAINFO]);
151
- $this->assertEquals(2, $_SERVER['_curl'][CURLOPT_SSL_VERIFYHOST]);
152
- $this->assertEquals(true, $_SERVER['_curl'][CURLOPT_SSL_VERIFYPEER]);
153
- }
154
-
155
- public function testAddsVerifyAsTrue()
156
- {
157
- $f = new CurlFactory();
158
- $f([
159
- 'http_method' => 'GET',
160
- 'headers' => ['host' => ['foo.com']],
161
- 'client' => ['verify' => true],
162
- ]);
163
- $this->assertEquals(2, $_SERVER['_curl'][CURLOPT_SSL_VERIFYHOST]);
164
- $this->assertEquals(true, $_SERVER['_curl'][CURLOPT_SSL_VERIFYPEER]);
165
- $this->assertArrayNotHasKey(CURLOPT_CAINFO, $_SERVER['_curl']);
166
- }
167
-
168
- public function testCanDisableVerify()
169
- {
170
- $f = new CurlFactory();
171
- $f([
172
- 'http_method' => 'GET',
173
- 'headers' => ['host' => ['foo.com']],
174
- 'client' => ['verify' => false],
175
- ]);
176
- $this->assertEquals(0, $_SERVER['_curl'][CURLOPT_SSL_VERIFYHOST]);
177
- $this->assertEquals(false, $_SERVER['_curl'][CURLOPT_SSL_VERIFYPEER]);
178
- }
179
-
180
- public function testAddsProxy()
181
- {
182
- $f = new CurlFactory();
183
- $f([
184
- 'http_method' => 'GET',
185
- 'headers' => ['host' => ['foo.com']],
186
- 'client' => ['proxy' => 'http://bar.com'],
187
- ]);
188
- $this->assertEquals('http://bar.com', $_SERVER['_curl'][CURLOPT_PROXY]);
189
- }
190
-
191
- public function testAddsViaScheme()
192
- {
193
- $f = new CurlFactory();
194
- $f([
195
- 'http_method' => 'GET',
196
- 'scheme' => 'http',
197
- 'headers' => ['host' => ['foo.com']],
198
- 'client' => [
199
- 'proxy' => ['http' => 'http://bar.com', 'https' => 'https://t'],
200
- ],
201
- ]);
202
- $this->assertEquals('http://bar.com', $_SERVER['_curl'][CURLOPT_PROXY]);
203
- }
204
-
205
- /**
206
- * @expectedException \InvalidArgumentException
207
- * @expectedExceptionMessage SSL private key not found: /does/not/exist
208
- */
209
- public function testValidatesSslKey()
210
- {
211
- $f = new CurlFactory();
212
- $f([
213
- 'http_method' => 'GET',
214
- 'headers' => ['host' => ['foo.com']],
215
- 'client' => ['ssl_key' => '/does/not/exist'],
216
- ]);
217
- }
218
-
219
- public function testAddsSslKey()
220
- {
221
- $f = new CurlFactory();
222
- $f([
223
- 'http_method' => 'GET',
224
- 'headers' => ['host' => ['foo.com']],
225
- 'client' => ['ssl_key' => __FILE__],
226
- ]);
227
- $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLKEY]);
228
- }
229
-
230
- public function testAddsSslKeyWithPassword()
231
- {
232
- $f = new CurlFactory();
233
- $f([
234
- 'http_method' => 'GET',
235
- 'headers' => ['host' => ['foo.com']],
236
- 'client' => ['ssl_key' => [__FILE__, 'test']],
237
- ]);
238
- $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLKEY]);
239
- $this->assertEquals('test', $_SERVER['_curl'][CURLOPT_SSLKEYPASSWD]);
240
- }
241
-
242
- /**
243
- * @expectedException \InvalidArgumentException
244
- * @expectedExceptionMessage SSL certificate not found: /does/not/exist
245
- */
246
- public function testValidatesCert()
247
- {
248
- $f = new CurlFactory();
249
- $f([
250
- 'http_method' => 'GET',
251
- 'headers' => ['host' => ['foo.com']],
252
- 'client' => ['cert' => '/does/not/exist'],
253
- ]);
254
- }
255
-
256
- public function testAddsCert()
257
- {
258
- $f = new CurlFactory();
259
- $f([
260
- 'http_method' => 'GET',
261
- 'headers' => ['host' => ['foo.com']],
262
- 'client' => ['cert' => __FILE__],
263
- ]);
264
- $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLCERT]);
265
- }
266
-
267
- public function testAddsCertWithPassword()
268
- {
269
- $f = new CurlFactory();
270
- $f([
271
- 'http_method' => 'GET',
272
- 'headers' => ['host' => ['foo.com']],
273
- 'client' => ['cert' => [__FILE__, 'test']],
274
- ]);
275
- $this->assertEquals(__FILE__, $_SERVER['_curl'][CURLOPT_SSLCERT]);
276
- $this->assertEquals('test', $_SERVER['_curl'][CURLOPT_SSLCERTPASSWD]);
277
- }
278
-
279
- /**
280
- * @expectedException \InvalidArgumentException
281
- * @expectedExceptionMessage progress client option must be callable
282
- */
283
- public function testValidatesProgress()
284
- {
285
- $f = new CurlFactory();
286
- $f([
287
- 'http_method' => 'GET',
288
- 'headers' => ['host' => ['foo.com']],
289
- 'client' => ['progress' => 'foo'],
290
- ]);
291
- }
292
-
293
- public function testEmitsDebugInfoToStream()
294
- {
295
- $res = fopen('php://memory', 'r+');
296
- Server::flush();
297
- Server::enqueue([['status' => 200]]);
298
- $a = new CurlMultiHandler();
299
- $response = $a([
300
- 'http_method' => 'HEAD',
301
- 'headers' => ['host' => [Server::$host]],
302
- 'client' => ['debug' => $res],
303
- ]);
304
- $response->wait();
305
- rewind($res);
306
- $output = str_replace("\r", '', stream_get_contents($res));
307
- $this->assertContains(
308
- "> HEAD / HTTP/1.1\nhost: 127.0.0.1:8125\n\n",
309
- $output
310
- );
311
- $this->assertContains("< HTTP/1.1 200", $output);
312
- fclose($res);
313
- }
314
-
315
- public function testEmitsProgressToFunction()
316
- {
317
- Server::flush();
318
- Server::enqueue([['status' => 200]]);
319
- $a = new CurlMultiHandler();
320
- $called = [];
321
- $response = $a([
322
- 'http_method' => 'HEAD',
323
- 'headers' => ['host' => [Server::$host]],
324
- 'client' => [
325
- 'progress' => function () use (&$called) {
326
- $called[] = func_get_args();
327
- },
328
- ],
329
- ]);
330
- $response->wait();
331
- $this->assertNotEmpty($called);
332
- foreach ($called as $call) {
333
- $this->assertCount(4, $call);
334
- }
335
- }
336
-
337
- private function addDecodeResponse($withEncoding = true)
338
- {
339
- $content = gzencode('test');
340
- $response = [
341
- 'status' => 200,
342
- 'reason' => 'OK',
343
- 'headers' => ['Content-Length' => [strlen($content)]],
344
- 'body' => $content,
345
- ];
346
-
347
- if ($withEncoding) {
348
- $response['headers']['Content-Encoding'] = ['gzip'];
349
- }
350
-
351
- Server::flush();
352
- Server::enqueue([$response]);
353
-
354
- return $content;
355
- }
356
-
357
- public function testDecodesGzippedResponses()
358
- {
359
- $this->addDecodeResponse();
360
- $handler = new CurlMultiHandler();
361
- $response = $handler([
362
- 'http_method' => 'GET',
363
- 'headers' => ['host' => [Server::$host]],
364
- 'client' => ['decode_content' => true],
365
- ]);
366
- $response->wait();
367
- $this->assertEquals('test', Core::body($response));
368
- $this->assertEquals('', $_SERVER['_curl'][CURLOPT_ENCODING]);
369
- $sent = Server::received()[0];
370
- $this->assertNull(Core::header($sent, 'Accept-Encoding'));
371
- }
372
-
373
- public function testDecodesGzippedResponsesWithHeader()
374
- {
375
- $this->addDecodeResponse();
376
- $handler = new CurlMultiHandler();
377
- $response = $handler([
378
- 'http_method' => 'GET',
379
- 'headers' => [
380
- 'host' => [Server::$host],
381
- 'Accept-Encoding' => ['gzip'],
382
- ],
383
- 'client' => ['decode_content' => true],
384
- ]);
385
- $response->wait();
386
- $this->assertEquals('gzip', $_SERVER['_curl'][CURLOPT_ENCODING]);
387
- $sent = Server::received()[0];
388
- $this->assertEquals('gzip', Core::header($sent, 'Accept-Encoding'));
389
- $this->assertEquals('test', Core::body($response));
390
- }
391
-
392
- public function testDoesNotForceDecode()
393
- {
394
- $content = $this->addDecodeResponse();
395
- $handler = new CurlMultiHandler();
396
- $response = $handler([
397
- 'http_method' => 'GET',
398
- 'headers' => ['host' => [Server::$host]],
399
- 'client' => ['decode_content' => false],
400
- ]);
401
- $response->wait();
402
- $sent = Server::received()[0];
403
- $this->assertNull(Core::header($sent, 'Accept-Encoding'));
404
- $this->assertEquals($content, Core::body($response));
405
- }
406
-
407
- public function testProtocolVersion()
408
- {
409
- Server::flush();
410
- Server::enqueue([['status' => 200]]);
411
- $a = new CurlMultiHandler();
412
- $a([
413
- 'http_method' => 'GET',
414
- 'headers' => ['host' => [Server::$host]],
415
- 'version' => 1.0,
416
- ]);
417
- $this->assertEquals(CURL_HTTP_VERSION_1_0, $_SERVER['_curl'][CURLOPT_HTTP_VERSION]);
418
- }
419
-
420
- /**
421
- * @expectedException \InvalidArgumentException
422
- */
423
- public function testValidatesSaveTo()
424
- {
425
- $handler = new CurlMultiHandler();
426
- $handler([
427
- 'http_method' => 'GET',
428
- 'headers' => ['host' => [Server::$host]],
429
- 'client' => ['save_to' => true],
430
- ]);
431
- }
432
-
433
- public function testSavesToStream()
434
- {
435
- $stream = fopen('php://memory', 'r+');
436
- $this->addDecodeResponse();
437
- $handler = new CurlMultiHandler();
438
- $response = $handler([
439
- 'http_method' => 'GET',
440
- 'headers' => ['host' => [Server::$host]],
441
- 'client' => [
442
- 'decode_content' => true,
443
- 'save_to' => $stream,
444
- ],
445
- ]);
446
- $response->wait();
447
- rewind($stream);
448
- $this->assertEquals('test', stream_get_contents($stream));
449
- }
450
-
451
- public function testSavesToGuzzleStream()
452
- {
453
- $stream = Stream::factory();
454
- $this->addDecodeResponse();
455
- $handler = new CurlMultiHandler();
456
- $response = $handler([
457
- 'http_method' => 'GET',
458
- 'headers' => ['host' => [Server::$host]],
459
- 'client' => [
460
- 'decode_content' => true,
461
- 'save_to' => $stream,
462
- ],
463
- ]);
464
- $response->wait();
465
- $this->assertEquals('test', (string) $stream);
466
- }
467
-
468
- public function testSavesToFileOnDisk()
469
- {
470
- $tmpfile = tempnam(sys_get_temp_dir(), 'testfile');
471
- $this->addDecodeResponse();
472
- $handler = new CurlMultiHandler();
473
- $response = $handler([
474
- 'http_method' => 'GET',
475
- 'headers' => ['host' => [Server::$host]],
476
- 'client' => [
477
- 'decode_content' => true,
478
- 'save_to' => $tmpfile,
479
- ],
480
- ]);
481
- $response->wait();
482
- $this->assertEquals('test', file_get_contents($tmpfile));
483
- unlink($tmpfile);
484
- }
485
-
486
- /**
487
- * @expectedException \InvalidArgumentException
488
- */
489
- public function testValidatesBody()
490
- {
491
- $handler = new CurlMultiHandler();
492
- $handler([
493
- 'http_method' => 'GET',
494
- 'headers' => ['host' => [Server::$host]],
495
- 'body' => false,
496
- ]);
497
- }
498
-
499
- public function testAddsLargePayloadFromStreamWithNoSizeUsingChunked()
500
- {
501
- $stream = Stream::factory('foo');
502
- $stream = FnStream::decorate($stream, [
503
- 'getSize' => function () {
504
- return null;
505
- }
506
- ]);
507
- $this->addDecodeResponse();
508
- $handler = new CurlMultiHandler();
509
- $response = $handler([
510
- 'http_method' => 'GET',
511
- 'headers' => ['host' => [Server::$host]],
512
- 'body' => $stream,
513
- ]);
514
- $response->wait();
515
- $sent = Server::received()[0];
516
- $this->assertEquals('chunked', Core::header($sent, 'Transfer-Encoding'));
517
- $this->assertNull(Core::header($sent, 'Content-Length'));
518
- $this->assertEquals('foo', $sent['body']);
519
- }
520
-
521
- public function testAddsPayloadFromIterator()
522
- {
523
- $iter = new \ArrayIterator(['f', 'o', 'o']);
524
- $this->addDecodeResponse();
525
- $handler = new CurlMultiHandler();
526
- $response = $handler([
527
- 'http_method' => 'GET',
528
- 'headers' => ['host' => [Server::$host]],
529
- 'body' => $iter,
530
- ]);
531
- $response->wait();
532
- $sent = Server::received()[0];
533
- $this->assertEquals('chunked', Core::header($sent, 'Transfer-Encoding'));
534
- $this->assertNull(Core::header($sent, 'Content-Length'));
535
- $this->assertEquals('foo', $sent['body']);
536
- }
537
-
538
- public function testAddsPayloadFromResource()
539
- {
540
- $res = fopen('php://memory', 'r+');
541
- $data = str_repeat('.', 1000000);
542
- fwrite($res, $data);
543
- rewind($res);
544
- $this->addDecodeResponse();
545
- $handler = new CurlMultiHandler();
546
- $response = $handler([
547
- 'http_method' => 'GET',
548
- 'headers' => [
549
- 'host' => [Server::$host],
550
- 'content-length' => [1000000],
551
- ],
552
- 'body' => $res,
553
- ]);
554
- $response->wait();
555
- $sent = Server::received()[0];
556
- $this->assertNull(Core::header($sent, 'Transfer-Encoding'));
557
- $this->assertEquals(1000000, Core::header($sent, 'Content-Length'));
558
- $this->assertEquals($data, $sent['body']);
559
- }
560
-
561
- public function testAddsContentLengthFromStream()
562
- {
563
- $stream = Stream::factory('foo');
564
- $this->addDecodeResponse();
565
- $handler = new CurlMultiHandler();
566
- $response = $handler([
567
- 'http_method' => 'GET',
568
- 'headers' => ['host' => [Server::$host]],
569
- 'body' => $stream,
570
- ]);
571
- $response->wait();
572
- $sent = Server::received()[0];
573
- $this->assertEquals(3, Core::header($sent, 'Content-Length'));
574
- $this->assertNull(Core::header($sent, 'Transfer-Encoding'));
575
- $this->assertEquals('foo', $sent['body']);
576
- }
577
-
578
- public function testDoesNotAddMultipleContentLengthHeaders()
579
- {
580
- $this->addDecodeResponse();
581
- $handler = new CurlMultiHandler();
582
- $response = $handler([
583
- 'http_method' => 'GET',
584
- 'headers' => [
585
- 'host' => [Server::$host],
586
- 'content-length' => [3],
587
- ],
588
- 'body' => 'foo',
589
- ]);
590
- $response->wait();
591
- $sent = Server::received()[0];
592
- $this->assertEquals(3, Core::header($sent, 'Content-Length'));
593
- $this->assertNull(Core::header($sent, 'Transfer-Encoding'));
594
- $this->assertEquals('foo', $sent['body']);
595
- }
596
-
597
- public function testSendsPostWithNoBodyOrDefaultContentType()
598
- {
599
- Server::flush();
600
- Server::enqueue([['status' => 200]]);
601
- $handler = new CurlMultiHandler();
602
- $response = $handler([
603
- 'http_method' => 'POST',
604
- 'uri' => '/',
605
- 'headers' => ['host' => [Server::$host]],
606
- ]);
607
- $response->wait();
608
- $received = Server::received()[0];
609
- $this->assertEquals('POST', $received['http_method']);
610
- $this->assertNull(Core::header($received, 'content-type'));
611
- $this->assertSame('0', Core::firstHeader($received, 'content-length'));
612
- }
613
-
614
- public function testParseProtocolVersion()
615
- {
616
- $res = CurlFactory::createResponse(
617
- function () {},
618
- [],
619
- ['curl' => ['errno' => null]],
620
- ['HTTP/1.1 200 Ok'],
621
- null
622
- );
623
-
624
- $this->assertSame('1.1', $res['version']);
625
- }
626
-
627
- public function testFailsWhenNoResponseAndNoBody()
628
- {
629
- $res = CurlFactory::createResponse(function () {}, [], [], [], null);
630
- $this->assertInstanceOf('GuzzleHttp\Ring\Exception\RingException', $res['error']);
631
- $this->assertContains(
632
- 'No response was received for a request with no body',
633
- $res['error']->getMessage()
634
- );
635
- }
636
-
637
- public function testFailsWhenCannotRewindRetry()
638
- {
639
- $res = CurlFactory::createResponse(function () {}, [
640
- 'body' => new NoSeekStream(Stream::factory('foo'))
641
- ], [], [], null);
642
- $this->assertInstanceOf('GuzzleHttp\Ring\Exception\RingException', $res['error']);
643
- $this->assertContains(
644
- 'rewind the request body failed',
645
- $res['error']->getMessage()
646
- );
647
- }
648
-
649
- public function testRetriesWhenBodyCanBeRewound()
650
- {
651
- $callHandler = $called = false;
652
- $res = CurlFactory::createResponse(function () use (&$callHandler) {
653
- $callHandler = true;
654
- return ['status' => 200];
655
- }, [
656
- 'body' => FnStream::decorate(Stream::factory('test'), [
657
- 'seek' => function () use (&$called) {
658
- $called = true;
659
- return true;
660
- }
661
- ])
662
- ], [], [], null);
663
-
664
- $this->assertTrue($callHandler);
665
- $this->assertTrue($called);
666
- $this->assertEquals('200', $res['status']);
667
- }
668
-
669
- public function testFailsWhenRetryMoreThanThreeTimes()
670
- {
671
- $call = 0;
672
- $mock = new MockHandler(function (array $request) use (&$mock, &$call) {
673
- $call++;
674
- return CurlFactory::createResponse($mock, $request, [], [], null);
675
- });
676
- $response = $mock([
677
- 'http_method' => 'GET',
678
- 'body' => 'test',
679
- ]);
680
- $this->assertEquals(3, $call);
681
- $this->assertArrayHasKey('error', $response);
682
- $this->assertContains(
683
- 'The cURL request was retried 3 times',
684
- $response['error']->getMessage()
685
- );
686
- }
687
-
688
- public function testHandles100Continue()
689
- {
690
- Server::flush();
691
- Server::enqueue([
692
- [
693
- 'status' => '200',
694
- 'reason' => 'OK',
695
- 'headers' => [
696
- 'Test' => ['Hello'],
697
- 'Content-Length' => ['4'],
698
- ],
699
- 'body' => 'test',
700
- ],
701
- ]);
702
-
703
- $request = [
704
- 'http_method' => 'PUT',
705
- 'headers' => [
706
- 'Host' => [Server::$host],
707
- 'Expect' => ['100-Continue'],
708
- ],
709
- 'body' => 'test',
710
- ];
711
-
712
- $handler = new CurlMultiHandler();
713
- $response = $handler($request)->wait();
714
- $this->assertEquals(200, $response['status']);
715
- $this->assertEquals('OK', $response['reason']);
716
- $this->assertEquals(['Hello'], $response['headers']['Test']);
717
- $this->assertEquals(['4'], $response['headers']['Content-Length']);
718
- $this->assertEquals('test', Core::body($response));
719
- }
720
-
721
- public function testCreatesConnectException()
722
- {
723
- $m = new \ReflectionMethod('GuzzleHttp\Ring\Client\CurlFactory', 'createErrorResponse');
724
- $m->setAccessible(true);
725
- $response = $m->invoke(
726
- null,
727
- function () {},
728
- [],
729
- [
730
- 'err_message' => 'foo',
731
- 'curl' => [
732
- 'errno' => CURLE_COULDNT_CONNECT,
733
- ]
734
- ]
735
- );
736
- $this->assertInstanceOf('GuzzleHttp\Ring\Exception\ConnectException', $response['error']);
737
- }
738
-
739
- public function testParsesLastResponseOnly()
740
- {
741
- $response1 = [
742
- 'status' => 301,
743
- 'headers' => [
744
- 'Content-Length' => ['0'],
745
- 'Location' => ['/foo']
746
- ]
747
- ];
748
-
749
- $response2 = [
750
- 'status' => 200,
751
- 'headers' => [
752
- 'Content-Length' => ['0'],
753
- 'Foo' => ['bar']
754
- ]
755
- ];
756
-
757
- Server::flush();
758
- Server::enqueue([$response1, $response2]);
759
-
760
- $a = new CurlMultiHandler();
761
- $response = $a([
762
- 'http_method' => 'GET',
763
- 'headers' => ['Host' => [Server::$host]],
764
- 'client' => [
765
- 'curl' => [
766
- CURLOPT_FOLLOWLOCATION => true
767
- ]
768
- ]
769
- ])->wait();
770
-
771
- $this->assertEquals(1, $response['transfer_stats']['redirect_count']);
772
- $this->assertEquals('http://127.0.0.1:8125/foo', $response['effective_url']);
773
- $this->assertEquals(['bar'], $response['headers']['Foo']);
774
- $this->assertEquals(200, $response['status']);
775
- $this->assertFalse(Core::hasHeader($response, 'Location'));
776
- }
777
-
778
- public function testMaintainsMultiHeaderOrder()
779
- {
780
- Server::flush();
781
- Server::enqueue([
782
- [
783
- 'status' => 200,
784
- 'headers' => [
785
- 'Content-Length' => ['0'],
786
- 'Foo' => ['a', 'b'],
787
- 'foo' => ['c', 'd'],
788
- ]
789
- ]
790
- ]);
791
-
792
- $a = new CurlMultiHandler();
793
- $response = $a([
794
- 'http_method' => 'GET',
795
- 'headers' => ['Host' => [Server::$host]]
796
- ])->wait();
797
-
798
- $this->assertEquals(
799
- ['a', 'b', 'c', 'd'],
800
- Core::headerLines($response, 'Foo')
801
- );
802
- }
803
-
804
- /**
805
- * @expectedException \RuntimeException
806
- * @expectedExceptionMessage Directory /path/to/does/not does not exist for save_to value of /path/to/does/not/exist.txt
807
- */
808
- public function testThrowsWhenDirNotFound()
809
- {
810
- $request = [
811
- 'http_method' => 'GET',
812
- 'headers' => ['host' => [Server::$url]],
813
- 'client' => ['save_to' => '/path/to/does/not/exist.txt'],
814
- ];
815
-
816
- $f = new CurlFactory();
817
- $f($request);
818
- }
819
- }
820
-
821
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/tests/Client/CurlHandlerTest.php DELETED
@@ -1,96 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Ring\Client;
3
-
4
- use GuzzleHttp\Ring\Client\CurlHandler;
5
-
6
- class CurlHandlerTest extends \PHPUnit_Framework_TestCase
7
- {
8
- protected function setUp()
9
- {
10
- if (!function_exists('curl_reset')) {
11
- $this->markTestSkipped('curl_reset() is not available');
12
- }
13
- }
14
-
15
- protected function getHandler($factory = null, $options = [])
16
- {
17
- return new CurlHandler($options);
18
- }
19
-
20
- public function testCanSetMaxHandles()
21
- {
22
- $a = new CurlHandler(['max_handles' => 10]);
23
- $this->assertEquals(10, $this->readAttribute($a, 'maxHandles'));
24
- }
25
-
26
- public function testCreatesCurlErrors()
27
- {
28
- $handler = new CurlHandler();
29
- $response = $handler([
30
- 'http_method' => 'GET',
31
- 'uri' => '/',
32
- 'headers' => ['host' => ['localhost:123']],
33
- 'client' => ['timeout' => 0.001, 'connect_timeout' => 0.001],
34
- ]);
35
- $this->assertNull($response['status']);
36
- $this->assertNull($response['reason']);
37
- $this->assertEquals([], $response['headers']);
38
- $this->assertInstanceOf(
39
- 'GuzzleHttp\Ring\Exception\RingException',
40
- $response['error']
41
- );
42
-
43
- $this->assertEquals(
44
- 1,
45
- preg_match('/^cURL error \d+: .*$/', $response['error']->getMessage())
46
- );
47
- }
48
-
49
- public function testReleasesAdditionalEasyHandles()
50
- {
51
- Server::flush();
52
- $response = [
53
- 'status' => 200,
54
- 'headers' => ['Content-Length' => [4]],
55
- 'body' => 'test',
56
- ];
57
-
58
- Server::enqueue([$response, $response, $response, $response]);
59
- $a = new CurlHandler(['max_handles' => 2]);
60
-
61
- $fn = function () use (&$calls, $a, &$fn) {
62
- if (++$calls < 4) {
63
- $a([
64
- 'http_method' => 'GET',
65
- 'headers' => ['host' => [Server::$host]],
66
- 'client' => ['progress' => $fn],
67
- ]);
68
- }
69
- };
70
-
71
- $request = [
72
- 'http_method' => 'GET',
73
- 'headers' => ['host' => [Server::$host]],
74
- 'client' => [
75
- 'progress' => $fn,
76
- ],
77
- ];
78
-
79
- $a($request);
80
- $this->assertCount(2, $this->readAttribute($a, 'handles'));
81
- }
82
-
83
- public function testReusesHandles()
84
- {
85
- Server::flush();
86
- $response = ['status' => 200];
87
- Server::enqueue([$response, $response]);
88
- $a = new CurlHandler();
89
- $request = [
90
- 'http_method' => 'GET',
91
- 'headers' => ['host' => [Server::$host]],
92
- ];
93
- $a($request);
94
- $a($request);
95
- }
96
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/tests/Client/CurlMultiHandlerTest.php DELETED
@@ -1,165 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Ring\Client;
3
-
4
- use GuzzleHttp\Ring\Client\CurlMultiHandler;
5
-
6
- class CurlMultiHandlerTest extends \PHPUnit_Framework_TestCase
7
- {
8
- public function testSendsRequest()
9
- {
10
- Server::enqueue([['status' => 200]]);
11
- $a = new CurlMultiHandler();
12
- $response = $a([
13
- 'http_method' => 'GET',
14
- 'headers' => ['host' => [Server::$host]],
15
- ]);
16
- $this->assertInstanceOf('GuzzleHttp\Ring\Future\FutureArray', $response);
17
- $this->assertEquals(200, $response['status']);
18
- $this->assertArrayHasKey('transfer_stats', $response);
19
- $realUrl = trim($response['transfer_stats']['url'], '/');
20
- $this->assertEquals(trim(Server::$url, '/'), $realUrl);
21
- $this->assertArrayHasKey('effective_url', $response);
22
- $this->assertEquals(
23
- trim(Server::$url, '/'),
24
- trim($response['effective_url'], '/')
25
- );
26
- }
27
-
28
- public function testCreatesErrorResponses()
29
- {
30
- $url = 'http://localhost:123/';
31
- $a = new CurlMultiHandler();
32
- $response = $a([
33
- 'http_method' => 'GET',
34
- 'headers' => ['host' => ['localhost:123']],
35
- ]);
36
- $this->assertInstanceOf('GuzzleHttp\Ring\Future\FutureArray', $response);
37
- $this->assertNull($response['status']);
38
- $this->assertNull($response['reason']);
39
- $this->assertEquals([], $response['headers']);
40
- $this->assertArrayHasKey('error', $response);
41
- $this->assertContains('cURL error ', $response['error']->getMessage());
42
- $this->assertArrayHasKey('transfer_stats', $response);
43
- $this->assertEquals(
44
- trim($url, '/'),
45
- trim($response['transfer_stats']['url'], '/')
46
- );
47
- $this->assertArrayHasKey('effective_url', $response);
48
- $this->assertEquals(
49
- trim($url, '/'),
50
- trim($response['effective_url'], '/')
51
- );
52
- }
53
-
54
- public function testSendsFuturesWhenDestructed()
55
- {
56
- Server::enqueue([['status' => 200]]);
57
- $a = new CurlMultiHandler();
58
- $response = $a([
59
- 'http_method' => 'GET',
60
- 'headers' => ['host' => [Server::$host]],
61
- ]);
62
- $this->assertInstanceOf('GuzzleHttp\Ring\Future\FutureArray', $response);
63
- $a->__destruct();
64
- $this->assertEquals(200, $response['status']);
65
- }
66
-
67
- public function testCanSetMaxHandles()
68
- {
69
- $a = new CurlMultiHandler(['max_handles' => 2]);
70
- $this->assertEquals(2, $this->readAttribute($a, 'maxHandles'));
71
- }
72
-
73
- public function testCanSetSelectTimeout()
74
- {
75
- $a = new CurlMultiHandler(['select_timeout' => 2]);
76
- $this->assertEquals(2, $this->readAttribute($a, 'selectTimeout'));
77
- }
78
-
79
- public function testSendsFuturesWhenMaxHandlesIsReached()
80
- {
81
- $request = [
82
- 'http_method' => 'PUT',
83
- 'headers' => ['host' => [Server::$host]],
84
- 'future' => 'lazy', // passing this to control the test
85
- ];
86
- $response = ['status' => 200];
87
- Server::flush();
88
- Server::enqueue([$response, $response, $response]);
89
- $a = new CurlMultiHandler(['max_handles' => 3]);
90
- for ($i = 0; $i < 5; $i++) {
91
- $responses[] = $a($request);
92
- }
93
- $this->assertCount(3, Server::received());
94
- $responses[3]->cancel();
95
- $responses[4]->cancel();
96
- }
97
-
98
- public function testCanCancel()
99
- {
100
- Server::flush();
101
- $response = ['status' => 200];
102
- Server::enqueue(array_fill_keys(range(0, 10), $response));
103
- $a = new CurlMultiHandler();
104
- $responses = [];
105
-
106
- for ($i = 0; $i < 10; $i++) {
107
- $response = $a([
108
- 'http_method' => 'GET',
109
- 'headers' => ['host' => [Server::$host]],
110
- 'future' => 'lazy',
111
- ]);
112
- $response->cancel();
113
- $responses[] = $response;
114
- }
115
-
116
- $this->assertCount(0, Server::received());
117
-
118
- foreach ($responses as $response) {
119
- $this->assertTrue($this->readAttribute($response, 'isRealized'));
120
- }
121
- }
122
-
123
- public function testCannotCancelFinished()
124
- {
125
- Server::flush();
126
- Server::enqueue([['status' => 200]]);
127
- $a = new CurlMultiHandler();
128
- $response = $a([
129
- 'http_method' => 'GET',
130
- 'headers' => ['host' => [Server::$host]],
131
- ]);
132
- $response->wait();
133
- $response->cancel();
134
- }
135
-
136
- public function testDelaysInParallel()
137
- {
138
- Server::flush();
139
- Server::enqueue([['status' => 200]]);
140
- $a = new CurlMultiHandler();
141
- $expected = microtime(true) + (100 / 1000);
142
- $response = $a([
143
- 'http_method' => 'GET',
144
- 'headers' => ['host' => [Server::$host]],
145
- 'client' => ['delay' => 100],
146
- ]);
147
- $response->wait();
148
- $this->assertGreaterThanOrEqual($expected, microtime(true));
149
- }
150
-
151
- public function testSendsNonLazyFutures()
152
- {
153
- $request = [
154
- 'http_method' => 'GET',
155
- 'headers' => ['host' => [Server::$host]],
156
- 'future' => true,
157
- ];
158
- Server::flush();
159
- Server::enqueue([['status' => 202]]);
160
- $a = new CurlMultiHandler();
161
- $response = $a($request);
162
- $this->assertInstanceOf('GuzzleHttp\Ring\Future\FutureArray', $response);
163
- $this->assertEquals(202, $response['status']);
164
- }
165
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/tests/Client/MiddlewareTest.php DELETED
@@ -1,65 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Ring\Client;
3
-
4
- use GuzzleHttp\Ring\Client\Middleware;
5
- use GuzzleHttp\Ring\Future\CompletedFutureArray;
6
-
7
- class MiddlewareTest extends \PHPUnit_Framework_TestCase
8
- {
9
- public function testFutureCallsDefaultHandler()
10
- {
11
- $future = new CompletedFutureArray(['status' => 200]);
12
- $calledA = false;
13
- $a = function (array $req) use (&$calledA, $future) {
14
- $calledA = true;
15
- return $future;
16
- };
17
- $calledB = false;
18
- $b = function (array $req) use (&$calledB) { $calledB = true; };
19
- $s = Middleware::wrapFuture($a, $b);
20
- $s([]);
21
- $this->assertTrue($calledA);
22
- $this->assertFalse($calledB);
23
- }
24
-
25
- public function testFutureCallsStreamingHandler()
26
- {
27
- $future = new CompletedFutureArray(['status' => 200]);
28
- $calledA = false;
29
- $a = function (array $req) use (&$calledA) { $calledA = true; };
30
- $calledB = false;
31
- $b = function (array $req) use (&$calledB, $future) {
32
- $calledB = true;
33
- return $future;
34
- };
35
- $s = Middleware::wrapFuture($a, $b);
36
- $result = $s(['client' => ['future' => true]]);
37
- $this->assertFalse($calledA);
38
- $this->assertTrue($calledB);
39
- $this->assertSame($future, $result);
40
- }
41
-
42
- public function testStreamingCallsDefaultHandler()
43
- {
44
- $calledA = false;
45
- $a = function (array $req) use (&$calledA) { $calledA = true; };
46
- $calledB = false;
47
- $b = function (array $req) use (&$calledB) { $calledB = true; };
48
- $s = Middleware::wrapStreaming($a, $b);
49
- $s([]);
50
- $this->assertTrue($calledA);
51
- $this->assertFalse($calledB);
52
- }
53
-
54
- public function testStreamingCallsStreamingHandler()
55
- {
56
- $calledA = false;
57
- $a = function (array $req) use (&$calledA) { $calledA = true; };
58
- $calledB = false;
59
- $b = function (array $req) use (&$calledB) { $calledB = true; };
60
- $s = Middleware::wrapStreaming($a, $b);
61
- $s(['client' => ['stream' => true]]);
62
- $this->assertFalse($calledA);
63
- $this->assertTrue($calledB);
64
- }
65
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/tests/Client/MockHandlerTest.php DELETED
@@ -1,86 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Ring\Client;
3
-
4
- use GuzzleHttp\Ring\Client\MockHandler;
5
- use GuzzleHttp\Ring\Future\FutureArray;
6
- use React\Promise\Deferred;
7
-
8
- class MockHandlerTest extends \PHPUnit_Framework_TestCase
9
- {
10
- public function testReturnsArray()
11
- {
12
- $mock = new MockHandler(['status' => 200]);
13
- $response = $mock([]);
14
- $this->assertEquals(200, $response['status']);
15
- $this->assertEquals([], $response['headers']);
16
- $this->assertNull($response['body']);
17
- $this->assertNull($response['reason']);
18
- $this->assertNull($response['effective_url']);
19
- }
20
-
21
- public function testReturnsFutures()
22
- {
23
- $deferred = new Deferred();
24
- $future = new FutureArray(
25
- $deferred->promise(),
26
- function () use ($deferred) {
27
- $deferred->resolve(['status' => 200]);
28
- }
29
- );
30
- $mock = new MockHandler($future);
31
- $response = $mock([]);
32
- $this->assertInstanceOf('GuzzleHttp\Ring\Future\FutureArray', $response);
33
- $this->assertEquals(200, $response['status']);
34
- }
35
-
36
- public function testReturnsFuturesWithThenCall()
37
- {
38
- $deferred = new Deferred();
39
- $future = new FutureArray(
40
- $deferred->promise(),
41
- function () use ($deferred) {
42
- $deferred->resolve(['status' => 200]);
43
- }
44
- );
45
- $mock = new MockHandler($future);
46
- $response = $mock([]);
47
- $this->assertInstanceOf('GuzzleHttp\Ring\Future\FutureArray', $response);
48
- $this->assertEquals(200, $response['status']);
49
- $req = null;
50
- $promise = $response->then(function ($value) use (&$req) {
51
- $req = $value;
52
- $this->assertEquals(200, $req['status']);
53
- });
54
- $this->assertInstanceOf('React\Promise\PromiseInterface', $promise);
55
- $this->assertEquals(200, $req['status']);
56
- }
57
-
58
- public function testReturnsFuturesAndProxiesCancel()
59
- {
60
- $c = null;
61
- $deferred = new Deferred();
62
- $future = new FutureArray(
63
- $deferred->promise(),
64
- function () {},
65
- function () use (&$c) {
66
- $c = true;
67
- return true;
68
- }
69
- );
70
- $mock = new MockHandler($future);
71
- $response = $mock([]);
72
- $this->assertInstanceOf('GuzzleHttp\Ring\Future\FutureArray', $response);
73
- $response->cancel();
74
- $this->assertTrue($c);
75
- }
76
-
77
- /**
78
- * @expectedException \InvalidArgumentException
79
- * @expectedExceptionMessage Response must be an array or FutureArrayInterface. Found
80
- */
81
- public function testEnsuresMockIsValid()
82
- {
83
- $mock = new MockHandler('foo');
84
- $mock([]);
85
- }
86
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/tests/Client/Server.php DELETED
@@ -1,183 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Ring\Client;
3
-
4
- use GuzzleHttp\Ring\Client\StreamHandler;
5
- use GuzzleHttp\Ring\Core;
6
-
7
- /**
8
- * Class uses to control the test webserver.
9
- *
10
- * Queued responses will be served to requests using a FIFO order. All requests
11
- * received by the server are stored on the node.js server and can be retrieved
12
- * by calling {@see Server::received()}.
13
- *
14
- * Mock responses that don't require data to be transmitted over HTTP a great
15
- * for testing. Mock response, however, cannot test the actual sending of an
16
- * HTTP request using cURL. This test server allows the simulation of any
17
- * number of HTTP request response transactions to test the actual sending of
18
- * requests over the wire without having to leave an internal network.
19
- */
20
- class Server
21
- {
22
- public static $started;
23
- public static $url = 'http://127.0.0.1:8125/';
24
- public static $host = '127.0.0.1:8125';
25
- public static $port = 8125;
26
-
27
- /**
28
- * Flush the received requests from the server
29
- * @throws \RuntimeException
30
- */
31
- public static function flush()
32
- {
33
- self::send('DELETE', '/guzzle-server/requests');
34
- }
35
-
36
- /**
37
- * Queue an array of responses or a single response on the server.
38
- *
39
- * Any currently queued responses will be overwritten. Subsequent requests
40
- * on the server will return queued responses in FIFO order.
41
- *
42
- * @param array $responses An array of responses. The shape of a response
43
- * is the shape described in the RingPHP spec.
44
- * @throws \Exception
45
- */
46
- public static function enqueue(array $responses)
47
- {
48
- $data = [];
49
-
50
- foreach ($responses as $response) {
51
- if (!is_array($response)) {
52
- throw new \Exception('Each response must be an array');
53
- }
54
-
55
- if (isset($response['body'])) {
56
- $response['body'] = base64_encode($response['body']);
57
- }
58
-
59
- $response += ['headers' => [], 'reason' => '', 'body' => ''];
60
- $data[] = $response;
61
- }
62
-
63
- self::send('PUT', '/guzzle-server/responses', json_encode($data));
64
- }
65
-
66
- /**
67
- * Get all of the received requests as a RingPHP request structure.
68
- *
69
- * @return array
70
- * @throws \RuntimeException
71
- */
72
- public static function received()
73
- {
74
- if (!self::$started) {
75
- return [];
76
- }
77
-
78
- $response = self::send('GET', '/guzzle-server/requests');
79
- $body = Core::body($response);
80
- $result = json_decode($body, true);
81
- if ($result === false) {
82
- throw new \RuntimeException('Error decoding response: '
83
- . json_last_error());
84
- }
85
-
86
- foreach ($result as &$res) {
87
- if (isset($res['uri'])) {
88
- $res['resource'] = $res['uri'];
89
- }
90
- if (isset($res['query_string'])) {
91
- $res['resource'] .= '?' . $res['query_string'];
92
- }
93
- if (!isset($res['resource'])) {
94
- $res['resource'] = '';
95
- }
96
- // Ensure that headers are all arrays
97
- if (isset($res['headers'])) {
98
- foreach ($res['headers'] as &$h) {
99
- $h = (array) $h;
100
- }
101
- unset($h);
102
- }
103
- }
104
-
105
- unset($res);
106
- return $result;
107
- }
108
-
109
- /**
110
- * Stop running the node.js server
111
- */
112
- public static function stop()
113
- {
114
- if (self::$started) {
115
- self::send('DELETE', '/guzzle-server');
116
- }
117
-
118
- self::$started = false;
119
- }
120
-
121
- public static function wait($maxTries = 20)
122
- {
123
- $tries = 0;
124
- while (!self::isListening() && ++$tries < $maxTries) {
125
- usleep(100000);
126
- }
127
-
128
- if (!self::isListening()) {
129
- throw new \RuntimeException('Unable to contact node.js server');
130
- }
131
- }
132
-
133
- public static function start()
134
- {
135
- if (self::$started) {
136
- return;
137
- }
138
-
139
- try {
140
- self::wait();
141
- } catch (\Exception $e) {
142
- exec('node ' . __DIR__ . \DIRECTORY_SEPARATOR . 'server.js '
143
- . self::$port . ' >> /tmp/server.log 2>&1 &');
144
- self::wait();
145
- }
146
-
147
- self::$started = true;
148
- }
149
-
150
- private static function isListening()
151
- {
152
- $response = self::send('GET', '/guzzle-server/perf', null, [
153
- 'connect_timeout' => 1,
154
- 'timeout' => 1
155
- ]);
156
-
157
- return !isset($response['error']);
158
- }
159
-
160
- private static function send(
161
- $method,
162
- $path,
163
- $body = null,
164
- array $client = []
165
- ) {
166
- $handler = new StreamHandler();
167
-
168
- $request = [
169
- 'http_method' => $method,
170
- 'uri' => $path,
171
- 'request_port' => 8125,
172
- 'headers' => ['host' => ['127.0.0.1:8125']],
173
- 'body' => $body,
174
- 'client' => $client,
175
- ];
176
-
177
- if ($body) {
178
- $request['headers']['content-length'] = [strlen($body)];
179
- }
180
-
181
- return $handler($request);
182
- }
183
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/tests/Client/StreamHandlerTest.php DELETED
@@ -1,480 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Ring\Client;
3
-
4
- use GuzzleHttp\Ring\Client\ClientUtils;
5
- use GuzzleHttp\Ring\Core;
6
- use GuzzleHttp\Ring\Client\StreamHandler;
7
-
8
- class StreamHandlerTest extends \PHPUnit_Framework_TestCase
9
- {
10
- public function testReturnsResponseForSuccessfulRequest()
11
- {
12
- $this->queueRes();
13
- $handler = new StreamHandler();
14
- $response = $handler([
15
- 'http_method' => 'GET',
16
- 'uri' => '/',
17
- 'headers' => [
18
- 'host' => [Server::$host],
19
- 'Foo' => ['Bar'],
20
- ],
21
- ]);
22
-
23
- $this->assertEquals('1.1', $response['version']);
24
- $this->assertEquals(200, $response['status']);
25
- $this->assertEquals('OK', $response['reason']);
26
- $this->assertEquals(['Bar'], $response['headers']['Foo']);
27
- $this->assertEquals(['8'], $response['headers']['Content-Length']);
28
- $this->assertEquals('hi there', Core::body($response));
29
-
30
- $sent = Server::received()[0];
31
- $this->assertEquals('GET', $sent['http_method']);
32
- $this->assertEquals('/', $sent['resource']);
33
- $this->assertEquals(['127.0.0.1:8125'], $sent['headers']['host']);
34
- $this->assertEquals('Bar', Core::header($sent, 'foo'));
35
- }
36
-
37
- public function testAddsErrorToResponse()
38
- {
39
- $handler = new StreamHandler();
40
- $result = $handler([
41
- 'http_method' => 'GET',
42
- 'headers' => ['host' => ['localhost:123']],
43
- 'client' => ['timeout' => 0.01],
44
- ]);
45
- $this->assertInstanceOf(
46
- 'GuzzleHttp\Ring\Future\CompletedFutureArray',
47
- $result
48
- );
49
- $this->assertNull($result['status']);
50
- $this->assertNull($result['body']);
51
- $this->assertEquals([], $result['headers']);
52
- $this->assertInstanceOf(
53
- 'GuzzleHttp\Ring\Exception\RingException',
54
- $result['error']
55
- );
56
- }
57
-
58
- public function testEnsuresTheHttpProtocol()
59
- {
60
- $handler = new StreamHandler();
61
- $result = $handler([
62
- 'http_method' => 'GET',
63
- 'url' => 'ftp://localhost:123',
64
- ]);
65
- $this->assertArrayHasKey('error', $result);
66
- $this->assertContains(
67
- 'URL is invalid: ftp://localhost:123',
68
- $result['error']->getMessage()
69
- );
70
- }
71
-
72
- public function testStreamAttributeKeepsStreamOpen()
73
- {
74
- $this->queueRes();
75
- $handler = new StreamHandler();
76
- $response = $handler([
77
- 'http_method' => 'PUT',
78
- 'uri' => '/foo',
79
- 'query_string' => 'baz=bar',
80
- 'headers' => [
81
- 'host' => [Server::$host],
82
- 'Foo' => ['Bar'],
83
- ],
84
- 'body' => 'test',
85
- 'client' => ['stream' => true],
86
- ]);
87
-
88
- $this->assertEquals(200, $response['status']);
89
- $this->assertEquals('OK', $response['reason']);
90
- $this->assertEquals('8', Core::header($response, 'Content-Length'));
91
- $body = $response['body'];
92
- $this->assertTrue(is_resource($body));
93
- $this->assertEquals('http', stream_get_meta_data($body)['wrapper_type']);
94
- $this->assertEquals('hi there', stream_get_contents($body));
95
- fclose($body);
96
- $sent = Server::received()[0];
97
- $this->assertEquals('PUT', $sent['http_method']);
98
- $this->assertEquals('/foo', $sent['uri']);
99
- $this->assertEquals('baz=bar', $sent['query_string']);
100
- $this->assertEquals('/foo?baz=bar', $sent['resource']);
101
- $this->assertEquals('127.0.0.1:8125', Core::header($sent, 'host'));
102
- $this->assertEquals('Bar', Core::header($sent, 'foo'));
103
- }
104
-
105
- public function testDrainsResponseIntoTempStream()
106
- {
107
- $this->queueRes();
108
- $handler = new StreamHandler();
109
- $response = $handler([
110
- 'http_method' => 'GET',
111
- 'uri' => '/',
112
- 'headers' => ['host' => [Server::$host]],
113
- ]);
114
- $body = $response['body'];
115
- $this->assertEquals('php://temp', stream_get_meta_data($body)['uri']);
116
- $this->assertEquals('hi', fread($body, 2));
117
- fclose($body);
118
- }
119
-
120
- public function testDrainsResponseIntoSaveToBody()
121
- {
122
- $r = fopen('php://temp', 'r+');
123
- $this->queueRes();
124
- $handler = new StreamHandler();
125
- $response = $handler([
126
- 'http_method' => 'GET',
127
- 'uri' => '/',
128
- 'headers' => ['host' => [Server::$host]],
129
- 'client' => ['save_to' => $r],
130
- ]);
131
- $body = $response['body'];
132
- $this->assertEquals('php://temp', stream_get_meta_data($body)['uri']);
133
- $this->assertEquals('hi', fread($body, 2));
134
- $this->assertEquals(' there', stream_get_contents($r));
135
- fclose($r);
136
- }
137
-
138
- public function testDrainsResponseIntoSaveToBodyAtPath()
139
- {
140
- $tmpfname = tempnam('/tmp', 'save_to_path');
141
- $this->queueRes();
142
- $handler = new StreamHandler();
143
- $response = $handler([
144
- 'http_method' => 'GET',
145
- 'uri' => '/',
146
- 'headers' => ['host' => [Server::$host]],
147
- 'client' => ['save_to' => $tmpfname],
148
- ]);
149
- $body = $response['body'];
150
- $this->assertInstanceOf('GuzzleHttp\Stream\StreamInterface', $body);
151
- $this->assertEquals($tmpfname, $body->getMetadata('uri'));
152
- $this->assertEquals('hi', $body->read(2));
153
- $body->close();
154
- unlink($tmpfname);
155
- }
156
-
157
- public function testAutomaticallyDecompressGzip()
158
- {
159
- Server::flush();
160
- $content = gzencode('test');
161
- Server::enqueue([
162
- [
163
- 'status' => 200,
164
- 'reason' => 'OK',
165
- 'headers' => [
166
- 'Content-Encoding' => ['gzip'],
167
- 'Content-Length' => [strlen($content)],
168
- ],
169
- 'body' => $content,
170
- ],
171
- ]);
172
-
173
- $handler = new StreamHandler();
174
- $response = $handler([
175
- 'http_method' => 'GET',
176
- 'headers' => ['host' => [Server::$host]],
177
- 'uri' => '/',
178
- 'client' => ['decode_content' => true],
179
- ]);
180
- $this->assertEquals('test', Core::body($response));
181
- }
182
-
183
- public function testDoesNotForceGzipDecode()
184
- {
185
- Server::flush();
186
- $content = gzencode('test');
187
- Server::enqueue([
188
- [
189
- 'status' => 200,
190
- 'reason' => 'OK',
191
- 'headers' => [
192
- 'Content-Encoding' => ['gzip'],
193
- 'Content-Length' => [strlen($content)],
194
- ],
195
- 'body' => $content,
196
- ],
197
- ]);
198
-
199
- $handler = new StreamHandler();
200
- $response = $handler([
201
- 'http_method' => 'GET',
202
- 'headers' => ['host' => [Server::$host]],
203
- 'uri' => '/',
204
- 'client' => ['stream' => true, 'decode_content' => false],
205
- ]);
206
- $this->assertSame($content, Core::body($response));
207
- }
208
-
209
- public function testProtocolVersion()
210
- {
211
- $this->queueRes();
212
- $handler = new StreamHandler();
213
- $handler([
214
- 'http_method' => 'GET',
215
- 'uri' => '/',
216
- 'headers' => ['host' => [Server::$host]],
217
- 'version' => 1.0,
218
- ]);
219
-
220
- $this->assertEquals(1.0, Server::received()[0]['version']);
221
- }
222
-
223
- protected function getSendResult(array $opts)
224
- {
225
- $this->queueRes();
226
- $handler = new StreamHandler();
227
- $opts['stream'] = true;
228
- return $handler([
229
- 'http_method' => 'GET',
230
- 'uri' => '/',
231
- 'headers' => ['host' => [Server::$host]],
232
- 'client' => $opts,
233
- ]);
234
- }
235
-
236
- public function testAddsProxy()
237
- {
238
- $res = $this->getSendResult(['stream' => true, 'proxy' => '127.0.0.1:8125']);
239
- $opts = stream_context_get_options($res['body']);
240
- $this->assertEquals('127.0.0.1:8125', $opts['http']['proxy']);
241
- }
242
-
243
- public function testAddsTimeout()
244
- {
245
- $res = $this->getSendResult(['stream' => true, 'timeout' => 200]);
246
- $opts = stream_context_get_options($res['body']);
247
- $this->assertEquals(200, $opts['http']['timeout']);
248
- }
249
-
250
- public function testVerifiesVerifyIsValidIfPath()
251
- {
252
- $res = $this->getSendResult(['verify' => '/does/not/exist']);
253
- $this->assertContains(
254
- 'SSL CA bundle not found: /does/not/exist',
255
- (string) $res['error']
256
- );
257
- }
258
-
259
- public function testVerifyCanBeDisabled()
260
- {
261
- $res = $this->getSendResult(['verify' => false]);
262
- $this->assertArrayNotHasKey('error', $res);
263
- }
264
-
265
- public function testVerifiesCertIfValidPath()
266
- {
267
- $res = $this->getSendResult(['cert' => '/does/not/exist']);
268
- $this->assertContains(
269
- 'SSL certificate not found: /does/not/exist',
270
- (string) $res['error']
271
- );
272
- }
273
-
274
- public function testVerifyCanBeSetToPath()
275
- {
276
- $path = $path = ClientUtils::getDefaultCaBundle();
277
- $res = $this->getSendResult(['verify' => $path]);
278
- $this->assertArrayNotHasKey('error', $res);
279
- $opts = stream_context_get_options($res['body']);
280
- $this->assertEquals(true, $opts['ssl']['verify_peer']);
281
- $this->assertEquals($path, $opts['ssl']['cafile']);
282
- $this->assertTrue(file_exists($opts['ssl']['cafile']));
283
- }
284
-
285
- public function testUsesSystemDefaultBundle()
286
- {
287
- $path = $path = ClientUtils::getDefaultCaBundle();
288
- $res = $this->getSendResult(['verify' => true]);
289
- $this->assertArrayNotHasKey('error', $res);
290
- $opts = stream_context_get_options($res['body']);
291
- if (PHP_VERSION_ID < 50600) {
292
- $this->assertEquals($path, $opts['ssl']['cafile']);
293
- }
294
- }
295
-
296
- public function testEnsuresVerifyOptionIsValid()
297
- {
298
- $res = $this->getSendResult(['verify' => 10]);
299
- $this->assertContains(
300
- 'Invalid verify request option',
301
- (string) $res['error']
302
- );
303
- }
304
-
305
- public function testCanSetPasswordWhenSettingCert()
306
- {
307
- $path = __FILE__;
308
- $res = $this->getSendResult(['cert' => [$path, 'foo']]);
309
- $opts = stream_context_get_options($res['body']);
310
- $this->assertEquals($path, $opts['ssl']['local_cert']);
311
- $this->assertEquals('foo', $opts['ssl']['passphrase']);
312
- }
313
-
314
- public function testDebugAttributeWritesToStream()
315
- {
316
- $this->queueRes();
317
- $f = fopen('php://temp', 'w+');
318
- $this->getSendResult(['debug' => $f]);
319
- fseek($f, 0);
320
- $contents = stream_get_contents($f);
321
- $this->assertContains('<GET http://127.0.0.1:8125/> [CONNECT]', $contents);
322
- $this->assertContains('<GET http://127.0.0.1:8125/> [FILE_SIZE_IS]', $contents);
323
- $this->assertContains('<GET http://127.0.0.1:8125/> [PROGRESS]', $contents);
324
- }
325
-
326
- public function testDebugAttributeWritesStreamInfoToBuffer()
327
- {
328
- $called = false;
329
- $this->queueRes();
330
- $buffer = fopen('php://temp', 'r+');
331
- $this->getSendResult([
332
- 'progress' => function () use (&$called) { $called = true; },
333
- 'debug' => $buffer,
334
- ]);
335
- fseek($buffer, 0);
336
- $contents = stream_get_contents($buffer);
337
- $this->assertContains('<GET http://127.0.0.1:8125/> [CONNECT]', $contents);
338
- $this->assertContains('<GET http://127.0.0.1:8125/> [FILE_SIZE_IS] message: "Content-Length: 8"', $contents);
339
- $this->assertContains('<GET http://127.0.0.1:8125/> [PROGRESS] bytes_max: "8"', $contents);
340
- $this->assertTrue($called);
341
- }
342
-
343
- public function testEmitsProgressInformation()
344
- {
345
- $called = [];
346
- $this->queueRes();
347
- $this->getSendResult([
348
- 'progress' => function () use (&$called) {
349
- $called[] = func_get_args();
350
- },
351
- ]);
352
- $this->assertNotEmpty($called);
353
- $this->assertEquals(8, $called[0][0]);
354
- $this->assertEquals(0, $called[0][1]);
355
- }
356
-
357
- public function testEmitsProgressInformationAndDebugInformation()
358
- {
359
- $called = [];
360
- $this->queueRes();
361
- $buffer = fopen('php://memory', 'w+');
362
- $this->getSendResult([
363
- 'debug' => $buffer,
364
- 'progress' => function () use (&$called) {
365
- $called[] = func_get_args();
366
- },
367
- ]);
368
- $this->assertNotEmpty($called);
369
- $this->assertEquals(8, $called[0][0]);
370
- $this->assertEquals(0, $called[0][1]);
371
- rewind($buffer);
372
- $this->assertNotEmpty(stream_get_contents($buffer));
373
- fclose($buffer);
374
- }
375
-
376
- public function testAddsProxyByProtocol()
377
- {
378
- $url = str_replace('http', 'tcp', Server::$url);
379
- $res = $this->getSendResult(['proxy' => ['http' => $url]]);
380
- $opts = stream_context_get_options($res['body']);
381
- $this->assertEquals($url, $opts['http']['proxy']);
382
- }
383
-
384
- public function testPerformsShallowMergeOfCustomContextOptions()
385
- {
386
- $res = $this->getSendResult([
387
- 'stream_context' => [
388
- 'http' => [
389
- 'request_fulluri' => true,
390
- 'method' => 'HEAD',
391
- ],
392
- 'socket' => [
393
- 'bindto' => '127.0.0.1:0',
394
- ],
395
- 'ssl' => [
396
- 'verify_peer' => false,
397
- ],
398
- ],
399
- ]);
400
-
401
- $opts = stream_context_get_options($res['body']);
402
- $this->assertEquals('HEAD', $opts['http']['method']);
403
- $this->assertTrue($opts['http']['request_fulluri']);
404
- $this->assertFalse($opts['ssl']['verify_peer']);
405
- $this->assertEquals('127.0.0.1:0', $opts['socket']['bindto']);
406
- }
407
-
408
- public function testEnsuresThatStreamContextIsAnArray()
409
- {
410
- $res = $this->getSendResult(['stream_context' => 'foo']);
411
- $this->assertContains(
412
- 'stream_context must be an array',
413
- (string) $res['error']
414
- );
415
- }
416
-
417
- public function testDoesNotAddContentTypeByDefault()
418
- {
419
- $this->queueRes();
420
- $handler = new StreamHandler();
421
- $handler([
422
- 'http_method' => 'PUT',
423
- 'uri' => '/',
424
- 'headers' => ['host' => [Server::$host], 'content-length' => [3]],
425
- 'body' => 'foo',
426
- ]);
427
- $req = Server::received()[0];
428
- $this->assertEquals('', Core::header($req, 'Content-Type'));
429
- $this->assertEquals(3, Core::header($req, 'Content-Length'));
430
- }
431
-
432
- private function queueRes()
433
- {
434
- Server::flush();
435
- Server::enqueue([
436
- [
437
- 'status' => 200,
438
- 'reason' => 'OK',
439
- 'headers' => [
440
- 'Foo' => ['Bar'],
441
- 'Content-Length' => [8],
442
- ],
443
- 'body' => 'hi there',
444
- ],
445
- ]);
446
- }
447
-
448
- public function testSupports100Continue()
449
- {
450
- Server::flush();
451
- Server::enqueue([
452
- [
453
- 'status' => '200',
454
- 'reason' => 'OK',
455
- 'headers' => [
456
- 'Test' => ['Hello'],
457
- 'Content-Length' => ['4'],
458
- ],
459
- 'body' => 'test',
460
- ],
461
- ]);
462
-
463
- $request = [
464
- 'http_method' => 'PUT',
465
- 'headers' => [
466
- 'Host' => [Server::$host],
467
- 'Expect' => ['100-Continue'],
468
- ],
469
- 'body' => 'test',
470
- ];
471
-
472
- $handler = new StreamHandler();
473
- $response = $handler($request);
474
- $this->assertEquals(200, $response['status']);
475
- $this->assertEquals('OK', $response['reason']);
476
- $this->assertEquals(['Hello'], $response['headers']['Test']);
477
- $this->assertEquals(['4'], $response['headers']['Content-Length']);
478
- $this->assertEquals('test', Core::body($response));
479
- }
480
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/tests/Client/server.js DELETED
@@ -1,241 +0,0 @@
1
- /**
2
- * Guzzle node.js test server to return queued responses to HTTP requests and
3
- * expose a RESTful API for enqueueing responses and retrieving the requests
4
- * that have been received.
5
- *
6
- * - Delete all requests that have been received:
7
- * > DELETE /guzzle-server/requests
8
- * > Host: 127.0.0.1:8125
9
- *
10
- * - Enqueue responses
11
- * > PUT /guzzle-server/responses
12
- * > Host: 127.0.0.1:8125
13
- * >
14
- * > [{'status': 200, 'reason': 'OK', 'headers': {}, 'body': '' }]
15
- *
16
- * - Get the received requests
17
- * > GET /guzzle-server/requests
18
- * > Host: 127.0.0.1:8125
19
- *
20
- * < HTTP/1.1 200 OK
21
- * <
22
- * < [{'http_method': 'GET', 'uri': '/', 'headers': {}, 'body': 'string'}]
23
- *
24
- * - Attempt access to the secure area
25
- * > GET /secure/by-digest/qop-auth/guzzle-server/requests
26
- * > Host: 127.0.0.1:8125
27
- *
28
- * < HTTP/1.1 401 Unauthorized
29
- * < WWW-Authenticate: Digest realm="Digest Test", qop="auth", nonce="0796e98e1aeef43141fab2a66bf4521a", algorithm="MD5", stale="false"
30
- * <
31
- * < 401 Unauthorized
32
- *
33
- * - Shutdown the server
34
- * > DELETE /guzzle-server
35
- * > Host: 127.0.0.1:8125
36
- *
37
- * @package Guzzle PHP <http://www.guzzlephp.org>
38
- * @license See the LICENSE file that was distributed with this source code.
39
- */
40
-
41
- var http = require('http');
42
- var url = require('url');
43
-
44
- /**
45
- * Guzzle node.js server
46
- * @class
47
- */
48
- var GuzzleServer = function(port, log) {
49
-
50
- this.port = port;
51
- this.log = log;
52
- this.responses = [];
53
- this.requests = [];
54
- var that = this;
55
-
56
- var md5 = function(input) {
57
- var crypto = require('crypto');
58
- var hasher = crypto.createHash('md5');
59
- hasher.update(input);
60
- return hasher.digest('hex');
61
- }
62
-
63
- /**
64
- * Node.js HTTP server authentication module.
65
- *
66
- * It is only initialized on demand (by loadAuthentifier). This avoids
67
- * requiring the dependency to http-auth on standard operations, and the
68
- * performance hit at startup.
69
- */
70
- var auth;
71
-
72
- /**
73
- * Provides authentication handlers (Basic, Digest).
74
- */
75
- var loadAuthentifier = function(type, options) {
76
- var typeId = type;
77
- if (type == 'digest') {
78
- typeId += '.'+(options && options.qop ? options.qop : 'none');
79
- }
80
- if (!loadAuthentifier[typeId]) {
81
- if (!auth) {
82
- try {
83
- auth = require('http-auth');
84
- } catch (e) {
85
- if (e.code == 'MODULE_NOT_FOUND') {
86
- return;
87
- }
88
- }
89
- }
90
- switch (type) {
91
- case 'digest':
92
- var digestParams = {
93
- realm: 'Digest Test',
94
- login: 'me',
95
- password: 'test'
96
- };
97
- if (options && options.qop) {
98
- digestParams.qop = options.qop;
99
- }
100
- loadAuthentifier[typeId] = auth.digest(digestParams, function(username, callback) {
101
- callback(md5(digestParams.login + ':' + digestParams.realm + ':' + digestParams.password));
102
- });
103
- break
104
- }
105
- }
106
- return loadAuthentifier[typeId];
107
- };
108
-
109
- var firewallRequest = function(request, req, res, requestHandlerCallback) {
110
- var securedAreaUriParts = request.uri.match(/^\/secure\/by-(digest)(\/qop-([^\/]*))?(\/.*)$/);
111
- if (securedAreaUriParts) {
112
- var authentifier = loadAuthentifier(securedAreaUriParts[1], { qop: securedAreaUriParts[2] });
113
- if (!authentifier) {
114
- res.writeHead(501, 'HTTP authentication not implemented', { 'Content-Length': 0 });
115
- res.end();
116
- return;
117
- }
118
- authentifier.check(req, res, function(req, res) {
119
- req.url = securedAreaUriParts[4];
120
- requestHandlerCallback(request, req, res);
121
- });
122
- } else {
123
- requestHandlerCallback(request, req, res);
124
- }
125
- };
126
-
127
- var controlRequest = function(request, req, res) {
128
- if (req.url == '/guzzle-server/perf') {
129
- res.writeHead(200, 'OK', {'Content-Length': 16});
130
- res.end('Body of response');
131
- } else if (req.method == 'DELETE') {
132
- if (req.url == '/guzzle-server/requests') {
133
- // Clear the received requests
134
- that.requests = [];
135
- res.writeHead(200, 'OK', { 'Content-Length': 0 });
136
- res.end();
137
- if (that.log) {
138
- console.log('Flushing requests');
139
- }
140
- } else if (req.url == '/guzzle-server') {
141
- // Shutdown the server
142
- res.writeHead(200, 'OK', { 'Content-Length': 0, 'Connection': 'close' });
143
- res.end();
144
- if (that.log) {
145
- console.log('Shutting down');
146
- }
147
- that.server.close();
148
- }
149
- } else if (req.method == 'GET') {
150
- if (req.url === '/guzzle-server/requests') {
151
- if (that.log) {
152
- console.log('Sending received requests');
153
- }
154
- // Get received requests
155
- var body = JSON.stringify(that.requests);
156
- res.writeHead(200, 'OK', { 'Content-Length': body.length });
157
- res.end(body);
158
- }
159
- } else if (req.method == 'PUT' && req.url == '/guzzle-server/responses') {
160
- if (that.log) {
161
- console.log('Adding responses...');
162
- }
163
- if (!request.body) {
164
- if (that.log) {
165
- console.log('No response data was provided');
166
- }
167
- res.writeHead(400, 'NO RESPONSES IN REQUEST', { 'Content-Length': 0 });
168
- } else {
169
- that.responses = eval('(' + request.body + ')');
170
- for (var i = 0; i < that.responses.length; i++) {
171
- if (that.responses[i].body) {
172
- that.responses[i].body = new Buffer(that.responses[i].body, 'base64');
173
- }
174
- }
175
- if (that.log) {
176
- console.log(that.responses);
177
- }
178
- res.writeHead(200, 'OK', { 'Content-Length': 0 });
179
- }
180
- res.end();
181
- }
182
- };
183
-
184
- var receivedRequest = function(request, req, res) {
185
- if (req.url.indexOf('/guzzle-server') === 0) {
186
- controlRequest(request, req, res);
187
- } else if (req.url.indexOf('/guzzle-server') == -1 && !that.responses.length) {
188
- res.writeHead(500);
189
- res.end('No responses in queue');
190
- } else {
191
- if (that.log) {
192
- console.log('Returning response from queue and adding request');
193
- }
194
- that.requests.push(request);
195
- var response = that.responses.shift();
196
- res.writeHead(response.status, response.reason, response.headers);
197
- res.end(response.body);
198
- }
199
- };
200
-
201
- this.start = function() {
202
-
203
- that.server = http.createServer(function(req, res) {
204
-
205
- var parts = url.parse(req.url, false);
206
- var request = {
207
- http_method: req.method,
208
- scheme: parts.scheme,
209
- uri: parts.pathname,
210
- query_string: parts.query,
211
- headers: req.headers,
212
- version: req.httpVersion,
213
- body: ''
214
- };
215
-
216
- // Receive each chunk of the request body
217
- req.addListener('data', function(chunk) {
218
- request.body += chunk;
219
- });
220
-
221
- // Called when the request completes
222
- req.addListener('end', function() {
223
- firewallRequest(request, req, res, receivedRequest);
224
- });
225
- });
226
-
227
- that.server.listen(this.port, '127.0.0.1');
228
-
229
- if (this.log) {
230
- console.log('Server running at http://127.0.0.1:8125/');
231
- }
232
- };
233
- };
234
-
235
- // Get the port from the arguments
236
- port = process.argv.length >= 3 ? process.argv[2] : 8125;
237
- log = process.argv.length >= 4 ? process.argv[3] : false;
238
-
239
- // Start the server
240
- server = new GuzzleServer(port, log);
241
- server.start();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/tests/CoreTest.php DELETED
@@ -1,336 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Ring;
3
-
4
- use GuzzleHttp\Ring\Core;
5
- use GuzzleHttp\Ring\Future\CompletedFutureArray;
6
- use GuzzleHttp\Ring\Future\FutureArray;
7
- use GuzzleHttp\Stream\Stream;
8
- use React\Promise\Deferred;
9
-
10
- class CoreTest extends \PHPUnit_Framework_TestCase
11
- {
12
- public function testReturnsNullNoHeadersAreSet()
13
- {
14
- $this->assertNull(Core::header([], 'Foo'));
15
- $this->assertNull(Core::firstHeader([], 'Foo'));
16
- }
17
-
18
- public function testChecksIfHasHeader()
19
- {
20
- $message = [
21
- 'headers' => [
22
- 'Foo' => ['Bar', 'Baz'],
23
- 'foo' => ['hello'],
24
- 'bar' => ['1']
25
- ]
26
- ];
27
- $this->assertTrue(Core::hasHeader($message, 'Foo'));
28
- $this->assertTrue(Core::hasHeader($message, 'foo'));
29
- $this->assertTrue(Core::hasHeader($message, 'FoO'));
30
- $this->assertTrue(Core::hasHeader($message, 'bar'));
31
- $this->assertFalse(Core::hasHeader($message, 'barr'));
32
- }
33
-
34
- public function testReturnsFirstHeaderWhenSimple()
35
- {
36
- $this->assertEquals('Bar', Core::firstHeader([
37
- 'headers' => ['Foo' => ['Bar', 'Baz']],
38
- ], 'Foo'));
39
- }
40
-
41
- public function testReturnsFirstHeaderWhenMultiplePerLine()
42
- {
43
- $this->assertEquals('Bar', Core::firstHeader([
44
- 'headers' => ['Foo' => ['Bar, Baz']],
45
- ], 'Foo'));
46
- }
47
-
48
- public function testExtractsCaseInsensitiveHeader()
49
- {
50
- $this->assertEquals(
51
- 'hello',
52
- Core::header(['headers' => ['foo' => ['hello']]], 'FoO')
53
- );
54
- }
55
-
56
- public function testExtractsCaseInsensitiveHeaderLines()
57
- {
58
- $this->assertEquals(
59
- ['a', 'b', 'c', 'd'],
60
- Core::headerLines([
61
- 'headers' => [
62
- 'foo' => ['a', 'b'],
63
- 'Foo' => ['c', 'd']
64
- ]
65
- ], 'foo')
66
- );
67
- }
68
-
69
- public function testExtractsHeaderLines()
70
- {
71
- $this->assertEquals(
72
- ['bar', 'baz'],
73
- Core::headerLines([
74
- 'headers' => [
75
- 'Foo' => ['bar', 'baz'],
76
- ],
77
- ], 'Foo')
78
- );
79
- }
80
-
81
- public function testExtractsHeaderAsString()
82
- {
83
- $this->assertEquals(
84
- 'bar, baz',
85
- Core::header([
86
- 'headers' => [
87
- 'Foo' => ['bar', 'baz'],
88
- ],
89
- ], 'Foo', true)
90
- );
91
- }
92
-
93
- public function testReturnsNullWhenHeaderNotFound()
94
- {
95
- $this->assertNull(Core::header(['headers' => []], 'Foo'));
96
- }
97
-
98
- public function testRemovesHeaders()
99
- {
100
- $message = [
101
- 'headers' => [
102
- 'foo' => ['bar'],
103
- 'Foo' => ['bam'],
104
- 'baz' => ['123'],
105
- ],
106
- ];
107
-
108
- $this->assertSame($message, Core::removeHeader($message, 'bam'));
109
- $this->assertEquals([
110
- 'headers' => ['baz' => ['123']],
111
- ], Core::removeHeader($message, 'foo'));
112
- }
113
-
114
- public function testCreatesUrl()
115
- {
116
- $req = [
117
- 'scheme' => 'http',
118
- 'headers' => ['host' => ['foo.com']],
119
- 'uri' => '/',
120
- ];
121
-
122
- $this->assertEquals('http://foo.com/', Core::url($req));
123
- }
124
-
125
- /**
126
- * @expectedException \InvalidArgumentException
127
- * @expectedExceptionMessage No Host header was provided
128
- */
129
- public function testEnsuresHostIsAvailableWhenCreatingUrls()
130
- {
131
- Core::url([]);
132
- }
133
-
134
- public function testCreatesUrlWithQueryString()
135
- {
136
- $req = [
137
- 'scheme' => 'http',
138
- 'headers' => ['host' => ['foo.com']],
139
- 'uri' => '/',
140
- 'query_string' => 'foo=baz',
141
- ];
142
-
143
- $this->assertEquals('http://foo.com/?foo=baz', Core::url($req));
144
- }
145
-
146
- public function testUsesUrlIfSet()
147
- {
148
- $req = ['url' => 'http://foo.com'];
149
- $this->assertEquals('http://foo.com', Core::url($req));
150
- }
151
-
152
- public function testReturnsNullWhenNoBody()
153
- {
154
- $this->assertNull(Core::body([]));
155
- }
156
-
157
- public function testReturnsStreamAsString()
158
- {
159
- $this->assertEquals(
160
- 'foo',
161
- Core::body(['body' => Stream::factory('foo')])
162
- );
163
- }
164
-
165
- public function testReturnsString()
166
- {
167
- $this->assertEquals('foo', Core::body(['body' => 'foo']));
168
- }
169
-
170
- public function testReturnsResourceContent()
171
- {
172
- $r = fopen('php://memory', 'w+');
173
- fwrite($r, 'foo');
174
- rewind($r);
175
- $this->assertEquals('foo', Core::body(['body' => $r]));
176
- fclose($r);
177
- }
178
-
179
- public function testReturnsIteratorContent()
180
- {
181
- $a = new \ArrayIterator(['a', 'b', 'cd', '']);
182
- $this->assertEquals('abcd', Core::body(['body' => $a]));
183
- }
184
-
185
- public function testReturnsObjectToString()
186
- {
187
- $this->assertEquals('foo', Core::body(['body' => new StrClass]));
188
- }
189
-
190
- /**
191
- * @expectedException \InvalidArgumentException
192
- */
193
- public function testEnsuresBodyIsValid()
194
- {
195
- Core::body(['body' => false]);
196
- }
197
-
198
- public function testParsesHeadersFromLines()
199
- {
200
- $lines = ['Foo: bar', 'Foo: baz', 'Abc: 123', 'Def: a, b'];
201
- $this->assertEquals([
202
- 'Foo' => ['bar', 'baz'],
203
- 'Abc' => ['123'],
204
- 'Def' => ['a, b'],
205
- ], Core::headersFromLines($lines));
206
- }
207
-
208
- public function testParsesHeadersFromLinesWithMultipleLines()
209
- {
210
- $lines = ['Foo: bar', 'Foo: baz', 'Foo: 123'];
211
- $this->assertEquals([
212
- 'Foo' => ['bar', 'baz', '123'],
213
- ], Core::headersFromLines($lines));
214
- }
215
-
216
- public function testCreatesArrayCallFunctions()
217
- {
218
- $called = [];
219
- $a = function ($a, $b) use (&$called) {
220
- $called['a'] = func_get_args();
221
- };
222
- $b = function ($a, $b) use (&$called) {
223
- $called['b'] = func_get_args();
224
- };
225
- $c = Core::callArray([$a, $b]);
226
- $c(1, 2);
227
- $this->assertEquals([1, 2], $called['a']);
228
- $this->assertEquals([1, 2], $called['b']);
229
- }
230
-
231
- public function testRewindsGuzzleStreams()
232
- {
233
- $str = Stream::factory('foo');
234
- $this->assertTrue(Core::rewindBody(['body' => $str]));
235
- }
236
-
237
- public function testRewindsStreams()
238
- {
239
- $str = Stream::factory('foo')->detach();
240
- $this->assertTrue(Core::rewindBody(['body' => $str]));
241
- }
242
-
243
- public function testRewindsIterators()
244
- {
245
- $iter = new \ArrayIterator(['foo']);
246
- $this->assertTrue(Core::rewindBody(['body' => $iter]));
247
- }
248
-
249
- public function testRewindsStrings()
250
- {
251
- $this->assertTrue(Core::rewindBody(['body' => 'hi']));
252
- }
253
-
254
- public function testRewindsToStrings()
255
- {
256
- $this->assertTrue(Core::rewindBody(['body' => new StrClass()]));
257
- }
258
-
259
- public function typeProvider()
260
- {
261
- return [
262
- ['foo', 'string(3) "foo"'],
263
- [true, 'bool(true)'],
264
- [false, 'bool(false)'],
265
- [10, 'int(10)'],
266
- [1.0, 'float(1)'],
267
- [new StrClass(), 'object(GuzzleHttp\Tests\Ring\StrClass)'],
268
- [['foo'], 'array(1)']
269
- ];
270
- }
271
-
272
- /**
273
- * @dataProvider typeProvider
274
- */
275
- public function testDescribesType($input, $output)
276
- {
277
- $this->assertEquals($output, Core::describeType($input));
278
- }
279
-
280
- public function testDoesSleep()
281
- {
282
- $t = microtime(true);
283
- $expected = $t + (100 / 1000);
284
- Core::doSleep(['client' => ['delay' => 100]]);
285
- $this->assertGreaterThanOrEqual($expected, microtime(true));
286
- }
287
-
288
- public function testProxiesFuture()
289
- {
290
- $f = new CompletedFutureArray(['status' => 200]);
291
- $res = null;
292
- $proxied = Core::proxy($f, function ($value) use (&$res) {
293
- $value['foo'] = 'bar';
294
- $res = $value;
295
- return $value;
296
- });
297
- $this->assertNotSame($f, $proxied);
298
- $this->assertEquals(200, $f->wait()['status']);
299
- $this->assertArrayNotHasKey('foo', $f->wait());
300
- $this->assertEquals('bar', $proxied->wait()['foo']);
301
- $this->assertEquals(200, $proxied->wait()['status']);
302
- }
303
-
304
- public function testProxiesDeferredFuture()
305
- {
306
- $d = new Deferred();
307
- $f = new FutureArray($d->promise());
308
- $f2 = Core::proxy($f);
309
- $d->resolve(['foo' => 'bar']);
310
- $this->assertEquals('bar', $f['foo']);
311
- $this->assertEquals('bar', $f2['foo']);
312
- }
313
-
314
- public function testProxiesDeferredFutureFailure()
315
- {
316
- $d = new Deferred();
317
- $f = new FutureArray($d->promise());
318
- $f2 = Core::proxy($f);
319
- $d->reject(new \Exception('foo'));
320
- try {
321
- $f2['hello?'];
322
- $this->fail('did not throw');
323
- } catch (\Exception $e) {
324
- $this->assertEquals('foo', $e->getMessage());
325
- }
326
-
327
- }
328
- }
329
-
330
- final class StrClass
331
- {
332
- public function __toString()
333
- {
334
- return 'foo';
335
- }
336
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/tests/Future/CompletedFutureArrayTest.php DELETED
@@ -1,21 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Ring\Future;
3
-
4
- use GuzzleHttp\Ring\Future\CompletedFutureArray;
5
-
6
- class CompletedFutureArrayTest extends \PHPUnit_Framework_TestCase
7
- {
8
- public function testReturnsAsArray()
9
- {
10
- $f = new CompletedFutureArray(['foo' => 'bar']);
11
- $this->assertEquals('bar', $f['foo']);
12
- $this->assertFalse(isset($f['baz']));
13
- $f['abc'] = '123';
14
- $this->assertTrue(isset($f['abc']));
15
- $this->assertEquals(['foo' => 'bar', 'abc' => '123'], iterator_to_array($f));
16
- $this->assertEquals(2, count($f));
17
- unset($f['abc']);
18
- $this->assertEquals(1, count($f));
19
- $this->assertEquals(['foo' => 'bar'], iterator_to_array($f));
20
- }
21
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/tests/Future/CompletedFutureValueTest.php DELETED
@@ -1,46 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Ring\Future;
3
-
4
- use GuzzleHttp\Ring\Exception\CancelledFutureAccessException;
5
- use GuzzleHttp\Ring\Future\CompletedFutureValue;
6
-
7
- class CompletedFutureValueTest extends \PHPUnit_Framework_TestCase
8
- {
9
- public function testReturnsValue()
10
- {
11
- $f = new CompletedFutureValue('hi');
12
- $this->assertEquals('hi', $f->wait());
13
- $f->cancel();
14
-
15
- $a = null;
16
- $f->then(function ($v) use (&$a) {
17
- $a = $v;
18
- });
19
- $this->assertSame('hi', $a);
20
- }
21
-
22
- public function testThrows()
23
- {
24
- $ex = new \Exception('foo');
25
- $f = new CompletedFutureValue(null, $ex);
26
- $f->cancel();
27
- try {
28
- $f->wait();
29
- $this->fail('did not throw');
30
- } catch (\Exception $e) {
31
- $this->assertSame($e, $ex);
32
- }
33
- }
34
-
35
- public function testMarksAsCancelled()
36
- {
37
- $ex = new CancelledFutureAccessException();
38
- $f = new CompletedFutureValue(null, $ex);
39
- try {
40
- $f->wait();
41
- $this->fail('did not throw');
42
- } catch (\Exception $e) {
43
- $this->assertSame($e, $ex);
44
- }
45
- }
46
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/tests/Future/FutureArrayTest.php DELETED
@@ -1,56 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Ring\Future;
3
-
4
- use GuzzleHttp\Ring\Future\FutureArray;
5
- use React\Promise\Deferred;
6
-
7
- class FutureArrayTest extends \PHPUnit_Framework_TestCase
8
- {
9
- public function testLazilyCallsDeref()
10
- {
11
- $c = false;
12
- $deferred = new Deferred();
13
- $f = new FutureArray(
14
- $deferred->promise(),
15
- function () use (&$c, $deferred) {
16
- $c = true;
17
- $deferred->resolve(['status' => 200]);
18
- }
19
- );
20
- $this->assertFalse($c);
21
- $this->assertFalse($this->readAttribute($f, 'isRealized'));
22
- $this->assertEquals(200, $f['status']);
23
- $this->assertTrue($c);
24
- }
25
-
26
- public function testActsLikeArray()
27
- {
28
- $deferred = new Deferred();
29
- $f = new FutureArray(
30
- $deferred->promise(),
31
- function () use (&$c, $deferred) {
32
- $deferred->resolve(['status' => 200]);
33
- }
34
- );
35
-
36
- $this->assertTrue(isset($f['status']));
37
- $this->assertEquals(200, $f['status']);
38
- $this->assertEquals(['status' => 200], $f->wait());
39
- $this->assertEquals(1, count($f));
40
- $f['baz'] = 10;
41
- $this->assertEquals(10, $f['baz']);
42
- unset($f['baz']);
43
- $this->assertFalse(isset($f['baz']));
44
- $this->assertEquals(['status' => 200], iterator_to_array($f));
45
- }
46
-
47
- /**
48
- * @expectedException \RuntimeException
49
- */
50
- public function testThrowsWhenAccessingInvalidProperty()
51
- {
52
- $deferred = new Deferred();
53
- $f = new FutureArray($deferred->promise(), function () {});
54
- $f->foo;
55
- }
56
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/tests/Future/FutureValueTest.php DELETED
@@ -1,109 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Ring\Future;
3
-
4
- use GuzzleHttp\Ring\Exception\CancelledFutureAccessException;
5
- use GuzzleHttp\Ring\Future\FutureValue;
6
- use React\Promise\Deferred;
7
-
8
- class FutureValueTest extends \PHPUnit_Framework_TestCase
9
- {
10
- public function testDerefReturnsValue()
11
- {
12
- $called = 0;
13
- $deferred = new Deferred();
14
-
15
- $f = new FutureValue(
16
- $deferred->promise(),
17
- function () use ($deferred, &$called) {
18
- $called++;
19
- $deferred->resolve('foo');
20
- }
21
- );
22
-
23
- $this->assertEquals('foo', $f->wait());
24
- $this->assertEquals(1, $called);
25
- $this->assertEquals('foo', $f->wait());
26
- $this->assertEquals(1, $called);
27
- $f->cancel();
28
- $this->assertTrue($this->readAttribute($f, 'isRealized'));
29
- }
30
-
31
- /**
32
- * @expectedException \GuzzleHttp\Ring\Exception\CancelledFutureAccessException
33
- */
34
- public function testThrowsWhenAccessingCancelled()
35
- {
36
- $f = new FutureValue(
37
- (new Deferred())->promise(),
38
- function () {},
39
- function () { return true; }
40
- );
41
- $f->cancel();
42
- $f->wait();
43
- }
44
-
45
- /**
46
- * @expectedException \OutOfBoundsException
47
- */
48
- public function testThrowsWhenDerefFailure()
49
- {
50
- $called = false;
51
- $deferred = new Deferred();
52
- $f = new FutureValue(
53
- $deferred->promise(),
54
- function () use(&$called) {
55
- $called = true;
56
- }
57
- );
58
- $deferred->reject(new \OutOfBoundsException());
59
- $f->wait();
60
- $this->assertFalse($called);
61
- }
62
-
63
- /**
64
- * @expectedException \GuzzleHttp\Ring\Exception\RingException
65
- * @expectedExceptionMessage Waiting did not resolve future
66
- */
67
- public function testThrowsWhenDerefDoesNotResolve()
68
- {
69
- $deferred = new Deferred();
70
- $f = new FutureValue(
71
- $deferred->promise(),
72
- function () use(&$called) {
73
- $called = true;
74
- }
75
- );
76
- $f->wait();
77
- }
78
-
79
- public function testThrowingCancelledFutureAccessExceptionCancels()
80
- {
81
- $deferred = new Deferred();
82
- $f = new FutureValue(
83
- $deferred->promise(),
84
- function () use ($deferred) {
85
- throw new CancelledFutureAccessException();
86
- }
87
- );
88
- try {
89
- $f->wait();
90
- $this->fail('did not throw');
91
- } catch (CancelledFutureAccessException $e) {}
92
- }
93
-
94
- /**
95
- * @expectedException \Exception
96
- * @expectedExceptionMessage foo
97
- */
98
- public function testThrowingExceptionInDerefMarksAsFailed()
99
- {
100
- $deferred = new Deferred();
101
- $f = new FutureValue(
102
- $deferred->promise(),
103
- function () {
104
- throw new \Exception('foo');
105
- }
106
- );
107
- $f->wait();
108
- }
109
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/ringphp/tests/bootstrap.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
- require __DIR__ . '/../vendor/autoload.php';
3
- require __DIR__ . '/Client/Server.php';
4
-
5
- use GuzzleHttp\Tests\Ring\Client\Server;
6
-
7
- Server::start();
8
-
9
- register_shutdown_function(function () {
10
- Server::stop();
11
- });
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/phpunit.xml.dist DELETED
@@ -1,17 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <phpunit bootstrap="./vendor/autoload.php"
3
- colors="true">
4
- <testsuites>
5
- <testsuite>
6
- <directory>tests</directory>
7
- </testsuite>
8
- </testsuites>
9
- <filter>
10
- <whitelist>
11
- <directory suffix=".php">src</directory>
12
- <exclude>
13
- <file>src/functions.php</file>
14
- </exclude>
15
- </whitelist>
16
- </filter>
17
- </phpunit>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/AppendStreamTest.php DELETED
@@ -1,178 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Stream;
3
-
4
- use GuzzleHttp\Stream\AppendStream;
5
- use GuzzleHttp\Stream\Stream;
6
-
7
- class AppendStreamTest extends \PHPUnit_Framework_TestCase
8
- {
9
- /**
10
- * @expectedException \InvalidArgumentException
11
- * @expectedExceptionMessage Each stream must be readable
12
- */
13
- public function testValidatesStreamsAreReadable()
14
- {
15
- $a = new AppendStream();
16
- $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface')
17
- ->setMethods(['isReadable'])
18
- ->getMockForAbstractClass();
19
- $s->expects($this->once())
20
- ->method('isReadable')
21
- ->will($this->returnValue(false));
22
- $a->addStream($s);
23
- }
24
-
25
- public function testValidatesSeekType()
26
- {
27
- $a = new AppendStream();
28
- $this->assertFalse($a->seek(100, SEEK_CUR));
29
- }
30
-
31
- public function testTriesToRewindOnSeek()
32
- {
33
- $a = new AppendStream();
34
- $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface')
35
- ->setMethods(['isReadable', 'seek', 'isSeekable'])
36
- ->getMockForAbstractClass();
37
- $s->expects($this->once())
38
- ->method('isReadable')
39
- ->will($this->returnValue(true));
40
- $s->expects($this->once())
41
- ->method('isSeekable')
42
- ->will($this->returnValue(true));
43
- $s->expects($this->once())
44
- ->method('seek')
45
- ->will($this->returnValue(false));
46
- $a->addStream($s);
47
- $this->assertFalse($a->seek(10));
48
- }
49
-
50
- public function testSeeksToPositionByReading()
51
- {
52
- $a = new AppendStream([
53
- Stream::factory('foo'),
54
- Stream::factory('bar'),
55
- Stream::factory('baz'),
56
- ]);
57
-
58
- $this->assertTrue($a->seek(3));
59
- $this->assertEquals(3, $a->tell());
60
- $this->assertEquals('bar', $a->read(3));
61
- $a->seek(6);
62
- $this->assertEquals(6, $a->tell());
63
- $this->assertEquals('baz', $a->read(3));
64
- }
65
-
66
- public function testDetachesEachStream()
67
- {
68
- $s1 = Stream::factory('foo');
69
- $s2 = Stream::factory('foo');
70
- $a = new AppendStream([$s1, $s2]);
71
- $this->assertSame('foofoo', (string) $a);
72
- $a->detach();
73
- $this->assertSame('', (string) $a);
74
- $this->assertSame(0, $a->getSize());
75
- }
76
-
77
- public function testClosesEachStream()
78
- {
79
- $s1 = Stream::factory('foo');
80
- $a = new AppendStream([$s1]);
81
- $a->close();
82
- $this->assertSame('', (string) $a);
83
- }
84
-
85
- public function testIsNotWritable()
86
- {
87
- $a = new AppendStream([Stream::factory('foo')]);
88
- $this->assertFalse($a->isWritable());
89
- $this->assertTrue($a->isSeekable());
90
- $this->assertTrue($a->isReadable());
91
- $this->assertFalse($a->write('foo'));
92
- }
93
-
94
- public function testDoesNotNeedStreams()
95
- {
96
- $a = new AppendStream();
97
- $this->assertEquals('', (string) $a);
98
- }
99
-
100
- public function testCanReadFromMultipleStreams()
101
- {
102
- $a = new AppendStream([
103
- Stream::factory('foo'),
104
- Stream::factory('bar'),
105
- Stream::factory('baz'),
106
- ]);
107
- $this->assertFalse($a->eof());
108
- $this->assertSame(0, $a->tell());
109
- $this->assertEquals('foo', $a->read(3));
110
- $this->assertEquals('bar', $a->read(3));
111
- $this->assertEquals('baz', $a->read(3));
112
- $this->assertTrue($a->eof());
113
- $this->assertSame(9, $a->tell());
114
- $this->assertEquals('foobarbaz', (string) $a);
115
- }
116
-
117
- public function testCanDetermineSizeFromMultipleStreams()
118
- {
119
- $a = new AppendStream([
120
- Stream::factory('foo'),
121
- Stream::factory('bar')
122
- ]);
123
- $this->assertEquals(6, $a->getSize());
124
-
125
- $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface')
126
- ->setMethods(['isSeekable', 'isReadable'])
127
- ->getMockForAbstractClass();
128
- $s->expects($this->once())
129
- ->method('isSeekable')
130
- ->will($this->returnValue(null));
131
- $s->expects($this->once())
132
- ->method('isReadable')
133
- ->will($this->returnValue(true));
134
- $a->addStream($s);
135
- $this->assertNull($a->getSize());
136
- }
137
-
138
- public function testCatchesExceptionsWhenCastingToString()
139
- {
140
- $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface')
141
- ->setMethods(['read', 'isReadable', 'eof'])
142
- ->getMockForAbstractClass();
143
- $s->expects($this->once())
144
- ->method('read')
145
- ->will($this->throwException(new \RuntimeException('foo')));
146
- $s->expects($this->once())
147
- ->method('isReadable')
148
- ->will($this->returnValue(true));
149
- $s->expects($this->any())
150
- ->method('eof')
151
- ->will($this->returnValue(false));
152
- $a = new AppendStream([$s]);
153
- $this->assertFalse($a->eof());
154
- $this->assertSame('', (string) $a);
155
- }
156
-
157
- public function testCanDetach()
158
- {
159
- $s = new AppendStream();
160
- $s->detach();
161
- }
162
-
163
- public function testReturnsEmptyMetadata()
164
- {
165
- $s = new AppendStream();
166
- $this->assertEquals([], $s->getMetadata());
167
- $this->assertNull($s->getMetadata('foo'));
168
- }
169
-
170
- /**
171
- * @expectedException \GuzzleHttp\Stream\Exception\CannotAttachException
172
- */
173
- public function testCannotAttach()
174
- {
175
- $p = new AppendStream();
176
- $p->attach('a');
177
- }
178
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/AsyncReadStreamTest.php DELETED
@@ -1,186 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Stream;
3
-
4
- use GuzzleHttp\Stream\AsyncReadStream;
5
- use GuzzleHttp\Stream\BufferStream;
6
- use GuzzleHttp\Stream\FnStream;
7
- use GuzzleHttp\Stream\Stream;
8
-
9
- class AsyncReadStreamTest extends \PHPUnit_Framework_TestCase
10
- {
11
- /**
12
- * @expectedException \InvalidArgumentException
13
- * @expectedExceptionMessage Buffer must be readable and writable
14
- */
15
- public function testValidatesReadableBuffer()
16
- {
17
- new AsyncReadStream(FnStream::decorate(
18
- Stream::factory(),
19
- ['isReadable' => function () { return false; }]
20
- ));
21
- }
22
-
23
- /**
24
- * @expectedException \InvalidArgumentException
25
- * @expectedExceptionMessage Buffer must be readable and writable
26
- */
27
- public function testValidatesWritableBuffer()
28
- {
29
- new AsyncReadStream(FnStream::decorate(
30
- Stream::factory(),
31
- ['isWritable' => function () { return false; }]
32
- ));
33
- }
34
-
35
- public function testValidatesHwmMetadata()
36
- {
37
- $a = new AsyncReadStream(Stream::factory(), [
38
- 'drain' => function() {}
39
- ]);
40
- $this->assertNull($this->readAttribute($a, 'drain'));
41
- }
42
-
43
- /**
44
- * @expectedException \InvalidArgumentException
45
- * @expectedExceptionMessage pump must be callable
46
- */
47
- public function testValidatesPumpIsCallable()
48
- {
49
- new AsyncReadStream(new BufferStream(), ['pump' => true]);
50
- }
51
-
52
- /**
53
- * @expectedException \InvalidArgumentException
54
- * @expectedExceptionMessage drain must be callable
55
- */
56
- public function testValidatesDrainIsCallable()
57
- {
58
- new AsyncReadStream(new BufferStream(), ['drain' => true]);
59
- }
60
-
61
- public function testCanInitialize()
62
- {
63
- $buffer = new BufferStream();
64
- $a = new AsyncReadStream($buffer, [
65
- 'size' => 10,
66
- 'drain' => function () {},
67
- 'pump' => function () {},
68
- ]);
69
- $this->assertSame($buffer, $this->readAttribute($a, 'stream'));
70
- $this->assertTrue(is_callable($this->readAttribute($a, 'drain')));
71
- $this->assertTrue(is_callable($this->readAttribute($a, 'pump')));
72
- $this->assertTrue($a->isReadable());
73
- $this->assertFalse($a->isSeekable());
74
- $this->assertFalse($a->isWritable());
75
- $this->assertFalse($a->write('foo'));
76
- $this->assertEquals(10, $a->getSize());
77
- }
78
-
79
- public function testReadsFromBufferWithNoDrainOrPump()
80
- {
81
- $buffer = new BufferStream();
82
- $a = new AsyncReadStream($buffer);
83
- $buffer->write('foo');
84
- $this->assertNull($a->getSize());
85
- $this->assertEquals('foo', $a->read(10));
86
- $this->assertEquals('', $a->read(10));
87
- }
88
-
89
- public function testCallsPumpForMoreDataWhenRequested()
90
- {
91
- $called = 0;
92
- $buffer = new BufferStream();
93
- $a = new AsyncReadStream($buffer, [
94
- 'pump' => function ($size) use (&$called) {
95
- $called++;
96
- return str_repeat('.', $size);
97
- }
98
- ]);
99
- $buffer->write('foobar');
100
- $this->assertEquals('foo', $a->read(3));
101
- $this->assertEquals(0, $called);
102
- $this->assertEquals('bar.....', $a->read(8));
103
- $this->assertEquals(1, $called);
104
- $this->assertEquals('..', $a->read(2));
105
- $this->assertEquals(2, $called);
106
- }
107
-
108
- public function testCallsDrainWhenNeeded()
109
- {
110
- $called = 0;
111
- $buffer = new BufferStream(5);
112
- $a = new AsyncReadStream($buffer, [
113
- 'drain' => function (BufferStream $b) use (&$called, $buffer) {
114
- $this->assertSame($b, $buffer);
115
- $called++;
116
- }
117
- ]);
118
-
119
- $buffer->write('foobar');
120
- $this->assertEquals(6, $buffer->getSize());
121
- $this->assertEquals(0, $called);
122
-
123
- $a->read(3);
124
- $this->assertTrue($this->readAttribute($a, 'needsDrain'));
125
- $this->assertEquals(3, $buffer->getSize());
126
- $this->assertEquals(0, $called);
127
-
128
- $a->read(3);
129
- $this->assertEquals(0, $buffer->getSize());
130
- $this->assertFalse($this->readAttribute($a, 'needsDrain'));
131
- $this->assertEquals(1, $called);
132
- }
133
-
134
- public function testCreatesBufferWithNoConfig()
135
- {
136
- list($buffer, $async) = AsyncReadStream::create();
137
- $this->assertInstanceOf('GuzzleHttp\Stream\BufferStream', $buffer);
138
- $this->assertInstanceOf('GuzzleHttp\Stream\AsyncReadStream', $async);
139
- }
140
-
141
- public function testCreatesBufferWithSpecifiedBuffer()
142
- {
143
- $buf = new BufferStream();
144
- list($buffer, $async) = AsyncReadStream::create(['buffer' => $buf]);
145
- $this->assertSame($buf, $buffer);
146
- $this->assertInstanceOf('GuzzleHttp\Stream\AsyncReadStream', $async);
147
- }
148
-
149
- public function testCreatesNullStream()
150
- {
151
- list($buffer, $async) = AsyncReadStream::create(['max_buffer' => 0]);
152
- $this->assertInstanceOf('GuzzleHttp\Stream\NullStream', $buffer);
153
- $this->assertInstanceOf('GuzzleHttp\Stream\AsyncReadStream', $async);
154
- }
155
-
156
- public function testCreatesDroppingStream()
157
- {
158
- list($buffer, $async) = AsyncReadStream::create(['max_buffer' => 5]);
159
- $this->assertInstanceOf('GuzzleHttp\Stream\DroppingStream', $buffer);
160
- $this->assertInstanceOf('GuzzleHttp\Stream\AsyncReadStream', $async);
161
- $buffer->write('12345678910');
162
- $this->assertEquals(5, $buffer->getSize());
163
- }
164
-
165
- public function testCreatesOnWriteStream()
166
- {
167
- $c = 0;
168
- $b = new BufferStream();
169
- list($buffer, $async) = AsyncReadStream::create([
170
- 'buffer' => $b,
171
- 'write' => function (BufferStream $buf, $data) use (&$c, $b) {
172
- $this->assertSame($buf, $b);
173
- $this->assertEquals('foo', $data);
174
- $c++;
175
- }
176
- ]);
177
- $this->assertInstanceOf('GuzzleHttp\Stream\FnStream', $buffer);
178
- $this->assertInstanceOf('GuzzleHttp\Stream\AsyncReadStream', $async);
179
- $this->assertEquals(0, $c);
180
- $this->assertEquals(3, $buffer->write('foo'));
181
- $this->assertEquals(1, $c);
182
- $this->assertEquals(3, $buffer->write('foo'));
183
- $this->assertEquals(2, $c);
184
- $this->assertEquals('foofoo', (string) $buffer);
185
- }
186
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/BufferStreamTest.php DELETED
@@ -1,69 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Stream;
3
-
4
- use GuzzleHttp\Stream\BufferStream;
5
-
6
- class BufferStreamTest extends \PHPUnit_Framework_TestCase
7
- {
8
- public function testHasMetadata()
9
- {
10
- $b = new BufferStream(10);
11
- $this->assertTrue($b->isReadable());
12
- $this->assertTrue($b->isWritable());
13
- $this->assertFalse($b->isSeekable());
14
- $this->assertEquals(null, $b->getMetadata('foo'));
15
- $this->assertEquals(10, $b->getMetadata('hwm'));
16
- $this->assertEquals([], $b->getMetadata());
17
- }
18
-
19
- public function testRemovesReadDataFromBuffer()
20
- {
21
- $b = new BufferStream();
22
- $this->assertEquals(3, $b->write('foo'));
23
- $this->assertEquals(3, $b->getSize());
24
- $this->assertFalse($b->eof());
25
- $this->assertEquals('foo', $b->read(10));
26
- $this->assertTrue($b->eof());
27
- $this->assertEquals('', $b->read(10));
28
- }
29
-
30
- public function testCanCastToStringOrGetContents()
31
- {
32
- $b = new BufferStream();
33
- $b->write('foo');
34
- $b->write('baz');
35
- $this->assertEquals('foo', $b->read(3));
36
- $b->write('bar');
37
- $this->assertEquals('bazbar', (string) $b);
38
- $this->assertFalse($b->tell());
39
- }
40
-
41
- public function testDetachClearsBuffer()
42
- {
43
- $b = new BufferStream();
44
- $b->write('foo');
45
- $b->detach();
46
- $this->assertEquals(0, $b->tell());
47
- $this->assertTrue($b->eof());
48
- $this->assertEquals(3, $b->write('abc'));
49
- $this->assertEquals('abc', $b->read(10));
50
- }
51
-
52
- public function testExceedingHighwaterMarkReturnsFalseButStillBuffers()
53
- {
54
- $b = new BufferStream(5);
55
- $this->assertEquals(3, $b->write('hi '));
56
- $this->assertFalse($b->write('hello'));
57
- $this->assertEquals('hi hello', (string) $b);
58
- $this->assertEquals(4, $b->write('test'));
59
- }
60
-
61
- /**
62
- * @expectedException \GuzzleHttp\Stream\Exception\CannotAttachException
63
- */
64
- public function testCannotAttach()
65
- {
66
- $p = new BufferStream();
67
- $p->attach('a');
68
- }
69
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/CachingStreamTest.php DELETED
@@ -1,136 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Stream;
3
-
4
- use GuzzleHttp\Stream\Stream;
5
- use GuzzleHttp\Stream\CachingStream;
6
- use GuzzleHttp\Stream\Utils;
7
-
8
- /**
9
- * @covers GuzzleHttp\Stream\CachingStream
10
- */
11
- class CachingStreamTest extends \PHPUnit_Framework_TestCase
12
- {
13
- /** @var CachingStream */
14
- protected $body;
15
-
16
- /** @var Stream */
17
- protected $decorated;
18
-
19
- public function setUp()
20
- {
21
- $this->decorated = Stream::factory('testing');
22
- $this->body = new CachingStream($this->decorated);
23
- }
24
-
25
- public function tearDown()
26
- {
27
- $this->decorated->close();
28
- $this->body->close();
29
- }
30
-
31
- public function testUsesRemoteSizeIfPossible()
32
- {
33
- $body = Stream::factory('test');
34
- $caching = new CachingStream($body);
35
- $this->assertEquals(4, $caching->getSize());
36
- }
37
-
38
- /**
39
- * @expectedException \RuntimeException
40
- * @expectedExceptionMessage Cannot seek to byte 10
41
- */
42
- public function testCannotSeekPastWhatHasBeenRead()
43
- {
44
- $this->body->seek(10);
45
- }
46
-
47
- public function testCannotUseSeekEnd()
48
- {
49
- $this->assertFalse($this->body->seek(2, SEEK_END));
50
- }
51
-
52
- public function testRewindUsesSeek()
53
- {
54
- $a = Stream::factory('foo');
55
- $d = $this->getMockBuilder('GuzzleHttp\Stream\CachingStream')
56
- ->setMethods(array('seek'))
57
- ->setConstructorArgs(array($a))
58
- ->getMock();
59
- $d->expects($this->once())
60
- ->method('seek')
61
- ->with(0)
62
- ->will($this->returnValue(true));
63
- $d->seek(0);
64
- }
65
-
66
- public function testCanSeekToReadBytes()
67
- {
68
- $this->assertEquals('te', $this->body->read(2));
69
- $this->body->seek(0);
70
- $this->assertEquals('test', $this->body->read(4));
71
- $this->assertEquals(4, $this->body->tell());
72
- $this->body->seek(2);
73
- $this->assertEquals(2, $this->body->tell());
74
- $this->body->seek(2, SEEK_CUR);
75
- $this->assertEquals(4, $this->body->tell());
76
- $this->assertEquals('ing', $this->body->read(3));
77
- }
78
-
79
- public function testWritesToBufferStream()
80
- {
81
- $this->body->read(2);
82
- $this->body->write('hi');
83
- $this->body->seek(0);
84
- $this->assertEquals('tehiing', (string) $this->body);
85
- }
86
-
87
- public function testSkipsOverwrittenBytes()
88
- {
89
- $decorated = Stream::factory(
90
- implode("\n", array_map(function ($n) {
91
- return str_pad($n, 4, '0', STR_PAD_LEFT);
92
- }, range(0, 25)))
93
- );
94
-
95
- $body = new CachingStream($decorated);
96
-
97
- $this->assertEquals("0000\n", Utils::readline($body));
98
- $this->assertEquals("0001\n", Utils::readline($body));
99
- // Write over part of the body yet to be read, so skip some bytes
100
- $this->assertEquals(5, $body->write("TEST\n"));
101
- $this->assertEquals(5, $this->readAttribute($body, 'skipReadBytes'));
102
- // Read, which skips bytes, then reads
103
- $this->assertEquals("0003\n", Utils::readline($body));
104
- $this->assertEquals(0, $this->readAttribute($body, 'skipReadBytes'));
105
- $this->assertEquals("0004\n", Utils::readline($body));
106
- $this->assertEquals("0005\n", Utils::readline($body));
107
-
108
- // Overwrite part of the cached body (so don't skip any bytes)
109
- $body->seek(5);
110
- $this->assertEquals(5, $body->write("ABCD\n"));
111
- $this->assertEquals(0, $this->readAttribute($body, 'skipReadBytes'));
112
- $this->assertEquals("TEST\n", Utils::readline($body));
113
- $this->assertEquals("0003\n", Utils::readline($body));
114
- $this->assertEquals("0004\n", Utils::readline($body));
115
- $this->assertEquals("0005\n", Utils::readline($body));
116
- $this->assertEquals("0006\n", Utils::readline($body));
117
- $this->assertEquals(5, $body->write("1234\n"));
118
- $this->assertEquals(5, $this->readAttribute($body, 'skipReadBytes'));
119
-
120
- // Seek to 0 and ensure the overwritten bit is replaced
121
- $body->seek(0);
122
- $this->assertEquals("0000\nABCD\nTEST\n0003\n0004\n0005\n0006\n1234\n0008\n0009\n", $body->read(50));
123
-
124
- // Ensure that casting it to a string does not include the bit that was overwritten
125
- $this->assertContains("0000\nABCD\nTEST\n0003\n0004\n0005\n0006\n1234\n0008\n0009\n", (string) $body);
126
- }
127
-
128
- public function testClosesBothStreams()
129
- {
130
- $s = fopen('php://temp', 'r');
131
- $a = Stream::factory($s);
132
- $d = new CachingStream($a);
133
- $d->close();
134
- $this->assertFalse(is_resource($s));
135
- }
136
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/DroppingStreamTest.php DELETED
@@ -1,26 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Stream;
3
-
4
- use GuzzleHttp\Stream\BufferStream;
5
- use GuzzleHttp\Stream\DroppingStream;
6
-
7
- class DroppingStreamTest extends \PHPUnit_Framework_TestCase
8
- {
9
- public function testBeginsDroppingWhenSizeExceeded()
10
- {
11
- $stream = new BufferStream();
12
- $drop = new DroppingStream($stream, 5);
13
- $this->assertEquals(3, $drop->write('hel'));
14
- $this->assertFalse($drop->write('lo'));
15
- $this->assertEquals(5, $drop->getSize());
16
- $this->assertEquals('hello', $drop->read(5));
17
- $this->assertEquals(0, $drop->getSize());
18
- $drop->write('12345678910');
19
- $this->assertEquals(5, $stream->getSize());
20
- $this->assertEquals(5, $drop->getSize());
21
- $this->assertEquals('12345', (string) $drop);
22
- $this->assertEquals(0, $drop->getSize());
23
- $drop->write('hello');
24
- $this->assertFalse($drop->write('test'));
25
- }
26
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/Exception/SeekExceptionTest.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Stream\Exception;
3
-
4
- use GuzzleHttp\Stream\Exception\SeekException;
5
- use GuzzleHttp\Stream\Stream;
6
-
7
- class SeekExceptionTest extends \PHPUnit_Framework_TestCase
8
- {
9
- public function testHasStream()
10
- {
11
- $s = Stream::factory('foo');
12
- $e = new SeekException($s, 10);
13
- $this->assertSame($s, $e->getStream());
14
- $this->assertContains('10', $e->getMessage());
15
- }
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/FnStreamTest.php DELETED
@@ -1,89 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Stream;
3
-
4
- use GuzzleHttp\Stream\Stream;
5
- use GuzzleHttp\Stream\FnStream;
6
-
7
- /**
8
- * @covers GuzzleHttp\Stream\FnStream
9
- */
10
- class FnStreamTest extends \PHPUnit_Framework_TestCase
11
- {
12
- /**
13
- * @expectedException \BadMethodCallException
14
- * @expectedExceptionMessage seek() is not implemented in the FnStream
15
- */
16
- public function testThrowsWhenNotImplemented()
17
- {
18
- (new FnStream([]))->seek(1);
19
- }
20
-
21
- public function testProxiesToFunction()
22
- {
23
- $s = new FnStream([
24
- 'read' => function ($len) {
25
- $this->assertEquals(3, $len);
26
- return 'foo';
27
- }
28
- ]);
29
-
30
- $this->assertEquals('foo', $s->read(3));
31
- }
32
-
33
- public function testCanCloseOnDestruct()
34
- {
35
- $called = false;
36
- $s = new FnStream([
37
- 'close' => function () use (&$called) {
38
- $called = true;
39
- }
40
- ]);
41
- unset($s);
42
- $this->assertTrue($called);
43
- }
44
-
45
- public function testDoesNotRequireClose()
46
- {
47
- $s = new FnStream([]);
48
- unset($s);
49
- }
50
-
51
- public function testDecoratesStream()
52
- {
53
- $a = Stream::factory('foo');
54
- $b = FnStream::decorate($a, []);
55
- $this->assertEquals(3, $b->getSize());
56
- $this->assertEquals($b->isWritable(), true);
57
- $this->assertEquals($b->isReadable(), true);
58
- $this->assertEquals($b->isSeekable(), true);
59
- $this->assertEquals($b->read(3), 'foo');
60
- $this->assertEquals($b->tell(), 3);
61
- $this->assertEquals($a->tell(), 3);
62
- $this->assertEquals($b->eof(), true);
63
- $this->assertEquals($a->eof(), true);
64
- $b->seek(0);
65
- $this->assertEquals('foo', (string) $b);
66
- $b->seek(0);
67
- $this->assertEquals('foo', $b->getContents());
68
- $this->assertEquals($a->getMetadata(), $b->getMetadata());
69
- $b->seek(0, SEEK_END);
70
- $b->write('bar');
71
- $this->assertEquals('foobar', (string) $b);
72
- $this->assertInternalType('resource', $b->detach());
73
- $b->close();
74
- }
75
-
76
- public function testDecoratesWithCustomizations()
77
- {
78
- $called = false;
79
- $a = Stream::factory('foo');
80
- $b = FnStream::decorate($a, [
81
- 'read' => function ($len) use (&$called, $a) {
82
- $called = true;
83
- return $a->read($len);
84
- }
85
- ]);
86
- $this->assertEquals('foo', $b->read(3));
87
- $this->assertTrue($called);
88
- }
89
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/GuzzleStreamWrapperTest.php DELETED
@@ -1,99 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Stream;
3
-
4
- use GuzzleHttp\Stream\GuzzleStreamWrapper;
5
- use GuzzleHttp\Stream\Stream;
6
-
7
- /**
8
- * @covers GuzzleHttp\Stream\GuzzleStreamWrapper
9
- */
10
- class GuzzleStreamWrapperTest extends \PHPUnit_Framework_TestCase
11
- {
12
- public function testResource()
13
- {
14
- $stream = Stream::factory('foo');
15
- $handle = GuzzleStreamWrapper::getResource($stream);
16
- $this->assertSame('foo', fread($handle, 3));
17
- $this->assertSame(3, ftell($handle));
18
- $this->assertSame(3, fwrite($handle, 'bar'));
19
- $this->assertSame(0, fseek($handle, 0));
20
- $this->assertSame('foobar', fread($handle, 6));
21
- $this->assertTrue(feof($handle));
22
-
23
- // This fails on HHVM for some reason
24
- if (!defined('HHVM_VERSION')) {
25
- $this->assertEquals([
26
- 'dev' => 0,
27
- 'ino' => 0,
28
- 'mode' => 33206,
29
- 'nlink' => 0,
30
- 'uid' => 0,
31
- 'gid' => 0,
32
- 'rdev' => 0,
33
- 'size' => 6,
34
- 'atime' => 0,
35
- 'mtime' => 0,
36
- 'ctime' => 0,
37
- 'blksize' => 0,
38
- 'blocks' => 0,
39
- 0 => 0,
40
- 1 => 0,
41
- 2 => 33206,
42
- 3 => 0,
43
- 4 => 0,
44
- 5 => 0,
45
- 6 => 0,
46
- 7 => 6,
47
- 8 => 0,
48
- 9 => 0,
49
- 10 => 0,
50
- 11 => 0,
51
- 12 => 0,
52
- ], fstat($handle));
53
- }
54
-
55
- $this->assertTrue(fclose($handle));
56
- $this->assertSame('foobar', (string) $stream);
57
- }
58
-
59
- /**
60
- * @expectedException \InvalidArgumentException
61
- */
62
- public function testValidatesStream()
63
- {
64
- $stream = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface')
65
- ->setMethods(['isReadable', 'isWritable'])
66
- ->getMockForAbstractClass();
67
- $stream->expects($this->once())
68
- ->method('isReadable')
69
- ->will($this->returnValue(false));
70
- $stream->expects($this->once())
71
- ->method('isWritable')
72
- ->will($this->returnValue(false));
73
- GuzzleStreamWrapper::getResource($stream);
74
- }
75
-
76
- /**
77
- * @expectedException \PHPUnit_Framework_Error_Warning
78
- */
79
- public function testReturnsFalseWhenStreamDoesNotExist()
80
- {
81
- fopen('guzzle://foo', 'r');
82
- }
83
-
84
- public function testCanOpenReadonlyStream()
85
- {
86
- $stream = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface')
87
- ->setMethods(['isReadable', 'isWritable'])
88
- ->getMockForAbstractClass();
89
- $stream->expects($this->once())
90
- ->method('isReadable')
91
- ->will($this->returnValue(false));
92
- $stream->expects($this->once())
93
- ->method('isWritable')
94
- ->will($this->returnValue(true));
95
- $r = GuzzleStreamWrapper::getResource($stream);
96
- $this->assertInternalType('resource', $r);
97
- fclose($r);
98
- }
99
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/InflateStreamTest.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Stream;
3
-
4
- use GuzzleHttp\Stream\InflateStream;
5
- use GuzzleHttp\Stream\Stream;
6
-
7
- class InflateStreamtest extends \PHPUnit_Framework_TestCase
8
- {
9
- public function testInflatesStreams()
10
- {
11
- $content = gzencode('test');
12
- $a = Stream::factory($content);
13
- $b = new InflateStream($a);
14
- $this->assertEquals('test', (string) $b);
15
- }
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/LazyOpenStreamTest.php DELETED
@@ -1,64 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Stream;
3
-
4
- use GuzzleHttp\Stream\LazyOpenStream;
5
-
6
- class LazyOpenStreamTest extends \PHPUnit_Framework_TestCase
7
- {
8
- private $fname;
9
-
10
- public function setup()
11
- {
12
- $this->fname = tempnam('/tmp', 'tfile');
13
-
14
- if (file_exists($this->fname)) {
15
- unlink($this->fname);
16
- }
17
- }
18
-
19
- public function tearDown()
20
- {
21
- if (file_exists($this->fname)) {
22
- unlink($this->fname);
23
- }
24
- }
25
-
26
- public function testOpensLazily()
27
- {
28
- $l = new LazyOpenStream($this->fname, 'w+');
29
- $l->write('foo');
30
- $this->assertInternalType('array', $l->getMetadata());
31
- $this->assertFileExists($this->fname);
32
- $this->assertEquals('foo', file_get_contents($this->fname));
33
- $this->assertEquals('foo', (string) $l);
34
- }
35
-
36
- public function testProxiesToFile()
37
- {
38
- file_put_contents($this->fname, 'foo');
39
- $l = new LazyOpenStream($this->fname, 'r');
40
- $this->assertEquals('foo', $l->read(4));
41
- $this->assertTrue($l->eof());
42
- $this->assertEquals(3, $l->tell());
43
- $this->assertTrue($l->isReadable());
44
- $this->assertTrue($l->isSeekable());
45
- $this->assertFalse($l->isWritable());
46
- $l->seek(1);
47
- $this->assertEquals('oo', $l->getContents());
48
- $this->assertEquals('foo', (string) $l);
49
- $this->assertEquals(3, $l->getSize());
50
- $this->assertInternalType('array', $l->getMetadata());
51
- $l->close();
52
- }
53
-
54
- public function testDetachesUnderlyingStream()
55
- {
56
- file_put_contents($this->fname, 'foo');
57
- $l = new LazyOpenStream($this->fname, 'r');
58
- $r = $l->detach();
59
- $this->assertInternalType('resource', $r);
60
- fseek($r, 0);
61
- $this->assertEquals('foo', stream_get_contents($r));
62
- fclose($r);
63
- }
64
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/LimitStreamTest.php DELETED
@@ -1,133 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Http;
3
-
4
- use GuzzleHttp\Stream\FnStream;
5
- use GuzzleHttp\Stream\Stream;
6
- use GuzzleHttp\Stream\LimitStream;
7
- use GuzzleHttp\Stream\NoSeekStream;
8
-
9
- /**
10
- * @covers GuzzleHttp\Stream\LimitStream
11
- */
12
- class LimitStreamTest extends \PHPUnit_Framework_TestCase
13
- {
14
- /** @var LimitStream */
15
- protected $body;
16
-
17
- /** @var Stream */
18
- protected $decorated;
19
-
20
- public function setUp()
21
- {
22
- $this->decorated = Stream::factory(fopen(__FILE__, 'r'));
23
- $this->body = new LimitStream($this->decorated, 10, 3);
24
- }
25
-
26
- public function testReturnsSubset()
27
- {
28
- $body = new LimitStream(Stream::factory('foo'), -1, 1);
29
- $this->assertEquals('oo', (string) $body);
30
- $this->assertTrue($body->eof());
31
- $body->seek(0);
32
- $this->assertFalse($body->eof());
33
- $this->assertEquals('oo', $body->read(100));
34
- $this->assertTrue($body->eof());
35
- }
36
-
37
- public function testReturnsSubsetWhenCastToString()
38
- {
39
- $body = Stream::factory('foo_baz_bar');
40
- $limited = new LimitStream($body, 3, 4);
41
- $this->assertEquals('baz', (string) $limited);
42
- }
43
-
44
- public function testReturnsSubsetOfEmptyBodyWhenCastToString()
45
- {
46
- $body = Stream::factory('');
47
- $limited = new LimitStream($body, 0, 10);
48
- $this->assertEquals('', (string) $limited);
49
- }
50
-
51
- public function testSeeksWhenConstructed()
52
- {
53
- $this->assertEquals(0, $this->body->tell());
54
- $this->assertEquals(3, $this->decorated->tell());
55
- }
56
-
57
- public function testAllowsBoundedSeek()
58
- {
59
- $this->assertEquals(true, $this->body->seek(100));
60
- $this->assertEquals(10, $this->body->tell());
61
- $this->assertEquals(13, $this->decorated->tell());
62
- $this->assertEquals(true, $this->body->seek(0));
63
- $this->assertEquals(0, $this->body->tell());
64
- $this->assertEquals(3, $this->decorated->tell());
65
- $this->assertEquals(false, $this->body->seek(-10));
66
- $this->assertEquals(0, $this->body->tell());
67
- $this->assertEquals(3, $this->decorated->tell());
68
- $this->assertEquals(true, $this->body->seek(5));
69
- $this->assertEquals(5, $this->body->tell());
70
- $this->assertEquals(8, $this->decorated->tell());
71
- $this->assertEquals(false, $this->body->seek(1000, SEEK_END));
72
- }
73
-
74
- public function testReadsOnlySubsetOfData()
75
- {
76
- $data = $this->body->read(100);
77
- $this->assertEquals(10, strlen($data));
78
- $this->assertFalse($this->body->read(1000));
79
-
80
- $this->body->setOffset(10);
81
- $newData = $this->body->read(100);
82
- $this->assertEquals(10, strlen($newData));
83
- $this->assertNotSame($data, $newData);
84
- }
85
-
86
- /**
87
- * @expectedException \GuzzleHttp\Stream\Exception\SeekException
88
- * @expectedExceptionMessage Could not seek the stream to position 2
89
- */
90
- public function testThrowsWhenCurrentGreaterThanOffsetSeek()
91
- {
92
- $a = Stream::factory('foo_bar');
93
- $b = new NoSeekStream($a);
94
- $c = new LimitStream($b);
95
- $a->getContents();
96
- $c->setOffset(2);
97
- }
98
-
99
- public function testClaimsConsumedWhenReadLimitIsReached()
100
- {
101
- $this->assertFalse($this->body->eof());
102
- $this->body->read(1000);
103
- $this->assertTrue($this->body->eof());
104
- }
105
-
106
- public function testContentLengthIsBounded()
107
- {
108
- $this->assertEquals(10, $this->body->getSize());
109
- }
110
-
111
- public function testGetContentsIsBasedOnSubset()
112
- {
113
- $body = new LimitStream(Stream::factory('foobazbar'), 3, 3);
114
- $this->assertEquals('baz', $body->getContents());
115
- }
116
-
117
- public function testReturnsNullIfSizeCannotBeDetermined()
118
- {
119
- $a = new FnStream([
120
- 'getSize' => function () { return null; },
121
- 'tell' => function () { return 0; },
122
- ]);
123
- $b = new LimitStream($a);
124
- $this->assertNull($b->getSize());
125
- }
126
-
127
- public function testLengthLessOffsetWhenNoLimitSize()
128
- {
129
- $a = Stream::factory('foo_bar');
130
- $b = new LimitStream($a, -1, 4);
131
- $this->assertEquals(3, $b->getSize());
132
- }
133
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/NoSeekStreamTest.php DELETED
@@ -1,41 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Stream;
3
-
4
- use GuzzleHttp\Stream\Stream;
5
- use GuzzleHttp\Stream\NoSeekStream;
6
-
7
- /**
8
- * @covers GuzzleHttp\Stream\NoSeekStream
9
- * @covers GuzzleHttp\Stream\StreamDecoratorTrait
10
- */
11
- class NoSeekStreamTest extends \PHPUnit_Framework_TestCase
12
- {
13
- public function testCannotSeek()
14
- {
15
- $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface')
16
- ->setMethods(['isSeekable', 'seek'])
17
- ->getMockForAbstractClass();
18
- $s->expects($this->never())->method('seek');
19
- $s->expects($this->never())->method('isSeekable');
20
- $wrapped = new NoSeekStream($s);
21
- $this->assertFalse($wrapped->isSeekable());
22
- $this->assertFalse($wrapped->seek(2));
23
- }
24
-
25
- public function testHandlesClose()
26
- {
27
- $s = Stream::factory('foo');
28
- $wrapped = new NoSeekStream($s);
29
- $wrapped->close();
30
- $this->assertFalse($wrapped->write('foo'));
31
- }
32
-
33
- public function testCanAttach()
34
- {
35
- $s1 = Stream::factory('foo');
36
- $s2 = Stream::factory('bar');
37
- $wrapped = new NoSeekStream($s1);
38
- $wrapped->attach($s2->detach());
39
- $this->assertEquals('bar', (string) $wrapped);
40
- }
41
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/NullStreamTest.php DELETED
@@ -1,39 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Stream;
3
-
4
- use GuzzleHttp\Stream\NullStream;
5
-
6
- class NullStreamTest extends \PHPUnit_Framework_TestCase
7
- {
8
- public function testDoesNothing()
9
- {
10
- $b = new NullStream();
11
- $this->assertEquals('', $b->read(10));
12
- $this->assertEquals(4, $b->write('test'));
13
- $this->assertEquals('', (string) $b);
14
- $this->assertNull($b->getMetadata('a'));
15
- $this->assertEquals([], $b->getMetadata());
16
- $this->assertEquals(0, $b->getSize());
17
- $this->assertEquals('', $b->getContents());
18
- $this->assertEquals(0, $b->tell());
19
-
20
- $this->assertTrue($b->isReadable());
21
- $this->assertTrue($b->isWritable());
22
- $this->assertTrue($b->isSeekable());
23
- $this->assertFalse($b->seek(10));
24
-
25
- $this->assertTrue($b->eof());
26
- $b->detach();
27
- $this->assertTrue($b->eof());
28
- $b->close();
29
- }
30
-
31
- /**
32
- * @expectedException \GuzzleHttp\Stream\Exception\CannotAttachException
33
- */
34
- public function testCannotAttach()
35
- {
36
- $p = new NullStream();
37
- $p->attach('a');
38
- }
39
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/PumpStreamTest.php DELETED
@@ -1,77 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Stream;
3
-
4
- use GuzzleHttp\Stream\LimitStream;
5
- use GuzzleHttp\Stream\PumpStream;
6
- use GuzzleHttp\Stream\Stream;
7
-
8
- class PumpStreamTest extends \PHPUnit_Framework_TestCase
9
- {
10
- public function testHasMetadataAndSize()
11
- {
12
- $p = new PumpStream(function () {}, [
13
- 'metadata' => ['foo' => 'bar'],
14
- 'size' => 100
15
- ]);
16
-
17
- $this->assertEquals('bar', $p->getMetadata('foo'));
18
- $this->assertEquals(['foo' => 'bar'], $p->getMetadata());
19
- $this->assertEquals(100, $p->getSize());
20
- }
21
-
22
- public function testCanReadFromCallable()
23
- {
24
- $p = Stream::factory(function ($size) {
25
- return 'a';
26
- });
27
- $this->assertEquals('a', $p->read(1));
28
- $this->assertEquals(1, $p->tell());
29
- $this->assertEquals('aaaaa', $p->read(5));
30
- $this->assertEquals(6, $p->tell());
31
- }
32
-
33
- public function testStoresExcessDataInBuffer()
34
- {
35
- $called = [];
36
- $p = Stream::factory(function ($size) use (&$called) {
37
- $called[] = $size;
38
- return 'abcdef';
39
- });
40
- $this->assertEquals('a', $p->read(1));
41
- $this->assertEquals('b', $p->read(1));
42
- $this->assertEquals('cdef', $p->read(4));
43
- $this->assertEquals('abcdefabc', $p->read(9));
44
- $this->assertEquals([1, 9, 3], $called);
45
- }
46
-
47
- public function testInifiniteStreamWrappedInLimitStream()
48
- {
49
- $p = Stream::factory(function () { return 'a'; });
50
- $s = new LimitStream($p, 5);
51
- $this->assertEquals('aaaaa', (string) $s);
52
- }
53
-
54
- public function testDescribesCapabilities()
55
- {
56
- $p = Stream::factory(function () {});
57
- $this->assertTrue($p->isReadable());
58
- $this->assertFalse($p->isSeekable());
59
- $this->assertFalse($p->isWritable());
60
- $this->assertNull($p->getSize());
61
- $this->assertFalse($p->write('aa'));
62
- $this->assertEquals('', $p->getContents());
63
- $this->assertEquals('', (string) $p);
64
- $p->close();
65
- $this->assertEquals('', $p->read(10));
66
- $this->assertTrue($p->eof());
67
- }
68
-
69
- /**
70
- * @expectedException \GuzzleHttp\Stream\Exception\CannotAttachException
71
- */
72
- public function testCannotAttach()
73
- {
74
- $p = Stream::factory(function () {});
75
- $p->attach('a');
76
- }
77
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/StreamDecoratorTraitTest.php DELETED
@@ -1,147 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Stream;
3
-
4
- use GuzzleHttp\Stream\StreamInterface;
5
- use GuzzleHttp\Stream\Stream;
6
- use GuzzleHttp\Stream\StreamDecoratorTrait;
7
-
8
- class Str implements StreamInterface
9
- {
10
- use StreamDecoratorTrait;
11
- }
12
-
13
- /**
14
- * @covers GuzzleHttp\Stream\StreamDecoratorTrait
15
- */
16
- class StreamDecoratorTraitTest extends \PHPUnit_Framework_TestCase
17
- {
18
- private $a;
19
- private $b;
20
- private $c;
21
-
22
- public function setUp()
23
- {
24
- $this->c = fopen('php://temp', 'r+');
25
- fwrite($this->c, 'foo');
26
- fseek($this->c, 0);
27
- $this->a = Stream::factory($this->c);
28
- $this->b = new Str($this->a);
29
- }
30
-
31
- public function testCatchesExceptionsWhenCastingToString()
32
- {
33
- $s = $this->getMockBuilder('GuzzleHttp\Stream\StreamInterface')
34
- ->setMethods(['read'])
35
- ->getMockForAbstractClass();
36
- $s->expects($this->once())
37
- ->method('read')
38
- ->will($this->throwException(new \Exception('foo')));
39
- $msg = '';
40
- set_error_handler(function ($errNo, $str) use (&$msg) { $msg = $str; });
41
- echo new Str($s);
42
- restore_error_handler();
43
- $this->assertContains('foo', $msg);
44
- }
45
-
46
- public function testToString()
47
- {
48
- $this->assertEquals('foo', (string) $this->b);
49
- }
50
-
51
- public function testHasSize()
52
- {
53
- $this->assertEquals(3, $this->b->getSize());
54
- $this->assertSame($this->b, $this->b->setSize(2));
55
- $this->assertEquals(2, $this->b->getSize());
56
- }
57
-
58
- public function testReads()
59
- {
60
- $this->assertEquals('foo', $this->b->read(10));
61
- }
62
-
63
- public function testCheckMethods()
64
- {
65
- $this->assertEquals($this->a->isReadable(), $this->b->isReadable());
66
- $this->assertEquals($this->a->isWritable(), $this->b->isWritable());
67
- $this->assertEquals($this->a->isSeekable(), $this->b->isSeekable());
68
- }
69
-
70
- public function testSeeksAndTells()
71
- {
72
- $this->assertTrue($this->b->seek(1));
73
- $this->assertEquals(1, $this->a->tell());
74
- $this->assertEquals(1, $this->b->tell());
75
- $this->assertTrue($this->b->seek(0));
76
- $this->assertEquals(0, $this->a->tell());
77
- $this->assertEquals(0, $this->b->tell());
78
- $this->assertTrue($this->b->seek(0, SEEK_END));
79
- $this->assertEquals(3, $this->a->tell());
80
- $this->assertEquals(3, $this->b->tell());
81
- }
82
-
83
- public function testGetsContents()
84
- {
85
- $this->assertEquals('foo', $this->b->getContents());
86
- $this->assertEquals('', $this->b->getContents());
87
- $this->b->seek(1);
88
- $this->assertEquals('oo', $this->b->getContents(1));
89
- }
90
-
91
- public function testCloses()
92
- {
93
- $this->b->close();
94
- $this->assertFalse(is_resource($this->c));
95
- }
96
-
97
- public function testDetaches()
98
- {
99
- $this->b->detach();
100
- $this->assertFalse($this->b->isReadable());
101
- }
102
-
103
- /**
104
- * @expectedException \GuzzleHttp\Stream\Exception\CannotAttachException
105
- */
106
- public function testCannotAttachByDefault()
107
- {
108
- $this->b->attach('a');
109
- }
110
-
111
- public function testWrapsMetadata()
112
- {
113
- $this->assertSame($this->b->getMetadata(), $this->a->getMetadata());
114
- $this->assertSame($this->b->getMetadata('uri'), $this->a->getMetadata('uri'));
115
- }
116
-
117
- public function testWrapsWrites()
118
- {
119
- $this->b->seek(0, SEEK_END);
120
- $this->b->write('foo');
121
- $this->assertEquals('foofoo', (string) $this->a);
122
- }
123
-
124
- /**
125
- * @expectedException \UnexpectedValueException
126
- */
127
- public function testThrowsWithInvalidGetter()
128
- {
129
- $this->b->foo;
130
- }
131
-
132
- /**
133
- * @expectedException \BadMethodCallException
134
- */
135
- public function testThrowsWhenGetterNotImplemented()
136
- {
137
- $s = new BadStream();
138
- $s->stream;
139
- }
140
- }
141
-
142
- class BadStream
143
- {
144
- use StreamDecoratorTrait;
145
-
146
- public function __construct() {}
147
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/StreamTest.php DELETED
@@ -1,252 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Stream;
3
-
4
- use GuzzleHttp\Stream\Stream;
5
-
6
- /**
7
- * @covers GuzzleHttp\Stream\Stream
8
- */
9
- class StreamTest extends \PHPUnit_Framework_TestCase
10
- {
11
- /**
12
- * @expectedException \InvalidArgumentException
13
- */
14
- public function testConstructorThrowsExceptionOnInvalidArgument()
15
- {
16
- new Stream(true);
17
- }
18
-
19
- public function testConstructorInitializesProperties()
20
- {
21
- $handle = fopen('php://temp', 'r+');
22
- fwrite($handle, 'data');
23
- $stream = new Stream($handle);
24
- $this->assertTrue($stream->isReadable());
25
- $this->assertTrue($stream->isWritable());
26
- $this->assertTrue($stream->isSeekable());
27
- $this->assertEquals('php://temp', $stream->getMetadata('uri'));
28
- $this->assertInternalType('array', $stream->getMetadata());
29
- $this->assertEquals(4, $stream->getSize());
30
- $this->assertFalse($stream->eof());
31
- $stream->close();
32
- }
33
-
34
- public function testStreamClosesHandleOnDestruct()
35
- {
36
- $handle = fopen('php://temp', 'r');
37
- $stream = new Stream($handle);
38
- unset($stream);
39
- $this->assertFalse(is_resource($handle));
40
- }
41
-
42
- public function testConvertsToString()
43
- {
44
- $handle = fopen('php://temp', 'w+');
45
- fwrite($handle, 'data');
46
- $stream = new Stream($handle);
47
- $this->assertEquals('data', (string) $stream);
48
- $this->assertEquals('data', (string) $stream);
49
- $stream->close();
50
- }
51
-
52
- public function testGetsContents()
53
- {
54
- $handle = fopen('php://temp', 'w+');
55
- fwrite($handle, 'data');
56
- $stream = new Stream($handle);
57
- $this->assertEquals('', $stream->getContents());
58
- $stream->seek(0);
59
- $this->assertEquals('data', $stream->getContents());
60
- $this->assertEquals('', $stream->getContents());
61
- }
62
-
63
- public function testChecksEof()
64
- {
65
- $handle = fopen('php://temp', 'w+');
66
- fwrite($handle, 'data');
67
- $stream = new Stream($handle);
68
- $this->assertFalse($stream->eof());
69
- $stream->read(4);
70
- $this->assertTrue($stream->eof());
71
- $stream->close();
72
- }
73
-
74
- public function testAllowsSettingManualSize()
75
- {
76
- $handle = fopen('php://temp', 'w+');
77
- fwrite($handle, 'data');
78
- $stream = new Stream($handle);
79
- $stream->setSize(10);
80
- $this->assertEquals(10, $stream->getSize());
81
- $stream->close();
82
- }
83
-
84
- public function testGetSize()
85
- {
86
- $size = filesize(__FILE__);
87
- $handle = fopen(__FILE__, 'r');
88
- $stream = new Stream($handle);
89
- $this->assertEquals($size, $stream->getSize());
90
- // Load from cache
91
- $this->assertEquals($size, $stream->getSize());
92
- $stream->close();
93
- }
94
-
95
- public function testEnsuresSizeIsConsistent()
96
- {
97
- $h = fopen('php://temp', 'w+');
98
- $this->assertEquals(3, fwrite($h, 'foo'));
99
- $stream = new Stream($h);
100
- $this->assertEquals(3, $stream->getSize());
101
- $this->assertEquals(4, $stream->write('test'));
102
- $this->assertEquals(7, $stream->getSize());
103
- $this->assertEquals(7, $stream->getSize());
104
- $stream->close();
105
- }
106
-
107
- public function testProvidesStreamPosition()
108
- {
109
- $handle = fopen('php://temp', 'w+');
110
- $stream = new Stream($handle);
111
- $this->assertEquals(0, $stream->tell());
112
- $stream->write('foo');
113
- $this->assertEquals(3, $stream->tell());
114
- $stream->seek(1);
115
- $this->assertEquals(1, $stream->tell());
116
- $this->assertSame(ftell($handle), $stream->tell());
117
- $stream->close();
118
- }
119
-
120
- public function testKeepsPositionOfResource()
121
- {
122
- $h = fopen(__FILE__, 'r');
123
- fseek($h, 10);
124
- $stream = Stream::factory($h);
125
- $this->assertEquals(10, $stream->tell());
126
- $stream->close();
127
- }
128
-
129
- public function testCanDetachAndAttachStream()
130
- {
131
- $r = fopen('php://temp', 'w+');
132
- $stream = new Stream($r);
133
- $stream->write('foo');
134
- $this->assertTrue($stream->isReadable());
135
- $this->assertSame($r, $stream->detach());
136
- $this->assertNull($stream->detach());
137
-
138
- $this->assertFalse($stream->isReadable());
139
- $this->assertFalse($stream->read(10));
140
- $this->assertFalse($stream->isWritable());
141
- $this->assertFalse($stream->write('bar'));
142
- $this->assertFalse($stream->isSeekable());
143
- $this->assertFalse($stream->seek(10));
144
- $this->assertFalse($stream->tell());
145
- $this->assertTrue($stream->eof());
146
- $this->assertNull($stream->getSize());
147
- $this->assertSame('', (string) $stream);
148
- $this->assertSame('', $stream->getContents());
149
-
150
- $stream->attach($r);
151
- $stream->seek(0);
152
- $this->assertEquals('foo', $stream->getContents());
153
- $this->assertTrue($stream->isReadable());
154
- $this->assertTrue($stream->isWritable());
155
- $this->assertTrue($stream->isSeekable());
156
-
157
- $stream->close();
158
- }
159
-
160
- public function testCloseClearProperties()
161
- {
162
- $handle = fopen('php://temp', 'r+');
163
- $stream = new Stream($handle);
164
- $stream->close();
165
-
166
- $this->assertEmpty($stream->getMetadata());
167
- $this->assertFalse($stream->isSeekable());
168
- $this->assertFalse($stream->isReadable());
169
- $this->assertFalse($stream->isWritable());
170
- $this->assertNull($stream->getSize());
171
- }
172
-
173
- public function testCreatesWithFactory()
174
- {
175
- $stream = Stream::factory('foo');
176
- $this->assertInstanceOf('GuzzleHttp\Stream\Stream', $stream);
177
- $this->assertEquals('foo', $stream->getContents());
178
- $stream->close();
179
- }
180
-
181
- public function testFactoryCreatesFromEmptyString()
182
- {
183
- $s = Stream::factory();
184
- $this->assertInstanceOf('GuzzleHttp\Stream\Stream', $s);
185
- }
186
-
187
- public function testFactoryCreatesFromResource()
188
- {
189
- $r = fopen(__FILE__, 'r');
190
- $s = Stream::factory($r);
191
- $this->assertInstanceOf('GuzzleHttp\Stream\Stream', $s);
192
- $this->assertSame(file_get_contents(__FILE__), (string) $s);
193
- }
194
-
195
- public function testFactoryCreatesFromObjectWithToString()
196
- {
197
- $r = new HasToString();
198
- $s = Stream::factory($r);
199
- $this->assertInstanceOf('GuzzleHttp\Stream\Stream', $s);
200
- $this->assertEquals('foo', (string) $s);
201
- }
202
-
203
- public function testCreatePassesThrough()
204
- {
205
- $s = Stream::factory('foo');
206
- $this->assertSame($s, Stream::factory($s));
207
- }
208
-
209
- /**
210
- * @expectedException \InvalidArgumentException
211
- */
212
- public function testThrowsExceptionForUnknown()
213
- {
214
- Stream::factory(new \stdClass());
215
- }
216
-
217
- public function testReturnsCustomMetadata()
218
- {
219
- $s = Stream::factory('foo', ['metadata' => ['hwm' => 3]]);
220
- $this->assertEquals(3, $s->getMetadata('hwm'));
221
- $this->assertArrayHasKey('hwm', $s->getMetadata());
222
- }
223
-
224
- public function testCanSetSize()
225
- {
226
- $s = Stream::factory('', ['size' => 10]);
227
- $this->assertEquals(10, $s->getSize());
228
- }
229
-
230
- public function testCanCreateIteratorBasedStream()
231
- {
232
- $a = new \ArrayIterator(['foo', 'bar', '123']);
233
- $p = Stream::factory($a);
234
- $this->assertInstanceOf('GuzzleHttp\Stream\PumpStream', $p);
235
- $this->assertEquals('foo', $p->read(3));
236
- $this->assertFalse($p->eof());
237
- $this->assertEquals('b', $p->read(1));
238
- $this->assertEquals('a', $p->read(1));
239
- $this->assertEquals('r12', $p->read(3));
240
- $this->assertFalse($p->eof());
241
- $this->assertEquals('3', $p->getContents());
242
- $this->assertTrue($p->eof());
243
- $this->assertEquals(9, $p->tell());
244
- }
245
- }
246
-
247
- class HasToString
248
- {
249
- public function __toString() {
250
- return 'foo';
251
- }
252
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/guzzlehttp/streams/tests/UtilsTest.php DELETED
@@ -1,155 +0,0 @@
1
- <?php
2
- namespace GuzzleHttp\Tests\Stream;
3
-
4
- use GuzzleHttp\Stream\FnStream;
5
- use GuzzleHttp\Stream\NoSeekStream;
6
- use GuzzleHttp\Stream\Stream;
7
- use GuzzleHttp\Stream\Utils;
8
-
9
- class UtilsTest extends \PHPUnit_Framework_TestCase
10
- {
11
- public function testCopiesToString()
12
- {
13
- $s = Stream::factory('foobaz');
14
- $this->assertEquals('foobaz', Utils::copyToString($s));
15
- $s->seek(0);
16
- $this->assertEquals('foo', Utils::copyToString($s, 3));
17
- $this->assertEquals('baz', Utils::copyToString($s, 3));
18
- $this->assertEquals('', Utils::copyToString($s));
19
- }
20
-
21
- public function testCopiesToStringStopsWhenReadFails()
22
- {
23
- $s1 = Stream::factory('foobaz');
24
- $s1 = FnStream::decorate($s1, [
25
- 'read' => function () {
26
- return false;
27
- }
28
- ]);
29
- $result = Utils::copyToString($s1);
30
- $this->assertEquals('', $result);
31
- }
32
-
33
- public function testCopiesToStream()
34
- {
35
- $s1 = Stream::factory('foobaz');
36
- $s2 = Stream::factory('');
37
- Utils::copyToStream($s1, $s2);
38
- $this->assertEquals('foobaz', (string) $s2);
39
- $s2 = Stream::factory('');
40
- $s1->seek(0);
41
- Utils::copyToStream($s1, $s2, 3);
42
- $this->assertEquals('foo', (string) $s2);
43
- Utils::copyToStream($s1, $s2, 3);
44
- $this->assertEquals('foobaz', (string) $s2);
45
- }
46
-
47
- public function testStopsCopyToStreamWhenWriteFails()
48
- {
49
- $s1 = Stream::factory('foobaz');
50
- $s2 = Stream::factory('');
51
- $s2 = FnStream::decorate($s2, ['write' => function () { return 0; }]);
52
- Utils::copyToStream($s1, $s2);
53
- $this->assertEquals('', (string) $s2);
54
- }
55
-
56
- public function testStopsCopyToSteamWhenWriteFailsWithMaxLen()
57
- {
58
- $s1 = Stream::factory('foobaz');
59
- $s2 = Stream::factory('');
60
- $s2 = FnStream::decorate($s2, ['write' => function () { return 0; }]);
61
- Utils::copyToStream($s1, $s2, 10);
62
- $this->assertEquals('', (string) $s2);
63
- }
64
-
65
- public function testStopsCopyToSteamWhenReadFailsWithMaxLen()
66
- {
67
- $s1 = Stream::factory('foobaz');
68
- $s1 = FnStream::decorate($s1, ['read' => function () { return ''; }]);
69
- $s2 = Stream::factory('');
70
- Utils::copyToStream($s1, $s2, 10);
71
- $this->assertEquals('', (string) $s2);
72
- }
73
-
74
- public function testReadsLines()
75
- {
76
- $s = Stream::factory("foo\nbaz\nbar");
77
- $this->assertEquals("foo\n", Utils::readline($s));
78
- $this->assertEquals("baz\n", Utils::readline($s));
79
- $this->assertEquals("bar", Utils::readline($s));
80
- }
81
-
82
- public function testReadsLinesUpToMaxLength()
83
- {
84
- $s = Stream::factory("12345\n");
85
- $this->assertEquals("123", Utils::readline($s, 4));
86
- $this->assertEquals("45\n", Utils::readline($s));
87
- }
88
-
89
- public function testReadsLineUntilFalseReturnedFromRead()
90
- {
91
- $s = $this->getMockBuilder('GuzzleHttp\Stream\Stream')
92
- ->setMethods(['read', 'eof'])
93
- ->disableOriginalConstructor()
94
- ->getMock();
95
- $s->expects($this->exactly(2))
96
- ->method('read')
97
- ->will($this->returnCallback(function () {
98
- static $c = false;
99
- if ($c) {
100
- return false;
101
- }
102
- $c = true;
103
- return 'h';
104
- }));
105
- $s->expects($this->exactly(2))
106
- ->method('eof')
107
- ->will($this->returnValue(false));
108
- $this->assertEquals("h", Utils::readline($s));
109
- }
110
-
111
- public function testCalculatesHash()
112
- {
113
- $s = Stream::factory('foobazbar');
114
- $this->assertEquals(md5('foobazbar'), Utils::hash($s, 'md5'));
115
- }
116
-
117
- /**
118
- * @expectedException \GuzzleHttp\Stream\Exception\SeekException
119
- */
120
- public function testCalculatesHashThrowsWhenSeekFails()
121
- {
122
- $s = new NoSeekStream(Stream::factory('foobazbar'));
123
- $s->read(2);
124
- Utils::hash($s, 'md5');
125
- }
126
-
127
- public function testCalculatesHashSeeksToOriginalPosition()
128
- {
129
- $s = Stream::factory('foobazbar');
130
- $s->seek(4);
131
- $this->assertEquals(md5('foobazbar'), Utils::hash($s, 'md5'));
132
- $this->assertEquals(4, $s->tell());
133
- }
134
-
135
- public function testOpensFilesSuccessfully()
136
- {
137
- $r = Utils::open(__FILE__, 'r');
138
- $this->assertInternalType('resource', $r);
139
- fclose($r);
140
- }
141
-
142
- /**
143
- * @expectedException \RuntimeException
144
- * @expectedExceptionMessage Unable to open /path/to/does/not/exist using mode r
145
- */
146
- public function testThrowsExceptionNotWarning()
147
- {
148
- Utils::open('/path/to/does/not/exist', 'r');
149
- }
150
-
151
- public function testProxiesToFactory()
152
- {
153
- $this->assertEquals('foo', (string) Utils::create('foo'));
154
- }
155
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/phpunit.xml.dist DELETED
@@ -1,25 +0,0 @@
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/bootstrap.php"
13
- >
14
- <testsuites>
15
- <testsuite name="Promise Test Suite">
16
- <directory>./tests/</directory>
17
- </testsuite>
18
- </testsuites>
19
-
20
- <filter>
21
- <whitelist>
22
- <directory>./src/</directory>
23
- </whitelist>
24
- </filter>
25
- </phpunit>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/DeferredTest.php DELETED
@@ -1,42 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise;
4
-
5
- use React\Promise\PromiseAdapter\CallbackPromiseAdapter;
6
-
7
- class DeferredTest extends TestCase
8
- {
9
- use PromiseTest\FullTestTrait;
10
-
11
- public function getPromiseTestAdapter(callable $canceller = null)
12
- {
13
- $d = new Deferred($canceller);
14
-
15
- return new CallbackPromiseAdapter([
16
- 'promise' => [$d, 'promise'],
17
- 'resolve' => [$d, 'resolve'],
18
- 'reject' => [$d, 'reject'],
19
- 'notify' => [$d, 'progress'],
20
- 'settle' => [$d, 'resolve'],
21
- ]);
22
- }
23
-
24
- /** @test */
25
- public function progressIsAnAliasForNotify()
26
- {
27
- $deferred = new Deferred();
28
-
29
- $sentinel = new \stdClass();
30
-
31
- $mock = $this->createCallableMock();
32
- $mock
33
- ->expects($this->once())
34
- ->method('__invoke')
35
- ->with($sentinel);
36
-
37
- $deferred->promise()
38
- ->then($this->expectCallableNever(), $this->expectCallableNever(), $mock);
39
-
40
- $deferred->progress($sentinel);
41
- }
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/FulfilledPromiseTest.php DELETED
@@ -1,50 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise;
4
-
5
- use React\Promise\PromiseAdapter\CallbackPromiseAdapter;
6
-
7
- class FulfilledPromiseTest extends TestCase
8
- {
9
- use PromiseTest\PromiseSettledTestTrait,
10
- PromiseTest\PromiseFulfilledTestTrait;
11
-
12
- public function getPromiseTestAdapter(callable $canceller = null)
13
- {
14
- $promise = null;
15
-
16
- return new CallbackPromiseAdapter([
17
- 'promise' => function () use (&$promise) {
18
- if (!$promise) {
19
- throw new \LogicException('FulfilledPromise must be resolved before obtaining the promise');
20
- }
21
-
22
- return $promise;
23
- },
24
- 'resolve' => function ($value = null) use (&$promise) {
25
- if (!$promise) {
26
- $promise = new FulfilledPromise($value);
27
- }
28
- },
29
- 'reject' => function () {
30
- throw new \LogicException('You cannot call reject() for React\Promise\FulfilledPromise');
31
- },
32
- 'notify' => function () {
33
- // no-op
34
- },
35
- 'settle' => function ($value = null) use (&$promise) {
36
- if (!$promise) {
37
- $promise = new FulfilledPromise($value);
38
- }
39
- },
40
- ]);
41
- }
42
-
43
- /** @test */
44
- public function shouldThrowExceptionIfConstructedWithAPromise()
45
- {
46
- $this->setExpectedException('\InvalidArgumentException');
47
-
48
- return new FulfilledPromise(new FulfilledPromise());
49
- }
50
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/FunctionAllTest.php DELETED
@@ -1,97 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise;
4
-
5
- class FunctionAllTest extends TestCase
6
- {
7
- /** @test */
8
- public function shouldResolveEmptyInput()
9
- {
10
- $mock = $this->createCallableMock();
11
- $mock
12
- ->expects($this->once())
13
- ->method('__invoke')
14
- ->with($this->identicalTo([]));
15
-
16
- all([])
17
- ->then($mock);
18
- }
19
-
20
- /** @test */
21
- public function shouldResolveValuesArray()
22
- {
23
- $mock = $this->createCallableMock();
24
- $mock
25
- ->expects($this->once())
26
- ->method('__invoke')
27
- ->with($this->identicalTo([1, 2, 3]));
28
-
29
- all([1, 2, 3])
30
- ->then($mock);
31
- }
32
-
33
- /** @test */
34
- public function shouldResolvePromisesArray()
35
- {
36
- $mock = $this->createCallableMock();
37
- $mock
38
- ->expects($this->once())
39
- ->method('__invoke')
40
- ->with($this->identicalTo([1, 2, 3]));
41
-
42
- all([resolve(1), resolve(2), resolve(3)])
43
- ->then($mock);
44
- }
45
-
46
- /** @test */
47
- public function shouldResolveSparseArrayInput()
48
- {
49
- $mock = $this->createCallableMock();
50
- $mock
51
- ->expects($this->once())
52
- ->method('__invoke')
53
- ->with($this->identicalTo([null, 1, null, 1, 1]));
54
-
55
- all([null, 1, null, 1, 1])
56
- ->then($mock);
57
- }
58
-
59
- /** @test */
60
- public function shouldRejectIfAnyInputPromiseRejects()
61
- {
62
- $mock = $this->createCallableMock();
63
- $mock
64
- ->expects($this->once())
65
- ->method('__invoke')
66
- ->with($this->identicalTo(2));
67
-
68
- all([resolve(1), reject(2), resolve(3)])
69
- ->then($this->expectCallableNever(), $mock);
70
- }
71
-
72
- /** @test */
73
- public function shouldAcceptAPromiseForAnArray()
74
- {
75
- $mock = $this->createCallableMock();
76
- $mock
77
- ->expects($this->once())
78
- ->method('__invoke')
79
- ->with($this->identicalTo([1, 2, 3]));
80
-
81
- all(resolve([1, 2, 3]))
82
- ->then($mock);
83
- }
84
-
85
- /** @test */
86
- public function shouldResolveToEmptyArrayWhenInputPromiseDoesNotResolveToArray()
87
- {
88
- $mock = $this->createCallableMock();
89
- $mock
90
- ->expects($this->once())
91
- ->method('__invoke')
92
- ->with($this->identicalTo([]));
93
-
94
- all(resolve(1))
95
- ->then($mock);
96
- }
97
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/FunctionAnyTest.php DELETED
@@ -1,116 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise;
4
-
5
- class FunctionAnyTest extends TestCase
6
- {
7
- /** @test */
8
- public function shouldResolveToNullWithEmptyInputArray()
9
- {
10
- $mock = $this->createCallableMock();
11
- $mock
12
- ->expects($this->once())
13
- ->method('__invoke')
14
- ->with($this->identicalTo(null));
15
-
16
- any([])
17
- ->then($mock);
18
- }
19
-
20
- /** @test */
21
- public function shouldResolveWithAnInputValue()
22
- {
23
- $mock = $this->createCallableMock();
24
- $mock
25
- ->expects($this->once())
26
- ->method('__invoke')
27
- ->with($this->identicalTo(1));
28
-
29
- any([1, 2, 3])
30
- ->then($mock);
31
- }
32
-
33
- /** @test */
34
- public function shouldResolveWithAPromisedInputValue()
35
- {
36
- $mock = $this->createCallableMock();
37
- $mock
38
- ->expects($this->once())
39
- ->method('__invoke')
40
- ->with($this->identicalTo(1));
41
-
42
- any([resolve(1), resolve(2), resolve(3)])
43
- ->then($mock);
44
- }
45
-
46
- /** @test */
47
- public function shouldRejectWithAllRejectedInputValuesIfAllInputsAreRejected()
48
- {
49
- $mock = $this->createCallableMock();
50
- $mock
51
- ->expects($this->once())
52
- ->method('__invoke')
53
- ->with($this->identicalTo([0 => 1, 1 => 2, 2 => 3]));
54
-
55
- any([reject(1), reject(2), reject(3)])
56
- ->then($this->expectCallableNever(), $mock);
57
- }
58
-
59
- /** @test */
60
- public function shouldResolveWhenFirstInputPromiseResolves()
61
- {
62
- $mock = $this->createCallableMock();
63
- $mock
64
- ->expects($this->once())
65
- ->method('__invoke')
66
- ->with($this->identicalTo(1));
67
-
68
- any([resolve(1), reject(2), reject(3)])
69
- ->then($mock);
70
- }
71
-
72
- /** @test */
73
- public function shouldAcceptAPromiseForAnArray()
74
- {
75
- $mock = $this->createCallableMock();
76
- $mock
77
- ->expects($this->once())
78
- ->method('__invoke')
79
- ->with($this->identicalTo(1));
80
-
81
- any(resolve([1, 2, 3]))
82
- ->then($mock);
83
- }
84
-
85
- /** @test */
86
- public function shouldResolveToNullArrayWhenInputPromiseDoesNotResolveToArray()
87
- {
88
- $mock = $this->createCallableMock();
89
- $mock
90
- ->expects($this->once())
91
- ->method('__invoke')
92
- ->with($this->identicalTo(null));
93
-
94
- any(resolve(1))
95
- ->then($mock);
96
- }
97
-
98
- /** @test */
99
- public function shouldNotRelyOnArryIndexesWhenUnwrappingToASingleResolutionValue()
100
- {
101
- $mock = $this->createCallableMock();
102
- $mock
103
- ->expects($this->once())
104
- ->method('__invoke')
105
- ->with($this->identicalTo(2));
106
-
107
- $d1 = new Deferred();
108
- $d2 = new Deferred();
109
-
110
- any(['abc' => $d1->promise(), 1 => $d2->promise()])
111
- ->then($mock);
112
-
113
- $d2->resolve(2);
114
- $d1->resolve(1);
115
- }
116
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/FunctionCheckTypehintTest.php DELETED
@@ -1,118 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise;
4
-
5
- class FunctionCheckTypehintTest extends TestCase
6
- {
7
- /** @test */
8
- public function shouldAcceptClosureCallbackWithTypehint()
9
- {
10
- $this->assertTrue(_checkTypehint(function (\InvalidArgumentException $e) {
11
- }, new \InvalidArgumentException()));
12
- $this->assertfalse(_checkTypehint(function (\InvalidArgumentException $e) {
13
- }, new \Exception()));
14
- }
15
-
16
- /** @test */
17
- public function shouldAcceptFunctionStringCallbackWithTypehint()
18
- {
19
- $this->assertTrue(_checkTypehint('React\Promise\testCallbackWithTypehint', new \InvalidArgumentException()));
20
- $this->assertfalse(_checkTypehint('React\Promise\testCallbackWithTypehint', new \Exception()));
21
- }
22
-
23
- /** @test */
24
- public function shouldAcceptInvokableObjectCallbackWithTypehint()
25
- {
26
- $this->assertTrue(_checkTypehint(new TestCallbackWithTypehintClass(), new \InvalidArgumentException()));
27
- $this->assertfalse(_checkTypehint(new TestCallbackWithTypehintClass(), new \Exception()));
28
- }
29
-
30
- /** @test */
31
- public function shouldAcceptObjectMethodCallbackWithTypehint()
32
- {
33
- $this->assertTrue(_checkTypehint([new TestCallbackWithTypehintClass(), 'testCallback'], new \InvalidArgumentException()));
34
- $this->assertfalse(_checkTypehint([new TestCallbackWithTypehintClass(), 'testCallback'], new \Exception()));
35
- }
36
-
37
- /** @test */
38
- public function shouldAcceptStaticClassCallbackWithTypehint()
39
- {
40
- $this->assertTrue(_checkTypehint(['React\Promise\TestCallbackWithTypehintClass', 'testCallbackStatic'], new \InvalidArgumentException()));
41
- $this->assertfalse(_checkTypehint(['React\Promise\TestCallbackWithTypehintClass', 'testCallbackStatic'], new \Exception()));
42
- }
43
-
44
- /** @test */
45
- public function shouldAcceptClosureCallbackWithoutTypehint()
46
- {
47
- $this->assertTrue(_checkTypehint(function (\InvalidArgumentException $e) {
48
- }, new \InvalidArgumentException()));
49
- }
50
-
51
- /** @test */
52
- public function shouldAcceptFunctionStringCallbackWithoutTypehint()
53
- {
54
- $this->assertTrue(_checkTypehint('React\Promise\testCallbackWithoutTypehint', new \InvalidArgumentException()));
55
- }
56
-
57
- /** @test */
58
- public function shouldAcceptInvokableObjectCallbackWithoutTypehint()
59
- {
60
- $this->assertTrue(_checkTypehint(new TestCallbackWithoutTypehintClass(), new \InvalidArgumentException()));
61
- }
62
-
63
- /** @test */
64
- public function shouldAcceptObjectMethodCallbackWithoutTypehint()
65
- {
66
- $this->assertTrue(_checkTypehint([new TestCallbackWithoutTypehintClass(), 'testCallback'], new \InvalidArgumentException()));
67
- }
68
-
69
- /** @test */
70
- public function shouldAcceptStaticClassCallbackWithoutTypehint()
71
- {
72
- $this->assertTrue(_checkTypehint(['React\Promise\TestCallbackWithoutTypehintClass', 'testCallbackStatic'], new \InvalidArgumentException()));
73
- }
74
- }
75
-
76
- function testCallbackWithTypehint(\InvalidArgumentException $e)
77
- {
78
- }
79
-
80
- function testCallbackWithoutTypehint()
81
- {
82
- }
83
-
84
- class TestCallbackWithTypehintClass
85
- {
86
- public function __invoke(\InvalidArgumentException $e)
87
- {
88
-
89
- }
90
-
91
- public function testCallback(\InvalidArgumentException $e)
92
- {
93
-
94
- }
95
-
96
- public static function testCallbackStatic(\InvalidArgumentException $e)
97
- {
98
-
99
- }
100
- }
101
-
102
- class TestCallbackWithoutTypehintClass
103
- {
104
- public function __invoke()
105
- {
106
-
107
- }
108
-
109
- public function testCallback()
110
- {
111
-
112
- }
113
-
114
- public static function testCallbackStatic()
115
- {
116
-
117
- }
118
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/FunctionMapTest.php DELETED
@@ -1,125 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise;
4
-
5
- class FunctionMapTest extends TestCase
6
- {
7
- protected function mapper()
8
- {
9
- return function ($val) {
10
- return $val * 2;
11
- };
12
- }
13
-
14
- protected function promiseMapper()
15
- {
16
- return function ($val) {
17
- return resolve($val * 2);
18
- };
19
- }
20
-
21
- /** @test */
22
- public function shouldMapInputValuesArray()
23
- {
24
- $mock = $this->createCallableMock();
25
- $mock
26
- ->expects($this->once())
27
- ->method('__invoke')
28
- ->with($this->identicalTo([2, 4, 6]));
29
-
30
- map(
31
- [1, 2, 3],
32
- $this->mapper()
33
- )->then($mock);
34
- }
35
-
36
- /** @test */
37
- public function shouldMapInputPromisesArray()
38
- {
39
- $mock = $this->createCallableMock();
40
- $mock
41
- ->expects($this->once())
42
- ->method('__invoke')
43
- ->with($this->identicalTo([2, 4, 6]));
44
-
45
- map(
46
- [resolve(1), resolve(2), resolve(3)],
47
- $this->mapper()
48
- )->then($mock);
49
- }
50
-
51
- /** @test */
52
- public function shouldMapMixedInputArray()
53
- {
54
- $mock = $this->createCallableMock();
55
- $mock
56
- ->expects($this->once())
57
- ->method('__invoke')
58
- ->with($this->identicalTo([2, 4, 6]));
59
-
60
- map(
61
- [1, resolve(2), 3],
62
- $this->mapper()
63
- )->then($mock);
64
- }
65
-
66
- /** @test */
67
- public function shouldMapInputWhenMapperReturnsAPromise()
68
- {
69
- $mock = $this->createCallableMock();
70
- $mock
71
- ->expects($this->once())
72
- ->method('__invoke')
73
- ->with($this->identicalTo([2, 4, 6]));
74
-
75
- map(
76
- [1, 2, 3],
77
- $this->promiseMapper()
78
- )->then($mock);
79
- }
80
-
81
- /** @test */
82
- public function shouldAcceptAPromiseForAnArray()
83
- {
84
- $mock = $this->createCallableMock();
85
- $mock
86
- ->expects($this->once())
87
- ->method('__invoke')
88
- ->with($this->identicalTo([2, 4, 6]));
89
-
90
- map(
91
- resolve([1, resolve(2), 3]),
92
- $this->mapper()
93
- )->then($mock);
94
- }
95
-
96
- /** @test */
97
- public function shouldResolveToEmptyArrayWhenInputPromiseDoesNotResolveToArray()
98
- {
99
- $mock = $this->createCallableMock();
100
- $mock
101
- ->expects($this->once())
102
- ->method('__invoke')
103
- ->with($this->identicalTo([]));
104
-
105
- map(
106
- resolve(1),
107
- $this->mapper()
108
- )->then($mock);
109
- }
110
-
111
- /** @test */
112
- public function shouldRejectWhenInputContainsRejection()
113
- {
114
- $mock = $this->createCallableMock();
115
- $mock
116
- ->expects($this->once())
117
- ->method('__invoke')
118
- ->with($this->identicalTo(2));
119
-
120
- map(
121
- [resolve(1), reject(2), resolve(3)],
122
- $this->mapper()
123
- )->then($this->expectCallableNever(), $mock);
124
- }
125
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/FunctionRaceTest.php DELETED
@@ -1,122 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise;
4
-
5
- class FunctionRaceTest extends TestCase
6
- {
7
- /** @test */
8
- public function shouldResolveEmptyInput()
9
- {
10
- $mock = $this->createCallableMock();
11
- $mock
12
- ->expects($this->once())
13
- ->method('__invoke')
14
- ->with($this->identicalTo(null));
15
-
16
- race(
17
- []
18
- )->then($mock);
19
- }
20
-
21
- /** @test */
22
- public function shouldResolveValuesArray()
23
- {
24
- $mock = $this->createCallableMock();
25
- $mock
26
- ->expects($this->once())
27
- ->method('__invoke')
28
- ->with($this->identicalTo(1));
29
-
30
- race(
31
- [1, 2, 3]
32
- )->then($mock);
33
- }
34
-
35
- /** @test */
36
- public function shouldResolvePromisesArray()
37
- {
38
- $mock = $this->createCallableMock();
39
- $mock
40
- ->expects($this->once())
41
- ->method('__invoke')
42
- ->with($this->identicalTo(2));
43
-
44
- $d1 = new Deferred();
45
- $d2 = new Deferred();
46
- $d3 = new Deferred();
47
-
48
- race(
49
- [$d1->promise(), $d2->promise(), $d3->promise()]
50
- )->then($mock);
51
-
52
- $d2->resolve(2);
53
-
54
- $d1->resolve(1);
55
- $d3->resolve(3);
56
- }
57
-
58
- /** @test */
59
- public function shouldResolveSparseArrayInput()
60
- {
61
- $mock = $this->createCallableMock();
62
- $mock
63
- ->expects($this->once())
64
- ->method('__invoke')
65
- ->with($this->identicalTo(null));
66
-
67
- race(
68
- [null, 1, null, 2, 3]
69
- )->then($mock);
70
- }
71
-
72
- /** @test */
73
- public function shouldRejectIfFirstSettledPromiseRejects()
74
- {
75
- $mock = $this->createCallableMock();
76
- $mock
77
- ->expects($this->once())
78
- ->method('__invoke')
79
- ->with($this->identicalTo(2));
80
-
81
- $d1 = new Deferred();
82
- $d2 = new Deferred();
83
- $d3 = new Deferred();
84
-
85
- race(
86
- [$d1->promise(), $d2->promise(), $d3->promise()]
87
- )->then($this->expectCallableNever(), $mock);
88
-
89
- $d2->reject(2);
90
-
91
- $d1->resolve(1);
92
- $d3->resolve(3);
93
- }
94
-
95
- /** @test */
96
- public function shouldAcceptAPromiseForAnArray()
97
- {
98
- $mock = $this->createCallableMock();
99
- $mock
100
- ->expects($this->once())
101
- ->method('__invoke')
102
- ->with($this->identicalTo(1));
103
-
104
- race(
105
- resolve([1, 2, 3])
106
- )->then($mock);
107
- }
108
-
109
- /** @test */
110
- public function shouldResolveToNullWhenInputPromiseDoesNotResolveToArray()
111
- {
112
- $mock = $this->createCallableMock();
113
- $mock
114
- ->expects($this->once())
115
- ->method('__invoke')
116
- ->with($this->identicalTo(null));
117
-
118
- race(
119
- resolve(1)
120
- )->then($mock);
121
- }
122
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/FunctionReduceTest.php DELETED
@@ -1,290 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise;
4
-
5
- class FunctionReduceTest extends TestCase
6
- {
7
- protected function plus()
8
- {
9
- return function ($sum, $val) {
10
- return $sum + $val;
11
- };
12
- }
13
-
14
- protected function append()
15
- {
16
- return function ($sum, $val) {
17
- return $sum . $val;
18
- };
19
- }
20
-
21
- /** @test */
22
- public function shouldReduceValuesWithoutInitialValue()
23
- {
24
- $mock = $this->createCallableMock();
25
- $mock
26
- ->expects($this->once())
27
- ->method('__invoke')
28
- ->with($this->identicalTo(6));
29
-
30
- reduce(
31
- [1, 2, 3],
32
- $this->plus()
33
- )->then($mock);
34
- }
35
-
36
- /** @test */
37
- public function shouldReduceValuesWithInitialValue()
38
- {
39
- $mock = $this->createCallableMock();
40
- $mock
41
- ->expects($this->once())
42
- ->method('__invoke')
43
- ->with($this->identicalTo(7));
44
-
45
- reduce(
46
- [1, 2, 3],
47
- $this->plus(),
48
- 1
49
- )->then($mock);
50
- }
51
-
52
- /** @test */
53
- public function shouldReduceValuesWithInitialPromise()
54
- {
55
- $mock = $this->createCallableMock();
56
- $mock
57
- ->expects($this->once())
58
- ->method('__invoke')
59
- ->with($this->identicalTo(7));
60
-
61
- reduce(
62
- [1, 2, 3],
63
- $this->plus(),
64
- resolve(1)
65
- )->then($mock);
66
- }
67
-
68
- /** @test */
69
- public function shouldReducePromisedValuesWithoutInitialValue()
70
- {
71
- $mock = $this->createCallableMock();
72
- $mock
73
- ->expects($this->once())
74
- ->method('__invoke')
75
- ->with($this->identicalTo(6));
76
-
77
- reduce(
78
- [resolve(1), resolve(2), resolve(3)],
79
- $this->plus()
80
- )->then($mock);
81
- }
82
-
83
- /** @test */
84
- public function shouldReducePromisedValuesWithInitialValue()
85
- {
86
- $mock = $this->createCallableMock();
87
- $mock
88
- ->expects($this->once())
89
- ->method('__invoke')
90
- ->with($this->identicalTo(7));
91
-
92
- reduce(
93
- [resolve(1), resolve(2), resolve(3)],
94
- $this->plus(),
95
- 1
96
- )->then($mock);
97
- }
98
-
99
- /** @test */
100
- public function shouldReducePromisedValuesWithInitialPromise()
101
- {
102
- $mock = $this->createCallableMock();
103
- $mock
104
- ->expects($this->once())
105
- ->method('__invoke')
106
- ->with($this->identicalTo(7));
107
-
108
- reduce(
109
- [resolve(1), resolve(2), resolve(3)],
110
- $this->plus(),
111
- resolve(1)
112
- )->then($mock);
113
- }
114
-
115
- /** @test */
116
- public function shouldReduceEmptyInputWithInitialValue()
117
- {
118
- $mock = $this->createCallableMock();
119
- $mock
120
- ->expects($this->once())
121
- ->method('__invoke')
122
- ->with($this->identicalTo(1));
123
-
124
- reduce(
125
- [],
126
- $this->plus(),
127
- 1
128
- )->then($mock);
129
- }
130
-
131
- /** @test */
132
- public function shouldReduceEmptyInputWithInitialPromise()
133
- {
134
- $mock = $this->createCallableMock();
135
- $mock
136
- ->expects($this->once())
137
- ->method('__invoke')
138
- ->with($this->identicalTo(1));
139
-
140
- reduce(
141
- [],
142
- $this->plus(),
143
- resolve(1)
144
- )->then($mock);
145
- }
146
-
147
- /** @test */
148
- public function shouldRejectWhenInputContainsRejection()
149
- {
150
- $mock = $this->createCallableMock();
151
- $mock
152
- ->expects($this->once())
153
- ->method('__invoke')
154
- ->with($this->identicalTo(2));
155
-
156
- reduce(
157
- [resolve(1), reject(2), resolve(3)],
158
- $this->plus(),
159
- resolve(1)
160
- )->then($this->expectCallableNever(), $mock);
161
- }
162
-
163
- /** @test */
164
- public function shouldResolveWithNullWhenInputIsEmptyAndNoInitialValueOrPromiseProvided()
165
- {
166
- // Note: this is different from when.js's behavior!
167
- // In when.reduce(), this rejects with a TypeError exception (following
168
- // JavaScript's [].reduce behavior.
169
- // We're following PHP's array_reduce behavior and resolve with NULL.
170
- $mock = $this->createCallableMock();
171
- $mock
172
- ->expects($this->once())
173
- ->method('__invoke')
174
- ->with($this->identicalTo(null));
175
-
176
- reduce(
177
- [],
178
- $this->plus()
179
- )->then($mock);
180
- }
181
-
182
- /** @test */
183
- public function shouldAllowSparseArrayInputWithoutInitialValue()
184
- {
185
- $mock = $this->createCallableMock();
186
- $mock
187
- ->expects($this->once())
188
- ->method('__invoke')
189
- ->with($this->identicalTo(3));
190
-
191
- reduce(
192
- [null, null, 1, null, 1, 1],
193
- $this->plus()
194
- )->then($mock);
195
- }
196
-
197
- /** @test */
198
- public function shouldAllowSparseArrayInputWithInitialValue()
199
- {
200
- $mock = $this->createCallableMock();
201
- $mock
202
- ->expects($this->once())
203
- ->method('__invoke')
204
- ->with($this->identicalTo(4));
205
-
206
- reduce(
207
- [null, null, 1, null, 1, 1],
208
- $this->plus(),
209
- 1
210
- )->then($mock);
211
- }
212
-
213
- /** @test */
214
- public function shouldReduceInInputOrder()
215
- {
216
- $mock = $this->createCallableMock();
217
- $mock
218
- ->expects($this->once())
219
- ->method('__invoke')
220
- ->with($this->identicalTo('123'));
221
-
222
- reduce(
223
- [1, 2, 3],
224
- $this->append(),
225
- ''
226
- )->then($mock);
227
- }
228
-
229
- /** @test */
230
- public function shouldAcceptAPromiseForAnArray()
231
- {
232
- $mock = $this->createCallableMock();
233
- $mock
234
- ->expects($this->once())
235
- ->method('__invoke')
236
- ->with($this->identicalTo('123'));
237
-
238
- reduce(
239
- resolve([1, 2, 3]),
240
- $this->append(),
241
- ''
242
- )->then($mock);
243
- }
244
-
245
- /** @test */
246
- public function shouldResolveToInitialValueWhenInputPromiseDoesNotResolveToAnArray()
247
- {
248
- $mock = $this->createCallableMock();
249
- $mock
250
- ->expects($this->once())
251
- ->method('__invoke')
252
- ->with($this->identicalTo(1));
253
-
254
- reduce(
255
- resolve(1),
256
- $this->plus(),
257
- 1
258
- )->then($mock);
259
- }
260
-
261
- /** @test */
262
- public function shouldProvideCorrectBasisValue()
263
- {
264
- $insertIntoArray = function ($arr, $val, $i) {
265
- $arr[$i] = $val;
266
-
267
- return $arr;
268
- };
269
-
270
- $d1 = new Deferred();
271
- $d2 = new Deferred();
272
- $d3 = new Deferred();
273
-
274
- $mock = $this->createCallableMock();
275
- $mock
276
- ->expects($this->once())
277
- ->method('__invoke')
278
- ->with($this->identicalTo([1, 2, 3]));
279
-
280
- reduce(
281
- [$d1->promise(), $d2->promise(), $d3->promise()],
282
- $insertIntoArray,
283
- []
284
- )->then($mock);
285
-
286
- $d3->resolve(3);
287
- $d1->resolve(1);
288
- $d2->resolve(2);
289
- }
290
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/FunctionRejectTest.php DELETED
@@ -1,64 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise;
4
-
5
- class FunctionRejectTest extends TestCase
6
- {
7
- /** @test */
8
- public function shouldRejectAnImmediateValue()
9
- {
10
- $expected = 123;
11
-
12
- $mock = $this->createCallableMock();
13
- $mock
14
- ->expects($this->once())
15
- ->method('__invoke')
16
- ->with($this->identicalTo($expected));
17
-
18
- reject($expected)
19
- ->then(
20
- $this->expectCallableNever(),
21
- $mock
22
- );
23
- }
24
-
25
- /** @test */
26
- public function shouldRejectAFulfilledPromise()
27
- {
28
- $expected = 123;
29
-
30
- $resolved = new FulfilledPromise($expected);
31
-
32
- $mock = $this->createCallableMock();
33
- $mock
34
- ->expects($this->once())
35
- ->method('__invoke')
36
- ->with($this->identicalTo($expected));
37
-
38
- reject($resolved)
39
- ->then(
40
- $this->expectCallableNever(),
41
- $mock
42
- );
43
- }
44
-
45
- /** @test */
46
- public function shouldRejectARejectedPromise()
47
- {
48
- $expected = 123;
49
-
50
- $resolved = new RejectedPromise($expected);
51
-
52
- $mock = $this->createCallableMock();
53
- $mock
54
- ->expects($this->once())
55
- ->method('__invoke')
56
- ->with($this->identicalTo($expected));
57
-
58
- reject($resolved)
59
- ->then(
60
- $this->expectCallableNever(),
61
- $mock
62
- );
63
- }
64
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/FunctionResolveTest.php DELETED
@@ -1,102 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise;
4
-
5
- class FunctionResolveTest extends TestCase
6
- {
7
- /** @test */
8
- public function shouldResolveAnImmediateValue()
9
- {
10
- $expected = 123;
11
-
12
- $mock = $this->createCallableMock();
13
- $mock
14
- ->expects($this->once())
15
- ->method('__invoke')
16
- ->with($this->identicalTo($expected));
17
-
18
- resolve($expected)
19
- ->then(
20
- $mock,
21
- $this->expectCallableNever()
22
- );
23
- }
24
-
25
- /** @test */
26
- public function shouldResolveAFulfilledPromise()
27
- {
28
- $expected = 123;
29
-
30
- $resolved = new FulfilledPromise($expected);
31
-
32
- $mock = $this->createCallableMock();
33
- $mock
34
- ->expects($this->once())
35
- ->method('__invoke')
36
- ->with($this->identicalTo($expected));
37
-
38
- resolve($resolved)
39
- ->then(
40
- $mock,
41
- $this->expectCallableNever()
42
- );
43
- }
44
-
45
- /** @test */
46
- public function shouldRejectARejectedPromise()
47
- {
48
- $expected = 123;
49
-
50
- $resolved = new RejectedPromise($expected);
51
-
52
- $mock = $this->createCallableMock();
53
- $mock
54
- ->expects($this->once())
55
- ->method('__invoke')
56
- ->with($this->identicalTo($expected));
57
-
58
- resolve($resolved)
59
- ->then(
60
- $this->expectCallableNever(),
61
- $mock
62
- );
63
- }
64
-
65
- /** @test */
66
- public function shouldSupportDeepNestingInPromiseChains()
67
- {
68
- $d = new Deferred();
69
- $d->resolve(false);
70
-
71
- $result = resolve(resolve($d->promise()->then(function ($val) {
72
- $d = new Deferred();
73
- $d->resolve($val);
74
-
75
- $identity = function ($val) {
76
- return $val;
77
- };
78
-
79
- return resolve($d->promise()->then($identity))->then(
80
- function ($val) {
81
- return !$val;
82
- }
83
- );
84
- })));
85
-
86
- $mock = $this->createCallableMock();
87
- $mock
88
- ->expects($this->once())
89
- ->method('__invoke')
90
- ->with($this->identicalTo(true));
91
-
92
- $result->then($mock);
93
- }
94
-
95
- /** @test */
96
- public function returnsExtendePromiseForSimplePromise()
97
- {
98
- $promise = $this->getMock('React\Promise\PromiseInterface');
99
-
100
- $this->assertInstanceOf('React\Promise\ExtendedPromiseInterface', resolve($promise));
101
- }
102
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/FunctionSomeTest.php DELETED
@@ -1,126 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise;
4
-
5
- class FunctionSomeTest extends TestCase
6
- {
7
- /** @test */
8
- public function shouldResolveEmptyInput()
9
- {
10
- $mock = $this->createCallableMock();
11
- $mock
12
- ->expects($this->once())
13
- ->method('__invoke')
14
- ->with($this->identicalTo([]));
15
-
16
- some(
17
- [],
18
- 1
19
- )->then($mock);
20
- }
21
-
22
- /** @test */
23
- public function shouldResolveValuesArray()
24
- {
25
- $mock = $this->createCallableMock();
26
- $mock
27
- ->expects($this->once())
28
- ->method('__invoke')
29
- ->with($this->identicalTo([1, 2]));
30
-
31
- some(
32
- [1, 2, 3],
33
- 2
34
- )->then($mock);
35
- }
36
-
37
- /** @test */
38
- public function shouldResolvePromisesArray()
39
- {
40
- $mock = $this->createCallableMock();
41
- $mock
42
- ->expects($this->once())
43
- ->method('__invoke')
44
- ->with($this->identicalTo([1, 2]));
45
-
46
- some(
47
- [resolve(1), resolve(2), resolve(3)],
48
- 2
49
- )->then($mock);
50
- }
51
-
52
- /** @test */
53
- public function shouldResolveSparseArrayInput()
54
- {
55
- $mock = $this->createCallableMock();
56
- $mock
57
- ->expects($this->once())
58
- ->method('__invoke')
59
- ->with($this->identicalTo([null, 1]));
60
-
61
- some(
62
- [null, 1, null, 2, 3],
63
- 2
64
- )->then($mock);
65
- }
66
-
67
- /** @test */
68
- public function shouldRejectIfAnyInputPromiseRejectsBeforeDesiredNumberOfInputsAreResolved()
69
- {
70
- $mock = $this->createCallableMock();
71
- $mock
72
- ->expects($this->once())
73
- ->method('__invoke')
74
- ->with($this->identicalTo([1 => 2, 2 => 3]));
75
-
76
- some(
77
- [resolve(1), reject(2), reject(3)],
78
- 2
79
- )->then($this->expectCallableNever(), $mock);
80
- }
81
-
82
- /** @test */
83
- public function shouldAcceptAPromiseForAnArray()
84
- {
85
- $mock = $this->createCallableMock();
86
- $mock
87
- ->expects($this->once())
88
- ->method('__invoke')
89
- ->with($this->identicalTo([1, 2]));
90
-
91
- some(
92
- resolve([1, 2, 3]),
93
- 2
94
- )->then($mock);
95
- }
96
-
97
- /** @test */
98
- public function shouldResolveWithEmptyArrayIfHowManyIsLessThanOne()
99
- {
100
- $mock = $this->createCallableMock();
101
- $mock
102
- ->expects($this->once())
103
- ->method('__invoke')
104
- ->with($this->identicalTo([]));
105
-
106
- some(
107
- [1],
108
- 0
109
- )->then($mock);
110
- }
111
-
112
- /** @test */
113
- public function shouldResolveToEmptyArrayWhenInputPromiseDoesNotResolveToArray()
114
- {
115
- $mock = $this->createCallableMock();
116
- $mock
117
- ->expects($this->once())
118
- ->method('__invoke')
119
- ->with($this->identicalTo([]));
120
-
121
- some(
122
- resolve(1),
123
- 1
124
- )->then($mock);
125
- }
126
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/LazyPromiseTest.php DELETED
@@ -1,107 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise;
4
-
5
- use React\Promise\PromiseAdapter\CallbackPromiseAdapter;
6
-
7
- class LazyPromiseTest extends TestCase
8
- {
9
- use PromiseTest\FullTestTrait;
10
-
11
- public function getPromiseTestAdapter(callable $canceller = null)
12
- {
13
- $d = new Deferred($canceller);
14
-
15
- $factory = function () use ($d) {
16
- return $d->promise();
17
- };
18
-
19
- return new CallbackPromiseAdapter([
20
- 'promise' => function () use ($factory) {
21
- return new LazyPromise($factory);
22
- },
23
- 'resolve' => [$d, 'resolve'],
24
- 'reject' => [$d, 'reject'],
25
- 'notify' => [$d, 'progress'],
26
- 'settle' => [$d, 'resolve'],
27
- ]);
28
- }
29
-
30
- /** @test */
31
- public function shouldNotCallFactoryIfThenIsNotInvoked()
32
- {
33
- $factory = $this->createCallableMock();
34
- $factory
35
- ->expects($this->never())
36
- ->method('__invoke');
37
-
38
- new LazyPromise($factory);
39
- }
40
-
41
- /** @test */
42
- public function shouldCallFactoryIfThenIsInvoked()
43
- {
44
- $factory = $this->createCallableMock();
45
- $factory
46
- ->expects($this->once())
47
- ->method('__invoke');
48
-
49
- $p = new LazyPromise($factory);
50
- $p->then();
51
- }
52
-
53
- /** @test */
54
- public function shouldReturnPromiseFromFactory()
55
- {
56
- $factory = $this->createCallableMock();
57
- $factory
58
- ->expects($this->once())
59
- ->method('__invoke')
60
- ->will($this->returnValue(new FulfilledPromise(1)));
61
-
62
- $onFulfilled = $this->createCallableMock();
63
- $onFulfilled
64
- ->expects($this->once())
65
- ->method('__invoke')
66
- ->with($this->identicalTo(1));
67
-
68
- $p = new LazyPromise($factory);
69
-
70
- $p->then($onFulfilled);
71
- }
72
-
73
- /** @test */
74
- public function shouldReturnPromiseIfFactoryReturnsNull()
75
- {
76
- $factory = $this->createCallableMock();
77
- $factory
78
- ->expects($this->once())
79
- ->method('__invoke')
80
- ->will($this->returnValue(null));
81
-
82
- $p = new LazyPromise($factory);
83
- $this->assertInstanceOf('React\\Promise\\PromiseInterface', $p->then());
84
- }
85
-
86
- /** @test */
87
- public function shouldReturnRejectedPromiseIfFactoryThrowsException()
88
- {
89
- $exception = new \Exception();
90
-
91
- $factory = $this->createCallableMock();
92
- $factory
93
- ->expects($this->once())
94
- ->method('__invoke')
95
- ->will($this->throwException($exception));
96
-
97
- $onRejected = $this->createCallableMock();
98
- $onRejected
99
- ->expects($this->once())
100
- ->method('__invoke')
101
- ->with($this->identicalTo($exception));
102
-
103
- $p = new LazyPromise($factory);
104
-
105
- $p->then($this->expectCallableNever(), $onRejected);
106
- }
107
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/PromiseAdapter/CallbackPromiseAdapter.php DELETED
@@ -1,40 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise\PromiseAdapter;
4
-
5
- use React\Promise;
6
-
7
- class CallbackPromiseAdapter implements PromiseAdapterInterface
8
- {
9
- private $callbacks;
10
-
11
- public function __construct(array $callbacks)
12
- {
13
- $this->callbacks = $callbacks;
14
- }
15
-
16
- public function promise()
17
- {
18
- return call_user_func_array($this->callbacks['promise'], func_get_args());
19
- }
20
-
21
- public function resolve()
22
- {
23
- return call_user_func_array($this->callbacks['resolve'], func_get_args());
24
- }
25
-
26
- public function reject()
27
- {
28
- return call_user_func_array($this->callbacks['reject'], func_get_args());
29
- }
30
-
31
- public function notify()
32
- {
33
- return call_user_func_array($this->callbacks['notify'], func_get_args());
34
- }
35
-
36
- public function settle()
37
- {
38
- return call_user_func_array($this->callbacks['settle'], func_get_args());
39
- }
40
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/PromiseAdapter/PromiseAdapterInterface.php DELETED
@@ -1,14 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise\PromiseAdapter;
4
-
5
- use React\Promise;
6
-
7
- interface PromiseAdapterInterface
8
- {
9
- public function promise();
10
- public function resolve();
11
- public function reject();
12
- public function notify();
13
- public function settle();
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/PromiseTest.php DELETED
@@ -1,116 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise;
4
-
5
- use React\Promise\PromiseAdapter\CallbackPromiseAdapter;
6
-
7
- class PromiseTest extends TestCase
8
- {
9
- use PromiseTest\FullTestTrait;
10
-
11
- public function getPromiseTestAdapter(callable $canceller = null)
12
- {
13
- $resolveCallback = $rejectCallback = $progressCallback = null;
14
-
15
- $promise = new Promise(function ($resolve, $reject, $progress) use (&$resolveCallback, &$rejectCallback, &$progressCallback) {
16
- $resolveCallback = $resolve;
17
- $rejectCallback = $reject;
18
- $progressCallback = $progress;
19
- }, $canceller);
20
-
21
- return new CallbackPromiseAdapter([
22
- 'promise' => function () use ($promise) {
23
- return $promise;
24
- },
25
- 'resolve' => $resolveCallback,
26
- 'reject' => $rejectCallback,
27
- 'notify' => $progressCallback,
28
- 'settle' => $resolveCallback,
29
- ]);
30
- }
31
-
32
- /** @test */
33
- public function shouldRejectIfResolverThrowsException()
34
- {
35
- $exception = new \Exception('foo');
36
-
37
- $promise = new Promise(function () use ($exception) {
38
- throw $exception;
39
- });
40
-
41
- $mock = $this->createCallableMock();
42
- $mock
43
- ->expects($this->once())
44
- ->method('__invoke')
45
- ->with($this->identicalTo($exception));
46
-
47
- $promise
48
- ->then($this->expectCallableNever(), $mock);
49
- }
50
-
51
- /** @test */
52
- public function shouldFulfillIfFullfilledWithSimplePromise()
53
- {
54
- $adapter = $this->getPromiseTestAdapter();
55
-
56
- $mock = $this->createCallableMock();
57
- $mock
58
- ->expects($this->once())
59
- ->method('__invoke')
60
- ->with($this->identicalTo('foo'));
61
-
62
- $adapter->promise()
63
- ->then($mock);
64
-
65
- $adapter->resolve(new SimpleFulfilledTestPromise());
66
- }
67
-
68
- /** @test */
69
- public function shouldRejectIfRejectedWithSimplePromise()
70
- {
71
- $adapter = $this->getPromiseTestAdapter();
72
-
73
- $mock = $this->createCallableMock();
74
- $mock
75
- ->expects($this->once())
76
- ->method('__invoke')
77
- ->with($this->identicalTo('foo'));
78
-
79
- $adapter->promise()
80
- ->then($this->expectCallableNever(), $mock);
81
-
82
- $adapter->resolve(new SimpleRejectedTestPromise());
83
- }
84
- }
85
-
86
- class SimpleFulfilledTestPromise implements PromiseInterface
87
- {
88
- public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
89
- {
90
- try {
91
- if ($onFulfilled) {
92
- $onFulfilled('foo');
93
- }
94
-
95
- return new self('foo');
96
- } catch (\Exception $exception) {
97
- return new RejectedPromise($exception);
98
- }
99
- }
100
- }
101
-
102
- class SimpleRejectedTestPromise implements PromiseInterface
103
- {
104
- public function then(callable $onFulfilled = null, callable $onRejected = null, callable $onProgress = null)
105
- {
106
- try {
107
- if ($onRejected) {
108
- $onRejected('foo');
109
- }
110
-
111
- return new self('foo');
112
- } catch (\Exception $exception) {
113
- return new RejectedPromise($exception);
114
- }
115
- }
116
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/PromiseTest/CancelTestTrait.php DELETED
@@ -1,206 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise\PromiseTest;
4
-
5
- use React\Promise;
6
-
7
- trait CancelTestTrait
8
- {
9
- /**
10
- * @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
11
- */
12
- abstract public function getPromiseTestAdapter(callable $canceller = null);
13
-
14
- /** @test */
15
- public function cancelShouldCallCancellerWithResolverArguments()
16
- {
17
- $mock = $this->createCallableMock();
18
- $mock
19
- ->expects($this->once())
20
- ->method('__invoke')
21
- ->with($this->isType('callable'), $this->isType('callable'), $this->isType('callable'));
22
-
23
- $adapter = $this->getPromiseTestAdapter($mock);
24
-
25
- $adapter->promise()->cancel();
26
- }
27
-
28
- /** @test */
29
- public function cancelShouldFulfillPromiseIfCancellerFulfills()
30
- {
31
- $adapter = $this->getPromiseTestAdapter(function ($resolve) {
32
- $resolve(1);
33
- });
34
-
35
- $mock = $this->createCallableMock();
36
- $mock
37
- ->expects($this->once())
38
- ->method('__invoke')
39
- ->with($this->identicalTo(1));
40
-
41
- $adapter->promise()
42
- ->then($mock, $this->expectCallableNever());
43
-
44
- $adapter->promise()->cancel();
45
- }
46
-
47
- /** @test */
48
- public function cancelShouldRejectPromiseIfCancellerRejects()
49
- {
50
- $adapter = $this->getPromiseTestAdapter(function ($resolve, $reject) {
51
- $reject(1);
52
- });
53
-
54
- $mock = $this->createCallableMock();
55
- $mock
56
- ->expects($this->once())
57
- ->method('__invoke')
58
- ->with($this->identicalTo(1));
59
-
60
- $adapter->promise()
61
- ->then($this->expectCallableNever(), $mock);
62
-
63
- $adapter->promise()->cancel();
64
- }
65
-
66
- /** @test */
67
- public function cancelShouldRejectPromiseWithExceptionIfCancellerThrows()
68
- {
69
- $e = new \Exception();
70
-
71
- $adapter = $this->getPromiseTestAdapter(function () use ($e) {
72
- throw $e;
73
- });
74
-
75
- $mock = $this->createCallableMock();
76
- $mock
77
- ->expects($this->once())
78
- ->method('__invoke')
79
- ->with($this->identicalTo($e));
80
-
81
- $adapter->promise()
82
- ->then($this->expectCallableNever(), $mock);
83
-
84
- $adapter->promise()->cancel();
85
- }
86
-
87
- /** @test */
88
- public function cancelShouldProgressPromiseIfCancellerNotifies()
89
- {
90
- $adapter = $this->getPromiseTestAdapter(function ($resolve, $reject, $progress) {
91
- $progress(1);
92
- });
93
-
94
- $mock = $this->createCallableMock();
95
- $mock
96
- ->expects($this->once())
97
- ->method('__invoke')
98
- ->with($this->identicalTo(1));
99
-
100
- $adapter->promise()
101
- ->then($this->expectCallableNever(), $this->expectCallableNever(), $mock);
102
-
103
- $adapter->promise()->cancel();
104
- }
105
-
106
- /** @test */
107
- public function cancelShouldCallCancellerOnlyOnceIfCancellerResolves()
108
- {
109
- $mock = $this->createCallableMock();
110
- $mock
111
- ->expects($this->once())
112
- ->method('__invoke')
113
- ->will($this->returnCallback(function ($resolve) {
114
- $resolve();
115
- }));
116
-
117
- $adapter = $this->getPromiseTestAdapter($mock);
118
-
119
- $adapter->promise()->cancel();
120
- $adapter->promise()->cancel();
121
- }
122
-
123
- /** @test */
124
- public function cancelShouldHaveNoEffectIfCancellerDoesNothing()
125
- {
126
- $adapter = $this->getPromiseTestAdapter(function () {});
127
-
128
- $adapter->promise()
129
- ->then($this->expectCallableNever(), $this->expectCallableNever());
130
-
131
- $adapter->promise()->cancel();
132
- $adapter->promise()->cancel();
133
- }
134
-
135
- /** @test */
136
- public function cancelShouldCallCancellerFromDeepNestedPromiseChain()
137
- {
138
- $mock = $this->createCallableMock();
139
- $mock
140
- ->expects($this->once())
141
- ->method('__invoke');
142
-
143
- $adapter = $this->getPromiseTestAdapter($mock);
144
-
145
- $promise = $adapter->promise()
146
- ->then(function () {
147
- return new Promise\Promise(function () {});
148
- })
149
- ->then(function () {
150
- $d = new Promise\Deferred();
151
-
152
- return $d->promise();
153
- })
154
- ->then(function () {
155
- return new Promise\Promise(function () {});
156
- });
157
-
158
- $promise->cancel();
159
- }
160
-
161
- /** @test */
162
- public function cancelCalledOnChildrenSouldOnlyCancelWhenAllChildrenCancelled()
163
- {
164
- $adapter = $this->getPromiseTestAdapter($this->expectCallableNever());
165
-
166
- $child1 = $adapter->promise()
167
- ->then()
168
- ->then();
169
-
170
- $adapter->promise()
171
- ->then();
172
-
173
- $child1->cancel();
174
- }
175
-
176
- /** @test */
177
- public function cancelShouldTriggerCancellerWhenAllChildrenCancel()
178
- {
179
- $adapter = $this->getPromiseTestAdapter($this->expectCallableOnce());
180
-
181
- $child1 = $adapter->promise()
182
- ->then()
183
- ->then();
184
-
185
- $child2 = $adapter->promise()
186
- ->then();
187
-
188
- $child1->cancel();
189
- $child2->cancel();
190
- }
191
-
192
- /** @test */
193
- public function cancelShouldAlwaysTriggerCancellerWhenCalledOnRootPromise()
194
- {
195
- $adapter = $this->getPromiseTestAdapter($this->expectCallableOnce());
196
-
197
- $adapter->promise()
198
- ->then()
199
- ->then();
200
-
201
- $adapter->promise()
202
- ->then();
203
-
204
- $adapter->promise()->cancel();
205
- }
206
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/PromiseTest/FullTestTrait.php DELETED
@@ -1,15 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise\PromiseTest;
4
-
5
- trait FullTestTrait
6
- {
7
- use PromisePendingTestTrait,
8
- PromiseSettledTestTrait,
9
- PromiseFulfilledTestTrait,
10
- PromiseRejectedTestTrait,
11
- ResolveTestTrait,
12
- RejectTestTrait,
13
- NotifyTestTrait,
14
- CancelTestTrait;
15
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/PromiseTest/NotifyTestTrait.php DELETED
@@ -1,336 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise\PromiseTest;
4
-
5
- trait NotifyTestTrait
6
- {
7
- /**
8
- * @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
9
- */
10
- abstract public function getPromiseTestAdapter(callable $canceller = null);
11
-
12
- /** @test */
13
- public function notifyShouldProgress()
14
- {
15
- $adapter = $this->getPromiseTestAdapter();
16
-
17
- $sentinel = new \stdClass();
18
-
19
- $mock = $this->createCallableMock();
20
- $mock
21
- ->expects($this->once())
22
- ->method('__invoke')
23
- ->with($sentinel);
24
-
25
- $adapter->promise()
26
- ->then($this->expectCallableNever(), $this->expectCallableNever(), $mock);
27
-
28
- $adapter->notify($sentinel);
29
- }
30
-
31
- /** @test */
32
- public function notifyShouldPropagateProgressToDownstreamPromises()
33
- {
34
- $adapter = $this->getPromiseTestAdapter();
35
-
36
- $sentinel = new \stdClass();
37
-
38
- $mock = $this->createCallableMock();
39
- $mock
40
- ->expects($this->once())
41
- ->method('__invoke')
42
- ->will($this->returnArgument(0));
43
-
44
- $mock2 = $this->createCallableMock();
45
- $mock2
46
- ->expects($this->once())
47
- ->method('__invoke')
48
- ->with($sentinel);
49
-
50
- $adapter->promise()
51
- ->then(
52
- $this->expectCallableNever(),
53
- $this->expectCallableNever(),
54
- $mock
55
- )
56
- ->then(
57
- $this->expectCallableNever(),
58
- $this->expectCallableNever(),
59
- $mock2
60
- );
61
-
62
- $adapter->notify($sentinel);
63
- }
64
-
65
- /** @test */
66
- public function notifyShouldPropagateTransformedProgressToDownstreamPromises()
67
- {
68
- $adapter = $this->getPromiseTestAdapter();
69
-
70
- $sentinel = new \stdClass();
71
-
72
- $mock = $this->createCallableMock();
73
- $mock
74
- ->expects($this->once())
75
- ->method('__invoke')
76
- ->will($this->returnValue($sentinel));
77
-
78
- $mock2 = $this->createCallableMock();
79
- $mock2
80
- ->expects($this->once())
81
- ->method('__invoke')
82
- ->with($sentinel);
83
-
84
- $adapter->promise()
85
- ->then(
86
- $this->expectCallableNever(),
87
- $this->expectCallableNever(),
88
- $mock
89
- )
90
- ->then(
91
- $this->expectCallableNever(),
92
- $this->expectCallableNever(),
93
- $mock2
94
- );
95
-
96
- $adapter->notify(1);
97
- }
98
-
99
- /** @test */
100
- public function notifyShouldPropagateCaughtExceptionValueAsProgress()
101
- {
102
- $adapter = $this->getPromiseTestAdapter();
103
-
104
- $exception = new \Exception();
105
-
106
- $mock = $this->createCallableMock();
107
- $mock
108
- ->expects($this->once())
109
- ->method('__invoke')
110
- ->will($this->throwException($exception));
111
-
112
- $mock2 = $this->createCallableMock();
113
- $mock2
114
- ->expects($this->once())
115
- ->method('__invoke')
116
- ->with($this->identicalTo($exception));
117
-
118
- $adapter->promise()
119
- ->then(
120
- $this->expectCallableNever(),
121
- $this->expectCallableNever(),
122
- $mock
123
- )
124
- ->then(
125
- $this->expectCallableNever(),
126
- $this->expectCallableNever(),
127
- $mock2
128
- );
129
-
130
- $adapter->notify(1);
131
- }
132
-
133
- /** @test */
134
- public function notifyShouldForwardProgressEventsWhenIntermediaryCallbackTiedToAResolvedPromiseReturnsAPromise()
135
- {
136
- $adapter = $this->getPromiseTestAdapter();
137
- $adapter2 = $this->getPromiseTestAdapter();
138
-
139
- $promise2 = $adapter2->promise();
140
-
141
- $sentinel = new \stdClass();
142
-
143
- $mock = $this->createCallableMock();
144
- $mock
145
- ->expects($this->once())
146
- ->method('__invoke')
147
- ->with($sentinel);
148
-
149
- // resolve BEFORE attaching progress handler
150
- $adapter->resolve();
151
-
152
- $adapter->promise()
153
- ->then(function () use ($promise2) {
154
- return $promise2;
155
- })
156
- ->then(
157
- $this->expectCallableNever(),
158
- $this->expectCallableNever(),
159
- $mock
160
- );
161
-
162
- $adapter2->notify($sentinel);
163
- }
164
-
165
- /** @test */
166
- public function notifyShouldForwardProgressEventsWhenIntermediaryCallbackTiedToAnUnresolvedPromiseReturnsAPromise()
167
- {
168
- $adapter = $this->getPromiseTestAdapter();
169
- $adapter2 = $this->getPromiseTestAdapter();
170
-
171
- $promise2 = $adapter2->promise();
172
-
173
- $sentinel = new \stdClass();
174
-
175
- $mock = $this->createCallableMock();
176
- $mock
177
- ->expects($this->once())
178
- ->method('__invoke')
179
- ->with($sentinel);
180
-
181
- $adapter->promise()
182
- ->then(function () use ($promise2) {
183
- return $promise2;
184
- })
185
- ->then(
186
- $this->expectCallableNever(),
187
- $this->expectCallableNever(),
188
- $mock
189
- );
190
-
191
- // resolve AFTER attaching progress handler
192
- $adapter->resolve();
193
- $adapter2->notify($sentinel);
194
- }
195
-
196
- /** @test */
197
- public function notifyShouldForwardProgressWhenResolvedWithAnotherPromise()
198
- {
199
- $adapter = $this->getPromiseTestAdapter();
200
- $adapter2 = $this->getPromiseTestAdapter();
201
-
202
- $sentinel = new \stdClass();
203
-
204
- $mock = $this->createCallableMock();
205
- $mock
206
- ->expects($this->once())
207
- ->method('__invoke')
208
- ->will($this->returnValue($sentinel));
209
-
210
- $mock2 = $this->createCallableMock();
211
- $mock2
212
- ->expects($this->once())
213
- ->method('__invoke')
214
- ->with($sentinel);
215
-
216
- $adapter->promise()
217
- ->then(
218
- $this->expectCallableNever(),
219
- $this->expectCallableNever(),
220
- $mock
221
- )
222
- ->then(
223
- $this->expectCallableNever(),
224
- $this->expectCallableNever(),
225
- $mock2
226
- );
227
-
228
- $adapter->resolve($adapter2->promise());
229
- $adapter2->notify($sentinel);
230
- }
231
-
232
- /** @test */
233
- public function notifyShouldAllowResolveAfterProgress()
234
- {
235
- $adapter = $this->getPromiseTestAdapter();
236
-
237
- $mock = $this->createCallableMock();
238
- $mock
239
- ->expects($this->at(0))
240
- ->method('__invoke')
241
- ->with($this->identicalTo(1));
242
- $mock
243
- ->expects($this->at(1))
244
- ->method('__invoke')
245
- ->with($this->identicalTo(2));
246
-
247
- $adapter->promise()
248
- ->then(
249
- $mock,
250
- $this->expectCallableNever(),
251
- $mock
252
- );
253
-
254
- $adapter->notify(1);
255
- $adapter->resolve(2);
256
- }
257
-
258
- /** @test */
259
- public function notifyShouldAllowRejectAfterProgress()
260
- {
261
- $adapter = $this->getPromiseTestAdapter();
262
-
263
- $mock = $this->createCallableMock();
264
- $mock
265
- ->expects($this->at(0))
266
- ->method('__invoke')
267
- ->with($this->identicalTo(1));
268
- $mock
269
- ->expects($this->at(1))
270
- ->method('__invoke')
271
- ->with($this->identicalTo(2));
272
-
273
- $adapter->promise()
274
- ->then(
275
- $this->expectCallableNever(),
276
- $mock,
277
- $mock
278
- );
279
-
280
- $adapter->notify(1);
281
- $adapter->reject(2);
282
- }
283
-
284
- /** @test */
285
- public function notifyShouldReturnSilentlyOnProgressWhenAlreadyRejected()
286
- {
287
- $adapter = $this->getPromiseTestAdapter();
288
-
289
- $adapter->reject(1);
290
-
291
- $this->assertNull($adapter->notify());
292
- }
293
-
294
- /** @test */
295
- public function notifyShouldInvokeProgressHandler()
296
- {
297
- $adapter = $this->getPromiseTestAdapter();
298
-
299
- $mock = $this->createCallableMock();
300
- $mock
301
- ->expects($this->once())
302
- ->method('__invoke')
303
- ->with($this->identicalTo(1));
304
-
305
- $adapter->promise()->progress($mock);
306
- $adapter->notify(1);
307
- }
308
-
309
- /** @test */
310
- public function notifyShouldInvokeProgressHandlerFromDone()
311
- {
312
- $adapter = $this->getPromiseTestAdapter();
313
-
314
- $mock = $this->createCallableMock();
315
- $mock
316
- ->expects($this->once())
317
- ->method('__invoke')
318
- ->with($this->identicalTo(1));
319
-
320
- $this->assertNull($adapter->promise()->done(null, null, $mock));
321
- $adapter->notify(1);
322
- }
323
-
324
- /** @test */
325
- public function notifyShouldThrowExceptionThrownProgressHandlerFromDone()
326
- {
327
- $adapter = $this->getPromiseTestAdapter();
328
-
329
- $this->setExpectedException('\Exception', 'UnhandledRejectionException');
330
-
331
- $this->assertNull($adapter->promise()->done(null, null, function () {
332
- throw new \Exception('UnhandledRejectionException');
333
- }));
334
- $adapter->notify(1);
335
- }
336
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/PromiseTest/PromiseFulfilledTestTrait.php DELETED
@@ -1,351 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise\PromiseTest;
4
-
5
- trait PromiseFulfilledTestTrait
6
- {
7
- /**
8
- * @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
9
- */
10
- abstract public function getPromiseTestAdapter(callable $canceller = null);
11
-
12
- /** @test */
13
- public function fulfilledPromiseShouldBeImmutable()
14
- {
15
- $adapter = $this->getPromiseTestAdapter();
16
-
17
- $mock = $this->createCallableMock();
18
- $mock
19
- ->expects($this->once())
20
- ->method('__invoke')
21
- ->with($this->identicalTo(1));
22
-
23
- $adapter->resolve(1);
24
- $adapter->resolve(2);
25
-
26
- $adapter->promise()
27
- ->then(
28
- $mock,
29
- $this->expectCallableNever()
30
- );
31
- }
32
-
33
- /** @test */
34
- public function fulfilledPromiseShouldInvokeNewlyAddedCallback()
35
- {
36
- $adapter = $this->getPromiseTestAdapter();
37
-
38
- $adapter->resolve(1);
39
-
40
- $mock = $this->createCallableMock();
41
- $mock
42
- ->expects($this->once())
43
- ->method('__invoke')
44
- ->with($this->identicalTo(1));
45
-
46
- $adapter->promise()
47
- ->then($mock, $this->expectCallableNever());
48
- }
49
-
50
- /** @test */
51
- public function thenShouldForwardResultWhenCallbackIsNull()
52
- {
53
- $adapter = $this->getPromiseTestAdapter();
54
-
55
- $mock = $this->createCallableMock();
56
- $mock
57
- ->expects($this->once())
58
- ->method('__invoke')
59
- ->with($this->identicalTo(1));
60
-
61
- $adapter->resolve(1);
62
- $adapter->promise()
63
- ->then(
64
- null,
65
- $this->expectCallableNever()
66
- )
67
- ->then(
68
- $mock,
69
- $this->expectCallableNever()
70
- );
71
- }
72
-
73
- /** @test */
74
- public function thenShouldForwardCallbackResultToNextCallback()
75
- {
76
- $adapter = $this->getPromiseTestAdapter();
77
-
78
- $mock = $this->createCallableMock();
79
- $mock
80
- ->expects($this->once())
81
- ->method('__invoke')
82
- ->with($this->identicalTo(2));
83
-
84
- $adapter->resolve(1);
85
- $adapter->promise()
86
- ->then(
87
- function ($val) {
88
- return $val + 1;
89
- },
90
- $this->expectCallableNever()
91
- )
92
- ->then(
93
- $mock,
94
- $this->expectCallableNever()
95
- );
96
- }
97
-
98
- /** @test */
99
- public function thenShouldForwardPromisedCallbackResultValueToNextCallback()
100
- {
101
- $adapter = $this->getPromiseTestAdapter();
102
-
103
- $mock = $this->createCallableMock();
104
- $mock
105
- ->expects($this->once())
106
- ->method('__invoke')
107
- ->with($this->identicalTo(2));
108
-
109
- $adapter->resolve(1);
110
- $adapter->promise()
111
- ->then(
112
- function ($val) {
113
- return \React\Promise\resolve($val + 1);
114
- },
115
- $this->expectCallableNever()
116
- )
117
- ->then(
118
- $mock,
119
- $this->expectCallableNever()
120
- );
121
- }
122
-
123
- /** @test */
124
- public function thenShouldSwitchFromCallbacksToErrbacksWhenCallbackReturnsARejection()
125
- {
126
- $adapter = $this->getPromiseTestAdapter();
127
-
128
- $mock = $this->createCallableMock();
129
- $mock
130
- ->expects($this->once())
131
- ->method('__invoke')
132
- ->with($this->identicalTo(2));
133
-
134
- $adapter->resolve(1);
135
- $adapter->promise()
136
- ->then(
137
- function ($val) {
138
- return \React\Promise\reject($val + 1);
139
- },
140
- $this->expectCallableNever()
141
- )
142
- ->then(
143
- $this->expectCallableNever(),
144
- $mock
145
- );
146
- }
147
-
148
- /** @test */
149
- public function thenShouldSwitchFromCallbacksToErrbacksWhenCallbackThrows()
150
- {
151
- $adapter = $this->getPromiseTestAdapter();
152
-
153
- $exception = new \Exception();
154
-
155
- $mock = $this->createCallableMock();
156
- $mock
157
- ->expects($this->once())
158
- ->method('__invoke')
159
- ->will($this->throwException($exception));
160
-
161
- $mock2 = $this->createCallableMock();
162
- $mock2
163
- ->expects($this->once())
164
- ->method('__invoke')
165
- ->with($this->identicalTo($exception));
166
-
167
- $adapter->resolve(1);
168
- $adapter->promise()
169
- ->then(
170
- $mock,
171
- $this->expectCallableNever()
172
- )
173
- ->then(
174
- $this->expectCallableNever(),
175
- $mock2
176
- );
177
- }
178
-
179
- /** @test */
180
- public function cancelShouldReturnNullForFulfilledPromise()
181
- {
182
- $adapter = $this->getPromiseTestAdapter();
183
-
184
- $adapter->resolve();
185
-
186
- $this->assertNull($adapter->promise()->cancel());
187
- }
188
-
189
- /** @test */
190
- public function cancelShouldHaveNoEffectForFulfilledPromise()
191
- {
192
- $adapter = $this->getPromiseTestAdapter($this->expectCallableNever());
193
-
194
- $adapter->resolve();
195
-
196
- $adapter->promise()->cancel();
197
- }
198
-
199
- /** @test */
200
- public function doneShouldInvokeFulfillmentHandlerForFulfilledPromise()
201
- {
202
- $adapter = $this->getPromiseTestAdapter();
203
-
204
- $mock = $this->createCallableMock();
205
- $mock
206
- ->expects($this->once())
207
- ->method('__invoke')
208
- ->with($this->identicalTo(1));
209
-
210
- $adapter->resolve(1);
211
- $this->assertNull($adapter->promise()->done($mock));
212
- }
213
-
214
- /** @test */
215
- public function doneShouldThrowExceptionThrownFulfillmentHandlerForFulfilledPromise()
216
- {
217
- $adapter = $this->getPromiseTestAdapter();
218
-
219
- $this->setExpectedException('\Exception', 'UnhandledRejectionException');
220
-
221
- $adapter->resolve(1);
222
- $this->assertNull($adapter->promise()->done(function () {
223
- throw new \Exception('UnhandledRejectionException');
224
- }));
225
- }
226
-
227
- /** @test */
228
- public function doneShouldThrowUnhandledRejectionExceptionWhenFulfillmentHandlerRejectsForFulfilledPromise()
229
- {
230
- $adapter = $this->getPromiseTestAdapter();
231
-
232
- $this->setExpectedException('React\\Promise\\UnhandledRejectionException');
233
-
234
- $adapter->resolve(1);
235
- $this->assertNull($adapter->promise()->done(function () {
236
- return \React\Promise\reject();
237
- }));
238
- }
239
-
240
- /** @test */
241
- public function otherwiseShouldNotInvokeRejectionHandlerForFulfilledPromise()
242
- {
243
- $adapter = $this->getPromiseTestAdapter();
244
-
245
- $adapter->resolve(1);
246
- $adapter->promise()->otherwise($this->expectCallableNever());
247
- }
248
-
249
- /** @test */
250
- public function alwaysShouldNotSuppressValueForFulfilledPromise()
251
- {
252
- $adapter = $this->getPromiseTestAdapter();
253
-
254
- $value = new \stdClass();
255
-
256
- $mock = $this->createCallableMock();
257
- $mock
258
- ->expects($this->once())
259
- ->method('__invoke')
260
- ->with($this->identicalTo($value));
261
-
262
- $adapter->resolve($value);
263
- $adapter->promise()
264
- ->always(function () {})
265
- ->then($mock);
266
- }
267
-
268
- /** @test */
269
- public function alwaysShouldNotSuppressValueWhenHandlerReturnsANonPromiseForFulfilledPromise()
270
- {
271
- $adapter = $this->getPromiseTestAdapter();
272
-
273
- $value = new \stdClass();
274
-
275
- $mock = $this->createCallableMock();
276
- $mock
277
- ->expects($this->once())
278
- ->method('__invoke')
279
- ->with($this->identicalTo($value));
280
-
281
- $adapter->resolve($value);
282
- $adapter->promise()
283
- ->always(function () {
284
- return 1;
285
- })
286
- ->then($mock);
287
- }
288
-
289
- /** @test */
290
- public function alwaysShouldNotSuppressValueWhenHandlerReturnsAPromiseForFulfilledPromise()
291
- {
292
- $adapter = $this->getPromiseTestAdapter();
293
-
294
- $value = new \stdClass();
295
-
296
- $mock = $this->createCallableMock();
297
- $mock
298
- ->expects($this->once())
299
- ->method('__invoke')
300
- ->with($this->identicalTo($value));
301
-
302
- $adapter->resolve($value);
303
- $adapter->promise()
304
- ->always(function () {
305
- return \React\Promise\resolve(1);
306
- })
307
- ->then($mock);
308
- }
309
-
310
- /** @test */
311
- public function alwaysShouldRejectWhenHandlerThrowsForFulfilledPromise()
312
- {
313
- $adapter = $this->getPromiseTestAdapter();
314
-
315
- $exception = new \Exception();
316
-
317
- $mock = $this->createCallableMock();
318
- $mock
319
- ->expects($this->once())
320
- ->method('__invoke')
321
- ->with($this->identicalTo($exception));
322
-
323
- $adapter->resolve(1);
324
- $adapter->promise()
325
- ->always(function () use ($exception) {
326
- throw $exception;
327
- })
328
- ->then(null, $mock);
329
- }
330
-
331
- /** @test */
332
- public function alwaysShouldRejectWhenHandlerRejectsForFulfilledPromise()
333
- {
334
- $adapter = $this->getPromiseTestAdapter();
335
-
336
- $exception = new \Exception();
337
-
338
- $mock = $this->createCallableMock();
339
- $mock
340
- ->expects($this->once())
341
- ->method('__invoke')
342
- ->with($this->identicalTo($exception));
343
-
344
- $adapter->resolve(1);
345
- $adapter->promise()
346
- ->always(function () use ($exception) {
347
- return \React\Promise\reject($exception);
348
- })
349
- ->then(null, $mock);
350
- }
351
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/PromiseTest/PromisePendingTestTrait.php DELETED
@@ -1,68 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise\PromiseTest;
4
-
5
- trait PromisePendingTestTrait
6
- {
7
- /**
8
- * @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
9
- */
10
- abstract public function getPromiseTestAdapter(callable $canceller = null);
11
-
12
- /** @test */
13
- public function thenShouldReturnAPromiseForPendingPromise()
14
- {
15
- $adapter = $this->getPromiseTestAdapter();
16
-
17
- $this->assertInstanceOf('React\\Promise\\PromiseInterface', $adapter->promise()->then());
18
- }
19
-
20
- /** @test */
21
- public function thenShouldReturnAllowNullForPendingPromise()
22
- {
23
- $adapter = $this->getPromiseTestAdapter();
24
-
25
- $this->assertInstanceOf('React\\Promise\\PromiseInterface', $adapter->promise()->then(null, null, null));
26
- }
27
-
28
- /** @test */
29
- public function cancelShouldReturnNullForPendingPromise()
30
- {
31
- $adapter = $this->getPromiseTestAdapter();
32
-
33
- $this->assertNull($adapter->promise()->cancel());
34
- }
35
-
36
- /** @test */
37
- public function doneShouldReturnNullForPendingPromise()
38
- {
39
- $adapter = $this->getPromiseTestAdapter();
40
-
41
- $this->assertNull($adapter->promise()->done());
42
- }
43
-
44
- /** @test */
45
- public function doneShouldReturnAllowNullForPendingPromise()
46
- {
47
- $adapter = $this->getPromiseTestAdapter();
48
-
49
- $this->assertNull($adapter->promise()->done(null, null, null));
50
- }
51
-
52
- /** @test */
53
- public function otherwiseShouldNotInvokeRejectionHandlerForPendingPromise()
54
- {
55
- $adapter = $this->getPromiseTestAdapter();
56
-
57
- $adapter->settle();
58
- $adapter->promise()->otherwise($this->expectCallableNever());
59
- }
60
-
61
- /** @test */
62
- public function alwaysShouldReturnAPromiseForPendingPromise()
63
- {
64
- $adapter = $this->getPromiseTestAdapter();
65
-
66
- $this->assertInstanceOf('React\\Promise\\PromiseInterface', $adapter->promise()->always(function () {}));
67
- }
68
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/PromiseTest/PromiseRejectedTestTrait.php DELETED
@@ -1,492 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise\PromiseTest;
4
-
5
- use React\Promise\Deferred;
6
-
7
- trait PromiseRejectedTestTrait
8
- {
9
- /**
10
- * @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
11
- */
12
- abstract public function getPromiseTestAdapter(callable $canceller = null);
13
-
14
- /** @test */
15
- public function rejectedPromiseShouldBeImmutable()
16
- {
17
- $adapter = $this->getPromiseTestAdapter();
18
-
19
- $mock = $this->createCallableMock();
20
- $mock
21
- ->expects($this->once())
22
- ->method('__invoke')
23
- ->with($this->identicalTo(1));
24
-
25
- $adapter->reject(1);
26
- $adapter->reject(2);
27
-
28
- $adapter->promise()
29
- ->then(
30
- $this->expectCallableNever(),
31
- $mock
32
- );
33
- }
34
-
35
- /** @test */
36
- public function rejectedPromiseShouldInvokeNewlyAddedCallback()
37
- {
38
- $adapter = $this->getPromiseTestAdapter();
39
-
40
- $adapter->reject(1);
41
-
42
- $mock = $this->createCallableMock();
43
- $mock
44
- ->expects($this->once())
45
- ->method('__invoke')
46
- ->with($this->identicalTo(1));
47
-
48
- $adapter->promise()
49
- ->then($this->expectCallableNever(), $mock);
50
- }
51
-
52
- /** @test */
53
- public function shouldForwardUndefinedRejectionValue()
54
- {
55
- $adapter = $this->getPromiseTestAdapter();
56
-
57
- $mock = $this->createCallableMock();
58
- $mock
59
- ->expects($this->once())
60
- ->method('__invoke')
61
- ->with(null);
62
-
63
- $adapter->reject(1);
64
- $adapter->promise()
65
- ->then(
66
- $this->expectCallableNever(),
67
- function () {
68
- // Presence of rejection handler is enough to switch back
69
- // to resolve mode, even though it returns undefined.
70
- // The ONLY way to propagate a rejection is to re-throw or
71
- // return a rejected promise;
72
- }
73
- )
74
- ->then(
75
- $mock,
76
- $this->expectCallableNever()
77
- );
78
- }
79
-
80
- /** @test */
81
- public function shouldSwitchFromErrbacksToCallbacksWhenErrbackDoesNotExplicitlyPropagate()
82
- {
83
- $adapter = $this->getPromiseTestAdapter();
84
-
85
- $mock = $this->createCallableMock();
86
- $mock
87
- ->expects($this->once())
88
- ->method('__invoke')
89
- ->with($this->identicalTo(2));
90
-
91
- $adapter->reject(1);
92
- $adapter->promise()
93
- ->then(
94
- $this->expectCallableNever(),
95
- function ($val) {
96
- return $val + 1;
97
- }
98
- )
99
- ->then(
100
- $mock,
101
- $this->expectCallableNever()
102
- );
103
- }
104
-
105
- /** @test */
106
- public function shouldSwitchFromErrbacksToCallbacksWhenErrbackReturnsAResolution()
107
- {
108
- $adapter = $this->getPromiseTestAdapter();
109
-
110
- $mock = $this->createCallableMock();
111
- $mock
112
- ->expects($this->once())
113
- ->method('__invoke')
114
- ->with($this->identicalTo(2));
115
-
116
- $adapter->reject(1);
117
- $adapter->promise()
118
- ->then(
119
- $this->expectCallableNever(),
120
- function ($val) {
121
- return \React\Promise\resolve($val + 1);
122
- }
123
- )
124
- ->then(
125
- $mock,
126
- $this->expectCallableNever()
127
- );
128
- }
129
-
130
- /** @test */
131
- public function shouldPropagateRejectionsWhenErrbackThrows()
132
- {
133
- $adapter = $this->getPromiseTestAdapter();
134
-
135
- $exception = new \Exception();
136
-
137
- $mock = $this->createCallableMock();
138
- $mock
139
- ->expects($this->once())
140
- ->method('__invoke')
141
- ->will($this->throwException($exception));
142
-
143
- $mock2 = $this->createCallableMock();
144
- $mock2
145
- ->expects($this->once())
146
- ->method('__invoke')
147
- ->with($this->identicalTo($exception));
148
-
149
- $adapter->reject(1);
150
- $adapter->promise()
151
- ->then(
152
- $this->expectCallableNever(),
153
- $mock
154
- )
155
- ->then(
156
- $this->expectCallableNever(),
157
- $mock2
158
- );
159
- }
160
-
161
- /** @test */
162
- public function shouldPropagateRejectionsWhenErrbackReturnsARejection()
163
- {
164
- $adapter = $this->getPromiseTestAdapter();
165
-
166
- $mock = $this->createCallableMock();
167
- $mock
168
- ->expects($this->once())
169
- ->method('__invoke')
170
- ->with($this->identicalTo(2));
171
-
172
- $adapter->reject(1);
173
- $adapter->promise()
174
- ->then(
175
- $this->expectCallableNever(),
176
- function ($val) {
177
- return \React\Promise\reject($val + 1);
178
- }
179
- )
180
- ->then(
181
- $this->expectCallableNever(),
182
- $mock
183
- );
184
- }
185
-
186
- /** @test */
187
- public function doneShouldInvokeRejectionHandlerForRejectedPromise()
188
- {
189
- $adapter = $this->getPromiseTestAdapter();
190
-
191
- $mock = $this->createCallableMock();
192
- $mock
193
- ->expects($this->once())
194
- ->method('__invoke')
195
- ->with($this->identicalTo(1));
196
-
197
- $adapter->reject(1);
198
- $this->assertNull($adapter->promise()->done(null, $mock));
199
- }
200
-
201
- /** @test */
202
- public function doneShouldThrowExceptionThrownByRejectionHandlerForRejectedPromise()
203
- {
204
- $adapter = $this->getPromiseTestAdapter();
205
-
206
- $this->setExpectedException('\Exception', 'UnhandledRejectionException');
207
-
208
- $adapter->reject(1);
209
- $this->assertNull($adapter->promise()->done(null, function () {
210
- throw new \Exception('UnhandledRejectionException');
211
- }));
212
- }
213
-
214
- /** @test */
215
- public function doneShouldThrowUnhandledRejectionExceptionWhenRejectedWithNonExceptionForRejectedPromise()
216
- {
217
- $adapter = $this->getPromiseTestAdapter();
218
-
219
- $this->setExpectedException('React\\Promise\\UnhandledRejectionException');
220
-
221
- $adapter->reject(1);
222
- $this->assertNull($adapter->promise()->done());
223
- }
224
-
225
- /** @test */
226
- public function doneShouldThrowUnhandledRejectionExceptionWhenRejectionHandlerRejectsForRejectedPromise()
227
- {
228
- $adapter = $this->getPromiseTestAdapter();
229
-
230
- $this->setExpectedException('React\\Promise\\UnhandledRejectionException');
231
-
232
- $adapter->reject(1);
233
- $this->assertNull($adapter->promise()->done(null, function () {
234
- return \React\Promise\reject();
235
- }));
236
- }
237
-
238
- /** @test */
239
- public function doneShouldThrowRejectionExceptionWhenRejectionHandlerRejectsWithExceptionForRejectedPromise()
240
- {
241
- $adapter = $this->getPromiseTestAdapter();
242
-
243
- $this->setExpectedException('\Exception', 'UnhandledRejectionException');
244
-
245
- $adapter->reject(1);
246
- $this->assertNull($adapter->promise()->done(null, function () {
247
- return \React\Promise\reject(new \Exception('UnhandledRejectionException'));
248
- }));
249
- }
250
-
251
- /** @test */
252
- public function doneShouldThrowExceptionProvidedAsRejectionValueForRejectedPromise()
253
- {
254
- $adapter = $this->getPromiseTestAdapter();
255
-
256
- $this->setExpectedException('\Exception', 'UnhandledRejectionException');
257
-
258
- $adapter->reject(new \Exception('UnhandledRejectionException'));
259
- $this->assertNull($adapter->promise()->done());
260
- }
261
-
262
- /** @test */
263
- public function doneShouldThrowWithDeepNestingPromiseChainsForRejectedPromise()
264
- {
265
- $this->setExpectedException('\Exception', 'UnhandledRejectionException');
266
-
267
- $exception = new \Exception('UnhandledRejectionException');
268
-
269
- $d = new Deferred();
270
- $d->resolve();
271
-
272
- $result = \React\Promise\resolve(\React\Promise\resolve($d->promise()->then(function () use ($exception) {
273
- $d = new Deferred();
274
- $d->resolve();
275
-
276
- return \React\Promise\resolve($d->promise()->then(function () {}))->then(
277
- function () use ($exception) {
278
- throw $exception;
279
- }
280
- );
281
- })));
282
-
283
- $result->done();
284
- }
285
-
286
- /** @test */
287
- public function doneShouldRecoverWhenRejectionHandlerCatchesExceptionForRejectedPromise()
288
- {
289
- $adapter = $this->getPromiseTestAdapter();
290
-
291
- $adapter->reject(new \Exception('UnhandledRejectionException'));
292
- $this->assertNull($adapter->promise()->done(null, function (\Exception $e) {
293
-
294
- }));
295
- }
296
-
297
- /** @test */
298
- public function otherwiseShouldInvokeRejectionHandlerForRejectedPromise()
299
- {
300
- $adapter = $this->getPromiseTestAdapter();
301
-
302
- $mock = $this->createCallableMock();
303
- $mock
304
- ->expects($this->once())
305
- ->method('__invoke')
306
- ->with($this->identicalTo(1));
307
-
308
- $adapter->reject(1);
309
- $adapter->promise()->otherwise($mock);
310
- }
311
-
312
- /** @test */
313
- public function otherwiseShouldInvokeNonTypeHintedRejectionHandlerIfReasonIsAnExceptionForRejectedPromise()
314
- {
315
- $adapter = $this->getPromiseTestAdapter();
316
-
317
- $exception = new \Exception();
318
-
319
- $mock = $this->createCallableMock();
320
- $mock
321
- ->expects($this->once())
322
- ->method('__invoke')
323
- ->with($this->identicalTo($exception));
324
-
325
- $adapter->reject($exception);
326
- $adapter->promise()
327
- ->otherwise(function ($reason) use ($mock) {
328
- $mock($reason);
329
- });
330
- }
331
-
332
- /** @test */
333
- public function otherwiseShouldInvokeRejectionHandlerIfReasonMatchesTypehintForRejectedPromise()
334
- {
335
- $adapter = $this->getPromiseTestAdapter();
336
-
337
- $exception = new \InvalidArgumentException();
338
-
339
- $mock = $this->createCallableMock();
340
- $mock
341
- ->expects($this->once())
342
- ->method('__invoke')
343
- ->with($this->identicalTo($exception));
344
-
345
- $adapter->reject($exception);
346
- $adapter->promise()
347
- ->otherwise(function (\InvalidArgumentException $reason) use ($mock) {
348
- $mock($reason);
349
- });
350
- }
351
-
352
- /** @test */
353
- public function otherwiseShouldNotInvokeRejectionHandlerIfReaonsDoesNotMatchTypehintForRejectedPromise()
354
- {
355
- $adapter = $this->getPromiseTestAdapter();
356
-
357
- $exception = new \Exception();
358
-
359
- $mock = $this->expectCallableNever();
360
-
361
- $adapter->reject($exception);
362
- $adapter->promise()
363
- ->otherwise(function (\InvalidArgumentException $reason) use ($mock) {
364
- $mock($reason);
365
- });
366
- }
367
-
368
- /** @test */
369
- public function alwaysShouldNotSuppressRejectionForRejectedPromise()
370
- {
371
- $adapter = $this->getPromiseTestAdapter();
372
-
373
- $exception = new \Exception();
374
-
375
- $mock = $this->createCallableMock();
376
- $mock
377
- ->expects($this->once())
378
- ->method('__invoke')
379
- ->with($this->identicalTo($exception));
380
-
381
- $adapter->reject($exception);
382
- $adapter->promise()
383
- ->always(function () {})
384
- ->then(null, $mock);
385
- }
386
-
387
- /** @test */
388
- public function alwaysShouldNotSuppressRejectionWhenHandlerReturnsANonPromiseForRejectedPromise()
389
- {
390
- $adapter = $this->getPromiseTestAdapter();
391
-
392
- $exception = new \Exception();
393
-
394
- $mock = $this->createCallableMock();
395
- $mock
396
- ->expects($this->once())
397
- ->method('__invoke')
398
- ->with($this->identicalTo($exception));
399
-
400
- $adapter->reject($exception);
401
- $adapter->promise()
402
- ->always(function () {
403
- return 1;
404
- })
405
- ->then(null, $mock);
406
- }
407
-
408
- /** @test */
409
- public function alwaysShouldNotSuppressRejectionWhenHandlerReturnsAPromiseForRejectedPromise()
410
- {
411
- $adapter = $this->getPromiseTestAdapter();
412
-
413
- $exception = new \Exception();
414
-
415
- $mock = $this->createCallableMock();
416
- $mock
417
- ->expects($this->once())
418
- ->method('__invoke')
419
- ->with($this->identicalTo($exception));
420
-
421
- $adapter->reject($exception);
422
- $adapter->promise()
423
- ->always(function () {
424
- return \React\Promise\resolve(1);
425
- })
426
- ->then(null, $mock);
427
- }
428
-
429
- /** @test */
430
- public function alwaysShouldRejectWhenHandlerThrowsForRejectedPromise()
431
- {
432
- $adapter = $this->getPromiseTestAdapter();
433
-
434
- $exception1 = new \Exception();
435
- $exception2 = new \Exception();
436
-
437
- $mock = $this->createCallableMock();
438
- $mock
439
- ->expects($this->once())
440
- ->method('__invoke')
441
- ->with($this->identicalTo($exception2));
442
-
443
- $adapter->reject($exception1);
444
- $adapter->promise()
445
- ->always(function () use ($exception2) {
446
- throw $exception2;
447
- })
448
- ->then(null, $mock);
449
- }
450
-
451
- /** @test */
452
- public function alwaysShouldRejectWhenHandlerRejectsForRejectedPromise()
453
- {
454
- $adapter = $this->getPromiseTestAdapter();
455
-
456
- $exception1 = new \Exception();
457
- $exception2 = new \Exception();
458
-
459
- $mock = $this->createCallableMock();
460
- $mock
461
- ->expects($this->once())
462
- ->method('__invoke')
463
- ->with($this->identicalTo($exception2));
464
-
465
- $adapter->reject($exception1);
466
- $adapter->promise()
467
- ->always(function () use ($exception2) {
468
- return \React\Promise\reject($exception2);
469
- })
470
- ->then(null, $mock);
471
- }
472
-
473
- /** @test */
474
- public function cancelShouldReturnNullForRejectedPromise()
475
- {
476
- $adapter = $this->getPromiseTestAdapter();
477
-
478
- $adapter->reject();
479
-
480
- $this->assertNull($adapter->promise()->cancel());
481
- }
482
-
483
- /** @test */
484
- public function cancelShouldHaveNoEffectForRejectedPromise()
485
- {
486
- $adapter = $this->getPromiseTestAdapter($this->expectCallableNever());
487
-
488
- $adapter->reject();
489
-
490
- $adapter->promise()->cancel();
491
- }
492
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/PromiseTest/PromiseSettledTestTrait.php DELETED
@@ -1,86 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise\PromiseTest;
4
-
5
- trait PromiseSettledTestTrait
6
- {
7
- /**
8
- * @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
9
- */
10
- abstract public function getPromiseTestAdapter(callable $canceller = null);
11
-
12
- /** @test */
13
- public function thenShouldReturnAPromiseForSettledPromise()
14
- {
15
- $adapter = $this->getPromiseTestAdapter();
16
-
17
- $adapter->settle();
18
- $this->assertInstanceOf('React\\Promise\\PromiseInterface', $adapter->promise()->then());
19
- }
20
-
21
- /** @test */
22
- public function thenShouldReturnAllowNullForSettledPromise()
23
- {
24
- $adapter = $this->getPromiseTestAdapter();
25
-
26
- $adapter->settle();
27
- $this->assertInstanceOf('React\\Promise\\PromiseInterface', $adapter->promise()->then(null, null, null));
28
- }
29
-
30
- /** @test */
31
- public function cancelShouldReturnNullForSettledPromise()
32
- {
33
- $adapter = $this->getPromiseTestAdapter();
34
-
35
- $adapter->settle();
36
-
37
- $this->assertNull($adapter->promise()->cancel());
38
- }
39
-
40
- /** @test */
41
- public function cancelShouldHaveNoEffectForSettledPromise()
42
- {
43
- $adapter = $this->getPromiseTestAdapter($this->expectCallableNever());
44
-
45
- $adapter->settle();
46
-
47
- $adapter->promise()->cancel();
48
- }
49
-
50
- /** @test */
51
- public function doneShouldReturnNullForSettledPromise()
52
- {
53
- $adapter = $this->getPromiseTestAdapter();
54
-
55
- $adapter->settle();
56
- $this->assertNull($adapter->promise()->done(null, function () {}));
57
- }
58
-
59
- /** @test */
60
- public function doneShouldReturnAllowNullForSettledPromise()
61
- {
62
- $adapter = $this->getPromiseTestAdapter();
63
-
64
- $adapter->settle();
65
- $this->assertNull($adapter->promise()->done(null, function () {}, null));
66
- }
67
-
68
- /** @test */
69
- public function progressShouldNotInvokeProgressHandlerForSettledPromise()
70
- {
71
- $adapter = $this->getPromiseTestAdapter();
72
-
73
- $adapter->settle();
74
- $adapter->promise()->progress($this->expectCallableNever());
75
- $adapter->notify();
76
- }
77
-
78
- /** @test */
79
- public function alwaysShouldReturnAPromiseForSettledPromise()
80
- {
81
- $adapter = $this->getPromiseTestAdapter();
82
-
83
- $adapter->settle();
84
- $this->assertInstanceOf('React\\Promise\\PromiseInterface', $adapter->promise()->always(function () {}));
85
- }
86
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/PromiseTest/RejectTestTrait.php DELETED
@@ -1,368 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise\PromiseTest;
4
-
5
- use React\Promise;
6
- use React\Promise\Deferred;
7
-
8
- trait RejectTestTrait
9
- {
10
- /**
11
- * @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
12
- */
13
- abstract public function getPromiseTestAdapter(callable $canceller = null);
14
-
15
- /** @test */
16
- public function rejectShouldRejectWithAnImmediateValue()
17
- {
18
- $adapter = $this->getPromiseTestAdapter();
19
-
20
- $mock = $this->createCallableMock();
21
- $mock
22
- ->expects($this->once())
23
- ->method('__invoke')
24
- ->with($this->identicalTo(1));
25
-
26
- $adapter->promise()
27
- ->then($this->expectCallableNever(), $mock);
28
-
29
- $adapter->reject(1);
30
- }
31
-
32
- /** @test */
33
- public function rejectShouldRejectWithFulfilledPromise()
34
- {
35
- $adapter = $this->getPromiseTestAdapter();
36
-
37
- $mock = $this->createCallableMock();
38
- $mock
39
- ->expects($this->once())
40
- ->method('__invoke')
41
- ->with($this->identicalTo(1));
42
-
43
- $adapter->promise()
44
- ->then($this->expectCallableNever(), $mock);
45
-
46
- $adapter->reject(Promise\resolve(1));
47
- }
48
-
49
- /** @test */
50
- public function rejectShouldRejectWithRejectedPromise()
51
- {
52
- $adapter = $this->getPromiseTestAdapter();
53
-
54
- $mock = $this->createCallableMock();
55
- $mock
56
- ->expects($this->once())
57
- ->method('__invoke')
58
- ->with($this->identicalTo(1));
59
-
60
- $adapter->promise()
61
- ->then($this->expectCallableNever(), $mock);
62
-
63
- $adapter->reject(Promise\reject(1));
64
- }
65
-
66
- /** @test */
67
- public function rejectShouldForwardReasonWhenCallbackIsNull()
68
- {
69
- $adapter = $this->getPromiseTestAdapter();
70
-
71
- $mock = $this->createCallableMock();
72
- $mock
73
- ->expects($this->once())
74
- ->method('__invoke')
75
- ->with($this->identicalTo(1));
76
-
77
- $adapter->promise()
78
- ->then(
79
- $this->expectCallableNever()
80
- )
81
- ->then(
82
- $this->expectCallableNever(),
83
- $mock
84
- );
85
-
86
- $adapter->reject(1);
87
- }
88
-
89
- /** @test */
90
- public function rejectShouldMakePromiseImmutable()
91
- {
92
- $adapter = $this->getPromiseTestAdapter();
93
-
94
- $mock = $this->createCallableMock();
95
- $mock
96
- ->expects($this->once())
97
- ->method('__invoke')
98
- ->with($this->identicalTo(1));
99
-
100
- $adapter->promise()
101
- ->then(null, function ($value) use ($adapter) {
102
- $adapter->reject(3);
103
-
104
- return Promise\reject($value);
105
- })
106
- ->then(
107
- $this->expectCallableNever(),
108
- $mock
109
- );
110
-
111
- $adapter->reject(1);
112
- $adapter->reject(2);
113
- }
114
-
115
- /** @test */
116
- public function notifyShouldInvokeOtherwiseHandler()
117
- {
118
- $adapter = $this->getPromiseTestAdapter();
119
-
120
- $mock = $this->createCallableMock();
121
- $mock
122
- ->expects($this->once())
123
- ->method('__invoke')
124
- ->with($this->identicalTo(1));
125
-
126
- $adapter->promise()
127
- ->otherwise($mock);
128
-
129
- $adapter->reject(1);
130
- }
131
-
132
- /** @test */
133
- public function doneShouldInvokeRejectionHandler()
134
- {
135
- $adapter = $this->getPromiseTestAdapter();
136
-
137
- $mock = $this->createCallableMock();
138
- $mock
139
- ->expects($this->once())
140
- ->method('__invoke')
141
- ->with($this->identicalTo(1));
142
-
143
- $this->assertNull($adapter->promise()->done(null, $mock));
144
- $adapter->reject(1);
145
- }
146
-
147
- /** @test */
148
- public function doneShouldThrowExceptionThrownByRejectionHandler()
149
- {
150
- $adapter = $this->getPromiseTestAdapter();
151
-
152
- $this->setExpectedException('\Exception', 'UnhandledRejectionException');
153
-
154
- $this->assertNull($adapter->promise()->done(null, function () {
155
- throw new \Exception('UnhandledRejectionException');
156
- }));
157
- $adapter->reject(1);
158
- }
159
-
160
- /** @test */
161
- public function doneShouldThrowUnhandledRejectionExceptionWhenRejectedWithNonException()
162
- {
163
- $adapter = $this->getPromiseTestAdapter();
164
-
165
- $this->setExpectedException('React\\Promise\\UnhandledRejectionException');
166
-
167
- $this->assertNull($adapter->promise()->done());
168
- $adapter->reject(1);
169
- }
170
-
171
- /** @test */
172
- public function doneShouldThrowUnhandledRejectionExceptionWhenRejectionHandlerRejects()
173
- {
174
- $adapter = $this->getPromiseTestAdapter();
175
-
176
- $this->setExpectedException('React\\Promise\\UnhandledRejectionException');
177
-
178
- $this->assertNull($adapter->promise()->done(null, function () {
179
- return \React\Promise\reject();
180
- }));
181
- $adapter->reject(1);
182
- }
183
-
184
- /** @test */
185
- public function doneShouldThrowRejectionExceptionWhenRejectionHandlerRejectsWithException()
186
- {
187
- $adapter = $this->getPromiseTestAdapter();
188
-
189
- $this->setExpectedException('\Exception', 'UnhandledRejectionException');
190
-
191
- $this->assertNull($adapter->promise()->done(null, function () {
192
- return \React\Promise\reject(new \Exception('UnhandledRejectionException'));
193
- }));
194
- $adapter->reject(1);
195
- }
196
-
197
- /** @test */
198
- public function doneShouldThrowUnhandledRejectionExceptionWhenRejectionHandlerRetunsPendingPromiseWhichRejectsLater()
199
- {
200
- $adapter = $this->getPromiseTestAdapter();
201
-
202
- $this->setExpectedException('React\\Promise\\UnhandledRejectionException');
203
-
204
- $d = new Deferred();
205
- $promise = $d->promise();
206
-
207
- $this->assertNull($adapter->promise()->done(null, function () use ($promise) {
208
- return $promise;
209
- }));
210
- $adapter->reject(1);
211
- $d->reject(1);
212
- }
213
-
214
- /** @test */
215
- public function doneShouldThrowExceptionProvidedAsRejectionValue()
216
- {
217
- $adapter = $this->getPromiseTestAdapter();
218
-
219
- $this->setExpectedException('\Exception', 'UnhandledRejectionException');
220
-
221
- $this->assertNull($adapter->promise()->done());
222
- $adapter->reject(new \Exception('UnhandledRejectionException'));
223
- }
224
-
225
- /** @test */
226
- public function doneShouldThrowWithDeepNestingPromiseChains()
227
- {
228
- $this->setExpectedException('\Exception', 'UnhandledRejectionException');
229
-
230
- $exception = new \Exception('UnhandledRejectionException');
231
-
232
- $d = new Deferred();
233
-
234
- $result = \React\Promise\resolve(\React\Promise\resolve($d->promise()->then(function () use ($exception) {
235
- $d = new Deferred();
236
- $d->resolve();
237
-
238
- return \React\Promise\resolve($d->promise()->then(function () {}))->then(
239
- function () use ($exception) {
240
- throw $exception;
241
- }
242
- );
243
- })));
244
-
245
- $result->done();
246
-
247
- $d->resolve();
248
- }
249
-
250
- /** @test */
251
- public function doneShouldRecoverWhenRejectionHandlerCatchesException()
252
- {
253
- $adapter = $this->getPromiseTestAdapter();
254
-
255
- $this->assertNull($adapter->promise()->done(null, function (\Exception $e) {
256
-
257
- }));
258
- $adapter->reject(new \Exception('UnhandledRejectionException'));
259
- }
260
-
261
- /** @test */
262
- public function alwaysShouldNotSuppressRejection()
263
- {
264
- $adapter = $this->getPromiseTestAdapter();
265
-
266
- $exception = new \Exception();
267
-
268
- $mock = $this->createCallableMock();
269
- $mock
270
- ->expects($this->once())
271
- ->method('__invoke')
272
- ->with($this->identicalTo($exception));
273
-
274
- $adapter->promise()
275
- ->always(function () {})
276
- ->then(null, $mock);
277
-
278
- $adapter->reject($exception);
279
- }
280
-
281
- /** @test */
282
- public function alwaysShouldNotSuppressRejectionWhenHandlerReturnsANonPromise()
283
- {
284
- $adapter = $this->getPromiseTestAdapter();
285
-
286
- $exception = new \Exception();
287
-
288
- $mock = $this->createCallableMock();
289
- $mock
290
- ->expects($this->once())
291
- ->method('__invoke')
292
- ->with($this->identicalTo($exception));
293
-
294
- $adapter->promise()
295
- ->always(function () {
296
- return 1;
297
- })
298
- ->then(null, $mock);
299
-
300
- $adapter->reject($exception);
301
- }
302
-
303
- /** @test */
304
- public function alwaysShouldNotSuppressRejectionWhenHandlerReturnsAPromise()
305
- {
306
- $adapter = $this->getPromiseTestAdapter();
307
-
308
- $exception = new \Exception();
309
-
310
- $mock = $this->createCallableMock();
311
- $mock
312
- ->expects($this->once())
313
- ->method('__invoke')
314
- ->with($this->identicalTo($exception));
315
-
316
- $adapter->promise()
317
- ->always(function () {
318
- return \React\Promise\resolve(1);
319
- })
320
- ->then(null, $mock);
321
-
322
- $adapter->reject($exception);
323
- }
324
-
325
- /** @test */
326
- public function alwaysShouldRejectWhenHandlerThrowsForRejection()
327
- {
328
- $adapter = $this->getPromiseTestAdapter();
329
-
330
- $exception = new \Exception();
331
-
332
- $mock = $this->createCallableMock();
333
- $mock
334
- ->expects($this->once())
335
- ->method('__invoke')
336
- ->with($this->identicalTo($exception));
337
-
338
- $adapter->promise()
339
- ->always(function () use ($exception) {
340
- throw $exception;
341
- })
342
- ->then(null, $mock);
343
-
344
- $adapter->reject($exception);
345
- }
346
-
347
- /** @test */
348
- public function alwaysShouldRejectWhenHandlerRejectsForRejection()
349
- {
350
- $adapter = $this->getPromiseTestAdapter();
351
-
352
- $exception = new \Exception();
353
-
354
- $mock = $this->createCallableMock();
355
- $mock
356
- ->expects($this->once())
357
- ->method('__invoke')
358
- ->with($this->identicalTo($exception));
359
-
360
- $adapter->promise()
361
- ->always(function () use ($exception) {
362
- return \React\Promise\reject($exception);
363
- })
364
- ->then(null, $mock);
365
-
366
- $adapter->reject($exception);
367
- }
368
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/PromiseTest/ResolveTestTrait.php DELETED
@@ -1,263 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise\PromiseTest;
4
-
5
- use React\Promise;
6
-
7
- trait ResolveTestTrait
8
- {
9
- /**
10
- * @return \React\Promise\PromiseAdapter\PromiseAdapterInterface
11
- */
12
- abstract public function getPromiseTestAdapter(callable $canceller = null);
13
-
14
- /** @test */
15
- public function resolveShouldResolve()
16
- {
17
- $adapter = $this->getPromiseTestAdapter();
18
-
19
- $mock = $this->createCallableMock();
20
- $mock
21
- ->expects($this->once())
22
- ->method('__invoke')
23
- ->with($this->identicalTo(1));
24
-
25
- $adapter->promise()
26
- ->then($mock);
27
-
28
- $adapter->resolve(1);
29
- }
30
-
31
- /** @test */
32
- public function resolveShouldResolveWithPromisedValue()
33
- {
34
- $adapter = $this->getPromiseTestAdapter();
35
-
36
- $mock = $this->createCallableMock();
37
- $mock
38
- ->expects($this->once())
39
- ->method('__invoke')
40
- ->with($this->identicalTo(1));
41
-
42
- $adapter->promise()
43
- ->then($mock);
44
-
45
- $adapter->resolve(Promise\resolve(1));
46
- }
47
-
48
- /** @test */
49
- public function resolveShouldRejectWhenResolvedWithRejectedPromise()
50
- {
51
- $adapter = $this->getPromiseTestAdapter();
52
-
53
- $mock = $this->createCallableMock();
54
- $mock
55
- ->expects($this->once())
56
- ->method('__invoke')
57
- ->with($this->identicalTo(1));
58
-
59
- $adapter->promise()
60
- ->then($this->expectCallableNever(), $mock);
61
-
62
- $adapter->resolve(Promise\reject(1));
63
- }
64
-
65
- /** @test */
66
- public function resolveShouldForwardValueWhenCallbackIsNull()
67
- {
68
- $adapter = $this->getPromiseTestAdapter();
69
-
70
- $mock = $this->createCallableMock();
71
- $mock
72
- ->expects($this->once())
73
- ->method('__invoke')
74
- ->with($this->identicalTo(1));
75
-
76
- $adapter->promise()
77
- ->then(
78
- null,
79
- $this->expectCallableNever()
80
- )
81
- ->then(
82
- $mock,
83
- $this->expectCallableNever()
84
- );
85
-
86
- $adapter->resolve(1);
87
- }
88
-
89
- /** @test */
90
- public function resolveShouldMakePromiseImmutable()
91
- {
92
- $adapter = $this->getPromiseTestAdapter();
93
-
94
- $mock = $this->createCallableMock();
95
- $mock
96
- ->expects($this->once())
97
- ->method('__invoke')
98
- ->with($this->identicalTo(1));
99
-
100
- $adapter->promise()
101
- ->then(function ($value) use ($adapter) {
102
- $adapter->resolve(3);
103
-
104
- return $value;
105
- })
106
- ->then(
107
- $mock,
108
- $this->expectCallableNever()
109
- );
110
-
111
- $adapter->resolve(1);
112
- $adapter->resolve(2);
113
- }
114
-
115
- /** @test */
116
- public function doneShouldInvokeFulfillmentHandler()
117
- {
118
- $adapter = $this->getPromiseTestAdapter();
119
-
120
- $mock = $this->createCallableMock();
121
- $mock
122
- ->expects($this->once())
123
- ->method('__invoke')
124
- ->with($this->identicalTo(1));
125
-
126
- $this->assertNull($adapter->promise()->done($mock));
127
- $adapter->resolve(1);
128
- }
129
-
130
- /** @test */
131
- public function doneShouldThrowExceptionThrownFulfillmentHandler()
132
- {
133
- $adapter = $this->getPromiseTestAdapter();
134
-
135
- $this->setExpectedException('\Exception', 'UnhandledRejectionException');
136
-
137
- $this->assertNull($adapter->promise()->done(function () {
138
- throw new \Exception('UnhandledRejectionException');
139
- }));
140
- $adapter->resolve(1);
141
- }
142
-
143
- /** @test */
144
- public function doneShouldThrowUnhandledRejectionExceptionWhenFulfillmentHandlerRejects()
145
- {
146
- $adapter = $this->getPromiseTestAdapter();
147
-
148
- $this->setExpectedException('React\\Promise\\UnhandledRejectionException');
149
-
150
- $this->assertNull($adapter->promise()->done(function () {
151
- return \React\Promise\reject();
152
- }));
153
- $adapter->resolve(1);
154
- }
155
-
156
- /** @test */
157
- public function alwaysShouldNotSuppressValue()
158
- {
159
- $adapter = $this->getPromiseTestAdapter();
160
-
161
- $value = new \stdClass();
162
-
163
- $mock = $this->createCallableMock();
164
- $mock
165
- ->expects($this->once())
166
- ->method('__invoke')
167
- ->with($this->identicalTo($value));
168
-
169
- $adapter->promise()
170
- ->always(function () {})
171
- ->then($mock);
172
-
173
- $adapter->resolve($value);
174
- }
175
-
176
- /** @test */
177
- public function alwaysShouldNotSuppressValueWhenHandlerReturnsANonPromise()
178
- {
179
- $adapter = $this->getPromiseTestAdapter();
180
-
181
- $value = new \stdClass();
182
-
183
- $mock = $this->createCallableMock();
184
- $mock
185
- ->expects($this->once())
186
- ->method('__invoke')
187
- ->with($this->identicalTo($value));
188
-
189
- $adapter->promise()
190
- ->always(function () {
191
- return 1;
192
- })
193
- ->then($mock);
194
-
195
- $adapter->resolve($value);
196
- }
197
-
198
- /** @test */
199
- public function alwaysShouldNotSuppressValueWhenHandlerReturnsAPromise()
200
- {
201
- $adapter = $this->getPromiseTestAdapter();
202
-
203
- $value = new \stdClass();
204
-
205
- $mock = $this->createCallableMock();
206
- $mock
207
- ->expects($this->once())
208
- ->method('__invoke')
209
- ->with($this->identicalTo($value));
210
-
211
- $adapter->promise()
212
- ->always(function () {
213
- return \React\Promise\resolve(1);
214
- })
215
- ->then($mock);
216
-
217
- $adapter->resolve($value);
218
- }
219
-
220
- /** @test */
221
- public function alwaysShouldRejectWhenHandlerThrowsForFulfillment()
222
- {
223
- $adapter = $this->getPromiseTestAdapter();
224
-
225
- $exception = new \Exception();
226
-
227
- $mock = $this->createCallableMock();
228
- $mock
229
- ->expects($this->once())
230
- ->method('__invoke')
231
- ->with($this->identicalTo($exception));
232
-
233
- $adapter->promise()
234
- ->always(function () use ($exception) {
235
- throw $exception;
236
- })
237
- ->then(null, $mock);
238
-
239
- $adapter->resolve(1);
240
- }
241
-
242
- /** @test */
243
- public function alwaysShouldRejectWhenHandlerRejectsForFulfillment()
244
- {
245
- $adapter = $this->getPromiseTestAdapter();
246
-
247
- $exception = new \Exception();
248
-
249
- $mock = $this->createCallableMock();
250
- $mock
251
- ->expects($this->once())
252
- ->method('__invoke')
253
- ->with($this->identicalTo($exception));
254
-
255
- $adapter->promise()
256
- ->always(function () use ($exception) {
257
- return \React\Promise\reject($exception);
258
- })
259
- ->then(null, $mock);
260
-
261
- $adapter->resolve(1);
262
- }
263
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/RejectedPromiseTest.php DELETED
@@ -1,50 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise;
4
-
5
- use React\Promise\PromiseAdapter\CallbackPromiseAdapter;
6
-
7
- class RejectedPromiseTest extends TestCase
8
- {
9
- use PromiseTest\PromiseSettledTestTrait,
10
- PromiseTest\PromiseRejectedTestTrait;
11
-
12
- public function getPromiseTestAdapter(callable $canceller = null)
13
- {
14
- $promise = null;
15
-
16
- return new CallbackPromiseAdapter([
17
- 'promise' => function () use (&$promise) {
18
- if (!$promise) {
19
- throw new \LogicException('RejectedPromise must be rejected before obtaining the promise');
20
- }
21
-
22
- return $promise;
23
- },
24
- 'resolve' => function () {
25
- throw new \LogicException('You cannot call resolve() for React\Promise\RejectedPromise');
26
- },
27
- 'reject' => function ($reason = null) use (&$promise) {
28
- if (!$promise) {
29
- $promise = new RejectedPromise($reason);
30
- }
31
- },
32
- 'notify' => function () {
33
- // no-op
34
- },
35
- 'settle' => function ($reason = null) use (&$promise) {
36
- if (!$promise) {
37
- $promise = new RejectedPromise($reason);
38
- }
39
- },
40
- ]);
41
- }
42
-
43
- /** @test */
44
- public function shouldThrowExceptionIfConstructedWithAPromise()
45
- {
46
- $this->setExpectedException('\InvalidArgumentException');
47
-
48
- return new RejectedPromise(new RejectedPromise());
49
- }
50
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/Stub/CallableStub.php DELETED
@@ -1,10 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise\Stub;
4
-
5
- class CallableStub
6
- {
7
- public function __invoke()
8
- {
9
- }
10
- }
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/TestCase.php DELETED
@@ -1,41 +0,0 @@
1
- <?php
2
-
3
- namespace React\Promise;
4
-
5
- class TestCase extends \PHPUnit_Framework_TestCase
6
- {
7
- public function expectCallableExactly($amount)
8
- {
9
- $mock = $this->createCallableMock();
10
- $mock
11
- ->expects($this->exactly($amount))
12
- ->method('__invoke');
13
-
14
- return $mock;
15
- }
16
-
17
- public function expectCallableOnce()
18
- {
19
- $mock = $this->createCallableMock();
20
- $mock
21
- ->expects($this->once())
22
- ->method('__invoke');
23
-
24
- return $mock;
25
- }
26
-
27
- public function expectCallableNever()
28
- {
29
- $mock = $this->createCallableMock();
30
- $mock
31
- ->expects($this->never())
32
- ->method('__invoke');
33
-
34
- return $mock;
35
- }
36
-
37
- public function createCallableMock()
38
- {
39
- return $this->getMock('React\\Promise\Stub\CallableStub');
40
- }
41
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/constantcontact/react/promise/tests/bootstrap.php DELETED
@@ -1,7 +0,0 @@
1
- <?php
2
-
3
- $loader = @include __DIR__.'/../vendor/autoload.php';
4
- if (!$loader) {
5
- $loader = require __DIR__.'/../../../../vendor/autoload.php';
6
- }
7
- $loader->addPsr4('React\\Promise\\', __DIR__);
 
 
 
 
 
 
 
vendor/monolog/monolog/{CHANGELOG.mdown → CHANGELOG.md} RENAMED
@@ -1,3 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ### 1.21.0 (2016-07-29)
2
 
3
  * Break: Reverted the addition of $context when the ErrorHandler handles regular php errors from 1.20.0 as it was causing issues
1
+ ### 1.23.0 (2017-06-19)
2
+
3
+ * Improved SyslogUdpHandler's support for RFC5424 and added optional `$ident` argument
4
+ * Fixed GelfHandler truncation to be per field and not per message
5
+ * Fixed compatibility issue with PHP <5.3.6
6
+ * Fixed support for headless Chrome in ChromePHPHandler
7
+ * Fixed support for latest Aws SDK in DynamoDbHandler
8
+ * Fixed support for SwiftMailer 6.0+ in SwiftMailerHandler
9
+
10
+ ### 1.22.1 (2017-03-13)
11
+
12
+ * Fixed lots of minor issues in the new Slack integrations
13
+ * Fixed support for allowInlineLineBreaks in LineFormatter when formatting exception backtraces
14
+
15
+ ### 1.22.0 (2016-11-26)
16
+
17
+ * Added SlackbotHandler and SlackWebhookHandler to set up Slack integration more easily
18
+ * Added MercurialProcessor to add mercurial revision and branch names to log records
19
+ * Added support for AWS SDK v3 in DynamoDbHandler
20
+ * Fixed fatal errors occuring when normalizing generators that have been fully consumed
21
+ * Fixed RollbarHandler to include a level (rollbar level), monolog_level (original name), channel and datetime (unix)
22
+ * Fixed RollbarHandler not flushing records automatically, calling close() explicitly is not necessary anymore
23
+ * Fixed SyslogUdpHandler to avoid sending empty frames
24
+ * Fixed a few PHP 7.0 and 7.1 compatibility issues
25
+
26
  ### 1.21.0 (2016-07-29)
27
 
28
  * Break: Reverted the addition of $context when the ErrorHandler handles regular php errors from 1.20.0 as it was causing issues
vendor/monolog/monolog/{README.mdown → README.md} RENAMED
File without changes
vendor/monolog/monolog/doc/01-usage.md DELETED
@@ -1,231 +0,0 @@
1
- # Using Monolog
2
-
3
- - [Installation](#installation)
4
- - [Core Concepts](#core-concepts)
5
- - [Log Levels](#log-levels)
6
- - [Configuring a logger](#configuring-a-logger)
7
- - [Adding extra data in the records](#adding-extra-data-in-the-records)
8
- - [Leveraging channels](#leveraging-channels)
9
- - [Customizing the log format](#customizing-the-log-format)
10
-
11
- ## Installation
12
-
13
- Monolog is available on Packagist ([monolog/monolog](http://packagist.org/packages/monolog/monolog))
14
- and as such installable via [Composer](http://getcomposer.org/).
15
-
16
- ```bash
17
- composer require monolog/monolog
18
- ```
19
-
20
- If you do not use Composer, you can grab the code from GitHub, and use any
21
- PSR-0 compatible autoloader (e.g. the [Symfony2 ClassLoader component](https://github.com/symfony/ClassLoader))
22
- to load Monolog classes.
23
-
24
- ## Core Concepts
25
-
26
- Every `Logger` instance has a channel (name) and a stack of handlers. Whenever
27
- you add a record to the logger, it traverses the handler stack. Each handler
28
- decides whether it fully handled the record, and if so, the propagation of the
29
- record ends there.
30
-
31
- This allows for flexible logging setups, for example having a `StreamHandler` at
32
- the bottom of the stack that will log anything to disk, and on top of that add
33
- a `MailHandler` that will send emails only when an error message is logged.
34
- Handlers also have a `$bubble` property which defines whether they block the
35
- record or not if they handled it. In this example, setting the `MailHandler`'s
36
- `$bubble` argument to false means that records handled by the `MailHandler` will
37
- not propagate to the `StreamHandler` anymore.
38
-
39
- You can create many `Logger`s, each defining a channel (e.g.: db, request,
40
- router, ..) and each of them combining various handlers, which can be shared
41
- or not. The channel is reflected in the logs and allows you to easily see or
42
- filter records.
43
-
44
- Each Handler also has a Formatter, a default one with settings that make sense
45
- will be created if you don't set one. The formatters normalize and format
46
- incoming records so that they can be used by the handlers to output useful
47
- information.
48
-
49
- Custom severity levels are not available. Only the eight
50
- [RFC 5424](http://tools.ietf.org/html/rfc5424) levels (debug, info, notice,
51
- warning, error, critical, alert, emergency) are present for basic filtering
52
- purposes, but for sorting and other use cases that would require
53
- flexibility, you should add Processors to the Logger that can add extra
54
- information (tags, user ip, ..) to the records before they are handled.
55
-
56
- ## Log Levels
57
-
58
- Monolog supports the logging levels described by [RFC 5424](http://tools.ietf.org/html/rfc5424).
59
-
60
- - **DEBUG** (100): Detailed debug information.
61
-
62
- - **INFO** (200): Interesting events. Examples: User logs in, SQL logs.
63
-
64
- - **NOTICE** (250): Normal but significant events.
65
-
66
- - **WARNING** (300): Exceptional occurrences that are not errors. Examples:
67
- Use of deprecated APIs, poor use of an API, undesirable things that are not
68
- necessarily wrong.
69
-
70
- - **ERROR** (400): Runtime errors that do not require immediate action but
71
- should typically be logged and monitored.
72
-
73
- - **CRITICAL** (500): Critical conditions. Example: Application component
74
- unavailable, unexpected exception.
75
-
76
- - **ALERT** (550): Action must be taken immediately. Example: Entire website
77
- down, database unavailable, etc. This should trigger the SMS alerts and wake
78
- you up.
79
-
80
- - **EMERGENCY** (600): Emergency: system is unusable.
81
-
82
- ## Configuring a logger
83
-
84
- Here is a basic setup to log to a file and to firephp on the DEBUG level:
85
-
86
- ```php
87
- <?php
88
-
89
- use Monolog\Logger;
90
- use Monolog\Handler\StreamHandler;
91
- use Monolog\Handler\FirePHPHandler;
92
-
93
- // Create the logger
94
- $logger = new Logger('my_logger');
95
- // Now add some handlers
96
- $logger->pushHandler(new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG));
97
- $logger->pushHandler(new FirePHPHandler());
98
-
99
- // You can now use your logger
100
- $logger->addInfo('My logger is now ready');
101
- ```
102
-
103
- Let's explain it. The first step is to create the logger instance which will
104
- be used in your code. The argument is a channel name, which is useful when
105
- you use several loggers (see below for more details about it).
106
-
107
- The logger itself does not know how to handle a record. It delegates it to
108
- some handlers. The code above registers two handlers in the stack to allow
109
- handling records in two different ways.
110
-
111
- Note that the FirePHPHandler is called first as it is added on top of the
112
- stack. This allows you to temporarily add a logger with bubbling disabled if
113
- you want to override other configured loggers.
114
-
115
- > If you use Monolog standalone and are looking for an easy way to
116
- > configure many handlers, the [theorchard/monolog-cascade](https://github.com/theorchard/monolog-cascade)
117
- > can help you build complex logging configs via PHP arrays, yaml or json configs.
118
-
119
- ## Adding extra data in the records
120
-
121
- Monolog provides two different ways to add extra informations along the simple
122
- textual message.
123
-
124
- ### Using the logging context
125
-
126
- The first way is the context, allowing to pass an array of data along the
127
- record:
128
-
129
- ```php
130
- <?php
131
-
132
- $logger->addInfo('Adding a new user', array('username' => 'Seldaek'));
133
- ```
134
-
135
- Simple handlers (like the StreamHandler for instance) will simply format
136
- the array to a string but richer handlers can take advantage of the context
137
- (FirePHP is able to display arrays in pretty way for instance).
138
-
139
- ### Using processors
140
-
141
- The second way is to add extra data for all records by using a processor.
142
- Processors can be any callable. They will get the record as parameter and
143
- must return it after having eventually changed the `extra` part of it. Let's
144
- write a processor adding some dummy data in the record:
145
-
146
- ```php
147
- <?php
148
-
149
- $logger->pushProcessor(function ($record) {
150
- $record['extra']['dummy'] = 'Hello world!';
151
-
152
- return $record;
153
- });
154
- ```
155
-
156
- Monolog provides some built-in processors that can be used in your project.
157
- Look at the [dedicated chapter](https://github.com/Seldaek/monolog/blob/master/doc/02-handlers-formatters-processors.md#processors) for the list.
158
-
159
- > Tip: processors can also be registered on a specific handler instead of
160
- the logger to apply only for this handler.
161
-
162
- ## Leveraging channels
163
-
164
- Channels are a great way to identify to which part of the application a record
165
- is related. This is useful in big applications (and is leveraged by
166
- MonologBundle in Symfony2).
167
-
168
- Picture two loggers sharing a handler that writes to a single log file.
169
- Channels would allow you to identify the logger that issued every record.
170
- You can easily grep through the log files filtering this or that channel.
171
-
172
- ```php
173
- <?php
174
-
175
- use Monolog\Logger;
176
- use Monolog\Handler\StreamHandler;
177
- use Monolog\Handler\FirePHPHandler;
178
-
179
- // Create some handlers
180
- $stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG);
181
- $firephp = new FirePHPHandler();
182
-
183
- // Create the main logger of the app
184
- $logger = new Logger('my_logger');
185
- $logger->pushHandler($stream);
186
- $logger->pushHandler($firephp);
187
-
188
- // Create a logger for the security-related stuff with a different channel
189
- $securityLogger = new Logger('security');
190
- $securityLogger->pushHandler($stream);
191
- $securityLogger->pushHandler($firephp);
192
-
193
- // Or clone the first one to only change the channel
194
- $securityLogger = $logger->withName('security');
195
- ```
196
-
197
- ## Customizing the log format
198
-
199
- In Monolog it's easy to customize the format of the logs written into files,
200
- sockets, mails, databases and other handlers. Most of the handlers use the
201
-
202
- ```php
203
- $record['formatted']
204
- ```
205
-
206
- value to be automatically put into the log device. This value depends on the
207
- formatter settings. You can choose between predefined formatter classes or
208
- write your own (e.g. a multiline text file for human-readable output).
209
-
210
- To configure a predefined formatter class, just set it as the handler's field:
211
-
212
- ```php
213
- // the default date format is "Y-m-d H:i:s"
214
- $dateFormat = "Y n j, g:i a";
215
- // the default output format is "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"
216
- $output = "%datetime% > %level_name% > %message% %context% %extra%\n";
217
- // finally, create a formatter
218
- $formatter = new LineFormatter($output, $dateFormat);
219
-
220
- // Create a handler
221
- $stream = new StreamHandler(__DIR__.'/my_app.log', Logger::DEBUG);
222
- $stream->setFormatter($formatter);
223
- // bind it to a logger object
224
- $securityLogger = new Logger('security');
225
- $securityLogger->pushHandler($stream);
226
- ```
227
-
228
- You may also reuse the same formatter between multiple handlers and share those
229
- handlers between multiple loggers.
230
-
231
- [Handlers, Formatters and Processors](02-handlers-formatters-processors.md) &rarr;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/doc/02-handlers-formatters-processors.md DELETED
@@ -1,155 +0,0 @@
1
- # Handlers, Formatters and Processors
2
-
3
- - [Handlers](#handlers)
4
- - [Log to files and syslog](#log-to-files-and-syslog)
5
- - [Send alerts and emails](#send-alerts-and-emails)
6
- - [Log specific servers and networked logging](#log-specific-servers-and-networked-logging)
7
- - [Logging in development](#logging-in-development)
8
- - [Log to databases](#log-to-databases)
9
- - [Wrappers / Special Handlers](#wrappers--special-handlers)
10
- - [Formatters](#formatters)
11
- - [Processors](#processors)
12
- - [Third Party Packages](#third-party-packages)
13
-
14
- ## Handlers
15
-
16
- ### Log to files and syslog
17
-
18
- - _StreamHandler_: Logs records into any PHP stream, use this for log files.
19
- - _RotatingFileHandler_: Logs records to a file and creates one logfile per day.
20
- It will also delete files older than `$maxFiles`. You should use
21
- [logrotate](http://linuxcommand.org/man_pages/logrotate8.html) for high profile
22
- setups though, this is just meant as a quick and dirty solution.
23
- - _SyslogHandler_: Logs records to the syslog.
24
- - _ErrorLogHandler_: Logs records to PHP's
25
- [`error_log()`](http://docs.php.net/manual/en/function.error-log.php) function.
26
-
27
- ### Send alerts and emails
28
-
29
- - _NativeMailerHandler_: Sends emails using PHP's
30
- [`mail()`](http://php.net/manual/en/function.mail.php) function.
31
- - _SwiftMailerHandler_: Sends emails using a [`Swift_Mailer`](http://swiftmailer.org/) instance.
32
- - _PushoverHandler_: Sends mobile notifications via the [Pushover](https://www.pushover.net/) API.
33
- - _HipChatHandler_: Logs records to a [HipChat](http://hipchat.com) chat room using its API.
34
- - _FlowdockHandler_: Logs records to a [Flowdock](https://www.flowdock.com/) account.
35
- - _SlackHandler_: Logs records to a [Slack](https://www.slack.com/) account.
36
- - _MandrillHandler_: Sends emails via the Mandrill API using a [`Swift_Message`](http://swiftmailer.org/) instance.
37
- - _FleepHookHandler_: Logs records to a [Fleep](https://fleep.io/) conversation using Webhooks.
38
- - _IFTTTHandler_: Notifies an [IFTTT](https://ifttt.com/maker) trigger with the log channel, level name and message.
39
-
40
- ### Log specific servers and networked logging
41
-
42
- - _SocketHandler_: Logs records to [sockets](http://php.net/fsockopen), use this
43
- for UNIX and TCP sockets. See an [example](sockets.md).
44
- - _AmqpHandler_: Logs records to an [amqp](http://www.amqp.org/) compatible
45
- server. Requires the [php-amqp](http://pecl.php.net/package/amqp) extension (1.0+).
46
- - _GelfHandler_: Logs records to a [Graylog2](http://www.graylog2.org) server.
47
- - _CubeHandler_: Logs records to a [Cube](http://square.github.com/cube/) server.
48
- - _RavenHandler_: Logs records to a [Sentry](http://getsentry.com/) server using
49
- [raven](https://packagist.org/packages/raven/raven).
50
- - _ZendMonitorHandler_: Logs records to the Zend Monitor present in Zend Server.
51
- - _NewRelicHandler_: Logs records to a [NewRelic](http://newrelic.com/) application.
52
- - _LogglyHandler_: Logs records to a [Loggly](http://www.loggly.com/) account.
53
- - _RollbarHandler_: Logs records to a [Rollbar](https://rollbar.com/) account.
54
- - _SyslogUdpHandler_: Logs records to a remote [Syslogd](http://www.rsyslog.com/) server.
55
- - _LogEntriesHandler_: Logs records to a [LogEntries](http://logentries.com/) account.
56
-
57
- ### Logging in development
58
-
59
- - _FirePHPHandler_: Handler for [FirePHP](http://www.firephp.org/), providing
60
- inline `console` messages within [FireBug](http://getfirebug.com/).
61
- - _ChromePHPHandler_: Handler for [ChromePHP](http://www.chromephp.com/), providing
62
- inline `console` messages within Chrome.
63
- - _BrowserConsoleHandler_: Handler to send logs to browser's Javascript `console` with
64
- no browser extension required. Most browsers supporting `console` API are supported.
65
- - _PHPConsoleHandler_: Handler for [PHP Console](https://chrome.google.com/webstore/detail/php-console/nfhmhhlpfleoednkpnnnkolmclajemef), providing
66
- inline `console` and notification popup messages within Chrome.
67
-
68
- ### Log to databases
69
-
70
- - _RedisHandler_: Logs records to a [redis](http://redis.io) server.
71
- - _MongoDBHandler_: Handler to write records in MongoDB via a
72
- [Mongo](http://pecl.php.net/package/mongo) extension connection.
73
- - _CouchDBHandler_: Logs records to a CouchDB server.
74
- - _DoctrineCouchDBHandler_: Logs records to a CouchDB server via the Doctrine CouchDB ODM.
75
- - _ElasticSearchHandler_: Logs records to an Elastic Search server.
76
- - _DynamoDbHandler_: Logs records to a DynamoDB table with the [AWS SDK](https://github.com/aws/aws-sdk-php).
77
-
78
- ### Wrappers / Special Handlers
79
-
80
- - _FingersCrossedHandler_: A very interesting wrapper. It takes a logger as
81
- parameter and will accumulate log records of all levels until a record
82
- exceeds the defined severity level. At which point it delivers all records,
83
- including those of lower severity, to the handler it wraps. This means that
84
- until an error actually happens you will not see anything in your logs, but
85
- when it happens you will have the full information, including debug and info
86
- records. This provides you with all the information you need, but only when
87
- you need it.
88
- - _DeduplicationHandler_: Useful if you are sending notifications or emails
89
- when critical errors occur. It takes a logger as parameter and will
90
- accumulate log records of all levels until the end of the request (or
91
- `flush()` is called). At that point it delivers all records to the handler
92
- it wraps, but only if the records are unique over a given time period
93
- (60seconds by default). If the records are duplicates they are simply
94
- discarded. The main use of this is in case of critical failure like if your
95
- database is unreachable for example all your requests will fail and that
96
- can result in a lot of notifications being sent. Adding this handler reduces
97
- the amount of notifications to a manageable level.
98
- - _WhatFailureGroupHandler_: This handler extends the _GroupHandler_ ignoring
99
- exceptions raised by each child handler. This allows you to ignore issues
100
- where a remote tcp connection may have died but you do not want your entire
101
- application to crash and may wish to continue to log to other handlers.
102
- - _BufferHandler_: This handler will buffer all the log records it receives
103
- until `close()` is called at which point it will call `handleBatch()` on the
104
- handler it wraps with all the log messages at once. This is very useful to
105
- send an email with all records at once for example instead of having one mail
106
- for every log record.
107
- - _GroupHandler_: This handler groups other handlers. Every record received is
108
- sent to all the handlers it is configured with.
109
- - _FilterHandler_: This handler only lets records of the given levels through
110
- to the wrapped handler.
111
- - _SamplingHandler_: Wraps around another handler and lets you sample records
112
- if you only want to store some of them.
113
- - _NullHandler_: Any record it can handle will be thrown away. This can be used
114
- to put on top of an existing handler stack to disable it temporarily.
115
- - _PsrHandler_: Can be used to forward log records to an existing PSR-3 logger
116
- - _TestHandler_: Used for testing, it records everything that is sent to it and
117
- has accessors to read out the information.
118
- - _HandlerWrapper_: A simple handler wrapper you can inherit from to create
119
- your own wrappers easily.
120
-
121
- ## Formatters
122
-
123
- - _LineFormatter_: Formats a log record into a one-line string.
124
- - _HtmlFormatter_: Used to format log records into a human readable html table, mainly suitable for emails.
125
- - _NormalizerFormatter_: Normalizes objects/resources down to strings so a record can easily be serialized/encoded.
126
- - _ScalarFormatter_: Used to format log records into an associative array of scalar values.
127
- - _JsonFormatter_: Encodes a log record into json.
128
- - _WildfireFormatter_: Used to format log records into the Wildfire/FirePHP protocol, only useful for the FirePHPHandler.
129
- - _ChromePHPFormatter_: Used to format log records into the ChromePHP format, only useful for the ChromePHPHandler.
130
- - _GelfMessageFormatter_: Used to format log records into Gelf message instances, only useful for the GelfHandler.
131
- - _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).
132
- - _ElasticaFormatter_: Used to format log records into an Elastica\Document object, only useful for the ElasticSearchHandler.
133
- - _LogglyFormatter_: Used to format log records into Loggly messages, only useful for the LogglyHandler.
134
- - _FlowdockFormatter_: Used to format log records into Flowdock messages, only useful for the FlowdockHandler.
135
- - _MongoDBFormatter_: Converts \DateTime instances to \MongoDate and objects recursively to arrays, only useful with the MongoDBHandler.
136
-
137
- ## Processors
138
-
139
- - _PsrLogMessageProcessor_: Processes a log record's message according to PSR-3 rules, replacing `{foo}` with the value from `$context['foo']`.
140
- - _IntrospectionProcessor_: Adds the line/file/class/method from which the log call originated.
141
- - _WebProcessor_: Adds the current request URI, request method and client IP to a log record.
142
- - _MemoryUsageProcessor_: Adds the current memory usage to a log record.
143
- - _MemoryPeakUsageProcessor_: Adds the peak memory usage to a log record.
144
- - _ProcessIdProcessor_: Adds the process id to a log record.
145
- - _UidProcessor_: Adds a unique identifier to a log record.
146
- - _GitProcessor_: Adds the current git branch and commit to a log record.
147
- - _TagProcessor_: Adds an array of predefined tags to a log record.
148
-
149
- ## Third Party Packages
150
-
151
- Third party handlers, formatters and processors are
152
- [listed in the wiki](https://github.com/Seldaek/monolog/wiki/Third-Party-Packages). You
153
- can also add your own there if you publish one.
154
-
155
- &larr; [Usage](01-usage.md) | [Utility classes](03-utilities.md) &rarr;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/doc/03-utilities.md DELETED
@@ -1,13 +0,0 @@
1
- # Utilities
2
-
3
- - _Registry_: The `Monolog\Registry` class lets you configure global loggers that you
4
- can then statically access from anywhere. It is not really a best practice but can
5
- help in some older codebases or for ease of use.
6
- - _ErrorHandler_: The `Monolog\ErrorHandler` class allows you to easily register
7
- a Logger instance as an exception handler, error handler or fatal error handler.
8
- - _ErrorLevelActivationStrategy_: Activates a FingersCrossedHandler when a certain log
9
- level is reached.
10
- - _ChannelLevelActivationStrategy_: Activates a FingersCrossedHandler when a certain
11
- log level is reached, depending on which channel received the log record.
12
-
13
- &larr; [Handlers, Formatters and Processors](02-handlers-formatters-processors.md) | [Extending Monolog](04-extending.md) &rarr;
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/doc/04-extending.md DELETED
@@ -1,76 +0,0 @@
1
- # Extending Monolog
2
-
3
- Monolog is fully extensible, allowing you to adapt your logger to your needs.
4
-
5
- ## Writing your own handler
6
-
7
- Monolog provides many built-in handlers. But if the one you need does not
8
- exist, you can write it and use it in your logger. The only requirement is
9
- to implement `Monolog\Handler\HandlerInterface`.
10
-
11
- Let's write a PDOHandler to log records to a database. We will extend the
12
- abstract class provided by Monolog to keep things DRY.
13
-
14
- ```php
15
- <?php
16
-
17
- use Monolog\Logger;
18
- use Monolog\Handler\AbstractProcessingHandler;
19
-
20
- class PDOHandler extends AbstractProcessingHandler
21
- {
22
- private $initialized = false;
23
- private $pdo;
24
- private $statement;
25
-
26
- public function __construct(PDO $pdo, $level = Logger::DEBUG, $bubble = true)
27
- {
28
- $this->pdo = $pdo;
29
- parent::__construct($level, $bubble);
30
- }
31
-
32
- protected function write(array $record)
33
- {
34
- if (!$this->initialized) {
35
- $this->initialize();
36
- }
37
-
38
- $this->statement->execute(array(
39
- 'channel' => $record['channel'],
40
- 'level' => $record['level'],
41
- 'message' => $record['formatted'],
42
- 'time' => $record['datetime']->format('U'),
43
- ));
44
- }
45
-
46
- private function initialize()
47
- {
48
- $this->pdo->exec(
49
- 'CREATE TABLE IF NOT EXISTS monolog '
50
- .'(channel VARCHAR(255), level INTEGER, message LONGTEXT, time INTEGER UNSIGNED)'
51
- );
52
- $this->statement = $this->pdo->prepare(
53
- 'INSERT INTO monolog (channel, level, message, time) VALUES (:channel, :level, :message, :time)'
54
- );
55
-
56
- $this->initialized = true;
57
- }
58
- }
59
- ```
60
-
61
- You can now use this handler in your logger:
62
-
63
- ```php
64
- <?php
65
-
66
- $logger->pushHandler(new PDOHandler(new PDO('sqlite:logs.sqlite')));
67
-
68
- // You can now use your logger
69
- $logger->addInfo('My logger is now ready');
70
- ```
71
-
72
- The `Monolog\Handler\AbstractProcessingHandler` class provides most of the
73
- logic needed for the handler, including the use of processors and the formatting
74
- of the record (which is why we use ``$record['formatted']`` instead of ``$record['message']``).
75
-
76
- &larr; [Utility classes](03-utilities.md)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/doc/sockets.md DELETED
@@ -1,39 +0,0 @@
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
- You can use a `unix://` prefix to access unix sockets and `udp://` to open UDP sockets instead of the default TCP.
11
-
12
- Basic Example
13
- -------------
14
-
15
- ```php
16
- <?php
17
-
18
- use Monolog\Logger;
19
- use Monolog\Handler\SocketHandler;
20
-
21
- // Create the logger
22
- $logger = new Logger('my_logger');
23
-
24
- // Create the handler
25
- $handler = new SocketHandler('unix:///var/log/httpd_app_log.socket');
26
- $handler->setPersistent(true);
27
-
28
- // Now add the handler
29
- $logger->pushHandler($handler, Logger::DEBUG);
30
-
31
- // You can now use your logger
32
- $logger->addInfo('My logger is now ready');
33
-
34
- ```
35
-
36
- In this example, using syslog-ng, you should see the log on the log server:
37
-
38
- cweb1 [2012-02-26 00:12:03] my_logger.INFO: My logger is now ready [] []
39
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/phpunit.xml.dist DELETED
@@ -1,19 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
-
3
- <phpunit bootstrap="vendor/autoload.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
-
16
- <php>
17
- <ini name="date.timezone" value="UTC"/>
18
- </php>
19
- </phpunit>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/src/Monolog/Handler/Slack/SlackRecord.php ADDED
@@ -0,0 +1,294 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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\Slack;
13
+
14
+ use Monolog\Logger;
15
+ use Monolog\Formatter\NormalizerFormatter;
16
+ use Monolog\Formatter\FormatterInterface;
17
+
18
+ /**
19
+ * Slack record utility helping to log to Slack webhooks or API.
20
+ *
21
+ * @author Greg Kedzierski <greg@gregkedzierski.com>
22
+ * @author Haralan Dobrev <hkdobrev@gmail.com>
23
+ * @see https://api.slack.com/incoming-webhooks
24
+ * @see https://api.slack.com/docs/message-attachments
25
+ */
26
+ class SlackRecord
27
+ {
28
+ const COLOR_DANGER = 'danger';
29
+
30
+ const COLOR_WARNING = 'warning';
31
+
32
+ const COLOR_GOOD = 'good';
33
+
34
+ const COLOR_DEFAULT = '#e3e4e6';
35
+
36
+ /**
37
+ * Slack channel (encoded ID or name)
38
+ * @var string|null
39
+ */
40
+ private $channel;
41
+
42
+ /**
43
+ * Name of a bot
44
+ * @var string|null
45
+ */
46
+ private $username;
47
+
48
+ /**
49
+ * User icon e.g. 'ghost', 'http://example.com/user.png'
50
+ * @var string
51
+ */
52
+ private $userIcon;
53
+
54
+ /**
55
+ * Whether the message should be added to Slack as attachment (plain text otherwise)
56
+ * @var bool
57
+ */
58
+ private $useAttachment;
59
+
60
+ /**
61
+ * Whether the the context/extra messages added to Slack as attachments are in a short style
62
+ * @var bool
63
+ */
64
+ private $useShortAttachment;
65
+
66
+ /**
67
+ * Whether the attachment should include context and extra data
68
+ * @var bool
69
+ */
70
+ private $includeContextAndExtra;
71
+
72
+ /**
73
+ * Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2']
74
+ * @var array
75
+ */
76
+ private $excludeFields;
77
+
78
+ /**
79
+ * @var FormatterInterface
80
+ */
81
+ private $formatter;
82
+
83
+ /**
84
+ * @var NormalizerFormatter
85
+ */
86
+ private $normalizerFormatter;
87
+
88
+ public function __construct($channel = null, $username = null, $useAttachment = true, $userIcon = null, $useShortAttachment = false, $includeContextAndExtra = false, array $excludeFields = array(), FormatterInterface $formatter = null)
89
+ {
90
+ $this->channel = $channel;
91
+ $this->username = $username;
92
+ $this->userIcon = trim($userIcon, ':');
93
+ $this->useAttachment = $useAttachment;
94
+ $this->useShortAttachment = $useShortAttachment;
95
+ $this->includeContextAndExtra = $includeContextAndExtra;
96
+ $this->excludeFields = $excludeFields;
97
+ $this->formatter = $formatter;
98
+
99
+ if ($this->includeContextAndExtra) {
100
+ $this->normalizerFormatter = new NormalizerFormatter();
101
+ }
102
+ }
103
+
104
+ public function getSlackData(array $record)
105
+ {
106
+ $dataArray = array();
107
+ $record = $this->excludeFields($record);
108
+
109
+ if ($this->username) {
110
+ $dataArray['username'] = $this->username;
111
+ }
112
+
113
+ if ($this->channel) {
114
+ $dataArray['channel'] = $this->channel;
115
+ }
116
+
117
+ if ($this->formatter && !$this->useAttachment) {
118
+ $message = $this->formatter->format($record);
119
+ } else {
120
+ $message = $record['message'];
121
+ }
122
+
123
+ if ($this->useAttachment) {
124
+ $attachment = array(
125
+ 'fallback' => $message,
126
+ 'text' => $message,
127
+ 'color' => $this->getAttachmentColor($record['level']),
128
+ 'fields' => array(),
129
+ 'mrkdwn_in' => array('fields'),
130
+ 'ts' => $record['datetime']->getTimestamp()
131
+ );
132
+
133
+ if ($this->useShortAttachment) {
134
+ $attachment['title'] = $record['level_name'];
135
+ } else {
136
+ $attachment['title'] = 'Message';
137
+ $attachment['fields'][] = $this->generateAttachmentField('Level', $record['level_name']);
138
+ }
139
+
140
+
141
+ if ($this->includeContextAndExtra) {
142
+ foreach (array('extra', 'context') as $key) {
143
+ if (empty($record[$key])) {
144
+ continue;
145
+ }
146
+
147
+ if ($this->useShortAttachment) {
148
+ $attachment['fields'][] = $this->generateAttachmentField(
149
+ ucfirst($key),
150
+ $record[$key]
151
+ );
152
+ } else {
153
+ // Add all extra fields as individual fields in attachment
154
+ $attachment['fields'] = array_merge(
155
+ $attachment['fields'],
156
+ $this->generateAttachmentFields($record[$key])
157
+ );
158
+ }
159
+ }
160
+ }
161
+
162
+ $dataArray['attachments'] = array($attachment);
163
+ } else {
164
+ $dataArray['text'] = $message;
165
+ }
166
+
167
+ if ($this->userIcon) {
168
+ if (filter_var($this->userIcon, FILTER_VALIDATE_URL)) {
169
+ $dataArray['icon_url'] = $this->userIcon;
170
+ } else {
171
+ $dataArray['icon_emoji'] = ":{$this->userIcon}:";
172
+ }
173
+ }
174
+
175
+ return $dataArray;
176
+ }
177
+
178
+ /**
179
+ * Returned a Slack message attachment color associated with
180
+ * provided level.
181
+ *
182
+ * @param int $level
183
+ * @return string
184
+ */
185
+ public function getAttachmentColor($level)
186
+ {
187
+ switch (true) {
188
+ case $level >= Logger::ERROR:
189
+ return self::COLOR_DANGER;
190
+ case $level >= Logger::WARNING:
191
+ return self::COLOR_WARNING;
192
+ case $level >= Logger::INFO:
193
+ return self::COLOR_GOOD;
194
+ default:
195
+ return self::COLOR_DEFAULT;
196
+ }
197
+ }
198
+
199
+ /**
200
+ * Stringifies an array of key/value pairs to be used in attachment fields
201
+ *
202
+ * @param array $fields
203
+ *
204
+ * @return string
205
+ */
206
+ public function stringify($fields)
207
+ {
208
+ $normalized = $this->normalizerFormatter->format($fields);
209
+ $prettyPrintFlag = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 128;
210
+
211
+ $hasSecondDimension = count(array_filter($normalized, 'is_array'));
212
+ $hasNonNumericKeys = !count(array_filter(array_keys($normalized), 'is_numeric'));
213
+
214
+ return $hasSecondDimension || $hasNonNumericKeys
215
+ ? json_encode($normalized, $prettyPrintFlag)
216
+ : json_encode($normalized);
217
+ }
218
+
219
+ /**
220
+ * Sets the formatter
221
+ *
222
+ * @param FormatterInterface $formatter
223
+ */
224
+ public function setFormatter(FormatterInterface $formatter)
225
+ {
226
+ $this->formatter = $formatter;
227
+ }
228
+
229
+ /**
230
+ * Generates attachment field
231
+ *
232
+ * @param string $title
233
+ * @param string|array $value\
234
+ *
235
+ * @return array
236
+ */
237
+ private function generateAttachmentField($title, $value)
238
+ {
239
+ $value = is_array($value)
240
+ ? sprintf('```%s```', $this->stringify($value))
241
+ : $value;
242
+
243
+ return array(
244
+ 'title' => $title,
245
+ 'value' => $value,
246
+ 'short' => false
247
+ );
248
+ }
249
+
250
+ /**
251
+ * Generates a collection of attachment fields from array
252
+ *
253
+ * @param array $data
254
+ *
255
+ * @return array
256
+ */
257
+ private function generateAttachmentFields(array $data)
258
+ {
259
+ $fields = array();
260
+ foreach ($data as $key => $value) {
261
+ $fields[] = $this->generateAttachmentField($key, $value);
262
+ }
263
+
264
+ return $fields;
265
+ }
266
+
267
+ /**
268
+ * Get a copy of record with fields excluded according to $this->excludeFields
269
+ *
270
+ * @param array $record
271
+ *
272
+ * @return array
273
+ */
274
+ private function excludeFields(array $record)
275
+ {
276
+ foreach ($this->excludeFields as $field) {
277
+ $keys = explode('.', $field);
278
+ $node = &$record;
279
+ $lastKey = end($keys);
280
+ foreach ($keys as $key) {
281
+ if (!isset($node[$key])) {
282
+ break;
283
+ }
284
+ if ($lastKey === $key) {
285
+ unset($node[$key]);
286
+ break;
287
+ }
288
+ $node = &$node[$key];
289
+ }
290
+ }
291
+
292
+ return $record;
293
+ }
294
+ }
vendor/monolog/monolog/src/Monolog/Handler/SlackWebhookHandler.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\Formatter\FormatterInterface;
15
+ use Monolog\Logger;
16
+ use Monolog\Handler\Slack\SlackRecord;
17
+
18
+ /**
19
+ * Sends notifications through Slack Webhooks
20
+ *
21
+ * @author Haralan Dobrev <hkdobrev@gmail.com>
22
+ * @see https://api.slack.com/incoming-webhooks
23
+ */
24
+ class SlackWebhookHandler extends AbstractProcessingHandler
25
+ {
26
+ /**
27
+ * Slack Webhook token
28
+ * @var string
29
+ */
30
+ private $webhookUrl;
31
+
32
+ /**
33
+ * Instance of the SlackRecord util class preparing data for Slack API.
34
+ * @var SlackRecord
35
+ */
36
+ private $slackRecord;
37
+
38
+ /**
39
+ * @param string $webhookUrl Slack Webhook URL
40
+ * @param string|null $channel Slack channel (encoded ID or name)
41
+ * @param string|null $username Name of a bot
42
+ * @param bool $useAttachment Whether the message should be added to Slack as attachment (plain text otherwise)
43
+ * @param string|null $iconEmoji The emoji name to use (or null)
44
+ * @param bool $useShortAttachment Whether the the context/extra messages added to Slack as attachments are in a short style
45
+ * @param bool $includeContextAndExtra Whether the attachment should include context and extra data
46
+ * @param int $level The minimum logging level at which this handler will be triggered
47
+ * @param bool $bubble Whether the messages that are handled can bubble up the stack or not
48
+ * @param array $excludeFields Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2']
49
+ */
50
+ public function __construct($webhookUrl, $channel = null, $username = null, $useAttachment = true, $iconEmoji = null, $useShortAttachment = false, $includeContextAndExtra = false, $level = Logger::CRITICAL, $bubble = true, array $excludeFields = array())
51
+ {
52
+ parent::__construct($level, $bubble);
53
+
54
+ $this->webhookUrl = $webhookUrl;
55
+
56
+ $this->slackRecord = new SlackRecord(
57
+ $channel,
58
+ $username,
59
+ $useAttachment,
60
+ $iconEmoji,
61
+ $useShortAttachment,
62
+ $includeContextAndExtra,
63
+ $excludeFields,
64
+ $this->formatter
65
+ );
66
+ }
67
+
68
+ public function getSlackRecord()
69
+ {
70
+ return $this->slackRecord;
71
+ }
72
+
73
+ /**
74
+ * {@inheritdoc}
75
+ *
76
+ * @param array $record
77
+ */
78
+ protected function write(array $record)
79
+ {
80
+ $postData = $this->slackRecord->getSlackData($record);
81
+ $postString = json_encode($postData);
82
+
83
+ $ch = curl_init();
84
+ $options = array(
85
+ CURLOPT_URL => $this->webhookUrl,
86
+ CURLOPT_POST => true,
87
+ CURLOPT_RETURNTRANSFER => true,
88
+ CURLOPT_HTTPHEADER => array('Content-type: application/json'),
89
+ CURLOPT_POSTFIELDS => $postString
90
+ );
91
+ if (defined('CURLOPT_SAFE_UPLOAD')) {
92
+ $options[CURLOPT_SAFE_UPLOAD] = true;
93
+ }
94
+
95
+ curl_setopt_array($ch, $options);
96
+
97
+ Curl\Util::execute($ch);
98
+ }
99
+
100
+ public function setFormatter(FormatterInterface $formatter)
101
+ {
102
+ parent::setFormatter($formatter);
103
+ $this->slackRecord->setFormatter($formatter);
104
+
105
+ return $this;
106
+ }
107
+
108
+ public function getFormatter()
109
+ {
110
+ $formatter = parent::getFormatter();
111
+ $this->slackRecord->setFormatter($formatter);
112
+
113
+ return $formatter;
114
+ }
115
+ }
vendor/monolog/monolog/src/Monolog/Handler/SlackbotHandler.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
+
16
+ /**
17
+ * Sends notifications through Slack's Slackbot
18
+ *
19
+ * @author Haralan Dobrev <hkdobrev@gmail.com>
20
+ * @see https://slack.com/apps/A0F81R8ET-slackbot
21
+ */
22
+ class SlackbotHandler extends AbstractProcessingHandler
23
+ {
24
+ /**
25
+ * The slug of the Slack team
26
+ * @var string
27
+ */
28
+ private $slackTeam;
29
+
30
+ /**
31
+ * Slackbot token
32
+ * @var string
33
+ */
34
+ private $token;
35
+
36
+ /**
37
+ * Slack channel name
38
+ * @var string
39
+ */
40
+ private $channel;
41
+
42
+ /**
43
+ * @param string $slackTeam Slack team slug
44
+ * @param string $token Slackbot token
45
+ * @param string $channel Slack channel (encoded ID or name)
46
+ * @param int $level The minimum logging level at which this handler will be triggered
47
+ * @param bool $bubble Whether the messages that are handled can bubble up the stack or not
48
+ */
49
+ public function __construct($slackTeam, $token, $channel, $level = Logger::CRITICAL, $bubble = true)
50
+ {
51
+ parent::__construct($level, $bubble);
52
+
53
+ $this->slackTeam = $slackTeam;
54
+ $this->token = $token;
55
+ $this->channel = $channel;
56
+ }
57
+
58
+ /**
59
+ * {@inheritdoc}
60
+ *
61
+ * @param array $record
62
+ */
63
+ protected function write(array $record)
64
+ {
65
+ $slackbotUrl = sprintf(
66
+ 'https://%s.slack.com/services/hooks/slackbot?token=%s&channel=%s',
67
+ $this->slackTeam,
68
+ $this->token,
69
+ $this->channel
70
+ );
71
+
72
+ $ch = curl_init();
73
+ curl_setopt($ch, CURLOPT_URL, $slackbotUrl);
74
+ curl_setopt($ch, CURLOPT_POST, true);
75
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
76
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $record['message']);
77
+
78
+ Curl\Util::execute($ch);
79
+ }
80
+ }
vendor/monolog/monolog/src/Monolog/Processor/MercurialProcessor.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Monolog package.
5
+ *
6
+ * (c) Jonathan A. Schweder <jonathanschweder@gmail.com>
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 Hg branch and Hg revision number in all records
18
+ *
19
+ * @author Jonathan A. Schweder <jonathanschweder@gmail.com>
20
+ */
21
+ class MercurialProcessor
22
+ {
23
+ private $level;
24
+ private static $cache;
25
+
26
+ public function __construct($level = Logger::DEBUG)
27
+ {
28
+ $this->level = Logger::toMonologLevel($level);
29
+ }
30
+
31
+ /**
32
+ * @param array $record
33
+ * @return array
34
+ */
35
+ public function __invoke(array $record)
36
+ {
37
+ // return if the level is not high enough
38
+ if ($record['level'] < $this->level) {
39
+ return $record;
40
+ }
41
+
42
+ $record['extra']['hg'] = self::getMercurialInfo();
43
+
44
+ return $record;
45
+ }
46
+
47
+ private static function getMercurialInfo()
48
+ {
49
+ if (self::$cache) {
50
+ return self::$cache;
51
+ }
52
+
53
+ $result = explode(' ', trim(`hg id -nb`));
54
+ if (count($result) >= 3) {
55
+ return self::$cache = array(
56
+ 'branch' => $result[1],
57
+ 'revision' => $result[2],
58
+ );
59
+ }
60
+
61
+ return self::$cache = array();
62
+ }
63
+ }
vendor/monolog/monolog/tests/Monolog/ErrorHandlerTest.php DELETED
@@ -1,31 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Formatter/ChromePHPFormatterTest.php DELETED
@@ -1,158 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Formatter/ElasticaFormatterTest.php DELETED
@@ -1,79 +0,0 @@
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.000000+00:00';
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Formatter/FlowdockFormatterTest.php DELETED
@@ -1,55 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Formatter/FluentdFormatterTest.php DELETED
@@ -1,62 +0,0 @@
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 FluentdFormatterTest extends TestCase
18
- {
19
- /**
20
- * @covers Monolog\Formatter\FluentdFormatter::__construct
21
- * @covers Monolog\Formatter\FluentdFormatter::isUsingLevelsInTag
22
- */
23
- public function testConstruct()
24
- {
25
- $formatter = new FluentdFormatter();
26
- $this->assertEquals(false, $formatter->isUsingLevelsInTag());
27
- $formatter = new FluentdFormatter(false);
28
- $this->assertEquals(false, $formatter->isUsingLevelsInTag());
29
- $formatter = new FluentdFormatter(true);
30
- $this->assertEquals(true, $formatter->isUsingLevelsInTag());
31
- }
32
-
33
- /**
34
- * @covers Monolog\Formatter\FluentdFormatter::format
35
- */
36
- public function testFormat()
37
- {
38
- $record = $this->getRecord(Logger::WARNING);
39
- $record['datetime'] = new \DateTime("@0");
40
-
41
- $formatter = new FluentdFormatter();
42
- $this->assertEquals(
43
- '["test",0,{"message":"test","extra":[],"level":300,"level_name":"WARNING"}]',
44
- $formatter->format($record)
45
- );
46
- }
47
-
48
- /**
49
- * @covers Monolog\Formatter\FluentdFormatter::format
50
- */
51
- public function testFormatWithTag()
52
- {
53
- $record = $this->getRecord(Logger::ERROR);
54
- $record['datetime'] = new \DateTime("@0");
55
-
56
- $formatter = new FluentdFormatter(true);
57
- $this->assertEquals(
58
- '["test.error",0,{"message":"test","extra":[]}]',
59
- $formatter->format($record)
60
- );
61
- }
62
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Formatter/GelfMessageFormatterTest.php DELETED
@@ -1,234 +0,0 @@
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
- public function testFormatWithLargeData()
201
- {
202
- $formatter = new GelfMessageFormatter();
203
- $record = array(
204
- 'level' => Logger::ERROR,
205
- 'level_name' => 'ERROR',
206
- 'channel' => 'meh',
207
- 'context' => array('exception' => str_repeat(' ', 32767)),
208
- 'datetime' => new \DateTime("@0"),
209
- 'extra' => array('key' => str_repeat(' ', 32767)),
210
- 'message' => 'log'
211
- );
212
- $message = $formatter->format($record);
213
- $messageArray = $message->toArray();
214
-
215
- // 200 for padding + metadata
216
- $length = 200;
217
-
218
- foreach ($messageArray as $key => $value) {
219
- if (!in_array($key, array('level', 'timestamp'))) {
220
- $length += strlen($value);
221
- }
222
- }
223
-
224
- // in graylog2/gelf-php before 1.4.1 empty strings are filtered and won't be included in the message
225
- // though it should be sufficient to ensure that the entire message length does not exceed the maximum
226
- // length being allowed
227
- $this->assertLessThanOrEqual(32766, $length, 'The message length is no longer than the maximum allowed length');
228
- }
229
-
230
- private function isLegacy()
231
- {
232
- return interface_exists('\Gelf\IMessagePublisher');
233
- }
234
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Formatter/JsonFormatterTest.php DELETED
@@ -1,122 +0,0 @@
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
-
79
- public function testDefFormatWithException()
80
- {
81
- $formatter = new JsonFormatter();
82
- $exception = new \RuntimeException('Foo');
83
- $message = $formatter->format(array(
84
- 'level_name' => 'CRITICAL',
85
- 'channel' => 'core',
86
- 'context' => array('exception' => $exception),
87
- 'datetime' => new \DateTime(),
88
- 'extra' => array(),
89
- 'message' => 'foobar',
90
- ));
91
-
92
- if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
93
- $path = substr(json_encode($exception->getFile(), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), 1, -1);
94
- } else {
95
- $path = substr(json_encode($exception->getFile()), 1, -1);
96
- }
97
- $this->assertEquals('{"level_name":"CRITICAL","channel":"core","context":{"exception":{"class":"RuntimeException","message":"'.$exception->getMessage().'","code":'.$exception->getCode().',"file":"'.$path.':'.$exception->getLine().'"}},"datetime":'.json_encode(new \DateTime()).',"extra":[],"message":"foobar"}'."\n", $message);
98
- }
99
-
100
- public function testDefFormatWithPreviousException()
101
- {
102
- $formatter = new JsonFormatter();
103
- $exception = new \RuntimeException('Foo', 0, new \LogicException('Wut?'));
104
- $message = $formatter->format(array(
105
- 'level_name' => 'CRITICAL',
106
- 'channel' => 'core',
107
- 'context' => array('exception' => $exception),
108
- 'datetime' => new \DateTime(),
109
- 'extra' => array(),
110
- 'message' => 'foobar',
111
- ));
112
-
113
- if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
114
- $pathPrevious = substr(json_encode($exception->getPrevious()->getFile(), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), 1, -1);
115
- $pathException = substr(json_encode($exception->getFile(), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), 1, -1);
116
- } else {
117
- $pathPrevious = substr(json_encode($exception->getPrevious()->getFile()), 1, -1);
118
- $pathException = substr(json_encode($exception->getFile()), 1, -1);
119
- }
120
- $this->assertEquals('{"level_name":"CRITICAL","channel":"core","context":{"exception":{"class":"RuntimeException","message":"'.$exception->getMessage().'","code":'.$exception->getCode().',"file":"'.$pathException.':'.$exception->getLine().'","previous":{"class":"LogicException","message":"'.$exception->getPrevious()->getMessage().'","code":'.$exception->getPrevious()->getCode().',"file":"'.$pathPrevious.':'.$exception->getPrevious()->getLine().'"}}},"datetime":'.json_encode(new \DateTime()).',"extra":[],"message":"foobar"}'."\n", $message);
121
- }
122
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Formatter/LineFormatterTest.php DELETED
@@ -1,222 +0,0 @@
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 testContextAndExtraReplacement()
95
- {
96
- $formatter = new LineFormatter('%context.foo% => %extra.foo%');
97
- $message = $formatter->format(array(
98
- 'level_name' => 'ERROR',
99
- 'channel' => 'meh',
100
- 'context' => array('foo' => 'bar'),
101
- 'datetime' => new \DateTime,
102
- 'extra' => array('foo' => 'xbar'),
103
- 'message' => 'log',
104
- ));
105
- $this->assertEquals('bar => xbar', $message);
106
- }
107
-
108
- public function testDefFormatWithObject()
109
- {
110
- $formatter = new LineFormatter(null, 'Y-m-d');
111
- $message = $formatter->format(array(
112
- 'level_name' => 'ERROR',
113
- 'channel' => 'meh',
114
- 'context' => array(),
115
- 'datetime' => new \DateTime,
116
- 'extra' => array('foo' => new TestFoo, 'bar' => new TestBar, 'baz' => array(), 'res' => fopen('php://memory', 'rb')),
117
- 'message' => 'foobar',
118
- ));
119
-
120
- $this->assertEquals('['.date('Y-m-d').'] meh.ERROR: foobar [] {"foo":"[object] (Monolog\\\\Formatter\\\\TestFoo: {\\"foo\\":\\"foo\\"})","bar":"[object] (Monolog\\\\Formatter\\\\TestBar: bar)","baz":[],"res":"[resource] (stream)"}'."\n", $message);
121
- }
122
-
123
- public function testDefFormatWithException()
124
- {
125
- $formatter = new LineFormatter(null, 'Y-m-d');
126
- $message = $formatter->format(array(
127
- 'level_name' => 'CRITICAL',
128
- 'channel' => 'core',
129
- 'context' => array('exception' => new \RuntimeException('Foo')),
130
- 'datetime' => new \DateTime,
131
- 'extra' => array(),
132
- 'message' => 'foobar',
133
- ));
134
-
135
- $path = str_replace('\\/', '/', json_encode(__FILE__));
136
-
137
- $this->assertEquals('['.date('Y-m-d').'] core.CRITICAL: foobar {"exception":"[object] (RuntimeException(code: 0): Foo at '.substr($path, 1, -1).':'.(__LINE__ - 8).')"} []'."\n", $message);
138
- }
139
-
140
- public function testDefFormatWithPreviousException()
141
- {
142
- $formatter = new LineFormatter(null, 'Y-m-d');
143
- $previous = new \LogicException('Wut?');
144
- $message = $formatter->format(array(
145
- 'level_name' => 'CRITICAL',
146
- 'channel' => 'core',
147
- 'context' => array('exception' => new \RuntimeException('Foo', 0, $previous)),
148
- 'datetime' => new \DateTime,
149
- 'extra' => array(),
150
- 'message' => 'foobar',
151
- ));
152
-
153
- $path = str_replace('\\/', '/', json_encode(__FILE__));
154
-
155
- $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);
156
- }
157
-
158
- public function testBatchFormat()
159
- {
160
- $formatter = new LineFormatter(null, 'Y-m-d');
161
- $message = $formatter->formatBatch(array(
162
- array(
163
- 'level_name' => 'CRITICAL',
164
- 'channel' => 'test',
165
- 'message' => 'bar',
166
- 'context' => array(),
167
- 'datetime' => new \DateTime,
168
- 'extra' => array(),
169
- ),
170
- array(
171
- 'level_name' => 'WARNING',
172
- 'channel' => 'log',
173
- 'message' => 'foo',
174
- 'context' => array(),
175
- 'datetime' => new \DateTime,
176
- 'extra' => array(),
177
- ),
178
- ));
179
- $this->assertEquals('['.date('Y-m-d').'] test.CRITICAL: bar [] []'."\n".'['.date('Y-m-d').'] log.WARNING: foo [] []'."\n", $message);
180
- }
181
-
182
- public function testFormatShouldStripInlineLineBreaks()
183
- {
184
- $formatter = new LineFormatter(null, 'Y-m-d');
185
- $message = $formatter->format(
186
- array(
187
- 'message' => "foo\nbar",
188
- 'context' => array(),
189
- 'extra' => array(),
190
- )
191
- );
192
-
193
- $this->assertRegExp('/foo bar/', $message);
194
- }
195
-
196
- public function testFormatShouldNotStripInlineLineBreaksWhenFlagIsSet()
197
- {
198
- $formatter = new LineFormatter(null, 'Y-m-d', true);
199
- $message = $formatter->format(
200
- array(
201
- 'message' => "foo\nbar",
202
- 'context' => array(),
203
- 'extra' => array(),
204
- )
205
- );
206
-
207
- $this->assertRegExp('/foo\nbar/', $message);
208
- }
209
- }
210
-
211
- class TestFoo
212
- {
213
- public $foo = 'foo';
214
- }
215
-
216
- class TestBar
217
- {
218
- public function __toString()
219
- {
220
- return 'bar';
221
- }
222
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Formatter/LogglyFormatterTest.php DELETED
@@ -1,40 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Formatter/LogstashFormatterTest.php DELETED
@@ -1,333 +0,0 @@
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
- public function tearDown()
19
- {
20
- \PHPUnit_Framework_Error_Warning::$enabled = true;
21
-
22
- return parent::tearDown();
23
- }
24
-
25
- /**
26
- * @covers Monolog\Formatter\LogstashFormatter::format
27
- */
28
- public function testDefaultFormatter()
29
- {
30
- $formatter = new LogstashFormatter('test', 'hostname');
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 = json_decode($formatter->format($record), true);
42
-
43
- $this->assertEquals("1970-01-01T00:00:00.000000+00:00", $message['@timestamp']);
44
- $this->assertEquals('log', $message['@message']);
45
- $this->assertEquals('meh', $message['@fields']['channel']);
46
- $this->assertContains('meh', $message['@tags']);
47
- $this->assertEquals(Logger::ERROR, $message['@fields']['level']);
48
- $this->assertEquals('test', $message['@type']);
49
- $this->assertEquals('hostname', $message['@source']);
50
-
51
- $formatter = new LogstashFormatter('mysystem');
52
-
53
- $message = json_decode($formatter->format($record), true);
54
-
55
- $this->assertEquals('mysystem', $message['@type']);
56
- }
57
-
58
- /**
59
- * @covers Monolog\Formatter\LogstashFormatter::format
60
- */
61
- public function testFormatWithFileAndLine()
62
- {
63
- $formatter = new LogstashFormatter('test');
64
- $record = array(
65
- 'level' => Logger::ERROR,
66
- 'level_name' => 'ERROR',
67
- 'channel' => 'meh',
68
- 'context' => array('from' => 'logger'),
69
- 'datetime' => new \DateTime("@0"),
70
- 'extra' => array('file' => 'test', 'line' => 14),
71
- 'message' => 'log',
72
- );
73
-
74
- $message = json_decode($formatter->format($record), true);
75
-
76
- $this->assertEquals('test', $message['@fields']['file']);
77
- $this->assertEquals(14, $message['@fields']['line']);
78
- }
79
-
80
- /**
81
- * @covers Monolog\Formatter\LogstashFormatter::format
82
- */
83
- public function testFormatWithContext()
84
- {
85
- $formatter = new LogstashFormatter('test');
86
- $record = array(
87
- 'level' => Logger::ERROR,
88
- 'level_name' => 'ERROR',
89
- 'channel' => 'meh',
90
- 'context' => array('from' => 'logger'),
91
- 'datetime' => new \DateTime("@0"),
92
- 'extra' => array('key' => 'pair'),
93
- 'message' => 'log',
94
- );
95
-
96
- $message = json_decode($formatter->format($record), true);
97
-
98
- $message_array = $message['@fields'];
99
-
100
- $this->assertArrayHasKey('ctxt_from', $message_array);
101
- $this->assertEquals('logger', $message_array['ctxt_from']);
102
-
103
- // Test with extraPrefix
104
- $formatter = new LogstashFormatter('test', null, null, 'CTX');
105
- $message = json_decode($formatter->format($record), true);
106
-
107
- $message_array = $message['@fields'];
108
-
109
- $this->assertArrayHasKey('CTXfrom', $message_array);
110
- $this->assertEquals('logger', $message_array['CTXfrom']);
111
- }
112
-
113
- /**
114
- * @covers Monolog\Formatter\LogstashFormatter::format
115
- */
116
- public function testFormatWithExtra()
117
- {
118
- $formatter = new LogstashFormatter('test');
119
- $record = array(
120
- 'level' => Logger::ERROR,
121
- 'level_name' => 'ERROR',
122
- 'channel' => 'meh',
123
- 'context' => array('from' => 'logger'),
124
- 'datetime' => new \DateTime("@0"),
125
- 'extra' => array('key' => 'pair'),
126
- 'message' => 'log',
127
- );
128
-
129
- $message = json_decode($formatter->format($record), true);
130
-
131
- $message_array = $message['@fields'];
132
-
133
- $this->assertArrayHasKey('key', $message_array);
134
- $this->assertEquals('pair', $message_array['key']);
135
-
136
- // Test with extraPrefix
137
- $formatter = new LogstashFormatter('test', null, 'EXT');
138
- $message = json_decode($formatter->format($record), true);
139
-
140
- $message_array = $message['@fields'];
141
-
142
- $this->assertArrayHasKey('EXTkey', $message_array);
143
- $this->assertEquals('pair', $message_array['EXTkey']);
144
- }
145
-
146
- public function testFormatWithApplicationName()
147
- {
148
- $formatter = new LogstashFormatter('app', 'test');
149
- $record = array(
150
- 'level' => Logger::ERROR,
151
- 'level_name' => 'ERROR',
152
- 'channel' => 'meh',
153
- 'context' => array('from' => 'logger'),
154
- 'datetime' => new \DateTime("@0"),
155
- 'extra' => array('key' => 'pair'),
156
- 'message' => 'log',
157
- );
158
-
159
- $message = json_decode($formatter->format($record), true);
160
-
161
- $this->assertArrayHasKey('@type', $message);
162
- $this->assertEquals('app', $message['@type']);
163
- }
164
-
165
- /**
166
- * @covers Monolog\Formatter\LogstashFormatter::format
167
- */
168
- public function testDefaultFormatterV1()
169
- {
170
- $formatter = new LogstashFormatter('test', 'hostname', null, 'ctxt_', LogstashFormatter::V1);
171
- $record = array(
172
- 'level' => Logger::ERROR,
173
- 'level_name' => 'ERROR',
174
- 'channel' => 'meh',
175
- 'context' => array(),
176
- 'datetime' => new \DateTime("@0"),
177
- 'extra' => array(),
178
- 'message' => 'log',
179
- );
180
-
181
- $message = json_decode($formatter->format($record), true);
182
-
183
- $this->assertEquals("1970-01-01T00:00:00.000000+00:00", $message['@timestamp']);
184
- $this->assertEquals("1", $message['@version']);
185
- $this->assertEquals('log', $message['message']);
186
- $this->assertEquals('meh', $message['channel']);
187
- $this->assertEquals('ERROR', $message['level']);
188
- $this->assertEquals('test', $message['type']);
189
- $this->assertEquals('hostname', $message['host']);
190
-
191
- $formatter = new LogstashFormatter('mysystem', null, null, 'ctxt_', LogstashFormatter::V1);
192
-
193
- $message = json_decode($formatter->format($record), true);
194
-
195
- $this->assertEquals('mysystem', $message['type']);
196
- }
197
-
198
- /**
199
- * @covers Monolog\Formatter\LogstashFormatter::format
200
- */
201
- public function testFormatWithFileAndLineV1()
202
- {
203
- $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1);
204
- $record = array(
205
- 'level' => Logger::ERROR,
206
- 'level_name' => 'ERROR',
207
- 'channel' => 'meh',
208
- 'context' => array('from' => 'logger'),
209
- 'datetime' => new \DateTime("@0"),
210
- 'extra' => array('file' => 'test', 'line' => 14),
211
- 'message' => 'log',
212
- );
213
-
214
- $message = json_decode($formatter->format($record), true);
215
-
216
- $this->assertEquals('test', $message['file']);
217
- $this->assertEquals(14, $message['line']);
218
- }
219
-
220
- /**
221
- * @covers Monolog\Formatter\LogstashFormatter::format
222
- */
223
- public function testFormatWithContextV1()
224
- {
225
- $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1);
226
- $record = array(
227
- 'level' => Logger::ERROR,
228
- 'level_name' => 'ERROR',
229
- 'channel' => 'meh',
230
- 'context' => array('from' => 'logger'),
231
- 'datetime' => new \DateTime("@0"),
232
- 'extra' => array('key' => 'pair'),
233
- 'message' => 'log',
234
- );
235
-
236
- $message = json_decode($formatter->format($record), true);
237
-
238
- $this->assertArrayHasKey('ctxt_from', $message);
239
- $this->assertEquals('logger', $message['ctxt_from']);
240
-
241
- // Test with extraPrefix
242
- $formatter = new LogstashFormatter('test', null, null, 'CTX', LogstashFormatter::V1);
243
- $message = json_decode($formatter->format($record), true);
244
-
245
- $this->assertArrayHasKey('CTXfrom', $message);
246
- $this->assertEquals('logger', $message['CTXfrom']);
247
- }
248
-
249
- /**
250
- * @covers Monolog\Formatter\LogstashFormatter::format
251
- */
252
- public function testFormatWithExtraV1()
253
- {
254
- $formatter = new LogstashFormatter('test', null, null, 'ctxt_', LogstashFormatter::V1);
255
- $record = array(
256
- 'level' => Logger::ERROR,
257
- 'level_name' => 'ERROR',
258
- 'channel' => 'meh',
259
- 'context' => array('from' => 'logger'),
260
- 'datetime' => new \DateTime("@0"),
261
- 'extra' => array('key' => 'pair'),
262
- 'message' => 'log',
263
- );
264
-
265
- $message = json_decode($formatter->format($record), true);
266
-
267
- $this->assertArrayHasKey('key', $message);
268
- $this->assertEquals('pair', $message['key']);
269
-
270
- // Test with extraPrefix
271
- $formatter = new LogstashFormatter('test', null, 'EXT', 'ctxt_', LogstashFormatter::V1);
272
- $message = json_decode($formatter->format($record), true);
273
-
274
- $this->assertArrayHasKey('EXTkey', $message);
275
- $this->assertEquals('pair', $message['EXTkey']);
276
- }
277
-
278
- public function testFormatWithApplicationNameV1()
279
- {
280
- $formatter = new LogstashFormatter('app', 'test', null, 'ctxt_', LogstashFormatter::V1);
281
- $record = array(
282
- 'level' => Logger::ERROR,
283
- 'level_name' => 'ERROR',
284
- 'channel' => 'meh',
285
- 'context' => array('from' => 'logger'),
286
- 'datetime' => new \DateTime("@0"),
287
- 'extra' => array('key' => 'pair'),
288
- 'message' => 'log',
289
- );
290
-
291
- $message = json_decode($formatter->format($record), true);
292
-
293
- $this->assertArrayHasKey('type', $message);
294
- $this->assertEquals('app', $message['type']);
295
- }
296
-
297
- public function testFormatWithLatin9Data()
298
- {
299
- if (version_compare(PHP_VERSION, '5.5.0', '<')) {
300
- // Ignore the warning that will be emitted by PHP <5.5.0
301
- \PHPUnit_Framework_Error_Warning::$enabled = false;
302
- }
303
- $formatter = new LogstashFormatter('test', 'hostname');
304
- $record = array(
305
- 'level' => Logger::ERROR,
306
- 'level_name' => 'ERROR',
307
- 'channel' => '¯\_(ツ)_/¯',
308
- 'context' => array(),
309
- 'datetime' => new \DateTime("@0"),
310
- 'extra' => array(
311
- 'user_agent' => "\xD6WN; FBCR/OrangeEspa\xF1a; Vers\xE3o/4.0; F\xE4rist",
312
- ),
313
- 'message' => 'log',
314
- );
315
-
316
- $message = json_decode($formatter->format($record), true);
317
-
318
- $this->assertEquals("1970-01-01T00:00:00.000000+00:00", $message['@timestamp']);
319
- $this->assertEquals('log', $message['@message']);
320
- $this->assertEquals('¯\_(ツ)_/¯', $message['@fields']['channel']);
321
- $this->assertContains('¯\_(ツ)_/¯', $message['@tags']);
322
- $this->assertEquals(Logger::ERROR, $message['@fields']['level']);
323
- $this->assertEquals('test', $message['@type']);
324
- $this->assertEquals('hostname', $message['@source']);
325
- if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
326
- $this->assertEquals('ÖWN; FBCR/OrangeEspaña; Versão/4.0; Färist', $message['@fields']['user_agent']);
327
- } else {
328
- // PHP <5.5 does not return false for an element encoding failure,
329
- // instead it emits a warning (possibly) and nulls the value.
330
- $this->assertEquals(null, $message['@fields']['user_agent']);
331
- }
332
- }
333
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Formatter/MongoDBFormatterTest.php DELETED
@@ -1,262 +0,0 @@
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
- * @author Florian Plattner <me@florianplattner.de>
18
- */
19
- class MongoDBFormatterTest extends \PHPUnit_Framework_TestCase
20
- {
21
- public function setUp()
22
- {
23
- if (!class_exists('MongoDate')) {
24
- $this->markTestSkipped('mongo extension not installed');
25
- }
26
- }
27
-
28
- public function constructArgumentProvider()
29
- {
30
- return array(
31
- array(1, true, 1, true),
32
- array(0, false, 0, false),
33
- );
34
- }
35
-
36
- /**
37
- * @param $traceDepth
38
- * @param $traceAsString
39
- * @param $expectedTraceDepth
40
- * @param $expectedTraceAsString
41
- *
42
- * @dataProvider constructArgumentProvider
43
- */
44
- public function testConstruct($traceDepth, $traceAsString, $expectedTraceDepth, $expectedTraceAsString)
45
- {
46
- $formatter = new MongoDBFormatter($traceDepth, $traceAsString);
47
-
48
- $reflTrace = new \ReflectionProperty($formatter, 'exceptionTraceAsString');
49
- $reflTrace->setAccessible(true);
50
- $this->assertEquals($expectedTraceAsString, $reflTrace->getValue($formatter));
51
-
52
- $reflDepth = new\ReflectionProperty($formatter, 'maxNestingLevel');
53
- $reflDepth->setAccessible(true);
54
- $this->assertEquals($expectedTraceDepth, $reflDepth->getValue($formatter));
55
- }
56
-
57
- public function testSimpleFormat()
58
- {
59
- $record = array(
60
- 'message' => 'some log message',
61
- 'context' => array(),
62
- 'level' => Logger::WARNING,
63
- 'level_name' => Logger::getLevelName(Logger::WARNING),
64
- 'channel' => 'test',
65
- 'datetime' => new \DateTime('2014-02-01 00:00:00'),
66
- 'extra' => array(),
67
- );
68
-
69
- $formatter = new MongoDBFormatter();
70
- $formattedRecord = $formatter->format($record);
71
-
72
- $this->assertCount(7, $formattedRecord);
73
- $this->assertEquals('some log message', $formattedRecord['message']);
74
- $this->assertEquals(array(), $formattedRecord['context']);
75
- $this->assertEquals(Logger::WARNING, $formattedRecord['level']);
76
- $this->assertEquals(Logger::getLevelName(Logger::WARNING), $formattedRecord['level_name']);
77
- $this->assertEquals('test', $formattedRecord['channel']);
78
- $this->assertInstanceOf('\MongoDate', $formattedRecord['datetime']);
79
- $this->assertEquals('0.00000000 1391212800', $formattedRecord['datetime']->__toString());
80
- $this->assertEquals(array(), $formattedRecord['extra']);
81
- }
82
-
83
- public function testRecursiveFormat()
84
- {
85
- $someObject = new \stdClass();
86
- $someObject->foo = 'something';
87
- $someObject->bar = 'stuff';
88
-
89
- $record = array(
90
- 'message' => 'some log message',
91
- 'context' => array(
92
- 'stuff' => new \DateTime('2014-02-01 02:31:33'),
93
- 'some_object' => $someObject,
94
- 'context_string' => 'some string',
95
- 'context_int' => 123456,
96
- 'except' => new \Exception('exception message', 987),
97
- ),
98
- 'level' => Logger::WARNING,
99
- 'level_name' => Logger::getLevelName(Logger::WARNING),
100
- 'channel' => 'test',
101
- 'datetime' => new \DateTime('2014-02-01 00:00:00'),
102
- 'extra' => array(),
103
- );
104
-
105
- $formatter = new MongoDBFormatter();
106
- $formattedRecord = $formatter->format($record);
107
-
108
- $this->assertCount(5, $formattedRecord['context']);
109
- $this->assertInstanceOf('\MongoDate', $formattedRecord['context']['stuff']);
110
- $this->assertEquals('0.00000000 1391221893', $formattedRecord['context']['stuff']->__toString());
111
- $this->assertEquals(
112
- array(
113
- 'foo' => 'something',
114
- 'bar' => 'stuff',
115
- 'class' => 'stdClass',
116
- ),
117
- $formattedRecord['context']['some_object']
118
- );
119
- $this->assertEquals('some string', $formattedRecord['context']['context_string']);
120
- $this->assertEquals(123456, $formattedRecord['context']['context_int']);
121
-
122
- $this->assertCount(5, $formattedRecord['context']['except']);
123
- $this->assertEquals('exception message', $formattedRecord['context']['except']['message']);
124
- $this->assertEquals(987, $formattedRecord['context']['except']['code']);
125
- $this->assertInternalType('string', $formattedRecord['context']['except']['file']);
126
- $this->assertInternalType('integer', $formattedRecord['context']['except']['code']);
127
- $this->assertInternalType('string', $formattedRecord['context']['except']['trace']);
128
- $this->assertEquals('Exception', $formattedRecord['context']['except']['class']);
129
- }
130
-
131
- public function testFormatDepthArray()
132
- {
133
- $record = array(
134
- 'message' => 'some log message',
135
- 'context' => array(
136
- 'nest2' => array(
137
- 'property' => 'anything',
138
- 'nest3' => array(
139
- 'nest4' => 'value',
140
- 'property' => 'nothing',
141
- ),
142
- ),
143
- ),
144
- 'level' => Logger::WARNING,
145
- 'level_name' => Logger::getLevelName(Logger::WARNING),
146
- 'channel' => 'test',
147
- 'datetime' => new \DateTime('2014-02-01 00:00:00'),
148
- 'extra' => array(),
149
- );
150
-
151
- $formatter = new MongoDBFormatter(2);
152
- $formattedResult = $formatter->format($record);
153
-
154
- $this->assertEquals(
155
- array(
156
- 'nest2' => array(
157
- 'property' => 'anything',
158
- 'nest3' => '[...]',
159
- ),
160
- ),
161
- $formattedResult['context']
162
- );
163
- }
164
-
165
- public function testFormatDepthArrayInfiniteNesting()
166
- {
167
- $record = array(
168
- 'message' => 'some log message',
169
- 'context' => array(
170
- 'nest2' => array(
171
- 'property' => 'something',
172
- 'nest3' => array(
173
- 'property' => 'anything',
174
- 'nest4' => array(
175
- 'property' => 'nothing',
176
- ),
177
- ),
178
- ),
179
- ),
180
- 'level' => Logger::WARNING,
181
- 'level_name' => Logger::getLevelName(Logger::WARNING),
182
- 'channel' => 'test',
183
- 'datetime' => new \DateTime('2014-02-01 00:00:00'),
184
- 'extra' => array(),
185
- );
186
-
187
- $formatter = new MongoDBFormatter(0);
188
- $formattedResult = $formatter->format($record);
189
-
190
- $this->assertEquals(
191
- array(
192
- 'nest2' => array(
193
- 'property' => 'something',
194
- 'nest3' => array(
195
- 'property' => 'anything',
196
- 'nest4' => array(
197
- 'property' => 'nothing',
198
- ),
199
- ),
200
- ),
201
- ),
202
- $formattedResult['context']
203
- );
204
- }
205
-
206
- public function testFormatDepthObjects()
207
- {
208
- $someObject = new \stdClass();
209
- $someObject->property = 'anything';
210
- $someObject->nest3 = new \stdClass();
211
- $someObject->nest3->property = 'nothing';
212
- $someObject->nest3->nest4 = 'invisible';
213
-
214
- $record = array(
215
- 'message' => 'some log message',
216
- 'context' => array(
217
- 'nest2' => $someObject,
218
- ),
219
- 'level' => Logger::WARNING,
220
- 'level_name' => Logger::getLevelName(Logger::WARNING),
221
- 'channel' => 'test',
222
- 'datetime' => new \DateTime('2014-02-01 00:00:00'),
223
- 'extra' => array(),
224
- );
225
-
226
- $formatter = new MongoDBFormatter(2, true);
227
- $formattedResult = $formatter->format($record);
228
-
229
- $this->assertEquals(
230
- array(
231
- 'nest2' => array(
232
- 'property' => 'anything',
233
- 'nest3' => '[...]',
234
- 'class' => 'stdClass',
235
- ),
236
- ),
237
- $formattedResult['context']
238
- );
239
- }
240
-
241
- public function testFormatDepthException()
242
- {
243
- $record = array(
244
- 'message' => 'some log message',
245
- 'context' => array(
246
- 'nest2' => new \Exception('exception message', 987),
247
- ),
248
- 'level' => Logger::WARNING,
249
- 'level_name' => Logger::getLevelName(Logger::WARNING),
250
- 'channel' => 'test',
251
- 'datetime' => new \DateTime('2014-02-01 00:00:00'),
252
- 'extra' => array(),
253
- );
254
-
255
- $formatter = new MongoDBFormatter(2, false);
256
- $formattedRecord = $formatter->format($record);
257
-
258
- $this->assertEquals('exception message', $formattedRecord['context']['nest2']['message']);
259
- $this->assertEquals(987, $formattedRecord['context']['nest2']['code']);
260
- $this->assertEquals('[...]', $formattedRecord['context']['nest2']['trace']);
261
- }
262
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Formatter/NormalizerFormatterTest.php DELETED
@@ -1,405 +0,0 @@
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 tearDown()
20
- {
21
- \PHPUnit_Framework_Error_Warning::$enabled = true;
22
-
23
- return parent::tearDown();
24
- }
25
-
26
- public function testFormat()
27
- {
28
- $formatter = new NormalizerFormatter('Y-m-d');
29
- $formatted = $formatter->format(array(
30
- 'level_name' => 'ERROR',
31
- 'channel' => 'meh',
32
- 'message' => 'foo',
33
- 'datetime' => new \DateTime,
34
- 'extra' => array('foo' => new TestFooNorm, 'bar' => new TestBarNorm, 'baz' => array(), 'res' => fopen('php://memory', 'rb')),
35
- 'context' => array(
36
- 'foo' => 'bar',
37
- 'baz' => 'qux',
38
- 'inf' => INF,
39
- '-inf' => -INF,
40
- 'nan' => acos(4),
41
- ),
42
- ));
43
-
44
- $this->assertEquals(array(
45
- 'level_name' => 'ERROR',
46
- 'channel' => 'meh',
47
- 'message' => 'foo',
48
- 'datetime' => date('Y-m-d'),
49
- 'extra' => array(
50
- 'foo' => '[object] (Monolog\\Formatter\\TestFooNorm: {"foo":"foo"})',
51
- 'bar' => '[object] (Monolog\\Formatter\\TestBarNorm: bar)',
52
- 'baz' => array(),
53
- 'res' => '[resource] (stream)',
54
- ),
55
- 'context' => array(
56
- 'foo' => 'bar',
57
- 'baz' => 'qux',
58
- 'inf' => 'INF',
59
- '-inf' => '-INF',
60
- 'nan' => 'NaN',
61
- ),
62
- ), $formatted);
63
- }
64
-
65
- public function testFormatExceptions()
66
- {
67
- $formatter = new NormalizerFormatter('Y-m-d');
68
- $e = new \LogicException('bar');
69
- $e2 = new \RuntimeException('foo', 0, $e);
70
- $formatted = $formatter->format(array(
71
- 'exception' => $e2,
72
- ));
73
-
74
- $this->assertGreaterThan(5, count($formatted['exception']['trace']));
75
- $this->assertTrue(isset($formatted['exception']['previous']));
76
- unset($formatted['exception']['trace'], $formatted['exception']['previous']);
77
-
78
- $this->assertEquals(array(
79
- 'exception' => array(
80
- 'class' => get_class($e2),
81
- 'message' => $e2->getMessage(),
82
- 'code' => $e2->getCode(),
83
- 'file' => $e2->getFile().':'.$e2->getLine(),
84
- ),
85
- ), $formatted);
86
- }
87
-
88
- public function testFormatSoapFaultException()
89
- {
90
- if (!class_exists('SoapFault')) {
91
- $this->markTestSkipped('Requires the soap extension');
92
- }
93
-
94
- $formatter = new NormalizerFormatter('Y-m-d');
95
- $e = new \SoapFault('foo', 'bar', 'hello', 'world');
96
- $formatted = $formatter->format(array(
97
- 'exception' => $e,
98
- ));
99
-
100
- unset($formatted['exception']['trace']);
101
-
102
- $this->assertEquals(array(
103
- 'exception' => array(
104
- 'class' => 'SoapFault',
105
- 'message' => 'bar',
106
- 'code' => 0,
107
- 'file' => $e->getFile().':'.$e->getLine(),
108
- 'faultcode' => 'foo',
109
- 'faultactor' => 'hello',
110
- 'detail' => 'world',
111
- ),
112
- ), $formatted);
113
- }
114
-
115
- public function testFormatToStringExceptionHandle()
116
- {
117
- $formatter = new NormalizerFormatter('Y-m-d');
118
- $this->setExpectedException('RuntimeException', 'Could not convert to string');
119
- $formatter->format(array(
120
- 'myObject' => new TestToStringError(),
121
- ));
122
- }
123
-
124
- public function testBatchFormat()
125
- {
126
- $formatter = new NormalizerFormatter('Y-m-d');
127
- $formatted = $formatter->formatBatch(array(
128
- array(
129
- 'level_name' => 'CRITICAL',
130
- 'channel' => 'test',
131
- 'message' => 'bar',
132
- 'context' => array(),
133
- 'datetime' => new \DateTime,
134
- 'extra' => array(),
135
- ),
136
- array(
137
- 'level_name' => 'WARNING',
138
- 'channel' => 'log',
139
- 'message' => 'foo',
140
- 'context' => array(),
141
- 'datetime' => new \DateTime,
142
- 'extra' => array(),
143
- ),
144
- ));
145
- $this->assertEquals(array(
146
- array(
147
- 'level_name' => 'CRITICAL',
148
- 'channel' => 'test',
149
- 'message' => 'bar',
150
- 'context' => array(),
151
- 'datetime' => date('Y-m-d'),
152
- 'extra' => array(),
153
- ),
154
- array(
155
- 'level_name' => 'WARNING',
156
- 'channel' => 'log',
157
- 'message' => 'foo',
158
- 'context' => array(),
159
- 'datetime' => date('Y-m-d'),
160
- 'extra' => array(),
161
- ),
162
- ), $formatted);
163
- }
164
-
165
- /**
166
- * Test issue #137
167
- */
168
- public function testIgnoresRecursiveObjectReferences()
169
- {
170
- // set up the recursion
171
- $foo = new \stdClass();
172
- $bar = new \stdClass();
173
-
174
- $foo->bar = $bar;
175
- $bar->foo = $foo;
176
-
177
- // set an error handler to assert that the error is not raised anymore
178
- $that = $this;
179
- set_error_handler(function ($level, $message, $file, $line, $context) use ($that) {
180
- if (error_reporting() & $level) {
181
- restore_error_handler();
182
- $that->fail("$message should not be raised");
183
- }
184
- });
185
-
186
- $formatter = new NormalizerFormatter();
187
- $reflMethod = new \ReflectionMethod($formatter, 'toJson');
188
- $reflMethod->setAccessible(true);
189
- $res = $reflMethod->invoke($formatter, array($foo, $bar), true);
190
-
191
- restore_error_handler();
192
-
193
- $this->assertEquals(@json_encode(array($foo, $bar)), $res);
194
- }
195
-
196
- public function testIgnoresInvalidTypes()
197
- {
198
- // set up the recursion
199
- $resource = fopen(__FILE__, 'r');
200
-
201
- // set an error handler to assert that the error is not raised anymore
202
- $that = $this;
203
- set_error_handler(function ($level, $message, $file, $line, $context) use ($that) {
204
- if (error_reporting() & $level) {
205
- restore_error_handler();
206
- $that->fail("$message should not be raised");
207
- }
208
- });
209
-
210
- $formatter = new NormalizerFormatter();
211
- $reflMethod = new \ReflectionMethod($formatter, 'toJson');
212
- $reflMethod->setAccessible(true);
213
- $res = $reflMethod->invoke($formatter, array($resource), true);
214
-
215
- restore_error_handler();
216
-
217
- $this->assertEquals(@json_encode(array($resource)), $res);
218
- }
219
-
220
- /**
221
- * @expectedException RuntimeException
222
- */
223
- public function testThrowsOnInvalidEncoding()
224
- {
225
- if (version_compare(PHP_VERSION, '5.5.0', '<')) {
226
- // Ignore the warning that will be emitted by PHP <5.5.0
227
- \PHPUnit_Framework_Error_Warning::$enabled = false;
228
- }
229
- $formatter = new NormalizerFormatter();
230
- $reflMethod = new \ReflectionMethod($formatter, 'toJson');
231
- $reflMethod->setAccessible(true);
232
-
233
- // send an invalid unicode sequence as a object that can't be cleaned
234
- $record = new \stdClass;
235
- $record->message = "\xB1\x31";
236
- $res = $reflMethod->invoke($formatter, $record);
237
- if (PHP_VERSION_ID < 50500 && $res === '{"message":null}') {
238
- throw new \RuntimeException('PHP 5.3/5.4 throw a warning and null the value instead of returning false entirely');
239
- }
240
- }
241
-
242
- public function testConvertsInvalidEncodingAsLatin9()
243
- {
244
- if (version_compare(PHP_VERSION, '5.5.0', '<')) {
245
- // Ignore the warning that will be emitted by PHP <5.5.0
246
- \PHPUnit_Framework_Error_Warning::$enabled = false;
247
- }
248
- $formatter = new NormalizerFormatter();
249
- $reflMethod = new \ReflectionMethod($formatter, 'toJson');
250
- $reflMethod->setAccessible(true);
251
-
252
- $res = $reflMethod->invoke($formatter, array('message' => "\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE"));
253
-
254
- if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
255
- $this->assertSame('{"message":"€ŠšŽžŒœŸ"}', $res);
256
- } else {
257
- // PHP <5.5 does not return false for an element encoding failure,
258
- // instead it emits a warning (possibly) and nulls the value.
259
- $this->assertSame('{"message":null}', $res);
260
- }
261
- }
262
-
263
- /**
264
- * @param mixed $in Input
265
- * @param mixed $expect Expected output
266
- * @covers Monolog\Formatter\NormalizerFormatter::detectAndCleanUtf8
267
- * @dataProvider providesDetectAndCleanUtf8
268
- */
269
- public function testDetectAndCleanUtf8($in, $expect)
270
- {
271
- $formatter = new NormalizerFormatter();
272
- $formatter->detectAndCleanUtf8($in);
273
- $this->assertSame($expect, $in);
274
- }
275
-
276
- public function providesDetectAndCleanUtf8()
277
- {
278
- $obj = new \stdClass;
279
-
280
- return array(
281
- 'null' => array(null, null),
282
- 'int' => array(123, 123),
283
- 'float' => array(123.45, 123.45),
284
- 'bool false' => array(false, false),
285
- 'bool true' => array(true, true),
286
- 'ascii string' => array('abcdef', 'abcdef'),
287
- 'latin9 string' => array("\xB1\x31\xA4\xA6\xA8\xB4\xB8\xBC\xBD\xBE\xFF", '±1€ŠšŽžŒœŸÿ'),
288
- 'unicode string' => array('¤¦¨´¸¼½¾€ŠšŽžŒœŸ', '¤¦¨´¸¼½¾€ŠšŽžŒœŸ'),
289
- 'empty array' => array(array(), array()),
290
- 'array' => array(array('abcdef'), array('abcdef')),
291
- 'object' => array($obj, $obj),
292
- );
293
- }
294
-
295
- /**
296
- * @param int $code
297
- * @param string $msg
298
- * @dataProvider providesHandleJsonErrorFailure
299
- */
300
- public function testHandleJsonErrorFailure($code, $msg)
301
- {
302
- $formatter = new NormalizerFormatter();
303
- $reflMethod = new \ReflectionMethod($formatter, 'handleJsonError');
304
- $reflMethod->setAccessible(true);
305
-
306
- $this->setExpectedException('RuntimeException', $msg);
307
- $reflMethod->invoke($formatter, $code, 'faked');
308
- }
309
-
310
- public function providesHandleJsonErrorFailure()
311
- {
312
- return array(
313
- 'depth' => array(JSON_ERROR_DEPTH, 'Maximum stack depth exceeded'),
314
- 'state' => array(JSON_ERROR_STATE_MISMATCH, 'Underflow or the modes mismatch'),
315
- 'ctrl' => array(JSON_ERROR_CTRL_CHAR, 'Unexpected control character found'),
316
- 'default' => array(-1, 'Unknown error'),
317
- );
318
- }
319
-
320
- public function testExceptionTraceWithArgs()
321
- {
322
- if (defined('HHVM_VERSION')) {
323
- $this->markTestSkipped('Not supported in HHVM since it detects errors differently');
324
- }
325
-
326
- // This happens i.e. in React promises or Guzzle streams where stream wrappers are registered
327
- // and no file or line are included in the trace because it's treated as internal function
328
- set_error_handler(function ($errno, $errstr, $errfile, $errline) {
329
- throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
330
- });
331
-
332
- try {
333
- // This will contain $resource and $wrappedResource as arguments in the trace item
334
- $resource = fopen('php://memory', 'rw+');
335
- fwrite($resource, 'test_resource');
336
- $wrappedResource = new TestFooNorm;
337
- $wrappedResource->foo = $resource;
338
- // Just do something stupid with a resource/wrapped resource as argument
339
- array_keys($wrappedResource);
340
- } catch (\Exception $e) {
341
- restore_error_handler();
342
- }
343
-
344
- $formatter = new NormalizerFormatter();
345
- $record = array('context' => array('exception' => $e));
346
- $result = $formatter->format($record);
347
-
348
- $this->assertRegExp(
349
- '%"resource":"\[resource\] \(stream\)"%',
350
- $result['context']['exception']['trace'][0]
351
- );
352
-
353
- if (version_compare(PHP_VERSION, '5.5.0', '>=')) {
354
- $pattern = '%"wrappedResource":"\[object\] \(Monolog\\\\\\\\Formatter\\\\\\\\TestFooNorm: \)"%';
355
- } else {
356
- $pattern = '%\\\\"foo\\\\":null%';
357
- }
358
-
359
- // Tests that the wrapped resource is ignored while encoding, only works for PHP <= 5.4
360
- $this->assertRegExp(
361
- $pattern,
362
- $result['context']['exception']['trace'][0]
363
- );
364
- }
365
- }
366
-
367
- class TestFooNorm
368
- {
369
- public $foo = 'foo';
370
- }
371
-
372
- class TestBarNorm
373
- {
374
- public function __toString()
375
- {
376
- return 'bar';
377
- }
378
- }
379
-
380
- class TestStreamFoo
381
- {
382
- public $foo;
383
- public $resource;
384
-
385
- public function __construct($resource)
386
- {
387
- $this->resource = $resource;
388
- $this->foo = 'BAR';
389
- }
390
-
391
- public function __toString()
392
- {
393
- fseek($this->resource, 0);
394
-
395
- return $this->foo . ' - ' . (string) stream_get_contents($this->resource);
396
- }
397
- }
398
-
399
- class TestToStringError
400
- {
401
- public function __toString()
402
- {
403
- throw new \RuntimeException('Could not convert to string');
404
- }
405
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Formatter/ScalarFormatterTest.php DELETED
@@ -1,110 +0,0 @@
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
- class ScalarFormatterTest extends \PHPUnit_Framework_TestCase
15
- {
16
- private $formatter;
17
-
18
- public function setUp()
19
- {
20
- $this->formatter = new ScalarFormatter();
21
- }
22
-
23
- public function buildTrace(\Exception $e)
24
- {
25
- $data = array();
26
- $trace = $e->getTrace();
27
- foreach ($trace as $frame) {
28
- if (isset($frame['file'])) {
29
- $data[] = $frame['file'].':'.$frame['line'];
30
- } else {
31
- $data[] = json_encode($frame);
32
- }
33
- }
34
-
35
- return $data;
36
- }
37
-
38
- public function encodeJson($data)
39
- {
40
- if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
41
- return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
42
- }
43
-
44
- return json_encode($data);
45
- }
46
-
47
- public function testFormat()
48
- {
49
- $exception = new \Exception('foo');
50
- $formatted = $this->formatter->format(array(
51
- 'foo' => 'string',
52
- 'bar' => 1,
53
- 'baz' => false,
54
- 'bam' => array(1, 2, 3),
55
- 'bat' => array('foo' => 'bar'),
56
- 'bap' => \DateTime::createFromFormat(\DateTime::ISO8601, '1970-01-01T00:00:00+0000'),
57
- 'ban' => $exception,
58
- ));
59
-
60
- $this->assertSame(array(
61
- 'foo' => 'string',
62
- 'bar' => 1,
63
- 'baz' => false,
64
- 'bam' => $this->encodeJson(array(1, 2, 3)),
65
- 'bat' => $this->encodeJson(array('foo' => 'bar')),
66
- 'bap' => '1970-01-01 00:00:00',
67
- 'ban' => $this->encodeJson(array(
68
- 'class' => get_class($exception),
69
- 'message' => $exception->getMessage(),
70
- 'code' => $exception->getCode(),
71
- 'file' => $exception->getFile() . ':' . $exception->getLine(),
72
- 'trace' => $this->buildTrace($exception),
73
- )),
74
- ), $formatted);
75
- }
76
-
77
- public function testFormatWithErrorContext()
78
- {
79
- $context = array('file' => 'foo', 'line' => 1);
80
- $formatted = $this->formatter->format(array(
81
- 'context' => $context,
82
- ));
83
-
84
- $this->assertSame(array(
85
- 'context' => $this->encodeJson($context),
86
- ), $formatted);
87
- }
88
-
89
- public function testFormatWithExceptionContext()
90
- {
91
- $exception = new \Exception('foo');
92
- $formatted = $this->formatter->format(array(
93
- 'context' => array(
94
- 'exception' => $exception,
95
- ),
96
- ));
97
-
98
- $this->assertSame(array(
99
- 'context' => $this->encodeJson(array(
100
- 'exception' => array(
101
- 'class' => get_class($exception),
102
- 'message' => $exception->getMessage(),
103
- 'code' => $exception->getCode(),
104
- 'file' => $exception->getFile() . ':' . $exception->getLine(),
105
- 'trace' => $this->buildTrace($exception),
106
- ),
107
- )),
108
- ), $formatted);
109
- }
110
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Formatter/WildfireFormatterTest.php DELETED
@@ -1,142 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/AbstractHandlerTest.php DELETED
@@ -1,115 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/AbstractProcessingHandlerTest.php DELETED
@@ -1,80 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/AmqpHandlerTest.php DELETED
@@ -1,136 +0,0 @@
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\Connection\AMQPConnection;
18
-
19
- /**
20
- * @covers Monolog\Handler\RotatingFileHandler
21
- */
22
- class AmqpHandlerTest extends TestCase
23
- {
24
- public function testHandleAmqpExt()
25
- {
26
- if (!class_exists('AMQPConnection') || !class_exists('AMQPExchange')) {
27
- $this->markTestSkipped("amqp-php not installed");
28
- }
29
-
30
- if (!class_exists('AMQPChannel')) {
31
- $this->markTestSkipped("Please update AMQP to version >= 1.0");
32
- }
33
-
34
- $messages = array();
35
-
36
- $exchange = $this->getMock('AMQPExchange', array('publish', 'setName'), array(), '', false);
37
- $exchange->expects($this->once())
38
- ->method('setName')
39
- ->with('log')
40
- ;
41
- $exchange->expects($this->any())
42
- ->method('publish')
43
- ->will($this->returnCallback(function ($message, $routing_key, $flags = 0, $attributes = array()) use (&$messages) {
44
- $messages[] = array($message, $routing_key, $flags, $attributes);
45
- }))
46
- ;
47
-
48
- $handler = new AmqpHandler($exchange, 'log');
49
-
50
- $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
51
-
52
- $expected = array(
53
- array(
54
- 'message' => 'test',
55
- 'context' => array(
56
- 'data' => array(),
57
- 'foo' => 34,
58
- ),
59
- 'level' => 300,
60
- 'level_name' => 'WARNING',
61
- 'channel' => 'test',
62
- 'extra' => array(),
63
- ),
64
- 'warn.test',
65
- 0,
66
- array(
67
- 'delivery_mode' => 2,
68
- 'content_type' => 'application/json',
69
- ),
70
- );
71
-
72
- $handler->handle($record);
73
-
74
- $this->assertCount(1, $messages);
75
- $messages[0][0] = json_decode($messages[0][0], true);
76
- unset($messages[0][0]['datetime']);
77
- $this->assertEquals($expected, $messages[0]);
78
- }
79
-
80
- public function testHandlePhpAmqpLib()
81
- {
82
- if (!class_exists('PhpAmqpLib\Connection\AMQPConnection')) {
83
- $this->markTestSkipped("php-amqplib not installed");
84
- }
85
-
86
- $messages = array();
87
-
88
- $exchange = $this->getMock('PhpAmqpLib\Channel\AMQPChannel', array('basic_publish', '__destruct'), array(), '', false);
89
-
90
- $exchange->expects($this->any())
91
- ->method('basic_publish')
92
- ->will($this->returnCallback(function (AMQPMessage $msg, $exchange = "", $routing_key = "", $mandatory = false, $immediate = false, $ticket = null) use (&$messages) {
93
- $messages[] = array($msg, $exchange, $routing_key, $mandatory, $immediate, $ticket);
94
- }))
95
- ;
96
-
97
- $handler = new AmqpHandler($exchange, 'log');
98
-
99
- $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
100
-
101
- $expected = array(
102
- array(
103
- 'message' => 'test',
104
- 'context' => array(
105
- 'data' => array(),
106
- 'foo' => 34,
107
- ),
108
- 'level' => 300,
109
- 'level_name' => 'WARNING',
110
- 'channel' => 'test',
111
- 'extra' => array(),
112
- ),
113
- 'log',
114
- 'warn.test',
115
- false,
116
- false,
117
- null,
118
- array(
119
- 'delivery_mode' => 2,
120
- 'content_type' => 'application/json',
121
- ),
122
- );
123
-
124
- $handler->handle($record);
125
-
126
- $this->assertCount(1, $messages);
127
-
128
- /* @var $msg AMQPMessage */
129
- $msg = $messages[0][0];
130
- $messages[0][0] = json_decode($msg->body, true);
131
- $messages[0][] = $msg->get_properties();
132
- unset($messages[0][0]['datetime']);
133
-
134
- $this->assertEquals($expected, $messages[0]);
135
- }
136
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/BrowserConsoleHandlerTest.php DELETED
@@ -1,130 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/BufferHandlerTest.php DELETED
@@ -1,158 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/ChromePHPHandlerTest.php DELETED
@@ -1,141 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/CouchDBHandlerTest.php DELETED
@@ -1,31 +0,0 @@
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
- $handler = new CouchDBHandler();
24
-
25
- try {
26
- $handler->handle($record);
27
- } catch (\RuntimeException $e) {
28
- $this->markTestSkipped('Could not connect to couchdb server on http://localhost:5984');
29
- }
30
- }
31
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/DeduplicationHandlerTest.php DELETED
@@ -1,165 +0,0 @@
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 DeduplicationHandlerTest extends TestCase
18
- {
19
- /**
20
- * @covers Monolog\Handler\DeduplicationHandler::flush
21
- */
22
- public function testFlushPassthruIfAllRecordsUnderTrigger()
23
- {
24
- $test = new TestHandler();
25
- @unlink(sys_get_temp_dir().'/monolog_dedup.log');
26
- $handler = new DeduplicationHandler($test, sys_get_temp_dir().'/monolog_dedup.log', 0);
27
-
28
- $handler->handle($this->getRecord(Logger::DEBUG));
29
- $handler->handle($this->getRecord(Logger::INFO));
30
-
31
- $handler->flush();
32
-
33
- $this->assertTrue($test->hasInfoRecords());
34
- $this->assertTrue($test->hasDebugRecords());
35
- $this->assertFalse($test->hasWarningRecords());
36
- }
37
-
38
- /**
39
- * @covers Monolog\Handler\DeduplicationHandler::flush
40
- * @covers Monolog\Handler\DeduplicationHandler::appendRecord
41
- */
42
- public function testFlushPassthruIfEmptyLog()
43
- {
44
- $test = new TestHandler();
45
- @unlink(sys_get_temp_dir().'/monolog_dedup.log');
46
- $handler = new DeduplicationHandler($test, sys_get_temp_dir().'/monolog_dedup.log', 0);
47
-
48
- $handler->handle($this->getRecord(Logger::ERROR, 'Foo:bar'));
49
- $handler->handle($this->getRecord(Logger::CRITICAL, "Foo\nbar"));
50
-
51
- $handler->flush();
52
-
53
- $this->assertTrue($test->hasErrorRecords());
54
- $this->assertTrue($test->hasCriticalRecords());
55
- $this->assertFalse($test->hasWarningRecords());
56
- }
57
-
58
- /**
59
- * @covers Monolog\Handler\DeduplicationHandler::flush
60
- * @covers Monolog\Handler\DeduplicationHandler::appendRecord
61
- * @covers Monolog\Handler\DeduplicationHandler::isDuplicate
62
- * @depends testFlushPassthruIfEmptyLog
63
- */
64
- public function testFlushSkipsIfLogExists()
65
- {
66
- $test = new TestHandler();
67
- $handler = new DeduplicationHandler($test, sys_get_temp_dir().'/monolog_dedup.log', 0);
68
-
69
- $handler->handle($this->getRecord(Logger::ERROR, 'Foo:bar'));
70
- $handler->handle($this->getRecord(Logger::CRITICAL, "Foo\nbar"));
71
-
72
- $handler->flush();
73
-
74
- $this->assertFalse($test->hasErrorRecords());
75
- $this->assertFalse($test->hasCriticalRecords());
76
- $this->assertFalse($test->hasWarningRecords());
77
- }
78
-
79
- /**
80
- * @covers Monolog\Handler\DeduplicationHandler::flush
81
- * @covers Monolog\Handler\DeduplicationHandler::appendRecord
82
- * @covers Monolog\Handler\DeduplicationHandler::isDuplicate
83
- * @depends testFlushPassthruIfEmptyLog
84
- */
85
- public function testFlushPassthruIfLogTooOld()
86
- {
87
- $test = new TestHandler();
88
- $handler = new DeduplicationHandler($test, sys_get_temp_dir().'/monolog_dedup.log', 0);
89
-
90
- $record = $this->getRecord(Logger::ERROR);
91
- $record['datetime']->modify('+62seconds');
92
- $handler->handle($record);
93
- $record = $this->getRecord(Logger::CRITICAL);
94
- $record['datetime']->modify('+62seconds');
95
- $handler->handle($record);
96
-
97
- $handler->flush();
98
-
99
- $this->assertTrue($test->hasErrorRecords());
100
- $this->assertTrue($test->hasCriticalRecords());
101
- $this->assertFalse($test->hasWarningRecords());
102
- }
103
-
104
- /**
105
- * @covers Monolog\Handler\DeduplicationHandler::flush
106
- * @covers Monolog\Handler\DeduplicationHandler::appendRecord
107
- * @covers Monolog\Handler\DeduplicationHandler::isDuplicate
108
- * @covers Monolog\Handler\DeduplicationHandler::collectLogs
109
- */
110
- public function testGcOldLogs()
111
- {
112
- $test = new TestHandler();
113
- @unlink(sys_get_temp_dir().'/monolog_dedup.log');
114
- $handler = new DeduplicationHandler($test, sys_get_temp_dir().'/monolog_dedup.log', 0);
115
-
116
- // handle two records from yesterday, and one recent
117
- $record = $this->getRecord(Logger::ERROR);
118
- $record['datetime']->modify('-1day -10seconds');
119
- $handler->handle($record);
120
- $record2 = $this->getRecord(Logger::CRITICAL);
121
- $record2['datetime']->modify('-1day -10seconds');
122
- $handler->handle($record2);
123
- $record3 = $this->getRecord(Logger::CRITICAL);
124
- $record3['datetime']->modify('-30seconds');
125
- $handler->handle($record3);
126
-
127
- // log is written as none of them are duplicate
128
- $handler->flush();
129
- $this->assertSame(
130
- $record['datetime']->getTimestamp() . ":ERROR:test\n" .
131
- $record2['datetime']->getTimestamp() . ":CRITICAL:test\n" .
132
- $record3['datetime']->getTimestamp() . ":CRITICAL:test\n",
133
- file_get_contents(sys_get_temp_dir() . '/monolog_dedup.log')
134
- );
135
- $this->assertTrue($test->hasErrorRecords());
136
- $this->assertTrue($test->hasCriticalRecords());
137
- $this->assertFalse($test->hasWarningRecords());
138
-
139
- // clear test handler
140
- $test->clear();
141
- $this->assertFalse($test->hasErrorRecords());
142
- $this->assertFalse($test->hasCriticalRecords());
143
-
144
- // log new records, duplicate log gets GC'd at the end of this flush call
145
- $handler->handle($record = $this->getRecord(Logger::ERROR));
146
- $handler->handle($record2 = $this->getRecord(Logger::CRITICAL));
147
- $handler->flush();
148
-
149
- // log should now contain the new errors and the previous one that was recent enough
150
- $this->assertSame(
151
- $record3['datetime']->getTimestamp() . ":CRITICAL:test\n" .
152
- $record['datetime']->getTimestamp() . ":ERROR:test\n" .
153
- $record2['datetime']->getTimestamp() . ":CRITICAL:test\n",
154
- file_get_contents(sys_get_temp_dir() . '/monolog_dedup.log')
155
- );
156
- $this->assertTrue($test->hasErrorRecords());
157
- $this->assertTrue($test->hasCriticalRecords());
158
- $this->assertFalse($test->hasWarningRecords());
159
- }
160
-
161
- public static function tearDownAfterClass()
162
- {
163
- @unlink(sys_get_temp_dir().'/monolog_dedup.log');
164
- }
165
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/DoctrineCouchDBHandlerTest.php DELETED
@@ -1,52 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/DynamoDbHandlerTest.php DELETED
@@ -1,75 +0,0 @@
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
- private $client;
19
-
20
- public function setUp()
21
- {
22
- if (!class_exists('Aws\DynamoDb\DynamoDbClient')) {
23
- $this->markTestSkipped('aws/aws-sdk-php not installed');
24
- }
25
-
26
- $this->client = $this->getMockBuilder('Aws\DynamoDb\DynamoDbClient')
27
- ->setMethods(array('formatAttributes', '__call'))
28
- ->disableOriginalConstructor()->getMock();
29
- }
30
-
31
- public function testConstruct()
32
- {
33
- $this->assertInstanceOf('Monolog\Handler\DynamoDbHandler', new DynamoDbHandler($this->client, 'foo'));
34
- }
35
-
36
- public function testInterface()
37
- {
38
- $this->assertInstanceOf('Monolog\Handler\HandlerInterface', new DynamoDbHandler($this->client, 'foo'));
39
- }
40
-
41
- public function testGetFormatter()
42
- {
43
- $handler = new DynamoDbHandler($this->client, 'foo');
44
- $this->assertInstanceOf('Monolog\Formatter\ScalarFormatter', $handler->getFormatter());
45
- }
46
-
47
- public function testHandle()
48
- {
49
- $record = $this->getRecord();
50
- $formatter = $this->getMock('Monolog\Formatter\FormatterInterface');
51
- $formatted = array('foo' => 1, 'bar' => 2);
52
- $handler = new DynamoDbHandler($this->client, 'foo');
53
- $handler->setFormatter($formatter);
54
-
55
- $formatter
56
- ->expects($this->once())
57
- ->method('format')
58
- ->with($record)
59
- ->will($this->returnValue($formatted));
60
- $this->client
61
- ->expects($this->once())
62
- ->method('formatAttributes')
63
- ->with($this->isType('array'))
64
- ->will($this->returnValue($formatted));
65
- $this->client
66
- ->expects($this->once())
67
- ->method('__call')
68
- ->with('putItem', array(array(
69
- 'TableName' => 'foo',
70
- 'Item' => $formatted,
71
- )));
72
-
73
- $handler->handle($record);
74
- }
75
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/ElasticSearchHandlerTest.php DELETED
@@ -1,239 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/ErrorLogHandlerTest.php DELETED
@@ -1,66 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/FilterHandlerTest.php DELETED
@@ -1,170 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/FingersCrossedHandlerTest.php DELETED
@@ -1,279 +0,0 @@
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
- use Psr\Log\LogLevel;
19
-
20
- class FingersCrossedHandlerTest extends TestCase
21
- {
22
- /**
23
- * @covers Monolog\Handler\FingersCrossedHandler::__construct
24
- * @covers Monolog\Handler\FingersCrossedHandler::handle
25
- * @covers Monolog\Handler\FingersCrossedHandler::activate
26
- */
27
- public function testHandleBuffers()
28
- {
29
- $test = new TestHandler();
30
- $handler = new FingersCrossedHandler($test);
31
- $handler->handle($this->getRecord(Logger::DEBUG));
32
- $handler->handle($this->getRecord(Logger::INFO));
33
- $this->assertFalse($test->hasDebugRecords());
34
- $this->assertFalse($test->hasInfoRecords());
35
- $handler->handle($this->getRecord(Logger::WARNING));
36
- $handler->close();
37
- $this->assertTrue($test->hasInfoRecords());
38
- $this->assertTrue(count($test->getRecords()) === 3);
39
- }
40
-
41
- /**
42
- * @covers Monolog\Handler\FingersCrossedHandler::handle
43
- * @covers Monolog\Handler\FingersCrossedHandler::activate
44
- */
45
- public function testHandleStopsBufferingAfterTrigger()
46
- {
47
- $test = new TestHandler();
48
- $handler = new FingersCrossedHandler($test);
49
- $handler->handle($this->getRecord(Logger::WARNING));
50
- $handler->handle($this->getRecord(Logger::DEBUG));
51
- $handler->close();
52
- $this->assertTrue($test->hasWarningRecords());
53
- $this->assertTrue($test->hasDebugRecords());
54
- }
55
-
56
- /**
57
- * @covers Monolog\Handler\FingersCrossedHandler::handle
58
- * @covers Monolog\Handler\FingersCrossedHandler::activate
59
- * @covers Monolog\Handler\FingersCrossedHandler::reset
60
- */
61
- public function testHandleRestartBufferingAfterReset()
62
- {
63
- $test = new TestHandler();
64
- $handler = new FingersCrossedHandler($test);
65
- $handler->handle($this->getRecord(Logger::WARNING));
66
- $handler->handle($this->getRecord(Logger::DEBUG));
67
- $handler->reset();
68
- $handler->handle($this->getRecord(Logger::INFO));
69
- $handler->close();
70
- $this->assertTrue($test->hasWarningRecords());
71
- $this->assertTrue($test->hasDebugRecords());
72
- $this->assertFalse($test->hasInfoRecords());
73
- }
74
-
75
- /**
76
- * @covers Monolog\Handler\FingersCrossedHandler::handle
77
- * @covers Monolog\Handler\FingersCrossedHandler::activate
78
- */
79
- public function testHandleRestartBufferingAfterBeingTriggeredWhenStopBufferingIsDisabled()
80
- {
81
- $test = new TestHandler();
82
- $handler = new FingersCrossedHandler($test, Logger::WARNING, 0, false, false);
83
- $handler->handle($this->getRecord(Logger::DEBUG));
84
- $handler->handle($this->getRecord(Logger::WARNING));
85
- $handler->handle($this->getRecord(Logger::INFO));
86
- $handler->close();
87
- $this->assertTrue($test->hasWarningRecords());
88
- $this->assertTrue($test->hasDebugRecords());
89
- $this->assertFalse($test->hasInfoRecords());
90
- }
91
-
92
- /**
93
- * @covers Monolog\Handler\FingersCrossedHandler::handle
94
- * @covers Monolog\Handler\FingersCrossedHandler::activate
95
- */
96
- public function testHandleBufferLimit()
97
- {
98
- $test = new TestHandler();
99
- $handler = new FingersCrossedHandler($test, Logger::WARNING, 2);
100
- $handler->handle($this->getRecord(Logger::DEBUG));
101
- $handler->handle($this->getRecord(Logger::DEBUG));
102
- $handler->handle($this->getRecord(Logger::INFO));
103
- $handler->handle($this->getRecord(Logger::WARNING));
104
- $this->assertTrue($test->hasWarningRecords());
105
- $this->assertTrue($test->hasInfoRecords());
106
- $this->assertFalse($test->hasDebugRecords());
107
- }
108
-
109
- /**
110
- * @covers Monolog\Handler\FingersCrossedHandler::handle
111
- * @covers Monolog\Handler\FingersCrossedHandler::activate
112
- */
113
- public function testHandleWithCallback()
114
- {
115
- $test = new TestHandler();
116
- $handler = new FingersCrossedHandler(function ($record, $handler) use ($test) {
117
- return $test;
118
- });
119
- $handler->handle($this->getRecord(Logger::DEBUG));
120
- $handler->handle($this->getRecord(Logger::INFO));
121
- $this->assertFalse($test->hasDebugRecords());
122
- $this->assertFalse($test->hasInfoRecords());
123
- $handler->handle($this->getRecord(Logger::WARNING));
124
- $this->assertTrue($test->hasInfoRecords());
125
- $this->assertTrue(count($test->getRecords()) === 3);
126
- }
127
-
128
- /**
129
- * @covers Monolog\Handler\FingersCrossedHandler::handle
130
- * @covers Monolog\Handler\FingersCrossedHandler::activate
131
- * @expectedException RuntimeException
132
- */
133
- public function testHandleWithBadCallbackThrowsException()
134
- {
135
- $handler = new FingersCrossedHandler(function ($record, $handler) {
136
- return 'foo';
137
- });
138
- $handler->handle($this->getRecord(Logger::WARNING));
139
- }
140
-
141
- /**
142
- * @covers Monolog\Handler\FingersCrossedHandler::isHandling
143
- */
144
- public function testIsHandlingAlways()
145
- {
146
- $test = new TestHandler();
147
- $handler = new FingersCrossedHandler($test, Logger::ERROR);
148
- $this->assertTrue($handler->isHandling($this->getRecord(Logger::DEBUG)));
149
- }
150
-
151
- /**
152
- * @covers Monolog\Handler\FingersCrossedHandler::__construct
153
- * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::__construct
154
- * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::isHandlerActivated
155
- */
156
- public function testErrorLevelActivationStrategy()
157
- {
158
- $test = new TestHandler();
159
- $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy(Logger::WARNING));
160
- $handler->handle($this->getRecord(Logger::DEBUG));
161
- $this->assertFalse($test->hasDebugRecords());
162
- $handler->handle($this->getRecord(Logger::WARNING));
163
- $this->assertTrue($test->hasDebugRecords());
164
- $this->assertTrue($test->hasWarningRecords());
165
- }
166
-
167
- /**
168
- * @covers Monolog\Handler\FingersCrossedHandler::__construct
169
- * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::__construct
170
- * @covers Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy::isHandlerActivated
171
- */
172
- public function testErrorLevelActivationStrategyWithPsrLevel()
173
- {
174
- $test = new TestHandler();
175
- $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy('warning'));
176
- $handler->handle($this->getRecord(Logger::DEBUG));
177
- $this->assertFalse($test->hasDebugRecords());
178
- $handler->handle($this->getRecord(Logger::WARNING));
179
- $this->assertTrue($test->hasDebugRecords());
180
- $this->assertTrue($test->hasWarningRecords());
181
- }
182
-
183
- /**
184
- * @covers Monolog\Handler\FingersCrossedHandler::__construct
185
- * @covers Monolog\Handler\FingersCrossedHandler::activate
186
- */
187
- public function testOverrideActivationStrategy()
188
- {
189
- $test = new TestHandler();
190
- $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy('warning'));
191
- $handler->handle($this->getRecord(Logger::DEBUG));
192
- $this->assertFalse($test->hasDebugRecords());
193
- $handler->activate();
194
- $this->assertTrue($test->hasDebugRecords());
195
- $handler->handle($this->getRecord(Logger::INFO));
196
- $this->assertTrue($test->hasInfoRecords());
197
- }
198
-
199
- /**
200
- * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::__construct
201
- * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::isHandlerActivated
202
- */
203
- public function testChannelLevelActivationStrategy()
204
- {
205
- $test = new TestHandler();
206
- $handler = new FingersCrossedHandler($test, new ChannelLevelActivationStrategy(Logger::ERROR, array('othertest' => Logger::DEBUG)));
207
- $handler->handle($this->getRecord(Logger::WARNING));
208
- $this->assertFalse($test->hasWarningRecords());
209
- $record = $this->getRecord(Logger::DEBUG);
210
- $record['channel'] = 'othertest';
211
- $handler->handle($record);
212
- $this->assertTrue($test->hasDebugRecords());
213
- $this->assertTrue($test->hasWarningRecords());
214
- }
215
-
216
- /**
217
- * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::__construct
218
- * @covers Monolog\Handler\FingersCrossed\ChannelLevelActivationStrategy::isHandlerActivated
219
- */
220
- public function testChannelLevelActivationStrategyWithPsrLevels()
221
- {
222
- $test = new TestHandler();
223
- $handler = new FingersCrossedHandler($test, new ChannelLevelActivationStrategy('error', array('othertest' => 'debug')));
224
- $handler->handle($this->getRecord(Logger::WARNING));
225
- $this->assertFalse($test->hasWarningRecords());
226
- $record = $this->getRecord(Logger::DEBUG);
227
- $record['channel'] = 'othertest';
228
- $handler->handle($record);
229
- $this->assertTrue($test->hasDebugRecords());
230
- $this->assertTrue($test->hasWarningRecords());
231
- }
232
-
233
- /**
234
- * @covers Monolog\Handler\FingersCrossedHandler::handle
235
- * @covers Monolog\Handler\FingersCrossedHandler::activate
236
- */
237
- public function testHandleUsesProcessors()
238
- {
239
- $test = new TestHandler();
240
- $handler = new FingersCrossedHandler($test, Logger::INFO);
241
- $handler->pushProcessor(function ($record) {
242
- $record['extra']['foo'] = true;
243
-
244
- return $record;
245
- });
246
- $handler->handle($this->getRecord(Logger::WARNING));
247
- $this->assertTrue($test->hasWarningRecords());
248
- $records = $test->getRecords();
249
- $this->assertTrue($records[0]['extra']['foo']);
250
- }
251
-
252
- /**
253
- * @covers Monolog\Handler\FingersCrossedHandler::close
254
- */
255
- public function testPassthruOnClose()
256
- {
257
- $test = new TestHandler();
258
- $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy(Logger::WARNING), 0, true, true, Logger::INFO);
259
- $handler->handle($this->getRecord(Logger::DEBUG));
260
- $handler->handle($this->getRecord(Logger::INFO));
261
- $handler->close();
262
- $this->assertFalse($test->hasDebugRecords());
263
- $this->assertTrue($test->hasInfoRecords());
264
- }
265
-
266
- /**
267
- * @covers Monolog\Handler\FingersCrossedHandler::close
268
- */
269
- public function testPsrLevelPassthruOnClose()
270
- {
271
- $test = new TestHandler();
272
- $handler = new FingersCrossedHandler($test, new ErrorLevelActivationStrategy(Logger::WARNING), 0, true, true, LogLevel::INFO);
273
- $handler->handle($this->getRecord(Logger::DEBUG));
274
- $handler->handle($this->getRecord(Logger::INFO));
275
- $handler->close();
276
- $this->assertFalse($test->hasDebugRecords());
277
- $this->assertTrue($test->hasInfoRecords());
278
- }
279
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/FirePHPHandlerTest.php DELETED
@@ -1,96 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/Fixtures/.gitkeep DELETED
File without changes
vendor/monolog/monolog/tests/Monolog/Handler/FleepHookHandlerTest.php DELETED
@@ -1,85 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/FlowdockHandlerTest.php DELETED
@@ -1,88 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerLegacyTest.php DELETED
@@ -1,95 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/GelfHandlerTest.php DELETED
@@ -1,117 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/GelfMockMessagePublisher.php DELETED
@@ -1,25 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/GroupHandlerTest.php DELETED
@@ -1,112 +0,0 @@
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
-
90
- /**
91
- * @covers Monolog\Handler\GroupHandler::handle
92
- */
93
- public function testHandleBatchUsesProcessors()
94
- {
95
- $testHandlers = array(new TestHandler(), new TestHandler());
96
- $handler = new GroupHandler($testHandlers);
97
- $handler->pushProcessor(function ($record) {
98
- $record['extra']['foo'] = true;
99
-
100
- return $record;
101
- });
102
- $handler->handleBatch(array($this->getRecord(Logger::DEBUG), $this->getRecord(Logger::INFO)));
103
- foreach ($testHandlers as $test) {
104
- $this->assertTrue($test->hasDebugRecords());
105
- $this->assertTrue($test->hasInfoRecords());
106
- $this->assertTrue(count($test->getRecords()) === 2);
107
- $records = $test->getRecords();
108
- $this->assertTrue($records[0]['extra']['foo']);
109
- $this->assertTrue($records[1]['extra']['foo']);
110
- }
111
- }
112
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/HandlerWrapperTest.php DELETED
@@ -1,130 +0,0 @@
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
- /**
17
- * @author Alexey Karapetov <alexey@karapetov.com>
18
- */
19
- class HandlerWrapperTest extends TestCase
20
- {
21
- /**
22
- * @var HandlerWrapper
23
- */
24
- private $wrapper;
25
-
26
- private $handler;
27
-
28
- public function setUp()
29
- {
30
- parent::setUp();
31
- $this->handler = $this->getMock('Monolog\\Handler\\HandlerInterface');
32
- $this->wrapper = new HandlerWrapper($this->handler);
33
- }
34
-
35
- /**
36
- * @return array
37
- */
38
- public function trueFalseDataProvider()
39
- {
40
- return array(
41
- array(true),
42
- array(false),
43
- );
44
- }
45
-
46
- /**
47
- * @param $result
48
- * @dataProvider trueFalseDataProvider
49
- */
50
- public function testIsHandling($result)
51
- {
52
- $record = $this->getRecord();
53
- $this->handler->expects($this->once())
54
- ->method('isHandling')
55
- ->with($record)
56
- ->willReturn($result);
57
-
58
- $this->assertEquals($result, $this->wrapper->isHandling($record));
59
- }
60
-
61
- /**
62
- * @param $result
63
- * @dataProvider trueFalseDataProvider
64
- */
65
- public function testHandle($result)
66
- {
67
- $record = $this->getRecord();
68
- $this->handler->expects($this->once())
69
- ->method('handle')
70
- ->with($record)
71
- ->willReturn($result);
72
-
73
- $this->assertEquals($result, $this->wrapper->handle($record));
74
- }
75
-
76
- /**
77
- * @param $result
78
- * @dataProvider trueFalseDataProvider
79
- */
80
- public function testHandleBatch($result)
81
- {
82
- $records = $this->getMultipleRecords();
83
- $this->handler->expects($this->once())
84
- ->method('handleBatch')
85
- ->with($records)
86
- ->willReturn($result);
87
-
88
- $this->assertEquals($result, $this->wrapper->handleBatch($records));
89
- }
90
-
91
- public function testPushProcessor()
92
- {
93
- $processor = function () {};
94
- $this->handler->expects($this->once())
95
- ->method('pushProcessor')
96
- ->with($processor);
97
-
98
- $this->assertEquals($this->wrapper, $this->wrapper->pushProcessor($processor));
99
- }
100
-
101
- public function testPopProcessor()
102
- {
103
- $processor = function () {};
104
- $this->handler->expects($this->once())
105
- ->method('popProcessor')
106
- ->willReturn($processor);
107
-
108
- $this->assertEquals($processor, $this->wrapper->popProcessor());
109
- }
110
-
111
- public function testSetFormatter()
112
- {
113
- $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
114
- $this->handler->expects($this->once())
115
- ->method('setFormatter')
116
- ->with($formatter);
117
-
118
- $this->assertEquals($this->wrapper, $this->wrapper->setFormatter($formatter));
119
- }
120
-
121
- public function testGetFormatter()
122
- {
123
- $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
124
- $this->handler->expects($this->once())
125
- ->method('getFormatter')
126
- ->willReturn($formatter);
127
-
128
- $this->assertEquals($formatter, $this->wrapper->getFormatter());
129
- }
130
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/HipChatHandlerTest.php DELETED
@@ -1,279 +0,0 @@
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
- /** @var HipChatHandler */
25
- private $handler;
26
-
27
- public function testWriteHeader()
28
- {
29
- $this->createHandler();
30
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
31
- fseek($this->res, 0);
32
- $content = fread($this->res, 1024);
33
-
34
- $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);
35
-
36
- return $content;
37
- }
38
-
39
- public function testWriteCustomHostHeader()
40
- {
41
- $this->createHandler('myToken', 'room1', 'Monolog', true, 'hipchat.foo.bar');
42
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
43
- fseek($this->res, 0);
44
- $content = fread($this->res, 1024);
45
-
46
- $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);
47
-
48
- return $content;
49
- }
50
-
51
- public function testWriteV2()
52
- {
53
- $this->createHandler('myToken', 'room1', 'Monolog', false, 'hipchat.foo.bar', 'v2');
54
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
55
- fseek($this->res, 0);
56
- $content = fread($this->res, 1024);
57
-
58
- $this->assertRegexp('/POST \/v2\/room\/room1\/notification\?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);
59
-
60
- return $content;
61
- }
62
-
63
- public function testWriteV2Notify()
64
- {
65
- $this->createHandler('myToken', 'room1', 'Monolog', true, 'hipchat.foo.bar', 'v2');
66
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
67
- fseek($this->res, 0);
68
- $content = fread($this->res, 1024);
69
-
70
- $this->assertRegexp('/POST \/v2\/room\/room1\/notification\?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);
71
-
72
- return $content;
73
- }
74
-
75
- public function testRoomSpaces()
76
- {
77
- $this->createHandler('myToken', 'room name', 'Monolog', false, 'hipchat.foo.bar', 'v2');
78
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
79
- fseek($this->res, 0);
80
- $content = fread($this->res, 1024);
81
-
82
- $this->assertRegexp('/POST \/v2\/room\/room%20name\/notification\?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);
83
-
84
- return $content;
85
- }
86
-
87
- /**
88
- * @depends testWriteHeader
89
- */
90
- public function testWriteContent($content)
91
- {
92
- $this->assertRegexp('/notify=0&message=test1&message_format=text&color=red&room_id=room1&from=Monolog$/', $content);
93
- }
94
-
95
- public function testWriteContentV1WithoutName()
96
- {
97
- $this->createHandler('myToken', 'room1', null, false, 'hipchat.foo.bar', 'v1');
98
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
99
- fseek($this->res, 0);
100
- $content = fread($this->res, 1024);
101
-
102
- $this->assertRegexp('/notify=0&message=test1&message_format=text&color=red&room_id=room1&from=$/', $content);
103
-
104
- return $content;
105
- }
106
-
107
- /**
108
- * @depends testWriteCustomHostHeader
109
- */
110
- public function testWriteContentNotify($content)
111
- {
112
- $this->assertRegexp('/notify=1&message=test1&message_format=text&color=red&room_id=room1&from=Monolog$/', $content);
113
- }
114
-
115
- /**
116
- * @depends testWriteV2
117
- */
118
- public function testWriteContentV2($content)
119
- {
120
- $this->assertRegexp('/notify=false&message=test1&message_format=text&color=red&from=Monolog$/', $content);
121
- }
122
-
123
- /**
124
- * @depends testWriteV2Notify
125
- */
126
- public function testWriteContentV2Notify($content)
127
- {
128
- $this->assertRegexp('/notify=true&message=test1&message_format=text&color=red&from=Monolog$/', $content);
129
- }
130
-
131
- public function testWriteContentV2WithoutName()
132
- {
133
- $this->createHandler('myToken', 'room1', null, false, 'hipchat.foo.bar', 'v2');
134
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
135
- fseek($this->res, 0);
136
- $content = fread($this->res, 1024);
137
-
138
- $this->assertRegexp('/notify=false&message=test1&message_format=text&color=red$/', $content);
139
-
140
- return $content;
141
- }
142
-
143
- public function testWriteWithComplexMessage()
144
- {
145
- $this->createHandler();
146
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'Backup of database "example" finished in 16 minutes.'));
147
- fseek($this->res, 0);
148
- $content = fread($this->res, 1024);
149
-
150
- $this->assertRegexp('/message=Backup\+of\+database\+%22example%22\+finished\+in\+16\+minutes\./', $content);
151
- }
152
-
153
- public function testWriteTruncatesLongMessage()
154
- {
155
- $this->createHandler();
156
- $this->handler->handle($this->getRecord(Logger::CRITICAL, str_repeat('abcde', 2000)));
157
- fseek($this->res, 0);
158
- $content = fread($this->res, 12000);
159
-
160
- $this->assertRegexp('/message='.str_repeat('abcde', 1900).'\+%5Btruncated%5D/', $content);
161
- }
162
-
163
- /**
164
- * @dataProvider provideLevelColors
165
- */
166
- public function testWriteWithErrorLevelsAndColors($level, $expectedColor)
167
- {
168
- $this->createHandler();
169
- $this->handler->handle($this->getRecord($level, 'Backup of database "example" finished in 16 minutes.'));
170
- fseek($this->res, 0);
171
- $content = fread($this->res, 1024);
172
-
173
- $this->assertRegexp('/color='.$expectedColor.'/', $content);
174
- }
175
-
176
- public function provideLevelColors()
177
- {
178
- return array(
179
- array(Logger::DEBUG, 'gray'),
180
- array(Logger::INFO, 'green'),
181
- array(Logger::WARNING, 'yellow'),
182
- array(Logger::ERROR, 'red'),
183
- array(Logger::CRITICAL, 'red'),
184
- array(Logger::ALERT, 'red'),
185
- array(Logger::EMERGENCY,'red'),
186
- array(Logger::NOTICE, 'green'),
187
- );
188
- }
189
-
190
- /**
191
- * @dataProvider provideBatchRecords
192
- */
193
- public function testHandleBatch($records, $expectedColor)
194
- {
195
- $this->createHandler();
196
-
197
- $this->handler->handleBatch($records);
198
-
199
- fseek($this->res, 0);
200
- $content = fread($this->res, 1024);
201
-
202
- $this->assertRegexp('/color='.$expectedColor.'/', $content);
203
- }
204
-
205
- public function provideBatchRecords()
206
- {
207
- return array(
208
- array(
209
- array(
210
- array('level' => Logger::WARNING, 'message' => 'Oh bugger!', 'level_name' => 'warning', 'datetime' => new \DateTime()),
211
- array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()),
212
- array('level' => Logger::CRITICAL, 'message' => 'Everything is broken!', 'level_name' => 'critical', 'datetime' => new \DateTime()),
213
- ),
214
- 'red',
215
- ),
216
- array(
217
- array(
218
- array('level' => Logger::WARNING, 'message' => 'Oh bugger!', 'level_name' => 'warning', 'datetime' => new \DateTime()),
219
- array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()),
220
- ),
221
- 'yellow',
222
- ),
223
- array(
224
- array(
225
- array('level' => Logger::DEBUG, 'message' => 'Just debugging.', 'level_name' => 'debug', 'datetime' => new \DateTime()),
226
- array('level' => Logger::NOTICE, 'message' => 'Something noticeable happened.', 'level_name' => 'notice', 'datetime' => new \DateTime()),
227
- ),
228
- 'green',
229
- ),
230
- array(
231
- array(
232
- array('level' => Logger::DEBUG, 'message' => 'Just debugging.', 'level_name' => 'debug', 'datetime' => new \DateTime()),
233
- ),
234
- 'gray',
235
- ),
236
- );
237
- }
238
-
239
- private function createHandler($token = 'myToken', $room = 'room1', $name = 'Monolog', $notify = false, $host = 'api.hipchat.com', $version = 'v1')
240
- {
241
- $constructorArgs = array($token, $room, $name, $notify, Logger::DEBUG, true, true, 'text', $host, $version);
242
- $this->res = fopen('php://memory', 'a');
243
- $this->handler = $this->getMock(
244
- '\Monolog\Handler\HipChatHandler',
245
- array('fsockopen', 'streamSetTimeout', 'closeSocket'),
246
- $constructorArgs
247
- );
248
-
249
- $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString');
250
- $reflectionProperty->setAccessible(true);
251
- $reflectionProperty->setValue($this->handler, 'localhost:1234');
252
-
253
- $this->handler->expects($this->any())
254
- ->method('fsockopen')
255
- ->will($this->returnValue($this->res));
256
- $this->handler->expects($this->any())
257
- ->method('streamSetTimeout')
258
- ->will($this->returnValue(true));
259
- $this->handler->expects($this->any())
260
- ->method('closeSocket')
261
- ->will($this->returnValue(true));
262
-
263
- $this->handler->setFormatter($this->getIdentityFormatter());
264
- }
265
-
266
- /**
267
- * @expectedException InvalidArgumentException
268
- */
269
- public function testCreateWithTooLongName()
270
- {
271
- $hipChatHandler = new HipChatHandler('token', 'room', 'SixteenCharsHere');
272
- }
273
-
274
- public function testCreateWithTooLongNameV2()
275
- {
276
- // creating a handler with too long of a name but using the v2 api doesn't matter.
277
- $hipChatHandler = new HipChatHandler('token', 'room', 'SixteenCharsHere', false, Logger::CRITICAL, true, true, 'test', 'api.hipchat.com', 'v2');
278
- }
279
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/LogEntriesHandlerTest.php DELETED
@@ -1,84 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/MailHandlerTest.php DELETED
@@ -1,75 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/MockRavenClient.php DELETED
@@ -1,27 +0,0 @@
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
- $data = array_merge($this->get_user_data(), $data);
21
- $this->lastData = $data;
22
- $this->lastStack = $stack;
23
- }
24
-
25
- public $lastData;
26
- public $lastStack;
27
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/MongoDBHandlerTest.php DELETED
@@ -1,65 +0,0 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/NativeMailerHandlerTest.php DELETED
@@ -1,111 +0,0 @@
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 InvalidArgumentException;
17
-
18
- function mail($to, $subject, $message, $additional_headers = null, $additional_parameters = null)
19
- {
20
- $GLOBALS['mail'][] = func_get_args();
21
- }
22
-
23
- class NativeMailerHandlerTest extends TestCase
24
- {
25
- protected function setUp()
26
- {
27
- $GLOBALS['mail'] = array();
28
- }
29
-
30
- /**
31
- * @expectedException InvalidArgumentException
32
- */
33
- public function testConstructorHeaderInjection()
34
- {
35
- $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', "receiver@example.org\r\nFrom: faked@attacker.org");
36
- }
37
-
38
- /**
39
- * @expectedException InvalidArgumentException
40
- */
41
- public function testSetterHeaderInjection()
42
- {
43
- $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org');
44
- $mailer->addHeader("Content-Type: text/html\r\nFrom: faked@attacker.org");
45
- }
46
-
47
- /**
48
- * @expectedException InvalidArgumentException
49
- */
50
- public function testSetterArrayHeaderInjection()
51
- {
52
- $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org');
53
- $mailer->addHeader(array("Content-Type: text/html\r\nFrom: faked@attacker.org"));
54
- }
55
-
56
- /**
57
- * @expectedException InvalidArgumentException
58
- */
59
- public function testSetterContentTypeInjection()
60
- {
61
- $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org');
62
- $mailer->setContentType("text/html\r\nFrom: faked@attacker.org");
63
- }
64
-
65
- /**
66
- * @expectedException InvalidArgumentException
67
- */
68
- public function testSetterEncodingInjection()
69
- {
70
- $mailer = new NativeMailerHandler('spammer@example.org', 'dear victim', 'receiver@example.org');
71
- $mailer->setEncoding("utf-8\r\nFrom: faked@attacker.org");
72
- }
73
-
74
- public function testSend()
75
- {
76
- $to = 'spammer@example.org';
77
- $subject = 'dear victim';
78
- $from = 'receiver@example.org';
79
-
80
- $mailer = new NativeMailerHandler($to, $subject, $from);
81
- $mailer->handleBatch(array());
82
-
83
- // batch is empty, nothing sent
84
- $this->assertEmpty($GLOBALS['mail']);
85
-
86
- // non-empty batch
87
- $mailer->handle($this->getRecord(Logger::ERROR, "Foo\nBar\r\n\r\nBaz"));
88
- $this->assertNotEmpty($GLOBALS['mail']);
89
- $this->assertInternalType('array', $GLOBALS['mail']);
90
- $this->assertArrayHasKey('0', $GLOBALS['mail']);
91
- $params = $GLOBALS['mail'][0];
92
- $this->assertCount(5, $params);
93
- $this->assertSame($to, $params[0]);
94
- $this->assertSame($subject, $params[1]);
95
- $this->assertStringEndsWith(" test.ERROR: Foo Bar Baz [] []\n", $params[2]);
96
- $this->assertSame("From: $from\r\nContent-type: text/plain; charset=utf-8\r\n", $params[3]);
97
- $this->assertSame('', $params[4]);
98
- }
99
-
100
- public function testMessageSubjectFormatting()
101
- {
102
- $mailer = new NativeMailerHandler('to@example.org', 'Alert: %level_name% %message%', 'from@example.org');
103
- $mailer->handle($this->getRecord(Logger::ERROR, "Foo\nBar\r\n\r\nBaz"));
104
- $this->assertNotEmpty($GLOBALS['mail']);
105
- $this->assertInternalType('array', $GLOBALS['mail']);
106
- $this->assertArrayHasKey('0', $GLOBALS['mail']);
107
- $params = $GLOBALS['mail'][0];
108
- $this->assertCount(5, $params);
109
- $this->assertSame('Alert: ERROR Foo Bar Baz', $params[1]);
110
- }
111
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/NewRelicHandlerTest.php DELETED
@@ -1,200 +0,0 @@
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\TestCase;
16
- use Monolog\Logger;
17
-
18
- class NewRelicHandlerTest extends TestCase
19
- {
20
- public static $appname;
21
- public static $customParameters;
22
- public static $transactionName;
23
-
24
- public function setUp()
25
- {
26
- self::$appname = null;
27
- self::$customParameters = array();
28
- self::$transactionName = null;
29
- }
30
-
31
- /**
32
- * @expectedException Monolog\Handler\MissingExtensionException
33
- */
34
- public function testThehandlerThrowsAnExceptionIfTheNRExtensionIsNotLoaded()
35
- {
36
- $handler = new StubNewRelicHandlerWithoutExtension();
37
- $handler->handle($this->getRecord(Logger::ERROR));
38
- }
39
-
40
- public function testThehandlerCanHandleTheRecord()
41
- {
42
- $handler = new StubNewRelicHandler();
43
- $handler->handle($this->getRecord(Logger::ERROR));
44
- }
45
-
46
- public function testThehandlerCanAddContextParamsToTheNewRelicTrace()
47
- {
48
- $handler = new StubNewRelicHandler();
49
- $handler->handle($this->getRecord(Logger::ERROR, 'log message', array('a' => 'b')));
50
- $this->assertEquals(array('context_a' => 'b'), self::$customParameters);
51
- }
52
-
53
- public function testThehandlerCanAddExplodedContextParamsToTheNewRelicTrace()
54
- {
55
- $handler = new StubNewRelicHandler(Logger::ERROR, true, self::$appname, true);
56
- $handler->handle($this->getRecord(
57
- Logger::ERROR,
58
- 'log message',
59
- array('a' => array('key1' => 'value1', 'key2' => 'value2'))
60
- ));
61
- $this->assertEquals(
62
- array('context_a_key1' => 'value1', 'context_a_key2' => 'value2'),
63
- self::$customParameters
64
- );
65
- }
66
-
67
- public function testThehandlerCanAddExtraParamsToTheNewRelicTrace()
68
- {
69
- $record = $this->getRecord(Logger::ERROR, 'log message');
70
- $record['extra'] = array('c' => 'd');
71
-
72
- $handler = new StubNewRelicHandler();
73
- $handler->handle($record);
74
-
75
- $this->assertEquals(array('extra_c' => 'd'), self::$customParameters);
76
- }
77
-
78
- public function testThehandlerCanAddExplodedExtraParamsToTheNewRelicTrace()
79
- {
80
- $record = $this->getRecord(Logger::ERROR, 'log message');
81
- $record['extra'] = array('c' => array('key1' => 'value1', 'key2' => 'value2'));
82
-
83
- $handler = new StubNewRelicHandler(Logger::ERROR, true, self::$appname, true);
84
- $handler->handle($record);
85
-
86
- $this->assertEquals(
87
- array('extra_c_key1' => 'value1', 'extra_c_key2' => 'value2'),
88
- self::$customParameters
89
- );
90
- }
91
-
92
- public function testThehandlerCanAddExtraContextAndParamsToTheNewRelicTrace()
93
- {
94
- $record = $this->getRecord(Logger::ERROR, 'log message', array('a' => 'b'));
95
- $record['extra'] = array('c' => 'd');
96
-
97
- $handler = new StubNewRelicHandler();
98
- $handler->handle($record);
99
-
100
- $expected = array(
101
- 'context_a' => 'b',
102
- 'extra_c' => 'd',
103
- );
104
-
105
- $this->assertEquals($expected, self::$customParameters);
106
- }
107
-
108
- public function testThehandlerCanHandleTheRecordsFormattedUsingTheLineFormatter()
109
- {
110
- $handler = new StubNewRelicHandler();
111
- $handler->setFormatter(new LineFormatter());
112
- $handler->handle($this->getRecord(Logger::ERROR));
113
- }
114
-
115
- public function testTheAppNameIsNullByDefault()
116
- {
117
- $handler = new StubNewRelicHandler();
118
- $handler->handle($this->getRecord(Logger::ERROR, 'log message'));
119
-
120
- $this->assertEquals(null, self::$appname);
121
- }
122
-
123
- public function testTheAppNameCanBeInjectedFromtheConstructor()
124
- {
125
- $handler = new StubNewRelicHandler(Logger::DEBUG, false, 'myAppName');
126
- $handler->handle($this->getRecord(Logger::ERROR, 'log message'));
127
-
128
- $this->assertEquals('myAppName', self::$appname);
129
- }
130
-
131
- public function testTheAppNameCanBeOverriddenFromEachLog()
132
- {
133
- $handler = new StubNewRelicHandler(Logger::DEBUG, false, 'myAppName');
134
- $handler->handle($this->getRecord(Logger::ERROR, 'log message', array('appname' => 'logAppName')));
135
-
136
- $this->assertEquals('logAppName', self::$appname);
137
- }
138
-
139
- public function testTheTransactionNameIsNullByDefault()
140
- {
141
- $handler = new StubNewRelicHandler();
142
- $handler->handle($this->getRecord(Logger::ERROR, 'log message'));
143
-
144
- $this->assertEquals(null, self::$transactionName);
145
- }
146
-
147
- public function testTheTransactionNameCanBeInjectedFromTheConstructor()
148
- {
149
- $handler = new StubNewRelicHandler(Logger::DEBUG, false, null, false, 'myTransaction');
150
- $handler->handle($this->getRecord(Logger::ERROR, 'log message'));
151
-
152
- $this->assertEquals('myTransaction', self::$transactionName);
153
- }
154
-
155
- public function testTheTransactionNameCanBeOverriddenFromEachLog()
156
- {
157
- $handler = new StubNewRelicHandler(Logger::DEBUG, false, null, false, 'myTransaction');
158
- $handler->handle($this->getRecord(Logger::ERROR, 'log message', array('transaction_name' => 'logTransactName')));
159
-
160
- $this->assertEquals('logTransactName', self::$transactionName);
161
- }
162
- }
163
-
164
- class StubNewRelicHandlerWithoutExtension extends NewRelicHandler
165
- {
166
- protected function isNewRelicEnabled()
167
- {
168
- return false;
169
- }
170
- }
171
-
172
- class StubNewRelicHandler extends NewRelicHandler
173
- {
174
- protected function isNewRelicEnabled()
175
- {
176
- return true;
177
- }
178
- }
179
-
180
- function newrelic_notice_error()
181
- {
182
- return true;
183
- }
184
-
185
- function newrelic_set_appname($appname)
186
- {
187
- return NewRelicHandlerTest::$appname = $appname;
188
- }
189
-
190
- function newrelic_name_transaction($transactionName)
191
- {
192
- return NewRelicHandlerTest::$transactionName = $transactionName;
193
- }
194
-
195
- function newrelic_add_custom_parameter($key, $value)
196
- {
197
- NewRelicHandlerTest::$customParameters[$key] = $value;
198
-
199
- return true;
200
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/NullHandlerTest.php DELETED
@@ -1,33 +0,0 @@
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\NullHandler::handle
19
- */
20
- class NullHandlerTest extends TestCase
21
- {
22
- public function testHandle()
23
- {
24
- $handler = new NullHandler();
25
- $this->assertTrue($handler->handle($this->getRecord()));
26
- }
27
-
28
- public function testHandleLowerLevelRecord()
29
- {
30
- $handler = new NullHandler(Logger::WARNING);
31
- $this->assertFalse($handler->handle($this->getRecord(Logger::DEBUG)));
32
- }
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/PHPConsoleHandlerTest.php DELETED
@@ -1,273 +0,0 @@
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 Exception;
15
- use Monolog\ErrorHandler;
16
- use Monolog\Logger;
17
- use Monolog\TestCase;
18
- use PhpConsole\Connector;
19
- use PhpConsole\Dispatcher\Debug as DebugDispatcher;
20
- use PhpConsole\Dispatcher\Errors as ErrorDispatcher;
21
- use PhpConsole\Handler;
22
- use PHPUnit_Framework_MockObject_MockObject;
23
-
24
- /**
25
- * @covers Monolog\Handler\PHPConsoleHandler
26
- * @author Sergey Barbushin https://www.linkedin.com/in/barbushin
27
- */
28
- class PHPConsoleHandlerTest extends TestCase
29
- {
30
- /** @var Connector|PHPUnit_Framework_MockObject_MockObject */
31
- protected $connector;
32
- /** @var DebugDispatcher|PHPUnit_Framework_MockObject_MockObject */
33
- protected $debugDispatcher;
34
- /** @var ErrorDispatcher|PHPUnit_Framework_MockObject_MockObject */
35
- protected $errorDispatcher;
36
-
37
- protected function setUp()
38
- {
39
- if (!class_exists('PhpConsole\Connector')) {
40
- $this->markTestSkipped('PHP Console library not found. See https://github.com/barbushin/php-console#installation');
41
- }
42
- $this->connector = $this->initConnectorMock();
43
-
44
- $this->debugDispatcher = $this->initDebugDispatcherMock($this->connector);
45
- $this->connector->setDebugDispatcher($this->debugDispatcher);
46
-
47
- $this->errorDispatcher = $this->initErrorDispatcherMock($this->connector);
48
- $this->connector->setErrorsDispatcher($this->errorDispatcher);
49
- }
50
-
51
- protected function initDebugDispatcherMock(Connector $connector)
52
- {
53
- return $this->getMockBuilder('PhpConsole\Dispatcher\Debug')
54
- ->disableOriginalConstructor()
55
- ->setMethods(array('dispatchDebug'))
56
- ->setConstructorArgs(array($connector, $connector->getDumper()))
57
- ->getMock();
58
- }
59
-
60
- protected function initErrorDispatcherMock(Connector $connector)
61
- {
62
- return $this->getMockBuilder('PhpConsole\Dispatcher\Errors')
63
- ->disableOriginalConstructor()
64
- ->setMethods(array('dispatchError', 'dispatchException'))
65
- ->setConstructorArgs(array($connector, $connector->getDumper()))
66
- ->getMock();
67
- }
68
-
69
- protected function initConnectorMock()
70
- {
71
- $connector = $this->getMockBuilder('PhpConsole\Connector')
72
- ->disableOriginalConstructor()
73
- ->setMethods(array(
74
- 'sendMessage',
75
- 'onShutDown',
76
- 'isActiveClient',
77
- 'setSourcesBasePath',
78
- 'setServerEncoding',
79
- 'setPassword',
80
- 'enableSslOnlyMode',
81
- 'setAllowedIpMasks',
82
- 'setHeadersLimit',
83
- 'startEvalRequestsListener',
84
- ))
85
- ->getMock();
86
-
87
- $connector->expects($this->any())
88
- ->method('isActiveClient')
89
- ->will($this->returnValue(true));
90
-
91
- return $connector;
92
- }
93
-
94
- protected function getHandlerDefaultOption($name)
95
- {
96
- $handler = new PHPConsoleHandler(array(), $this->connector);
97
- $options = $handler->getOptions();
98
-
99
- return $options[$name];
100
- }
101
-
102
- protected function initLogger($handlerOptions = array(), $level = Logger::DEBUG)
103
- {
104
- return new Logger('test', array(
105
- new PHPConsoleHandler($handlerOptions, $this->connector, $level),
106
- ));
107
- }
108
-
109
- public function testInitWithDefaultConnector()
110
- {
111
- $handler = new PHPConsoleHandler();
112
- $this->assertEquals(spl_object_hash(Connector::getInstance()), spl_object_hash($handler->getConnector()));
113
- }
114
-
115
- public function testInitWithCustomConnector()
116
- {
117
- $handler = new PHPConsoleHandler(array(), $this->connector);
118
- $this->assertEquals(spl_object_hash($this->connector), spl_object_hash($handler->getConnector()));
119
- }
120
-
121
- public function testDebug()
122
- {
123
- $this->debugDispatcher->expects($this->once())->method('dispatchDebug')->with($this->equalTo('test'));
124
- $this->initLogger()->addDebug('test');
125
- }
126
-
127
- public function testDebugContextInMessage()
128
- {
129
- $message = 'test';
130
- $tag = 'tag';
131
- $context = array($tag, 'custom' => mt_rand());
132
- $expectedMessage = $message . ' ' . json_encode(array_slice($context, 1));
133
- $this->debugDispatcher->expects($this->once())->method('dispatchDebug')->with(
134
- $this->equalTo($expectedMessage),
135
- $this->equalTo($tag)
136
- );
137
- $this->initLogger()->addDebug($message, $context);
138
- }
139
-
140
- public function testDebugTags($tagsContextKeys = null)
141
- {
142
- $expectedTags = mt_rand();
143
- $logger = $this->initLogger($tagsContextKeys ? array('debugTagsKeysInContext' => $tagsContextKeys) : array());
144
- if (!$tagsContextKeys) {
145
- $tagsContextKeys = $this->getHandlerDefaultOption('debugTagsKeysInContext');
146
- }
147
- foreach ($tagsContextKeys as $key) {
148
- $debugDispatcher = $this->initDebugDispatcherMock($this->connector);
149
- $debugDispatcher->expects($this->once())->method('dispatchDebug')->with(
150
- $this->anything(),
151
- $this->equalTo($expectedTags)
152
- );
153
- $this->connector->setDebugDispatcher($debugDispatcher);
154
- $logger->addDebug('test', array($key => $expectedTags));
155
- }
156
- }
157
-
158
- public function testError($classesPartialsTraceIgnore = null)
159
- {
160
- $code = E_USER_NOTICE;
161
- $message = 'message';
162
- $file = __FILE__;
163
- $line = __LINE__;
164
- $this->errorDispatcher->expects($this->once())->method('dispatchError')->with(
165
- $this->equalTo($code),
166
- $this->equalTo($message),
167
- $this->equalTo($file),
168
- $this->equalTo($line),
169
- $classesPartialsTraceIgnore ?: $this->equalTo($this->getHandlerDefaultOption('classesPartialsTraceIgnore'))
170
- );
171
- $errorHandler = ErrorHandler::register($this->initLogger($classesPartialsTraceIgnore ? array('classesPartialsTraceIgnore' => $classesPartialsTraceIgnore) : array()), false);
172
- $errorHandler->registerErrorHandler(array(), false, E_USER_WARNING);
173
- $errorHandler->handleError($code, $message, $file, $line);
174
- }
175
-
176
- public function testException()
177
- {
178
- $e = new Exception();
179
- $this->errorDispatcher->expects($this->once())->method('dispatchException')->with(
180
- $this->equalTo($e)
181
- );
182
- $handler = $this->initLogger();
183
- $handler->log(
184
- \Psr\Log\LogLevel::ERROR,
185
- sprintf('Uncaught Exception %s: "%s" at %s line %s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()),
186
- array('exception' => $e)
187
- );
188
- }
189
-
190
- /**
191
- * @expectedException Exception
192
- */
193
- public function testWrongOptionsThrowsException()
194
- {
195
- new PHPConsoleHandler(array('xxx' => 1));
196
- }
197
-
198
- public function testOptionEnabled()
199
- {
200
- $this->debugDispatcher->expects($this->never())->method('dispatchDebug');
201
- $this->initLogger(array('enabled' => false))->addDebug('test');
202
- }
203
-
204
- public function testOptionClassesPartialsTraceIgnore()
205
- {
206
- $this->testError(array('Class', 'Namespace\\'));
207
- }
208
-
209
- public function testOptionDebugTagsKeysInContext()
210
- {
211
- $this->testDebugTags(array('key1', 'key2'));
212
- }
213
-
214
- public function testOptionUseOwnErrorsAndExceptionsHandler()
215
- {
216
- $this->initLogger(array('useOwnErrorsHandler' => true, 'useOwnExceptionsHandler' => true));
217
- $this->assertEquals(array(Handler::getInstance(), 'handleError'), set_error_handler(function () {
218
- }));
219
- $this->assertEquals(array(Handler::getInstance(), 'handleException'), set_exception_handler(function () {
220
- }));
221
- }
222
-
223
- public static function provideConnectorMethodsOptionsSets()
224
- {
225
- return array(
226
- array('sourcesBasePath', 'setSourcesBasePath', __DIR__),
227
- array('serverEncoding', 'setServerEncoding', 'cp1251'),
228
- array('password', 'setPassword', '******'),
229
- array('enableSslOnlyMode', 'enableSslOnlyMode', true, false),
230
- array('ipMasks', 'setAllowedIpMasks', array('127.0.0.*')),
231
- array('headersLimit', 'setHeadersLimit', 2500),
232
- array('enableEvalListener', 'startEvalRequestsListener', true, false),
233
- );
234
- }
235
-
236
- /**
237
- * @dataProvider provideConnectorMethodsOptionsSets
238
- */
239
- public function testOptionCallsConnectorMethod($option, $method, $value, $isArgument = true)
240
- {
241
- $expectCall = $this->connector->expects($this->once())->method($method);
242
- if ($isArgument) {
243
- $expectCall->with($value);
244
- }
245
- new PHPConsoleHandler(array($option => $value), $this->connector);
246
- }
247
-
248
- public function testOptionDetectDumpTraceAndSource()
249
- {
250
- new PHPConsoleHandler(array('detectDumpTraceAndSource' => true), $this->connector);
251
- $this->assertTrue($this->connector->getDebugDispatcher()->detectTraceAndSource);
252
- }
253
-
254
- public static function provideDumperOptionsValues()
255
- {
256
- return array(
257
- array('dumperLevelLimit', 'levelLimit', 1001),
258
- array('dumperItemsCountLimit', 'itemsCountLimit', 1002),
259
- array('dumperItemSizeLimit', 'itemSizeLimit', 1003),
260
- array('dumperDumpSizeLimit', 'dumpSizeLimit', 1004),
261
- array('dumperDetectCallbacks', 'detectCallbacks', true),
262
- );
263
- }
264
-
265
- /**
266
- * @dataProvider provideDumperOptionsValues
267
- */
268
- public function testDumperOptions($option, $dumperProperty, $value)
269
- {
270
- new PHPConsoleHandler(array($option => $value), $this->connector);
271
- $this->assertEquals($value, $this->connector->getDumper()->$dumperProperty);
272
- }
273
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/PsrHandlerTest.php DELETED
@@ -1,50 +0,0 @@
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\PsrHandler::handle
19
- */
20
- class PsrHandlerTest extends TestCase
21
- {
22
- public function logLevelProvider()
23
- {
24
- $levels = array();
25
- $monologLogger = new Logger('');
26
-
27
- foreach ($monologLogger->getLevels() as $levelName => $level) {
28
- $levels[] = array($levelName, $level);
29
- }
30
-
31
- return $levels;
32
- }
33
-
34
- /**
35
- * @dataProvider logLevelProvider
36
- */
37
- public function testHandlesAllLevels($levelName, $level)
38
- {
39
- $message = 'Hello, world! ' . $level;
40
- $context = array('foo' => 'bar', 'level' => $level);
41
-
42
- $psrLogger = $this->getMock('Psr\Log\NullLogger');
43
- $psrLogger->expects($this->once())
44
- ->method('log')
45
- ->with(strtolower($levelName), $message, $context);
46
-
47
- $handler = new PsrHandler($psrLogger);
48
- $handler->handle(array('level' => $level, 'level_name' => $levelName, 'message' => $message, 'context' => $context));
49
- }
50
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/PushoverHandlerTest.php DELETED
@@ -1,141 +0,0 @@
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
- * Almost all examples (expected header, titles, messages) taken from
19
- * https://www.pushover.net/api
20
- * @author Sebastian Göttschkes <sebastian.goettschkes@googlemail.com>
21
- * @see https://www.pushover.net/api
22
- */
23
- class PushoverHandlerTest extends TestCase
24
- {
25
- private $res;
26
- private $handler;
27
-
28
- public function testWriteHeader()
29
- {
30
- $this->createHandler();
31
- $this->handler->setHighPriorityLevel(Logger::EMERGENCY); // skip priority notifications
32
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
33
- fseek($this->res, 0);
34
- $content = fread($this->res, 1024);
35
-
36
- $this->assertRegexp('/POST \/1\/messages.json HTTP\/1.1\\r\\nHost: api.pushover.net\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content);
37
-
38
- return $content;
39
- }
40
-
41
- /**
42
- * @depends testWriteHeader
43
- */
44
- public function testWriteContent($content)
45
- {
46
- $this->assertRegexp('/token=myToken&user=myUser&message=test1&title=Monolog&timestamp=\d{10}$/', $content);
47
- }
48
-
49
- public function testWriteWithComplexTitle()
50
- {
51
- $this->createHandler('myToken', 'myUser', 'Backup finished - SQL1');
52
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
53
- fseek($this->res, 0);
54
- $content = fread($this->res, 1024);
55
-
56
- $this->assertRegexp('/title=Backup\+finished\+-\+SQL1/', $content);
57
- }
58
-
59
- public function testWriteWithComplexMessage()
60
- {
61
- $this->createHandler();
62
- $this->handler->setHighPriorityLevel(Logger::EMERGENCY); // skip priority notifications
63
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'Backup of database "example" finished in 16 minutes.'));
64
- fseek($this->res, 0);
65
- $content = fread($this->res, 1024);
66
-
67
- $this->assertRegexp('/message=Backup\+of\+database\+%22example%22\+finished\+in\+16\+minutes\./', $content);
68
- }
69
-
70
- public function testWriteWithTooLongMessage()
71
- {
72
- $message = str_pad('test', 520, 'a');
73
- $this->createHandler();
74
- $this->handler->setHighPriorityLevel(Logger::EMERGENCY); // skip priority notifications
75
- $this->handler->handle($this->getRecord(Logger::CRITICAL, $message));
76
- fseek($this->res, 0);
77
- $content = fread($this->res, 1024);
78
-
79
- $expectedMessage = substr($message, 0, 505);
80
-
81
- $this->assertRegexp('/message=' . $expectedMessage . '&title/', $content);
82
- }
83
-
84
- public function testWriteWithHighPriority()
85
- {
86
- $this->createHandler();
87
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
88
- fseek($this->res, 0);
89
- $content = fread($this->res, 1024);
90
-
91
- $this->assertRegexp('/token=myToken&user=myUser&message=test1&title=Monolog&timestamp=\d{10}&priority=1$/', $content);
92
- }
93
-
94
- public function testWriteWithEmergencyPriority()
95
- {
96
- $this->createHandler();
97
- $this->handler->handle($this->getRecord(Logger::EMERGENCY, 'test1'));
98
- fseek($this->res, 0);
99
- $content = fread($this->res, 1024);
100
-
101
- $this->assertRegexp('/token=myToken&user=myUser&message=test1&title=Monolog&timestamp=\d{10}&priority=2&retry=30&expire=25200$/', $content);
102
- }
103
-
104
- public function testWriteToMultipleUsers()
105
- {
106
- $this->createHandler('myToken', array('userA', 'userB'));
107
- $this->handler->handle($this->getRecord(Logger::EMERGENCY, 'test1'));
108
- fseek($this->res, 0);
109
- $content = fread($this->res, 1024);
110
-
111
- $this->assertRegexp('/token=myToken&user=userA&message=test1&title=Monolog&timestamp=\d{10}&priority=2&retry=30&expire=25200POST/', $content);
112
- $this->assertRegexp('/token=myToken&user=userB&message=test1&title=Monolog&timestamp=\d{10}&priority=2&retry=30&expire=25200$/', $content);
113
- }
114
-
115
- private function createHandler($token = 'myToken', $user = 'myUser', $title = 'Monolog')
116
- {
117
- $constructorArgs = array($token, $user, $title);
118
- $this->res = fopen('php://memory', 'a');
119
- $this->handler = $this->getMock(
120
- '\Monolog\Handler\PushoverHandler',
121
- array('fsockopen', 'streamSetTimeout', 'closeSocket'),
122
- $constructorArgs
123
- );
124
-
125
- $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString');
126
- $reflectionProperty->setAccessible(true);
127
- $reflectionProperty->setValue($this->handler, 'localhost:1234');
128
-
129
- $this->handler->expects($this->any())
130
- ->method('fsockopen')
131
- ->will($this->returnValue($this->res));
132
- $this->handler->expects($this->any())
133
- ->method('streamSetTimeout')
134
- ->will($this->returnValue(true));
135
- $this->handler->expects($this->any())
136
- ->method('closeSocket')
137
- ->will($this->returnValue(true));
138
-
139
- $this->handler->setFormatter($this->getIdentityFormatter());
140
- }
141
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/RavenHandlerTest.php DELETED
@@ -1,227 +0,0 @@
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
- class RavenHandlerTest extends TestCase
19
- {
20
- public function setUp()
21
- {
22
- if (!class_exists('Raven_Client')) {
23
- $this->markTestSkipped('raven/raven not installed');
24
- }
25
-
26
- require_once __DIR__ . '/MockRavenClient.php';
27
- }
28
-
29
- /**
30
- * @covers Monolog\Handler\RavenHandler::__construct
31
- */
32
- public function testConstruct()
33
- {
34
- $handler = new RavenHandler($this->getRavenClient());
35
- $this->assertInstanceOf('Monolog\Handler\RavenHandler', $handler);
36
- }
37
-
38
- protected function getHandler($ravenClient)
39
- {
40
- $handler = new RavenHandler($ravenClient);
41
-
42
- return $handler;
43
- }
44
-
45
- protected function getRavenClient()
46
- {
47
- $dsn = 'http://43f6017361224d098402974103bfc53d:a6a0538fc2934ba2bed32e08741b2cd3@marca.python.live.cheggnet.com:9000/1';
48
-
49
- return new MockRavenClient($dsn);
50
- }
51
-
52
- public function testDebug()
53
- {
54
- $ravenClient = $this->getRavenClient();
55
- $handler = $this->getHandler($ravenClient);
56
-
57
- $record = $this->getRecord(Logger::DEBUG, 'A test debug message');
58
- $handler->handle($record);
59
-
60
- $this->assertEquals($ravenClient::DEBUG, $ravenClient->lastData['level']);
61
- $this->assertContains($record['message'], $ravenClient->lastData['message']);
62
- }
63
-
64
- public function testWarning()
65
- {
66
- $ravenClient = $this->getRavenClient();
67
- $handler = $this->getHandler($ravenClient);
68
-
69
- $record = $this->getRecord(Logger::WARNING, 'A test warning message');
70
- $handler->handle($record);
71
-
72
- $this->assertEquals($ravenClient::WARNING, $ravenClient->lastData['level']);
73
- $this->assertContains($record['message'], $ravenClient->lastData['message']);
74
- }
75
-
76
- public function testTag()
77
- {
78
- $ravenClient = $this->getRavenClient();
79
- $handler = $this->getHandler($ravenClient);
80
-
81
- $tags = array(1, 2, 'foo');
82
- $record = $this->getRecord(Logger::INFO, 'test', array('tags' => $tags));
83
- $handler->handle($record);
84
-
85
- $this->assertEquals($tags, $ravenClient->lastData['tags']);
86
- }
87
-
88
- public function testExtraParameters()
89
- {
90
- $ravenClient = $this->getRavenClient();
91
- $handler = $this->getHandler($ravenClient);
92
-
93
- $checksum = '098f6bcd4621d373cade4e832627b4f6';
94
- $release = '05a671c66aefea124cc08b76ea6d30bb';
95
- $record = $this->getRecord(Logger::INFO, 'test', array('checksum' => $checksum, 'release' => $release));
96
- $handler->handle($record);
97
-
98
- $this->assertEquals($checksum, $ravenClient->lastData['checksum']);
99
- $this->assertEquals($release, $ravenClient->lastData['release']);
100
- }
101
-
102
- public function testFingerprint()
103
- {
104
- $ravenClient = $this->getRavenClient();
105
- $handler = $this->getHandler($ravenClient);
106
-
107
- $fingerprint = array('{{ default }}', 'other value');
108
- $record = $this->getRecord(Logger::INFO, 'test', array('fingerprint' => $fingerprint));
109
- $handler->handle($record);
110
-
111
- $this->assertEquals($fingerprint, $ravenClient->lastData['fingerprint']);
112
- }
113
-
114
- public function testUserContext()
115
- {
116
- $ravenClient = $this->getRavenClient();
117
- $handler = $this->getHandler($ravenClient);
118
-
119
- $recordWithNoContext = $this->getRecord(Logger::INFO, 'test with default user context');
120
- // set user context 'externally'
121
-
122
- $user = array(
123
- 'id' => '123',
124
- 'email' => 'test@test.com',
125
- );
126
-
127
- $recordWithContext = $this->getRecord(Logger::INFO, 'test', array('user' => $user));
128
-
129
- $ravenClient->user_context(array('id' => 'test_user_id'));
130
- // handle context
131
- $handler->handle($recordWithContext);
132
- $this->assertEquals($user, $ravenClient->lastData['user']);
133
-
134
- // check to see if its reset
135
- $handler->handle($recordWithNoContext);
136
- $this->assertInternalType('array', $ravenClient->context->user);
137
- $this->assertSame('test_user_id', $ravenClient->context->user['id']);
138
-
139
- // handle with null context
140
- $ravenClient->user_context(null);
141
- $handler->handle($recordWithContext);
142
- $this->assertEquals($user, $ravenClient->lastData['user']);
143
-
144
- // check to see if its reset
145
- $handler->handle($recordWithNoContext);
146
- $this->assertNull($ravenClient->context->user);
147
- }
148
-
149
- public function testException()
150
- {
151
- $ravenClient = $this->getRavenClient();
152
- $handler = $this->getHandler($ravenClient);
153
-
154
- try {
155
- $this->methodThatThrowsAnException();
156
- } catch (\Exception $e) {
157
- $record = $this->getRecord(Logger::ERROR, $e->getMessage(), array('exception' => $e));
158
- $handler->handle($record);
159
- }
160
-
161
- $this->assertEquals($record['message'], $ravenClient->lastData['message']);
162
- }
163
-
164
- public function testHandleBatch()
165
- {
166
- $records = $this->getMultipleRecords();
167
- $records[] = $this->getRecord(Logger::WARNING, 'warning');
168
- $records[] = $this->getRecord(Logger::WARNING, 'warning');
169
-
170
- $logFormatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
171
- $logFormatter->expects($this->once())->method('formatBatch');
172
-
173
- $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
174
- $formatter->expects($this->once())->method('format')->with($this->callback(function ($record) {
175
- return $record['level'] == 400;
176
- }));
177
-
178
- $handler = $this->getHandler($this->getRavenClient());
179
- $handler->setBatchFormatter($logFormatter);
180
- $handler->setFormatter($formatter);
181
- $handler->handleBatch($records);
182
- }
183
-
184
- public function testHandleBatchDoNothingIfRecordsAreBelowLevel()
185
- {
186
- $records = array(
187
- $this->getRecord(Logger::DEBUG, 'debug message 1'),
188
- $this->getRecord(Logger::DEBUG, 'debug message 2'),
189
- $this->getRecord(Logger::INFO, 'information'),
190
- );
191
-
192
- $handler = $this->getMock('Monolog\Handler\RavenHandler', null, array($this->getRavenClient()));
193
- $handler->expects($this->never())->method('handle');
194
- $handler->setLevel(Logger::ERROR);
195
- $handler->handleBatch($records);
196
- }
197
-
198
- public function testGetSetBatchFormatter()
199
- {
200
- $ravenClient = $this->getRavenClient();
201
- $handler = $this->getHandler($ravenClient);
202
-
203
- $handler->setBatchFormatter($formatter = new LineFormatter());
204
- $this->assertSame($formatter, $handler->getBatchFormatter());
205
- }
206
-
207
- public function testRelease()
208
- {
209
- $ravenClient = $this->getRavenClient();
210
- $handler = $this->getHandler($ravenClient);
211
- $release = 'v42.42.42';
212
- $handler->setRelease($release);
213
- $record = $this->getRecord(Logger::INFO, 'test');
214
- $handler->handle($record);
215
- $this->assertEquals($release, $ravenClient->lastData['release']);
216
-
217
- $localRelease = 'v41.41.41';
218
- $record = $this->getRecord(Logger::INFO, 'test', array('release' => $localRelease));
219
- $handler->handle($record);
220
- $this->assertEquals($localRelease, $ravenClient->lastData['release']);
221
- }
222
-
223
- private function methodThatThrowsAnException()
224
- {
225
- throw new \Exception('This is an exception');
226
- }
227
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/RedisHandlerTest.php DELETED
@@ -1,127 +0,0 @@
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
- class RedisHandlerTest extends TestCase
19
- {
20
- /**
21
- * @expectedException InvalidArgumentException
22
- */
23
- public function testConstructorShouldThrowExceptionForInvalidRedis()
24
- {
25
- new RedisHandler(new \stdClass(), 'key');
26
- }
27
-
28
- public function testConstructorShouldWorkWithPredis()
29
- {
30
- $redis = $this->getMock('Predis\Client');
31
- $this->assertInstanceof('Monolog\Handler\RedisHandler', new RedisHandler($redis, 'key'));
32
- }
33
-
34
- public function testConstructorShouldWorkWithRedis()
35
- {
36
- $redis = $this->getMock('Redis');
37
- $this->assertInstanceof('Monolog\Handler\RedisHandler', new RedisHandler($redis, 'key'));
38
- }
39
-
40
- public function testPredisHandle()
41
- {
42
- $redis = $this->getMock('Predis\Client', array('rpush'));
43
-
44
- // Predis\Client uses rpush
45
- $redis->expects($this->once())
46
- ->method('rpush')
47
- ->with('key', 'test');
48
-
49
- $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
50
-
51
- $handler = new RedisHandler($redis, 'key');
52
- $handler->setFormatter(new LineFormatter("%message%"));
53
- $handler->handle($record);
54
- }
55
-
56
- public function testRedisHandle()
57
- {
58
- $redis = $this->getMock('Redis', array('rpush'));
59
-
60
- // Redis uses rPush
61
- $redis->expects($this->once())
62
- ->method('rPush')
63
- ->with('key', 'test');
64
-
65
- $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
66
-
67
- $handler = new RedisHandler($redis, 'key');
68
- $handler->setFormatter(new LineFormatter("%message%"));
69
- $handler->handle($record);
70
- }
71
-
72
- public function testRedisHandleCapped()
73
- {
74
- $redis = $this->getMock('Redis', array('multi', 'rpush', 'ltrim', 'exec'));
75
-
76
- // Redis uses multi
77
- $redis->expects($this->once())
78
- ->method('multi')
79
- ->will($this->returnSelf());
80
-
81
- $redis->expects($this->once())
82
- ->method('rpush')
83
- ->will($this->returnSelf());
84
-
85
- $redis->expects($this->once())
86
- ->method('ltrim')
87
- ->will($this->returnSelf());
88
-
89
- $redis->expects($this->once())
90
- ->method('exec')
91
- ->will($this->returnSelf());
92
-
93
- $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
94
-
95
- $handler = new RedisHandler($redis, 'key', Logger::DEBUG, true, 10);
96
- $handler->setFormatter(new LineFormatter("%message%"));
97
- $handler->handle($record);
98
- }
99
-
100
- public function testPredisHandleCapped()
101
- {
102
- $redis = $this->getMock('Predis\Client', array('transaction'));
103
-
104
- $redisTransaction = $this->getMock('Predis\Client', array('rpush', 'ltrim'));
105
-
106
- $redisTransaction->expects($this->once())
107
- ->method('rpush')
108
- ->will($this->returnSelf());
109
-
110
- $redisTransaction->expects($this->once())
111
- ->method('ltrim')
112
- ->will($this->returnSelf());
113
-
114
- // Redis uses multi
115
- $redis->expects($this->once())
116
- ->method('transaction')
117
- ->will($this->returnCallback(function ($cb) use ($redisTransaction) {
118
- $cb($redisTransaction);
119
- }));
120
-
121
- $record = $this->getRecord(Logger::WARNING, 'test', array('data' => new \stdClass, 'foo' => 34));
122
-
123
- $handler = new RedisHandler($redis, 'key', Logger::DEBUG, true, 10);
124
- $handler->setFormatter(new LineFormatter("%message%"));
125
- $handler->handle($record);
126
- }
127
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/RollbarHandlerTest.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 Exception;
15
+ use Monolog\TestCase;
16
+ use Monolog\Logger;
17
+ use PHPUnit_Framework_MockObject_MockObject as MockObject;
18
+
19
+ /**
20
+ * @author Erik Johansson <erik.pm.johansson@gmail.com>
21
+ * @see https://rollbar.com/docs/notifier/rollbar-php/
22
+ *
23
+ * @coversDefaultClass Monolog\Handler\RollbarHandler
24
+ */
25
+ class RollbarHandlerTest extends TestCase
26
+ {
27
+ /**
28
+ * @var MockObject
29
+ */
30
+ private $rollbarNotifier;
31
+
32
+ /**
33
+ * @var array
34
+ */
35
+ public $reportedExceptionArguments = null;
36
+
37
+ protected function setUp()
38
+ {
39
+ parent::setUp();
40
+
41
+ $this->setupRollbarNotifierMock();
42
+ }
43
+
44
+ /**
45
+ * When reporting exceptions to Rollbar the
46
+ * level has to be set in the payload data
47
+ */
48
+ public function testExceptionLogLevel()
49
+ {
50
+ $handler = $this->createHandler();
51
+
52
+ $handler->handle($this->createExceptionRecord(Logger::DEBUG));
53
+
54
+ $this->assertEquals('debug', $this->reportedExceptionArguments['payload']['level']);
55
+ }
56
+
57
+ private function setupRollbarNotifierMock()
58
+ {
59
+ $this->rollbarNotifier = $this->getMockBuilder('RollbarNotifier')
60
+ ->setMethods(array('report_message', 'report_exception', 'flush'))
61
+ ->getMock();
62
+
63
+ $that = $this;
64
+
65
+ $this->rollbarNotifier
66
+ ->expects($this->any())
67
+ ->method('report_exception')
68
+ ->willReturnCallback(function ($exception, $context, $payload) use ($that) {
69
+ $that->reportedExceptionArguments = compact('exception', 'context', 'payload');
70
+ });
71
+ }
72
+
73
+ private function createHandler()
74
+ {
75
+ return new RollbarHandler($this->rollbarNotifier, Logger::DEBUG);
76
+ }
77
+
78
+ private function createExceptionRecord($level = Logger::DEBUG, $message = 'test', $exception = null)
79
+ {
80
+ return $this->getRecord($level, $message, array(
81
+ 'exception' => $exception ?: new Exception()
82
+ ));
83
+ }
84
+ }
vendor/monolog/monolog/tests/Monolog/Handler/RotatingFileHandlerTest.php DELETED
@@ -1,211 +0,0 @@
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 PHPUnit_Framework_Error_Deprecated;
16
-
17
- /**
18
- * @covers Monolog\Handler\RotatingFileHandler
19
- */
20
- class RotatingFileHandlerTest extends TestCase
21
- {
22
- /**
23
- * This var should be private but then the anonymous function
24
- * in the `setUp` method won't be able to set it. `$this` cant't
25
- * be used in the anonymous function in `setUp` because PHP 5.3
26
- * does not support it.
27
- */
28
- public $lastError;
29
-
30
- public function setUp()
31
- {
32
- $dir = __DIR__.'/Fixtures';
33
- chmod($dir, 0777);
34
- if (!is_writable($dir)) {
35
- $this->markTestSkipped($dir.' must be writable to test the RotatingFileHandler.');
36
- }
37
- $this->lastError = null;
38
- $self = $this;
39
- // workaround with &$self used for PHP 5.3
40
- set_error_handler(function($code, $message) use (&$self) {
41
- $self->lastError = array(
42
- 'code' => $code,
43
- 'message' => $message,
44
- );
45
- });
46
- }
47
-
48
- private function assertErrorWasTriggered($code, $message)
49
- {
50
- if (empty($this->lastError)) {
51
- $this->fail(
52
- sprintf(
53
- 'Failed asserting that error with code `%d` and message `%s` was triggered',
54
- $code,
55
- $message
56
- )
57
- );
58
- }
59
- $this->assertEquals($code, $this->lastError['code'], sprintf('Expected an error with code %d to be triggered, got `%s` instead', $code, $this->lastError['code']));
60
- $this->assertEquals($message, $this->lastError['message'], sprintf('Expected an error with message `%d` to be triggered, got `%s` instead', $message, $this->lastError['message']));
61
- }
62
-
63
- public function testRotationCreatesNewFile()
64
- {
65
- touch(__DIR__.'/Fixtures/foo-'.date('Y-m-d', time() - 86400).'.rot');
66
-
67
- $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot');
68
- $handler->setFormatter($this->getIdentityFormatter());
69
- $handler->handle($this->getRecord());
70
-
71
- $log = __DIR__.'/Fixtures/foo-'.date('Y-m-d').'.rot';
72
- $this->assertTrue(file_exists($log));
73
- $this->assertEquals('test', file_get_contents($log));
74
- }
75
-
76
- /**
77
- * @dataProvider rotationTests
78
- */
79
- public function testRotation($createFile, $dateFormat, $timeCallback)
80
- {
81
- touch($old1 = __DIR__.'/Fixtures/foo-'.date($dateFormat, $timeCallback(-1)).'.rot');
82
- touch($old2 = __DIR__.'/Fixtures/foo-'.date($dateFormat, $timeCallback(-2)).'.rot');
83
- touch($old3 = __DIR__.'/Fixtures/foo-'.date($dateFormat, $timeCallback(-3)).'.rot');
84
- touch($old4 = __DIR__.'/Fixtures/foo-'.date($dateFormat, $timeCallback(-4)).'.rot');
85
-
86
- $log = __DIR__.'/Fixtures/foo-'.date($dateFormat).'.rot';
87
-
88
- if ($createFile) {
89
- touch($log);
90
- }
91
-
92
- $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2);
93
- $handler->setFormatter($this->getIdentityFormatter());
94
- $handler->setFilenameFormat('{filename}-{date}', $dateFormat);
95
- $handler->handle($this->getRecord());
96
-
97
- $handler->close();
98
-
99
- $this->assertTrue(file_exists($log));
100
- $this->assertTrue(file_exists($old1));
101
- $this->assertEquals($createFile, file_exists($old2));
102
- $this->assertEquals($createFile, file_exists($old3));
103
- $this->assertEquals($createFile, file_exists($old4));
104
- $this->assertEquals('test', file_get_contents($log));
105
- }
106
-
107
- public function rotationTests()
108
- {
109
- $now = time();
110
- $dayCallback = function($ago) use ($now) {
111
- return $now + 86400 * $ago;
112
- };
113
- $monthCallback = function($ago) {
114
- return gmmktime(0, 0, 0, date('n') + $ago, date('d'), date('Y'));
115
- };
116
- $yearCallback = function($ago) {
117
- return gmmktime(0, 0, 0, date('n'), date('d'), date('Y') + $ago);
118
- };
119
-
120
- return array(
121
- 'Rotation is triggered when the file of the current day is not present'
122
- => array(true, RotatingFileHandler::FILE_PER_DAY, $dayCallback),
123
- 'Rotation is not triggered when the file of the current day is already present'
124
- => array(false, RotatingFileHandler::FILE_PER_DAY, $dayCallback),
125
-
126
- 'Rotation is triggered when the file of the current month is not present'
127
- => array(true, RotatingFileHandler::FILE_PER_MONTH, $monthCallback),
128
- 'Rotation is not triggered when the file of the current month is already present'
129
- => array(false, RotatingFileHandler::FILE_PER_MONTH, $monthCallback),
130
-
131
- 'Rotation is triggered when the file of the current year is not present'
132
- => array(true, RotatingFileHandler::FILE_PER_YEAR, $yearCallback),
133
- 'Rotation is not triggered when the file of the current year is already present'
134
- => array(false, RotatingFileHandler::FILE_PER_YEAR, $yearCallback),
135
- );
136
- }
137
-
138
- /**
139
- * @dataProvider dateFormatProvider
140
- */
141
- public function testAllowOnlyFixedDefinedDateFormats($dateFormat, $valid)
142
- {
143
- $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2);
144
- $handler->setFilenameFormat('{filename}-{date}', $dateFormat);
145
- if (!$valid) {
146
- $this->assertErrorWasTriggered(
147
- E_USER_DEPRECATED,
148
- 'Invalid date format - format must be one of RotatingFileHandler::FILE_PER_DAY ("Y-m-d"), '.
149
- 'RotatingFileHandler::FILE_PER_MONTH ("Y-m") or RotatingFileHandler::FILE_PER_YEAR ("Y"), '.
150
- 'or you can set one of the date formats using slashes, underscores and/or dots instead of dashes.'
151
- );
152
- }
153
- }
154
-
155
- public function dateFormatProvider()
156
- {
157
- return array(
158
- array(RotatingFileHandler::FILE_PER_DAY, true),
159
- array(RotatingFileHandler::FILE_PER_MONTH, true),
160
- array(RotatingFileHandler::FILE_PER_YEAR, true),
161
- array('m-d-Y', false),
162
- array('Y-m-d-h-i', false)
163
- );
164
- }
165
-
166
- /**
167
- * @dataProvider filenameFormatProvider
168
- */
169
- public function testDisallowFilenameFormatsWithoutDate($filenameFormat, $valid)
170
- {
171
- $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot', 2);
172
- $handler->setFilenameFormat($filenameFormat, RotatingFileHandler::FILE_PER_DAY);
173
- if (!$valid) {
174
- $this->assertErrorWasTriggered(
175
- E_USER_DEPRECATED,
176
- 'Invalid filename format - format should contain at least `{date}`, because otherwise rotating is impossible.'
177
- );
178
- }
179
- }
180
-
181
- public function filenameFormatProvider()
182
- {
183
- return array(
184
- array('{filename}', false),
185
- array('{filename}-{date}', true),
186
- array('{date}', true),
187
- array('foobar-{date}', true),
188
- array('foo-{date}-bar', true),
189
- array('{date}-foobar', true),
190
- array('foobar', false),
191
- );
192
- }
193
-
194
- public function testReuseCurrentFile()
195
- {
196
- $log = __DIR__.'/Fixtures/foo-'.date('Y-m-d').'.rot';
197
- file_put_contents($log, "foo");
198
- $handler = new RotatingFileHandler(__DIR__.'/Fixtures/foo.rot');
199
- $handler->setFormatter($this->getIdentityFormatter());
200
- $handler->handle($this->getRecord());
201
- $this->assertEquals('footest', file_get_contents($log));
202
- }
203
-
204
- public function tearDown()
205
- {
206
- foreach (glob(__DIR__.'/Fixtures/*.rot') as $file) {
207
- unlink($file);
208
- }
209
- restore_error_handler();
210
- }
211
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/SamplingHandlerTest.php DELETED
@@ -1,33 +0,0 @@
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
- /**
17
- * @covers Monolog\Handler\SamplingHandler::handle
18
- */
19
- class SamplingHandlerTest extends TestCase
20
- {
21
- public function testHandle()
22
- {
23
- $testHandler = new TestHandler();
24
- $handler = new SamplingHandler($testHandler, 2);
25
- for ($i = 0; $i < 10000; $i++) {
26
- $handler->handle($this->getRecord());
27
- }
28
- $count = count($testHandler->getRecords());
29
- // $count should be half of 10k, so between 4k and 6k
30
- $this->assertLessThan(6000, $count);
31
- $this->assertGreaterThan(4000, $count);
32
- }
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/Slack/SlackRecordTest.php ADDED
@@ -0,0 +1,387 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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\Slack;
13
+
14
+ use Monolog\Logger;
15
+ use Monolog\TestCase;
16
+
17
+ /**
18
+ * @coversDefaultClass Monolog\Handler\Slack\SlackRecord
19
+ */
20
+ class SlackRecordTest extends TestCase
21
+ {
22
+ private $jsonPrettyPrintFlag;
23
+
24
+ protected function setUp()
25
+ {
26
+ $this->jsonPrettyPrintFlag = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 128;
27
+ }
28
+
29
+ public function dataGetAttachmentColor()
30
+ {
31
+ return array(
32
+ array(Logger::DEBUG, SlackRecord::COLOR_DEFAULT),
33
+ array(Logger::INFO, SlackRecord::COLOR_GOOD),
34
+ array(Logger::NOTICE, SlackRecord::COLOR_GOOD),
35
+ array(Logger::WARNING, SlackRecord::COLOR_WARNING),
36
+ array(Logger::ERROR, SlackRecord::COLOR_DANGER),
37
+ array(Logger::CRITICAL, SlackRecord::COLOR_DANGER),
38
+ array(Logger::ALERT, SlackRecord::COLOR_DANGER),
39
+ array(Logger::EMERGENCY, SlackRecord::COLOR_DANGER),
40
+ );
41
+ }
42
+
43
+ /**
44
+ * @dataProvider dataGetAttachmentColor
45
+ * @param int $logLevel
46
+ * @param string $expectedColour RGB hex color or name of Slack color
47
+ * @covers ::getAttachmentColor
48
+ */
49
+ public function testGetAttachmentColor($logLevel, $expectedColour)
50
+ {
51
+ $slackRecord = new SlackRecord();
52
+ $this->assertSame(
53
+ $expectedColour,
54
+ $slackRecord->getAttachmentColor($logLevel)
55
+ );
56
+ }
57
+
58
+ public function testAddsChannel()
59
+ {
60
+ $channel = '#test';
61
+ $record = new SlackRecord($channel);
62
+ $data = $record->getSlackData($this->getRecord());
63
+
64
+ $this->assertArrayHasKey('channel', $data);
65
+ $this->assertSame($channel, $data['channel']);
66
+ }
67
+
68
+ public function testNoUsernameByDefault()
69
+ {
70
+ $record = new SlackRecord();
71
+ $data = $record->getSlackData($this->getRecord());
72
+
73
+ $this->assertArrayNotHasKey('username', $data);
74
+ }
75
+
76
+ /**
77
+ * @return array
78
+ */
79
+ public function dataStringify()
80
+ {
81
+ $jsonPrettyPrintFlag = defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : 128;
82
+
83
+ $multipleDimensions = array(array(1, 2));
84
+ $numericKeys = array('library' => 'monolog');
85
+ $singleDimension = array(1, 'Hello', 'Jordi');
86
+
87
+ return array(
88
+ array(array(), '[]'),
89
+ array($multipleDimensions, json_encode($multipleDimensions, $jsonPrettyPrintFlag)),
90
+ array($numericKeys, json_encode($numericKeys, $jsonPrettyPrintFlag)),
91
+ array($singleDimension, json_encode($singleDimension))
92
+ );
93
+ }
94
+
95
+ /**
96
+ * @dataProvider dataStringify
97
+ */
98
+ public function testStringify($fields, $expectedResult)
99
+ {
100
+ $slackRecord = new SlackRecord(
101
+ '#test',
102
+ 'test',
103
+ true,
104
+ null,
105
+ true,
106
+ true
107
+ );
108
+
109
+ $this->assertSame($expectedResult, $slackRecord->stringify($fields));
110
+ }
111
+
112
+ public function testAddsCustomUsername()
113
+ {
114
+ $username = 'Monolog bot';
115
+ $record = new SlackRecord(null, $username);
116
+ $data = $record->getSlackData($this->getRecord());
117
+
118
+ $this->assertArrayHasKey('username', $data);
119
+ $this->assertSame($username, $data['username']);
120
+ }
121
+
122
+ public function testNoIcon()
123
+ {
124
+ $record = new SlackRecord();
125
+ $data = $record->getSlackData($this->getRecord());
126
+
127
+ $this->assertArrayNotHasKey('icon_emoji', $data);
128
+ }
129
+
130
+ public function testAddsIcon()
131
+ {
132
+ $record = $this->getRecord();
133
+ $slackRecord = new SlackRecord(null, null, false, 'ghost');
134
+ $data = $slackRecord->getSlackData($record);
135
+
136
+ $slackRecord2 = new SlackRecord(null, null, false, 'http://github.com/Seldaek/monolog');
137
+ $data2 = $slackRecord2->getSlackData($record);
138
+
139
+ $this->assertArrayHasKey('icon_emoji', $data);
140
+ $this->assertSame(':ghost:', $data['icon_emoji']);
141
+ $this->assertArrayHasKey('icon_url', $data2);
142
+ $this->assertSame('http://github.com/Seldaek/monolog', $data2['icon_url']);
143
+ }
144
+
145
+ public function testAttachmentsNotPresentIfNoAttachment()
146
+ {
147
+ $record = new SlackRecord(null, null, false);
148
+ $data = $record->getSlackData($this->getRecord());
149
+
150
+ $this->assertArrayNotHasKey('attachments', $data);
151
+ }
152
+
153
+ public function testAddsOneAttachment()
154
+ {
155
+ $record = new SlackRecord();
156
+ $data = $record->getSlackData($this->getRecord());
157
+
158
+ $this->assertArrayHasKey('attachments', $data);
159
+ $this->assertArrayHasKey(0, $data['attachments']);
160
+ $this->assertInternalType('array', $data['attachments'][0]);
161
+ }
162
+
163
+ public function testTextEqualsMessageIfNoAttachment()
164
+ {
165
+ $message = 'Test message';
166
+ $record = new SlackRecord(null, null, false);
167
+ $data = $record->getSlackData($this->getRecord(Logger::WARNING, $message));
168
+
169
+ $this->assertArrayHasKey('text', $data);
170
+ $this->assertSame($message, $data['text']);
171
+ }
172
+
173
+ public function testTextEqualsFormatterOutput()
174
+ {
175
+ $formatter = $this->getMock('Monolog\\Formatter\\FormatterInterface');
176
+ $formatter
177
+ ->expects($this->any())
178
+ ->method('format')
179
+ ->will($this->returnCallback(function ($record) { return $record['message'] . 'test'; }));
180
+
181
+ $formatter2 = $this->getMock('Monolog\\Formatter\\FormatterInterface');
182
+ $formatter2
183
+ ->expects($this->any())
184
+ ->method('format')
185
+ ->will($this->returnCallback(function ($record) { return $record['message'] . 'test1'; }));
186
+
187
+ $message = 'Test message';
188
+ $record = new SlackRecord(null, null, false, null, false, false, array(), $formatter);
189
+ $data = $record->getSlackData($this->getRecord(Logger::WARNING, $message));
190
+
191
+ $this->assertArrayHasKey('text', $data);
192
+ $this->assertSame($message . 'test', $data['text']);
193
+
194
+ $record->setFormatter($formatter2);
195
+ $data = $record->getSlackData($this->getRecord(Logger::WARNING, $message));
196
+
197
+ $this->assertArrayHasKey('text', $data);
198
+ $this->assertSame($message . 'test1', $data['text']);
199
+ }
200
+
201
+ public function testAddsFallbackAndTextToAttachment()
202
+ {
203
+ $message = 'Test message';
204
+ $record = new SlackRecord(null);
205
+ $data = $record->getSlackData($this->getRecord(Logger::WARNING, $message));
206
+
207
+ $this->assertSame($message, $data['attachments'][0]['text']);
208
+ $this->assertSame($message, $data['attachments'][0]['fallback']);
209
+ }
210
+
211
+ public function testMapsLevelToColorAttachmentColor()
212
+ {
213
+ $record = new SlackRecord(null);
214
+ $errorLoggerRecord = $this->getRecord(Logger::ERROR);
215
+ $emergencyLoggerRecord = $this->getRecord(Logger::EMERGENCY);
216
+ $warningLoggerRecord = $this->getRecord(Logger::WARNING);
217
+ $infoLoggerRecord = $this->getRecord(Logger::INFO);
218
+ $debugLoggerRecord = $this->getRecord(Logger::DEBUG);
219
+
220
+ $data = $record->getSlackData($errorLoggerRecord);
221
+ $this->assertSame(SlackRecord::COLOR_DANGER, $data['attachments'][0]['color']);
222
+
223
+ $data = $record->getSlackData($emergencyLoggerRecord);
224
+ $this->assertSame(SlackRecord::COLOR_DANGER, $data['attachments'][0]['color']);
225
+
226
+ $data = $record->getSlackData($warningLoggerRecord);
227
+ $this->assertSame(SlackRecord::COLOR_WARNING, $data['attachments'][0]['color']);
228
+
229
+ $data = $record->getSlackData($infoLoggerRecord);
230
+ $this->assertSame(SlackRecord::COLOR_GOOD, $data['attachments'][0]['color']);
231
+
232
+ $data = $record->getSlackData($debugLoggerRecord);
233
+ $this->assertSame(SlackRecord::COLOR_DEFAULT, $data['attachments'][0]['color']);
234
+ }
235
+
236
+ public function testAddsShortAttachmentWithoutContextAndExtra()
237
+ {
238
+ $level = Logger::ERROR;
239
+ $levelName = Logger::getLevelName($level);
240
+ $record = new SlackRecord(null, null, true, null, true);
241
+ $data = $record->getSlackData($this->getRecord($level, 'test', array('test' => 1)));
242
+
243
+ $attachment = $data['attachments'][0];
244
+ $this->assertArrayHasKey('title', $attachment);
245
+ $this->assertArrayHasKey('fields', $attachment);
246
+ $this->assertSame($levelName, $attachment['title']);
247
+ $this->assertSame(array(), $attachment['fields']);
248
+ }
249
+
250
+ public function testAddsShortAttachmentWithContextAndExtra()
251
+ {
252
+ $level = Logger::ERROR;
253
+ $levelName = Logger::getLevelName($level);
254
+ $context = array('test' => 1);
255
+ $extra = array('tags' => array('web'));
256
+ $record = new SlackRecord(null, null, true, null, true, true);
257
+ $loggerRecord = $this->getRecord($level, 'test', $context);
258
+ $loggerRecord['extra'] = $extra;
259
+ $data = $record->getSlackData($loggerRecord);
260
+
261
+ $attachment = $data['attachments'][0];
262
+ $this->assertArrayHasKey('title', $attachment);
263
+ $this->assertArrayHasKey('fields', $attachment);
264
+ $this->assertCount(2, $attachment['fields']);
265
+ $this->assertSame($levelName, $attachment['title']);
266
+ $this->assertSame(
267
+ array(
268
+ array(
269
+ 'title' => 'Extra',
270
+ 'value' => sprintf('```%s```', json_encode($extra, $this->jsonPrettyPrintFlag)),
271
+ 'short' => false
272
+ ),
273
+ array(
274
+ 'title' => 'Context',
275
+ 'value' => sprintf('```%s```', json_encode($context, $this->jsonPrettyPrintFlag)),
276
+ 'short' => false
277
+ )
278
+ ),
279
+ $attachment['fields']
280
+ );
281
+ }
282
+
283
+ public function testAddsLongAttachmentWithoutContextAndExtra()
284
+ {
285
+ $level = Logger::ERROR;
286
+ $levelName = Logger::getLevelName($level);
287
+ $record = new SlackRecord(null, null, true, null);
288
+ $data = $record->getSlackData($this->getRecord($level, 'test', array('test' => 1)));
289
+
290
+ $attachment = $data['attachments'][0];
291
+ $this->assertArrayHasKey('title', $attachment);
292
+ $this->assertArrayHasKey('fields', $attachment);
293
+ $this->assertCount(1, $attachment['fields']);
294
+ $this->assertSame('Message', $attachment['title']);
295
+ $this->assertSame(
296
+ array(array(
297
+ 'title' => 'Level',
298
+ 'value' => $levelName,
299
+ 'short' => false
300
+ )),
301
+ $attachment['fields']
302
+ );
303
+ }
304
+
305
+ public function testAddsLongAttachmentWithContextAndExtra()
306
+ {
307
+ $level = Logger::ERROR;
308
+ $levelName = Logger::getLevelName($level);
309
+ $context = array('test' => 1);
310
+ $extra = array('tags' => array('web'));
311
+ $record = new SlackRecord(null, null, true, null, false, true);
312
+ $loggerRecord = $this->getRecord($level, 'test', $context);
313
+ $loggerRecord['extra'] = $extra;
314
+ $data = $record->getSlackData($loggerRecord);
315
+
316
+ $expectedFields = array(
317
+ array(
318
+ 'title' => 'Level',
319
+ 'value' => $levelName,
320
+ 'short' => false,
321
+ ),
322
+ array(
323
+ 'title' => 'tags',
324
+ 'value' => sprintf('```%s```', json_encode($extra['tags'])),
325
+ 'short' => false
326
+ ),
327
+ array(
328
+ 'title' => 'test',
329
+ 'value' => $context['test'],
330
+ 'short' => false
331
+ )
332
+ );
333
+
334
+ $attachment = $data['attachments'][0];
335
+ $this->assertArrayHasKey('title', $attachment);
336
+ $this->assertArrayHasKey('fields', $attachment);
337
+ $this->assertCount(3, $attachment['fields']);
338
+ $this->assertSame('Message', $attachment['title']);
339
+ $this->assertSame(
340
+ $expectedFields,
341
+ $attachment['fields']
342
+ );
343
+ }
344
+
345
+ public function testAddsTimestampToAttachment()
346
+ {
347
+ $record = $this->getRecord();
348
+ $slackRecord = new SlackRecord();
349
+ $data = $slackRecord->getSlackData($this->getRecord());
350
+
351
+ $attachment = $data['attachments'][0];
352
+ $this->assertArrayHasKey('ts', $attachment);
353
+ $this->assertSame($record['datetime']->getTimestamp(), $attachment['ts']);
354
+ }
355
+
356
+ public function testExcludeExtraAndContextFields()
357
+ {
358
+ $record = $this->getRecord(
359
+ Logger::WARNING,
360
+ 'test',
361
+ array('info' => array('library' => 'monolog', 'author' => 'Jordi'))
362
+ );
363
+ $record['extra'] = array('tags' => array('web', 'cli'));
364
+
365
+ $slackRecord = new SlackRecord(null, null, true, null, false, true, array('context.info.library', 'extra.tags.1'));
366
+ $data = $slackRecord->getSlackData($record);
367
+ $attachment = $data['attachments'][0];
368
+
369
+ $expected = array(
370
+ array(
371
+ 'title' => 'info',
372
+ 'value' => sprintf('```%s```', json_encode(array('author' => 'Jordi'), $this->jsonPrettyPrintFlag)),
373
+ 'short' => false
374
+ ),
375
+ array(
376
+ 'title' => 'tags',
377
+ 'value' => sprintf('```%s```', json_encode(array('web'))),
378
+ 'short' => false
379
+ ),
380
+ );
381
+
382
+ foreach ($expected as $field) {
383
+ $this->assertNotFalse(array_search($field, $attachment['fields']));
384
+ break;
385
+ }
386
+ }
387
+ }
vendor/monolog/monolog/tests/Monolog/Handler/SlackHandlerTest.php DELETED
@@ -1,151 +0,0 @@
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
- /**
19
- * @author Greg Kedzierski <greg@gregkedzierski.com>
20
- * @see https://api.slack.com/
21
- */
22
- class SlackHandlerTest extends TestCase
23
- {
24
- /**
25
- * @var resource
26
- */
27
- private $res;
28
-
29
- /**
30
- * @var SlackHandler
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 \/api\/chat.postMessage HTTP\/1.1\\r\\nHost: slack.com\\r\\nContent-Type: application\/x-www-form-urlencoded\\r\\nContent-Length: \d{2,4}\\r\\n\\r\\n/', $content);
49
- }
50
-
51
- public function testWriteContent()
52
- {
53
- $this->createHandler();
54
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
55
- fseek($this->res, 0);
56
- $content = fread($this->res, 1024);
57
-
58
- $this->assertRegexp('/token=myToken&channel=channel1&username=Monolog&text=&attachments=.*$/', $content);
59
- }
60
-
61
- public function testWriteContentUsesFormatterIfProvided()
62
- {
63
- $this->createHandler('myToken', 'channel1', 'Monolog', false);
64
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
65
- fseek($this->res, 0);
66
- $content = fread($this->res, 1024);
67
-
68
- $this->createHandler('myToken', 'channel1', 'Monolog', false);
69
- $this->handler->setFormatter(new LineFormatter('foo--%message%'));
70
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test2'));
71
- fseek($this->res, 0);
72
- $content2 = fread($this->res, 1024);
73
-
74
- $this->assertRegexp('/token=myToken&channel=channel1&username=Monolog&text=test1.*$/', $content);
75
- $this->assertRegexp('/token=myToken&channel=channel1&username=Monolog&text=foo--test2.*$/', $content2);
76
- }
77
-
78
- public function testWriteContentWithEmoji()
79
- {
80
- $this->createHandler('myToken', 'channel1', 'Monolog', true, 'alien');
81
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
82
- fseek($this->res, 0);
83
- $content = fread($this->res, 1024);
84
-
85
- $this->assertRegexp('/icon_emoji=%3Aalien%3A$/', $content);
86
- }
87
-
88
- /**
89
- * @dataProvider provideLevelColors
90
- */
91
- public function testWriteContentWithColors($level, $expectedColor)
92
- {
93
- $this->createHandler();
94
- $this->handler->handle($this->getRecord($level, 'test1'));
95
- fseek($this->res, 0);
96
- $content = fread($this->res, 1024);
97
-
98
- $this->assertRegexp('/color%22%3A%22'.$expectedColor.'/', $content);
99
- }
100
-
101
- public function testWriteContentWithPlainTextMessage()
102
- {
103
- $this->createHandler('myToken', 'channel1', 'Monolog', false);
104
- $this->handler->handle($this->getRecord(Logger::CRITICAL, 'test1'));
105
- fseek($this->res, 0);
106
- $content = fread($this->res, 1024);
107
-
108
- $this->assertRegexp('/text=test1/', $content);
109
- }
110
-
111
- public function provideLevelColors()
112
- {
113
- return array(
114
- array(Logger::DEBUG, '%23e3e4e6'), // escaped #e3e4e6
115
- array(Logger::INFO, 'good'),
116
- array(Logger::NOTICE, 'good'),
117
- array(Logger::WARNING, 'warning'),
118
- array(Logger::ERROR, 'danger'),
119
- array(Logger::CRITICAL, 'danger'),
120
- array(Logger::ALERT, 'danger'),
121
- array(Logger::EMERGENCY,'danger'),
122
- );
123
- }
124
-
125
- private function createHandler($token = 'myToken', $channel = 'channel1', $username = 'Monolog', $useAttachment = true, $iconEmoji = null, $useShortAttachment = false, $includeExtra = false)
126
- {
127
- $constructorArgs = array($token, $channel, $username, $useAttachment, $iconEmoji, Logger::DEBUG, true, $useShortAttachment, $includeExtra);
128
- $this->res = fopen('php://memory', 'a');
129
- $this->handler = $this->getMock(
130
- '\Monolog\Handler\SlackHandler',
131
- array('fsockopen', 'streamSetTimeout', 'closeSocket'),
132
- $constructorArgs
133
- );
134
-
135
- $reflectionProperty = new \ReflectionProperty('\Monolog\Handler\SocketHandler', 'connectionString');
136
- $reflectionProperty->setAccessible(true);
137
- $reflectionProperty->setValue($this->handler, 'localhost:1234');
138
-
139
- $this->handler->expects($this->any())
140
- ->method('fsockopen')
141
- ->will($this->returnValue($this->res));
142
- $this->handler->expects($this->any())
143
- ->method('streamSetTimeout')
144
- ->will($this->returnValue(true));
145
- $this->handler->expects($this->any())
146
- ->method('closeSocket')
147
- ->will($this->returnValue(true));
148
-
149
- $this->handler->setFormatter($this->getIdentityFormatter());
150
- }
151
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/SlackWebhookHandlerTest.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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\Handler\Slack\SlackRecord;
18
+
19
+ /**
20
+ * @author Haralan Dobrev <hkdobrev@gmail.com>
21
+ * @see https://api.slack.com/incoming-webhooks
22
+ * @coversDefaultClass Monolog\Handler\SlackWebhookHandler
23
+ */
24
+ class SlackWebhookHandlerTest extends TestCase
25
+ {
26
+ const WEBHOOK_URL = 'https://hooks.slack.com/services/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E';
27
+
28
+ /**
29
+ * @covers ::__construct
30
+ * @covers ::getSlackRecord
31
+ */
32
+ public function testConstructorMinimal()
33
+ {
34
+ $handler = new SlackWebhookHandler(self::WEBHOOK_URL);
35
+ $record = $this->getRecord();
36
+ $slackRecord = $handler->getSlackRecord();
37
+ $this->assertInstanceOf('Monolog\Handler\Slack\SlackRecord', $slackRecord);
38
+ $this->assertEquals(array(
39
+ 'attachments' => array(
40
+ array(
41
+ 'fallback' => 'test',
42
+ 'text' => 'test',
43
+ 'color' => SlackRecord::COLOR_WARNING,
44
+ 'fields' => array(
45
+ array(
46
+ 'title' => 'Level',
47
+ 'value' => 'WARNING',
48
+ 'short' => false,
49
+ ),
50
+ ),
51
+ 'title' => 'Message',
52
+ 'mrkdwn_in' => array('fields'),
53
+ 'ts' => $record['datetime']->getTimestamp(),
54
+ ),
55
+ ),
56
+ ), $slackRecord->getSlackData($record));
57
+ }
58
+
59
+ /**
60
+ * @covers ::__construct
61
+ * @covers ::getSlackRecord
62
+ */
63
+ public function testConstructorFull()
64
+ {
65
+ $handler = new SlackWebhookHandler(
66
+ self::WEBHOOK_URL,
67
+ 'test-channel',
68
+ 'test-username',
69
+ false,
70
+ ':ghost:',
71
+ false,
72
+ false,
73
+ Logger::DEBUG,
74
+ false
75
+ );
76
+
77
+ $slackRecord = $handler->getSlackRecord();
78
+ $this->assertInstanceOf('Monolog\Handler\Slack\SlackRecord', $slackRecord);
79
+ $this->assertEquals(array(
80
+ 'username' => 'test-username',
81
+ 'text' => 'test',
82
+ 'channel' => 'test-channel',
83
+ 'icon_emoji' => ':ghost:',
84
+ ), $slackRecord->getSlackData($this->getRecord()));
85
+ }
86
+
87
+ /**
88
+ * @covers ::getFormatter
89
+ */
90
+ public function testGetFormatter()
91
+ {
92
+ $handler = new SlackWebhookHandler(self::WEBHOOK_URL);
93
+ $formatter = $handler->getFormatter();
94
+ $this->assertInstanceOf('Monolog\Formatter\FormatterInterface', $formatter);
95
+ }
96
+
97
+ /**
98
+ * @covers ::setFormatter
99
+ */
100
+ public function testSetFormatter()
101
+ {
102
+ $handler = new SlackWebhookHandler(self::WEBHOOK_URL);
103
+ $formatter = new LineFormatter();
104
+ $handler->setFormatter($formatter);
105
+ $this->assertSame($formatter, $handler->getFormatter());
106
+ }
107
+ }
vendor/monolog/monolog/tests/Monolog/Handler/SlackbotHandlerTest.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\Handler;
13
+
14
+ use Monolog\TestCase;
15
+ use Monolog\Logger;
16
+
17
+ /**
18
+ * @author Haralan Dobrev <hkdobrev@gmail.com>
19
+ * @see https://slack.com/apps/A0F81R8ET-slackbot
20
+ * @coversDefaultClass Monolog\Handler\SlackbotHandler
21
+ */
22
+ class SlackbotHandlerTest extends TestCase
23
+ {
24
+ /**
25
+ * @covers ::__construct
26
+ */
27
+ public function testConstructorMinimal()
28
+ {
29
+ $handler = new SlackbotHandler('test-team', 'test-token', 'test-channel');
30
+ $this->assertInstanceOf('Monolog\Handler\AbstractProcessingHandler', $handler);
31
+ }
32
+
33
+ /**
34
+ * @covers ::__construct
35
+ */
36
+ public function testConstructorFull()
37
+ {
38
+ $handler = new SlackbotHandler(
39
+ 'test-team',
40
+ 'test-token',
41
+ 'test-channel',
42
+ Logger::DEBUG,
43
+ false
44
+ );
45
+ $this->assertInstanceOf('Monolog\Handler\AbstractProcessingHandler', $handler);
46
+ }
47
+ }
vendor/monolog/monolog/tests/Monolog/Handler/SocketHandlerTest.php DELETED
@@ -1,309 +0,0 @@
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 Pablo de Leon Belloc <pablolb@gmail.com>
19
- */
20
- class SocketHandlerTest extends TestCase
21
- {
22
- /**
23
- * @var Monolog\Handler\SocketHandler
24
- */
25
- private $handler;
26
-
27
- /**
28
- * @var resource
29
- */
30
- private $res;
31
-
32
- /**
33
- * @expectedException UnexpectedValueException
34
- */
35
- public function testInvalidHostname()
36
- {
37
- $this->createHandler('garbage://here');
38
- $this->writeRecord('data');
39
- }
40
-
41
- /**
42
- * @expectedException \InvalidArgumentException
43
- */
44
- public function testBadConnectionTimeout()
45
- {
46
- $this->createHandler('localhost:1234');
47
- $this->handler->setConnectionTimeout(-1);
48
- }
49
-
50
- public function testSetConnectionTimeout()
51
- {
52
- $this->createHandler('localhost:1234');
53
- $this->handler->setConnectionTimeout(10.1);
54
- $this->assertEquals(10.1, $this->handler->getConnectionTimeout());
55
- }
56
-
57
- /**
58
- * @expectedException \InvalidArgumentException
59
- */
60
- public function testBadTimeout()
61
- {
62
- $this->createHandler('localhost:1234');
63
- $this->handler->setTimeout(-1);
64
- }
65
-
66
- public function testSetTimeout()
67
- {
68
- $this->createHandler('localhost:1234');
69
- $this->handler->setTimeout(10.25);
70
- $this->assertEquals(10.25, $this->handler->getTimeout());
71
- }
72
-
73
- public function testSetWritingTimeout()
74
- {
75
- $this->createHandler('localhost:1234');
76
- $this->handler->setWritingTimeout(10.25);
77
- $this->assertEquals(10.25, $this->handler->getWritingTimeout());
78
- }
79
-
80
- public function testSetConnectionString()
81
- {
82
- $this->createHandler('tcp://localhost:9090');
83
- $this->assertEquals('tcp://localhost:9090', $this->handler->getConnectionString());
84
- }
85
-
86
- /**
87
- * @expectedException UnexpectedValueException
88
- */
89
- public function testExceptionIsThrownOnFsockopenError()
90
- {
91
- $this->setMockHandler(array('fsockopen'));
92
- $this->handler->expects($this->once())
93
- ->method('fsockopen')
94
- ->will($this->returnValue(false));
95
- $this->writeRecord('Hello world');
96
- }
97
-
98
- /**
99
- * @expectedException UnexpectedValueException
100
- */
101
- public function testExceptionIsThrownOnPfsockopenError()
102
- {
103
- $this->setMockHandler(array('pfsockopen'));
104
- $this->handler->expects($this->once())
105
- ->method('pfsockopen')
106
- ->will($this->returnValue(false));
107
- $this->handler->setPersistent(true);
108
- $this->writeRecord('Hello world');
109
- }
110
-
111
- /**
112
- * @expectedException UnexpectedValueException
113
- */
114
- public function testExceptionIsThrownIfCannotSetTimeout()
115
- {
116
- $this->setMockHandler(array('streamSetTimeout'));
117
- $this->handler->expects($this->once())
118
- ->method('streamSetTimeout')
119
- ->will($this->returnValue(false));
120
- $this->writeRecord('Hello world');
121
- }
122
-
123
- /**
124
- * @expectedException RuntimeException
125
- */
126
- public function testWriteFailsOnIfFwriteReturnsFalse()
127
- {
128
- $this->setMockHandler(array('fwrite'));
129
-
130
- $callback = function ($arg) {
131
- $map = array(
132
- 'Hello world' => 6,
133
- 'world' => false,
134
- );
135
-
136
- return $map[$arg];
137
- };
138
-
139
- $this->handler->expects($this->exactly(2))
140
- ->method('fwrite')
141
- ->will($this->returnCallback($callback));
142
-
143
- $this->writeRecord('Hello world');
144
- }
145
-
146
- /**
147
- * @expectedException RuntimeException
148
- */
149
- public function testWriteFailsIfStreamTimesOut()
150
- {
151
- $this->setMockHandler(array('fwrite', 'streamGetMetadata'));
152
-
153
- $callback = function ($arg) {
154
- $map = array(
155
- 'Hello world' => 6,
156
- 'world' => 5,
157
- );
158
-
159
- return $map[$arg];
160
- };
161
-
162
- $this->handler->expects($this->exactly(1))
163
- ->method('fwrite')
164
- ->will($this->returnCallback($callback));
165
- $this->handler->expects($this->exactly(1))
166
- ->method('streamGetMetadata')
167
- ->will($this->returnValue(array('timed_out' => true)));
168
-
169
- $this->writeRecord('Hello world');
170
- }
171
-
172
- /**
173
- * @expectedException RuntimeException
174
- */
175
- public function testWriteFailsOnIncompleteWrite()
176
- {
177
- $this->setMockHandler(array('fwrite', 'streamGetMetadata'));
178
-
179
- $res = $this->res;
180
- $callback = function ($string) use ($res) {
181
- fclose($res);
182
-
183
- return strlen('Hello');
184
- };
185
-
186
- $this->handler->expects($this->exactly(1))
187
- ->method('fwrite')
188
- ->will($this->returnCallback($callback));
189
- $this->handler->expects($this->exactly(1))
190
- ->method('streamGetMetadata')
191
- ->will($this->returnValue(array('timed_out' => false)));
192
-
193
- $this->writeRecord('Hello world');
194
- }
195
-
196
- public function testWriteWithMemoryFile()
197
- {
198
- $this->setMockHandler();
199
- $this->writeRecord('test1');
200
- $this->writeRecord('test2');
201
- $this->writeRecord('test3');
202
- fseek($this->res, 0);
203
- $this->assertEquals('test1test2test3', fread($this->res, 1024));
204
- }
205
-
206
- public function testWriteWithMock()
207
- {
208
- $this->setMockHandler(array('fwrite'));
209
-
210
- $callback = function ($arg) {
211
- $map = array(
212
- 'Hello world' => 6,
213
- 'world' => 5,
214
- );
215
-
216
- return $map[$arg];
217
- };
218
-
219
- $this->handler->expects($this->exactly(2))
220
- ->method('fwrite')
221
- ->will($this->returnCallback($callback));
222
-
223
- $this->writeRecord('Hello world');
224
- }
225
-
226
- public function testClose()
227
- {
228
- $this->setMockHandler();
229
- $this->writeRecord('Hello world');
230
- $this->assertInternalType('resource', $this->res);
231
- $this->handler->close();
232
- $this->assertFalse(is_resource($this->res), "Expected resource to be closed after closing handler");
233
- }
234
-
235
- public function testCloseDoesNotClosePersistentSocket()
236
- {
237
- $this->setMockHandler();
238
- $this->handler->setPersistent(true);
239
- $this->writeRecord('Hello world');
240
- $this->assertTrue(is_resource($this->res));
241
- $this->handler->close();
242
- $this->assertTrue(is_resource($this->res));
243
- }
244
-
245
- /**
246
- * @expectedException \RuntimeException
247
- */
248
- public function testAvoidInfiniteLoopWhenNoDataIsWrittenForAWritingTimeoutSeconds()
249
- {
250
- $this->setMockHandler(array('fwrite', 'streamGetMetadata'));
251
-
252
- $this->handler->expects($this->any())
253
- ->method('fwrite')
254
- ->will($this->returnValue(0));
255
-
256
- $this->handler->expects($this->any())
257
- ->method('streamGetMetadata')
258
- ->will($this->returnValue(array('timed_out' => false)));
259
-
260
- $this->handler->setWritingTimeout(1);
261
-
262
- $this->writeRecord('Hello world');
263
- }
264
-
265
- private function createHandler($connectionString)
266
- {
267
- $this->handler = new SocketHandler($connectionString);
268
- $this->handler->setFormatter($this->getIdentityFormatter());
269
- }
270
-
271
- private function writeRecord($string)
272
- {
273
- $this->handler->handle($this->getRecord(Logger::WARNING, $string));
274
- }
275
-
276
- private function setMockHandler(array $methods = array())
277
- {
278
- $this->res = fopen('php://memory', 'a');
279
-
280
- $defaultMethods = array('fsockopen', 'pfsockopen', 'streamSetTimeout');
281
- $newMethods = array_diff($methods, $defaultMethods);
282
-
283
- $finalMethods = array_merge($defaultMethods, $newMethods);
284
-
285
- $this->handler = $this->getMock(
286
- '\Monolog\Handler\SocketHandler', $finalMethods, array('localhost:1234')
287
- );
288
-
289
- if (!in_array('fsockopen', $methods)) {
290
- $this->handler->expects($this->any())
291
- ->method('fsockopen')
292
- ->will($this->returnValue($this->res));
293
- }
294
-
295
- if (!in_array('pfsockopen', $methods)) {
296
- $this->handler->expects($this->any())
297
- ->method('pfsockopen')
298
- ->will($this->returnValue($this->res));
299
- }
300
-
301
- if (!in_array('streamSetTimeout', $methods)) {
302
- $this->handler->expects($this->any())
303
- ->method('streamSetTimeout')
304
- ->will($this->returnValue(true));
305
- }
306
-
307
- $this->handler->setFormatter($this->getIdentityFormatter());
308
- }
309
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/StreamHandlerTest.php DELETED
@@ -1,184 +0,0 @@
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 StreamHandlerTest extends TestCase
18
- {
19
- /**
20
- * @covers Monolog\Handler\StreamHandler::__construct
21
- * @covers Monolog\Handler\StreamHandler::write
22
- */
23
- public function testWrite()
24
- {
25
- $handle = fopen('php://memory', 'a+');
26
- $handler = new StreamHandler($handle);
27
- $handler->setFormatter($this->getIdentityFormatter());
28
- $handler->handle($this->getRecord(Logger::WARNING, 'test'));
29
- $handler->handle($this->getRecord(Logger::WARNING, 'test2'));
30
- $handler->handle($this->getRecord(Logger::WARNING, 'test3'));
31
- fseek($handle, 0);
32
- $this->assertEquals('testtest2test3', fread($handle, 100));
33
- }
34
-
35
- /**
36
- * @covers Monolog\Handler\StreamHandler::close
37
- */
38
- public function testCloseKeepsExternalHandlersOpen()
39
- {
40
- $handle = fopen('php://memory', 'a+');
41
- $handler = new StreamHandler($handle);
42
- $this->assertTrue(is_resource($handle));
43
- $handler->close();
44
- $this->assertTrue(is_resource($handle));
45
- }
46
-
47
- /**
48
- * @covers Monolog\Handler\StreamHandler::close
49
- */
50
- public function testClose()
51
- {
52
- $handler = new StreamHandler('php://memory');
53
- $handler->handle($this->getRecord(Logger::WARNING, 'test'));
54
- $streamProp = new \ReflectionProperty('Monolog\Handler\StreamHandler', 'stream');
55
- $streamProp->setAccessible(true);
56
- $handle = $streamProp->getValue($handler);
57
-
58
- $this->assertTrue(is_resource($handle));
59
- $handler->close();
60
- $this->assertFalse(is_resource($handle));
61
- }
62
-
63
- /**
64
- * @covers Monolog\Handler\StreamHandler::write
65
- */
66
- public function testWriteCreatesTheStreamResource()
67
- {
68
- $handler = new StreamHandler('php://memory');
69
- $handler->handle($this->getRecord());
70
- }
71
-
72
- /**
73
- * @covers Monolog\Handler\StreamHandler::__construct
74
- * @covers Monolog\Handler\StreamHandler::write
75
- */
76
- public function testWriteLocking()
77
- {
78
- $temp = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'monolog_locked_log';
79
- $handler = new StreamHandler($temp, Logger::DEBUG, true, null, true);
80
- $handler->handle($this->getRecord());
81
- }
82
-
83
- /**
84
- * @expectedException LogicException
85
- * @covers Monolog\Handler\StreamHandler::__construct
86
- * @covers Monolog\Handler\StreamHandler::write
87
- */
88
- public function testWriteMissingResource()
89
- {
90
- $handler = new StreamHandler(null);
91
- $handler->handle($this->getRecord());
92
- }
93
-
94
- public function invalidArgumentProvider()
95
- {
96
- return array(
97
- array(1),
98
- array(array()),
99
- array(array('bogus://url')),
100
- );
101
- }
102
-
103
- /**
104
- * @dataProvider invalidArgumentProvider
105
- * @expectedException InvalidArgumentException
106
- * @covers Monolog\Handler\StreamHandler::__construct
107
- */
108
- public function testWriteInvalidArgument($invalidArgument)
109
- {
110
- $handler = new StreamHandler($invalidArgument);
111
- }
112
-
113
- /**
114
- * @expectedException UnexpectedValueException
115
- * @covers Monolog\Handler\StreamHandler::__construct
116
- * @covers Monolog\Handler\StreamHandler::write
117
- */
118
- public function testWriteInvalidResource()
119
- {
120
- $handler = new StreamHandler('bogus://url');
121
- $handler->handle($this->getRecord());
122
- }
123
-
124
- /**
125
- * @expectedException UnexpectedValueException
126
- * @covers Monolog\Handler\StreamHandler::__construct
127
- * @covers Monolog\Handler\StreamHandler::write
128
- */
129
- public function testWriteNonExistingResource()
130
- {
131
- $handler = new StreamHandler('ftp://foo/bar/baz/'.rand(0, 10000));
132
- $handler->handle($this->getRecord());
133
- }
134
-
135
- /**
136
- * @covers Monolog\Handler\StreamHandler::__construct
137
- * @covers Monolog\Handler\StreamHandler::write
138
- */
139
- public function testWriteNonExistingPath()
140
- {
141
- $handler = new StreamHandler(sys_get_temp_dir().'/bar/'.rand(0, 10000).DIRECTORY_SEPARATOR.rand(0, 10000));
142
- $handler->handle($this->getRecord());
143
- }
144
-
145
- /**
146
- * @covers Monolog\Handler\StreamHandler::__construct
147
- * @covers Monolog\Handler\StreamHandler::write
148
- */
149
- public function testWriteNonExistingFileResource()
150
- {
151
- $handler = new StreamHandler('file://'.sys_get_temp_dir().'/bar/'.rand(0, 10000).DIRECTORY_SEPARATOR.rand(0, 10000));
152
- $handler->handle($this->getRecord());
153
- }
154
-
155
- /**
156
- * @expectedException Exception
157
- * @expectedExceptionMessageRegExp /There is no existing directory at/
158
- * @covers Monolog\Handler\StreamHandler::__construct
159
- * @covers Monolog\Handler\StreamHandler::write
160
- */
161
- public function testWriteNonExistingAndNotCreatablePath()
162
- {
163
- if (defined('PHP_WINDOWS_VERSION_BUILD')) {
164
- $this->markTestSkipped('Permissions checks can not run on windows');
165
- }
166
- $handler = new StreamHandler('/foo/bar/'.rand(0, 10000).DIRECTORY_SEPARATOR.rand(0, 10000));
167
- $handler->handle($this->getRecord());
168
- }
169
-
170
- /**
171
- * @expectedException Exception
172
- * @expectedExceptionMessageRegExp /There is no existing directory at/
173
- * @covers Monolog\Handler\StreamHandler::__construct
174
- * @covers Monolog\Handler\StreamHandler::write
175
- */
176
- public function testWriteNonExistingAndNotCreatableFileResource()
177
- {
178
- if (defined('PHP_WINDOWS_VERSION_BUILD')) {
179
- $this->markTestSkipped('Permissions checks can not run on windows');
180
- }
181
- $handler = new StreamHandler('file:///foo/bar/'.rand(0, 10000).DIRECTORY_SEPARATOR.rand(0, 10000));
182
- $handler->handle($this->getRecord());
183
- }
184
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/SwiftMailerHandlerTest.php DELETED
@@ -1,113 +0,0 @@
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 SwiftMailerHandlerTest extends TestCase
18
- {
19
- /** @var \Swift_Mailer|\PHPUnit_Framework_MockObject_MockObject */
20
- private $mailer;
21
-
22
- public function setUp()
23
- {
24
- $this->mailer = $this
25
- ->getMockBuilder('Swift_Mailer')
26
- ->disableOriginalConstructor()
27
- ->getMock();
28
- }
29
-
30
- public function testMessageCreationIsLazyWhenUsingCallback()
31
- {
32
- $this->mailer->expects($this->never())
33
- ->method('send');
34
-
35
- $callback = function () {
36
- throw new \RuntimeException('Swift_Message creation callback should not have been called in this test');
37
- };
38
- $handler = new SwiftMailerHandler($this->mailer, $callback);
39
-
40
- $records = array(
41
- $this->getRecord(Logger::DEBUG),
42
- $this->getRecord(Logger::INFO),
43
- );
44
- $handler->handleBatch($records);
45
- }
46
-
47
- public function testMessageCanBeCustomizedGivenLoggedData()
48
- {
49
- // Wire Mailer to expect a specific Swift_Message with a customized Subject
50
- $expectedMessage = new \Swift_Message();
51
- $this->mailer->expects($this->once())
52
- ->method('send')
53
- ->with($this->callback(function ($value) use ($expectedMessage) {
54
- return $value instanceof \Swift_Message
55
- && $value->getSubject() === 'Emergency'
56
- && $value === $expectedMessage;
57
- }));
58
-
59
- // Callback dynamically changes subject based on number of logged records
60
- $callback = function ($content, array $records) use ($expectedMessage) {
61
- $subject = count($records) > 0 ? 'Emergency' : 'Normal';
62
- $expectedMessage->setSubject($subject);
63
-
64
- return $expectedMessage;
65
- };
66
- $handler = new SwiftMailerHandler($this->mailer, $callback);
67
-
68
- // Logging 1 record makes this an Emergency
69
- $records = array(
70
- $this->getRecord(Logger::EMERGENCY),
71
- );
72
- $handler->handleBatch($records);
73
- }
74
-
75
- public function testMessageSubjectFormatting()
76
- {
77
- // Wire Mailer to expect a specific Swift_Message with a customized Subject
78
- $messageTemplate = new \Swift_Message();
79
- $messageTemplate->setSubject('Alert: %level_name% %message%');
80
- $receivedMessage = null;
81
-
82
- $this->mailer->expects($this->once())
83
- ->method('send')
84
- ->with($this->callback(function ($value) use (&$receivedMessage) {
85
- $receivedMessage = $value;
86
- return true;
87
- }));
88
-
89
- $handler = new SwiftMailerHandler($this->mailer, $messageTemplate);
90
-
91
- $records = array(
92
- $this->getRecord(Logger::EMERGENCY),
93
- );
94
- $handler->handleBatch($records);
95
-
96
- $this->assertEquals('Alert: EMERGENCY test', $receivedMessage->getSubject());
97
- }
98
-
99
- public function testMessageHaveUniqueId()
100
- {
101
- $messageTemplate = \Swift_Message::newInstance();
102
- $handler = new SwiftMailerHandler($this->mailer, $messageTemplate);
103
-
104
- $method = new \ReflectionMethod('Monolog\Handler\SwiftMailerHandler', 'buildMessage');
105
- $method->setAccessible(true);
106
- $method->invokeArgs($handler, array($messageTemplate, array()));
107
-
108
- $builtMessage1 = $method->invoke($handler, $messageTemplate, array());
109
- $builtMessage2 = $method->invoke($handler, $messageTemplate, array());
110
-
111
- $this->assertFalse($builtMessage1->getId() === $builtMessage2->getId(), 'Two different messages have the same id');
112
- }
113
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/SyslogHandlerTest.php DELETED
@@ -1,44 +0,0 @@
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
- class SyslogHandlerTest extends \PHPUnit_Framework_TestCase
17
- {
18
- /**
19
- * @covers Monolog\Handler\SyslogHandler::__construct
20
- */
21
- public function testConstruct()
22
- {
23
- $handler = new SyslogHandler('test');
24
- $this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler);
25
-
26
- $handler = new SyslogHandler('test', LOG_USER);
27
- $this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler);
28
-
29
- $handler = new SyslogHandler('test', 'user');
30
- $this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler);
31
-
32
- $handler = new SyslogHandler('test', LOG_USER, Logger::DEBUG, true, LOG_PERROR);
33
- $this->assertInstanceOf('Monolog\Handler\SyslogHandler', $handler);
34
- }
35
-
36
- /**
37
- * @covers Monolog\Handler\SyslogHandler::__construct
38
- */
39
- public function testConstructInvalidFacility()
40
- {
41
- $this->setExpectedException('UnexpectedValueException');
42
- $handler = new SyslogHandler('test', 'unknown');
43
- }
44
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/SyslogUdpHandlerTest.php DELETED
@@ -1,49 +0,0 @@
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
- * @requires extension sockets
16
- */
17
- class SyslogUdpHandlerTest extends \PHPUnit_Framework_TestCase
18
- {
19
- /**
20
- * @expectedException UnexpectedValueException
21
- */
22
- public function testWeValidateFacilities()
23
- {
24
- $handler = new SyslogUdpHandler("ip", null, "invalidFacility");
25
- }
26
-
27
- public function testWeSplitIntoLines()
28
- {
29
- $handler = new SyslogUdpHandler("127.0.0.1", 514, "authpriv");
30
- $handler->setFormatter(new \Monolog\Formatter\ChromePHPFormatter());
31
-
32
- $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('write'), array('lol', 'lol'));
33
- $socket->expects($this->at(0))
34
- ->method('write')
35
- ->with("lol", "<".(LOG_AUTHPRIV + LOG_WARNING).">1 ");
36
- $socket->expects($this->at(1))
37
- ->method('write')
38
- ->with("hej", "<".(LOG_AUTHPRIV + LOG_WARNING).">1 ");
39
-
40
- $handler->setSocket($socket);
41
-
42
- $handler->handle($this->getRecordWithMessage("hej\nlol"));
43
- }
44
-
45
- protected function getRecordWithMessage($msg)
46
- {
47
- return array('message' => $msg, 'level' => \Monolog\Logger::WARNING, 'context' => null, 'extra' => array(), 'channel' => 'lol');
48
- }
49
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/TestHandlerTest.php DELETED
@@ -1,66 +0,0 @@
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\TestHandler
19
- */
20
- class TestHandlerTest extends TestCase
21
- {
22
- /**
23
- * @dataProvider methodProvider
24
- */
25
- public function testHandler($method, $level)
26
- {
27
- $handler = new TestHandler;
28
- $record = $this->getRecord($level, 'test'.$method);
29
- $this->assertFalse($handler->{'has'.$method}($record), 'has'.$method);
30
- $this->assertFalse($handler->{'has'.$method.'ThatContains'}('test'), 'has'.$method.'ThatContains');
31
- $this->assertFalse($handler->{'has'.$method.'ThatPasses'}(function ($rec) {
32
- return true;
33
- }), 'has'.$method.'ThatPasses');
34
- $this->assertFalse($handler->{'has'.$method.'ThatMatches'}('/test\w+/'));
35
- $this->assertFalse($handler->{'has'.$method.'Records'}(), 'has'.$method.'Records');
36
- $handler->handle($record);
37
-
38
- $this->assertFalse($handler->{'has'.$method}('bar'), 'has'.$method);
39
- $this->assertTrue($handler->{'has'.$method}($record), 'has'.$method);
40
- $this->assertTrue($handler->{'has'.$method}('test'.$method), 'has'.$method);
41
- $this->assertTrue($handler->{'has'.$method.'ThatContains'}('test'), 'has'.$method.'ThatContains');
42
- $this->assertTrue($handler->{'has'.$method.'ThatPasses'}(function ($rec) {
43
- return true;
44
- }), 'has'.$method.'ThatPasses');
45
- $this->assertTrue($handler->{'has'.$method.'ThatMatches'}('/test\w+/'));
46
- $this->assertTrue($handler->{'has'.$method.'Records'}(), 'has'.$method.'Records');
47
-
48
- $records = $handler->getRecords();
49
- unset($records[0]['formatted']);
50
- $this->assertEquals(array($record), $records);
51
- }
52
-
53
- public function methodProvider()
54
- {
55
- return array(
56
- array('Emergency', Logger::EMERGENCY),
57
- array('Alert' , Logger::ALERT),
58
- array('Critical' , Logger::CRITICAL),
59
- array('Error' , Logger::ERROR),
60
- array('Warning' , Logger::WARNING),
61
- array('Info' , Logger::INFO),
62
- array('Notice' , Logger::NOTICE),
63
- array('Debug' , Logger::DEBUG),
64
- );
65
- }
66
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/UdpSocketTest.php DELETED
@@ -1,64 +0,0 @@
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\Handler\SyslogUdp\UdpSocket;
16
-
17
- /**
18
- * @requires extension sockets
19
- */
20
- class UdpSocketTest extends TestCase
21
- {
22
- public function testWeDoNotTruncateShortMessages()
23
- {
24
- $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('send'), array('lol', 'lol'));
25
-
26
- $socket->expects($this->at(0))
27
- ->method('send')
28
- ->with("HEADER: The quick brown fox jumps over the lazy dog");
29
-
30
- $socket->write("The quick brown fox jumps over the lazy dog", "HEADER: ");
31
- }
32
-
33
- public function testLongMessagesAreTruncated()
34
- {
35
- $socket = $this->getMock('\Monolog\Handler\SyslogUdp\UdpSocket', array('send'), array('lol', 'lol'));
36
-
37
- $truncatedString = str_repeat("derp", 16254).'d';
38
-
39
- $socket->expects($this->exactly(1))
40
- ->method('send')
41
- ->with("HEADER" . $truncatedString);
42
-
43
- $longString = str_repeat("derp", 20000);
44
-
45
- $socket->write($longString, "HEADER");
46
- }
47
-
48
- public function testDoubleCloseDoesNotError()
49
- {
50
- $socket = new UdpSocket('127.0.0.1', 514);
51
- $socket->close();
52
- $socket->close();
53
- }
54
-
55
- /**
56
- * @expectedException LogicException
57
- */
58
- public function testWriteAfterCloseErrors()
59
- {
60
- $socket = new UdpSocket('127.0.0.1', 514);
61
- $socket->close();
62
- $socket->write('foo', "HEADER");
63
- }
64
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/WhatFailureGroupHandlerTest.php DELETED
@@ -1,121 +0,0 @@
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 WhatFailureGroupHandlerTest extends TestCase
18
- {
19
- /**
20
- * @covers Monolog\Handler\WhatFailureGroupHandler::__construct
21
- * @expectedException InvalidArgumentException
22
- */
23
- public function testConstructorOnlyTakesHandler()
24
- {
25
- new WhatFailureGroupHandler(array(new TestHandler(), "foo"));
26
- }
27
-
28
- /**
29
- * @covers Monolog\Handler\WhatFailureGroupHandler::__construct
30
- * @covers Monolog\Handler\WhatFailureGroupHandler::handle
31
- */
32
- public function testHandle()
33
- {
34
- $testHandlers = array(new TestHandler(), new TestHandler());
35
- $handler = new WhatFailureGroupHandler($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\WhatFailureGroupHandler::handleBatch
47
- */
48
- public function testHandleBatch()
49
- {
50
- $testHandlers = array(new TestHandler(), new TestHandler());
51
- $handler = new WhatFailureGroupHandler($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\WhatFailureGroupHandler::isHandling
62
- */
63
- public function testIsHandling()
64
- {
65
- $testHandlers = array(new TestHandler(Logger::ERROR), new TestHandler(Logger::WARNING));
66
- $handler = new WhatFailureGroupHandler($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\WhatFailureGroupHandler::handle
74
- */
75
- public function testHandleUsesProcessors()
76
- {
77
- $test = new TestHandler();
78
- $handler = new WhatFailureGroupHandler(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
-
90
- /**
91
- * @covers Monolog\Handler\WhatFailureGroupHandler::handle
92
- */
93
- public function testHandleException()
94
- {
95
- $test = new TestHandler();
96
- $exception = new ExceptionTestHandler();
97
- $handler = new WhatFailureGroupHandler(array($exception, $test, $exception));
98
- $handler->pushProcessor(function ($record) {
99
- $record['extra']['foo'] = true;
100
-
101
- return $record;
102
- });
103
- $handler->handle($this->getRecord(Logger::WARNING));
104
- $this->assertTrue($test->hasWarningRecords());
105
- $records = $test->getRecords();
106
- $this->assertTrue($records[0]['extra']['foo']);
107
- }
108
- }
109
-
110
- class ExceptionTestHandler extends TestHandler
111
- {
112
- /**
113
- * {@inheritdoc}
114
- */
115
- public function handle(array $record)
116
- {
117
- parent::handle($record);
118
-
119
- throw new \Exception("ExceptionTestHandler::handle");
120
- }
121
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/Handler/ZendMonitorHandlerTest.php DELETED
@@ -1,69 +0,0 @@
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\TestCase;
14
-
15
- class ZendMonitorHandlerTest extends TestCase
16
- {
17
- protected $zendMonitorHandler;
18
-
19
- public function setUp()
20
- {
21
- if (!function_exists('zend_monitor_custom_event')) {
22
- $this->markTestSkipped('ZendServer is not installed');
23
- }
24
- }
25
-
26
- /**
27
- * @covers Monolog\Handler\ZendMonitorHandler::write
28
- */
29
- public function testWrite()
30
- {
31
- $record = $this->getRecord();
32
- $formatterResult = array(
33
- 'message' => $record['message'],
34
- );
35
-
36
- $zendMonitor = $this->getMockBuilder('Monolog\Handler\ZendMonitorHandler')
37
- ->setMethods(array('writeZendMonitorCustomEvent', 'getDefaultFormatter'))
38
- ->getMock();
39
-
40
- $formatterMock = $this->getMockBuilder('Monolog\Formatter\NormalizerFormatter')
41
- ->disableOriginalConstructor()
42
- ->getMock();
43
-
44
- $formatterMock->expects($this->once())
45
- ->method('format')
46
- ->will($this->returnValue($formatterResult));
47
-
48
- $zendMonitor->expects($this->once())
49
- ->method('getDefaultFormatter')
50
- ->will($this->returnValue($formatterMock));
51
-
52
- $levelMap = $zendMonitor->getLevelMap();
53
-
54
- $zendMonitor->expects($this->once())
55
- ->method('writeZendMonitorCustomEvent')
56
- ->with($levelMap[$record['level']], $record['message'], $formatterResult);
57
-
58
- $zendMonitor->handle($record);
59
- }
60
-
61
- /**
62
- * @covers Monolog\Handler\ZendMonitorHandler::getDefaultFormatter
63
- */
64
- public function testGetDefaultFormatterReturnsNormalizerFormatter()
65
- {
66
- $zendMonitor = new ZendMonitorHandler();
67
- $this->assertInstanceOf('Monolog\Formatter\NormalizerFormatter', $zendMonitor->getDefaultFormatter());
68
- }
69
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor/monolog/monolog/tests/Monolog/LoggerTest.php DELETED
@@ -1,548 +0,0 @@
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\Processor\WebProcessor;
15
- use Monolog\Handler\TestHandler;
16
-
17
- class LoggerTest extends \PHPUnit_Framework_TestCase
18
- {
19
- /**
20
- * @covers Monolog\Logger::getName
21
- */
22
- public function testGetName()
23
- {
24
- $logger = new Logger('foo');
25
- $this->assertEquals('foo', $logger->getName());
26
- }
27
-
28
- /**
29
- * @covers Monolog\Logger::getLevelName
30
- */
31
- public function testGetLevelName()
32
- {
33
- $this->assertEquals('ERROR', Logger::getLevelName(Logger::ERROR));
34
- }
35
-
36
- /**
37
- * @covers Monolog\Logger::withName
38
- */
39
- public function testWithName()
40
- {
41
- $first = new Logger('first', array($handler = new TestHandler()));
42
- $second = $first->withName('second');
43
-
44
- $this->assertSame('first', $first->getName());
45
- $this->assertSame('second', $second->getName());
46
- $this->assertSame($handler, $second->popHandler());
47
- }
48
-
49
- /**
50
- * @covers Monolog\Logger::toMonologLevel
51
- */
52
- public function testConvertPSR3ToMonologLevel()
53
- {
54
- $this->assertEquals(Logger::toMonologLevel('debug'), 100);
55
- $this->assertEquals(Logger::toMonologLevel('info'), 200);
56
- $this->assertEquals(Logger::toMonologLevel('notice'), 250);
57
- $this->assertEquals(Logger::toMonologLevel('warning'), 300);
58
- $this->assertEquals(Logger::toMonologLevel('error'), 400);
59
- $this->assertEquals(Logger::toMonologLevel('critical'), 500);
60
- $this->assertEquals(Logger::toMonologLevel('alert'), 550);
61
- $this->assertEquals(Logger::toMonologLevel('emergency'), 600);
62
- }
63
-
64
- /**
65
- * @covers Monolog\Logger::getLevelName
66
- * @expectedException InvalidArgumentException
67
- */
68
- public function testGetLevelNameThrows()
69
- {
70
- Logger::getLevelName(5);
71
- }
72
-
73
- /**
74
- * @covers Monolog\Logger::__construct
75
- */
76
- public function testChannel()
77
- {
78
- $logger = new Logger('foo');
79
- $handler = new TestHandler;
80
- $logger->pushHandler($handler);
81
- $logger->addWarning('test');
82
- list($record) = $handler->getRecords();
83
- $this->assertEquals('foo', $record['channel']);
84
- }
85
-
86
- /**
87
- * @covers Monolog\Logger::addRecord
88
- */
89
- public function testLog()
90
- {
91
- $logger = new Logger(__METHOD__);
92
-
93
- $handler = $this->getMock('Monolog\Handler\NullHandler', array('handle'));
94
- $handler->expects($this->once())
95
- ->method('handle');
96
- $logger->pushHandler($handler);
97
-
98
- $this->assertTrue($logger->addWarning('test'));
99
- }
100
-
101
- /**
102
- * @covers Monolog\Logger::addRecord
103
- */
104
- public function testLogNotHandled()
105
- {
106
- $logger = new Logger(__METHOD__);
107
-
108
- $handler = $this->getMock('Monolog\Handler\NullHandler', array('handle'), array(Logger::ERROR));
109
- $handler->expects($this->never())
110
- ->method('handle');
111
- $logger->pushHandler($handler);
112
-
113
- $this->assertFalse($logger->addWarning('test'));
114
- }
115
-
116
- public function testHandlersInCtor()
117
- {
118
- $handler1 = new TestHandler;
119
- $handler2 = new TestHandler;
120
- $logger = new Logger(__METHOD__, array($handler1, $handler2));
121
-
122
- $this->assertEquals($handler1, $logger->popHandler());
123
- $this->assertEquals($handler2, $logger->popHandler());
124
- }
125
-
126
- public function testProcessorsInCtor()
127
- {
128
- $processor1 = new WebProcessor;
129
- $processor2 = new WebProcessor;
130
- $logger = new Logger(__METHOD__, array(), array($processor1, $processor2));
131
-
132
- $this->assertEquals($processor1, $logger->popProcessor());
133
- $this->assertEquals($processor2, $logger->popProcessor());
134
- }
135
-
136
- /**
137
- * @covers Monolog\Logger::pushHandler
138
- * @covers Monolog\Logger::popHandler
139
- * @expectedException LogicException
140
- */
141
- public function testPushPopHandler()
142
- {
143
- $logger = new Logger(__METHOD__);
144
- $handler1 = new TestHandler;
145
- $handler2 = new TestHandler;
146
-
147
- $logger->pushHandler($handler1);
148
- $logger->pushHandler($handler2);
149
-
150
- $this->assertEquals($handler2, $logger->popHandler());
151
- $this->assertEquals($handler1, $logger->popHandler());
152
- $logger->popHandler();
153
- }
154
-
155
- /**
156
- * @covers Monolog\Logger::setHandlers
157
- */
158
- public function testSetHandlers()
159
- {
160
- $logger = new Logger(__METHOD__);
161
- $handler1 = new TestHandler;
162
- $handler2 = new TestHandler;
163
-
164
- $logger->pushHandler($handler1);
165
- $logger->setHandlers(array($handler2));
166
-
167
- // handler1 has been removed
168
- $this->assertEquals(array($handler2), $logger->getHandlers());
169
-
170
- $logger->setHandlers(array(
171
- "AMapKey" => $handler1,
172
- "Woop" => $handler2,
173
- ));
174
-
175
- // Keys have been scrubbed
176
- $this->assertEquals(array($handler1, $handler2), $logger->getHandlers());
177
- }
178
-
179
- /**
180
- * @covers Monolog\Logger::pushProcessor
181
- * @covers Monolog\Logger::popProcessor
182
- * @expectedException LogicException
183
- */
184
- public function testPushPopProcessor()
185
- {
186
- $logger = new Logger(__METHOD__);
187
- $processor1 = new WebProcessor;
188
- $processor2 = new WebProcessor;
189
-
190
- $logger->pushProcessor($processor1);
191
- $logger->pushProcessor($processor2);
192
-
193
- $this->assertEquals($processor2, $logger->popProcessor());
194
- $this->assertEquals($processor1, $logger->popProcessor());
195
- $logger->popProcessor();
196
- }
197
-
198
- /**
199
- * @covers Monolog\Logger::pushProcessor
200
- * @expectedException InvalidArgumentException
201
- */
202
- public function testPushProcessorWithNonCallable()
203
- {
204
- $logger = new Logger(__METHOD__);
205
-
206
- $logger->pushProcessor(new \stdClass());
207
- }
208
-
209
- /**
210
- * @covers Monolog\Logger::addRecord
211
- */
212
- public function testProcessorsAreExecuted()
213
- {
214
- $logger = new Logger(__METHOD__);
215
- $handler = new TestHandler;
216
- $logger->pushHandler($handler);
217
- $logger->pushProcessor(function ($record) {
218
- $record['extra']['win'] = true;
219
-
220
- return $record;
221
- });
222
- $logger->addError('test');
223
- list($record) = $handler->getRecords();
224
- $this->assertTrue($record['extra']['win']);
225
- }
226
-
227
- /**
228
- * @covers Monolog\Logger::addRecord
229
- */
230
- public function testProcessorsAreCalledOnlyOnce()
231
- {
232
- $logger = new Logger(__METHOD__);
233
- $handler = $this->getMock('Monolog\Handler\HandlerInterface');
234
- $handler->expects($this->any())
235
- ->method('isHandling')
236
- ->will($this->returnValue(true))
237
- ;
238
- $handler->expects($this->any())
239
- ->method('handle')
240
- ->will($this->returnValue(true))
241
- ;
242
- $logger->pushHandler($handler);
243
-
244
- $processor = $this->getMockBuilder('Monolog\Processor\WebProcessor')
245
- ->disableOriginalConstructor()
246
- ->setMethods(array('__invoke'))
247
- ->getMock()
248
- ;
249
- $processor->expects($this->once())
250
- ->method('__invoke')
251
- ->will($this->returnArgument(0))
252
- ;
253
- $logger->pushProcessor($processor);
254
-
255
- $logger->addError('test');
256
- }
257
-
258
- /**
259
- * @covers Monolog\Logger::addRecord
260
- */
261
- public function testProcessorsNotCalledWhenNotHandled()
262
- {
263
- $logger = new Logger(__METHOD__);
264
- $handler = $this->getMock('Monolog\Handler\HandlerInterface');
265
- $handler->expects($this->once())
266
- ->method('isHandling')
267
- ->will($this->returnValue(false))
268
- ;
269
- $logger->pushHandler($handler);
270
- $that = $this;
271
- $logger->pushProcessor(function ($record) use ($that) {
272
- $that->fail('The processor should not be called');
273
- });
274
- $logger->addAlert('test');
275
- }
276
-
277
- /**
278
- * @covers Monolog\Logger::addRecord
279
- */
280
- public function testHandlersNotCalledBeforeFirstHandling()
281
- {
282
- $logger = new Logger(__METHOD__);
283
-
284
- $handler1 = $this->getMock('Monolog\Handler\HandlerInterface');
285
- $handler1->expects($this->never())
286
- ->method('isHandling')
287
- ->will($this->returnValue(false))
288
- ;
289
- $handler1->expects($this->once())
290
- ->method('handle')
291
- ->will($this->returnValue(false))
292
- ;
293
- $logger->pushHandler($handler1);
294
-
295
- $handler2 = $this->getMock('Monolog\Handler\HandlerInterface');
296
- $handler2->expects($this->once())
297
- ->method('isHandling')
298
- ->will($this->returnValue(true))
299
- ;
300
- $handler2->expects($this->once())
301
- ->method('handle')
302
- ->will($this->returnValue(false))
303
- ;
304
- $logger->pushHandler($handler2);
305
-
306
- $handler3 = $this->getMock('Monolog\Handler\HandlerInterface');
307
- $handler3->expects($this->once())
308
- ->method('isHandling')
309
- ->will($this->returnValue(false))
310
- ;
311
- $handler3->expects($this->never())
312
- ->method('handle')
313
- ;
314
- $logger->pushHandler($handler3);
315
-
316
- $logger->debug('test');
317
- }
318
-
319
- /**
320
- * @covers Monolog\Logger::addRecord
321
- */
322
- public function testHandlersNotCalledBeforeFirstHandlingWithAssocArray()
323
- {
324
- $handler1 = $this->getMock('Monolog\Handler\HandlerInterface');
325
- $handler1->expects($this->never())
326
- ->method('isHandling')
327
- ->will($this->returnValue(false))
328
- ;
329
- $handler1->expects($this->once())
330
- ->method('handle')
331
- ->will($this->returnValue(false))
332
- ;
333
-
334
- $handler2 = $this->getMock('Monolog\Handler\HandlerInterface');
335
- $handler2->expects($this->once())
336
- ->method('isHandling')
337
- ->will($this->returnValue(true))
338
- ;
339
- $handler2->expects($this->once())
340
- ->method('handle')
341
- ->will($this->returnValue(false))
342
- ;
343
-
344
- $handler3 = $this->getMock('Monolog\Handler\HandlerInterface');
345
- $handler3->expects($this->once())
346
- ->method('isHandling')
347
- ->will($this->returnValue(false))
348
- ;
349
- $handler3->expects($this->never())
350
- ->method('handle')
351
- ;
352
-
353
- $logger = new Logger(__METHOD__, array('last' => $handler3, 'second' => $handler2, 'first' => $handler1));
354
-
355
- $logger->debug('test');
356
- }
357
-
358
- /**
359
- * @covers Monolog\Logger::addRecord
360
- */
361
- public function testBubblingWhenTheHandlerReturnsFalse()
362
- {
363
- $logger = new Logger(__METHOD__);
364
-
365
- $handler1 = $this->getMock('Monolog\Handler\HandlerInterface');
366
- $handler1->expects($this->any())
367
- ->method('isHandling')
368
- ->will($this->returnValue(true))
369
- ;
370
- $handler1->expects($this->once())
371
- ->method('handle')
372
- ->will($this->returnValue(false))
373
- ;
374
- $logger->pushHandler($handler1);
375
-
376
- $handler2 = $this->getMock('Monolog\Handler\HandlerInterface');
377
- $handler2->expects($this->any())
378
- ->method('isHandling')
379
- ->will($this->returnValue(true))
380
- ;
381
- $handler2->expects($this->once())
382
- ->method('handle')
383
-