WC Vendors - Version 1.4.3

Version Description

No Upgrade required at this time.

Download this release

Release Info

Developer digitalchild
Plugin Icon 128x128 WC Vendors
Version 1.4.3
Comparing to
See all releases

Code changes from version 1.4.2 to 1.4.3

Files changed (107) hide show
  1. trunk/WCVendors/assets/css/wcv-frontend.css +544 -0
  2. trunk/WCVendors/assets/images/icons/truck.png +0 -0
  3. trunk/WCVendors/assets/js/front-orders.js +9 -0
  4. trunk/WCVendors/assets/js/wcv-admin-quick-edit.js +34 -0
  5. trunk/WCVendors/classes/admin/class-admin-page.php +590 -0
  6. trunk/WCVendors/classes/admin/class-admin-reports.php +398 -0
  7. trunk/WCVendors/classes/admin/class-admin-users.php +411 -0
  8. trunk/WCVendors/classes/admin/class-product-meta.php +264 -0
  9. trunk/WCVendors/classes/admin/class-vendor-applicants.php +101 -0
  10. trunk/WCVendors/classes/admin/class-vendor-reports.php +121 -0
  11. trunk/WCVendors/classes/admin/emails/class-emails.php +131 -0
  12. trunk/WCVendors/classes/admin/emails/class-wc-approve-vendor.php +165 -0
  13. trunk/WCVendors/classes/admin/emails/class-wc-notify-admin.php +171 -0
  14. trunk/WCVendors/classes/admin/emails/class-wc-notify-shipped.php +198 -0
  15. trunk/WCVendors/classes/admin/emails/class-wc-notify-vendor.php +265 -0
  16. trunk/WCVendors/classes/admin/settings/README.md +126 -0
  17. trunk/WCVendors/classes/admin/settings/assets/css/sf-styles.css +167 -0
  18. trunk/WCVendors/classes/admin/settings/assets/img/tip.png +0 -0
  19. trunk/WCVendors/classes/admin/settings/assets/js/bootstrap-tooltip.js +126 -0
  20. trunk/WCVendors/classes/admin/settings/assets/js/js.iml +10 -0
  21. trunk/WCVendors/classes/admin/settings/assets/js/select2/select2.css +564 -0
  22. trunk/WCVendors/classes/admin/settings/assets/js/select2/select2.js +2506 -0
  23. trunk/WCVendors/classes/admin/settings/assets/js/select2/select2.min.css +440 -0
  24. trunk/WCVendors/classes/admin/settings/assets/js/select2/select2.min.js +1564 -0
  25. trunk/WCVendors/classes/admin/settings/assets/js/select2/select2.png +0 -0
  26. trunk/WCVendors/classes/admin/settings/assets/js/select2/select2x2.png +0 -0
  27. trunk/WCVendors/classes/admin/settings/assets/js/select2/spinner.gif +0 -0
  28. trunk/WCVendors/classes/admin/settings/assets/js/sf-jquery.js +23 -0
  29. trunk/WCVendors/classes/admin/settings/classes/sf-class-format-options.php +347 -0
  30. trunk/WCVendors/classes/admin/settings/classes/sf-class-sanitize.php +160 -0
  31. trunk/WCVendors/classes/admin/settings/classes/sf-class-settings.php +910 -0
  32. trunk/WCVendors/classes/admin/settings/sf-options.php +306 -0
  33. trunk/WCVendors/classes/class-commission.php +341 -0
  34. trunk/WCVendors/classes/class-cron.php +165 -0
  35. trunk/WCVendors/classes/class-install.php +285 -0
  36. trunk/WCVendors/classes/class-queries.php +278 -0
  37. trunk/WCVendors/classes/class-shipping.php +250 -0
  38. trunk/WCVendors/classes/class-vendors.php +413 -0
  39. trunk/WCVendors/classes/front/class-vendor-cart.php +63 -0
  40. trunk/WCVendors/classes/front/class-vendor-shop.php +266 -0
  41. trunk/WCVendors/classes/front/dashboard/class-vendor-dashboard.php +384 -0
  42. trunk/WCVendors/classes/front/orders/class-export-csv.php +77 -0
  43. trunk/WCVendors/classes/front/orders/class-orders.php +294 -0
  44. trunk/WCVendors/classes/front/orders/class-submit-comment.php +81 -0
  45. trunk/WCVendors/classes/front/signup/class-vendor-signup.php +133 -0
  46. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/assets/icons/index.php +0 -0
  47. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/assets/icons/paypalap.png +0 -0
  48. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/assets/index.php +0 -0
  49. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/ChangeLog.txt +33 -0
  50. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/LICENSE.txt +41 -0
  51. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/README.md +57 -0
  52. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/build.xml +24 -0
  53. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/config/cert_key.pem +31 -0
  54. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/config/sdk_config.ini +26 -0
  55. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/IPPCredential.php +53 -0
  56. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPAPIService.php +62 -0
  57. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPAuthenticationManager.php +91 -0
  58. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPBaseService.php +88 -0
  59. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPCertificateCredential.php +72 -0
  60. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPConfigManager.php +124 -0
  61. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPConnectionManager.php +48 -0
  62. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPCredentialManager.php +117 -0
  63. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPHttpConnection.php +184 -0
  64. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPLoggingManager.php +84 -0
  65. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPObjectTransformer.php +33 -0
  66. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPSignatureCredential.php +49 -0
  67. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPUtils.php +274 -0
  68. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/auth/AuthUtil.php +83 -0
  69. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/auth/PPAuth.php +1073 -0
  70. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/cacert.pem +171 -0
  71. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/exceptions/PPConfigurationException.php +9 -0
  72. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/exceptions/PPConnectionException.php +20 -0
  73. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/exceptions/PPInvalidCredentialException.php +22 -0
  74. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/exceptions/PPMissingCredentialException.php +22 -0
  75. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/exceptions/PPTransformerException.php +20 -0
  76. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/services/AdaptivePayments/AdaptivePayments.php +5797 -0
  77. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/services/AdaptivePayments/AdaptivePaymentsService.php +314 -0
  78. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/index.php +0 -0
  79. trunk/WCVendors/classes/gateways/PayPal_AdvPayments/paypal_ap.php +542 -0
  80. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/ChangeLog.txt +48 -0
  81. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/LICENSE.txt +41 -0
  82. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/README.md +60 -0
  83. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/build.xml +24 -0
  84. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/config/sdk-cert.pem +41 -0
  85. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/config/sdk_config.ini +39 -0
  86. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/IPPCredential.php +53 -0
  87. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPAPIService.php +62 -0
  88. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPAuthenticationManager.php +99 -0
  89. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPBaseService.php +88 -0
  90. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPCertificateCredential.php +77 -0
  91. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPConfigManager.php +121 -0
  92. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPConnectionManager.php +48 -0
  93. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPCredentialManager.php +119 -0
  94. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPHttpConnection.php +184 -0
  95. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPLoggingManager.php +84 -0
  96. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPObjectTransformer.php +33 -0
  97. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPSignatureCredential.php +56 -0
  98. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPUtils.php +284 -0
  99. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/auth/AuthUtil.php +83 -0
  100. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/auth/PPAuth.php +1057 -0
  101. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/cacert.pem +171 -0
  102. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/exceptions/PPConfigurationException.php +9 -0
  103. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/exceptions/PPConnectionException.php +20 -0
  104. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/exceptions/PPInvalidCredentialException.php +22 -0
  105. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/exceptions/PPMissingCredentialException.php +22 -0
  106. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/exceptions/PPTransformerException.php +20 -0
  107. trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/services/PayPalAPIInterfaceService/PayPalAPIInterfaceService.php +7812 -0
trunk/WCVendors/assets/css/wcv-frontend.css ADDED
@@ -0,0 +1,544 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ * Bootstrap v2.1.1
3
+ *
4
+ * Copyright 2012 Twitter, Inc
5
+ * Licensed under the Apache License v2.0
6
+ * http://www.apache.org/licenses/LICENSE-2.0
7
+ *
8
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
9
+ */
10
+ clearfix {
11
+ *zoom: 1;
12
+ }
13
+
14
+ .clearfix:before, .clearfix:after {
15
+ display: table;
16
+ content: "";
17
+ line-height: 0;
18
+ }
19
+
20
+ .clearfix:after {
21
+ clear: both;
22
+ }
23
+
24
+ .hide-text {
25
+ font: 0/0 a;
26
+ color: transparent;
27
+ text-shadow: none;
28
+ background-color: transparent;
29
+ border: 0;
30
+ }
31
+
32
+ .input-block-level {
33
+ display: block;
34
+ width: 100%;
35
+ min-height: 30px;
36
+ -webkit-box-sizing: border-box;
37
+ -moz-box-sizing: border-box;
38
+ box-sizing: border-box;
39
+ }
40
+
41
+ .btn {
42
+ display: inline-block;
43
+ *display: inline;
44
+ *zoom: 1;
45
+ padding: 4px 14px;
46
+ margin-bottom: 0;
47
+ font-size: 14px;
48
+ line-height: 20px;
49
+ *line-height: 20px;
50
+ text-align: center;
51
+ vertical-align: middle;
52
+ cursor: pointer;
53
+ color: #333333;
54
+ text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
55
+ background-color: #f5f5f5;
56
+ background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
57
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
58
+ background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
59
+ background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
60
+ background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
61
+ background-repeat: repeat-x;
62
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);
63
+ border-color: #e6e6e6 #e6e6e6 #bfbfbf;
64
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
65
+ *background-color: #e6e6e6;
66
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
67
+ border: 1px solid #bbbbbb;
68
+ *border: 0;
69
+ border-bottom-color: #a2a2a2;
70
+ -webkit-border-radius: 4px;
71
+ -moz-border-radius: 4px;
72
+ border-radius: 4px;
73
+ *margin-left: .3em;
74
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
75
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
76
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
77
+ }
78
+
79
+ .btn:hover, .btn:active, .btn.active, .btn.disabled, .btn[disabled] {
80
+ color: #333333;
81
+ background-color: #e6e6e6;
82
+ *background-color: #d9d9d9;
83
+ }
84
+
85
+ .btn:active, .btn.active {
86
+ background-color: #cccccc \9;
87
+ }
88
+
89
+ .btn:first-child {
90
+ *margin-left: 0;
91
+ }
92
+
93
+ .btn:hover {
94
+ color: #333333;
95
+ text-decoration: none;
96
+ background-color: #e6e6e6;
97
+ *background-color: #d9d9d9;
98
+ background-position: 0 -15px;
99
+ -webkit-transition: background-position 0.1s linear;
100
+ -moz-transition: background-position 0.1s linear;
101
+ -o-transition: background-position 0.1s linear;
102
+ transition: background-position 0.1s linear;
103
+ }
104
+
105
+ .btn:focus {
106
+ outline: thin dotted #333;
107
+ outline: 5px auto -webkit-focus-ring-color;
108
+ outline-offset: -2px;
109
+ }
110
+
111
+ .btn.active, .btn:active {
112
+ background-color: #e6e6e6;
113
+ background-color: #d9d9d9 \9;
114
+ background-image: none;
115
+ outline: 0;
116
+ -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
117
+ -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
118
+ box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
119
+ }
120
+
121
+ .btn.disabled, .btn[disabled] {
122
+ cursor: default;
123
+ background-color: #e6e6e6;
124
+ background-image: none;
125
+ opacity: 0.65;
126
+ filter: alpha(opacity=65);
127
+ -webkit-box-shadow: none;
128
+ -moz-box-shadow: none;
129
+ box-shadow: none;
130
+ }
131
+
132
+ .btn-large {
133
+ padding: 9px 14px;
134
+ font-size: 16px;
135
+ line-height: normal;
136
+ -webkit-border-radius: 5px;
137
+ -moz-border-radius: 5px;
138
+ border-radius: 5px;
139
+ }
140
+
141
+ .btn-large [class^="icon-"] {
142
+ margin-top: 2px;
143
+ }
144
+
145
+ .btn-small {
146
+ padding: 3px 9px;
147
+ font-size: 12px;
148
+ line-height: 18px;
149
+ }
150
+
151
+ .btn-small [class^="icon-"] {
152
+ margin-top: 0;
153
+ }
154
+
155
+ .btn-mini {
156
+ padding: 2px 6px;
157
+ font-size: 11px;
158
+ line-height: 17px;
159
+ }
160
+
161
+ .btn-block {
162
+ display: block;
163
+ width: 100%;
164
+ padding-left: 0;
165
+ padding-right: 0;
166
+ -webkit-box-sizing: border-box;
167
+ -moz-box-sizing: border-box;
168
+ box-sizing: border-box;
169
+ }
170
+
171
+ .btn-block + .btn-block {
172
+ margin-top: 5px;
173
+ }
174
+
175
+ input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="button"].btn-block {
176
+ width: 100%;
177
+ }
178
+
179
+ .btn-primary.active, .btn-warning.active, .btn-danger.active, .btn-success.active, .btn-info.active, .btn-inverse.active {
180
+ color: rgba(255, 255, 255, 0.75);
181
+ }
182
+
183
+ .btn {
184
+ border-color: #c5c5c5;
185
+ border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);
186
+ }
187
+
188
+ .btn-primary {
189
+ color: #ffffff;
190
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
191
+ background-color: #006dcc;
192
+ background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
193
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
194
+ background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
195
+ background-image: -o-linear-gradient(top, #0088cc, #0044cc);
196
+ background-image: linear-gradient(to bottom, #0088cc, #0044cc);
197
+ background-repeat: repeat-x;
198
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);
199
+ border-color: #0044cc #0044cc #002a80;
200
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
201
+ *background-color: #0044cc;
202
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
203
+ }
204
+
205
+ .btn-primary:hover, .btn-primary:active, .btn-primary.active, .btn-primary.disabled, .btn-primary[disabled] {
206
+ color: #ffffff;
207
+ background-color: #0044cc;
208
+ *background-color: #003bb3;
209
+ }
210
+
211
+ .btn-primary:active, .btn-primary.active {
212
+ background-color: #003399 \9;
213
+ }
214
+
215
+ .btn-warning {
216
+ color: #ffffff;
217
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
218
+ background-color: #faa732;
219
+ background-image: -moz-linear-gradient(top, #fbb450, #f89406);
220
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));
221
+ background-image: -webkit-linear-gradient(top, #fbb450, #f89406);
222
+ background-image: -o-linear-gradient(top, #fbb450, #f89406);
223
+ background-image: linear-gradient(to bottom, #fbb450, #f89406);
224
+ background-repeat: repeat-x;
225
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);
226
+ border-color: #f89406 #f89406 #ad6704;
227
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
228
+ *background-color: #f89406;
229
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
230
+ }
231
+
232
+ .btn-warning:hover, .btn-warning:active, .btn-warning.active, .btn-warning.disabled, .btn-warning[disabled] {
233
+ color: #ffffff;
234
+ background-color: #f89406;
235
+ *background-color: #df8505;
236
+ }
237
+
238
+ .btn-warning:active, .btn-warning.active {
239
+ background-color: #c67605 \9;
240
+ }
241
+
242
+ .btn-danger {
243
+ color: #ffffff;
244
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
245
+ background-color: #da4f49;
246
+ background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f);
247
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));
248
+ background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f);
249
+ background-image: -o-linear-gradient(top, #ee5f5b, #bd362f);
250
+ background-image: linear-gradient(to bottom, #ee5f5b, #bd362f);
251
+ background-repeat: repeat-x;
252
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);
253
+ border-color: #bd362f #bd362f #802420;
254
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
255
+ *background-color: #bd362f;
256
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
257
+ }
258
+
259
+ .btn-danger:hover, .btn-danger:active, .btn-danger.active, .btn-danger.disabled, .btn-danger[disabled] {
260
+ color: #ffffff;
261
+ background-color: #bd362f;
262
+ *background-color: #a9302a;
263
+ }
264
+
265
+ .btn-danger:active, .btn-danger.active {
266
+ background-color: #942a25 \9;
267
+ }
268
+
269
+ .btn-success {
270
+ color: #ffffff;
271
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
272
+ background-color: #5bb75b;
273
+ background-image: -moz-linear-gradient(top, #62c462, #51a351);
274
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));
275
+ background-image: -webkit-linear-gradient(top, #62c462, #51a351);
276
+ background-image: -o-linear-gradient(top, #62c462, #51a351);
277
+ background-image: linear-gradient(to bottom, #62c462, #51a351);
278
+ background-repeat: repeat-x;
279
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0);
280
+ border-color: #51a351 #51a351 #387038;
281
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
282
+ *background-color: #51a351;
283
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
284
+ }
285
+
286
+ .btn-success:hover, .btn-success:active, .btn-success.active, .btn-success.disabled, .btn-success[disabled] {
287
+ color: #ffffff;
288
+ background-color: #51a351;
289
+ *background-color: #499249;
290
+ }
291
+
292
+ .btn-success:active, .btn-success.active {
293
+ background-color: #408140 \9;
294
+ }
295
+
296
+ .btn-info {
297
+ color: #ffffff;
298
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
299
+ background-color: #49afcd;
300
+ background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4);
301
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));
302
+ background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4);
303
+ background-image: -o-linear-gradient(top, #5bc0de, #2f96b4);
304
+ background-image: linear-gradient(to bottom, #5bc0de, #2f96b4);
305
+ background-repeat: repeat-x;
306
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);
307
+ border-color: #2f96b4 #2f96b4 #1f6377;
308
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
309
+ *background-color: #2f96b4;
310
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
311
+ }
312
+
313
+ .btn-info:hover, .btn-info:active, .btn-info.active, .btn-info.disabled, .btn-info[disabled] {
314
+ color: #ffffff;
315
+ background-color: #2f96b4;
316
+ *background-color: #2a85a0;
317
+ }
318
+
319
+ .btn-info:active, .btn-info.active {
320
+ background-color: #24748c \9;
321
+ }
322
+
323
+ .btn-inverse {
324
+ color: #ffffff;
325
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
326
+ background-color: #363636;
327
+ background-image: -moz-linear-gradient(top, #444444, #222222);
328
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222));
329
+ background-image: -webkit-linear-gradient(top, #444444, #222222);
330
+ background-image: -o-linear-gradient(top, #444444, #222222);
331
+ background-image: linear-gradient(to bottom, #444444, #222222);
332
+ background-repeat: repeat-x;
333
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);
334
+ border-color: #222222 #222222 #000000;
335
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
336
+ *background-color: #222222;
337
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
338
+ }
339
+
340
+ .btn-inverse:hover, .btn-inverse:active, .btn-inverse.active, .btn-inverse.disabled, .btn-inverse[disabled] {
341
+ color: #ffffff;
342
+ background-color: #222222;
343
+ *background-color: #151515;
344
+ }
345
+
346
+ .btn-inverse:active, .btn-inverse.active {
347
+ background-color: #080808 \9;
348
+ }
349
+
350
+ button.btn, input[type="submit"].btn {
351
+ *padding-top: 3px;
352
+ *padding-bottom: 3px;
353
+ }
354
+
355
+ button.btn::-moz-focus-inner, input[type="submit"].btn::-moz-focus-inner {
356
+ padding: 0;
357
+ border: 0;
358
+ }
359
+
360
+ button.btn.btn-large, input[type="submit"].btn.btn-large {
361
+ *padding-top: 7px;
362
+ *padding-bottom: 7px;
363
+ }
364
+
365
+ button.btn.btn-small, input[type="submit"].btn.btn-small {
366
+ *padding-top: 3px;
367
+ *padding-bottom: 3px;
368
+ }
369
+
370
+ button.btn.btn-mini, input[type="submit"].btn.btn-mini {
371
+ *padding-top: 1px;
372
+ *padding-bottom: 1px;
373
+ }
374
+
375
+ .btn-link, .btn-link:active, .btn-link[disabled] {
376
+ background-color: transparent;
377
+ background-image: none;
378
+ -webkit-box-shadow: none;
379
+ -moz-box-shadow: none;
380
+ box-shadow: none;
381
+ }
382
+
383
+ .btn-link {
384
+ border-color: transparent;
385
+ cursor: pointer;
386
+ color: #0088cc;
387
+ -webkit-border-radius: 0;
388
+ -moz-border-radius: 0;
389
+ border-radius: 0;
390
+ }
391
+
392
+ .btn-link:hover {
393
+ color: #005580;
394
+ text-decoration: underline;
395
+ background-color: transparent;
396
+ }
397
+
398
+ .btn-link[disabled]:hover {
399
+ color: #333333;
400
+ text-decoration: none;
401
+ }
402
+
403
+ table {
404
+ max-width: 100%;
405
+ background-color: transparent;
406
+ border-collapse: collapse;
407
+ border-spacing: 0;
408
+ }
409
+
410
+ .table {
411
+ width: 100%;
412
+ margin-bottom: 20px;
413
+ }
414
+
415
+ .table th, .table td {
416
+ padding: 8px;
417
+ line-height: 20px;
418
+ text-align: left;
419
+ vertical-align: top;
420
+ border-top: 1px solid #dddddd;
421
+ }
422
+
423
+ .table th {
424
+ font-weight: bold;
425
+ }
426
+
427
+ .table thead th {
428
+ vertical-align: bottom;
429
+ }
430
+
431
+ .table caption + thead tr:first-child th, .table caption + thead tr:first-child td, .table colgroup + thead tr:first-child th, .table colgroup + thead tr:first-child td, .table thead:first-child tr:first-child th, .table thead:first-child tr:first-child td {
432
+ border-top: 0;
433
+ }
434
+
435
+ .table tbody + tbody {
436
+ border-top: 2px solid #dddddd;
437
+ }
438
+
439
+ .table-condensed th, .table-condensed td {
440
+ padding: 4px 5px;
441
+ }
442
+
443
+ .table-bordered {
444
+ border: 1px solid #dddddd;
445
+ border-collapse: separate;
446
+ *border-collapse: collapse;
447
+ border-left: 0;
448
+ -webkit-border-radius: 4px;
449
+ -moz-border-radius: 4px;
450
+ border-radius: 4px;
451
+ }
452
+
453
+ .table-bordered th, .table-bordered td {
454
+ border-left: 1px solid #dddddd;
455
+ }
456
+
457
+ .table-bordered caption + thead tr:first-child th, .table-bordered caption + tbody tr:first-child th, .table-bordered caption + tbody tr:first-child td, .table-bordered colgroup + thead tr:first-child th, .table-bordered colgroup + tbody tr:first-child th, .table-bordered colgroup + tbody tr:first-child td, .table-bordered thead:first-child tr:first-child th, .table-bordered tbody:first-child tr:first-child th, .table-bordered tbody:first-child tr:first-child td {
458
+ border-top: 0;
459
+ }
460
+
461
+ .table-bordered thead:first-child tr:first-child th:first-child, .table-bordered tbody:first-child tr:first-child td:first-child {
462
+ -webkit-border-top-left-radius: 4px;
463
+ border-top-left-radius: 4px;
464
+ -moz-border-radius-topleft: 4px;
465
+ }
466
+
467
+ .table-bordered thead:first-child tr:first-child th:last-child, .table-bordered tbody:first-child tr:first-child td:last-child {
468
+ -webkit-border-top-right-radius: 4px;
469
+ border-top-right-radius: 4px;
470
+ -moz-border-radius-topright: 4px;
471
+ }
472
+
473
+ .table-bordered thead:last-child tr:last-child th:first-child, .table-bordered tbody:last-child tr:last-child td:first-child, .table-bordered tfoot:last-child tr:last-child td:first-child {
474
+ -webkit-border-radius: 0 0 0 4px;
475
+ -moz-border-radius: 0 0 0 4px;
476
+ border-radius: 0 0 0 4px;
477
+ -webkit-border-bottom-left-radius: 4px;
478
+ border-bottom-left-radius: 4px;
479
+ -moz-border-radius-bottomleft: 4px;
480
+ }
481
+
482
+ .table-bordered thead:last-child tr:last-child th:last-child, .table-bordered tbody:last-child tr:last-child td:last-child, .table-bordered tfoot:last-child tr:last-child td:last-child {
483
+ -webkit-border-bottom-right-radius: 4px;
484
+ border-bottom-right-radius: 4px;
485
+ -moz-border-radius-bottomright: 4px;
486
+ }
487
+
488
+ .table-bordered caption + thead tr:first-child th:first-child, .table-bordered caption + tbody tr:first-child td:first-child, .table-bordered colgroup + thead tr:first-child th:first-child, .table-bordered colgroup + tbody tr:first-child td:first-child {
489
+ -webkit-border-top-left-radius: 4px;
490
+ border-top-left-radius: 4px;
491
+ -moz-border-radius-topleft: 4px;
492
+ }
493
+
494
+ .table-bordered caption + thead tr:first-child th:last-child, .table-bordered caption + tbody tr:first-child td:last-child, .table-bordered colgroup + thead tr:first-child th:last-child, .table-bordered colgroup + tbody tr:first-child td:last-child {
495
+ -webkit-border-top-right-radius: 4px;
496
+ border-top-right-radius: 4px;
497
+ -moz-border-radius-topleft: 4px;
498
+ }
499
+
500
+ .table-striped tbody tr:nth-child(odd) td, .table-striped tbody tr:nth-child(odd) th {
501
+ background-color: #f9f9f9;
502
+ }
503
+
504
+ .table-hover tbody tr:hover td, .table-hover tbody tr:hover th {
505
+ background-color: #f5f5f5;
506
+ }
507
+
508
+ table [class*=span], .row-fluid table [class*=span] {
509
+ display: table-cell;
510
+ float: none;
511
+ margin-left: 0;
512
+ }
513
+
514
+ .table tbody tr.success td {
515
+ background-color: #dff0d8;
516
+ }
517
+
518
+ .table tbody tr.error td {
519
+ background-color: #f2dede;
520
+ }
521
+
522
+ .table tbody tr.warning td {
523
+ background-color: #fcf8e3;
524
+ }
525
+
526
+ .table tbody tr.info td {
527
+ background-color: #d9edf7;
528
+ }
529
+
530
+ .table-hover tbody tr.success:hover td {
531
+ background-color: #d0e9c6;
532
+ }
533
+
534
+ .table-hover tbody tr.error:hover td {
535
+ background-color: #ebcccc;
536
+ }
537
+
538
+ .table-hover tbody tr.warning:hover td {
539
+ background-color: #faf2cc;
540
+ }
541
+
542
+ .table-hover tbody tr.info:hover td {
543
+ background-color: #c4e3f3;
544
+ }
trunk/WCVendors/assets/images/icons/truck.png ADDED
Binary file
trunk/WCVendors/assets/js/front-orders.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ jQuery(function () {
2
+ jQuery('p.custom_tracking_link_field, p.custom_tracking_provider_field').hide();
3
+ jQuery('div.order-comments, div.order-tracking').hide();
4
+
5
+ jQuery('a.order-comments-link, a.order-tracking-link').on('click', function (e) {
6
+ e.preventDefault();
7
+ jQuery(this).next('div').slideToggle();
8
+ });
9
+ });
trunk/WCVendors/assets/js/wcv-admin-quick-edit.js ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(function(){
2
+ jQuery('#the-list').on('click', '.editinline', function(){
3
+
4
+ if (jQuery('.inline-edit-author').length && jQuery('.inline-edit-author-new').length) {
5
+ jQuery('.inline-edit-author').hide();
6
+ jQuery('.inline-edit-author').attr('class', 'inline-edit-author-old');
7
+ jQuery('select[name=post_author]').attr('name', 'post_author-old');
8
+ jQuery('.inline-edit-author-new').attr('class', 'inline-edit-author');
9
+ jQuery('select[name=post_author-new]').attr('name', 'post_author');
10
+ }
11
+
12
+ inlineEditPost.revert();
13
+
14
+ var post_id = jQuery(this).closest('tr').attr('id');
15
+
16
+ post_id = post_id.replace("post-", "");
17
+
18
+ var wcv_inline_data = jQuery('#vendor_' + post_id),
19
+ wc_inline_data = jQuery('#woocommerce_inline_' + post_id );
20
+
21
+ var vendor = wcv_inline_data.find("#_vendor").text();
22
+
23
+ jQuery('select[name="post_author"] option[value="' + vendor + '"]', '.inline-edit-row').attr('selected', 'selected');
24
+
25
+ var product_type = wc_inline_data.find('.product_type').val();
26
+
27
+ if (product_type=='simple' || product_type=='external') {
28
+ jQuery('.vendor', '.inline-edit-row').show();
29
+ } else {
30
+ jQuery('.vendor', '.inline-edit-row').hide();
31
+ }
32
+
33
+ });
34
+ });
trunk/WCVendors/classes/admin/class-admin-page.php ADDED
@@ -0,0 +1,590 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCV_Admin_Setup
4
+ {
5
+ /**
6
+ * WC > Referrals menu
7
+ */
8
+
9
+
10
+ public function __construct()
11
+ {
12
+ add_filter( 'set-screen-option', array( 'WCV_Admin_Setup', 'set_table_option' ), 10, 3 );
13
+ add_action( 'admin_menu', array( 'WCV_Admin_Setup', 'menu' ) );
14
+
15
+ add_action( 'woocommerce_admin_order_data_after_shipping_address', array( $this, 'add_vendor_details' ), 10, 2 );
16
+ add_action( 'woocommerce_admin_order_actions_end', array( $this, 'append_actions' ), 10, 1 );
17
+ }
18
+
19
+
20
+ public function add_vendor_details( $order )
21
+ {
22
+ $actions = $this->append_actions( $order, true );
23
+
24
+ if (empty( $actions['wc_pv_shipped']['name'] )) {
25
+ return;
26
+ }
27
+
28
+ echo '<h4>' . __('Vendors shipped', 'wcvendors') . '</h4><br/>';
29
+ echo $actions['wc_pv_shipped']['name'];
30
+ }
31
+
32
+ public function append_actions( $order, $order_page = false )
33
+ {
34
+ global $woocommerce;
35
+
36
+ $authors = WCV_Vendors::get_vendors_from_order( $order );
37
+ $authors = $authors ? array_keys( $authors ) : array();
38
+ if ( empty( $authors ) ) return false;
39
+
40
+ $shipped = (array) get_post_meta( $order->id, 'wc_pv_shipped', true );
41
+ $string = '</br></br>';
42
+
43
+ foreach ($authors as $author ) {
44
+ $string .= in_array( $author, $shipped ) ? '&#10004; ' : '&#10005; ';
45
+ $string .= WCV_Vendors::get_vendor_shop_name( $author );
46
+ $string .= '</br>';
47
+ }
48
+
49
+ $response = array(
50
+ 'url' => '#',
51
+ 'name' => __('Vendors Shipped', 'wcvendors') . $string,
52
+ 'action' => 'wc_pv_shipped',
53
+ 'image_url' => wcv_assets_url . '/images/icons/truck.png',
54
+ );
55
+
56
+ if ( ! $order_page ) {
57
+ printf( '<a class="button tips %s" href="%s" data-tip="%s"><img style="width:16px;height:16px;" src="%s"></a>', $response['action'], $response['url'], $response['name'], $response['image_url'] );
58
+ } else {
59
+ echo $response['name'];
60
+ }
61
+
62
+ return $response;
63
+ }
64
+
65
+
66
+ /**
67
+ *
68
+ */
69
+ public static function menu()
70
+ {
71
+ $hook = add_submenu_page(
72
+ 'woocommerce',
73
+ __( 'Commission', 'wcvendors' ), __( 'Commission', 'wcvendors' ),
74
+ 'manage_woocommerce',
75
+ 'pv_admin_commissions',
76
+ array( 'WCV_Admin_Setup', 'commissions_page' )
77
+ );
78
+
79
+ add_action( "load-$hook", array( 'WCV_Admin_Setup', 'add_options' ) );
80
+ }
81
+
82
+
83
+ /**
84
+ *
85
+ *
86
+ * @param unknown $status
87
+ * @param unknown $option
88
+ * @param unknown $value
89
+ *
90
+ * @return unknown
91
+ */
92
+ public function set_table_option( $status, $option, $value )
93
+ {
94
+ if ( $option == 'commission_per_page' ) {
95
+ return $value;
96
+ }
97
+ }
98
+
99
+
100
+ /**
101
+ *
102
+ */
103
+ public static function add_options()
104
+ {
105
+ global $PV_Admin_Page;
106
+
107
+ $args = array(
108
+ 'label' => 'Rows',
109
+ 'default' => 10,
110
+ 'option' => 'commission_per_page'
111
+ );
112
+ add_screen_option( 'per_page', $args );
113
+
114
+ $PV_Admin_Page = new WCV_Admin_Page();
115
+
116
+ }
117
+
118
+
119
+ /**
120
+ * HTML setup for the WC > Commission page
121
+ */
122
+ public static function commissions_page()
123
+ {
124
+ global $woocommerce, $PV_Admin_Page;
125
+
126
+ $PV_Admin_Page->prepare_items();
127
+
128
+ ?>
129
+
130
+ <div class="wrap">
131
+
132
+ <div id="icon-woocommerce" class="icon32 icon32-woocommerce-reports"><br/></div>
133
+ <h2><?php _e( 'Commission', 'wcvendors' ); ?></h2>
134
+
135
+ <form id="posts-filter" method="POST">
136
+
137
+ <input type="hidden" name="page" value="pv_admin_commissions"/>
138
+ <?php $PV_Admin_Page->display() ?>
139
+
140
+ </form>
141
+ <div id="ajax-response"></div>
142
+ <br class="clear"/>
143
+ </div>
144
+ <?php
145
+ }
146
+
147
+
148
+ }
149
+
150
+
151
+ if ( !class_exists( 'WP_List_Table' ) ) require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php';
152
+
153
+ /**
154
+ * WC_Simple_Referral_Admin class.
155
+ *
156
+ * @extends WP_List_Table
157
+ */
158
+ class WCV_Admin_Page extends WP_List_Table
159
+ {
160
+
161
+ public $index;
162
+
163
+
164
+ /**
165
+ * __construct function.
166
+ *
167
+ * @access public
168
+ */
169
+ function __construct()
170
+ {
171
+ global $status, $page;
172
+
173
+ $this->index = 0;
174
+
175
+ //Set parent defaults
176
+ parent::__construct( array(
177
+ 'singular' => 'commission',
178
+ 'plural' => 'commissions',
179
+ 'ajax' => false
180
+ ) );
181
+ }
182
+
183
+
184
+ /**
185
+ * column_default function.
186
+ *
187
+ * @access public
188
+ *
189
+ * @param unknown $item
190
+ * @param mixed $column_name
191
+ *
192
+ * @return unknown
193
+ */
194
+ function column_default( $item, $column_name )
195
+ {
196
+ global $wpdb;
197
+
198
+ switch ( $column_name ) {
199
+ case 'id' :
200
+ return $item->id;
201
+ case 'vendor_id' :
202
+ $user = get_userdata( $item->vendor_id );
203
+
204
+ return '<a href="' . admin_url( 'user-edit.php?user_id=' . $item->vendor_id ) . '">' . WCV_Vendors::get_vendor_shop_name( $item->vendor_id ) . '</a>';
205
+ case 'total_due' :
206
+ return woocommerce_price( $item->total_due + $item->total_shipping + $item->tax );
207
+ case 'product_id' :
208
+ $parent = get_post_ancestors( $item->product_id );
209
+ $product_id = $parent ? $parent[ 0 ] : $item->product_id;
210
+ return '<a href="' . admin_url( 'post.php?post=' . $product_id . '&action=edit' ) . '">' . get_the_title( $item->product_id ) . '</a>';
211
+ case 'order_id' :
212
+ return '<a href="' . admin_url( 'post.php?post=' . $item->order_id . '&action=edit' ) . '">' . $item->order_id . '</a>';
213
+ case 'status' :
214
+ return $item->status;
215
+ case 'time' :
216
+ return date_i18n( get_option( 'date_format' ), strtotime( $item->time ) );
217
+ }
218
+ }
219
+
220
+
221
+ /**
222
+ * column_cb function.
223
+ *
224
+ * @access public
225
+ *
226
+ * @param mixed $item
227
+ *
228
+ * @return unknown
229
+ */
230
+ function column_cb( $item )
231
+ {
232
+ return sprintf(
233
+ '<input type="checkbox" name="%1$s[]" value="%2$s" />',
234
+ /*$1%s*/
235
+ 'id',
236
+ /*$2%s*/
237
+ $item->id
238
+ );
239
+ }
240
+
241
+
242
+ /**
243
+ * get_columns function.
244
+ *
245
+ * @access public
246
+ * @return unknown
247
+ */
248
+ function get_columns()
249
+ {
250
+ $columns = array(
251
+ 'cb' => '<input type="checkbox" />',
252
+ 'product_id' => __( 'Product', 'wcvendors' ),
253
+ 'order_id' => __( 'Order ID', 'wcvendors' ),
254
+ 'vendor_id' => __( 'Vendor', 'wcvendors' ),
255
+ 'total_due' => __( 'Total', 'wcvendors' ),
256
+ 'status' => __( 'Status', 'wcvendors' ),
257
+ 'time' => __( 'Date', 'wcvendors' ),
258
+ );
259
+
260
+ return $columns;
261
+ }
262
+
263
+
264
+ /**
265
+ * get_sortable_columns function.
266
+ *
267
+ * @access public
268
+ * @return unknown
269
+ */
270
+ function get_sortable_columns()
271
+ {
272
+ $sortable_columns = array(
273
+ 'time' => array( 'time', true ),
274
+ 'product_id' => array( 'product_id', false ),
275
+ 'order_id' => array( 'order_id', false ),
276
+ 'total_due' => array( 'total_due', false ),
277
+ 'status' => array( 'status', false ),
278
+ 'vendor_id' => array( 'vendor_id', false ),
279
+ 'status' => array( 'status', false ),
280
+ );
281
+
282
+ return $sortable_columns;
283
+ }
284
+
285
+
286
+ /**
287
+ * Get bulk actions
288
+ *
289
+ * @return unknown
290
+ */
291
+ function get_bulk_actions()
292
+ {
293
+ $actions = array(
294
+ 'mark_paid' => __( 'Mark paid', 'wcvendors' ),
295
+ 'mark_due' => __( 'Mark due', 'wcvendors' ),
296
+ 'mark_reversed' => __( 'Mark reversed', 'wcvendors' ),
297
+ // 'delete' => __('Delete', 'wcvendors'),
298
+ );
299
+
300
+ return $actions;
301
+ }
302
+
303
+
304
+ /**
305
+ *
306
+ */
307
+ function extra_tablenav( $which )
308
+ {
309
+ if ( $which == 'top' ) {
310
+ ?>
311
+ <div class="alignleft actions"><?php
312
+ $this->months_dropdown( 'commission' );
313
+ submit_button( __( 'Filter' ), false, false, false, array( 'id' => "post-query-submit", 'name' => 'do-filter' ) );
314
+ ?></div>
315
+ <div class="alignleft actions"><?php
316
+ $this->status_dropdown( 'commission' );
317
+ submit_button( __( 'Filter' ), false, false, false, array( 'id' => "post-query-submit", 'name' => 'do-filter' ) );
318
+ ?></div><?php
319
+ }
320
+ }
321
+
322
+
323
+ /**
324
+ * Display a monthly dropdown for filtering items
325
+ *
326
+ * @since 3.1.0
327
+ * @access protected
328
+ *
329
+ * @param unknown $post_type
330
+ */
331
+ function months_dropdown( $post_type )
332
+ {
333
+ global $wpdb, $wp_locale;
334
+
335
+ $table_name = $wpdb->prefix . "pv_commission";
336
+
337
+ $months = $wpdb->get_results( "
338
+ SELECT DISTINCT YEAR( time ) AS year, MONTH( time ) AS month
339
+ FROM $table_name
340
+ ORDER BY time DESC
341
+ " );
342
+
343
+ $month_count = count( $months );
344
+
345
+ if ( !$month_count || ( 1 == $month_count && 0 == $months[ 0 ]->month ) )
346
+ return;
347
+
348
+ $m = isset( $_POST[ 'm' ] ) ? (int) $_POST[ 'm' ] : 0;
349
+ ?>
350
+ <select name="m">
351
+ <option<?php selected( $m, 0 ); ?> value='0'><?php _e( 'Show all dates' ); ?></option>
352
+ <?php
353
+ foreach ( $months as $arc_row ) {
354
+ if ( 0 == $arc_row->year )
355
+ continue;
356
+
357
+ $month = zeroise( $arc_row->month, 2 );
358
+ $year = $arc_row->year;
359
+
360
+ printf( "<option %s value='%s'>%s</option>\n",
361
+ selected( $m, $year . $month, false ),
362
+ esc_attr( $arc_row->year . $month ),
363
+ /* translators: 1: month name, 2: 4-digit year */
364
+ sprintf( __( '%1$s %2$d' ), $wp_locale->get_month( $month ), $year )
365
+ );
366
+ }
367
+ ?>
368
+ </select>
369
+ <?php
370
+ }
371
+
372
+ /**
373
+ * Display a status dropdown for filtering items
374
+ *
375
+ * @since 3.1.0
376
+ * @access protected
377
+ *
378
+ * @param unknown $post_type
379
+ */
380
+ function status_dropdown( $post_type )
381
+ {
382
+ $com_status = isset( $_POST[ 'com_status' ] ) ? $_POST[ 'com_status' ] : '';
383
+ ?>
384
+ <select name="com_status">
385
+ <option<?php selected( $com_status, '' ); ?> value=''><?php _e( 'Show all Statuses', 'wcvendors' ); ?></option>
386
+ <option<?php selected( $com_status, 'due' ); ?> value="due">Due</option>
387
+ <option<?php selected( $com_status, 'paid' ); ?> value="paid">Paid</option>
388
+ <option<?php selected( $com_status, 'reversed' ); ?> value="reversed">Reversed</option>
389
+ </select>
390
+ <?php
391
+ }
392
+
393
+
394
+ /**
395
+ * Process bulk actions
396
+ *
397
+ * @return unknown
398
+ */
399
+ function process_bulk_action()
400
+ {
401
+ if ( !isset( $_POST[ 'id' ] ) ) return;
402
+
403
+ $items = array_map( 'intval', $_POST[ 'id' ] );
404
+ $ids = implode( ',', $items );
405
+
406
+ switch ( $this->current_action() ) {
407
+ case 'mark_paid':
408
+ $result = $this->mark_paid( $ids );
409
+
410
+ if ( $result )
411
+ echo '<div class="updated"><p>' . __( 'Commission marked paid.', 'wcvendors' ) . '</p></div>';
412
+ break;
413
+
414
+ case 'mark_due':
415
+ $result = $this->mark_due( $ids );
416
+
417
+ if ( $result )
418
+ echo '<div class="updated"><p>' . __( 'Commission marked due.', 'wcvendors' ) . '</p></div>';
419
+ break;
420
+
421
+ case 'mark_reversed':
422
+ $result = $this->mark_reversed( $ids );
423
+
424
+ if ( $result )
425
+ echo '<div class="updated"><p>' . __( 'Commission marked reversed.', 'wcvendors' ) . '</p></div>';
426
+ break;
427
+
428
+ default:
429
+ // code...
430
+ break;
431
+ }
432
+
433
+ }
434
+
435
+
436
+ /**
437
+ *
438
+ *
439
+ * @param unknown $ids (optional)
440
+ *
441
+ * @return unknown
442
+ */
443
+ public function mark_paid( $ids = array() )
444
+ {
445
+ global $wpdb;
446
+
447
+ $table_name = $wpdb->prefix . "pv_commission";
448
+
449
+ $query = "UPDATE `{$table_name}` SET `status` = 'paid' WHERE id IN ($ids) AND `status` = 'due'";
450
+ $result = $wpdb->query( $query );
451
+
452
+ return $result;
453
+ }
454
+
455
+
456
+ /**
457
+ *
458
+ *
459
+ * @param unknown $ids (optional)
460
+ *
461
+ * @return unknown
462
+ */
463
+ public function mark_reversed( $ids = array() )
464
+ {
465
+ global $wpdb;
466
+
467
+ $table_name = $wpdb->prefix . "pv_commission";
468
+
469
+ $query = "UPDATE `{$table_name}` SET `status` = 'reversed' WHERE id IN ($ids) AND `status` = 'due'";
470
+ $result = $wpdb->query( $query );
471
+
472
+ return $result;
473
+ }
474
+
475
+
476
+ /**
477
+ *
478
+ *
479
+ * @param unknown $ids (optional)
480
+ *
481
+ * @return unknown
482
+ */
483
+ public function mark_due( $ids = array() )
484
+ {
485
+ global $wpdb;
486
+
487
+ $table_name = $wpdb->prefix . "pv_commission";
488
+
489
+ $query = "UPDATE `{$table_name}` SET `status` = 'due' WHERE id IN ($ids)";
490
+ $result = $wpdb->query( $query );
491
+
492
+ return $result;
493
+ }
494
+
495
+
496
+ /**
497
+ * prepare_items function.
498
+ *
499
+ * @access public
500
+ */
501
+ function prepare_items()
502
+ {
503
+ global $wpdb;
504
+
505
+ $per_page = $this->get_items_per_page( 'commission_per_page', 10 );
506
+ $current_page = $this->get_pagenum();
507
+
508
+ $orderby = !empty( $_REQUEST[ 'orderby' ] ) ? esc_attr( $_REQUEST[ 'orderby' ] ) : 'time';
509
+ $order = ( !empty( $_REQUEST[ 'order' ] ) && $_REQUEST[ 'order' ] == 'asc' ) ? 'ASC' : 'DESC';
510
+ $com_status = !empty( $_REQUEST[ 'com_status' ] ) ? esc_attr( $_REQUEST[ 'com_status' ] ) : '';
511
+ $status_sql = '';
512
+ $time_sql = '';
513
+
514
+ /**
515
+ * Init column headers
516
+ */
517
+ $this->_column_headers = $this->get_column_info();
518
+
519
+
520
+ /**
521
+ * Process bulk actions
522
+ */
523
+ $this->process_bulk_action();
524
+
525
+ /**
526
+ * Get items
527
+ */
528
+ $sql = "SELECT COUNT(id) FROM {$wpdb->prefix}pv_commission";
529
+
530
+ if ( !empty( $_POST[ 'm' ] ) ) {
531
+ $year = substr( $_POST[ 'm' ], 0, 4 );
532
+ $month = substr( $_POST[ 'm' ], 4, 2 );
533
+
534
+ $time_sql = "
535
+ WHERE MONTH(`time`) = '$month'
536
+ AND YEAR(`time`) = '$year'
537
+ ";
538
+
539
+ $sql .= $time_sql;
540
+ }
541
+
542
+ if ( !empty( $_POST[ 'com_status' ] ) ) {
543
+
544
+ if ( $time_sql == '' ) {
545
+ $status_sql = "
546
+ WHERE status = '$com_status'
547
+ ";
548
+ } else {
549
+ $status_sql = "
550
+ AND status = '$com_status'
551
+ ";
552
+ }
553
+
554
+
555
+ $sql .= $status_sql;
556
+ }
557
+
558
+ $max = $wpdb->get_var( $sql );
559
+
560
+ $sql = "
561
+ SELECT * FROM {$wpdb->prefix}pv_commission
562
+ ";
563
+
564
+ if ( !empty( $_POST[ 'm' ] ) ) {
565
+ $sql .= $time_sql;
566
+ }
567
+
568
+ if ( !empty( $_POST['com_status'] ) ) {
569
+ $sql .= $status_sql;
570
+ }
571
+
572
+ $sql .= "
573
+ ORDER BY `{$orderby}` {$order}
574
+ LIMIT %d, %d
575
+ ";
576
+
577
+ $this->items = $wpdb->get_results( $wpdb->prepare( $sql, ( $current_page - 1 ) * $per_page, $per_page ) );
578
+
579
+ /**
580
+ * Pagination
581
+ */
582
+ $this->set_pagination_args( array(
583
+ 'total_items' => $max,
584
+ 'per_page' => $per_page,
585
+ 'total_pages' => ceil( $max / $per_page )
586
+ ) );
587
+ }
588
+
589
+
590
+ }
trunk/WCVendors/classes/admin/class-admin-reports.php ADDED
@@ -0,0 +1,398 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WCV_Admin_Reports class.
4
+ *
5
+ * Shows reports related to software in the woocommerce backend
6
+ *
7
+ * @author Matt Gates <http://mgates.me>
8
+ * @package
9
+ */
10
+
11
+
12
+ class WCV_Admin_Reports
13
+ {
14
+
15
+
16
+ /**
17
+ * __construct function.
18
+ *
19
+ * @access public
20
+ * @return void
21
+ *
22
+ * @param bool $debug (optional) (default: false)
23
+ */
24
+ function __construct( $debug = false )
25
+ {
26
+ add_filter( 'woocommerce_reports_charts', array( $this, 'reports_tab' ) );
27
+ }
28
+
29
+ /**
30
+ * reports_tab function.
31
+ *
32
+ * @access public
33
+ *
34
+ * @param unknown $reports
35
+ *
36
+ * @return void
37
+ */
38
+ function reports_tab( $reports )
39
+ {
40
+ $reports[ 'vendors' ] = array(
41
+ 'title' => __( 'WC Vendors', 'wcvendors' ),
42
+ 'charts' => array(
43
+ array(
44
+ 'title' => __( 'Overview', 'wcvendors' ),
45
+ 'description' => '',
46
+ 'hide_title' => true,
47
+ 'function' => array( $this, 'sales' ),
48
+ ),
49
+ array(
50
+ 'title' => __( 'Commission by vendor', 'wcvendors' ),
51
+ 'description' => '',
52
+ 'hide_title' => true,
53
+ 'function' => array( $this, 'commission' ),
54
+ ),
55
+ array(
56
+ 'title' => __( 'Commission by product', 'wcvendors' ),
57
+ 'description' => '',
58
+ 'hide_title' => true,
59
+ 'function' => array( $this, 'commission' ),
60
+ ),
61
+ ),
62
+ );
63
+
64
+ return $reports;
65
+ }
66
+
67
+ public function products()
68
+ {
69
+ # code...
70
+ }
71
+
72
+
73
+ /**
74
+ *
75
+ */
76
+ function sales()
77
+ {
78
+ global $start_date, $end_date, $woocommerce, $wpdb;
79
+
80
+ $start_date = !empty( $_POST[ 'start_date' ] ) ? $_POST[ 'start_date' ] : strtotime( date( 'Ymd', strtotime( date( 'Ym', current_time( 'timestamp' ) ) . '01' ) ) );
81
+ $end_date = !empty( $_POST[ 'end_date' ] ) ? $_POST[ 'end_date' ] : strtotime( date( 'Ymd', current_time( 'timestamp' ) ) );
82
+
83
+ if ( !empty( $_POST[ 'start_date' ] ) ) {
84
+ $start_date = strtotime( $_POST[ 'start_date' ] );
85
+ }
86
+
87
+ if ( !empty( $_POST[ 'end_date' ] ) ) {
88
+ $end_date = strtotime( $_POST[ 'end_date' ] );
89
+ }
90
+
91
+ $after = date( 'Y-m-d', $start_date );
92
+ $before = date( 'Y-m-d', strtotime( '+1 day', $end_date ) );
93
+
94
+ $commission_due = $wpdb->get_var( "
95
+ SELECT SUM(total_due + total_shipping + tax) FROM {$wpdb->prefix}pv_commission WHERE status = 'due'
96
+ AND time >= '" . $after . "'
97
+ AND time <= '" . $before . "'
98
+ " );
99
+
100
+ $reversed = $wpdb->get_var( "
101
+ SELECT SUM(total_due + total_shipping + tax) FROM {$wpdb->prefix}pv_commission WHERE status = 'reversed'
102
+ AND time >= '" . $after . "'
103
+ AND time <= '" . $before . "'
104
+ " );
105
+
106
+ $paid = $wpdb->get_var( "
107
+ SELECT SUM(total_due + total_shipping + tax) FROM {$wpdb->prefix}pv_commission WHERE status = 'paid'
108
+ AND time >= '" . $after . "'
109
+ AND time <= '" . $before . "'
110
+ " );
111
+
112
+ ?>
113
+
114
+ <form method="post" action="">
115
+ <p><label for="from"><?php _e( 'From:', 'wcvendors' ); ?></label>
116
+ <input type="text" size="9" placeholder="yyyy-mm-dd" value="<?php echo esc_attr( date( 'Y-m-d', $start_date ) ); ?>" name="start_date" class="range_datepicker from" id="from" />
117
+ <label for="to"><?php _e( 'To:', 'wcvendors' ); ?></label>
118
+ <input type="text" size="9" placeholder="yyyy-mm-dd" value="<?php echo esc_attr( date( 'Y-m-d', $end_date ) ); ?>" name="end_date" class="range_datepicker to" id="to" />
119
+ <input type="submit" class="button" value="<?php _e( 'Show', 'wcvendors' ); ?>"/></p>
120
+ </form>
121
+
122
+ <div id="poststuff" class="woocommerce-reports-wrap">
123
+ <div class="woocommerce-reports-sidebar">
124
+ <div class="postbox">
125
+ <h3><span><?php _e( 'Total paid in range', 'wcvendors' ); ?></span></h3>
126
+
127
+ <div class="inside">
128
+ <p class="stat"><?php if ( $paid > 0 ) echo woocommerce_price( $paid ); else _e( 'n/a', 'wcvendors' ); ?></p>
129
+ </div>
130
+ </div>
131
+ <div class="postbox">
132
+ <h3><span><?php _e( 'Total due in range', 'wcvendors' ); ?></span></h3>
133
+
134
+ <div class="inside">
135
+ <p class="stat"><?php if ( $commission_due > 0 ) echo woocommerce_price( $commission_due ); else _e( 'n/a', 'wcvendors' ); ?></p>
136
+ </div>
137
+ </div>
138
+ <div class="postbox">
139
+ <h3><span><?php _e( 'Total reversed in range', 'wcvendors' ); ?></span></h3>
140
+
141
+ <div class="inside">
142
+ <p class="stat"><?php if ( $reversed > 0 ) echo woocommerce_price( $reversed ); else _e( 'n/a', 'wcvendors' ); ?></p>
143
+ </div>
144
+ </div>
145
+ </div>
146
+
147
+ <div class="woocommerce-reports-main">
148
+ <div class="postbox">
149
+ <h3><span><?php _e( 'Recent Commission', 'wcvendors' ); ?></span></h3>
150
+
151
+ <div>
152
+ <?php
153
+ $commission = $wpdb->get_results( "
154
+ SELECT * FROM {$wpdb->prefix}pv_commission
155
+ WHERE time >= '" . $after . "'
156
+ AND time <= '" . $before . "'
157
+ ORDER BY time DESC
158
+ " );
159
+
160
+ if ( sizeof( $commission ) > 0 ) {
161
+
162
+ ?>
163
+ <div class="woocommerce_order_items_wrapper">
164
+ <table id="commission-table" class="woocommerce_order_items" cellspacing="0">
165
+ <thead>
166
+ <tr>
167
+ <th><?php _e( 'Order', 'wcvendors' ) ?></th>
168
+ <th><?php _e( 'Product', 'wcvendors' ) ?></th>
169
+ <th><?php _e( 'Vendor', 'wcvendors' ) ?></th>
170
+ <th><?php _e( 'Total', 'wcvendors' ) ?></th>
171
+ <th><?php _e( 'Date &amp; Time', 'wcvendors' ) ?></th>
172
+ <th><?php _e( 'Status', 'wcvendors' ) ?></th>
173
+ </tr>
174
+ </thead>
175
+ <tbody>
176
+ <?php $i = 1;
177
+ foreach ( $commission as $row ) : $i++ ?>
178
+ <tr<?php if ( $i % 2 == 1 ) echo ' class="alternate"' ?>>
179
+ <td><?php if ( $row->order_id ) : ?><a
180
+ href="<?php echo admin_url( 'post.php?post=' . $row->order_id . '&action=edit' ); ?>"><?php echo $row->order_id; ?></a><?php else : _e( 'N/A', 'wcvendors' ); endif; ?>
181
+ </td>
182
+ <td><?php echo get_the_title( $row->product_id ); ?></td>
183
+ <td><?php echo WCV_Vendors::get_vendor_shop_name( $row->vendor_id ); ?></td>
184
+ <td><?php echo woocommerce_price( $row->total_due + $row->total_shipping + $row->tax ) ?></td>
185
+ <td><?php echo date( __( 'D j M Y \a\t h:ia', 'wcvendors' ), strtotime( $row->time ) ) ?></td>
186
+ <td><?php echo $row->status ?></td>
187
+ </tr>
188
+ <?php endforeach; ?>
189
+ </tbody>
190
+ </table>
191
+ </div>
192
+ <?php
193
+ } else {
194
+ ?><p><?php _e( 'No commission yet', 'wcvendors' ) ?></p><?php
195
+ }
196
+ ?>
197
+ </div>
198
+ </div>
199
+ </div>
200
+ </div>
201
+ <?php
202
+
203
+ }
204
+
205
+
206
+ /**
207
+ *
208
+ */
209
+ function commission()
210
+ {
211
+ global $start_date, $end_date, $woocommerce, $wpdb;
212
+
213
+ $latest_woo = version_compare( $woocommerce->version, '2.3', '>' );
214
+
215
+ $first_year = $wpdb->get_var( "SELECT time FROM {$wpdb->prefix}pv_commission ORDER BY time ASC LIMIT 1;" );
216
+ $first_year = $first_year ? date( 'Y', strtotime( $first_year ) ) : date( 'Y' );
217
+ $current_year = isset( $_POST[ 'show_year' ] ) ? $_POST[ 'show_year' ] : date( 'Y', current_time( 'timestamp' ) );
218
+ $start_date = strtotime( $current_year . '0101' );
219
+
220
+ $vendors = get_users( array( 'role' => 'vendor' ) );
221
+ $vendors = apply_filters( 'pv_commission_vendors_list', $vendors );
222
+ $selected_vendor = !empty( $_POST[ 'show_vendor' ] ) ? (int) $_POST[ 'show_vendor' ] : false;
223
+ $products = !empty( $_POST[ 'product_ids' ] ) ? (array) $_POST[ 'product_ids' ] : array();
224
+
225
+ ?>
226
+
227
+ <form method="post" action="" class="report_filters">
228
+ <label for="show_year"><?php _e( 'Show:', 'wcvendors' ); ?></label>
229
+ <select name="show_year" id="show_year">
230
+ <?php
231
+ for ( $i = $first_year; $i <= date( 'Y' ); $i++ )
232
+ printf( '<option value="%s" %s>%s</option>', $i, selected( $current_year, $i, false ), $i );
233
+ ?>
234
+ </select>
235
+ <?php if ( $_GET[ 'report' ] == 2 ) {
236
+ if ($latest_woo) { ?>
237
+ <input type="hidden" class="wc-product-search" style="width:203px;" name="product_ids[]" data-placeholder="<?php _e( 'Search for a product&hellip;', 'woocommerce' ); ?>" data-action="woocommerce_json_search_products_and_variations" />
238
+ <?php } else { ?>
239
+ <select id="product_ids" name="product_ids[]" class="ajax_chosen_select_products" multiple="multiple"
240
+ data-placeholder="<?php _e( 'Type in a product name to start searching...', 'wcvendors' ); ?>"
241
+ style="width: 400px;"></select>
242
+ <script type="text/javascript">
243
+ jQuery(function () {
244
+
245
+ // Ajax Chosen Product Selectors
246
+ jQuery("select.ajax_chosen_select_products").ajaxChosen({
247
+ method: 'GET',
248
+ url: '<?php echo admin_url('admin-ajax.php'); ?>',
249
+ dataType: 'json',
250
+ afterTypeDelay: 100,
251
+ data: {
252
+ action: 'woocommerce_json_search_products',
253
+ security: '<?php echo wp_create_nonce("search-products"); ?>'
254
+ }
255
+ }, function (data) {
256
+
257
+ var terms = {};
258
+
259
+ jQuery.each(data, function (i, val) {
260
+ terms[i] = val;
261
+ });
262
+
263
+ return terms;
264
+ });
265
+
266
+ });
267
+ </script>
268
+
269
+ <?php }
270
+ } else { ?>
271
+ <select class="chosen_select" id="show_vendor" name="show_vendor" style="width: 300px;"
272
+ data-placeholder="<?php _e( 'Select a vendor&hellip;', 'wcvendors' ); ?>">
273
+ <option></option>
274
+ <?php foreach ( $vendors as $key => $vendor ) printf( '<option value="%s" %s>%s</option>', $vendor->ID, selected( $selected_vendor, $vendor->ID, false ), $vendor->display_name ); ?>
275
+ </select>
276
+ <?php } ?>
277
+ <input type="submit" class="button" value="<?php _e( 'Show', 'wcvendors' ); ?>"/>
278
+ </form>
279
+
280
+ <?php
281
+
282
+ if ( !empty( $selected_vendor ) || !empty( $products ) ) {
283
+
284
+ foreach ($products as $key => $product_id) {
285
+ $_product = get_product($product_id);
286
+ $childs = $_product->get_children();
287
+ $products = array_merge($childs, $products);
288
+ }
289
+
290
+ $commissions = array();
291
+ $filter = !empty( $selected_vendor ) ? (" WHERE vendor_id = " . $selected_vendor) : (" WHERE product_id IN ( " . implode( ', ', $products ) ." )");
292
+
293
+ $sql = "SELECT
294
+ SUM(total_due + total_shipping + tax) as total,
295
+ SUM(total_due) as commission,
296
+ SUM(total_shipping) as shipping,
297
+ SUM(tax) as tax
298
+ FROM {$wpdb->prefix}pv_commission
299
+ ";
300
+
301
+ $paid_sql = "SELECT SUM(total_due + total_shipping + tax) FROM {$wpdb->prefix}pv_commission " . $filter . " AND status = 'paid'";
302
+ $reversed_sql = "SELECT SUM(total_due + total_shipping + tax) FROM {$wpdb->prefix}pv_commission" . $filter . " AND status = 'reversed'";
303
+ $date_sql = " AND date_format(`time`,'%%Y%%m') = %d";
304
+
305
+ for ( $count = 0; $count < 12; $count++ ) {
306
+ $time = strtotime( date( 'Ym', strtotime( '+ ' . $count . ' MONTH', $start_date ) ) . '01' );
307
+ if ( $time > current_time( 'timestamp' ) ) continue;
308
+
309
+ $month = date( 'Ym', strtotime( date( 'Ym', strtotime( '+ ' . $count . ' MONTH', $start_date ) ) . '01' ) );
310
+
311
+ $fetch_results = $wpdb->prepare( $sql . $filter . $date_sql, $month );
312
+
313
+ $results = $wpdb->get_results( $fetch_results );
314
+ if ( !empty( $results[ 0 ] ) ) {
315
+ extract( get_object_vars( $results[ 0 ] ) );
316
+ }
317
+
318
+ $paid = $wpdb->get_var( $wpdb->prepare( $paid_sql . $date_sql, $month ) );
319
+ $reversed = $wpdb->get_var( $wpdb->prepare( $reversed_sql . $date_sql, $month ) );
320
+
321
+ $commissions[ date( 'M', strtotime( $month . '01' ) ) ] = array(
322
+ 'commission' => $commission,
323
+ 'tax' => $tax,
324
+ 'shipping' => $shipping,
325
+ 'reversed' => $reversed,
326
+ 'paid' => $paid,
327
+ 'total' => $total - $reversed - $paid,
328
+ );
329
+
330
+ }
331
+
332
+ ?>
333
+
334
+ <div class="woocommerce-reports-main">
335
+ <table class="widefat">
336
+ <thead>
337
+ <tr>
338
+ <th><?php _e( 'Month', 'wcvendors' ); ?></th>
339
+ <th class="total_row"><?php _e( 'Commission', 'wcvendors' ); ?></th>
340
+ <th class="total_row"><?php _e( 'Tax', 'wcvendors' ); ?></th>
341
+ <th class="total_row"><?php _e( 'Shipping', 'wcvendors' ); ?></th>
342
+ <th class="total_row"><?php _e( 'Reversed', 'wcvendors' ); ?></th>
343
+ <th class="total_row"><?php _e( 'Paid', 'wcvendors' ); ?></th>
344
+ <th class="total_row"><b><?php _e( 'Total', 'wcvendors' ); ?></th>
345
+ </tr>
346
+ </thead>
347
+ <tfoot>
348
+ <tr>
349
+ <?php
350
+ $total = array(
351
+ 'commission' => 0,
352
+ 'tax' => 0,
353
+ 'shipping' => 0,
354
+ 'reversed' => 0,
355
+ 'paid' => 0,
356
+ 'total' => 0,
357
+ );
358
+
359
+ foreach ( $commissions as $month => $commission ) {
360
+ $total[ 'commission' ] += $commission[ 'commission' ];
361
+ $total[ 'tax' ] += $commission[ 'tax' ];
362
+ $total[ 'shipping' ] += $commission[ 'shipping' ];
363
+ $total[ 'reversed' ] += $commission[ 'reversed' ];
364
+ $total[ 'paid' ] += $commission[ 'paid' ];
365
+ $total[ 'total' ] += $commission[ 'total' ];
366
+ }
367
+
368
+ echo '<td>' . __( 'Total', 'wcvendors' ) . '</td>';
369
+
370
+ foreach ( $total as $value ) {
371
+ echo '<td class="total_row">' . woocommerce_price( $value ) . '</td>';
372
+ }
373
+ ?>
374
+ </tr>
375
+ </tfoot>
376
+ <tbody>
377
+ <?php
378
+ foreach ( $commissions as $month => $commission ) {
379
+ $alt = ( isset( $alt ) && $alt == 'alt' ) ? '' : 'alt';
380
+
381
+ echo '<tr class="' . $alt . '"><td>' . $month . '</td>';
382
+
383
+ foreach ( $commission as $value ) {
384
+ echo '<td class="total_row">' . woocommerce_price( $value ) . '</td>';
385
+ }
386
+
387
+ echo '</tr>';
388
+ }
389
+ ?>
390
+ </tbody>
391
+ </table>
392
+ </div>
393
+
394
+ <?php } ?>
395
+ <?php
396
+
397
+ }
398
+ }
trunk/WCVendors/classes/admin/class-admin-users.php ADDED
@@ -0,0 +1,411 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * WP-Admin users page
5
+ *
6
+ * @author Matt Gates <http://mgates.me>
7
+ * @package ProductVendor
8
+ */
9
+
10
+
11
+ class WCV_Admin_Users
12
+ {
13
+
14
+
15
+ /**
16
+ * Constructor
17
+ */
18
+ function __construct()
19
+ {
20
+ if ( !is_admin() ) return;
21
+
22
+ add_action( 'edit_user_profile', array( $this, 'show_extra_profile_fields' ) );
23
+ add_action( 'edit_user_profile_update', array( $this, 'save_extra_profile_fields' ) );
24
+
25
+ add_filter( 'add_menu_classes', array( $this, 'show_pending_number' ) );
26
+
27
+ // Disabling non-vendor related items on the admin screens
28
+ if ( WCV_Vendors::is_vendor( get_current_user_id() ) ) {
29
+ add_filter( 'woocommerce_csv_product_role', array( $this, 'csv_import_suite_compatibility' ) );
30
+ add_filter( 'woocommerce_csv_product_export_args', array( $this, 'csv_import_suite_compatibility_export' ) );
31
+
32
+ // Admin page lockdown
33
+ remove_action( 'admin_init', 'woocommerce_prevent_admin_access' );
34
+ add_action( 'admin_init', array( $this, 'prevent_admin_access' ) );
35
+
36
+ add_filter( 'woocommerce_prevent_admin_access', array( $this, 'deny_admin_access' ) );
37
+
38
+
39
+ // WC > Product page fixes
40
+ add_action( 'load-post-new.php', array( $this, 'confirm_access_to_add' ) );
41
+ add_action( 'load-edit.php', array( $this, 'edit_nonvendors' ) );
42
+ add_filter( 'views_edit-product', array( $this, 'hide_nonvendor_links' ) );
43
+
44
+ add_action( 'pre_get_posts', array( $this, 'users_own_attachments' ) );
45
+ add_action( 'admin_menu', array( $this, 'remove_menu_page' ), 99 );
46
+ add_action( 'add_meta_boxes', array( $this, 'remove_meta_boxes' ), 99 );
47
+ add_filter( 'product_type_selector', array( $this, 'filter_product_types' ), 99, 2 );
48
+ add_filter( 'product_type_options', array( $this, 'filter_product_type_options' ), 99 );
49
+
50
+ add_filter( 'woocommerce_duplicate_product_capability', array( $this, 'add_duplicate_capability' ) );
51
+
52
+ // WC > Product featured
53
+ $product_misc = (array) WC_Vendors::$pv_options->get_option( 'hide_product_misc' );
54
+ if ($product_misc['featured']) {
55
+
56
+ add_filter( 'manage_edit-product_columns', array($this, 'manage_product_columns'), 99);
57
+ }
58
+
59
+ }
60
+
61
+ }
62
+
63
+ public function confirm_access_to_add()
64
+ {
65
+ if ( empty( $_GET['post_type'] ) || $_GET['post_type'] != 'product' ) {
66
+ return;
67
+ }
68
+
69
+ $can_submit = WC_Vendors::$pv_options->get_option( 'can_submit_products' );
70
+ if ( !$can_submit ) {
71
+ wp_die( 'You are not allowed to submit products.' );
72
+ }
73
+ }
74
+
75
+ // public function get_terms_filter( $terms, $tax, $args )
76
+ // {
77
+ // if ( $tax[0] != 'product_type' || ( $tax[0] == 'product_type' && ! empty( $args['include'] ) ) ) {
78
+ // return $terms;
79
+ // }
80
+
81
+ // $products = WCV_Vendors::get_vendor_products( get_current_user_id() );
82
+ // $ids = array();
83
+ // foreach ( $products as $product ) {
84
+ // $ids[ ] = ( $product->ID );
85
+ // $product = get_product( $product )->product_type;
86
+ // var_dump($product);exit;
87
+ // }
88
+
89
+ // $args['include'] = $ids;
90
+
91
+ // var_dump($terms);exit;
92
+
93
+ // $terms = get_terms( $tax[0], $args);
94
+
95
+
96
+ // return $terms;
97
+ // }
98
+
99
+ public function csv_import_suite_compatibility( $capability )
100
+ {
101
+ return 'manage_product';
102
+ }
103
+
104
+ public function csv_import_suite_compatibility_export( $args )
105
+ {
106
+ $args[ 'author' ] = get_current_user_id();
107
+
108
+ return $args;
109
+ }
110
+
111
+ public function add_duplicate_capability( $capability )
112
+ {
113
+ return 'manage_product';
114
+ }
115
+
116
+
117
+ /**
118
+ *
119
+ *
120
+ * @param unknown $menu
121
+ *
122
+ * @return unknown
123
+ */
124
+ public function show_pending_number( $menu )
125
+ {
126
+ $num_posts = wp_count_posts( 'product', 'readable' );
127
+
128
+ $pending_count = !empty( $num_posts->pending ) ? $num_posts->pending : 0;
129
+ $menu_str = 'edit.php?post_type=product';
130
+
131
+ foreach ( $menu as $menu_key => $menu_data ) {
132
+ if ( $menu_str != $menu_data[ 2 ] ) continue;
133
+ $menu[ $menu_key ][ 0 ] .= " <span class='update-plugins count-$pending_count'><span class='plugin-count'>" . number_format_i18n( $pending_count ) . '</span></span>';
134
+ }
135
+
136
+ return $menu;
137
+ }
138
+
139
+
140
+ /**
141
+ *
142
+ *
143
+ * @param unknown $types
144
+ * @param unknown $product_type
145
+ *
146
+ * @return unknown
147
+ */
148
+ function filter_product_types( $types, $product_type )
149
+ {
150
+ $product_panel = (array) WC_Vendors::$pv_options->get_option( 'hide_product_panel' );
151
+ $product_misc = (array) WC_Vendors::$pv_options->get_option( 'hide_product_misc' );
152
+ $product_types = (array) WC_Vendors::$pv_options->get_option( 'hide_product_types' );
153
+ $css = WC_Vendors::$pv_options->get_option( 'product_page_css' );
154
+ $count = 0;
155
+
156
+ foreach ( $product_panel as $key => $value ) {
157
+ if ( $value ) $css .= sprintf( '.%s_tab{display:none !important;}', $key );
158
+ }
159
+
160
+ if ( !empty( $product_misc[ 'taxes' ] ) ) {
161
+ $css .= '.form-field._tax_status_field, .form-field._tax_class_field{display:none !important;}';
162
+ }
163
+
164
+ unset( $product_misc[ 'taxes' ] );
165
+
166
+ foreach ( $product_misc as $key => $value ) {
167
+ if ( $value ) $css .= sprintf( '._%s_field{display:none !important;}', $key );
168
+ }
169
+
170
+ foreach ( $product_types as $value ) {
171
+ if ( !$value ) $count++;
172
+ }
173
+
174
+ if ( $count === 1 ) {
175
+ $css .= '#product-type{display:none !important;}';
176
+ }
177
+
178
+ echo '<style>';
179
+ echo $css;
180
+ echo '</style>';
181
+
182
+ foreach ( $types as $key => $value ) {
183
+ if ( !empty( $product_types[ $key ] ) ) {
184
+ unset( $types[ $key ] );
185
+ }
186
+ }
187
+
188
+ return $types;
189
+ }
190
+
191
+
192
+ /**
193
+ *
194
+ *
195
+ * @param unknown $types
196
+ *
197
+ * @return unknown
198
+ */
199
+ function filter_product_type_options( $types )
200
+ {
201
+ $product_options = WC_Vendors::$pv_options->get_option( 'hide_product_type_options' );
202
+
203
+ if ( !$product_options ) return $types;
204
+
205
+ foreach ( $types as $key => $value ) {
206
+ if ( !empty( $product_options[ $key ] ) ) {
207
+ unset( $types[ $key ] );
208
+ }
209
+ }
210
+
211
+ return $types;
212
+ }
213
+
214
+
215
+ /**
216
+ * Show attachments only belonging to vendor
217
+ *
218
+ * @param object $wp_query_obj
219
+ */
220
+ function users_own_attachments( $wp_query_obj )
221
+ {
222
+ global $current_user, $pagenow;
223
+
224
+ if ( $pagenow == 'upload.php' || ( $pagenow == 'admin-ajax.php' && !empty( $_POST[ 'action' ] ) && $_POST[ 'action' ] == 'query-attachments' ) ) {
225
+ $wp_query_obj->set( 'author', $current_user->ID );
226
+ }
227
+ }
228
+
229
+
230
+ /**
231
+ * Allow vendors to access admin when disabled
232
+ */
233
+ public function prevent_admin_access()
234
+ {
235
+ $permitted_user = ( current_user_can( 'edit_posts' ) || current_user_can( 'manage_woocommerce' ) || current_user_can( 'vendor' ) );
236
+
237
+ if ( get_option( 'woocommerce_lock_down_admin' ) == 'yes' && !is_ajax() && !$permitted_user ) {
238
+ wp_safe_redirect( get_permalink( woocommerce_get_page_id( 'myaccount' ) ) );
239
+ exit;
240
+ }
241
+ }
242
+
243
+ public function deny_admin_access()
244
+ {
245
+ return false;
246
+ }
247
+
248
+
249
+ /**
250
+ * Request when load-edit.php
251
+ */
252
+ public function edit_nonvendors()
253
+ {
254
+ add_action( 'request', array( $this, 'hide_nonvendor_products' ) );
255
+ }
256
+
257
+
258
+ /**
259
+ * Hide links that don't matter anymore from vendors
260
+ *
261
+ * @param array $views
262
+ *
263
+ * @return array
264
+ */
265
+ public function hide_nonvendor_links( $views )
266
+ {
267
+ return array();
268
+ }
269
+
270
+
271
+ /**
272
+ * Hide products that don't belong to the vendor
273
+ *
274
+ * @param array $query_vars
275
+ *
276
+ * @return array
277
+ */
278
+ public function hide_nonvendor_products( $query_vars )
279
+ {
280
+ $query_vars[ 'author' ] = get_current_user_id();
281
+
282
+ return $query_vars;
283
+ }
284
+
285
+
286
+ /**
287
+ * Remove the media library menu
288
+ */
289
+ public function remove_menu_page()
290
+ {
291
+ global $pagenow, $woocommerce;
292
+
293
+ remove_menu_page( 'index.php' ); /* Hides Dashboard menu */
294
+ remove_menu_page( 'separator1' ); /* Hides separator under Dashboard menu*/
295
+ remove_all_actions( 'admin_notices' );
296
+
297
+ if ( $pagenow == 'index.php' ) {
298
+ wp_redirect( admin_url( 'profile.php' ) );
299
+ }
300
+ }
301
+
302
+
303
+ /**
304
+ *
305
+ */
306
+ public function remove_meta_boxes()
307
+ {
308
+ remove_meta_box( 'postcustom', 'product', 'normal' );
309
+ remove_meta_box( 'wpseo_meta', 'product', 'normal' );
310
+ remove_meta_box( 'expirationdatediv', 'product', 'side' );
311
+ }
312
+
313
+
314
+ /**
315
+ * Update the vendor PayPal email
316
+ *
317
+ * @param int $vendor_id
318
+ *
319
+ * @return bool
320
+ */
321
+ public function save_extra_profile_fields( $vendor_id )
322
+ {
323
+ if ( !current_user_can( 'edit_user', $vendor_id ) ) return false;
324
+
325
+ $users = get_users( array( 'meta_key' => 'pv_shop_slug', 'meta_value' => sanitize_title( $_POST[ 'pv_shop_name' ] ) ) );
326
+ if ( empty( $users ) || $users[ 0 ]->ID == $vendor_id ) {
327
+ update_user_meta( $vendor_id, 'pv_shop_name', $_POST[ 'pv_shop_name' ] );
328
+ update_user_meta( $vendor_id, 'pv_shop_slug', sanitize_title( $_POST[ 'pv_shop_name' ] ) );
329
+ }
330
+
331
+ update_user_meta( $vendor_id, 'pv_paypal', $_POST[ 'pv_paypal' ] );
332
+ update_user_meta( $vendor_id, 'pv_shop_html_enabled', isset( $_POST[ 'pv_shop_html_enabled' ] ) );
333
+ update_user_meta( $vendor_id, 'pv_custom_commission_rate', $_POST[ 'pv_custom_commission_rate' ] );
334
+ update_user_meta( $vendor_id, 'pv_shop_description', $_POST[ 'pv_shop_description' ] );
335
+ update_user_meta( $vendor_id, 'pv_seller_info', $_POST[ 'pv_seller_info' ] );
336
+
337
+ do_action( 'wcvendors_update_admin_user', $vendor_id );
338
+ }
339
+
340
+
341
+ /**
342
+ * Show the PayPal field and commision due table
343
+ *
344
+ * @param unknown $user
345
+ */
346
+ public function show_extra_profile_fields( $user )
347
+ {
348
+ ?>
349
+ <h3><?php _e( 'WC Vendors', 'wcvendors' ); ?></h3>
350
+ <table class="form-table">
351
+ <tbody>
352
+ <?php do_action( 'wcvendors_admin_before_shop_html', $user ); ?>
353
+ <tr>
354
+ <th scope="row">Shop HTML</th>
355
+ <td>
356
+ <label for="pv_shop_html_enabled">
357
+ <input name="pv_shop_html_enabled" type="checkbox"
358
+ id="pv_shop_html_enabled" <?php checked( true, get_user_meta( $user->ID, 'pv_shop_html_enabled', true ), $echo = true ) ?>/>
359
+ <?php _e( 'Enable HTML for the shop description', 'wcvendors' ); ?>
360
+ </label>
361
+ </td>
362
+ </tr>
363
+ <?php do_action( 'wcvendors_admin_after_shop_html', $user ); ?>
364
+ <tr>
365
+ <th><label for="pv_shop_name"><?php _e( 'Shop name', 'wcvendors' ); ?></label></th>
366
+ <td><input type="text" name="pv_shop_name" id="pv_shop_name"
367
+ value="<?php echo get_user_meta( $user->ID, 'pv_shop_name', true ); ?>" class="regular-text">
368
+ </td>
369
+ </tr>
370
+ <?php do_action( 'wcvendors_admin_after_shop_name', $user ); ?>
371
+ <tr>
372
+ <th><label for="pv_paypal"><?php _e( 'PayPal E-mail', 'wcvendors' ); ?> <span
373
+ class="description">(<?php _e( 'required', 'wcvendors' ); ?>)</span></label></th>
374
+ <td><input type="email" name="pv_paypal" id="pv_paypal"
375
+ value="<?php echo get_user_meta( $user->ID, 'pv_paypal', true ); ?>" class="regular-text">
376
+ </td>
377
+ </tr>
378
+ <?php do_action( 'wcvendors_admin_after_paypal', $user ); ?>
379
+ <tr>
380
+ <th><label for="pv_custom_commission_rate"><?php _e( 'Commission rate', 'wcvendors' ); ?> (%)</label></th>
381
+ <td><input type="number" step="0.01" max="100" min="0" name="pv_custom_commission_rate" placeholder="<?php _e( 'Leave blank for default', 'wcvendors' ); ?>" id="pv_custom_commission_rate"
382
+ value="<?php echo get_user_meta( $user->ID, 'pv_custom_commission_rate', true ); ?>" class="regular-text">
383
+ </td>
384
+ </tr>
385
+ <?php do_action( 'wcvendors_admin_after_commission_due', $user ); ?>
386
+ <tr>
387
+ <th><label for="pv_seller_info"><?php _e( 'Seller info', 'wcvendors' ); ?></label></th>
388
+ <td><?php wp_editor( get_user_meta( $user->ID, 'pv_seller_info', true ), 'pv_seller_info' ); ?></td>
389
+ </tr>
390
+ <?php do_action( 'wcvendors_admin_after_seller_info', $user ); ?>
391
+ <tr>
392
+ <th><label for="pv_shop_description"><?php _e( 'Shop description', 'wcvendors' ); ?></label>
393
+ </th>
394
+ <td><?php wp_editor( get_user_meta( $user->ID, 'pv_shop_description', true ), 'pv_shop_description' ); ?></td>
395
+ </tr>
396
+ <?php do_action( 'wcvendors_admin_after_shop_description', $user ); ?>
397
+ </tbody>
398
+ </table>
399
+ <?php
400
+ }
401
+
402
+ /*
403
+ Remove featured check box from the product listing
404
+ */
405
+ public function manage_product_columns( $columns ){
406
+ global $woocommerce;
407
+ unset($columns['featured']);
408
+ return $columns;
409
+ }
410
+
411
+ }
trunk/WCVendors/classes/admin/class-product-meta.php ADDED
@@ -0,0 +1,264 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Product meta configurations
5
+ *
6
+ * @package ProductVendor
7
+ */
8
+
9
+
10
+ class WCV_Product_Meta
11
+ {
12
+
13
+
14
+ /**
15
+ * Constructor
16
+ */
17
+ function __construct()
18
+ {
19
+ if ( !current_user_can( 'manage_woocommerce' ) ) return;
20
+
21
+ // Allow products to have authors
22
+ add_post_type_support( 'product', 'author' );
23
+
24
+ add_action( 'add_meta_boxes', array( $this, 'change_author_meta_box_title' ) );
25
+ add_action( 'wp_dropdown_users', array( $this, 'author_vendor_roles' ), 0, 1 );
26
+ add_action( 'woocommerce_product_write_panel_tabs', array( $this, 'add_tab' ) );
27
+ add_action( 'woocommerce_product_write_panels', array( $this, 'add_panel' ) );
28
+ add_action( 'woocommerce_process_product_meta', array( $this, 'save_panel' ) );
29
+
30
+ add_action( 'woocommerce_product_quick_edit_end', array($this, 'display_vendor_dd_quick_edit') );
31
+ add_action( 'woocommerce_product_quick_edit_save', array($this, 'save_vendor_quick_edit'), 2, 99 );
32
+ add_action( 'manage_product_posts_custom_column', array($this, 'display_vendor_column'), 2, 99 );
33
+ add_filter( 'manage_product_posts_columns', array($this, 'vendor_column_quickedit') );
34
+
35
+ }
36
+
37
+
38
+ /**
39
+ * Change the "Author" metabox to "Vendor"
40
+ */
41
+ public function change_author_meta_box_title()
42
+ {
43
+ global $wp_meta_boxes;
44
+ $wp_meta_boxes[ 'product' ][ 'normal' ][ 'core' ][ 'authordiv' ][ 'title' ] = __( 'Vendor', 'wcvendors' );;
45
+ }
46
+
47
+
48
+ /**
49
+ * Override the authors selectbox with +vendor roles
50
+ *
51
+ * @param html $output
52
+ *
53
+ * @return html
54
+ */
55
+ public function author_vendor_roles( $output )
56
+ {
57
+ global $post;
58
+
59
+ if ( empty( $post ) ) return $output;
60
+
61
+ // Return if this isn't a WooCommerce product post type
62
+ if ( $post->post_type != 'product' ) return $output;
63
+
64
+ // Return if this isn't the vendor author override dropdown
65
+ if ( !strpos( $output, 'post_author_override' ) ) return $output;
66
+
67
+ $args = array(
68
+ 'selected' => $post->post_author,
69
+ 'id' => 'post_author_override',
70
+ );
71
+
72
+ $output = $this->vendor_selectbox( $args );
73
+
74
+ return $output;
75
+ }
76
+
77
+
78
+ /**
79
+ * Create a selectbox to display vendor & administrator roles
80
+ *
81
+ * @param array $args
82
+ *
83
+ * @return html
84
+ */
85
+ public function vendor_selectbox( $args )
86
+ {
87
+ $default_args = array(
88
+ 'placeholder',
89
+ 'id',
90
+ 'class',
91
+ );
92
+
93
+ foreach ( $default_args as $key ) {
94
+ if ( !is_array( $key ) && empty( $args[ $key ] ) ) $args[ $key ] = '';
95
+ else if ( is_array( $key ) ) foreach ( $key as $val ) $args[ $key ][ $val ] = esc_attr( $args[ $key ][ $val ] );
96
+ }
97
+ extract( $args );
98
+
99
+ $roles = array( 'vendor', 'administrator' );
100
+ $user_args = array( 'fields' => array( 'ID', 'user_login' ) );
101
+
102
+ $output = "<select style='width:200px;' name='$id' id='$id' class='$class' data-placeholder='$placeholder'>\n";
103
+ $output .= "\t<option value=''></option>\n";
104
+
105
+ foreach ( $roles as $role ) {
106
+
107
+ $new_args = $user_args;
108
+ $new_args[ 'role' ] = $role;
109
+ $users = get_users( $new_args );
110
+
111
+ if ( empty( $users ) ) continue;
112
+ foreach ( (array) $users as $user ) {
113
+ $select = selected( $user->ID, $selected, false );
114
+ $output .= "\t<option value='$user->ID' $select>$user->user_login</option>\n";
115
+ }
116
+
117
+ }
118
+ $output .= "</select>";
119
+
120
+ // Convert this selectbox with jQuery Chosen
121
+ $output .= '<script type="text/javascript">jQuery(function() {jQuery("#' . $id . '").chosen();});</script>';
122
+
123
+ return $output;
124
+ }
125
+
126
+
127
+ /**
128
+ * Save commission rate of a product
129
+ *
130
+ * @param int $post_id
131
+ */
132
+ public function save_panel( $post_id )
133
+ {
134
+ if ( isset( $_POST[ 'pv_commission_rate' ] ) ) {
135
+ update_post_meta( $post_id, 'pv_commission_rate', is_numeric( $_POST[ 'pv_commission_rate' ] ) ? (float) $_POST[ 'pv_commission_rate' ] : false );
136
+ }
137
+
138
+ }
139
+
140
+
141
+ /**
142
+ * Add the Commission tab to a product
143
+ */
144
+ public function add_tab()
145
+ {
146
+ ?>
147
+ <li class="commission_tab">
148
+ <a href="#commission"><?php _e( 'Commission', 'wcvendors' ) ?></a>
149
+ </li> <?php
150
+ }
151
+
152
+
153
+ /**
154
+ * Add the Commission panel to a product
155
+ */
156
+ public function add_panel()
157
+ {
158
+ global $post; ?>
159
+
160
+ <div id="commission" class="panel woocommerce_options_panel">
161
+ <fieldset>
162
+
163
+ <p class='form-field commission_rate_field'>
164
+ <label for='pv_commission_rate'><?php _e( 'Commission', 'wcvendors' ); ?> (%)</label>
165
+ <input type='number' id='pv_commission_rate'
166
+ name='pv_commission_rate'
167
+ class='short'
168
+ max="100"
169
+ min="0"
170
+ step='any'
171
+ placeholder='<?php _e( 'Leave blank for default', 'wcvendors' ); ?>'
172
+ value="<?php echo get_post_meta( $post->ID, 'pv_commission_rate', true ); ?>"/>
173
+ </p>
174
+
175
+ </fieldset>
176
+ </div> <?php
177
+
178
+ }
179
+
180
+ /*
181
+ * Rename the Authors column to Vendor on products page
182
+ */
183
+ public function vendor_column_quickedit($posts_columns) {
184
+ $posts_columns['author'] = __( 'Vendor', 'wcvendors' );
185
+
186
+ return $posts_columns;
187
+ }
188
+
189
+ /*
190
+ * Display the vendor drop down on the quick edit screen
191
+ */
192
+ public function display_vendor_dd_quick_edit() {
193
+
194
+ global $post;
195
+ $selected = $post->post_author;
196
+
197
+ $roles = array( 'vendor', 'administrator' );
198
+ $user_args = array( 'fields' => array( 'ID', 'display_name' ) );
199
+
200
+ $output = "<select style='width:200px;' name='post_author-new' class='select'>\n";
201
+
202
+ foreach ( $roles as $role ) {
203
+
204
+ $new_args = $user_args;
205
+ $new_args[ 'role' ] = $role;
206
+ $users = get_users( $new_args );
207
+
208
+ if ( empty( $users ) ) continue;
209
+ foreach ( (array) $users as $user ) {
210
+ $select = selected( $user->ID, $selected, false );
211
+ $output .= "\t<option value='$user->ID' $select>$user->display_name</option>\n";
212
+ }
213
+
214
+ }
215
+ $output .= "</select>";
216
+
217
+ ?>
218
+ <br class="clear" />
219
+ <label class="inline-edit-author-new">
220
+ <span class="title"><?php _e('Vendor', 'wcvendors' ); ?></span>
221
+ <?php echo $output; ?>
222
+ </label>
223
+ <?php
224
+ }
225
+
226
+
227
+ /*
228
+ * Save the vendor on the quick edit screen
229
+ */
230
+ public function save_vendor_quick_edit( $product ) {
231
+
232
+ if ( $product->is_type('simple') || $product->is_type('external') ) {
233
+ if ( isset( $_REQUEST['_vendor'] ) ) {
234
+ $vendor = wc_clean($_REQUEST['_vendor']);
235
+ $product->post->post_author = $vendor;
236
+ }
237
+ }
238
+ return $product;
239
+ }
240
+
241
+ /*
242
+ * Display hidden column data for js
243
+ */
244
+ public function display_vendor_column( $column, $post_id ){
245
+
246
+ $vendor = get_post_field( 'post_author', $post_id );
247
+
248
+ switch ( $column ) {
249
+ case 'name' :
250
+
251
+ ?>
252
+ <div class="hidden vendor" id="vendor_<?php echo $post_id; ?>">
253
+ <div id="post_author"><?php echo $vendor; ?></div>
254
+ </div>
255
+ <?php
256
+
257
+ break;
258
+
259
+ default :
260
+ break;
261
+ }
262
+
263
+ }
264
+ }
trunk/WCVendors/classes/admin/class-vendor-applicants.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ *
5
+ */
6
+ class WCV_Vendor_Applicants
7
+ {
8
+
9
+ function __construct()
10
+ {
11
+ add_filter( 'user_row_actions', array( $this, 'user_row_actions' ), 10, 2 );
12
+ add_filter( 'load-users.php', array( $this, 'user_row_actions_commit' ) );
13
+ }
14
+
15
+ /**
16
+ *
17
+ *
18
+ * @param unknown $actions
19
+ * @param unknown $user_object
20
+ *
21
+ * @return unknown
22
+ */
23
+ function user_row_actions( $actions, $user_object )
24
+ {
25
+ if ( !empty( $_GET[ 'role' ] ) && $_GET[ 'role' ] == 'pending_vendor' ) {
26
+ $actions[ 'approve_vendor' ] = "<a href='?role=pending_vendor&action=approve_vendor&user_id=" . $user_object->ID . "'>" . __( 'Approve', 'cgc_ub' ) . "</a>";
27
+ $actions[ 'deny_vendor' ] = "<a href='?role=pending_vendor&action=deny_vendor&user_id=" . $user_object->ID . "'>" . __( 'Deny', 'cgc_ub' ) . "</a>";
28
+ }
29
+
30
+ return $actions;
31
+ }
32
+
33
+
34
+ /**
35
+ *
36
+ */
37
+ public function user_row_actions_commit()
38
+ {
39
+ if ( !empty( $_GET[ 'action' ] ) && !empty( $_GET[ 'user_id' ] ) ) {
40
+
41
+ $wp_user_object = new WP_User( (int) $_GET[ 'user_id' ] );
42
+
43
+ switch ( $_GET[ 'action' ] ) {
44
+ case 'approve_vendor':
45
+ $role = 'vendor';
46
+ add_action( 'admin_notices', array( $this, 'approved' ) );
47
+ break;
48
+
49
+ case 'deny_vendor':
50
+ $role = 'subscriber';
51
+ add_action( 'admin_notices', array( $this, 'denied' ) );
52
+ break;
53
+
54
+ default:
55
+ // code...
56
+ break;
57
+ }
58
+
59
+ $wp_user_object->set_role( $role );
60
+
61
+ }
62
+ }
63
+
64
+
65
+ /**
66
+ *
67
+ */
68
+ public function denied()
69
+ {
70
+ echo '<div class="updated">';
71
+ echo '<p>' . __( 'Vendor has been <b>denied</b>.', 'wcvendors' ) . '</p>';
72
+ echo '</div>';
73
+ }
74
+
75
+
76
+ /**
77
+ *
78
+ */
79
+ public function approved()
80
+ {
81
+ echo '<div class="updated">';
82
+ echo '<p>' . __( 'Vendor has been <b>approved</b>.', 'wcvendors' ) . '</p>';
83
+ echo '</div>';
84
+ }
85
+
86
+
87
+ /**
88
+ *
89
+ *
90
+ * @param unknown $values
91
+ *
92
+ * @return unknown
93
+ */
94
+ public function show_pending_vendors_link( $values )
95
+ {
96
+ $values[ 'pending_vendors' ] = '<a href="?role=asd">' . __( 'Pending Vendors', 'wcvendors' ) . ' <span class="count">(3)</span></a>';
97
+
98
+ return $values;
99
+ }
100
+
101
+ }
trunk/WCVendors/classes/admin/class-vendor-reports.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Report views
5
+ *
6
+ * @author Matt Gates <http://mgates.me>
7
+ * @package ProductVendor
8
+ */
9
+
10
+
11
+ class WCV_Vendor_Reports
12
+ {
13
+
14
+
15
+ /**
16
+ * Constructor
17
+ */
18
+ function __construct()
19
+ {
20
+ $this->vendor_id = !current_user_can( 'manage_woocommerce' ) ? wp_get_current_user()->ID : '';
21
+ if ( !empty ( $this->vendor_id ) ) {
22
+ add_filter( 'woocommerce_reports_charts', array( $this, 'filter_tabs' ), 99 );
23
+ add_filter( 'woocommerce_json_search_found_products', array( $this, 'filter_products_json' ) );
24
+ add_filter( 'woocommerce_reports_product_sales_order_items', array( $this, 'filter_products' ) );
25
+ add_filter( 'woocommerce_reports_top_sellers_order_items', array( $this, 'filter_products' ) );
26
+ add_filter( 'woocommerce_reports_top_earners_order_items', array( $this, 'filter_products' ) );
27
+ }
28
+
29
+ }
30
+
31
+ /**
32
+ * Show only reports that are useful to a vendor
33
+ *
34
+ * @param array $tabs
35
+ *
36
+ * @return array
37
+ */
38
+ public function filter_tabs( $tabs )
39
+ {
40
+ global $woocommerce;
41
+
42
+ $remove = array(
43
+ 'woocommerce_sales_overview',
44
+ 'woocommerce_daily_sales',
45
+ 'woocommerce_monthly_sales',
46
+ 'woocommerce_monthly_taxes',
47
+ 'woocommerce_category_sales',
48
+ 'woocommerce_coupon_sales',
49
+ );
50
+
51
+ $reports = $tabs[ 'orders' ][ 'reports' ];
52
+
53
+ foreach ( $reports as $key => $chart ) {
54
+ if ( $key == 'coupon_usage' ) {
55
+ unset( $tabs[ 'orders' ][ 'reports' ][ $key ] );
56
+ }
57
+ }
58
+
59
+ // These are admin tabs
60
+ $return = array(
61
+ 'orders' => $tabs[ 'orders' ]
62
+ );
63
+
64
+ return $return;
65
+ }
66
+
67
+
68
+ /**
69
+ * Filter products based on current vendor
70
+ *
71
+ * @param unknown $orders
72
+ *
73
+ * @return unknown
74
+ */
75
+ public function filter_products( $orders )
76
+ {
77
+ $products = WCV_Vendors::get_vendor_products( $this->vendor_id );
78
+
79
+ $ids = array();
80
+ foreach ( $products as $product ) {
81
+ $ids[ ] = ( $product->ID );
82
+ }
83
+
84
+ foreach ( $orders as $key => $order ) {
85
+
86
+ if ( !in_array( $order->product_id, $ids ) ) {
87
+ unset( $orders[ $key ] );
88
+ continue;
89
+ } else {
90
+ if ( !empty( $order->line_total ) ) {
91
+ $orders[ $key ]->line_total = WCV_Commission::calculate_commission( $order->line_total, $order->product_id, $order );
92
+ }
93
+ }
94
+
95
+ }
96
+
97
+ return $orders;
98
+ }
99
+
100
+
101
+ /**
102
+ *
103
+ *
104
+ * @param unknown $products
105
+ *
106
+ * @return unknown
107
+ */
108
+ public function filter_products_json( $products )
109
+ {
110
+ $vendor_products = WCV_Vendors::get_vendor_products( $this->vendor_id );
111
+
112
+ $ids = array();
113
+ foreach ( $vendor_products as $vendor_product ) {
114
+ $ids[ $vendor_product->ID ] = $vendor_product->post_title;
115
+ }
116
+
117
+ return array_intersect_key( $products, $ids );
118
+ }
119
+
120
+
121
+ }
trunk/WCVendors/classes/admin/emails/class-emails.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
4
+
5
+ /**
6
+ *
7
+ *
8
+ * @author Matt Gates <http://mgates.me>
9
+ * @package
10
+ */
11
+
12
+
13
+ class WCV_Emails
14
+ {
15
+
16
+
17
+ /**
18
+ *
19
+ */
20
+ function __construct()
21
+ {
22
+ add_action( 'woocommerce_email_classes', array( $this, 'check_items' ) );
23
+ add_filter( 'woocommerce_resend_order_emails_available', array( $this, 'order_action' ) );
24
+ add_filter( 'woocommerce_order_product_title', array( 'WCV_Emails', 'show_vendor_in_email' ), 10, 2 );
25
+ add_action( 'set_user_role', array( $this, 'application_status_email' ), 10, 2 );
26
+ add_action( 'transition_post_status', array( $this, 'trigger_new_product' ), 10, 3 );
27
+ }
28
+
29
+ public function trigger_new_product( $from, $to, $post )
30
+ {
31
+ global $woocommerce;
32
+
33
+ if ( $from != $to && $post->post_status == 'pending' && WCV_Vendors::is_vendor( $post->post_author ) ) {
34
+ $mails = $woocommerce->mailer()->get_emails();
35
+ if ( !empty( $mails ) ) {
36
+ $mails[ 'WC_Email_Notify_Admin' ]->trigger( $post->post_id, $post );
37
+ }
38
+ }
39
+ }
40
+
41
+
42
+ /**
43
+ *
44
+ *
45
+ * @param unknown $user_id
46
+ * @param unknown $role
47
+ */
48
+ function application_status_email( $user_id, $role )
49
+ {
50
+ global $woocommerce;
51
+
52
+ if ( !empty( $_POST[ 'apply_for_vendor' ] ) || ( !empty( $_GET[ 'action' ] ) && ( $_GET[ 'action' ] == 'approve_vendor' || $_GET[ 'action' ] == 'deny_vendor' ) ) ) {
53
+
54
+ if ( $role == 'pending_vendor' ) {
55
+ $status = __( 'pending', 'wcvendors' );
56
+ } else if ( $role == 'vendor' ) {
57
+ $status = __( 'approved', 'wcvendors' );
58
+ } else if ( !empty( $_GET[ 'action' ] ) && $_GET[ 'action' ] == 'deny_vendor' ) {
59
+ $status = __( 'denied', 'wcvendors' );
60
+ }
61
+
62
+ $mails = $woocommerce->mailer()->get_emails();
63
+
64
+ if ( isset( $status ) && !empty( $mails ) ) {
65
+ $mails[ 'WC_Email_Approve_Vendor' ]->trigger( $user_id, $status );
66
+ }
67
+ }
68
+ }
69
+
70
+
71
+ /**
72
+ *
73
+ *
74
+ * @param unknown $name
75
+ * @param unknown $_product
76
+ *
77
+ * @return unknown
78
+ */
79
+ function show_vendor_in_email( $name, $_product )
80
+ {
81
+ $product = get_post( $_product->id );
82
+
83
+ $sold_by = WCV_Vendors::is_vendor( $product->post_author )
84
+ ? sprintf( '<a href="%s">%s</a>', WCV_Vendors::get_vendor_shop_page( $product->post_author ), WCV_Vendors::get_vendor_shop_name( $product->post_author ) )
85
+ : get_bloginfo( 'name' );
86
+
87
+ $name .= '<small><br />' . apply_filters('wcvendors_sold_by_in_email', __( 'Sold by: ', 'wcvendors' )). $sold_by . '</small><br />';
88
+
89
+ return $name;
90
+ }
91
+
92
+
93
+ /**
94
+ *
95
+ *
96
+ * @param unknown $available_emails
97
+ *
98
+ * @return unknown
99
+ */
100
+ public function order_action( $available_emails )
101
+ {
102
+ $available_emails[ ] = 'vendor_new_order';
103
+
104
+ return $available_emails;
105
+ }
106
+
107
+
108
+ /**
109
+ *
110
+ *
111
+ * @param unknown $emails
112
+ *
113
+ * @return unknown
114
+ */
115
+ public function check_items( $emails )
116
+ {
117
+ require_once wcv_plugin_dir . 'classes/admin/emails/class-wc-notify-admin.php';
118
+ require_once wcv_plugin_dir . 'classes/admin/emails/class-wc-notify-vendor.php';
119
+ require_once wcv_plugin_dir . 'classes/admin/emails/class-wc-approve-vendor.php';
120
+ require_once wcv_plugin_dir . 'classes/admin/emails/class-wc-notify-shipped.php';
121
+
122
+ $emails[ 'WC_Email_Notify_Vendor' ] = new WC_Email_Notify_Vendor();
123
+ $emails[ 'WC_Email_Approve_Vendor' ] = new WC_Email_Approve_Vendor();
124
+ $emails[ 'WC_Email_Notify_Admin' ] = new WC_Email_Notify_Admin();
125
+ $emails[ 'WC_Email_Notify_Shipped' ] = new WC_Email_Notify_Shipped();
126
+
127
+ return $emails;
128
+ }
129
+
130
+
131
+ }
trunk/WCVendors/classes/admin/emails/class-wc-approve-vendor.php ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
4
+
5
+ /**
6
+ * New Order Email
7
+ *
8
+ * An email sent to the admin when a new order is received/paid for.
9
+ *
10
+ * @class WC_Email_Approve_Vendor
11
+ * @version 2.0.0
12
+ * @extends WC_Email
13
+ * @author WooThemes
14
+ * @package WooCommerce/Classes/Emails
15
+ */
16
+
17
+
18
+ class WC_Email_Approve_Vendor extends WC_Email
19
+ {
20
+
21
+
22
+ /**
23
+ * Constructor
24
+ */
25
+ function __construct()
26
+ {
27
+ $this->id = 'vendor_application';
28
+ $this->title = __( 'Vendor Application', 'wcvendors' );
29
+ $this->description = __( 'Vendor application will either be approved, denied, or pending.', 'wcvendors' );
30
+
31
+ $this->heading = __( 'Application {status}', 'wcvendors' );
32
+ $this->subject = __( '[{blogname}] Your vendor application has been {status}', 'wcvendors' );
33
+
34
+ $this->template_base = dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) . '/views/emails/';
35
+ $this->template_html = 'application-status.php';
36
+ $this->template_plain = 'application-status.php';
37
+
38
+ // Call parent constuctor
39
+ parent::__construct();
40
+
41
+ // Other settings
42
+ $this->recipient = $this->get_option( 'recipient' );
43
+
44
+ if ( !$this->recipient )
45
+ $this->recipient = get_option( 'admin_email' );
46
+ }
47
+
48
+ /**
49
+ * trigger function.
50
+ *
51
+ * @access public
52
+ * @return void
53
+ *
54
+ * @param unknown $order_id
55
+ */
56
+ function trigger( $user_id, $status )
57
+ {
58
+ if ( !$this->is_enabled() ) return;
59
+
60
+ $this->find[ ] = '{status}';
61
+ $this->replace[ ] = $status;
62
+
63
+ $this->status = $status;
64
+
65
+ $this->user = get_userdata( $user_id );
66
+ $user_email = $this->user->user_email;
67
+
68
+ $this->send( $user_email, $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
69
+
70
+ if ( $status == __( 'pending', 'wcvendors' ) ) {
71
+ $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
72
+ }
73
+ }
74
+
75
+ /**
76
+ * get_content_html function.
77
+ *
78
+ * @access public
79
+ * @return string
80
+ */
81
+ function get_content_html()
82
+ {
83
+ ob_start();
84
+ wc_get_template( $this->template_html, array(
85
+ 'status' => $this->status,
86
+ 'user' => $this->user,
87
+ 'email_heading' => $this->get_heading()
88
+ ), 'woocommerce/', $this->template_base );
89
+
90
+ return ob_get_clean();
91
+ }
92
+
93
+
94
+ /**
95
+ * get_content_plain function.
96
+ *
97
+ * @access public
98
+ * @return string
99
+ */
100
+ function get_content_plain()
101
+ {
102
+ ob_start();
103
+ wc_get_template( $this->template_plain, array(
104
+ 'status' => $this->status,
105
+ 'user' => $this->user,
106
+ 'email_heading' => $this->get_heading()
107
+ ), 'woocommerce/', $this->template_base );
108
+
109
+ return ob_get_clean();
110
+ }
111
+
112
+
113
+ /**
114
+ * Initialise Settings Form Fields
115
+ *
116
+ * @access public
117
+ * @return void
118
+ */
119
+ function init_form_fields()
120
+ {
121
+ $this->form_fields = array(
122
+ 'enabled' => array(
123
+ 'title' => __( 'Enable/Disable', 'wcvendors' ),
124
+ 'type' => 'checkbox',
125
+ 'label' => __( 'Enable this email notification', 'wcvendors' ),
126
+ 'default' => 'yes'
127
+ ),
128
+ 'recipient' => array(
129
+ 'title' => __( 'Recipient(s)', 'woocommerce' ),
130
+ 'type' => 'text',
131
+ 'description' => sprintf( __( 'Enter recipients (comma separated) for this email. Defaults to <code>%s</code>.', 'wcvendors' ), esc_attr( get_option( 'admin_email' ) ) ),
132
+ 'placeholder' => '',
133
+ 'default' => ''
134
+ ),
135
+ 'subject' => array(
136
+ 'title' => __( 'Subject', 'wcvendors' ),
137
+ 'type' => 'text',
138
+ 'description' => sprintf( __( 'This controls the email subject line. Leave blank to use the default subject: <code>%s</code>.', 'wcvendors' ), $this->subject ),
139
+ 'placeholder' => '',
140
+ 'default' => ''
141
+ ),
142
+ 'heading' => array(
143
+ 'title' => __( 'Email Heading', 'wcvendors' ),
144
+ 'type' => 'text',
145
+ 'description' => sprintf( __( 'This controls the main heading contained within the email notification. Leave blank to use the default heading: <code>%s</code>.', 'wcvendors' ), $this->heading ),
146
+ 'placeholder' => '',
147
+ 'default' => ''
148
+ ),
149
+ 'email_type' => array(
150
+ 'title' => __( 'Email type', 'wcvendors' ),
151
+ 'type' => 'select',
152
+ 'description' => __( 'Choose which format of email to send.', 'wcvendors' ),
153
+ 'default' => 'html',
154
+ 'class' => 'email_type',
155
+ 'options' => array(
156
+ 'plain' => __( 'Plain text', 'wcvendors' ),
157
+ 'html' => __( 'HTML', 'wcvendors' ),
158
+ 'multipart' => __( 'Multipart', 'wcvendors' ),
159
+ )
160
+ )
161
+ );
162
+ }
163
+
164
+
165
+ }
trunk/WCVendors/classes/admin/emails/class-wc-notify-admin.php ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
4
+
5
+ /**
6
+ * New Order Email
7
+ *
8
+ * An email sent to the admin when a new product is created.
9
+ *
10
+ * @class WC_Email_Notify_Admin
11
+ * @version 2.0.0
12
+ * @extends WC_Email
13
+ * @author WooThemes
14
+ * @package WooCommerce/Classes/Emails
15
+ */
16
+
17
+
18
+ class WC_Email_Notify_Admin extends WC_Email
19
+ {
20
+
21
+
22
+ /**
23
+ * Constructor
24
+ */
25
+ function __construct()
26
+ {
27
+ $this->id = 'admin_new_vendor_product';
28
+ $this->title = __( 'New Vendor Product', 'wcvendors' );
29
+ $this->description = __( 'New order emails are sent when a new product is submitted by a vendor', 'wcvendors' );
30
+
31
+ $this->heading = __( 'New product submitted: {product_name}', 'wcvendors' );
32
+ $this->subject = __( '[{blogname}] New product submitted by {vendor_name} - {product_name}', 'wcvendors' );
33
+
34
+ $this->template_base = dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) . '/views/emails/';
35
+ $this->template_html = 'new-product.php';
36
+ $this->template_plain = 'new-product.php';
37
+
38
+ // Triggers for this email
39
+ add_action( 'transition_post_status', array( $this, 'trigger' ), 10, 3 );
40
+
41
+ // Call parent constuctor
42
+ parent::__construct();
43
+
44
+ // Other settings
45
+ $this->recipient = $this->get_option( 'recipient' );
46
+
47
+ if ( !$this->recipient )
48
+ $this->recipient = get_option( 'admin_email' );
49
+ }
50
+
51
+
52
+ /**
53
+ * trigger function.
54
+ *
55
+ * @access public
56
+ * @return void
57
+ *
58
+ * @param unknown $order_id
59
+ */
60
+ function trigger( $post_id, $post )
61
+ {
62
+ if ( !WCV_Vendors::is_vendor( $post->post_author ) ) {
63
+ return;
64
+ }
65
+
66
+ $this->find[ ] = '{product_name}';
67
+ $this->product_name = $post->post_title;
68
+ $this->replace[ ] = $this->product_name;
69
+
70
+ $this->find[ ] = '{vendor_name}';
71
+ $this->vendor_name = WCV_Vendors::get_vendor_shop_name( $post->post_author );
72
+ $this->replace[ ] = $this->vendor_name;
73
+
74
+ $this->post_id = $post->ID;
75
+
76
+ $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
77
+ }
78
+
79
+ /**
80
+ * get_content_html function.
81
+ *
82
+ * @access public
83
+ * @return string
84
+ */
85
+ function get_content_html()
86
+ {
87
+ ob_start();
88
+ wc_get_template( $this->template_html, array(
89
+ 'product_name' => $this->product_name,
90
+ 'vendor_name' => $this->vendor_name,
91
+ 'post_id' => $this->post_id,
92
+ 'email_heading' => $this->get_heading()
93
+ ), 'woocommerce/', $this->template_base );
94
+
95
+ return ob_get_clean();
96
+ }
97
+
98
+
99
+ /**
100
+ * get_content_plain function.
101
+ *
102
+ * @access public
103
+ * @return string
104
+ */
105
+ function get_content_plain()
106
+ {
107
+ ob_start();
108
+ wc_get_template( $this->template_plain, array(
109
+ 'product_name' => $this->product_name,
110
+ 'vendor_name' => $this->vendor_name,
111
+ 'post_id' => $this->post_id,
112
+ 'email_heading' => $this->get_heading()
113
+ ), 'woocommerce/', $this->template_base );
114
+
115
+ return ob_get_clean();
116
+ }
117
+
118
+
119
+ /**
120
+ * Initialise Settings Form Fields
121
+ *
122
+ * @access public
123
+ * @return void
124
+ */
125
+ function init_form_fields()
126
+ {
127
+ $this->form_fields = array(
128
+ 'enabled' => array(
129
+ 'title' => __( 'Enable/Disable', 'wcvendors' ),
130
+ 'type' => 'checkbox',
131
+ 'label' => __( 'Enable this email notification', 'wcvendors' ),
132
+ 'default' => 'yes'
133
+ ),
134
+ 'recipient' => array(
135
+ 'title' => __( 'Recipient(s)', 'woocommerce' ),
136
+ 'type' => 'text',
137
+ 'description' => sprintf( __( 'Enter recipients (comma separated) for this email. Defaults to <code>%s</code>.', 'woocommerce' ), esc_attr( get_option( 'admin_email' ) ) ),
138
+ 'placeholder' => '',
139
+ 'default' => ''
140
+ ),
141
+ 'subject' => array(
142
+ 'title' => __( 'Subject', 'wcvendors' ),
143
+ 'type' => 'text',
144
+ 'description' => sprintf( __( 'This controls the email subject line. Leave blank to use the default subject: <code>%s</code>.', 'wcvendors' ), $this->subject ),
145
+ 'placeholder' => '',
146
+ 'default' => ''
147
+ ),
148
+ 'heading' => array(
149
+ 'title' => __( 'Email Heading', 'wcvendors' ),
150
+ 'type' => 'text',
151
+ 'description' => sprintf( __( 'This controls the main heading contained within the email notification. Leave blank to use the default heading: <code>%s</code>.', 'wcvendors' ), $this->heading ),
152
+ 'placeholder' => '',
153
+ 'default' => ''
154
+ ),
155
+ 'email_type' => array(
156
+ 'title' => __( 'Email type', 'wcvendors' ),
157
+ 'type' => 'select',
158
+ 'description' => __( 'Choose which format of email to send.', 'wcvendors' ),
159
+ 'default' => 'html',
160
+ 'class' => 'email_type',
161
+ 'options' => array(
162
+ 'plain' => __( 'Plain text', 'wcvendors' ),
163
+ 'html' => __( 'HTML', 'wcvendors' ),
164
+ 'multipart' => __( 'Multipart', 'wcvendors' ),
165
+ )
166
+ )
167
+ );
168
+ }
169
+
170
+
171
+ }
trunk/WCVendors/classes/admin/emails/class-wc-notify-shipped.php ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
4
+
5
+ /**
6
+ * New Order Email
7
+ *
8
+ * An email sent to the admin when a new product is created.
9
+ *
10
+ * @class WC_Email_Notify_Shipped
11
+ * @version 2.0.0
12
+ * @extends WC_Email
13
+ * @author WooThemes
14
+ * @package WooCommerce/Classes/Emails
15
+ */
16
+
17
+
18
+ class WC_Email_Notify_Shipped extends WC_Email
19
+ {
20
+
21
+
22
+ /**
23
+ * Constructor
24
+ */
25
+ function __construct()
26
+ {
27
+ $this->id = 'vendor_notify_shipped';
28
+ $this->title = __( 'Vendor has shipped', 'wcvendors' );
29
+ $this->description = __( 'An email is sent when a vendor has marked one of their orders as shipped.', 'wcvendors' );
30
+
31
+ $this->heading = __( 'Your order has been shipped', 'wcvendors' );
32
+ $this->subject = __( '[{blogname}] Your order has been shipped ({order_number}) - {order_date}', 'wcvendors' );
33
+
34
+ $this->template_html = 'notify-vendor-shipped.php';
35
+ $this->template_plain = 'notify-vendor-shipped.php';
36
+ $this->template_base = dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) . '/views/emails/';
37
+
38
+ // Call parent constuctor
39
+ parent::__construct();
40
+ }
41
+
42
+
43
+ /**
44
+ * trigger function.
45
+ *
46
+ * @access public
47
+ * @return void
48
+ *
49
+ * @param unknown $order_id
50
+ */
51
+ function trigger( $order_id, $vendor_id )
52
+ {
53
+ $this->object = new WC_Order( $order_id );
54
+ $this->current_vendor = $vendor_id;
55
+
56
+ $this->find[ ] = '{order_date}';
57
+ $this->replace[ ] = date_i18n( woocommerce_date_format(), strtotime( $this->object->order_date ) );
58
+
59
+ $this->find[ ] = '{order_number}';
60
+ $this->replace[ ] = $this->object->get_order_number();
61
+
62
+ if ( !$this->is_enabled() ) return;
63
+
64
+ add_filter( 'woocommerce_order_get_items', array( $this, 'check_items' ), 10, 2 );
65
+ add_filter( 'woocommerce_get_order_item_totals', array( $this, 'check_order_totals' ), 10, 2 );
66
+ $this->send( $this->object->billing_email, $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
67
+ remove_filter( 'woocommerce_get_order_item_totals', array( $this, 'check_order_totals' ), 10, 2 );
68
+ remove_filter( 'woocommerce_order_get_items', array( $this, 'check_items' ), 10, 2 );
69
+ }
70
+
71
+
72
+ /**
73
+ *
74
+ *
75
+ * @param unknown $items
76
+ * @param unknown $order
77
+ *
78
+ * @return unknown
79
+ */
80
+ public function check_items( $items, $order )
81
+ {
82
+ foreach ( $items as $key => $product ) {
83
+
84
+ if ( empty( $product[ 'product_id' ] ) ) {
85
+ unset( $items[ $key ] );
86
+ continue;
87
+ }
88
+
89
+ $author = WCV_Vendors::get_vendor_from_product( $product[ 'product_id' ] );
90
+
91
+ if ( $this->current_vendor != $author ) {
92
+ unset( $items[ $key ] );
93
+ continue;
94
+ }
95
+
96
+ }
97
+
98
+ return $items;
99
+ }
100
+
101
+ /**
102
+ *
103
+ *
104
+ * @param unknown $total_rows
105
+ * @param unknown $order
106
+ *
107
+ * @return unknown
108
+ */
109
+ public function check_order_totals( $total_rows, $order )
110
+ {
111
+ $return[ 'cart_subtotal' ] = $total_rows[ 'cart_subtotal' ];
112
+ $return[ 'cart_subtotal' ][ 'label' ] = __( 'Subtotal:', 'wcvendors' );
113
+
114
+ return $return;
115
+ }
116
+
117
+ /**
118
+ * get_content_html function.
119
+ *
120
+ * @access public
121
+ * @return string
122
+ */
123
+ function get_content_html()
124
+ {
125
+ ob_start();
126
+ wc_get_template( $this->template_html, array(
127
+ 'order' => $this->object,
128
+ 'email_heading' => $this->get_heading()
129
+ ), 'woocommerce/', $this->template_base );
130
+
131
+ return ob_get_clean();
132
+ }
133
+
134
+
135
+ /**
136
+ * get_content_plain function.
137
+ *
138
+ * @access public
139
+ * @return string
140
+ */
141
+ function get_content_plain()
142
+ {
143
+ ob_start();
144
+ wc_get_template( $this->template_plain, array(
145
+ 'order' => $this->object,
146
+ 'email_heading' => $this->get_heading()
147
+ ), 'woocommerce/', $this->template_base );
148
+
149
+ return ob_get_clean();
150
+ }
151
+
152
+
153
+ /**
154
+ * Initialise Settings Form Fields
155
+ *
156
+ * @access public
157
+ * @return void
158
+ */
159
+ function init_form_fields()
160
+ {
161
+ $this->form_fields = array(
162
+ 'enabled' => array(
163
+ 'title' => __( 'Enable/Disable', 'wcvendors' ),
164
+ 'type' => 'checkbox',
165
+ 'label' => __( 'Enable this email notification', 'wcvendors' ),
166
+ 'default' => 'yes'
167
+ ),
168
+ 'subject' => array(
169
+ 'title' => __( 'Subject', 'wcvendors' ),
170
+ 'type' => 'text',
171
+ 'description' => sprintf( __( 'This controls the email subject line. Leave blank to use the default subject: <code>%s</code>.', 'wcvendors' ), $this->subject ),
172
+ 'placeholder' => '',
173
+ 'default' => ''
174
+ ),
175
+ 'heading' => array(
176
+ 'title' => __( 'Email Heading', 'wcvendors' ),
177
+ 'type' => 'text',
178
+ 'description' => sprintf( __( 'This controls the main heading contained within the email notification. Leave blank to use the default heading: <code>%s</code>.', 'wcvendors' ), $this->heading ),
179
+ 'placeholder' => '',
180
+ 'default' => ''
181
+ ),
182
+ 'email_type' => array(
183
+ 'title' => __( 'Email type', 'wcvendors' ),
184
+ 'type' => 'select',
185
+ 'description' => __( 'Choose which format of email to send.', 'wcvendors' ),
186
+ 'default' => 'html',
187
+ 'class' => 'email_type',
188
+ 'options' => array(
189
+ 'plain' => __( 'Plain text', 'wcvendors' ),
190
+ 'html' => __( 'HTML', 'wcvendors' ),
191
+ 'multipart' => __( 'Multipart', 'wcvendors' ),
192
+ )
193
+ )
194
+ );
195
+ }
196
+
197
+
198
+ }
trunk/WCVendors/classes/admin/emails/class-wc-notify-vendor.php ADDED
@@ -0,0 +1,265 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
4
+
5
+ /**
6
+ * New Order Email
7
+ *
8
+ * An email sent to the admin when a new order is received/paid for.
9
+ *
10
+ * @class WC_Email_Notify_Vendor
11
+ * @version 2.0.0
12
+ * @extends WC_Email
13
+ * @author WooThemes
14
+ * @package WooCommerce/Classes/Emails
15
+ */
16
+
17
+
18
+ class WC_Email_Notify_Vendor extends WC_Email
19
+ {
20
+
21
+ /**
22
+ * Constructor
23
+ */
24
+ function __construct()
25
+ {
26
+ $this->id = 'vendor_new_order';
27
+ $this->title = __( 'Notify vendors', 'wcvendors' );
28
+ $this->description = __( 'New order emails are sent when an order is received/paid by a customer.', 'wcvendors' );
29
+
30
+ $this->heading = __( 'New customer order', 'wcvendors' );
31
+ $this->subject = __( '[{blogname}] New customer order ({order_number}) - {order_date}', 'wcvendors' );
32
+
33
+ $this->template_html = 'admin-new-order.php';
34
+ $this->template_plain = 'plain/admin-new-order.php';
35
+ $this->template_base = dirname( dirname( dirname( dirname( __FILE__ ) ) ) ) . '/views/emails/';
36
+
37
+ // Triggers for this email
38
+ add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ) );
39
+ add_action( 'woocommerce_order_status_pending_to_completed_notification', array( $this, 'trigger' ) );
40
+ add_action( 'woocommerce_order_status_failed_to_processing_notification', array( $this, 'trigger' ) );
41
+ add_action( 'woocommerce_order_status_failed_to_completed_notification', array( $this, 'trigger' ) );
42
+
43
+ $this->recipient = get_option( 'admin_email' );
44
+
45
+ // Call parent constuctor
46
+ parent::__construct();
47
+
48
+ }
49
+
50
+
51
+ /**
52
+ * trigger function.
53
+ *
54
+ * @access public
55
+ * @return void
56
+ *
57
+ * @param unknown $order_id
58
+ */
59
+ function trigger( $order_id )
60
+ {
61
+ global $woocommerce;
62
+
63
+ if ( $order_id ) {
64
+ $this->object = new WC_Order( $order_id );
65
+
66
+ $this->find[ ] = '{order_date}';
67
+ $this->replace[ ] = date_i18n( woocommerce_date_format(), strtotime( $this->object->order_date ) );
68
+
69
+ $this->find[ ] = '{order_number}';
70
+ $this->replace[ ] = $this->object->get_order_number();
71
+
72
+ }
73
+
74
+ if ( !$this->is_enabled() ) return;
75
+
76
+ $vendors = $this->get_vendors( $this->object );
77
+
78
+ if ( empty( $vendors ) ) return;
79
+
80
+ add_filter( 'woocommerce_order_get_items', array( $this, 'check_items' ), 10, 2 );
81
+ add_filter( 'woocommerce_get_order_item_totals', array( $this, 'check_order_totals' ), 10, 2 );
82
+ foreach ( $vendors as $user_id => $user_email ) {
83
+ $this->current_vendor = $user_id;
84
+ $this->send( $user_email, $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
85
+ }
86
+ remove_filter( 'woocommerce_get_order_item_totals', array( $this, 'check_order_totals' ), 10, 2 );
87
+ remove_filter( 'woocommerce_order_get_items', array( $this, 'check_items' ), 10, 2 );
88
+
89
+ }
90
+
91
+
92
+ /**
93
+ *
94
+ *
95
+ * @param unknown $total_rows
96
+ * @param unknown $order
97
+ *
98
+ * @return unknown
99
+ */
100
+ function check_order_totals( $total_rows, $order )
101
+ {
102
+ $return[ 'cart_subtotal' ] = $total_rows[ 'cart_subtotal' ];
103
+ $return[ 'cart_subtotal' ][ 'label' ] = __( 'Commission Subtotal:', 'wcvendors' );
104
+
105
+ $dues = WCV_Vendors::get_vendor_dues_from_order( $order );
106
+
107
+ foreach ( $dues as $due ) {
108
+ if ( $this->current_vendor == $due['vendor_id'] ) {
109
+ if (!empty($return[ 'shipping' ])) $return[ 'shipping' ] = $total_rows[ 'shipping' ];
110
+ $return[ 'shipping' ]['label'] = __( 'Shipping Subtotal:', 'wcvendors' );
111
+ $return[ 'shipping' ][ 'value' ] = woocommerce_price( $due['shipping'] );
112
+ break;
113
+ }
114
+ }
115
+
116
+ return $return;
117
+ }
118
+
119
+
120
+ /**
121
+ *
122
+ *
123
+ * @param unknown $order
124
+ *
125
+ * @return unknown
126
+ */
127
+ public function get_vendors( $order )
128
+ {
129
+ $items = $order->get_items();
130
+
131
+ foreach ( $items as $key => $product ) {
132
+
133
+ if ( empty( $product[ 'product_id' ] ) ) continue;
134
+ $author = WCV_Vendors::get_vendor_from_product( $product[ 'product_id' ] );
135
+
136
+ // Only store the vendor authors
137
+ if ( !WCV_Vendors::is_vendor( $author ) ) {
138
+ unset( $items[ $key ] );
139
+ continue;
140
+ }
141
+
142
+ $vendors[ $author ] = get_userdata( $author )->user_email;
143
+ }
144
+
145
+ return $vendors;
146
+ }
147
+
148
+ /**
149
+ *
150
+ *
151
+ * @param unknown $items
152
+ * @param unknown $order
153
+ *
154
+ * @return unknown
155
+ */
156
+ function check_items( $items, $order )
157
+ {
158
+ foreach ( $items as $key => $product ) {
159
+
160
+ // If this is a line item
161
+ if ($product['type'] == 'line_item') {
162
+
163
+ $author = WCV_Vendors::get_vendor_from_product( $product[ 'product_id' ] );
164
+
165
+ if ( $this->current_vendor != $author) {
166
+ unset( $items[ $key ] );
167
+ continue;
168
+ } else {
169
+ $commission_due = WCV_Commission::calculate_commission( $product[ 'line_subtotal' ], $product[ 'product_id' ], $order );
170
+
171
+ $items[ $key ][ 'line_subtotal' ] = $commission_due;
172
+ $items[ $key ][ 'line_total' ] = $commission_due;
173
+ unset( $items[ $key ][ 'line_tax' ] );
174
+ }
175
+ }
176
+
177
+ }
178
+
179
+
180
+ return $items;
181
+ }
182
+
183
+
184
+ /**
185
+ * get_content_html function.
186
+ *
187
+ * @access public
188
+ * @return string
189
+ */
190
+ function get_content_html()
191
+ {
192
+ ob_start();
193
+ wc_get_template( $this->template_html, array(
194
+ 'order' => $this->object,
195
+ 'email_heading' => $this->get_heading()
196
+ ), 'woocommerce/', $this->template_base );
197
+
198
+ return ob_get_clean();
199
+ }
200
+
201
+
202
+ /**
203
+ * get_content_plain function.
204
+ *
205
+ * @access public
206
+ * @return string
207
+ */
208
+ function get_content_plain()
209
+ {
210
+ ob_start();
211
+ wc_get_template( $this->template_plain, array(
212
+ 'order' => $this->object,
213
+ 'email_heading' => $this->get_heading()
214
+ ), 'woocommerce/', $this->template_base );
215
+
216
+ return ob_get_clean();
217
+ }
218
+
219
+
220
+ /**
221
+ * Initialise Settings Form Fields
222
+ *
223
+ * @access public
224
+ * @return void
225
+ */
226
+ function init_form_fields()
227
+ {
228
+ $this->form_fields = array(
229
+ 'enabled' => array(
230
+ 'title' => __( 'Enable/Disable', 'wcvendors' ),
231
+ 'type' => 'checkbox',
232
+ 'label' => __( 'Enable this email notification', 'wcvendors' ),
233
+ 'default' => 'yes'
234
+ ),
235
+ 'subject' => array(
236
+ 'title' => __( 'Subject', 'wcvendors' ),
237
+ 'type' => 'text',
238
+ 'description' => sprintf( __( 'This controls the email subject line. Leave blank to use the default subject: <code>%s</code>.', 'wcvendors' ), $this->subject ),
239
+ 'placeholder' => '',
240
+ 'default' => ''
241
+ ),
242
+ 'heading' => array(
243
+ 'title' => __( 'Email Heading', 'wcvendors' ),
244
+ 'type' => 'text',
245
+ 'description' => sprintf( __( 'This controls the main heading contained within the email notification. Leave blank to use the default heading: <code>%s</code>.', 'wcvendors' ), $this->heading ),
246
+ 'placeholder' => '',
247
+ 'default' => ''
248
+ ),
249
+ 'email_type' => array(
250
+ 'title' => __( 'Email type', 'wcvendors' ),
251
+ 'type' => 'select',
252
+ 'description' => __( 'Choose which format of email to send.', 'wcvendors' ),
253
+ 'default' => 'html',
254
+ 'class' => 'email_type',
255
+ 'options' => array(
256
+ 'plain' => __( 'Plain text', 'wcvendors' ),
257
+ 'html' => __( 'HTML', 'wcvendors' ),
258
+ 'multipart' => __( 'Multipart', 'wcvendors' ),
259
+ )
260
+ )
261
+ );
262
+ }
263
+
264
+
265
+ }
trunk/WCVendors/classes/admin/settings/README.md ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ WP Simple Settings Framework
2
+ ================================
3
+
4
+ A minimalistic framework for Wordpress Settings API.
5
+
6
+ Quick start
7
+ ------------
8
+
9
+ * [Download the latest release](https://github.com/Geczy/WP-Simple-Settings-Framework/zipball/master) (zip)
10
+
11
+ * Or, clone the repo, `git clone git://github.com/Geczy/WP-Simple-Settings-Framework.git`
12
+
13
+ Installation
14
+ ------------
15
+ 1. Include the framework in your Wordpress plugin by using:
16
+
17
+ ```php
18
+ <?php
19
+ add_action( 'init', 'sf_load_settings' );
20
+ function sf_load_settings() {
21
+ require 'classes/sf-class-settings.php';
22
+ $settings_framework = new SF_Settings_API($id = 'my_plugin_name', $title = 'My Plugin Title', $menu = 'plugins.php', __FILE__);
23
+ }
24
+ ```
25
+
26
+ Optionally, you might want to make `$settings_framework` a global variable so that you can use the [helper functions](#helpers).
27
+
28
+ 2. Open `sf-options.php` to begin configuring your options.
29
+
30
+ Features
31
+ ------------
32
+
33
+ ### Automatic settings page
34
+ Don't want it under the Plugins tab like in the screenshot? No problem, you can choose where you want it!
35
+
36
+ You can also change "Simple Settings" submenu to be anything you'd like.
37
+
38
+ ![settings page example](http://i.imgur.com/aEGUD.png)
39
+
40
+ ---
41
+
42
+ ### Tooltips
43
+ ![tooltips example](http://i.imgur.com/Z3Pnk.png)
44
+
45
+ Optional tooltips using [Twitter Bootstrap](http://twitter.github.com/bootstrap/javascript.html#tooltips)!
46
+
47
+ ---
48
+
49
+ ### Select box replacement
50
+ ![select box replacement](http://i.imgur.com/ikOXH.png)
51
+
52
+ Utilizing [Select2](http://ivaynberg.github.com/select2/) to display select boxes. It's pretty cool!
53
+
54
+ ---
55
+
56
+ ### Multiple tabs
57
+ ![multiple tabs example](http://i.imgur.com/OUM4i.png)
58
+
59
+ Create multiple tabs for your options.
60
+
61
+ ---
62
+
63
+ ### Input types
64
+
65
+ * Text
66
+ * Number
67
+ * Textarea
68
+ * Checkbox
69
+ * Radio
70
+ * Select
71
+ * WP Pages
72
+
73
+ Helpers
74
+ ------------
75
+
76
+ Update or add a new option
77
+
78
+ ```php
79
+ <?php
80
+ $settings_framework->update_option('your_option', 'new_value');
81
+ ```
82
+
83
+ Get an existing option's value
84
+
85
+ ```php
86
+ <?php
87
+ $settings_framework->get_option('your_option');
88
+ ```
89
+
90
+ Example configuration
91
+ ------------
92
+
93
+ Check out the [example config](https://github.com/Geczy/WP-Simple-Settings-Framework/blob/master/sf-options.php) for an idea of how to use every input type.
94
+
95
+ Here's an example of one type, though:
96
+
97
+ ```php
98
+ <?php
99
+ $options[] = array(
100
+ 'name' => __( 'Name', 'geczy' ),
101
+ 'desc' => __( 'Please tell me who you are.', 'geczy' ),
102
+ 'id' => 'text_sample',
103
+ 'type' => 'text',
104
+ );
105
+ ```
106
+
107
+
108
+ Bug tracker
109
+ -----------
110
+
111
+ Have a bug? Please create an issue here on GitHub!
112
+
113
+ https://github.com/Geczy/WP-Simple-Settings-Framework/issues/
114
+
115
+ Copyright and License
116
+ ---------------------
117
+
118
+ Copyright 2012 Matthew Gates
119
+
120
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
121
+
122
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
123
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
124
+ * Neither the names of the copyright holders nor the names of the contributors may be used to endorse or promote products derived from this software without specific prior written permission.
125
+
126
+ http://www.opensource.org/licenses/bsd-license.php
trunk/WCVendors/classes/admin/settings/assets/css/sf-styles.css ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ a.sf-tips {
2
+ height: 16px;
3
+ width: 16px;
4
+ margin-top: 0.2em;
5
+ float: right;
6
+ background: url(../img/tip.png) no-repeat top left;
7
+ }
8
+
9
+ /*!
10
+ * Bootstrap v2.3.1 [Styles for Tooltips]
11
+ *
12
+ * Copyright 2012 Twitter, Inc
13
+ * Licensed under the Apache License v2.0
14
+ * http://www.apache.org/licenses/LICENSE-2.0
15
+ *
16
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
17
+ */
18
+ .clearfix {
19
+ *zoom: 1;
20
+ }
21
+
22
+ .clearfix:before, .clearfix:after {
23
+ display: table;
24
+ content: "";
25
+ line-height: 0;
26
+ }
27
+
28
+ .clearfix:after {
29
+ clear: both;
30
+ }
31
+
32
+ .hide-text {
33
+ font: 0/0 a;
34
+ color: transparent;
35
+ text-shadow: none;
36
+ background-color: transparent;
37
+ border: 0;
38
+ }
39
+
40
+ .input-block-level {
41
+ display: block;
42
+ width: 100%;
43
+ min-height: 30px;
44
+ -webkit-box-sizing: border-box;
45
+ -moz-box-sizing: border-box;
46
+ box-sizing: border-box;
47
+ }
48
+
49
+ /* Tooltips */
50
+ .tooltip {
51
+ text-shadow: none;
52
+ }
53
+
54
+ .tooltip {
55
+ position: absolute;
56
+ z-index: 1030;
57
+ display: block;
58
+ visibility: visible;
59
+ font-size: 11px;
60
+ line-height: 1.4;
61
+ opacity: 0;
62
+ filter: alpha(opacity=0);
63
+ }
64
+
65
+ .tooltip.in {
66
+ opacity: 0.8;
67
+ filter: alpha(opacity=80);
68
+ }
69
+
70
+ .tooltip.top {
71
+ margin-top: -3px;
72
+ padding: 5px 0;
73
+ }
74
+
75
+ .tooltip.right {
76
+ margin-left: 3px;
77
+ padding: 0 5px;
78
+ }
79
+
80
+ .tooltip.bottom {
81
+ margin-top: 3px;
82
+ padding: 5px 0;
83
+ }
84
+
85
+ .tooltip.left {
86
+ margin-left: -3px;
87
+ padding: 0 5px;
88
+ }
89
+
90
+ .tooltip-inner {
91
+ max-width: 200px;
92
+ padding: 8px;
93
+ color: #ffffff;
94
+ text-align: center;
95
+ text-decoration: none;
96
+ background-color: #000000;
97
+ -webkit-border-radius: 4px;
98
+ -moz-border-radius: 4px;
99
+ border-radius: 4px;
100
+ }
101
+
102
+ .tooltip-arrow {
103
+ position: absolute;
104
+ width: 0;
105
+ height: 0;
106
+ border-color: transparent;
107
+ border-style: solid;
108
+ }
109
+
110
+ .tooltip.top .tooltip-arrow {
111
+ bottom: 0;
112
+ left: 50%;
113
+ margin-left: -5px;
114
+ border-width: 5px 5px 0;
115
+ border-top-color: #000000;
116
+ }
117
+
118
+ .tooltip.right .tooltip-arrow {
119
+ top: 50%;
120
+ left: 0;
121
+ margin-top: -5px;
122
+ border-width: 5px 5px 5px 0;
123
+ border-right-color: #000000;
124
+ }
125
+
126
+ .tooltip.left .tooltip-arrow {
127
+ top: 50%;
128
+ right: 0;
129
+ margin-top: -5px;
130
+ border-width: 5px 0 5px 5px;
131
+ border-left-color: #000000;
132
+ }
133
+
134
+ .tooltip.bottom .tooltip-arrow {
135
+ top: 0;
136
+ left: 50%;
137
+ margin-left: -5px;
138
+ border-width: 0 5px 5px;
139
+ border-bottom-color: #000000;
140
+ }
141
+
142
+ /* Animation */
143
+ .fade {
144
+ opacity: 0;
145
+ -webkit-transition: opacity 0.15s linear;
146
+ -moz-transition: opacity 0.15s linear;
147
+ -o-transition: opacity 0.15s linear;
148
+ transition: opacity 0.15s linear;
149
+ }
150
+
151
+ .fade.in {
152
+ opacity: 1;
153
+ }
154
+
155
+ .collapse {
156
+ position: relative;
157
+ height: 0;
158
+ overflow: hidden;
159
+ -webkit-transition: height 0.35s ease;
160
+ -moz-transition: height 0.35s ease;
161
+ -o-transition: height 0.35s ease;
162
+ transition: height 0.35s ease;
163
+ }
164
+
165
+ .collapse.in {
166
+ height: auto;
167
+ }
trunk/WCVendors/classes/admin/settings/assets/img/tip.png ADDED
Binary file
trunk/WCVendors/classes/admin/settings/assets/js/bootstrap-tooltip.js ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Bootstrap.js by @fat & @mdo
3
+ * plugins: bootstrap-transition.js, bootstrap-tooltip.js
4
+ * 2.3.1
5
+ * Copyright 2012 Twitter, Inc.
6
+ * http://www.apache.org/licenses/LICENSE-2.0.txt
7
+ */
8
+ !function (a) {
9
+ a(function () {
10
+ a.support.transition = function () {
11
+ var a = function () {
12
+ var a = document.createElement("bootstrap"), b = {WebkitTransition: "webkitTransitionEnd", MozTransition: "transitionend", OTransition: "oTransitionEnd otransitionend", transition: "transitionend"}, c;
13
+ for (c in b)if (a.style[c] !== undefined)return b[c]
14
+ }();
15
+ return a && {end: a}
16
+ }()
17
+ })
18
+ }(window.jQuery), !function (a) {
19
+ var b = function (a, b) {
20
+ this.init("tooltip", a, b)
21
+ };
22
+ b.prototype = {constructor: b, init: function (b, c, d) {
23
+ var e, f, g, h, i;
24
+ this.type = b, this.$element = a(c), this.options = this.getOptions(d), this.enabled = !0, g = this.options.trigger.split(" ");
25
+ for (i = g.length; i--;)h = g[i], h == "click" ? this.$element.on("click." + this.type, this.options.selector, a.proxy(this.toggle, this)) : h != "manual" && (e = h == "hover" ? "mouseenter" : "focus", f = h == "hover" ? "mouseleave" : "blur", this.$element.on(e + "." + this.type, this.options.selector, a.proxy(this.enter, this)), this.$element.on(f + "." + this.type, this.options.selector, a.proxy(this.leave, this)));
26
+ this.options.selector ? this._options = a.extend({}, this.options, {trigger: "manual", selector: ""}) : this.fixTitle()
27
+ }, getOptions: function (b) {
28
+ return b = a.extend({}, a.fn[this.type].defaults, this.$element.data(), b), b.delay && typeof b.delay == "number" && (b.delay = {show: b.delay, hide: b.delay}), b
29
+ }, enter: function (b) {
30
+ var c = a.fn[this.type].defaults, d = {}, e;
31
+ this._options && a.each(this._options, function (a, b) {
32
+ c[a] != b && (d[a] = b)
33
+ }, this), e = a(b.currentTarget)[this.type](d).data(this.type);
34
+ if (!e.options.delay || !e.options.delay.show)return e.show();
35
+ clearTimeout(this.timeout), e.hoverState = "in", this.timeout = setTimeout(function () {
36
+ e.hoverState == "in" && e.show()
37
+ }, e.options.delay.show)
38
+ }, leave: function (b) {
39
+ var c = a(b.currentTarget)[this.type](this._options).data(this.type);
40
+ this.timeout && clearTimeout(this.timeout);
41
+ if (!c.options.delay || !c.options.delay.hide)return c.hide();
42
+ c.hoverState = "out", this.timeout = setTimeout(function () {
43
+ c.hoverState == "out" && c.hide()
44
+ }, c.options.delay.hide)
45
+ }, show: function () {
46
+ var b, c, d, e, f, g, h = a.Event("show");
47
+ if (this.hasContent() && this.enabled) {
48
+ this.$element.trigger(h);
49
+ if (h.isDefaultPrevented())return;
50
+ b = this.tip(), this.setContent(), this.options.animation && b.addClass("fade"), f = typeof this.options.placement == "function" ? this.options.placement.call(this, b[0], this.$element[0]) : this.options.placement, b.detach().css({top: 0, left: 0, display: "block"}), this.options.container ? b.appendTo(this.options.container) : b.insertAfter(this.$element), c = this.getPosition(), d = b[0].offsetWidth, e = b[0].offsetHeight;
51
+ switch (f) {
52
+ case"bottom":
53
+ g = {top: c.top + c.height, left: c.left + c.width / 2 - d / 2};
54
+ break;
55
+ case"top":
56
+ g = {top: c.top - e, left: c.left + c.width / 2 - d / 2};
57
+ break;
58
+ case"left":
59
+ g = {top: c.top + c.height / 2 - e / 2, left: c.left - d};
60
+ break;
61
+ case"right":
62
+ g = {top: c.top + c.height / 2 - e / 2, left: c.left + c.width}
63
+ }
64
+ this.applyPlacement(g, f), this.$element.trigger("shown")
65
+ }
66
+ }, applyPlacement: function (a, b) {
67
+ var c = this.tip(), d = c[0].offsetWidth, e = c[0].offsetHeight, f, g, h, i;
68
+ c.offset(a).addClass(b).addClass("in"), f = c[0].offsetWidth, g = c[0].offsetHeight, b == "top" && g != e && (a.top = a.top + e - g, i = !0), b == "bottom" || b == "top" ? (h = 0, a.left < 0 && (h = a.left * -2, a.left = 0, c.offset(a), f = c[0].offsetWidth, g = c[0].offsetHeight), this.replaceArrow(h - d + f, f, "left")) : this.replaceArrow(g - e, g, "top"), i && c.offset(a)
69
+ }, replaceArrow: function (a, b, c) {
70
+ this.arrow().css(c, a ? 50 * (1 - a / b) + "%" : "")
71
+ }, setContent: function () {
72
+ var a = this.tip(), b = this.getTitle();
73
+ a.find(".tooltip-inner")[this.options.html ? "html" : "text"](b), a.removeClass("fade in top bottom left right")
74
+ }, hide: function () {
75
+ function e() {
76
+ var b = setTimeout(function () {
77
+ c.off(a.support.transition.end).detach()
78
+ }, 500);
79
+ c.one(a.support.transition.end, function () {
80
+ clearTimeout(b), c.detach()
81
+ })
82
+ }
83
+
84
+ var b = this, c = this.tip(), d = a.Event("hide");
85
+ this.$element.trigger(d);
86
+ if (d.isDefaultPrevented())return;
87
+ return c.removeClass("in"), a.support.transition && this.$tip.hasClass("fade") ? e() : c.detach(), this.$element.trigger("hidden"), this
88
+ }, fixTitle: function () {
89
+ var a = this.$element;
90
+ (a.attr("title") || typeof a.attr("data-original-title") != "string") && a.attr("data-original-title", a.attr("title") || "").attr("title", "")
91
+ }, hasContent: function () {
92
+ return this.getTitle()
93
+ }, getPosition: function () {
94
+ var b = this.$element[0];
95
+ return a.extend({}, typeof b.getBoundingClientRect == "function" ? b.getBoundingClientRect() : {width: b.offsetWidth, height: b.offsetHeight}, this.$element.offset())
96
+ }, getTitle: function () {
97
+ var a, b = this.$element, c = this.options;
98
+ return a = b.attr("data-original-title") || (typeof c.title == "function" ? c.title.call(b[0]) : c.title), a
99
+ }, tip: function () {
100
+ return this.$tip = this.$tip || a(this.options.template)
101
+ }, arrow: function () {
102
+ return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
103
+ }, validate: function () {
104
+ this.$element[0].parentNode || (this.hide(), this.$element = null, this.options = null)
105
+ }, enable: function () {
106
+ this.enabled = !0
107
+ }, disable: function () {
108
+ this.enabled = !1
109
+ }, toggleEnabled: function () {
110
+ this.enabled = !this.enabled
111
+ }, toggle: function (b) {
112
+ var c = b ? a(b.currentTarget)[this.type](this._options).data(this.type) : this;
113
+ c.tip().hasClass("in") ? c.hide() : c.show()
114
+ }, destroy: function () {
115
+ this.hide().$element.off("." + this.type).removeData(this.type)
116
+ }};
117
+ var c = a.fn.tooltip;
118
+ a.fn.tooltip = function (c) {
119
+ return this.each(function () {
120
+ var d = a(this), e = d.data("tooltip"), f = typeof c == "object" && c;
121
+ e || d.data("tooltip", e = new b(this, f)), typeof c == "string" && e[c]()
122
+ })
123
+ }, a.fn.tooltip.Constructor = b, a.fn.tooltip.defaults = {animation: !0, placement: "top", selector: !1, template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', trigger: "hover focus", title: "", delay: 0, html: !1, container: !1}, a.fn.tooltip.noConflict = function () {
124
+ return a.fn.tooltip = c, this
125
+ }
126
+ }(window.jQuery)
trunk/WCVendors/classes/admin/settings/assets/js/js.iml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <module type="WEB_MODULE" version="4">
3
+ <component name="NewModuleRootManager" inherit-compiler-output="true">
4
+ <exclude-output />
5
+ <content url="file://$MODULE_DIR$" />
6
+ <orderEntry type="inheritedJdk" />
7
+ <orderEntry type="sourceFolder" forTests="false" />
8
+ </component>
9
+ </module>
10
+
trunk/WCVendors/classes/admin/settings/assets/js/select2/select2.css ADDED
@@ -0,0 +1,564 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Version: @@ver@@ Timestamp: @@timestamp@@
3
+ */
4
+ .select2-container {
5
+ position: relative;
6
+ display: inline-block;
7
+ /* inline-block for ie7 */
8
+ zoom: 1;
9
+ *display: inline;
10
+ vertical-align: top;
11
+ }
12
+
13
+ .select2-container,
14
+ .select2-drop,
15
+ .select2-search,
16
+ .select2-search input {
17
+ /*
18
+ Force border-box so that % widths fit the parent
19
+ container without overlap because of margin/padding.
20
+
21
+ More Info : http://www.quirksmode.org/css/box.html
22
+ */
23
+ -moz-box-sizing: border-box; /* firefox */
24
+ -ms-box-sizing: border-box; /* ie */
25
+ -webkit-box-sizing: border-box; /* webkit */
26
+ -khtml-box-sizing: border-box; /* konqueror */
27
+ box-sizing: border-box; /* css3 */
28
+ }
29
+
30
+ .select2-container .select2-choice {
31
+ background-color: #fff;
32
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.5, white));
33
+ background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 50%);
34
+ background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 50%);
35
+ background-image: -o-linear-gradient(bottom, #eeeeee 0%, #ffffff 50%);
36
+ background-image: -ms-linear-gradient(top, #eeeeee 0%, #ffffff 50%);
37
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
38
+ background-image: linear-gradient(top, #eeeeee 0%, #ffffff 50%);
39
+ -webkit-border-radius: 4px;
40
+ -moz-border-radius: 4px;
41
+ border-radius: 4px;
42
+ -moz-background-clip: padding;
43
+ -webkit-background-clip: padding-box;
44
+ background-clip: padding-box;
45
+ border: 1px solid #aaa;
46
+ display: block;
47
+ overflow: hidden;
48
+ white-space: nowrap;
49
+ position: relative;
50
+ height: 26px;
51
+ line-height: 26px;
52
+ padding: 0 0 0 8px;
53
+ color: #444;
54
+ text-decoration: none;
55
+ }
56
+
57
+ .select2-container.select2-drop-above .select2-choice {
58
+ border-bottom-color: #aaa;
59
+ -webkit-border-radius: 0px 0px 4px 4px;
60
+ -moz-border-radius: 0px 0px 4px 4px;
61
+ border-radius: 0px 0px 4px 4px;
62
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(0.9, white));
63
+ background-image: -webkit-linear-gradient(center bottom, #eeeeee 0%, white 90%);
64
+ background-image: -moz-linear-gradient(center bottom, #eeeeee 0%, white 90%);
65
+ background-image: -o-linear-gradient(bottom, #eeeeee 0%, white 90%);
66
+ background-image: -ms-linear-gradient(top, #eeeeee 0%, #ffffff 90%);
67
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
68
+ background-image: linear-gradient(top, #eeeeee 0%, #ffffff 90%);
69
+ }
70
+
71
+ .select2-container .select2-choice span {
72
+ margin-right: 26px;
73
+ display: block;
74
+ overflow: hidden;
75
+ white-space: nowrap;
76
+ -o-text-overflow: ellipsis;
77
+ -ms-text-overflow: ellipsis;
78
+ text-overflow: ellipsis;
79
+ }
80
+
81
+ .select2-container .select2-choice abbr {
82
+ display: block;
83
+ position: absolute;
84
+ right: 26px;
85
+ top: 8px;
86
+ width: 12px;
87
+ height: 12px;
88
+ font-size: 1px;
89
+ background: url('select2.png') right top no-repeat;
90
+ cursor: pointer;
91
+ text-decoration: none;
92
+ border: 0;
93
+ outline: 0;
94
+ }
95
+
96
+ .select2-container .select2-choice abbr:hover {
97
+ background-position: right -11px;
98
+ cursor: pointer;
99
+ }
100
+
101
+ .select2-drop {
102
+ background: #fff;
103
+ color: #000;
104
+ border: 1px solid #aaa;
105
+ border-top: 0;
106
+ position: absolute;
107
+ top: 100%;
108
+ -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
109
+ -moz-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
110
+ -o-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
111
+ box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
112
+ z-index: 9999;
113
+ width: 100%;
114
+ margin-top: -1px;
115
+
116
+ -webkit-border-radius: 0 0 4px 4px;
117
+ -moz-border-radius: 0 0 4px 4px;
118
+ border-radius: 0 0 4px 4px;
119
+ }
120
+
121
+ .select2-drop.select2-drop-above {
122
+ -webkit-border-radius: 4px 4px 0px 0px;
123
+ -moz-border-radius: 4px 4px 0px 0px;
124
+ border-radius: 4px 4px 0px 0px;
125
+ margin-top: 1px;
126
+ border-top: 1px solid #aaa;
127
+ border-bottom: 0;
128
+
129
+ -webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
130
+ -moz-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
131
+ -o-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
132
+ box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
133
+ }
134
+
135
+ .select2-container .select2-choice div {
136
+ -webkit-border-radius: 0 4px 4px 0;
137
+ -moz-border-radius: 0 4px 4px 0;
138
+ border-radius: 0 4px 4px 0;
139
+ -moz-background-clip: padding;
140
+ -webkit-background-clip: padding-box;
141
+ background-clip: padding-box;
142
+ background: #ccc;
143
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee));
144
+ background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%);
145
+ background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%);
146
+ background-image: -o-linear-gradient(bottom, #ccc 0%, #eee 60%);
147
+ background-image: -ms-linear-gradient(top, #cccccc 0%, #eeeeee 60%);
148
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cccccc', endColorstr='#eeeeee', GradientType=0);
149
+ background-image: linear-gradient(top, #cccccc 0%, #eeeeee 60%);
150
+ border-left: 1px solid #aaa;
151
+ position: absolute;
152
+ right: 0;
153
+ top: 0;
154
+ display: block;
155
+ height: 100%;
156
+ width: 18px;
157
+ }
158
+
159
+ .select2-container .select2-choice div b {
160
+ background: url('select2.png') no-repeat 0 1px;
161
+ display: block;
162
+ width: 100%;
163
+ height: 100%;
164
+ }
165
+
166
+ .select2-search {
167
+ display: inline-block;
168
+ white-space: nowrap;
169
+ z-index: 10000;
170
+ position: relative;
171
+ min-height: 26px;
172
+ width: 100%;
173
+ margin: 0;
174
+ padding-left: 4px;
175
+ padding-right: 4px;
176
+ }
177
+
178
+ .select2-search-hidden {
179
+ display: block;
180
+ position: absolute;
181
+ left: -10000px;
182
+ }
183
+
184
+ .select2-search input {
185
+ background: #fff url('select2.png') no-repeat 100% -22px;
186
+ background: url('select2.png') no-repeat 100% -22px, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
187
+ background: url('select2.png') no-repeat 100% -22px, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
188
+ background: url('select2.png') no-repeat 100% -22px, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
189
+ background: url('select2.png') no-repeat 100% -22px, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
190
+ background: url('select2.png') no-repeat 100% -22px, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
191
+ background: url('select2.png') no-repeat 100% -22px, linear-gradient(top, #ffffff 85%, #eeeeee 99%);
192
+ padding: 4px 20px 4px 5px;
193
+ outline: 0;
194
+ border: 1px solid #aaa;
195
+ font-family: sans-serif;
196
+ font-size: 1em;
197
+ width: 100%;
198
+ margin: 0;
199
+ height: auto !important;
200
+ min-height: 26px;
201
+ -webkit-box-shadow: none;
202
+ -moz-box-shadow: none;
203
+ box-shadow: none;
204
+ border-radius: 0;
205
+ -moz-border-radius: 0;
206
+ -webkit-border-radius: 0;
207
+ }
208
+
209
+ .select2-drop.select2-drop-above .select2-search input {
210
+ margin-top: 4px;
211
+ }
212
+
213
+ .select2-search input.select2-active {
214
+ background: #fff url('spinner.gif') no-repeat 100%;
215
+ background: url('spinner.gif') no-repeat 100%, -webkit-gradient(linear, left bottom, left top, color-stop(0.85, white), color-stop(0.99, #eeeeee));
216
+ background: url('spinner.gif') no-repeat 100%, -webkit-linear-gradient(center bottom, white 85%, #eeeeee 99%);
217
+ background: url('spinner.gif') no-repeat 100%, -moz-linear-gradient(center bottom, white 85%, #eeeeee 99%);
218
+ background: url('spinner.gif') no-repeat 100%, -o-linear-gradient(bottom, white 85%, #eeeeee 99%);
219
+ background: url('spinner.gif') no-repeat 100%, -ms-linear-gradient(top, #ffffff 85%, #eeeeee 99%);
220
+ background: url('spinner.gif') no-repeat 100%, linear-gradient(top, #ffffff 85%, #eeeeee 99%);
221
+ }
222
+
223
+ .select2-container-active .select2-choice,
224
+ .select2-container-active .select2-choices {
225
+ -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
226
+ -moz-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
227
+ -o-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
228
+ box-shadow: 0 0 5px rgba(0, 0, 0, .3);
229
+ border: 1px solid #5897fb;
230
+ outline: none;
231
+ }
232
+
233
+ .select2-dropdown-open .select2-choice {
234
+ border: 1px solid #aaa;
235
+ border-bottom-color: transparent;
236
+ -webkit-box-shadow: 0 1px 0 #fff inset;
237
+ -moz-box-shadow: 0 1px 0 #fff inset;
238
+ -o-box-shadow: 0 1px 0 #fff inset;
239
+ box-shadow: 0 1px 0 #fff inset;
240
+ background-color: #eee;
241
+ background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, white), color-stop(0.5, #eeeeee));
242
+ background-image: -webkit-linear-gradient(center bottom, white 0%, #eeeeee 50%);
243
+ background-image: -moz-linear-gradient(center bottom, white 0%, #eeeeee 50%);
244
+ background-image: -o-linear-gradient(bottom, white 0%, #eeeeee 50%);
245
+ background-image: -ms-linear-gradient(top, #ffffff 0%, #eeeeee 50%);
246
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
247
+ background-image: linear-gradient(top, #ffffff 0%, #eeeeee 50%);
248
+ -webkit-border-bottom-left-radius: 0;
249
+ -webkit-border-bottom-right-radius: 0;
250
+ -moz-border-radius-bottomleft: 0;
251
+ -moz-border-radius-bottomright: 0;
252
+ border-bottom-left-radius: 0;
253
+ border-bottom-right-radius: 0;
254
+ }
255
+
256
+ .select2-dropdown-open .select2-choice div {
257
+ background: transparent;
258
+ border-left: none;
259
+ }
260
+
261
+ .select2-dropdown-open .select2-choice div b {
262
+ background-position: -18px 1px;
263
+ }
264
+
265
+ /* results */
266
+ .select2-results {
267
+ margin: 4px 4px 4px 0;
268
+ padding: 0 0 0 4px;
269
+ position: relative;
270
+ overflow-x: hidden;
271
+ overflow-y: auto;
272
+ max-height: 200px;
273
+ }
274
+
275
+ .select2-results ul.select2-result-sub {
276
+ margin: 0 0 0 0;
277
+ }
278
+
279
+ .select2-results ul.select2-result-sub > li .select2-result-label {
280
+ padding-left: 20px
281
+ }
282
+
283
+ .select2-results ul.select2-result-sub ul.select2-result-sub > li .select2-result-label {
284
+ padding-left: 40px
285
+ }
286
+
287
+ .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label {
288
+ padding-left: 60px
289
+ }
290
+
291
+ .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label {
292
+ padding-left: 80px
293
+ }
294
+
295
+ .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label {
296
+ padding-left: 100px
297
+ }
298
+
299
+ .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label {
300
+ padding-left: 110px
301
+ }
302
+
303
+ .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label {
304
+ padding-left: 120px
305
+ }
306
+
307
+ .select2-results li {
308
+ list-style: none;
309
+ display: list-item;
310
+ }
311
+
312
+ .select2-results li.select2-result-with-children > .select2-result-label {
313
+ font-weight: bold;
314
+ }
315
+
316
+ .select2-results .select2-result-label {
317
+ padding: 3px 7px 4px;
318
+ margin: 0;
319
+ cursor: pointer;
320
+ }
321
+
322
+ .select2-results .select2-highlighted {
323
+ background: #3875d7;
324
+ color: #fff;
325
+ }
326
+
327
+ .select2-results li em {
328
+ background: #feffde;
329
+ font-style: normal;
330
+ }
331
+
332
+ .select2-results .select2-highlighted em {
333
+ background: transparent;
334
+ }
335
+
336
+ .select2-results .select2-no-results,
337
+ .select2-results .select2-searching,
338
+ .select2-results .select2-selection-limit {
339
+ background: #f4f4f4;
340
+ display: list-item;
341
+ }
342
+
343
+ /*
344
+ disabled look for already selected choices in the results dropdown
345
+ .select2-results .select2-disabled.select2-highlighted {
346
+ color: #666;
347
+ background: #f4f4f4;
348
+ display: list-item;
349
+ cursor: default;
350
+ }
351
+ .select2-results .select2-disabled {
352
+ background: #f4f4f4;
353
+ display: list-item;
354
+ cursor: default;
355
+ }
356
+ */
357
+ .select2-results .select2-disabled {
358
+ display: none;
359
+ }
360
+
361
+ .select2-more-results.select2-active {
362
+ background: #f4f4f4 url('spinner.gif') no-repeat 100%;
363
+ }
364
+
365
+ .select2-more-results {
366
+ background: #f4f4f4;
367
+ display: list-item;
368
+ }
369
+
370
+ /* disabled styles */
371
+
372
+ .select2-container.select2-container-disabled .select2-choice {
373
+ background-color: #f4f4f4;
374
+ background-image: none;
375
+ border: 1px solid #ddd;
376
+ cursor: default;
377
+ }
378
+
379
+ .select2-container.select2-container-disabled .select2-choice div {
380
+ background-color: #f4f4f4;
381
+ background-image: none;
382
+ border-left: 0;
383
+ }
384
+
385
+ .select2-container.select2-container-disabled .select2-choice abbr {
386
+ display: none
387
+ }
388
+
389
+ /* multiselect */
390
+
391
+ .select2-container-multi .select2-choices {
392
+ background-color: #fff;
393
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
394
+ background-image: -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
395
+ background-image: -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
396
+ background-image: -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
397
+ background-image: -ms-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
398
+ background-image: linear-gradient(top, #eeeeee 1%, #ffffff 15%);
399
+ border: 1px solid #aaa;
400
+ margin: 0;
401
+ padding: 0;
402
+ cursor: text;
403
+ overflow: hidden;
404
+ height: auto !important;
405
+ height: 1%;
406
+ position: relative;
407
+ }
408
+
409
+ .select2-container-multi .select2-choices {
410
+ min-height: 26px;
411
+ }
412
+
413
+ .select2-container-multi.select2-container-active .select2-choices {
414
+ -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
415
+ -moz-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
416
+ -o-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
417
+ box-shadow: 0 0 5px rgba(0, 0, 0, .3);
418
+ border: 1px solid #5897fb;
419
+ outline: none;
420
+ }
421
+
422
+ .select2-container-multi .select2-choices li {
423
+ float: left;
424
+ list-style: none;
425
+ }
426
+
427
+ .select2-container-multi .select2-choices .select2-search-field {
428
+ white-space: nowrap;
429
+ margin: 0;
430
+ padding: 0;
431
+ }
432
+
433
+ .select2-container-multi .select2-choices .select2-search-field input {
434
+ color: #666;
435
+ background: transparent !important;
436
+ font-family: sans-serif;
437
+ font-size: 100%;
438
+ height: 15px;
439
+ padding: 5px;
440
+ margin: 1px 0;
441
+ outline: 0;
442
+ border: 0;
443
+ -webkit-box-shadow: none;
444
+ -moz-box-shadow: none;
445
+ -o-box-shadow: none;
446
+ box-shadow: none;
447
+ }
448
+
449
+ .select2-container-multi .select2-choices .select2-search-field input.select2-active {
450
+ background: #fff url('spinner.gif') no-repeat 100% !important;
451
+ }
452
+
453
+ .select2-default {
454
+ color: #999 !important;
455
+ }
456
+
457
+ .select2-container-multi .select2-choices .select2-search-choice {
458
+ -webkit-border-radius: 3px;
459
+ -moz-border-radius: 3px;
460
+ border-radius: 3px;
461
+ -moz-background-clip: padding;
462
+ -webkit-background-clip: padding-box;
463
+ background-clip: padding-box;
464
+ background-color: #e4e4e4;
465
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0);
466
+ background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
467
+ background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
468
+ background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
469
+ background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
470
+ background-image: -ms-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
471
+ background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
472
+ -webkit-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
473
+ -moz-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
474
+ box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
475
+ color: #333;
476
+ border: 1px solid #aaaaaa;
477
+ line-height: 13px;
478
+ padding: 3px 5px 3px 18px;
479
+ margin: 3px 0 3px 5px;
480
+ position: relative;
481
+ cursor: default;
482
+ }
483
+
484
+ .select2-container-multi .select2-choices .select2-search-choice span {
485
+ cursor: default;
486
+ }
487
+
488
+ .select2-container-multi .select2-choices .select2-search-choice-focus {
489
+ background: #d4d4d4;
490
+ }
491
+
492
+ .select2-search-choice-close {
493
+ display: block;
494
+ position: absolute;
495
+ right: 3px;
496
+ top: 4px;
497
+ width: 12px;
498
+ height: 13px;
499
+ font-size: 1px;
500
+ background: url('select2.png') right top no-repeat;
501
+ outline: none;
502
+ }
503
+
504
+ .select2-container-multi .select2-search-choice-close {
505
+ left: 3px;
506
+ }
507
+
508
+ .select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover {
509
+ background-position: right -11px;
510
+ }
511
+
512
+ .select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close {
513
+ background-position: right -11px;
514
+ }
515
+
516
+ /* disabled styles */
517
+
518
+ .select2-container-multi.select2-container-disabled .select2-choices {
519
+ background-color: #f4f4f4;
520
+ background-image: none;
521
+ border: 1px solid #ddd;
522
+ cursor: default;
523
+ }
524
+
525
+ .select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice {
526
+ background-image: none;
527
+ background-color: #f4f4f4;
528
+ border: 1px solid #ddd;
529
+ padding: 3px 5px 3px 5px;
530
+ }
531
+
532
+ .select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close {
533
+ display: none;
534
+ }
535
+
536
+ /* end multiselect */
537
+
538
+ .select2-result-selectable .select2-match,
539
+ .select2-result-unselectable .select2-result-selectable .select2-match {
540
+ text-decoration: underline;
541
+ }
542
+
543
+ .select2-result-unselectable .select2-match {
544
+ text-decoration: none;
545
+ }
546
+
547
+ .select2-offscreen {
548
+ position: absolute;
549
+ left: -10000px;
550
+ }
551
+
552
+ /* Retina-ize icons */
553
+
554
+ @media only screen and (-webkit-min-device-pixel-ratio: 1.5) {
555
+ .select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice div b {
556
+ background-image: url('select2x2.png') !important;
557
+ background-repeat: no-repeat !important;
558
+ background-size: 60px 40px !important;
559
+ }
560
+
561
+ .select2-search input {
562
+ background-position: 100% -21px !important;
563
+ }
564
+ }
trunk/WCVendors/classes/admin/settings/assets/js/select2/select2.js ADDED
@@ -0,0 +1,2506 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Copyright 2012 Igor Vaynberg
3
+
4
+ Version: @@ver@@ Timestamp: @@timestamp@@
5
+
6
+ This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
7
+ General Public License version 2 (the "GPL License"). You may choose either license to govern your
8
+ use of this software only upon the condition that you accept all of the terms of either the Apache
9
+ License or the GPL License.
10
+
11
+ You may obtain a copy of the Apache License and the GPL License at:
12
+
13
+ http://www.apache.org/licenses/LICENSE-2.0
14
+ http://www.gnu.org/licenses/gpl-2.0.html
15
+
16
+ Unless required by applicable law or agreed to in writing, software distributed under the
17
+ Apache License or the GPL Licesnse is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
18
+ CONDITIONS OF ANY KIND, either express or implied. See the Apache License and the GPL License for
19
+ the specific language governing permissions and limitations under the Apache License and the GPL License.
20
+ */
21
+ (function ($) {
22
+ if (typeof $.fn.each2 == "undefined") {
23
+ $.fn.extend({
24
+ /*
25
+ * 4-10 times faster .each replacement
26
+ * use it carefully, as it overrides jQuery context of element on each iteration
27
+ */
28
+ each2: function (c) {
29
+ var j = $([0]), i = -1, l = this.length;
30
+ while (
31
+ ++i < l
32
+ && (j.context = j[0] = this[i])
33
+ && c.call(j[0], i, j) !== false //"this"=DOM, i=index, j=jQuery object
34
+ );
35
+ return this;
36
+ }
37
+ });
38
+ }
39
+ })(jQuery);
40
+
41
+ (function ($, undefined) {
42
+ "use strict";
43
+ /*global document, window, jQuery, console */
44
+
45
+ if (window.Select2 !== undefined) {
46
+ return;
47
+ }
48
+
49
+ var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer,
50
+ lastMousePosition, $document;
51
+
52
+ KEY = {
53
+ TAB: 9,
54
+ ENTER: 13,
55
+ ESC: 27,
56
+ SPACE: 32,
57
+ LEFT: 37,
58
+ UP: 38,
59
+ RIGHT: 39,
60
+ DOWN: 40,
61
+ SHIFT: 16,
62
+ CTRL: 17,
63
+ ALT: 18,
64
+ PAGE_UP: 33,
65
+ PAGE_DOWN: 34,
66
+ HOME: 36,
67
+ END: 35,
68
+ BACKSPACE: 8,
69
+ DELETE: 46,
70
+ isArrow: function (k) {
71
+ k = k.which ? k.which : k;
72
+ switch (k) {
73
+ case KEY.LEFT:
74
+ case KEY.RIGHT:
75
+ case KEY.UP:
76
+ case KEY.DOWN:
77
+ return true;
78
+ }
79
+ return false;
80
+ },
81
+ isControl: function (e) {
82
+ var k = e.which;
83
+ switch (k) {
84
+ case KEY.SHIFT:
85
+ case KEY.CTRL:
86
+ case KEY.ALT:
87
+ return true;
88
+ }
89
+
90
+ if (e.metaKey) return true;
91
+
92
+ return false;
93
+ },
94
+ isFunctionKey: function (k) {
95
+ k = k.which ? k.which : k;
96
+ return k >= 112 && k <= 123;
97
+ }
98
+ };
99
+
100
+ $document = $(document);
101
+
102
+ nextUid = (function () {
103
+ var counter = 1;
104
+ return function () {
105
+ return counter++;
106
+ };
107
+ }());
108
+
109
+ function indexOf(value, array) {
110
+ var i = 0, l = array.length, v;
111
+
112
+ if (typeof value === "undefined") {
113
+ return -1;
114
+ }
115
+
116
+ if (value.constructor === String) {
117
+ for (; i < l; i = i + 1) if (value.localeCompare(array[i]) === 0) return i;
118
+ } else {
119
+ for (; i < l; i = i + 1) {
120
+ v = array[i];
121
+ if (v.constructor === String) {
122
+ if (v.localeCompare(value) === 0) return i;
123
+ } else {
124
+ if (v === value) return i;
125
+ }
126
+ }
127
+ }
128
+ return -1;
129
+ }
130
+
131
+ /**
132
+ * Compares equality of a and b taking into account that a and b may be strings, in which case localeCompare is used
133
+ * @param a
134
+ * @param b
135
+ */
136
+ function equal(a, b) {
137
+ if (a === b) return true;
138
+ if (a === undefined || b === undefined) return false;
139
+ if (a === null || b === null) return false;
140
+ if (a.constructor === String) return a.localeCompare(b) === 0;
141
+ if (b.constructor === String) return b.localeCompare(a) === 0;
142
+ return false;
143
+ }
144
+
145
+ /**
146
+ * Splits the string into an array of values, trimming each value. An empty array is returned for nulls or empty
147
+ * strings
148
+ * @param string
149
+ * @param separator
150
+ */
151
+ function splitVal(string, separator) {
152
+ var val, i, l;
153
+ if (string === null || string.length < 1) return [];
154
+ val = string.split(separator);
155
+ for (i = 0, l = val.length; i < l; i = i + 1) val[i] = $.trim(val[i]);
156
+ return val;
157
+ }
158
+
159
+ function getSideBorderPadding(element) {
160
+ return element.outerWidth(false) - element.width();
161
+ }
162
+
163
+ function installKeyUpChangeEvent(element) {
164
+ var key = "keyup-change-value";
165
+ element.bind("keydown", function () {
166
+ if ($.data(element, key) === undefined) {
167
+ $.data(element, key, element.val());
168
+ }
169
+ });
170
+ element.bind("keyup", function () {
171
+ var val = $.data(element, key);
172
+ if (val !== undefined && element.val() !== val) {
173
+ $.removeData(element, key);
174
+ element.trigger("keyup-change");
175
+ }
176
+ });
177
+ }
178
+
179
+ $document.bind("mousemove", function (e) {
180
+ lastMousePosition = {x: e.pageX, y: e.pageY};
181
+ });
182
+
183
+ /**
184
+ * filters mouse events so an event is fired only if the mouse moved.
185
+ *
186
+ * filters out mouse events that occur when mouse is stationary but
187
+ * the elements under the pointer are scrolled.
188
+ */
189
+ function installFilteredMouseMove(element) {
190
+ element.bind("mousemove", function (e) {
191
+ var lastpos = lastMousePosition;
192
+ if (lastpos === undefined || lastpos.x !== e.pageX || lastpos.y !== e.pageY) {
193
+ $(e.target).trigger("mousemove-filtered", e);
194
+ }
195
+ });
196
+ }
197
+
198
+ /**
199
+ * Debounces a function. Returns a function that calls the original fn function only if no invocations have been made
200
+ * within the last quietMillis milliseconds.
201
+ *
202
+ * @param quietMillis number of milliseconds to wait before invoking fn
203
+ * @param fn function to be debounced
204
+ * @param ctx object to be used as this reference within fn
205
+ * @return debounced version of fn
206
+ */
207
+ function debounce(quietMillis, fn, ctx) {
208
+ ctx = ctx || undefined;
209
+ var timeout;
210
+ return function () {
211
+ var args = arguments;
212
+ window.clearTimeout(timeout);
213
+ timeout = window.setTimeout(function () {
214
+ fn.apply(ctx, args);
215
+ }, quietMillis);
216
+ };
217
+ }
218
+
219
+ /**
220
+ * A simple implementation of a thunk
221
+ * @param formula function used to lazily initialize the thunk
222
+ * @return {Function}
223
+ */
224
+ function thunk(formula) {
225
+ var evaluated = false,
226
+ value;
227
+ return function () {
228
+ if (evaluated === false) {
229
+ value = formula();
230
+ evaluated = true;
231
+ }
232
+ return value;
233
+ };
234
+ };
235
+
236
+ function installDebouncedScroll(threshold, element) {
237
+ var notify = debounce(threshold, function (e) {
238
+ element.trigger("scroll-debounced", e);
239
+ });
240
+ element.bind("scroll", function (e) {
241
+ if (indexOf(e.target, element.get()) >= 0) notify(e);
242
+ });
243
+ }
244
+
245
+ function killEvent(event) {
246
+ event.preventDefault();
247
+ event.stopPropagation();
248
+ }
249
+
250
+ function killEventImmediately(event) {
251
+ event.preventDefault();
252
+ event.stopImmediatePropagation();
253
+ }
254
+
255
+ function measureTextWidth(e) {
256
+ if (!sizer) {
257
+ var style = e[0].currentStyle || window.getComputedStyle(e[0], null);
258
+ sizer = $("<div></div>").css({
259
+ position: "absolute",
260
+ left: "-10000px",
261
+ top: "-10000px",
262
+ display: "none",
263
+ fontSize: style.fontSize,
264
+ fontFamily: style.fontFamily,
265
+ fontStyle: style.fontStyle,
266
+ fontWeight: style.fontWeight,
267
+ letterSpacing: style.letterSpacing,
268
+ textTransform: style.textTransform,
269
+ whiteSpace: "nowrap"
270
+ });
271
+ $("body").append(sizer);
272
+ }
273
+ sizer.text(e.val());
274
+ return sizer.width();
275
+ }
276
+
277
+ function markMatch(text, term, markup) {
278
+ var match = text.toUpperCase().indexOf(term.toUpperCase()),
279
+ tl = term.length;
280
+
281
+ if (match < 0) {
282
+ markup.push(text);
283
+ return;
284
+ }
285
+
286
+ markup.push(text.substring(0, match));
287
+ markup.push("<span class='select2-match'>");
288
+ markup.push(text.substring(match, match + tl));
289
+ markup.push("</span>");
290
+ markup.push(text.substring(match + tl, text.length));
291
+ }
292
+
293
+ /**
294
+ * Produces an ajax-based query function
295
+ *
296
+ * @param options object containing configuration paramters
297
+ * @param options.transport function that will be used to execute the ajax request. must be compatible with parameters supported by $.ajax
298
+ * @param options.url url for the data
299
+ * @param options.data a function(searchTerm, pageNumber, context) that should return an object containing query string parameters for the above url.
300
+ * @param options.dataType request data type: ajax, jsonp, other datatatypes supported by jQuery's $.ajax function or the transport function if specified
301
+ * @param options.traditional a boolean flag that should be true if you wish to use the traditional style of param serialization for the ajax request
302
+ * @param options.quietMillis (optional) milliseconds to wait before making the ajaxRequest, helps debounce the ajax function if invoked too often
303
+ * @param options.results a function(remoteData, pageNumber) that converts data returned form the remote request to the format expected by Select2.
304
+ * The expected format is an object containing the following keys:
305
+ * results array of objects that will be used as choices
306
+ * more (optional) boolean indicating whether there are more results available
307
+ * Example: {results:[{id:1, text:'Red'},{id:2, text:'Blue'}], more:true}
308
+ */
309
+ function ajax(options) {
310
+ var timeout, // current scheduled but not yet executed request
311
+ requestSequence = 0, // sequence used to drop out-of-order responses
312
+ handler = null,
313
+ quietMillis = options.quietMillis || 100;
314
+
315
+ return function (query) {
316
+ window.clearTimeout(timeout);
317
+ timeout = window.setTimeout(function () {
318
+ requestSequence += 1; // increment the sequence
319
+ var requestNumber = requestSequence, // this request's sequence number
320
+ data = options.data, // ajax data function
321
+ transport = options.transport || $.ajax,
322
+ traditional = options.traditional || false,
323
+ type = options.type || 'GET'; // set type of request (GET or POST)
324
+
325
+ data = data.call(this, query.term, query.page, query.context);
326
+
327
+ if (null !== handler) {
328
+ handler.abort();
329
+ }
330
+
331
+ handler = transport.call(null, {
332
+ url: options.url,
333
+ dataType: options.dataType,
334
+ data: data,
335
+ type: type,
336
+ traditional: traditional,
337
+ success: function (data) {
338
+ if (requestNumber < requestSequence) {
339
+ return;
340
+ }
341
+ // TODO 3.0 - replace query.page with query so users have access to term, page, etc.
342
+ var results = options.results(data, query.page);
343
+ query.callback(results);
344
+ }
345
+ });
346
+ }, quietMillis);
347
+ };
348
+ }
349
+
350
+ /**
351
+ * Produces a query function that works with a local array
352
+ *
353
+ * @param options object containing configuration parameters. The options parameter can either be an array or an
354
+ * object.
355
+ *
356
+ * If the array form is used it is assumed that it contains objects with 'id' and 'text' keys.
357
+ *
358
+ * If the object form is used ti is assumed that it contains 'data' and 'text' keys. The 'data' key should contain
359
+ * an array of objects that will be used as choices. These objects must contain at least an 'id' key. The 'text'
360
+ * key can either be a String in which case it is expected that each element in the 'data' array has a key with the
361
+ * value of 'text' which will be used to match choices. Alternatively, text can be a function(item) that can extract
362
+ * the text.
363
+ */
364
+ function local(options) {
365
+ var data = options, // data elements
366
+ dataText,
367
+ text = function (item) {
368
+ return "" + item.text;
369
+ }; // function used to retrieve the text portion of a data item that is matched against the search
370
+
371
+ if (!$.isArray(data)) {
372
+ text = data.text;
373
+ // if text is not a function we assume it to be a key name
374
+ if (!$.isFunction(text)) {
375
+ dataText = data.text; // we need to store this in a separate variable because in the next step data gets reset and data.text is no longer available
376
+ text = function (item) {
377
+ return item[dataText];
378
+ };
379
+ }
380
+ data = data.results;
381
+ }
382
+
383
+ return function (query) {
384
+ var t = query.term, filtered = { results: [] }, process;
385
+ if (t === "") {
386
+ query.callback({results: data});
387
+ return;
388
+ }
389
+
390
+ process = function (datum, collection) {
391
+ var group, attr;
392
+ datum = datum[0];
393
+ if (datum.children) {
394
+ group = {};
395
+ for (attr in datum) {
396
+ if (datum.hasOwnProperty(attr)) group[attr] = datum[attr];
397
+ }
398
+ group.children = [];
399
+ $(datum.children).each2(function (i, childDatum) {
400
+ process(childDatum, group.children);
401
+ });
402
+ if (group.children.length) {
403
+ collection.push(group);
404
+ }
405
+ } else {
406
+ if (query.matcher(t, text(datum))) {
407
+ collection.push(datum);
408
+ }
409
+ }
410
+ };
411
+
412
+ $(data).each2(function (i, datum) {
413
+ process(datum, filtered.results);
414
+ });
415
+ query.callback(filtered);
416
+ };
417
+ }
418
+
419
+ // TODO javadoc
420
+ function tags(data) {
421
+ // TODO even for a function we should probably return a wrapper that does the same object/string check as
422
+ // the function for arrays. otherwise only functions that return objects are supported.
423
+ if ($.isFunction(data)) {
424
+ return data;
425
+ }
426
+
427
+ // if not a function we assume it to be an array
428
+
429
+ return function (query) {
430
+ var t = query.term, filtered = {results: []};
431
+ $(data).each(function () {
432
+ var isObject = this.text !== undefined,
433
+ text = isObject ? this.text : this;
434
+ if (t === "" || query.matcher(t, text)) {
435
+ filtered.results.push(isObject ? this : {id: this, text: this});
436
+ }
437
+ });
438
+ query.callback(filtered);
439
+ };
440
+ }
441
+
442
+ /**
443
+ * Checks if the formatter function should be used.
444
+ *
445
+ * Throws an error if it is not a function. Returns true if it should be used,
446
+ * false if no formatting should be performed.
447
+ *
448
+ * @param formatter
449
+ */
450
+ function checkFormatter(formatter, formatterName) {
451
+ if ($.isFunction(formatter)) return true;
452
+ if (!formatter) return false;
453
+ throw new Error("formatterName must be a function or a falsy value");
454
+ }
455
+
456
+ function evaluate(val) {
457
+ return $.isFunction(val) ? val() : val;
458
+ }
459
+
460
+ function countResults(results) {
461
+ var count = 0;
462
+ $.each(results, function (i, item) {
463
+ if (item.children) {
464
+ count += countResults(item.children);
465
+ } else {
466
+ count++;
467
+ }
468
+ });
469
+ return count;
470
+ }
471
+
472
+ /**
473
+ * Default tokenizer. This function uses breaks the input on substring match of any string from the
474
+ * opts.tokenSeparators array and uses opts.createSearchChoice to create the choice object. Both of those
475
+ * two options have to be defined in order for the tokenizer to work.
476
+ *
477
+ * @param input text user has typed so far or pasted into the search field
478
+ * @param selection currently selected choices
479
+ * @param selectCallback function(choice) callback tho add the choice to selection
480
+ * @param opts select2's opts
481
+ * @return undefined/null to leave the current input unchanged, or a string to change the input to the returned value
482
+ */
483
+ function defaultTokenizer(input, selection, selectCallback, opts) {
484
+ var original = input, // store the original so we can compare and know if we need to tell the search to update its text
485
+ dupe = false, // check for whether a token we extracted represents a duplicate selected choice
486
+ token, // token
487
+ index, // position at which the separator was found
488
+ i, l, // looping variables
489
+ separator; // the matched separator
490
+
491
+ if (!opts.createSearchChoice || !opts.tokenSeparators || opts.tokenSeparators.length < 1) return undefined;
492
+
493
+ while (true) {
494
+ index = -1;
495
+
496
+ for (i = 0, l = opts.tokenSeparators.length; i < l; i++) {
497
+ separator = opts.tokenSeparators[i];
498
+ index = input.indexOf(separator);
499
+ if (index >= 0) break;
500
+ }
501
+
502
+ if (index < 0) break; // did not find any token separator in the input string, bail
503
+
504
+ token = input.substring(0, index);
505
+ input = input.substring(index + separator.length);
506
+
507
+ if (token.length > 0) {
508
+ token = opts.createSearchChoice(token, selection);
509
+ if (token !== undefined && token !== null && opts.id(token) !== undefined && opts.id(token) !== null) {
510
+ dupe = false;
511
+ for (i = 0, l = selection.length; i < l; i++) {
512
+ if (equal(opts.id(token), opts.id(selection[i]))) {
513
+ dupe = true;
514
+ break;
515
+ }
516
+ }
517
+
518
+ if (!dupe) selectCallback(token);
519
+ }
520
+ }
521
+ }
522
+
523
+ if (original.localeCompare(input) != 0) return input;
524
+ }
525
+
526
+ /**
527
+ * blurs any Select2 container that has focus when an element outside them was clicked or received focus
528
+ *
529
+ * also takes care of clicks on label tags that point to the source element
530
+ */
531
+ $document.ready(function () {
532
+ $document.bind("mousedown touchend", function (e) {
533
+ var target = $(e.target).closest("div.select2-container").get(0), attr;
534
+ if (target) {
535
+ $document.find("div.select2-container-active").each(function () {
536
+ if (this !== target) $(this).data("select2").blur();
537
+ });
538
+ } else {
539
+ target = $(e.target).closest("div.select2-drop").get(0);
540
+ $document.find("div.select2-drop-active").each(function () {
541
+ if (this !== target) $(this).data("select2").blur();
542
+ });
543
+ }
544
+
545
+ target = $(e.target);
546
+ attr = target.attr("for");
547
+ if ("LABEL" === e.target.tagName && attr && attr.length > 0) {
548
+ attr = attr.replace(/([\[\].])/g, '\\$1');
549
+ /* escapes [, ], and . so properly selects the id */
550
+ target = $("#" + attr);
551
+ target = target.data("select2");
552
+ if (target !== undefined) {
553
+ target.focus();
554
+ e.preventDefault();
555
+ }
556
+ }
557
+ });
558
+ });
559
+
560
+ /**
561
+ * Creates a new class
562
+ *
563
+ * @param superClass
564
+ * @param methods
565
+ */
566
+ function clazz(SuperClass, methods) {
567
+ var constructor = function () {
568
+ };
569
+ constructor.prototype = new SuperClass;
570
+ constructor.prototype.constructor = constructor;
571
+ constructor.prototype.parent = SuperClass.prototype;
572
+ constructor.prototype = $.extend(constructor.prototype, methods);
573
+ return constructor;
574
+ }
575
+
576
+ AbstractSelect2 = clazz(Object, {
577
+
578
+ // abstract
579
+ bind: function (func) {
580
+ var self = this;
581
+ return function () {
582
+ func.apply(self, arguments);
583
+ };
584
+ },
585
+
586
+ // abstract
587
+ init: function (opts) {
588
+ var results, search, resultsSelector = ".select2-results";
589
+
590
+ // prepare options
591
+ this.opts = opts = this.prepareOpts(opts);
592
+
593
+ this.id = opts.id;
594
+
595
+ // destroy if called on an existing component
596
+ if (opts.element.data("select2") !== undefined &&
597
+ opts.element.data("select2") !== null) {
598
+ this.destroy();
599
+ }
600
+
601
+ this.enabled = true;
602
+ this.container = this.createContainer();
603
+
604
+ this.containerId = "s2id_" + (opts.element.attr("id") || "autogen" + nextUid());
605
+ this.containerSelector = "#" + this.containerId.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1');
606
+ this.container.attr("id", this.containerId);
607
+
608
+ // cache the body so future lookups are cheap
609
+ this.body = thunk(function () {
610
+ return opts.element.closest("body");
611
+ });
612
+
613
+ if (opts.element.attr("class") !== undefined) {
614
+ this.container.addClass(opts.element.attr("class").replace(/validate\[[\S ]+] ?/, ''));
615
+ }
616
+
617
+ this.container.css(evaluate(opts.containerCss));
618
+ this.container.addClass(evaluate(opts.containerCssClass));
619
+
620
+ // swap container for the element
621
+ this.opts.element
622
+ .data("select2", this)
623
+ .hide()
624
+ .before(this.container);
625
+ this.container.data("select2", this);
626
+
627
+ this.dropdown = this.container.find(".select2-drop");
628
+ this.dropdown.addClass(evaluate(opts.dropdownCssClass));
629
+ this.dropdown.data("select2", this);
630
+
631
+ this.results = results = this.container.find(resultsSelector);
632
+ this.search = search = this.container.find("input.select2-input");
633
+
634
+ search.attr("tabIndex", this.opts.element.attr("tabIndex"));
635
+
636
+ this.resultsPage = 0;
637
+ this.context = null;
638
+
639
+ // initialize the container
640
+ this.initContainer();
641
+ this.initContainerWidth();
642
+
643
+ installFilteredMouseMove(this.results);
644
+ this.dropdown.delegate(resultsSelector, "mousemove-filtered", this.bind(this.highlightUnderEvent));
645
+
646
+ installDebouncedScroll(80, this.results);
647
+ this.dropdown.delegate(resultsSelector, "scroll-debounced", this.bind(this.loadMoreIfNeeded));
648
+
649
+ // if jquery.mousewheel plugin is installed we can prevent out-of-bounds scrolling of results via mousewheel
650
+ if ($.fn.mousewheel) {
651
+ results.mousewheel(function (e, delta, deltaX, deltaY) {
652
+ var top = results.scrollTop(), height;
653
+ if (deltaY > 0 && top - deltaY <= 0) {
654
+ results.scrollTop(0);
655
+ killEvent(e);
656
+ } else if (deltaY < 0 && results.get(0).scrollHeight - results.scrollTop() + deltaY <= results.height()) {
657
+ results.scrollTop(results.get(0).scrollHeight - results.height());
658
+ killEvent(e);
659
+ }
660
+ });
661
+ }
662
+
663
+ installKeyUpChangeEvent(search);
664
+ search.bind("keyup-change", this.bind(this.updateResults));
665
+ search.bind("focus", function () {
666
+ search.addClass("select2-focused");
667
+ if (search.val() === " ") search.val("");
668
+ });
669
+ search.bind("blur", function () {
670
+ search.removeClass("select2-focused");
671
+ });
672
+
673
+ this.dropdown.delegate(resultsSelector, "mouseup", this.bind(function (e) {
674
+ if ($(e.target).closest(".select2-result-selectable:not(.select2-disabled)").length > 0) {
675
+ this.highlightUnderEvent(e);
676
+ this.selectHighlighted(e);
677
+ } else {
678
+ this.focusSearch();
679
+ }
680
+ killEvent(e);
681
+ }));
682
+
683
+ // trap all mouse events from leaving the dropdown. sometimes there may be a modal that is listening
684
+ // for mouse events outside of itself so it can close itself. since the dropdown is now outside the select2's
685
+ // dom it will trigger the popup close, which is not what we want
686
+ this.dropdown.bind("click mouseup mousedown", function (e) {
687
+ e.stopPropagation();
688
+ });
689
+
690
+ if ($.isFunction(this.opts.initSelection)) {
691
+ // initialize selection based on the current value of the source element
692
+ this.initSelection();
693
+
694
+ // if the user has provided a function that can set selection based on the value of the source element
695
+ // we monitor the change event on the element and trigger it, allowing for two way synchronization
696
+ this.monitorSource();
697
+ }
698
+
699
+ if (opts.element.is(":disabled") || opts.element.is("[readonly='readonly']")) this.disable();
700
+ },
701
+
702
+ // abstract
703
+ destroy: function () {
704
+ var select2 = this.opts.element.data("select2");
705
+ if (select2 !== undefined) {
706
+ select2.container.remove();
707
+ select2.dropdown.remove();
708
+ select2.opts.element
709
+ .removeData("select2")
710
+ .unbind(".select2")
711
+ .show();
712
+ }
713
+ },
714
+
715
+ // abstract
716
+ prepareOpts: function (opts) {
717
+ var element, select, idKey, ajaxUrl;
718
+
719
+ element = opts.element;
720
+
721
+ if (element.get(0).tagName.toLowerCase() === "select") {
722
+ this.select = select = opts.element;
723
+ }
724
+
725
+ if (select) {
726
+ // these options are not allowed when attached to a select because they are picked up off the element itself
727
+ $.each(["id", "multiple", "ajax", "query", "createSearchChoice", "initSelection", "data", "tags"], function () {
728
+ if (this in opts) {
729
+ throw new Error("Option '" + this + "' is not allowed for Select2 when attached to a <select> element.");
730
+ }
731
+ });
732
+ }
733
+
734
+ opts = $.extend({}, {
735
+ populateResults: function (container, results, query) {
736
+ var populate, data, result, children, id = this.opts.id, self = this;
737
+
738
+ populate = function (results, container, depth) {
739
+
740
+ var i, l, result, selectable, compound, node, label, innerContainer, formatted;
741
+ for (i = 0, l = results.length; i < l; i = i + 1) {
742
+
743
+ result = results[i];
744
+ selectable = id(result) !== undefined;
745
+ compound = result.children && result.children.length > 0;
746
+
747
+ node = $("<li></li>");
748
+ node.addClass("select2-results-dept-" + depth);
749
+ node.addClass("select2-result");
750
+ node.addClass(selectable ? "select2-result-selectable" : "select2-result-unselectable");
751
+ if (compound) {
752
+ node.addClass("select2-result-with-children");
753
+ }
754
+ node.addClass(self.opts.formatResultCssClass(result));
755
+
756
+ label = $("<div></div>");
757
+ label.addClass("select2-result-label");
758
+
759
+ formatted = opts.formatResult(result, label, query);
760
+ if (formatted !== undefined) {
761
+ label.html(self.opts.escapeMarkup(formatted));
762
+ }
763
+
764
+ node.append(label);
765
+
766
+ if (compound) {
767
+
768
+ innerContainer = $("<ul></ul>");
769
+ innerContainer.addClass("select2-result-sub");
770
+ populate(result.children, innerContainer, depth + 1);
771
+ node.append(innerContainer);
772
+ }
773
+
774
+ node.data("select2-data", result);
775
+ container.append(node);
776
+ }
777
+ };
778
+
779
+ populate(results, container, 0);
780
+ }
781
+ }, $.fn.select2.defaults, opts);
782
+
783
+ if (typeof(opts.id) !== "function") {
784
+ idKey = opts.id;
785
+ opts.id = function (e) {
786
+ return e[idKey];
787
+ };
788
+ }
789
+
790
+ if (select) {
791
+ opts.query = this.bind(function (query) {
792
+ var data = { results: [], more: false },
793
+ term = query.term,
794
+ children, firstChild, process;
795
+
796
+ process = function (element, collection) {
797
+ var group;
798
+ if (element.is("option")) {
799
+ if (query.matcher(term, element.text(), element)) {
800
+ collection.push({id: element.attr("value"), text: element.text(), element: element.get(), css: element.attr("class")});
801
+ }
802
+ } else if (element.is("optgroup")) {
803
+ group = {text: element.attr("label"), children: [], element: element.get(), css: element.attr("class")};
804
+ element.children().each2(function (i, elm) {
805
+ process(elm, group.children);
806
+ });
807
+ if (group.children.length > 0) {
808
+ collection.push(group);
809
+ }
810
+ }
811
+ };
812
+
813
+ children = element.children();
814
+
815
+ // ignore the placeholder option if there is one
816
+ if (this.getPlaceholder() !== undefined && children.length > 0) {
817
+ firstChild = children[0];
818
+ if ($(firstChild).text() === "") {
819
+ children = children.not(firstChild);
820
+ }
821
+ }
822
+
823
+ children.each2(function (i, elm) {
824
+ process(elm, data.results);
825
+ });
826
+
827
+ query.callback(data);
828
+ });
829
+ // this is needed because inside val() we construct choices from options and there id is hardcoded
830
+ opts.id = function (e) {
831
+ return e.id;
832
+ };
833
+ opts.formatResultCssClass = function (data) {
834
+ return data.css;
835
+ }
836
+ } else {
837
+ if (!("query" in opts)) {
838
+ if ("ajax" in opts) {
839
+ ajaxUrl = opts.element.data("ajax-url");
840
+ if (ajaxUrl && ajaxUrl.length > 0) {
841
+ opts.ajax.url = ajaxUrl;
842
+ }
843
+ opts.query = ajax(opts.ajax);
844
+ } else if ("data" in opts) {
845
+ opts.query = local(opts.data);
846
+ } else if ("tags" in opts) {
847
+ opts.query = tags(opts.tags);
848
+ opts.createSearchChoice = function (term) {
849
+ return {id: term, text: term};
850
+ };
851
+ opts.initSelection = function (element, callback) {
852
+ var data = [];
853
+ $(splitVal(element.val(), opts.separator)).each(function () {
854
+ var id = this, text = this, tags = opts.tags;
855
+ if ($.isFunction(tags)) tags = tags();
856
+ $(tags).each(function () {
857
+ if (equal(this.id, id)) {
858
+ text = this.text;
859
+ return false;
860
+ }
861
+ });
862
+ data.push({id: id, text: text});
863
+ });
864
+
865
+ callback(data);
866
+ };
867
+ }
868
+ }
869
+ }
870
+ if (typeof(opts.query) !== "function") {
871
+ throw "query function not defined for Select2 " + opts.element.attr("id");
872
+ }
873
+
874
+ return opts;
875
+ },
876
+
877
+ /**
878
+ * Monitor the original element for changes and update select2 accordingly
879
+ */
880
+ // abstract
881
+ monitorSource: function () {
882
+ this.opts.element.bind("change.select2", this.bind(function (e) {
883
+ if (this.opts.element.data("select2-change-triggered") !== true) {
884
+ this.initSelection();
885
+ }
886
+ }));
887
+ },
888
+
889
+ /**
890
+ * Triggers the change event on the source element
891
+ */
892
+ // abstract
893
+ triggerChange: function (details) {
894
+
895
+ details = details || {};
896
+ details = $.extend({}, details, { type: "change", val: this.val() });
897
+ // prevents recursive triggering
898
+ this.opts.element.data("select2-change-triggered", true);
899
+ this.opts.element.trigger(details);
900
+ this.opts.element.data("select2-change-triggered", false);
901
+
902
+ // some validation frameworks ignore the change event and listen instead to keyup, click for selects
903
+ // so here we trigger the click event manually
904
+ this.opts.element.click();
905
+
906
+ // ValidationEngine ignorea the change event and listens instead to blur
907
+ // so here we trigger the blur event manually if so desired
908
+ if (this.opts.blurOnChange)
909
+ this.opts.element.blur();
910
+ },
911
+
912
+
913
+ // abstract
914
+ enable: function () {
915
+ if (this.enabled) return;
916
+
917
+ this.enabled = true;
918
+ this.container.removeClass("select2-container-disabled");
919
+ this.opts.element.removeAttr("disabled");
920
+ },
921
+
922
+ // abstract
923
+ disable: function () {
924
+ if (!this.enabled) return;
925
+
926
+ this.close();
927
+
928
+ this.enabled = false;
929
+ this.container.addClass("select2-container-disabled");
930
+ this.opts.element.attr("disabled", "disabled");
931
+ },
932
+
933
+ // abstract
934
+ opened: function () {
935
+ return this.container.hasClass("select2-dropdown-open");
936
+ },
937
+
938
+ // abstract
939
+ positionDropdown: function () {
940
+ var offset = this.container.offset(),
941
+ height = this.container.outerHeight(true),
942
+ width = this.container.outerWidth(true),
943
+ dropHeight = this.dropdown.outerHeight(true),
944
+ viewportBottom = $(window).scrollTop() + document.documentElement.clientHeight,
945
+ dropTop = offset.top + height,
946
+ dropLeft = offset.left,
947
+ enoughRoomBelow = dropTop + dropHeight <= viewportBottom,
948
+ enoughRoomAbove = (offset.top - dropHeight) >= this.body().scrollTop(),
949
+ aboveNow = this.dropdown.hasClass("select2-drop-above"),
950
+ bodyOffset,
951
+ above,
952
+ css;
953
+
954
+ // console.log("below/ droptop:", dropTop, "dropHeight", dropHeight, "sum", (dropTop+dropHeight)+" viewport bottom", viewportBottom, "enough?", enoughRoomBelow);
955
+ // console.log("above/ offset.top", offset.top, "dropHeight", dropHeight, "top", (offset.top-dropHeight), "scrollTop", this.body().scrollTop(), "enough?", enoughRoomAbove);
956
+
957
+ // fix positioning when body has an offset and is not position: static
958
+
959
+ if (this.body().css('position') !== 'static') {
960
+ bodyOffset = this.body().offset();
961
+ dropTop -= bodyOffset.top;
962
+ dropLeft -= bodyOffset.left;
963
+ }
964
+
965
+ // always prefer the current above/below alignment, unless there is not enough room
966
+
967
+ if (aboveNow) {
968
+ above = true;
969
+ if (!enoughRoomAbove && enoughRoomBelow) above = false;
970
+ } else {
971
+ above = false;
972
+ if (!enoughRoomBelow && enoughRoomAbove) above = true;
973
+ }
974
+
975
+ if (above) {
976
+ dropTop = offset.top - dropHeight;
977
+ this.container.addClass("select2-drop-above");
978
+ this.dropdown.addClass("select2-drop-above");
979
+ }
980
+ else {
981
+ this.container.removeClass("select2-drop-above");
982
+ this.dropdown.removeClass("select2-drop-above");
983
+ }
984
+
985
+ css = $.extend({
986
+ top: dropTop,
987
+ left: dropLeft,
988
+ width: width
989
+ }, evaluate(this.opts.dropdownCss));
990
+
991
+ this.dropdown.css(css);
992
+ },
993
+
994
+ // abstract
995
+ shouldOpen: function () {
996
+ var event;
997
+
998
+ if (this.opened()) return false;
999
+
1000
+ event = $.Event("open");
1001
+ this.opts.element.trigger(event);
1002
+ return !event.isDefaultPrevented();
1003
+ },
1004
+
1005
+ // abstract
1006
+ clearDropdownAlignmentPreference: function () {
1007
+ // clear the classes used to figure out the preference of where the dropdown should be opened
1008
+ this.container.removeClass("select2-drop-above");
1009
+ this.dropdown.removeClass("select2-drop-above");
1010
+ },
1011
+
1012
+ /**
1013
+ * Opens the dropdown
1014
+ *
1015
+ * @return {Boolean} whether or not dropdown was opened. This method will return false if, for example,
1016
+ * the dropdown is already open, or if the 'open' event listener on the element called preventDefault().
1017
+ */
1018
+ // abstract
1019
+ open: function () {
1020
+
1021
+ if (!this.shouldOpen()) return false;
1022
+
1023
+ window.setTimeout(this.bind(this.opening), 1);
1024
+
1025
+ return true;
1026
+ },
1027
+
1028
+ /**
1029
+ * Performs the opening of the dropdown
1030
+ */
1031
+ // abstract
1032
+ opening: function () {
1033
+ var cid = this.containerId, selector = this.containerSelector,
1034
+ scroll = "scroll." + cid, resize = "resize." + cid;
1035
+
1036
+ this.container.parents().each(function () {
1037
+ $(this).bind(scroll, function () {
1038
+ var s2 = $(selector);
1039
+ if (s2.length == 0) {
1040
+ $(this).unbind(scroll);
1041
+ }
1042
+ s2.select2("close");
1043
+ });
1044
+ });
1045
+
1046
+ window.setTimeout(function () {
1047
+ // this is done inside a timeout because IE will sometimes fire a resize event while opening
1048
+ // the dropdown and that causes this handler to immediately close it. this way the dropdown
1049
+ // has a chance to fully open before we start listening to resize events
1050
+ $(window).bind(resize, function () {
1051
+ var s2 = $(selector);
1052
+ if (s2.length == 0) {
1053
+ $(window).unbind(resize);
1054
+ }
1055
+ s2.select2("close");
1056
+ })
1057
+ }, 10);
1058
+
1059
+ this.clearDropdownAlignmentPreference();
1060
+
1061
+ if (this.search.val() === " ") {
1062
+ this.search.val("");
1063
+ }
1064
+
1065
+ this.container.addClass("select2-dropdown-open").addClass("select2-container-active");
1066
+
1067
+ this.updateResults(true);
1068
+
1069
+ if (this.dropdown[0] !== this.body().children().last()[0]) {
1070
+ this.dropdown.detach().appendTo(this.body());
1071
+ }
1072
+
1073
+ this.dropdown.show();
1074
+
1075
+ this.positionDropdown();
1076
+ this.dropdown.addClass("select2-drop-active");
1077
+
1078
+ this.ensureHighlightVisible();
1079
+
1080
+ this.focusSearch();
1081
+ },
1082
+
1083
+ // abstract
1084
+ close: function () {
1085
+ if (!this.opened()) return;
1086
+
1087
+ var self = this;
1088
+
1089
+ this.container.parents().each(function () {
1090
+ $(this).unbind("scroll." + self.containerId);
1091
+ });
1092
+ $(window).unbind("resize." + this.containerId);
1093
+
1094
+ this.clearDropdownAlignmentPreference();
1095
+
1096
+ this.dropdown.hide();
1097
+ this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active");
1098
+ this.results.empty();
1099
+ this.clearSearch();
1100
+
1101
+ this.opts.element.trigger($.Event("close"));
1102
+ },
1103
+
1104
+ // abstract
1105
+ clearSearch: function () {
1106
+
1107
+ },
1108
+
1109
+ // abstract
1110
+ ensureHighlightVisible: function () {
1111
+ var results = this.results, children, index, child, hb, rb, y, more;
1112
+
1113
+ index = this.highlight();
1114
+
1115
+ if (index < 0) return;
1116
+
1117
+ if (index == 0) {
1118
+
1119
+ // if the first element is highlighted scroll all the way to the top,
1120
+ // that way any unselectable headers above it will also be scrolled
1121
+ // into view
1122
+
1123
+ results.scrollTop(0);
1124
+ return;
1125
+ }
1126
+
1127
+ children = results.find(".select2-result-selectable");
1128
+
1129
+ child = $(children[index]);
1130
+
1131
+ hb = child.offset().top + child.outerHeight(true);
1132
+
1133
+ // if this is the last child lets also make sure select2-more-results is visible
1134
+ if (index === children.length - 1) {
1135
+ more = results.find("li.select2-more-results");
1136
+ if (more.length > 0) {
1137
+ hb = more.offset().top + more.outerHeight(true);
1138
+ }
1139
+ }
1140
+
1141
+ rb = results.offset().top + results.outerHeight(true);
1142
+ if (hb > rb) {
1143
+ results.scrollTop(results.scrollTop() + (hb - rb));
1144
+ }
1145
+ y = child.offset().top - results.offset().top;
1146
+
1147
+ // make sure the top of the element is visible
1148
+ if (y < 0) {
1149
+ results.scrollTop(results.scrollTop() + y); // y is negative
1150
+ }
1151
+ },
1152
+
1153
+ // abstract
1154
+ moveHighlight: function (delta) {
1155
+ var choices = this.results.find(".select2-result-selectable"),
1156
+ index = this.highlight();
1157
+
1158
+ while (index > -1 && index < choices.length) {
1159
+ index += delta;
1160
+ var choice = $(choices[index]);
1161
+ if (choice.hasClass("select2-result-selectable") && !choice.hasClass("select2-disabled")) {
1162
+ this.highlight(index);
1163
+ break;
1164
+ }
1165
+ }
1166
+ },
1167
+
1168
+ // abstract
1169
+ highlight: function (index) {
1170
+ var choices = this.results.find(".select2-result-selectable").not(".select2-disabled");
1171
+
1172
+ if (arguments.length === 0) {
1173
+ return indexOf(choices.filter(".select2-highlighted")[0], choices.get());
1174
+ }
1175
+
1176
+ if (index >= choices.length) index = choices.length - 1;
1177
+ if (index < 0) index = 0;
1178
+
1179
+ choices.removeClass("select2-highlighted");
1180
+
1181
+ $(choices[index]).addClass("select2-highlighted");
1182
+ this.ensureHighlightVisible();
1183
+
1184
+ },
1185
+
1186
+ // abstract
1187
+ countSelectableResults: function () {
1188
+ return this.results.find(".select2-result-selectable").not(".select2-disabled").length;
1189
+ },
1190
+
1191
+ // abstract
1192
+ highlightUnderEvent: function (event) {
1193
+ var el = $(event.target).closest(".select2-result-selectable");
1194
+ if (el.length > 0 && !el.is(".select2-highlighted")) {
1195
+ var choices = this.results.find('.select2-result-selectable');
1196
+ this.highlight(choices.index(el));
1197
+ } else if (el.length == 0) {
1198
+ // if we are over an unselectable item remove al highlights
1199
+ this.results.find(".select2-highlighted").removeClass("select2-highlighted");
1200
+ }
1201
+ },
1202
+
1203
+ // abstract
1204
+ loadMoreIfNeeded: function () {
1205
+ var results = this.results,
1206
+ more = results.find("li.select2-more-results"),
1207
+ below, // pixels the element is below the scroll fold, below==0 is when the element is starting to be visible
1208
+ offset = -1, // index of first element without data
1209
+ page = this.resultsPage + 1,
1210
+ self = this,
1211
+ term = this.search.val(),
1212
+ context = this.context;
1213
+
1214
+ if (more.length === 0) return;
1215
+ below = more.offset().top - results.offset().top - results.height();
1216
+
1217
+ if (below <= 0) {
1218
+ more.addClass("select2-active");
1219
+ this.opts.query({
1220
+ term: term,
1221
+ page: page,
1222
+ context: context,
1223
+ matcher: this.opts.matcher,
1224
+ callback: this.bind(function (data) {
1225
+
1226
+ // ignore a response if the select2 has been closed before it was received
1227
+ if (!self.opened()) return;
1228
+
1229
+
1230
+ self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context: context});
1231
+
1232
+ if (data.more === true) {
1233
+ more.detach().appendTo(results).text(self.opts.formatLoadMore(page + 1));
1234
+ window.setTimeout(function () {
1235
+ self.loadMoreIfNeeded();
1236
+ }, 10);
1237
+ } else {
1238
+ more.remove();
1239
+ }
1240
+ self.positionDropdown();
1241
+ self.resultsPage = page;
1242
+ })});
1243
+ }
1244
+ },
1245
+
1246
+ /**
1247
+ * Default tokenizer function which does nothing
1248
+ */
1249
+ tokenize: function () {
1250
+
1251
+ },
1252
+
1253
+ /**
1254
+ * @param initial whether or not this is the call to this method right after the dropdown has been opened
1255
+ */
1256
+ // abstract
1257
+ updateResults: function (initial) {
1258
+ var search = this.search, results = this.results, opts = this.opts, data, self = this, input;
1259
+
1260
+ // if the search is currently hidden we do not alter the results
1261
+ if (initial !== true && (this.showSearchInput === false || !this.opened())) {
1262
+ return;
1263
+ }
1264
+
1265
+ search.addClass("select2-active");
1266
+
1267
+ function postRender() {
1268
+ results.scrollTop(0);
1269
+ search.removeClass("select2-active");
1270
+ self.positionDropdown();
1271
+ }
1272
+
1273
+ function render(html) {
1274
+ results.html(self.opts.escapeMarkup(html));
1275
+ postRender();
1276
+ }
1277
+
1278
+ if (opts.maximumSelectionSize >= 1) {
1279
+ data = this.data();
1280
+ if ($.isArray(data) && data.length >= opts.maximumSelectionSize && checkFormatter(opts.formatSelectionTooBig, "formatSelectionTooBig")) {
1281
+ render("<li class='select2-selection-limit'>" + opts.formatSelectionTooBig(opts.maximumSelectionSize) + "</li>");
1282
+ return;
1283
+ }
1284
+ }
1285
+
1286
+ if (search.val().length < opts.minimumInputLength) {
1287
+ if (checkFormatter(opts.formatInputTooShort, "formatInputTooShort")) {
1288
+ render("<li class='select2-no-results'>" + opts.formatInputTooShort(search.val(), opts.minimumInputLength) + "</li>");
1289
+ } else {
1290
+ render("");
1291
+ }
1292
+ return;
1293
+ }
1294
+ else if (opts.formatSearching()) {
1295
+ render("<li class='select2-searching'>" + opts.formatSearching() + "</li>");
1296
+ }
1297
+
1298
+ // give the tokenizer a chance to pre-process the input
1299
+ input = this.tokenize();
1300
+ if (input != undefined && input != null) {
1301
+ search.val(input);
1302
+ }
1303
+
1304
+ this.resultsPage = 1;
1305
+ opts.query({
1306
+ term: search.val(),
1307
+ page: this.resultsPage,
1308
+ context: null,
1309
+ matcher: opts.matcher,
1310
+ callback: this.bind(function (data) {
1311
+ var def; // default choice
1312
+
1313
+ // ignore a response if the select2 has been closed before it was received
1314
+ if (!this.opened()) return;
1315
+
1316
+ // save context, if any
1317
+ this.context = (data.context === undefined) ? null : data.context;
1318
+
1319
+ // create a default choice and prepend it to the list
1320
+ if (this.opts.createSearchChoice && search.val() !== "") {
1321
+ def = this.opts.createSearchChoice.call(null, search.val(), data.results);
1322
+ if (def !== undefined && def !== null && self.id(def) !== undefined && self.id(def) !== null) {
1323
+ if ($(data.results).filter(
1324
+ function () {
1325
+ return equal(self.id(this), self.id(def));
1326
+ }).length === 0) {
1327
+ data.results.unshift(def);
1328
+ }
1329
+ }
1330
+ }
1331
+
1332
+ if (data.results.length === 0 && checkFormatter(opts.formatNoMatches, "formatNoMatches")) {
1333
+ render("<li class='select2-no-results'>" + opts.formatNoMatches(search.val()) + "</li>");
1334
+ return;
1335
+ }
1336
+
1337
+ results.empty();
1338
+ self.opts.populateResults.call(this, results, data.results, {term: search.val(), page: this.resultsPage, context: null});
1339
+
1340
+ if (data.more === true && checkFormatter(opts.formatLoadMore, "formatLoadMore")) {
1341
+ results.append("<li class='select2-more-results'>" + self.opts.escapeMarkup(opts.formatLoadMore(this.resultsPage)) + "</li>");
1342
+ window.setTimeout(function () {
1343
+ self.loadMoreIfNeeded();
1344
+ }, 10);
1345
+ }
1346
+
1347
+ this.postprocessResults(data, initial);
1348
+
1349
+ postRender();
1350
+ })});
1351
+ },
1352
+
1353
+ // abstract
1354
+ cancel: function () {
1355
+ this.close();
1356
+ },
1357
+
1358
+ // abstract
1359
+ blur: function () {
1360
+ this.close();
1361
+ this.container.removeClass("select2-container-active");
1362
+ this.dropdown.removeClass("select2-drop-active");
1363
+ // synonymous to .is(':focus'), which is available in jquery >= 1.6
1364
+ if (this.search[0] === document.activeElement) {
1365
+ this.search.blur();
1366
+ }
1367
+ this.clearSearch();
1368
+ this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
1369
+ this.opts.element.triggerHandler("blur");
1370
+ },
1371
+
1372
+ // abstract
1373
+ focusSearch: function () {
1374
+ // need to do it here as well as in timeout so it works in IE
1375
+ this.search.show();
1376
+ this.search.focus();
1377
+
1378
+ /* we do this in a timeout so that current event processing can complete before this code is executed.
1379
+ this makes sure the search field is focussed even if the current event would blur it */
1380
+ window.setTimeout(this.bind(function () {
1381
+ // reset the value so IE places the cursor at the end of the input box
1382
+ this.search.show();
1383
+ this.search.focus();
1384
+ this.search.val(this.search.val());
1385
+ }), 10);
1386
+ },
1387
+
1388
+ // abstract
1389
+ selectHighlighted: function () {
1390
+ var index = this.highlight(),
1391
+ highlighted = this.results.find(".select2-highlighted").not(".select2-disabled"),
1392
+ data = highlighted.closest('.select2-result-selectable').data("select2-data");
1393
+ if (data) {
1394
+ highlighted.addClass("select2-disabled");
1395
+ this.highlight(index);
1396
+ this.onSelect(data);
1397
+ }
1398
+ },
1399
+
1400
+ // abstract
1401
+ getPlaceholder: function () {
1402
+ return this.opts.element.attr("placeholder") ||
1403
+ this.opts.element.attr("data-placeholder") || // jquery 1.4 compat
1404
+ this.opts.element.data("placeholder") ||
1405
+ this.opts.placeholder;
1406
+ },
1407
+
1408
+ /**
1409
+ * Get the desired width for the container element. This is
1410
+ * derived first from option `width` passed to select2, then
1411
+ * the inline 'style' on the original element, and finally
1412
+ * falls back to the jQuery calculated element width.
1413
+ */
1414
+ // abstract
1415
+ initContainerWidth: function () {
1416
+ function resolveContainerWidth() {
1417
+ var style, attrs, matches, i, l;
1418
+
1419
+ if (this.opts.width === "off") {
1420
+ return null;
1421
+ } else if (this.opts.width === "element") {
1422
+ return this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px';
1423
+ } else if (this.opts.width === "copy" || this.opts.width === "resolve") {
1424
+ // check if there is inline style on the element that contains width
1425
+ style = this.opts.element.attr('style');
1426
+ if (style !== undefined) {
1427
+ attrs = style.split(';');
1428
+ for (i = 0, l = attrs.length; i < l; i = i + 1) {
1429
+ matches = attrs[i].replace(/\s/g, '')
1430
+ .match(/width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/);
1431
+ if (matches !== null && matches.length >= 1)
1432
+ return matches[1];
1433
+ }
1434
+ }
1435
+
1436
+ if (this.opts.width === "resolve") {
1437
+ // next check if css('width') can resolve a width that is percent based, this is sometimes possible
1438
+ // when attached to input type=hidden or elements hidden via css
1439
+ style = this.opts.element.css('width');
1440
+ if (style.indexOf("%") > 0) return style;
1441
+
1442
+ // finally, fallback on the calculated width of the element
1443
+ return (this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px');
1444
+ }
1445
+
1446
+ return null;
1447
+ } else if ($.isFunction(this.opts.width)) {
1448
+ return this.opts.width();
1449
+ } else {
1450
+ return this.opts.width;
1451
+ }
1452
+ };
1453
+
1454
+ var width = resolveContainerWidth.call(this);
1455
+ if (width !== null) {
1456
+ this.container.attr("style", "width: " + width);
1457
+ }
1458
+ }
1459
+ });
1460
+
1461
+ SingleSelect2 = clazz(AbstractSelect2, {
1462
+
1463
+ // single
1464
+
1465
+ createContainer: function () {
1466
+ var container = $("<div></div>", {
1467
+ "class": "select2-container"
1468
+ }).html([
1469
+ " <a href='javascript:void(0)' onclick='return false;' class='select2-choice'>",
1470
+ " <span></span><abbr class='select2-search-choice-close' style='display:none;'></abbr>",
1471
+ " <div><b></b></div>" ,
1472
+ "</a>",
1473
+ " <div class='select2-drop select2-offscreen'>" ,
1474
+ " <div class='select2-search'>" ,
1475
+ " <input type='text' autocomplete='off' class='select2-input'/>" ,
1476
+ " </div>" ,
1477
+ " <ul class='select2-results'>" ,
1478
+ " </ul>" ,
1479
+ "</div>"].join(""));
1480
+ return container;
1481
+ },
1482
+
1483
+ // single
1484
+ opening: function () {
1485
+ this.search.show();
1486
+ this.parent.opening.apply(this, arguments);
1487
+ this.dropdown.removeClass("select2-offscreen");
1488
+ },
1489
+
1490
+ // single
1491
+ close: function () {
1492
+ if (!this.opened()) return;
1493
+ this.parent.close.apply(this, arguments);
1494
+ this.dropdown.removeAttr("style").addClass("select2-offscreen").insertAfter(this.selection).show();
1495
+ },
1496
+
1497
+ // single
1498
+ focus: function () {
1499
+ this.close();
1500
+ this.selection.focus();
1501
+ },
1502
+
1503
+ // single
1504
+ isFocused: function () {
1505
+ return this.selection[0] === document.activeElement;
1506
+ },
1507
+
1508
+ // single
1509
+ cancel: function () {
1510
+ this.parent.cancel.apply(this, arguments);
1511
+ this.selection.focus();
1512
+ },
1513
+
1514
+ // single
1515
+ initContainer: function () {
1516
+
1517
+ var selection,
1518
+ container = this.container,
1519
+ dropdown = this.dropdown,
1520
+ clickingInside = false;
1521
+
1522
+ this.selection = selection = container.find(".select2-choice");
1523
+
1524
+ this.search.bind("keydown", this.bind(function (e) {
1525
+ if (!this.enabled) return;
1526
+
1527
+ if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
1528
+ // prevent the page from scrolling
1529
+ killEvent(e);
1530
+ return;
1531
+ }
1532
+
1533
+ if (this.opened()) {
1534
+ switch (e.which) {
1535
+ case KEY.UP:
1536
+ case KEY.DOWN:
1537
+ this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
1538
+ killEvent(e);
1539
+ return;
1540
+ case KEY.TAB:
1541
+ case KEY.ENTER:
1542
+ this.selectHighlighted();
1543
+ killEvent(e);
1544
+ return;
1545
+ case KEY.ESC:
1546
+ this.cancel(e);
1547
+ killEvent(e);
1548
+ return;
1549
+ }
1550
+ } else {
1551
+
1552
+ if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {
1553
+ return;
1554
+ }
1555
+
1556
+ if (this.opts.openOnEnter === false && e.which === KEY.ENTER) {
1557
+ return;
1558
+ }
1559
+
1560
+ this.open();
1561
+
1562
+ if (e.which === KEY.ENTER) {
1563
+ // do not propagate the event otherwise we open, and propagate enter which closes
1564
+ return;
1565
+ }
1566
+ }
1567
+ }));
1568
+
1569
+ this.search.bind("focus", this.bind(function () {
1570
+ this.selection.attr("tabIndex", "-1");
1571
+ }));
1572
+ this.search.bind("blur", this.bind(function () {
1573
+ if (!this.opened()) this.container.removeClass("select2-container-active");
1574
+ window.setTimeout(this.bind(function () {
1575
+ // restore original tab index
1576
+ var ti = this.opts.element.attr("tabIndex");
1577
+ if (ti) {
1578
+ this.selection.attr("tabIndex", ti);
1579
+ } else {
1580
+ this.selection.removeAttr("tabIndex");
1581
+ }
1582
+ }), 10);
1583
+ }));
1584
+
1585
+ selection.delegate("abbr", "mousedown", this.bind(function (e) {
1586
+ if (!this.enabled) return;
1587
+ this.clear();
1588
+ killEventImmediately(e);
1589
+ this.close();
1590
+ this.triggerChange();
1591
+ this.selection.focus();
1592
+ }));
1593
+
1594
+ selection.bind("mousedown", this.bind(function (e) {
1595
+ clickingInside = true;
1596
+
1597
+ if (this.opened()) {
1598
+ this.close();
1599
+ this.selection.focus();
1600
+ } else if (this.enabled) {
1601
+ this.open();
1602
+ }
1603
+
1604
+ clickingInside = false;
1605
+ }));
1606
+
1607
+ dropdown.bind("mousedown", this.bind(function () {
1608
+ this.search.focus();
1609
+ }));
1610
+
1611
+ selection.bind("focus", this.bind(function () {
1612
+ this.container.addClass("select2-container-active");
1613
+ // hide the search so the tab key does not focus on it
1614
+ this.search.attr("tabIndex", "-1");
1615
+ }));
1616
+
1617
+ selection.bind("blur", this.bind(function () {
1618
+ if (!this.opened()) {
1619
+ this.container.removeClass("select2-container-active");
1620
+ }
1621
+ window.setTimeout(this.bind(function () {
1622
+ this.search.attr("tabIndex", this.opts.element.attr("tabIndex"));
1623
+ }), 10);
1624
+ }));
1625
+
1626
+ selection.bind("keydown", this.bind(function (e) {
1627
+ if (!this.enabled) return;
1628
+
1629
+ if (e.which == KEY.DOWN || e.which == KEY.UP
1630
+ || (e.which == KEY.ENTER && this.opts.openOnEnter)) {
1631
+ this.open();
1632
+ killEvent(e);
1633
+ return;
1634
+ }
1635
+
1636
+ if (e.which == KEY.DELETE || e.which == KEY.BACKSPACE) {
1637
+ if (this.opts.allowClear) {
1638
+ this.clear();
1639
+ }
1640
+ killEvent(e);
1641
+ return;
1642
+ }
1643
+ }));
1644
+ selection.bind("keypress", this.bind(function (e) {
1645
+ var key = String.fromCharCode(e.which);
1646
+ this.search.val(key);
1647
+ this.open();
1648
+ }));
1649
+
1650
+ this.setPlaceholder();
1651
+
1652
+ this.search.bind("focus", this.bind(function () {
1653
+ this.container.addClass("select2-container-active");
1654
+ }));
1655
+ },
1656
+
1657
+ // single
1658
+ clear: function () {
1659
+ this.opts.element.val("");
1660
+ this.selection.find("span").empty();
1661
+ this.selection.removeData("select2-data");
1662
+ this.setPlaceholder();
1663
+ },
1664
+
1665
+ /**
1666
+ * Sets selection based on source element's value
1667
+ */
1668
+ // single
1669
+ initSelection: function () {
1670
+ var selected;
1671
+ if (this.opts.element.val() === "" && this.opts.element.text() === "") {
1672
+ this.close();
1673
+ this.setPlaceholder();
1674
+ } else {
1675
+ var self = this;
1676
+ this.opts.initSelection.call(null, this.opts.element, function (selected) {
1677
+ if (selected !== undefined && selected !== null) {
1678
+ self.updateSelection(selected);
1679
+ self.close();
1680
+ self.setPlaceholder();
1681
+ }
1682
+ });
1683
+ }
1684
+ },
1685
+
1686
+ // single
1687
+ prepareOpts: function () {
1688
+ var opts = this.parent.prepareOpts.apply(this, arguments);
1689
+
1690
+ if (opts.element.get(0).tagName.toLowerCase() === "select") {
1691
+ // install the selection initializer
1692
+ opts.initSelection = function (element, callback) {
1693
+ var selected = element.find(":selected");
1694
+ // a single select box always has a value, no need to null check 'selected'
1695
+ if ($.isFunction(callback))
1696
+ callback({id: selected.attr("value"), text: selected.text(), element: selected});
1697
+ };
1698
+ }
1699
+
1700
+ return opts;
1701
+ },
1702
+
1703
+ // single
1704
+ setPlaceholder: function () {
1705
+ var placeholder = this.getPlaceholder();
1706
+
1707
+ if (this.opts.element.val() === "" && placeholder !== undefined) {
1708
+
1709
+ // check for a first blank option if attached to a select
1710
+ if (this.select && this.select.find("option:first").text() !== "") return;
1711
+
1712
+ this.selection.find("span").html(this.opts.escapeMarkup(placeholder));
1713
+
1714
+ this.selection.addClass("select2-default");
1715
+
1716
+ this.selection.find("abbr").hide();
1717
+ }
1718
+ },
1719
+
1720
+ // single
1721
+ postprocessResults: function (data, initial) {
1722
+ var selected = 0, self = this, showSearchInput = true;
1723
+
1724
+ // find the selected element in the result list
1725
+
1726
+ this.results.find(".select2-result-selectable").each2(function (i, elm) {
1727
+ if (equal(self.id(elm.data("select2-data")), self.opts.element.val())) {
1728
+ selected = i;
1729
+ return false;
1730
+ }
1731
+ });
1732
+
1733
+ // and highlight it
1734
+
1735
+ this.highlight(selected);
1736
+
1737
+ // hide the search box if this is the first we got the results and there are a few of them
1738
+
1739
+ if (initial === true) {
1740
+ showSearchInput = this.showSearchInput = countResults(data.results) >= this.opts.minimumResultsForSearch;
1741
+ this.dropdown.find(".select2-search")[showSearchInput ? "removeClass" : "addClass"]("select2-search-hidden");
1742
+
1743
+ //add "select2-with-searchbox" to the container if search box is shown
1744
+ $(this.dropdown, this.container)[showSearchInput ? "addClass" : "removeClass"]("select2-with-searchbox");
1745
+ }
1746
+
1747
+ },
1748
+
1749
+ // single
1750
+ onSelect: function (data) {
1751
+ var old = this.opts.element.val();
1752
+
1753
+ this.opts.element.val(this.id(data));
1754
+ this.updateSelection(data);
1755
+ this.close();
1756
+ this.selection.focus();
1757
+
1758
+ if (!equal(old, this.id(data))) {
1759
+ this.triggerChange();
1760
+ }
1761
+ },
1762
+
1763
+ // single
1764
+ updateSelection: function (data) {
1765
+
1766
+ var container = this.selection.find("span"), formatted;
1767
+
1768
+ this.selection.data("select2-data", data);
1769
+
1770
+ container.empty();
1771
+ formatted = this.opts.formatSelection(data, container);
1772
+ if (formatted !== undefined) {
1773
+ container.append(this.opts.escapeMarkup(formatted));
1774
+ }
1775
+
1776
+ this.selection.removeClass("select2-default");
1777
+
1778
+ if (this.opts.allowClear && this.getPlaceholder() !== undefined) {
1779
+ this.selection.find("abbr").show();
1780
+ }
1781
+ },
1782
+
1783
+ // single
1784
+ val: function () {
1785
+ var val, data = null, self = this;
1786
+
1787
+ if (arguments.length === 0) {
1788
+ return this.opts.element.val();
1789
+ }
1790
+
1791
+ val = arguments[0];
1792
+
1793
+ if (this.select) {
1794
+ this.select
1795
+ .val(val)
1796
+ .find(":selected").each2(function (i, elm) {
1797
+ data = {id: elm.attr("value"), text: elm.text()};
1798
+ return false;
1799
+ });
1800
+ this.updateSelection(data);
1801
+ this.setPlaceholder();
1802
+ } else {
1803
+ if (this.opts.initSelection === undefined) {
1804
+ throw new Error("cannot call val() if initSelection() is not defined");
1805
+ }
1806
+ // val is an id. !val is true for [undefined,null,'']
1807
+ if (!val) {
1808
+ this.clear();
1809
+ return;
1810
+ }
1811
+ this.opts.element.val(val);
1812
+ this.opts.initSelection(this.opts.element, function (data) {
1813
+ self.opts.element.val(!data ? "" : self.id(data));
1814
+ self.updateSelection(data);
1815
+ self.setPlaceholder();
1816
+ });
1817
+ }
1818
+ },
1819
+
1820
+ // single
1821
+ clearSearch: function () {
1822
+ this.search.val("");
1823
+ },
1824
+
1825
+ // single
1826
+ data: function (value) {
1827
+ var data;
1828
+
1829
+ if (arguments.length === 0) {
1830
+ data = this.selection.data("select2-data");
1831
+ if (data == undefined) data = null;
1832
+ return data;
1833
+ } else {
1834
+ if (!value || value === "") {
1835
+ this.clear();
1836
+ } else {
1837
+ this.opts.element.val(!value ? "" : this.id(value));
1838
+ this.updateSelection(value);
1839
+ }
1840
+ }
1841
+ }
1842
+ });
1843
+
1844
+ MultiSelect2 = clazz(AbstractSelect2, {
1845
+
1846
+ // multi
1847
+ createContainer: function () {
1848
+ var container = $("<div></div>", {
1849
+ "class": "select2-container select2-container-multi"
1850
+ }).html([
1851
+ " <ul class='select2-choices'>",
1852
+ //"<li class='select2-search-choice'><span>California</span><a href="javascript:void(0)" class="select2-search-choice-close"></a></li>" ,
1853
+ " <li class='select2-search-field'>" ,
1854
+ " <input type='text' autocomplete='off' class='select2-input'>" ,
1855
+ " </li>" ,
1856
+ "</ul>" ,
1857
+ "<div class='select2-drop select2-drop-multi' style='display:none;'>" ,
1858
+ " <ul class='select2-results'>" ,
1859
+ " </ul>" ,
1860
+ "</div>"].join(""));
1861
+ return container;
1862
+ },
1863
+
1864
+ // multi
1865
+ prepareOpts: function () {
1866
+ var opts = this.parent.prepareOpts.apply(this, arguments);
1867
+
1868
+ // TODO validate placeholder is a string if specified
1869
+
1870
+ if (opts.element.get(0).tagName.toLowerCase() === "select") {
1871
+ // install sthe selection initializer
1872
+ opts.initSelection = function (element, callback) {
1873
+
1874
+ var data = [];
1875
+ element.find(":selected").each2(function (i, elm) {
1876
+ data.push({id: elm.attr("value"), text: elm.text(), element: elm});
1877
+ });
1878
+
1879
+ if ($.isFunction(callback))
1880
+ callback(data);
1881
+ };
1882
+ }
1883
+
1884
+ return opts;
1885
+ },
1886
+
1887
+ // multi
1888
+ initContainer: function () {
1889
+
1890
+ var selector = ".select2-choices", selection;
1891
+
1892
+ this.searchContainer = this.container.find(".select2-search-field");
1893
+ this.selection = selection = this.container.find(selector);
1894
+
1895
+ this.search.bind("keydown", this.bind(function (e) {
1896
+ if (!this.enabled) return;
1897
+
1898
+ if (e.which === KEY.BACKSPACE && this.search.val() === "") {
1899
+ this.close();
1900
+
1901
+ var choices,
1902
+ selected = selection.find(".select2-search-choice-focus");
1903
+ if (selected.length > 0) {
1904
+ this.unselect(selected.first());
1905
+ this.search.width(10);
1906
+ killEvent(e);
1907
+ return;
1908
+ }
1909
+
1910
+ choices = selection.find(".select2-search-choice");
1911
+ if (choices.length > 0) {
1912
+ choices.last().addClass("select2-search-choice-focus");
1913
+ }
1914
+ } else {
1915
+ selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
1916
+ }
1917
+
1918
+ if (this.opened()) {
1919
+ switch (e.which) {
1920
+ case KEY.UP:
1921
+ case KEY.DOWN:
1922
+ this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
1923
+ killEvent(e);
1924
+ return;
1925
+ case KEY.ENTER:
1926
+ case KEY.TAB:
1927
+ this.selectHighlighted();
1928
+ killEvent(e);
1929
+ return;
1930
+ case KEY.ESC:
1931
+ this.cancel(e);
1932
+ killEvent(e);
1933
+ return;
1934
+ }
1935
+ }
1936
+
1937
+ if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e)
1938
+ || e.which === KEY.BACKSPACE || e.which === KEY.ESC) {
1939
+ return;
1940
+ }
1941
+
1942
+ if (this.opts.openOnEnter === false && e.which === KEY.ENTER) {
1943
+ return;
1944
+ }
1945
+
1946
+ this.open();
1947
+
1948
+ if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
1949
+ // prevent the page from scrolling
1950
+ killEvent(e);
1951
+ }
1952
+ }));
1953
+
1954
+ this.search.bind("keyup", this.bind(this.resizeSearch));
1955
+
1956
+ this.search.bind("blur", this.bind(function (e) {
1957
+ this.container.removeClass("select2-container-active");
1958
+ this.search.removeClass("select2-focused");
1959
+ this.clearSearch();
1960
+ e.stopImmediatePropagation();
1961
+ }));
1962
+
1963
+ this.container.delegate(selector, "mousedown", this.bind(function (e) {
1964
+ if (!this.enabled) return;
1965
+ if ($(e.target).closest(".select2-search-choice").length > 0) {
1966
+ // clicked inside a select2 search choice, do not open
1967
+ return;
1968
+ }
1969
+ this.clearPlaceholder();
1970
+ this.open();
1971
+ this.focusSearch();
1972
+ e.preventDefault();
1973
+ }));
1974
+
1975
+ this.container.delegate(selector, "focus", this.bind(function () {
1976
+ if (!this.enabled) return;
1977
+ this.container.addClass("select2-container-active");
1978
+ this.dropdown.addClass("select2-drop-active");
1979
+ this.clearPlaceholder();
1980
+ }));
1981
+
1982
+ // set the placeholder if necessary
1983
+ this.clearSearch();
1984
+ },
1985
+
1986
+ // multi
1987
+ enable: function () {
1988
+ if (this.enabled) return;
1989
+
1990
+ this.parent.enable.apply(this, arguments);
1991
+
1992
+ this.search.removeAttr("disabled");
1993
+ },
1994
+
1995
+ // multi
1996
+ disable: function () {
1997
+ if (!this.enabled) return;
1998
+
1999
+ this.parent.disable.apply(this, arguments);
2000
+
2001
+ this.search.attr("disabled", true);
2002
+ },
2003
+
2004
+ // multi
2005
+ initSelection: function () {
2006
+ var data;
2007
+ if (this.opts.element.val() === "" && this.opts.element.text() === "") {
2008
+ this.updateSelection([]);
2009
+ this.close();
2010
+ // set the placeholder if necessary
2011
+ this.clearSearch();
2012
+ }
2013
+ if (this.select || this.opts.element.val() !== "") {
2014
+ var self = this;
2015
+ this.opts.initSelection.call(null, this.opts.element, function (data) {
2016
+ if (data !== undefined && data !== null) {
2017
+ self.updateSelection(data);
2018
+ self.close();
2019
+ // set the placeholder if necessary
2020
+ self.clearSearch();
2021
+ }
2022
+ });
2023
+ }
2024
+ },
2025
+
2026
+ // multi
2027
+ clearSearch: function () {
2028
+ var placeholder = this.getPlaceholder();
2029
+
2030
+ if (placeholder !== undefined && this.getVal().length === 0 && this.search.hasClass("select2-focused") === false) {
2031
+ this.search.val(placeholder).addClass("select2-default");
2032
+ // stretch the search box to full width of the container so as much of the placeholder is visible as possible
2033
+ this.resizeSearch();
2034
+ } else {
2035
+ // we set this to " " instead of "" and later clear it on focus() because there is a firefox bug
2036
+ // that does not properly render the caret when the field starts out blank
2037
+ this.search.val(" ").width(10);
2038
+ }
2039
+ },
2040
+
2041
+ // multi
2042
+ clearPlaceholder: function () {
2043
+ if (this.search.hasClass("select2-default")) {
2044
+ this.search.val("").removeClass("select2-default");
2045
+ } else {
2046
+ // work around for the space character we set to avoid firefox caret bug
2047
+ if (this.search.val() === " ") this.search.val("");
2048
+ }
2049
+ },
2050
+
2051
+ // multi
2052
+ opening: function () {
2053
+ this.parent.opening.apply(this, arguments);
2054
+
2055
+ this.clearPlaceholder();
2056
+ this.resizeSearch();
2057
+ this.focusSearch();
2058
+ },
2059
+
2060
+ // multi
2061
+ close: function () {
2062
+ if (!this.opened()) return;
2063
+ this.parent.close.apply(this, arguments);
2064
+ },
2065
+
2066
+ // multi
2067
+ focus: function () {
2068
+ this.close();
2069
+ this.search.focus();
2070
+ },
2071
+
2072
+ // multi
2073
+ isFocused: function () {
2074
+ return this.search.hasClass("select2-focused");
2075
+ },
2076
+
2077
+ // multi
2078
+ updateSelection: function (data) {
2079
+ var ids = [], filtered = [], self = this;
2080
+
2081
+ // filter out duplicates
2082
+ $(data).each(function () {
2083
+ if (indexOf(self.id(this), ids) < 0) {
2084
+ ids.push(self.id(this));
2085
+ filtered.push(this);
2086
+ }
2087
+ });
2088
+ data = filtered;
2089
+
2090
+ this.selection.find(".select2-search-choice").remove();
2091
+ $(data).each(function () {
2092
+ self.addSelectedChoice(this);
2093
+ });
2094
+ self.postprocessResults();
2095
+ },
2096
+
2097
+ tokenize: function () {
2098
+ var input = this.search.val();
2099
+ input = this.opts.tokenizer(input, this.data(), this.bind(this.onSelect), this.opts);
2100
+ if (input != null && input != undefined) {
2101
+ this.search.val(input);
2102
+ if (input.length > 0) {
2103
+ this.open();
2104
+ }
2105
+ }
2106
+
2107
+ },
2108
+
2109
+ // multi
2110
+ onSelect: function (data) {
2111
+ this.addSelectedChoice(data);
2112
+ if (this.select || !this.opts.closeOnSelect) this.postprocessResults();
2113
+
2114
+ if (this.opts.closeOnSelect) {
2115
+ this.close();
2116
+ this.search.width(10);
2117
+ } else {
2118
+ if (this.countSelectableResults() > 0) {
2119
+ this.search.width(10);
2120
+ this.resizeSearch();
2121
+ this.positionDropdown();
2122
+ } else {
2123
+ // if nothing left to select close
2124
+ this.close();
2125
+ }
2126
+ }
2127
+
2128
+ // since its not possible to select an element that has already been
2129
+ // added we do not need to check if this is a new element before firing change
2130
+ this.triggerChange({ added: data });
2131
+
2132
+ this.focusSearch();
2133
+ },
2134
+
2135
+ // multi
2136
+ cancel: function () {
2137
+ this.close();
2138
+ this.focusSearch();
2139
+ },
2140
+
2141
+ // multi
2142
+ addSelectedChoice: function (data) {
2143
+ var choice = $(
2144
+ "<li class='select2-search-choice'>" +
2145
+ " <div></div>" +
2146
+ " <a href='javascript:void(0)' onclick='return false;' class='select2-search-choice-close' tabindex='-1'></a>" +
2147
+ "</li>"),
2148
+ id = this.id(data),
2149
+ val = this.getVal(),
2150
+ formatted;
2151
+
2152
+ formatted = this.opts.formatSelection(data, choice.find("div"));
2153
+ if (formatted != undefined) {
2154
+ choice.find("div").replaceWith("<div>" + this.opts.escapeMarkup(formatted) + "</div>");
2155
+ }
2156
+ choice.find(".select2-search-choice-close")
2157
+ .bind("mousedown", killEvent)
2158
+ .bind("click dblclick", this.bind(function (e) {
2159
+ if (!this.enabled) return;
2160
+
2161
+ $(e.target).closest(".select2-search-choice").fadeOut('fast', this.bind(function () {
2162
+ this.unselect($(e.target));
2163
+ this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
2164
+ this.close();
2165
+ this.focusSearch();
2166
+ })).dequeue();
2167
+ killEvent(e);
2168
+ })).bind("focus", this.bind(function () {
2169
+ if (!this.enabled) return;
2170
+ this.container.addClass("select2-container-active");
2171
+ this.dropdown.addClass("select2-drop-active");
2172
+ }));
2173
+
2174
+ choice.data("select2-data", data);
2175
+ choice.insertBefore(this.searchContainer);
2176
+
2177
+ val.push(id);
2178
+ this.setVal(val);
2179
+ },
2180
+
2181
+ // multi
2182
+ unselect: function (selected) {
2183
+ var val = this.getVal(),
2184
+ data,
2185
+ index;
2186
+
2187
+ selected = selected.closest(".select2-search-choice");
2188
+
2189
+ if (selected.length === 0) {
2190
+ throw "Invalid argument: " + selected + ". Must be .select2-search-choice";
2191
+ }
2192
+
2193
+ data = selected.data("select2-data");
2194
+
2195
+ index = indexOf(this.id(data), val);
2196
+
2197
+ if (index >= 0) {
2198
+ val.splice(index, 1);
2199
+ this.setVal(val);
2200
+ if (this.select) this.postprocessResults();
2201
+ }
2202
+ selected.remove();
2203
+ this.triggerChange({ removed: data });
2204
+ },
2205
+
2206
+ // multi
2207
+ postprocessResults: function () {
2208
+ var val = this.getVal(),
2209
+ choices = this.results.find(".select2-result-selectable"),
2210
+ compound = this.results.find(".select2-result-with-children"),
2211
+ self = this;
2212
+
2213
+ choices.each2(function (i, choice) {
2214
+ var id = self.id(choice.data("select2-data"));
2215
+ if (indexOf(id, val) >= 0) {
2216
+ choice.addClass("select2-disabled").removeClass("select2-result-selectable");
2217
+ } else {
2218
+ choice.removeClass("select2-disabled").addClass("select2-result-selectable");
2219
+ }
2220
+ });
2221
+
2222
+ compound.each2(function (i, e) {
2223
+ if (!e.is('.select2-result-selectable') && e.find(".select2-result-selectable").length == 0) { // FIX FOR HIRECHAL DATA
2224
+ e.addClass("select2-disabled");
2225
+ } else {
2226
+ e.removeClass("select2-disabled");
2227
+ }
2228
+ });
2229
+
2230
+ choices.each2(function (i, choice) {
2231
+ if (!choice.hasClass("select2-disabled") && choice.hasClass("select2-result-selectable")) {
2232
+ self.highlight(0);
2233
+ return false;
2234
+ }
2235
+ });
2236
+
2237
+ },
2238
+
2239
+ // multi
2240
+ resizeSearch: function () {
2241
+
2242
+ var minimumWidth, left, maxWidth, containerLeft, searchWidth,
2243
+ sideBorderPadding = getSideBorderPadding(this.search);
2244
+
2245
+ minimumWidth = measureTextWidth(this.search) + 10;
2246
+
2247
+ left = this.search.offset().left;
2248
+
2249
+ maxWidth = this.selection.width();
2250
+ containerLeft = this.selection.offset().left;
2251
+
2252
+ searchWidth = maxWidth - (left - containerLeft) - sideBorderPadding;
2253
+ if (searchWidth < minimumWidth) {
2254
+ searchWidth = maxWidth - sideBorderPadding;
2255
+ }
2256
+
2257
+ if (searchWidth < 40) {
2258
+ searchWidth = maxWidth - sideBorderPadding;
2259
+ }
2260
+ this.search.width(searchWidth);
2261
+ },
2262
+
2263
+ // multi
2264
+ getVal: function () {
2265
+ var val;
2266
+ if (this.select) {
2267
+ val = this.select.val();
2268
+ return val === null ? [] : val;
2269
+ } else {
2270
+ val = this.opts.element.val();
2271
+ return splitVal(val, this.opts.separator);
2272
+ }
2273
+ },
2274
+
2275
+ // multi
2276
+ setVal: function (val) {
2277
+ var unique;
2278
+ if (this.select) {
2279
+ this.select.val(val);
2280
+ } else {
2281
+ unique = [];
2282
+ // filter out duplicates
2283
+ $(val).each(function () {
2284
+ if (indexOf(this, unique) < 0) unique.push(this);
2285
+ });
2286
+ this.opts.element.val(unique.length === 0 ? "" : unique.join(this.opts.separator));
2287
+ }
2288
+ },
2289
+
2290
+ // multi
2291
+ val: function () {
2292
+ var val, data = [], self = this;
2293
+
2294
+ if (arguments.length === 0) {
2295
+ return this.getVal();
2296
+ }
2297
+
2298
+ val = arguments[0];
2299
+
2300
+ if (!val) {
2301
+ this.opts.element.val("");
2302
+ this.updateSelection([]);
2303
+ this.clearSearch();
2304
+ return;
2305
+ }
2306
+
2307
+ // val is a list of ids
2308
+ this.setVal(val);
2309
+
2310
+ if (this.select) {
2311
+ this.select.find(":selected").each(function () {
2312
+ data.push({id: $(this).attr("value"), text: $(this).text()});
2313
+ });
2314
+ this.updateSelection(data);
2315
+ } else {
2316
+ if (this.opts.initSelection === undefined) {
2317
+ throw new Error("val() cannot be called if initSelection() is not defined")
2318
+ }
2319
+
2320
+ this.opts.initSelection(this.opts.element, function (data) {
2321
+ var ids = $(data).map(self.id);
2322
+ self.setVal(ids);
2323
+ self.updateSelection(data);
2324
+ self.clearSearch();
2325
+ });
2326
+ }
2327
+ this.clearSearch();
2328
+ },
2329
+
2330
+ // multi
2331
+ onSortStart: function () {
2332
+ if (this.select) {
2333
+ throw new Error("Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead.");
2334
+ }
2335
+
2336
+ // collapse search field into 0 width so its container can be collapsed as well
2337
+ this.search.width(0);
2338
+ // hide the container
2339
+ this.searchContainer.hide();
2340
+ },
2341
+
2342
+ // multi
2343
+ onSortEnd: function () {
2344
+
2345
+ var val = [], self = this;
2346
+
2347
+ // show search and move it to the end of the list
2348
+ this.searchContainer.show();
2349
+ // make sure the search container is the last item in the list
2350
+ this.searchContainer.appendTo(this.searchContainer.parent());
2351
+ // since we collapsed the width in dragStarted, we resize it here
2352
+ this.resizeSearch();
2353
+
2354
+ // update selection
2355
+
2356
+ this.selection.find(".select2-search-choice").each(function () {
2357
+ val.push(self.opts.id($(this).data("select2-data")));
2358
+ });
2359
+ this.setVal(val);
2360
+ this.triggerChange();
2361
+ },
2362
+
2363
+ // multi
2364
+ data: function (values) {
2365
+ var self = this, ids;
2366
+ if (arguments.length === 0) {
2367
+ return this.selection
2368
+ .find(".select2-search-choice")
2369
+ .map(function () {
2370
+ return $(this).data("select2-data");
2371
+ })
2372
+ .get();
2373
+ } else {
2374
+ if (!values) {
2375
+ values = [];
2376
+ }
2377
+ ids = $.map(values, function (e) {
2378
+ return self.opts.id(e)
2379
+ });
2380
+ this.setVal(ids);
2381
+ this.updateSelection(values);
2382
+ this.clearSearch();
2383
+ }
2384
+ }
2385
+ });
2386
+
2387
+ $.fn.select2 = function () {
2388
+
2389
+ var args = Array.prototype.slice.call(arguments, 0),
2390
+ opts,
2391
+ select2,
2392
+ value, multiple, allowedMethods = ["val", "destroy", "opened", "open", "close", "focus", "isFocused", "container", "onSortStart", "onSortEnd", "enable", "disable", "positionDropdown", "data"];
2393
+
2394
+ this.each(function () {
2395
+ if (args.length === 0 || typeof(args[0]) === "object") {
2396
+ opts = args.length === 0 ? {} : $.extend({}, args[0]);
2397
+ opts.element = $(this);
2398
+
2399
+ if (opts.element.get(0).tagName.toLowerCase() === "select") {
2400
+ multiple = opts.element.attr("multiple");
2401
+ } else {
2402
+ multiple = opts.multiple || false;
2403
+ if ("tags" in opts) {
2404
+ opts.multiple = multiple = true;
2405
+ }
2406
+ }
2407
+
2408
+ select2 = multiple ? new MultiSelect2() : new SingleSelect2();
2409
+ select2.init(opts);
2410
+ } else if (typeof(args[0]) === "string") {
2411
+
2412
+ if (indexOf(args[0], allowedMethods) < 0) {
2413
+ throw "Unknown method: " + args[0];
2414
+ }
2415
+
2416
+ value = undefined;
2417
+ select2 = $(this).data("select2");
2418
+ if (select2 === undefined) return;
2419
+ if (args[0] === "container") {
2420
+ value = select2.container;
2421
+ } else {
2422
+ value = select2[args[0]].apply(select2, args.slice(1));
2423
+ }
2424
+ if (value !== undefined) {
2425
+ return false;
2426
+ }
2427
+ } else {
2428
+ throw "Invalid arguments to select2 plugin: " + args;
2429
+ }
2430
+ });
2431
+ return (value === undefined) ? this : value;
2432
+ };
2433
+
2434
+ // plugin defaults, accessible to users
2435
+ $.fn.select2.defaults = {
2436
+ width: "copy",
2437
+ closeOnSelect: true,
2438
+ openOnEnter: true,
2439
+ containerCss: {},
2440
+ dropdownCss: {},
2441
+ containerCssClass: "",
2442
+ dropdownCssClass: "",
2443
+ formatResult: function (result, container, query) {
2444
+ var markup = [];
2445
+ markMatch(result.text, query.term, markup);
2446
+ return markup.join("");
2447
+ },
2448
+ formatSelection: function (data, container) {
2449
+ return data ? data.text : undefined;
2450
+ },
2451
+ formatResultCssClass: function (data) {
2452
+ return undefined;
2453
+ },
2454
+ formatNoMatches: function () {
2455
+ return "No matches found";
2456
+ },
2457
+ formatInputTooShort: function (input, min) {
2458
+ return "Please enter " + (min - input.length) + " more characters";
2459
+ },
2460
+ formatSelectionTooBig: function (limit) {
2461
+ return "You can only select " + limit + " item" + (limit == 1 ? "" : "s");
2462
+ },
2463
+ formatLoadMore: function (pageNumber) {
2464
+ return "Loading more results...";
2465
+ },
2466
+ formatSearching: function () {
2467
+ return "Searching...";
2468
+ },
2469
+ minimumResultsForSearch: 0,
2470
+ minimumInputLength: 0,
2471
+ maximumSelectionSize: 0,
2472
+ id: function (e) {
2473
+ return e.id;
2474
+ },
2475
+ matcher: function (term, text) {
2476
+ return text.toUpperCase().indexOf(term.toUpperCase()) >= 0;
2477
+ },
2478
+ separator: ",",
2479
+ tokenSeparators: [],
2480
+ tokenizer: defaultTokenizer,
2481
+ escapeMarkup: function (markup) {
2482
+ if (markup && typeof(markup) === "string") {
2483
+ return markup.replace(/&/g, "&amp;");
2484
+ }
2485
+ return markup;
2486
+ },
2487
+ blurOnChange: false
2488
+ };
2489
+
2490
+ // exports
2491
+ window.Select2 = {
2492
+ query: {
2493
+ ajax: ajax,
2494
+ local: local,
2495
+ tags: tags
2496
+ }, util: {
2497
+ debounce: debounce,
2498
+ markMatch: markMatch
2499
+ }, "class": {
2500
+ "abstract": AbstractSelect2,
2501
+ "single": SingleSelect2,
2502
+ "multi": MultiSelect2
2503
+ }
2504
+ };
2505
+
2506
+ }(jQuery));
trunk/WCVendors/classes/admin/settings/assets/js/select2/select2.min.css ADDED
@@ -0,0 +1,440 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .select2-container {
2
+ position: relative;
3
+ zoom: 1;
4
+ display: inline;
5
+ vertical-align: top;
6
+ }
7
+
8
+ .select2-container, .select2-drop, .select2-search, .select2-search input {
9
+ -moz-box-sizing: border-box;
10
+ -ms-box-sizing: border-box;
11
+ -webkit-box-sizing: border-box;
12
+ -khtml-box-sizing: border-box;
13
+ box-sizing: border-box;
14
+ }
15
+
16
+ .select2-container .select2-choice {
17
+ background-color: #fff;
18
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
19
+ background-image: linear-gradient(top, #eeeeee0%, #ffffff50%);
20
+ -webkit-border-radius: 4px;
21
+ -moz-border-radius: 4px;
22
+ border-radius: 4px;
23
+ -moz-background-clip: padding;
24
+ -webkit-background-clip: padding-box;
25
+ background-clip: padding-box;
26
+ border: 1px solid #aaa;
27
+ display: block;
28
+ overflow: hidden;
29
+ white-space: nowrap;
30
+ position: relative;
31
+ height: 26px;
32
+ line-height: 26px;
33
+ color: #444;
34
+ text-decoration: none;
35
+ padding: 0 0 0 8px;
36
+ }
37
+
38
+ .select2-container.select2-drop-above .select2-choice {
39
+ border-bottom-color: #aaa;
40
+ -webkit-border-radius: 0 0 4px 4px;
41
+ -moz-border-radius: 0 0 4px 4px;
42
+ border-radius: 0 0 4px 4px;
43
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0);
44
+ background-image: linear-gradient(top, #eeeeee0%, #ffffff90%);
45
+ }
46
+
47
+ .select2-container .select2-choice span {
48
+ margin-right: 26px;
49
+ display: block;
50
+ overflow: hidden;
51
+ white-space: nowrap;
52
+ -o-text-overflow: ellipsis;
53
+ -ms-text-overflow: ellipsis;
54
+ text-overflow: ellipsis;
55
+ }
56
+
57
+ .select2-container .select2-choice abbr {
58
+ display: block;
59
+ position: absolute;
60
+ right: 26px;
61
+ top: 8px;
62
+ width: 12px;
63
+ height: 12px;
64
+ font-size: 1px;
65
+ background: url(select2.png) right top no-repeat;
66
+ cursor: pointer;
67
+ text-decoration: none;
68
+ border: 0;
69
+ outline: 0;
70
+ }
71
+
72
+ .select2-container .select2-choice abbr:hover {
73
+ background-position: right -11px;
74
+ cursor: pointer;
75
+ }
76
+
77
+ .select2-drop {
78
+ background: #fff;
79
+ color: #000;
80
+ border: 1px solid #aaa;
81
+ border-top: 0;
82
+ position: absolute;
83
+ top: 100%;
84
+ -webkit-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
85
+ -moz-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
86
+ -o-box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
87
+ box-shadow: 0 4px 5px rgba(0, 0, 0, .15);
88
+ z-index: 9999;
89
+ width: 100%;
90
+ margin-top: -1px;
91
+ -webkit-border-radius: 0 0 4px 4px;
92
+ -moz-border-radius: 0 0 4px 4px;
93
+ border-radius: 0 0 4px 4px;
94
+ }
95
+
96
+ .select2-drop.select2-drop-above {
97
+ -webkit-border-radius: 4px 4px 0 0;
98
+ -moz-border-radius: 4px 4px 0 0;
99
+ border-radius: 4px 4px 0 0;
100
+ margin-top: 1px;
101
+ border-top: 1px solid #aaa;
102
+ border-bottom: 0;
103
+ -webkit-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
104
+ -moz-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
105
+ -o-box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
106
+ box-shadow: 0 -4px 5px rgba(0, 0, 0, .15);
107
+ }
108
+
109
+ .select2-container .select2-choice div {
110
+ -webkit-border-radius: 0 4px 4px 0;
111
+ -moz-border-radius: 0 4px 4px 0;
112
+ border-radius: 0 4px 4px 0;
113
+ -moz-background-clip: padding;
114
+ -webkit-background-clip: padding-box;
115
+ background-clip: padding-box;
116
+ background: #ccc;
117
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cccccc', endColorstr='#eeeeee', GradientType=0);
118
+ background-image: linear-gradient(top, #cccccc0%, #eeeeee60%);
119
+ border-left: 1px solid #aaa;
120
+ position: absolute;
121
+ right: 0;
122
+ top: 0;
123
+ display: block;
124
+ height: 100%;
125
+ width: 18px;
126
+ }
127
+
128
+ .select2-container .select2-choice div b {
129
+ background: url(select2.png) no-repeat 0 1px;
130
+ display: block;
131
+ width: 100%;
132
+ height: 100%;
133
+ }
134
+
135
+ .select2-search {
136
+ display: inline-block;
137
+ white-space: nowrap;
138
+ z-index: 10000;
139
+ position: relative;
140
+ min-height: 26px;
141
+ width: 100%;
142
+ padding-left: 4px;
143
+ padding-right: 4px;
144
+ margin: 0;
145
+ }
146
+
147
+ .select2-search-hidden {
148
+ display: block;
149
+ position: absolute;
150
+ left: -10000px;
151
+ }
152
+
153
+ .select2-search input {
154
+ background: url(select2.png) no-repeat 100% -22px linear-gradient(top, #ffffff85%, #eeeeee99%);
155
+ outline: 0;
156
+ border: 1px solid #aaa;
157
+ font-family: sans-serif;
158
+ font-size: 1em;
159
+ width: 100%;
160
+ height: auto !important;
161
+ min-height: 26px;
162
+ -webkit-box-shadow: none;
163
+ -moz-box-shadow: none;
164
+ box-shadow: none;
165
+ border-radius: 0;
166
+ -moz-border-radius: 0;
167
+ -webkit-border-radius: 0;
168
+ margin: 0;
169
+ padding: 4px 20px 4px 5px;
170
+ }
171
+
172
+ .select2-drop.select2-drop-above .select2-search input {
173
+ margin-top: 4px;
174
+ }
175
+
176
+ .select2-search input.select2-active {
177
+ background: url(spinner.gif) no-repeat 100% linear-gradient(top, #ffffff85%, #eeeeee99%);
178
+ }
179
+
180
+ .select2-dropdown-open .select2-choice {
181
+ border: 1px solid #aaa;
182
+ border-bottom-color: transparent;
183
+ -webkit-box-shadow: 0 1px 0 #fff inset;
184
+ -moz-box-shadow: 0 1px 0 #fff inset;
185
+ -o-box-shadow: 0 1px 0 #fff inset;
186
+ box-shadow: 0 1px 0 #fff inset;
187
+ background-color: #eee;
188
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
189
+ background-image: linear-gradient(top, #ffffff0%, #eeeeee50%);
190
+ -webkit-border-bottom-left-radius: 0;
191
+ -webkit-border-bottom-right-radius: 0;
192
+ -moz-border-radius-bottomleft: 0;
193
+ -moz-border-radius-bottomright: 0;
194
+ border-bottom-left-radius: 0;
195
+ border-bottom-right-radius: 0;
196
+ }
197
+
198
+ .select2-dropdown-open .select2-choice div {
199
+ background: transparent;
200
+ border-left: none;
201
+ }
202
+
203
+ .select2-dropdown-open .select2-choice div b {
204
+ background-position: -18px 1px;
205
+ }
206
+
207
+ .select2-results {
208
+ position: relative;
209
+ overflow-x: hidden;
210
+ overflow-y: auto;
211
+ max-height: 200px;
212
+ margin: 4px 4px 4px 0;
213
+ padding: 0 0 0 4px;
214
+ }
215
+
216
+ .select2-results ul.select2-result-sub {
217
+ margin: 0;
218
+ }
219
+
220
+ .select2-results ul.select2-result-sub > li .select2-result-label {
221
+ padding-left: 20px;
222
+ }
223
+
224
+ .select2-results ul.select2-result-sub ul.select2-result-sub > li .select2-result-label {
225
+ padding-left: 40px;
226
+ }
227
+
228
+ .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label {
229
+ padding-left: 60px;
230
+ }
231
+
232
+ .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label {
233
+ padding-left: 80px;
234
+ }
235
+
236
+ .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label {
237
+ padding-left: 100px;
238
+ }
239
+
240
+ .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label {
241
+ padding-left: 110px;
242
+ }
243
+
244
+ .select2-results ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub ul.select2-result-sub > li .select2-result-label {
245
+ padding-left: 120px;
246
+ }
247
+
248
+ .select2-results li {
249
+ list-style: none;
250
+ display: list-item;
251
+ }
252
+
253
+ .select2-results li.select2-result-with-children > .select2-result-label {
254
+ font-weight: 700;
255
+ }
256
+
257
+ .select2-results .select2-result-label {
258
+ cursor: pointer;
259
+ margin: 0;
260
+ padding: 3px 7px 4px;
261
+ }
262
+
263
+ .select2-results .select2-highlighted {
264
+ background: #3875d7;
265
+ color: #fff;
266
+ }
267
+
268
+ .select2-results li em {
269
+ background: #feffde;
270
+ font-style: normal;
271
+ }
272
+
273
+ .select2-results .select2-highlighted em {
274
+ background: transparent;
275
+ }
276
+
277
+ .select2-more-results.select2-active {
278
+ background: #f4f4f4 url(spinner.gif) no-repeat 100%;
279
+ }
280
+
281
+ .select2-container.select2-container-disabled .select2-choice div {
282
+ background-color: #f4f4f4;
283
+ background-image: none;
284
+ border-left: 0;
285
+ }
286
+
287
+ .select2-container-multi .select2-choices {
288
+ background-color: #fff;
289
+ background-image: linear-gradient(top, #eeeeee1%, #ffffff15%);
290
+ border: 1px solid #aaa;
291
+ cursor: text;
292
+ overflow: hidden;
293
+ height: auto !important;
294
+ position: relative;
295
+ min-height: 26px;
296
+ margin: 0;
297
+ padding: 0;
298
+ }
299
+
300
+ .select2-container-multi .select2-choices li {
301
+ float: left;
302
+ list-style: none;
303
+ }
304
+
305
+ .select2-container-multi .select2-choices .select2-search-field {
306
+ white-space: nowrap;
307
+ margin: 0;
308
+ padding: 0;
309
+ }
310
+
311
+ .select2-container-multi .select2-choices .select2-search-field input {
312
+ color: #666;
313
+ background: transparent !important;
314
+ font-family: sans-serif;
315
+ font-size: 100%;
316
+ height: 15px;
317
+ outline: 0;
318
+ border: 0;
319
+ -webkit-box-shadow: none;
320
+ -moz-box-shadow: none;
321
+ -o-box-shadow: none;
322
+ box-shadow: none;
323
+ margin: 1px 0;
324
+ padding: 5px;
325
+ }
326
+
327
+ .select2-container-multi .select2-choices .select2-search-field input.select2-active {
328
+ background: #fff url(spinner.gif) no-repeat 100% !important;
329
+ }
330
+
331
+ .select2-default {
332
+ color: #999 !important;
333
+ }
334
+
335
+ .select2-container-multi .select2-choices .select2-search-choice {
336
+ -webkit-border-radius: 3px;
337
+ -moz-border-radius: 3px;
338
+ border-radius: 3px;
339
+ -moz-background-clip: padding;
340
+ -webkit-background-clip: padding-box;
341
+ background-clip: padding-box;
342
+ background-color: #e4e4e4;
343
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0);
344
+ background-image: linear-gradient(top, #f4f4f420%, #f0f0f050%, #e8e8e852%, #eeeeee100%);
345
+ -webkit-box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
346
+ -moz-box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
347
+ box-shadow: 0 0 2px #fff inset, 0 1px 0 rgba(0, 0, 0, 0.05);
348
+ color: #333;
349
+ border: 1px solid #aaa;
350
+ line-height: 13px;
351
+ position: relative;
352
+ cursor: default;
353
+ margin: 3px 0 3px 5px;
354
+ padding: 3px 5px 3px 18px;
355
+ }
356
+
357
+ .select2-container-multi .select2-choices .select2-search-choice span {
358
+ cursor: default;
359
+ }
360
+
361
+ .select2-container-multi .select2-choices .select2-search-choice-focus {
362
+ background: #d4d4d4;
363
+ }
364
+
365
+ .select2-search-choice-close {
366
+ display: block;
367
+ position: absolute;
368
+ right: 3px;
369
+ top: 4px;
370
+ width: 12px;
371
+ height: 13px;
372
+ font-size: 1px;
373
+ background: url(select2.png) right top no-repeat;
374
+ outline: none;
375
+ }
376
+
377
+ .select2-container-multi .select2-search-choice-close {
378
+ left: 3px;
379
+ }
380
+
381
+ .select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice {
382
+ background-image: none;
383
+ background-color: #f4f4f4;
384
+ border: 1px solid #ddd;
385
+ padding: 3px 5px;
386
+ }
387
+
388
+ .select2-result-selectable .select2-match, .select2-result-unselectable .select2-result-selectable .select2-match {
389
+ text-decoration: underline;
390
+ }
391
+
392
+ .select2-result-unselectable .select2-match {
393
+ text-decoration: none;
394
+ }
395
+
396
+ .select2-offscreen {
397
+ position: absolute;
398
+ left: -10000px;
399
+ }
400
+
401
+ .select2-container-active .select2-choice, .select2-container-active .select2-choices, .select2-container-multi.select2-container-active .select2-choices {
402
+ -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
403
+ -moz-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
404
+ -o-box-shadow: 0 0 5px rgba(0, 0, 0, .3);
405
+ box-shadow: 0 0 5px rgba(0, 0, 0, .3);
406
+ border: 1px solid #5897fb;
407
+ outline: none;
408
+ }
409
+
410
+ .select2-results .select2-no-results, .select2-results .select2-searching, .select2-results .select2-selection-limit, .select2-more-results {
411
+ background: #f4f4f4;
412
+ display: list-item;
413
+ }
414
+
415
+ .select2-results .select2-disabled, .select2-container.select2-container-disabled .select2-choice abbr, .select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close {
416
+ display: none;
417
+ }
418
+
419
+ .select2-container.select2-container-disabled .select2-choice, .select2-container-multi.select2-container-disabled .select2-choices {
420
+ background-color: #f4f4f4;
421
+ background-image: none;
422
+ border: 1px solid #ddd;
423
+ cursor: default;
424
+ }
425
+
426
+ .select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover, .select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close {
427
+ background-position: right -11px;
428
+ }
429
+
430
+ @media only screen and -webkit-min-device-pixel-ratio 15 {
431
+ .select2-search input, .select2-search-choice-close, .select2-container .select2-choice abbr, .select2-container .select2-choice div b {
432
+ background-image: url(select2x2.png) !important;
433
+ background-repeat: no-repeat !important;
434
+ background-size: 60px 40px !important;
435
+ }
436
+
437
+ .select2-search input {
438
+ background-position: 100% -21px !important;
439
+ }
440
+ }
trunk/WCVendors/classes/admin/settings/assets/js/select2/select2.min.js ADDED
@@ -0,0 +1,1564 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ Copyright 2012 Igor Vaynberg
3
+
4
+ Version: @@ver@@ Timestamp: @@timestamp@@
5
+
6
+ This software is licensed under the Apache License, Version 2.0 (the "Apache License") or the GNU
7
+ General Public License version 2 (the "GPL License"). You may choose either license to govern your
8
+ use of this software only upon the condition that you accept all of the terms of either the Apache
9
+ License or the GPL License.
10
+
11
+ You may obtain a copy of the Apache License and the GPL License at:
12
+
13
+ http://www.apache.org/licenses/LICENSE-2.0
14
+ http://www.gnu.org/licenses/gpl-2.0.html
15
+
16
+ Unless required by applicable law or agreed to in writing, software distributed under the
17
+ Apache License or the GPL Licesnse is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
18
+ CONDITIONS OF ANY KIND, either express or implied. See the Apache License and the GPL License for
19
+ the specific language governing permissions and limitations under the Apache License and the GPL License.
20
+ */
21
+ (function ($) {
22
+ if (typeof $.fn.each2 == "undefined") {
23
+ $.fn.extend({each2: function (c) {
24
+ var j = $([0]), i = -1, l = this.length;
25
+ while (++i < l && (j.context = j[0] = this[i]) && c.call(j[0], i, j) !== false);
26
+ return this
27
+ }})
28
+ }
29
+ })(jQuery);
30
+ (function ($, undefined) {
31
+ "use strict";
32
+ if (window.Select2 !== undefined) {
33
+ return
34
+ }
35
+ var KEY, AbstractSelect2, SingleSelect2, MultiSelect2, nextUid, sizer, lastMousePosition, $document;
36
+ KEY = {TAB: 9, ENTER: 13, ESC: 27, SPACE: 32, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, SHIFT: 16, CTRL: 17, ALT: 18, PAGE_UP: 33, PAGE_DOWN: 34, HOME: 36, END: 35, BACKSPACE: 8, DELETE: 46, isArrow: function (k) {
37
+ k = k.which ? k.which : k;
38
+ switch (k) {
39
+ case KEY.LEFT:
40
+ case KEY.RIGHT:
41
+ case KEY.UP:
42
+ case KEY.DOWN:
43
+ return true
44
+ }
45
+ return false
46
+ }, isControl: function (e) {
47
+ var k = e.which;
48
+ switch (k) {
49
+ case KEY.SHIFT:
50
+ case KEY.CTRL:
51
+ case KEY.ALT:
52
+ return true
53
+ }
54
+ if (e.metaKey)return true;
55
+ return false
56
+ }, isFunctionKey: function (k) {
57
+ k = k.which ? k.which : k;
58
+ return k >= 112 && k <= 123
59
+ }};
60
+ $document = $(document);
61
+ nextUid = (function () {
62
+ var counter = 1;
63
+ return function () {
64
+ return counter++
65
+ }
66
+ }());
67
+ function indexOf(value, array) {
68
+ var i = 0, l = array.length, v;
69
+ if (typeof value === "undefined") {
70
+ return-1
71
+ }
72
+ if (value.constructor === String) {
73
+ for (; i < l; i = i + 1)if (value.localeCompare(array[i]) === 0)return i
74
+ } else {
75
+ for (; i < l; i = i + 1) {
76
+ v = array[i];
77
+ if (v.constructor === String) {
78
+ if (v.localeCompare(value) === 0)return i
79
+ } else {
80
+ if (v === value)return i
81
+ }
82
+ }
83
+ }
84
+ return-1
85
+ }
86
+
87
+ function equal(a, b) {
88
+ if (a === b)return true;
89
+ if (a === undefined || b === undefined)return false;
90
+ if (a === null || b === null)return false;
91
+ if (a.constructor === String)return a.localeCompare(b) === 0;
92
+ if (b.constructor === String)return b.localeCompare(a) === 0;
93
+ return false
94
+ }
95
+
96
+ function splitVal(string, separator) {
97
+ var val, i, l;
98
+ if (string === null || string.length < 1)return[];
99
+ val = string.split(separator);
100
+ for (i = 0, l = val.length; i < l; i = i + 1)val[i] = $.trim(val[i]);
101
+ return val
102
+ }
103
+
104
+ function getSideBorderPadding(element) {
105
+ return element.outerWidth(false) - element.width()
106
+ }
107
+
108
+ function installKeyUpChangeEvent(element) {
109
+ var key = "keyup-change-value";
110
+ element.bind("keydown", function () {
111
+ if ($.data(element, key) === undefined) {
112
+ $.data(element, key, element.val())
113
+ }
114
+ });
115
+ element.bind("keyup", function () {
116
+ var val = $.data(element, key);
117
+ if (val !== undefined && element.val() !== val) {
118
+ $.removeData(element, key);
119
+ element.trigger("keyup-change")
120
+ }
121
+ })
122
+ }
123
+
124
+ $document.bind("mousemove", function (e) {
125
+ lastMousePosition = {x: e.pageX, y: e.pageY}
126
+ });
127
+ function installFilteredMouseMove(element) {
128
+ element.bind("mousemove", function (e) {
129
+ var lastpos = lastMousePosition;
130
+ if (lastpos === undefined || lastpos.x !== e.pageX || lastpos.y !== e.pageY) {
131
+ $(e.target).trigger("mousemove-filtered", e)
132
+ }
133
+ })
134
+ }
135
+
136
+ function debounce(quietMillis, fn, ctx) {
137
+ ctx = ctx || undefined;
138
+ var timeout;
139
+ return function () {
140
+ var args = arguments;
141
+ window.clearTimeout(timeout);
142
+ timeout = window.setTimeout(function () {
143
+ fn.apply(ctx, args)
144
+ }, quietMillis)
145
+ }
146
+ }
147
+
148
+ function thunk(formula) {
149
+ var evaluated = false, value;
150
+ return function () {
151
+ if (evaluated === false) {
152
+ value = formula();
153
+ evaluated = true
154
+ }
155
+ return value
156
+ }
157
+ };
158
+ function installDebouncedScroll(threshold, element) {
159
+ var notify = debounce(threshold, function (e) {
160
+ element.trigger("scroll-debounced", e)
161
+ });
162
+ element.bind("scroll", function (e) {
163
+ if (indexOf(e.target, element.get()) >= 0)notify(e)
164
+ })
165
+ }
166
+
167
+ function killEvent(event) {
168
+ event.preventDefault();
169
+ event.stopPropagation()
170
+ }
171
+
172
+ function killEventImmediately(event) {
173
+ event.preventDefault();
174
+ event.stopImmediatePropagation()
175
+ }
176
+
177
+ function measureTextWidth(e) {
178
+ if (!sizer) {
179
+ var style = e[0].currentStyle || window.getComputedStyle(e[0], null);
180
+ sizer = $("<div></div>").css({position: "absolute", left: "-10000px", top: "-10000px", display: "none", fontSize: style.fontSize, fontFamily: style.fontFamily, fontStyle: style.fontStyle, fontWeight: style.fontWeight, letterSpacing: style.letterSpacing, textTransform: style.textTransform, whiteSpace: "nowrap"});
181
+ $("body").append(sizer)
182
+ }
183
+ sizer.text(e.val());
184
+ return sizer.width()
185
+ }
186
+
187
+ function markMatch(text, term, markup) {
188
+ var match = text.toUpperCase().indexOf(term.toUpperCase()), tl = term.length;
189
+ if (match < 0) {
190
+ markup.push(text);
191
+ return
192
+ }
193
+ markup.push(text.substring(0, match));
194
+ markup.push("<span class='select2-match'>");
195
+ markup.push(text.substring(match, match + tl));
196
+ markup.push("</span>");
197
+ markup.push(text.substring(match + tl, text.length))
198
+ }
199
+
200
+ function ajax(options) {
201
+ var timeout, requestSequence = 0, handler = null, quietMillis = options.quietMillis || 100;
202
+ return function (query) {
203
+ window.clearTimeout(timeout);
204
+ timeout = window.setTimeout(function () {
205
+ requestSequence += 1;
206
+ var requestNumber = requestSequence, data = options.data, transport = options.transport || $.ajax, traditional = options.traditional || false, type = options.type || 'GET';
207
+ data = data.call(this, query.term, query.page, query.context);
208
+ if (null !== handler) {
209
+ handler.abort()
210
+ }
211
+ handler = transport.call(null, {url: options.url, dataType: options.dataType, data: data, type: type, traditional: traditional, success: function (data) {
212
+ if (requestNumber < requestSequence) {
213
+ return
214
+ }
215
+ var results = options.results(data, query.page);
216
+ query.callback(results)
217
+ }})
218
+ }, quietMillis)
219
+ }
220
+ }
221
+
222
+ function local(options) {
223
+ var data = options, dataText, text = function (item) {
224
+ return"" + item.text
225
+ };
226
+ if (!$.isArray(data)) {
227
+ text = data.text;
228
+ if (!$.isFunction(text)) {
229
+ dataText = data.text;
230
+ text = function (item) {
231
+ return item[dataText]
232
+ }
233
+ }
234
+ data = data.results
235
+ }
236
+ return function (query) {
237
+ var t = query.term, filtered = {results: []}, process;
238
+ if (t === "") {
239
+ query.callback({results: data});
240
+ return
241
+ }
242
+ process = function (datum, collection) {
243
+ var group, attr;
244
+ datum = datum[0];
245
+ if (datum.children) {
246
+ group = {};
247
+ for (attr in datum) {
248
+ if (datum.hasOwnProperty(attr))group[attr] = datum[attr]
249
+ }
250
+ group.children = [];
251
+ $(datum.children).each2(function (i, childDatum) {
252
+ process(childDatum, group.children)
253
+ });
254
+ if (group.children.length) {
255
+ collection.push(group)
256
+ }
257
+ } else {
258
+ if (query.matcher(t, text(datum))) {
259
+ collection.push(datum)
260
+ }
261
+ }
262
+ };
263
+ $(data).each2(function (i, datum) {
264
+ process(datum, filtered.results)
265
+ });
266
+ query.callback(filtered)
267
+ }
268
+ }
269
+
270
+ function tags(data) {
271
+ if ($.isFunction(data)) {
272
+ return data
273
+ }
274
+ return function (query) {
275
+ var t = query.term, filtered = {results: []};
276
+ $(data).each(function () {
277
+ var isObject = this.text !== undefined, text = isObject ? this.text : this;
278
+ if (t === "" || query.matcher(t, text)) {
279
+ filtered.results.push(isObject ? this : {id: this, text: this})
280
+ }
281
+ });
282
+ query.callback(filtered)
283
+ }
284
+ }
285
+
286
+ function checkFormatter(formatter, formatterName) {
287
+ if ($.isFunction(formatter))return true;
288
+ if (!formatter)return false;
289
+ throw new Error("formatterName must be a function or a falsy value")
290
+ }
291
+
292
+ function evaluate(val) {
293
+ return $.isFunction(val) ? val() : val
294
+ }
295
+
296
+ function countResults(results) {
297
+ var count = 0;
298
+ $.each(results, function (i, item) {
299
+ if (item.children) {
300
+ count += countResults(item.children)
301
+ } else {
302
+ count++
303
+ }
304
+ });
305
+ return count
306
+ }
307
+
308
+ function defaultTokenizer(input, selection, selectCallback, opts) {
309
+ var original = input, dupe = false, token, index, i, l, separator;
310
+ if (!opts.createSearchChoice || !opts.tokenSeparators || opts.tokenSeparators.length < 1)return undefined;
311
+ while (true) {
312
+ index = -1;
313
+ for (i = 0, l = opts.tokenSeparators.length; i < l; i++) {
314
+ separator = opts.tokenSeparators[i];
315
+ index = input.indexOf(separator);
316
+ if (index >= 0)break
317
+ }
318
+ if (index < 0)break;
319
+ token = input.substring(0, index);
320
+ input = input.substring(index + separator.length);
321
+ if (token.length > 0) {
322
+ token = opts.createSearchChoice(token, selection);
323
+ if (token !== undefined && token !== null && opts.id(token) !== undefined && opts.id(token) !== null) {
324
+ dupe = false;
325
+ for (i = 0, l = selection.length; i < l; i++) {
326
+ if (equal(opts.id(token), opts.id(selection[i]))) {
327
+ dupe = true;
328
+ break
329
+ }
330
+ }
331
+ if (!dupe)selectCallback(token)
332
+ }
333
+ }
334
+ }
335
+ if (original.localeCompare(input) != 0)return input
336
+ }
337
+
338
+ $document.ready(function () {
339
+ $document.bind("mousedown touchend", function (e) {
340
+ var target = $(e.target).closest("div.select2-container").get(0), attr;
341
+ if (target) {
342
+ $document.find("div.select2-container-active").each(function () {
343
+ if (this !== target)$(this).data("select2").blur()
344
+ })
345
+ } else {
346
+ target = $(e.target).closest("div.select2-drop").get(0);
347
+ $document.find("div.select2-drop-active").each(function () {
348
+ if (this !== target)$(this).data("select2").blur()
349
+ })
350
+ }
351
+ target = $(e.target);
352
+ attr = target.attr("for");
353
+ if ("LABEL" === e.target.tagName && attr && attr.length > 0) {
354
+ attr = attr.replace(/([\[\].])/g, '\\$1');
355
+ target = $("#" + attr);
356
+ target = target.data("select2");
357
+ if (target !== undefined) {
358
+ target.focus();
359
+ e.preventDefault()
360
+ }
361
+ }
362
+ })
363
+ });
364
+ function clazz(SuperClass, methods) {
365
+ var constructor = function () {
366
+ };
367
+ constructor.prototype = new SuperClass;
368
+ constructor.prototype.constructor = constructor;
369
+ constructor.prototype.parent = SuperClass.prototype;
370
+ constructor.prototype = $.extend(constructor.prototype, methods);
371
+ return constructor
372
+ }
373
+
374
+ AbstractSelect2 = clazz(Object, {bind: function (func) {
375
+ var self = this;
376
+ return function () {
377
+ func.apply(self, arguments)
378
+ }
379
+ }, init: function (opts) {
380
+ var results, search, resultsSelector = ".select2-results";
381
+ this.opts = opts = this.prepareOpts(opts);
382
+ this.id = opts.id;
383
+ if (opts.element.data("select2") !== undefined && opts.element.data("select2") !== null) {
384
+ this.destroy()
385
+ }
386
+ this.enabled = true;
387
+ this.container = this.createContainer();
388
+ this.containerId = "s2id_" + (opts.element.attr("id") || "autogen" + nextUid());
389
+ this.containerSelector = "#" + this.containerId.replace(/([;&,\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g, '\\$1');
390
+ this.container.attr("id", this.containerId);
391
+ this.body = thunk(function () {
392
+ return opts.element.closest("body")
393
+ });
394
+ if (opts.element.attr("class") !== undefined) {
395
+ this.container.addClass(opts.element.attr("class").replace(/validate\[[\S ]+] ?/, ''))
396
+ }
397
+ this.container.css(evaluate(opts.containerCss));
398
+ this.container.addClass(evaluate(opts.containerCssClass));
399
+ this.opts.element.data("select2", this).hide().before(this.container);
400
+ this.container.data("select2", this);
401
+ this.dropdown = this.container.find(".select2-drop");
402
+ this.dropdown.addClass(evaluate(opts.dropdownCssClass));
403
+ this.dropdown.data("select2", this);
404
+ this.results = results = this.container.find(resultsSelector);
405
+ this.search = search = this.container.find("input.select2-input");
406
+ search.attr("tabIndex", this.opts.element.attr("tabIndex"));
407
+ this.resultsPage = 0;
408
+ this.context = null;
409
+ this.initContainer();
410
+ this.initContainerWidth();
411
+ installFilteredMouseMove(this.results);
412
+ this.dropdown.delegate(resultsSelector, "mousemove-filtered", this.bind(this.highlightUnderEvent));
413
+ installDebouncedScroll(80, this.results);
414
+ this.dropdown.delegate(resultsSelector, "scroll-debounced", this.bind(this.loadMoreIfNeeded));
415
+ if ($.fn.mousewheel) {
416
+ results.mousewheel(function (e, delta, deltaX, deltaY) {
417
+ var top = results.scrollTop(), height;
418
+ if (deltaY > 0 && top - deltaY <= 0) {
419
+ results.scrollTop(0);
420
+ killEvent(e)
421
+ } else if (deltaY < 0 && results.get(0).scrollHeight - results.scrollTop() + deltaY <= results.height()) {
422
+ results.scrollTop(results.get(0).scrollHeight - results.height());
423
+ killEvent(e)
424
+ }
425
+ })
426
+ }
427
+ installKeyUpChangeEvent(search);
428
+ search.bind("keyup-change", this.bind(this.updateResults));
429
+ search.bind("focus", function () {
430
+ search.addClass("select2-focused");
431
+ if (search.val() === " ")search.val("")
432
+ });
433
+ search.bind("blur", function () {
434
+ search.removeClass("select2-focused")
435
+ });
436
+ this.dropdown.delegate(resultsSelector, "mouseup", this.bind(function (e) {
437
+ if ($(e.target).closest(".select2-result-selectable:not(.select2-disabled)").length > 0) {
438
+ this.highlightUnderEvent(e);
439
+ this.selectHighlighted(e)
440
+ } else {
441
+ this.focusSearch()
442
+ }
443
+ killEvent(e)
444
+ }));
445
+ this.dropdown.bind("click mouseup mousedown", function (e) {
446
+ e.stopPropagation()
447
+ });
448
+ if ($.isFunction(this.opts.initSelection)) {
449
+ this.initSelection();
450
+ this.monitorSource()
451
+ }
452
+ if (opts.element.is(":disabled") || opts.element.is("[readonly='readonly']"))this.disable()
453
+ }, destroy: function () {
454
+ var select2 = this.opts.element.data("select2");
455
+ if (select2 !== undefined) {
456
+ select2.container.remove();
457
+ select2.dropdown.remove();
458
+ select2.opts.element.removeData("select2").unbind(".select2").show()
459
+ }
460
+ }, prepareOpts: function (opts) {
461
+ var element, select, idKey, ajaxUrl;
462
+ element = opts.element;
463
+ if (element.get(0).tagName.toLowerCase() === "select") {
464
+ this.select = select = opts.element
465
+ }
466
+ if (select) {
467
+ $.each(["id", "multiple", "ajax", "query", "createSearchChoice", "initSelection", "data", "tags"], function () {
468
+ if (this in opts) {
469
+ throw new Error("Option '" + this + "' is not allowed for Select2 when attached to a <select> element.")
470
+ }
471
+ })
472
+ }
473
+ opts = $.extend({}, {populateResults: function (container, results, query) {
474
+ var populate, data, result, children, id = this.opts.id, self = this;
475
+ populate = function (results, container, depth) {
476
+ var i, l, result, selectable, compound, node, label, innerContainer, formatted;
477
+ for (i = 0, l = results.length; i < l; i = i + 1) {
478
+ result = results[i];
479
+ selectable = id(result) !== undefined;
480
+ compound = result.children && result.children.length > 0;
481
+ node = $("<li></li>");
482
+ node.addClass("select2-results-dept-" + depth);
483
+ node.addClass("select2-result");
484
+ node.addClass(selectable ? "select2-result-selectable" : "select2-result-unselectable");
485
+ if (compound) {
486
+ node.addClass("select2-result-with-children")
487
+ }
488
+ node.addClass(self.opts.formatResultCssClass(result));
489
+ label = $("<div></div>");
490
+ label.addClass("select2-result-label");
491
+ formatted = opts.formatResult(result, label, query);
492
+ if (formatted !== undefined) {
493
+ label.html(self.opts.escapeMarkup(formatted))
494
+ }
495
+ node.append(label);
496
+ if (compound) {
497
+ innerContainer = $("<ul></ul>");
498
+ innerContainer.addClass("select2-result-sub");
499
+ populate(result.children, innerContainer, depth + 1);
500
+ node.append(innerContainer)
501
+ }
502
+ node.data("select2-data", result);
503
+ container.append(node)
504
+ }
505
+ };
506
+ populate(results, container, 0)
507
+ }}, $.fn.select2.defaults, opts);
508
+ if (typeof(opts.id) !== "function") {
509
+ idKey = opts.id;
510
+ opts.id = function (e) {
511
+ return e[idKey]
512
+ }
513
+ }
514
+ if (select) {
515
+ opts.query = this.bind(function (query) {
516
+ var data = {results: [], more: false}, term = query.term, children, firstChild, process;
517
+ process = function (element, collection) {
518
+ var group;
519
+ if (element.is("option")) {
520
+ if (query.matcher(term, element.text(), element)) {
521
+ collection.push({id: element.attr("value"), text: element.text(), element: element.get(), css: element.attr("class")})
522
+ }
523
+ } else if (element.is("optgroup")) {
524
+ group = {text: element.attr("label"), children: [], element: element.get(), css: element.attr("class")};
525
+ element.children().each2(function (i, elm) {
526
+ process(elm, group.children)
527
+ });
528
+ if (group.children.length > 0) {
529
+ collection.push(group)
530
+ }
531
+ }
532
+ };
533
+ children = element.children();
534
+ if (this.getPlaceholder() !== undefined && children.length > 0) {
535
+ firstChild = children[0];
536
+ if ($(firstChild).text() === "") {
537
+ children = children.not(firstChild)
538
+ }
539
+ }
540
+ children.each2(function (i, elm) {
541
+ process(elm, data.results)
542
+ });
543
+ query.callback(data)
544
+ });
545
+ opts.id = function (e) {
546
+ return e.id
547
+ };
548
+ opts.formatResultCssClass = function (data) {
549
+ return data.css
550
+ }
551
+ } else {
552
+ if (!("query"in opts)) {
553
+ if ("ajax"in opts) {
554
+ ajaxUrl = opts.element.data("ajax-url");
555
+ if (ajaxUrl && ajaxUrl.length > 0) {
556
+ opts.ajax.url = ajaxUrl
557
+ }
558
+ opts.query = ajax(opts.ajax)
559
+ } else if ("data"in opts) {
560
+ opts.query = local(opts.data)
561
+ } else if ("tags"in opts) {
562
+ opts.query = tags(opts.tags);
563
+ opts.createSearchChoice = function (term) {
564
+ return{id: term, text: term}
565
+ };
566
+ opts.initSelection = function (element, callback) {
567
+ var data = [];
568
+ $(splitVal(element.val(), opts.separator)).each(function () {
569
+ var id = this, text = this, tags = opts.tags;
570
+ if ($.isFunction(tags))tags = tags();
571
+ $(tags).each(function () {
572
+ if (equal(this.id, id)) {
573
+ text = this.text;
574
+ return false
575
+ }
576
+ });
577
+ data.push({id: id, text: text})
578
+ });
579
+ callback(data)
580
+ }
581
+ }
582
+ }
583
+ }
584
+ if (typeof(opts.query) !== "function") {
585
+ throw"query function not defined for Select2 " + opts.element.attr("id")
586
+ }
587
+ return opts
588
+ }, monitorSource: function () {
589
+ this.opts.element.bind("change.select2", this.bind(function (e) {
590
+ if (this.opts.element.data("select2-change-triggered") !== true) {
591
+ this.initSelection()
592
+ }
593
+ }))
594
+ }, triggerChange: function (details) {
595
+ details = details || {};
596
+ details = $.extend({}, details, {type: "change", val: this.val()});
597
+ this.opts.element.data("select2-change-triggered", true);
598
+ this.opts.element.trigger(details);
599
+ this.opts.element.data("select2-change-triggered", false);
600
+ this.opts.element.click();
601
+ if (this.opts.blurOnChange)this.opts.element.blur()
602
+ }, enable: function () {
603
+ if (this.enabled)return;
604
+ this.enabled = true;
605
+ this.container.removeClass("select2-container-disabled");
606
+ this.opts.element.removeAttr("disabled")
607
+ }, disable: function () {
608
+ if (!this.enabled)return;
609
+ this.close();
610
+ this.enabled = false;
611
+ this.container.addClass("select2-container-disabled");
612
+ this.opts.element.attr("disabled", "disabled")
613
+ }, opened: function () {
614
+ return this.container.hasClass("select2-dropdown-open")
615
+ }, positionDropdown: function () {
616
+ var offset = this.container.offset(), height = this.container.outerHeight(true), width = this.container.outerWidth(true), dropHeight = this.dropdown.outerHeight(true), viewportBottom = $(window).scrollTop() + document.documentElement.clientHeight, dropTop = offset.top + height, dropLeft = offset.left, enoughRoomBelow = dropTop + dropHeight <= viewportBottom, enoughRoomAbove = (offset.top - dropHeight) >= this.body().scrollTop(), aboveNow = this.dropdown.hasClass("select2-drop-above"), bodyOffset, above, css;
617
+ if (this.body().css('position') !== 'static') {
618
+ bodyOffset = this.body().offset();
619
+ dropTop -= bodyOffset.top;
620
+ dropLeft -= bodyOffset.left
621
+ }
622
+ if (aboveNow) {
623
+ above = true;
624
+ if (!enoughRoomAbove && enoughRoomBelow)above = false
625
+ } else {
626
+ above = false;
627
+ if (!enoughRoomBelow && enoughRoomAbove)above = true
628
+ }
629
+ if (above) {
630
+ dropTop = offset.top - dropHeight;
631
+ this.container.addClass("select2-drop-above");
632
+ this.dropdown.addClass("select2-drop-above")
633
+ } else {
634
+ this.container.removeClass("select2-drop-above");
635
+ this.dropdown.removeClass("select2-drop-above")
636
+ }
637
+ css = $.extend({top: dropTop, left: dropLeft, width: width}, evaluate(this.opts.dropdownCss));
638
+ this.dropdown.css(css)
639
+ }, shouldOpen: function () {
640
+ var event;
641
+ if (this.opened())return false;
642
+ event = $.Event("open");
643
+ this.opts.element.trigger(event);
644
+ return!event.isDefaultPrevented()
645
+ }, clearDropdownAlignmentPreference: function () {
646
+ this.container.removeClass("select2-drop-above");
647
+ this.dropdown.removeClass("select2-drop-above")
648
+ }, open: function () {
649
+ if (!this.shouldOpen())return false;
650
+ window.setTimeout(this.bind(this.opening), 1);
651
+ return true
652
+ }, opening: function () {
653
+ var cid = this.containerId, selector = this.containerSelector, scroll = "scroll." + cid, resize = "resize." + cid;
654
+ this.container.parents().each(function () {
655
+ $(this).bind(scroll, function () {
656
+ var s2 = $(selector);
657
+ if (s2.length == 0) {
658
+ $(this).unbind(scroll)
659
+ }
660
+ s2.select2("close")
661
+ })
662
+ });
663
+ window.setTimeout(function () {
664
+ $(window).bind(resize, function () {
665
+ var s2 = $(selector);
666
+ if (s2.length == 0) {
667
+ $(window).unbind(resize)
668
+ }
669
+ s2.select2("close")
670
+ })
671
+ }, 10);
672
+ this.clearDropdownAlignmentPreference();
673
+ if (this.search.val() === " ") {
674
+ this.search.val("")
675
+ }
676
+ this.container.addClass("select2-dropdown-open").addClass("select2-container-active");
677
+ this.updateResults(true);
678
+ if (this.dropdown[0] !== this.body().children().last()[0]) {
679
+ this.dropdown.detach().appendTo(this.body())
680
+ }
681
+ this.dropdown.show();
682
+ this.positionDropdown();
683
+ this.dropdown.addClass("select2-drop-active");
684
+ this.ensureHighlightVisible();
685
+ this.focusSearch()
686
+ }, close: function () {
687
+ if (!this.opened())return;
688
+ var self = this;
689
+ this.container.parents().each(function () {
690
+ $(this).unbind("scroll." + self.containerId)
691
+ });
692
+ $(window).unbind("resize." + this.containerId);
693
+ this.clearDropdownAlignmentPreference();
694
+ this.dropdown.hide();
695
+ this.container.removeClass("select2-dropdown-open").removeClass("select2-container-active");
696
+ this.results.empty();
697
+ this.clearSearch();
698
+ this.opts.element.trigger($.Event("close"))
699
+ }, clearSearch: function () {
700
+ }, ensureHighlightVisible: function () {
701
+ var results = this.results, children, index, child, hb, rb, y, more;
702
+ index = this.highlight();
703
+ if (index < 0)return;
704
+ if (index == 0) {
705
+ results.scrollTop(0);
706
+ return
707
+ }
708
+ children = results.find(".select2-result-selectable");
709
+ child = $(children[index]);
710
+ hb = child.offset().top + child.outerHeight(true);
711
+ if (index === children.length - 1) {
712
+ more = results.find("li.select2-more-results");
713
+ if (more.length > 0) {
714
+ hb = more.offset().top + more.outerHeight(true)
715
+ }
716
+ }
717
+ rb = results.offset().top + results.outerHeight(true);
718
+ if (hb > rb) {
719
+ results.scrollTop(results.scrollTop() + (hb - rb))
720
+ }
721
+ y = child.offset().top - results.offset().top;
722
+ if (y < 0) {
723
+ results.scrollTop(results.scrollTop() + y)
724
+ }
725
+ }, moveHighlight: function (delta) {
726
+ var choices = this.results.find(".select2-result-selectable"), index = this.highlight();
727
+ while (index > -1 && index < choices.length) {
728
+ index += delta;
729
+ var choice = $(choices[index]);
730
+ if (choice.hasClass("select2-result-selectable") && !choice.hasClass("select2-disabled")) {
731
+ this.highlight(index);
732
+ break
733
+ }
734
+ }
735
+ }, highlight: function (index) {
736
+ var choices = this.results.find(".select2-result-selectable").not(".select2-disabled");
737
+ if (arguments.length === 0) {
738
+ return indexOf(choices.filter(".select2-highlighted")[0], choices.get())
739
+ }
740
+ if (index >= choices.length)index = choices.length - 1;
741
+ if (index < 0)index = 0;
742
+ choices.removeClass("select2-highlighted");
743
+ $(choices[index]).addClass("select2-highlighted");
744
+ this.ensureHighlightVisible()
745
+ }, countSelectableResults: function () {
746
+ return this.results.find(".select2-result-selectable").not(".select2-disabled").length
747
+ }, highlightUnderEvent: function (event) {
748
+ var el = $(event.target).closest(".select2-result-selectable");
749
+ if (el.length > 0 && !el.is(".select2-highlighted")) {
750
+ var choices = this.results.find('.select2-result-selectable');
751
+ this.highlight(choices.index(el))
752
+ } else if (el.length == 0) {
753
+ this.results.find(".select2-highlighted").removeClass("select2-highlighted")
754
+ }
755
+ }, loadMoreIfNeeded: function () {
756
+ var results = this.results, more = results.find("li.select2-more-results"), below, offset = -1, page = this.resultsPage + 1, self = this, term = this.search.val(), context = this.context;
757
+ if (more.length === 0)return;
758
+ below = more.offset().top - results.offset().top - results.height();
759
+ if (below <= 0) {
760
+ more.addClass("select2-active");
761
+ this.opts.query({term: term, page: page, context: context, matcher: this.opts.matcher, callback: this.bind(function (data) {
762
+ if (!self.opened())return;
763
+ self.opts.populateResults.call(this, results, data.results, {term: term, page: page, context: context});
764
+ if (data.more === true) {
765
+ more.detach().appendTo(results).text(self.opts.formatLoadMore(page + 1));
766
+ window.setTimeout(function () {
767
+ self.loadMoreIfNeeded()
768
+ }, 10)
769
+ } else {
770
+ more.remove()
771
+ }
772
+ self.positionDropdown();
773
+ self.resultsPage = page
774
+ })})
775
+ }
776
+ }, tokenize: function () {
777
+ }, updateResults: function (initial) {
778
+ var search = this.search, results = this.results, opts = this.opts, data, self = this, input;
779
+ if (initial !== true && (this.showSearchInput === false || !this.opened())) {
780
+ return
781
+ }
782
+ search.addClass("select2-active");
783
+ function postRender() {
784
+ results.scrollTop(0);
785
+ search.removeClass("select2-active");
786
+ self.positionDropdown()
787
+ }
788
+
789
+ function render(html) {
790
+ results.html(self.opts.escapeMarkup(html));
791
+ postRender()
792
+ }
793
+
794
+ if (opts.maximumSelectionSize >= 1) {
795
+ data = this.data();
796
+ if ($.isArray(data) && data.length >= opts.maximumSelectionSize && checkFormatter(opts.formatSelectionTooBig, "formatSelectionTooBig")) {
797
+ render("<li class='select2-selection-limit'>" + opts.formatSelectionTooBig(opts.maximumSelectionSize) + "</li>");
798
+ return
799
+ }
800
+ }
801
+ if (search.val().length < opts.minimumInputLength) {
802
+ if (checkFormatter(opts.formatInputTooShort, "formatInputTooShort")) {
803
+ render("<li class='select2-no-results'>" + opts.formatInputTooShort(search.val(), opts.minimumInputLength) + "</li>")
804
+ } else {
805
+ render("")
806
+ }
807
+ return
808
+ } else if (opts.formatSearching()) {
809
+ render("<li class='select2-searching'>" + opts.formatSearching() + "</li>")
810
+ }
811
+ input = this.tokenize();
812
+ if (input != undefined && input != null) {
813
+ search.val(input)
814
+ }
815
+ this.resultsPage = 1;
816
+ opts.query({term: search.val(), page: this.resultsPage, context: null, matcher: opts.matcher, callback: this.bind(function (data) {
817
+ var def;
818
+ if (!this.opened())return;
819
+ this.context = (data.context === undefined) ? null : data.context;
820
+ if (this.opts.createSearchChoice && search.val() !== "") {
821
+ def = this.opts.createSearchChoice.call(null, search.val(), data.results);
822
+ if (def !== undefined && def !== null && self.id(def) !== undefined && self.id(def) !== null) {
823
+ if ($(data.results).filter(function () {
824
+ return equal(self.id(this), self.id(def))
825
+ }).length === 0) {
826
+ data.results.unshift(def)
827
+ }
828
+ }
829
+ }
830
+ if (data.results.length === 0 && checkFormatter(opts.formatNoMatches, "formatNoMatches")) {
831
+ render("<li class='select2-no-results'>" + opts.formatNoMatches(search.val()) + "</li>");
832
+ return
833
+ }
834
+ results.empty();
835
+ self.opts.populateResults.call(this, results, data.results, {term: search.val(), page: this.resultsPage, context: null});
836
+ if (data.more === true && checkFormatter(opts.formatLoadMore, "formatLoadMore")) {
837
+ results.append("<li class='select2-more-results'>" + self.opts.escapeMarkup(opts.formatLoadMore(this.resultsPage)) + "</li>");
838
+ window.setTimeout(function () {
839
+ self.loadMoreIfNeeded()
840
+ }, 10)
841
+ }
842
+ this.postprocessResults(data, initial);
843
+ postRender()
844
+ })})
845
+ }, cancel: function () {
846
+ this.close()
847
+ }, blur: function () {
848
+ this.close();
849
+ this.container.removeClass("select2-container-active");
850
+ this.dropdown.removeClass("select2-drop-active");
851
+ if (this.search[0] === document.activeElement) {
852
+ this.search.blur()
853
+ }
854
+ this.clearSearch();
855
+ this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
856
+ this.opts.element.triggerHandler("blur")
857
+ }, focusSearch: function () {
858
+ this.search.show();
859
+ this.search.focus();
860
+ window.setTimeout(this.bind(function () {
861
+ this.search.show();
862
+ this.search.focus();
863
+ this.search.val(this.search.val())
864
+ }), 10)
865
+ }, selectHighlighted: function () {
866
+ var index = this.highlight(), highlighted = this.results.find(".select2-highlighted").not(".select2-disabled"), data = highlighted.closest('.select2-result-selectable').data("select2-data");
867
+ if (data) {
868
+ highlighted.addClass("select2-disabled");
869
+ this.highlight(index);
870
+ this.onSelect(data)
871
+ }
872
+ }, getPlaceholder: function () {
873
+ return this.opts.element.attr("placeholder") || this.opts.element.attr("data-placeholder") || this.opts.element.data("placeholder") || this.opts.placeholder
874
+ }, initContainerWidth: function () {
875
+ function resolveContainerWidth() {
876
+ var style, attrs, matches, i, l;
877
+ if (this.opts.width === "off") {
878
+ return null
879
+ } else if (this.opts.width === "element") {
880
+ return this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px'
881
+ } else if (this.opts.width === "copy" || this.opts.width === "resolve") {
882
+ style = this.opts.element.attr('style');
883
+ if (style !== undefined) {
884
+ attrs = style.split(';');
885
+ for (i = 0, l = attrs.length; i < l; i = i + 1) {
886
+ matches = attrs[i].replace(/\s/g, '').match(/width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/);
887
+ if (matches !== null && matches.length >= 1)return matches[1]
888
+ }
889
+ }
890
+ if (this.opts.width === "resolve") {
891
+ style = this.opts.element.css('width');
892
+ if (style.indexOf("%") > 0)return style;
893
+ return(this.opts.element.outerWidth(false) === 0 ? 'auto' : this.opts.element.outerWidth(false) + 'px')
894
+ }
895
+ return null
896
+ } else if ($.isFunction(this.opts.width)) {
897
+ return this.opts.width()
898
+ } else {
899
+ return this.opts.width
900
+ }
901
+ };
902
+ var width = resolveContainerWidth.call(this);
903
+ if (width !== null) {
904
+ this.container.attr("style", "width: " + width)
905
+ }
906
+ }});
907
+ SingleSelect2 = clazz(AbstractSelect2, {createContainer: function () {
908
+ var container = $("<div></div>", {"class": "select2-container"}).html([" <a href='#' onclick='return false;' class='select2-choice'>", " <span></span><abbr class='select2-search-choice-close' style='display:none;'></abbr>", " <div><b></b></div>", "</a>", " <div class='select2-drop select2-offscreen'>", " <div class='select2-search'>", " <input type='text' autocomplete='off' class='select2-input'/>", " </div>", " <ul class='select2-results'>", " </ul>", "</div>"].join(""));
909
+ return container
910
+ }, opening: function () {
911
+ this.search.show();
912
+ this.parent.opening.apply(this, arguments);
913
+ this.dropdown.removeClass("select2-offscreen")
914
+ }, close: function () {
915
+ if (!this.opened())return;
916
+ this.parent.close.apply(this, arguments);
917
+ this.dropdown.removeAttr("style").addClass("select2-offscreen").insertAfter(this.selection).show()
918
+ }, focus: function () {
919
+ this.close();
920
+ this.selection.focus()
921
+ }, isFocused: function () {
922
+ return this.selection[0] === document.activeElement
923
+ }, cancel: function () {
924
+ this.parent.cancel.apply(this, arguments);
925
+ this.selection.focus()
926
+ }, initContainer: function () {
927
+ var selection, container = this.container, dropdown = this.dropdown, clickingInside = false;
928
+ this.selection = selection = container.find(".select2-choice");
929
+ this.search.bind("keydown", this.bind(function (e) {
930
+ if (!this.enabled)return;
931
+ if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
932
+ killEvent(e);
933
+ return
934
+ }
935
+ if (this.opened()) {
936
+ switch (e.which) {
937
+ case KEY.UP:
938
+ case KEY.DOWN:
939
+ this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
940
+ killEvent(e);
941
+ return;
942
+ case KEY.TAB:
943
+ case KEY.ENTER:
944
+ this.selectHighlighted();
945
+ killEvent(e);
946
+ return;
947
+ case KEY.ESC:
948
+ this.cancel(e);
949
+ killEvent(e);
950
+ return
951
+ }
952
+ } else {
953
+ if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.ESC) {
954
+ return
955
+ }
956
+ if (this.opts.openOnEnter === false && e.which === KEY.ENTER) {
957
+ return
958
+ }
959
+ this.open();
960
+ if (e.which === KEY.ENTER) {
961
+ return
962
+ }
963
+ }
964
+ }));
965
+ this.search.bind("focus", this.bind(function () {
966
+ this.selection.attr("tabIndex", "-1")
967
+ }));
968
+ this.search.bind("blur", this.bind(function () {
969
+ if (!this.opened())this.container.removeClass("select2-container-active");
970
+ window.setTimeout(this.bind(function () {
971
+ var ti = this.opts.element.attr("tabIndex");
972
+ if (ti) {
973
+ this.selection.attr("tabIndex", ti)
974
+ } else {
975
+ this.selection.removeAttr("tabIndex")
976
+ }
977
+ }), 10)
978
+ }));
979
+ selection.delegate("abbr", "mousedown", this.bind(function (e) {
980
+ if (!this.enabled)return;
981
+ this.clear();
982
+ killEventImmediately(e);
983
+ this.close();
984
+ this.triggerChange();
985
+ this.selection.focus()
986
+ }));
987
+ selection.bind("mousedown", this.bind(function (e) {
988
+ clickingInside = true;
989
+ if (this.opened()) {
990
+ this.close();
991
+ this.selection.focus()
992
+ } else if (this.enabled) {
993
+ this.open()
994
+ }
995
+ clickingInside = false
996
+ }));
997
+ dropdown.bind("mousedown", this.bind(function () {
998
+ this.search.focus()
999
+ }));
1000
+ selection.bind("focus", this.bind(function () {
1001
+ this.container.addClass("select2-container-active");
1002
+ this.search.attr("tabIndex", "-1")
1003
+ }));
1004
+ selection.bind("blur", this.bind(function () {
1005
+ if (!this.opened()) {
1006
+ this.container.removeClass("select2-container-active")
1007
+ }
1008
+ window.setTimeout(this.bind(function () {
1009
+ this.search.attr("tabIndex", this.opts.element.attr("tabIndex"))
1010
+ }), 10)
1011
+ }));
1012
+ selection.bind("keydown", this.bind(function (e) {
1013
+ if (!this.enabled)return;
1014
+ if (e.which == KEY.DOWN || e.which == KEY.UP || (e.which == KEY.ENTER && this.opts.openOnEnter)) {
1015
+ this.open();
1016
+ killEvent(e);
1017
+ return
1018
+ }
1019
+ if (e.which == KEY.DELETE || e.which == KEY.BACKSPACE) {
1020
+ if (this.opts.allowClear) {
1021
+ this.clear()
1022
+ }
1023
+ killEvent(e);
1024
+ return
1025
+ }
1026
+ }));
1027
+ selection.bind("keypress", this.bind(function (e) {
1028
+ var key = String.fromCharCode(e.which);
1029
+ this.search.val(key);
1030
+ this.open()
1031
+ }));
1032
+ this.setPlaceholder();
1033
+ this.search.bind("focus", this.bind(function () {
1034
+ this.container.addClass("select2-container-active")
1035
+ }))
1036
+ }, clear: function () {
1037
+ this.opts.element.val("");
1038
+ this.selection.find("span").empty();
1039
+ this.selection.removeData("select2-data");
1040
+ this.setPlaceholder()
1041
+ }, initSelection: function () {
1042
+ var selected;
1043
+ if (this.opts.element.val() === "" && this.opts.element.text() === "") {
1044
+ this.close();
1045
+ this.setPlaceholder()
1046
+ } else {
1047
+ var self = this;
1048
+ this.opts.initSelection.call(null, this.opts.element, function (selected) {
1049
+ if (selected !== undefined && selected !== null) {
1050
+ self.updateSelection(selected);
1051
+ self.close();
1052
+ self.setPlaceholder()
1053
+ }
1054
+ })
1055
+ }
1056
+ }, prepareOpts: function () {
1057
+ var opts = this.parent.prepareOpts.apply(this, arguments);
1058
+ if (opts.element.get(0).tagName.toLowerCase() === "select") {
1059
+ opts.initSelection = function (element, callback) {
1060
+ var selected = element.find(":selected");
1061
+ if ($.isFunction(callback))callback({id: selected.attr("value"), text: selected.text(), element: selected})
1062
+ }
1063
+ }
1064
+ return opts
1065
+ }, setPlaceholder: function () {
1066
+ var placeholder = this.getPlaceholder();
1067
+ if (this.opts.element.val() === "" && placeholder !== undefined) {
1068
+ if (this.select && this.select.find("option:first").text() !== "")return;
1069
+ this.selection.find("span").html(this.opts.escapeMarkup(placeholder));
1070
+ this.selection.addClass("select2-default");
1071
+ this.selection.find("abbr").hide()
1072
+ }
1073
+ }, postprocessResults: function (data, initial) {
1074
+ var selected = 0, self = this, showSearchInput = true;
1075
+ this.results.find(".select2-result-selectable").each2(function (i, elm) {
1076
+ if (equal(self.id(elm.data("select2-data")), self.opts.element.val())) {
1077
+ selected = i;
1078
+ return false
1079
+ }
1080
+ });
1081
+ this.highlight(selected);
1082
+ if (initial === true) {
1083
+ showSearchInput = this.showSearchInput = countResults(data.results) >= this.opts.minimumResultsForSearch;
1084
+ this.dropdown.find(".select2-search")[showSearchInput ? "removeClass" : "addClass"]("select2-search-hidden");
1085
+ $(this.dropdown, this.container)[showSearchInput ? "addClass" : "removeClass"]("select2-with-searchbox")
1086
+ }
1087
+ }, onSelect: function (data) {
1088
+ var old = this.opts.element.val();
1089
+ this.opts.element.val(this.id(data));
1090
+ this.updateSelection(data);
1091
+ this.close();
1092
+ this.selection.focus();
1093
+ if (!equal(old, this.id(data))) {
1094
+ this.triggerChange()
1095
+ }
1096
+ }, updateSelection: function (data) {
1097
+ var container = this.selection.find("span"), formatted;
1098
+ this.selection.data("select2-data", data);
1099
+ container.empty();
1100
+ formatted = this.opts.formatSelection(data, container);
1101
+ if (formatted !== undefined) {
1102
+ container.append(this.opts.escapeMarkup(formatted))
1103
+ }
1104
+ this.selection.removeClass("select2-default");
1105
+ if (this.opts.allowClear && this.getPlaceholder() !== undefined) {
1106
+ this.selection.find("abbr").show()
1107
+ }
1108
+ }, val: function () {
1109
+ var val, data = null, self = this;
1110
+ if (arguments.length === 0) {
1111
+ return this.opts.element.val()
1112
+ }
1113
+ val = arguments[0];
1114
+ if (this.select) {
1115
+ this.select.val(val).find(":selected").each2(function (i, elm) {
1116
+ data = {id: elm.attr("value"), text: elm.text()};
1117
+ return false
1118
+ });
1119
+ this.updateSelection(data);
1120
+ this.setPlaceholder()
1121
+ } else {
1122
+ if (this.opts.initSelection === undefined) {
1123
+ throw new Error("cannot call val() if initSelection() is not defined")
1124
+ }
1125
+ if (!val) {
1126
+ this.clear();
1127
+ return
1128
+ }
1129
+ this.opts.element.val(val);
1130
+ this.opts.initSelection(this.opts.element, function (data) {
1131
+ self.opts.element.val(!data ? "" : self.id(data));
1132
+ self.updateSelection(data);
1133
+ self.setPlaceholder()
1134
+ })
1135
+ }
1136
+ }, clearSearch: function () {
1137
+ this.search.val("")
1138
+ }, data: function (value) {
1139
+ var data;
1140
+ if (arguments.length === 0) {
1141
+ data = this.selection.data("select2-data");
1142
+ if (data == undefined)data = null;
1143
+ return data
1144
+ } else {
1145
+ if (!value || value === "") {
1146
+ this.clear()
1147
+ } else {
1148
+ this.opts.element.val(!value ? "" : this.id(value));
1149
+ this.updateSelection(value)
1150
+ }
1151
+ }
1152
+ }});
1153
+ MultiSelect2 = clazz(AbstractSelect2, {createContainer: function () {
1154
+ var container = $("<div></div>", {"class": "select2-container select2-container-multi"}).html([" <ul class='select2-choices'>", " <li class='select2-search-field'>", " <input type='text' autocomplete='off' class='select2-input'>", " </li>", "</ul>", "<div class='select2-drop select2-drop-multi' style='display:none;'>", " <ul class='select2-results'>", " </ul>", "</div>"].join(""));
1155
+ return container
1156
+ }, prepareOpts: function () {
1157
+ var opts = this.parent.prepareOpts.apply(this, arguments);
1158
+ if (opts.element.get(0).tagName.toLowerCase() === "select") {
1159
+ opts.initSelection = function (element, callback) {
1160
+ var data = [];
1161
+ element.find(":selected").each2(function (i, elm) {
1162
+ data.push({id: elm.attr("value"), text: elm.text(), element: elm})
1163
+ });
1164
+ if ($.isFunction(callback))callback(data)
1165
+ }
1166
+ }
1167
+ return opts
1168
+ }, initContainer: function () {
1169
+ var selector = ".select2-choices", selection;
1170
+ this.searchContainer = this.container.find(".select2-search-field");
1171
+ this.selection = selection = this.container.find(selector);
1172
+ this.search.bind("keydown", this.bind(function (e) {
1173
+ if (!this.enabled)return;
1174
+ if (e.which === KEY.BACKSPACE && this.search.val() === "") {
1175
+ this.close();
1176
+ var choices, selected = selection.find(".select2-search-choice-focus");
1177
+ if (selected.length > 0) {
1178
+ this.unselect(selected.first());
1179
+ this.search.width(10);
1180
+ killEvent(e);
1181
+ return
1182
+ }
1183
+ choices = selection.find(".select2-search-choice");
1184
+ if (choices.length > 0) {
1185
+ choices.last().addClass("select2-search-choice-focus")
1186
+ }
1187
+ } else {
1188
+ selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus")
1189
+ }
1190
+ if (this.opened()) {
1191
+ switch (e.which) {
1192
+ case KEY.UP:
1193
+ case KEY.DOWN:
1194
+ this.moveHighlight((e.which === KEY.UP) ? -1 : 1);
1195
+ killEvent(e);
1196
+ return;
1197
+ case KEY.ENTER:
1198
+ case KEY.TAB:
1199
+ this.selectHighlighted();
1200
+ killEvent(e);
1201
+ return;
1202
+ case KEY.ESC:
1203
+ this.cancel(e);
1204
+ killEvent(e);
1205
+ return
1206
+ }
1207
+ }
1208
+ if (e.which === KEY.TAB || KEY.isControl(e) || KEY.isFunctionKey(e) || e.which === KEY.BACKSPACE || e.which === KEY.ESC) {
1209
+ return
1210
+ }
1211
+ if (this.opts.openOnEnter === false && e.which === KEY.ENTER) {
1212
+ return
1213
+ }
1214
+ this.open();
1215
+ if (e.which === KEY.PAGE_UP || e.which === KEY.PAGE_DOWN) {
1216
+ killEvent(e)
1217
+ }
1218
+ }));
1219
+ this.search.bind("keyup", this.bind(this.resizeSearch));
1220
+ this.search.bind("blur", this.bind(function (e) {
1221
+ this.container.removeClass("select2-container-active");
1222
+ this.search.removeClass("select2-focused");
1223
+ this.clearSearch();
1224
+ e.stopImmediatePropagation()
1225
+ }));
1226
+ this.container.delegate(selector, "mousedown", this.bind(function (e) {
1227
+ if (!this.enabled)return;
1228
+ if ($(e.target).closest(".select2-search-choice").length > 0) {
1229
+ return
1230
+ }
1231
+ this.clearPlaceholder();
1232
+ this.open();
1233
+ this.focusSearch();
1234
+ e.preventDefault()
1235
+ }));
1236
+ this.container.delegate(selector, "focus", this.bind(function () {
1237
+ if (!this.enabled)return;
1238
+ this.container.addClass("select2-container-active");
1239
+ this.dropdown.addClass("select2-drop-active");
1240
+ this.clearPlaceholder()
1241
+ }));
1242
+ this.clearSearch()
1243
+ }, enable: function () {
1244
+ if (this.enabled)return;
1245
+ this.parent.enable.apply(this, arguments);
1246
+ this.search.removeAttr("disabled")
1247
+ }, disable: function () {
1248
+ if (!this.enabled)return;
1249
+ this.parent.disable.apply(this, arguments);
1250
+ this.search.attr("disabled", true)
1251
+ }, initSelection: function () {
1252
+ var data;
1253
+ if (this.opts.element.val() === "" && this.opts.element.text() === "") {
1254
+ this.updateSelection([]);
1255
+ this.close();
1256
+ this.clearSearch()
1257
+ }
1258
+ if (this.select || this.opts.element.val() !== "") {
1259
+ var self = this;
1260
+ this.opts.initSelection.call(null, this.opts.element, function (data) {
1261
+ if (data !== undefined && data !== null) {
1262
+ self.updateSelection(data);
1263
+ self.close();
1264
+ self.clearSearch()
1265
+ }
1266
+ })
1267
+ }
1268
+ }, clearSearch: function () {
1269
+ var placeholder = this.getPlaceholder();
1270
+ if (placeholder !== undefined && this.getVal().length === 0 && this.search.hasClass("select2-focused") === false) {
1271
+ this.search.val(placeholder).addClass("select2-default");
1272
+ this.resizeSearch()
1273
+ } else {
1274
+ this.search.val(" ").width(10)
1275
+ }
1276
+ }, clearPlaceholder: function () {
1277
+ if (this.search.hasClass("select2-default")) {
1278
+ this.search.val("").removeClass("select2-default")
1279
+ } else {
1280
+ if (this.search.val() === " ")this.search.val("")
1281
+ }
1282
+ }, opening: function () {
1283
+ this.parent.opening.apply(this, arguments);
1284
+ this.clearPlaceholder();
1285
+ this.resizeSearch();
1286
+ this.focusSearch()
1287
+ }, close: function () {
1288
+ if (!this.opened())return;
1289
+ this.parent.close.apply(this, arguments)
1290
+ }, focus: function () {
1291
+ this.close();
1292
+ this.search.focus()
1293
+ }, isFocused: function () {
1294
+ return this.search.hasClass("select2-focused")
1295
+ }, updateSelection: function (data) {
1296
+ var ids = [], filtered = [], self = this;
1297
+ $(data).each(function () {
1298
+ if (indexOf(self.id(this), ids) < 0) {
1299
+ ids.push(self.id(this));
1300
+ filtered.push(this)
1301
+ }
1302
+ });
1303
+ data = filtered;
1304
+ this.selection.find(".select2-search-choice").remove();
1305
+ $(data).each(function () {
1306
+ self.addSelectedChoice(this)
1307
+ });
1308
+ self.postprocessResults()
1309
+ }, tokenize: function () {
1310
+ var input = this.search.val();
1311
+ input = this.opts.tokenizer(input, this.data(), this.bind(this.onSelect), this.opts);
1312
+ if (input != null && input != undefined) {
1313
+ this.search.val(input);
1314
+ if (input.length > 0) {
1315
+ this.open()
1316
+ }
1317
+ }
1318
+ }, onSelect: function (data) {
1319
+ this.addSelectedChoice(data);
1320
+ if (this.select || !this.opts.closeOnSelect)this.postprocessResults();
1321
+ if (this.opts.closeOnSelect) {
1322
+ this.close();
1323
+ this.search.width(10)
1324
+ } else {
1325
+ if (this.countSelectableResults() > 0) {
1326
+ this.search.width(10);
1327
+ this.resizeSearch();
1328
+ this.positionDropdown()
1329
+ } else {
1330
+ this.close()
1331
+ }
1332
+ }
1333
+ this.triggerChange({added: data});
1334
+ this.focusSearch()
1335
+ }, cancel: function () {
1336
+ this.close();
1337
+ this.focusSearch()
1338
+ }, addSelectedChoice: function (data) {
1339
+ var choice = $("<li class='select2-search-choice'>" + " <div></div>" + " <a href='#' onclick='return false;' class='select2-search-choice-close' tabindex='-1'></a>" + "</li>"), id = this.id(data), val = this.getVal(), formatted;
1340
+ formatted = this.opts.formatSelection(data, choice.find("div"));
1341
+ if (formatted != undefined) {
1342
+ choice.find("div").replaceWith("<div>" + this.opts.escapeMarkup(formatted) + "</div>")
1343
+ }
1344
+ choice.find(".select2-search-choice-close").bind("mousedown", killEvent).bind("click dblclick", this.bind(function (e) {
1345
+ if (!this.enabled)return;
1346
+ $(e.target).closest(".select2-search-choice").fadeOut('fast', this.bind(function () {
1347
+ this.unselect($(e.target));
1348
+ this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus");
1349
+ this.close();
1350
+ this.focusSearch()
1351
+ })).dequeue();
1352
+ killEvent(e)
1353
+ })).bind("focus", this.bind(function () {
1354
+ if (!this.enabled)return;
1355
+ this.container.addClass("select2-container-active");
1356
+ this.dropdown.addClass("select2-drop-active")
1357
+ }));
1358
+ choice.data("select2-data", data);
1359
+ choice.insertBefore(this.searchContainer);
1360
+ val.push(id);
1361
+ this.setVal(val)
1362
+ }, unselect: function (selected) {
1363
+ var val = this.getVal(), data, index;
1364
+ selected = selected.closest(".select2-search-choice");
1365
+ if (selected.length === 0) {
1366
+ throw"Invalid argument: " + selected + ". Must be .select2-search-choice"
1367
+ }
1368
+ data = selected.data("select2-data");
1369
+ index = indexOf(this.id(data), val);
1370
+ if (index >= 0) {
1371
+ val.splice(index, 1);
1372
+ this.setVal(val);
1373
+ if (this.select)this.postprocessResults()
1374
+ }
1375
+ selected.remove();
1376
+ this.triggerChange({removed: data})
1377
+ }, postprocessResults: function () {
1378
+ var val = this.getVal(), choices = this.results.find(".select2-result-selectable"), compound = this.results.find(".select2-result-with-children"), self = this;
1379
+ choices.each2(function (i, choice) {
1380
+ var id = self.id(choice.data("select2-data"));
1381
+ if (indexOf(id, val) >= 0) {
1382
+ choice.addClass("select2-disabled").removeClass("select2-result-selectable")
1383
+ } else {
1384
+ choice.removeClass("select2-disabled").addClass("select2-result-selectable")
1385
+ }
1386
+ });
1387
+ compound.each2(function (i, e) {
1388
+ if (e.find(".select2-result-selectable").length == 0) {
1389
+ e.addClass("select2-disabled")
1390
+ } else {
1391
+ e.removeClass("select2-disabled")
1392
+ }
1393
+ });
1394
+ choices.each2(function (i, choice) {
1395
+ if (!choice.hasClass("select2-disabled") && choice.hasClass("select2-result-selectable")) {
1396
+ self.highlight(0);
1397
+ return false
1398
+ }
1399
+ })
1400
+ }, resizeSearch: function () {
1401
+ var minimumWidth, left, maxWidth, containerLeft, searchWidth, sideBorderPadding = getSideBorderPadding(this.search);
1402
+ minimumWidth = measureTextWidth(this.search) + 10;
1403
+ left = this.search.offset().left;
1404
+ maxWidth = this.selection.width();
1405
+ containerLeft = this.selection.offset().left;
1406
+ searchWidth = maxWidth - (left - containerLeft) - sideBorderPadding;
1407
+ if (searchWidth < minimumWidth) {
1408
+ searchWidth = maxWidth - sideBorderPadding
1409
+ }
1410
+ if (searchWidth < 40) {
1411
+ searchWidth = maxWidth - sideBorderPadding
1412
+ }
1413
+ this.search.width(searchWidth)
1414
+ }, getVal: function () {
1415
+ var val;
1416
+ if (this.select) {
1417
+ val = this.select.val();
1418
+ return val === null ? [] : val
1419
+ } else {
1420
+ val = this.opts.element.val();
1421
+ return splitVal(val, this.opts.separator)
1422
+ }
1423
+ }, setVal: function (val) {
1424
+ var unique;
1425
+ if (this.select) {
1426
+ this.select.val(val)
1427
+ } else {
1428
+ unique = [];
1429
+ $(val).each(function () {
1430
+ if (indexOf(this, unique) < 0)unique.push(this)
1431
+ });
1432
+ this.opts.element.val(unique.length === 0 ? "" : unique.join(this.opts.separator))
1433
+ }
1434
+ }, val: function () {
1435
+ var val, data = [], self = this;
1436
+ if (arguments.length === 0) {
1437
+ return this.getVal()
1438
+ }
1439
+ val = arguments[0];
1440
+ if (!val) {
1441
+ this.opts.element.val("");
1442
+ this.updateSelection([]);
1443
+ this.clearSearch();
1444
+ return
1445
+ }
1446
+ this.setVal(val);
1447
+ if (this.select) {
1448
+ this.select.find(":selected").each(function () {
1449
+ data.push({id: $(this).attr("value"), text: $(this).text()})
1450
+ });
1451
+ this.updateSelection(data)
1452
+ } else {
1453
+ if (this.opts.initSelection === undefined) {
1454
+ throw new Error("val() cannot be called if initSelection() is not defined")
1455
+ }
1456
+ this.opts.initSelection(this.opts.element, function (data) {
1457
+ var ids = $(data).map(self.id);
1458
+ self.setVal(ids);
1459
+ self.updateSelection(data);
1460
+ self.clearSearch()
1461
+ })
1462
+ }
1463
+ this.clearSearch()
1464
+ }, onSortStart: function () {
1465
+ if (this.select) {
1466
+ throw new Error("Sorting of elements is not supported when attached to <select>. Attach to <input type='hidden'/> instead.")
1467
+ }
1468
+ this.search.width(0);
1469
+ this.searchContainer.hide()
1470
+ }, onSortEnd: function () {
1471
+ var val = [], self = this;
1472
+ this.searchContainer.show();
1473
+ this.searchContainer.appendTo(this.searchContainer.parent());
1474
+ this.resizeSearch();
1475
+ this.selection.find(".select2-search-choice").each(function () {
1476
+ val.push(self.opts.id($(this).data("select2-data")))
1477
+ });
1478
+ this.setVal(val);
1479
+ this.triggerChange()
1480
+ }, data: function (values) {
1481
+ var self = this, ids;
1482
+ if (arguments.length === 0) {
1483
+ return this.selection.find(".select2-search-choice").map(function () {
1484
+ return $(this).data("select2-data")
1485
+ }).get()
1486
+ } else {
1487
+ if (!values) {
1488
+ values = []
1489
+ }
1490
+ ids = $.map(values, function (e) {
1491
+ return self.opts.id(e)
1492
+ });
1493
+ this.setVal(ids);
1494
+ this.updateSelection(values);
1495
+ this.clearSearch()
1496
+ }
1497
+ }});
1498
+ $.fn.select2 = function () {
1499
+ var args = Array.prototype.slice.call(arguments, 0), opts, select2, value, multiple, allowedMethods = ["val", "destroy", "opened", "open", "close", "focus", "isFocused", "container", "onSortStart", "onSortEnd", "enable", "disable", "positionDropdown", "data"];
1500
+ this.each(function () {
1501
+ if (args.length === 0 || typeof(args[0]) === "object") {
1502
+ opts = args.length === 0 ? {} : $.extend({}, args[0]);
1503
+ opts.element = $(this);
1504
+ if (opts.element.get(0).tagName.toLowerCase() === "select") {
1505
+ multiple = opts.element.attr("multiple")
1506
+ } else {
1507
+ multiple = opts.multiple || false;
1508
+ if ("tags"in opts) {
1509
+ opts.multiple = multiple = true
1510
+ }
1511
+ }
1512
+ select2 = multiple ? new MultiSelect2() : new SingleSelect2();
1513
+ select2.init(opts)
1514
+ } else if (typeof(args[0]) === "string") {
1515
+ if (indexOf(args[0], allowedMethods) < 0) {
1516
+ throw"Unknown method: " + args[0]
1517
+ }
1518
+ value = undefined;
1519
+ select2 = $(this).data("select2");
1520
+ if (select2 === undefined)return;
1521
+ if (args[0] === "container") {
1522
+ value = select2.container
1523
+ } else {
1524
+ value = select2[args[0]].apply(select2, args.slice(1))
1525
+ }
1526
+ if (value !== undefined) {
1527
+ return false
1528
+ }
1529
+ } else {
1530
+ throw"Invalid arguments to select2 plugin: " + args
1531
+ }
1532
+ });
1533
+ return(value === undefined) ? this : value
1534
+ };
1535
+ $.fn.select2.defaults = {width: "copy", closeOnSelect: true, openOnEnter: true, containerCss: {}, dropdownCss: {}, containerCssClass: "", dropdownCssClass: "", formatResult: function (result, container, query) {
1536
+ var markup = [];
1537
+ markMatch(result.text, query.term, markup);
1538
+ return markup.join("")
1539
+ }, formatSelection: function (data, container) {
1540
+ return data ? data.text : undefined
1541
+ }, formatResultCssClass: function (data) {
1542
+ return undefined
1543
+ }, formatNoMatches: function () {
1544
+ return"No matches found"
1545
+ }, formatInputTooShort: function (input, min) {
1546
+ return"Please enter " + (min - input.length) + " more characters"
1547
+ }, formatSelectionTooBig: function (limit) {
1548
+ return"You can only select " + limit + " item" + (limit == 1 ? "" : "s")
1549
+ }, formatLoadMore: function (pageNumber) {
1550
+ return"Loading more results..."
1551
+ }, formatSearching: function () {
1552
+ return"Searching..."
1553
+ }, minimumResultsForSearch: 0, minimumInputLength: 0, maximumSelectionSize: 0, id: function (e) {
1554
+ return e.id
1555
+ }, matcher: function (term, text) {
1556
+ return text.toUpperCase().indexOf(term.toUpperCase()) >= 0
1557
+ }, separator: ",", tokenSeparators: [], tokenizer: defaultTokenizer, escapeMarkup: function (markup) {
1558
+ if (markup && typeof(markup) === "string") {
1559
+ return markup.replace(/&/g, "&amp;")
1560
+ }
1561
+ return markup
1562
+ }, blurOnChange: false};
1563
+ window.Select2 = {query: {ajax: ajax, local: local, tags: tags}, util: {debounce: debounce, markMatch: markMatch}, "class": {"abstract": AbstractSelect2, "single": SingleSelect2, "multi": MultiSelect2}}
1564
+ }(jQuery));
trunk/WCVendors/classes/admin/settings/assets/js/select2/select2.png ADDED
Binary file
trunk/WCVendors/classes/admin/settings/assets/js/select2/select2x2.png ADDED
Binary file
trunk/WCVendors/classes/admin/settings/assets/js/select2/spinner.gif ADDED
Binary file
trunk/WCVendors/classes/admin/settings/assets/js/sf-jquery.js ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function () {
2
+
3
+ jQuery(".sf-tips").tooltip({ animation: true, html: true, delay: { show: 300, hide: 100 } });
4
+
5
+
6
+ //This if statement checks if the color picker widget exists within jQuery UI
7
+ //If it does exist then we initialize the WordPress color picker on our text input field
8
+ if (typeof jQuery.wp === 'object' && typeof jQuery.wp.wpColorPicker === 'function') {
9
+ jQuery('.colorpick').wpColorPicker();
10
+ } else {
11
+ // Color picker
12
+ jQuery('.colorpick').each(function () {
13
+ jQuery('.colorpickdiv', jQuery(this).parent()).farbtastic(this);
14
+ jQuery(this).click(function () {
15
+ if (jQuery(this).val() == "") jQuery(this).val('#');
16
+ jQuery('.colorpickdiv', jQuery(this).parent()).show();
17
+ });
18
+ });
19
+ jQuery(document).mousedown(function () {
20
+ jQuery('.colorpickdiv').hide();
21
+ });
22
+ }
23
+ });
trunk/WCVendors/classes/admin/settings/classes/sf-class-format-options.php ADDED
@@ -0,0 +1,347 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Format an options array into HTML
5
+ * This class has been deprecated
6
+ *
7
+ * @author Matt Gates <http://mgates.me>
8
+ * @package WordPress
9
+ */
10
+
11
+
12
+ if ( !class_exists( 'SF_Format_Options' ) ) {
13
+
14
+ class SF_Format_Options extends SF_Settings_API
15
+ {
16
+
17
+ /**
18
+ * Format an option array into HTML
19
+ *
20
+ *
21
+ * @access public
22
+ *
23
+ * @param unknown $setting
24
+ *
25
+ * @return string HTML.
26
+ */
27
+ public function settings_options_format( $setting )
28
+ {
29
+ if ( empty( $setting ) ) return false;
30
+
31
+ $defaults = apply_filters( $this->id . '_options_defaults', array(
32
+ 'name' => '',
33
+ 'desc' => '',
34
+ 'placeholder' => '',
35
+ 'class' => '',
36
+ 'tip' => '',
37
+ 'id' => '',
38
+ 'css' => '',
39
+ 'type' => 'text',
40
+ 'std' => '',
41
+ 'select2' => false,
42
+ 'multiple' => false,
43
+ 'options' => array(),
44
+ 'restrict' => array(),
45
+ 'settings' => array()
46
+ ) );
47
+
48
+ // Each to it's own variable for slim-ness' sakes.
49
+ $setting = shortcode_atts( $defaults, $setting );
50
+
51
+ $restrict_defaults = array(
52
+ 'min' => 0,
53
+ 'max' => '',
54
+ 'step' => 'any',
55
+ );
56
+
57
+ $setting[ 'restrict' ] = shortcode_atts( $restrict_defaults, $setting[ 'restrict' ] );
58
+
59
+ $setting[ 'value' ] = $this->get_option( $setting[ 'id' ] );
60
+ $setting[ 'value' ] = $setting[ 'value' ] !== false ? maybe_unserialize( $setting[ 'value' ] ) : false;
61
+ $setting[ 'value' ] = SF_Format_Options::sanitize_value( $setting[ 'value' ], $setting );
62
+
63
+ $setting[ 'title' ] = $setting[ 'name' ];
64
+ $setting[ 'name' ] = $this->id . "_options[{$setting['id']}]";
65
+
66
+ $setting[ 'grouped' ] = !$setting[ 'title' ] ? ' style="padding-top:0px;"' : '';
67
+ $setting[ 'tip' ] = SF_Format_Options::get_formatted_tip( $setting[ 'tip' ] );
68
+
69
+ $header_types = apply_filters( $this->id . '_options_header_types', array( 'heading', 'title' ) );
70
+
71
+ extract( $setting );
72
+
73
+ $description = $desc && !$grouped && $type != 'checkbox'
74
+ ? '<br /><small>' . $desc . '</small>'
75
+ : '<label for="' . $id . '"> ' . $desc . '</label>';
76
+
77
+ $description = ( ( in_array( $type, $header_types ) || $type == 'radio' ) && !empty( $desc ) )
78
+ ? '<p>' . $desc . '</p>'
79
+ : $description;
80
+
81
+ ?>
82
+
83
+ <?php if ( !in_array( $type, $header_types ) ) : ?>
84
+ <!-- Header of the option. -->
85
+ <tr valign="top">
86
+ <th scope="row"<?php echo $grouped; ?>>
87
+
88
+ <?php echo $tip; ?>
89
+
90
+ <?php if ( !$grouped ) : ?>
91
+ <label for="<?php echo $name; ?>" class="description"><?php echo $title; ?></label>
92
+ <?php endif; ?>
93
+
94
+ </th>
95
+ <td <?php echo $grouped; ?> >
96
+ <?php endif; ?>
97
+
98
+ <?php foreach ( $header_types as $header ) :
99
+ if ( $type != $header ) continue; ?>
100
+ <tr>
101
+ <th scope="col" colspan="2">
102
+ <h3 class="title"><?php echo $title; ?></h3>
103
+ <?php echo $description; ?>
104
+ </th>
105
+ </tr>
106
+ <?php endforeach; ?>
107
+
108
+ <?php switch ( $type ) :
109
+
110
+ case 'text' :
111
+ case 'color' :
112
+ case 'number' :
113
+ if ( $type == 'color' ) {
114
+ $type = 'text';
115
+ $class .= ' colorpick';
116
+ $description .= '<div id="colorPickerDiv_' . $id . '" class="colorpickdiv" style="z-index: 100;background:#eee;border:1px solid #ccc;position:absolute;display:none;"></div>';
117
+ }
118
+ ?>
119
+ <input name="<?php echo $name; ?>"
120
+ id="<?php echo $id; ?>"
121
+ type="<?php echo $type; ?>"
122
+
123
+ <?php if ( $type == 'number' ): ?>
124
+ min="<?php echo $restrict[ 'min' ]; ?>"
125
+ max="<?php echo $restrict[ 'max' ]; ?>"
126
+ step="<?php echo $restrict[ 'step' ]; ?>"
127
+ <?php endif; ?>
128
+
129
+ class="regular-text <?php echo $class; ?>"
130
+ style="<?php echo $css; ?>"
131
+ placeholder="<?php echo $placeholder; ?>"
132
+ value="<?php echo $value !== false ? $value : $std; ?>"
133
+ />
134
+ <?php echo $description;
135
+ break;
136
+
137
+ case 'checkbox':
138
+
139
+ $selected = ( $value !== false ) ? $value : $std;
140
+
141
+ if ( $multiple ) :
142
+
143
+ foreach ( $options as $key => $desc ) : ?>
144
+
145
+ <input name="<?php echo $name; ?><?php echo $multiple ? '[]' : ''; ?>"
146
+ id="<?php echo $id . '_' . $key; ?>"
147
+ type="checkbox"
148
+ class="<?php echo $class; ?>"
149
+ style="<?php echo $css; ?>"
150
+ value="<?php echo $key; ?>"
151
+ <?php self::checked( $value, $key ); ?>
152
+ />
153
+ <label for="<?php echo $id . '_' . $key; ?>">
154
+ <?php echo $desc; ?>
155
+ </label>
156
+ <br/>
157
+ <?php
158
+
159
+ endforeach;
160
+
161
+ else : ?>
162
+
163
+ <input name="<?php echo $name; ?>"
164
+ id="<?php echo $id ?>"
165
+ type="checkbox"
166
+ class="<?php echo $class; ?>"
167
+ style="<?php echo $css; ?>"
168
+ <?php checked( $selected, 1 ); ?>
169
+ />
170
+ <?php echo $description;
171
+ endif;
172
+ break;
173
+
174
+ case 'radio':
175
+
176
+ $selected = ( $value !== false ) ? $value : $std;
177
+
178
+ foreach ( $options as $key => $val ) : ?>
179
+ <label class="radio">
180
+ <input type="radio"
181
+ name="<?php echo $name; ?>"
182
+ id="<?php echo $key; ?>"
183
+ value="<?php echo $key; ?>"
184
+ class="<?php echo $class; ?>"
185
+ <?php checked( $selected, $key ); ?>
186
+ />
187
+ <?php echo $val; ?>
188
+ </label><br/>
189
+ <?php endforeach;
190
+ echo $description;
191
+ break;
192
+
193
+ case 'single_select_page':
194
+
195
+ $selected = ( $value !== false ) ? $value : $std;
196
+
197
+ $args = array(
198
+ 'name' => $name,
199
+ 'id' => $id,
200
+ 'sort_order' => 'ASC',
201
+ 'echo' => 0,
202
+ 'selected' => $selected
203
+ );
204
+
205
+ echo str_replace( "'>", "'><option></option>", wp_dropdown_pages( $args ) );
206
+
207
+ echo $description;
208
+
209
+ if ( $select2 ) : ?>
210
+ <script type="text/javascript">jQuery(function () {
211
+ jQuery("#<?php echo $id; ?>").select2({ allowClear: true, placeholder: "<?php _e( 'Select a page...', 'geczy' ); ?>", width: '350px' });
212
+ });</script>
213
+ <?php endif;
214
+
215
+ break;
216
+
217
+ case 'select':
218
+
219
+ $selected = ( $value !== false ) ? $value : $std;
220
+ $options = apply_filters( $this->id . '_select_options', $options, $setting ); ?>
221
+
222
+ <select id="<?php echo $id; ?>"
223
+ class="<?php echo $class; ?>"
224
+ style="<?php echo $css; ?>"
225
+ name="<?php echo $name; ?><?php echo $multiple ? '[]' : ''; ?>"
226
+ <?php echo $multiple ? 'multiple="multiple"' : ''; ?>>
227
+
228
+ <?php foreach ( $options as $key => $val ) : ?>
229
+ <option
230
+ value="<?php echo $key; ?>" <?php self::selected( $selected, $key ); ?>><?php echo $val; ?></option>
231
+ <?php endforeach; ?>
232
+ </select>
233
+
234
+ <?php echo $description;
235
+
236
+ if ( $select2 ) : ?>
237
+ <script type="text/javascript">jQuery(function () {
238
+ jQuery("#<?php echo $id; ?>").select2({ width: '350px' });
239
+ });</script>
240
+ <?php endif;
241
+
242
+ break;
243
+
244
+ case 'textarea':
245
+ ?>
246
+ <textarea name="<?php echo $name; ?>"
247
+ id="<?php echo $id; ?>"
248
+ class="large-text <?php echo $class; ?>"
249
+ style="<?php if ( $css ) echo $css; else echo 'width:300px;'; ?>"
250
+ placeholder="<?php echo $placeholder; ?>"
251
+ rows="3"
252
+ ><?php echo ( $value !== false ) ? $value : $std; ?></textarea>
253
+ <?php echo $description;
254
+ break;
255
+
256
+ case 'wysiwyg':
257
+ wp_editor( $value, $id, array( 'textarea_name' => $name ) );
258
+ echo $description;
259
+ break;
260
+
261
+ default :
262
+ do_action( $this->id . '_options_type_' . $type, $setting );
263
+ break;
264
+
265
+ endswitch;
266
+
267
+ /* Footer of the option. */
268
+ if ( !in_array( $type, $header_types ) ) echo '</td></tr>';
269
+
270
+ }
271
+
272
+
273
+ /**
274
+ *
275
+ *
276
+ * @param unknown $haystack
277
+ * @param unknown $current
278
+ */
279
+ private function selected( $haystack, $current )
280
+ {
281
+
282
+ if ( is_array( $haystack ) && in_array( $current, $haystack ) ) {
283
+ $current = $haystack = 1;
284
+ }
285
+
286
+ selected( $haystack, $current );
287
+ }
288
+
289
+
290
+ /**
291
+ *
292
+ *
293
+ * @param unknown $haystack
294
+ * @param unknown $current
295
+ */
296
+ private function checked( $haystack, $current )
297
+ {
298
+
299
+ if ( is_array( $haystack ) && !empty( $haystack[ $current ] ) ) {
300
+ $current = $haystack = 1;
301
+ }
302
+
303
+ checked( $haystack, $current );
304
+ }
305
+
306
+
307
+ /**
308
+ * Format a tooltip given a string
309
+ *
310
+ * @param string $tip
311
+ *
312
+ * @return string
313
+ */
314
+ private function get_formatted_tip( $tip )
315
+ {
316
+ return $tip ? sprintf( '<a href="#" title="%s" class="sf-tips" tabindex="99"></a>', $tip ) : '';
317
+ }
318
+
319
+
320
+ /**
321
+ *
322
+ *
323
+ * @param unknown $value
324
+ * @param unknown $setting
325
+ *
326
+ * @return unknown
327
+ */
328
+ private function sanitize_value( $value, $setting )
329
+ {
330
+ if ( $value !== false && $setting[ 'type' ] != 'wysiwyg' ) {
331
+ if ( is_array( $value ) ) {
332
+ foreach ( $value as $key => $output ) {
333
+ $value[ $key ] = esc_attr( $output );
334
+ }
335
+ } else {
336
+ $value = esc_attr( $value );
337
+ }
338
+ }
339
+
340
+ return apply_filters( $this->id . '_options_sanitize_value', $value, $setting );
341
+ }
342
+
343
+
344
+ }
345
+
346
+
347
+ }
trunk/WCVendors/classes/admin/settings/classes/sf-class-sanitize.php ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Sanitize filters
5
+ *
6
+ * @author Matt Gates <http://mgates.me>
7
+ * @package WordPress
8
+ */
9
+
10
+
11
+ if ( !class_exists( 'SF_Sanitize' ) ) {
12
+
13
+ class SF_Sanitize
14
+ {
15
+
16
+
17
+ /**
18
+ * Hooks
19
+ */
20
+ function __construct()
21
+ {
22
+ add_filter( 'geczy_sanitize_color', 'sanitize_text_field' );
23
+ add_filter( 'geczy_sanitize_text', 'sanitize_text_field' );
24
+ add_filter( 'geczy_sanitize_number', array( 'SF_Sanitize', 'sanitize_number_field' ) );
25
+ add_filter( 'geczy_sanitize_textarea', array( 'SF_Sanitize', 'sanitize_textarea' ) );
26
+ add_filter( 'geczy_sanitize_wysiwyg', array( 'SF_Sanitize', 'sanitize_wysiwyg' ) );
27
+ add_filter( 'geczy_sanitize_checkbox', array( 'SF_Sanitize', 'sanitize_checkbox' ), 10, 2 );
28
+ add_filter( 'geczy_sanitize_radio', array( 'SF_Sanitize', 'sanitize_enum' ), 10, 2 );
29
+ add_filter( 'geczy_sanitize_select', array( 'SF_Sanitize', 'sanitize_enum' ), 10, 2 );
30
+ add_filter( 'geczy_sanitize_single_select_page', array( 'SF_Sanitize', 'sanitize_select_pages' ), 10, 2 );
31
+ }
32
+
33
+
34
+ /**
35
+ * Numeric sanitization
36
+ *
37
+ * @param int $input
38
+ *
39
+ * @return int
40
+ */
41
+ public static function sanitize_number_field( $input )
42
+ {
43
+ $output = is_numeric( $input ) ? (float) $input : false;
44
+
45
+ return $input;
46
+ }
47
+
48
+
49
+ /**
50
+ * Textarea sanitization
51
+ *
52
+ * @param string $input
53
+ *
54
+ * @return string
55
+ */
56
+ public static function sanitize_textarea( $input )
57
+ {
58
+ global $allowedposttags;
59
+ $output = wp_kses( $input, $allowedposttags );
60
+
61
+ return $output;
62
+ }
63
+
64
+
65
+ /**
66
+ * WYSIWYG sanitization
67
+ *
68
+ * @param string $input
69
+ *
70
+ * @return string
71
+ */
72
+ public static function sanitize_wysiwyg( $input )
73
+ {
74
+ return $input;
75
+ }
76
+
77
+
78
+ /**
79
+ * Checkbox sanitization
80
+ *
81
+ * @param int $input
82
+ * @param unknown $option
83
+ *
84
+ * @return int
85
+ */
86
+ public static function sanitize_checkbox( $input, $option )
87
+ {
88
+ if ( !empty( $option[ 'multiple' ] ) ) {
89
+
90
+ $defaults = array_keys( $option[ 'options' ] );
91
+
92
+ foreach ( $defaults as $value ) {
93
+
94
+ if ( !is_array( $input ) ) {
95
+ $output[ $value ] = 0;
96
+ } else {
97
+ $output[ $value ] = in_array( $value, $input ) ? 1 : 0;
98
+ }
99
+
100
+ }
101
+
102
+ $output = serialize( $output );
103
+ } else {
104
+ $output = $input ? 1 : 0;
105
+ }
106
+
107
+ return $output;
108
+ }
109
+
110
+
111
+ /**
112
+ * Array sanitization
113
+ *
114
+ * @param unknown $input
115
+ * @param array $option
116
+ *
117
+ * @return bool
118
+ */
119
+ public static function sanitize_enum( $input, $option )
120
+ {
121
+ $output = $input;
122
+
123
+ $sfs = new SF_Sanitize();
124
+
125
+ if ( is_array( $input ) ) {
126
+ foreach ( $input as $value ) {
127
+ if ( !$sfs->sanitize_enum( $value, $option ) ) {
128
+ $output = false;
129
+ break;
130
+ }
131
+ }
132
+ $output = $output ? serialize( $output ) : $output;
133
+ } else {
134
+ $output = array_key_exists( $input, $option[ 'options' ] ) ? $input : false;
135
+ }
136
+
137
+ return $output;
138
+ }
139
+
140
+
141
+ /**
142
+ * Select box for pages sanitize
143
+ *
144
+ * @param int $input
145
+ * @param int $option
146
+ *
147
+ * @return int
148
+ */
149
+ public static function sanitize_select_pages( $input, $option )
150
+ {
151
+ $output = get_page( $input ) ? (int) $input : 0;
152
+
153
+ return $output;
154
+ }
155
+
156
+
157
+ }
158
+
159
+
160
+ }
trunk/WCVendors/classes/admin/settings/classes/sf-class-settings.php ADDED
@@ -0,0 +1,910 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * WP-Simple-Settings-Framework
5
+ *
6
+ * Copyright (c) 2012 Matt Gates.
7
+ * All rights reserved.
8
+ *
9
+ * Redistribution and use in source and binary forms, with or without
10
+ * modification, are permitted provided that the following conditions
11
+ * are met:
12
+ *
13
+ * * Redistributions of source code must retain the above copyright
14
+ * notice, this list of conditions and the following disclaimer.
15
+ *
16
+ * * Redistributions in binary form must reproduce the above copyright
17
+ * notice, this list of conditions and the following disclaimer in
18
+ * the documentation and/or other materials provided with the
19
+ * distribution.
20
+ *
21
+ * * Neither the names of the copyright holders nor the names of the
22
+ * contributors may be used to endorse or promote products derived
23
+ * from this software without specific prior written permission.
24
+ *
25
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36
+ * POSSIBILITY OF SUCH DAMAGE.
37
+ *
38
+ * @subpackage WP-Simple-Settings-Framework
39
+ * @copyright 2012 Matt Gates.
40
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
41
+ * @link http://mgates.me
42
+ * @version 1.1
43
+ * @author Matt Gates <info@mgates.me>
44
+ * @package WordPress
45
+ */
46
+
47
+
48
+ if ( !class_exists( 'SF_Settings_API' ) ) {
49
+
50
+ class SF_Settings_API
51
+ {
52
+
53
+ private $data = array();
54
+
55
+ /**
56
+ * Init
57
+ *
58
+ * @param string $id
59
+ * @param string $title
60
+ * @param string $menu (optional)
61
+ * @param string $file
62
+ */
63
+ public function __construct( $id, $title, $menu = '', $file )
64
+ {
65
+ $this->assets_url = trailingslashit( plugins_url( 'assets/', dirname( __FILE__ ) ) );
66
+ $this->id = $id;
67
+ $this->title = $title;
68
+ $this->menu = empty( $menu ) ? 'plugins.php' : $menu;
69
+
70
+ $this->file = $file;
71
+
72
+ $this->includes();
73
+ $this->actions();
74
+ }
75
+
76
+
77
+ // ==================================================================
78
+ //
79
+ // Getter and setter.
80
+ //
81
+ // ------------------------------------------------------------------
82
+
83
+ /**
84
+ * Setter
85
+ *
86
+ * @param unknown $name
87
+ * @param unknown $value
88
+ */
89
+ public function __set( $name, $value )
90
+ {
91
+ if ( isset ( $this->data[ $name ] ) && is_array( $this->data[ $name ] ) ) {
92
+ $this->data[ $name ] = array_merge( $this->data[ $name ], $value );
93
+ } else {
94
+ $this->data[ $name ] = $value;
95
+ }
96
+ }
97
+
98
+
99
+ /**
100
+ * Getter
101
+ *
102
+ * @param unknown $name
103
+ *
104
+ * @return unknown
105
+ */
106
+ public function __get( $name )
107
+ {
108
+ if ( array_key_exists( $name, $this->data ) ) {
109
+ return $this->data[ $name ];
110
+ }
111
+
112
+ return null;
113
+ }
114
+
115
+
116
+ /**
117
+ * Isset
118
+ *
119
+ * @param unknown $name
120
+ *
121
+ * @return unknown
122
+ */
123
+ public function __isset( $name )
124
+ {
125
+ return isset( $this->data[ $name ] );
126
+ }
127
+
128
+
129
+ /**
130
+ * Unset
131
+ *
132
+ * @param unknown $name
133
+ */
134
+ public function __unset( $name )
135
+ {
136
+ unset( $this->data[ $name ] );
137
+ }
138
+
139
+
140
+ /**
141
+ * Add a "Settings" link to the plugins.php page
142
+ *
143
+ * @param array $links
144
+ * @param array $file
145
+ *
146
+ * @return array
147
+ */
148
+ public function add_settings_link( $links, $file )
149
+ {
150
+ $this_plugin = plugin_basename( $this->file );
151
+ $page = strpos( $this->menu, '.php' ) ? $this->menu : 'admin.php';
152
+ if ( $file == $this_plugin ) {
153
+ $settings_link = '<a href="' . $page . '?page=' . $this->id . '">' . __( 'Settings', 'geczy' ) . '</a>';
154
+ array_unshift( $links, $settings_link );
155
+ }
156
+
157
+ return $links;
158
+ }
159
+
160
+
161
+ // ==================================================================
162
+ //
163
+ // Begin initialization.
164
+ //
165
+ // ------------------------------------------------------------------
166
+
167
+ /**
168
+ * Core files
169
+ */
170
+ private function includes()
171
+ {
172
+ require_once dirname( __FILE__ ) . '/sf-class-sanitize.php';
173
+ require_once dirname( __FILE__ ) . '/sf-class-format-options.php';
174
+ new SF_Sanitize;
175
+ }
176
+
177
+
178
+ /**
179
+ * Hooks
180
+ */
181
+ private function actions()
182
+ {
183
+ add_action( 'admin_enqueue_scripts', array( &$this, 'admin_enqueue_scripts' ) );
184
+ add_action( 'admin_init', array( &$this, 'register_options' ) );
185
+ add_action( 'admin_menu', array( &$this, 'create_menu' ) );
186
+ add_filter( 'plugin_action_links', array( &$this, 'add_settings_link' ), 10, 2 );
187
+ }
188
+
189
+
190
+ /**
191
+ * Admin scripts and styles
192
+ */
193
+ public function admin_enqueue_scripts()
194
+ {
195
+ wp_register_script( 'bootstrap-tooltip', $this->assets_url . 'js/bootstrap-tooltip.js', array( 'jquery' ), '1.0' );
196
+ wp_register_script( 'select2', $this->assets_url . 'js/select2/select2.min.js', array( 'jquery' ), '1.0' );
197
+ wp_register_script( 'sf-scripts', $this->assets_url . 'js/sf-jquery.js', array( 'jquery' ), '1.0' );
198
+ wp_register_style( 'select2', $this->assets_url . 'js/select2/select2.css' );
199
+ wp_register_style( 'sf-styles', $this->assets_url . 'css/sf-styles.css' );
200
+ }
201
+
202
+
203
+ /**
204
+ * Admin scripts and styles
205
+ */
206
+ public function admin_print_scripts()
207
+ {
208
+ global $wp_version;
209
+
210
+ //Check wp version and load appropriate scripts for colorpicker.
211
+ if ( 3.5 <= $wp_version ) {
212
+ wp_enqueue_style( 'wp-color-picker' );
213
+ wp_enqueue_script( 'wp-color-picker' );
214
+ } else {
215
+ wp_enqueue_style( 'farbtastic' );
216
+ wp_enqueue_script( 'farbtastic' );
217
+ }
218
+
219
+ wp_enqueue_script( 'bootstrap-tooltip' );
220
+ wp_enqueue_script( 'select2' );
221
+ wp_enqueue_script( 'sf-scripts' );
222
+
223
+ wp_enqueue_style( 'wp-color-picker' );
224
+ wp_enqueue_style( 'select2' );
225
+ wp_enqueue_style( 'sf-styles' );
226
+ }
227
+
228
+
229
+ /**
230
+ * Register setting
231
+ */
232
+ public function register_options()
233
+ {
234
+ register_setting( $this->id . '_options_nonce', $this->id . '_options', array( &$this, 'validate_options' ) );
235
+ }
236
+
237
+
238
+ /**
239
+ * Create menu
240
+ */
241
+ public function create_menu()
242
+ {
243
+ $page = add_submenu_page( $this->menu, $this->title, $this->title, apply_filters( $this->id . '_manage_options', 'manage_options' ), $this->id, array( &$this, 'init_settings_page' ) );
244
+ add_action( 'admin_print_scripts-' . $page, array( &$this, 'admin_print_scripts' ) );
245
+ }
246
+
247
+
248
+ /**
249
+ * Parse options into tabbed organization
250
+ *
251
+ * @return array
252
+ */
253
+ private function parse_options()
254
+ {
255
+ $options = $this->options;
256
+
257
+ foreach ( $options as $option ) {
258
+
259
+ if ( $option[ 'type' ] == 'heading' ) {
260
+ $tab_name = sanitize_title( $option[ 'name' ] );
261
+ $this->tab_headers = array( $tab_name => $option[ 'name' ] );
262
+
263
+ continue;
264
+ }
265
+
266
+ $option[ 'tab' ] = $tab_name;
267
+ $tabs[ $tab_name ][ ] = $option;
268
+
269
+ }
270
+
271
+ $this->tabs = $tabs;
272
+
273
+ return $tabs;
274
+ }
275
+
276
+
277
+ /**
278
+ * Load the options array from a file
279
+ *
280
+ * @param string $option_file
281
+ */
282
+ public function load_options( $option_file )
283
+ {
284
+ if ( !empty( $this->options ) ) return;
285
+
286
+ if ( file_exists( $option_file ) ) {
287
+ require $option_file;
288
+ $this->options = apply_filters( $this->id . '_options', $options );
289
+ $this->parse_options();
290
+
291
+ $this->current_options = $this->get_current_options();
292
+
293
+ /* If the option has no saved data, load the defaults. */
294
+ /* @TODO: Can prob add this to the activation hook. */
295
+ $this->set_defaults( $this->current_options );
296
+ } else {
297
+ wp_die( __( 'Could not load settings at: ', 'geczy' ) . '<br/><code>' . $option_file . '</code>', __( 'Error - WP Settings Framework', 'geczy' ) );
298
+ }
299
+ }
300
+
301
+
302
+ /**
303
+ *
304
+ *
305
+ * @return unknown
306
+ */
307
+ public function get_current_options()
308
+ {
309
+ if ( !empty( $this->current_options ) )
310
+ return $this->current_options;
311
+
312
+ $options = get_option( $this->id . '_options' );
313
+
314
+ if ( $options ) {
315
+ $options = array_map( 'maybe_unserialize', $options );
316
+ }
317
+
318
+ return $options;
319
+ }
320
+
321
+
322
+ /**
323
+ * Sanitize and validate post fields
324
+ *
325
+ * @param unknown $input
326
+ *
327
+ * @return unknown
328
+ */
329
+ public function validate_options( $input )
330
+ {
331
+ if ( !isset( $_POST[ 'update' ] ) )
332
+ return $this->get_defaults();
333
+
334
+ $clean = $this->current_options;
335
+ $tabname = $_POST[ 'currentTab' ];
336
+
337
+ foreach ( $this->tabs[ $tabname ] as $option ) :
338
+
339
+ if ( !isset( $option[ 'id' ] ) )
340
+ continue;
341
+
342
+ if ( !isset( $option[ 'type' ] ) )
343
+ continue;
344
+
345
+ if ( $option[ 'type' ] == 'select' ) {
346
+ $option[ 'options' ] = apply_filters( $this->id . '_select_options', $option[ 'options' ], $option );
347
+ }
348
+
349
+ $id = sanitize_text_field( strtolower( $option[ 'id' ] ) );
350
+
351
+ // Set checkbox to false if it wasn't sent in the $_POST
352
+ if ( 'checkbox' == $option[ 'type' ] && !isset( $input[ $id ] ) )
353
+ $input[ $id ] = 0;
354
+
355
+ // For a value to be submitted to database it must pass through a sanitization filter
356
+ if ( has_filter( 'geczy_sanitize_' . $option[ 'type' ] ) ) {
357
+ $clean[ $id ] = apply_filters( 'geczy_sanitize_' . $option[ 'type' ], $input[ $id ], $option );
358
+ }
359
+
360
+ endforeach;
361
+
362
+ do_action( $this->id . '_options_updated', $clean, $tabname );
363
+ add_settings_error( $this->id, 'save_options', __( 'Settings saved.', 'geczy' ), 'updated' );
364
+
365
+ return apply_filters( $this->id . '_options_on_update', $clean, $tabname );
366
+ }
367
+
368
+
369
+ /**
370
+ * Create default options
371
+ *
372
+ * @param unknown $current_options (optional)
373
+ */
374
+ private function set_defaults( $current_options = array() )
375
+ {
376
+ $options = $this->get_defaults( $current_options );
377
+ if ( $options ) {
378
+ update_option( $this->id . '_options', $options );
379
+ }
380
+ }
381
+
382
+
383
+ /**
384
+ * Retrieve default options
385
+ *
386
+ * @param unknown $currents (optional)
387
+ *
388
+ * @return array
389
+ */
390
+ private function get_defaults( $currents = array() )
391
+ {
392
+ $output = array();
393
+ $config = $this->options;
394
+ $flag = false;
395
+
396
+ if ( $currents ) {
397
+ foreach ( $config as $value ) {
398
+ if ( !isset( $value[ 'id' ] ) || !isset( $value[ 'std' ] ) || !isset( $value[ 'type' ] ) )
399
+ continue;
400
+
401
+ if ( !isset( $currents[ $value[ 'id' ] ] ) ) {
402
+ $flag = true;
403
+ }
404
+ }
405
+ }
406
+
407
+ foreach ( $config as $option ) {
408
+ if ( !isset( $option[ 'id' ] ) || !isset( $option[ 'std' ] ) || !isset( $option[ 'type' ] ) )
409
+ continue;
410
+
411
+ if ( $currents && isset( $currents[ $option[ 'id' ] ] ) ) {
412
+ $output[ $option[ 'id' ] ] = $currents[ $option[ 'id' ] ];
413
+ } else if ( has_filter( 'geczy_sanitize_' . $option[ 'type' ] ) ) {
414
+ $output[ $option[ 'id' ] ] = apply_filters( 'geczy_sanitize_' . $option[ 'type' ], $option[ 'std' ], $option );
415
+ }
416
+ }
417
+
418
+ if ( $currents ) {
419
+ $output = array_merge( $currents, $output );
420
+ }
421
+
422
+ return !$flag && $currents ? array() : $output;
423
+ }
424
+
425
+
426
+ /**
427
+ * HTML header
428
+ */
429
+ private function template_header()
430
+ {
431
+ ?>
432
+ <div class="wrap">
433
+ <?php screen_icon(); ?><h2><?php echo $this->title; ?></h2>
434
+
435
+ <h2 class="nav-tab-wrapper">
436
+ <?php echo $this->display_tabs(); ?>
437
+ </h2><?php
438
+
439
+ if ( !empty ( $_REQUEST[ 'settings-updated' ] ) )
440
+ settings_errors();
441
+
442
+ }
443
+
444
+
445
+ /**
446
+ * HTML body
447
+ *
448
+ * @return unknown
449
+ */
450
+ private function template_body()
451
+ {
452
+
453
+ if ( empty( $this->options ) ) return false;
454
+
455
+
456
+ $options = $this->options;
457
+ $tabs = $this->get_tabs();
458
+ $tabname = !empty ( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : $tabs[ 0 ][ 'slug' ];
459
+
460
+ $options = apply_filters( $this->id . '_options_tab-' . $tabname, $this->tabs[ $tabname ] ); ?>
461
+
462
+ <form method="post" action="options.php">
463
+ <?php settings_fields( $this->id . '_options_nonce' ); ?>
464
+ <table class="form-table">
465
+
466
+ <?php
467
+ foreach ( $options as $value ) :
468
+ $this->settings_options_format( $value );
469
+ endforeach;
470
+
471
+ do_action( $this->id . '_options_tab-' . $tabname );
472
+ ?>
473
+
474
+ </table>
475
+
476
+ <p class="submit">
477
+ <input type="hidden" name="currentTab" value="<?php echo $tabname; ?>">
478
+ <input type="submit" name="update" class="button-primary"
479
+ value="<?php echo sprintf( __( 'Save %s changes', 'geczy' ), $this->tab_headers[ $tabname ] ); ?>"/>
480
+ </p>
481
+ </form> <?php
482
+
483
+ }
484
+
485
+
486
+ /**
487
+ * HTML footer
488
+ */
489
+ private function template_footer()
490
+ {
491
+ echo '</div>';
492
+ }
493
+
494
+
495
+ /**
496
+ * Create the settings page
497
+ */
498
+ public function init_settings_page()
499
+ {
500
+
501
+ $this->template_header();
502
+ $this->template_body();
503
+ $this->template_footer();
504
+
505
+ }
506
+
507
+
508
+ /**
509
+ * Retrieve tabs
510
+ *
511
+ * @return array
512
+ */
513
+ private function get_tabs()
514
+ {
515
+ $tabs = array();
516
+ foreach ( $this->options as $option ) {
517
+
518
+ if ( $option[ 'type' ] != 'heading' )
519
+ continue;
520
+
521
+ $option[ 'slug' ] = sanitize_title( $option[ 'name' ] );
522
+ unset( $option[ 'type' ] );
523
+
524
+ $tabs[ ] = $option;
525
+ }
526
+
527
+ return $tabs;
528
+ }
529
+
530
+
531
+ /**
532
+ * Heading for navigation
533
+ *
534
+ * @return string
535
+ */
536
+ private function display_tabs()
537
+ {
538
+ $tabs = $this->get_tabs();
539
+ $tabname = !empty ( $_GET[ 'tab' ] ) ? $_GET[ 'tab' ] : $tabs[ 0 ][ 'slug' ];
540
+ $menu = '';
541
+
542
+ foreach ( $tabs as $tab ) {
543
+ $class = $tabname == $tab[ 'slug' ] ? 'nav-tab-active' : '';
544
+
545
+ $fields = array(
546
+ 'page' => $this->id,
547
+ 'tab' => $tab[ 'slug' ],
548
+ );
549
+
550
+ $query = http_build_query( array_merge( $_GET, $fields ) );
551
+ $menu .= sprintf( '<a id="%s-tab" class="nav-tab %s" title="%s" href="?%s">%s</a>', $tab[ 'slug' ], $class, $tab[ 'name' ], $query, esc_html( $tab[ 'name' ] ) );
552
+ }
553
+
554
+ return $menu;
555
+ }
556
+
557
+
558
+ /**
559
+ * Update an option
560
+ *
561
+ * @param string $name
562
+ * @param string $value
563
+ *
564
+ * @return bool
565
+ */
566
+ public function update_option( $name, $value )
567
+ {
568
+ // Overwrite the key/value pair
569
+ $this->current_options = array( $name => $value ) + (array) $this->current_options;
570
+
571
+ return update_option( $this->id . '_options', $this->current_options );
572
+ }
573
+
574
+
575
+ /**
576
+ * Get an option
577
+ *
578
+ * @param string $name
579
+ * @param string $default (optional)
580
+ *
581
+ * @return bool
582
+ */
583
+ public function get_option( $name, $default = false )
584
+ {
585
+ return isset( $this->current_options[ $name ] ) ? maybe_unserialize( $this->current_options[ $name ] ) : $default;
586
+ }
587
+
588
+
589
+ public function settings_options_format( $setting )
590
+ {
591
+ if ( empty( $setting ) ) return false;
592
+
593
+ $defaults = apply_filters( $this->id . '_options_defaults', array(
594
+ 'name' => '',
595
+ 'desc' => '',
596
+ 'placeholder' => '',
597
+ 'class' => '',
598
+ 'tip' => '',
599
+ 'id' => '',
600
+ 'css' => '',
601
+ 'type' => 'text',
602
+ 'std' => '',
603
+ 'select2' => false,
604
+ 'multiple' => false,
605
+ 'options' => array(),
606
+ 'restrict' => array(),
607
+ 'settings' => array()
608
+ ) );
609
+
610
+ // Each to it's own variable for slim-ness' sakes.
611
+ $setting = shortcode_atts( $defaults, $setting );
612
+
613
+ $restrict_defaults = array(
614
+ 'min' => 0,
615
+ 'max' => '',
616
+ 'step' => 'any',
617
+ );
618
+
619
+ $setting[ 'restrict' ] = shortcode_atts( $restrict_defaults, $setting[ 'restrict' ] );
620
+
621
+ $setting[ 'value' ] = $this->get_option( $setting[ 'id' ] );
622
+ $setting[ 'value' ] = $setting[ 'value' ] !== false ? maybe_unserialize( $setting[ 'value' ] ) : false;
623
+ $setting[ 'value' ] = $this->sanitize_value( $setting[ 'value' ], $setting );
624
+
625
+ $setting[ 'title' ] = $setting[ 'name' ];
626
+ $setting[ 'name' ] = $this->id . "_options[{$setting['id']}]";
627
+
628
+ $setting[ 'grouped' ] = !$setting[ 'title' ] ? ' style="padding-top:0px;"' : '';
629
+ $setting[ 'tip' ] = $this->get_formatted_tip( $setting[ 'tip' ] );
630
+
631
+ $header_types = apply_filters( $this->id . '_options_header_types', array( 'heading', 'title' ) );
632
+
633
+ extract( $setting );
634
+
635
+ $description = $desc && !$grouped && $type != 'checkbox'
636
+ ? '<br /><small>' . $desc . '</small>'
637
+ : '<label for="' . $id . '"> ' . $desc . '</label>';
638
+
639
+ $description = ( ( in_array( $type, $header_types ) || $type == 'radio' ) && !empty( $desc ) )
640
+ ? '<p>' . $desc . '</p>'
641
+ : $description;
642
+
643
+ ?>
644
+
645
+ <?php if ( !in_array( $type, $header_types ) ) : ?>
646
+ <!-- Header of the option. -->
647
+ <tr valign="top">
648
+ <th scope="row"<?php echo $grouped; ?>>
649
+
650
+ <?php echo $tip; ?>
651
+
652
+ <?php if ( !$grouped ) : ?>
653
+ <label for="<?php echo $name; ?>" class="description"><?php echo $title; ?></label>
654
+ <?php endif; ?>
655
+
656
+ </th>
657
+ <td <?php echo $grouped; ?> >
658
+ <?php endif; ?>
659
+
660
+ <?php foreach ( $header_types as $header ) :
661
+ if ( $type != $header ) continue; ?>
662
+ <tr>
663
+ <th scope="col" colspan="2">
664
+ <h3 class="title"><?php echo $title; ?></h3>
665
+ <?php echo $description; ?>
666
+ </th>
667
+ </tr>
668
+ <?php endforeach; ?>
669
+
670
+ <?php switch ( $type ) :
671
+
672
+ case 'text' :
673
+ case 'color' :
674
+ case 'number' :
675
+ if ( $type == 'color' ) {
676
+ $type = 'text';
677
+ $class .= ' colorpick';
678
+ $description .= '<div id="colorPickerDiv_' . $id . '" class="colorpickdiv" style="z-index: 100;background:#eee;border:1px solid #ccc;position:absolute;display:none;"></div>';
679
+ }
680
+ ?>
681
+ <input name="<?php echo $name; ?>"
682
+ id="<?php echo $id; ?>"
683
+ type="<?php echo $type; ?>"
684
+
685
+ <?php if ( $type == 'number' ): ?>
686
+ min="<?php echo $restrict[ 'min' ]; ?>"
687
+ max="<?php echo $restrict[ 'max' ]; ?>"
688
+ step="<?php echo $restrict[ 'step' ]; ?>"
689
+ <?php endif; ?>
690
+
691
+ class="regular-text <?php echo $class; ?>"
692
+ style="<?php echo $css; ?>"
693
+ placeholder="<?php echo $placeholder; ?>"
694
+ value="<?php echo $value !== false ? $value : $std; ?>"
695
+ />
696
+ <?php echo $description;
697
+ break;
698
+
699
+ case 'checkbox':
700
+
701
+ $selected = ( $value !== false ) ? $value : $std;
702
+
703
+ if ( $multiple ) :
704
+
705
+ foreach ( $options as $key => $desc ) : ?>
706
+
707
+ <input name="<?php echo $name; ?><?php echo $multiple ? '[]' : ''; ?>"
708
+ id="<?php echo $id . '_' . $key; ?>"
709
+ type="checkbox"
710
+ class="<?php echo $class; ?>"
711
+ style="<?php echo $css; ?>"
712
+ value="<?php echo $key; ?>"
713
+ <?php @checked( $selected[$key], 1 ); ?>
714
+ />
715
+ <label for="<?php echo $id . '_' . $key; ?>">
716
+ <?php echo $desc; ?>
717
+ </label>
718
+ <br/>
719
+ <?php
720
+
721
+ endforeach;
722
+
723
+ else : ?>
724
+
725
+ <input name="<?php echo $name; ?>"
726
+ id="<?php echo $id ?>"
727
+ type="checkbox"
728
+ class="<?php echo $class; ?>"
729
+ style="<?php echo $css; ?>"
730
+ <?php checked( $selected, 1 ); ?>
731
+ />
732
+ <?php echo $description;
733
+ endif;
734
+ break;
735
+
736
+ case 'radio':
737
+
738
+ $selected = ( $value !== false ) ? $value : $std;
739
+
740
+ foreach ( $options as $key => $val ) : ?>
741
+ <label class="radio">
742
+ <input type="radio"
743
+ name="<?php echo $name; ?>"
744
+ id="<?php echo $key; ?>"
745
+ value="<?php echo $key; ?>"
746
+ class="<?php echo $class; ?>"
747
+ <?php checked( $selected, $key ); ?>
748
+ />
749
+ <?php echo $val; ?>
750
+ </label><br/>
751
+ <?php endforeach;
752
+ echo $description;
753
+ break;
754
+
755
+ case 'single_select_page':
756
+
757
+ $selected = ( $value !== false ) ? $value : $std;
758
+
759
+ $args = array(
760
+ 'name' => $name,
761
+ 'id' => $id,
762
+ 'sort_order' => 'ASC',
763
+ 'echo' => 0,
764
+ 'selected' => $selected
765
+ );
766
+
767
+ echo str_replace( "'>", "'><option></option>", wp_dropdown_pages( $args ) );
768
+
769
+ echo $description;
770
+
771
+ if ( $select2 ) : ?>
772
+ <script type="text/javascript">jQuery(function () {
773
+ jQuery("#<?php echo $id; ?>").select2({ allowClear: true, placeholder: "<?php _e( 'Select a page...', 'geczy' ); ?>", width: '350px' });
774
+ });</script>
775
+ <?php endif;
776
+
777
+ break;
778
+
779
+ case 'select':
780
+
781
+ $selected = ( $value !== false ) ? $value : $std;
782
+ $options = apply_filters( $this->id . '_select_options', $options, $setting ); ?>
783
+
784
+ <select id="<?php echo $id; ?>"
785
+ class="<?php echo $class; ?>"
786
+ style="<?php echo $css; ?>"
787
+ name="<?php echo $name; ?><?php echo $multiple ? '[]' : ''; ?>"
788
+ <?php echo $multiple ? 'multiple="multiple"' : ''; ?>>
789
+
790
+ <?php foreach ( $options as $key => $val ) : ?>
791
+ <option
792
+ value="<?php echo $key; ?>" <?php self::selected( $selected, $key ); ?>><?php echo $val; ?></option>
793
+ <?php endforeach; ?>
794
+ </select>
795
+
796
+ <?php echo $description;
797
+
798
+ if ( $select2 ) : ?>
799
+ <script type="text/javascript">jQuery(function () {
800
+ jQuery("#<?php echo $id; ?>").select2({ width: '350px' });
801
+ });</script>
802
+ <?php endif;
803
+
804
+ break;
805
+
806
+ case 'textarea':
807
+ ?>
808
+ <textarea name="<?php echo $name; ?>"
809
+ id="<?php echo $id; ?>"
810
+ class="large-text <?php echo $class; ?>"
811
+ style="<?php if ( $css ) echo $css; else echo 'width:300px;'; ?>"
812
+ placeholder="<?php echo $placeholder; ?>"
813
+ rows="3"
814
+ ><?php echo ( $value !== false ) ? $value : $std; ?></textarea>
815
+ <?php echo $description;
816
+ break;
817
+
818
+ case 'wysiwyg':
819
+ wp_editor( $value, $id, array( 'textarea_name' => $name ) );
820
+ echo $description;
821
+ break;
822
+
823
+ default :
824
+ do_action( $this->id . '_options_type_' . $type, $setting );
825
+ break;
826
+
827
+ endswitch;
828
+
829
+ /* Footer of the option. */
830
+ if ( !in_array( $type, $header_types ) ) echo '</td></tr>';
831
+
832
+ }
833
+
834
+
835
+ /**
836
+ *
837
+ *
838
+ * @param unknown $haystack
839
+ * @param unknown $current
840
+ */
841
+ private function selected( $haystack, $current )
842
+ {
843
+
844
+ if ( is_array( $haystack ) && in_array( $current, $haystack ) ) {
845
+ $current = $haystack = 1;
846
+ }
847
+
848
+ selected( $haystack, $current );
849
+ }
850
+
851
+
852
+ /**
853
+ *
854
+ *
855
+ * @param unknown $haystack
856
+ * @param unknown $current
857
+ */
858
+ private function checked( $haystack, $current )
859
+ {
860
+
861
+ if ( is_array( $haystack ) && !empty( $haystack[ $current ] ) ) {
862
+ $current = $haystack = 1;
863
+ }
864
+
865
+ checked( $haystack, $current );
866
+ }
867
+
868
+
869
+ /**
870
+ * Format a tooltip given a string
871
+ *
872
+ * @param string $tip
873
+ *
874
+ * @return string
875
+ */
876
+ private function get_formatted_tip( $tip )
877
+ {
878
+ return $tip ? sprintf( '<a href="#" title="%s" class="sf-tips" tabindex="99"></a>', $tip ) : '';
879
+ }
880
+
881
+
882
+ /**
883
+ *
884
+ *
885
+ * @param unknown $value
886
+ * @param unknown $setting
887
+ *
888
+ * @return unknown
889
+ */
890
+ private function sanitize_value( $value, $setting )
891
+ {
892
+ if ( $value !== false && $setting[ 'type' ] != 'wysiwyg' ) {
893
+ if ( is_array( $value ) ) {
894
+ foreach ( $value as $key => $output ) {
895
+ $value[ $key ] = esc_attr( $output );
896
+ }
897
+ } else {
898
+ $value = esc_attr( $value );
899
+ }
900
+ }
901
+
902
+ return apply_filters( $this->id . '_options_sanitize_value', $value, $setting );
903
+ }
904
+
905
+
906
+
907
+ }
908
+
909
+
910
+ }
trunk/WCVendors/classes/admin/settings/sf-options.php ADDED
@@ -0,0 +1,306 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $options = array();
3
+
4
+ $options[ ] = array( 'name' => __( 'General', 'wcvendors' ), 'type' => 'heading' );
5
+ $options[ ] = array( 'name' => __( 'General options', 'wcvendors' ), 'type' => 'title', 'desc' => __( ' ', 'wcvendors' ) );
6
+
7
+ $options[ ] = array(
8
+ 'name' => __( 'Default commission (%)', 'wcvendors' ),
9
+ 'desc' => __( 'The default rate the vendor receives for each product. If a product has a commission rate already set, this value will be ignored for that product.', 'wcvendors' ),
10
+ 'id' => 'default_commission',
11
+ 'css' => 'width:70px;',
12
+ 'type' => 'number',
13
+ 'restrict' => array(
14
+ 'min' => 0,
15
+ 'max' => 100
16
+ )
17
+ );
18
+
19
+ $options[ ] = array(
20
+ 'name' => __( 'Registration', 'wcvendors' ),
21
+ 'desc' => __( 'Allow users or guests to apply to become a vendor', 'wcvendors' ),
22
+ 'tip' => __( 'This will show a checkbox on the My Account page\'s registration form asking if the user would like to apply to be a vendor. Also, on the Vendor Dashboard, users can apply to become a vendor.', 'wcvendors' ),
23
+ 'id' => 'show_vendor_registration',
24
+ 'type' => 'checkbox',
25
+ 'std' => true,
26
+ );
27
+
28
+ $options[ ] = array(
29
+ 'desc' => __( 'Approve vendor applications manually', 'wcvendors' ),
30
+ 'tip' => __( 'With this unchecked, all vendor applications are automatically accepted. Otherwise, you must approve each manually.', 'wcvendors' ),
31
+ 'id' => 'manual_vendor_registration',
32
+ 'type' => 'checkbox',
33
+ 'std' => true,
34
+ );
35
+
36
+ $options[ ] = array(
37
+ 'name' => __( 'Taxes', 'wcvendors' ),
38
+ 'desc' => __( 'Give vendors any tax collected per-product', 'wcvendors' ),
39
+ 'tip' => __( 'The tax collected on a vendor\'s product will be given to him in its entirety', 'wcvendors' ),
40
+ 'id' => 'give_tax',
41
+ 'type' => 'checkbox',
42
+ 'std' => false,
43
+ );
44
+
45
+ $options[ ] = array( 'name' => __( 'Shop options', 'wcvendors' ), 'type' => 'title', 'desc' => __( ' ', 'wcvendors' ) );
46
+
47
+ $options[ ] = array(
48
+ 'name' => __( 'Shop HTML', 'wcvendors' ),
49
+ 'desc' => __( 'Enable HTML for a vendor\'s shop description by default', 'wcvendors' ),
50
+ 'id' => 'shop_html_enabled',
51
+ 'type' => 'checkbox',
52
+ 'std' => true,
53
+ );
54
+
55
+ $options[ ] = array(
56
+ 'name' => __( 'Vendor shop page', 'wcvendors' ),
57
+ 'desc' => __( 'Eg: <code>yoursite.com/[your_setting_here]/[vendor_name_here]</code>', 'wcvendors' ),
58
+ 'id' => 'vendor_shop_permalink',
59
+ 'type' => 'text',
60
+ 'std' => 'vendors/',
61
+ );
62
+
63
+ $options[ ] = array(
64
+ 'name' => __( 'Shop Headers', 'wcvendors' ),
65
+ 'desc' => __( 'Enable vendor shop headers', 'wcvendors' ),
66
+ 'tip' => __( 'This will override the HTML Shop description output on product-archive pages.', 'wcvendors' ),
67
+ 'id' => 'shop_headers_enabled',
68
+ 'type' => 'checkbox',
69
+ 'std' => false,
70
+ );
71
+
72
+ $options[ ] = array( 'name' => __( 'Products', 'wcvendors' ), 'type' => 'heading' );
73
+ $options[ ] = array( 'name' => __( 'Product Add Page', 'wcvendors' ), 'type' => 'title', 'desc' => __( 'Configure what to hide from all vendors when adding a product', 'wcvendors' ) );
74
+
75
+ $options[ ] = array(
76
+ 'name' => __( 'Left side panel', 'wcvendors' ),
77
+ 'desc' => __( 'Hide these areas of the add product page for vendors', 'wcvendors' ),
78
+ 'id' => 'hide_product_panel',
79
+ 'options' => array(
80
+ 'inventory' => 'Inventory',
81
+ 'shipping' => 'Shipping',
82
+ 'linked_product' => 'Linked Products',
83
+ 'attribute' => 'Attributes',
84
+ 'advanced' => 'Advanced',
85
+ ),
86
+ 'type' => 'checkbox',
87
+ 'multiple' => true,
88
+ );
89
+
90
+ $options[ ] = array(
91
+ 'name' => __( 'Types', 'wcvendors' ),
92
+ 'desc' => __( 'Hide these product types from the vendor', 'wcvendors' ),
93
+ 'id' => 'hide_product_types',
94
+ 'options' => array(
95
+ 'simple' => 'Simple',
96
+ 'variable' => 'Variable',
97
+ 'grouped' => 'Grouped',
98
+ 'external' => 'External / affiliate',
99
+ ),
100
+ 'type' => 'checkbox',
101
+ 'multiple' => true,
102
+ );
103
+
104
+ $options[ ] = array(
105
+ 'name' => __( 'Type options', 'wcvendors' ),
106
+ 'desc' => __( 'Hide these product options from the vendor', 'wcvendors' ),
107
+ 'id' => 'hide_product_type_options',
108
+ 'options' => array(
109
+ 'virtual' => 'Virtual',
110
+ 'downloadable' => 'Downloadable',
111
+ ),
112
+ 'type' => 'checkbox',
113
+ 'multiple' => true,
114
+ );
115
+
116
+ $options[ ] = array(
117
+ 'name' => __( 'Miscellaneous', 'wcvendors' ),
118
+ 'id' => 'hide_product_misc',
119
+ 'options' => array(
120
+ 'taxes' => 'Taxes',
121
+ 'sku' => 'SKU',
122
+ 'featured' => 'Featured',
123
+ ),
124
+ 'type' => 'checkbox',
125
+ 'multiple' => true,
126
+ );
127
+
128
+ $options[ ] = array(
129
+ 'name' => __( 'Stylesheet', 'wcvendors' ),
130
+ 'desc' => __( 'You can add CSS in this textarea, which will be loaded on the product add/edit page for vendors.', 'wcvendors' ),
131
+ 'id' => 'product_page_css',
132
+ 'type' => 'textarea',
133
+ );
134
+
135
+
136
+ $options[ ] = array( 'name' => __( 'Capabilities', 'wcvendors' ), 'type' => 'heading', 'id' => 'capabilities' );
137
+ $options[ ] = array( 'name' => __( 'Permissions', 'wcvendors' ), 'id' => 'permissions', 'type' => 'title', 'desc' => __( 'General permissions used around the shop', 'wcvendors' ) );
138
+
139
+ $options[ ] = array(
140
+ 'name' => __( 'Orders', 'wcvendors' ),
141
+ 'desc' => __( 'View orders', 'wcvendors' ),
142
+ 'tip' => __( 'Show customer details such as email, address, name, etc, for each order', 'wcvendors' ),
143
+ 'id' => 'can_show_orders',
144
+ 'type' => 'checkbox',
145
+ 'std' => true,
146
+ );
147
+
148
+ $options[ ] = array(
149
+ 'desc' => __( 'View comments', 'wcvendors' ),
150
+ 'tip' => __( 'View all vendor comments for an order on the frontend', 'wcvendors' ),
151
+ 'id' => 'can_view_order_comments',
152
+ 'type' => 'checkbox',
153
+ 'std' => true,
154
+ );
155
+
156
+ $options[ ] = array(
157
+ 'desc' => __( 'Submit comments', 'wcvendors' ),
158
+ 'tip' => __( 'Submit comments for an order on the frontend. Eg, tracking ID for a product', 'wcvendors' ),
159
+ 'id' => 'can_submit_order_comments',
160
+ 'type' => 'checkbox',
161
+ 'std' => true,
162
+ );
163
+
164
+ $options[ ] = array(
165
+ 'desc' => __( 'View email addresses', 'wcvendors' ),
166
+ 'tip' => __( 'While viewing order details on the frontend, you can disable or enable email addresses', 'wcvendors' ),
167
+ 'id' => 'can_view_order_emails',
168
+ 'type' => 'checkbox',
169
+ 'std' => true,
170
+ );
171
+
172
+ $options[ ] = array(
173
+ 'desc' => __( 'Export a CSV file of orders for a product', 'wcvendors' ),
174
+ 'tip' => __( 'Vendors could export orders for a product on the frontend', 'wcvendors' ),
175
+ 'id' => 'can_export_csv',
176
+ 'type' => 'checkbox',
177
+ 'std' => true,
178
+ );
179
+
180
+ $options[ ] = array(
181
+ 'name' => __( 'Reports', 'wcvendors' ),
182
+ 'desc' => __( 'View backend sales reports', 'wcvendors' ),
183
+ 'tip' => __( 'Graphs and tables via the Reports page in backend. The reports will only display sales data that pertain to their products', 'wcvendors' ),
184
+ 'id' => 'can_view_backend_reports',
185
+ 'type' => 'checkbox',
186
+ 'std' => true,
187
+ );
188
+
189
+ $options[ ] = array(
190
+ 'desc' => __( 'View Frontend sales reports', 'wcvendors' ),
191
+ 'tip' => __( 'Sales table on the frontend on the My Account page. The table will only display sales data that pertain to their products', 'wcvendors' ),
192
+ 'id' => 'can_view_frontend_reports',
193
+ 'type' => 'checkbox',
194
+ 'std' => true,
195
+ );
196
+
197
+ $options[ ] = array(
198
+ 'name' => __( 'Products', 'wcvendors' ),
199
+ 'desc' => __( 'Submit products', 'wcvendors' ),
200
+ 'tip' => __( 'Vendors could submit a product through the backend, and an admin would approve or deny it', 'wcvendors' ),
201
+ 'id' => 'can_submit_products',
202
+ 'type' => 'checkbox',
203
+ 'std' => true,
204
+ );
205
+
206
+ $options[ ] = array(
207
+ 'desc' => __( 'Edit live products', 'wcvendors' ),
208
+ 'tip' => __( 'Vendors could edit an approved product after it has already gone live. There is no approval or review after editing a live product. This could be dangerous with malicious vendors, so take caution.', 'wcvendors' ),
209
+ 'id' => 'can_edit_published_products',
210
+ 'type' => 'checkbox',
211
+ 'std' => false,
212
+ );
213
+
214
+ $options[ ] = array(
215
+ 'desc' => __( 'Submit products live without requiring approval', 'wcvendors' ),
216
+ 'tip' => __( 'Vendors can submit products without review or approval from a shop admin. This could be dangerous with malicious vendors, so take caution.', 'wcvendors' ),
217
+ 'id' => 'can_submit_live_products',
218
+ 'type' => 'checkbox',
219
+ 'std' => false,
220
+ );
221
+
222
+ $options[ ] = array( 'name' => __( 'Pages', 'wcvendors' ), 'type' => 'heading' );
223
+ $options[ ] = array( 'name' => __( 'Page configuration', 'wcvendors' ), 'type' => 'title', 'desc' => __( ' ', 'wcvendors' ) );
224
+
225
+ $options[ ] = array(
226
+ 'name' => __( 'Vendor dashboard', 'wcvendors' ),
227
+ 'desc' => __( 'Choose the page that has the shortcode <code>[wcv_vendor_dashboard]</code><br/>By default, My Account > Vendor Dashboard should have the shortcode.', 'wcvendors' ),
228
+ 'id' => 'vendor_dashboard_page',
229
+ 'type' => 'single_select_page',
230
+ 'select2' => true,
231
+ );
232
+
233
+ $options[ ] = array(
234
+ 'name' => __( 'Shop settings', 'wcvendors' ),
235
+ 'desc' => __( 'Choose the page that has the shortcode <code>[wcv_shop_settings]</code><br/>These are the shop settings a vendor can configure.', 'wcvendors' ),
236
+ 'id' => 'shop_settings_page',
237
+ 'type' => 'single_select_page',
238
+ 'select2' => true,
239
+ );
240
+
241
+ $options[ ] = array(
242
+ 'name' => __( 'Orders page', 'wcvendors' ),
243
+ 'desc' => __( 'Choose the page that has the shortcode <code>[wcv_orders]</code><br/>By default, My Account > Orders should have the shortcode.', 'wcvendors' ),
244
+ 'id' => 'orders_page',
245
+ 'type' => 'single_select_page',
246
+ 'select2' => true,
247
+ );
248
+
249
+ $options[ ] = array(
250
+ 'name' => __( 'Vendor terms', 'wcvendors' ),
251
+ 'desc' => __( 'These terms are shown to a user when submitting an application to become a vendor.<br/>If left blank, no terms will be shown to the applicant.', 'wcvendors' ),
252
+ 'id' => 'terms_to_apply_page',
253
+ 'type' => 'single_select_page',
254
+ 'select2' => true,
255
+ );
256
+
257
+ $total_due = 0;
258
+ if ( !empty( $_GET[ 'tab' ] ) && $_GET[ 'tab' ] == 'payments' ) {
259
+ global $wpdb;
260
+
261
+ $table_name = $wpdb->prefix . "pv_commission";
262
+ $query = "SELECT sum(total_due + total_shipping + tax) as total
263
+ FROM `{$table_name}`
264
+ WHERE status = %s";
265
+ $results = $wpdb->get_results( $wpdb->prepare( $query, 'due' ) );
266
+
267
+ $total_due = array_shift( $results )->total;
268
+ }
269
+ $options[ ] = array( 'name' => __( 'Payments', 'wcvendors' ), 'type' => 'heading' );
270
+ $options[ ] = array(
271
+ 'name' => __( 'User payments', 'wcvendors' ), 'type' => 'title', 'desc' =>
272
+ sprintf( __( 'Total commission currently due: %s. <a href="%s">View details</a>.', 'wcvendors' ), !function_exists( 'woocommerce_price' ) ? $total_due : woocommerce_price( $total_due ), '?page=pv_admin_commissions' ) .
273
+ '<br/><br/>' . sprintf( __( 'Make sure you update your PayPal Adaptive Payments settings <a href="%s">here</a>.', 'wcvendors' ), 'admin.php?page=wc-settings&tab=checkout&section=wc_paypalap' )
274
+ );
275
+
276
+ $options[ ] = array(
277
+ 'name' => __( 'Instant pay', 'wcvendors' ),
278
+ 'desc' => __( 'Instantly pay vendors their commission when an order is made', 'wcvendors' ),
279
+ 'tip' => __( 'For this to work, customers must checkout with the PayPal Adaptive Payments gateway. Using other gateways will not pay vendors instantly', 'wcvendors' ),
280
+ 'id' => 'instapay',
281
+ 'type' => 'checkbox',
282
+ 'std' => true,
283
+ );
284
+
285
+ $options[ ] = array(
286
+ 'name' => __( 'Payment schedule', 'wcvendors' ),
287
+ 'desc' => __( 'Note: Schedule will only work if instant pay is unchecked', 'wcvendors' ),
288
+ 'id' => 'schedule',
289
+ 'type' => 'radio',
290
+ 'std' => 'manual',
291
+ 'options' => array(
292
+ 'weekly' => __( 'Weekly', 'wcvendors' ),
293
+ 'biweekly' => __( 'Biweekly', 'wcvendors' ),
294
+ 'monthly' => __( 'Monthly', 'wcvendors' ),
295
+ 'manual' => __( 'Manual', 'wcvendors' ),
296
+ 'now' => '<span style="color:green;"><strong>' . __( 'Now', 'wcvendors' ) . '</strong></span>',
297
+ )
298
+ );
299
+
300
+ $options[ ] = array(
301
+ 'name' => __( 'Email notification', 'wcvendors' ),
302
+ 'desc' => __( 'Send the WooCommerce admin an email each time a payment has been made via the payment schedule options above', 'wcvendors' ),
303
+ 'id' => 'mail_mass_pay_results',
304
+ 'type' => 'checkbox',
305
+ 'std' => true,
306
+ );
trunk/WCVendors/classes/class-commission.php ADDED
@@ -0,0 +1,341 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Commission functions
5
+ *
6
+ * @author Matt Gates <http://mgates.me>
7
+ * @package ProductVendor
8
+ */
9
+
10
+
11
+ class WCV_Commission
12
+ {
13
+
14
+
15
+ /**
16
+ * Constructor
17
+ */
18
+ function __construct()
19
+ {
20
+ $this->completed_statuses = apply_filters( 'wcvendors_completed_statuses', array(
21
+ 'completed',
22
+ 'processing',
23
+ ) );
24
+
25
+ $this->reverse_statuses = apply_filters( 'wcvendors_reversed_statuses', array(
26
+ 'pending',
27
+ 'refunded',
28
+ 'cancelled',
29
+ 'failed',
30
+ ) );
31
+
32
+ $this->check_order_reverse();
33
+ $this->check_order_complete();
34
+ }
35
+
36
+
37
+ /**
38
+ * Run actions when an order is reversed
39
+ */
40
+ public function check_order_reverse()
41
+ {
42
+ foreach ( $this->completed_statuses as $completed ) {
43
+ foreach ( $this->reverse_statuses as $reversed ) {
44
+ add_action( "woocommerce_order_status_{$completed}_to_{$reversed}", array( 'WCV_Commission', 'reverse_due_commission' ) );
45
+ }
46
+ }
47
+ }
48
+
49
+
50
+ /**
51
+ * Runs only on a manual order update by a human
52
+ */
53
+ public function check_order_complete()
54
+ {
55
+ foreach ( $this->completed_statuses as $completed ) {
56
+ add_action( 'woocommerce_order_status_' . $completed, array( 'WCV_Commission', 'log_commission_due' ) );
57
+ }
58
+ }
59
+
60
+
61
+ /**
62
+ * Reverse commission for an entire order
63
+ *
64
+ * Only runs if the order has been logged in pv_commission table
65
+ *
66
+ * @param int $order_id
67
+ *
68
+ * @return unknown
69
+ */
70
+ public function reverse_due_commission( $order_id )
71
+ {
72
+ global $wpdb;
73
+
74
+ // Check if this order exists
75
+ $count = WCV_Commission::count_commission_by_order( $order_id );
76
+ if ( !$count ) return false;
77
+
78
+ // Deduct this amount from the vendor's total due
79
+ $results = WCV_Commission::sum_total_due_for_order( $order_id );
80
+ $ids = implode( ',', $results[ 'ids' ] );
81
+ $table_name = $wpdb->prefix . "pv_commission";
82
+
83
+ $query = "UPDATE `{$table_name}` SET `status` = '%s' WHERE id IN ({$ids})";
84
+ $results = $wpdb->query( $wpdb->prepare( $query, 'reversed' ) );
85
+
86
+ return $results;
87
+ }
88
+
89
+
90
+ /**
91
+ * Store all commission due for an order
92
+ *
93
+ * @return bool
94
+ *
95
+ * @param int $order_id
96
+ */
97
+ public static function log_commission_due( $order_id )
98
+ {
99
+ global $woocommerce;
100
+
101
+ $order = new WC_Order( $order_id );
102
+ $dues = WCV_Vendors::get_vendor_dues_from_order( $order, false );
103
+
104
+ foreach ( $dues as $vendor_id => $details ) {
105
+
106
+ // Only process vendor commission
107
+ if ( !WCV_Vendors::is_vendor( $vendor_id ) ) continue;
108
+
109
+ // See if they currently have an amount due
110
+ $due = WCV_Vendors::count_due_by_vendor( $vendor_id, $order_id );
111
+ if ( $due > 0 ) continue;
112
+
113
+ // Get the dues in an easy format for inserting to our table
114
+ $insert_due = array();
115
+
116
+ foreach ( $details as $key => $detail ) {
117
+ $product_id = $detail['product_id'];
118
+
119
+ $insert_due[ $product_id ] = array(
120
+ 'order_id' => $order_id,
121
+ 'vendor_id' => $vendor_id,
122
+ 'product_id' => $product_id,
123
+ 'total_due' => !empty( $insert_due[ $product_id ][ 'total_due' ] ) ? ( $detail[ 'commission' ] + $insert_due[ $product_id ][ 'total_due' ] ) : $detail[ 'commission' ],
124
+ 'total_shipping' => !empty( $insert_due[ $product_id ][ 'total_shipping' ] ) ? ( $detail[ 'shipping' ] + $insert_due[ $product_id ][ 'total_shipping' ] ) : $detail[ 'shipping' ],
125
+ 'tax' => !empty( $insert_due[ $product_id ][ 'tax' ] ) ? ( $detail[ 'tax' ] + $insert_due[ $product_id ][ 'tax' ] ) : $detail[ 'tax' ],
126
+ 'qty' => !empty( $insert_due[ $product_id ][ 'qty' ] ) ? ( $detail[ 'qty' ] + $insert_due[ $product_id ][ 'qty' ] ) : $detail[ 'qty' ],
127
+ 'time' => $order->order_date,
128
+ );
129
+ }
130
+
131
+ if ( !empty( $insert_due ) ) {
132
+ WCV_Commission::insert_new_commission( array_values( $insert_due ) );
133
+ }
134
+ }
135
+
136
+ }
137
+
138
+
139
+ /**
140
+ * Add up the totals for an order for each vendor
141
+ *
142
+ * @param int $order_id
143
+ *
144
+ * @return array
145
+ */
146
+ public function sum_total_due_for_order( $order_id )
147
+ {
148
+ global $wpdb;
149
+
150
+ $table_name = $wpdb->prefix . "pv_commission";
151
+ $query = "SELECT `id`, `total_due`, `total_shipping`, `tax`, `vendor_id`
152
+ FROM `{$table_name}`
153
+ WHERE `order_id` = %d
154
+ AND `status` = %s";
155
+
156
+ $results = $wpdb->get_results( $wpdb->prepare( $query, $order_id, 'due' ) );
157
+
158
+ foreach ( $results as $commission ) {
159
+ $commission_ids[ ] = $commission->id;
160
+
161
+ $pay[ $commission->vendor_id ] = !empty( $pay[ $commission->vendor_id ] )
162
+ ? ( $pay[ $commission->vendor_id ] + ( $commission->total_due + $commission->total_shipping + $commission->tax ) )
163
+ : ( $commission->total_due + $commission->total_shipping + $commission->tax );
164
+ }
165
+
166
+ $return = array(
167
+ 'vendors' => $pay,
168
+ 'ids' => $commission_ids,
169
+ );
170
+
171
+ return $return;
172
+ }
173
+
174
+
175
+ /**
176
+ * Return all commission outstanding with a 'due' status
177
+ *
178
+ * @return object
179
+ */
180
+ public static function get_all_due()
181
+ {
182
+ global $wpdb;
183
+
184
+ $table_name = $wpdb->prefix . "pv_commission";
185
+ $query = "SELECT id, vendor_id, total_due
186
+ FROM `{$table_name}`
187
+ WHERE status = %s";
188
+ $results = $wpdb->get_results( $wpdb->prepare( $query, 'due' ) );
189
+
190
+ return $results;
191
+ }
192
+
193
+
194
+ /**
195
+ * Check if this order has commission logged already
196
+ *
197
+ * @param int $order_id
198
+ *
199
+ * @return int
200
+ */
201
+ public function count_commission_by_order( $order_id )
202
+ {
203
+ global $wpdb;
204
+ $table_name = $wpdb->prefix . "pv_commission";
205
+
206
+ if ( is_array( $order_id ) )
207
+ $order_id = implode( ',', $order_id );
208
+
209
+ $query = "SELECT COUNT(order_id) AS order_count
210
+ FROM {$table_name}
211
+ WHERE order_id IN ($order_id)
212
+ AND status <> %s";
213
+ $count = $wpdb->get_var( $wpdb->prepare( $query, 'reversed' ) );
214
+
215
+ return $count;
216
+ }
217
+
218
+
219
+ /**
220
+ * Product's commission rate in percentage form
221
+ *
222
+ * Eg: 50 for 50%
223
+ *
224
+ * @param int $product_id
225
+ *
226
+ * @return float
227
+ */
228
+ public static function get_commission_rate( $product_id )
229
+ {
230
+
231
+ $commission = 0;
232
+
233
+ $parent = get_post_ancestors( $product_id );
234
+ if ( $parent ) $product_id = $parent[ 0 ];
235
+
236
+ $vendor_id = WCV_Vendors::get_vendor_from_product( $product_id );
237
+
238
+ $product_commission = get_post_meta( $product_id, 'pv_commission_rate', true );
239
+ $vendor_commission = WCV_Vendors::get_default_commission( $vendor_id );
240
+ $default_commission = WC_Vendors::$pv_options->get_option( 'default_commission' );
241
+
242
+ if ( $product_commission != '' && $product_commission !== false ) {
243
+ $commission = $product_commission;
244
+ }
245
+
246
+ else if ( $vendor_commission != '' && $vendor_commission !== false ) {
247
+ $commission = $vendor_commission;
248
+ }
249
+
250
+ else if ( $default_commission != '' && $default_commission !== false ) {
251
+ $commission = $default_commission;
252
+ }
253
+
254
+ return apply_filters( 'wcv_commission_rate_percent', $commission, $product_id );
255
+ }
256
+
257
+
258
+ /**
259
+ * Commission due for a product based on a rate and price
260
+ *
261
+ * @param float $product_price
262
+ * @param unknown $product_id
263
+ *
264
+ * @return float
265
+ */
266
+ public static function calculate_commission( $product_price, $product_id, $order )
267
+ {
268
+ $commission_rate = WCV_Commission::get_commission_rate( $product_id );
269
+ $commission = $product_price * ( $commission_rate / 100 );
270
+ $commission = round( $commission, 2 );
271
+
272
+ return apply_filters( 'wcv_commission_rate', $commission, $product_id, $product_price, $order );
273
+ }
274
+
275
+
276
+ /**
277
+ * Log commission to the pv_commission table
278
+ *
279
+ * Will either update or insert to the database
280
+ *
281
+ * @param array $orders
282
+ *
283
+ * @return unknown
284
+ */
285
+ public static function insert_new_commission( $orders = array() )
286
+ {
287
+ global $wpdb;
288
+
289
+ if ( empty( $orders ) ) return false;
290
+
291
+ $table = $wpdb->prefix . "pv_commission";
292
+
293
+ // Insert the time and default status 'due'
294
+ foreach ( $orders as $key => $order ) {
295
+ $orders[ $key ][ 'time' ] = $order['time'];
296
+ $orders[ $key ][ 'status' ] = 'due';
297
+ }
298
+
299
+ foreach ( $orders as $key => $order ) {
300
+ $where = array(
301
+ 'order_id' => $order[ 'order_id' ],
302
+ 'product_id' => $order[ 'product_id' ],
303
+ 'vendor_id' => $order[ 'vendor_id' ],
304
+ 'qty' => $order[ 'qty' ],
305
+ );
306
+ $update = $wpdb->update( $table, $order, $where );
307
+ if ( !$update ) $insert = $wpdb->insert( $table, $order );
308
+ }
309
+
310
+ do_action( 'wcv_commissions_inserted', $orders );
311
+ }
312
+
313
+
314
+ /**
315
+ * Set commission to 'paid' for an entire order
316
+ *
317
+ *
318
+ * @access public
319
+ *
320
+ * @param mixed $order_id An array of Order IDs or an int.
321
+ * @param unknown $column_ids (optional)
322
+ *
323
+ * @return bool.
324
+ */
325
+ public function set_order_commission_paid( $order_id, $column_ids = false )
326
+ {
327
+ global $wpdb;
328
+
329
+ $table_name = $wpdb->prefix . "pv_commission";
330
+
331
+ if ( is_array( $order_id ) )
332
+ $order_id = implode( ',', $order_id );
333
+
334
+ $query = "UPDATE `{$table_name}` SET `status` = 'paid' WHERE order_id IN ($order_id)";
335
+ $result = $wpdb->query( $query );
336
+
337
+ return $result;
338
+ }
339
+
340
+
341
+ }
trunk/WCVendors/classes/class-cron.php ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Cron class
4
+ *
5
+ * @package ProductVendor
6
+ */
7
+
8
+
9
+ class WCV_Cron
10
+ {
11
+
12
+
13
+ /**
14
+ * Constructor
15
+ */
16
+ function __construct()
17
+ {
18
+ add_filter( 'cron_schedules', array( 'WCV_Cron', 'custom_cron_intervals' ) );
19
+ add_action( WC_Vendors::$id . '_options_updated', array( 'WCV_Cron', 'check_schedule' ) );
20
+ add_filter( WC_Vendors::$id . '_options_on_update', array( 'WCV_Cron', 'check_schedule_now' ) );
21
+ }
22
+
23
+
24
+ /**
25
+ * Re-add cron schedule when the settings have been updated
26
+ *
27
+ * @param array
28
+ * @param unknown $options
29
+ */
30
+ public static function check_schedule( $options )
31
+ {
32
+ $old_interval = wp_get_schedule( 'pv_schedule_mass_payments' );
33
+ $new_interval = $options[ 'schedule' ];
34
+ $instapay = $options[ 'instapay' ];
35
+
36
+ /**
37
+ * 1. The user actually changed the schedule
38
+ * 2. Instapay is turned off
39
+ * 3. Manual was not selected
40
+ */
41
+ if ( ( $old_interval != $new_interval ) && !$instapay && $new_interval != 'manual' ) {
42
+ WCV_Cron::remove_cron_schedule( $options );
43
+ WCV_Cron::schedule_cron( $new_interval );
44
+ }
45
+
46
+ if ( $new_interval == 'manual' || $instapay ) {
47
+ WCV_Cron::remove_cron_schedule( $options );
48
+ }
49
+
50
+ }
51
+
52
+
53
+ /**
54
+ * Check if the user chose "Now" on the Schedule settings
55
+ *
56
+ * @param array $options
57
+ *
58
+ * @return array
59
+ */
60
+ public static function check_schedule_now( $options )
61
+ {
62
+ $old_schedule = WC_Vendors::$pv_options->get_option( 'schedule' );
63
+ $new_schedule = $options[ 'schedule' ];
64
+
65
+ if ( $new_schedule == 'now' ) {
66
+ $return = WCV_Cron::pay_now();
67
+ $options[ 'schedule' ] = $old_schedule;
68
+ WCV_Cron::schedule_cron( $old_schedule );
69
+ add_settings_error( WC_Vendors::$pv_options->id, 'save_options', $return[ 'message' ], $return[ 'status' ] );
70
+ }
71
+
72
+ return $options;
73
+ }
74
+
75
+
76
+ /**
77
+ * Pay all outstanding commission using Paypal Mass Pay
78
+ *
79
+ * @return array
80
+ */
81
+ public static function pay_now()
82
+ {
83
+ $mass_pay = new WCV_Mass_Pay;
84
+ $mass_pay = $mass_pay->do_payments();
85
+
86
+ $message = !empty( $mass_pay[ 'total' ] )
87
+ ? $mass_pay[ 'msg' ] . '<br/>' . sprintf( __( 'Payment total: %s', 'wcvendors' ), woocommerce_price( $mass_pay[ 'total' ] ) )
88
+ : $mass_pay[ 'msg' ];
89
+
90
+ return array(
91
+ 'message' => $message,
92
+ 'status' => $mass_pay[ 'status' ]
93
+ );
94
+ }
95
+
96
+
97
+ /**
98
+ * Remove the mass payments schedule
99
+ *
100
+ * @return bool
101
+ */
102
+ private static function remove_cron_schedule()
103
+ {
104
+ $timestamp = wp_next_scheduled( 'pv_schedule_mass_payments' );
105
+
106
+ return wp_unschedule_event( $timestamp, 'pv_schedule_mass_payments' );
107
+ }
108
+
109
+
110
+ /**
111
+ * Schedule a cron event on a specified interval
112
+ *
113
+ * @param string $interval
114
+ *
115
+ * @return bool
116
+ */
117
+ public static function schedule_cron( $interval )
118
+ {
119
+ // Scheduled event
120
+ add_action( 'pv_schedule_mass_payments', array( 'WCV_Cron', 'pay_now' ) );
121
+
122
+ // Schedule the event
123
+ if ( !wp_next_scheduled( 'pv_schedule_mass_payments' ) ) {
124
+ wp_schedule_event( time(), $interval, 'pv_schedule_mass_payments' );
125
+
126
+ return true;
127
+ }
128
+
129
+ return false;
130
+ }
131
+
132
+
133
+ /**
134
+ * Add new schedule intervals to WP
135
+ *
136
+ * Weekly
137
+ * Biweekly
138
+ * Monthly
139
+ *
140
+ * @param array $schedules
141
+ *
142
+ * @return array
143
+ */
144
+ public static function custom_cron_intervals( $schedules )
145
+ {
146
+ $schedules[ 'weekly' ] = array(
147
+ 'interval' => 604800,
148
+ 'display' => __( 'Once Weekly' )
149
+ );
150
+
151
+ $schedules[ 'biweekly' ] = array(
152
+ 'interval' => 1209600,
153
+ 'display' => __( 'Once every two weeks' )
154
+ );
155
+
156
+ $schedules[ 'monthly' ] = array(
157
+ 'interval' => 2635200,
158
+ 'display' => __( 'Once a month' )
159
+ );
160
+
161
+ return $schedules;
162
+ }
163
+
164
+
165
+ }
trunk/WCVendors/classes/class-install.php ADDED
@@ -0,0 +1,285 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Install class on activation.
4
+ *
5
+ * @author Matt Gates <http://mgates.me>
6
+ * @package ProductVendor
7
+ */
8
+
9
+
10
+ class WCV_Install
11
+ {
12
+
13
+ /**
14
+ * Checks if install is requierd
15
+ *
16
+ * @return unknown
17
+ */
18
+ public function init()
19
+ {
20
+ $db_version = WC_Vendors::$pv_options->get_option( 'db_version' );
21
+
22
+ // 1.0 install
23
+ if ( version_compare( $db_version, '1.0', '<' ) ) {
24
+ $this->install_prdtvendor();
25
+ WC_Vendors::$pv_options->update_option( 'db_version', '1.4.2' );
26
+ }
27
+
28
+ // 1.0.1 allows vendors to upload roles
29
+ if ( version_compare( $db_version, '1.0.1', '<' ) ) {
30
+ $this->add_new_roles();
31
+ WC_Vendors::$pv_options->update_option( 'db_version', '1.0.1' );
32
+ }
33
+
34
+ // 1.3.0 add a 'vendor dashboard' page
35
+ if ( version_compare( $db_version, '1.3.0', '<' ) ) {
36
+ $this->create_new_pages();
37
+ WC_Vendors::$pv_options->update_option( 'db_version', '1.3.0' );
38
+ }
39
+
40
+ // 1.3.2 adds 'qty' to the pv_commission table
41
+ if ( version_compare( $db_version, '1.3.2', '<' ) ) {
42
+ $this->update_to( '1.3.2' );
43
+ WC_Vendors::$pv_options->update_option( 'db_version', '1.3.2' );
44
+ }
45
+
46
+ // 1.4.0 adds 'pending_vendor' role
47
+ if ( version_compare( $db_version, '1.4.0', '<' ) ) {
48
+ $this->update_to( '1.4.0' );
49
+ WC_Vendors::$pv_options->update_option( 'db_version', '1.4.0' );
50
+ flush_rewrite_rules();
51
+ }
52
+
53
+ if ( version_compare( $db_version, '1.4.2', '<' ) ) {
54
+ $this->update_to( '1.4.2' );
55
+ WC_Vendors::$pv_options->update_option( 'db_version', '1.4.2' );
56
+ }
57
+
58
+ if ( version_compare( $db_version, '1.4.3', '<' ) ) {
59
+ $this->update_to( '1.4.3' );
60
+ WC_Vendors::$pv_options->update_option( 'db_version', '1.4.3' );
61
+ }
62
+
63
+ if ( version_compare( $db_version, '1.4.5', '<' ) ) {
64
+ $this->update_to( '1.4.5' );
65
+ WC_Vendors::$pv_options->update_option( 'db_version', '1.4.5' );
66
+ }
67
+
68
+ }
69
+
70
+
71
+ /**
72
+ * Grouped functions for installing the Product Vendor plugin
73
+ */
74
+ private function install_prdtvendor()
75
+ {
76
+ // Clear the cron
77
+ wp_clear_scheduled_hook( 'pv_schedule_mass_payments' );
78
+
79
+ // Add the vendors role
80
+ $this->add_new_roles();
81
+
82
+ // Create tables
83
+ $this->create_new_tables();
84
+
85
+ // Create the Orders page if it doesn't exist
86
+ $orders_page = WC_Vendors::$pv_options->get_option( 'orders_page' );
87
+ if ( empty( $orders_page ) ) $this->create_new_pages();
88
+ }
89
+
90
+
91
+ /**
92
+ * Add the new Vendor role
93
+ *
94
+ * @return bool
95
+ */
96
+ private function add_new_roles()
97
+ {
98
+ remove_role( 'pending_vendor' );
99
+ add_role( 'pending_vendor', __( 'Pending Vendor', 'wcvendors' ), array(
100
+ 'read' => true,
101
+ 'edit_posts' => false,
102
+ 'delete_posts' => false
103
+ ) );
104
+
105
+ remove_role( 'vendor' );
106
+ add_role( 'vendor', 'Vendor', array(
107
+ 'assign_product_terms' => true,
108
+ 'edit_products' => true,
109
+ 'edit_published_products' => false,
110
+ 'manage_product' => true,
111
+ 'publish_products' => false,
112
+ 'read' => true,
113
+ 'upload_files' => true,
114
+ 'view_woocommerce_reports' => true,
115
+ ) );
116
+ }
117
+
118
+
119
+ /**
120
+ * Create the pv_commission table
121
+ */
122
+ private function create_new_tables()
123
+ {
124
+ global $wpdb;
125
+
126
+ $table_name = $wpdb->prefix . "pv_commission";
127
+ require_once ABSPATH . 'wp-admin/includes/upgrade.php';
128
+
129
+ $sql = "CREATE TABLE $table_name (
130
+ id bigint(20) NOT NULL AUTO_INCREMENT,
131
+ product_id bigint(20) NOT NULL,
132
+ order_id bigint(20) NOT NULL,
133
+ vendor_id bigint(20) NOT NULL,
134
+ total_due decimal(20,2) NOT NULL,
135
+ qty BIGINT( 20 ) NOT NULL,
136
+ total_shipping decimal(20,2) NOT NULL,
137
+ tax decimal(20,2) NOT NULL,
138
+ status varchar(20) NOT NULL DEFAULT 'due',
139
+ time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
140
+ UNIQUE KEY id (id)
141
+ );";
142
+ dbDelta( $sql );
143
+ }
144
+
145
+
146
+ /**
147
+ * Create a page
148
+ *
149
+ * @access public
150
+ * @return void
151
+ *
152
+ * @param mixed $slug Slug for the new page
153
+ * @param mixed $option Option name to store the page's ID
154
+ * @param string $page_title (optional) (default: '') Title for the new page
155
+ * @param string $page_content (optional) (default: '') Content for the new page
156
+ * @param int $post_parent (optional) (default: 0) Parent for the new page
157
+ */
158
+ function create_page( $slug, $page_title = '', $page_content = '', $post_parent = 0 )
159
+ {
160
+ global $wpdb;
161
+
162
+ $page_id = WC_Vendors::$pv_options->get_option( $slug . '_page' );
163
+
164
+ if ( $page_id > 0 && get_post( $page_id ) ) {
165
+ return $page_id;
166
+ }
167
+
168
+ $page_found = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM " . $wpdb->posts . " WHERE post_name = %s LIMIT 1;", $slug ) );
169
+ if ( $page_found ) {
170
+ if ( !$page_id ) {
171
+ WC_Vendors::$pv_options->update_option( $slug . '_page', $page_found );
172
+
173
+ return $page_found;
174
+ }
175
+
176
+ return $page_id;
177
+ }
178
+
179
+ $page_data = array(
180
+ 'post_status' => 'publish',
181
+ 'post_type' => 'page',
182
+ 'post_author' => 1,
183
+ 'post_name' => $slug,
184
+ 'post_title' => $page_title,
185
+ 'post_content' => $page_content,
186
+ 'post_parent' => $post_parent,
187
+ 'comment_status' => 'closed'
188
+ );
189
+
190
+ $page_id = wp_insert_post( $page_data );
191
+ WC_Vendors::$pv_options->update_option( $slug . '_page', $page_id );
192
+
193
+ return $page_id;
194
+ }
195
+
196
+
197
+ /**
198
+ * Create the Orders page for the frontend
199
+ */
200
+ private function create_new_pages()
201
+ {
202
+ global $wpdb;
203
+
204
+ $vendor_page_id = $this->create_page( 'vendor_dashboard', __( 'Vendor Dashboard', 'wcvendors' ), '[wcv_vendor_dashboard]' );
205
+ $this->create_page( 'orders', __( 'Orders', 'wcvendors' ), '[wcv_orders]', $vendor_page_id );
206
+ $this->create_page( 'shop_settings', __( 'Shop Settings', 'wcvendors' ), '[wcv_shop_settings]', $vendor_page_id );
207
+ }
208
+
209
+
210
+ /**
211
+ *
212
+ *
213
+ * @param unknown $version
214
+ */
215
+ public function update_to( $version )
216
+ {
217
+ global $wpdb;
218
+
219
+ $table_name = $wpdb->prefix . "pv_commission";
220
+
221
+ switch ( $version ) {
222
+
223
+ case '1.3.2':
224
+
225
+ $sql = "ALTER TABLE `{$table_name}` ADD `qty` BIGINT( 20 ) NOT NULL AFTER `total_due`";
226
+ $wpdb->query( $sql );
227
+
228
+ $sql = "SELECT * FROM `{$table_name}`";
229
+ $results = $wpdb->get_results( $sql );
230
+ foreach ( $results as $key => $value ) {
231
+
232
+ $order = new WC_Order( $value->order_id );
233
+
234
+ foreach ( $order->get_items() as $o_key => $o_value ) {
235
+
236
+ if ( $value->product_id == $o_value[ 'product_id' ] || ( !empty( $o_value[ 'variation_id' ] ) && $value->product_id == $o_value[ 'variation_id' ] ) ) {
237
+ $wpdb->update(
238
+ $table_name,
239
+ array( 'qty' => $o_value[ 'qty' ] ),
240
+ array( 'id' => $value->id ),
241
+ array( '%d' ),
242
+ array( '%d' )
243
+ );
244
+ }
245
+ }
246
+
247
+ }
248
+
249
+ break;
250
+
251
+ case '1.4.0':
252
+
253
+ add_role( 'pending_vendor', __( 'Pending Vendor', 'wcvendors' ), array(
254
+ 'read' => true,
255
+ 'edit_posts' => false,
256
+ 'delete_posts' => false
257
+ ) );
258
+
259
+ $this->create_new_pages();
260
+
261
+ break;
262
+
263
+ case '1.4.2':
264
+
265
+ $sql = "ALTER TABLE `{$table_name}` ADD `total_shipping` decimal(20,2) NOT NULL AFTER `total_due`";
266
+ $wpdb->query( $sql );
267
+
268
+ case '1.4.3':
269
+
270
+ $sql = "ALTER TABLE `{$table_name}` ADD `tax` decimal(20,2) NOT NULL AFTER `total_shipping`";
271
+ $wpdb->query( $sql );
272
+
273
+ case '1.4.5':
274
+
275
+ // Flush rules to fix the /page/2/ issue on vendor shop pages
276
+ update_option( WC_Vendors::$id . '_flush_rules', true );
277
+
278
+ default:
279
+ // code...
280
+ break;
281
+ }
282
+ }
283
+
284
+
285
+ }
trunk/WCVendors/classes/class-queries.php ADDED
@@ -0,0 +1,278 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCV_Queries
4
+ {
5
+
6
+ /**
7
+ *
8
+ *
9
+ * @param unknown $user_id
10
+ *
11
+ * @return unknown
12
+ */
13
+
14
+
15
+ public static function get_commission_products( $user_id )
16
+ {
17
+ global $wpdb;
18
+
19
+ $dates = WCV_Queries::orders_within_range();
20
+ $vendor_products = array();
21
+
22
+ $results = $wpdb->get_results( "
23
+ SELECT product_id
24
+ FROM {$wpdb->prefix}pv_commission
25
+ WHERE vendor_id = {$user_id}
26
+ AND time >= '" . $dates[ 'after' ] . "'
27
+ AND time <= '" . $dates[ 'before' ] . "'
28
+ AND status != 'reversed'
29
+ GROUP BY product_id" );
30
+
31
+ foreach ( $results as $value ) {
32
+ $ids[ ] = $value->product_id;
33
+ }
34
+
35
+ if ( !empty( $ids ) ) {
36
+ $vendor_products = get_posts( array(
37
+ 'numberposts' => -1,
38
+ 'orderby' => 'post_date',
39
+ 'post_type' => array( 'product', 'product_variation' ),
40
+ 'order' => 'DESC',
41
+ 'include' => $ids
42
+ )
43
+ );
44
+ }
45
+
46
+ return $vendor_products;
47
+ }
48
+
49
+ /**
50
+ *
51
+ *
52
+ * @param unknown $order_id
53
+ *
54
+ * @return unknown
55
+ */
56
+
57
+
58
+ public static function get_products_for_order( $order_id )
59
+ {
60
+ global $wpdb;
61
+
62
+ $vendor_products = array();
63
+
64
+ $results = $wpdb->get_results( "
65
+ SELECT product_id
66
+ FROM {$wpdb->prefix}pv_commission
67
+ WHERE order_id = {$order_id}
68
+ AND status != 'reversed'
69
+ AND vendor_id = " . get_current_user_id() . "
70
+ GROUP BY product_id" );
71
+
72
+ foreach ( $results as $value ) {
73
+ $ids[ ] = $value->product_id;
74
+ }
75
+
76
+ return $ids;
77
+ }
78
+
79
+
80
+ /**
81
+ * All orders for a specific product
82
+ *
83
+ * @param array $product_ids
84
+ * @param array $args (optional)
85
+ *
86
+ * @return object
87
+ */
88
+ public static function get_orders_for_products( array $product_ids, array $args = array() )
89
+ {
90
+ global $wpdb;
91
+
92
+ if ( empty( $product_ids ) ) return false;
93
+
94
+ $dates = WCV_Queries::orders_within_range();
95
+
96
+ $defaults = array(
97
+ 'status' => apply_filters( 'wcvendors_completed_statuses', array( 'completed', 'processing' ) ),
98
+ 'dates' => array( 'before' => $dates[ 'before' ], 'after' => $dates[ 'after' ] ),
99
+ );
100
+
101
+ $args = wp_parse_args( $args, $defaults );
102
+
103
+
104
+ $sql = "
105
+ SELECT order_id
106
+ FROM {$wpdb->prefix}pv_commission as order_items
107
+ WHERE product_id IN ('" . implode( "','", $product_ids ) . "')
108
+ AND time >= '" . $args[ 'dates' ][ 'after' ] . "'
109
+ AND time <= '" . $args[ 'dates' ][ 'before' ] . "'
110
+ AND status != 'reversed'
111
+ ";
112
+
113
+ if ( !empty( $args[ 'vendor_id' ] ) ) {
114
+ $sql .= "
115
+ AND vendor_id = {$args['vendor_id']}
116
+ ";
117
+ }
118
+
119
+ $sql .= "
120
+ GROUP BY order_id
121
+ ORDER BY time DESC
122
+ ";
123
+
124
+ $orders = $wpdb->get_results( $sql );
125
+
126
+ return $orders;
127
+ }
128
+
129
+
130
+ /**
131
+ * Sum of orders for a specific product
132
+ *
133
+ * @param array $product_ids
134
+ * @param array $args (optional)
135
+ *
136
+ * @return object
137
+ */
138
+ public static function sum_orders_for_products( array $product_ids, array $args = array() )
139
+ {
140
+ global $wpdb;
141
+
142
+ $dates = WCV_Queries::orders_within_range();
143
+
144
+ $defaults = array(
145
+ 'status' => apply_filters( 'wcvendors_completed_statuses', array( 'completed', 'processing' ) ),
146
+ 'dates' => array( 'before' => $dates[ 'before' ], 'after' => $dates[ 'after' ] ),
147
+ );
148
+
149
+ foreach ( $product_ids as $id ) {
150
+ $posts = get_posts( array(
151
+ 'numberposts' => -1,
152
+ 'post_type' => 'product_variation',
153
+ 'post_parent' => $id,
154
+ )
155
+ );
156
+
157
+ if ( !empty( $posts ) ) {
158
+ foreach ( $posts as $post ) {
159
+ $product_ids[ ] = $post->ID;
160
+ }
161
+ }
162
+ }
163
+
164
+ $args = wp_parse_args( $args, $defaults );
165
+
166
+ $sql = "
167
+ SELECT COUNT(order_id) as total_orders,
168
+ SUM(total_due + total_shipping + tax) as line_total,
169
+ SUM(qty) as qty,
170
+ product_id
171
+
172
+ FROM {$wpdb->prefix}pv_commission
173
+
174
+ WHERE product_id IN ('" . implode( "','", $product_ids ) . "')
175
+ AND time >= '" . $args[ 'dates' ][ 'after' ] . "'
176
+ AND time <= '" . $args[ 'dates' ][ 'before' ] . "'
177
+ AND status != 'reversed'
178
+ ";
179
+
180
+ if ( !empty( $args[ 'vendor_id' ] ) ) {
181
+ $sql .= "
182
+ AND vendor_id = {$args['vendor_id']}
183
+ ";
184
+ }
185
+
186
+ $sql .= "
187
+ GROUP BY product_id
188
+ ORDER BY time DESC;
189
+ ";
190
+
191
+ $orders = $wpdb->get_results( $sql );
192
+
193
+ return $orders;
194
+ }
195
+
196
+
197
+ /**
198
+ * Sum of orders for a specific order
199
+ *
200
+ * @param array $order_ids
201
+ * @param array $args (optional)
202
+ *
203
+ * @return object
204
+ */
205
+ public static function sum_for_orders( array $order_ids, array $args = array() )
206
+ {
207
+ global $wpdb;
208
+
209
+ $dates = WCV_Queries::orders_within_range();
210
+
211
+ $defaults = array(
212
+ 'status' => apply_filters( 'wcvendors_completed_statuses', array( 'completed', 'processing' ) ),
213
+ 'dates' => array( 'before' => $dates[ 'before' ], 'after' => $dates[ 'after' ] ),
214
+ );
215
+
216
+ $args = wp_parse_args( $args, $defaults );
217
+
218
+ $sql = "
219
+ SELECT COUNT(order_id) as total_orders,
220
+ SUM(total_due + total_shipping + tax) as line_total,
221
+ SUM(qty) as qty,
222
+ product_id
223
+
224
+ FROM {$wpdb->prefix}pv_commission
225
+
226
+ WHERE order_id IN ('" . implode( "','", $order_ids ) . "')
227
+ AND time >= '" . $args[ 'dates' ][ 'after' ] . "'
228
+ AND time <= '" . $args[ 'dates' ][ 'before' ] . "'
229
+ AND status != 'reversed'
230
+ ";
231
+
232
+ if ( !empty( $args[ 'vendor_id' ] ) ) {
233
+ $sql .= "
234
+ AND vendor_id = {$args['vendor_id']}
235
+ ";
236
+ }
237
+
238
+ $sql .= "
239
+ GROUP BY order_id
240
+ ORDER BY time DESC;
241
+ ";
242
+
243
+ $orders = $wpdb->get_results( $sql );
244
+
245
+ return $orders;
246
+ }
247
+
248
+
249
+ /**
250
+ * Orders for range filter function
251
+ *
252
+ * @return array
253
+ */
254
+ public static function orders_within_range()
255
+ {
256
+ global $start_date, $end_date;
257
+
258
+ $start_date = !empty( $_SESSION[ 'PV_Session' ][ 'start_date' ] ) ? $_SESSION[ 'PV_Session' ][ 'start_date' ] : strtotime( date( 'Ymd', strtotime( date( 'Ym', current_time( 'timestamp' ) ) . '01' ) ) );
259
+ $end_date = !empty( $_SESSION[ 'PV_Session' ][ 'end_date' ] ) ? $_SESSION[ 'PV_Session' ][ 'end_date' ] : strtotime( date( 'Ymd', current_time( 'timestamp' ) ) );
260
+
261
+ if ( !empty( $_POST[ 'start_date' ] ) ) {
262
+ $start_date = strtotime( $_POST[ 'start_date' ] );
263
+ $_SESSION[ 'PV_Session' ][ 'start_date' ] = $start_date;
264
+ }
265
+
266
+ if ( !empty( $_POST[ 'end_date' ] ) ) {
267
+ $end_date = strtotime( $_POST[ 'end_date' ] );
268
+ $_SESSION[ 'PV_Session' ][ 'end_date' ] = $end_date;
269
+ }
270
+
271
+ $after = date( 'Y-m-d', $start_date );
272
+ $before = date( 'Y-m-d', strtotime( '+1 day', $end_date ) );
273
+
274
+ return array( 'after' => $after, 'before' => $before );
275
+ }
276
+
277
+
278
+ }
trunk/WCVendors/classes/class-shipping.php ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shipping functions
5
+ *
6
+ * @author Matt Gates <http://mgates.me>, WC Vendors <http://wcvendors.com>
7
+ * @package ProductVendor
8
+ */
9
+
10
+
11
+ class WCV_Shipping
12
+ {
13
+ public static $trs2_shipping_rates;
14
+ public static $trs2_shipping_calc_type;
15
+ public static $pps_shipping_costs = array();
16
+
17
+
18
+ /**
19
+ * Constructor
20
+ */
21
+ function __construct()
22
+ {
23
+ // Table Rate Shipping 2 by WooThemes
24
+ if ( function_exists( 'woocommerce_get_shipping_method_table_rate' ) ) {
25
+ add_action( 'wp', array( $this, 'trs2_clear_transients' ) );
26
+ add_action( 'woocommerce_checkout_update_order_meta', array( 'WCV_Shipping', 'trs2_add_shipping_data' ), 1, 2 );
27
+ add_action( 'wc_trs2_matched_rates', array( 'WCV_Shipping', 'trs2_store_shipping_data' ), 10, 3 );
28
+ }
29
+ }
30
+
31
+
32
+ /**
33
+ *
34
+ *
35
+ * @param unknown $order_id
36
+ * @param unknown $product
37
+ * @param unknown $author
38
+ *
39
+ * @return unknown
40
+ */
41
+ public static function get_shipping_due( $order_id, $product, $author )
42
+ {
43
+ global $woocommerce;
44
+
45
+ $shipping_due = 0;
46
+ $method = '';
47
+ $_product = get_product( $product[ 'product_id' ] );
48
+ $order = wc_get_order( $order_id );
49
+
50
+ if ( $_product && $_product->needs_shipping() && !$_product->is_downloadable() ) {
51
+
52
+ // Get Shipping methods.
53
+ $shipping_methods = $order->get_shipping_methods();
54
+
55
+ // TODO: Currently this only allows one shipping method per order, this definitely needs changing
56
+ foreach ($shipping_methods as $shipping_method) {
57
+ $method = $shipping_method['method_id'];
58
+ break;
59
+ }
60
+
61
+ // Table Rate Shipping 2
62
+ if ( strstr( $method, 'table_rate' ) !== false ) {
63
+ // $shipping_due = WCV_Shipping::trs2_get_due( $order_id, $product[ 'product_id' ] );
64
+
65
+ // Per Product Shipping 2
66
+ } else if ( function_exists( 'woocommerce_per_product_shipping' ) && $method == 'per_product' ) {
67
+ $shipping_due = WCV_Shipping::pps_get_due( $order_id, $product );
68
+
69
+ // Local Delivery
70
+ } else if ( $method == 'local_delivery' ) {
71
+ $local_delivery = get_option( 'woocommerce_local_delivery_settings' );
72
+
73
+ if ( $local_delivery[ 'type' ] == 'product' ) {
74
+ $shipping_due = $product[ 'qty' ] * $local_delivery[ 'fee' ];
75
+ }
76
+
77
+ // International Delivery
78
+ } else if ( $method == 'international_delivery' ) {
79
+ $int_delivery = get_option( 'woocommerce_international_delivery_settings' );
80
+
81
+ if ( $int_delivery[ 'type' ] == 'item' ) {
82
+ $WC_Shipping_International_Delivery = new WC_Shipping_International_Delivery();
83
+ $fee = $WC_Shipping_International_Delivery->get_fee( $int_delivery[ 'fee' ], $_product->get_price() );
84
+ $shipping_due = ( $int_delivery[ 'cost' ] + $fee ) * $product[ 'qty' ];
85
+ }
86
+
87
+ }
88
+ }
89
+
90
+ $shipping_due = apply_filters( 'wcvendors_shipping_due', $shipping_due, $order_id, $product );
91
+
92
+ return $shipping_due;
93
+ }
94
+
95
+
96
+ /**
97
+ *
98
+ *
99
+ * @param unknown $order_id
100
+ * @param unknown $product
101
+ *
102
+ * @return unknown
103
+ */
104
+ public function pps_get_due( $order_id, $product )
105
+ {
106
+ global $woocommerce;
107
+
108
+ $item_shipping_cost = 0;
109
+
110
+ $order = new WC_Order( $order_id );
111
+ $package[ 'destination' ][ 'country' ] = $order->shipping_country;
112
+ $package[ 'destination' ][ 'state' ] = $order->shipping_state;
113
+ $package[ 'destination' ][ 'postcode' ] = $order->shipping_postcode;
114
+ $product_id = !empty( $product['variation_id'] ) ? $product['variation_id'] : $product['product_id'];
115
+
116
+ if ( !empty( $product['variation_id'] ) ) {
117
+ $rule = woocommerce_per_product_shipping_get_matching_rule( $product['variation_id'], $package );
118
+ }
119
+
120
+ if ( empty( $rule ) ) {
121
+ $rule = woocommerce_per_product_shipping_get_matching_rule( $product['product_id'], $package );
122
+ }
123
+
124
+ if ( !empty( $rule ) ) {
125
+ $item_shipping_cost += $rule->rule_item_cost * $product[ 'qty' ];
126
+
127
+ if ( !empty(self::$pps_shipping_costs[$order_id]) && ! in_array( $rule->rule_id, self::$pps_shipping_costs[$order_id] ) ) {
128
+ $item_shipping_cost += $rule->rule_cost;
129
+ } else if ( empty( self::$pps_shipping_costs[$order_id] ) ) {
130
+ $item_shipping_cost += $rule->rule_cost;
131
+ }
132
+
133
+ self::$pps_shipping_costs[$order_id][] = $rule->rule_id;
134
+ }
135
+
136
+ return $item_shipping_cost;
137
+ }
138
+
139
+
140
+ /**
141
+ *
142
+ */
143
+ public function trs2_clear_transients()
144
+ {
145
+ global $woocommerce;
146
+
147
+ if ( is_checkout() ) {
148
+ $woocommerce->clear_product_transients();
149
+ }
150
+ }
151
+
152
+
153
+ /**
154
+ *
155
+ *
156
+ * @param unknown $order_id
157
+ * @param unknown $product_id
158
+ *
159
+ * @return unknown
160
+ */
161
+ public function trs2_get_due( $order_id, $product_id )
162
+ {
163
+ if ( !function_exists( 'woocommerce_get_shipping_method_table_rate' ) ) return;
164
+
165
+ $shipping_due = 0;
166
+
167
+ WCV_Shipping::trs2_retrieve_shipping_data( $order_id );
168
+ if ( !empty( WCV_Shipping::$trs2_shipping_calc_type ) ) {
169
+
170
+ $ship_id = ( WCV_Shipping::$trs2_shipping_calc_type == 'class' ) ? get_product( $product_id )->get_shipping_class_id() : $product_id;
171
+
172
+ if ( !empty( WCV_Shipping::$trs2_shipping_rates[ $ship_id ] ) ) {
173
+ $shipping_due = WCV_Shipping::$trs2_shipping_rates[ $ship_id ];
174
+ unset( WCV_Shipping::$trs2_shipping_rates[ $ship_id ] );
175
+ }
176
+ }
177
+
178
+ return $shipping_due;
179
+ }
180
+
181
+
182
+ /**
183
+ *
184
+ *
185
+ * @param unknown $order_id
186
+ */
187
+ public function trs2_retrieve_shipping_data( $order_id )
188
+ {
189
+ global $woocommerce;
190
+
191
+ if ( !empty( WCV_Shipping::$trs2_shipping_rates ) ) return;
192
+
193
+ WCV_Shipping::$trs2_shipping_rates = array_filter( (array) get_post_meta( $order_id, '_wcvendors_trs2_shipping_rates', true ) );
194
+ WCV_Shipping::$trs2_shipping_calc_type = get_post_meta( $order_id, '_wcvendors_trs2_shipping_calc_type', true );
195
+ }
196
+
197
+
198
+ /**
199
+ *
200
+ *
201
+ * @param unknown $type
202
+ * @param unknown $rates
203
+ * @param unknown $per_item
204
+ */
205
+ public function trs2_store_shipping_data( $type, $rates, $per_item )
206
+ {
207
+ global $woocommerce;
208
+
209
+ $types = (array) $woocommerce->session->trs2_shipping_class_type;
210
+ $types[ ] = $type;
211
+ $woocommerce->session->trs2_shipping_class_type = $types;
212
+
213
+ $items = (array) $woocommerce->session->trs2_shipping_rates;
214
+ $items[ ] = $per_item;
215
+ $woocommerce->session->trs2_shipping_rates = $items;
216
+ }
217
+
218
+
219
+ /**
220
+ *
221
+ *
222
+ * @param unknown $order_id
223
+ * @param unknown $post
224
+ *
225
+ * @return unknown
226
+ */
227
+ public function trs2_add_shipping_data( $order_id, $post )
228
+ {
229
+ global $woocommerce;
230
+
231
+ if ( empty( $woocommerce->session->trs2_shipping_rates ) ) {
232
+ return false;
233
+ }
234
+
235
+ $order = new WC_Order( $order_id );
236
+
237
+ foreach ( $woocommerce->session->trs2_shipping_rates as $key => $shipping_rates ) {
238
+
239
+ if ( is_array( $shipping_rates ) && array_sum( $shipping_rates ) == $order->order_shipping ) {
240
+ $shipping_calc_type = $woocommerce->session->trs2_shipping_class_type[ $key ];
241
+ update_post_meta( $order_id, '_wcvendors_trs2_shipping_rates', $shipping_rates );
242
+ update_post_meta( $order_id, '_wcvendors_trs2_shipping_calc_type', $shipping_calc_type );
243
+
244
+ break;
245
+ }
246
+ }
247
+
248
+ unset( $woocommerce->session->trs2_shipping_rates, $woocommerce->session->trs2_shipping_class_type );
249
+ }
250
+ }
trunk/WCVendors/classes/class-vendors.php ADDED
@@ -0,0 +1,413 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Vendor functions
5
+ *
6
+ * @author Matt Gates <http://mgates.me>, WC Vendors <http://wcvendors.com>
7
+ * @package WCVendors
8
+ */
9
+
10
+
11
+ class WCV_Vendors
12
+ {
13
+
14
+ /**
15
+ * Retrieve all products for a vendor
16
+ *
17
+ * @param int $vendor_id
18
+ *
19
+ * @return object
20
+ */
21
+ public static function get_vendor_products( $vendor_id )
22
+ {
23
+ $args = array(
24
+ 'numberposts' => -1,
25
+ 'post_type' => 'product',
26
+ 'author' => $vendor_id,
27
+ 'post_status' => 'publish',
28
+ );
29
+
30
+ $args = apply_filters( 'pv_get_vendor_products_args', $args );
31
+
32
+ return get_posts( $args );
33
+ }
34
+
35
+ public static function get_default_commission( $vendor_id )
36
+ {
37
+ return get_user_meta( $vendor_id, 'pv_custom_commission_rate', true );
38
+ }
39
+
40
+
41
+ /**
42
+ * Vendor IDs and PayPal addresses from an order
43
+ *
44
+ * @param object $order
45
+ * @param unknown $items (optional)
46
+ *
47
+ * @return array
48
+ */
49
+ public static function get_vendors_from_order( $order, $items = false )
50
+ {
51
+ if ( !$order ) return;
52
+ if ( !$items ) $items = $order->get_items();
53
+
54
+ $vendors = array();
55
+ foreach ( $items as $key => $product ) {
56
+
57
+ $author = WCV_Vendors::get_vendor_from_product( $product[ 'product_id' ] );
58
+
59
+ // Only store the vendor authors
60
+ if ( !WCV_Vendors::is_vendor( $author ) ) continue;
61
+
62
+ $vendors[ $author ] = the_author_meta( 'author_paypal', $author );
63
+ }
64
+
65
+ return apply_filters( 'pv_vendors_from_order', $vendors, $order );
66
+ }
67
+
68
+
69
+ /**
70
+ *
71
+ *
72
+ * @param unknown $order
73
+ * @param unknown $group (optional)
74
+ *
75
+ * @return unknown
76
+ */
77
+ public static function get_vendor_dues_from_order( $order, $group = true )
78
+ {
79
+ global $woocommerce;
80
+
81
+ $give_tax = WC_Vendors::$pv_options->get_option( 'give_tax' );
82
+ $receiver = array();
83
+ $shipping_given = 0;
84
+ $tax_given = 0;
85
+
86
+ WCV_Shipping::$pps_shipping_costs = array();
87
+
88
+ foreach ( $order->get_items() as $key => $product ) {
89
+
90
+ $product_id = !empty( $product[ 'variation_id' ] ) ? $product[ 'variation_id' ] : $product[ 'product_id' ];
91
+ $author = WCV_Vendors::get_vendor_from_product( $product_id );
92
+ $is_vendor = WCV_Vendors::is_vendor( $author );
93
+ $commission = $is_vendor ? WCV_Commission::calculate_commission( $product[ 'line_subtotal' ], $product_id, $order ) : 0;
94
+ $tax = !empty( $product[ 'line_tax' ] ) ? (float) $product[ 'line_tax' ] : 0;
95
+ // Check if shipping is enabled
96
+ if ( get_option('woocommerce_calc_shipping') === 'no' ) { $shipping = 0; } else {
97
+ $shipping = WCV_Shipping::get_shipping_due( $order->id, $product, $author );
98
+ }
99
+
100
+ if ( $is_vendor ) {
101
+
102
+ $shipping_given += $shipping;
103
+ $tax_given += $give_tax ? $tax : 0;
104
+
105
+ $give = 0;
106
+ $give += !empty( $receiver[ $author ][ 'total' ] ) ? $receiver[ $author ][ 'total' ] : 0;
107
+ $give += $shipping;
108
+ $give += $commission;
109
+ $give += $give_tax ? $tax : 0;
110
+
111
+ if ( $group ) {
112
+
113
+ $receiver[ $author ] = array(
114
+ 'vendor_id' => (int) $author,
115
+ 'commission' => !empty( $receiver[ $author ][ 'commission' ] ) ? $receiver[ $author ][ 'commission' ] + $commission : $commission,
116
+ 'shipping' => !empty( $receiver[ $author ][ 'shipping' ] ) ? $receiver[ $author ][ 'shipping' ] + $shipping : $shipping,
117
+ 'tax' => $give_tax ? ( !empty( $receiver[ $author ][ 'tax' ] ) ? $receiver[ $author ][ 'tax' ] + $tax : $tax ) : 0,
118
+ 'qty' => !empty( $receiver[ $author ][ 'qty' ] ) ? $receiver[ $author ][ 'qty' ] + $product[ 'qty' ] : $product[ 'qty' ],
119
+ 'total' => $give,
120
+ );
121
+
122
+ } else {
123
+
124
+ $receiver[ $author ][ $key ] = array(
125
+ 'vendor_id' => (int) $author,
126
+ 'product_id' => $product_id,
127
+ 'commission' => $commission,
128
+ 'shipping' => $shipping,
129
+ 'tax' => $give_tax ? $tax : 0,
130
+ 'qty' => $product[ 'qty' ],
131
+ 'total' => $shipping + $commission + ( $give_tax ? $tax : 0 ),
132
+ );
133
+
134
+ }
135
+
136
+ }
137
+
138
+ $admin_comm = $product[ 'line_subtotal' ] - $commission;
139
+
140
+ if ( $group ) {
141
+ $receiver[ 1 ] = array(
142
+ 'vendor_id' => 1,
143
+ 'qty' => !empty( $receiver[ 1 ][ 'qty' ] ) ? $receiver[ 1 ][ 'qty' ] + $product[ 'qty' ] : $product[ 'qty' ],
144
+ 'commission' => !empty( $receiver[ 1 ][ 'commission' ] ) ? $receiver[ 1 ][ 'commission' ] + $admin_comm : $admin_comm,
145
+ 'total' => !empty( $receiver[ 1 ] ) ? $receiver[ 1 ][ 'total' ] + $admin_comm : $admin_comm,
146
+ );
147
+ } else {
148
+ $receiver[ 1 ][ $key ] = array(
149
+ 'vendor_id' => 1,
150
+ 'product_id' => $product_id,
151
+ 'commission' => $admin_comm,
152
+ 'shipping' => 0,
153
+ 'tax' => 0,
154
+ 'qty' => $product[ 'qty' ],
155
+ 'total' => $admin_comm,
156
+ );
157
+ }
158
+
159
+ }
160
+
161
+ // Add remainders on end to admin
162
+ $discount = $order->get_total_discount();
163
+ $shipping = ( $order->order_shipping - $shipping_given );
164
+ $tax = round(( $order->order_tax + $order->order_shipping_tax ) - $tax_given, 2);
165
+ $total = ( $tax + $shipping ) - $discount;
166
+
167
+ if ( $group ) {
168
+ $receiver[ 1 ][ 'commission' ] = $receiver[ 1 ][ 'commission' ] - $discount;
169
+ $receiver[ 1 ][ 'shipping' ] = $shipping;
170
+ $receiver[ 1 ][ 'tax' ] = $tax;
171
+ $receiver[ 1 ][ 'total' ] += $total;
172
+ } else {
173
+ $receiver[ 1 ][ $key ][ 'commission' ] = $receiver[ 1 ][ $key ][ 'commission' ] - $discount;
174
+ $receiver[ 1 ][ $key ][ 'shipping' ] = ( $order->order_shipping - $shipping_given );
175
+ $receiver[ 1 ][ $key ][ 'tax' ] = $tax;
176
+ $receiver[ 1 ][ $key ][ 'total' ] += $total;
177
+ }
178
+
179
+ // Reset the array keys
180
+ // $receivers = array_values( $receiver );
181
+
182
+ return $receiver;
183
+ }
184
+
185
+
186
+ /**
187
+ * Return the PayPal address for a vendor
188
+ *
189
+ * If no PayPal is set, it returns the vendor's email
190
+ *
191
+ * @param int $vendor_id
192
+ *
193
+ * @return string
194
+ */
195
+ public static function get_vendor_paypal( $vendor_id )
196
+ {
197
+ $paypal = get_user_meta( $vendor_id, $meta_key = 'pv_paypal', true );
198
+ $paypal = !empty( $paypal ) ? $paypal : get_the_author_meta( 'user_email', $vendor_id, false );
199
+
200
+ return $paypal;
201
+ }
202
+
203
+
204
+ /**
205
+ * Check if a vendor has an amount due for an order already
206
+ *
207
+ * @param int $vendor_id
208
+ * @param int $order_id
209
+ *
210
+ * @return int
211
+ */
212
+ public static function count_due_by_vendor( $vendor_id, $order_id )
213
+ {
214
+ global $wpdb;
215
+
216
+ $table_name = $wpdb->prefix . "pv_commission";
217
+
218
+ $query = "SELECT COUNT(*)
219
+ FROM {$table_name}
220
+ WHERE vendor_id = %s
221
+ AND order_id = %s
222
+ AND status = %s";
223
+ $count = $wpdb->get_var( $wpdb->prepare( $query, $vendor_id, $order_id, 'due' ) );
224
+
225
+ return $count;
226
+ }
227
+
228
+
229
+ /**
230
+ * All commission due for a specific vendor
231
+ *
232
+ * @param int $vendor_id
233
+ *
234
+ * @return int
235
+ */
236
+ public static function get_due_orders_by_vendor( $vendor_id )
237
+ {
238
+ global $wpdb;
239
+
240
+ $table_name = $wpdb->prefix . "pv_commission";
241
+
242
+ $query = "SELECT *
243
+ FROM {$table_name}
244
+ WHERE vendor_id = %s
245
+ AND status = %s";
246
+ $results = $wpdb->get_results( $wpdb->prepare( $query, $vendor_id, 'due' ) );
247
+
248
+ return $results;
249
+ }
250
+
251
+
252
+ /**
253
+ *
254
+ *
255
+ * @param unknown $product_id
256
+ *
257
+ * @return unknown
258
+ */
259
+ public static function get_vendor_from_product( $product_id )
260
+ {
261
+ $parent = get_post_ancestors( $product_id );
262
+ if ( $parent ) $product_id = $parent[ 0 ];
263
+
264
+ $post = get_post( $product_id );
265
+ $author = $post ? $post->post_author : 1;
266
+ $author = apply_filters( 'pv_product_author', $author, $product_id );
267
+
268
+ return $author;
269
+ }
270
+
271
+
272
+ /**
273
+ * Checks whether the ID provided is vendor capable or not
274
+ *
275
+ * @param int $user_id
276
+ *
277
+ * @return bool
278
+ */
279
+ public static function is_vendor( $user_id )
280
+ {
281
+ $user = get_userdata( $user_id );
282
+
283
+ $role = !empty( $user->roles ) ? array_shift( $user->roles ) : false;
284
+ $is_vendor = $role == 'vendor';
285
+
286
+ return apply_filters( 'pv_is_vendor', $is_vendor, $user_id );
287
+ }
288
+
289
+
290
+ /**
291
+ * Grabs the vendor ID whether a username or an int is provided
292
+ * and returns the vendor_id if it's actually a vendor
293
+ *
294
+ * @param unknown $input
295
+ *
296
+ * @return unknown
297
+ */
298
+ public static function get_vendor_id( $input )
299
+ {
300
+ if ( empty( $input ) ) {
301
+ return false;
302
+ }
303
+
304
+ $users = get_users( array( 'meta_key' => 'pv_shop_slug', 'meta_value' => sanitize_title( $input ) ) );
305
+
306
+ if ( !empty( $users ) && count( $users ) == 1 ) {
307
+ $vendor = $users[ 0 ];
308
+ } else {
309
+ $int_vendor = is_numeric( $input );
310
+ $vendor = !empty( $int_vendor ) ? get_userdata( $input ) : get_user_by( 'login', $input );
311
+ }
312
+
313
+ if ( $vendor ) {
314
+ $vendor_id = $vendor->ID;
315
+ if ( self::is_vendor( $vendor_id ) ) {
316
+ return $vendor_id;
317
+ }
318
+ }
319
+
320
+ return false;
321
+ }
322
+
323
+
324
+ /**
325
+ * Retrieve the shop page for a specific vendor
326
+ *
327
+ * @param unknown $vendor_id
328
+ *
329
+ * @return string
330
+ */
331
+ public static function get_vendor_shop_page( $vendor_id )
332
+ {
333
+ $vendor_id = self::get_vendor_id( $vendor_id );
334
+ if ( !$vendor_id ) return;
335
+
336
+ $slug = get_user_meta( $vendor_id, 'pv_shop_slug', true );
337
+ $vendor = !$slug ? get_userdata( $vendor_id )->user_login : $slug;
338
+
339
+ if ( get_option( 'permalink_structure' ) ) {
340
+ $permalink = trailingslashit( WC_Vendors::$pv_options->get_option( 'vendor_shop_permalink' ) );
341
+
342
+ return trailingslashit( home_url( sprintf( '/%s%s', $permalink, $vendor ) ) );
343
+ } else {
344
+ return add_query_arg( array( 'vendor_shop' => $vendor ), get_post_type_archive_link( 'product' ) );
345
+ }
346
+ }
347
+
348
+
349
+ /**
350
+ * Retrieve the shop name for a specific vendor
351
+ *
352
+ * @param unknown $vendor_id
353
+ *
354
+ * @return string
355
+ */
356
+ public static function get_vendor_shop_name( $vendor_id )
357
+ {
358
+ $vendor_id = self::get_vendor_id( $vendor_id );
359
+ $name = $vendor_id ? get_user_meta( $vendor_id, 'pv_shop_name', true ) : false;
360
+ $shop_name = !$name ? get_userdata( $vendor_id )->user_login : $name;
361
+
362
+ return $shop_name;
363
+ }
364
+
365
+
366
+ /**
367
+ *
368
+ *
369
+ * @param unknown $user_id
370
+ *
371
+ * @return unknown
372
+ */
373
+ public static function is_pending( $user_id )
374
+ {
375
+ $user = get_userdata( $user_id );
376
+
377
+ $role = !empty( $user->roles ) ? array_shift( $user->roles ) : false;
378
+ $is_pending = ( $role == 'pending_vendor' );
379
+
380
+ return $is_pending;
381
+ }
382
+
383
+ /*
384
+ * Is this a vendor product ?
385
+ * @param uknown $role
386
+ */
387
+ public static function is_vendor_product($role) {
388
+ return ($role === 'Vendor') ? true : false;
389
+ }
390
+
391
+ /*
392
+ * Is this the vendors shop archive page ?
393
+ */
394
+ public static function is_vendor_page() {
395
+
396
+ $vendor_shop = urldecode( get_query_var( 'vendor_shop' ) );
397
+ $vendor_id = WCV_Vendors::get_vendor_id( $vendor_shop );
398
+
399
+ return $vendor_id ? true : false;
400
+
401
+ }
402
+
403
+ /*
404
+ * Is this a vendor single product page ?
405
+ */
406
+ public static function is_vendor_product_page($vendor_id) {
407
+
408
+ $vendor_product = WCV_Vendors::is_vendor_product( wcv_get_user_role($vendor_id) );
409
+ return $vendor_product ? true : false;
410
+
411
+ }
412
+
413
+ }
trunk/WCVendors/classes/front/class-vendor-cart.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ *
5
+ *
6
+ * @author Matt Gates <http://mgates.me>
7
+ * @package
8
+ */
9
+
10
+
11
+ class WCV_Vendor_Cart
12
+ {
13
+
14
+
15
+ /**
16
+ *
17
+ */
18
+ function __construct()
19
+ {
20
+ add_filter( 'woocommerce_get_item_data', array( 'WCV_Vendor_Cart', 'sold_by' ), 10, 2 );
21
+ add_action( 'woocommerce_product_meta_start', array( 'WCV_Vendor_Cart', 'sold_by_meta' ), 10, 2 );
22
+ }
23
+
24
+
25
+ /**
26
+ *
27
+ *
28
+ * @param unknown $values
29
+ * @param unknown $cart_item
30
+ *
31
+ * @return unknown
32
+ */
33
+ public static function sold_by( $values, $cart_item )
34
+ {
35
+ $author_id = $cart_item[ 'data' ]->post->post_author;
36
+ $sold_by = WCV_Vendors::is_vendor( $author_id )
37
+ ? sprintf( '<a href="%s" target="_TOP">%s</a>', WCV_Vendors::get_vendor_shop_page( $author_id ), WCV_Vendors::get_vendor_shop_name( $author_id ) )
38
+ : get_bloginfo( 'name' );
39
+
40
+ $values[ ] = array(
41
+ 'name' => apply_filters('wcvendors_cart_sold_by', __( 'Sold by', 'wcvendors' )),
42
+ 'display' => $sold_by,
43
+ );
44
+
45
+ return $values;
46
+ }
47
+
48
+
49
+ /**
50
+ *
51
+ */
52
+ public static function sold_by_meta()
53
+ {
54
+ $author_id = get_the_author_meta( 'ID' );
55
+
56
+ $sold_by = WCV_Vendors::is_vendor( $author_id )
57
+ ? sprintf( '<a href="%s">%s</a>', WCV_Vendors::get_vendor_shop_page( $author_id ), WCV_Vendors::get_vendor_shop_name( $author_id ) )
58
+ : get_bloginfo( 'name' );
59
+
60
+ echo apply_filters('wcvendors_cart_sold_by_meta', __( 'Sold by: ', 'wcvendors' )) . $sold_by . '<br/>';
61
+ }
62
+
63
+ }
trunk/WCVendors/classes/front/class-vendor-shop.php ADDED
@@ -0,0 +1,266 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shop functions for each vendor.
5
+ *
6
+ * @author Matt Gates <http://mgates.me>
7
+ * @package ProductVendor
8
+ */
9
+
10
+
11
+ class WCV_Vendor_Shop
12
+ {
13
+
14
+ public static $seller_info;
15
+
16
+ /**
17
+ * init
18
+ */
19
+ function __construct()
20
+ {
21
+
22
+ add_filter( 'product_enquiry_send_to', array( 'WCV_Vendor_Shop', 'product_enquiry_compatibility' ), 10, 2 );
23
+
24
+ add_action( 'woocommerce_product_query', array( $this, 'vendor_shop_query' ), 10, 2 );
25
+ add_filter( 'init', array( $this, 'add_rewrite_rules' ), 0 );
26
+
27
+ add_action( 'woocommerce_before_main_content', array( 'WCV_Vendor_Shop', 'shop_description' ), 30 );
28
+ add_filter( 'woocommerce_product_tabs', array( 'WCV_Vendor_Shop', 'seller_info_tab' ) );
29
+ add_filter( 'post_type_archive_link', array( 'WCV_Vendor_Shop', 'change_archive_link' ) );
30
+
31
+ // Add sold by to product loop before add to cart
32
+ add_action( 'woocommerce_after_shop_loop_item', array('WCV_Vendor_Shop', 'template_loop_sold_by'), 9 );
33
+
34
+ // Remove Page Title if on Vendor Shop
35
+ add_filter ( 'woocommerce_show_page_title', array('WCV_Vendor_Shop', 'remove_vendor_title') );
36
+
37
+ // Show vendor on all sales related invoices
38
+ add_action( 'woocommerce_add_order_item_meta', array('WCV_Vendor_Shop', 'add_vendor_to_order_item_meta'), 10, 2 );
39
+
40
+ // Add a vendor header
41
+ if (WC_Vendors::$pv_options->get_option( 'shop_headers_enabled' ) ) {
42
+ add_action( 'woocommerce_before_main_content', array('WCV_Vendor_Shop', 'vendor_main_header'), 20 );
43
+ add_action( 'woocommerce_before_single_product', array('WCV_Vendor_Shop', 'vendor_mini_header'));
44
+ }
45
+
46
+ }
47
+
48
+ public static function change_archive_link( $link )
49
+ {
50
+ $vendor_shop = urldecode( get_query_var( 'vendor_shop' ) );
51
+ $vendor_id = WCV_Vendors::get_vendor_id( $vendor_shop );
52
+
53
+ return !$vendor_id ? $link : WCV_Vendors::get_vendor_shop_page( $vendor_id );
54
+ }
55
+
56
+ public static function vendor_shop_query( $q, $that )
57
+ {
58
+ $vendor_shop = urldecode( get_query_var( 'vendor_shop' ) );
59
+ $vendor_id = WCV_Vendors::get_vendor_id( $vendor_shop );
60
+
61
+ if ( !$vendor_id ) return;
62
+ add_filter( 'woocommerce_page_title', array( 'WCV_Vendor_Shop', 'page_title' ) );
63
+
64
+ $q->set( 'author', $vendor_id );
65
+ }
66
+
67
+ public static function product_enquiry_compatibility( $send_to, $product_id )
68
+ {
69
+ $author_id = get_post( $product_id )->post_author;
70
+ if ( WCV_Vendors::is_vendor( $author_id ) ) {
71
+ $send_to = get_userdata( $author_id )->user_email;
72
+ }
73
+
74
+ return $send_to;
75
+ }
76
+
77
+
78
+ /**
79
+ *
80
+ *
81
+ * @param unknown $tabs
82
+ *
83
+ * @return unknown
84
+ */
85
+ public static function seller_info_tab( $tabs )
86
+ {
87
+ global $post;
88
+
89
+ if ( WCV_Vendors::is_vendor( $post->post_author ) ) {
90
+
91
+ $seller_info = get_user_meta( $post->post_author, 'pv_seller_info', true );
92
+ $has_html = get_user_meta( $post->post_author, 'pv_shop_html_enabled', true );
93
+ $global_html = WC_Vendors::$pv_options->get_option( 'shop_html_enabled' );
94
+
95
+ if ( !empty( $seller_info ) ) {
96
+
97
+ $seller_info = do_shortcode( $seller_info );
98
+ self::$seller_info = '<div class="pv_seller_info">';
99
+ self::$seller_info .= ( $global_html || $has_html ) ? wpautop( wptexturize( wp_kses_post( $seller_info ) ) ) : sanitize_text_field( $seller_info );
100
+ self::$seller_info .= '</div>';
101
+
102
+ $tabs[ 'seller_info' ] = array(
103
+ 'title' => apply_filters( 'wcvendors_seller_info_label', __( 'Seller info', 'wcvendors' ) ),
104
+ 'priority' => 50,
105
+ 'callback' => array( 'WCV_Vendor_Shop', 'seller_info_tab_panel' ),
106
+ );
107
+ }
108
+ }
109
+
110
+ return $tabs;
111
+ }
112
+
113
+
114
+ /**
115
+ *
116
+ */
117
+ public static function seller_info_tab_panel()
118
+ {
119
+ echo self::$seller_info;
120
+ }
121
+
122
+
123
+ /**
124
+ * Show the description a vendor sets when viewing products by that vendor
125
+ */
126
+ public static function shop_description()
127
+ {
128
+ $vendor_shop = urldecode( get_query_var( 'vendor_shop' ) );
129
+ $vendor_id = WCV_Vendors::get_vendor_id( $vendor_shop );
130
+
131
+ if ( $vendor_id ) {
132
+ $has_html = get_user_meta( $vendor_id, 'pv_shop_html_enabled', true );
133
+ $global_html = WC_Vendors::$pv_options->get_option( 'shop_html_enabled' );
134
+ $description = do_shortcode( get_user_meta( $vendor_id, 'pv_shop_description', true ) );
135
+
136
+ echo '<div class="pv_shop_description">';
137
+ echo ( $global_html || $has_html ) ? wpautop( wptexturize( wp_kses_post( $description ) ) ) : sanitize_text_field( $description );
138
+ echo '</div>';
139
+ }
140
+ }
141
+
142
+ /**
143
+ *
144
+ */
145
+ public static function add_rewrite_rules()
146
+ {
147
+ $permalink = untrailingslashit( WC_Vendors::$pv_options->get_option( 'vendor_shop_permalink' ) );
148
+
149
+ // Remove beginning slash
150
+ if ( substr( $permalink, 0, 1 ) == '/' ) {
151
+ $permalink = substr( $permalink, 1, strlen( $permalink ) );
152
+ }
153
+
154
+ add_rewrite_tag( '%vendor_shop%', '([^&]+)' );
155
+
156
+ add_rewrite_rule( $permalink . '/([^/]*)/page/([0-9]+)', 'index.php?post_type=product&vendor_shop=$matches[1]&paged=$matches[2]', 'top' );
157
+ add_rewrite_rule( $permalink . '/([^/]*)', 'index.php?post_type=product&vendor_shop=$matches[1]', 'top' );
158
+ }
159
+
160
+
161
+ public static function page_title( $page_title = "" )
162
+ {
163
+ $vendor_shop = urldecode( get_query_var( 'vendor_shop' ) );
164
+ $vendor_id = WCV_Vendors::get_vendor_id( $vendor_shop );
165
+
166
+ return $vendor_id ? WCV_Vendors::get_vendor_shop_name( $vendor_id ) : $page_title;
167
+ }
168
+
169
+
170
+ /*
171
+ Adding sold by to product loop
172
+ */
173
+ public static function template_loop_sold_by($product_id) {
174
+ $author = WCV_Vendors::get_vendor_from_product( $product_id );
175
+ $sold_by = WCV_Vendors::is_vendor( $author )
176
+ ? sprintf( '<a href="%s">%s</a>', WCV_Vendors::get_vendor_shop_page( $author), WCV_Vendors::get_vendor_shop_name( $author ) )
177
+ : get_bloginfo( 'name' );
178
+ echo '<small>' . apply_filters('wcvendors_sold_by_in_loop', __( 'Sold by: ', 'wcvendors' )). $sold_by . '</small> <br />';
179
+ }
180
+
181
+
182
+ /*
183
+ * Remove the Page title from Archive-Product while on a vendor Page
184
+ */
185
+ public static function remove_vendor_title() {
186
+ if ( WCV_Vendors::is_vendor_page() ) {
187
+ return false;
188
+ }
189
+ }
190
+
191
+ /*
192
+ * Display a vendor header at the top of the vendors product archive page
193
+ */
194
+ public static function vendor_main_header() {
195
+
196
+ // Remove the basic shop description from the loop
197
+ remove_action( 'woocommerce_before_main_content', array('WCV_Vendor_Shop', 'shop_description' ), 30);
198
+
199
+ if (WCV_Vendors::is_vendor_page()) {
200
+ $vendor_shop = urldecode( get_query_var( 'vendor_shop' ) );
201
+ $vendor_id = WCV_Vendors::get_vendor_id( $vendor_shop );
202
+ $shop_name = get_user_meta( $vendor_id, 'pv_shop_name', true );
203
+
204
+ // Shop description
205
+ $has_html = get_user_meta( $vendor_id, 'pv_shop_html_enabled', true );
206
+ $global_html = WC_Vendors::$pv_options->get_option( 'shop_html_enabled' );
207
+ $description = do_shortcode( get_user_meta( $vendor_id, 'pv_shop_description', true ) );
208
+ $shop_description = ( $global_html || $has_html ) ? wpautop( wptexturize( wp_kses_post( $description ) ) ) : sanitize_text_field( $description );
209
+
210
+ do_action('wcv_before_main_header', $vendor_id);
211
+
212
+ wc_get_template( 'vendor-main-header.php', array(
213
+ 'shop_name' => $shop_name,
214
+ 'vendor_id' => $vendor_id,
215
+ 'shop_description' => $shop_description
216
+ ), 'wc-product-vendor/front/', wcv_plugin_dir . 'views/front/' );
217
+
218
+ do_action('wcv_after_main_header', $vendor_id);
219
+
220
+ }
221
+ }
222
+
223
+
224
+ /*
225
+ * Display a vendor header at the top of the single-product page
226
+ */
227
+ public static function vendor_mini_header() {
228
+
229
+ global $product;
230
+
231
+ if (WCV_Vendors::is_vendor_product_page($product->post->post_author)) {
232
+
233
+ $vendor = get_userdata( $product->post->post_author );
234
+ $vendor_shop_link = site_url( WC_Vendors::$pv_options->get_option( 'vendor_shop_permalink' ) .'/' .$vendor->pv_shop_slug );
235
+
236
+ $has_html = $vendor->pv_shop_html_enabled;
237
+ $global_html = WC_Vendors::$pv_options->get_option( 'shop_html_enabled' );
238
+ $description = do_shortcode( $vendor->pv_shop_description );
239
+ $shop_description = ( $global_html || $has_html ) ? wpautop( wptexturize( wp_kses_post( $description ) ) ) : sanitize_text_field( $description );
240
+
241
+ do_action('wcv_before_mini_header', $vendor->ID);
242
+
243
+ wc_get_template( 'vendor-mini-header.php', array(
244
+ 'vendor' => $vendor,
245
+ 'vendor_shop_link' => $vendor_shop_link,
246
+ 'shop_description' => $shop_description,
247
+ 'shop_name' => $vendor->pv_shop_name,
248
+ ), 'wc-product-vendor/front/', wcv_plugin_dir . 'views/front/' );
249
+
250
+ do_action('wcv_after_mini_header', $vendor->ID);
251
+
252
+ }
253
+ }
254
+
255
+ /*
256
+ * Add Vendor to Order item Meta
257
+ * Thanks to Asbjoern Andersen for the code
258
+ *
259
+ */
260
+ public static function add_vendor_to_order_item_meta( $item_id, $cart_item) {
261
+ $vendor_id = $cart_item[ 'data' ]->post->post_author;
262
+ $sold_by = WCV_Vendors::is_vendor( $vendor_id ) ? sprintf( WCV_Vendors::get_vendor_shop_name( $vendor_id ) ): get_bloginfo( 'name' );
263
+ wc_add_order_item_meta( $item_id, apply_filters('wcvendors_sold_by_in_email', __('Sold by', 'wcvendors')), $sold_by);
264
+ }
265
+
266
+ }
trunk/WCVendors/classes/front/dashboard/class-vendor-dashboard.php ADDED
@@ -0,0 +1,384 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * My account views
5
+ *
6
+ * @author Matt Gates <http://mgates.me>
7
+ * @package ProductVendor
8
+ */
9
+
10
+
11
+ class WCV_Vendor_Dashboard
12
+ {
13
+
14
+
15
+ /**
16
+ * __construct()
17
+ */
18
+ function __construct()
19
+ {
20
+ add_shortcode( 'wcv_shop_settings', array( $this, 'display_vendor_settings' ) );
21
+ add_shortcode( 'wcv_vendor_dashboard', array( $this, 'display_vendor_products' ) );
22
+
23
+ add_action( 'template_redirect', array( $this, 'check_access' ) );
24
+ add_action( 'init', array( $this, 'save_vendor_settings' ) );
25
+ }
26
+
27
+ public function save_vendor_settings()
28
+ {
29
+ global $woocommerce;
30
+
31
+ $user_id = get_current_user_id();
32
+
33
+ if ( !empty( $_GET['wc_pv_mark_shipped'] ) ) {
34
+ $order_id = $_GET['wc_pv_mark_shipped'];
35
+ $shippers = (array) get_post_meta( $order_id, 'wc_pv_shipped', true );
36
+
37
+ if( in_array($user_id, $shippers)) {
38
+ foreach ($shippers as $key => $value) {
39
+ if ( $value == $user_id ) {
40
+ unset($shippers[$key]);
41
+ + do_action('wcvendors_vendor_unship', $order_id, $user_id);
42
+ wc_add_notice( __( 'Order unmarked shipped. <br><br>Caution: Clicking Reload in your browser will mark the order as shipped and email the buyer again, potentially spamming them.', 'wcvendors' ), 'success');
43
+ break;
44
+ }
45
+ }
46
+ } else {
47
+ $shippers[] = $user_id;
48
+ $mails = $woocommerce->mailer()->get_emails();
49
+ if ( !empty( $mails ) ) {
50
+ $mails[ 'WC_Email_Notify_Shipped' ]->trigger( $order_id, $user_id );
51
+ }
52
+ + do_action('wcvendors_vendor_ship', $order_id, $user_id);
53
+ wc_add_notice( __( 'Order marked shipped. <br><br>Caution: Clicking Reload in your browser will unmark the order as shipped.', 'wcvendors' ), 'success' );
54
+ }
55
+
56
+ update_post_meta( $order_id, 'wc_pv_shipped', $shippers );
57
+ return;
58
+ }
59
+
60
+ if ( isset( $_POST[ 'update_tracking' ] ) ) {
61
+ $order_id = (int) $_POST[ 'order_id' ];
62
+ $product_id = (int) $_POST[ 'product_id' ];
63
+
64
+ $tracking_provider = woocommerce_clean( $_POST[ 'tracking_provider' ] );
65
+ $custom_tracking_provider = woocommerce_clean( $_POST[ 'custom_tracking_provider' ] );
66
+ $custom_tracking_link = woocommerce_clean( $_POST[ 'custom_tracking_link' ] );
67
+ $tracking_number = woocommerce_clean( $_POST[ 'tracking_number' ] );
68
+ $date_shipped = woocommerce_clean( strtotime( $_POST[ 'date_shipped' ] ) );
69
+
70
+ $order = new WC_Order( $order_id );
71
+ $products = $order->get_items();
72
+ foreach ( $products as $key => $value ) {
73
+ if ( $value[ 'product_id' ] == $product_id || $value[ 'variation_id' ] == $product_id ) {
74
+ $order_item_id = $key;
75
+ break;
76
+ }
77
+ }
78
+ if ( $order_item_id ) {
79
+ woocommerce_delete_order_item_meta( $order_item_id, __( 'Tracking number', 'wcvendors' ) );
80
+ woocommerce_add_order_item_meta( $order_item_id, __( 'Tracking number', 'wcvendors' ), $tracking_number );
81
+
82
+ $message = __( 'Success. Your tracking number has been updated.', 'wcvendors' );
83
+ wc_add_notice( $message, 'success' );
84
+
85
+ // Update order data
86
+ update_post_meta( $order_id, '_tracking_provider', $tracking_provider );
87
+ update_post_meta( $order_id, '_custom_tracking_provider', $custom_tracking_provider );
88
+ update_post_meta( $order_id, '_tracking_number', $tracking_number );
89
+ update_post_meta( $order_id, '_custom_tracking_link', $custom_tracking_link );
90
+ update_post_meta( $order_id, '_date_shipped', $date_shipped );
91
+ }
92
+
93
+ }
94
+
95
+ if ( empty( $_POST[ 'vendor_application_submit' ] ) ) {
96
+ return false;
97
+ }
98
+
99
+ if ( !wp_verify_nonce( $_POST[ 'wc-product-vendor-nonce' ], 'save-shop-settings' ) ) {
100
+ return false;
101
+ }
102
+
103
+
104
+ if ( isset( $_POST[ 'pv_paypal' ] ) ) {
105
+ if ( !is_email( $_POST[ 'pv_paypal' ] ) ) {
106
+ wc_add_notice( __( 'Your PayPal address is not a valid email address.', 'wcvendors' ), 'error' );
107
+ } else {
108
+ update_user_meta( $user_id, 'pv_paypal', $_POST[ 'pv_paypal' ] );
109
+ }
110
+ }
111
+
112
+ if ( !empty( $_POST[ 'pv_shop_name' ] ) ) {
113
+ $users = get_users( array( 'meta_key' => 'pv_shop_slug', 'meta_value' => sanitize_title( $_POST[ 'pv_shop_name' ] ) ) );
114
+ if ( !empty( $users ) && $users[ 0 ]->ID != $user_id ) {
115
+ wc_add_notice( __( 'That shop name is already taken. Your shop name must be unique.', 'wcvendors' ), 'error' );
116
+ } else {
117
+ update_user_meta( $user_id, 'pv_shop_name', $_POST[ 'pv_shop_name' ] );
118
+ update_user_meta( $user_id, 'pv_shop_slug', sanitize_title( $_POST[ 'pv_shop_name' ] ) );
119
+ }
120
+ }
121
+
122
+ if ( isset( $_POST[ 'pv_shop_description' ] ) ) {
123
+ update_user_meta( $user_id, 'pv_shop_description', $_POST[ 'pv_shop_description' ] );
124
+ }
125
+
126
+ if ( isset( $_POST[ 'pv_seller_info' ] ) ) {
127
+ update_user_meta( $user_id, 'pv_seller_info', $_POST[ 'pv_seller_info' ] );
128
+ }
129
+
130
+ do_action( 'wcvendors_shop_settings_saved', $user_id );
131
+
132
+ if ( !wc_notice_count() ) {
133
+ wc_add_notice( __( 'Settings saved.', 'wcvendors' ), 'success' );
134
+ }
135
+ }
136
+
137
+
138
+ /**
139
+ *
140
+ */
141
+ public function check_access()
142
+ {
143
+ $vendor_dashboard_page = WC_Vendors::$pv_options->get_option( 'vendor_dashboard_page' );
144
+ $shop_settings_page = WC_Vendors::$pv_options->get_option( 'shop_settings_page' );
145
+
146
+ if ( ( is_page( $vendor_dashboard_page ) || is_page( $shop_settings_page ) ) && !is_user_logged_in() ) {
147
+ wp_redirect( get_permalink( woocommerce_get_page_id( 'myaccount' ) ) );
148
+ exit;
149
+ }
150
+ }
151
+
152
+
153
+ /**
154
+ * [wcv_vendor_dashboard] shortcode
155
+ *
156
+ * @param array $atts
157
+ *
158
+ * @return unknown
159
+ */
160
+ public function display_vendor_products( $atts )
161
+ {
162
+ global $start_date, $end_date;
163
+
164
+ $start_date = !empty( $_SESSION[ 'PV_Session' ][ 'start_date' ] ) ? $_SESSION[ 'PV_Session' ][ 'start_date' ] : strtotime( date( 'Ymd', strtotime( date( 'Ym', current_time( 'timestamp' ) ) . '01' ) ) );
165
+ $end_date = !empty( $_SESSION[ 'PV_Session' ][ 'end_date' ] ) ? $_SESSION[ 'PV_Session' ][ 'end_date' ] : strtotime( date( 'Ymd', current_time( 'timestamp' ) ) );
166
+
167
+ $can_view_orders = WC_Vendors::$pv_options->get_option( 'can_show_orders' );
168
+ $settings_page = get_permalink( WC_Vendors::$pv_options->get_option( 'shop_settings_page' ) );
169
+ $can_submit = WC_Vendors::$pv_options->get_option( 'can_submit_products' );
170
+ if ( $can_submit ) $submit_link = admin_url( 'post-new.php?post_type=product' );
171
+
172
+ if ( !$this->can_view_vendor_page() ) {
173
+ return false;
174
+ }
175
+
176
+ extract( shortcode_atts( array(
177
+ 'user_id' => get_current_user_id(),
178
+ 'datepicker' => true,
179
+ ), $atts ) );
180
+
181
+ $vendor_products = WCV_Queries::get_commission_products( $user_id );
182
+ $products = array();
183
+ foreach ($vendor_products as $_product) {
184
+ $products[] = $_product->ID;
185
+ }
186
+
187
+ $vendor_summary = $this->format_product_details( $vendor_products );
188
+ $order_summary = WCV_Queries::get_orders_for_products( $products );
189
+ $shop_page = WCV_Vendors::get_vendor_shop_page( wp_get_current_user()->user_login );
190
+
191
+ wp_enqueue_style( 'wcv_frontend_style', wcv_assets_url . 'css/wcv-frontend.css' );
192
+
193
+ // WC Shipment Tracking Providers
194
+ global $WC_Shipment_Tracking;
195
+
196
+ $providers = !empty( $WC_Shipment_Tracking->providers ) ? $WC_Shipment_Tracking->providers : false;
197
+ $provider_array = array();
198
+
199
+ if ( $providers ) {
200
+ foreach ( $providers as $providerss ) {
201
+ foreach ( $providerss as $provider => $format ) {
202
+ $provider_array[ sanitize_title( $provider ) ] = urlencode( $format );
203
+ }
204
+ }
205
+ }
206
+
207
+ ob_start();
208
+ do_action( 'wcvendors_before_dashboard' );
209
+
210
+ wc_print_notices();
211
+ wc_get_template( 'links.php', array(
212
+ 'shop_page' => urldecode($shop_page),
213
+ 'settings_page' => $settings_page,
214
+ 'can_submit' => $can_submit,
215
+ 'submit_link' => $submit_link,
216
+ ), 'wc-product-vendor/dashboard/', wcv_plugin_dir . 'views/dashboard/' );
217
+
218
+ if ( $can_view_sales = WC_Vendors::$pv_options->get_option( 'can_view_frontend_reports' ) ) {
219
+
220
+ wc_get_template( 'reports.php', array(
221
+ 'start_date' => $start_date,
222
+ 'end_date' => $end_date,
223
+ 'vendor_products' => $vendor_products,
224
+ 'vendor_summary' => $vendor_summary,
225
+ 'datepicker' => $datepicker,
226
+ 'can_view_orders' => $can_view_orders,
227
+ ), 'wc-product-vendor/dashboard/', wcv_plugin_dir . 'views/dashboard/' );
228
+ }
229
+
230
+ wc_get_template( 'orders.php', array(
231
+ 'start_date' => $start_date,
232
+ 'end_date' => $end_date,
233
+ 'vendor_products' => $vendor_products,
234
+ 'order_summary' => $order_summary,
235
+ 'datepicker' => $datepicker,
236
+ 'providers' => $providers,
237
+ 'provider_array' => $provider_array,
238
+ 'can_view_orders' => $can_view_orders,
239
+ ), 'wc-product-vendor/dashboard/', wcv_plugin_dir . 'views/dashboard/' );
240
+ do_action( 'wcvendors_after_dashboard' );
241
+
242
+ return ob_get_clean();
243
+ }
244
+
245
+
246
+ /**
247
+ * [pv_recent_vendor_sales] shortcode
248
+ *
249
+ * @param array $atts
250
+ *
251
+ * @return unknown
252
+ */
253
+ public function display_vendor_settings( $atts )
254
+ {
255
+ global $woocommerce;
256
+
257
+ if ( !$this->can_view_vendor_page() ) {
258
+ return false;
259
+ }
260
+
261
+ extract( shortcode_atts( array(
262
+ 'user_id' => get_current_user_id(),
263
+ 'paypal_address' => true,
264
+ 'shop_description' => true,
265
+ ), $atts ) );
266
+
267
+ $description = get_user_meta( $user_id, 'pv_shop_description', true );
268
+ $seller_info = get_user_meta( $user_id, 'pv_seller_info', true );
269
+ $has_html = get_user_meta( $user_id, 'pv_shop_html_enabled', true );
270
+ $shop_page = WCV_Vendors::get_vendor_shop_page( wp_get_current_user()->user_login );
271
+ $global_html = WC_Vendors::$pv_options->get_option( 'shop_html_enabled' );
272
+
273
+ ob_start();
274
+ wc_get_template( 'settings.php', array(
275
+ 'description' => $description,
276
+ 'global_html' => $global_html,
277
+ 'has_html' => $has_html,
278
+ 'paypal_address' => $paypal_address,
279
+ 'seller_info' => $seller_info,
280
+ 'shop_description' => $shop_description,
281
+ 'shop_page' => $shop_page,
282
+ 'user_id' => $user_id,
283
+ ), 'wc-product-vendor/dashboard/settings/', wcv_plugin_dir . 'views/dashboard/settings/' );
284
+
285
+ return ob_get_clean();
286
+ }
287
+
288
+
289
+ /**
290
+ *
291
+ *
292
+ * @return unknown
293
+ */
294
+ public function can_view_vendor_page()
295
+ {
296
+ if ( !is_user_logged_in() ) {
297
+
298
+ return false;
299
+
300
+ } else if ( !WCV_Vendors::is_vendor( get_current_user_id() ) ) {
301
+
302
+ wc_get_template( 'denied.php', array(), 'wc-product-vendor/dashboard/', wcv_plugin_dir . 'views/dashboard/' );
303
+
304
+ return false;
305
+
306
+ }
307
+
308
+ return true;
309
+ }
310
+
311
+
312
+ /**
313
+ * Format products for easier displaying
314
+ *
315
+ * @param object $products
316
+ *
317
+ * @return array
318
+ */
319
+ public function format_product_details( $products )
320
+ {
321
+ if ( empty( $products ) ) return false;
322
+
323
+ $orders_page = get_permalink( WC_Vendors::$pv_options->get_option( 'orders_page' ) );
324
+ $default_commission = WC_Vendors::$pv_options->get_option( 'default_commission' );
325
+ $total_qty = $total_cost = 0;
326
+ $data = array(
327
+ 'products' => array(),
328
+ 'total_qty' => '',
329
+ 'total_cost' => '',
330
+ );
331
+
332
+ foreach ( $products as $product )
333
+ $ids[ ] = $product->ID;
334
+
335
+ $orders = WCV_Queries::sum_orders_for_products( $ids, array( 'vendor_id' => get_current_user_id() ) );
336
+
337
+ if ( $orders )
338
+ foreach ( $orders as $order_item ) {
339
+ if ( $order_item->qty < 1 ) continue;
340
+
341
+ $commission_rate = WCV_Commission::get_commission_rate( $order_item->product_id );
342
+ $_product = get_product( $order_item->product_id );
343
+ $id = !empty($_product->parent->id) ? $_product->parent->id : $order_item->product_id;
344
+
345
+ $data[ 'products' ][$id] = array(
346
+ 'id' => $id,
347
+ 'title' => $_product->get_title(),
348
+ 'qty' => !empty($data[ 'products' ][$id]) ? $data[ 'products' ][$id]['qty'] + $order_item->qty : $order_item->qty,
349
+ 'cost' => !empty($data[ 'products' ][$id]) ? $data[ 'products' ][$id]['cost'] + $order_item->line_total : $order_item->line_total,
350
+ 'view_orders_url' => esc_url( add_query_arg( 'orders_for_product', $id, $orders_page ) ),
351
+ 'commission_rate' => $commission_rate,
352
+ );
353
+
354
+ $total_qty += $order_item->qty;
355
+ $total_cost += $order_item->line_total;
356
+
357
+ }
358
+
359
+ $data[ 'total_qty' ] = $total_qty;
360
+ $data[ 'total_cost' ] = $total_cost;
361
+
362
+ // Sort by product title
363
+ if ( !empty( $data[ 'products' ] ) )
364
+ usort( $data[ 'products' ], array( $this, 'sort_by_title' ) );
365
+
366
+ return $data;
367
+ }
368
+
369
+
370
+ /**
371
+ * Sort an array by 'title'
372
+ *
373
+ * @param array $a
374
+ * @param array $b
375
+ *
376
+ * @return array
377
+ */
378
+ private function sort_by_title( array $a, array $b )
379
+ {
380
+ return strcasecmp( $a[ 'title' ], $b[ 'title' ] );
381
+ }
382
+
383
+
384
+ }
trunk/WCVendors/classes/front/orders/class-export-csv.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCV_Export_CSV
4
+ {
5
+
6
+ /**
7
+ * Sort the data for CSV output first
8
+ *
9
+ * @param int $product_id
10
+ * @param array $headers
11
+ * @param array $body
12
+ * @param array $items
13
+ */
14
+
15
+
16
+ public static function output_csv( $product_id, $headers, $body, $items )
17
+ {
18
+ foreach ( $body as $i => $data ) {
19
+
20
+ unset( $body[ $i ][ 'comments' ] );
21
+
22
+ foreach ( $items[ $i ][ 'items' ] as $item ) {
23
+
24
+ $item_meta = new WC_Order_Item_Meta( $item[ 'item_meta' ] );
25
+ $item_meta = $item_meta->display( true, true );
26
+
27
+ if ( !empty( $item_meta ) ) {
28
+ $meta = true;
29
+ $body[ $i ][ ] = $item[ 'qty' ] . 'x: ' . html_entity_decode( $item_meta );
30
+ } else {
31
+ $body[ $i ][ ] = $item[ 'qty' ];
32
+ }
33
+
34
+ }
35
+ }
36
+
37
+ if ( $meta ) $headers[ 'meta' ] = __( 'Extra data', 'wcvendors' );
38
+ else $headers[ 'quantity' ] = __( 'Quantity', 'wcvendors' );
39
+
40
+ $headers = apply_filters( 'wcvendors_csv_headers', $headers, $product_id, $items );
41
+ $body = apply_filters( 'wcvendors_csv_body', $body, $product_id, $items );
42
+
43
+ WCV_Export_CSV::download( $headers, $body, $product_id );
44
+ }
45
+
46
+
47
+ /**
48
+ * Send the CSV to the browser for download
49
+ *
50
+ * @param array $headers
51
+ * @param array $body
52
+ * @param string $filename
53
+ */
54
+ public static function download( $headers, $body, $filename )
55
+ {
56
+ // Clear browser output before this point
57
+ ob_end_clean();
58
+
59
+ // Output headers so that the file is downloaded rather than displayed
60
+ header( 'Content-Type: text/csv; charset=utf-8' );
61
+ header( 'Content-Disposition: attachment; filename=orders_for_' . $filename . '.csv' );
62
+
63
+ // Create a file pointer connected to the output stream
64
+ $output = fopen( 'php://output', 'w' );
65
+
66
+ // Output the column headings
67
+ fputcsv( $output, $headers );
68
+
69
+ // Body
70
+ foreach ( $body as $data )
71
+ fputcsv( $output, $data );
72
+
73
+ die();
74
+ }
75
+
76
+
77
+ }
trunk/WCVendors/classes/front/orders/class-orders.php ADDED
@@ -0,0 +1,294 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * My account views
5
+ *
6
+ * @author Matt Gates <http://mgates.me>
7
+ * @package ProductVendor
8
+ */
9
+
10
+
11
+ class WCV_Orders
12
+ {
13
+
14
+
15
+ /**
16
+ * __construct()
17
+ */
18
+ function __construct()
19
+ {
20
+ $this->can_view_orders = WC_Vendors::$pv_options->get_option( 'can_show_orders' );
21
+ $this->can_export_csv = WC_Vendors::$pv_options->get_option( 'can_export_csv' );
22
+ $this->can_view_emails = WC_Vendors::$pv_options->get_option( 'can_view_order_emails' );
23
+
24
+ add_action( 'template_redirect', array( $this, 'check_access' ) );
25
+ add_action( 'wp', array( $this, 'display_shortcodes' ) );
26
+ }
27
+
28
+
29
+ /**
30
+ *
31
+ */
32
+ public function check_access()
33
+ {
34
+ if ( is_page( WC_Vendors::$pv_options->get_option( 'orders_page' ) ) && !is_user_logged_in() ) {
35
+ wp_redirect( get_permalink( woocommerce_get_page_id( 'myaccount' ) ) );
36
+ exit;
37
+ }
38
+ }
39
+
40
+
41
+ /**
42
+ *
43
+ */
44
+ public function display_shortcodes()
45
+ {
46
+ if ( is_page( WC_Vendors::$pv_options->get_option( 'orders_page' ) ) && $this->can_view_orders ) {
47
+
48
+ wp_enqueue_script( 'jquery' );
49
+
50
+ $this->product_id = !empty( $_GET[ 'orders_for_product' ] ) ? (int) $_GET[ 'orders_for_product' ] : false;
51
+ $products = array( $this->product_id );
52
+
53
+ $_product = get_product( $this->product_id );
54
+ $children = $_product->get_children();
55
+ if ( !empty( $children ) ) {
56
+ $products = array_merge($products, $children);
57
+ $products = array_unique($products);
58
+ }
59
+
60
+ $this->orders = WCV_Queries::get_orders_for_products( $products, array( 'vendor_id' => get_current_user_id() ) );
61
+
62
+ add_action( 'init', array( $this, 'verify_order_access' ) );
63
+ add_shortcode( 'wcv_orders', array( $this, 'display_product_orders' ) );
64
+
65
+ if ( $this->can_export_csv && !empty( $_POST[ 'export_orders' ] ) ) {
66
+ $this->download_csv();
67
+ }
68
+
69
+ }
70
+
71
+ }
72
+
73
+
74
+ /**
75
+ *
76
+ *
77
+ * @return unknown
78
+ */
79
+ public function download_csv()
80
+ {
81
+ if ( !$this->orders ) return false;
82
+
83
+ extract( WCV_Orders::format_order_details( $this->orders, $this->product_id ) );
84
+ $headers = WCV_Orders::get_headers();
85
+
86
+ // Export the CSV
87
+ require_once wcv_plugin_dir . 'classes/front/orders/class-export-csv.php';
88
+ WCV_Export_CSV::output_csv( $this->product_id, $headers, $body, $items );
89
+ }
90
+
91
+
92
+ /**
93
+ * Use views to display the Orders page
94
+ *
95
+ * @return html
96
+ */
97
+ public function display_product_orders()
98
+ {
99
+ if ( !WCV_Vendors::is_vendor( get_current_user_id() ) ) {
100
+ ob_start();
101
+ wc_get_template( 'denied.php', array(), 'wc-product-vendor/dashboard/', wcv_plugin_dir . 'views/dashboard/' );
102
+
103
+ return ob_get_clean();
104
+ }
105
+
106
+ if ( empty( $_GET[ 'orders_for_product' ] ) ) {
107
+ return __( 'You haven\'t selected a product\'s orders to view! Please go back to the Vendor Dashboard and click Show Orders on the product you\'d like to view.', 'wcvendors' );
108
+ }
109
+
110
+ if ( !$this->orders ) {
111
+ return __( 'No orders.', 'wcvendors' );;
112
+ }
113
+
114
+ if ( !empty( $_POST[ 'submit_comment' ] ) ) {
115
+ require_once wcv_plugin_dir . 'classes/front/orders/class-submit-comment.php';
116
+ WCV_Submit_Comment::new_comment( $this->orders );
117
+ }
118
+
119
+ if ( isset( $_POST[ 'mark_shipped' ] ) ) {
120
+ $order_id = (int) $_POST[ 'order_id' ];
121
+ $product_id = (int) $_POST[ 'product_id' ];
122
+ exit;
123
+ }
124
+
125
+ if ( isset( $_POST[ 'update_tracking' ] ) ) {
126
+ $order_id = (int) $_POST[ 'order_id' ];
127
+ $product_id = (int) $_POST[ 'product_id' ];
128
+
129
+ $tracking_provider = woocommerce_clean( $_POST[ 'tracking_provider' ] );
130
+ $custom_tracking_provider = woocommerce_clean( $_POST[ 'custom_tracking_provider' ] );
131
+ $custom_tracking_link = woocommerce_clean( $_POST[ 'custom_tracking_link' ] );
132
+ $tracking_number = woocommerce_clean( $_POST[ 'tracking_number' ] );
133
+ $date_shipped = woocommerce_clean( strtotime( $_POST[ 'date_shipped' ] ) );
134
+
135
+ $order = new WC_Order( $order_id );
136
+ $products = $order->get_items();
137
+ foreach ( $products as $key => $value ) {
138
+ if ( $value[ 'product_id' ] == $product_id || $value[ 'variation_id' ] == $product_id ) {
139
+ $order_item_id = $key;
140
+ break;
141
+ }
142
+ }
143
+ if ( $order_item_id ) {
144
+ woocommerce_delete_order_item_meta( $order_item_id, __( 'Tracking number', 'wcvendors' ) );
145
+ woocommerce_add_order_item_meta( $order_item_id, __( 'Tracking number', 'wcvendors' ), $tracking_number );
146
+
147
+ $message = __( 'Success. Your tracking number has been updated.', 'wcvendors' );
148
+ wc_add_notice( $message, 'success' );
149
+
150
+ // Update order data
151
+ update_post_meta( $order_id, '_tracking_provider', $tracking_provider );
152
+ update_post_meta( $order_id, '_custom_tracking_provider', $custom_tracking_provider );
153
+ update_post_meta( $order_id, '_tracking_number', $tracking_number );
154
+ update_post_meta( $order_id, '_custom_tracking_link', $custom_tracking_link );
155
+ update_post_meta( $order_id, '_date_shipped', $date_shipped );
156
+ }
157
+
158
+ }
159
+
160
+ $headers = WCV_Orders::get_headers();
161
+ $all = WCV_Orders::format_order_details( $this->orders, $this->product_id );
162
+
163
+ wp_enqueue_style( 'pv_frontend_style', wcv_assets_url . 'css/wcv-frontend.css' );
164
+ wp_enqueue_script( 'pv_frontend_script', wcv_assets_url . 'js/front-orders.js' );
165
+
166
+ // WC Shipment Tracking Providers
167
+ global $WC_Shipment_Tracking;
168
+
169
+ $providers = !empty( $WC_Shipment_Tracking->providers ) ? $WC_Shipment_Tracking->providers : false;
170
+ $provider_array = array();
171
+
172
+ if ( $providers ) {
173
+ foreach ( $providers as $providerss ) {
174
+ foreach ( $providerss as $provider => $format ) {
175
+ $provider_array[ sanitize_title( $provider ) ] = urlencode( $format );
176
+ }
177
+ }
178
+ }
179
+ // End
180
+
181
+ ob_start();
182
+ // Show the Export CSV button
183
+ if ( $this->can_export_csv ) {
184
+ wc_get_template( 'csv-export.php', array(), 'wc-product-vendor/orders/', wcv_plugin_dir . 'views/orders/' );
185
+ }
186
+
187
+ wc_get_template( 'orders.php', array(
188
+ 'headers' => $headers,
189
+ 'body' => $all[ 'body' ],
190
+ 'items' => $all[ 'items' ],
191
+ 'product_id' => $all[ 'product_id' ],
192
+ 'providers' => $providers,
193
+ 'provider_array' => $provider_array,
194
+ ), 'wc-product-vendor/orders/', wcv_plugin_dir . 'views/orders/' );
195
+
196
+ return ob_get_clean();
197
+ }
198
+
199
+
200
+ /**
201
+ * Headers for the Orders page
202
+ *
203
+ * @return array
204
+ */
205
+ public function get_headers()
206
+ {
207
+ $headers = array(
208
+ 'order' => __( 'Order', 'wcvendors' ),
209
+ 'product' => __( 'Product Title', 'wcvendors' ),
210
+ 'name' => __( 'Full name', 'wcvendors' ),
211
+ 'address' => __( 'Address', 'wcvendors' ),
212
+ 'city' => __( 'City', 'wcvendors' ),
213
+ 'state' => __( 'State', 'wcvendors' ),
214
+ 'zip' => __( 'Zip', 'wcvendors' ),
215
+ 'email' => __( 'Email address', 'wcvendors' ),
216
+ 'date' => __( 'Date', 'wcvendors' ),
217
+ );
218
+
219
+ if ( !$this->can_view_emails ) {
220
+ unset( $headers[ 'email' ] );
221
+ }
222
+
223
+ return $headers;
224
+ }
225
+
226
+
227
+ /**
228
+ * Format the orders with just the products we want
229
+ *
230
+ * @param object $orders
231
+ * @param int $product_id
232
+ *
233
+ * @return array
234
+ */
235
+ public function format_order_details( $orders, $product_id )
236
+ {
237
+ $body = $items = array();
238
+ $product = get_product( $product_id )->get_title();
239
+
240
+ foreach ( $orders as $i => $order ) {
241
+ $i = $order->order_id;
242
+ $order = new WC_Order ( $i );
243
+ $body[ $i ] = array(
244
+ 'order_number' => $order->get_order_number(),
245
+ 'product' => $product,
246
+ 'name' => $order->shipping_first_name . ' ' . $order->shipping_last_name,
247
+ 'address' => $order->shipping_address_1,
248
+ 'city' => $order->shipping_city,
249
+ 'state' => $order->shipping_state,
250
+ 'zip' => $order->shipping_postcode,
251
+ 'email' => $order->billing_email,
252
+ 'date' => $order->order_date,
253
+ 'comments' => wptexturize( $order->customer_note ),
254
+ );
255
+
256
+ if ( !$this->can_view_emails ) {
257
+ unset( $body[ $i ][ 'email' ] );
258
+ }
259
+
260
+ $items[ $i ][ 'total_qty' ] = 0;
261
+ foreach ( $order->get_items() as $line_id => $item ) {
262
+
263
+ if ( $item[ 'product_id' ] != $product_id && $item[ 'variation_id' ] != $product_id ) continue;
264
+
265
+ $items[ $i ][ 'items' ][ ] = $item;
266
+ $items[ $i ][ 'total_qty' ] += $item[ 'qty' ];
267
+ }
268
+
269
+ }
270
+
271
+ return array( 'body' => $body, 'items' => $items, 'product_id' => $product_id );
272
+ }
273
+
274
+
275
+ /**
276
+ * Verify the current user can view orders for a product
277
+ *
278
+ * @param int $product_id
279
+ */
280
+ public function verify_order_access()
281
+ {
282
+ if ( !is_user_logged_in() || empty( $this->product_id ) ) {
283
+ wp_safe_redirect( apply_filters( 'woocommerce_get_myaccount_page_id', get_permalink( woocommerce_get_page_id( 'myaccount' ) ) ) );
284
+ exit;
285
+ }
286
+
287
+ $product = get_post( $this->product_id );
288
+ if ( empty ( $product ) || $product->post_type != 'product' || get_current_user_id() != $product->post_author ) {
289
+ wp_safe_redirect( apply_filters( 'woocommerce_get_myaccount_page_id', get_permalink( woocommerce_get_page_id( 'myaccount' ) ) ) );
290
+ exit;
291
+ }
292
+ }
293
+
294
+ }
trunk/WCVendors/classes/front/orders/class-submit-comment.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCV_Submit_Comment
4
+ {
5
+
6
+ /**
7
+ * Submit a comment for an order
8
+ *
9
+ * @param object $orders
10
+ *
11
+ * @return unknown
12
+ */
13
+ public static function new_comment( $orders )
14
+ {
15
+ global $woocommerce;
16
+
17
+ $user = wp_get_current_user();
18
+ $user = $user->ID;
19
+
20
+ // Security
21
+ if ( !wp_verify_nonce( $_POST[ '_wpnonce' ], 'add-comment' ) ) return false;
22
+
23
+ // Check if this product belongs to the vendor submitting the comment
24
+ $product_id = (int) $_POST[ 'product_id' ];
25
+ $author = WCV_Vendors::get_vendor_from_product( $product_id );
26
+ if ( $author != $user ) return false;
27
+
28
+ // Find the order belonging to this comment
29
+ foreach ( $orders as $order ) {
30
+ if ( $order->order_id == $_POST[ 'order_id' ] ) {
31
+ $found_order = $order;
32
+ break;
33
+ }
34
+ }
35
+
36
+ // No order was found
37
+ if ( empty( $found_order ) ) return false;
38
+
39
+ // Don't submit empty comments
40
+ if ( empty( $_POST[ 'comment_text' ] ) ) {
41
+ wc_add_notice( __( 'You\'ve left the comment field empty!', 'wcvendors' ), 'error' );
42
+
43
+ return false;
44
+ }
45
+
46
+ // Only submit if the order has the product belonging to this vendor
47
+ $found_order = new WC_Order ( $found_order->order_id );
48
+ $valid_order = false;
49
+ foreach ( $found_order->get_items() as $item ) {
50
+ if ( $item[ 'product_id' ] == $product_id ) {
51
+ $valid_order = true;
52
+ break;
53
+ }
54
+ }
55
+
56
+ if ( $valid_order ) {
57
+ $comment = esc_textarea( $_POST[ 'comment_text' ] );
58
+
59
+ add_filter( 'woocommerce_new_order_note_data', array( __CLASS__, 'filter_comment' ), 10, 2 );
60
+ $found_order->add_order_note( $comment, 1 );
61
+ remove_filter( 'woocommerce_new_order_note_data', array( __CLASS__, 'filter_comment' ), 10, 2 );
62
+
63
+ wc_add_notice( __( 'Success. The customer has been notified of your comment.', 'wcvendors' ), 'success' );
64
+ }
65
+
66
+ }
67
+
68
+ public function filter_comment( $commentdata, $order )
69
+ {
70
+ $user_id = get_current_user_id();
71
+
72
+ $commentdata[ 'user_id' ] = $user_id;
73
+ $commentdata[ 'comment_author' ] = WCV_Vendors::get_vendor_shop_name( $user_id );
74
+ $commentdata[ 'comment_author_url' ] = WCV_Vendors::get_vendor_shop_page( $user_id );
75
+ $commentdata[ 'comment_author_email' ] = wp_get_current_user()->user_email;
76
+
77
+ return $commentdata;
78
+ }
79
+
80
+
81
+ }
trunk/WCVendors/classes/front/signup/class-vendor-signup.php ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Signup form for applying as a vendor
5
+ *
6
+ * @author Matt Gates <http://mgates.me>
7
+ * @package ProductVendor
8
+ */
9
+
10
+
11
+ class WCV_Vendor_Signup
12
+ {
13
+
14
+
15
+ /**
16
+ * __construct()
17
+ */
18
+ function __construct()
19
+ {
20
+ if ( !WC_Vendors::$pv_options->get_option( 'show_vendor_registration' ) ) return;
21
+
22
+ $this->terms_page = WC_Vendors::$pv_options->get_option( 'terms_to_apply_page' );
23
+
24
+ add_action( 'register_form', array( $this, 'vendor_option' ) );
25
+ add_action( 'woocommerce_created_customer', array( $this, 'save_pending' ), 10, 2 );
26
+ add_action( 'register_post', array( $this, 'apply_form' ), 10 );
27
+ add_action( 'init', array( $this, 'apply_form' ), 10 );
28
+ }
29
+
30
+
31
+ /**
32
+ *
33
+ */
34
+ public function vendor_option()
35
+ {
36
+ ?>
37
+ <div class="clear"></div>
38
+
39
+ <p class="form-row">
40
+ <input class="input-checkbox"
41
+ id="apply_for_vendor" <?php checked( isset( $_POST[ 'apply_for_vendor' ] ), true ) ?> type="checkbox"
42
+ name="apply_for_vendor" value="1"/>
43
+ <label for="apply_for_vendor"
44
+ class="checkbox"><?php echo apply_filters('wcvendors_vendor_registration_checkbox', __( 'Apply to become a vendor? ', 'wcvendors' )); ?></label>
45
+ </p>
46
+
47
+ <?php if ( $this->terms_page ) { ?>
48
+ <p class="form-row agree-to-terms-container" style="display:none">
49
+ <input class="input-checkbox"
50
+ id="agree_to_terms" <?php checked( isset( $_POST[ 'agree_to_terms' ] ), true ) ?> type="checkbox"
51
+ name="agree_to_terms" value="1"/>
52
+ <label for="agree_to_terms"
53
+ class="checkbox"><?php printf( __( 'I have read and accepted the <a href="%s">terms and conditions</a>', 'wcvendors' ), get_permalink( $this->terms_page ) ); ?></label>
54
+ </p>
55
+
56
+ <script type="text/javascript">
57
+ jQuery(function () {
58
+ if (jQuery('#apply_for_vendor').is(':checked')) {
59
+ jQuery('.agree-to-terms-container').show();
60
+ }
61
+
62
+ jQuery('#apply_for_vendor').on('click', function () {
63
+ jQuery('.agree-to-terms-container').slideToggle();
64
+ });
65
+ })
66
+ </script>
67
+ <?php } ?>
68
+
69
+ <div class="clear"></div>
70
+ <?php
71
+ }
72
+
73
+
74
+ /**
75
+ *
76
+ *
77
+ * @param unknown $user_id
78
+ */
79
+ public function save_pending( $user_id )
80
+ {
81
+ if ( isset( $_POST[ 'apply_for_vendor' ] ) ) {
82
+ global $woocommerce;
83
+
84
+ wc_clear_notices();
85
+
86
+ if ( user_can( $user_id, 'manage_options' ) ) {
87
+ wc_add_notice( __( 'Application denied. You are an administrator.', 'wcvendors' ), 'error' );
88
+ } else {
89
+ wc_add_notice( __( 'Your application has been submitted.', 'wcvendors' ), 'notice' );
90
+
91
+ $manual = WC_Vendors::$pv_options->get_option( 'manual_vendor_registration' );
92
+ $role = apply_filters( 'wcvendors_pending_role', ( $manual ? 'pending_vendor' : 'vendor' ) );
93
+
94
+ $wp_user_object = new WP_User( $user_id );
95
+ $wp_user_object->set_role( $role );
96
+
97
+ do_action( 'wcvendors_application_submited', $user_id );
98
+
99
+ add_filter( 'woocommerce_registration_redirect', array( 'WCV_Vendor_Signup', 'redirect_to_vendor_dash' ) );
100
+ }
101
+ }
102
+ }
103
+
104
+ public function redirect_to_vendor_dash( $redirect )
105
+ {
106
+ $vendor_dashboard_page = WC_Vendors::$pv_options->get_option( 'vendor_dashboard_page' );
107
+
108
+ return apply_filters( 'wcvendors_signup_redirect', get_permalink( $vendor_dashboard_page ) );
109
+ }
110
+
111
+
112
+ /**
113
+ *
114
+ *
115
+ * @return unknown
116
+ */
117
+ public function apply_form()
118
+ {
119
+ global $woocommerce;
120
+
121
+ if ( !isset( $_POST[ 'apply_for_vendor' ] ) ) return false;
122
+
123
+ if ( $this->terms_page && !isset( $_POST[ 'agree_to_terms' ] ) ) {
124
+ wc_clear_notices();
125
+ wc_add_notice( __( 'You must accept the terms and conditions to become a vendor.', 'wcvendors' ), 'error' );
126
+ } else if ( isset( $_POST[ 'apply_for_vendor_submit' ] ) ) {
127
+ self::save_pending( get_current_user_id() );
128
+ }
129
+
130
+ }
131
+
132
+
133
+ }
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/assets/icons/index.php ADDED
File without changes
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/assets/icons/paypalap.png ADDED
Binary file
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/assets/index.php ADDED
File without changes
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/ChangeLog.txt ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Version 1.2.95 - September 28, 2012
3
+
4
+ - Sender details (eg:email,phno) serialization bug fixed(https://github.com/paypal/SDKs/issues/30)
5
+ - Bug fixed for 'PPLoggingManager.php' to pickup configuration entries.(https://github.com/paypal/SDKs/issues/28)
6
+ - Updated SDK sample
7
+
8
+ --------------------------------------------------------------------------------------------------
9
+
10
+
11
+ Version 1.1.93 - August 13, 2012
12
+
13
+ - SDK refreshed to Release 1.8.1. Please refer https://www.x.com/developers/paypal/documentation-tools/release-notes#AdaptivePaymentsAPI
14
+ - SDK Core - Deserialization Logic Change
15
+ --------------------------------------------------------------------------------------------------
16
+
17
+
18
+ Version 1.0.92 - July 30, 2012
19
+
20
+ - Stable release
21
+ -------------------------------------------------------------------------------------------------
22
+ Version 0.7.92 - July 17, 2012
23
+ - wsdl update version 0.7.92
24
+ ------------------------------------------
25
+
26
+ Version 0.6.88 - Apr 17, 2012
27
+ ----------------------------------------
28
+ - Fix to get SDK working with Permissions API token
29
+ - wsdl update version 88.0
30
+
31
+ Version 0.6.86 - Feb 27, 2012
32
+ ----------------------------------------
33
+ - Initial release
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/LICENSE.txt ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ PAYPAL, INC.
2
+
3
+ SDK LICENSE
4
+
5
+ NOTICE TO USER: PayPal, Inc. is providing the Software and Documentation for use under the terms of this Agreement. Any use, reproduction, modification or distribution of the Software or Documentation, or any derivatives or portions hereof, constitutes your acceptance of this Agreement.
6
+
7
+ As used in this Agreement, "PayPal" means PayPal, Inc. "Software" means the software code accompanying this agreement. "Documentation" means the documents, specifications and all other items accompanying this Agreement other than the Software.
8
+
9
+ 1. LICENSE GRANT Subject to the terms of this Agreement, PayPal hereby grants you a non-exclusive, worldwide, royalty free license to use, reproduce, prepare derivative works from, publicly display, publicly perform, distribute and sublicense the Software for any purpose, provided the copyright notice below appears in a conspicuous location within the source code of the distributed Software and this license is distributed in the supporting documentation of the Software you distribute. Furthermore, you must comply with all third party licenses in order to use the third party software contained in the Software.
10
+
11
+ Subject to the terms of this Agreement, PayPal hereby grants you a non-exclusive, worldwide, royalty free license to use, reproduce, publicly display, publicly perform, distribute and sublicense the Documentation for any purpose. You may not modify the Documentation.
12
+
13
+ No title to the intellectual property in the Software or Documentation is transferred to you under the terms of this Agreement. You do not acquire any rights to the Software or the Documentation except as expressly set forth in this Agreement.
14
+
15
+ If you choose to distribute the Software in a commercial product, you do so with the understanding that you agree to defend, indemnify and hold harmless PayPal and its suppliers against any losses, damages and costs arising from the claims, lawsuits or other legal actions arising out of such distribution. You may distribute the Software in object code form under your own license, provided that your license agreement:
16
+
17
+ (a) complies with the terms and conditions of this license agreement;
18
+
19
+ (b) effectively disclaims all warranties and conditions, express or implied, on behalf of PayPal;
20
+
21
+ (c) effectively excludes all liability for damages on behalf of PayPal;
22
+
23
+ (d) states that any provisions that differ from this Agreement are offered by you alone and not PayPal; and
24
+
25
+ (e) states that the Software is available from you or PayPal and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
26
+
27
+ 2. DISCLAIMER OF WARRANTY
28
+ PAYPAL LICENSES THE SOFTWARE AND DOCUMENTATION TO YOU ONLY ON AN "AS IS" BASIS WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. PAYPAL MAKES NO WARRANTY THAT THE SOFTWARE OR DOCUMENTATION WILL BE ERROR-FREE. Each user of the Software or Documentation is solely responsible for determining the appropriateness of using and distributing the Software and Documentation and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs, or equipment, and unavailability or interruption of operations. Use of the Software and Documentation is made with the understanding that PayPal will not provide you with any technical or customer support or maintenance. Some states or jurisdictions do not allow the exclusion of implied warranties or limitations on how long an implied warranty may last, so the above limitations may not apply to you. To the extent permissible, any implied warranties are limited to ninety (90) days.
29
+
30
+
31
+ 3. LIMITATION OF LIABILITY
32
+ PAYPAL AND ITS SUPPLIERS SHALL NOT BE LIABLE FOR LOSS OR DAMAGE ARISING OUT OF THIS AGREEMENT OR FROM THE USE OF THE SOFTWARE OR DOCUMENTATION. IN NO EVENT WILL PAYPAL OR ITS SUPPLIERS BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES INCLUDING LOST PROFITS, LOST SAVINGS, COSTS, FEES, OR EXPENSES OF ANY KIND ARISING OUT OF ANY PROVISION OF THIS AGREEMENT OR THE USE OR THE INABILITY TO USE THE SOFTWARE OR DOCUMENTATION, HOWEVER CAUSED AND UNDER ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. PAYPAL'S AGGREGATE LIABILITY AND THAT OF ITS SUPPLIERS UNDER OR IN CONNECTION WITH THIS AGREEMENT SHALL BE LIMITED TO THE AMOUNT PAID BY YOU FOR THE SOFTWARE AND DOCUMENTATION.
33
+
34
+ 4. TRADEMARK USAGE
35
+ PayPal is a trademark PayPal, Inc. in the United States and other countries. Such trademarks may not be used to endorse or promote any product unless expressly permitted under separate agreement with PayPal.
36
+
37
+ 5. TERM
38
+ Your rights under this Agreement shall terminate if you fail to comply with any of the material terms or conditions of this Agreement and do not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all your rights under this Agreement terminate, you agree to cease use and distribution of the Software and Documentation as soon as reasonably practicable.
39
+
40
+ 6. GOVERNING LAW AND JURISDICTION. This Agreement is governed by the statutes and laws of the State of California, without regard to the conflicts of law principles thereof. If any part of this Agreement is found void and unenforceable, it will not affect the validity of the balance of the Agreement, which shall remain valid and enforceable according to its terms. Any dispute arising out of or related to this Agreement shall be brought in the courts of Santa Clara County, California, USA.
41
+
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/README.md ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ PayPal PHP Adaptive Payments SDK
3
+ ===============================
4
+
5
+ Prerequisites
6
+ -------------
7
+
8
+ PayPal's PHP Adaptive Payments SDK requires
9
+
10
+ * PHP 5.2 and above with curl extension enabled
11
+
12
+
13
+ Using the SDK
14
+ -------------
15
+
16
+ To use the SDK,
17
+
18
+ * Copy the config and lib folders into your project.
19
+ * Make sure that the lib folder in your project is available in PHP's include path
20
+ * Include the services\AdaptivePayments\AdaptivePaymentsService.php file in your code.
21
+ * Create a service wrapper object
22
+ * Create a request object as per your project's needs. All the API request and response classes are available in services\AdaptivePayments\AdaptivePaymentsService.php
23
+ * Invoke the appropriate method on the request object.
24
+
25
+ For example,
26
+
27
+ require_once('services/AdaptivePayments/AdaptivePaymentsService.php');
28
+ require_once('PPLoggingManager.php');
29
+
30
+ $payRequest = new PayRequest($requestEnvelope, $_POST['actionType'], $_POST['cancelUrl'], $_POST['currencyCode'], $receiverList, $_POST['returnUrl']);
31
+ // Add optional params
32
+ if($_POST["feesPayer"] != "") {
33
+ $payRequest->feesPayer = $_POST["feesPayer"];
34
+ }
35
+ ......
36
+
37
+ $service = new AdaptivePaymentsService();
38
+ $response = $service->Pay($payRequest);
39
+
40
+ $ack = strtoupper($response->responseEnvelope->ack);
41
+
42
+ if($ack == 'SUCCESS') {
43
+ // Success
44
+ }
45
+
46
+
47
+
48
+ SDK Configuration
49
+ -----------------
50
+
51
+ replace the API credential in config/sdk_config.ini . You can use the configuration file to configure
52
+
53
+ * (Multiple) API account credentials.
54
+ * Service endpoint and other HTTP connection parameters
55
+
56
+
57
+ Please refer to the sample config file provided with this bundle.
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/build.xml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project name="PayPal_PHP_SDK" default="build">
3
+
4
+
5
+ <condition property="PHPUNIT_PATH" value="phpunit.bat" else="phpunit">
6
+ <os family="windows"/>
7
+ </condition>
8
+
9
+ <target name="clean">
10
+ <delete dir="${basedir}/build"/>
11
+ </target>
12
+
13
+
14
+ <target name="phpunit">
15
+ <mkdir dir="tests/reports/"/>
16
+ <exec dir="${basedir}" executable="${PHPUNIT_PATH}" failonerror="true">
17
+ <arg
18
+ line="--testdox --include-path lib --log-junit tests\reports\phpunit.xml tests"/>
19
+ </exec>
20
+ </target>
21
+
22
+
23
+ <target name="build" depends="clean, phpunit"/>
24
+ </project>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/config/cert_key.pem ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIICXgIBAAKBgQCaGw566OIaeIsrp2tyzfwUtwapk2aPgL9N8oOoPmTmA/bqhqF8
3
+ 2X43EB2zZF1HY35kPp3L5rZSjqraEZz5j7W4DkXMS286wLnaoh02sVWbbXlLcZ/v
4
+ sAQzNgi1s2raOWonkcbAIAyhjVoGQjpuCn7y9YNgQfpZkgrh/R5ig8obQwIDAQAB
5
+ AoGBAI/YrZ2BAHzhBFdNQXi6WZEkfu2PD27oKKojs006YIhsLvEflmGpyqyvOGoZ
6
+ RxC6CGKeKEEKLCnHzicbxcEVqfKfOxrXkym3ldqBaYubL1OU62biDRtZZdIpG3TE
7
+ gBDRtU8gPQv1ykqY9KqdeORy8vu0lW9Zx9/4ccW126HLt/kxAkEAzF9NKltIc+gu
8
+ S79lzerE8qngiUSc/ccb1ssLj4v4Lf90HNeJ4oSQEikuN32GjPVrUpQYpC4fjcET
9
+ KmqE7k1V3wJBAMEJB3VRToeTQKhWet8JQPkcfES3B+l7NCauUcysSI5XZ9kVflLu
10
+ c5vzznMooRpcNtjJwDmkcnW0lhIQH/DKvx0CQQCWHJXoO54vDGYc2xuisQMyHha/
11
+ nHcXbA0FqqP2Lt/+oTifCq3LhITx4e+BcKDInmbTA9ZJmVsx2pQCPrUe+AzPAkA/
12
+ OU7ZDPVUkFU4DYMW8/f033CQLQaJYVH2bVfbWn41KMmZn2GNlg4FgTgYHbGOaa+J
13
+ F6M+/e6DQM96QQ/FFRK9AkEApx1r0di+W2ibrTANnk6QjQbva9JyOztI+Avg86X5
14
+ swB44tEsRImOTNsE6nfE/215AxjgI1vdn6uU4P8GIKfxnw==
15
+ -----END RSA PRIVATE KEY-----
16
+ -----BEGIN CERTIFICATE-----
17
+ MIICiDCCAfGgAwIBAgIDD/WUMA0GCSqGSIb3DQEBBQUAMIGfMQswCQYDVQQGEwJV
18
+ UzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMIU2FuIEpvc2UxFTATBgNV
19
+ BAoTDFBheVBhbCwgSW5jLjEWMBQGA1UECxQNc2FuZGJveF9jZXJ0czEbMBkGA1UE
20
+ AxQSc2FuZGJveF9jYW1lcmNoYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwu
21
+ Y29tMB4XDTExMDUwMjA1MDQ0NFoXDTIxMDQyOTA1MDQ0NFowYzElMCMGA1UEAxQc
22
+ Y2VydHVzZXJfYml6X2FwaTEucGF5cGFsLmNvbTEPMA0GA1UEChMGQm9uem9wMQ8w
23
+ DQYDVQQHEwZBdXN0aW4xCzAJBgNVBAgTAlRYMQswCQYDVQQGEwJVUzCBnzANBgkq
24
+ hkiG9w0BAQEFAAOBjQAwgYkCgYEAmhsOeujiGniLK6drcs38FLcGqZNmj4C/TfKD
25
+ qD5k5gP26oahfNl+NxAds2RdR2N+ZD6dy+a2Uo6q2hGc+Y+1uA5FzEtvOsC52qId
26
+ NrFVm215S3Gf77AEMzYItbNq2jlqJ5HGwCAMoY1aBkI6bgp+8vWDYEH6WZIK4f0e
27
+ YoPKG0MCAwEAAaMNMAswCQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOBgQBj6xWw
28
+ AumLzSodCWyocPcyKSooNa7wgJKzaVrf0Kxz2QBesKpsfe9UN3Dj04016FIUbkRI
29
+ 4qLJIkKHyeQRU9hvJ78tU7OeykDEVqlHAEE/Z4c5EIs6l9x60VqOpAjnaqX/9Jty
30
+ jXhqpINjolTh6D5jq8y4FX5krKqIYBCNDHM+cQ==
31
+ -----END CERTIFICATE-----
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/config/sdk_config.ini ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;Account credentials
2
+ [Account]
3
+ acct1.UserName = jb-us-seller_api1.paypal.com
4
+ acct1.Password = WX4WTU3S8MY44S7F
5
+ acct1.Signature = AFcWxV21C7fd0v3bYYYRCpSSRl31A7yDhhsPUU2XhtMoZXsWHFxu-RWy
6
+ acct1.AppId = APP-80W284485P519543T
7
+
8
+ ;Connection Information
9
+ [Http]
10
+ http.ConnectionTimeOut = 30
11
+ http.Retry = 5
12
+ ;http.Proxy
13
+
14
+ ;Service Configuration
15
+ [Service]
16
+ ; NOTE: Do not change the service binding configuration.
17
+ service.Binding = NV
18
+ service.EndPoint = "https://svcs.sandbox.paypal.com/"
19
+ service.RedirectURL = "https://www.sandbox.paypal.com/webscr&cmd="
20
+ service.DevCentralURL = "https://developer.paypal.com"
21
+
22
+ ;Logging Information
23
+ [Log]
24
+ log.FileName = PayPal.log
25
+ log.LogLevel = INFO
26
+ log.LogEnabled = true
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/IPPCredential.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Base class that represents API credentials
5
+ */
6
+ abstract class IPPCredential
7
+ {
8
+ /**
9
+ * Application Id that uniquely identifies the application
10
+ * The application Id is issued by PayPal.
11
+ * Test application Ids are available for the sandbox environment
12
+ * @var string
13
+ */
14
+ protected $applicationId;
15
+
16
+ /**
17
+ * API username
18
+ * @var string
19
+ */
20
+ protected $userName;
21
+
22
+ /**
23
+ * API password
24
+ * @var string
25
+ */
26
+ protected $password;
27
+
28
+ protected abstract function validate();
29
+
30
+ public function __construct( $userName, $password, $applicationId )
31
+ {
32
+ $this->userName = $userName;
33
+ $this->password = $password;
34
+ $this->applicationId = $applicationId;
35
+ }
36
+
37
+ public function getApplicationId()
38
+ {
39
+ return $this->applicationId;
40
+ }
41
+
42
+ public function getUserName()
43
+ {
44
+ return $this->userName;
45
+ }
46
+
47
+ public function getPassword()
48
+ {
49
+ return $this->password;
50
+ }
51
+ }
52
+
53
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPAPIService.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once 'PPCredentialManager.php';
3
+ require_once 'PPConnectionManager.php';
4
+ require_once 'PPObjectTransformer.php';
5
+ require_once 'PPLoggingManager.php';
6
+ require_once 'PPUtils.php';
7
+ require_once 'PPAuthenticationManager.php';
8
+
9
+ class PPAPIService
10
+ {
11
+ public $endpoint;
12
+ public $serviceName;
13
+ private $logger;
14
+
15
+ public function __construct( $serviceName = "" )
16
+ {
17
+ $this->serviceName = $serviceName;
18
+ $config = PPConfigManager::getInstance();
19
+ $this->endpoint = $config->get( 'service.EndPoint' );
20
+ $this->logger = new PPLoggingManager( __CLASS__ );
21
+ }
22
+
23
+ public function setServiceName( $serviceName )
24
+ {
25
+ $this->serviceName = $serviceName;
26
+ }
27
+
28
+
29
+ public function makeRequest( $apiMethod, $params, $apiUsername = null, $accessToken = null, $tokenSecret = null )
30
+ {
31
+
32
+ $authentication = new PPAuthenticationManager();
33
+ $connectionMgr = PPConnectionManager::getInstance();
34
+ $connection = $connectionMgr->getConnection();
35
+
36
+ $credMgr = PPCredentialManager::getInstance();
37
+ // $apiUsernam is optional, if null the default account in congif file is taken
38
+ $apIPPCredential = $credMgr->getCredentialObject( $apiUsername );
39
+ $config = PPConfigManager::getInstance();
40
+ if ( $config->get( 'service.Binding' ) == 'SOAP' ) {
41
+ $url = $this->endpoint;
42
+ if ( isset( $accessToken ) && isset( $tokenSecret ) ) {
43
+ $headers = $authentication->getPayPalHeaders( $apIPPCredential, $connection, $accessToken, $tokenSecret, $url );
44
+ } else {
45
+ $headers = null;
46
+ }
47
+ $params = $authentication->appendSoapHeader( $params, $apIPPCredential, $connection, $accessToken, $tokenSecret, $url );
48
+ } else {
49
+ $url = $this->endpoint . $this->serviceName . '/' . $apiMethod;
50
+ $headers = $authentication->getPayPalHeaders( $apIPPCredential, $connection, $accessToken, $tokenSecret, $url );
51
+ }
52
+
53
+
54
+ $this->logger->info( "Request: $params" );
55
+ $response = $connection->execute( $url, $params, $headers );
56
+ $this->logger->info( "Response: $response" );
57
+
58
+ return $response;
59
+ }
60
+
61
+
62
+ }
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPAuthenticationManager.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once 'IPPCredential.php';
3
+ require_once 'PPConfigManager.php';
4
+ require_once 'PPSignatureCredential.php';
5
+ require_once 'PPCertificateCredential.php';
6
+ require_once 'exceptions/PPInvalidCredentialException.php';
7
+ require_once 'auth/PPAuth.php';
8
+
9
+ class PPAuthenticationManager
10
+ {
11
+ public function getPayPalHeaders( $apiCred, $connection, $accessToken = null, $tokenSecret = null, $url = null )
12
+ {
13
+ $config = PPConfigManager::getInstance();
14
+
15
+ if ( isset( $accessToken ) && isset( $tokenSecret ) ) {
16
+ $headers_arr[ ] = "X-PAYPAL-AUTHORIZATION: " . $this->generateAuthString( $apiCred, $accessToken, $tokenSecret, $url );
17
+ //$headers_arr[] = "CLIENT-AUTH: No cert";
18
+ } // Add headers required for service authentication
19
+ else if ( $apiCred instanceof PPSignatureCredential ) {
20
+ $headers_arr[ ] = "X-PAYPAL-SECURITY-USERID: " . $apiCred->getUserName();
21
+ $headers_arr[ ] = "X-PAYPAL-SECURITY-PASSWORD: " . $apiCred->getPassword();
22
+ $headers_arr[ ] = "X-PAYPAL-SECURITY-SIGNATURE: " . $apiCred->getSignature();
23
+ } else if ( $apiCred instanceof PPCertificateCredential ) {
24
+
25
+ $headers_arr[ ] = "X-PAYPAL-SECURITY-USERID: " . $apiCred->getUserName();
26
+ $headers_arr[ ] = "X-PAYPAL-SECURITY-PASSWORD: " . $apiCred->getPassword();
27
+ $connection->setSSLCert( $apiCred->getCertificatePath(), $apiCred->getPassPhrase() );
28
+ }
29
+
30
+ // Add other headers
31
+ $headers_arr[ ] = "X-PAYPAL-APPLICATION-ID: " . $apiCred->getApplicationId();
32
+ $headers_arr[ ] = "X-PAYPAL-REQUEST-DATA-FORMAT: " . $config->get( 'service.Binding' );
33
+ $headers_arr[ ] = "X-PAYPAL-RESPONSE-DATA-FORMAT: " . $config->get( 'service.Binding' );
34
+ $headers_arr[ ] = "X-PAYPAL-DEVICE-IPADDRESS: " . PPUtils::getLocalIPAddress();
35
+ $headers_arr[ ] = "X-PAYPAL-REQUEST-SOURCE: " . PPUtils::getRequestSource();
36
+
37
+ return $headers_arr;
38
+ }
39
+
40
+ public function appendSoapHeader( $payLoad, $apiCred, $connection, $accessToken = null, $tokenSecret = null, $url = null )
41
+ {
42
+ $soapHeader = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn=\"urn:ebay:api:PayPalAPI\" xmlns:ebl=\"urn:ebay:apis:eBLBaseComponents\" xmlns:cc=\"urn:ebay:apis:CoreComponentTypes\" xmlns:ed=\"urn:ebay:apis:EnhancedDataTypes\">";
43
+
44
+ if ( isset( $accessToken ) && isset( $tokenSecret ) ) {
45
+ $soapHeader .= "<soapenv:Header>";
46
+ $soapHeader .= "<urn:RequesterCredentials/>";
47
+ $soapHeader .= "</soapenv:Header>";
48
+ } else if ( $apiCred instanceof PPSignatureCredential ) {
49
+ $soapHeader .= "<soapenv:Header>";
50
+ $soapHeader .= "<urn:RequesterCredentials>";
51
+ $soapHeader .= "<ebl:Credentials>";
52
+ $soapHeader .= "<ebl:Username>" . $apiCred->getUserName() . "</ebl:Username>";
53
+ $soapHeader .= "<ebl:Password>" . $apiCred->getPassword() . "</ebl:Password>";
54
+ $soapHeader .= "<ebl:Signature>" . $apiCred->getSignature() . "</ebl:Signature>";
55
+ $soapHeader .= "</ebl:Credentials>";
56
+ $soapHeader .= "</urn:RequesterCredentials>";
57
+ $soapHeader .= "</soapenv:Header>";
58
+ } else if ( $apiCred instanceof PPCertificateCredential ) {
59
+ $soapHeader .= "<soapenv:Header>";
60
+ $soapHeader .= "<urn:RequesterCredentials>";
61
+ $soapHeader .= "<ebl:Credentials>";
62
+ $soapHeader .= "<ebl:Username>" . $apiCred->getUserName() . "</ebl:Username>";
63
+ $soapHeader .= "<ebl:Password>" . $apiCred->getPassword() . "</ebl:Password>";
64
+ $soapHeader .= "</ebl:Credentials>";
65
+ $soapHeader .= "</urn:RequesterCredentials>";
66
+ $soapHeader .= "</soapenv:Header>";
67
+ $connection->setSSLCert( $apiCred->getCertificatePath(), $apiCred->getPassPhrase() );
68
+ }
69
+ $soapHeader .= "<soapenv:Body>";
70
+ $soapHeader .= $payLoad;
71
+ $soapHeader .= "</soapenv:Body>";
72
+ $soapHeader .= "</soapenv:Envelope>";
73
+
74
+ return $soapHeader;
75
+
76
+ }
77
+
78
+ private function generateAuthString( $apiCred, $accessToken, $tokenSecret, $endpoint )
79
+ {
80
+ $key = $apiCred->getUserName();
81
+ $secret = $apiCred->getPassword();
82
+ $auth = new AuthSignature();
83
+ $response = $auth->genSign( $key, $secret, $accessToken, $tokenSecret, 'POST', $endpoint );
84
+ $authString = "token=" . $accessToken . ",signature=" . $response[ 'oauth_signature' ] . ",timestamp=" . $response[ 'oauth_timestamp' ];
85
+
86
+ return $authString;
87
+ }
88
+
89
+ }
90
+
91
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPBaseService.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once 'PPAPIService.php';
3
+
4
+
5
+ class PPBaseService
6
+ {
7
+
8
+ private $serviceName;
9
+
10
+ /*
11
+ * Setters and getters for Third party authentication (Permission Services)
12
+ */
13
+ protected $accessToken;
14
+ protected $tokenSecret;
15
+ protected $lastRequest;
16
+ protected $lastResponse;
17
+
18
+ public function getLastRequest()
19
+ {
20
+ return $this->lastRequest;
21
+ }
22
+
23
+ public function setLastRequest( $lastRqst )
24
+ {
25
+ $this->lastRequest = $lastRqst;
26
+ }
27
+
28
+ public function getLastResponse()
29
+ {
30
+ return $this->lastResponse;
31
+ }
32
+
33
+ public function setLastResponse( $lastRspns )
34
+ {
35
+ $this->lastResponse = $lastRspns;
36
+ }
37
+
38
+ public function getAccessToken()
39
+ {
40
+ return $this->accessToken;
41
+ }
42
+
43
+ public function setAccessToken( $accessToken )
44
+ {
45
+ $this->accessToken = $accessToken;
46
+ }
47
+
48
+ public function getTokenSecret()
49
+ {
50
+ return $this->tokenSecret;
51
+ }
52
+
53
+ public function setTokenSecret( $tokenSecret )
54
+ {
55
+ $this->tokenSecret = $tokenSecret;
56
+ }
57
+
58
+ public function __construct( $serviceName )
59
+ {
60
+ $this->serviceName = $serviceName;
61
+ }
62
+
63
+ public function getServiceName()
64
+ {
65
+ return $this->serviceName;
66
+ }
67
+
68
+ public function call( $method, $requestObject, $apiUsername = null )
69
+ {
70
+ $params = $this->marshall( $requestObject );
71
+ $service = new PPAPIService();
72
+ $service->setServiceName( $this->serviceName );
73
+
74
+ $this->lastRequest = $params;
75
+ $this->lastResponse = $service->makeRequest( $method, $params, $apiUsername, $this->accessToken, $this->tokenSecret );
76
+
77
+ return $this->lastResponse;
78
+ }
79
+
80
+ private function marshall( $object )
81
+ {
82
+ $transformer = new PPObjectTransformer();
83
+
84
+ return $transformer->toString( $object );
85
+ }
86
+ }
87
+
88
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPCertificateCredential.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once 'IPPCredential.php';
3
+ require_once 'PPConfigManager.php';
4
+ require_once 'exceptions/PPMissingCredentialException.php';
5
+
6
+ class PPCertificateCredential extends IPPCredential
7
+ {
8
+
9
+ private $certificatePath;
10
+
11
+ private $passPhrase;
12
+
13
+ public function __construct( $userName, $password, $certPath, $appId, $passPhrase )
14
+ {
15
+ parent::__construct( $userName, $password, $appId );
16
+ $this->certificatePath = $certPath;
17
+ $this->passPhrase = $passPhrase;
18
+ $this->validate();
19
+ }
20
+
21
+ public function validate()
22
+ {
23
+
24
+ if ( $this->userName == null || $this->userName == "" ) {
25
+ throw new PPMissingCredentialException( "username cannot be empty" );
26
+ }
27
+ if ( $this->password == null || $this->password == "" ) {
28
+ throw new PPMissingCredentialException( "password cannot be empty" );
29
+ }
30
+ if ( $this->certificatePath == null || $this->certificatePath == "" ) {
31
+ throw new PPMissingCredentialException( "certificate cannot be empty" );
32
+ }
33
+ if ( $this->passPhrase == null || $this->passPhrase == "" ) {
34
+ throw new PPMissingCredentialException( "passphrase cannot be empty" );
35
+ }
36
+ if ( $this->applicationId == null || $this->applicationId == "" ) {
37
+ throw new PPMissingCredentialException( "applicationId cannot be empty" );
38
+ }
39
+ }
40
+
41
+ public function getUserName()
42
+ {
43
+ return $this->userName;
44
+ }
45
+
46
+ public function getPassword()
47
+ {
48
+ return $this->password;
49
+ }
50
+
51
+ public function getCertificatePath()
52
+ {
53
+ if ( realpath( $this->certificatePath ) ) {
54
+ return realpath( $this->certificatePath );
55
+ } else {
56
+ return realpath( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . ".." . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . $this->certificatePath );
57
+ }
58
+ }
59
+
60
+ public function getPassPhrase()
61
+ {
62
+ return $this->passPhrase;
63
+ }
64
+
65
+ public function getApplicationId()
66
+ {
67
+ return $this->applicationId;
68
+ }
69
+
70
+ }
71
+
72
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPConfigManager.php ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PPConfigManager loads the SDK configuration file and
4
+ * hands out appropriate config params to other classes
5
+ */
6
+ require_once 'exceptions/PPConfigurationException.php';
7
+
8
+ class PPConfigManager
9
+ {
10
+
11
+ private $config;
12
+ /**
13
+ *
14
+ *
15
+ * @var PPConfigManager
16
+ */
17
+ private static $instance;
18
+
19
+ private function __construct()
20
+ {
21
+ $configFile = dirname( __FILE__ ) . DIRECTORY_SEPARATOR . ".."
22
+ . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "sdk_config.ini";
23
+ $this->load( $configFile );
24
+ }
25
+
26
+ // create singleton object for PPConfigManager
27
+ public static function getInstance()
28
+ {
29
+ if ( !isset( self::$instance ) ) {
30
+ self::$instance = new PPConfigManager();
31
+ }
32
+
33
+ return self::$instance;
34
+ }
35
+
36
+ //used to load the file
37
+ private function load( $fileName )
38
+ {
39
+ if ( class_exists( 'Woocommerce' ) ) {
40
+ global $woocommerce;
41
+ $gateways = $woocommerce->payment_gateways->payment_gateways();
42
+ $settings = $gateways[ 'paypalap' ]->settings;
43
+
44
+ $mode = $settings[ 'sandbox_enabled' ];
45
+
46
+ $this->config = array(
47
+ 'acct1.UserName' => $mode == 'yes' ? $settings[ 'username' ] : $settings[ 'username_live' ],
48
+ 'acct1.Password' => $mode == 'yes' ? $settings[ 'password' ] : $settings[ 'password_live' ],
49
+ 'acct1.Signature' => $mode == 'yes' ? $settings[ 'signature' ] : $settings[ 'signature_live' ],
50
+ 'acct1.AppId' => $mode == 'yes' ? 'APP-80W284485P519543T' : $settings[ 'app_id' ],
51
+
52
+ 'service.Binding' => 'NV',
53
+ 'service.EndPoint' => $mode == 'yes' ? 'https://svcs.sandbox.paypal.com/' : 'https://svcs.paypal.com/',
54
+ 'service.RedirectURL' => $mode == 'yes' ? 'https://sandbox.paypal.com/webscr&cmd=' : 'https://paypal.com/webscr&cmd=',
55
+ 'service.DevCentralURL' => 'https://developer.paypal.com',
56
+ 'http.ConnectionTimeOut' => '30',
57
+ 'http.Retry' => '5',
58
+ 'log.FileName' => 'PayPal.log',
59
+ 'log.LogLevel' => 'INFO',
60
+ 'log.LogEnabled' => $settings[ 'logging_enabled' ] == 'yes' ? 'true' : 'false',
61
+ );
62
+ } else {
63
+ $this->config = @parse_ini_file( $fileName );
64
+ }
65
+
66
+ if ( $this->config == null || count( $this->config ) == 0 ) {
67
+ throw new PPConfigurationException( "Config file $fileName not found", "303" );
68
+ }
69
+ }
70
+
71
+ /**
72
+ * simple getter for configuration params
73
+ * If an exact match for key is not found,
74
+ * does a "contains" search on the key
75
+ */
76
+ public function get( $searchKey )
77
+ {
78
+
79
+ if ( array_key_exists( $searchKey, $this->config ) ) {
80
+ return $this->config[ $searchKey ];
81
+ } else {
82
+ $arr = array();
83
+ foreach ( $this->config as $k => $v ) {
84
+ if ( strstr( $k, $searchKey ) ) {
85
+ $arr[ $k ] = $v;
86
+ }
87
+ }
88
+
89
+ return $arr;
90
+ }
91
+
92
+ }
93
+
94
+ /**
95
+ * Utility method for handling account configuration
96
+ * return config key corresponding to the API userId passed in
97
+ *
98
+ * If $userId is null, returns config keys corresponding to
99
+ * all configured accounts
100
+ */
101
+ public function getIniPrefix( $userId = null )
102
+ {
103
+
104
+ if ( $userId == null ) {
105
+ $arr = array();
106
+ foreach ( $this->config as $key => $value ) {
107
+ $pos = strpos( $key, '.' );
108
+ if ( strstr( $key, "acct" ) ) {
109
+ $arr[ ] = substr( $key, 0, $pos );
110
+ }
111
+ }
112
+
113
+ return array_unique( $arr );
114
+ } else {
115
+ $iniPrefix = array_search( $userId, $this->config );
116
+ $pos = strpos( $iniPrefix, '.' );
117
+ $acct = substr( $iniPrefix, 0, $pos );
118
+
119
+ return $acct;
120
+ }
121
+ }
122
+ }
123
+
124
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPConnectionManager.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once 'PPHttpConnection.php';
3
+ require_once 'PPConfigManager.php';
4
+ class PPConnectionManager
5
+ {
6
+ /**
7
+ * reference to singleton instance
8
+ * @var PPConnectionManager
9
+ */
10
+ private static $instance;
11
+
12
+ private function __construct()
13
+ {
14
+ }
15
+
16
+ public static function getInstance()
17
+ {
18
+ if ( self::$instance == null ) {
19
+ self::$instance = new PPConnectionManager();
20
+ }
21
+
22
+ return self::$instance;
23
+ }
24
+
25
+ /**
26
+ * This function returns a new PPHttpConnection object
27
+ */
28
+ public function getConnection()
29
+ {
30
+
31
+ $connection = new PPHttpConnection();
32
+
33
+ $configMgr = PPConfigManager::getInstance();
34
+ if ( ( $configMgr->get( "http.ConnectionTimeOut" ) ) ) {
35
+ $connection->setHttpTimeout( $configMgr->get( "http.ConnectionTimeOut" ) );
36
+ }
37
+ if ( $configMgr->get( "http.Proxy" ) ) {
38
+ $connection->setHttpProxy( $configMgr->get( "http.Proxy" ) );
39
+ }
40
+ if ( $configMgr->get( "http.Retry" ) ) {
41
+ $retry = $configMgr->get( "http.Retry" );
42
+ $connection->setHttpRetry( $retry );
43
+ }
44
+
45
+ return $connection;
46
+ }
47
+
48
+ }
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPCredentialManager.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once 'IPPCredential.php';
3
+ require_once 'PPConfigManager.php';
4
+ require_once 'PPSignatureCredential.php';
5
+ require_once 'PPCertificateCredential.php';
6
+ require_once 'exceptions/PPInvalidCredentialException.php';
7
+
8
+ class PPCredentialManager
9
+ {
10
+
11
+ private static $instance;
12
+ //hashmap to contain credentials for accounts.
13
+ private $credentialHashmap = array();
14
+ /**
15
+ * Contains the API username of the default account to use
16
+ * when authenticating API calls.
17
+ * @var string
18
+ */
19
+ private $defaultAccountName;
20
+
21
+ /*
22
+ * Constructor initialize credential for multiple accounts specified in property file.
23
+ */
24
+ private function __construct()
25
+ {
26
+ try {
27
+ $this->initCredential();
28
+ } catch ( Exception $e ) {
29
+ $this->credentialHashmap = array();
30
+ throw $e;
31
+ }
32
+ }
33
+
34
+ /*
35
+ * Create singleton instance for this class.
36
+ */
37
+ public static function getInstance()
38
+ {
39
+ if ( !isset( self::$instance ) ) {
40
+ self::$instance = new PPCredentialManager();
41
+ }
42
+
43
+ return self::$instance;
44
+ }
45
+
46
+ /*
47
+ * Load credentials for multiple accounts, with priority given to Signature credential.
48
+ */
49
+ private function initCredential()
50
+ {
51
+ $configMgr = PPConfigManager::getInstance();
52
+ $suffix = 1;
53
+ $prefix = "acct";
54
+
55
+ $credArr = $configMgr->get( $prefix );
56
+ $arrayPartKeys = $configMgr->getIniPrefix();
57
+ if ( count( $arrayPartKeys ) == 0 )
58
+ throw new MissingCredentialException( "No valid API accounts have been configured" );
59
+
60
+ while ( in_array( $prefix . $suffix, $arrayPartKeys ) ) {
61
+
62
+ if ( isset( $credArr[ $prefix . $suffix . ".Signature" ] )
63
+ && $credArr[ $prefix . $suffix . ".Signature" ] != null && $credArr[ $prefix . $suffix . ".Signature" ] != ""
64
+ ) {
65
+
66
+ $userName = isset( $credArr[ $prefix . $suffix . '.UserName' ] ) ? $credArr[ $prefix . $suffix . '.UserName' ] : "";
67
+ $password = isset( $credArr[ $prefix . $suffix . '.Password' ] ) ? $credArr[ $prefix . $suffix . '.Password' ] : "";
68
+ $signature = isset( $credArr[ $prefix . $suffix . '.Signature' ] ) ? $credArr[ $prefix . $suffix . '.Signature' ] : "";
69
+ $appId = isset( $credArr[ $prefix . $suffix . '.AppId' ] ) ? $credArr[ $prefix . $suffix . '.AppId' ] : "";
70
+ $this->credentialHashmap[ $userName ] = new PPSignatureCredential( $userName, $password, $signature, $appId );
71
+
72
+ } elseif ( isset( $credArr[ $prefix . $suffix . ".CertPath" ] )
73
+ && $credArr[ $prefix . $suffix . ".CertPath" ] != null && $credArr[ $prefix . $suffix . ".CertPath" ] != ""
74
+ ) {
75
+
76
+ $userName = isset( $credArr[ $prefix . $suffix . '.UserName' ] ) ? $credArr[ $prefix . $suffix . '.UserName' ] : "";
77
+ $password = isset( $credArr[ $prefix . $suffix . '.Password' ] ) ? $credArr[ $prefix . $suffix . '.Password' ] : "";
78
+ $passPhrase = isset( $credArr[ $prefix . $suffix . '.CertKey' ] ) ? $credArr[ $prefix . $suffix . '.CertKey' ] : "";
79
+ $certPath = isset( $credArr[ $prefix . $suffix . '.CertPath' ] ) ? $credArr[ $prefix . $suffix . '.CertPath' ] : "";
80
+ $appId = isset( $credArr[ $prefix . $suffix . '.AppId' ] ) ? $credArr[ $prefix . $suffix . '.AppId' ] : "";
81
+ $this->credentialHashmap[ $userName ] = new PPCertificateCredential( $userName, $password, $certPath, $appId, $passPhrase );
82
+
83
+ }
84
+ if ( $this->defaultAccountName == null )
85
+ $this->defaultAccountName = $credArr[ $prefix . $suffix . '.UserName' ];
86
+ $suffix++;
87
+ }
88
+
89
+ }
90
+
91
+ /*
92
+ * Obtain Credential Object based on UserId provided.
93
+ */
94
+ public function getCredentialObject( $userId = null )
95
+ {
96
+
97
+ if ( $userId == null )
98
+ $credObj = $this->credentialHashmap[ $this->defaultAccountName ];
99
+ else if ( array_key_exists( $userId, $this->credentialHashmap ) )
100
+ $credObj = $this->credentialHashmap[ $userId ];
101
+
102
+ if ( empty( $credObj ) ) {
103
+ throw new PPInvalidCredentialException( "Invalid userId $userId" );
104
+ }
105
+
106
+ return $credObj;
107
+ }
108
+
109
+
110
+ public function __clone()
111
+ {
112
+ trigger_error( 'Clone is not allowed.', E_USER_ERROR );
113
+ }
114
+
115
+ }
116
+
117
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPHttpConnection.php ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once 'exceptions/PPConnectionException.php';
4
+ require_once 'exceptions/PPConfigurationException.php';
5
+ require_once 'PPLoggingManager.php';
6
+ /**
7
+ * A wrapper class based on the curl extension.
8
+ * Requires the PHP curl module to be enabled.
9
+ * See for full requirements the PHP manual: http://php.net/curl
10
+ */
11
+
12
+
13
+ class PPHttpConnection
14
+ {
15
+
16
+ const HTTP_GET = 'GET';
17
+ const HTTP_POST = 'POST';
18
+
19
+ /**
20
+ * curl options to be set for the request
21
+ */
22
+ private $curlOpt = array();
23
+
24
+ /**
25
+ * Number of times a retry must be attempted on getting an HTTP error
26
+ * @var integer
27
+ */
28
+ private $retry;
29
+
30
+ /**
31
+ * HTTP status codes for which a retry must be attempted
32
+ */
33
+ private static $retryCodes = array( '401', '403', '404', );
34
+
35
+ private $logger;
36
+
37
+
38
+ /**
39
+ * Some default options for curl
40
+ * These are typically overridden by PPConnectionManager
41
+ */
42
+ public static $DEFAULT_CURL_OPTS = array(
43
+ CURLOPT_CONNECTTIMEOUT => 10,
44
+ CURLOPT_RETURNTRANSFER => true,
45
+ CURLOPT_TIMEOUT => 60, // maximum number of seconds to allow cURL functions to execute
46
+ CURLOPT_USERAGENT => 'PayPal-PHP-SDK',
47
+ CURLOPT_POST => 1,
48
+ CURLOPT_HTTPHEADER => array(),
49
+ CURLOPT_SSL_VERIFYHOST => 1,
50
+ CURLOPT_SSL_VERIFYPEER => 2
51
+ );
52
+
53
+ public function __construct()
54
+ {
55
+ if ( !function_exists( "curl_init" ) ) {
56
+ throw new PPConfigurationException( "Curl module is not available on this system" );
57
+ }
58
+ $this->curlOpt = self::$DEFAULT_CURL_OPTS;
59
+ $this->logger = new PPLoggingManager( __CLASS__ );
60
+ }
61
+
62
+ /**
63
+ * Set ssl parameters for certificate based client authentication
64
+ *
65
+ * @param string $certPath - path to client certificate file (PEM formatted file)
66
+ */
67
+ public function setSSLCert( $certPath, $passPhrase )
68
+ {
69
+ $this->curlOpt[ CURLOPT_SSLCERT ] = realpath( $certPath );
70
+ $this->curlOpt[ CURLOPT_SSLCERTPASSWD ] = $passPhrase;
71
+ }
72
+
73
+ /**
74
+ * Set connection timeout in seconds
75
+ *
76
+ * @param integer $timeout
77
+ */
78
+ public function setHttpTimeout( $timeout )
79
+ {
80
+ $this->curlOpt[ CURLOPT_CONNECTTIMEOUT ] = $timeout;
81
+ }
82
+
83
+ /**
84
+ * Set HTTP proxy information
85
+ *
86
+ * @param string $proxy
87
+ *
88
+ * @throws PPConfigurationException
89
+ */
90
+ public function setHttpProxy( $proxy )
91
+ {
92
+ $urlParts = parse_url( $proxy );
93
+ if ( $urlParts == false || !array_key_exists( "host", $urlParts ) )
94
+ throw new PPConfigurationException( "Invalid proxy configuration " . $proxy );
95
+
96
+ $this->curlOpt[ CURLOPT_PROXY ] = $urlParts[ "host" ];
97
+ if ( isset( $urlParts[ "port" ] ) )
98
+ $this->curlOpt[ CURLOPT_PROXY ] .= ":" . $urlParts[ "port" ];
99
+ if ( isset( $urlParts[ "user" ] ) )
100
+ $this->curlOpt[ URLOPT_PROXYUSERPWD ] = $urlParts[ "user" ] . ":" . $urlParts[ "pass" ];
101
+ }
102
+
103
+ public function setHttpHeaders( $headers )
104
+ {
105
+ $this->curlOpt[ CURLOPT_HTTPHEADER ] = $headers;
106
+ }
107
+
108
+ /**
109
+ * @param integer $retry
110
+ */
111
+ public function setHttpRetry( $retry )
112
+ {
113
+ $this->retry = $retry;
114
+ }
115
+
116
+ /**
117
+ * Executes an HTTP request
118
+ *
119
+ * @param string $url
120
+ * @param string $params query string OR POST content as a string
121
+ * @param array $headers array of HTTP headers to be added to existing headers
122
+ * @param string $method HTTP method (GET, POST etc) defaults to POST
123
+ *
124
+ * @throws PPConnectionException
125
+ */
126
+ public function execute( $url, $params, $headers = null, $method = null )
127
+ {
128
+
129
+ $ch = curl_init( $url );
130
+
131
+ $this->curlOpt[ CURLOPT_POSTFIELDS ] = $params;
132
+ $this->curlOpt[ CURLOPT_URL ] = $url;
133
+ $this->curlOpt[ CURLOPT_HEADER ] = false;
134
+ if ( isset( $headers ) ) {
135
+ $this->curlOpt[ CURLOPT_HTTPHEADER ] = array_merge( $this->curlOpt[ CURLOPT_HTTPHEADER ], $headers );
136
+ }
137
+ foreach ( $this->curlOpt[ CURLOPT_HTTPHEADER ] as $header ) {
138
+ //TODO: Strip out credentials when logging.
139
+ $this->logger->info( "Adding header $header" );
140
+ }
141
+ if ( isset( $method ) ) {
142
+ $this->curlOpt[ CURLOPT_CUSTOMREQUEST ] = $method;
143
+ }
144
+
145
+ // curl_setopt_array available only in PHP 5 >= 5.1.3
146
+ curl_setopt_array( $ch, $this->curlOpt );
147
+
148
+ $result = curl_exec( $ch );
149
+
150
+ if ( curl_errno( $ch ) == 60 ) {
151
+ $this->logger->info( "Invalid or no certificate authority found, retrying using bundled CA certs" );
152
+ curl_setopt( $ch, CURLOPT_CAINFO,
153
+ dirname( __FILE__ ) . '/cacert.pem' );
154
+ $result = curl_exec( $ch );
155
+ }
156
+ $httpStatus = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
157
+ $retries = 0;
158
+ if ( in_array( $httpStatus, self::$retryCodes ) && isset( $this->retry ) ) {
159
+ $this->logger->info( "Got $httpStatus response from server. Retrying" );
160
+
161
+ do {
162
+ $result = curl_exec( $ch );
163
+ $httpStatus = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
164
+
165
+ } while ( in_array( $httpStatus, self::$retryCodes ) && ++$retries < $this->retry );
166
+
167
+
168
+ }
169
+ if ( curl_errno( $ch ) ) {
170
+ $ex = new PPConnectionException( $url, curl_error( $ch ), curl_errno( $ch ) );
171
+ curl_close( $ch );
172
+ throw $ex;
173
+ }
174
+
175
+ curl_close( $ch );
176
+
177
+ if ( in_array( $httpStatus, self::$retryCodes ) ) {
178
+ throw new PPConnectionException( $url, "Retried " . $retries . " times, Http Response code " . $httpStatus );
179
+ }
180
+
181
+ return $result;
182
+ }
183
+
184
+ }
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPLoggingManager.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Simple Logging Manager.
5
+ * This does an error_log for now
6
+ * Potential frameworks to use are PEAR logger, log4php from Apache
7
+ */
8
+
9
+ class PPLoggingLevel
10
+ {
11
+
12
+ // FINE Logging Level
13
+ const FINE = 3;
14
+
15
+ // INFO Logging Level
16
+ const INFO = 2;
17
+
18
+ // WARN Logging Level
19
+ const WARN = 1;
20
+
21
+ // ERROR Logging Level
22
+ const ERROR = 0;
23
+ }
24
+
25
+ class PPLoggingManager
26
+ {
27
+
28
+ // Default Logging Level
29
+ const DEFAULT_LOGGING_LEVEL = 0;
30
+
31
+ // Logger name
32
+ private $loggerName;
33
+
34
+ // Log enabled
35
+ private $isLoggingEnabled;
36
+
37
+ // Configured logging level
38
+ private $loggingLevel;
39
+
40
+ // Configured logging file
41
+ private $loggerFile;
42
+
43
+ public function __construct( $loggerName )
44
+ {
45
+ $this->loggerName = $loggerName;
46
+ $config = PPConfigManager::getInstance();
47
+ $this->loggerFile = ( $config->get( 'log.FileName' ) ) ? $config->get( 'log.FileName' ) : ini_get( 'error_log' );
48
+ $loggingEnabled = $config->get( 'log.LogEnabled' );
49
+ $this->isLoggingEnabled = ( isset( $loggingEnabled ) ) ? $loggingEnabled : false;
50
+ $loggingLevel = strtoupper( $config->get( 'log.LogLevel' ) );
51
+ $this->loggingLevel = ( isset( $loggingLevel ) && defined( "PPLoggingLevel::$loggingLevel" ) ) ? constant( "PPLoggingLevel::$loggingLevel" ) : PPLoggingManager::DEFAULT_LOGGING_LEVEL;
52
+
53
+ }
54
+
55
+ public function log( $message, $level = PPLoggingLevel::INFO )
56
+ {
57
+ if ( $this->isLoggingEnabled && ( $level <= $this->loggingLevel ) ) {
58
+ error_log( $this->loggerName . ": $message\n", 3, $this->loggerFile );
59
+ }
60
+ }
61
+
62
+ public function error( $message )
63
+ {
64
+ $this->log( $message, PPLoggingLevel::ERROR );
65
+ }
66
+
67
+ public function warning( $message )
68
+ {
69
+ $this->log( $message, PPLoggingLevel::WARN );
70
+ }
71
+
72
+ public function info( $message )
73
+ {
74
+ $this->log( $message, PPLoggingLevel::INFO );
75
+ }
76
+
77
+ public function fine( $message )
78
+ {
79
+ $this->log( $message, PPLoggingLevel::FINE );
80
+ }
81
+
82
+ }
83
+
84
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPObjectTransformer.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Utility class for transforming PHP objects into
4
+ * appropriate service payload type and vice versa
5
+ */
6
+ class PPObjectTransformer
7
+ {
8
+
9
+ public function toString( $object )
10
+ {
11
+
12
+ if ( $object == null ) {
13
+ throw new PPTransformerException( "Empty object" );
14
+ }
15
+
16
+ $confManager = PPConfigManager::getInstance();
17
+ switch ( strtoupper( $confManager->get( "service.Binding" ) ) ) {
18
+ case 'SOAP':
19
+ return $object->toXMLString();
20
+
21
+ case 'XML':
22
+ case 'JSON':
23
+ return "";
24
+ case 'NVP':
25
+ default:
26
+ return $object->toNVPString();
27
+ }
28
+ }
29
+
30
+
31
+ }
32
+
33
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPSignatureCredential.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once 'exceptions/PPMissingCredentialException.php';
4
+ require_once 'IPPCredential.php';
5
+ require_once 'PPConfigManager.php';
6
+
7
+ /**
8
+ * API signature based credentials
9
+ */
10
+ class PPSignatureCredential extends IPPCredential
11
+ {
12
+
13
+ /**
14
+ * API Signature
15
+ * @var string
16
+ */
17
+ private $signature;
18
+
19
+ public function __construct( $userName, $password, $signature, $appId )
20
+ {
21
+ parent::__construct( $userName, $password, $appId );
22
+ $this->signature = $signature;
23
+ $this->validate();
24
+ }
25
+
26
+ public function validate()
27
+ {
28
+
29
+ if ( $this->userName == null || $this->userName == "" ) {
30
+ throw new PPMissingCredentialException( "username cannot be empty" );
31
+ }
32
+ if ( $this->password == null || $this->password == "" ) {
33
+ throw new PPMissingCredentialException( "password cannot be empty" );
34
+ }
35
+ if ( $this->signature == null || $this->signature == "" ) {
36
+ throw new PPMissingCredentialException( "signature cannot be empty" );
37
+ }
38
+ if ( $this->applicationId == null || $this->applicationId == "" ) {
39
+ throw new PPMissingCredentialException( "applicationId cannot be empty" );
40
+ }
41
+ }
42
+
43
+ public function getSignature()
44
+ {
45
+ return $this->signature;
46
+ }
47
+ }
48
+
49
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/PPUtils.php ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class PPUtils
3
+ {
4
+
5
+ const SDK_VERSION = "1.2.95";
6
+ const SDK_NAME = "sdk-adaptivepayments-php ";
7
+
8
+ /**
9
+ *
10
+ * Convert a Name Value Pair (NVP) formatted string into
11
+ * an associative array taking care to urldecode array values
12
+ *
13
+ * @param string $nvpString
14
+ */
15
+ public static function nvpToMap( $nvpString )
16
+ {
17
+
18
+ $ret = array();
19
+ $params = explode( "&", $nvpString );
20
+ foreach ( $params as $p ) {
21
+ list( $k, $v ) = explode( "=", $p );
22
+ $ret[ $k ] = urldecode( $v );
23
+ }
24
+
25
+ return $ret;
26
+ }
27
+
28
+ /**
29
+ * Returns true if the array contains a key like $key
30
+ *
31
+ * @param array $map
32
+ * @param regex $key
33
+ */
34
+ public static function array_match_key( $map, $key )
35
+ {
36
+ $key = str_replace( "(", "\(", $key );
37
+ $key = str_replace( ")", "\)", $key );
38
+ $key = str_replace( ".", "\.", $key );
39
+ $pattern = "/$key*/";
40
+ foreach ( $map as $k => $v ) {
41
+ preg_match( $pattern, $k, $matches );
42
+ if ( count( $matches ) > 0 )
43
+ return true;
44
+ }
45
+
46
+ return false;
47
+ }
48
+
49
+ /**
50
+ *
51
+ * Get the local IP address. The client address is a required
52
+ * request parameter for some API calls
53
+ */
54
+ public static function getLocalIPAddress()
55
+ {
56
+
57
+ if ( array_key_exists( "SERVER_ADDR", $_SERVER ) ) {
58
+ // SERVER_ADDR is available only if we are running the CGI SAPI
59
+ return $_SERVER[ 'SERVER_ADDR' ];
60
+ } else if ( function_exists( "gethostname" ) ) {
61
+ // gethostname is available only in PHP >= v5.3
62
+ return gethostbyname( gethostname() );
63
+ } else {
64
+ // fallback if nothing works
65
+ return "127.0.0.1";
66
+ }
67
+ }
68
+
69
+ /**
70
+ *
71
+ * Compute the value that needs to sent for the PAYPAL_REQUEST_SOURCE
72
+ * parameter when making API calls
73
+ */
74
+ public static function getRequestSource()
75
+ {
76
+ return str_replace( " ", "_", self::SDK_NAME ) . self::SDK_VERSION;
77
+ }
78
+
79
+ public static function xmlToArray( $xmlInput )
80
+ {
81
+
82
+ $xml = simplexml_load_string( $xmlInput );
83
+
84
+ $ns = $xml->getNamespaces( true );
85
+
86
+ $soap = $xml->children( $ns[ 'SOAP-ENV' ] );
87
+ $getChild = $soap->Body->children();
88
+
89
+ $ret = PPUtils::convertXmlObjToArr( $getChild, $array = array() );
90
+
91
+ return $ret;
92
+ }
93
+
94
+ /*foreach ($ret as $arry)
95
+ {
96
+ if (isset($arry['children']) && is_array($arry['children'])&& ($arry['children'])!=null) {
97
+ foreach ($arry['children'] as $novel)
98
+ {
99
+
100
+ }
101
+ }
102
+ else if ($arry['name'] != null)
103
+ {
104
+ $a = $arry['name'] ;
105
+ $b= $arry['text'];
106
+ if (isset($arry['attribute']))
107
+ {
108
+ $c = $arry['attribute'];
109
+ }
110
+ }
111
+
112
+
113
+ }*/
114
+
115
+ /*public function xml2array ( $xmlObject, $out = array () )
116
+ {
117
+ foreach ( (array) $xmlObject as $index => $node )
118
+ {
119
+ $out[$index] = ( is_object ( $node ) ) ? PPUtils::xml2array ( $node ) : $node;
120
+ }
121
+ return $out;
122
+ }*/
123
+
124
+
125
+ function convertXmlObjToArr( $obj, &$arr )
126
+ {
127
+ $children = $obj->children();
128
+ foreach ( $children as $elementName => $node ) {
129
+ $nextIdx = count( $arr );
130
+ $arr[ $nextIdx ] = array();
131
+ $arr[ $nextIdx ][ 'name' ] = strtolower( (string) $elementName );
132
+ $arr[ $nextIdx ][ 'attributes' ] = array();
133
+ $attributes = $node->attributes();
134
+ foreach ( $attributes as $attributeName => $attributeValue ) {
135
+ $attribName = strtolower( trim( (string) $attributeName ) );
136
+ $attribVal = trim( (string) $attributeValue );
137
+ $arr[ $nextIdx ][ 'attributes' ][ $attribName ] = $attribVal;
138
+ }
139
+ $text = (string) $node;
140
+ $text = trim( $text );
141
+ if ( strlen( $text ) > 0 ) {
142
+ $arr[ $nextIdx ][ 'text' ] = $text;
143
+ }
144
+ $arr[ $nextIdx ][ 'children' ] = array();
145
+ PPutils::convertXmlObjToArr( $node, $arr[ $nextIdx ][ 'children' ] );
146
+ }
147
+
148
+ return $arr;
149
+ }
150
+
151
+ }
152
+
153
+ /**
154
+ * @class xml2array
155
+ */
156
+
157
+
158
+ /**
159
+ * XMLToArray Generator Class
160
+ * @author : MA Razzaque Rupom <rupom_315@yahoo.com>, <rupom.bd@gmail.com>
161
+ * Moderator, phpResource (LINK1http://groups.yahoo.com/group/phpresource/LINK1)
162
+ * URL: LINK2http://www.rupom.infoLINK2
163
+ * @version : 1.0
164
+ * @date 06/05/2006
165
+ * Purpose : Creating Hierarchical Array from XML Data
166
+ * Released : Under GPL
167
+ */
168
+
169
+ class XmlToArray
170
+ {
171
+
172
+ var $xml = '';
173
+
174
+ /**
175
+ * Default Constructor
176
+ *
177
+ * @param $xml = xml data
178
+ *
179
+ * @return none
180
+ */
181
+
182
+ function XmlToArray( $xml )
183
+ {
184
+ $this->xml = $xml;
185
+ }
186
+
187
+ /**
188
+ * _struct_to_array($values, &$i)
189
+ *
190
+ * This is adds the contents of the return xml into the array for easier processing.
191
+ * Recursive, Static
192
+ *
193
+ * @access private
194
+ *
195
+ * @param array $values this is the xml data in an array
196
+ * @param int $i this is the current location in the array
197
+ *
198
+ * @return Array
199
+ */
200
+
201
+ function _struct_to_array( $values, &$i )
202
+ {
203
+ $child = array();
204
+ if ( isset( $values[ $i ][ 'value' ] ) ) array_push( $child, $values[ $i ][ 'value' ] );
205
+
206
+ while ( $i++ < count( $values ) ) {
207
+ switch ( $values[ $i ][ 'type' ] ) {
208
+ case 'cdata':
209
+ array_push( $child, $values[ $i ][ 'value' ] );
210
+ break;
211
+
212
+ case 'complete':
213
+ $name = $values[ $i ][ 'tag' ];
214
+ if ( !empty( $name ) ) {
215
+ $child[ $name ] = ( $values[ $i ][ 'value' ] ) ? ( $values[ $i ][ 'value' ] ) : '';
216
+ if ( isset( $values[ $i ][ 'attributes' ] ) ) {
217
+ $child[ $name ] = $values[ $i ][ 'attributes' ];
218
+ }
219
+ }
220
+ break;
221
+
222
+ case 'open':
223
+ $name = $values[ $i ][ 'tag' ];
224
+ $size = isset( $child[ $name ] ) ? sizeof( $child[ $name ] ) : 0;
225
+ $child[ $name ][ $size ] = $this->_struct_to_array( $values, $i );
226
+ break;
227
+
228
+ case 'close':
229
+ return $child;
230
+ break;
231
+ }
232
+ }
233
+
234
+ return $child;
235
+ }
236
+
237
+ //_struct_to_array
238
+
239
+ /**
240
+ * createArray($data)
241
+ *
242
+ * This is adds the contents of the return xml into the array for easier processing.
243
+ *
244
+ * @access public
245
+ *
246
+ * @param string $data this is the string of the xml data
247
+ *
248
+ * @return Array
249
+ */
250
+ function createArray()
251
+ {
252
+ $xml = $this->xml;
253
+ $values = array();
254
+ $index = array();
255
+ $array = array();
256
+ $parser = xml_parser_create();
257
+ xml_parser_set_option( $parser, XML_OPTION_SKIP_WHITE, 1 );
258
+ xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, 0 );
259
+ xml_parse_into_struct( $parser, $xml, $values, $index );
260
+ xml_parser_free( $parser );
261
+ $i = 0;
262
+ $name = $values[ $i ][ 'tag' ];
263
+ $array[ $name ] = isset( $values[ $i ][ 'attributes' ] ) ? $values[ $i ][ 'attributes' ] : '';
264
+ $array[ $name ] = $this->_struct_to_array( $values, $i );
265
+
266
+ return $array;
267
+ }
268
+ //createArray
269
+
270
+
271
+ }
272
+
273
+ //XmlToArray
274
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/auth/AuthUtil.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php //vim: foldmethod=marker
2
+
3
+ class MockOAuthDataStore extends OAuthDataStore
4
+ { /*{{{*/
5
+ private $consumer;
6
+ private $request_token;
7
+ private $access_token;
8
+ private $nonce;
9
+
10
+ function __construct()
11
+ { /*{{{*/
12
+ $this->consumer = new OAuthConsumer( "key", "secret", null );
13
+ $this->request_token = new OAuthToken( "requestkey", "requestsecret", 1 );
14
+ $this->access_token = new OAuthToken( "accesskey", "accesssecret", 1 );
15
+ $this->nonce = "nonce";
16
+ }
17
+
18
+ /*}}}*/
19
+
20
+ function lookup_consumer( $consumer_key )
21
+ { /*{{{*/
22
+ if ( $consumer_key == $this->consumer->key ) return $this->consumer;
23
+
24
+ return null;
25
+ }
26
+
27
+ /*}}}*/
28
+
29
+ function lookup_token( $consumer, $token_type, $token )
30
+ { /*{{{*/
31
+ $token_attrib = $token_type . "_token";
32
+ if ( $consumer->key == $this->consumer->key
33
+ && $token == $this->$token_attrib->key
34
+ ) {
35
+ return $this->$token_attrib;
36
+ }
37
+
38
+ return null;
39
+ }
40
+
41
+ /*}}}*/
42
+
43
+ function lookup_nonce( $consumer, $token, $nonce, $timestamp )
44
+ { /*{{{*/
45
+ if ( $consumer->key == $this->consumer->key
46
+ && ( ( $token && $token->key == $this->request_token->key )
47
+ || ( $token && $token->key == $this->access_token->key ) )
48
+ && $nonce == $this->nonce
49
+ ) {
50
+ return $this->nonce;
51
+ }
52
+
53
+ return null;
54
+ }
55
+
56
+ /*}}}*/
57
+
58
+ function new_request_token( $consumer, $callback = null )
59
+ { /*{{{*/
60
+ if ( $consumer->key == $this->consumer->key ) {
61
+ return $this->request_token;
62
+ }
63
+
64
+ return null;
65
+ }
66
+
67
+ /*}}}*/
68
+
69
+ function new_access_token( $token, $consumer, $verifier = null )
70
+ { /*{{{*/
71
+ if ( $consumer->key == $this->consumer->key
72
+ && $token->key == $this->request_token->key
73
+ ) {
74
+ return $this->access_token;
75
+ }
76
+
77
+ return null;
78
+ }
79
+ /*}}}*/
80
+ }
81
+
82
+ /*}}}*/
83
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/auth/PPAuth.php ADDED
@@ -0,0 +1,1073 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ //PayPal specific modification starts
3
+ //Method to be called for generating signature
4
+ require_once( "AuthUtil.php" );
5
+ class AuthSignature
6
+ {
7
+
8
+ public function genSign( $key, $secret, $token, $tokenSecret, $httpMethod, $endpoint )
9
+ {
10
+
11
+
12
+ $authServer = new OAuthServer( new MockOAuthDataStore() );
13
+ $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
14
+ $authServer->add_signature_method( $hmac_method );
15
+
16
+ $sig_method = $hmac_method;
17
+ $authConsumer = new OAuthConsumer( $key, $secret, null );
18
+ $authToken = null;
19
+ $authToken = new OAuthToken( $token, $tokenSecret );
20
+
21
+ //$params is the query param array which is required only in the httpMethod is "GET"
22
+
23
+ $params = array();
24
+ //set the Query parameters to $params if httpMethod is "GET"
25
+
26
+ $acc_req = OAuthRequest::from_consumer_and_token( $authConsumer, $authToken, $httpMethod, $endpoint, $params );
27
+
28
+ $acc_req->sign_request( $sig_method, $authConsumer, $authToken );
29
+ $response = OAuthutil::parseQueryString( $acc_req );
30
+
31
+ return $response;
32
+
33
+ }
34
+ }
35
+
36
+ //PayPal specific modification ends
37
+ /* Generic exception class
38
+ */
39
+ if ( !class_exists( 'OAuthException' ) ) {
40
+ class OAuthException extends Exception
41
+ {
42
+ // pass
43
+ }
44
+ }
45
+
46
+ if ( !class_exists( 'OAuthConsumer' ) ) {
47
+ class OAuthConsumer
48
+ {
49
+ public $key;
50
+ public $secret;
51
+
52
+ function __construct( $key, $secret, $callback_url = null )
53
+ {
54
+ $this->key = $key;
55
+ $this->secret = $secret;
56
+ $this->callback_url = $callback_url;
57
+ }
58
+
59
+ function __toString()
60
+ {
61
+ return "OAuthConsumer[key=$this->key,secret=$this->secret]";
62
+ }
63
+ }
64
+ }
65
+
66
+ if ( !class_exists( 'OAuthToken' ) ) {
67
+ class OAuthToken
68
+ {
69
+ // access tokens and request tokens
70
+ public $key;
71
+ public $secret;
72
+
73
+ /**
74
+ * key = the token
75
+ * secret = the token secret
76
+ */
77
+ function __construct( $key, $secret )
78
+ {
79
+ $this->key = $key;
80
+ $this->secret = $secret;
81
+ }
82
+
83
+ /**
84
+ * generates the basic string serialization of a token that a server
85
+ * would respond to request_token and access_token calls with
86
+ */
87
+ function to_string()
88
+ {
89
+ return "oauth_token=" .
90
+ OAuthUtil::urlencode_rfc3986( $this->key ) .
91
+ "&oauth_token_secret=" .
92
+ OAuthUtil::urlencode_rfc3986( $this->secret );
93
+ }
94
+
95
+ function __toString()
96
+ {
97
+ return $this->to_string();
98
+ }
99
+ }
100
+ }
101
+
102
+ /**
103
+ * A class for implementing a Signature Method
104
+ * See section 9 ("Signing Requests") in the spec
105
+ */
106
+ if ( !class_exists( 'OAuthSignatureMethod' ) ) {
107
+ abstract class OAuthSignatureMethod
108
+ {
109
+ /**
110
+ * Needs to return the name of the Signature Method (ie HMAC-SHA1)
111
+ * @return string
112
+ */
113
+ abstract public function get_name();
114
+
115
+ /**
116
+ * Build up the signature
117
+ * NOTE: The output of this function MUST NOT be urlencoded.
118
+ * the encoding is handled in OAuthRequest when the final
119
+ * request is serialized
120
+ *
121
+ * @param OAuthRequest $request
122
+ * @param OAuthConsumer $consumer
123
+ * @param OAuthToken $token
124
+ *
125
+ * @return string
126
+ */
127
+ abstract public function build_signature( $request, $consumer, $token );
128
+
129
+ /**
130
+ * Verifies that a given signature is correct
131
+ *
132
+ * @param OAuthRequest $request
133
+ * @param OAuthConsumer $consumer
134
+ * @param OAuthToken $token
135
+ * @param string $signature
136
+ *
137
+ * @return bool
138
+ */
139
+ public function check_signature( $request, $consumer, $token, $signature )
140
+ {
141
+ $built = $this->build_signature( $request, $consumer, $token );
142
+
143
+ return $built == $signature;
144
+ }
145
+ }
146
+ }
147
+
148
+ /**
149
+ * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
150
+ * where the Signature Base String is the text and the key is the concatenated values (each first
151
+ * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
152
+ * character (ASCII code 38) even if empty.
153
+ * - Chapter 9.2 ("HMAC-SHA1")
154
+ */
155
+ if ( !class_exists( 'OAuthSignatureMethod_HMAC_SHA1' ) ) {
156
+ class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod
157
+ {
158
+ function get_name()
159
+ {
160
+ return "HMAC-SHA1";
161
+ }
162
+
163
+ public function build_signature( $request, $consumer, $token )
164
+ {
165
+ $base_string = $request->get_signature_base_string();
166
+ $base_string = preg_replace( "/(%[A-Za-z0-9]{2})/e", "strtolower('\\0')", $base_string ); //convert base string to lowercase
167
+ $request->base_string = $base_string;
168
+
169
+ $key_parts = array(
170
+ $consumer->secret,
171
+ ( $token ) ? $token->secret : ""
172
+ );
173
+
174
+ $key_parts = OAuthUtil::urlencode_rfc3986( $key_parts );
175
+ $key = implode( '&', $key_parts );
176
+ $key = preg_replace( "/(%[A-Za-z0-9]{2})/e", "strtolower('\\0')", $key ); //convert to lowercase
177
+ return base64_encode( hash_hmac( 'sha1', $base_string, $key, true ) );
178
+ }
179
+ }
180
+ }
181
+ /**
182
+ * The PLAINTEXT method does not provide any security protection and SHOULD only be used
183
+ * over a secure channel such as HTTPS. It does not use the Signature Base String.
184
+ * - Chapter 9.4 ("PLAINTEXT")
185
+ */
186
+ if ( !class_exists( 'OAuthSignatureMethod_PLAINTEXT' ) ) {
187
+ class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod
188
+ {
189
+ public function get_name()
190
+ {
191
+ return "PLAINTEXT";
192
+ }
193
+
194
+ /**
195
+ * oauth_signature is set to the concatenated encoded values of the Consumer Secret and
196
+ * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
197
+ * empty. The result MUST be encoded again.
198
+ * - Chapter 9.4.1 ("Generating Signatures")
199
+ *
200
+ * Please note that the second encoding MUST NOT happen in the SignatureMethod, as
201
+ * OAuthRequest handles this!
202
+ */
203
+ public function build_signature( $request, $consumer, $token )
204
+ {
205
+ $key_parts = array(
206
+ $consumer->secret,
207
+ ( $token ) ? $token->secret : ""
208
+ );
209
+
210
+ $key_parts = OAuthUtil::urlencode_rfc3986( $key_parts );
211
+ $key = implode( '&', $key_parts );
212
+ $request->base_string = $key;
213
+
214
+ return $key;
215
+ }
216
+ }
217
+ }
218
+ /**
219
+ * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
220
+ * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
221
+ * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
222
+ * verified way to the Service Provider, in a manner which is beyond the scope of this
223
+ * specification.
224
+ * - Chapter 9.3 ("RSA-SHA1")
225
+ */
226
+ if ( !class_exists( 'OAuthSignatureMethod_RSA_SHA1' ) ) {
227
+ abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod
228
+ {
229
+ public function get_name()
230
+ {
231
+ return "RSA-SHA1";
232
+ }
233
+
234
+ // Up to the SP to implement this lookup of keys. Possible ideas are:
235
+ // (1) do a lookup in a table of trusted certs keyed off of consumer
236
+ // (2) fetch via http using a url provided by the requester
237
+ // (3) some sort of specific discovery code based on request
238
+ //
239
+ // Either way should return a string representation of the certificate
240
+ protected abstract function fetch_public_cert( &$request );
241
+
242
+ // Up to the SP to implement this lookup of keys. Possible ideas are:
243
+ // (1) do a lookup in a table of trusted certs keyed off of consumer
244
+ //
245
+ // Either way should return a string representation of the certificate
246
+ protected abstract function fetch_private_cert( &$request );
247
+
248
+ public function build_signature( $request, $consumer, $token )
249
+ {
250
+ $base_string = $request->get_signature_base_string();
251
+ $request->base_string = $base_string;
252
+
253
+ // Fetch the private key cert based on the request
254
+ $cert = $this->fetch_private_cert( $request );
255
+
256
+ // Pull the private key ID from the certificate
257
+ $privatekeyid = openssl_get_privatekey( $cert );
258
+
259
+ // Sign using the key
260
+ $ok = openssl_sign( $base_string, $signature, $privatekeyid );
261
+
262
+ // Release the key resource
263
+ openssl_free_key( $privatekeyid );
264
+
265
+ return base64_encode( $signature );
266
+ }
267
+
268
+ public function check_signature( $request, $consumer, $token, $signature )
269
+ {
270
+ $decoded_sig = base64_decode( $signature );
271
+
272
+ $base_string = $request->get_signature_base_string();
273
+
274
+ // Fetch the public key cert based on the request
275
+ $cert = $this->fetch_public_cert( $request );
276
+
277
+ // Pull the public key ID from the certificate
278
+ $publickeyid = openssl_get_publickey( $cert );
279
+
280
+ // Check the computed signature against the one passed in the query
281
+ $ok = openssl_verify( $base_string, $decoded_sig, $publickeyid );
282
+
283
+ // Release the key resource
284
+ openssl_free_key( $publickeyid );
285
+
286
+ return $ok == 1;
287
+ }
288
+ }
289
+ }
290
+
291
+ if ( !class_exists( 'OAuthRequest' ) ) {
292
+ class OAuthRequest
293
+ {
294
+ public $parameters;
295
+ protected $http_method;
296
+ protected $http_url;
297
+ // for debug purposes
298
+ public $base_string;
299
+ public static $version = '1.0';
300
+ public static $POST_INPUT = 'php://input';
301
+
302
+ function __construct( $http_method, $http_url, $parameters = null )
303
+ {
304
+ $parameters = ( $parameters ) ? $parameters : array();
305
+ $parameters = array_merge( OAuthUtil::parse_parameters( parse_url( $http_url, PHP_URL_QUERY ) ), $parameters );
306
+ $this->parameters = $parameters;
307
+ $this->http_method = $http_method;
308
+ $this->http_url = $http_url;
309
+ }
310
+
311
+
312
+ /**
313
+ * attempt to build up a request from what was passed to the server
314
+ */
315
+ public static function from_request( $http_method = null, $http_url = null, $parameters = null )
316
+ {
317
+ $scheme = ( !isset( $_SERVER[ 'HTTPS' ] ) || $_SERVER[ 'HTTPS' ] != "on" )
318
+ ? 'http'
319
+ : 'https';
320
+ $http_url = ( $http_url ) ? $http_url : $scheme .
321
+ '://' . $_SERVER[ 'HTTP_HOST' ] .
322
+ ':' .
323
+ $_SERVER[ 'SERVER_PORT' ] .
324
+ $_SERVER[ 'REQUEST_URI' ];
325
+ $http_method = ( $http_method ) ? $http_method : $_SERVER[ 'REQUEST_METHOD' ];
326
+
327
+ // We weren't handed any parameters, so let's find the ones relevant to
328
+ // this request.
329
+ // If you run XML-RPC or similar you should use this to provide your own
330
+ // parsed parameter-list
331
+ if ( !$parameters ) {
332
+ // Find request headers
333
+ $request_headers = OAuthUtil::get_headers();
334
+
335
+ // Parse the query-string to find GET parameters
336
+ $parameters = OAuthUtil::parse_parameters( $_SERVER[ 'QUERY_STRING' ] );
337
+
338
+ // It's a POST request of the proper content-type, so parse POST
339
+ // parameters and add those overriding any duplicates from GET
340
+ if ( $http_method == "POST"
341
+ && isset( $request_headers[ 'Content-Type' ] )
342
+ && strstr( $request_headers[ 'Content-Type' ],
343
+ 'application/x-www-form-urlencoded' )
344
+ ) {
345
+ $post_data = OAuthUtil::parse_parameters(
346
+ file_get_contents( self::$POST_INPUT )
347
+ );
348
+ $parameters = array_merge( $parameters, $post_data );
349
+ }
350
+
351
+ // We have a Authorization-header with OAuth data. Parse the header
352
+ // and add those overriding any duplicates from GET or POST
353
+ if ( isset( $request_headers[ 'Authorization' ] ) && substr( $request_headers[ 'Authorization' ], 0, 6 ) == 'OAuth ' ) {
354
+ $header_parameters = OAuthUtil::split_header(
355
+ $request_headers[ 'Authorization' ]
356
+ );
357
+ $parameters = array_merge( $parameters, $header_parameters );
358
+ }
359
+
360
+ }
361
+
362
+ return new OAuthRequest( $http_method, $http_url, $parameters );
363
+ }
364
+
365
+ /**
366
+ * pretty much a helper function to set up the request
367
+ */
368
+ public static function from_consumer_and_token( $consumer, $token, $http_method, $http_url, $parameters = null )
369
+ {
370
+ $parameters = ( $parameters ) ? $parameters : array();
371
+ $defaults = array(
372
+ "oauth_version" => OAuthRequest::$version,
373
+ // "oauth_nonce" => OAuthRequest::generate_nonce(),
374
+ "oauth_timestamp" => OAuthRequest::generate_timestamp(),
375
+
376
+ "oauth_consumer_key" => $consumer->key
377
+ );
378
+ if ( $token )
379
+ $defaults[ 'oauth_token' ] = $token->key;
380
+
381
+ $parameters = array_merge( $defaults, $parameters );
382
+ ksort( $parameters );
383
+
384
+ return new OAuthRequest( $http_method, $http_url, $parameters );
385
+ }
386
+
387
+ public function set_parameter( $name, $value, $allow_duplicates = true )
388
+ {
389
+ if ( $allow_duplicates && isset( $this->parameters[ $name ] ) ) {
390
+ // We have already added parameter(s) with this name, so add to the list
391
+ if ( is_scalar( $this->parameters[ $name ] ) ) {
392
+ // This is the first duplicate, so transform scalar (string)
393
+ // into an array so we can add the duplicates
394
+ $this->parameters[ $name ] = array( $this->parameters[ $name ] );
395
+ }
396
+
397
+ $this->parameters[ $name ][ ] = $value;
398
+ } else {
399
+ $this->parameters[ $name ] = $value;
400
+ }
401
+ }
402
+
403
+ public function get_parameter( $name )
404
+ {
405
+ return isset( $this->parameters[ $name ] ) ? $this->parameters[ $name ] : null;
406
+ }
407
+
408
+ public function get_parameters()
409
+ {
410
+ return $this->parameters;
411
+ }
412
+
413
+ public function unset_parameter( $name )
414
+ {
415
+ unset( $this->parameters[ $name ] );
416
+ }
417
+
418
+ /**
419
+ * The request parameters, sorted and concatenated into a normalized string.
420
+ * @return string
421
+ */
422
+ public function get_signable_parameters()
423
+ {
424
+ // Grab all parameters
425
+ $params = $this->parameters;
426
+ ksort( $params );
427
+ // Remove oauth_signature if present
428
+ // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
429
+ if ( isset( $params[ 'oauth_signature' ] ) ) {
430
+ unset( $params[ 'oauth_signature' ] );
431
+ }
432
+ foreach ( $params as $key => $value ) {
433
+ $res[ ] = $key . "=" . $value;
434
+ }
435
+
436
+ return implode( '&', $res );
437
+ //return OAuthUtil::build_http_query($params);
438
+ }
439
+
440
+ /**
441
+ * Returns the base string of this request
442
+ *
443
+ * The base string defined as the method, the url
444
+ * and the parameters (normalized), each urlencoded
445
+ * and the concated with &.
446
+ */
447
+ public function get_signature_base_string()
448
+ {
449
+ $parts = array(
450
+ $this->get_normalized_http_method(),
451
+ $this->get_normalized_http_url(),
452
+ $this->get_signable_parameters()
453
+ );
454
+
455
+ $parts = OAuthUtil::urlencode_rfc3986( $parts );
456
+
457
+ return implode( '&', $parts );
458
+ }
459
+
460
+ /**
461
+ * just uppercases the http method
462
+ */
463
+ public function get_normalized_http_method()
464
+ {
465
+ return strtoupper( $this->http_method );
466
+ }
467
+
468
+ /**
469
+ * parses the url and rebuilds it to be
470
+ * scheme://host/path
471
+ */
472
+ public function get_normalized_http_url()
473
+ {
474
+ $parts = parse_url( $this->http_url );
475
+
476
+ $scheme = ( isset( $parts[ 'scheme' ] ) ) ? $parts[ 'scheme' ] : 'http';
477
+ $port = ( isset( $parts[ 'port' ] ) ) ? $parts[ 'port' ] : ( ( $scheme == 'https' ) ? '443' : '80' );
478
+ $host = ( isset( $parts[ 'host' ] ) ) ? $parts[ 'host' ] : '';
479
+ $path = ( isset( $parts[ 'path' ] ) ) ? $parts[ 'path' ] : '';
480
+
481
+ if ( ( $scheme == 'https' && $port != '443' )
482
+ || ( $scheme == 'http' && $port != '80' )
483
+ ) {
484
+ $host = "$host:$port";
485
+ }
486
+
487
+ return "$scheme://$host$path";
488
+ }
489
+
490
+ /**
491
+ * builds a url usable for a GET request
492
+ */
493
+ public function to_url()
494
+ {
495
+ $post_data = $this->to_postdata();
496
+ $out = $this->get_normalized_http_url();
497
+ if ( $post_data ) {
498
+ $out .= '?' . $post_data;
499
+ }
500
+
501
+ return $out;
502
+ }
503
+
504
+ /**
505
+ * builds the data one would send in a POST request
506
+ */
507
+ public function to_postdata()
508
+ {
509
+ return OAuthUtil::build_http_query( $this->parameters );
510
+ }
511
+
512
+ /**
513
+ * builds the Authorization: header
514
+ */
515
+ public function to_header( $realm = null )
516
+ {
517
+ $first = true;
518
+ if ( $realm ) {
519
+ $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986( $realm ) . '"';
520
+ $first = false;
521
+ } else
522
+ $out = 'Authorization: OAuth';
523
+
524
+ $total = array();
525
+ foreach ( $this->parameters as $k => $v ) {
526
+ if ( substr( $k, 0, 5 ) != "oauth" ) continue;
527
+ if ( is_array( $v ) ) {
528
+ throw new OAuthException( 'Arrays not supported in headers' );
529
+ }
530
+ $out .= ( $first ) ? ' ' : ',';
531
+ $out .= OAuthUtil::urlencode_rfc3986( $k ) .
532
+ '="' .
533
+ OAuthUtil::urlencode_rfc3986( $v ) .
534
+ '"';
535
+ $first = false;
536
+ }
537
+
538
+ return $out;
539
+ }
540
+
541
+ public function __toString()
542
+ {
543
+ return $this->to_url();
544
+ }
545
+
546
+
547
+ public function sign_request( $signature_method, $consumer, $token )
548
+ {
549
+
550
+ $empty = false;
551
+ $msg = array();
552
+ if ( $token->key == null ) {
553
+ $msg[ ] = 'Token key';
554
+ }
555
+ if ( $token->secret == null ) {
556
+ $msg[ ] = 'Token secret';
557
+ }
558
+ if ( $consumer->key == null ) {
559
+
560
+ $msg[ ] = 'Consumer key';
561
+ }
562
+ if ( $consumer->secret == null ) {
563
+
564
+ $msg[ ] = 'Consumer secret';
565
+ }
566
+ if ( $this->http_url == null ) {
567
+
568
+ $msg[ ] = 'Endpoint';
569
+ }
570
+ if ( $this->http_method == null ) {
571
+
572
+ $msg[ ] = 'HTTP method';
573
+ }
574
+ if ( count( $msg ) ) {
575
+ throw new OAuthException( 'Enter valid ' . implode( ',', $msg ) );
576
+ }
577
+ $this->set_parameter(
578
+ "oauth_signature_method",
579
+ $signature_method->get_name(),
580
+ false );
581
+
582
+ $signature = $this->build_signature( $signature_method, $consumer, $token );
583
+ $this->set_parameter( "oauth_signature", $signature, false );
584
+
585
+ }
586
+
587
+ public function build_signature( $signature_method, $consumer, $token )
588
+ {
589
+ $signature = $signature_method->build_signature( $this, $consumer, $token );
590
+
591
+ return $signature;
592
+ }
593
+
594
+ /**
595
+ * util function: current timestamp
596
+ */
597
+ private static function generate_timestamp()
598
+ {
599
+ return time();
600
+ }
601
+
602
+ /**
603
+ * util function: current nonce
604
+ */
605
+ private static function generate_nonce()
606
+ {
607
+ $mt = microtime();
608
+ $rand = mt_rand();
609
+
610
+ return md5( $mt . $rand ); // md5s look nicer than numbers
611
+ }
612
+ }
613
+ }
614
+
615
+ if ( !class_exists( 'OAuthServer' ) ) {
616
+ class OAuthServer
617
+ {
618
+ protected $timestamp_threshold = 300; // in seconds, five minutes
619
+ protected $version = '1.0'; // hi blaine
620
+ protected $signature_methods = array();
621
+
622
+ protected $data_store;
623
+
624
+ function __construct( $data_store )
625
+ {
626
+ $this->data_store = $data_store;
627
+ }
628
+
629
+ public function add_signature_method( $signature_method )
630
+ {
631
+ $this->signature_methods[ $signature_method->get_name() ] =
632
+ $signature_method;
633
+ }
634
+
635
+ // high level functions
636
+
637
+ /**
638
+ * process a request_token request
639
+ * returns the request token on success
640
+ */
641
+ public function fetch_request_token( &$request )
642
+ {
643
+ $this->get_version( $request );
644
+
645
+ $consumer = $this->get_consumer( $request );
646
+
647
+ // no token required for the initial token request
648
+ $token = null;
649
+
650
+ $this->check_signature( $request, $consumer, $token );
651
+
652
+ // Rev A change
653
+ $callback = $request->get_parameter( 'oauth_callback' );
654
+ $new_token = $this->data_store->new_request_token( $consumer, $callback );
655
+
656
+ return $new_token;
657
+ }
658
+
659
+ /**
660
+ * process an access_token request
661
+ * returns the access token on success
662
+ */
663
+ public function fetch_access_token( &$request )
664
+ {
665
+ $this->get_version( $request );
666
+
667
+ $consumer = $this->get_consumer( $request );
668
+
669
+ // requires authorized request token
670
+ $token = $this->get_token( $request, $consumer, "request" );
671
+
672
+ $this->check_signature( $request, $consumer, $token );
673
+
674
+ // Rev A change
675
+ $verifier = $request->get_parameter( 'oauth_verifier' );
676
+ $new_token = $this->data_store->new_access_token( $token, $consumer, $verifier );
677
+
678
+ return $new_token;
679
+ }
680
+
681
+ /**
682
+ * verify an api call, checks all the parameters
683
+ */
684
+ public function verify_request( &$request )
685
+ {
686
+ $this->get_version( $request );
687
+ $consumer = $this->get_consumer( $request );
688
+ $token = $this->get_token( $request, $consumer, "access" );
689
+ $this->check_signature( $request, $consumer, $token );
690
+
691
+ return array( $consumer, $token );
692
+ }
693
+
694
+ // Internals from here
695
+ /**
696
+ * version 1
697
+ */
698
+ private function get_version( &$request )
699
+ {
700
+ $version = $request->get_parameter( "oauth_version" );
701
+ if ( !$version ) {
702
+ // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
703
+ // Chapter 7.0 ("Accessing Protected Ressources")
704
+ $version = '1.0';
705
+ }
706
+ if ( $version !== $this->version ) {
707
+ throw new OAuthException( "OAuth version '$version' not supported" );
708
+ }
709
+
710
+ return $version;
711
+ }
712
+
713
+ /**
714
+ * figure out the signature with some defaults
715
+ */
716
+ private function get_signature_method( $request )
717
+ {
718
+ $signature_method = $request instanceof OAuthRequest
719
+ ? $request->get_parameter( "oauth_signature_method" )
720
+ : null;
721
+
722
+ if ( !$signature_method ) {
723
+ // According to chapter 7 ("Accessing Protected Ressources") the signature-method
724
+ // parameter is required, and we can't just fallback to PLAINTEXT
725
+ throw new OAuthException( 'No signature method parameter. This parameter is required' );
726
+ }
727
+
728
+ if ( !in_array( $signature_method,
729
+ array_keys( $this->signature_methods ) )
730
+ ) {
731
+ throw new OAuthException(
732
+ "Signature method '$signature_method' not supported " .
733
+ "try one of the following: " .
734
+ implode( ", ", array_keys( $this->signature_methods ) )
735
+ );
736
+ }
737
+
738
+ return $this->signature_methods[ $signature_method ];
739
+ }
740
+
741
+ /**
742
+ * try to find the consumer for the provided request's consumer key
743
+ */
744
+ private function get_consumer( $request )
745
+ {
746
+ $consumer_key = $request instanceof OAuthRequest
747
+ ? $request->get_parameter( "oauth_consumer_key" )
748
+ : null;
749
+
750
+ if ( !$consumer_key ) {
751
+ throw new OAuthException( "Invalid consumer key" );
752
+ }
753
+
754
+ $consumer = $this->data_store->lookup_consumer( $consumer_key );
755
+ if ( !$consumer ) {
756
+ throw new OAuthException( "Invalid consumer" );
757
+ }
758
+
759
+ return $consumer;
760
+ }
761
+
762
+ /**
763
+ * try to find the token for the provided request's token key
764
+ */
765
+ private function get_token( $request, $consumer, $token_type = "access" )
766
+ {
767
+ $token_field = $request instanceof OAuthRequest
768
+ ? $request->get_parameter( 'oauth_token' )
769
+ : null;
770
+
771
+ $token = $this->data_store->lookup_token(
772
+ $consumer, $token_type, $token_field
773
+ );
774
+ if ( !$token ) {
775
+ throw new OAuthException( "Invalid $token_type token: $token_field" );
776
+ }
777
+
778
+ return $token;
779
+ }
780
+
781
+ /**
782
+ * all-in-one function to check the signature on a request
783
+ * should guess the signature method appropriately
784
+ */
785
+ private function check_signature( $request, $consumer, $token )
786
+ {
787
+ // this should probably be in a different method
788
+ $timestamp = $request instanceof OAuthRequest
789
+ ? $request->get_parameter( 'oauth_timestamp' )
790
+ : null;
791
+ $nonce = $request instanceof OAuthRequest
792
+ ? $request->get_parameter( 'oauth_nonce' )
793
+ : null;
794
+
795
+ $this->check_timestamp( $timestamp );
796
+ $this->check_nonce( $consumer, $token, $nonce, $timestamp );
797
+
798
+ $signature_method = $this->get_signature_method( $request );
799
+
800
+ $signature = $request->get_parameter( 'oauth_signature' );
801
+ $valid_sig = $signature_method->check_signature(
802
+ $request,
803
+ $consumer,
804
+ $token,
805
+ $signature
806
+ );
807
+
808
+ if ( !$valid_sig ) {
809
+ throw new OAuthException( "Invalid signature" );
810
+ }
811
+ }
812
+
813
+ /**
814
+ * check that the timestamp is new enough
815
+ */
816
+ private function check_timestamp( $timestamp )
817
+ {
818
+ if ( !$timestamp )
819
+ throw new OAuthException(
820
+ 'Missing timestamp parameter. The parameter is required'
821
+ );
822
+
823
+ // verify that timestamp is recentish
824
+ $now = time();
825
+ if ( abs( $now - $timestamp ) > $this->timestamp_threshold ) {
826
+ throw new OAuthException(
827
+ "Expired timestamp, yours $timestamp, ours $now"
828
+ );
829
+ }
830
+ }
831
+
832
+ /**
833
+ * check that the nonce is not repeated
834
+ */
835
+ private function check_nonce( $consumer, $token, $nonce, $timestamp )
836
+ {
837
+ if ( !$nonce )
838
+ throw new OAuthException(
839
+ 'Missing nonce parameter. The parameter is required'
840
+ );
841
+
842
+ // verify that the nonce is uniqueish
843
+ $found = $this->data_store->lookup_nonce(
844
+ $consumer,
845
+ $token,
846
+ $nonce,
847
+ $timestamp
848
+ );
849
+ if ( $found ) {
850
+ throw new OAuthException( "Nonce already used: $nonce" );
851
+ }
852
+ }
853
+
854
+ }
855
+ }
856
+
857
+ class OAuthDataStore
858
+ {
859
+ function lookup_consumer( $consumer_key )
860
+ {
861
+ // implement me
862
+ }
863
+
864
+ function lookup_token( $consumer, $token_type, $token )
865
+ {
866
+ // implement me
867
+ }
868
+
869
+ function lookup_nonce( $consumer, $token, $nonce, $timestamp )
870
+ {
871
+ // implement me
872
+ }
873
+
874
+ function new_request_token( $consumer, $callback = null )
875
+ {
876
+ // return a new token attached to this consumer
877
+ }
878
+
879
+ function new_access_token( $token, $consumer, $verifier = null )
880
+ {
881
+ // return a new access token attached to this consumer
882
+ // for the user associated with this token if the request token
883
+ // is authorized
884
+ // should also invalidate the request token
885
+ }
886
+
887
+ }
888
+
889
+ if ( !class_exists( 'OAuthUtil' ) ) {
890
+ class OAuthUtil
891
+ {
892
+ public static function urlencode_rfc3986( $input )
893
+ {
894
+ if ( is_array( $input ) ) {
895
+ return array_map( array( 'OAuthUtil', 'urlencode_rfc3986' ), $input );
896
+ } else if ( is_scalar( $input ) ) {
897
+ $tmp1 = str_replace( '%7E', '~', rawurlencode( $input ) );
898
+ $tmp2 = str_replace( ".", "%2E", $tmp1 );
899
+ $tmp3 = str_replace( "*", "%2A", $tmp2 );
900
+ $tmp4 = str_replace( '+', ' ', $tmp3 );
901
+ $tmp = str_replace( "-", "%2D", $tmp4 );
902
+
903
+ return $tmp;
904
+ /*$tmp1=str_replace('%7E', '~', rawurlencode($input));
905
+ $tmp2= str_replace(".","%2E",$tmp1);
906
+
907
+
908
+ return $tmp;*/
909
+ } else {
910
+ return '';
911
+ }
912
+ }
913
+
914
+ public static function parseQueryString( $str )
915
+ {
916
+ $op = array();
917
+ $pairs = explode( "&", $str );
918
+ foreach ( $pairs as $pair ) {
919
+ list( $k, $v ) = array_map( "urldecode", explode( "=", $pair ) );
920
+ $op[ $k ] = $v;
921
+ }
922
+
923
+ return $op;
924
+ }
925
+
926
+ //parses string to associative array -modified for PayPal Signature
927
+
928
+
929
+ // This decode function isn't taking into consideration the above
930
+ // modifications to the encoding process. However, this method doesn't
931
+ // seem to be used anywhere so leaving it as is.
932
+ public static function urldecode_rfc3986( $string )
933
+ {
934
+ return urldecode( $string );
935
+ }
936
+
937
+ // Utility function for turning the Authorization: header into
938
+ // parameters, has to do some unescaping
939
+ // Can filter out any non-oauth parameters if needed (default behaviour)
940
+ // May 28th, 2010 - method updated to tjerk.meesters for a speed improvement.
941
+ // see http://code.google.com/p/oauth/issues/detail?id=163
942
+ public static function split_header( $header, $only_allow_oauth_parameters = true )
943
+ {
944
+ $params = array();
945
+ if ( preg_match_all( '/(' . ( $only_allow_oauth_parameters ? 'oauth_' : '' ) . '[a-z_-]*)=(:?"([^"]*)"|([^,]*))/', $header, $matches ) ) {
946
+ foreach ( $matches[ 1 ] as $i => $h ) {
947
+ $params[ $h ] = OAuthUtil::urldecode_rfc3986( empty( $matches[ 3 ][ $i ] ) ? $matches[ 4 ][ $i ] : $matches[ 3 ][ $i ] );
948
+ }
949
+ if ( isset( $params[ 'realm' ] ) ) {
950
+ unset( $params[ 'realm' ] );
951
+ }
952
+ }
953
+
954
+ return $params;
955
+ }
956
+
957
+ // helper to try to sort out headers for people who aren't running apache
958
+ public static function get_headers()
959
+ {
960
+ if ( function_exists( 'apache_request_headers' ) ) {
961
+ // we need this to get the actual Authorization: header
962
+ // because apache tends to tell us it doesn't exist
963
+ $headers = apache_request_headers();
964
+
965
+ // sanitize the output of apache_request_headers because
966
+ // we always want the keys to be Cased-Like-This and arh()
967
+ // returns the headers in the same case as they are in the
968
+ // request
969
+ $out = array();
970
+ foreach ( $headers AS $key => $value ) {
971
+ $key = str_replace(
972
+ " ",
973
+ "-",
974
+ ucwords( strtolower( str_replace( "-", " ", $key ) ) )
975
+ );
976
+ $out[ $key ] = $value;
977
+ }
978
+ } else {
979
+ // otherwise we don't have apache and are just going to have to hope
980
+ // that $_SERVER actually contains what we need
981
+ $out = array();
982
+ if ( isset( $_SERVER[ 'CONTENT_TYPE' ] ) )
983
+ $out[ 'Content-Type' ] = $_SERVER[ 'CONTENT_TYPE' ];
984
+ if ( isset( $_ENV[ 'CONTENT_TYPE' ] ) )
985
+ $out[ 'Content-Type' ] = $_ENV[ 'CONTENT_TYPE' ];
986
+
987
+ foreach ( $_SERVER as $key => $value ) {
988
+ if ( substr( $key, 0, 5 ) == "HTTP_" ) {
989
+ // this is chaos, basically it is just there to capitalize the first
990
+ // letter of every word that is not an initial HTTP and strip HTTP
991
+ // code from przemek
992
+ $key = str_replace(
993
+ " ",
994
+ "-",
995
+ ucwords( strtolower( str_replace( "_", " ", substr( $key, 5 ) ) ) )
996
+ );
997
+ $out[ $key ] = $value;
998
+ }
999
+ }
1000
+ }
1001
+
1002
+ return $out;
1003
+ }
1004
+
1005
+ // This function takes a input like a=b&a=c&d=e and returns the parsed
1006
+ // parameters like this
1007
+ // array('a' => array('b','c'), 'd' => 'e')
1008
+ public static function parse_parameters( $input )
1009
+ {
1010
+ if ( !isset( $input ) || !$input ) return array();
1011
+
1012
+ $pairs = explode( '&', $input );
1013
+
1014
+ $parsed_parameters = array();
1015
+ foreach ( $pairs as $pair ) {
1016
+ $split = explode( '=', $pair, 2 );
1017
+ $parameter = OAuthUtil::urldecode_rfc3986( $split[ 0 ] );
1018
+ $value = isset( $split[ 1 ] ) ? OAuthUtil::urldecode_rfc3986( $split[ 1 ] ) : '';
1019
+
1020
+ if ( isset( $parsed_parameters[ $parameter ] ) ) {
1021
+ // We have already recieved parameter(s) with this name, so add to the list
1022
+ // of parameters with this name
1023
+
1024
+ if ( is_scalar( $parsed_parameters[ $parameter ] ) ) {
1025
+ // This is the first duplicate, so transform scalar (string) into an array
1026
+ // so we can add the duplicates
1027
+ $parsed_parameters[ $parameter ] = array( $parsed_parameters[ $parameter ] );
1028
+ }
1029
+
1030
+ $parsed_parameters[ $parameter ][ ] = $value;
1031
+ } else {
1032
+ $parsed_parameters[ $parameter ] = $value;
1033
+ }
1034
+ }
1035
+
1036
+ return $parsed_parameters;
1037
+ }
1038
+
1039
+ public static function build_http_query( $params )
1040
+ {
1041
+ if ( !$params ) return '';
1042
+
1043
+ // Urlencode both keys and values
1044
+ $keys = OAuthUtil::urlencode_rfc3986( array_keys( $params ) );
1045
+ $values = OAuthUtil::urlencode_rfc3986( array_values( $params ) );
1046
+ $params = array_combine( $keys, $values );
1047
+
1048
+ // Parameters are sorted by name, using lexicographical byte value ordering.
1049
+ // Ref: Spec: 9.1.1 (1)
1050
+ uksort( $params, 'strcmp' );
1051
+
1052
+ $pairs = array();
1053
+ foreach ( $params as $parameter => $value ) {
1054
+ if ( is_array( $value ) ) {
1055
+ // If two or more parameters share the same name, they are sorted by their value
1056
+ // Ref: Spec: 9.1.1 (1)
1057
+ // June 12th, 2010 - changed to sort because of issue 164 by hidetaka
1058
+ sort( $value, SORT_STRING );
1059
+ foreach ( $value as $duplicate_value ) {
1060
+ $pairs[ ] = $parameter . '=' . $duplicate_value;
1061
+ }
1062
+ } else {
1063
+ $pairs[ ] = $parameter . '=' . $value;
1064
+ }
1065
+ }
1066
+
1067
+ // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
1068
+ // Each name-value pair is separated by an '&' character (ASCII code 38)
1069
+ return implode( '&', $pairs );
1070
+ }
1071
+ }
1072
+ }
1073
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/cacert.pem ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Verisign Class 3 Public Primary Certification Authority
2
+ =======================================================
3
+ -----BEGIN CERTIFICATE-----
4
+ MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx
5
+ FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5
6
+ IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow
7
+ XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz
8
+ IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
9
+ A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94
10
+ f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol
11
+ hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtMEivPLCYA
12
+ TxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59Ah
13
+ WM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2Omuf
14
+ Tqj/ZA1k
15
+ -----END CERTIFICATE-----
16
+
17
+ Verisign Class 3 Public Primary Certification Authority - G2
18
+ ============================================================
19
+ -----BEGIN CERTIFICATE-----
20
+ MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT
21
+ MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
22
+ eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
23
+ biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
24
+ dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT
25
+ MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
26
+ eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
27
+ biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
28
+ dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO
29
+ FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71
30
+ lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB
31
+ MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT
32
+ 1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD
33
+ Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9
34
+ -----END CERTIFICATE-----
35
+
36
+
37
+ Verisign Class 3 Public Primary Certification Authority - G3
38
+ ============================================================
39
+ -----BEGIN CERTIFICATE-----
40
+ MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
41
+ UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
42
+ cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
43
+ IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
44
+ dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
45
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
46
+ dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
47
+ cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg
48
+ Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
49
+ ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1
50
+ EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc
51
+ cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw
52
+ EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj
53
+ 055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
54
+ ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f
55
+ j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
56
+ /Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0
57
+ xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa
58
+ t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
59
+ -----END CERTIFICATE-----
60
+
61
+ Verisign Class 4 Public Primary Certification Authority - G3
62
+ ============================================================
63
+ -----BEGIN CERTIFICATE-----
64
+ MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
65
+ UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
66
+ cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
67
+ IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
68
+ dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
69
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
70
+ dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
71
+ cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkg
72
+ Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
73
+ ggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaS
74
+ tBO3IFsJ+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM
75
+ 8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdLMEYH5IBtptiW
76
+ Lugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XYufTsgsbSPZUd5cBPhMnZo0QoBmrX
77
+ Razwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
78
+ j/ola09b5KROJ1WrIhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt
79
+ mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
80
+ fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c2NU8Qh0XwRJd
81
+ RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG
82
+ UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
83
+ -----END CERTIFICATE-----
84
+ VeriSign Class 3 Public Primary Certification Authority - G5
85
+ ============================================================
86
+ -----BEGIN CERTIFICATE-----
87
+ MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
88
+ BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
89
+ ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
90
+ IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp
91
+ ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB
92
+ yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln
93
+ biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh
94
+ dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt
95
+ YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
96
+ ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz
97
+ j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD
98
+ Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
99
+ Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r
100
+ fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/
101
+ BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv
102
+ Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
103
+ aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
104
+ SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+
105
+ X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE
106
+ KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC
107
+ Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE
108
+ ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
109
+ -----END CERTIFICATE-----
110
+ VeriSign Universal Root Certification Authority
111
+ ===============================================
112
+ -----BEGIN CERTIFICATE-----
113
+ MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE
114
+ BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
115
+ ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
116
+ IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u
117
+ IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV
118
+ UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
119
+ cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
120
+ IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0
121
+ aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj
122
+ 1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP
123
+ MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72
124
+ 9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I
125
+ AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR
126
+ tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G
127
+ CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O
128
+ a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
129
+ DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3
130
+ Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx
131
+ Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx
132
+ P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P
133
+ wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4
134
+ mJO37M2CYfE45k+XmCpajQ==
135
+ -----END CERTIFICATE-----
136
+
137
+ VeriSign Class 3 Public Primary Certification Authority - G4
138
+ ============================================================
139
+ -----BEGIN CERTIFICATE-----
140
+ MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC
141
+ VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3
142
+ b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz
143
+ ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj
144
+ YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL
145
+ MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU
146
+ cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo
147
+ b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5
148
+ IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8
149
+ Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz
150
+ rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB
151
+ /zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw
152
+ HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u
153
+ Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD
154
+ A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx
155
+ AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
156
+ -----END CERTIFICATE-----
157
+ Verisign Class 3 Public Primary Certification Authority
158
+ =======================================================
159
+ -----BEGIN CERTIFICATE-----
160
+ MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx
161
+ FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5
162
+ IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow
163
+ XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz
164
+ IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
165
+ A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94
166
+ f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol
167
+ hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABByUqkFFBky
168
+ CEHwxWsKzH4PIRnN5GfcX6kb5sroc50i2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWX
169
+ bj9T/UWZYB2oK0z5XqcJ2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/
170
+ D/xwzoiQ
171
+ -----END CERTIFICATE-----
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/exceptions/PPConfigurationException.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class PPConfigurationException extends Exception
3
+ {
4
+
5
+ public function __construct( $message = null, $code = 0 )
6
+ {
7
+ parent::__construct( $message, $code );
8
+ }
9
+ }
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/exceptions/PPConnectionException.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class PPConnectionException extends Exception
3
+ {
4
+ /**
5
+ * The url that was being connected to when the exception occured
6
+ * @var string
7
+ */
8
+ private $url;
9
+
10
+ public function __construct( $url, $message, $code = 0 )
11
+ {
12
+ parent::__construct( $message, $code );
13
+ $this->url = $url;
14
+ }
15
+
16
+ public function getUrl()
17
+ {
18
+ return $this->url;
19
+ }
20
+ }
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/exceptions/PPInvalidCredentialException.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ class PPInvalidCredentialException extends Exception
5
+ {
6
+
7
+ public function __construct( $message = null, $code = 0 )
8
+ {
9
+ parent::__construct( $message, $code );
10
+ }
11
+
12
+ public function errorMessage()
13
+ {
14
+ $errorMsg = 'Error on line ' . $this->getLine() . ' in ' . $this->getFile()
15
+ . ': <b>' . $this->getMessage() . '</b>';
16
+
17
+ return $errorMsg;
18
+ }
19
+
20
+ }
21
+
22
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/exceptions/PPMissingCredentialException.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ class PPMissingCredentialException extends Exception
5
+ {
6
+
7
+ public function __construct( $message = null, $code = 0 )
8
+ {
9
+ parent::__construct( $message, $code );
10
+ }
11
+
12
+ public function errorMessage()
13
+ {
14
+ $errorMsg = 'Error on line ' . $this->getLine() . ' in ' . $this->getFile()
15
+ . ': <b>' . $this->getMessage() . '</b>';
16
+
17
+ return $errorMsg;
18
+ }
19
+
20
+ }
21
+
22
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/exceptions/PPTransformerException.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class PPTransformerException extends Exception
3
+ {
4
+
5
+ public function __construct( $message = null, $code = 0 )
6
+ {
7
+ parent::__construct( $message, $code );
8
+ }
9
+
10
+ public function errorMessage()
11
+ {
12
+ $errorMsg = 'Error on line ' . $this->getLine() . ' in ' . $this->getFile()
13
+ . ': <b>' . $this->getMessage() . '</b>';
14
+
15
+ return $errorMsg;
16
+ }
17
+
18
+ }
19
+
20
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/services/AdaptivePayments/AdaptivePayments.php ADDED
@@ -0,0 +1,5797 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Stub objects for AdaptivePayments
4
+ * Auto generated code
5
+ *
6
+ */
7
+ require_once( 'PPUtils.php' );
8
+ /**
9
+ *
10
+ */
11
+ class AccountIdentifier
12
+ {
13
+
14
+ /**
15
+ *
16
+ * @access public
17
+ * @var string
18
+ */
19
+ public $email;
20
+
21
+ /**
22
+ *
23
+ * @access public
24
+ * @var PhoneNumberType
25
+ */
26
+ public $phone;
27
+
28
+
29
+ public function toNVPString( $prefix = '' )
30
+ {
31
+ $str = '';
32
+ $delim = '';
33
+ if ( $this->email != null ) {
34
+ $str .= $delim . $prefix . 'email=' . urlencode( $this->email );
35
+ $delim = '&';
36
+ }
37
+ if ( $this->phone != null ) {
38
+ $newPrefix = $prefix . 'phone.';
39
+ $str .= $delim . call_user_func( array( $this->phone, 'toNVPString' ), $newPrefix );
40
+ $delim = '&';
41
+ }
42
+
43
+ return $str;
44
+ }
45
+
46
+ public function init( $map = null, $prefix = '' )
47
+ {
48
+ if ( $map != null ) {
49
+ $mapKeyName = $prefix . 'email';
50
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
51
+ $this->email = $map[ $mapKeyName ];
52
+ }
53
+ if ( PPUtils::array_match_key( $map, $prefix . "phone." ) ) {
54
+ $newPrefix = $prefix . "phone.";
55
+ $this->phone = new PhoneNumberType();
56
+ $this->phone->init( $map, $newPrefix );
57
+ }
58
+
59
+ }
60
+ }
61
+ }
62
+
63
+
64
+ /**
65
+ *
66
+ */
67
+ class BaseAddress
68
+ {
69
+
70
+ /**
71
+ *
72
+ * @access public
73
+ * @var string
74
+ */
75
+ public $line1;
76
+
77
+ /**
78
+ *
79
+ * @access public
80
+ * @var string
81
+ */
82
+ public $line2;
83
+
84
+ /**
85
+ *
86
+ * @access public
87
+ * @var string
88
+ */
89
+ public $city;
90
+
91
+ /**
92
+ *
93
+ * @access public
94
+ * @var string
95
+ */
96
+ public $state;
97
+
98
+ /**
99
+ *
100
+ * @access public
101
+ * @var string
102
+ */
103
+ public $postalCode;
104
+
105
+ /**
106
+ *
107
+ * @access public
108
+ * @var string
109
+ */
110
+ public $countryCode;
111
+
112
+ /**
113
+ *
114
+ * @access public
115
+ * @var string
116
+ */
117
+ public $type;
118
+
119
+
120
+ public function init( $map = null, $prefix = '' )
121
+ {
122
+ if ( $map != null ) {
123
+ $mapKeyName = $prefix . 'line1';
124
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
125
+ $this->line1 = $map[ $mapKeyName ];
126
+ }
127
+ $mapKeyName = $prefix . 'line2';
128
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
129
+ $this->line2 = $map[ $mapKeyName ];
130
+ }
131
+ $mapKeyName = $prefix . 'city';
132
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
133
+ $this->city = $map[ $mapKeyName ];
134
+ }
135
+ $mapKeyName = $prefix . 'state';
136
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
137
+ $this->state = $map[ $mapKeyName ];
138
+ }
139
+ $mapKeyName = $prefix . 'postalCode';
140
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
141
+ $this->postalCode = $map[ $mapKeyName ];
142
+ }
143
+ $mapKeyName = $prefix . 'countryCode';
144
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
145
+ $this->countryCode = $map[ $mapKeyName ];
146
+ }
147
+ $mapKeyName = $prefix . 'type';
148
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
149
+ $this->type = $map[ $mapKeyName ];
150
+ }
151
+
152
+ }
153
+ }
154
+ }
155
+
156
+
157
+ /**
158
+ * Details about the end user of the application invoking this
159
+ * service.
160
+ */
161
+ class ClientDetailsType
162
+ {
163
+
164
+ /**
165
+ *
166
+ * @access public
167
+ * @var string
168
+ */
169
+ public $ipAddress;
170
+
171
+ /**
172
+ *
173
+ * @access public
174
+ * @var string
175
+ */
176
+ public $deviceId;
177
+
178
+ /**
179
+ *
180
+ * @access public
181
+ * @var string
182
+ */
183
+ public $applicationId;
184
+
185
+ /**
186
+ *
187
+ * @access public
188
+ * @var string
189
+ */
190
+ public $model;
191
+
192
+ /**
193
+ *
194
+ * @access public
195
+ * @var string
196
+ */
197
+ public $geoLocation;
198
+
199
+ /**
200
+ *
201
+ * @access public
202
+ * @var string
203
+ */
204
+ public $customerType;
205
+
206
+ /**
207
+ *
208
+ * @access public
209
+ * @var string
210
+ */
211
+ public $partnerName;
212
+
213
+ /**
214
+ *
215
+ * @access public
216
+ * @var string
217
+ */
218
+ public $customerId;
219
+
220
+
221
+ public function toNVPString( $prefix = '' )
222
+ {
223
+ $str = '';
224
+ $delim = '';
225
+ if ( $this->ipAddress != null ) {
226
+ $str .= $delim . $prefix . 'ipAddress=' . urlencode( $this->ipAddress );
227
+ $delim = '&';
228
+ }
229
+ if ( $this->deviceId != null ) {
230
+ $str .= $delim . $prefix . 'deviceId=' . urlencode( $this->deviceId );
231
+ $delim = '&';
232
+ }
233
+ if ( $this->applicationId != null ) {
234
+ $str .= $delim . $prefix . 'applicationId=' . urlencode( $this->applicationId );
235
+ $delim = '&';
236
+ }
237
+ if ( $this->model != null ) {
238
+ $str .= $delim . $prefix . 'model=' . urlencode( $this->model );
239
+ $delim = '&';
240
+ }
241
+ if ( $this->geoLocation != null ) {
242
+ $str .= $delim . $prefix . 'geoLocation=' . urlencode( $this->geoLocation );
243
+ $delim = '&';
244
+ }
245
+ if ( $this->customerType != null ) {
246
+ $str .= $delim . $prefix . 'customerType=' . urlencode( $this->customerType );
247
+ $delim = '&';
248
+ }
249
+ if ( $this->partnerName != null ) {
250
+ $str .= $delim . $prefix . 'partnerName=' . urlencode( $this->partnerName );
251
+ $delim = '&';
252
+ }
253
+ if ( $this->customerId != null ) {
254
+ $str .= $delim . $prefix . 'customerId=' . urlencode( $this->customerId );
255
+ $delim = '&';
256
+ }
257
+
258
+ return $str;
259
+ }
260
+
261
+ }
262
+
263
+
264
+ /**
265
+ *
266
+ */
267
+ class CurrencyType
268
+ {
269
+
270
+ /**
271
+ *
272
+ * @access public
273
+ * @var string
274
+ */
275
+ public $code;
276
+
277
+ /**
278
+ *
279
+ * @access public
280
+ * @var double
281
+ */
282
+ public $amount;
283
+
284
+ /**
285
+ * Constructor with arguments
286
+ */
287
+ public function __construct( $code = null, $amount = null )
288
+ {
289
+ $this->code = $code;
290
+ $this->amount = $amount;
291
+ }
292
+
293
+
294
+ public function toNVPString( $prefix = '' )
295
+ {
296
+ $str = '';
297
+ $delim = '';
298
+ if ( $this->code != null ) {
299
+ $str .= $delim . $prefix . 'code=' . urlencode( $this->code );
300
+ $delim = '&';
301
+ }
302
+ if ( $this->amount != null ) {
303
+ $str .= $delim . $prefix . 'amount=' . urlencode( $this->amount );
304
+ $delim = '&';
305
+ }
306
+
307
+ return $str;
308
+ }
309
+
310
+ public function init( $map = null, $prefix = '' )
311
+ {
312
+ if ( $map != null ) {
313
+ $mapKeyName = $prefix . 'code';
314
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
315
+ $this->code = $map[ $mapKeyName ];
316
+ }
317
+ $mapKeyName = $prefix . 'amount';
318
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
319
+ $this->amount = $map[ $mapKeyName ];
320
+ }
321
+
322
+ }
323
+ }
324
+ }
325
+
326
+
327
+ /**
328
+ * This type contains the detailed error information resulting
329
+ * from the service operation.
330
+ */
331
+ class ErrorData
332
+ {
333
+
334
+ /**
335
+ *
336
+ * @access public
337
+ * @var integer
338
+ */
339
+ public $errorId;
340
+
341
+ /**
342
+ *
343
+ * @access public
344
+ * @var string
345
+ */
346
+ public $domain;
347
+
348
+ /**
349
+ *
350
+ * @access public
351
+ * @var string
352
+ */
353
+ public $subdomain;
354
+
355
+ /**
356
+ *
357
+ * @access public
358
+ * @var ErrorSeverity
359
+ */
360
+ public $severity;
361
+
362
+ /**
363
+ *
364
+ * @access public
365
+ * @var ErrorCategory
366
+ */
367
+ public $category;
368
+
369
+ /**
370
+ *
371
+ * @access public
372
+ * @var string
373
+ */
374
+ public $message;
375
+
376
+ /**
377
+ *
378
+ * @access public
379
+ * @var string
380
+ */
381
+ public $exceptionId;
382
+
383
+ /**
384
+ *
385
+ * @array
386
+ * @access public
387
+ * @var ErrorParameter
388
+ */
389
+ public $parameter;
390
+
391
+
392
+ public function init( $map = null, $prefix = '' )
393
+ {
394
+ if ( $map != null ) {
395
+ $mapKeyName = $prefix . 'errorId';
396
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
397
+ $this->errorId = $map[ $mapKeyName ];
398
+ }
399
+ $mapKeyName = $prefix . 'domain';
400
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
401
+ $this->domain = $map[ $mapKeyName ];
402
+ }
403
+ $mapKeyName = $prefix . 'subdomain';
404
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
405
+ $this->subdomain = $map[ $mapKeyName ];
406
+ }
407
+ $mapKeyName = $prefix . 'severity';
408
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
409
+ $this->severity = $map[ $mapKeyName ];
410
+ }
411
+ $mapKeyName = $prefix . 'category';
412
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
413
+ $this->category = $map[ $mapKeyName ];
414
+ }
415
+ $mapKeyName = $prefix . 'message';
416
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
417
+ $this->message = $map[ $mapKeyName ];
418
+ }
419
+ $mapKeyName = $prefix . 'exceptionId';
420
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
421
+ $this->exceptionId = $map[ $mapKeyName ];
422
+ }
423
+ $i = 0;
424
+ while ( true ) {
425
+ if ( PPUtils::array_match_key( $map, $prefix . "parameter($i)" ) ) {
426
+ $newPrefix = $prefix . "parameter($i).";
427
+ $this->parameter[ $i ] = new ErrorParameter();
428
+ $this->parameter[ $i ]->init( $map, $newPrefix );
429
+ } else {
430
+ break;
431
+ }
432
+ $i++;
433
+ }
434
+
435
+ }
436
+ }
437
+ }
438
+
439
+
440
+ /**
441
+ *
442
+ */
443
+ class ErrorParameter
444
+ {
445
+
446
+ /**
447
+ *
448
+ * @access public
449
+ * @var string
450
+ */
451
+ public $name;
452
+
453
+ /**
454
+ *
455
+ * @access public
456
+ * @var string
457
+ */
458
+ public $value;
459
+
460
+
461
+ public function init( $map = null, $prefix = '' )
462
+ {
463
+ if ( $map != null ) {
464
+ $mapKeyName = $prefix . 'name';
465
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
466
+ $this->name = $map[ $mapKeyName ];
467
+ }
468
+ $mapKeyName = $prefix . 'value';
469
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
470
+ $this->value = $map[ $mapKeyName ];
471
+ }
472
+
473
+ }
474
+ }
475
+ }
476
+
477
+
478
+ /**
479
+ * This specifies a fault, encapsulating error data, with
480
+ * specific error codes.
481
+ */
482
+ class FaultMessage
483
+ {
484
+
485
+ /**
486
+ *
487
+ * @access public
488
+ * @var ResponseEnvelope
489
+ */
490
+ public $responseEnvelope;
491
+
492
+ /**
493
+ *
494
+ * @array
495
+ * @access public
496
+ * @var ErrorData
497
+ */
498
+ public $error;
499
+
500
+
501
+ public function init( $map = null, $prefix = '' )
502
+ {
503
+ if ( $map != null ) {
504
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
505
+ $newPrefix = $prefix . "responseEnvelope.";
506
+ $this->responseEnvelope = new ResponseEnvelope();
507
+ $this->responseEnvelope->init( $map, $newPrefix );
508
+ }
509
+ $i = 0;
510
+ while ( true ) {
511
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
512
+ $newPrefix = $prefix . "error($i).";
513
+ $this->error[ $i ] = new ErrorData();
514
+ $this->error[ $i ]->init( $map, $newPrefix );
515
+ } else {
516
+ break;
517
+ }
518
+ $i++;
519
+ }
520
+
521
+ }
522
+ }
523
+ }
524
+
525
+
526
+ /**
527
+ *
528
+ */
529
+ class PhoneNumberType
530
+ {
531
+
532
+ /**
533
+ *
534
+ * @access public
535
+ * @var string
536
+ */
537
+ public $countryCode;
538
+
539
+ /**
540
+ *
541
+ * @access public
542
+ * @var string
543
+ */
544
+ public $phoneNumber;
545
+
546
+ /**
547
+ *
548
+ * @access public
549
+ * @var string
550
+ */
551
+ public $extension;
552
+
553
+ /**
554
+ * Constructor with arguments
555
+ */
556
+ public function __construct( $countryCode = null, $phoneNumber = null )
557
+ {
558
+ $this->countryCode = $countryCode;
559
+ $this->phoneNumber = $phoneNumber;
560
+ }
561
+
562
+
563
+ public function toNVPString( $prefix = '' )
564
+ {
565
+ $str = '';
566
+ $delim = '';
567
+ if ( $this->countryCode != null ) {
568
+ $str .= $delim . $prefix . 'countryCode=' . urlencode( $this->countryCode );
569
+ $delim = '&';
570
+ }
571
+ if ( $this->phoneNumber != null ) {
572
+ $str .= $delim . $prefix . 'phoneNumber=' . urlencode( $this->phoneNumber );
573
+ $delim = '&';
574
+ }
575
+ if ( $this->extension != null ) {
576
+ $str .= $delim . $prefix . 'extension=' . urlencode( $this->extension );
577
+ $delim = '&';
578
+ }
579
+
580
+ return $str;
581
+ }
582
+
583
+ public function init( $map = null, $prefix = '' )
584
+ {
585
+ if ( $map != null ) {
586
+ $mapKeyName = $prefix . 'countryCode';
587
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
588
+ $this->countryCode = $map[ $mapKeyName ];
589
+ }
590
+ $mapKeyName = $prefix . 'phoneNumber';
591
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
592
+ $this->phoneNumber = $map[ $mapKeyName ];
593
+ }
594
+ $mapKeyName = $prefix . 'extension';
595
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
596
+ $this->extension = $map[ $mapKeyName ];
597
+ }
598
+
599
+ }
600
+ }
601
+ }
602
+
603
+
604
+ /**
605
+ * This specifies the list of parameters with every request to
606
+ * the service.
607
+ */
608
+ class RequestEnvelope
609
+ {
610
+
611
+ /**
612
+ * This specifies the required detail level that is needed by a
613
+ * client application pertaining to a particular data component
614
+ * (e.g., Item, Transaction, etc.). The detail level is
615
+ * specified in the DetailLevelCodeType which has all the
616
+ * enumerated values of the detail level for each component.
617
+ * @access public
618
+ * @var DetailLevelCode
619
+ */
620
+ public $detailLevel;
621
+
622
+ /**
623
+ * This should be the standard RFC 3066 language identification
624
+ * tag, e.g., en_US.
625
+ * @access public
626
+ * @var string
627
+ */
628
+ public $errorLanguage;
629
+
630
+ /**
631
+ * Constructor with arguments
632
+ */
633
+ public function __construct( $errorLanguage = null )
634
+ {
635
+ $this->errorLanguage = $errorLanguage;
636
+ }
637
+
638
+
639
+ public function toNVPString( $prefix = '' )
640
+ {
641
+ $str = '';
642
+ $delim = '';
643
+ if ( $this->detailLevel != null ) {
644
+ $str .= $delim . $prefix . 'detailLevel=' . urlencode( $this->detailLevel );
645
+ $delim = '&';
646
+ }
647
+ if ( $this->errorLanguage != null ) {
648
+ $str .= $delim . $prefix . 'errorLanguage=' . urlencode( $this->errorLanguage );
649
+ $delim = '&';
650
+ }
651
+
652
+ return $str;
653
+ }
654
+
655
+ }
656
+
657
+
658
+ /**
659
+ * This specifies a list of parameters with every response from
660
+ * a service.
661
+ */
662
+ class ResponseEnvelope
663
+ {
664
+
665
+ /**
666
+ *
667
+ * @access public
668
+ * @var dateTime
669
+ */
670
+ public $timestamp;
671
+
672
+ /**
673
+ * Application level acknowledgment code.
674
+ * @access public
675
+ * @var AckCode
676
+ */
677
+ public $ack;
678
+
679
+ /**
680
+ *
681
+ * @access public
682
+ * @var string
683
+ */
684
+ public $correlationId;
685
+
686
+ /**
687
+ *
688
+ * @access public
689
+ * @var string
690
+ */
691
+ public $build;
692
+
693
+
694
+ public function init( $map = null, $prefix = '' )
695
+ {
696
+ if ( $map != null ) {
697
+ $mapKeyName = $prefix . 'timestamp';
698
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
699
+ $this->timestamp = $map[ $mapKeyName ];
700
+ }
701
+ $mapKeyName = $prefix . 'ack';
702
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
703
+ $this->ack = $map[ $mapKeyName ];
704
+ }
705
+ $mapKeyName = $prefix . 'correlationId';
706
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
707
+ $this->correlationId = $map[ $mapKeyName ];
708
+ }
709
+ $mapKeyName = $prefix . 'build';
710
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
711
+ $this->build = $map[ $mapKeyName ];
712
+ }
713
+
714
+ }
715
+ }
716
+ }
717
+
718
+
719
+ /**
720
+ *
721
+ */
722
+ class Address
723
+ {
724
+
725
+ /**
726
+ *
727
+ * @access public
728
+ * @var string
729
+ */
730
+ public $addresseeName;
731
+
732
+ /**
733
+ *
734
+ * @access public
735
+ * @var BaseAddress
736
+ */
737
+ public $baseAddress;
738
+
739
+ /**
740
+ *
741
+ * @access public
742
+ * @var string
743
+ */
744
+ public $addressId;
745
+
746
+
747
+ public function init( $map = null, $prefix = '' )
748
+ {
749
+ if ( $map != null ) {
750
+ $mapKeyName = $prefix . 'addresseeName';
751
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
752
+ $this->addresseeName = $map[ $mapKeyName ];
753
+ }
754
+ if ( PPUtils::array_match_key( $map, $prefix . "baseAddress." ) ) {
755
+ $newPrefix = $prefix . "baseAddress.";
756
+ $this->baseAddress = new BaseAddress();
757
+ $this->baseAddress->init( $map, $newPrefix );
758
+ }
759
+ $mapKeyName = $prefix . 'addressId';
760
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
761
+ $this->addressId = $map[ $mapKeyName ];
762
+ }
763
+
764
+ }
765
+ }
766
+ }
767
+
768
+
769
+ /**
770
+ *
771
+ */
772
+ class AddressList
773
+ {
774
+
775
+ /**
776
+ *
777
+ * @array
778
+ * @access public
779
+ * @var Address
780
+ */
781
+ public $address;
782
+
783
+
784
+ public function init( $map = null, $prefix = '' )
785
+ {
786
+ if ( $map != null ) {
787
+ $i = 0;
788
+ while ( true ) {
789
+ if ( PPUtils::array_match_key( $map, $prefix . "address($i)" ) ) {
790
+ $newPrefix = $prefix . "address($i).";
791
+ $this->address[ $i ] = new Address();
792
+ $this->address[ $i ]->init( $map, $newPrefix );
793
+ } else {
794
+ break;
795
+ }
796
+ $i++;
797
+ }
798
+
799
+ }
800
+ }
801
+ }
802
+
803
+
804
+ /**
805
+ * A list of ISO currency codes.
806
+ */
807
+ class CurrencyCodeList
808
+ {
809
+
810
+ /**
811
+ *
812
+ * @array
813
+ * @access public
814
+ * @var string
815
+ */
816
+ public $currencyCode;
817
+
818
+ /**
819
+ * Constructor with arguments
820
+ */
821
+ public function __construct( $currencyCode = null )
822
+ {
823
+ $this->currencyCode = $currencyCode;
824
+ }
825
+
826
+
827
+ public function toNVPString( $prefix = '' )
828
+ {
829
+ $str = '';
830
+ $delim = '';
831
+ for ( $i = 0; $i < count( $this->currencyCode ); $i++ ) {
832
+ $str .= $delim . $prefix . "currencyCode($i)=" . urlencode( $this->currencyCode[ $i ] );
833
+ $delim = '&';
834
+ }
835
+
836
+ return $str;
837
+ }
838
+
839
+ }
840
+
841
+
842
+ /**
843
+ * A list of estimated currency conversions for a base
844
+ * currency.
845
+ */
846
+ class CurrencyConversionList
847
+ {
848
+
849
+ /**
850
+ *
851
+ * @access public
852
+ * @var CurrencyType
853
+ */
854
+ public $baseAmount;
855
+
856
+ /**
857
+ *
858
+ * @access public
859
+ * @var CurrencyList
860
+ */
861
+ public $currencyList;
862
+
863
+
864
+ public function init( $map = null, $prefix = '' )
865
+ {
866
+ if ( $map != null ) {
867
+ if ( PPUtils::array_match_key( $map, $prefix . "baseAmount." ) ) {
868
+ $newPrefix = $prefix . "baseAmount.";
869
+ $this->baseAmount = new CurrencyType();
870
+ $this->baseAmount->init( $map, $newPrefix );
871
+ }
872
+ if ( PPUtils::array_match_key( $map, $prefix . "currencyList." ) ) {
873
+ $newPrefix = $prefix . "currencyList.";
874
+ $this->currencyList = new CurrencyList();
875
+ $this->currencyList->init( $map, $newPrefix );
876
+ }
877
+
878
+ }
879
+ }
880
+ }
881
+
882
+
883
+ /**
884
+ * A table that contains a list of estimated currency
885
+ * conversions for a base currency in each row.
886
+ */
887
+ class CurrencyConversionTable
888
+ {
889
+
890
+ /**
891
+ *
892
+ * @array
893
+ * @access public
894
+ * @var CurrencyConversionList
895
+ */
896
+ public $currencyConversionList;
897
+
898
+
899
+ public function init( $map = null, $prefix = '' )
900
+ {
901
+ if ( $map != null ) {
902
+ $i = 0;
903
+ while ( true ) {
904
+ if ( PPUtils::array_match_key( $map, $prefix . "currencyConversionList($i)" ) ) {
905
+ $newPrefix = $prefix . "currencyConversionList($i).";
906
+ $this->currencyConversionList[ $i ] = new CurrencyConversionList();
907
+ $this->currencyConversionList[ $i ]->init( $map, $newPrefix );
908
+ } else {
909
+ break;
910
+ }
911
+ $i++;
912
+ }
913
+
914
+ }
915
+ }
916
+ }
917
+
918
+
919
+ /**
920
+ * A list of ISO currencies.
921
+ */
922
+ class CurrencyList
923
+ {
924
+
925
+ /**
926
+ *
927
+ * @array
928
+ * @access public
929
+ * @var CurrencyType
930
+ */
931
+ public $currency;
932
+
933
+ /**
934
+ * Constructor with arguments
935
+ */
936
+ public function __construct( $currency = null )
937
+ {
938
+ $this->currency = $currency;
939
+ }
940
+
941
+
942
+ public function toNVPString( $prefix = '' )
943
+ {
944
+ $str = '';
945
+ $delim = '';
946
+ for ( $i = 0; $i < count( $this->currency ); $i++ ) {
947
+ $newPrefix = $prefix . "currency($i).";
948
+ $str .= $delim . call_user_func( array( $this->currency[ $i ], 'toNVPString' ), $newPrefix );
949
+ $delim = '&';
950
+ }
951
+
952
+ return $str;
953
+ }
954
+
955
+ public function init( $map = null, $prefix = '' )
956
+ {
957
+ if ( $map != null ) {
958
+ $i = 0;
959
+ while ( true ) {
960
+ if ( PPUtils::array_match_key( $map, $prefix . "currency($i)" ) ) {
961
+ $newPrefix = $prefix . "currency($i).";
962
+ $this->currency[ $i ] = new CurrencyType();
963
+ $this->currency[ $i ]->init( $map, $newPrefix );
964
+ } else {
965
+ break;
966
+ }
967
+ $i++;
968
+ }
969
+
970
+ }
971
+ }
972
+ }
973
+
974
+
975
+ /**
976
+ * Customizable options that a client application can specify
977
+ * for display purposes.
978
+ */
979
+ class DisplayOptions
980
+ {
981
+
982
+ /**
983
+ *
984
+ * @access public
985
+ * @var string
986
+ */
987
+ public $emailHeaderImageUrl;
988
+
989
+ /**
990
+ *
991
+ * @access public
992
+ * @var string
993
+ */
994
+ public $emailMarketingImageUrl;
995
+
996
+ /**
997
+ *
998
+ * @access public
999
+ * @var string
1000
+ */
1001
+ public $headerImageUrl;
1002
+
1003
+ /**
1004
+ *
1005
+ * @access public
1006
+ * @var string
1007
+ */
1008
+ public $businessName;
1009
+
1010
+
1011
+ public function toNVPString( $prefix = '' )
1012
+ {
1013
+ $str = '';
1014
+ $delim = '';
1015
+ if ( $this->emailHeaderImageUrl != null ) {
1016
+ $str .= $delim . $prefix . 'emailHeaderImageUrl=' . urlencode( $this->emailHeaderImageUrl );
1017
+ $delim = '&';
1018
+ }
1019
+ if ( $this->emailMarketingImageUrl != null ) {
1020
+ $str .= $delim . $prefix . 'emailMarketingImageUrl=' . urlencode( $this->emailMarketingImageUrl );
1021
+ $delim = '&';
1022
+ }
1023
+ if ( $this->headerImageUrl != null ) {
1024
+ $str .= $delim . $prefix . 'headerImageUrl=' . urlencode( $this->headerImageUrl );
1025
+ $delim = '&';
1026
+ }
1027
+ if ( $this->businessName != null ) {
1028
+ $str .= $delim . $prefix . 'businessName=' . urlencode( $this->businessName );
1029
+ $delim = '&';
1030
+ }
1031
+
1032
+ return $str;
1033
+ }
1034
+
1035
+ public function init( $map = null, $prefix = '' )
1036
+ {
1037
+ if ( $map != null ) {
1038
+ $mapKeyName = $prefix . 'emailHeaderImageUrl';
1039
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1040
+ $this->emailHeaderImageUrl = $map[ $mapKeyName ];
1041
+ }
1042
+ $mapKeyName = $prefix . 'emailMarketingImageUrl';
1043
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1044
+ $this->emailMarketingImageUrl = $map[ $mapKeyName ];
1045
+ }
1046
+ $mapKeyName = $prefix . 'headerImageUrl';
1047
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1048
+ $this->headerImageUrl = $map[ $mapKeyName ];
1049
+ }
1050
+ $mapKeyName = $prefix . 'businessName';
1051
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1052
+ $this->businessName = $map[ $mapKeyName ];
1053
+ }
1054
+
1055
+ }
1056
+ }
1057
+ }
1058
+
1059
+
1060
+ /**
1061
+ *
1062
+ */
1063
+ class ErrorList
1064
+ {
1065
+
1066
+ /**
1067
+ *
1068
+ * @array
1069
+ * @access public
1070
+ * @var ErrorData
1071
+ */
1072
+ public $error;
1073
+
1074
+
1075
+ public function init( $map = null, $prefix = '' )
1076
+ {
1077
+ if ( $map != null ) {
1078
+ $i = 0;
1079
+ while ( true ) {
1080
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
1081
+ $newPrefix = $prefix . "error($i).";
1082
+ $this->error[ $i ] = new ErrorData();
1083
+ $this->error[ $i ]->init( $map, $newPrefix );
1084
+ } else {
1085
+ break;
1086
+ }
1087
+ $i++;
1088
+ }
1089
+
1090
+ }
1091
+ }
1092
+ }
1093
+
1094
+
1095
+ /**
1096
+ *
1097
+ */
1098
+ class FundingConstraint
1099
+ {
1100
+
1101
+ /**
1102
+ *
1103
+ * @access public
1104
+ * @var FundingTypeList
1105
+ */
1106
+ public $allowedFundingType;
1107
+
1108
+
1109
+ public function toNVPString( $prefix = '' )
1110
+ {
1111
+ $str = '';
1112
+ $delim = '';
1113
+ if ( $this->allowedFundingType != null ) {
1114
+ $newPrefix = $prefix . 'allowedFundingType.';
1115
+ $str .= $delim . call_user_func( array( $this->allowedFundingType, 'toNVPString' ), $newPrefix );
1116
+ $delim = '&';
1117
+ }
1118
+
1119
+ return $str;
1120
+ }
1121
+
1122
+ public function init( $map = null, $prefix = '' )
1123
+ {
1124
+ if ( $map != null ) {
1125
+ if ( PPUtils::array_match_key( $map, $prefix . "allowedFundingType." ) ) {
1126
+ $newPrefix = $prefix . "allowedFundingType.";
1127
+ $this->allowedFundingType = new FundingTypeList();
1128
+ $this->allowedFundingType->init( $map, $newPrefix );
1129
+ }
1130
+
1131
+ }
1132
+ }
1133
+ }
1134
+
1135
+
1136
+ /**
1137
+ * FundingTypeInfo represents one allowed funding type.
1138
+ */
1139
+ class FundingTypeInfo
1140
+ {
1141
+
1142
+ /**
1143
+ *
1144
+ * @access public
1145
+ * @var string
1146
+ */
1147
+ public $fundingType;
1148
+
1149
+ /**
1150
+ * Constructor with arguments
1151
+ */
1152
+ public function __construct( $fundingType = null )
1153
+ {
1154
+ $this->fundingType = $fundingType;
1155
+ }
1156
+
1157
+
1158
+ public function toNVPString( $prefix = '' )
1159
+ {
1160
+ $str = '';
1161
+ $delim = '';
1162
+ if ( $this->fundingType != null ) {
1163
+ $str .= $delim . $prefix . 'fundingType=' . urlencode( $this->fundingType );
1164
+ $delim = '&';
1165
+ }
1166
+
1167
+ return $str;
1168
+ }
1169
+
1170
+ public function init( $map = null, $prefix = '' )
1171
+ {
1172
+ if ( $map != null ) {
1173
+ $mapKeyName = $prefix . 'fundingType';
1174
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1175
+ $this->fundingType = $map[ $mapKeyName ];
1176
+ }
1177
+
1178
+ }
1179
+ }
1180
+ }
1181
+
1182
+
1183
+ /**
1184
+ *
1185
+ */
1186
+ class FundingTypeList
1187
+ {
1188
+
1189
+ /**
1190
+ *
1191
+ * @array
1192
+ * @access public
1193
+ * @var FundingTypeInfo
1194
+ */
1195
+ public $fundingTypeInfo;
1196
+
1197
+ /**
1198
+ * Constructor with arguments
1199
+ */
1200
+ public function __construct( $fundingTypeInfo = null )
1201
+ {
1202
+ $this->fundingTypeInfo = $fundingTypeInfo;
1203
+ }
1204
+
1205
+
1206
+ public function toNVPString( $prefix = '' )
1207
+ {
1208
+ $str = '';
1209
+ $delim = '';
1210
+ for ( $i = 0; $i < count( $this->fundingTypeInfo ); $i++ ) {
1211
+ $newPrefix = $prefix . "fundingTypeInfo($i).";
1212
+ $str .= $delim . call_user_func( array( $this->fundingTypeInfo[ $i ], 'toNVPString' ), $newPrefix );
1213
+ $delim = '&';
1214
+ }
1215
+
1216
+ return $str;
1217
+ }
1218
+
1219
+ public function init( $map = null, $prefix = '' )
1220
+ {
1221
+ if ( $map != null ) {
1222
+ $i = 0;
1223
+ while ( true ) {
1224
+ if ( PPUtils::array_match_key( $map, $prefix . "fundingTypeInfo($i)" ) ) {
1225
+ $newPrefix = $prefix . "fundingTypeInfo($i).";
1226
+ $this->fundingTypeInfo[ $i ] = new FundingTypeInfo();
1227
+ $this->fundingTypeInfo[ $i ]->init( $map, $newPrefix );
1228
+ } else {
1229
+ break;
1230
+ }
1231
+ $i++;
1232
+ }
1233
+
1234
+ }
1235
+ }
1236
+ }
1237
+
1238
+
1239
+ /**
1240
+ * Describes the conversion between 2 currencies.
1241
+ */
1242
+ class CurrencyConversion
1243
+ {
1244
+
1245
+ /**
1246
+ *
1247
+ * @access public
1248
+ * @var CurrencyType
1249
+ */
1250
+ public $from;
1251
+
1252
+ /**
1253
+ *
1254
+ * @access public
1255
+ * @var CurrencyType
1256
+ */
1257
+ public $to;
1258
+
1259
+ /**
1260
+ *
1261
+ * @access public
1262
+ * @var double
1263
+ */
1264
+ public $exchangeRate;
1265
+
1266
+
1267
+ public function init( $map = null, $prefix = '' )
1268
+ {
1269
+ if ( $map != null ) {
1270
+ if ( PPUtils::array_match_key( $map, $prefix . "from." ) ) {
1271
+ $newPrefix = $prefix . "from.";
1272
+ $this->from = new CurrencyType();
1273
+ $this->from->init( $map, $newPrefix );
1274
+ }
1275
+ if ( PPUtils::array_match_key( $map, $prefix . "to." ) ) {
1276
+ $newPrefix = $prefix . "to.";
1277
+ $this->to = new CurrencyType();
1278
+ $this->to->init( $map, $newPrefix );
1279
+ }
1280
+ $mapKeyName = $prefix . 'exchangeRate';
1281
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1282
+ $this->exchangeRate = $map[ $mapKeyName ];
1283
+ }
1284
+
1285
+ }
1286
+ }
1287
+ }
1288
+
1289
+
1290
+ /**
1291
+ * Funding source information.
1292
+ */
1293
+ class FundingSource
1294
+ {
1295
+
1296
+ /**
1297
+ *
1298
+ * @access public
1299
+ * @var string
1300
+ */
1301
+ public $lastFourOfAccountNumber;
1302
+
1303
+ /**
1304
+ *
1305
+ * @access public
1306
+ * @var string
1307
+ */
1308
+ public $type;
1309
+
1310
+ /**
1311
+ *
1312
+ * @access public
1313
+ * @var string
1314
+ */
1315
+ public $displayName;
1316
+
1317
+ /**
1318
+ *
1319
+ * @access public
1320
+ * @var string
1321
+ */
1322
+ public $fundingSourceId;
1323
+
1324
+ /**
1325
+ *
1326
+ * @access public
1327
+ * @var boolean
1328
+ */
1329
+ public $allowed;
1330
+
1331
+
1332
+ public function init( $map = null, $prefix = '' )
1333
+ {
1334
+ if ( $map != null ) {
1335
+ $mapKeyName = $prefix . 'lastFourOfAccountNumber';
1336
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1337
+ $this->lastFourOfAccountNumber = $map[ $mapKeyName ];
1338
+ }
1339
+ $mapKeyName = $prefix . 'type';
1340
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1341
+ $this->type = $map[ $mapKeyName ];
1342
+ }
1343
+ $mapKeyName = $prefix . 'displayName';
1344
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1345
+ $this->displayName = $map[ $mapKeyName ];
1346
+ }
1347
+ $mapKeyName = $prefix . 'fundingSourceId';
1348
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1349
+ $this->fundingSourceId = $map[ $mapKeyName ];
1350
+ }
1351
+ $mapKeyName = $prefix . 'allowed';
1352
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1353
+ $this->allowed = $map[ $mapKeyName ];
1354
+ }
1355
+
1356
+ }
1357
+ }
1358
+ }
1359
+
1360
+
1361
+ /**
1362
+ * Amount to be charged to a particular funding source.
1363
+ */
1364
+ class FundingPlanCharge
1365
+ {
1366
+
1367
+ /**
1368
+ *
1369
+ * @access public
1370
+ * @var CurrencyType
1371
+ */
1372
+ public $charge;
1373
+
1374
+ /**
1375
+ *
1376
+ * @access public
1377
+ * @var FundingSource
1378
+ */
1379
+ public $fundingSource;
1380
+
1381
+
1382
+ public function init( $map = null, $prefix = '' )
1383
+ {
1384
+ if ( $map != null ) {
1385
+ if ( PPUtils::array_match_key( $map, $prefix . "charge." ) ) {
1386
+ $newPrefix = $prefix . "charge.";
1387
+ $this->charge = new CurrencyType();
1388
+ $this->charge->init( $map, $newPrefix );
1389
+ }
1390
+ if ( PPUtils::array_match_key( $map, $prefix . "fundingSource." ) ) {
1391
+ $newPrefix = $prefix . "fundingSource.";
1392
+ $this->fundingSource = new FundingSource();
1393
+ $this->fundingSource->init( $map, $newPrefix );
1394
+ }
1395
+
1396
+ }
1397
+ }
1398
+ }
1399
+
1400
+
1401
+ /**
1402
+ * FundingPlan describes the funding sources to be used for a
1403
+ * specific payment.
1404
+ */
1405
+ class FundingPlan
1406
+ {
1407
+
1408
+ /**
1409
+ *
1410
+ * @access public
1411
+ * @var string
1412
+ */
1413
+ public $fundingPlanId;
1414
+
1415
+ /**
1416
+ *
1417
+ * @access public
1418
+ * @var CurrencyType
1419
+ */
1420
+ public $fundingAmount;
1421
+
1422
+ /**
1423
+ *
1424
+ * @access public
1425
+ * @var FundingSource
1426
+ */
1427
+ public $backupFundingSource;
1428
+
1429
+ /**
1430
+ *
1431
+ * @access public
1432
+ * @var CurrencyType
1433
+ */
1434
+ public $senderFees;
1435
+
1436
+ /**
1437
+ *
1438
+ * @access public
1439
+ * @var CurrencyConversion
1440
+ */
1441
+ public $currencyConversion;
1442
+
1443
+ /**
1444
+ *
1445
+ * @array
1446
+ * @access public
1447
+ * @var FundingPlanCharge
1448
+ */
1449
+ public $charge;
1450
+
1451
+
1452
+ public function init( $map = null, $prefix = '' )
1453
+ {
1454
+ if ( $map != null ) {
1455
+ $mapKeyName = $prefix . 'fundingPlanId';
1456
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1457
+ $this->fundingPlanId = $map[ $mapKeyName ];
1458
+ }
1459
+ if ( PPUtils::array_match_key( $map, $prefix . "fundingAmount." ) ) {
1460
+ $newPrefix = $prefix . "fundingAmount.";
1461
+ $this->fundingAmount = new CurrencyType();
1462
+ $this->fundingAmount->init( $map, $newPrefix );
1463
+ }
1464
+ if ( PPUtils::array_match_key( $map, $prefix . "backupFundingSource." ) ) {
1465
+ $newPrefix = $prefix . "backupFundingSource.";
1466
+ $this->backupFundingSource = new FundingSource();
1467
+ $this->backupFundingSource->init( $map, $newPrefix );
1468
+ }
1469
+ if ( PPUtils::array_match_key( $map, $prefix . "senderFees." ) ) {
1470
+ $newPrefix = $prefix . "senderFees.";
1471
+ $this->senderFees = new CurrencyType();
1472
+ $this->senderFees->init( $map, $newPrefix );
1473
+ }
1474
+ if ( PPUtils::array_match_key( $map, $prefix . "currencyConversion." ) ) {
1475
+ $newPrefix = $prefix . "currencyConversion.";
1476
+ $this->currencyConversion = new CurrencyConversion();
1477
+ $this->currencyConversion->init( $map, $newPrefix );
1478
+ }
1479
+ $i = 0;
1480
+ while ( true ) {
1481
+ if ( PPUtils::array_match_key( $map, $prefix . "charge($i)" ) ) {
1482
+ $newPrefix = $prefix . "charge($i).";
1483
+ $this->charge[ $i ] = new FundingPlanCharge();
1484
+ $this->charge[ $i ]->init( $map, $newPrefix );
1485
+ } else {
1486
+ break;
1487
+ }
1488
+ $i++;
1489
+ }
1490
+
1491
+ }
1492
+ }
1493
+ }
1494
+
1495
+
1496
+ /**
1497
+ * Details about the party that initiated this payment. The API
1498
+ * user is making this payment on behalf of the initiator. The
1499
+ * initiator can simply be an institution or a customer of the
1500
+ * institution.
1501
+ */
1502
+ class InitiatingEntity
1503
+ {
1504
+
1505
+ /**
1506
+ *
1507
+ * @access public
1508
+ * @var InstitutionCustomer
1509
+ */
1510
+ public $institutionCustomer;
1511
+
1512
+
1513
+ public function toNVPString( $prefix = '' )
1514
+ {
1515
+ $str = '';
1516
+ $delim = '';
1517
+ if ( $this->institutionCustomer != null ) {
1518
+ $newPrefix = $prefix . 'institutionCustomer.';
1519
+ $str .= $delim . call_user_func( array( $this->institutionCustomer, 'toNVPString' ), $newPrefix );
1520
+ $delim = '&';
1521
+ }
1522
+
1523
+ return $str;
1524
+ }
1525
+
1526
+ public function init( $map = null, $prefix = '' )
1527
+ {
1528
+ if ( $map != null ) {
1529
+ if ( PPUtils::array_match_key( $map, $prefix . "institutionCustomer." ) ) {
1530
+ $newPrefix = $prefix . "institutionCustomer.";
1531
+ $this->institutionCustomer = new InstitutionCustomer();
1532
+ $this->institutionCustomer->init( $map, $newPrefix );
1533
+ }
1534
+
1535
+ }
1536
+ }
1537
+ }
1538
+
1539
+
1540
+ /**
1541
+ * The customer of the initiating institution
1542
+ */
1543
+ class InstitutionCustomer
1544
+ {
1545
+
1546
+ /**
1547
+ * The unique identifier as assigned to the institution.
1548
+ * @access public
1549
+ * @var string
1550
+ */
1551
+ public $institutionId;
1552
+
1553
+ /**
1554
+ * The first (given) name of the end consumer as known by the
1555
+ * institution.
1556
+ * @access public
1557
+ * @var string
1558
+ */
1559
+ public $firstName;
1560
+
1561
+ /**
1562
+ * The last (family) name of the end consumer as known by the
1563
+ * institution.
1564
+ * @access public
1565
+ * @var string
1566
+ */
1567
+ public $lastName;
1568
+
1569
+ /**
1570
+ * The full name of the end consumer as known by the
1571
+ * institution.
1572
+ * @access public
1573
+ * @var string
1574
+ */
1575
+ public $displayName;
1576
+
1577
+ /**
1578
+ * The unique identifier as assigned to the end consumer by the
1579
+ * institution.
1580
+ * @access public
1581
+ * @var string
1582
+ */
1583
+ public $institutionCustomerId;
1584
+
1585
+ /**
1586
+ * The two-character ISO country code of the home country of
1587
+ * the end consumer
1588
+ * @access public
1589
+ * @var string
1590
+ */
1591
+ public $countryCode;
1592
+
1593
+ /**
1594
+ *
1595
+ * @access public
1596
+ * @var string
1597
+ */
1598
+ public $email;
1599
+
1600
+ /**
1601
+ * Constructor with arguments
1602
+ */
1603
+ public function __construct( $institutionId = null, $firstName = null, $lastName = null, $displayName = null, $institutionCustomerId = null, $countryCode = null )
1604
+ {
1605
+ $this->institutionId = $institutionId;
1606
+ $this->firstName = $firstName;
1607
+ $this->lastName = $lastName;
1608
+ $this->displayName = $displayName;
1609
+ $this->institutionCustomerId = $institutionCustomerId;
1610
+ $this->countryCode = $countryCode;
1611
+ }
1612
+
1613
+
1614
+ public function toNVPString( $prefix = '' )
1615
+ {
1616
+ $str = '';
1617
+ $delim = '';
1618
+ if ( $this->institutionId != null ) {
1619
+ $str .= $delim . $prefix . 'institutionId=' . urlencode( $this->institutionId );
1620
+ $delim = '&';
1621
+ }
1622
+ if ( $this->firstName != null ) {
1623
+ $str .= $delim . $prefix . 'firstName=' . urlencode( $this->firstName );
1624
+ $delim = '&';
1625
+ }
1626
+ if ( $this->lastName != null ) {
1627
+ $str .= $delim . $prefix . 'lastName=' . urlencode( $this->lastName );
1628
+ $delim = '&';
1629
+ }
1630
+ if ( $this->displayName != null ) {
1631
+ $str .= $delim . $prefix . 'displayName=' . urlencode( $this->displayName );
1632
+ $delim = '&';
1633
+ }
1634
+ if ( $this->institutionCustomerId != null ) {
1635
+ $str .= $delim . $prefix . 'institutionCustomerId=' . urlencode( $this->institutionCustomerId );
1636
+ $delim = '&';
1637
+ }
1638
+ if ( $this->countryCode != null ) {
1639
+ $str .= $delim . $prefix . 'countryCode=' . urlencode( $this->countryCode );
1640
+ $delim = '&';
1641
+ }
1642
+ if ( $this->email != null ) {
1643
+ $str .= $delim . $prefix . 'email=' . urlencode( $this->email );
1644
+ $delim = '&';
1645
+ }
1646
+
1647
+ return $str;
1648
+ }
1649
+
1650
+ public function init( $map = null, $prefix = '' )
1651
+ {
1652
+ if ( $map != null ) {
1653
+ $mapKeyName = $prefix . 'institutionId';
1654
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1655
+ $this->institutionId = $map[ $mapKeyName ];
1656
+ }
1657
+ $mapKeyName = $prefix . 'firstName';
1658
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1659
+ $this->firstName = $map[ $mapKeyName ];
1660
+ }
1661
+ $mapKeyName = $prefix . 'lastName';
1662
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1663
+ $this->lastName = $map[ $mapKeyName ];
1664
+ }
1665
+ $mapKeyName = $prefix . 'displayName';
1666
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1667
+ $this->displayName = $map[ $mapKeyName ];
1668
+ }
1669
+ $mapKeyName = $prefix . 'institutionCustomerId';
1670
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1671
+ $this->institutionCustomerId = $map[ $mapKeyName ];
1672
+ }
1673
+ $mapKeyName = $prefix . 'countryCode';
1674
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1675
+ $this->countryCode = $map[ $mapKeyName ];
1676
+ }
1677
+ $mapKeyName = $prefix . 'email';
1678
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1679
+ $this->email = $map[ $mapKeyName ];
1680
+ }
1681
+
1682
+ }
1683
+ }
1684
+ }
1685
+
1686
+
1687
+ /**
1688
+ * Describes an individual item for an invoice.
1689
+ */
1690
+ class InvoiceItem
1691
+ {
1692
+
1693
+ /**
1694
+ *
1695
+ * @access public
1696
+ * @var string
1697
+ */
1698
+ public $name;
1699
+
1700
+ /**
1701
+ *
1702
+ * @access public
1703
+ * @var string
1704
+ */
1705
+ public $identifier;
1706
+
1707
+ /**
1708
+ *
1709
+ * @access public
1710
+ * @var double
1711
+ */
1712
+ public $price;
1713
+
1714
+ /**
1715
+ *
1716
+ * @access public
1717
+ * @var double
1718
+ */
1719
+ public $itemPrice;
1720
+
1721
+ /**
1722
+ *
1723
+ * @access public
1724
+ * @var integer
1725
+ */
1726
+ public $itemCount;
1727
+
1728
+
1729
+ public function toNVPString( $prefix = '' )
1730
+ {
1731
+ $str = '';
1732
+ $delim = '';
1733
+ if ( $this->name != null ) {
1734
+ $str .= $delim . $prefix . 'name=' . urlencode( $this->name );
1735
+ $delim = '&';
1736
+ }
1737
+ if ( $this->identifier != null ) {
1738
+ $str .= $delim . $prefix . 'identifier=' . urlencode( $this->identifier );
1739
+ $delim = '&';
1740
+ }
1741
+ if ( $this->price != null ) {
1742
+ $str .= $delim . $prefix . 'price=' . urlencode( $this->price );
1743
+ $delim = '&';
1744
+ }
1745
+ if ( $this->itemPrice != null ) {
1746
+ $str .= $delim . $prefix . 'itemPrice=' . urlencode( $this->itemPrice );
1747
+ $delim = '&';
1748
+ }
1749
+ if ( $this->itemCount != null ) {
1750
+ $str .= $delim . $prefix . 'itemCount=' . urlencode( $this->itemCount );
1751
+ $delim = '&';
1752
+ }
1753
+
1754
+ return $str;
1755
+ }
1756
+
1757
+ public function init( $map = null, $prefix = '' )
1758
+ {
1759
+ if ( $map != null ) {
1760
+ $mapKeyName = $prefix . 'name';
1761
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1762
+ $this->name = $map[ $mapKeyName ];
1763
+ }
1764
+ $mapKeyName = $prefix . 'identifier';
1765
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1766
+ $this->identifier = $map[ $mapKeyName ];
1767
+ }
1768
+ $mapKeyName = $prefix . 'price';
1769
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1770
+ $this->price = $map[ $mapKeyName ];
1771
+ }
1772
+ $mapKeyName = $prefix . 'itemPrice';
1773
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1774
+ $this->itemPrice = $map[ $mapKeyName ];
1775
+ }
1776
+ $mapKeyName = $prefix . 'itemCount';
1777
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1778
+ $this->itemCount = $map[ $mapKeyName ];
1779
+ }
1780
+
1781
+ }
1782
+ }
1783
+ }
1784
+
1785
+
1786
+ /**
1787
+ * Describes a payment for a particular receiver (merchant),
1788
+ * contains list of additional per item details.
1789
+ */
1790
+ class InvoiceData
1791
+ {
1792
+
1793
+ /**
1794
+ *
1795
+ * @array
1796
+ * @access public
1797
+ * @var InvoiceItem
1798
+ */
1799
+ public $item;
1800
+
1801
+ /**
1802
+ *
1803
+ * @access public
1804
+ * @var double
1805
+ */
1806
+ public $totalTax;
1807
+
1808
+ /**
1809
+ *
1810
+ * @access public
1811
+ * @var double
1812
+ */
1813
+ public $totalShipping;
1814
+
1815
+
1816
+ public function toNVPString( $prefix = '' )
1817
+ {
1818
+ $str = '';
1819
+ $delim = '';
1820
+ for ( $i = 0; $i < count( $this->item ); $i++ ) {
1821
+ $newPrefix = $prefix . "item($i).";
1822
+ $str .= $delim . call_user_func( array( $this->item[ $i ], 'toNVPString' ), $newPrefix );
1823
+ $delim = '&';
1824
+ }
1825
+ if ( $this->totalTax != null ) {
1826
+ $str .= $delim . $prefix . 'totalTax=' . urlencode( $this->totalTax );
1827
+ $delim = '&';
1828
+ }
1829
+ if ( $this->totalShipping != null ) {
1830
+ $str .= $delim . $prefix . 'totalShipping=' . urlencode( $this->totalShipping );
1831
+ $delim = '&';
1832
+ }
1833
+
1834
+ return $str;
1835
+ }
1836
+
1837
+ public function init( $map = null, $prefix = '' )
1838
+ {
1839
+ if ( $map != null ) {
1840
+ $i = 0;
1841
+ while ( true ) {
1842
+ if ( PPUtils::array_match_key( $map, $prefix . "item($i)" ) ) {
1843
+ $newPrefix = $prefix . "item($i).";
1844
+ $this->item[ $i ] = new InvoiceItem();
1845
+ $this->item[ $i ]->init( $map, $newPrefix );
1846
+ } else {
1847
+ break;
1848
+ }
1849
+ $i++;
1850
+ }
1851
+ $mapKeyName = $prefix . 'totalTax';
1852
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1853
+ $this->totalTax = $map[ $mapKeyName ];
1854
+ }
1855
+ $mapKeyName = $prefix . 'totalShipping';
1856
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
1857
+ $this->totalShipping = $map[ $mapKeyName ];
1858
+ }
1859
+
1860
+ }
1861
+ }
1862
+ }
1863
+
1864
+
1865
+ /**
1866
+ * The error that resulted from an attempt to make a payment to
1867
+ * a receiver.
1868
+ */
1869
+ class PayError
1870
+ {
1871
+
1872
+ /**
1873
+ *
1874
+ * @access public
1875
+ * @var Receiver
1876
+ */
1877
+ public $receiver;
1878
+
1879
+ /**
1880
+ *
1881
+ * @access public
1882
+ * @var ErrorData
1883
+ */
1884
+ public $error;
1885
+
1886
+
1887
+ public function init( $map = null, $prefix = '' )
1888
+ {
1889
+ if ( $map != null ) {
1890
+ if ( PPUtils::array_match_key( $map, $prefix . "receiver." ) ) {
1891
+ $newPrefix = $prefix . "receiver.";
1892
+ $this->receiver = new Receiver();
1893
+ $this->receiver->init( $map, $newPrefix );
1894
+ }
1895
+ if ( PPUtils::array_match_key( $map, $prefix . "error." ) ) {
1896
+ $newPrefix = $prefix . "error.";
1897
+ $this->error = new ErrorData();
1898
+ $this->error->init( $map, $newPrefix );
1899
+ }
1900
+
1901
+ }
1902
+ }
1903
+ }
1904
+
1905
+
1906
+ /**
1907
+ *
1908
+ */
1909
+ class PayErrorList
1910
+ {
1911
+
1912
+ /**
1913
+ *
1914
+ * @array
1915
+ * @access public
1916
+ * @var PayError
1917
+ */
1918
+ public $payError;
1919
+
1920
+
1921
+ public function init( $map = null, $prefix = '' )
1922
+ {
1923
+ if ( $map != null ) {
1924
+ $i = 0;
1925
+ while ( true ) {
1926
+ if ( PPUtils::array_match_key( $map, $prefix . "payError($i)" ) ) {
1927
+ $newPrefix = $prefix . "payError($i).";
1928
+ $this->payError[ $i ] = new PayError();
1929
+ $this->payError[ $i ]->init( $map, $newPrefix );
1930
+ } else {
1931
+ break;
1932
+ }
1933
+ $i++;
1934
+ }
1935
+
1936
+ }
1937
+ }
1938
+ }
1939
+
1940
+
1941
+ /**
1942
+ * PaymentInfo represents the payment attempt made to a
1943
+ * Receiver of a PayRequest. If the execution of the payment
1944
+ * has not yet completed, there will not be any transaction
1945
+ * details.
1946
+ */
1947
+ class PaymentInfo
1948
+ {
1949
+
1950
+ /**
1951
+ *
1952
+ * @access public
1953
+ * @var string
1954
+ */
1955
+ public $transactionId;
1956
+
1957
+ /**
1958
+ *
1959
+ * @access public
1960
+ * @var string
1961
+ */
1962
+ public $transactionStatus;
1963
+
1964
+ /**
1965
+ *
1966
+ * @access public
1967
+ * @var Receiver
1968
+ */
1969
+ public $receiver;
1970
+
1971
+ /**
1972
+ *
1973
+ * @access public
1974
+ * @var double
1975
+ */
1976
+ public $refundedAmount;
1977
+
1978
+ /**
1979
+ *
1980
+ * @access public
1981
+ * @var boolean
1982
+ */
1983
+ public $pendingRefund;
1984
+
1985
+ /**
1986
+ *
1987
+ * @access public
1988
+ * @var string
1989
+ */
1990
+ public $senderTransactionId;
1991
+
1992
+ /**
1993
+ *
1994
+ * @access public
1995
+ * @var string
1996
+ */
1997
+ public $senderTransactionStatus;
1998
+
1999
+ /**
2000
+ *
2001
+ * @access public
2002
+ * @var string
2003
+ */
2004
+ public $pendingReason;
2005
+
2006
+
2007
+ public function init( $map = null, $prefix = '' )
2008
+ {
2009
+ if ( $map != null ) {
2010
+ $mapKeyName = $prefix . 'transactionId';
2011
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2012
+ $this->transactionId = $map[ $mapKeyName ];
2013
+ }
2014
+ $mapKeyName = $prefix . 'transactionStatus';
2015
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2016
+ $this->transactionStatus = $map[ $mapKeyName ];
2017
+ }
2018
+ if ( PPUtils::array_match_key( $map, $prefix . "receiver." ) ) {
2019
+ $newPrefix = $prefix . "receiver.";
2020
+ $this->receiver = new Receiver();
2021
+ $this->receiver->init( $map, $newPrefix );
2022
+ }
2023
+ $mapKeyName = $prefix . 'refundedAmount';
2024
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2025
+ $this->refundedAmount = $map[ $mapKeyName ];
2026
+ }
2027
+ $mapKeyName = $prefix . 'pendingRefund';
2028
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2029
+ $this->pendingRefund = $map[ $mapKeyName ];
2030
+ }
2031
+ $mapKeyName = $prefix . 'senderTransactionId';
2032
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2033
+ $this->senderTransactionId = $map[ $mapKeyName ];
2034
+ }
2035
+ $mapKeyName = $prefix . 'senderTransactionStatus';
2036
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2037
+ $this->senderTransactionStatus = $map[ $mapKeyName ];
2038
+ }
2039
+ $mapKeyName = $prefix . 'pendingReason';
2040
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2041
+ $this->pendingReason = $map[ $mapKeyName ];
2042
+ }
2043
+
2044
+ }
2045
+ }
2046
+ }
2047
+
2048
+
2049
+ /**
2050
+ *
2051
+ */
2052
+ class PaymentInfoList
2053
+ {
2054
+
2055
+ /**
2056
+ *
2057
+ * @array
2058
+ * @access public
2059
+ * @var PaymentInfo
2060
+ */
2061
+ public $paymentInfo;
2062
+
2063
+
2064
+ public function init( $map = null, $prefix = '' )
2065
+ {
2066
+ if ( $map != null ) {
2067
+ $i = 0;
2068
+ while ( true ) {
2069
+ if ( PPUtils::array_match_key( $map, $prefix . "paymentInfo($i)" ) ) {
2070
+ $newPrefix = $prefix . "paymentInfo($i).";
2071
+ $this->paymentInfo[ $i ] = new PaymentInfo();
2072
+ $this->paymentInfo[ $i ]->init( $map, $newPrefix );
2073
+ } else {
2074
+ break;
2075
+ }
2076
+ $i++;
2077
+ }
2078
+
2079
+ }
2080
+ }
2081
+ }
2082
+
2083
+
2084
+ /**
2085
+ * Receiver is the party where funds are transferred to. A
2086
+ * primary receiver receives a payment directly from the sender
2087
+ * in a chained split payment. A primary receiver should not be
2088
+ * specified when making a single or parallel split payment.
2089
+ */
2090
+ class Receiver
2091
+ {
2092
+
2093
+ /**
2094
+ *
2095
+ * @access public
2096
+ * @var double
2097
+ */
2098
+ public $amount;
2099
+
2100
+ /**
2101
+ *
2102
+ * @access public
2103
+ * @var string
2104
+ */
2105
+ public $email;
2106
+
2107
+ /**
2108
+ *
2109
+ * @access public
2110
+ * @var PhoneNumberType
2111
+ */
2112
+ public $phone;
2113
+
2114
+ /**
2115
+ *
2116
+ * @access public
2117
+ * @var boolean
2118
+ */
2119
+ public $primary;
2120
+
2121
+ /**
2122
+ *
2123
+ * @access public
2124
+ * @var string
2125
+ */
2126
+ public $invoiceId;
2127
+
2128
+ /**
2129
+ *
2130
+ * @access public
2131
+ * @var string
2132
+ */
2133
+ public $paymentType;
2134
+
2135
+ /**
2136
+ *
2137
+ * @access public
2138
+ * @var string
2139
+ */
2140
+ public $paymentSubType;
2141
+
2142
+ /**
2143
+ * Constructor with arguments
2144
+ */
2145
+ public function __construct( $amount = null )
2146
+ {
2147
+ $this->amount = $amount;
2148
+ }
2149
+
2150
+
2151
+ public function toNVPString( $prefix = '' )
2152
+ {
2153
+ $str = '';
2154
+ $delim = '';
2155
+ if ( $this->amount != null ) {
2156
+ $str .= $delim . $prefix . 'amount=' . urlencode( $this->amount );
2157
+ $delim = '&';
2158
+ }
2159
+ if ( $this->email != null ) {
2160
+ $str .= $delim . $prefix . 'email=' . urlencode( $this->email );
2161
+ $delim = '&';
2162
+ }
2163
+ if ( $this->phone != null ) {
2164
+ $newPrefix = $prefix . 'phone.';
2165
+ $str .= $delim . call_user_func( array( $this->phone, 'toNVPString' ), $newPrefix );
2166
+ $delim = '&';
2167
+ }
2168
+ if ( $this->primary != null ) {
2169
+ $str .= $delim . $prefix . 'primary=' . urlencode( $this->primary );
2170
+ $delim = '&';
2171
+ }
2172
+ if ( $this->invoiceId != null ) {
2173
+ $str .= $delim . $prefix . 'invoiceId=' . urlencode( $this->invoiceId );
2174
+ $delim = '&';
2175
+ }
2176
+ if ( $this->paymentType != null ) {
2177
+ $str .= $delim . $prefix . 'paymentType=' . urlencode( $this->paymentType );
2178
+ $delim = '&';
2179
+ }
2180
+ if ( $this->paymentSubType != null ) {
2181
+ $str .= $delim . $prefix . 'paymentSubType=' . urlencode( $this->paymentSubType );
2182
+ $delim = '&';
2183
+ }
2184
+
2185
+ return $str;
2186
+ }
2187
+
2188
+ public function init( $map = null, $prefix = '' )
2189
+ {
2190
+ if ( $map != null ) {
2191
+ $mapKeyName = $prefix . 'amount';
2192
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2193
+ $this->amount = $map[ $mapKeyName ];
2194
+ }
2195
+ $mapKeyName = $prefix . 'email';
2196
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2197
+ $this->email = $map[ $mapKeyName ];
2198
+ }
2199
+ if ( PPUtils::array_match_key( $map, $prefix . "phone." ) ) {
2200
+ $newPrefix = $prefix . "phone.";
2201
+ $this->phone = new PhoneNumberType();
2202
+ $this->phone->init( $map, $newPrefix );
2203
+ }
2204
+ $mapKeyName = $prefix . 'primary';
2205
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2206
+ $this->primary = $map[ $mapKeyName ];
2207
+ }
2208
+ $mapKeyName = $prefix . 'invoiceId';
2209
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2210
+ $this->invoiceId = $map[ $mapKeyName ];
2211
+ }
2212
+ $mapKeyName = $prefix . 'paymentType';
2213
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2214
+ $this->paymentType = $map[ $mapKeyName ];
2215
+ }
2216
+ $mapKeyName = $prefix . 'paymentSubType';
2217
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2218
+ $this->paymentSubType = $map[ $mapKeyName ];
2219
+ }
2220
+
2221
+ }
2222
+ }
2223
+ }
2224
+
2225
+
2226
+ /**
2227
+ *
2228
+ */
2229
+ class ReceiverList
2230
+ {
2231
+
2232
+ /**
2233
+ *
2234
+ * @array
2235
+ * @access public
2236
+ * @var Receiver
2237
+ */
2238
+ public $receiver;
2239
+
2240
+ /**
2241
+ * Constructor with arguments
2242
+ */
2243
+ public function __construct( $receiver = null )
2244
+ {
2245
+ $this->receiver = $receiver;
2246
+ }
2247
+
2248
+
2249
+ public function toNVPString( $prefix = '' )
2250
+ {
2251
+ $str = '';
2252
+ $delim = '';
2253
+ for ( $i = 0; $i < count( $this->receiver ); $i++ ) {
2254
+ $newPrefix = $prefix . "receiver($i).";
2255
+ $str .= $delim . call_user_func( array( $this->receiver[ $i ], 'toNVPString' ), $newPrefix );
2256
+ $delim = '&';
2257
+ }
2258
+
2259
+ return $str;
2260
+ }
2261
+
2262
+ }
2263
+
2264
+
2265
+ /**
2266
+ * The sender identifier type contains information to identify
2267
+ * a PayPal account.
2268
+ */
2269
+ class ReceiverIdentifier extends AccountIdentifier
2270
+ {
2271
+
2272
+
2273
+ public function toNVPString( $prefix = '' )
2274
+ {
2275
+ $str = parent::toNVPString( $prefix );
2276
+ if ( strlen( $str ) > 0 ) {
2277
+ $delim = '&';
2278
+ } else {
2279
+ $delim = '';
2280
+ }
2281
+
2282
+ return $str;
2283
+ }
2284
+
2285
+ public function init( $map = null, $prefix = '' )
2286
+ {
2287
+ if ( $map != null ) {
2288
+
2289
+ }
2290
+ }
2291
+ }
2292
+
2293
+
2294
+ /**
2295
+ * Options that apply to the receiver of a payment, allows
2296
+ * setting additional details for payment using invoice.
2297
+ */
2298
+ class ReceiverOptions
2299
+ {
2300
+
2301
+ /**
2302
+ *
2303
+ * @access public
2304
+ * @var string
2305
+ */
2306
+ public $description;
2307
+
2308
+ /**
2309
+ *
2310
+ * @access public
2311
+ * @var string
2312
+ */
2313
+ public $customId;
2314
+
2315
+ /**
2316
+ *
2317
+ * @access public
2318
+ * @var InvoiceData
2319
+ */
2320
+ public $invoiceData;
2321
+
2322
+ /**
2323
+ *
2324
+ * @access public
2325
+ * @var ReceiverIdentifier
2326
+ */
2327
+ public $receiver;
2328
+
2329
+ /**
2330
+ *
2331
+ * @access public
2332
+ * @var string
2333
+ */
2334
+ public $referrerCode;
2335
+
2336
+ /**
2337
+ * Constructor with arguments
2338
+ */
2339
+ public function __construct( $receiver = null )
2340
+ {
2341
+ $this->receiver = $receiver;
2342
+ }
2343
+
2344
+
2345
+ public function toNVPString( $prefix = '' )
2346
+ {
2347
+ $str = '';
2348
+ $delim = '';
2349
+ if ( $this->description != null ) {
2350
+ $str .= $delim . $prefix . 'description=' . urlencode( $this->description );
2351
+ $delim = '&';
2352
+ }
2353
+ if ( $this->customId != null ) {
2354
+ $str .= $delim . $prefix . 'customId=' . urlencode( $this->customId );
2355
+ $delim = '&';
2356
+ }
2357
+ if ( $this->invoiceData != null ) {
2358
+ $newPrefix = $prefix . 'invoiceData.';
2359
+ $str .= $delim . call_user_func( array( $this->invoiceData, 'toNVPString' ), $newPrefix );
2360
+ $delim = '&';
2361
+ }
2362
+ if ( $this->receiver != null ) {
2363
+ $newPrefix = $prefix . 'receiver.';
2364
+ $str .= $delim . call_user_func( array( $this->receiver, 'toNVPString' ), $newPrefix );
2365
+ $delim = '&';
2366
+ }
2367
+ if ( $this->referrerCode != null ) {
2368
+ $str .= $delim . $prefix . 'referrerCode=' . urlencode( $this->referrerCode );
2369
+ $delim = '&';
2370
+ }
2371
+
2372
+ return $str;
2373
+ }
2374
+
2375
+ public function init( $map = null, $prefix = '' )
2376
+ {
2377
+ if ( $map != null ) {
2378
+ $mapKeyName = $prefix . 'description';
2379
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2380
+ $this->description = $map[ $mapKeyName ];
2381
+ }
2382
+ $mapKeyName = $prefix . 'customId';
2383
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2384
+ $this->customId = $map[ $mapKeyName ];
2385
+ }
2386
+ if ( PPUtils::array_match_key( $map, $prefix . "invoiceData." ) ) {
2387
+ $newPrefix = $prefix . "invoiceData.";
2388
+ $this->invoiceData = new InvoiceData();
2389
+ $this->invoiceData->init( $map, $newPrefix );
2390
+ }
2391
+ if ( PPUtils::array_match_key( $map, $prefix . "receiver." ) ) {
2392
+ $newPrefix = $prefix . "receiver.";
2393
+ $this->receiver = new ReceiverIdentifier();
2394
+ $this->receiver->init( $map, $newPrefix );
2395
+ }
2396
+ $mapKeyName = $prefix . 'referrerCode';
2397
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2398
+ $this->referrerCode = $map[ $mapKeyName ];
2399
+ }
2400
+
2401
+ }
2402
+ }
2403
+ }
2404
+
2405
+
2406
+ /**
2407
+ * RefundInfo represents the refund attempt made to a Receiver
2408
+ * of a PayRequest.
2409
+ */
2410
+ class RefundInfo
2411
+ {
2412
+
2413
+ /**
2414
+ *
2415
+ * @access public
2416
+ * @var Receiver
2417
+ */
2418
+ public $receiver;
2419
+
2420
+ /**
2421
+ *
2422
+ * @access public
2423
+ * @var string
2424
+ */
2425
+ public $refundStatus;
2426
+
2427
+ /**
2428
+ *
2429
+ * @access public
2430
+ * @var double
2431
+ */
2432
+ public $refundNetAmount;
2433
+
2434
+ /**
2435
+ *
2436
+ * @access public
2437
+ * @var double
2438
+ */
2439
+ public $refundFeeAmount;
2440
+
2441
+ /**
2442
+ *
2443
+ * @access public
2444
+ * @var double
2445
+ */
2446
+ public $refundGrossAmount;
2447
+
2448
+ /**
2449
+ *
2450
+ * @access public
2451
+ * @var double
2452
+ */
2453
+ public $totalOfAllRefunds;
2454
+
2455
+ /**
2456
+ *
2457
+ * @access public
2458
+ * @var boolean
2459
+ */
2460
+ public $refundHasBecomeFull;
2461
+
2462
+ /**
2463
+ *
2464
+ * @access public
2465
+ * @var string
2466
+ */
2467
+ public $encryptedRefundTransactionId;
2468
+
2469
+ /**
2470
+ *
2471
+ * @access public
2472
+ * @var string
2473
+ */
2474
+ public $refundTransactionStatus;
2475
+
2476
+ /**
2477
+ *
2478
+ * @access public
2479
+ * @var ErrorList
2480
+ */
2481
+ public $errorList;
2482
+
2483
+
2484
+ public function init( $map = null, $prefix = '' )
2485
+ {
2486
+ if ( $map != null ) {
2487
+ if ( PPUtils::array_match_key( $map, $prefix . "receiver." ) ) {
2488
+ $newPrefix = $prefix . "receiver.";
2489
+ $this->receiver = new Receiver();
2490
+ $this->receiver->init( $map, $newPrefix );
2491
+ }
2492
+ $mapKeyName = $prefix . 'refundStatus';
2493
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2494
+ $this->refundStatus = $map[ $mapKeyName ];
2495
+ }
2496
+ $mapKeyName = $prefix . 'refundNetAmount';
2497
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2498
+ $this->refundNetAmount = $map[ $mapKeyName ];
2499
+ }
2500
+ $mapKeyName = $prefix . 'refundFeeAmount';
2501
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2502
+ $this->refundFeeAmount = $map[ $mapKeyName ];
2503
+ }
2504
+ $mapKeyName = $prefix . 'refundGrossAmount';
2505
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2506
+ $this->refundGrossAmount = $map[ $mapKeyName ];
2507
+ }
2508
+ $mapKeyName = $prefix . 'totalOfAllRefunds';
2509
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2510
+ $this->totalOfAllRefunds = $map[ $mapKeyName ];
2511
+ }
2512
+ $mapKeyName = $prefix . 'refundHasBecomeFull';
2513
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2514
+ $this->refundHasBecomeFull = $map[ $mapKeyName ];
2515
+ }
2516
+ $mapKeyName = $prefix . 'encryptedRefundTransactionId';
2517
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2518
+ $this->encryptedRefundTransactionId = $map[ $mapKeyName ];
2519
+ }
2520
+ $mapKeyName = $prefix . 'refundTransactionStatus';
2521
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2522
+ $this->refundTransactionStatus = $map[ $mapKeyName ];
2523
+ }
2524
+ if ( PPUtils::array_match_key( $map, $prefix . "errorList." ) ) {
2525
+ $newPrefix = $prefix . "errorList.";
2526
+ $this->errorList = new ErrorList();
2527
+ $this->errorList->init( $map, $newPrefix );
2528
+ }
2529
+
2530
+ }
2531
+ }
2532
+ }
2533
+
2534
+
2535
+ /**
2536
+ *
2537
+ */
2538
+ class RefundInfoList
2539
+ {
2540
+
2541
+ /**
2542
+ *
2543
+ * @array
2544
+ * @access public
2545
+ * @var RefundInfo
2546
+ */
2547
+ public $refundInfo;
2548
+
2549
+
2550
+ public function init( $map = null, $prefix = '' )
2551
+ {
2552
+ if ( $map != null ) {
2553
+ $i = 0;
2554
+ while ( true ) {
2555
+ if ( PPUtils::array_match_key( $map, $prefix . "refundInfo($i)" ) ) {
2556
+ $newPrefix = $prefix . "refundInfo($i).";
2557
+ $this->refundInfo[ $i ] = new RefundInfo();
2558
+ $this->refundInfo[ $i ]->init( $map, $newPrefix );
2559
+ } else {
2560
+ break;
2561
+ }
2562
+ $i++;
2563
+ }
2564
+
2565
+ }
2566
+ }
2567
+ }
2568
+
2569
+
2570
+ /**
2571
+ * Options that apply to the sender of a payment.
2572
+ */
2573
+ class SenderOptions
2574
+ {
2575
+
2576
+ /**
2577
+ * Require the user to select a shipping address during the web
2578
+ * flow.
2579
+ * @access public
2580
+ * @var boolean
2581
+ */
2582
+ public $requireShippingAddressSelection;
2583
+
2584
+ /**
2585
+ *
2586
+ * @access public
2587
+ * @var string
2588
+ */
2589
+ public $referrerCode;
2590
+
2591
+
2592
+ public function toNVPString( $prefix = '' )
2593
+ {
2594
+ $str = '';
2595
+ $delim = '';
2596
+ if ( $this->requireShippingAddressSelection != null ) {
2597
+ $str .= $delim . $prefix . 'requireShippingAddressSelection=' . urlencode( $this->requireShippingAddressSelection );
2598
+ $delim = '&';
2599
+ }
2600
+ if ( $this->referrerCode != null ) {
2601
+ $str .= $delim . $prefix . 'referrerCode=' . urlencode( $this->referrerCode );
2602
+ $delim = '&';
2603
+ }
2604
+
2605
+ return $str;
2606
+ }
2607
+
2608
+ public function init( $map = null, $prefix = '' )
2609
+ {
2610
+ if ( $map != null ) {
2611
+ $mapKeyName = $prefix . 'requireShippingAddressSelection';
2612
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2613
+ $this->requireShippingAddressSelection = $map[ $mapKeyName ];
2614
+ }
2615
+ $mapKeyName = $prefix . 'referrerCode';
2616
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2617
+ $this->referrerCode = $map[ $mapKeyName ];
2618
+ }
2619
+
2620
+ }
2621
+ }
2622
+ }
2623
+
2624
+
2625
+ /**
2626
+ * Details about the payer's tax info passed in by the merchant
2627
+ * or partner.
2628
+ */
2629
+ class TaxIdDetails
2630
+ {
2631
+
2632
+ /**
2633
+ * Tax id of the merchant/business.
2634
+ * @access public
2635
+ * @var string
2636
+ */
2637
+ public $taxId;
2638
+
2639
+ /**
2640
+ * Tax type of the Tax Id.
2641
+ * @access public
2642
+ * @var string
2643
+ */
2644
+ public $taxIdType;
2645
+
2646
+
2647
+ public function toNVPString( $prefix = '' )
2648
+ {
2649
+ $str = '';
2650
+ $delim = '';
2651
+ if ( $this->taxId != null ) {
2652
+ $str .= $delim . $prefix . 'taxId=' . urlencode( $this->taxId );
2653
+ $delim = '&';
2654
+ }
2655
+ if ( $this->taxIdType != null ) {
2656
+ $str .= $delim . $prefix . 'taxIdType=' . urlencode( $this->taxIdType );
2657
+ $delim = '&';
2658
+ }
2659
+
2660
+ return $str;
2661
+ }
2662
+
2663
+ public function init( $map = null, $prefix = '' )
2664
+ {
2665
+ if ( $map != null ) {
2666
+ $mapKeyName = $prefix . 'taxId';
2667
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2668
+ $this->taxId = $map[ $mapKeyName ];
2669
+ }
2670
+ $mapKeyName = $prefix . 'taxIdType';
2671
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2672
+ $this->taxIdType = $map[ $mapKeyName ];
2673
+ }
2674
+
2675
+ }
2676
+ }
2677
+ }
2678
+
2679
+
2680
+ /**
2681
+ * The sender identifier type contains information to identify
2682
+ * a PayPal account.
2683
+ */
2684
+ class SenderIdentifier extends AccountIdentifier
2685
+ {
2686
+
2687
+ /**
2688
+ *
2689
+ * @access public
2690
+ * @var boolean
2691
+ */
2692
+ public $useCredentials;
2693
+
2694
+ /**
2695
+ *
2696
+ * @access public
2697
+ * @var TaxIdDetails
2698
+ */
2699
+ public $taxIdDetails;
2700
+
2701
+
2702
+ public function toNVPString( $prefix = '' )
2703
+ {
2704
+ $str = parent::toNVPString( $prefix );
2705
+ if ( strlen( $str ) > 0 ) {
2706
+ $delim = '&';
2707
+ } else {
2708
+ $delim = '';
2709
+ }
2710
+ if ( $this->useCredentials != null ) {
2711
+ $str .= $delim . $prefix . 'useCredentials=' . urlencode( $this->useCredentials );
2712
+ $delim = '&';
2713
+ }
2714
+ if ( $this->taxIdDetails != null ) {
2715
+ $newPrefix = $prefix . 'taxIdDetails.';
2716
+ $str .= $delim . call_user_func( array( $this->taxIdDetails, 'toNVPString' ), $newPrefix );
2717
+ $delim = '&';
2718
+ }
2719
+
2720
+ return $str;
2721
+ }
2722
+
2723
+ public function init( $map = null, $prefix = '' )
2724
+ {
2725
+ if ( $map != null ) {
2726
+ $mapKeyName = $prefix . 'useCredentials';
2727
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2728
+ $this->useCredentials = $map[ $mapKeyName ];
2729
+ }
2730
+ if ( PPUtils::array_match_key( $map, $prefix . "taxIdDetails." ) ) {
2731
+ $newPrefix = $prefix . "taxIdDetails.";
2732
+ $this->taxIdDetails = new TaxIdDetails();
2733
+ $this->taxIdDetails->init( $map, $newPrefix );
2734
+ }
2735
+
2736
+ }
2737
+ }
2738
+ }
2739
+
2740
+
2741
+ /**
2742
+ *
2743
+ */
2744
+ class UserLimit
2745
+ {
2746
+
2747
+ /**
2748
+ *
2749
+ * @access public
2750
+ * @var string
2751
+ */
2752
+ public $limitType;
2753
+
2754
+ /**
2755
+ *
2756
+ * @access public
2757
+ * @var CurrencyType
2758
+ */
2759
+ public $limitAmount;
2760
+
2761
+
2762
+ public function init( $map = null, $prefix = '' )
2763
+ {
2764
+ if ( $map != null ) {
2765
+ $mapKeyName = $prefix . 'limitType';
2766
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2767
+ $this->limitType = $map[ $mapKeyName ];
2768
+ }
2769
+ if ( PPUtils::array_match_key( $map, $prefix . "limitAmount." ) ) {
2770
+ $newPrefix = $prefix . "limitAmount.";
2771
+ $this->limitAmount = new CurrencyType();
2772
+ $this->limitAmount->init( $map, $newPrefix );
2773
+ }
2774
+
2775
+ }
2776
+ }
2777
+ }
2778
+
2779
+
2780
+ /**
2781
+ * This type contains the detailed warning information
2782
+ * resulting from the service operation.
2783
+ */
2784
+ class WarningData
2785
+ {
2786
+
2787
+ /**
2788
+ *
2789
+ * @access public
2790
+ * @var integer
2791
+ */
2792
+ public $warningId;
2793
+
2794
+ /**
2795
+ *
2796
+ * @access public
2797
+ * @var string
2798
+ */
2799
+ public $message;
2800
+
2801
+
2802
+ public function init( $map = null, $prefix = '' )
2803
+ {
2804
+ if ( $map != null ) {
2805
+ $mapKeyName = $prefix . 'warningId';
2806
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2807
+ $this->warningId = $map[ $mapKeyName ];
2808
+ }
2809
+ $mapKeyName = $prefix . 'message';
2810
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
2811
+ $this->message = $map[ $mapKeyName ];
2812
+ }
2813
+
2814
+ }
2815
+ }
2816
+ }
2817
+
2818
+
2819
+ /**
2820
+ *
2821
+ */
2822
+ class WarningDataList
2823
+ {
2824
+
2825
+ /**
2826
+ *
2827
+ * @array
2828
+ * @access public
2829
+ * @var WarningData
2830
+ */
2831
+ public $warningData;
2832
+
2833
+
2834
+ public function init( $map = null, $prefix = '' )
2835
+ {
2836
+ if ( $map != null ) {
2837
+ $i = 0;
2838
+ while ( true ) {
2839
+ if ( PPUtils::array_match_key( $map, $prefix . "warningData($i)" ) ) {
2840
+ $newPrefix = $prefix . "warningData($i).";
2841
+ $this->warningData[ $i ] = new WarningData();
2842
+ $this->warningData[ $i ]->init( $map, $newPrefix );
2843
+ } else {
2844
+ break;
2845
+ }
2846
+ $i++;
2847
+ }
2848
+
2849
+ }
2850
+ }
2851
+ }
2852
+
2853
+
2854
+ /**
2855
+ * The request to cancel a Preapproval.
2856
+ */
2857
+ class CancelPreapprovalRequest
2858
+ {
2859
+
2860
+ /**
2861
+ *
2862
+ * @access public
2863
+ * @var RequestEnvelope
2864
+ */
2865
+ public $requestEnvelope;
2866
+
2867
+ /**
2868
+ *
2869
+ * @access public
2870
+ * @var string
2871
+ */
2872
+ public $preapprovalKey;
2873
+
2874
+ /**
2875
+ * Constructor with arguments
2876
+ */
2877
+ public function __construct( $requestEnvelope = null, $preapprovalKey = null )
2878
+ {
2879
+ $this->requestEnvelope = $requestEnvelope;
2880
+ $this->preapprovalKey = $preapprovalKey;
2881
+ }
2882
+
2883
+
2884
+ public function toNVPString( $prefix = '' )
2885
+ {
2886
+ $str = '';
2887
+ $delim = '';
2888
+ if ( $this->requestEnvelope != null ) {
2889
+ $newPrefix = $prefix . 'requestEnvelope.';
2890
+ $str .= $delim . call_user_func( array( $this->requestEnvelope, 'toNVPString' ), $newPrefix );
2891
+ $delim = '&';
2892
+ }
2893
+ if ( $this->preapprovalKey != null ) {
2894
+ $str .= $delim . $prefix . 'preapprovalKey=' . urlencode( $this->preapprovalKey );
2895
+ $delim = '&';
2896
+ }
2897
+
2898
+ return $str;
2899
+ }
2900
+
2901
+ }
2902
+
2903
+
2904
+ /**
2905
+ * The result of the CancelPreapprovalRequest.
2906
+ */
2907
+ class CancelPreapprovalResponse
2908
+ {
2909
+
2910
+ /**
2911
+ *
2912
+ * @access public
2913
+ * @var ResponseEnvelope
2914
+ */
2915
+ public $responseEnvelope;
2916
+
2917
+ /**
2918
+ *
2919
+ * @array
2920
+ * @access public
2921
+ * @var ErrorData
2922
+ */
2923
+ public $error;
2924
+
2925
+
2926
+ public function init( $map = null, $prefix = '' )
2927
+ {
2928
+ if ( $map != null ) {
2929
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
2930
+ $newPrefix = $prefix . "responseEnvelope.";
2931
+ $this->responseEnvelope = new ResponseEnvelope();
2932
+ $this->responseEnvelope->init( $map, $newPrefix );
2933
+ }
2934
+ $i = 0;
2935
+ while ( true ) {
2936
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
2937
+ $newPrefix = $prefix . "error($i).";
2938
+ $this->error[ $i ] = new ErrorData();
2939
+ $this->error[ $i ]->init( $map, $newPrefix );
2940
+ } else {
2941
+ break;
2942
+ }
2943
+ $i++;
2944
+ }
2945
+
2946
+ }
2947
+ }
2948
+ }
2949
+
2950
+
2951
+ /**
2952
+ * The request to confirm a Preapproval.
2953
+ */
2954
+ class ConfirmPreapprovalRequest
2955
+ {
2956
+
2957
+ /**
2958
+ *
2959
+ * @access public
2960
+ * @var RequestEnvelope
2961
+ */
2962
+ public $requestEnvelope;
2963
+
2964
+ /**
2965
+ *
2966
+ * @access public
2967
+ * @var string
2968
+ */
2969
+ public $preapprovalKey;
2970
+
2971
+ /**
2972
+ *
2973
+ * @access public
2974
+ * @var string
2975
+ */
2976
+ public $fundingSourceId;
2977
+
2978
+ /**
2979
+ *
2980
+ * @access public
2981
+ * @var string
2982
+ */
2983
+ public $pin;
2984
+
2985
+ /**
2986
+ * Constructor with arguments
2987
+ */
2988
+ public function __construct( $requestEnvelope = null, $preapprovalKey = null )
2989
+ {
2990
+ $this->requestEnvelope = $requestEnvelope;
2991
+ $this->preapprovalKey = $preapprovalKey;
2992
+ }
2993
+
2994
+
2995
+ public function toNVPString( $prefix = '' )
2996
+ {
2997
+ $str = '';
2998
+ $delim = '';
2999
+ if ( $this->requestEnvelope != null ) {
3000
+ $newPrefix = $prefix . 'requestEnvelope.';
3001
+ $str .= $delim . call_user_func( array( $this->requestEnvelope, 'toNVPString' ), $newPrefix );
3002
+ $delim = '&';
3003
+ }
3004
+ if ( $this->preapprovalKey != null ) {
3005
+ $str .= $delim . $prefix . 'preapprovalKey=' . urlencode( $this->preapprovalKey );
3006
+ $delim = '&';
3007
+ }
3008
+ if ( $this->fundingSourceId != null ) {
3009
+ $str .= $delim . $prefix . 'fundingSourceId=' . urlencode( $this->fundingSourceId );
3010
+ $delim = '&';
3011
+ }
3012
+ if ( $this->pin != null ) {
3013
+ $str .= $delim . $prefix . 'pin=' . urlencode( $this->pin );
3014
+ $delim = '&';
3015
+ }
3016
+
3017
+ return $str;
3018
+ }
3019
+
3020
+ }
3021
+
3022
+
3023
+ /**
3024
+ * The result of the ConfirmPreapprovalRequest.
3025
+ */
3026
+ class ConfirmPreapprovalResponse
3027
+ {
3028
+
3029
+ /**
3030
+ *
3031
+ * @access public
3032
+ * @var ResponseEnvelope
3033
+ */
3034
+ public $responseEnvelope;
3035
+
3036
+ /**
3037
+ *
3038
+ * @array
3039
+ * @access public
3040
+ * @var ErrorData
3041
+ */
3042
+ public $error;
3043
+
3044
+
3045
+ public function init( $map = null, $prefix = '' )
3046
+ {
3047
+ if ( $map != null ) {
3048
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
3049
+ $newPrefix = $prefix . "responseEnvelope.";
3050
+ $this->responseEnvelope = new ResponseEnvelope();
3051
+ $this->responseEnvelope->init( $map, $newPrefix );
3052
+ }
3053
+ $i = 0;
3054
+ while ( true ) {
3055
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
3056
+ $newPrefix = $prefix . "error($i).";
3057
+ $this->error[ $i ] = new ErrorData();
3058
+ $this->error[ $i ]->init( $map, $newPrefix );
3059
+ } else {
3060
+ break;
3061
+ }
3062
+ $i++;
3063
+ }
3064
+
3065
+ }
3066
+ }
3067
+ }
3068
+
3069
+
3070
+ /**
3071
+ * A request to convert one or more currencies into their
3072
+ * estimated values in other currencies.
3073
+ */
3074
+ class ConvertCurrencyRequest
3075
+ {
3076
+
3077
+ /**
3078
+ *
3079
+ * @access public
3080
+ * @var RequestEnvelope
3081
+ */
3082
+ public $requestEnvelope;
3083
+
3084
+ /**
3085
+ *
3086
+ * @access public
3087
+ * @var CurrencyList
3088
+ */
3089
+ public $baseAmountList;
3090
+
3091
+ /**
3092
+ *
3093
+ * @access public
3094
+ * @var CurrencyCodeList
3095
+ */
3096
+ public $convertToCurrencyList;
3097
+
3098
+ /**
3099
+ * The two-character ISO country code where fx suppposed to
3100
+ * happen
3101
+ * @access public
3102
+ * @var string
3103
+ */
3104
+ public $countryCode;
3105
+
3106
+ /**
3107
+ *
3108
+ * @access public
3109
+ * @var string
3110
+ */
3111
+ public $conversionType;
3112
+
3113
+ /**
3114
+ * Constructor with arguments
3115
+ */
3116
+ public function __construct( $requestEnvelope = null, $baseAmountList = null, $convertToCurrencyList = null )
3117
+ {
3118
+ $this->requestEnvelope = $requestEnvelope;
3119
+ $this->baseAmountList = $baseAmountList;
3120
+ $this->convertToCurrencyList = $convertToCurrencyList;
3121
+ }
3122
+
3123
+
3124
+ public function toNVPString( $prefix = '' )
3125
+ {
3126
+ $str = '';
3127
+ $delim = '';
3128
+ if ( $this->requestEnvelope != null ) {
3129
+ $newPrefix = $prefix . 'requestEnvelope.';
3130
+ $str .= $delim . call_user_func( array( $this->requestEnvelope, 'toNVPString' ), $newPrefix );
3131
+ $delim = '&';
3132
+ }
3133
+ if ( $this->baseAmountList != null ) {
3134
+ $newPrefix = $prefix . 'baseAmountList.';
3135
+ $str .= $delim . call_user_func( array( $this->baseAmountList, 'toNVPString' ), $newPrefix );
3136
+ $delim = '&';
3137
+ }
3138
+ if ( $this->convertToCurrencyList != null ) {
3139
+ $newPrefix = $prefix . 'convertToCurrencyList.';
3140
+ $str .= $delim . call_user_func( array( $this->convertToCurrencyList, 'toNVPString' ), $newPrefix );
3141
+ $delim = '&';
3142
+ }
3143
+ if ( $this->countryCode != null ) {
3144
+ $str .= $delim . $prefix . 'countryCode=' . urlencode( $this->countryCode );
3145
+ $delim = '&';
3146
+ }
3147
+ if ( $this->conversionType != null ) {
3148
+ $str .= $delim . $prefix . 'conversionType=' . urlencode( $this->conversionType );
3149
+ $delim = '&';
3150
+ }
3151
+
3152
+ return $str;
3153
+ }
3154
+
3155
+ }
3156
+
3157
+
3158
+ /**
3159
+ * A response that contains a table of estimated converted
3160
+ * currencies based on the Convert Currency Request.
3161
+ */
3162
+ class ConvertCurrencyResponse
3163
+ {
3164
+
3165
+ /**
3166
+ *
3167
+ * @access public
3168
+ * @var ResponseEnvelope
3169
+ */
3170
+ public $responseEnvelope;
3171
+
3172
+ /**
3173
+ *
3174
+ * @access public
3175
+ * @var CurrencyConversionTable
3176
+ */
3177
+ public $estimatedAmountTable;
3178
+
3179
+ /**
3180
+ *
3181
+ * @array
3182
+ * @access public
3183
+ * @var ErrorData
3184
+ */
3185
+ public $error;
3186
+
3187
+
3188
+ public function init( $map = null, $prefix = '' )
3189
+ {
3190
+ if ( $map != null ) {
3191
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
3192
+ $newPrefix = $prefix . "responseEnvelope.";
3193
+ $this->responseEnvelope = new ResponseEnvelope();
3194
+ $this->responseEnvelope->init( $map, $newPrefix );
3195
+ }
3196
+ if ( PPUtils::array_match_key( $map, $prefix . "estimatedAmountTable." ) ) {
3197
+ $newPrefix = $prefix . "estimatedAmountTable.";
3198
+ $this->estimatedAmountTable = new CurrencyConversionTable();
3199
+ $this->estimatedAmountTable->init( $map, $newPrefix );
3200
+ }
3201
+ $i = 0;
3202
+ while ( true ) {
3203
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
3204
+ $newPrefix = $prefix . "error($i).";
3205
+ $this->error[ $i ] = new ErrorData();
3206
+ $this->error[ $i ]->init( $map, $newPrefix );
3207
+ } else {
3208
+ break;
3209
+ }
3210
+ $i++;
3211
+ }
3212
+
3213
+ }
3214
+ }
3215
+ }
3216
+
3217
+
3218
+ /**
3219
+ * The request to execute the payment request.
3220
+ */
3221
+ class ExecutePaymentRequest
3222
+ {
3223
+
3224
+ /**
3225
+ *
3226
+ * @access public
3227
+ * @var RequestEnvelope
3228
+ */
3229
+ public $requestEnvelope;
3230
+
3231
+ /**
3232
+ *
3233
+ * @access public
3234
+ * @var string
3235
+ */
3236
+ public $payKey;
3237
+
3238
+ /**
3239
+ * Describes the action that is performed by this API
3240
+ * @access public
3241
+ * @var string
3242
+ */
3243
+ public $actionType;
3244
+
3245
+ /**
3246
+ *
3247
+ * @access public
3248
+ * @var string
3249
+ */
3250
+ public $fundingPlanId;
3251
+
3252
+ /**
3253
+ * Constructor with arguments
3254
+ */
3255
+ public function __construct( $requestEnvelope = null, $payKey = null )
3256
+ {
3257
+ $this->requestEnvelope = $requestEnvelope;
3258
+ $this->payKey = $payKey;
3259
+ }
3260
+
3261
+
3262
+ public function toNVPString( $prefix = '' )
3263
+ {
3264
+ $str = '';
3265
+ $delim = '';
3266
+ if ( $this->requestEnvelope != null ) {
3267
+ $newPrefix = $prefix . 'requestEnvelope.';
3268
+ $str .= $delim . call_user_func( array( $this->requestEnvelope, 'toNVPString' ), $newPrefix );
3269
+ $delim = '&';
3270
+ }
3271
+ if ( $this->payKey != null ) {
3272
+ $str .= $delim . $prefix . 'payKey=' . urlencode( $this->payKey );
3273
+ $delim = '&';
3274
+ }
3275
+ if ( $this->actionType != null ) {
3276
+ $str .= $delim . $prefix . 'actionType=' . urlencode( $this->actionType );
3277
+ $delim = '&';
3278
+ }
3279
+ if ( $this->fundingPlanId != null ) {
3280
+ $str .= $delim . $prefix . 'fundingPlanId=' . urlencode( $this->fundingPlanId );
3281
+ $delim = '&';
3282
+ }
3283
+
3284
+ return $str;
3285
+ }
3286
+
3287
+ }
3288
+
3289
+
3290
+ /**
3291
+ * The result of a payment execution.
3292
+ */
3293
+ class ExecutePaymentResponse
3294
+ {
3295
+
3296
+ /**
3297
+ *
3298
+ * @access public
3299
+ * @var ResponseEnvelope
3300
+ */
3301
+ public $responseEnvelope;
3302
+
3303
+ /**
3304
+ *
3305
+ * @access public
3306
+ * @var string
3307
+ */
3308
+ public $paymentExecStatus;
3309
+
3310
+ /**
3311
+ *
3312
+ * @access public
3313
+ * @var PayErrorList
3314
+ */
3315
+ public $payErrorList;
3316
+
3317
+ /**
3318
+ *
3319
+ * @array
3320
+ * @access public
3321
+ * @var ErrorData
3322
+ */
3323
+ public $error;
3324
+
3325
+
3326
+ public function init( $map = null, $prefix = '' )
3327
+ {
3328
+ if ( $map != null ) {
3329
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
3330
+ $newPrefix = $prefix . "responseEnvelope.";
3331
+ $this->responseEnvelope = new ResponseEnvelope();
3332
+ $this->responseEnvelope->init( $map, $newPrefix );
3333
+ }
3334
+ $mapKeyName = $prefix . 'paymentExecStatus';
3335
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
3336
+ $this->paymentExecStatus = $map[ $mapKeyName ];
3337
+ }
3338
+ if ( PPUtils::array_match_key( $map, $prefix . "payErrorList." ) ) {
3339
+ $newPrefix = $prefix . "payErrorList.";
3340
+ $this->payErrorList = new PayErrorList();
3341
+ $this->payErrorList->init( $map, $newPrefix );
3342
+ }
3343
+ $i = 0;
3344
+ while ( true ) {
3345
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
3346
+ $newPrefix = $prefix . "error($i).";
3347
+ $this->error[ $i ] = new ErrorData();
3348
+ $this->error[ $i ]->init( $map, $newPrefix );
3349
+ } else {
3350
+ break;
3351
+ }
3352
+ $i++;
3353
+ }
3354
+
3355
+ }
3356
+ }
3357
+ }
3358
+
3359
+
3360
+ /**
3361
+ * The request to get the allowed funding sources available for
3362
+ * a preapproval.
3363
+ */
3364
+ class GetAllowedFundingSourcesRequest
3365
+ {
3366
+
3367
+ /**
3368
+ *
3369
+ * @access public
3370
+ * @var RequestEnvelope
3371
+ */
3372
+ public $requestEnvelope;
3373
+
3374
+ /**
3375
+ *
3376
+ * @access public
3377
+ * @var string
3378
+ */
3379
+ public $key;
3380
+
3381
+ /**
3382
+ * Constructor with arguments
3383
+ */
3384
+ public function __construct( $requestEnvelope = null, $key = null )
3385
+ {
3386
+ $this->requestEnvelope = $requestEnvelope;
3387
+ $this->key = $key;
3388
+ }
3389
+
3390
+
3391
+ public function toNVPString( $prefix = '' )
3392
+ {
3393
+ $str = '';
3394
+ $delim = '';
3395
+ if ( $this->requestEnvelope != null ) {
3396
+ $newPrefix = $prefix . 'requestEnvelope.';
3397
+ $str .= $delim . call_user_func( array( $this->requestEnvelope, 'toNVPString' ), $newPrefix );
3398
+ $delim = '&';
3399
+ }
3400
+ if ( $this->key != null ) {
3401
+ $str .= $delim . $prefix . 'key=' . urlencode( $this->key );
3402
+ $delim = '&';
3403
+ }
3404
+
3405
+ return $str;
3406
+ }
3407
+
3408
+ }
3409
+
3410
+
3411
+ /**
3412
+ * The response to get the backup funding sources available for
3413
+ * a preapproval.
3414
+ */
3415
+ class GetAllowedFundingSourcesResponse
3416
+ {
3417
+
3418
+ /**
3419
+ *
3420
+ * @access public
3421
+ * @var ResponseEnvelope
3422
+ */
3423
+ public $responseEnvelope;
3424
+
3425
+ /**
3426
+ *
3427
+ * @array
3428
+ * @access public
3429
+ * @var FundingSource
3430
+ */
3431
+ public $fundingSource;
3432
+
3433
+ /**
3434
+ *
3435
+ * @array
3436
+ * @access public
3437
+ * @var ErrorData
3438
+ */
3439
+ public $error;
3440
+
3441
+
3442
+ public function init( $map = null, $prefix = '' )
3443
+ {
3444
+ if ( $map != null ) {
3445
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
3446
+ $newPrefix = $prefix . "responseEnvelope.";
3447
+ $this->responseEnvelope = new ResponseEnvelope();
3448
+ $this->responseEnvelope->init( $map, $newPrefix );
3449
+ }
3450
+ $i = 0;
3451
+ while ( true ) {
3452
+ if ( PPUtils::array_match_key( $map, $prefix . "fundingSource($i)" ) ) {
3453
+ $newPrefix = $prefix . "fundingSource($i).";
3454
+ $this->fundingSource[ $i ] = new FundingSource();
3455
+ $this->fundingSource[ $i ]->init( $map, $newPrefix );
3456
+ } else {
3457
+ break;
3458
+ }
3459
+ $i++;
3460
+ }
3461
+ $i = 0;
3462
+ while ( true ) {
3463
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
3464
+ $newPrefix = $prefix . "error($i).";
3465
+ $this->error[ $i ] = new ErrorData();
3466
+ $this->error[ $i ]->init( $map, $newPrefix );
3467
+ } else {
3468
+ break;
3469
+ }
3470
+ $i++;
3471
+ }
3472
+
3473
+ }
3474
+ }
3475
+ }
3476
+
3477
+
3478
+ /**
3479
+ * The request to get the options of a payment request.
3480
+ */
3481
+ class GetPaymentOptionsRequest
3482
+ {
3483
+
3484
+ /**
3485
+ *
3486
+ * @access public
3487
+ * @var RequestEnvelope
3488
+ */
3489
+ public $requestEnvelope;
3490
+
3491
+ /**
3492
+ *
3493
+ * @access public
3494
+ * @var string
3495
+ */
3496
+ public $payKey;
3497
+
3498
+ /**
3499
+ * Constructor with arguments
3500
+ */
3501
+ public function __construct( $requestEnvelope = null, $payKey = null )
3502
+ {
3503
+ $this->requestEnvelope = $requestEnvelope;
3504
+ $this->payKey = $payKey;
3505
+ }
3506
+
3507
+
3508
+ public function toNVPString( $prefix = '' )
3509
+ {
3510
+ $str = '';
3511
+ $delim = '';
3512
+ if ( $this->requestEnvelope != null ) {
3513
+ $newPrefix = $prefix . 'requestEnvelope.';
3514
+ $str .= $delim . call_user_func( array( $this->requestEnvelope, 'toNVPString' ), $newPrefix );
3515
+ $delim = '&';
3516
+ }
3517
+ if ( $this->payKey != null ) {
3518
+ $str .= $delim . $prefix . 'payKey=' . urlencode( $this->payKey );
3519
+ $delim = '&';
3520
+ }
3521
+
3522
+ return $str;
3523
+ }
3524
+
3525
+ }
3526
+
3527
+
3528
+ /**
3529
+ * The response message for the GetPaymentOption request
3530
+ */
3531
+ class GetPaymentOptionsResponse
3532
+ {
3533
+
3534
+ /**
3535
+ *
3536
+ * @access public
3537
+ * @var ResponseEnvelope
3538
+ */
3539
+ public $responseEnvelope;
3540
+
3541
+ /**
3542
+ *
3543
+ * @access public
3544
+ * @var InitiatingEntity
3545
+ */
3546
+ public $initiatingEntity;
3547
+
3548
+ /**
3549
+ *
3550
+ * @access public
3551
+ * @var DisplayOptions
3552
+ */
3553
+ public $displayOptions;
3554
+
3555
+ /**
3556
+ *
3557
+ * @access public
3558
+ * @var string
3559
+ */
3560
+ public $shippingAddressId;
3561
+
3562
+ /**
3563
+ *
3564
+ * @access public
3565
+ * @var SenderOptions
3566
+ */
3567
+ public $senderOptions;
3568
+
3569
+ /**
3570
+ *
3571
+ * @array
3572
+ * @access public
3573
+ * @var ReceiverOptions
3574
+ */
3575
+ public $receiverOptions;
3576
+
3577
+ /**
3578
+ *
3579
+ * @array
3580
+ * @access public
3581
+ * @var ErrorData
3582
+ */
3583
+ public $error;
3584
+
3585
+
3586
+ public function init( $map = null, $prefix = '' )
3587
+ {
3588
+ if ( $map != null ) {
3589
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
3590
+ $newPrefix = $prefix . "responseEnvelope.";
3591
+ $this->responseEnvelope = new ResponseEnvelope();
3592
+ $this->responseEnvelope->init( $map, $newPrefix );
3593
+ }
3594
+ if ( PPUtils::array_match_key( $map, $prefix . "initiatingEntity." ) ) {
3595
+ $newPrefix = $prefix . "initiatingEntity.";
3596
+ $this->initiatingEntity = new InitiatingEntity();
3597
+ $this->initiatingEntity->init( $map, $newPrefix );
3598
+ }
3599
+ if ( PPUtils::array_match_key( $map, $prefix . "displayOptions." ) ) {
3600
+ $newPrefix = $prefix . "displayOptions.";
3601
+ $this->displayOptions = new DisplayOptions();
3602
+ $this->displayOptions->init( $map, $newPrefix );
3603
+ }
3604
+ $mapKeyName = $prefix . 'shippingAddressId';
3605
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
3606
+ $this->shippingAddressId = $map[ $mapKeyName ];
3607
+ }
3608
+ if ( PPUtils::array_match_key( $map, $prefix . "senderOptions." ) ) {
3609
+ $newPrefix = $prefix . "senderOptions.";
3610
+ $this->senderOptions = new SenderOptions();
3611
+ $this->senderOptions->init( $map, $newPrefix );
3612
+ }
3613
+ $i = 0;
3614
+ while ( true ) {
3615
+ if ( PPUtils::array_match_key( $map, $prefix . "receiverOptions($i)" ) ) {
3616
+ $newPrefix = $prefix . "receiverOptions($i).";
3617
+ $this->receiverOptions[ $i ] = new ReceiverOptions();
3618
+ $this->receiverOptions[ $i ]->init( $map, $newPrefix );
3619
+ } else {
3620
+ break;
3621
+ }
3622
+ $i++;
3623
+ }
3624
+ $i = 0;
3625
+ while ( true ) {
3626
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
3627
+ $newPrefix = $prefix . "error($i).";
3628
+ $this->error[ $i ] = new ErrorData();
3629
+ $this->error[ $i ]->init( $map, $newPrefix );
3630
+ } else {
3631
+ break;
3632
+ }
3633
+ $i++;
3634
+ }
3635
+
3636
+ }
3637
+ }
3638
+ }
3639
+
3640
+
3641
+ /**
3642
+ * The request to look up the details of a PayRequest. The
3643
+ * PaymentDetailsRequest can be made with either a payKey,
3644
+ * trackingId, or a transactionId of the PayRequest.
3645
+ */
3646
+ class PaymentDetailsRequest
3647
+ {
3648
+
3649
+ /**
3650
+ *
3651
+ * @access public
3652
+ * @var RequestEnvelope
3653
+ */
3654
+ public $requestEnvelope;
3655
+
3656
+ /**
3657
+ *
3658
+ * @access public
3659
+ * @var string
3660
+ */
3661
+ public $payKey;
3662
+
3663
+ /**
3664
+ *
3665
+ * @access public
3666
+ * @var string
3667
+ */
3668
+ public $transactionId;
3669
+
3670
+ /**
3671
+ *
3672
+ * @access public
3673
+ * @var string
3674
+ */
3675
+ public $trackingId;
3676
+
3677
+ /**
3678
+ * Constructor with arguments
3679
+ */
3680
+ public function __construct( $requestEnvelope = null )
3681
+ {
3682
+ $this->requestEnvelope = $requestEnvelope;
3683
+ }
3684
+
3685
+
3686
+ public function toNVPString( $prefix = '' )
3687
+ {
3688
+ $str = '';
3689
+ $delim = '';
3690
+ if ( $this->requestEnvelope != null ) {
3691
+ $newPrefix = $prefix . 'requestEnvelope.';
3692
+ $str .= $delim . call_user_func( array( $this->requestEnvelope, 'toNVPString' ), $newPrefix );
3693
+ $delim = '&';
3694
+ }
3695
+ if ( $this->payKey != null ) {
3696
+ $str .= $delim . $prefix . 'payKey=' . urlencode( $this->payKey );
3697
+ $delim = '&';
3698
+ }
3699
+ if ( $this->transactionId != null ) {
3700
+ $str .= $delim . $prefix . 'transactionId=' . urlencode( $this->transactionId );
3701
+ $delim = '&';
3702
+ }
3703
+ if ( $this->trackingId != null ) {
3704
+ $str .= $delim . $prefix . 'trackingId=' . urlencode( $this->trackingId );
3705
+ $delim = '&';
3706
+ }
3707
+
3708
+ return $str;
3709
+ }
3710
+
3711
+ }
3712
+
3713
+
3714
+ /**
3715
+ * The details of the PayRequest as specified in the Pay
3716
+ * operation.
3717
+ */
3718
+ class PaymentDetailsResponse
3719
+ {
3720
+
3721
+ /**
3722
+ *
3723
+ * @access public
3724
+ * @var ResponseEnvelope
3725
+ */
3726
+ public $responseEnvelope;
3727
+
3728
+ /**
3729
+ *
3730
+ * @access public
3731
+ * @var string
3732
+ */
3733
+ public $cancelUrl;
3734
+
3735
+ /**
3736
+ *
3737
+ * @access public
3738
+ * @var string
3739
+ */
3740
+ public $currencyCode;
3741
+
3742
+ /**
3743
+ *
3744
+ * @access public
3745
+ * @var string
3746
+ */
3747
+ public $ipnNotificationUrl;
3748
+
3749
+ /**
3750
+ *
3751
+ * @access public
3752
+ * @var string
3753
+ */
3754
+ public $memo;
3755
+
3756
+ /**
3757
+ *
3758
+ * @access public
3759
+ * @var PaymentInfoList
3760
+ */
3761
+ public $paymentInfoList;
3762
+
3763
+ /**
3764
+ *
3765
+ * @access public
3766
+ * @var string
3767
+ */
3768
+ public $returnUrl;
3769
+
3770
+ /**
3771
+ *
3772
+ * @access public
3773
+ * @var string
3774
+ */
3775
+ public $senderEmail;
3776
+
3777
+ /**
3778
+ *
3779
+ * @access public
3780
+ * @var string
3781
+ */
3782
+ public $status;
3783
+
3784
+ /**
3785
+ *
3786
+ * @access public
3787
+ * @var string
3788
+ */
3789
+ public $trackingId;
3790
+
3791
+ /**
3792
+ *
3793
+ * @access public
3794
+ * @var string
3795
+ */
3796
+ public $payKey;
3797
+
3798
+ /**
3799
+ *
3800
+ * @access public
3801
+ * @var string
3802
+ */
3803
+ public $actionType;
3804
+
3805
+ /**
3806
+ *
3807
+ * @access public
3808
+ * @var string
3809
+ */
3810
+ public $feesPayer;
3811
+
3812
+ /**
3813
+ *
3814
+ * @access public
3815
+ * @var boolean
3816
+ */
3817
+ public $reverseAllParallelPaymentsOnError;
3818
+
3819
+ /**
3820
+ *
3821
+ * @access public
3822
+ * @var string
3823
+ */
3824
+ public $preapprovalKey;
3825
+
3826
+ /**
3827
+ *
3828
+ * @access public
3829
+ * @var FundingConstraint
3830
+ */
3831
+ public $fundingConstraint;
3832
+
3833
+ /**
3834
+ *
3835
+ * @access public
3836
+ * @var SenderIdentifier
3837
+ */
3838
+ public $sender;
3839
+
3840
+ /**
3841
+ *
3842
+ * @array
3843
+ * @access public
3844
+ * @var ErrorData
3845
+ */
3846
+ public $error;
3847
+
3848
+
3849
+ public function init( $map = null, $prefix = '' )
3850
+ {
3851
+ if ( $map != null ) {
3852
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
3853
+ $newPrefix = $prefix . "responseEnvelope.";
3854
+ $this->responseEnvelope = new ResponseEnvelope();
3855
+ $this->responseEnvelope->init( $map, $newPrefix );
3856
+ }
3857
+ $mapKeyName = $prefix . 'cancelUrl';
3858
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
3859
+ $this->cancelUrl = $map[ $mapKeyName ];
3860
+ }
3861
+ $mapKeyName = $prefix . 'currencyCode';
3862
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
3863
+ $this->currencyCode = $map[ $mapKeyName ];
3864
+ }
3865
+ $mapKeyName = $prefix . 'ipnNotificationUrl';
3866
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
3867
+ $this->ipnNotificationUrl = $map[ $mapKeyName ];
3868
+ }
3869
+ $mapKeyName = $prefix . 'memo';
3870
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
3871
+ $this->memo = $map[ $mapKeyName ];
3872
+ }
3873
+ if ( PPUtils::array_match_key( $map, $prefix . "paymentInfoList." ) ) {
3874
+ $newPrefix = $prefix . "paymentInfoList.";
3875
+ $this->paymentInfoList = new PaymentInfoList();
3876
+ $this->paymentInfoList->init( $map, $newPrefix );
3877
+ }
3878
+ $mapKeyName = $prefix . 'returnUrl';
3879
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
3880
+ $this->returnUrl = $map[ $mapKeyName ];
3881
+ }
3882
+ $mapKeyName = $prefix . 'senderEmail';
3883
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
3884
+ $this->senderEmail = $map[ $mapKeyName ];
3885
+ }
3886
+ $mapKeyName = $prefix . 'status';
3887
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
3888
+ $this->status = $map[ $mapKeyName ];
3889
+ }
3890
+ $mapKeyName = $prefix . 'trackingId';
3891
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
3892
+ $this->trackingId = $map[ $mapKeyName ];
3893
+ }
3894
+ $mapKeyName = $prefix . 'payKey';
3895
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
3896
+ $this->payKey = $map[ $mapKeyName ];
3897
+ }
3898
+ $mapKeyName = $prefix . 'actionType';
3899
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
3900
+ $this->actionType = $map[ $mapKeyName ];
3901
+ }
3902
+ $mapKeyName = $prefix . 'feesPayer';
3903
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
3904
+ $this->feesPayer = $map[ $mapKeyName ];
3905
+ }
3906
+ $mapKeyName = $prefix . 'reverseAllParallelPaymentsOnError';
3907
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
3908
+ $this->reverseAllParallelPaymentsOnError = $map[ $mapKeyName ];
3909
+ }
3910
+ $mapKeyName = $prefix . 'preapprovalKey';
3911
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
3912
+ $this->preapprovalKey = $map[ $mapKeyName ];
3913
+ }
3914
+ if ( PPUtils::array_match_key( $map, $prefix . "fundingConstraint." ) ) {
3915
+ $newPrefix = $prefix . "fundingConstraint.";
3916
+ $this->fundingConstraint = new FundingConstraint();
3917
+ $this->fundingConstraint->init( $map, $newPrefix );
3918
+ }
3919
+ if ( PPUtils::array_match_key( $map, $prefix . "sender." ) ) {
3920
+ $newPrefix = $prefix . "sender.";
3921
+ $this->sender = new SenderIdentifier();
3922
+ $this->sender->init( $map, $newPrefix );
3923
+ }
3924
+ $i = 0;
3925
+ while ( true ) {
3926
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
3927
+ $newPrefix = $prefix . "error($i).";
3928
+ $this->error[ $i ] = new ErrorData();
3929
+ $this->error[ $i ]->init( $map, $newPrefix );
3930
+ } else {
3931
+ break;
3932
+ }
3933
+ $i++;
3934
+ }
3935
+
3936
+ }
3937
+ }
3938
+ }
3939
+
3940
+
3941
+ /**
3942
+ * The PayRequest contains the payment instructions to make
3943
+ * from sender to receivers.
3944
+ */
3945
+ class PayRequest
3946
+ {
3947
+
3948
+ /**
3949
+ *
3950
+ * @access public
3951
+ * @var RequestEnvelope
3952
+ */
3953
+ public $requestEnvelope;
3954
+
3955
+ /**
3956
+ *
3957
+ * @access public
3958
+ * @var ClientDetailsType
3959
+ */
3960
+ public $clientDetails;
3961
+
3962
+ /**
3963
+ *
3964
+ * @access public
3965
+ * @var string
3966
+ */
3967
+ public $actionType;
3968
+
3969
+ /**
3970
+ *
3971
+ * @access public
3972
+ * @var string
3973
+ */
3974
+ public $cancelUrl;
3975
+
3976
+ /**
3977
+ *
3978
+ * @access public
3979
+ * @var string
3980
+ */
3981
+ public $currencyCode;
3982
+
3983
+ /**
3984
+ *
3985
+ * @access public
3986
+ * @var string
3987
+ */
3988
+ public $feesPayer;
3989
+
3990
+ /**
3991
+ *
3992
+ * @access public
3993
+ * @var string
3994
+ */
3995
+ public $ipnNotificationUrl;
3996
+
3997
+ /**
3998
+ *
3999
+ * @access public
4000
+ * @var string
4001
+ */
4002
+ public $memo;
4003
+
4004
+ /**
4005
+ *
4006
+ * @access public
4007
+ * @var string
4008
+ */
4009
+ public $pin;
4010
+
4011
+ /**
4012
+ *
4013
+ * @access public
4014
+ * @var string
4015
+ */
4016
+ public $preapprovalKey;
4017
+
4018
+ /**
4019
+ *
4020
+ * @access public
4021
+ * @var ReceiverList
4022
+ */
4023
+ public $receiverList;
4024
+
4025
+ /**
4026
+ *
4027
+ * @access public
4028
+ * @var boolean
4029
+ */
4030
+ public $reverseAllParallelPaymentsOnError;
4031
+
4032
+ /**
4033
+ *
4034
+ * @access public
4035
+ * @var string
4036
+ */
4037
+ public $senderEmail;
4038
+
4039
+ /**
4040
+ *
4041
+ * @access public
4042
+ * @var string
4043
+ */
4044
+ public $returnUrl;
4045
+
4046
+ /**
4047
+ *
4048
+ * @access public
4049
+ * @var string
4050
+ */
4051
+ public $trackingId;
4052
+
4053
+ /**
4054
+ *
4055
+ * @access public
4056
+ * @var FundingConstraint
4057
+ */
4058
+ public $fundingConstraint;
4059
+
4060
+ /**
4061
+ *
4062
+ * @access public
4063
+ * @var SenderIdentifier
4064
+ */
4065
+ public $sender;
4066
+
4067
+ /**
4068
+ * Constructor with arguments
4069
+ */
4070
+ public function __construct( $requestEnvelope = null, $actionType = null, $cancelUrl = null, $currencyCode = null, $receiverList = null, $returnUrl = null )
4071
+ {
4072
+ $this->requestEnvelope = $requestEnvelope;
4073
+ $this->actionType = $actionType;
4074
+ $this->cancelUrl = $cancelUrl;
4075
+ $this->currencyCode = $currencyCode;
4076
+ $this->receiverList = $receiverList;
4077
+ $this->returnUrl = $returnUrl;
4078
+ }
4079
+
4080
+
4081
+ public function toNVPString( $prefix = '' )
4082
+ {
4083
+ $str = '';
4084
+ $delim = '';
4085
+ if ( $this->requestEnvelope != null ) {
4086
+ $newPrefix = $prefix . 'requestEnvelope.';
4087
+ $str .= $delim . call_user_func( array( $this->requestEnvelope, 'toNVPString' ), $newPrefix );
4088
+ $delim = '&';
4089
+ }
4090
+ if ( $this->clientDetails != null ) {
4091
+ $newPrefix = $prefix . 'clientDetails.';
4092
+ $str .= $delim . call_user_func( array( $this->clientDetails, 'toNVPString' ), $newPrefix );
4093
+ $delim = '&';
4094
+ }
4095
+ if ( $this->actionType != null ) {
4096
+ $str .= $delim . $prefix . 'actionType=' . urlencode( $this->actionType );
4097
+ $delim = '&';
4098
+ }
4099
+ if ( $this->cancelUrl != null ) {
4100
+ $str .= $delim . $prefix . 'cancelUrl=' . urlencode( $this->cancelUrl );
4101
+ $delim = '&';
4102
+ }
4103
+ if ( $this->currencyCode != null ) {
4104
+ $str .= $delim . $prefix . 'currencyCode=' . urlencode( $this->currencyCode );
4105
+ $delim = '&';
4106
+ }
4107
+ if ( $this->feesPayer != null ) {
4108
+ $str .= $delim . $prefix . 'feesPayer=' . urlencode( $this->feesPayer );
4109
+ $delim = '&';
4110
+ }
4111
+ if ( $this->ipnNotificationUrl != null ) {
4112
+ $str .= $delim . $prefix . 'ipnNotificationUrl=' . urlencode( $this->ipnNotificationUrl );
4113
+ $delim = '&';
4114
+ }
4115
+ if ( $this->memo != null ) {
4116
+ $str .= $delim . $prefix . 'memo=' . urlencode( $this->memo );
4117
+ $delim = '&';
4118
+ }
4119
+ if ( $this->pin != null ) {
4120
+ $str .= $delim . $prefix . 'pin=' . urlencode( $this->pin );
4121
+ $delim = '&';
4122
+ }
4123
+ if ( $this->preapprovalKey != null ) {
4124
+ $str .= $delim . $prefix . 'preapprovalKey=' . urlencode( $this->preapprovalKey );
4125
+ $delim = '&';
4126
+ }
4127
+ if ( $this->receiverList != null ) {
4128
+ $newPrefix = $prefix . 'receiverList.';
4129
+ $str .= $delim . call_user_func( array( $this->receiverList, 'toNVPString' ), $newPrefix );
4130
+ $delim = '&';
4131
+ }
4132
+ if ( $this->reverseAllParallelPaymentsOnError != null ) {
4133
+ $str .= $delim . $prefix . 'reverseAllParallelPaymentsOnError=' . urlencode( $this->reverseAllParallelPaymentsOnError );
4134
+ $delim = '&';
4135
+ }
4136
+ if ( $this->senderEmail != null ) {
4137
+ $str .= $delim . $prefix . 'senderEmail=' . urlencode( $this->senderEmail );
4138
+ $delim = '&';
4139
+ }
4140
+ if ( $this->returnUrl != null ) {
4141
+ $str .= $delim . $prefix . 'returnUrl=' . urlencode( $this->returnUrl );
4142
+ $delim = '&';
4143
+ }
4144
+ if ( $this->trackingId != null ) {
4145
+ $str .= $delim . $prefix . 'trackingId=' . urlencode( $this->trackingId );
4146
+ $delim = '&';
4147
+ }
4148
+ if ( $this->fundingConstraint != null ) {
4149
+ $newPrefix = $prefix . 'fundingConstraint.';
4150
+ $str .= $delim . call_user_func( array( $this->fundingConstraint, 'toNVPString' ), $newPrefix );
4151
+ $delim = '&';
4152
+ }
4153
+ if ( $this->sender != null ) {
4154
+ $newPrefix = $prefix . 'sender.';
4155
+ $str .= $delim . call_user_func( array( $this->sender, 'toNVPString' ), $newPrefix );
4156
+ $delim = '&';
4157
+ }
4158
+
4159
+ return $str;
4160
+ }
4161
+
4162
+ }
4163
+
4164
+
4165
+ /**
4166
+ * The PayResponse contains the result of the Pay operation.
4167
+ * The payKey and execution status of the request should always
4168
+ * be provided.
4169
+ */
4170
+ class PayResponse
4171
+ {
4172
+
4173
+ /**
4174
+ *
4175
+ * @access public
4176
+ * @var ResponseEnvelope
4177
+ */
4178
+ public $responseEnvelope;
4179
+
4180
+ /**
4181
+ *
4182
+ * @access public
4183
+ * @var string
4184
+ */
4185
+ public $payKey;
4186
+
4187
+ /**
4188
+ *
4189
+ * @access public
4190
+ * @var string
4191
+ */
4192
+ public $paymentExecStatus;
4193
+
4194
+ /**
4195
+ *
4196
+ * @access public
4197
+ * @var PayErrorList
4198
+ */
4199
+ public $payErrorList;
4200
+
4201
+ /**
4202
+ *
4203
+ * @access public
4204
+ * @var FundingPlan
4205
+ */
4206
+ public $defaultFundingPlan;
4207
+
4208
+ /**
4209
+ *
4210
+ * @array
4211
+ * @access public
4212
+ * @var ErrorData
4213
+ */
4214
+ public $error;
4215
+
4216
+
4217
+ public function init( $map = null, $prefix = '' )
4218
+ {
4219
+ if ( $map != null ) {
4220
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
4221
+ $newPrefix = $prefix . "responseEnvelope.";
4222
+ $this->responseEnvelope = new ResponseEnvelope();
4223
+ $this->responseEnvelope->init( $map, $newPrefix );
4224
+ }
4225
+ $mapKeyName = $prefix . 'payKey';
4226
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4227
+ $this->payKey = $map[ $mapKeyName ];
4228
+ }
4229
+ $mapKeyName = $prefix . 'paymentExecStatus';
4230
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4231
+ $this->paymentExecStatus = $map[ $mapKeyName ];
4232
+ }
4233
+ if ( PPUtils::array_match_key( $map, $prefix . "payErrorList." ) ) {
4234
+ $newPrefix = $prefix . "payErrorList.";
4235
+ $this->payErrorList = new PayErrorList();
4236
+ $this->payErrorList->init( $map, $newPrefix );
4237
+ }
4238
+ if ( PPUtils::array_match_key( $map, $prefix . "defaultFundingPlan." ) ) {
4239
+ $newPrefix = $prefix . "defaultFundingPlan.";
4240
+ $this->defaultFundingPlan = new FundingPlan();
4241
+ $this->defaultFundingPlan->init( $map, $newPrefix );
4242
+ }
4243
+ $i = 0;
4244
+ while ( true ) {
4245
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
4246
+ $newPrefix = $prefix . "error($i).";
4247
+ $this->error[ $i ] = new ErrorData();
4248
+ $this->error[ $i ]->init( $map, $newPrefix );
4249
+ } else {
4250
+ break;
4251
+ }
4252
+ $i++;
4253
+ }
4254
+
4255
+ }
4256
+ }
4257
+ }
4258
+
4259
+
4260
+ /**
4261
+ * The request to look up the details of a Preapproval.
4262
+ */
4263
+ class PreapprovalDetailsRequest
4264
+ {
4265
+
4266
+ /**
4267
+ *
4268
+ * @access public
4269
+ * @var RequestEnvelope
4270
+ */
4271
+ public $requestEnvelope;
4272
+
4273
+ /**
4274
+ *
4275
+ * @access public
4276
+ * @var string
4277
+ */
4278
+ public $preapprovalKey;
4279
+
4280
+ /**
4281
+ *
4282
+ * @access public
4283
+ * @var boolean
4284
+ */
4285
+ public $getBillingAddress;
4286
+
4287
+ /**
4288
+ * Constructor with arguments
4289
+ */
4290
+ public function __construct( $requestEnvelope = null, $preapprovalKey = null )
4291
+ {
4292
+ $this->requestEnvelope = $requestEnvelope;
4293
+ $this->preapprovalKey = $preapprovalKey;
4294
+ }
4295
+
4296
+
4297
+ public function toNVPString( $prefix = '' )
4298
+ {
4299
+ $str = '';
4300
+ $delim = '';
4301
+ if ( $this->requestEnvelope != null ) {
4302
+ $newPrefix = $prefix . 'requestEnvelope.';
4303
+ $str .= $delim . call_user_func( array( $this->requestEnvelope, 'toNVPString' ), $newPrefix );
4304
+ $delim = '&';
4305
+ }
4306
+ if ( $this->preapprovalKey != null ) {
4307
+ $str .= $delim . $prefix . 'preapprovalKey=' . urlencode( $this->preapprovalKey );
4308
+ $delim = '&';
4309
+ }
4310
+ if ( $this->getBillingAddress != null ) {
4311
+ $str .= $delim . $prefix . 'getBillingAddress=' . urlencode( $this->getBillingAddress );
4312
+ $delim = '&';
4313
+ }
4314
+
4315
+ return $str;
4316
+ }
4317
+
4318
+ }
4319
+
4320
+
4321
+ /**
4322
+ * The details of the Preapproval as specified in the
4323
+ * Preapproval operation.
4324
+ */
4325
+ class PreapprovalDetailsResponse
4326
+ {
4327
+
4328
+ /**
4329
+ *
4330
+ * @access public
4331
+ * @var ResponseEnvelope
4332
+ */
4333
+ public $responseEnvelope;
4334
+
4335
+ /**
4336
+ *
4337
+ * @access public
4338
+ * @var boolean
4339
+ */
4340
+ public $approved;
4341
+
4342
+ /**
4343
+ *
4344
+ * @access public
4345
+ * @var string
4346
+ */
4347
+ public $cancelUrl;
4348
+
4349
+ /**
4350
+ *
4351
+ * @access public
4352
+ * @var integer
4353
+ */
4354
+ public $curPayments;
4355
+
4356
+ /**
4357
+ *
4358
+ * @access public
4359
+ * @var double
4360
+ */
4361
+ public $curPaymentsAmount;
4362
+
4363
+ /**
4364
+ *
4365
+ * @access public
4366
+ * @var integer
4367
+ */
4368
+ public $curPeriodAttempts;
4369
+
4370
+ /**
4371
+ *
4372
+ * @access public
4373
+ * @var dateTime
4374
+ */
4375
+ public $curPeriodEndingDate;
4376
+
4377
+ /**
4378
+ *
4379
+ * @access public
4380
+ * @var string
4381
+ */
4382
+ public $currencyCode;
4383
+
4384
+ /**
4385
+ *
4386
+ * @access public
4387
+ * @var integer
4388
+ */
4389
+ public $dateOfMonth;
4390
+
4391
+ /**
4392
+ *
4393
+ * @access public
4394
+ * @var DayOfWeek
4395
+ */
4396
+ public $dayOfWeek;
4397
+
4398
+ /**
4399
+ *
4400
+ * @access public
4401
+ * @var dateTime
4402
+ */
4403
+ public $endingDate;
4404
+
4405
+ /**
4406
+ *
4407
+ * @access public
4408
+ * @var double
4409
+ */
4410
+ public $maxAmountPerPayment;
4411
+
4412
+ /**
4413
+ *
4414
+ * @access public
4415
+ * @var integer
4416
+ */
4417
+ public $maxNumberOfPayments;
4418
+
4419
+ /**
4420
+ *
4421
+ * @access public
4422
+ * @var integer
4423
+ */
4424
+ public $maxNumberOfPaymentsPerPeriod;
4425
+
4426
+ /**
4427
+ *
4428
+ * @access public
4429
+ * @var double
4430
+ */
4431
+ public $maxTotalAmountOfAllPayments;
4432
+
4433
+ /**
4434
+ *
4435
+ * @access public
4436
+ * @var string
4437
+ */
4438
+ public $paymentPeriod;
4439
+
4440
+ /**
4441
+ *
4442
+ * @access public
4443
+ * @var string
4444
+ */
4445
+ public $pinType;
4446
+
4447
+ /**
4448
+ *
4449
+ * @access public
4450
+ * @var string
4451
+ */
4452
+ public $returnUrl;
4453
+
4454
+ /**
4455
+ *
4456
+ * @access public
4457
+ * @var string
4458
+ */
4459
+ public $senderEmail;
4460
+
4461
+ /**
4462
+ *
4463
+ * @access public
4464
+ * @var string
4465
+ */
4466
+ public $memo;
4467
+
4468
+ /**
4469
+ *
4470
+ * @access public
4471
+ * @var dateTime
4472
+ */
4473
+ public $startingDate;
4474
+
4475
+ /**
4476
+ *
4477
+ * @access public
4478
+ * @var string
4479
+ */
4480
+ public $status;
4481
+
4482
+ /**
4483
+ *
4484
+ * @access public
4485
+ * @var string
4486
+ */
4487
+ public $ipnNotificationUrl;
4488
+
4489
+ /**
4490
+ *
4491
+ * @access public
4492
+ * @var AddressList
4493
+ */
4494
+ public $addressList;
4495
+
4496
+ /**
4497
+ *
4498
+ * @access public
4499
+ * @var string
4500
+ */
4501
+ public $feesPayer;
4502
+
4503
+ /**
4504
+ *
4505
+ * @access public
4506
+ * @var boolean
4507
+ */
4508
+ public $displayMaxTotalAmount;
4509
+
4510
+ /**
4511
+ *
4512
+ * @array
4513
+ * @access public
4514
+ * @var ErrorData
4515
+ */
4516
+ public $error;
4517
+
4518
+
4519
+ public function init( $map = null, $prefix = '' )
4520
+ {
4521
+ if ( $map != null ) {
4522
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
4523
+ $newPrefix = $prefix . "responseEnvelope.";
4524
+ $this->responseEnvelope = new ResponseEnvelope();
4525
+ $this->responseEnvelope->init( $map, $newPrefix );
4526
+ }
4527
+ $mapKeyName = $prefix . 'approved';
4528
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4529
+ $this->approved = $map[ $mapKeyName ];
4530
+ }
4531
+ $mapKeyName = $prefix . 'cancelUrl';
4532
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4533
+ $this->cancelUrl = $map[ $mapKeyName ];
4534
+ }
4535
+ $mapKeyName = $prefix . 'curPayments';
4536
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4537
+ $this->curPayments = $map[ $mapKeyName ];
4538
+ }
4539
+ $mapKeyName = $prefix . 'curPaymentsAmount';
4540
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4541
+ $this->curPaymentsAmount = $map[ $mapKeyName ];
4542
+ }
4543
+ $mapKeyName = $prefix . 'curPeriodAttempts';
4544
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4545
+ $this->curPeriodAttempts = $map[ $mapKeyName ];
4546
+ }
4547
+ $mapKeyName = $prefix . 'curPeriodEndingDate';
4548
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4549
+ $this->curPeriodEndingDate = $map[ $mapKeyName ];
4550
+ }
4551
+ $mapKeyName = $prefix . 'currencyCode';
4552
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4553
+ $this->currencyCode = $map[ $mapKeyName ];
4554
+ }
4555
+ $mapKeyName = $prefix . 'dateOfMonth';
4556
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4557
+ $this->dateOfMonth = $map[ $mapKeyName ];
4558
+ }
4559
+ $mapKeyName = $prefix . 'dayOfWeek';
4560
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4561
+ $this->dayOfWeek = $map[ $mapKeyName ];
4562
+ }
4563
+ $mapKeyName = $prefix . 'endingDate';
4564
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4565
+ $this->endingDate = $map[ $mapKeyName ];
4566
+ }
4567
+ $mapKeyName = $prefix . 'maxAmountPerPayment';
4568
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4569
+ $this->maxAmountPerPayment = $map[ $mapKeyName ];
4570
+ }
4571
+ $mapKeyName = $prefix . 'maxNumberOfPayments';
4572
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4573
+ $this->maxNumberOfPayments = $map[ $mapKeyName ];
4574
+ }
4575
+ $mapKeyName = $prefix . 'maxNumberOfPaymentsPerPeriod';
4576
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4577
+ $this->maxNumberOfPaymentsPerPeriod = $map[ $mapKeyName ];
4578
+ }
4579
+ $mapKeyName = $prefix . 'maxTotalAmountOfAllPayments';
4580
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4581
+ $this->maxTotalAmountOfAllPayments = $map[ $mapKeyName ];
4582
+ }
4583
+ $mapKeyName = $prefix . 'paymentPeriod';
4584
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4585
+ $this->paymentPeriod = $map[ $mapKeyName ];
4586
+ }
4587
+ $mapKeyName = $prefix . 'pinType';
4588
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4589
+ $this->pinType = $map[ $mapKeyName ];
4590
+ }
4591
+ $mapKeyName = $prefix . 'returnUrl';
4592
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4593
+ $this->returnUrl = $map[ $mapKeyName ];
4594
+ }
4595
+ $mapKeyName = $prefix . 'senderEmail';
4596
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4597
+ $this->senderEmail = $map[ $mapKeyName ];
4598
+ }
4599
+ $mapKeyName = $prefix . 'memo';
4600
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4601
+ $this->memo = $map[ $mapKeyName ];
4602
+ }
4603
+ $mapKeyName = $prefix . 'startingDate';
4604
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4605
+ $this->startingDate = $map[ $mapKeyName ];
4606
+ }
4607
+ $mapKeyName = $prefix . 'status';
4608
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4609
+ $this->status = $map[ $mapKeyName ];
4610
+ }
4611
+ $mapKeyName = $prefix . 'ipnNotificationUrl';
4612
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4613
+ $this->ipnNotificationUrl = $map[ $mapKeyName ];
4614
+ }
4615
+ if ( PPUtils::array_match_key( $map, $prefix . "addressList." ) ) {
4616
+ $newPrefix = $prefix . "addressList.";
4617
+ $this->addressList = new AddressList();
4618
+ $this->addressList->init( $map, $newPrefix );
4619
+ }
4620
+ $mapKeyName = $prefix . 'feesPayer';
4621
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4622
+ $this->feesPayer = $map[ $mapKeyName ];
4623
+ }
4624
+ $mapKeyName = $prefix . 'displayMaxTotalAmount';
4625
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4626
+ $this->displayMaxTotalAmount = $map[ $mapKeyName ];
4627
+ }
4628
+ $i = 0;
4629
+ while ( true ) {
4630
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
4631
+ $newPrefix = $prefix . "error($i).";
4632
+ $this->error[ $i ] = new ErrorData();
4633
+ $this->error[ $i ]->init( $map, $newPrefix );
4634
+ } else {
4635
+ break;
4636
+ }
4637
+ $i++;
4638
+ }
4639
+
4640
+ }
4641
+ }
4642
+ }
4643
+
4644
+
4645
+ /**
4646
+ * A request to create a Preapproval. A Preapproval is an
4647
+ * agreement between a Paypal account holder (the sender) and
4648
+ * the API caller (the service invoker) to make payment(s) on
4649
+ * the the sender's behalf with various limitations defined.
4650
+ */
4651
+ class PreapprovalRequest
4652
+ {
4653
+
4654
+ /**
4655
+ *
4656
+ * @access public
4657
+ * @var RequestEnvelope
4658
+ */
4659
+ public $requestEnvelope;
4660
+
4661
+ /**
4662
+ *
4663
+ * @access public
4664
+ * @var ClientDetailsType
4665
+ */
4666
+ public $clientDetails;
4667
+
4668
+ /**
4669
+ *
4670
+ * @access public
4671
+ * @var string
4672
+ */
4673
+ public $cancelUrl;
4674
+
4675
+ /**
4676
+ *
4677
+ * @access public
4678
+ * @var string
4679
+ */
4680
+ public $currencyCode;
4681
+
4682
+ /**
4683
+ *
4684
+ * @access public
4685
+ * @var integer
4686
+ */
4687
+ public $dateOfMonth;
4688
+
4689
+ /**
4690
+ *
4691
+ * @access public
4692
+ * @var DayOfWeek
4693
+ */
4694
+ public $dayOfWeek;
4695
+
4696
+ /**
4697
+ *
4698
+ * @access public
4699
+ * @var dateTime
4700
+ */
4701
+ public $endingDate;
4702
+
4703
+ /**
4704
+ *
4705
+ * @access public
4706
+ * @var double
4707
+ */
4708
+ public $maxAmountPerPayment;
4709
+
4710
+ /**
4711
+ *
4712
+ * @access public
4713
+ * @var integer
4714
+ */
4715
+ public $maxNumberOfPayments;
4716
+
4717
+ /**
4718
+ *
4719
+ * @access public
4720
+ * @var integer
4721
+ */
4722
+ public $maxNumberOfPaymentsPerPeriod;
4723
+
4724
+ /**
4725
+ *
4726
+ * @access public
4727
+ * @var double
4728
+ */
4729
+ public $maxTotalAmountOfAllPayments;
4730
+
4731
+ /**
4732
+ *
4733
+ * @access public
4734
+ * @var string
4735
+ */
4736
+ public $paymentPeriod;
4737
+
4738
+ /**
4739
+ *
4740
+ * @access public
4741
+ * @var string
4742
+ */
4743
+ public $returnUrl;
4744
+
4745
+ /**
4746
+ *
4747
+ * @access public
4748
+ * @var string
4749
+ */
4750
+ public $memo;
4751
+
4752
+ /**
4753
+ *
4754
+ * @access public
4755
+ * @var string
4756
+ */
4757
+ public $ipnNotificationUrl;
4758
+
4759
+ /**
4760
+ *
4761
+ * @access public
4762
+ * @var string
4763
+ */
4764
+ public $senderEmail;
4765
+
4766
+ /**
4767
+ *
4768
+ * @access public
4769
+ * @var dateTime
4770
+ */
4771
+ public $startingDate;
4772
+
4773
+ /**
4774
+ *
4775
+ * @access public
4776
+ * @var string
4777
+ */
4778
+ public $pinType;
4779
+
4780
+ /**
4781
+ *
4782
+ * @access public
4783
+ * @var string
4784
+ */
4785
+ public $feesPayer;
4786
+
4787
+ /**
4788
+ *
4789
+ * @access public
4790
+ * @var boolean
4791
+ */
4792
+ public $displayMaxTotalAmount;
4793
+
4794
+ /**
4795
+ * Constructor with arguments
4796
+ */
4797
+ public function __construct( $requestEnvelope = null, $cancelUrl = null, $currencyCode = null, $returnUrl = null, $startingDate = null )
4798
+ {
4799
+ $this->requestEnvelope = $requestEnvelope;
4800
+ $this->cancelUrl = $cancelUrl;
4801
+ $this->currencyCode = $currencyCode;
4802
+ $this->returnUrl = $returnUrl;
4803
+ $this->startingDate = $startingDate;
4804
+ }
4805
+
4806
+
4807
+ public function toNVPString( $prefix = '' )
4808
+ {
4809
+ $str = '';
4810
+ $delim = '';
4811
+ if ( $this->requestEnvelope != null ) {
4812
+ $newPrefix = $prefix . 'requestEnvelope.';
4813
+ $str .= $delim . call_user_func( array( $this->requestEnvelope, 'toNVPString' ), $newPrefix );
4814
+ $delim = '&';
4815
+ }
4816
+ if ( $this->clientDetails != null ) {
4817
+ $newPrefix = $prefix . 'clientDetails.';
4818
+ $str .= $delim . call_user_func( array( $this->clientDetails, 'toNVPString' ), $newPrefix );
4819
+ $delim = '&';
4820
+ }
4821
+ if ( $this->cancelUrl != null ) {
4822
+ $str .= $delim . $prefix . 'cancelUrl=' . urlencode( $this->cancelUrl );
4823
+ $delim = '&';
4824
+ }
4825
+ if ( $this->currencyCode != null ) {
4826
+ $str .= $delim . $prefix . 'currencyCode=' . urlencode( $this->currencyCode );
4827
+ $delim = '&';
4828
+ }
4829
+ if ( $this->dateOfMonth != null ) {
4830
+ $str .= $delim . $prefix . 'dateOfMonth=' . urlencode( $this->dateOfMonth );
4831
+ $delim = '&';
4832
+ }
4833
+ if ( $this->dayOfWeek != null ) {
4834
+ $str .= $delim . $prefix . 'dayOfWeek=' . urlencode( $this->dayOfWeek );
4835
+ $delim = '&';
4836
+ }
4837
+ if ( $this->endingDate != null ) {
4838
+ $str .= $delim . $prefix . 'endingDate=' . urlencode( $this->endingDate );
4839
+ $delim = '&';
4840
+ }
4841
+ if ( $this->maxAmountPerPayment != null ) {
4842
+ $str .= $delim . $prefix . 'maxAmountPerPayment=' . urlencode( $this->maxAmountPerPayment );
4843
+ $delim = '&';
4844
+ }
4845
+ if ( $this->maxNumberOfPayments != null ) {
4846
+ $str .= $delim . $prefix . 'maxNumberOfPayments=' . urlencode( $this->maxNumberOfPayments );
4847
+ $delim = '&';
4848
+ }
4849
+ if ( $this->maxNumberOfPaymentsPerPeriod != null ) {
4850
+ $str .= $delim . $prefix . 'maxNumberOfPaymentsPerPeriod=' . urlencode( $this->maxNumberOfPaymentsPerPeriod );
4851
+ $delim = '&';
4852
+ }
4853
+ if ( $this->maxTotalAmountOfAllPayments != null ) {
4854
+ $str .= $delim . $prefix . 'maxTotalAmountOfAllPayments=' . urlencode( $this->maxTotalAmountOfAllPayments );
4855
+ $delim = '&';
4856
+ }
4857
+ if ( $this->paymentPeriod != null ) {
4858
+ $str .= $delim . $prefix . 'paymentPeriod=' . urlencode( $this->paymentPeriod );
4859
+ $delim = '&';
4860
+ }
4861
+ if ( $this->returnUrl != null ) {
4862
+ $str .= $delim . $prefix . 'returnUrl=' . urlencode( $this->returnUrl );
4863
+ $delim = '&';
4864
+ }
4865
+ if ( $this->memo != null ) {
4866
+ $str .= $delim . $prefix . 'memo=' . urlencode( $this->memo );
4867
+ $delim = '&';
4868
+ }
4869
+ if ( $this->ipnNotificationUrl != null ) {
4870
+ $str .= $delim . $prefix . 'ipnNotificationUrl=' . urlencode( $this->ipnNotificationUrl );
4871
+ $delim = '&';
4872
+ }
4873
+ if ( $this->senderEmail != null ) {
4874
+ $str .= $delim . $prefix . 'senderEmail=' . urlencode( $this->senderEmail );
4875
+ $delim = '&';
4876
+ }
4877
+ if ( $this->startingDate != null ) {
4878
+ $str .= $delim . $prefix . 'startingDate=' . urlencode( $this->startingDate );
4879
+ $delim = '&';
4880
+ }
4881
+ if ( $this->pinType != null ) {
4882
+ $str .= $delim . $prefix . 'pinType=' . urlencode( $this->pinType );
4883
+ $delim = '&';
4884
+ }
4885
+ if ( $this->feesPayer != null ) {
4886
+ $str .= $delim . $prefix . 'feesPayer=' . urlencode( $this->feesPayer );
4887
+ $delim = '&';
4888
+ }
4889
+ if ( $this->displayMaxTotalAmount != null ) {
4890
+ $str .= $delim . $prefix . 'displayMaxTotalAmount=' . urlencode( $this->displayMaxTotalAmount );
4891
+ $delim = '&';
4892
+ }
4893
+
4894
+ return $str;
4895
+ }
4896
+
4897
+ }
4898
+
4899
+
4900
+ /**
4901
+ * The result of the PreapprovalRequest is a preapprovalKey.
4902
+ */
4903
+ class PreapprovalResponse
4904
+ {
4905
+
4906
+ /**
4907
+ *
4908
+ * @access public
4909
+ * @var ResponseEnvelope
4910
+ */
4911
+ public $responseEnvelope;
4912
+
4913
+ /**
4914
+ *
4915
+ * @access public
4916
+ * @var string
4917
+ */
4918
+ public $preapprovalKey;
4919
+
4920
+ /**
4921
+ *
4922
+ * @array
4923
+ * @access public
4924
+ * @var ErrorData
4925
+ */
4926
+ public $error;
4927
+
4928
+
4929
+ public function init( $map = null, $prefix = '' )
4930
+ {
4931
+ if ( $map != null ) {
4932
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
4933
+ $newPrefix = $prefix . "responseEnvelope.";
4934
+ $this->responseEnvelope = new ResponseEnvelope();
4935
+ $this->responseEnvelope->init( $map, $newPrefix );
4936
+ }
4937
+ $mapKeyName = $prefix . 'preapprovalKey';
4938
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
4939
+ $this->preapprovalKey = $map[ $mapKeyName ];
4940
+ }
4941
+ $i = 0;
4942
+ while ( true ) {
4943
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
4944
+ $newPrefix = $prefix . "error($i).";
4945
+ $this->error[ $i ] = new ErrorData();
4946
+ $this->error[ $i ]->init( $map, $newPrefix );
4947
+ } else {
4948
+ break;
4949
+ }
4950
+ $i++;
4951
+ }
4952
+
4953
+ }
4954
+ }
4955
+ }
4956
+
4957
+
4958
+ /**
4959
+ * A request to make a refund based on various criteria. A
4960
+ * refund can be made against the entire payKey, an individual
4961
+ * transaction belonging to a payKey, a tracking id, or a
4962
+ * specific receiver of a payKey.
4963
+ */
4964
+ class RefundRequest
4965
+ {
4966
+
4967
+ /**
4968
+ *
4969
+ * @access public
4970
+ * @var RequestEnvelope
4971
+ */
4972
+ public $requestEnvelope;
4973
+
4974
+ /**
4975
+ *
4976
+ * @access public
4977
+ * @var string
4978
+ */
4979
+ public $currencyCode;
4980
+
4981
+ /**
4982
+ *
4983
+ * @access public
4984
+ * @var string
4985
+ */
4986
+ public $payKey;
4987
+
4988
+ /**
4989
+ *
4990
+ * @access public
4991
+ * @var string
4992
+ */
4993
+ public $transactionId;
4994
+
4995
+ /**
4996
+ *
4997
+ * @access public
4998
+ * @var string
4999
+ */
5000
+ public $trackingId;
5001
+
5002
+ /**
5003
+ *
5004
+ * @access public
5005
+ * @var ReceiverList
5006
+ */
5007
+ public $receiverList;
5008
+
5009
+ /**
5010
+ * Constructor with arguments
5011
+ */
5012
+ public function __construct( $requestEnvelope = null )
5013
+ {
5014
+ $this->requestEnvelope = $requestEnvelope;
5015
+ }
5016
+
5017
+
5018
+ public function toNVPString( $prefix = '' )
5019
+ {
5020
+ $str = '';
5021
+ $delim = '';
5022
+ if ( $this->requestEnvelope != null ) {
5023
+ $newPrefix = $prefix . 'requestEnvelope.';
5024
+ $str .= $delim . call_user_func( array( $this->requestEnvelope, 'toNVPString' ), $newPrefix );
5025
+ $delim = '&';
5026
+ }
5027
+ if ( $this->currencyCode != null ) {
5028
+ $str .= $delim . $prefix . 'currencyCode=' . urlencode( $this->currencyCode );
5029
+ $delim = '&';
5030
+ }
5031
+ if ( $this->payKey != null ) {
5032
+ $str .= $delim . $prefix . 'payKey=' . urlencode( $this->payKey );
5033
+ $delim = '&';
5034
+ }
5035
+ if ( $this->transactionId != null ) {
5036
+ $str .= $delim . $prefix . 'transactionId=' . urlencode( $this->transactionId );
5037
+ $delim = '&';
5038
+ }
5039
+ if ( $this->trackingId != null ) {
5040
+ $str .= $delim . $prefix . 'trackingId=' . urlencode( $this->trackingId );
5041
+ $delim = '&';
5042
+ }
5043
+ if ( $this->receiverList != null ) {
5044
+ $newPrefix = $prefix . 'receiverList.';
5045
+ $str .= $delim . call_user_func( array( $this->receiverList, 'toNVPString' ), $newPrefix );
5046
+ $delim = '&';
5047
+ }
5048
+
5049
+ return $str;
5050
+ }
5051
+
5052
+ }
5053
+
5054
+
5055
+ /**
5056
+ * The result of a Refund request.
5057
+ */
5058
+ class RefundResponse
5059
+ {
5060
+
5061
+ /**
5062
+ *
5063
+ * @access public
5064
+ * @var ResponseEnvelope
5065
+ */
5066
+ public $responseEnvelope;
5067
+
5068
+ /**
5069
+ *
5070
+ * @access public
5071
+ * @var string
5072
+ */
5073
+ public $currencyCode;
5074
+
5075
+ /**
5076
+ *
5077
+ * @access public
5078
+ * @var RefundInfoList
5079
+ */
5080
+ public $refundInfoList;
5081
+
5082
+ /**
5083
+ *
5084
+ * @array
5085
+ * @access public
5086
+ * @var ErrorData
5087
+ */
5088
+ public $error;
5089
+
5090
+
5091
+ public function init( $map = null, $prefix = '' )
5092
+ {
5093
+ if ( $map != null ) {
5094
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
5095
+ $newPrefix = $prefix . "responseEnvelope.";
5096
+ $this->responseEnvelope = new ResponseEnvelope();
5097
+ $this->responseEnvelope->init( $map, $newPrefix );
5098
+ }
5099
+ $mapKeyName = $prefix . 'currencyCode';
5100
+ if ( $map != null && array_key_exists( $mapKeyName, $map ) ) {
5101
+ $this->currencyCode = $map[ $mapKeyName ];
5102
+ }
5103
+ if ( PPUtils::array_match_key( $map, $prefix . "refundInfoList." ) ) {
5104
+ $newPrefix = $prefix . "refundInfoList.";
5105
+ $this->refundInfoList = new RefundInfoList();
5106
+ $this->refundInfoList->init( $map, $newPrefix );
5107
+ }
5108
+ $i = 0;
5109
+ while ( true ) {
5110
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
5111
+ $newPrefix = $prefix . "error($i).";
5112
+ $this->error[ $i ] = new ErrorData();
5113
+ $this->error[ $i ]->init( $map, $newPrefix );
5114
+ } else {
5115
+ break;
5116
+ }
5117
+ $i++;
5118
+ }
5119
+
5120
+ }
5121
+ }
5122
+ }
5123
+
5124
+
5125
+ /**
5126
+ * The request to set the options of a payment request.
5127
+ */
5128
+ class SetPaymentOptionsRequest
5129
+ {
5130
+
5131
+ /**
5132
+ *
5133
+ * @access public
5134
+ * @var RequestEnvelope
5135
+ */
5136
+ public $requestEnvelope;
5137
+
5138
+ /**
5139
+ *
5140
+ * @access public
5141
+ * @var string
5142
+ */
5143
+ public $payKey;
5144
+
5145
+ /**
5146
+ *
5147
+ * @access public
5148
+ * @var InitiatingEntity
5149
+ */
5150
+ public $initiatingEntity;
5151
+
5152
+ /**
5153
+ *
5154
+ * @access public
5155
+ * @var DisplayOptions
5156
+ */
5157
+ public $displayOptions;
5158
+
5159
+ /**
5160
+ *
5161
+ * @access public
5162
+ * @var string
5163
+ */
5164
+ public $shippingAddressId;
5165
+
5166
+ /**
5167
+ *
5168
+ * @access public
5169
+ * @var SenderOptions
5170
+ */
5171
+ public $senderOptions;
5172
+
5173
+ /**
5174
+ *
5175
+ * @array
5176
+ * @access public
5177
+ * @var ReceiverOptions
5178
+ */
5179
+ public $receiverOptions;
5180
+
5181
+ /**
5182
+ * Constructor with arguments
5183
+ */
5184
+ public function __construct( $requestEnvelope = null, $payKey = null )
5185
+ {
5186
+ $this->requestEnvelope = $requestEnvelope;
5187
+ $this->payKey = $payKey;
5188
+ }
5189
+
5190
+
5191
+ public function toNVPString( $prefix = '' )
5192
+ {
5193
+ $str = '';
5194
+ $delim = '';
5195
+ if ( $this->requestEnvelope != null ) {
5196
+ $newPrefix = $prefix . 'requestEnvelope.';
5197
+ $str .= $delim . call_user_func( array( $this->requestEnvelope, 'toNVPString' ), $newPrefix );
5198
+ $delim = '&';
5199
+ }
5200
+ if ( $this->payKey != null ) {
5201
+ $str .= $delim . $prefix . 'payKey=' . urlencode( $this->payKey );
5202
+ $delim = '&';
5203
+ }
5204
+ if ( $this->initiatingEntity != null ) {
5205
+ $newPrefix = $prefix . 'initiatingEntity.';
5206
+ $str .= $delim . call_user_func( array( $this->initiatingEntity, 'toNVPString' ), $newPrefix );
5207
+ $delim = '&';
5208
+ }
5209
+ if ( $this->displayOptions != null ) {
5210
+ $newPrefix = $prefix . 'displayOptions.';
5211
+ $str .= $delim . call_user_func( array( $this->displayOptions, 'toNVPString' ), $newPrefix );
5212
+ $delim = '&';
5213
+ }
5214
+ if ( $this->shippingAddressId != null ) {
5215
+ $str .= $delim . $prefix . 'shippingAddressId=' . urlencode( $this->shippingAddressId );
5216
+ $delim = '&';
5217
+ }
5218
+ if ( $this->senderOptions != null ) {
5219
+ $newPrefix = $prefix . 'senderOptions.';
5220
+ $str .= $delim . call_user_func( array( $this->senderOptions, 'toNVPString' ), $newPrefix );
5221
+ $delim = '&';
5222
+ }
5223
+ for ( $i = 0; $i < count( $this->receiverOptions ); $i++ ) {
5224
+ $newPrefix = $prefix . "receiverOptions($i).";
5225
+ $str .= $delim . call_user_func( array( $this->receiverOptions[ $i ], 'toNVPString' ), $newPrefix );
5226
+ $delim = '&';
5227
+ }
5228
+
5229
+ return $str;
5230
+ }
5231
+
5232
+ }
5233
+
5234
+
5235
+ /**
5236
+ * The response message for the SetPaymentOption request
5237
+ */
5238
+ class SetPaymentOptionsResponse
5239
+ {
5240
+
5241
+ /**
5242
+ *
5243
+ * @access public
5244
+ * @var ResponseEnvelope
5245
+ */
5246
+ public $responseEnvelope;
5247
+
5248
+ /**
5249
+ *
5250
+ * @array
5251
+ * @access public
5252
+ * @var ErrorData
5253
+ */
5254
+ public $error;
5255
+
5256
+
5257
+ public function init( $map = null, $prefix = '' )
5258
+ {
5259
+ if ( $map != null ) {
5260
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
5261
+ $newPrefix = $prefix . "responseEnvelope.";
5262
+ $this->responseEnvelope = new ResponseEnvelope();
5263
+ $this->responseEnvelope->init( $map, $newPrefix );
5264
+ }
5265
+ $i = 0;
5266
+ while ( true ) {
5267
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
5268
+ $newPrefix = $prefix . "error($i).";
5269
+ $this->error[ $i ] = new ErrorData();
5270
+ $this->error[ $i ]->init( $map, $newPrefix );
5271
+ } else {
5272
+ break;
5273
+ }
5274
+ $i++;
5275
+ }
5276
+
5277
+ }
5278
+ }
5279
+ }
5280
+
5281
+
5282
+ /**
5283
+ * The request to get the funding plans available for a
5284
+ * payment.
5285
+ */
5286
+ class GetFundingPlansRequest
5287
+ {
5288
+
5289
+ /**
5290
+ *
5291
+ * @access public
5292
+ * @var RequestEnvelope
5293
+ */
5294
+ public $requestEnvelope;
5295
+
5296
+ /**
5297
+ *
5298
+ * @access public
5299
+ * @var string
5300
+ */
5301
+ public $payKey;
5302
+
5303
+ /**
5304
+ * Constructor with arguments
5305
+ */
5306
+ public function __construct( $requestEnvelope = null, $payKey = null )
5307
+ {
5308
+ $this->requestEnvelope = $requestEnvelope;
5309
+ $this->payKey = $payKey;
5310
+ }
5311
+
5312
+
5313
+ public function toNVPString( $prefix = '' )
5314
+ {
5315
+ $str = '';
5316
+ $delim = '';
5317
+ if ( $this->requestEnvelope != null ) {
5318
+ $newPrefix = $prefix . 'requestEnvelope.';
5319
+ $str .= $delim . call_user_func( array( $this->requestEnvelope, 'toNVPString' ), $newPrefix );
5320
+ $delim = '&';
5321
+ }
5322
+ if ( $this->payKey != null ) {
5323
+ $str .= $delim . $prefix . 'payKey=' . urlencode( $this->payKey );
5324
+ $delim = '&';
5325
+ }
5326
+
5327
+ return $str;
5328
+ }
5329
+
5330
+ }
5331
+
5332
+
5333
+ /**
5334
+ * The response to get the funding plans available for a
5335
+ * payment.
5336
+ */
5337
+ class GetFundingPlansResponse
5338
+ {
5339
+
5340
+ /**
5341
+ *
5342
+ * @access public
5343
+ * @var ResponseEnvelope
5344
+ */
5345
+ public $responseEnvelope;
5346
+
5347
+ /**
5348
+ *
5349
+ * @array
5350
+ * @access public
5351
+ * @var FundingPlan
5352
+ */
5353
+ public $fundingPlan;
5354
+
5355
+ /**
5356
+ *
5357
+ * @array
5358
+ * @access public
5359
+ * @var ErrorData
5360
+ */
5361
+ public $error;
5362
+
5363
+
5364
+ public function init( $map = null, $prefix = '' )
5365
+ {
5366
+ if ( $map != null ) {
5367
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
5368
+ $newPrefix = $prefix . "responseEnvelope.";
5369
+ $this->responseEnvelope = new ResponseEnvelope();
5370
+ $this->responseEnvelope->init( $map, $newPrefix );
5371
+ }
5372
+ $i = 0;
5373
+ while ( true ) {
5374
+ if ( PPUtils::array_match_key( $map, $prefix . "fundingPlan($i)" ) ) {
5375
+ $newPrefix = $prefix . "fundingPlan($i).";
5376
+ $this->fundingPlan[ $i ] = new FundingPlan();
5377
+ $this->fundingPlan[ $i ]->init( $map, $newPrefix );
5378
+ } else {
5379
+ break;
5380
+ }
5381
+ $i++;
5382
+ }
5383
+ $i = 0;
5384
+ while ( true ) {
5385
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
5386
+ $newPrefix = $prefix . "error($i).";
5387
+ $this->error[ $i ] = new ErrorData();
5388
+ $this->error[ $i ]->init( $map, $newPrefix );
5389
+ } else {
5390
+ break;
5391
+ }
5392
+ $i++;
5393
+ }
5394
+
5395
+ }
5396
+ }
5397
+ }
5398
+
5399
+
5400
+ /**
5401
+ * The request to get the addresses available for a payment.
5402
+ */
5403
+ class GetAvailableShippingAddressesRequest
5404
+ {
5405
+
5406
+ /**
5407
+ *
5408
+ * @access public
5409
+ * @var RequestEnvelope
5410
+ */
5411
+ public $requestEnvelope;
5412
+
5413
+ /**
5414
+ * The key for which to provide the available addresses. Key
5415
+ * can be an AdaptivePayments key such as payKey or
5416
+ * preapprovalKey
5417
+ * @access public
5418
+ * @var string
5419
+ */
5420
+ public $key;
5421
+
5422
+ /**
5423
+ * Constructor with arguments
5424
+ */
5425
+ public function __construct( $requestEnvelope = null, $key = null )
5426
+ {
5427
+ $this->requestEnvelope = $requestEnvelope;
5428
+ $this->key = $key;
5429
+ }
5430
+
5431
+
5432
+ public function toNVPString( $prefix = '' )
5433
+ {
5434
+ $str = '';
5435
+ $delim = '';
5436
+ if ( $this->requestEnvelope != null ) {
5437
+ $newPrefix = $prefix . 'requestEnvelope.';
5438
+ $str .= $delim . call_user_func( array( $this->requestEnvelope, 'toNVPString' ), $newPrefix );
5439
+ $delim = '&';
5440
+ }
5441
+ if ( $this->key != null ) {
5442
+ $str .= $delim . $prefix . 'key=' . urlencode( $this->key );
5443
+ $delim = '&';
5444
+ }
5445
+
5446
+ return $str;
5447
+ }
5448
+
5449
+ }
5450
+
5451
+
5452
+ /**
5453
+ * The response to get the shipping addresses available for a
5454
+ * payment.
5455
+ */
5456
+ class GetAvailableShippingAddressesResponse
5457
+ {
5458
+
5459
+ /**
5460
+ *
5461
+ * @access public
5462
+ * @var ResponseEnvelope
5463
+ */
5464
+ public $responseEnvelope;
5465
+
5466
+ /**
5467
+ *
5468
+ * @array
5469
+ * @access public
5470
+ * @var Address
5471
+ */
5472
+ public $availableAddress;
5473
+
5474
+ /**
5475
+ *
5476
+ * @array
5477
+ * @access public
5478
+ * @var ErrorData
5479
+ */
5480
+ public $error;
5481
+
5482
+
5483
+ public function init( $map = null, $prefix = '' )
5484
+ {
5485
+ if ( $map != null ) {
5486
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
5487
+ $newPrefix = $prefix . "responseEnvelope.";
5488
+ $this->responseEnvelope = new ResponseEnvelope();
5489
+ $this->responseEnvelope->init( $map, $newPrefix );
5490
+ }
5491
+ $i = 0;
5492
+ while ( true ) {
5493
+ if ( PPUtils::array_match_key( $map, $prefix . "availableAddress($i)" ) ) {
5494
+ $newPrefix = $prefix . "availableAddress($i).";
5495
+ $this->availableAddress[ $i ] = new Address();
5496
+ $this->availableAddress[ $i ]->init( $map, $newPrefix );
5497
+ } else {
5498
+ break;
5499
+ }
5500
+ $i++;
5501
+ }
5502
+ $i = 0;
5503
+ while ( true ) {
5504
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
5505
+ $newPrefix = $prefix . "error($i).";
5506
+ $this->error[ $i ] = new ErrorData();
5507
+ $this->error[ $i ]->init( $map, $newPrefix );
5508
+ } else {
5509
+ break;
5510
+ }
5511
+ $i++;
5512
+ }
5513
+
5514
+ }
5515
+ }
5516
+ }
5517
+
5518
+
5519
+ /**
5520
+ * The request to get the addresses available for a payment.
5521
+ */
5522
+ class GetShippingAddressesRequest
5523
+ {
5524
+
5525
+ /**
5526
+ *
5527
+ * @access public
5528
+ * @var RequestEnvelope
5529
+ */
5530
+ public $requestEnvelope;
5531
+
5532
+ /**
5533
+ * The key for which to provide the available addresses. Key
5534
+ * can be an AdaptivePayments key such as payKey or
5535
+ * preapprovalKey
5536
+ * @access public
5537
+ * @var string
5538
+ */
5539
+ public $key;
5540
+
5541
+ /**
5542
+ * Constructor with arguments
5543
+ */
5544
+ public function __construct( $requestEnvelope = null, $key = null )
5545
+ {
5546
+ $this->requestEnvelope = $requestEnvelope;
5547
+ $this->key = $key;
5548
+ }
5549
+
5550
+
5551
+ public function toNVPString( $prefix = '' )
5552
+ {
5553
+ $str = '';
5554
+ $delim = '';
5555
+ if ( $this->requestEnvelope != null ) {
5556
+ $newPrefix = $prefix . 'requestEnvelope.';
5557
+ $str .= $delim . call_user_func( array( $this->requestEnvelope, 'toNVPString' ), $newPrefix );
5558
+ $delim = '&';
5559
+ }
5560
+ if ( $this->key != null ) {
5561
+ $str .= $delim . $prefix . 'key=' . urlencode( $this->key );
5562
+ $delim = '&';
5563
+ }
5564
+
5565
+ return $str;
5566
+ }
5567
+
5568
+ }
5569
+
5570
+
5571
+ /**
5572
+ * The response to get the shipping addresses available for a
5573
+ * payment.
5574
+ */
5575
+ class GetShippingAddressesResponse
5576
+ {
5577
+
5578
+ /**
5579
+ *
5580
+ * @access public
5581
+ * @var ResponseEnvelope
5582
+ */
5583
+ public $responseEnvelope;
5584
+
5585
+ /**
5586
+ *
5587
+ * @access public
5588
+ * @var Address
5589
+ */
5590
+ public $selectedAddress;
5591
+
5592
+ /**
5593
+ *
5594
+ * @array
5595
+ * @access public
5596
+ * @var ErrorData
5597
+ */
5598
+ public $error;
5599
+
5600
+
5601
+ public function init( $map = null, $prefix = '' )
5602
+ {
5603
+ if ( $map != null ) {
5604
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
5605
+ $newPrefix = $prefix . "responseEnvelope.";
5606
+ $this->responseEnvelope = new ResponseEnvelope();
5607
+ $this->responseEnvelope->init( $map, $newPrefix );
5608
+ }
5609
+ if ( PPUtils::array_match_key( $map, $prefix . "selectedAddress." ) ) {
5610
+ $newPrefix = $prefix . "selectedAddress.";
5611
+ $this->selectedAddress = new Address();
5612
+ $this->selectedAddress->init( $map, $newPrefix );
5613
+ }
5614
+ $i = 0;
5615
+ while ( true ) {
5616
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
5617
+ $newPrefix = $prefix . "error($i).";
5618
+ $this->error[ $i ] = new ErrorData();
5619
+ $this->error[ $i ]->init( $map, $newPrefix );
5620
+ } else {
5621
+ break;
5622
+ }
5623
+ $i++;
5624
+ }
5625
+
5626
+ }
5627
+ }
5628
+ }
5629
+
5630
+
5631
+ /**
5632
+ * The request to get the remaining limits for a user
5633
+ */
5634
+ class GetUserLimitsRequest
5635
+ {
5636
+
5637
+ /**
5638
+ *
5639
+ * @access public
5640
+ * @var RequestEnvelope
5641
+ */
5642
+ public $requestEnvelope;
5643
+
5644
+ /**
5645
+ * The account identifier for the user
5646
+ * @access public
5647
+ * @var AccountIdentifier
5648
+ */
5649
+ public $user;
5650
+
5651
+ /**
5652
+ *
5653
+ * @access public
5654
+ * @var string
5655
+ */
5656
+ public $country;
5657
+
5658
+ /**
5659
+ *
5660
+ * @access public
5661
+ * @var string
5662
+ */
5663
+ public $currencyCode;
5664
+
5665
+ /**
5666
+ * List of limit types
5667
+ * @array
5668
+ * @access public
5669
+ * @var string
5670
+ */
5671
+ public $limitType;
5672
+
5673
+ /**
5674
+ * Constructor with arguments
5675
+ */
5676
+ public function __construct( $requestEnvelope = null, $user = null, $country = null, $currencyCode = null, $limitType = null )
5677
+ {
5678
+ $this->requestEnvelope = $requestEnvelope;
5679
+ $this->user = $user;
5680
+ $this->country = $country;
5681
+ $this->currencyCode = $currencyCode;
5682
+ $this->limitType = $limitType;
5683
+ }
5684
+
5685
+
5686
+ public function toNVPString( $prefix = '' )
5687
+ {
5688
+ $str = '';
5689
+ $delim = '';
5690
+ if ( $this->requestEnvelope != null ) {
5691
+ $newPrefix = $prefix . 'requestEnvelope.';
5692
+ $str .= $delim . call_user_func( array( $this->requestEnvelope, 'toNVPString' ), $newPrefix );
5693
+ $delim = '&';
5694
+ }
5695
+ if ( $this->user != null ) {
5696
+ $newPrefix = $prefix . 'user.';
5697
+ $str .= $delim . call_user_func( array( $this->user, 'toNVPString' ), $newPrefix );
5698
+ $delim = '&';
5699
+ }
5700
+ if ( $this->country != null ) {
5701
+ $str .= $delim . $prefix . 'country=' . urlencode( $this->country );
5702
+ $delim = '&';
5703
+ }
5704
+ if ( $this->currencyCode != null ) {
5705
+ $str .= $delim . $prefix . 'currencyCode=' . urlencode( $this->currencyCode );
5706
+ $delim = '&';
5707
+ }
5708
+ for ( $i = 0; $i < count( $this->limitType ); $i++ ) {
5709
+ $str .= $delim . $prefix . "limitType($i)=" . urlencode( $this->limitType[ $i ] );
5710
+ $delim = '&';
5711
+ }
5712
+
5713
+ return $str;
5714
+ }
5715
+
5716
+ }
5717
+
5718
+
5719
+ /**
5720
+ * A response that contains a list of remaining limits
5721
+ */
5722
+ class GetUserLimitsResponse
5723
+ {
5724
+
5725
+ /**
5726
+ *
5727
+ * @access public
5728
+ * @var ResponseEnvelope
5729
+ */
5730
+ public $responseEnvelope;
5731
+
5732
+ /**
5733
+ *
5734
+ * @array
5735
+ * @access public
5736
+ * @var UserLimit
5737
+ */
5738
+ public $userLimit;
5739
+
5740
+ /**
5741
+ *
5742
+ * @access public
5743
+ * @var WarningDataList
5744
+ */
5745
+ public $warningDataList;
5746
+
5747
+ /**
5748
+ *
5749
+ * @array
5750
+ * @access public
5751
+ * @var ErrorData
5752
+ */
5753
+ public $error;
5754
+
5755
+
5756
+ public function init( $map = null, $prefix = '' )
5757
+ {
5758
+ if ( $map != null ) {
5759
+ if ( PPUtils::array_match_key( $map, $prefix . "responseEnvelope." ) ) {
5760
+ $newPrefix = $prefix . "responseEnvelope.";
5761
+ $this->responseEnvelope = new ResponseEnvelope();
5762
+ $this->responseEnvelope->init( $map, $newPrefix );
5763
+ }
5764
+ $i = 0;
5765
+ while ( true ) {
5766
+ if ( PPUtils::array_match_key( $map, $prefix . "userLimit($i)" ) ) {
5767
+ $newPrefix = $prefix . "userLimit($i).";
5768
+ $this->userLimit[ $i ] = new UserLimit();
5769
+ $this->userLimit[ $i ]->init( $map, $newPrefix );
5770
+ } else {
5771
+ break;
5772
+ }
5773
+ $i++;
5774
+ }
5775
+ if ( PPUtils::array_match_key( $map, $prefix . "warningDataList." ) ) {
5776
+ $newPrefix = $prefix . "warningDataList.";
5777
+ $this->warningDataList = new WarningDataList();
5778
+ $this->warningDataList->init( $map, $newPrefix );
5779
+ }
5780
+ $i = 0;
5781
+ while ( true ) {
5782
+ if ( PPUtils::array_match_key( $map, $prefix . "error($i)" ) ) {
5783
+ $newPrefix = $prefix . "error($i).";
5784
+ $this->error[ $i ] = new ErrorData();
5785
+ $this->error[ $i ]->init( $map, $newPrefix );
5786
+ } else {
5787
+ break;
5788
+ }
5789
+ $i++;
5790
+ }
5791
+
5792
+ }
5793
+ }
5794
+ }
5795
+
5796
+
5797
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/adaptivepayments-sdk/lib/services/AdaptivePayments/AdaptivePaymentsService.php ADDED
@@ -0,0 +1,314 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once( 'PPBaseService.php' );
3
+ require_once( 'AdaptivePayments.php' );
4
+ require_once( 'PPUtils.php' );
5
+
6
+
7
+ /**
8
+ * AUTO GENERATED code for AdaptivePayments
9
+ */
10
+ class AdaptivePaymentsService extends PPBaseService
11
+ {
12
+
13
+ // Service Version
14
+ private static $SERVICE_VERSION = "1.8.1";
15
+
16
+ // Service Name
17
+ private static $SERVICE_NAME = "AdaptivePayments";
18
+
19
+ public function __construct()
20
+ {
21
+ parent::__construct( 'AdaptivePayments' );
22
+ }
23
+
24
+
25
+ /**
26
+ * Service Call: CancelPreapproval
27
+ *
28
+ * @param CancelPreapprovalRequest $cancelPreapprovalRequest
29
+ *
30
+ * @return CancelPreapprovalResponse
31
+ * @throws APIException
32
+ */
33
+ public function CancelPreapproval( $cancelPreapprovalRequest, $apiUsername = null )
34
+ {
35
+ $ret = new CancelPreapprovalResponse();
36
+ $resp = $this->call( "CancelPreapproval", $cancelPreapprovalRequest, $apiUsername );
37
+ $ret->init( PPUtils::nvpToMap( $resp ) );
38
+
39
+ return $ret;
40
+ }
41
+
42
+
43
+ /**
44
+ * Service Call: ConfirmPreapproval
45
+ *
46
+ * @param ConfirmPreapprovalRequest $confirmPreapprovalRequest
47
+ *
48
+ * @return ConfirmPreapprovalResponse
49
+ * @throws APIException
50
+ */
51
+ public function ConfirmPreapproval( $confirmPreapprovalRequest, $apiUsername = null )
52
+ {
53
+ $ret = new ConfirmPreapprovalResponse();
54
+ $resp = $this->call( "ConfirmPreapproval", $confirmPreapprovalRequest, $apiUsername );
55
+ $ret->init( PPUtils::nvpToMap( $resp ) );
56
+
57
+ return $ret;
58
+ }
59
+
60
+
61
+ /**
62
+ * Service Call: ConvertCurrency
63
+ *
64
+ * @param ConvertCurrencyRequest $convertCurrencyRequest
65
+ *
66
+ * @return ConvertCurrencyResponse
67
+ * @throws APIException
68
+ */
69
+ public function ConvertCurrency( $convertCurrencyRequest, $apiUsername = null )
70
+ {
71
+ $ret = new ConvertCurrencyResponse();
72
+ $resp = $this->call( "ConvertCurrency", $convertCurrencyRequest, $apiUsername );
73
+ $ret->init( PPUtils::nvpToMap( $resp ) );
74
+
75
+ return $ret;
76
+ }
77
+
78
+
79
+ /**
80
+ * Service Call: ExecutePayment
81
+ *
82
+ * @param ExecutePaymentRequest $executePaymentRequest
83
+ *
84
+ * @return ExecutePaymentResponse
85
+ * @throws APIException
86
+ */
87
+ public function ExecutePayment( $executePaymentRequest, $apiUsername = null )
88
+ {
89
+ $ret = new ExecutePaymentResponse();
90
+ $resp = $this->call( "ExecutePayment", $executePaymentRequest, $apiUsername );
91
+ $ret->init( PPUtils::nvpToMap( $resp ) );
92
+
93
+ return $ret;
94
+ }
95
+
96
+
97
+ /**
98
+ * Service Call: GetAllowedFundingSources
99
+ *
100
+ * @param GetAllowedFundingSourcesRequest $getAllowedFundingSourcesRequest
101
+ *
102
+ * @return GetAllowedFundingSourcesResponse
103
+ * @throws APIException
104
+ */
105
+ public function GetAllowedFundingSources( $getAllowedFundingSourcesRequest, $apiUsername = null )
106
+ {
107
+ $ret = new GetAllowedFundingSourcesResponse();
108
+ $resp = $this->call( "GetAllowedFundingSources", $getAllowedFundingSourcesRequest, $apiUsername );
109
+ $ret->init( PPUtils::nvpToMap( $resp ) );
110
+
111
+ return $ret;
112
+ }
113
+
114
+
115
+ /**
116
+ * Service Call: GetPaymentOptions
117
+ *
118
+ * @param GetPaymentOptionsRequest $getPaymentOptionsRequest
119
+ *
120
+ * @return GetPaymentOptionsResponse
121
+ * @throws APIException
122
+ */
123
+ public function GetPaymentOptions( $getPaymentOptionsRequest, $apiUsername = null )
124
+ {
125
+ $ret = new GetPaymentOptionsResponse();
126
+ $resp = $this->call( "GetPaymentOptions", $getPaymentOptionsRequest, $apiUsername );
127
+ $ret->init( PPUtils::nvpToMap( $resp ) );
128
+
129
+ return $ret;
130
+ }
131
+
132
+
133
+ /**
134
+ * Service Call: PaymentDetails
135
+ *
136
+ * @param PaymentDetailsRequest $paymentDetailsRequest
137
+ *
138
+ * @return PaymentDetailsResponse
139
+ * @throws APIException
140
+ */
141
+ public function PaymentDetails( $paymentDetailsRequest, $apiUsername = null )
142
+ {
143
+ $ret = new PaymentDetailsResponse();
144
+ $resp = $this->call( "PaymentDetails", $paymentDetailsRequest, $apiUsername );
145
+ $ret->init( PPUtils::nvpToMap( $resp ) );
146
+
147
+ return $ret;
148
+ }
149
+
150
+
151
+ /**
152
+ * Service Call: Pay
153
+ *
154
+ * @param PayRequest $payRequest
155
+ *
156
+ * @return PayResponse
157
+ * @throws APIException
158
+ */
159
+ public function Pay( $payRequest, $apiUsername = null )
160
+ {
161
+ $ret = new PayResponse();
162
+ $resp = $this->call( "Pay", $payRequest, $apiUsername );
163
+ $ret->init( PPUtils::nvpToMap( $resp ) );
164
+
165
+ return $ret;
166
+ }
167
+
168
+
169
+ /**
170
+ * Service Call: PreapprovalDetails
171
+ *
172
+ * @param PreapprovalDetailsRequest $preapprovalDetailsRequest
173
+ *
174
+ * @return PreapprovalDetailsResponse
175
+ * @throws APIException
176
+ */
177
+ public function PreapprovalDetails( $preapprovalDetailsRequest, $apiUsername = null )
178
+ {
179
+ $ret = new PreapprovalDetailsResponse();
180
+ $resp = $this->call( "PreapprovalDetails", $preapprovalDetailsRequest, $apiUsername );
181
+ $ret->init( PPUtils::nvpToMap( $resp ) );
182
+
183
+ return $ret;
184
+ }
185
+
186
+
187
+ /**
188
+ * Service Call: Preapproval
189
+ *
190
+ * @param PreapprovalRequest $preapprovalRequest
191
+ *
192
+ * @return PreapprovalResponse
193
+ * @throws APIException
194
+ */
195
+ public function Preapproval( $preapprovalRequest, $apiUsername = null )
196
+ {
197
+ $ret = new PreapprovalResponse();
198
+ $resp = $this->call( "Preapproval", $preapprovalRequest, $apiUsername );
199
+ $ret->init( PPUtils::nvpToMap( $resp ) );
200
+
201
+ return $ret;
202
+ }
203
+
204
+
205
+ /**
206
+ * Service Call: Refund
207
+ *
208
+ * @param RefundRequest $refundRequest
209
+ *
210
+ * @return RefundResponse
211
+ * @throws APIException
212
+ */
213
+ public function Refund( $refundRequest, $apiUsername = null )
214
+ {
215
+ $ret = new RefundResponse();
216
+ $resp = $this->call( "Refund", $refundRequest, $apiUsername );
217
+ $ret->init( PPUtils::nvpToMap( $resp ) );
218
+
219
+ return $ret;
220
+ }
221
+
222
+
223
+ /**
224
+ * Service Call: SetPaymentOptions
225
+ *
226
+ * @param SetPaymentOptionsRequest $setPaymentOptionsRequest
227
+ *
228
+ * @return SetPaymentOptionsResponse
229
+ * @throws APIException
230
+ */
231
+ public function SetPaymentOptions( $setPaymentOptionsRequest, $apiUsername = null )
232
+ {
233
+ $ret = new SetPaymentOptionsResponse();
234
+ $resp = $this->call( "SetPaymentOptions", $setPaymentOptionsRequest, $apiUsername );
235
+ $ret->init( PPUtils::nvpToMap( $resp ) );
236
+
237
+ return $ret;
238
+ }
239
+
240
+
241
+ /**
242
+ * Service Call: GetFundingPlans
243
+ *
244
+ * @param GetFundingPlansRequest $getFundingPlansRequest
245
+ *
246
+ * @return GetFundingPlansResponse
247
+ * @throws APIException
248
+ */
249
+ public function GetFundingPlans( $getFundingPlansRequest, $apiUsername = null )
250
+ {
251
+ $ret = new GetFundingPlansResponse();
252
+ $resp = $this->call( "GetFundingPlans", $getFundingPlansRequest, $apiUsername );
253
+ $ret->init( PPUtils::nvpToMap( $resp ) );
254
+
255
+ return $ret;
256
+ }
257
+
258
+
259
+ /**
260
+ * Service Call: GetAvailableShippingAddresses
261
+ *
262
+ * @param GetAvailableShippingAddressesRequest $getAvailableShippingAddressesRequest
263
+ *
264
+ * @return GetAvailableShippingAddressesResponse
265
+ * @throws APIException
266
+ */
267
+ public function GetAvailableShippingAddresses( $getAvailableShippingAddressesRequest, $apiUsername = null )
268
+ {
269
+ $ret = new GetAvailableShippingAddressesResponse();
270
+ $resp = $this->call( "GetAvailableShippingAddresses", $getAvailableShippingAddressesRequest, $apiUsername );
271
+ $ret->init( PPUtils::nvpToMap( $resp ) );
272
+
273
+ return $ret;
274
+ }
275
+
276
+
277
+ /**
278
+ * Service Call: GetShippingAddresses
279
+ *
280
+ * @param GetShippingAddressesRequest $getShippingAddressesRequest
281
+ *
282
+ * @return GetShippingAddressesResponse
283
+ * @throws APIException
284
+ */
285
+ public function GetShippingAddresses( $getShippingAddressesRequest, $apiUsername = null )
286
+ {
287
+ $ret = new GetShippingAddressesResponse();
288
+ $resp = $this->call( "GetShippingAddresses", $getShippingAddressesRequest, $apiUsername );
289
+ $ret->init( PPUtils::nvpToMap( $resp ) );
290
+
291
+ return $ret;
292
+ }
293
+
294
+
295
+ /**
296
+ * Service Call: GetUserLimits
297
+ *
298
+ * @param GetUserLimitsRequest $getUserLimitsRequest
299
+ *
300
+ * @return GetUserLimitsResponse
301
+ * @throws APIException
302
+ */
303
+ public function GetUserLimits( $getUserLimitsRequest, $apiUsername = null )
304
+ {
305
+ $ret = new GetUserLimitsResponse();
306
+ $resp = $this->call( "GetUserLimits", $getUserLimitsRequest, $apiUsername );
307
+ $ret->init( PPUtils::nvpToMap( $resp ) );
308
+
309
+ return $ret;
310
+ }
311
+
312
+ }
313
+
314
+ ?>
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/PayPal_AP/classes/index.php ADDED
File without changes
trunk/WCVendors/classes/gateways/PayPal_AdvPayments/paypal_ap.php ADDED
@@ -0,0 +1,542 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( !class_exists( 'WC_Payment_Gateway' ) ) return false;
4
+
5
+ /**
6
+ * Add the gateway to WooCommerce
7
+ *
8
+ * @access public
9
+ *
10
+ * @param array $methods
11
+ *
12
+ * @return array
13
+ */
14
+
15
+
16
+ function add_paypal_ap_gateway( $methods )
17
+ {
18
+ $methods[ ] = 'WC_PaypalAP';
19
+
20
+ return $methods;
21
+ }
22
+
23
+
24
+ add_filter( 'woocommerce_payment_gateways', 'add_paypal_ap_gateway' );
25
+
26
+ class WC_PaypalAP extends WC_Payment_Gateway
27
+ {
28
+
29
+ public static $pluginDir;
30
+
31
+ /**
32
+ *
33
+ */
34
+ public function __construct()
35
+ {
36
+ global $woocommerce;
37
+
38
+ self::$pluginDir = trailingslashit( dirname( __FILE__ ) ) . 'PayPal_AP/';
39
+
40
+ /* Standard WooCommerce Configuration */
41
+ $this->id = 'paypalap';
42
+ $this->icon = plugin_dir_url( __FILE__ ) . 'PayPal_AP/assets/icons/paypalap.png';
43
+ $this->method_title = __( 'PayPal Adaptive Payments', 'wcvendors' );
44
+ $this->has_fields = false;
45
+
46
+ // Load the settings
47
+ $this->init_form_fields();
48
+ $this->init_settings();
49
+
50
+ $this->enabled = $this->settings[ 'enabled' ];
51
+ $this->title = $this->settings[ 'title' ];
52
+ $this->description = $this->settings[ 'description' ];
53
+
54
+ $this->currency = get_option( 'woocommerce_currency' );
55
+
56
+ /* PayPal Adaptive Payments Configuration. */
57
+ $this->sandbox = $this->settings[ 'sandbox_enabled' ];
58
+ $this->main_paypal = $this->sandbox == 'yes' ? $this->settings[ 'main_paypal' ] : $this->settings[ 'main_paypal_live' ];
59
+ $this->instapay = WC_Vendors::$pv_options->get_option( 'instapay' );
60
+ $this->give_tax = WC_Vendors::$pv_options->get_option( 'give_tax' );
61
+
62
+ add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
63
+
64
+ // Payment listener/API hook
65
+ add_action( 'woocommerce_api_wc_paypalap', array( $this, 'paypal_ap_ipn' ) );
66
+
67
+ $this->debug_me = false;
68
+ }
69
+
70
+
71
+ /**
72
+ *
73
+ *
74
+ * @return unknown
75
+ */
76
+ public function is_available()
77
+ {
78
+ return ( $this->is_valid_currency() && $this->enabled == 'yes' );
79
+ }
80
+
81
+
82
+ /**
83
+ *
84
+ *
85
+ * @return unknown
86
+ */
87
+ public function is_valid_currency()
88
+ {
89
+ return in_array( get_woocommerce_currency(), array( 'AUD', 'BRL', 'CAD', 'MXN', 'NZD', 'HKD', 'SGD', 'USD', 'EUR', 'JPY', 'TRY', 'NOK', 'CZK', 'DKK', 'HUF', 'ILS', 'MYR', 'PHP', 'PLN', 'SEK', 'CHF', 'TWD', 'THB', 'GBP', 'RMB' ) );
90
+ }
91
+
92
+
93
+ /**
94
+ *
95
+ */
96
+ public function include_paypal_sdk()
97
+ {
98
+ $path = self::$pluginDir . 'classes/adaptivepayments-sdk/lib';
99
+ set_include_path( get_include_path() . PATH_SEPARATOR . $path );
100
+ require_once 'services/AdaptivePayments/AdaptivePaymentsService.php';
101
+ }
102
+
103
+
104
+ /**
105
+ *
106
+ *
107
+ * @return unknown
108
+ */
109
+ public function paypal_ap_ipn()
110
+ {
111
+ if ( empty( $_GET[ 'paypal_chain_ipn' ] ) || empty( $_GET[ 'order_id' ] ) ) return false;
112
+
113
+ $order_id = (int) $_GET[ 'order_id' ];
114
+
115
+ $order = new WC_Order( $order_id );
116
+ if ( !$order ) return false;
117
+
118
+ if ( $_POST[ 'status' ] !== 'COMPLETED' ) {
119
+ $order->update_status( 'failed', sprintf( __( 'Something went wrong. Response from PayPal invalidated this order. Status: %s.', 'wcvendors' ), $_POST[ 'status' ] ) );
120
+ exit;
121
+ }
122
+
123
+ $order->payment_complete();
124
+ $order->add_order_note( __( 'IPN payment completed', 'wcvendors' ) );
125
+
126
+ if ( $this->instapay ) {
127
+ WCV_Commission::set_order_commission_paid( $order_id );
128
+ }
129
+ exit;
130
+ }
131
+
132
+
133
+ /**
134
+ * Initialise Gateway Settings Form Fields
135
+ *
136
+ * @access public
137
+ * @return void
138
+ */
139
+ function init_form_fields()
140
+ {
141
+
142
+ $this->form_fields = array();
143
+
144
+ // List each option in order of appearance with details
145
+ $this->form_fields[ 'enabled' ] = array(
146
+ 'title' => __( 'Enable PayPal Adaptive Payments', 'wcvendors' ),
147
+ 'default' => 'no',
148
+ 'type' => 'checkbox',
149
+ );
150
+
151
+ $this->form_fields[ 'title' ] = array(
152
+ 'title' => __( 'Method Title', 'wcvendors' ),
153
+ 'description' => __( 'This controls the title which the user sees during checkout.', 'wcvendors' ),
154
+ 'default' => __( 'PayPal', 'wcvendors' ),
155
+ 'type' => 'text'
156
+ );
157
+
158
+ $this->form_fields[ 'description' ] = array(
159
+ 'title' => __( 'Description', 'wcvendors' ),
160
+ 'description' => __( 'This controls the description which the user sees during checkout.', 'wcvendors' ),
161
+ 'default' => __( "Pay via PayPal!", 'wcvendors' ),
162
+ 'type' => 'textarea'
163
+ );
164
+
165
+ // ==================================================================
166
+ //
167
+ // Credentials
168
+ //
169
+ // ------------------------------------------------------------------
170
+
171
+ $this->form_fields[ ] = array(
172
+ 'title' => __( 'Live Credentials', 'wcvendors' ),
173
+ 'type' => 'title',
174
+ 'description' => sprintf( __( 'You must have an <a href="%s">Application ID</a> to process live transactions. You do not need one for testing in Sandbox mode.', 'wcvendors' )
175
+ , 'https://developer.paypal.com/webapps/developer/docs/classic/lifecycle/goingLive/' )
176
+ );
177
+
178
+ $this->form_fields[ 'main_paypal_live' ] = array(
179
+ 'title' => __( 'PayPal Email', 'wcvendors' ),
180
+ 'description' => __( 'The email address main payments should go to.', 'wcvendors' ),
181
+ 'type' => 'text'
182
+ );
183
+
184
+ $this->form_fields[ 'username_live' ] = array(
185
+ 'title' => __( 'API Username', 'wcvendors' ),
186
+ 'type' => 'text'
187
+ );
188
+
189
+ $this->form_fields[ 'password_live' ] = array(
190
+ 'title' => __( 'API Password', 'wcvendors' ),
191
+ 'type' => 'text'
192
+ );
193
+
194
+ $this->form_fields[ 'signature_live' ] = array(
195
+ 'title' => __( 'API Signature', 'wcvendors' ),
196
+ 'type' => 'text'
197
+ );
198
+
199
+ $this->form_fields[ 'app_id' ] = array(
200
+ 'title' => __( 'Application ID', 'wcvendors' ),
201
+ 'type' => 'text',
202
+ 'description' => __( 'Only required when doing live transactions.', 'wcvendors' ),
203
+ );
204
+
205
+ $this->form_fields[ ] = array(
206
+ 'title' => __( 'Sandbox Credentials', 'wcvendors' ),
207
+ 'type' => 'title',
208
+ 'description' => sprintf( __( 'You can signup for a sandbox developer account <a href="%s">here</a>. You need a developer account if you want to enable Sandbox mode for testing.', 'wcvendors' )
209
+ , 'https://developer.paypal.com/' )
210
+ );
211
+
212
+ $this->form_fields[ 'main_paypal' ] = array(
213
+ 'title' => __( 'PayPal Email', 'wcvendors' ),
214
+ 'description' => __( 'The email address main payments should go to.', 'wcvendors' ),
215
+ 'type' => 'text'
216
+ );
217
+
218
+ $this->form_fields[ 'username' ] = array(
219
+ 'title' => __( 'API Username', 'wcvendors' ),
220
+ 'type' => 'text'
221
+ );
222
+
223
+ $this->form_fields[ 'password' ] = array(
224
+ 'title' => __( 'API Password', 'wcvendors' ),
225
+ 'type' => 'text'
226
+ );
227
+
228
+ $this->form_fields[ 'signature' ] = array(
229
+ 'title' => __( 'API Signature', 'wcvendors' ),
230
+ 'type' => 'text'
231
+ );
232
+
233
+ // ==================================================================
234
+ //
235
+ // Misc. Settings
236
+ //
237
+ // ------------------------------------------------------------------
238
+
239
+ $this->form_fields[ ] = array(
240
+ 'title' => __( 'Misc. Settings', 'wcvendors' ),
241
+ 'type' => 'title',
242
+ );
243
+
244
+ $this->form_fields[ 'sandbox_enabled' ] = array(
245
+ 'title' => __( 'Enable PayPal Sandbox mode', 'wcvendors' ),
246
+ 'default' => 'yes',
247
+ 'type' => 'checkbox',
248
+ );
249
+
250
+ $this->form_fields[ 'logging_enabled' ] = array(
251
+ 'title' => __( 'Enable logging', 'wcvendors' ),
252
+ 'default' => 'no',
253
+ 'type' => 'checkbox',
254
+ );
255
+
256
+ }
257
+
258
+
259
+ /**
260
+ * Admin Panel Options
261
+ *
262
+ * @access public
263
+ * @return void
264
+ */
265
+ function admin_options()
266
+ {
267
+ ?>
268
+ <h3><?php echo $this->method_title; ?></h3>
269
+ <p><?php _e( 'The PayPal Adaptive Payments gateway can instantly pay your vendors their due commission (if enabled). Also used to mass pay vendors on a schedule / manual method (if enabled).', 'wcvendors' ); ?></p>
270
+ <table class="form-table">
271
+
272
+ <?php if ( $this->is_valid_currency() ) :
273
+
274
+ // Generate the HTML For the settings form.
275
+ $this->generate_settings_html();
276
+
277
+ else : ?>
278
+
279
+ <div class="inline error"><p>
280
+ <strong><?php _e( 'Gateway Disabled', 'wcvendors' ); ?></strong>: <?php printf( __( '%s does not support your store currency.', 'wcvendors' ), $this->method_title ); ?>
281
+ </p></div>
282
+
283
+ <?php endif; ?>
284
+
285
+ </table>
286
+ <?php
287
+ }
288
+
289
+
290
+ /**
291
+ *
292
+ *
293
+ * @param unknown $order
294
+ *
295
+ * @return unknown
296
+ */
297
+ private function get_receivers( $order )
298
+ {
299
+ $receivers = WCV_Vendors::get_vendor_dues_from_order( $order );
300
+
301
+ $i = 0;
302
+ $response = array();
303
+ foreach ( $receivers as $author => $values ) {
304
+ if ( empty( $values[ 'total' ] ) ) continue;
305
+
306
+ $response[ $i ] = new Receiver();
307
+ $response[ $i ]->email = $values[ 'vendor_id' ] == 1 ? $this->main_paypal : WCV_Vendors::get_vendor_paypal( $values[ 'vendor_id' ] );
308
+ $response[ $i ]->amount = $values[ 'total' ];
309
+ $response[ $i ]->primary = false;
310
+ $response[ $i ]->invoiceId = $order->id;
311
+ $i++;
312
+ }
313
+
314
+ if ( $this->debug_me ) {
315
+ var_dump( $response );
316
+ }
317
+
318
+ return $response;
319
+ }
320
+
321
+
322
+ /**
323
+ *
324
+ *
325
+ * @param unknown $order_id
326
+ *
327
+ * @return unknown
328
+ */
329
+ public function paypalap_check_form( $order_id )
330
+ {
331
+ global $woocommerce;
332
+
333
+ $this->include_paypal_sdk();
334
+ $this->logger = new PPLoggingManager( 'Pay' );
335
+ $order = new WC_Order( $order_id );
336
+
337
+ $receivers = $this->get_receivers( $order );
338
+ $receiverList = new ReceiverList( $receivers );
339
+
340
+ $actionType = 'CREATE';
341
+ $cancelUrl = $order->get_cancel_order_url();
342
+ $currencyCode = get_woocommerce_currency();
343
+ $returnUrl = add_query_arg( 'key', $order->order_key, add_query_arg( 'order', $order->id, get_permalink( apply_filters( 'woocommerce_get_checkout_redirect_page_id', woocommerce_get_page_id( 'thanks' ) ) ) ) );
344
+
345
+ $payRequest = new PayRequest( new RequestEnvelope( "en_US" ), $actionType, $cancelUrl, $currencyCode, $receiverList, $returnUrl );
346
+
347
+ // ==================================================================
348
+ //
349
+ // Optional params
350
+ //
351
+ // ------------------------------------------------------------------
352
+
353
+ $payRequest->feesPayer = 'EACHRECEIVER';
354
+
355
+ $args = array(
356
+ 'wc-api' => 'WC_PayPalAP',
357
+ 'paypal_chain_ipn' => '1',
358
+ 'order_id' => $order_id,
359
+ );
360
+
361
+ $payRequest->ipnNotificationUrl = str_replace( 'https:', 'http:', add_query_arg( $args, home_url( '/' ) ) );
362
+ $payRequest->memo = !empty( $order->customer_note ) ? $order->customer_note : '';
363
+ $payRequest->reverseAllParallelPaymentsOnError = true;
364
+
365
+ $service = new AdaptivePaymentsService();
366
+ try {
367
+ $response = $service->Pay( $payRequest );
368
+ } catch ( Exception $ex ) {
369
+ wc_add_notice( sprintf( __( 'Error: %s', 'wcvendors' ), $ex->getMessage() ), 'error' );
370
+
371
+ return false;
372
+ }
373
+
374
+ $this->logger->log( "Received payResponse:" );
375
+ $ack = strtoupper( $response->responseEnvelope->ack );
376
+
377
+ if ( $ack != 'SUCCESS' ) {
378
+ $order->update_status( 'cancelled', sprintf( __( 'Error ID: %s. %s', 'wcvendors' ), $response->error[ 0 ]->errorId, $response->error[ 0 ]->message ) );
379
+ wc_add_notice( sprintf( __( 'Error ID: %s. %s', 'wcvendors' ), $response->error[ 0 ]->errorId, $response->error[ 0 ]->message ), 'error' );
380
+
381
+ return false;
382
+ }
383
+
384
+ return $response->payKey;
385
+ }
386
+
387
+
388
+ /**
389
+ *
390
+ *
391
+ * @param unknown $order
392
+ * @param unknown $author_email
393
+ * @param unknown $setPaymentOptionsRequest
394
+ * @param unknown $is_admin (optional)
395
+ *
396
+ * @return unknown
397
+ */
398
+ public function set_vendor_items( $order, $setPaymentOptionsRequest )
399
+ {
400
+ $receivers = WCV_Vendors::get_vendor_dues_from_order( $order, false );
401
+ $receivers_two = WCV_Vendors::get_vendor_dues_from_order( $order );
402
+
403
+ foreach ( $receivers as $products ) {
404
+ $invoice_items = array();
405
+ $shipping_given = $tax_given = 0;
406
+
407
+ foreach ( $products as $key => $product ) {
408
+
409
+ $product_id = $product[ 'product_id' ];
410
+ $shipping_given += $product[ 'shipping' ];
411
+ $tax_given += $product[ 'tax' ];
412
+
413
+ if ( !empty( $product[ 'commission' ] ) ) {
414
+ $item = new InvoiceItem();
415
+ $item->name = get_the_title( $product_id );
416
+ $item->identifier = $product_id;
417
+ $item->price = $product[ 'commission' ];
418
+ $item->itemPrice = round( $product[ 'commission' ] / $product[ 'qty' ], 2 );
419
+ $item->itemCount = $product[ 'qty' ];
420
+ $invoice_items[ ] = $item;
421
+ }
422
+ }
423
+
424
+ if ( empty( $invoice_items ) ) {
425
+ continue;
426
+ }
427
+
428
+ $receiverOptions = new ReceiverOptions();
429
+ $setPaymentOptionsRequest->receiverOptions[ ] = $receiverOptions;
430
+
431
+ // Set the current vendor
432
+ $receiverId = new ReceiverIdentifier();
433
+ $receiverId->email = $product[ 'vendor_id' ] == 1 ? $this->main_paypal : WCV_Vendors::get_vendor_paypal( $product[ 'vendor_id' ] );
434
+
435
+ $receiverOptions->receiver = $receiverId;
436
+ $receiverOptions->invoiceData = new InvoiceData();
437
+ $receiverOptions->invoiceData->item = $invoice_items;
438
+ $receiverOptions->invoiceData->totalTax = round( $receivers_two[$product['vendor_id']]['tax'], 2 );
439
+ $receiverOptions->invoiceData->totalShipping = $receivers_two[$product['vendor_id']]['shipping'];
440
+ }
441
+
442
+ return $setPaymentOptionsRequest;
443
+ }
444
+
445
+
446
+ /**
447
+ *
448
+ *
449
+ * @param unknown $pay_key
450
+ * @param unknown $order_id
451
+ *
452
+ * @return unknown
453
+ */
454
+ public function set_paypal_author_specifics( $pay_key, $order_id )
455
+ {
456
+ global $woocommerce;
457
+
458
+ $this->include_paypal_sdk();
459
+ $order = new WC_Order( $order_id );
460
+
461
+ // Create request
462
+ $setPaymentOptionsRequest = new SetPaymentOptionsRequest( new RequestEnvelope( "en_US" ) );
463
+ $setPaymentOptionsRequest->payKey = $pay_key;
464
+
465
+ if ( $this->instapay ) {
466
+ $setPaymentOptionsRequest = $this->set_vendor_items( $order, $setPaymentOptionsRequest );
467
+ }
468
+
469
+ if ( $this->debug_me ) {
470
+ foreach ( $setPaymentOptionsRequest->receiverOptions as $k ) {
471
+ var_dump( $k->invoiceData );
472
+ }
473
+ exit;
474
+ }
475
+
476
+ $setPaymentOptionsRequest->senderOptions = new SenderOptions();
477
+ $setPaymentOptionsRequest->senderOptions->requireShippingAddressSelection = true;
478
+
479
+ $service = new AdaptivePaymentsService();
480
+ try {
481
+ $response = $service->SetPaymentOptions( $setPaymentOptionsRequest );
482
+ } catch ( Exception $ex ) {
483
+ wc_add_notice( sprintf( __( 'Error: %s', 'wcvendors' ), $ex->getMessage() ), 'error' );
484
+
485
+ return false;
486
+ }
487
+
488
+ $this->logger->error( "Received SetPaymentOptionsResponse:" );
489
+ $ack = strtoupper( $response->responseEnvelope->ack );
490
+ if ( $ack != "SUCCESS" ) {
491
+ $order->update_status( 'cancelled', __( sprintf( 'Error ID: %s. %s', $response->error[ 0 ]->errorId, $response->error[ 0 ]->message ), 'wcvendors' ) );
492
+ wc_add_notice( sprintf( 'Error ID: %s. %s', $response->error[ 0 ]->errorId, $response->error[ 0 ]->message ), 'error' );
493
+
494
+ return false;
495
+ }
496
+
497
+ return true;
498
+ }
499
+
500
+
501
+ /**
502
+ * Payment fields
503
+ */
504
+ function payment_fields()
505
+ {
506
+ if ( $description = $this->settings[ 'description' ] ) echo wpautop( wptexturize( $this->description ) );
507
+ }
508
+
509
+
510
+ /**
511
+ * Process the payment and return the result
512
+ *
513
+ * @param unknown $order_id
514
+ *
515
+ * @return unknown
516
+ */
517
+ function process_payment( $order_id )
518
+ {
519
+ global $woocommerce;
520
+
521
+ $order = new WC_Order( $order_id );
522
+ $pay_key = $this->paypalap_check_form( $order_id );
523
+
524
+ if ( !empty( $woocommerce->errors ) ) return false;
525
+
526
+ if ( $this->instapay ) {
527
+ $this->set_paypal_author_specifics( $pay_key, $order_id );
528
+ if ( !empty( $woocommerce->errors ) ) return false;
529
+ }
530
+
531
+ $paypal_redirect_url = $this->sandbox == 'yes' ? 'https://www.sandbox.paypal.com/webscr&cmd=' : 'https://www.paypal.com/webscr&cmd=';
532
+ $pay_url = $paypal_redirect_url . '_ap-payment&paykey=' . $pay_key;
533
+
534
+ return array(
535
+ 'result' => 'success',
536
+ 'redirect' => $pay_url,
537
+ );
538
+
539
+ }
540
+
541
+
542
+ }
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/ChangeLog.txt ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Version 1.2.95 - September 28, 2012
3
+
4
+ - SDK refreshed to Release 95. Please refer https://www.x.com/developers/paypal/documentation-tools/release-notes#MerchantAPI
5
+ - SDK now supports third party permission by subject header. Configure subject header
6
+ in the configuration file, this is basically third party merchant email address who has
7
+ given permission to you to call api on their behalf.
8
+ - Bug fixed for Page styling attributes (eg: cpp-header**) serialization. (https://github.com/paypal/SDKs/issues/31)
9
+ - Bug fixed for 'convertToXML' method for not escaping xml element correctly.(https://github.com/paypal/SDKs/issues/17)
10
+ - PayPal Endpoint is corrected in config file.(https://github.com/paypal/SDKs/issues/22)
11
+ - Bug fixed for BasicAmountType serialization without currencyID attribute.(https://github.com/paypal/SDKs/issues/23)
12
+ - Bug fixed for 'PPLoggingManager.php' to pickup configuration entries.(https://github.com/paypal/SDKs/issues/28)
13
+ - Updated SDK sample
14
+ --------------------------------------------------------------------------------------------------
15
+
16
+
17
+ Version 1.1.93 - August 14, 2012
18
+
19
+ - SDK refreshed to Release 93. Please refer https://www.x.com/developers/paypal/documentation-tools/release-notes#MerchantAPI
20
+ - SDK Core - Deserialization Logic Change
21
+ --------------------------------------------------------------------------------------------------
22
+
23
+
24
+ Version 1.0.92 - July 30, 2012
25
+
26
+ - Stable release
27
+ -------------------------------------------------------------------------------------------------
28
+ Version 0.7.92 - July 17, 2012
29
+
30
+ - wsdl update version 0.7.92
31
+ --------------------------------------------------------------------------------------------------
32
+
33
+ Version 0.7.90 - 11-June-2012
34
+
35
+ - SDK upgrade to latest WSDL release (90.0)
36
+ --------------------------------------------------------------------------------------------------
37
+
38
+ Version 0.7.88 - 17-Apr-2012
39
+
40
+ - Fix to get SDK working with Permissions API token
41
+
42
+ --------------------------------------------------------------------------------------------------
43
+
44
+ Version 0.6.88 - 27-Feb-2012
45
+
46
+ - Initial release
47
+
48
+ --------------------------------------------------------------------------------------------------
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/LICENSE.txt ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ PAYPAL, INC.
2
+
3
+ SDK LICENSE
4
+
5
+ NOTICE TO USER: PayPal, Inc. is providing the Software and Documentation for use under the terms of this Agreement. Any use, reproduction, modification or distribution of the Software or Documentation, or any derivatives or portions hereof, constitutes your acceptance of this Agreement.
6
+
7
+ As used in this Agreement, "PayPal" means PayPal, Inc. "Software" means the software code accompanying this agreement. "Documentation" means the documents, specifications and all other items accompanying this Agreement other than the Software.
8
+
9
+ 1. LICENSE GRANT Subject to the terms of this Agreement, PayPal hereby grants you a non-exclusive, worldwide, royalty free license to use, reproduce, prepare derivative works from, publicly display, publicly perform, distribute and sublicense the Software for any purpose, provided the copyright notice below appears in a conspicuous location within the source code of the distributed Software and this license is distributed in the supporting documentation of the Software you distribute. Furthermore, you must comply with all third party licenses in order to use the third party software contained in the Software.
10
+
11
+ Subject to the terms of this Agreement, PayPal hereby grants you a non-exclusive, worldwide, royalty free license to use, reproduce, publicly display, publicly perform, distribute and sublicense the Documentation for any purpose. You may not modify the Documentation.
12
+
13
+ No title to the intellectual property in the Software or Documentation is transferred to you under the terms of this Agreement. You do not acquire any rights to the Software or the Documentation except as expressly set forth in this Agreement.
14
+
15
+ If you choose to distribute the Software in a commercial product, you do so with the understanding that you agree to defend, indemnify and hold harmless PayPal and its suppliers against any losses, damages and costs arising from the claims, lawsuits or other legal actions arising out of such distribution. You may distribute the Software in object code form under your own license, provided that your license agreement:
16
+
17
+ (a) complies with the terms and conditions of this license agreement;
18
+
19
+ (b) effectively disclaims all warranties and conditions, express or implied, on behalf of PayPal;
20
+
21
+ (c) effectively excludes all liability for damages on behalf of PayPal;
22
+
23
+ (d) states that any provisions that differ from this Agreement are offered by you alone and not PayPal; and
24
+
25
+ (e) states that the Software is available from you or PayPal and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
26
+
27
+ 2. DISCLAIMER OF WARRANTY
28
+ PAYPAL LICENSES THE SOFTWARE AND DOCUMENTATION TO YOU ONLY ON AN "AS IS" BASIS WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. PAYPAL MAKES NO WARRANTY THAT THE SOFTWARE OR DOCUMENTATION WILL BE ERROR-FREE. Each user of the Software or Documentation is solely responsible for determining the appropriateness of using and distributing the Software and Documentation and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs, or equipment, and unavailability or interruption of operations. Use of the Software and Documentation is made with the understanding that PayPal will not provide you with any technical or customer support or maintenance. Some states or jurisdictions do not allow the exclusion of implied warranties or limitations on how long an implied warranty may last, so the above limitations may not apply to you. To the extent permissible, any implied warranties are limited to ninety (90) days.
29
+
30
+
31
+ 3. LIMITATION OF LIABILITY
32
+ PAYPAL AND ITS SUPPLIERS SHALL NOT BE LIABLE FOR LOSS OR DAMAGE ARISING OUT OF THIS AGREEMENT OR FROM THE USE OF THE SOFTWARE OR DOCUMENTATION. IN NO EVENT WILL PAYPAL OR ITS SUPPLIERS BE LIABLE TO YOU OR ANY THIRD PARTY FOR ANY DIRECT, INDIRECT, CONSEQUENTIAL, INCIDENTAL, OR SPECIAL DAMAGES INCLUDING LOST PROFITS, LOST SAVINGS, COSTS, FEES, OR EXPENSES OF ANY KIND ARISING OUT OF ANY PROVISION OF THIS AGREEMENT OR THE USE OR THE INABILITY TO USE THE SOFTWARE OR DOCUMENTATION, HOWEVER CAUSED AND UNDER ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY OR TORT INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. PAYPAL'S AGGREGATE LIABILITY AND THAT OF ITS SUPPLIERS UNDER OR IN CONNECTION WITH THIS AGREEMENT SHALL BE LIMITED TO THE AMOUNT PAID BY YOU FOR THE SOFTWARE AND DOCUMENTATION.
33
+
34
+ 4. TRADEMARK USAGE
35
+ PayPal is a trademark PayPal, Inc. in the United States and other countries. Such trademarks may not be used to endorse or promote any product unless expressly permitted under separate agreement with PayPal.
36
+
37
+ 5. TERM
38
+ Your rights under this Agreement shall terminate if you fail to comply with any of the material terms or conditions of this Agreement and do not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all your rights under this Agreement terminate, you agree to cease use and distribution of the Software and Documentation as soon as reasonably practicable.
39
+
40
+ 6. GOVERNING LAW AND JURISDICTION. This Agreement is governed by the statutes and laws of the State of California, without regard to the conflicts of law principles thereof. If any part of this Agreement is found void and unenforceable, it will not affect the validity of the balance of the Agreement, which shall remain valid and enforceable according to its terms. Any dispute arising out of or related to this Agreement shall be brought in the courts of Santa Clara County, California, USA.
41
+
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/README.md ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ PayPal PHP Merchant SDK
3
+ ===============================
4
+
5
+ Prerequisites
6
+ -------------
7
+
8
+ PayPal's PHP Merchant SDK requires
9
+
10
+ * PHP 5.2 and above with curl extension enabled
11
+
12
+
13
+ Using the SDK
14
+ -------------
15
+
16
+ To use the SDK,
17
+
18
+ * Copy the config and lib folders into your project.
19
+ * Make sure that the lib folder in your project is available in PHP's include path
20
+ * Include the services\PayPalAPIInterfaceService\PayPalAPIInterfaceServiceService.php file in your code.
21
+ * Create a service wrapper object
22
+ * Create a request object as per your project's needs. All the API request and response classes are available in services\PayPalAPIInterfaceService\PayPalAPIInterfaceServiceService.php
23
+ * Invoke the appropriate method on the request object.
24
+
25
+
26
+ For example,
27
+
28
+ require_once('services/PayPalAPIInterfaceService/PayPalAPIInterfaceServiceService.php'); require_once('PPLoggingManager.php');
29
+
30
+ $itemAmount = new BasicAmountType();
31
+ $itemAmount->currencyID = $_REQUEST['currencyCode'];
32
+ $itemAmount->value = $_REQUEST['itemAmount'];
33
+ $setECReqType = new SetExpressCheckoutRequestType();
34
+ $setECReqType->SetExpressCheckoutRequestDetails = $setECReqDetails;
35
+ $setECReqType->Version = '86.0';
36
+ $setECReq = new SetExpressCheckoutReq();
37
+ $setECReq->SetExpressCheckoutRequest = $setECReqType;
38
+ ......
39
+
40
+ $paypalService = new PayPalAPIInterfaceServiceService();
41
+ $setECResponse = $paypalService->SetExpressCheckout($setECReq);
42
+
43
+ $ack = strtoupper($setECResponse->Ack);
44
+
45
+ if($ack == 'SUCCESS') {
46
+ // Success
47
+ }
48
+
49
+
50
+
51
+ SDK Configuration
52
+ -----------------
53
+
54
+ replace the API credential in config/sdk_config.ini . You can use the configuration file to configure
55
+
56
+ * (Multiple) API account credentials.
57
+ * Service endpoint and other HTTP connection parameters
58
+
59
+
60
+ Please refer to the sample config file provided with this bundle.
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/build.xml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project name="PayPal_PHP_SDK" default="build">
3
+
4
+
5
+ <condition property="PHPUNIT_PATH" value="phpunit.bat" else="phpunit">
6
+ <os family="windows"/>
7
+ </condition>
8
+
9
+ <target name="clean">
10
+ <delete dir="${basedir}/build"/>
11
+ </target>
12
+
13
+
14
+ <target name="phpunit">
15
+ <mkdir dir="tests/reports/"/>
16
+ <exec dir="${basedir}" executable="${PHPUNIT_PATH}" failonerror="true">
17
+ <arg
18
+ line="--testdox --include-path lib --log-junit tests\reports\phpunit.xml tests"/>
19
+ </exec>
20
+ </target>
21
+
22
+
23
+ <target name="build" depends="clean, phpunit"/>
24
+ </project>
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/config/sdk-cert.pem ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Bag Attributes
2
+ localKeyID: E4 F0 42 FE 24 52 DD 61 B0 4A EE 64 74 62 6B 2F 6E 3B 31 7B
3
+ subject=/CN=certuser_biz_api1.paypal.com/O=Bonzop/L=Austin/ST=TX/C=US
4
+ issuer=/C=US/ST=California/L=San Jose/O=PayPal, Inc./OU=sandbox_certs/CN=sandbox_camerchapi/emailAddress=re@paypal.com
5
+ -----BEGIN CERTIFICATE-----
6
+ MIICiDCCAfGgAwIBAgIDD/WUMA0GCSqGSIb3DQEBBQUAMIGfMQswCQYDVQQGEwJV
7
+ UzETMBEGA1UECBMKQ2FsaWZvcm5pYTERMA8GA1UEBxMIU2FuIEpvc2UxFTATBgNV
8
+ BAoTDFBheVBhbCwgSW5jLjEWMBQGA1UECxQNc2FuZGJveF9jZXJ0czEbMBkGA1UE
9
+ AxQSc2FuZGJveF9jYW1lcmNoYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwu
10
+ Y29tMB4XDTExMDUwMjA1MDQ0NFoXDTIxMDQyOTA1MDQ0NFowYzElMCMGA1UEAxQc
11
+ Y2VydHVzZXJfYml6X2FwaTEucGF5cGFsLmNvbTEPMA0GA1UEChMGQm9uem9wMQ8w
12
+ DQYDVQQHEwZBdXN0aW4xCzAJBgNVBAgTAlRYMQswCQYDVQQGEwJVUzCBnzANBgkq
13
+ hkiG9w0BAQEFAAOBjQAwgYkCgYEAmhsOeujiGniLK6drcs38FLcGqZNmj4C/TfKD
14
+ qD5k5gP26oahfNl+NxAds2RdR2N+ZD6dy+a2Uo6q2hGc+Y+1uA5FzEtvOsC52qId
15
+ NrFVm215S3Gf77AEMzYItbNq2jlqJ5HGwCAMoY1aBkI6bgp+8vWDYEH6WZIK4f0e
16
+ YoPKG0MCAwEAAaMNMAswCQYDVR0TBAIwADANBgkqhkiG9w0BAQUFAAOBgQBj6xWw
17
+ AumLzSodCWyocPcyKSooNa7wgJKzaVrf0Kxz2QBesKpsfe9UN3Dj04016FIUbkRI
18
+ 4qLJIkKHyeQRU9hvJ78tU7OeykDEVqlHAEE/Z4c5EIs6l9x60VqOpAjnaqX/9Jty
19
+ jXhqpINjolTh6D5jq8y4FX5krKqIYBCNDHM+cQ==
20
+ -----END CERTIFICATE-----
21
+ Bag Attributes
22
+ localKeyID: E4 F0 42 FE 24 52 DD 61 B0 4A EE 64 74 62 6B 2F 6E 3B 31 7B
23
+ Key Attributes: <No Attributes>
24
+ -----BEGIN RSA PRIVATE KEY-----
25
+ Proc-Type: 4,ENCRYPTED
26
+ DEK-Info: DES-EDE3-CBC,18E53CC94575411A
27
+
28
+ Dbkm1iUDbpaY3abg08u1NKnzdd0tZwArMQKpRJ4zaVbm4qYkwAEvmKWGCemP0hwM
29
+ iA0EeLgbSbYbgXi+3Ba1Hm5kf5p5MbGqylgUNBVzKV+OtuPgZPnHclyHoJwRf8NU
30
+ e+wwRIDB/6ZpXt69t3poxmYR0MfhrgSm/YdBDRLJbBE8I51vTELmCRC2SN/5ebo+
31
+ TCNtGyf/upKBf0XfM8sY5SvffwSA1uaOLh0FwtYq0vQViFayPfmyBBDirVZqAFMt
32
+ DOuX2JaYUj9s9qVuwQIqHThJLhTqU/0eZjkYXy22F2ER8fNG77LQ5+SMevngWXjt
33
+ afErYBJYcSc1V/MX39126vaYL/AzLTBXHkSmJ0w+nCs+4ifVv9dJTb8W6W10ZWk6
34
+ HQrSuIhLbgbPg0J5LagYymCWjkl3UseJSFsUdH2EkQA4uBwKX4aJzH4n44H2sCk0
35
+ UCzDSGC6jWr7VOTpOk5+NHi/pqZhvpNn2Tg+jZt/kqKAa08di9jTP0eZbS4+bb6S
36
+ 9FtpOLWXKz/JZVLmA5v2o1L9kqvFoMsgvito4oK/j5jPGat22xTpoBnSom3+QsfB
37
+ ViOStyAh9MqGqsTh+YcNNUbv5dJ4IpmUAki64Cx4j90wFkpbUpoeT3l/0Gbuwnpy
38
+ Ugw97/qHVGlFAhrXDr72TqI2+YXFfxklyCLMNnsBvrM55NZcgxsH7UWp0hCNXq/j
39
+ FQNduuw6CAqfosj5aKjDRIll1MN0631yxkGxhsHiMQNMOCMe6+OwDs5gdF+Wvc4j
40
+ HlSAq1H0v3iZRcWs1qdf9eKMAc1k5T9TPHlcEgwv9zMWSGqvxizwNQ==
41
+ -----END RSA PRIVATE KEY-----
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/config/sdk_config.ini ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;Account credentials
2
+ [Account]
3
+ acct1.UserName = jb-us-seller_api1.paypal.com
4
+ acct1.Password = WX4WTU3S8MY44S7F
5
+ acct1.Signature = AFcWxV21C7fd0v3bYYYRCpSSRl31A7yDhhsPUU2XhtMoZXsWHFxu-RWy
6
+ acct1.AppId = APP-80W284485P519543T
7
+ # Subject is optinal, only required in case of third party permission
8
+ acct1.Subject =
9
+
10
+ ; Certificate Credentials Test Account
11
+ acct2.UserName = certuser_biz_api1.paypal.com
12
+ acct2.Password = D6JNKKULHN3G5B8A
13
+ ; Certificate path relative to config folder or absolute path in file system
14
+ acct2.CertPath = sdk-cert.pem
15
+ acct2.CertKey = password ; Password given when generating .PEM file from a .p12 file
16
+ acct2.AppId = APP-80W284485P519543T
17
+ # Subject is optinal, only required in case of third party permission
18
+ acct2.Subject =
19
+
20
+ ;Connection Information
21
+ [Http]
22
+ http.ConnectionTimeOut = 30
23
+ http.Retry = 5
24
+ ;http.Proxy
25
+
26
+ ;Service Configuration
27
+ [Service]
28
+ ; NOTE: Do not change the service binding configuration.
29
+ service.Binding = SOAP
30
+ service.EndPoint = "https://api-3t.sandbox.paypal.com/2.0/" ; Endpoint for 3-token credentials
31
+ ; Uncomment this line if you are using certificate credentials
32
+ ;service.EndPoint = "https://api.sandbox.paypal.com/2.0/"
33
+ service.RedirectURL = "https://www.sandbox.paypal.com/webscr&cmd="
34
+
35
+ ;Logging Information
36
+ [Log]
37
+ log.FileName = ../PayPal.log
38
+ log.LogLevel = INFO
39
+ log.LogEnabled = true
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/IPPCredential.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Base class that represents API credentials
5
+ */
6
+ abstract class IPPCredential
7
+ {
8
+ /**
9
+ * Application Id that uniquely identifies the application
10
+ * The application Id is issued by PayPal.
11
+ * Test application Ids are available for the sandbox environment
12
+ * @var string
13
+ */
14
+ protected $applicationId;
15
+
16
+ /**
17
+ * API username
18
+ * @var string
19
+ */
20
+ protected $userName;
21
+
22
+ /**
23
+ * API password
24
+ * @var string
25
+ */
26
+ protected $password;
27
+
28
+ protected abstract function validate();
29
+
30
+ public function __construct( $userName, $password, $applicationId )
31
+ {
32
+ $this->userName = $userName;
33
+ $this->password = $password;
34
+ $this->applicationId = $applicationId;
35
+ }
36
+
37
+ public function getApplicationId()
38
+ {
39
+ return $this->applicationId;
40
+ }
41
+
42
+ public function getUserName()
43
+ {
44
+ return $this->userName;
45
+ }
46
+
47
+ public function getPassword()
48
+ {
49
+ return $this->password;
50
+ }
51
+ }
52
+
53
+ ?>
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPAPIService.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once 'PPCredentialManager.php';
3
+ require_once 'PPConnectionManager.php';
4
+ require_once 'PPObjectTransformer.php';
5
+ require_once 'PPLoggingManager.php';
6
+ require_once 'PPUtils.php';
7
+ require_once 'PPAuthenticationManager.php';
8
+
9
+ class PPAPIService
10
+ {
11
+ public $endpoint;
12
+ public $serviceName;
13
+ private $logger;
14
+
15
+ public function __construct( $serviceName = "" )
16
+ {
17
+ $this->serviceName = $serviceName;
18
+ $config = PPConfigManager::getInstance();
19
+ $this->endpoint = $config->get( 'service.EndPoint' );
20
+ $this->logger = new PPLoggingManager( __CLASS__ );
21
+ }
22
+
23
+ public function setServiceName( $serviceName )
24
+ {
25
+ $this->serviceName = $serviceName;
26
+ }
27
+
28
+
29
+ public function makeRequest( $apiMethod, $params, $apiUsername = null, $accessToken = null, $tokenSecret = null )
30
+ {
31
+
32
+ $authentication = new PPAuthenticationManager();
33
+ $connectionMgr = PPConnectionManager::getInstance();
34
+ $connection = $connectionMgr->getConnection();
35
+
36
+ $credMgr = PPCredentialManager::getInstance();
37
+ // $apiUsernam is optional, if null the default account in congif file is taken
38
+ $apIPPCredential = $credMgr->getCredentialObject( $apiUsername );
39
+ $config = PPConfigManager::getInstance();
40
+ if ( $config->get( 'service.Binding' ) == 'SOAP' ) {
41
+ $url = $this->endpoint;
42
+ if ( isset( $accessToken ) && isset( $tokenSecret ) ) {
43
+ $headers = $authentication->getPayPalHeaders( $apIPPCredential, $connection, $accessToken, $tokenSecret, $url );
44
+ } else {
45
+ $headers = null;
46
+ }
47
+ $params = $authentication->appendSoapHeader( $params, $apIPPCredential, $connection, $accessToken, $tokenSecret, $url );
48
+ } else {
49
+ $url = $this->endpoint . $this->serviceName . '/' . $apiMethod;
50
+ $headers = $authentication->getPayPalHeaders( $apIPPCredential, $connection, $accessToken, $tokenSecret, $url );
51
+ }
52
+
53
+
54
+ $this->logger->info( "Request: $params" );
55
+ $response = $connection->execute( $url, $params, $headers );
56
+ $this->logger->info( "Response: $response" );
57
+
58
+ return $response;
59
+ }
60
+
61
+
62
+ }
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPAuthenticationManager.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once 'IPPCredential.php';
3
+ require_once 'PPConfigManager.php';
4
+ require_once 'PPSignatureCredential.php';
5
+ require_once 'PPCertificateCredential.php';
6
+ require_once 'exceptions/PPInvalidCredentialException.php';
7
+ require_once 'auth/PPAuth.php';
8
+
9
+ class PPAuthenticationManager
10
+ {
11
+ public function getPayPalHeaders( $apiCred, $connection, $accessToken = null, $tokenSecret = null, $url = null )
12
+ {
13
+ $config = PPConfigManager::getInstance();
14
+
15
+ if ( isset( $accessToken ) && isset( $tokenSecret ) ) {
16
+ $headers_arr[ ] = "X-PP-AUTHORIZATION: " . $this->generateAuthString( $apiCred, $accessToken, $tokenSecret, $url );
17
+ //$headers_arr[] = "CLIENT-AUTH: No cert";
18
+ } // Add headers required for service authentication
19
+ else if ( $apiCred instanceof PPSignatureCredential ) {
20
+ $headers_arr[ ] = "X-PAYPAL-SECURITY-USERID: " . $apiCred->getUserName();
21
+ $headers_arr[ ] = "X-PAYPAL-SECURITY-PASSWORD: " . $apiCred->getPassword();
22
+ $headers_arr[ ] = "X-PAYPAL-SECURITY-SIGNATURE: " . $apiCred->getSignature();
23
+ } else if ( $apiCred instanceof PPCertificateCredential ) {
24
+
25
+ $headers_arr[ ] = "X-PAYPAL-SECURITY-USERID: " . $apiCred->getUserName();
26
+ $headers_arr[ ] = "X-PAYPAL-SECURITY-PASSWORD: " . $apiCred->getPassword();
27
+ $connection->setSSLCert( $apiCred->getCertificatePath(), $apiCred->getPassPhrase() );
28
+ }
29
+
30
+ // Add other headers
31
+ $headers_arr[ ] = "X-PAYPAL-APPLICATION-ID: " . $apiCred->getApplicationId();
32
+ $headers_arr[ ] = "X-PAYPAL-REQUEST-DATA-FORMAT: " . $config->get( 'service.Binding' );
33
+ $headers_arr[ ] = "X-PAYPAL-RESPONSE-DATA-FORMAT: " . $config->get( 'service.Binding' );
34
+ $headers_arr[ ] = "X-PAYPAL-DEVICE-IPADDRESS: " . PPUtils::getLocalIPAddress();
35
+ $headers_arr[ ] = "X-PAYPAL-REQUEST-SOURCE: " . PPUtils::getRequestSource();
36
+
37
+ return $headers_arr;
38
+ }
39
+
40
+ public function appendSoapHeader( $payLoad, $apiCred, $connection, $accessToken = null, $tokenSecret = null, $url = null )
41
+ {
42
+ $soapHeader = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:urn=\"urn:ebay:api:PayPalAPI\" xmlns:ebl=\"urn:ebay:apis:eBLBaseComponents\" xmlns:cc=\"urn:ebay:apis:CoreComponentTypes\" xmlns:ed=\"urn:ebay:apis:EnhancedDataTypes\">";
43
+
44
+ if ( isset( $accessToken ) && isset( $tokenSecret ) ) {
45
+ $soapHeader .= "<soapenv:Header>";
46
+ $soapHeader .= "<urn:RequesterCredentials/>";
47
+ $soapHeader .= "</soapenv:Header>";
48
+ } else if ( $apiCred instanceof PPSignatureCredential ) {
49
+ $soapHeader .= "<soapenv:Header>";
50
+ $soapHeader .= "<urn:RequesterCredentials>";
51
+ $soapHeader .= "<ebl:Credentials>";
52
+ $soapHeader .= "<ebl:Username>" . $apiCred->getUserName() . "</ebl:Username>";
53
+ $soapHeader .= "<ebl:Password>" . $apiCred->getPassword() . "</ebl:Password>";
54
+ $soapHeader .= "<ebl:Signature>" . $apiCred->getSignature() . "</ebl:Signature>";
55
+ $subject = $apiCred->getSubject();
56
+ if ( isset( $subject ) && $subject != "" ) {
57
+ $soapHeader .= "<ebl:Subject>" . $apiCred->getSubject() . "</ebl:Subject>";
58
+ }
59
+ $soapHeader .= "</ebl:Credentials>";
60
+ $soapHeader .= "</urn:RequesterCredentials>";
61
+ $soapHeader .= "</soapenv:Header>";
62
+ } else if ( $apiCred instanceof PPCertificateCredential ) {
63
+ $soapHeader .= "<soapenv:Header>";
64
+ $soapHeader .= "<urn:RequesterCredentials>";
65
+ $soapHeader .= "<ebl:Credentials>";
66
+ $soapHeader .= "<ebl:Username>" . $apiCred->getUserName() . "</ebl:Username>";
67
+ $soapHeader .= "<ebl:Password>" . $apiCred->getPassword() . "</ebl:Password>";
68
+ $subject = $apiCred->getSubject();
69
+ if ( isset( $subject ) && $subject != "" ) {
70
+ $soapHeader .= "<ebl:Subject>" . $apiCred->getSubject() . "</ebl:Subject>";
71
+ }
72
+ $soapHeader .= "</ebl:Credentials>";
73
+ $soapHeader .= "</urn:RequesterCredentials>";
74
+ $soapHeader .= "</soapenv:Header>";
75
+ $connection->setSSLCert( $apiCred->getCertificatePath(), $apiCred->getPassPhrase() );
76
+ }
77
+ $soapHeader .= "<soapenv:Body>";
78
+ $soapHeader .= $payLoad;
79
+ $soapHeader .= "</soapenv:Body>";
80
+ $soapHeader .= "</soapenv:Envelope>";
81
+
82
+ return $soapHeader;
83
+
84
+ }
85
+
86
+ private function generateAuthString( $apiCred, $accessToken, $tokenSecret, $endpoint )
87
+ {
88
+ $key = $apiCred->getUserName();
89
+ $secret = $apiCred->getPassword();
90
+ $auth = new AuthSignature();
91
+ $response = $auth->genSign( $key, $secret, $accessToken, $tokenSecret, 'POST', $endpoint );
92
+ $authString = "token=" . $accessToken . ",signature=" . $response[ 'oauth_signature' ] . ",timestamp=" . $response[ 'oauth_timestamp' ];
93
+
94
+ return $authString;
95
+ }
96
+
97
+ }
98
+
99
+ ?>
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPBaseService.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once 'PPAPIService.php';
3
+
4
+
5
+ class PPBaseService
6
+ {
7
+
8
+ private $serviceName;
9
+
10
+ /*
11
+ * Setters and getters for Third party authentication (Permission Services)
12
+ */
13
+ protected $accessToken;
14
+ protected $tokenSecret;
15
+ protected $lastRequest;
16
+ protected $lastResponse;
17
+
18
+ public function getLastRequest()
19
+ {
20
+ return $this->lastRequest;
21
+ }
22
+
23
+ public function setLastRequest( $lastRqst )
24
+ {
25
+ $this->lastRequest = $lastRqst;
26
+ }
27
+
28
+ public function getLastResponse()
29
+ {
30
+ return $this->lastResponse;
31
+ }
32
+
33
+ public function setLastResponse( $lastRspns )
34
+ {
35
+ $this->lastResponse = $lastRspns;
36
+ }
37
+
38
+ public function getAccessToken()
39
+ {
40
+ return $this->accessToken;
41
+ }
42
+
43
+ public function setAccessToken( $accessToken )
44
+ {
45
+ $this->accessToken = $accessToken;
46
+ }
47
+
48
+ public function getTokenSecret()
49
+ {
50
+ return $this->tokenSecret;
51
+ }
52
+
53
+ public function setTokenSecret( $tokenSecret )
54
+ {
55
+ $this->tokenSecret = $tokenSecret;
56
+ }
57
+
58
+ public function __construct( $serviceName )
59
+ {
60
+ $this->serviceName = $serviceName;
61
+ }
62
+
63
+ public function getServiceName()
64
+ {
65
+ return $this->serviceName;
66
+ }
67
+
68
+ public function call( $method, $requestObject, $apiUsername = null )
69
+ {
70
+ $params = $this->marshall( $requestObject );
71
+ $service = new PPAPIService();
72
+ $service->setServiceName( $this->serviceName );
73
+
74
+ $this->lastRequest = $params;
75
+ $this->lastResponse = $service->makeRequest( $method, $params, $apiUsername, $this->accessToken, $this->tokenSecret );
76
+
77
+ return $this->lastResponse;
78
+ }
79
+
80
+ private function marshall( $object )
81
+ {
82
+ $transformer = new PPObjectTransformer();
83
+
84
+ return $transformer->toString( $object );
85
+ }
86
+ }
87
+
88
+ ?>
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPCertificateCredential.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once 'IPPCredential.php';
3
+ require_once 'PPConfigManager.php';
4
+ require_once 'exceptions/PPMissingCredentialException.php';
5
+
6
+ class PPCertificateCredential extends IPPCredential
7
+ {
8
+
9
+ private $certificatePath;
10
+ private $passPhrase;
11
+ private $subject;
12
+
13
+ public function __construct( $userName, $password, $certPath, $appId, $passPhrase, $subject )
14
+ {
15
+ parent::__construct( $userName, $password, $appId );
16
+ $this->certificatePath = $certPath;
17
+ $this->passPhrase = $passPhrase;
18
+ $this->subject = $subject;
19
+ $this->validate();
20
+ }
21
+
22
+ public function validate()
23
+ {
24
+
25
+ if ( $this->userName == null || $this->userName == "" ) {
26
+ throw new PPMissingCredentialException( "username cannot be empty" );
27
+ }
28
+ if ( $this->password == null || $this->password == "" ) {
29
+ throw new PPMissingCredentialException( "password cannot be empty" );
30
+ }
31
+ if ( $this->certificatePath == null || $this->certificatePath == "" ) {
32
+ throw new PPMissingCredentialException( "certificate cannot be empty" );
33
+ }
34
+ if ( $this->passPhrase == null || $this->passPhrase == "" ) {
35
+ throw new PPMissingCredentialException( "passphrase cannot be empty" );
36
+ }
37
+ if ( $this->applicationId == null || $this->applicationId == "" ) {
38
+ throw new PPMissingCredentialException( "applicationId cannot be empty" );
39
+ }
40
+ }
41
+
42
+ public function getUserName()
43
+ {
44
+ return $this->userName;
45
+ }
46
+
47
+ public function getPassword()
48
+ {
49
+ return $this->password;
50
+ }
51
+
52
+ public function getCertificatePath()
53
+ {
54
+ if ( realpath( $this->certificatePath ) ) {
55
+ return realpath( $this->certificatePath );
56
+ } else {
57
+ return realpath( dirname( __FILE__ ) . DIRECTORY_SEPARATOR . ".." . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . $this->certificatePath );
58
+ }
59
+ }
60
+
61
+ public function getPassPhrase()
62
+ {
63
+ return $this->passPhrase;
64
+ }
65
+
66
+ public function getApplicationId()
67
+ {
68
+ return $this->applicationId;
69
+ }
70
+
71
+ public function getSubject()
72
+ {
73
+ return $this->subject;
74
+ }
75
+ }
76
+
77
+ ?>
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPConfigManager.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * PPConfigManager loads the SDK configuration file and
4
+ * hands out appropriate config params to other classes
5
+ */
6
+ require_once 'exceptions/PPConfigurationException.php';
7
+
8
+ class PPConfigManager
9
+ {
10
+
11
+ private $config;
12
+ /**
13
+ * @var PPConfigManager
14
+ */
15
+ private static $instance;
16
+
17
+ private function __construct()
18
+ {
19
+ $configFile = dirname( __FILE__ ) . DIRECTORY_SEPARATOR . ".."
20
+ . DIRECTORY_SEPARATOR . "config" . DIRECTORY_SEPARATOR . "sdk_config.ini";
21
+ $this->load( $configFile );
22
+ }
23
+
24
+ // create singleton object for PPConfigManager
25
+ public static function getInstance()
26
+ {
27
+ if ( !isset( self::$instance ) ) {
28
+ self::$instance = new PPConfigManager();
29
+ }
30
+
31
+ return self::$instance;
32
+ }
33
+
34
+ //used to load the file
35
+ private function load( $fileName )
36
+ {
37
+ if ( class_exists( 'Woocommerce' ) ) {
38
+ global $woocommerce;
39
+ $gateways = $woocommerce->payment_gateways->payment_gateways();
40
+ $settings = $gateways[ 'paypalap' ]->settings;
41
+ $mode = $settings[ 'sandbox_enabled' ];
42
+
43
+ $this->config = array(
44
+ 'acct1.UserName' => $mode == 'yes' ? $settings[ 'username' ] : $settings[ 'username_live' ],
45
+ 'acct1.Password' => $mode == 'yes' ? $settings[ 'password' ] : $settings[ 'password_live' ],
46
+ 'acct1.Signature' => $mode == 'yes' ? $settings[ 'signature' ] : $settings[ 'signature_live' ],
47
+ 'acct1.AppId' => $mode == 'yes' ? 'APP-80W284485P519543T' : $settings[ 'app_id' ],
48
+
49
+ 'service.Binding' => 'SOAP',
50
+ 'service.EndPoint' => $mode == 'yes' ? 'https://api-3t.sandbox.paypal.com/2.0/' : 'https://api-3t.paypal.com/2.0/',
51
+ 'service.RedirectURL' => $mode == 'yes' ? 'https://sandbox.paypal.com/webscr&cmd=' : 'https://paypal.com/webscr&cmd=',
52
+ 'service.DevCentralURL' => 'https://developer.paypal.com',
53
+ 'http.ConnectionTimeOut' => '10',
54
+ 'http.Retry' => '5',
55
+ 'log.FileName' => 'PayPal.log',
56
+ 'log.LogLevel' => 'INFO',
57
+ 'log.LogEnabled' => $settings[ 'logging_enabled' ] == 'yes' ? 'true' : 'false',
58
+ );
59
+ } else {
60
+ $this->config = @parse_ini_file( $fileName );
61
+ }
62
+
63
+ if ( $this->config == null || count( $this->config ) == 0 ) {
64
+ throw new PPConfigurationException( "Config file $fileName not found", "303" );
65
+ }
66
+ }
67
+
68
+ /**
69
+ * simple getter for configuration params
70
+ * If an exact match for key is not found,
71
+ * does a "contains" search on the key
72
+ */
73
+ public function get( $searchKey )
74
+ {
75
+
76
+ if ( array_key_exists( $searchKey, $this->config ) ) {
77
+ return $this->config[ $searchKey ];
78
+ } else {
79
+ $arr = array();
80
+ foreach ( $this->config as $k => $v ) {
81
+ if ( strstr( $k, $searchKey ) ) {
82
+ $arr[ $k ] = $v;
83
+ }
84
+ }
85
+
86
+ return $arr;
87
+ }
88
+
89
+ }
90
+
91
+ /**
92
+ * Utility method for handling account configuration
93
+ * return config key corresponding to the API userId passed in
94
+ *
95
+ * If $userId is null, returns config keys corresponding to
96
+ * all configured accounts
97
+ */
98
+ public function getIniPrefix( $userId = null )
99
+ {
100
+
101
+ if ( $userId == null ) {
102
+ $arr = array();
103
+ foreach ( $this->config as $key => $value ) {
104
+ $pos = strpos( $key, '.' );
105
+ if ( strstr( $key, "acct" ) ) {
106
+ $arr[ ] = substr( $key, 0, $pos );
107
+ }
108
+ }
109
+
110
+ return array_unique( $arr );
111
+ } else {
112
+ $iniPrefix = array_search( $userId, $this->config );
113
+ $pos = strpos( $iniPrefix, '.' );
114
+ $acct = substr( $iniPrefix, 0, $pos );
115
+
116
+ return $acct;
117
+ }
118
+ }
119
+ }
120
+
121
+ ?>
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPConnectionManager.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once 'PPHttpConnection.php';
3
+ require_once 'PPConfigManager.php';
4
+ class PPConnectionManager
5
+ {
6
+ /**
7
+ * reference to singleton instance
8
+ * @var PPConnectionManager
9
+ */
10
+ private static $instance;
11
+
12
+ private function __construct()
13
+ {
14
+ }
15
+
16
+ public static function getInstance()
17
+ {
18
+ if ( self::$instance == null ) {
19
+ self::$instance = new PPConnectionManager();
20
+ }
21
+
22
+ return self::$instance;
23
+ }
24
+
25
+ /**
26
+ * This function returns a new PPHttpConnection object
27
+ */
28
+ public function getConnection()
29
+ {
30
+
31
+ $connection = new PPHttpConnection();
32
+
33
+ $configMgr = PPConfigManager::getInstance();
34
+ if ( ( $configMgr->get( "http.ConnectionTimeOut" ) ) ) {
35
+ $connection->setHttpTimeout( $configMgr->get( "http.ConnectionTimeOut" ) );
36
+ }
37
+ if ( $configMgr->get( "http.Proxy" ) ) {
38
+ $connection->setHttpProxy( $configMgr->get( "http.Proxy" ) );
39
+ }
40
+ if ( $configMgr->get( "http.Retry" ) ) {
41
+ $retry = $configMgr->get( "http.Retry" );
42
+ $connection->setHttpRetry( $retry );
43
+ }
44
+
45
+ return $connection;
46
+ }
47
+
48
+ }
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPCredentialManager.php ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once 'IPPCredential.php';
3
+ require_once 'PPConfigManager.php';
4
+ require_once 'PPSignatureCredential.php';
5
+ require_once 'PPCertificateCredential.php';
6
+ require_once 'exceptions/PPInvalidCredentialException.php';
7
+
8
+ class PPCredentialManager
9
+ {
10
+
11
+ private static $instance;
12
+ //hashmap to contain credentials for accounts.
13
+ private $credentialHashmap = array();
14
+ /**
15
+ * Contains the API username of the default account to use
16
+ * when authenticating API calls.
17
+ * @var string
18
+ */
19
+ private $defaultAccountName;
20
+
21
+ /*
22
+ * Constructor initialize credential for multiple accounts specified in property file.
23
+ */
24
+ private function __construct()
25
+ {
26
+ try {
27
+ $this->initCredential();
28
+ } catch ( Exception $e ) {
29
+ $this->credentialHashmap = array();
30
+ throw $e;
31
+ }
32
+ }
33
+
34
+ /*
35
+ * Create singleton instance for this class.
36
+ */
37
+ public static function getInstance()
38
+ {
39
+ if ( !isset( self::$instance ) ) {
40
+ self::$instance = new PPCredentialManager();
41
+ }
42
+
43
+ return self::$instance;
44
+ }
45
+
46
+ /*
47
+ * Load credentials for multiple accounts, with priority given to Signature credential.
48
+ */
49
+ private function initCredential()
50
+ {
51
+ $configMgr = PPConfigManager::getInstance();
52
+ $suffix = 1;
53
+ $prefix = "acct";
54
+
55
+ $credArr = $configMgr->get( $prefix );
56
+ $arrayPartKeys = $configMgr->getIniPrefix();
57
+ if ( count( $arrayPartKeys ) == 0 )
58
+ throw new MissingCredentialException( "No valid API accounts have been configured" );
59
+
60
+ while ( in_array( $prefix . $suffix, $arrayPartKeys ) ) {
61
+
62
+ if ( isset( $credArr[ $prefix . $suffix . ".Signature" ] )
63
+ && $credArr[ $prefix . $suffix . ".Signature" ] != null && $credArr[ $prefix . $suffix . ".Signature" ] != ""
64
+ ) {
65
+
66
+ $userName = isset( $credArr[ $prefix . $suffix . '.UserName' ] ) ? $credArr[ $prefix . $suffix . '.UserName' ] : "";
67
+ $password = isset( $credArr[ $prefix . $suffix . '.Password' ] ) ? $credArr[ $prefix . $suffix . '.Password' ] : "";
68
+ $signature = isset( $credArr[ $prefix . $suffix . '.Signature' ] ) ? $credArr[ $prefix . $suffix . '.Signature' ] : "";
69
+ $appId = isset( $credArr[ $prefix . $suffix . '.AppId' ] ) ? $credArr[ $prefix . $suffix . '.AppId' ] : "";
70
+ $subject = isset( $credArr[ $prefix . $suffix . '.Subject' ] ) ? $credArr[ $prefix . $suffix . '.Subject' ] : "";
71
+ $this->credentialHashmap[ $userName ] = new PPSignatureCredential( $userName, $password, $signature, $appId, $subject );
72
+
73
+ } elseif ( isset( $credArr[ $prefix . $suffix . ".CertPath" ] )
74
+ && $credArr[ $prefix . $suffix . ".CertPath" ] != null && $credArr[ $prefix . $suffix . ".CertPath" ] != ""
75
+ ) {
76
+
77
+ $userName = isset( $credArr[ $prefix . $suffix . '.UserName' ] ) ? $credArr[ $prefix . $suffix . '.UserName' ] : "";
78
+ $password = isset( $credArr[ $prefix . $suffix . '.Password' ] ) ? $credArr[ $prefix . $suffix . '.Password' ] : "";
79
+ $passPhrase = isset( $credArr[ $prefix . $suffix . '.CertKey' ] ) ? $credArr[ $prefix . $suffix . '.CertKey' ] : "";
80
+ $certPath = isset( $credArr[ $prefix . $suffix . '.CertPath' ] ) ? $credArr[ $prefix . $suffix . '.CertPath' ] : "";
81
+ $appId = isset( $credArr[ $prefix . $suffix . '.AppId' ] ) ? $credArr[ $prefix . $suffix . '.AppId' ] : "";
82
+ $subject = isset( $credArr[ $prefix . $suffix . '.Subject' ] ) ? $credArr[ $prefix . $suffix . '.Subject' ] : "";
83
+ $this->credentialHashmap[ $userName ] = new PPCertificateCredential( $userName, $password, $certPath, $appId, $passPhrase, $subject );
84
+
85
+ }
86
+ if ( $this->defaultAccountName == null )
87
+ $this->defaultAccountName = $credArr[ $prefix . $suffix . '.UserName' ];
88
+ $suffix++;
89
+ }
90
+
91
+ }
92
+
93
+ /*
94
+ * Obtain Credential Object based on UserId provided.
95
+ */
96
+ public function getCredentialObject( $userId = null )
97
+ {
98
+
99
+ if ( $userId == null )
100
+ $credObj = $this->credentialHashmap[ $this->defaultAccountName ];
101
+ else if ( array_key_exists( $userId, $this->credentialHashmap ) )
102
+ $credObj = $this->credentialHashmap[ $userId ];
103
+
104
+ if ( empty( $credObj ) ) {
105
+ throw new PPInvalidCredentialException( "Invalid userId $userId" );
106
+ }
107
+
108
+ return $credObj;
109
+ }
110
+
111
+
112
+ public function __clone()
113
+ {
114
+ trigger_error( 'Clone is not allowed.', E_USER_ERROR );
115
+ }
116
+
117
+ }
118
+
119
+ ?>
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPHttpConnection.php ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once 'exceptions/PPConnectionException.php';
4
+ require_once 'exceptions/PPConfigurationException.php';
5
+ require_once 'PPLoggingManager.php';
6
+ /**
7
+ * A wrapper class based on the curl extension.
8
+ * Requires the PHP curl module to be enabled.
9
+ * See for full requirements the PHP manual: http://php.net/curl
10
+ */
11
+
12
+
13
+ class PPHttpConnection
14
+ {
15
+
16
+ const HTTP_GET = 'GET';
17
+ const HTTP_POST = 'POST';
18
+
19
+ /**
20
+ * curl options to be set for the request
21
+ */
22
+ private $curlOpt = array();
23
+
24
+ /**
25
+ * Number of times a retry must be attempted on getting an HTTP error
26
+ * @var integer
27
+ */
28
+ private $retry;
29
+
30
+ /**
31
+ * HTTP status codes for which a retry must be attempted
32
+ */
33
+ private static $retryCodes = array( '401', '403', '404', );
34
+
35
+ private $logger;
36
+
37
+
38
+ /**
39
+ * Some default options for curl
40
+ * These are typically overridden by PPConnectionManager
41
+ */
42
+ public static $DEFAULT_CURL_OPTS = array(
43
+ CURLOPT_CONNECTTIMEOUT => 10,
44
+ CURLOPT_RETURNTRANSFER => true,
45
+ CURLOPT_TIMEOUT => 60, // maximum number of seconds to allow cURL functions to execute
46
+ CURLOPT_USERAGENT => 'PayPal-PHP-SDK',
47
+ CURLOPT_POST => 1,
48
+ CURLOPT_HTTPHEADER => array(),
49
+ CURLOPT_SSL_VERIFYHOST => 1,
50
+ CURLOPT_SSL_VERIFYPEER => 2
51
+ );
52
+
53
+ public function __construct()
54
+ {
55
+ if ( !function_exists( "curl_init" ) ) {
56
+ throw new PPConfigurationException( "Curl module is not available on this system" );
57
+ }
58
+ $this->curlOpt = self::$DEFAULT_CURL_OPTS;
59
+ $this->logger = new PPLoggingManager( __CLASS__ );
60
+ }
61
+
62
+ /**
63
+ * Set ssl parameters for certificate based client authentication
64
+ *
65
+ * @param string $certPath - path to client certificate file (PEM formatted file)
66
+ */
67
+ public function setSSLCert( $certPath, $passPhrase )
68
+ {
69
+ $this->curlOpt[ CURLOPT_SSLCERT ] = realpath( $certPath );
70
+ $this->curlOpt[ CURLOPT_SSLCERTPASSWD ] = $passPhrase;
71
+ }
72
+
73
+ /**
74
+ * Set connection timeout in seconds
75
+ *
76
+ * @param integer $timeout
77
+ */
78
+ public function setHttpTimeout( $timeout )
79
+ {
80
+ $this->curlOpt[ CURLOPT_CONNECTTIMEOUT ] = $timeout;
81
+ }
82
+
83
+ /**
84
+ * Set HTTP proxy information
85
+ *
86
+ * @param string $proxy
87
+ *
88
+ * @throws PPConfigurationException
89
+ */
90
+ public function setHttpProxy( $proxy )
91
+ {
92
+ $urlParts = parse_url( $proxy );
93
+ if ( $urlParts == false || !array_key_exists( "host", $urlParts ) )
94
+ throw new PPConfigurationException( "Invalid proxy configuration " . $proxy );
95
+
96
+ $this->curlOpt[ CURLOPT_PROXY ] = $urlParts[ "host" ];
97
+ if ( isset( $urlParts[ "port" ] ) )
98
+ $this->curlOpt[ CURLOPT_PROXY ] .= ":" . $urlParts[ "port" ];
99
+ if ( isset( $urlParts[ "user" ] ) )
100
+ $this->curlOpt[ URLOPT_PROXYUSERPWD ] = $urlParts[ "user" ] . ":" . $urlParts[ "pass" ];
101
+ }
102
+
103
+ public function setHttpHeaders( $headers )
104
+ {
105
+ $this->curlOpt[ CURLOPT_HTTPHEADER ] = $headers;
106
+ }
107
+
108
+ /**
109
+ * @param integer $retry
110
+ */
111
+ public function setHttpRetry( $retry )
112
+ {
113
+ $this->retry = $retry;
114
+ }
115
+
116
+ /**
117
+ * Executes an HTTP request
118
+ *
119
+ * @param string $url
120
+ * @param string $params query string OR POST content as a string
121
+ * @param array $headers array of HTTP headers to be added to existing headers
122
+ * @param string $method HTTP method (GET, POST etc) defaults to POST
123
+ *
124
+ * @throws PPConnectionException
125
+ */
126
+ public function execute( $url, $params, $headers = null, $method = null )
127
+ {
128
+
129
+ $ch = curl_init( $url );
130
+
131
+ $this->curlOpt[ CURLOPT_POSTFIELDS ] = $params;
132
+ $this->curlOpt[ CURLOPT_URL ] = $url;
133
+ $this->curlOpt[ CURLOPT_HEADER ] = false;
134
+ if ( isset( $headers ) ) {
135
+ $this->curlOpt[ CURLOPT_HTTPHEADER ] = array_merge( $this->curlOpt[ CURLOPT_HTTPHEADER ], $headers );
136
+ }
137
+ foreach ( $this->curlOpt[ CURLOPT_HTTPHEADER ] as $header ) {
138
+ //TODO: Strip out credentials when logging.
139
+ $this->logger->info( "Adding header $header" );
140
+ }
141
+ if ( isset( $method ) ) {
142
+ $this->curlOpt[ CURLOPT_CUSTOMREQUEST ] = $method;
143
+ }
144
+
145
+ // curl_setopt_array available only in PHP 5 >= 5.1.3
146
+ curl_setopt_array( $ch, $this->curlOpt );
147
+
148
+ $result = curl_exec( $ch );
149
+
150
+ if ( curl_errno( $ch ) == 60 ) {
151
+ $this->logger->info( "Invalid or no certificate authority found, retrying using bundled CA certs" );
152
+ curl_setopt( $ch, CURLOPT_CAINFO,
153
+ dirname( __FILE__ ) . '/cacert.pem' );
154
+ $result = curl_exec( $ch );
155
+ }
156
+ $httpStatus = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
157
+ $retries = 0;
158
+ if ( in_array( $httpStatus, self::$retryCodes ) && isset( $this->retry ) ) {
159
+ $this->logger->info( "Got $httpStatus response from server. Retrying" );
160
+
161
+ do {
162
+ $result = curl_exec( $ch );
163
+ $httpStatus = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
164
+
165
+ } while ( in_array( $httpStatus, self::$retryCodes ) && ++$retries < $this->retry );
166
+
167
+
168
+ }
169
+ if ( curl_errno( $ch ) ) {
170
+ $ex = new PPConnectionException( $url, curl_error( $ch ), curl_errno( $ch ) );
171
+ curl_close( $ch );
172
+ throw $ex;
173
+ }
174
+
175
+ curl_close( $ch );
176
+
177
+ if ( in_array( $httpStatus, self::$retryCodes ) ) {
178
+ throw new PPConnectionException( $url, "Retried " . $retries . " times, Http Response code " . $httpStatus );
179
+ }
180
+
181
+ return $result;
182
+ }
183
+
184
+ }
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPLoggingManager.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Simple Logging Manager.
5
+ * This does an error_log for now
6
+ * Potential frameworks to use are PEAR logger, log4php from Apache
7
+ */
8
+
9
+ class PPLoggingLevel
10
+ {
11
+
12
+ // FINE Logging Level
13
+ const FINE = 3;
14
+
15
+ // INFO Logging Level
16
+ const INFO = 2;
17
+
18
+ // WARN Logging Level
19
+ const WARN = 1;
20
+
21
+ // ERROR Logging Level
22
+ const ERROR = 0;
23
+ }
24
+
25
+ class PPLoggingManager
26
+ {
27
+
28
+ // Default Logging Level
29
+ const DEFAULT_LOGGING_LEVEL = 0;
30
+
31
+ // Logger name
32
+ private $loggerName;
33
+
34
+ // Log enabled
35
+ private $isLoggingEnabled;
36
+
37
+ // Configured logging level
38
+ private $loggingLevel;
39
+
40
+ // Configured logging file
41
+ private $loggerFile;
42
+
43
+ public function __construct( $loggerName )
44
+ {
45
+ $this->loggerName = $loggerName;
46
+ $config = PPConfigManager::getInstance();
47
+ $this->loggerFile = ( $config->get( 'log.FileName' ) ) ? $config->get( 'log.FileName' ) : ini_get( 'error_log' );
48
+ $loggingEnabled = $config->get( 'log.LogEnabled' );
49
+ $this->isLoggingEnabled = ( isset( $loggingEnabled ) ) ? $loggingEnabled : false;
50
+ $loggingLevel = strtoupper( $config->get( 'log.LogLevel' ) );
51
+ $this->loggingLevel = ( isset( $loggingLevel ) && defined( "PPLoggingLevel::$loggingLevel" ) ) ? constant( "PPLoggingLevel::$loggingLevel" ) : PPLoggingManager::DEFAULT_LOGGING_LEVEL;
52
+
53
+ }
54
+
55
+ public function log( $message, $level = PPLoggingLevel::INFO )
56
+ {
57
+ if ( $this->isLoggingEnabled && ( $level <= $this->loggingLevel ) ) {
58
+ error_log( $this->loggerName . ": $message\n", 3, $this->loggerFile );
59
+ }
60
+ }
61
+
62
+ public function error( $message )
63
+ {
64
+ $this->log( $message, PPLoggingLevel::ERROR );
65
+ }
66
+
67
+ public function warning( $message )
68
+ {
69
+ $this->log( $message, PPLoggingLevel::WARN );
70
+ }
71
+
72
+ public function info( $message )
73
+ {
74
+ $this->log( $message, PPLoggingLevel::INFO );
75
+ }
76
+
77
+ public function fine( $message )
78
+ {
79
+ $this->log( $message, PPLoggingLevel::FINE );
80
+ }
81
+
82
+ }
83
+
84
+ ?>
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPObjectTransformer.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Utility class for transforming PHP objects into
4
+ * appropriate service payload type and vice versa
5
+ */
6
+ class PPObjectTransformer
7
+ {
8
+
9
+ public function toString( $object )
10
+ {
11
+
12
+ if ( $object == null ) {
13
+ throw new PPTransformerException( "Empty object" );
14
+ }
15
+
16
+ $confManager = PPConfigManager::getInstance();
17
+ switch ( strtoupper( $confManager->get( "service.Binding" ) ) ) {
18
+ case 'SOAP':
19
+ return $object->toXMLString();
20
+
21
+ case 'XML':
22
+ case 'JSON':
23
+ return "";
24
+ case 'NVP':
25
+ default:
26
+ return $object->toNVPString();
27
+ }
28
+ }
29
+
30
+
31
+ }
32
+
33
+ ?>
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPSignatureCredential.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once 'exceptions/PPMissingCredentialException.php';
4
+ require_once 'IPPCredential.php';
5
+ require_once 'PPConfigManager.php';
6
+
7
+ /**
8
+ * API signature based credentials
9
+ */
10
+ class PPSignatureCredential extends IPPCredential
11
+ {
12
+
13
+ /**
14
+ * API Signature
15
+ * @var string
16
+ */
17
+ private $signature;
18
+ private $subject;
19
+
20
+ public function __construct( $userName, $password, $signature, $appId, $subject )
21
+ {
22
+ parent::__construct( $userName, $password, $appId );
23
+ $this->signature = $signature;
24
+ $this->subject = $subject;
25
+ $this->validate();
26
+ }
27
+
28
+ public function validate()
29
+ {
30
+
31
+ if ( $this->userName == null || $this->userName == "" ) {
32
+ throw new PPMissingCredentialException( "username cannot be empty" );
33
+ }
34
+ if ( $this->password == null || $this->password == "" ) {
35
+ throw new PPMissingCredentialException( "password cannot be empty" );
36
+ }
37
+ if ( $this->signature == null || $this->signature == "" ) {
38
+ throw new PPMissingCredentialException( "signature cannot be empty" );
39
+ }
40
+ if ( $this->applicationId == null || $this->applicationId == "" ) {
41
+ throw new PPMissingCredentialException( "applicationId cannot be empty" );
42
+ }
43
+ }
44
+
45
+ public function getSignature()
46
+ {
47
+ return $this->signature;
48
+ }
49
+
50
+ public function getSubject()
51
+ {
52
+ return $this->subject;
53
+ }
54
+ }
55
+
56
+ ?>
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/PPUtils.php ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class PPUtils
3
+ {
4
+
5
+ const SDK_VERSION = "1.2.95";
6
+ const SDK_NAME = "sdk-merchant-php ";
7
+
8
+ /**
9
+ *
10
+ * Convert a Name Value Pair (NVP) formatted string into
11
+ * an associative array taking care to urldecode array values
12
+ *
13
+ * @param string $nvpString
14
+ */
15
+ public static function nvpToMap( $nvpString )
16
+ {
17
+
18
+ $ret = array();
19
+ $params = explode( "&", $nvpString );
20
+ foreach ( $params as $p ) {
21
+ list( $k, $v ) = explode( "=", $p );
22
+ $ret[ $k ] = urldecode( $v );
23
+ }
24
+
25
+ return $ret;
26
+ }
27
+
28
+ /**
29
+ * Returns true if the array contains a key like $key
30
+ *
31
+ * @param array $map
32
+ * @param regex $key
33
+ */
34
+ public static function array_match_key( $map, $key )
35
+ {
36
+ $key = str_replace( "(", "\(", $key );
37
+ $key = str_replace( ")", "\)", $key );
38
+ $key = str_replace( ".", "\.", $key );
39
+ $pattern = "/$key*/";
40
+ foreach ( $map as $k => $v ) {
41
+ preg_match( $pattern, $k, $matches );
42
+ if ( count( $matches ) > 0 )
43
+ return true;
44
+ }
45
+
46
+ return false;
47
+ }
48
+
49
+ /**
50
+ *
51
+ * Get the local IP address. The client address is a required
52
+ * request parameter for some API calls
53
+ */
54
+ public static function getLocalIPAddress()
55
+ {
56
+
57
+ if ( array_key_exists( "SERVER_ADDR", $_SERVER ) ) {
58
+ // SERVER_ADDR is available only if we are running the CGI SAPI
59
+ return $_SERVER[ 'SERVER_ADDR' ];
60
+ } else if ( function_exists( "gethostname" ) ) {
61
+ // gethostname is available only in PHP >= v5.3
62
+ return gethostbyname( gethostname() );
63
+ } else {
64
+ // fallback if nothing works
65
+ return "127.0.0.1";
66
+ }
67
+ }
68
+
69
+ /**
70
+ *
71
+ * Compute the value that needs to sent for the PAYPAL_REQUEST_SOURCE
72
+ * parameter when making API calls
73
+ */
74
+ public static function getRequestSource()
75
+ {
76
+ return str_replace( " ", "-", self::SDK_NAME ) . self::SDK_VERSION;
77
+ }
78
+
79
+ public static function xmlToArray( $xmlInput )
80
+ {
81
+
82
+ $xml = simplexml_load_string( $xmlInput );
83
+
84
+ $ns = $xml->getNamespaces( true );
85
+
86
+ $soap = $xml->children( $ns[ 'SOAP-ENV' ] );
87
+ $getChild = $soap->Body->children();
88
+
89
+ $ret = PPUtils::convertXmlObjToArr( $getChild, $array = array() );
90
+
91
+ return $ret;
92
+ }
93
+
94
+ /*foreach ($ret as $arry)
95
+ {
96
+ if (isset($arry['children']) && is_array($arry['children'])&& ($arry['children'])!=null) {
97
+ foreach ($arry['children'] as $novel)
98
+ {
99
+
100
+ }
101
+ }
102
+ else if ($arry['name'] != null)
103
+ {
104
+ $a = $arry['name'] ;
105
+ $b= $arry['text'];
106
+ if (isset($arry['attribute']))
107
+ {
108
+ $c = $arry['attribute'];
109
+ }
110
+ }
111
+
112
+
113
+ }*/
114
+
115
+ /*public function xml2array ( $xmlObject, $out = array () )
116
+ {
117
+ foreach ( (array) $xmlObject as $index => $node )
118
+ {
119
+ $out[$index] = ( is_object ( $node ) ) ? PPUtils::xml2array ( $node ) : $node;
120
+ }
121
+ return $out;
122
+ }*/
123
+
124
+
125
+ function convertXmlObjToArr( $obj, &$arr )
126
+ {
127
+ $children = $obj->children();
128
+ foreach ( $children as $elementName => $node ) {
129
+ $nextIdx = count( $arr );
130
+ $arr[ $nextIdx ] = array();
131
+ $arr[ $nextIdx ][ 'name' ] = strtolower( (string) $elementName );
132
+ $arr[ $nextIdx ][ 'attributes' ] = array();
133
+ $attributes = $node->attributes();
134
+ foreach ( $attributes as $attributeName => $attributeValue ) {
135
+ $attribName = strtolower( trim( (string) $attributeName ) );
136
+ $attribVal = trim( (string) $attributeValue );
137
+ $arr[ $nextIdx ][ 'attributes' ][ $attribName ] = $attribVal;
138
+ }
139
+ $text = (string) $node;
140
+ $text = trim( $text );
141
+ if ( strlen( $text ) > 0 ) {
142
+ $arr[ $nextIdx ][ 'text' ] = $text;
143
+ }
144
+ $arr[ $nextIdx ][ 'children' ] = array();
145
+ PPutils::convertXmlObjToArr( $node, $arr[ $nextIdx ][ 'children' ] );
146
+ }
147
+
148
+ return $arr;
149
+ }
150
+
151
+ /**
152
+ * Escapes invalid xml characters
153
+ *
154
+ * @param $textContent = xml data to be escaped
155
+ */
156
+ public static function escapeInvalidXmlCharsRegex( $textContent )
157
+ {
158
+ return htmlspecialchars( $textContent, ( 1 | 2 ), 'UTF-8', false );
159
+ }
160
+
161
+ }
162
+
163
+ /**
164
+ * @class xml2array
165
+ */
166
+
167
+
168
+ /**
169
+ * XMLToArray Generator Class
170
+ * @author : MA Razzaque Rupom <rupom_315@yahoo.com>, <rupom.bd@gmail.com>
171
+ * Moderator, phpResource (LINK1http://groups.yahoo.com/group/phpresource/LINK1)
172
+ * URL: LINK2http://www.rupom.infoLINK2
173
+ * @version : 1.0
174
+ * @date 06/05/2006
175
+ * Purpose : Creating Hierarchical Array from XML Data
176
+ * Released : Under GPL
177
+ */
178
+
179
+ class XmlToArray
180
+ {
181
+
182
+ var $xml = '';
183
+
184
+ /**
185
+ * Default Constructor
186
+ *
187
+ * @param $xml = xml data
188
+ *
189
+ * @return none
190
+ */
191
+
192
+ function XmlToArray( $xml )
193
+ {
194
+ $this->xml = $xml;
195
+ }
196
+
197
+ /**
198
+ * _struct_to_array($values, &$i)
199
+ *
200
+ * This is adds the contents of the return xml into the array for easier processing.
201
+ * Recursive, Static
202
+ *
203
+ * @access private
204
+ *
205
+ * @param array $values this is the xml data in an array
206
+ * @param int $i this is the current location in the array
207
+ *
208
+ * @return Array
209
+ */
210
+
211
+ function _struct_to_array( $values, &$i )
212
+ {
213
+ $child = array();
214
+ if ( isset( $values[ $i ][ 'value' ] ) ) array_push( $child, $values[ $i ][ 'value' ] );
215
+
216
+ while ( $i++ < count( $values ) ) {
217
+ switch ( $values[ $i ][ 'type' ] ) {
218
+ case 'cdata':
219
+ array_push( $child, $values[ $i ][ 'value' ] );
220
+ break;
221
+
222
+ case 'complete':
223
+ $name = $values[ $i ][ 'tag' ];
224
+ if ( !empty( $name ) ) {
225
+ $child[ $name ] = ( $values[ $i ][ 'value' ] ) ? ( $values[ $i ][ 'value' ] ) : '';
226
+ if ( isset( $values[ $i ][ 'attributes' ] ) ) {
227
+ $child[ $name ] = $values[ $i ][ 'attributes' ];
228
+ }
229
+ }
230
+ break;
231
+
232
+ case 'open':
233
+ $name = $values[ $i ][ 'tag' ];
234
+ $size = isset( $child[ $name ] ) ? sizeof( $child[ $name ] ) : 0;
235
+ $child[ $name ][ $size ] = $this->_struct_to_array( $values, $i );
236
+ break;
237
+
238
+ case 'close':
239
+ return $child;
240
+ break;
241
+ }
242
+ }
243
+
244
+ return $child;
245
+ }
246
+
247
+ //_struct_to_array
248
+
249
+ /**
250
+ * createArray($data)
251
+ *
252
+ * This is adds the contents of the return xml into the array for easier processing.
253
+ *
254
+ * @access public
255
+ *
256
+ * @param string $data this is the string of the xml data
257
+ *
258
+ * @return Array
259
+ */
260
+ function createArray()
261
+ {
262
+ $xml = $this->xml;
263
+ $values = array();
264
+ $index = array();
265
+ $array = array();
266
+ $parser = xml_parser_create();
267
+ xml_parser_set_option( $parser, XML_OPTION_SKIP_WHITE, 1 );
268
+ xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, 0 );
269
+ xml_parse_into_struct( $parser, $xml, $values, $index );
270
+ xml_parser_free( $parser );
271
+ $i = 0;
272
+ $name = $values[ $i ][ 'tag' ];
273
+ $array[ $name ] = isset( $values[ $i ][ 'attributes' ] ) ? $values[ $i ][ 'attributes' ] : '';
274
+ $array[ $name ] = $this->_struct_to_array( $values, $i );
275
+
276
+ return $array;
277
+ }
278
+ //createArray
279
+
280
+
281
+ }
282
+
283
+ //XmlToArray
284
+ ?>
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/auth/AuthUtil.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php //vim: foldmethod=marker
2
+
3
+ class MockOAuthDataStore extends OAuthDataStore
4
+ { /*{{{*/
5
+ private $consumer;
6
+ private $request_token;
7
+ private $access_token;
8
+ private $nonce;
9
+
10
+ function __construct()
11
+ { /*{{{*/
12
+ $this->consumer = new OAuthConsumer( "key", "secret", null );
13
+ $this->request_token = new OAuthToken( "requestkey", "requestsecret", 1 );
14
+ $this->access_token = new OAuthToken( "accesskey", "accesssecret", 1 );
15
+ $this->nonce = "nonce";
16
+ }
17
+
18
+ /*}}}*/
19
+
20
+ function lookup_consumer( $consumer_key )
21
+ { /*{{{*/
22
+ if ( $consumer_key == $this->consumer->key ) return $this->consumer;
23
+
24
+ return null;
25
+ }
26
+
27
+ /*}}}*/
28
+
29
+ function lookup_token( $consumer, $token_type, $token )
30
+ { /*{{{*/
31
+ $token_attrib = $token_type . "_token";
32
+ if ( $consumer->key == $this->consumer->key
33
+ && $token == $this->$token_attrib->key
34
+ ) {
35
+ return $this->$token_attrib;
36
+ }
37
+
38
+ return null;
39
+ }
40
+
41
+ /*}}}*/
42
+
43
+ function lookup_nonce( $consumer, $token, $nonce, $timestamp )
44
+ { /*{{{*/
45
+ if ( $consumer->key == $this->consumer->key
46
+ && ( ( $token && $token->key == $this->request_token->key )
47
+ || ( $token && $token->key == $this->access_token->key ) )
48
+ && $nonce == $this->nonce
49
+ ) {
50
+ return $this->nonce;
51
+ }
52
+
53
+ return null;
54
+ }
55
+
56
+ /*}}}*/
57
+
58
+ function new_request_token( $consumer, $callback = null )
59
+ { /*{{{*/
60
+ if ( $consumer->key == $this->consumer->key ) {
61
+ return $this->request_token;
62
+ }
63
+
64
+ return null;
65
+ }
66
+
67
+ /*}}}*/
68
+
69
+ function new_access_token( $token, $consumer, $verifier = null )
70
+ { /*{{{*/
71
+ if ( $consumer->key == $this->consumer->key
72
+ && $token->key == $this->request_token->key
73
+ ) {
74
+ return $this->access_token;
75
+ }
76
+
77
+ return null;
78
+ }
79
+ /*}}}*/
80
+ }
81
+
82
+ /*}}}*/
83
+ ?>
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/auth/PPAuth.php ADDED
@@ -0,0 +1,1057 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ //PayPal specific modification starts
3
+ //Method to be called for generating signature
4
+ require_once( "AuthUtil.php" );
5
+ class AuthSignature
6
+ {
7
+
8
+ public function genSign( $key, $secret, $token, $tokenSecret, $httpMethod, $endpoint )
9
+ {
10
+
11
+
12
+ $authServer = new OAuthServer( new MockOAuthDataStore() );
13
+ $hmac_method = new OAuthSignatureMethod_HMAC_SHA1();
14
+ $authServer->add_signature_method( $hmac_method );
15
+
16
+ $sig_method = $hmac_method;
17
+ $authConsumer = new OAuthConsumer( $key, $secret, null );
18
+ $authToken = null;
19
+ $authToken = new OAuthToken( $token, $tokenSecret );
20
+
21
+ //$params is the query param array which is required only in the httpMethod is "GET"
22
+
23
+ $params = array();
24
+ //set the Query parameters to $params if httpMethod is "GET"
25
+
26
+ $acc_req = OAuthRequest::from_consumer_and_token( $authConsumer, $authToken, $httpMethod, $endpoint, $params );
27
+
28
+ $acc_req->sign_request( $sig_method, $authConsumer, $authToken );
29
+ $response = OAuthutil::parseQueryString( $acc_req );
30
+
31
+ return $response;
32
+
33
+ }
34
+ }
35
+
36
+ //PayPal specific modification ends
37
+ /* Generic exception class
38
+ */
39
+ class OAuthException extends Exception
40
+ {
41
+ // pass
42
+ }
43
+
44
+ class OAuthConsumer
45
+ {
46
+ public $key;
47
+ public $secret;
48
+
49
+ function __construct( $key, $secret, $callback_url = null )
50
+ {
51
+ $this->key = $key;
52
+ $this->secret = $secret;
53
+ $this->callback_url = $callback_url;
54
+ }
55
+
56
+ function __toString()
57
+ {
58
+ return "OAuthConsumer[key=$this->key,secret=$this->secret]";
59
+ }
60
+ }
61
+
62
+ class OAuthToken
63
+ {
64
+ // access tokens and request tokens
65
+ public $key;
66
+ public $secret;
67
+
68
+ /**
69
+ * key = the token
70
+ * secret = the token secret
71
+ */
72
+ function __construct( $key, $secret )
73
+ {
74
+ $this->key = $key;
75
+ $this->secret = $secret;
76
+ }
77
+
78
+ /**
79
+ * generates the basic string serialization of a token that a server
80
+ * would respond to request_token and access_token calls with
81
+ */
82
+ function to_string()
83
+ {
84
+ return "oauth_token=" .
85
+ OAuthUtil::urlencode_rfc3986( $this->key ) .
86
+ "&oauth_token_secret=" .
87
+ OAuthUtil::urlencode_rfc3986( $this->secret );
88
+ }
89
+
90
+ function __toString()
91
+ {
92
+ return $this->to_string();
93
+ }
94
+ }
95
+
96
+ /**
97
+ * A class for implementing a Signature Method
98
+ * See section 9 ("Signing Requests") in the spec
99
+ */
100
+ abstract class OAuthSignatureMethod
101
+ {
102
+ /**
103
+ * Needs to return the name of the Signature Method (ie HMAC-SHA1)
104
+ * @return string
105
+ */
106
+ abstract public function get_name();
107
+
108
+ /**
109
+ * Build up the signature
110
+ * NOTE: The output of this function MUST NOT be urlencoded.
111
+ * the encoding is handled in OAuthRequest when the final
112
+ * request is serialized
113
+ *
114
+ * @param OAuthRequest $request
115
+ * @param OAuthConsumer $consumer
116
+ * @param OAuthToken $token
117
+ *
118
+ * @return string
119
+ */
120
+ abstract public function build_signature( $request, $consumer, $token );
121
+
122
+ /**
123
+ * Verifies that a given signature is correct
124
+ *
125
+ * @param OAuthRequest $request
126
+ * @param OAuthConsumer $consumer
127
+ * @param OAuthToken $token
128
+ * @param string $signature
129
+ *
130
+ * @return bool
131
+ */
132
+ public function check_signature( $request, $consumer, $token, $signature )
133
+ {
134
+ $built = $this->build_signature( $request, $consumer, $token );
135
+
136
+ return $built == $signature;
137
+ }
138
+ }
139
+
140
+ /**
141
+ * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
142
+ * where the Signature Base String is the text and the key is the concatenated values (each first
143
+ * encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
144
+ * character (ASCII code 38) even if empty.
145
+ * - Chapter 9.2 ("HMAC-SHA1")
146
+ */
147
+ class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod
148
+ {
149
+ function get_name()
150
+ {
151
+ return "HMAC-SHA1";
152
+ }
153
+
154
+ public function build_signature( $request, $consumer, $token )
155
+ {
156
+ $base_string = $request->get_signature_base_string();
157
+ $base_string = preg_replace( "/(%[A-Za-z0-9]{2})/e", "strtolower('\\0')", $base_string ); //convert base string to lowercase
158
+ $request->base_string = $base_string;
159
+
160
+ $key_parts = array(
161
+ $consumer->secret,
162
+ ( $token ) ? $token->secret : ""
163
+ );
164
+
165
+ $key_parts = OAuthUtil::urlencode_rfc3986( $key_parts );
166
+ $key = implode( '&', $key_parts );
167
+ $key = preg_replace( "/(%[A-Za-z0-9]{2})/e", "strtolower('\\0')", $key ); //convert to lowercase
168
+ return base64_encode( hash_hmac( 'sha1', $base_string, $key, true ) );
169
+ }
170
+ }
171
+
172
+ /**
173
+ * The PLAINTEXT method does not provide any security protection and SHOULD only be used
174
+ * over a secure channel such as HTTPS. It does not use the Signature Base String.
175
+ * - Chapter 9.4 ("PLAINTEXT")
176
+ */
177
+ if ( !class_exists( 'OAuthSignatureMethod_PLAINTEXT' ) ) {
178
+ class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod
179
+ {
180
+ public function get_name()
181
+ {
182
+ return "PLAINTEXT";
183
+ }
184
+
185
+ /**
186
+ * oauth_signature is set to the concatenated encoded values of the Consumer Secret and
187
+ * Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
188
+ * empty. The result MUST be encoded again.
189
+ * - Chapter 9.4.1 ("Generating Signatures")
190
+ *
191
+ * Please note that the second encoding MUST NOT happen in the SignatureMethod, as
192
+ * OAuthRequest handles this!
193
+ */
194
+ public function build_signature( $request, $consumer, $token )
195
+ {
196
+ $key_parts = array(
197
+ $consumer->secret,
198
+ ( $token ) ? $token->secret : ""
199
+ );
200
+
201
+ $key_parts = OAuthUtil::urlencode_rfc3986( $key_parts );
202
+ $key = implode( '&', $key_parts );
203
+ $request->base_string = $key;
204
+
205
+ return $key;
206
+ }
207
+ }
208
+ }
209
+ /**
210
+ * The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
211
+ * [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
212
+ * EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
213
+ * verified way to the Service Provider, in a manner which is beyond the scope of this
214
+ * specification.
215
+ * - Chapter 9.3 ("RSA-SHA1")
216
+ */
217
+ abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod
218
+ {
219
+ public function get_name()
220
+ {
221
+ return "RSA-SHA1";
222
+ }
223
+
224
+ // Up to the SP to implement this lookup of keys. Possible ideas are:
225
+ // (1) do a lookup in a table of trusted certs keyed off of consumer
226
+ // (2) fetch via http using a url provided by the requester
227
+ // (3) some sort of specific discovery code based on request
228
+ //
229
+ // Either way should return a string representation of the certificate
230
+ protected abstract function fetch_public_cert( &$request );
231
+
232
+ // Up to the SP to implement this lookup of keys. Possible ideas are:
233
+ // (1) do a lookup in a table of trusted certs keyed off of consumer
234
+ //
235
+ // Either way should return a string representation of the certificate
236
+ protected abstract function fetch_private_cert( &$request );
237
+
238
+ public function build_signature( $request, $consumer, $token )
239
+ {
240
+ $base_string = $request->get_signature_base_string();
241
+ $request->base_string = $base_string;
242
+
243
+ // Fetch the private key cert based on the request
244
+ $cert = $this->fetch_private_cert( $request );
245
+
246
+ // Pull the private key ID from the certificate
247
+ $privatekeyid = openssl_get_privatekey( $cert );
248
+
249
+ // Sign using the key
250
+ $ok = openssl_sign( $base_string, $signature, $privatekeyid );
251
+
252
+ // Release the key resource
253
+ openssl_free_key( $privatekeyid );
254
+
255
+ return base64_encode( $signature );
256
+ }
257
+
258
+ public function check_signature( $request, $consumer, $token, $signature )
259
+ {
260
+ $decoded_sig = base64_decode( $signature );
261
+
262
+ $base_string = $request->get_signature_base_string();
263
+
264
+ // Fetch the public key cert based on the request
265
+ $cert = $this->fetch_public_cert( $request );
266
+
267
+ // Pull the public key ID from the certificate
268
+ $publickeyid = openssl_get_publickey( $cert );
269
+
270
+ // Check the computed signature against the one passed in the query
271
+ $ok = openssl_verify( $base_string, $decoded_sig, $publickeyid );
272
+
273
+ // Release the key resource
274
+ openssl_free_key( $publickeyid );
275
+
276
+ return $ok == 1;
277
+ }
278
+ }
279
+
280
+ class OAuthRequest
281
+ {
282
+ public $parameters;
283
+ protected $http_method;
284
+ protected $http_url;
285
+ // for debug purposes
286
+ public $base_string;
287
+ public static $version = '1.0';
288
+ public static $POST_INPUT = 'php://input';
289
+
290
+ function __construct( $http_method, $http_url, $parameters = null )
291
+ {
292
+ $parameters = ( $parameters ) ? $parameters : array();
293
+ $parameters = array_merge( OAuthUtil::parse_parameters( parse_url( $http_url, PHP_URL_QUERY ) ), $parameters );
294
+ $this->parameters = $parameters;
295
+ $this->http_method = $http_method;
296
+ $this->http_url = $http_url;
297
+ }
298
+
299
+
300
+ /**
301
+ * attempt to build up a request from what was passed to the server
302
+ */
303
+ public static function from_request( $http_method = null, $http_url = null, $parameters = null )
304
+ {
305
+ $scheme = ( !isset( $_SERVER[ 'HTTPS' ] ) || $_SERVER[ 'HTTPS' ] != "on" )
306
+ ? 'http'
307
+ : 'https';
308
+ $http_url = ( $http_url ) ? $http_url : $scheme .
309
+ '://' . $_SERVER[ 'HTTP_HOST' ] .
310
+ ':' .
311
+ $_SERVER[ 'SERVER_PORT' ] .
312
+ $_SERVER[ 'REQUEST_URI' ];
313
+ $http_method = ( $http_method ) ? $http_method : $_SERVER[ 'REQUEST_METHOD' ];
314
+
315
+ // We weren't handed any parameters, so let's find the ones relevant to
316
+ // this request.
317
+ // If you run XML-RPC or similar you should use this to provide your own
318
+ // parsed parameter-list
319
+ if ( !$parameters ) {
320
+ // Find request headers
321
+ $request_headers = OAuthUtil::get_headers();
322
+
323
+ // Parse the query-string to find GET parameters
324
+ $parameters = OAuthUtil::parse_parameters( $_SERVER[ 'QUERY_STRING' ] );
325
+
326
+ // It's a POST request of the proper content-type, so parse POST
327
+ // parameters and add those overriding any duplicates from GET
328
+ if ( $http_method == "POST"
329
+ && isset( $request_headers[ 'Content-Type' ] )
330
+ && strstr( $request_headers[ 'Content-Type' ],
331
+ 'application/x-www-form-urlencoded' )
332
+ ) {
333
+ $post_data = OAuthUtil::parse_parameters(
334
+ file_get_contents( self::$POST_INPUT )
335
+ );
336
+ $parameters = array_merge( $parameters, $post_data );
337
+ }
338
+
339
+ // We have a Authorization-header with OAuth data. Parse the header
340
+ // and add those overriding any duplicates from GET or POST
341
+ if ( isset( $request_headers[ 'Authorization' ] ) && substr( $request_headers[ 'Authorization' ], 0, 6 ) == 'OAuth ' ) {
342
+ $header_parameters = OAuthUtil::split_header(
343
+ $request_headers[ 'Authorization' ]
344
+ );
345
+ $parameters = array_merge( $parameters, $header_parameters );
346
+ }
347
+
348
+ }
349
+
350
+ return new OAuthRequest( $http_method, $http_url, $parameters );
351
+ }
352
+
353
+ /**
354
+ * pretty much a helper function to set up the request
355
+ */
356
+ public static function from_consumer_and_token( $consumer, $token, $http_method, $http_url, $parameters = null )
357
+ {
358
+ $parameters = ( $parameters ) ? $parameters : array();
359
+ $defaults = array(
360
+ "oauth_version" => OAuthRequest::$version,
361
+ // "oauth_nonce" => OAuthRequest::generate_nonce(),
362
+ "oauth_timestamp" => OAuthRequest::generate_timestamp(),
363
+
364
+ "oauth_consumer_key" => $consumer->key
365
+ );
366
+ if ( $token )
367
+ $defaults[ 'oauth_token' ] = $token->key;
368
+
369
+ $parameters = array_merge( $defaults, $parameters );
370
+ ksort( $parameters );
371
+
372
+ return new OAuthRequest( $http_method, $http_url, $parameters );
373
+ }
374
+
375
+ public function set_parameter( $name, $value, $allow_duplicates = true )
376
+ {
377
+ if ( $allow_duplicates && isset( $this->parameters[ $name ] ) ) {
378
+ // We have already added parameter(s) with this name, so add to the list
379
+ if ( is_scalar( $this->parameters[ $name ] ) ) {
380
+ // This is the first duplicate, so transform scalar (string)
381
+ // into an array so we can add the duplicates
382
+ $this->parameters[ $name ] = array( $this->parameters[ $name ] );
383
+ }
384
+
385
+ $this->parameters[ $name ][ ] = $value;
386
+ } else {
387
+ $this->parameters[ $name ] = $value;
388
+ }
389
+ }
390
+
391
+ public function get_parameter( $name )
392
+ {
393
+ return isset( $this->parameters[ $name ] ) ? $this->parameters[ $name ] : null;
394
+ }
395
+
396
+ public function get_parameters()
397
+ {
398
+ return $this->parameters;
399
+ }
400
+
401
+ public function unset_parameter( $name )
402
+ {
403
+ unset( $this->parameters[ $name ] );
404
+ }
405
+
406
+ /**
407
+ * The request parameters, sorted and concatenated into a normalized string.
408
+ * @return string
409
+ */
410
+ public function get_signable_parameters()
411
+ {
412
+ // Grab all parameters
413
+ $params = $this->parameters;
414
+ ksort( $params );
415
+ // Remove oauth_signature if present
416
+ // Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
417
+ if ( isset( $params[ 'oauth_signature' ] ) ) {
418
+ unset( $params[ 'oauth_signature' ] );
419
+ }
420
+ foreach ( $params as $key => $value ) {
421
+ $res[ ] = $key . "=" . $value;
422
+ }
423
+
424
+ return implode( '&', $res );
425
+ //return OAuthUtil::build_http_query($params);
426
+ }
427
+
428
+ /**
429
+ * Returns the base string of this request
430
+ *
431
+ * The base string defined as the method, the url
432
+ * and the parameters (normalized), each urlencoded
433
+ * and the concated with &.
434
+ */
435
+ public function get_signature_base_string()
436
+ {
437
+ $parts = array(
438
+ $this->get_normalized_http_method(),
439
+ $this->get_normalized_http_url(),
440
+ $this->get_signable_parameters()
441
+ );
442
+
443
+ $parts = OAuthUtil::urlencode_rfc3986( $parts );
444
+
445
+ return implode( '&', $parts );
446
+ }
447
+
448
+ /**
449
+ * just uppercases the http method
450
+ */
451
+ public function get_normalized_http_method()
452
+ {
453
+ return strtoupper( $this->http_method );
454
+ }
455
+
456
+ /**
457
+ * parses the url and rebuilds it to be
458
+ * scheme://host/path
459
+ */
460
+ public function get_normalized_http_url()
461
+ {
462
+ $parts = parse_url( $this->http_url );
463
+
464
+ $scheme = ( isset( $parts[ 'scheme' ] ) ) ? $parts[ 'scheme' ] : 'http';
465
+ $port = ( isset( $parts[ 'port' ] ) ) ? $parts[ 'port' ] : ( ( $scheme == 'https' ) ? '443' : '80' );
466
+ $host = ( isset( $parts[ 'host' ] ) ) ? $parts[ 'host' ] : '';
467
+ $path = ( isset( $parts[ 'path' ] ) ) ? $parts[ 'path' ] : '';
468
+
469
+ if ( ( $scheme == 'https' && $port != '443' )
470
+ || ( $scheme == 'http' && $port != '80' )
471
+ ) {
472
+ $host = "$host:$port";
473
+ }
474
+
475
+ return "$scheme://$host$path";
476
+ }
477
+
478
+ /**
479
+ * builds a url usable for a GET request
480
+ */
481
+ public function to_url()
482
+ {
483
+ $post_data = $this->to_postdata();
484
+ $out = $this->get_normalized_http_url();
485
+ if ( $post_data ) {
486
+ $out .= '?' . $post_data;
487
+ }
488
+
489
+ return $out;
490
+ }
491
+
492
+ /**
493
+ * builds the data one would send in a POST request
494
+ */
495
+ public function to_postdata()
496
+ {
497
+ return OAuthUtil::build_http_query( $this->parameters );
498
+ }
499
+
500
+ /**
501
+ * builds the Authorization: header
502
+ */
503
+ public function to_header( $realm = null )
504
+ {
505
+ $first = true;
506
+ if ( $realm ) {
507
+ $out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986( $realm ) . '"';
508
+ $first = false;
509
+ } else
510
+ $out = 'Authorization: OAuth';
511
+
512
+ $total = array();
513
+ foreach ( $this->parameters as $k => $v ) {
514
+ if ( substr( $k, 0, 5 ) != "oauth" ) continue;
515
+ if ( is_array( $v ) ) {
516
+ throw new OAuthException( 'Arrays not supported in headers' );
517
+ }
518
+ $out .= ( $first ) ? ' ' : ',';
519
+ $out .= OAuthUtil::urlencode_rfc3986( $k ) .
520
+ '="' .
521
+ OAuthUtil::urlencode_rfc3986( $v ) .
522
+ '"';
523
+ $first = false;
524
+ }
525
+
526
+ return $out;
527
+ }
528
+
529
+ public function __toString()
530
+ {
531
+ return $this->to_url();
532
+ }
533
+
534
+
535
+ public function sign_request( $signature_method, $consumer, $token )
536
+ {
537
+
538
+ $empty = false;
539
+ $msg = array();
540
+ if ( $token->key == null ) {
541
+ $msg[ ] = 'Token key';
542
+ }
543
+ if ( $token->secret == null ) {
544
+ $msg[ ] = 'Token secret';
545
+ }
546
+ if ( $consumer->key == null ) {
547
+
548
+ $msg[ ] = 'Consumer key';
549
+ }
550
+ if ( $consumer->secret == null ) {
551
+
552
+ $msg[ ] = 'Consumer secret';
553
+ }
554
+ if ( $this->http_url == null ) {
555
+
556
+ $msg[ ] = 'Endpoint';
557
+ }
558
+ if ( $this->http_method == null ) {
559
+
560
+ $msg[ ] = 'HTTP method';
561
+ }
562
+ if ( count( $msg ) ) {
563
+ throw new OAuthException( 'Enter valid ' . implode( ',', $msg ) );
564
+ }
565
+ $this->set_parameter(
566
+ "oauth_signature_method",
567
+ $signature_method->get_name(),
568
+ false );
569
+
570
+ $signature = $this->build_signature( $signature_method, $consumer, $token );
571
+ $this->set_parameter( "oauth_signature", $signature, false );
572
+
573
+ }
574
+
575
+ public function build_signature( $signature_method, $consumer, $token )
576
+ {
577
+ $signature = $signature_method->build_signature( $this, $consumer, $token );
578
+
579
+ return $signature;
580
+ }
581
+
582
+ /**
583
+ * util function: current timestamp
584
+ */
585
+ private static function generate_timestamp()
586
+ {
587
+ return time();
588
+ }
589
+
590
+ /**
591
+ * util function: current nonce
592
+ */
593
+ private static function generate_nonce()
594
+ {
595
+ $mt = microtime();
596
+ $rand = mt_rand();
597
+
598
+ return md5( $mt . $rand ); // md5s look nicer than numbers
599
+ }
600
+ }
601
+
602
+ class OAuthServer
603
+ {
604
+ protected $timestamp_threshold = 300; // in seconds, five minutes
605
+ protected $version = '1.0'; // hi blaine
606
+ protected $signature_methods = array();
607
+
608
+ protected $data_store;
609
+
610
+ function __construct( $data_store )
611
+ {
612
+ $this->data_store = $data_store;
613
+ }
614
+
615
+ public function add_signature_method( $signature_method )
616
+ {
617
+ $this->signature_methods[ $signature_method->get_name() ] =
618
+ $signature_method;
619
+ }
620
+
621
+ // high level functions
622
+
623
+ /**
624
+ * process a request_token request
625
+ * returns the request token on success
626
+ */
627
+ public function fetch_request_token( &$request )
628
+ {
629
+ $this->get_version( $request );
630
+
631
+ $consumer = $this->get_consumer( $request );
632
+
633
+ // no token required for the initial token request
634
+ $token = null;
635
+
636
+ $this->check_signature( $request, $consumer, $token );
637
+
638
+ // Rev A change
639
+ $callback = $request->get_parameter( 'oauth_callback' );
640
+ $new_token = $this->data_store->new_request_token( $consumer, $callback );
641
+
642
+ return $new_token;
643
+ }
644
+
645
+ /**
646
+ * process an access_token request
647
+ * returns the access token on success
648
+ */
649
+ public function fetch_access_token( &$request )
650
+ {
651
+ $this->get_version( $request );
652
+
653
+ $consumer = $this->get_consumer( $request );
654
+
655
+ // requires authorized request token
656
+ $token = $this->get_token( $request, $consumer, "request" );
657
+
658
+ $this->check_signature( $request, $consumer, $token );
659
+
660
+ // Rev A change
661
+ $verifier = $request->get_parameter( 'oauth_verifier' );
662
+ $new_token = $this->data_store->new_access_token( $token, $consumer, $verifier );
663
+
664
+ return $new_token;
665
+ }
666
+
667
+ /**
668
+ * verify an api call, checks all the parameters
669
+ */
670
+ public function verify_request( &$request )
671
+ {
672
+ $this->get_version( $request );
673
+ $consumer = $this->get_consumer( $request );
674
+ $token = $this->get_token( $request, $consumer, "access" );
675
+ $this->check_signature( $request, $consumer, $token );
676
+
677
+ return array( $consumer, $token );
678
+ }
679
+
680
+ // Internals from here
681
+ /**
682
+ * version 1
683
+ */
684
+ private function get_version( &$request )
685
+ {
686
+ $version = $request->get_parameter( "oauth_version" );
687
+ if ( !$version ) {
688
+ // Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
689
+ // Chapter 7.0 ("Accessing Protected Ressources")
690
+ $version = '1.0';
691
+ }
692
+ if ( $version !== $this->version ) {
693
+ throw new OAuthException( "OAuth version '$version' not supported" );
694
+ }
695
+
696
+ return $version;
697
+ }
698
+
699
+ /**
700
+ * figure out the signature with some defaults
701
+ */
702
+ private function get_signature_method( $request )
703
+ {
704
+ $signature_method = $request instanceof OAuthRequest
705
+ ? $request->get_parameter( "oauth_signature_method" )
706
+ : null;
707
+
708
+ if ( !$signature_method ) {
709
+ // According to chapter 7 ("Accessing Protected Ressources") the signature-method
710
+ // parameter is required, and we can't just fallback to PLAINTEXT
711
+ throw new OAuthException( 'No signature method parameter. This parameter is required' );
712
+ }
713
+
714
+ if ( !in_array( $signature_method,
715
+ array_keys( $this->signature_methods ) )
716
+ ) {
717
+ throw new OAuthException(
718
+ "Signature method '$signature_method' not supported " .
719
+ "try one of the following: " .
720
+ implode( ", ", array_keys( $this->signature_methods ) )
721
+ );
722
+ }
723
+
724
+ return $this->signature_methods[ $signature_method ];
725
+ }
726
+
727
+ /**
728
+ * try to find the consumer for the provided request's consumer key
729
+ */
730
+ private function get_consumer( $request )
731
+ {
732
+ $consumer_key = $request instanceof OAuthRequest
733
+ ? $request->get_parameter( "oauth_consumer_key" )
734
+ : null;
735
+
736
+ if ( !$consumer_key ) {
737
+ throw new OAuthException( "Invalid consumer key" );
738
+ }
739
+
740
+ $consumer = $this->data_store->lookup_consumer( $consumer_key );
741
+ if ( !$consumer ) {
742
+ throw new OAuthException( "Invalid consumer" );
743
+ }
744
+
745
+ return $consumer;
746
+ }
747
+
748
+ /**
749
+ * try to find the token for the provided request's token key
750
+ */
751
+ private function get_token( $request, $consumer, $token_type = "access" )
752
+ {
753
+ $token_field = $request instanceof OAuthRequest
754
+ ? $request->get_parameter( 'oauth_token' )
755
+ : null;
756
+
757
+ $token = $this->data_store->lookup_token(
758
+ $consumer, $token_type, $token_field
759
+ );
760
+ if ( !$token ) {
761
+ throw new OAuthException( "Invalid $token_type token: $token_field" );
762
+ }
763
+
764
+ return $token;
765
+ }
766
+
767
+ /**
768
+ * all-in-one function to check the signature on a request
769
+ * should guess the signature method appropriately
770
+ */
771
+ private function check_signature( $request, $consumer, $token )
772
+ {
773
+ // this should probably be in a different method
774
+ $timestamp = $request instanceof OAuthRequest
775
+ ? $request->get_parameter( 'oauth_timestamp' )
776
+ : null;
777
+ $nonce = $request instanceof OAuthRequest
778
+ ? $request->get_parameter( 'oauth_nonce' )
779
+ : null;
780
+
781
+ $this->check_timestamp( $timestamp );
782
+ $this->check_nonce( $consumer, $token, $nonce, $timestamp );
783
+
784
+ $signature_method = $this->get_signature_method( $request );
785
+
786
+ $signature = $request->get_parameter( 'oauth_signature' );
787
+ $valid_sig = $signature_method->check_signature(
788
+ $request,
789
+ $consumer,
790
+ $token,
791
+ $signature
792
+ );
793
+
794
+ if ( !$valid_sig ) {
795
+ throw new OAuthException( "Invalid signature" );
796
+ }
797
+ }
798
+
799
+ /**
800
+ * check that the timestamp is new enough
801
+ */
802
+ private function check_timestamp( $timestamp )
803
+ {
804
+ if ( !$timestamp )
805
+ throw new OAuthException(
806
+ 'Missing timestamp parameter. The parameter is required'
807
+ );
808
+
809
+ // verify that timestamp is recentish
810
+ $now = time();
811
+ if ( abs( $now - $timestamp ) > $this->timestamp_threshold ) {
812
+ throw new OAuthException(
813
+ "Expired timestamp, yours $timestamp, ours $now"
814
+ );
815
+ }
816
+ }
817
+
818
+ /**
819
+ * check that the nonce is not repeated
820
+ */
821
+ private function check_nonce( $consumer, $token, $nonce, $timestamp )
822
+ {
823
+ if ( !$nonce )
824
+ throw new OAuthException(
825
+ 'Missing nonce parameter. The parameter is required'
826
+ );
827
+
828
+ // verify that the nonce is uniqueish
829
+ $found = $this->data_store->lookup_nonce(
830
+ $consumer,
831
+ $token,
832
+ $nonce,
833
+ $timestamp
834
+ );
835
+ if ( $found ) {
836
+ throw new OAuthException( "Nonce already used: $nonce" );
837
+ }
838
+ }
839
+
840
+ }
841
+
842
+ class OAuthDataStore
843
+ {
844
+ function lookup_consumer( $consumer_key )
845
+ {
846
+ // implement me
847
+ }
848
+
849
+ function lookup_token( $consumer, $token_type, $token )
850
+ {
851
+ // implement me
852
+ }
853
+
854
+ function lookup_nonce( $consumer, $token, $nonce, $timestamp )
855
+ {
856
+ // implement me
857
+ }
858
+
859
+ function new_request_token( $consumer, $callback = null )
860
+ {
861
+ // return a new token attached to this consumer
862
+ }
863
+
864
+ function new_access_token( $token, $consumer, $verifier = null )
865
+ {
866
+ // return a new access token attached to this consumer
867
+ // for the user associated with this token if the request token
868
+ // is authorized
869
+ // should also invalidate the request token
870
+ }
871
+
872
+ }
873
+
874
+ class OAuthUtil
875
+ {
876
+ public static function urlencode_rfc3986( $input )
877
+ {
878
+ if ( is_array( $input ) ) {
879
+ return array_map( array( 'OAuthUtil', 'urlencode_rfc3986' ), $input );
880
+ } else if ( is_scalar( $input ) ) {
881
+ $tmp1 = str_replace( '%7E', '~', rawurlencode( $input ) );
882
+ $tmp2 = str_replace( ".", "%2E", $tmp1 );
883
+ $tmp3 = str_replace( "*", "%2A", $tmp2 );
884
+ $tmp4 = str_replace( '+', ' ', $tmp3 );
885
+ $tmp = str_replace( "-", "%2D", $tmp4 );
886
+
887
+ return $tmp;
888
+ /*$tmp1=str_replace('%7E', '~', rawurlencode($input));
889
+ $tmp2= str_replace(".","%2E",$tmp1);
890
+
891
+
892
+ return $tmp;*/
893
+ } else {
894
+ return '';
895
+ }
896
+ }
897
+
898
+ public static function parseQueryString( $str )
899
+ {
900
+ $op = array();
901
+ $pairs = explode( "&", $str );
902
+ foreach ( $pairs as $pair ) {
903
+ list( $k, $v ) = array_map( "urldecode", explode( "=", $pair ) );
904
+ $op[ $k ] = $v;
905
+ }
906
+
907
+ return $op;
908
+ }
909
+
910
+ //parses string to associative array -modified for PayPal Signature
911
+
912
+
913
+ // This decode function isn't taking into consideration the above
914
+ // modifications to the encoding process. However, this method doesn't
915
+ // seem to be used anywhere so leaving it as is.
916
+ public static function urldecode_rfc3986( $string )
917
+ {
918
+ return urldecode( $string );
919
+ }
920
+
921
+ // Utility function for turning the Authorization: header into
922
+ // parameters, has to do some unescaping
923
+ // Can filter out any non-oauth parameters if needed (default behaviour)
924
+ // May 28th, 2010 - method updated to tjerk.meesters for a speed improvement.
925
+ // see http://code.google.com/p/oauth/issues/detail?id=163
926
+ public static function split_header( $header, $only_allow_oauth_parameters = true )
927
+ {
928
+ $params = array();
929
+ if ( preg_match_all( '/(' . ( $only_allow_oauth_parameters ? 'oauth_' : '' ) . '[a-z_-]*)=(:?"([^"]*)"|([^,]*))/', $header, $matches ) ) {
930
+ foreach ( $matches[ 1 ] as $i => $h ) {
931
+ $params[ $h ] = OAuthUtil::urldecode_rfc3986( empty( $matches[ 3 ][ $i ] ) ? $matches[ 4 ][ $i ] : $matches[ 3 ][ $i ] );
932
+ }
933
+ if ( isset( $params[ 'realm' ] ) ) {
934
+ unset( $params[ 'realm' ] );
935
+ }
936
+ }
937
+
938
+ return $params;
939
+ }
940
+
941
+ // helper to try to sort out headers for people who aren't running apache
942
+ public static function get_headers()
943
+ {
944
+ if ( function_exists( 'apache_request_headers' ) ) {
945
+ // we need this to get the actual Authorization: header
946
+ // because apache tends to tell us it doesn't exist
947
+ $headers = apache_request_headers();
948
+
949
+ // sanitize the output of apache_request_headers because
950
+ // we always want the keys to be Cased-Like-This and arh()
951
+ // returns the headers in the same case as they are in the
952
+ // request
953
+ $out = array();
954
+ foreach ( $headers AS $key => $value ) {
955
+ $key = str_replace(
956
+ " ",
957
+ "-",
958
+ ucwords( strtolower( str_replace( "-", " ", $key ) ) )
959
+ );
960
+ $out[ $key ] = $value;
961
+ }
962
+ } else {
963
+ // otherwise we don't have apache and are just going to have to hope
964
+ // that $_SERVER actually contains what we need
965
+ $out = array();
966
+ if ( isset( $_SERVER[ 'CONTENT_TYPE' ] ) )
967
+ $out[ 'Content-Type' ] = $_SERVER[ 'CONTENT_TYPE' ];
968
+ if ( isset( $_ENV[ 'CONTENT_TYPE' ] ) )
969
+ $out[ 'Content-Type' ] = $_ENV[ 'CONTENT_TYPE' ];
970
+
971
+ foreach ( $_SERVER as $key => $value ) {
972
+ if ( substr( $key, 0, 5 ) == "HTTP_" ) {
973
+ // this is chaos, basically it is just there to capitalize the first
974
+ // letter of every word that is not an initial HTTP and strip HTTP
975
+ // code from przemek
976
+ $key = str_replace(
977
+ " ",
978
+ "-",
979
+ ucwords( strtolower( str_replace( "_", " ", substr( $key, 5 ) ) ) )
980
+ );
981
+ $out[ $key ] = $value;
982
+ }
983
+ }
984
+ }
985
+
986
+ return $out;
987
+ }
988
+
989
+ // This function takes a input like a=b&a=c&d=e and returns the parsed
990
+ // parameters like this
991
+ // array('a' => array('b','c'), 'd' => 'e')
992
+ public static function parse_parameters( $input )
993
+ {
994
+ if ( !isset( $input ) || !$input ) return array();
995
+
996
+ $pairs = explode( '&', $input );
997
+
998
+ $parsed_parameters = array();
999
+ foreach ( $pairs as $pair ) {
1000
+ $split = explode( '=', $pair, 2 );
1001
+ $parameter = OAuthUtil::urldecode_rfc3986( $split[ 0 ] );
1002
+ $value = isset( $split[ 1 ] ) ? OAuthUtil::urldecode_rfc3986( $split[ 1 ] ) : '';
1003
+
1004
+ if ( isset( $parsed_parameters[ $parameter ] ) ) {
1005
+ // We have already recieved parameter(s) with this name, so add to the list
1006
+ // of parameters with this name
1007
+
1008
+ if ( is_scalar( $parsed_parameters[ $parameter ] ) ) {
1009
+ // This is the first duplicate, so transform scalar (string) into an array
1010
+ // so we can add the duplicates
1011
+ $parsed_parameters[ $parameter ] = array( $parsed_parameters[ $parameter ] );
1012
+ }
1013
+
1014
+ $parsed_parameters[ $parameter ][ ] = $value;
1015
+ } else {
1016
+ $parsed_parameters[ $parameter ] = $value;
1017
+ }
1018
+ }
1019
+
1020
+ return $parsed_parameters;
1021
+ }
1022
+
1023
+ public static function build_http_query( $params )
1024
+ {
1025
+ if ( !$params ) return '';
1026
+
1027
+ // Urlencode both keys and values
1028
+ $keys = OAuthUtil::urlencode_rfc3986( array_keys( $params ) );
1029
+ $values = OAuthUtil::urlencode_rfc3986( array_values( $params ) );
1030
+ $params = array_combine( $keys, $values );
1031
+
1032
+ // Parameters are sorted by name, using lexicographical byte value ordering.
1033
+ // Ref: Spec: 9.1.1 (1)
1034
+ uksort( $params, 'strcmp' );
1035
+
1036
+ $pairs = array();
1037
+ foreach ( $params as $parameter => $value ) {
1038
+ if ( is_array( $value ) ) {
1039
+ // If two or more parameters share the same name, they are sorted by their value
1040
+ // Ref: Spec: 9.1.1 (1)
1041
+ // June 12th, 2010 - changed to sort because of issue 164 by hidetaka
1042
+ sort( $value, SORT_STRING );
1043
+ foreach ( $value as $duplicate_value ) {
1044
+ $pairs[ ] = $parameter . '=' . $duplicate_value;
1045
+ }
1046
+ } else {
1047
+ $pairs[ ] = $parameter . '=' . $value;
1048
+ }
1049
+ }
1050
+
1051
+ // For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
1052
+ // Each name-value pair is separated by an '&' character (ASCII code 38)
1053
+ return implode( '&', $pairs );
1054
+ }
1055
+ }
1056
+
1057
+ ?>
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/cacert.pem ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Verisign Class 3 Public Primary Certification Authority
2
+ =======================================================
3
+ -----BEGIN CERTIFICATE-----
4
+ MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkGA1UEBhMCVVMx
5
+ FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5
6
+ IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVow
7
+ XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz
8
+ IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
9
+ A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94
10
+ f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol
11
+ hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBAgUAA4GBALtMEivPLCYA
12
+ TxQT3ab7/AoRhIzzKBxnki98tsX63/Dolbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59Ah
13
+ WM1pF+NEHJwZRDmJXNycAA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2Omuf
14
+ Tqj/ZA1k
15
+ -----END CERTIFICATE-----
16
+
17
+ Verisign Class 3 Public Primary Certification Authority - G2
18
+ ============================================================
19
+ -----BEGIN CERTIFICATE-----
20
+ MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJBgNVBAYTAlVT
21
+ MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
22
+ eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
23
+ biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
24
+ dCBOZXR3b3JrMB4XDTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVT
25
+ MRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
26
+ eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2ln
27
+ biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVz
28
+ dCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCO
29
+ FoUgRm1HP9SFIIThbbP4pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71
30
+ lSk8UOg013gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwIDAQAB
31
+ MA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSkU01UbSuvDV1Ai2TT
32
+ 1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7iF6YM40AIOw7n60RzKprxaZLvcRTD
33
+ Oaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpYoJ2daZH9
34
+ -----END CERTIFICATE-----
35
+
36
+
37
+ Verisign Class 3 Public Primary Certification Authority - G3
38
+ ============================================================
39
+ -----BEGIN CERTIFICATE-----
40
+ MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
41
+ UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
42
+ cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
43
+ IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
44
+ dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
45
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
46
+ dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
47
+ cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg
48
+ Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
49
+ ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1
50
+ EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc
51
+ cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw
52
+ EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj
53
+ 055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
54
+ ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f
55
+ j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
56
+ /Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0
57
+ xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa
58
+ t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
59
+ -----END CERTIFICATE-----
60
+
61
+ Verisign Class 4 Public Primary Certification Authority - G3
62
+ ============================================================
63
+ -----BEGIN CERTIFICATE-----
64
+ MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
65
+ UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
66
+ cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
67
+ IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
68
+ dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
69
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
70
+ dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
71
+ cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDQgUHVibGljIFByaW1hcnkg
72
+ Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
73
+ ggEBAK3LpRFpxlmr8Y+1GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaS
74
+ tBO3IFsJ+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0GbdU6LM
75
+ 8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLmNxdLMEYH5IBtptiW
76
+ Lugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XYufTsgsbSPZUd5cBPhMnZo0QoBmrX
77
+ Razwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
78
+ j/ola09b5KROJ1WrIhVZPMq1CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXtt
79
+ mhwwjIDLk5Mqg6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
80
+ fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c2NU8Qh0XwRJd
81
+ RTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/bLvSHgCwIe34QWKCudiyxLtG
82
+ UPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
83
+ -----END CERTIFICATE-----
84
+ VeriSign Class 3 Public Primary Certification Authority - G5
85
+ ============================================================
86
+ -----BEGIN CERTIFICATE-----
87
+ MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
88
+ BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
89
+ ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
90
+ IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp
91
+ ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB
92
+ yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln
93
+ biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh
94
+ dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt
95
+ YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
96
+ ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz
97
+ j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD
98
+ Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
99
+ Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r
100
+ fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/
101
+ BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv
102
+ Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
103
+ aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
104
+ SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+
105
+ X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE
106
+ KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC
107
+ Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE
108
+ ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
109
+ -----END CERTIFICATE-----
110
+ VeriSign Universal Root Certification Authority
111
+ ===============================================
112
+ -----BEGIN CERTIFICATE-----
113
+ MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE
114
+ BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
115
+ ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
116
+ IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u
117
+ IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV
118
+ UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
119
+ cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
120
+ IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0
121
+ aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj
122
+ 1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP
123
+ MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72
124
+ 9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I
125
+ AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR
126
+ tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G
127
+ CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O
128
+ a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
129
+ DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3
130
+ Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx
131
+ Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx
132
+ P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P
133
+ wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4
134
+ mJO37M2CYfE45k+XmCpajQ==
135
+ -----END CERTIFICATE-----
136
+
137
+ VeriSign Class 3 Public Primary Certification Authority - G4
138
+ ============================================================
139
+ -----BEGIN CERTIFICATE-----
140
+ MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC
141
+ VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3
142
+ b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz
143
+ ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj
144
+ YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL
145
+ MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU
146
+ cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo
147
+ b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5
148
+ IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8
149
+ Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz
150
+ rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB
151
+ /zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw
152
+ HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u
153
+ Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD
154
+ A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx
155
+ AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
156
+ -----END CERTIFICATE-----
157
+ Verisign Class 3 Public Primary Certification Authority
158
+ =======================================================
159
+ -----BEGIN CERTIFICATE-----
160
+ MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkGA1UEBhMCVVMx
161
+ FzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmltYXJ5
162
+ IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVow
163
+ XzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAz
164
+ IFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUA
165
+ A4GNADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhEBarsAx94
166
+ f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/isI19wKTakyYbnsZogy1Ol
167
+ hec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABByUqkFFBky
168
+ CEHwxWsKzH4PIRnN5GfcX6kb5sroc50i2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWX
169
+ bj9T/UWZYB2oK0z5XqcJ2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/
170
+ D/xwzoiQ
171
+ -----END CERTIFICATE-----
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/exceptions/PPConfigurationException.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class PPConfigurationException extends Exception
3
+ {
4
+
5
+ public function __construct( $message = null, $code = 0 )
6
+ {
7
+ parent::__construct( $message, $code );
8
+ }
9
+ }
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/exceptions/PPConnectionException.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class PPConnectionException extends Exception
3
+ {
4
+ /**
5
+ * The url that was being connected to when the exception occured
6
+ * @var string
7
+ */
8
+ private $url;
9
+
10
+ public function __construct( $url, $message, $code = 0 )
11
+ {
12
+ parent::__construct( $message, $code );
13
+ $this->url = $url;
14
+ }
15
+
16
+ public function getUrl()
17
+ {
18
+ return $this->url;
19
+ }
20
+ }
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/exceptions/PPInvalidCredentialException.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ class PPInvalidCredentialException extends Exception
5
+ {
6
+
7
+ public function __construct( $message = null, $code = 0 )
8
+ {
9
+ parent::__construct( $message, $code );
10
+ }
11
+
12
+ public function errorMessage()
13
+ {
14
+ $errorMsg = 'Error on line ' . $this->getLine() . ' in ' . $this->getFile()
15
+ . ': <b>' . $this->getMessage() . '</b>';
16
+
17
+ return $errorMsg;
18
+ }
19
+
20
+ }
21
+
22
+ ?>
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/exceptions/PPMissingCredentialException.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ class PPMissingCredentialException extends Exception
5
+ {
6
+
7
+ public function __construct( $message = null, $code = 0 )
8
+ {
9
+ parent::__construct( $message, $code );
10
+ }
11
+
12
+ public function errorMessage()
13
+ {
14
+ $errorMsg = 'Error on line ' . $this->getLine() . ' in ' . $this->getFile()
15
+ . ': <b>' . $this->getMessage() . '</b>';
16
+
17
+ return $errorMsg;
18
+ }
19
+
20
+ }
21
+
22
+ ?>
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/exceptions/PPTransformerException.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class PPTransformerException extends Exception
3
+ {
4
+
5
+ public function __construct( $message = null, $code = 0 )
6
+ {
7
+ parent::__construct( $message, $code );
8
+ }
9
+
10
+ public function errorMessage()
11
+ {
12
+ $errorMsg = 'Error on line ' . $this->getLine() . ' in ' . $this->getFile()
13
+ . ': <b>' . $this->getMessage() . '</b>';
14
+
15
+ return $errorMsg;
16
+ }
17
+
18
+ }
19
+
20
+ ?>
trunk/WCVendors/classes/gateways/PayPal_Masspay/api/lib/services/PayPalAPIInterfaceService/PayPalAPIInterfaceService.php ADDED
@@ -0,0 +1,23178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Stub objects for PayPalAPIInterfaceService
4
+ * Auto generated code
5
+ *
6
+ */
7
+ require_once( 'PPUtils.php' );
8
+ /**
9
+ * On requests, you must set the currencyID attribute to one of
10
+ * the three-character currency codes for any of the supported
11
+ * PayPal currencies. Limitations: Must not exceed $10,000 USD
12
+ * in any currency. No currency symbol. Decimal separator must
13
+ * be a period (.), and the thousands separator must be a comma
14
+ * (,).
15
+ */
16
+ class BasicAmountType
17
+ {
18
+
19
+ /**
20
+ *
21
+ * @access public
22
+ * @var CurrencyCodeType
23
+ */
24
+ public $currencyID;
25
+
26
+ /**
27
+ *
28
+ * @access public
29
+ * @var string
30
+ */
31
+ public $value;
32
+
33
+ /**
34
+ * Constructor with arguments
35
+ */
36
+ public function __construct( $currencyID = null, $value = null )
37
+ {
38
+ $this->currencyID = $currencyID;
39
+ $this->value = $value;
40
+ }
41
+
42
+
43
+ public function toXMLString()
44
+ {
45
+ $str = '';
46
+ $str .= $this->getAttributeAsXml();
47
+ $str .= '>';
48
+ if ( $this->value != null ) {
49
+ $str .= PPUtils::escapeInvalidXmlCharsRegex( $this->value );
50
+ }
51
+
52
+ return $str;
53
+ }
54
+
55
+
56
+ private function getAttributeAsXml()
57
+ {
58
+ $str = '';
59
+ if ( $this->currencyID != null ) {
60
+ $str .= ' currencyID = "' . PPUtils::escapeInvalidXmlCharsRegex( $this->currencyID ) . '"';
61
+ }
62
+
63
+ return $str;
64
+ }
65
+
66
+ public function init( $arr = null )
67
+ {
68
+ if ( $arr != null ) {
69
+ foreach ( $arr as $arry ) {
70
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'currencyid' ) {
71
+ $this->currencyID = $arry[ "text" ];
72
+ }
73
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'value' ) {
74
+ $this->value = $arry[ "text" ];
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+
81
+
82
+ /**
83
+ *
84
+ */
85
+ class MeasureType
86
+ {
87
+
88
+ /**
89
+ *
90
+ * @access public
91
+ * @var string
92
+ */
93
+ public $unit;
94
+
95
+ /**
96
+ *
97
+ * @access public
98
+ * @var double
99
+ */
100
+ public $value;
101
+
102
+ /**
103
+ * Constructor with arguments
104
+ */
105
+ public function __construct( $unit = null, $value = null )
106
+ {
107
+ $this->unit = $unit;
108
+ $this->value = $value;
109
+ }
110
+
111
+
112
+ public function toXMLString()
113
+ {
114
+ $str = '';
115
+ $str .= $this->getAttributeAsXml();
116
+ $str .= '>';
117
+ if ( $this->value != null ) {
118
+ $str .= PPUtils::escapeInvalidXmlCharsRegex( $this->value );
119
+ }
120
+
121
+ return $str;
122
+ }
123
+
124
+
125
+ private function getAttributeAsXml()
126
+ {
127
+ $str = '';
128
+ if ( $this->unit != null ) {
129
+ $str .= ' unit = "' . PPUtils::escapeInvalidXmlCharsRegex( $this->unit ) . '"';
130
+ }
131
+
132
+ return $str;
133
+ }
134
+
135
+ public function init( $arr = null )
136
+ {
137
+ if ( $arr != null ) {
138
+ foreach ( $arr as $arry ) {
139
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'unit' ) {
140
+ $this->unit = $arry[ "text" ];
141
+ }
142
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'value' ) {
143
+ $this->value = $arry[ "text" ];
144
+ }
145
+ }
146
+ }
147
+ }
148
+ }
149
+
150
+
151
+ /**
152
+ * Value of the application-specific error parameter.
153
+ */
154
+ class ErrorParameterType
155
+ {
156
+
157
+ /**
158
+ * Value of the application-specific error parameter.
159
+ * @access public
160
+ * @var string
161
+ */
162
+ public $Value;
163
+
164
+
165
+ public function init( $arr = null )
166
+ {
167
+ if ( $arr != null ) {
168
+ foreach ( $arr as $arry ) {
169
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'value' ) {
170
+ $this->Value = $arry[ "text" ];
171
+ }
172
+ }
173
+ }
174
+ }
175
+ }
176
+
177
+
178
+ /**
179
+ * Error code can be used by a receiving application to
180
+ * debugging a response message. These codes will need to be
181
+ * uniquely defined for each application.
182
+ */
183
+ class ErrorType
184
+ {
185
+
186
+ /**
187
+ *
188
+ * @access public
189
+ * @var string
190
+ */
191
+ public $ShortMessage;
192
+
193
+ /**
194
+ *
195
+ * @access public
196
+ * @var string
197
+ */
198
+ public $LongMessage;
199
+
200
+ /**
201
+ * Error code can be used by a receiving application to
202
+ * debugging a response message. These codes will need to be
203
+ * uniquely defined for each application.
204
+ * @access public
205
+ * @var string
206
+ */
207
+ public $ErrorCode;
208
+
209
+ /**
210
+ * SeverityCode indicates whether the error is an application
211
+ * level error or if it is informational error, i.e., warning.
212
+ *
213
+ * @access public
214
+ * @var SeverityCodeType
215
+ */
216
+ public $SeverityCode;
217
+
218
+ /**
219
+ * This optional element may carry additional
220
+ * application-specific error variables that indicate specific
221
+ * information about the error condition particularly in the
222
+ * cases where there are multiple instances of the ErrorType
223
+ * which require additional context.
224
+ * @array
225
+ * @access public
226
+ * @var ErrorParameterType
227
+ */
228
+ public $ErrorParameters;
229
+
230
+
231
+ public function init( $arr = null )
232
+ {
233
+ if ( $arr != null ) {
234
+ foreach ( $arr as $arry ) {
235
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'shortmessage' ) {
236
+ $this->ShortMessage = $arry[ "text" ];
237
+ }
238
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'longmessage' ) {
239
+ $this->LongMessage = $arry[ "text" ];
240
+ }
241
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'errorcode' ) {
242
+ $this->ErrorCode = $arry[ "text" ];
243
+ }
244
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'severitycode' ) {
245
+ $this->SeverityCode = $arry[ "text" ];
246
+ }
247
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) ) {
248
+ $i = 0;
249
+ while ( true ) {
250
+ if ( $arry[ "name" ] == "errorparameters[$i]" ) {
251
+ $this->ErrorParameters[ $i ] = new ErrorParameterType();
252
+ $this->ErrorParameters[ $i ]->init( $arry[ "children" ] );
253
+ } else {
254
+ break;
255
+ }
256
+ $i++;
257
+ }
258
+ }
259
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) && ( $arry[ "name" ] == "errorparameters" ) ) {
260
+ $this->ErrorParameters = new ErrorParameterType();
261
+ $this->ErrorParameters->init( $arry[ "children" ] );
262
+ }
263
+ }
264
+ }
265
+ }
266
+ }
267
+
268
+
269
+ /**
270
+ * Base type definition of request payload that can carry any
271
+ * type of payload content with optional versioning information
272
+ * and detail level requirements.
273
+ */
274
+ class AbstractRequestType
275
+ {
276
+
277
+ /**
278
+ * This specifies the required detail level that is needed by a
279
+ * client application pertaining to a particular data component
280
+ * (e.g., Item, Transaction, etc.). The detail level is
281
+ * specified in the DetailLevelCodeType which has all the
282
+ * enumerated values of the detail level for each component.
283
+ * @array
284
+ * @access public
285
+ * @var DetailLevelCodeType
286
+ */
287
+ public $DetailLevel;
288
+
289
+ /**
290
+ * This should be the standard RFC 3066 language identification
291
+ * tag, e.g., en_US.
292
+ * @access public
293
+ * @var string
294
+ */
295
+ public $ErrorLanguage;
296
+
297
+ /**
298
+ * This refers to the version of the request payload schema.
299
+ * @access public
300
+ * @var string
301
+ */
302
+ public $Version;
303
+
304
+
305
+ public function toXMLString()
306
+ {
307
+ $str = '';
308
+ if ( $this->DetailLevel != null ) {
309
+ for ( $i = 0; $i < count( $this->DetailLevel ); $i++ ) {
310
+ $str .= '<ebl:DetailLevel>' . PPUtils::escapeInvalidXmlCharsRegex( $this->DetailLevel[ $i ] ) . '</ebl:DetailLevel>';
311
+ }
312
+ }
313
+ if ( $this->ErrorLanguage != null ) {
314
+ $str .= '<ebl:ErrorLanguage>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ErrorLanguage ) . '</ebl:ErrorLanguage>';
315
+ }
316
+ if ( $this->Version != null ) {
317
+ $str .= '<ebl:Version>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Version ) . '</ebl:Version>';
318
+ }
319
+
320
+ return $str;
321
+ }
322
+
323
+
324
+ }
325
+
326
+
327
+ /**
328
+ * Base type definition of a response payload that can carry
329
+ * any type of payload content with following optional
330
+ * elements: - timestamp of response message, - application
331
+ * level acknowledgement, and - application-level errors and
332
+ * warnings.
333
+ */
334
+ class AbstractResponseType
335
+ {
336
+
337
+ /**
338
+ * This value represents the date and time (GMT) when the
339
+ * response was generated by a service provider (as a result of
340
+ * processing of a request).
341
+ * @access public
342
+ * @var dateTime
343
+ */
344
+ public $Timestamp;
345
+
346
+ /**
347
+ * Application level acknowledgement code.
348
+ * @access public
349
+ * @var AckCodeType
350
+ */
351
+ public $Ack;
352
+
353
+ /**
354
+ * CorrelationID may be used optionally with an application
355
+ * level acknowledgement.
356
+ * @access public
357
+ * @var string
358
+ */
359
+ public $CorrelationID;
360
+
361
+ /**
362
+ *
363
+ * @array
364
+ * @access public
365
+ * @var ErrorType
366
+ */
367
+ public $Errors;
368
+
369
+ /**
370
+ * This refers to the version of the response payload schema.
371
+ * @access public
372
+ * @var string
373
+ */
374
+ public $Version;
375
+
376
+ /**
377
+ * This refers to the specific software build that was used in
378
+ * the deployment for processing the request and generating the
379
+ * response.
380
+ * @access public
381
+ * @var string
382
+ */
383
+ public $Build;
384
+
385
+
386
+ public function init( $arr = null )
387
+ {
388
+ if ( $arr != null ) {
389
+ foreach ( $arr as $arry ) {
390
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'timestamp' ) {
391
+ $this->Timestamp = $arry[ "text" ];
392
+ }
393
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'ack' ) {
394
+ $this->Ack = $arry[ "text" ];
395
+ }
396
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'correlationid' ) {
397
+ $this->CorrelationID = $arry[ "text" ];
398
+ }
399
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) ) {
400
+ $i = 0;
401
+ while ( true ) {
402
+ if ( $arry[ "name" ] == "errors[$i]" ) {
403
+ $this->Errors[ $i ] = new ErrorType();
404
+ $this->Errors[ $i ]->init( $arry[ "children" ] );
405
+ } else {
406
+ break;
407
+ }
408
+ $i++;
409
+ }
410
+ }
411
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) && ( $arry[ "name" ] == "errors" ) ) {
412
+ $this->Errors = new ErrorType();
413
+ $this->Errors->init( $arry[ "children" ] );
414
+ }
415
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'version' ) {
416
+ $this->Version = $arry[ "text" ];
417
+ }
418
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'build' ) {
419
+ $this->Build = $arry[ "text" ];
420
+ }
421
+ }
422
+ }
423
+ }
424
+ }
425
+
426
+
427
+ /**
428
+ * Country code associated with this phone number.
429
+ */
430
+ class PhoneNumberType
431
+ {
432
+
433
+ /**
434
+ * Country code associated with this phone number.
435
+ * @access public
436
+ * @var string
437
+ */
438
+ public $CountryCode;
439
+
440
+ /**
441
+ * Phone number associated with this phone.
442
+ * @access public
443
+ * @var string
444
+ */
445
+ public $PhoneNumber;
446
+
447
+ /**
448
+ * Extension associated with this phone number.
449
+ * @access public
450
+ * @var string
451
+ */
452
+ public $Extension;
453
+
454
+
455
+ public function toXMLString()
456
+ {
457
+ $str = '';
458
+ if ( $this->CountryCode != null ) {
459
+ $str .= '<ebl:CountryCode>' . PPUtils::escapeInvalidXmlCharsRegex( $this->CountryCode ) . '</ebl:CountryCode>';
460
+ }
461
+ if ( $this->PhoneNumber != null ) {
462
+ $str .= '<ebl:PhoneNumber>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PhoneNumber ) . '</ebl:PhoneNumber>';
463
+ }
464
+ if ( $this->Extension != null ) {
465
+ $str .= '<ebl:Extension>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Extension ) . '</ebl:Extension>';
466
+ }
467
+
468
+ return $str;
469
+ }
470
+
471
+
472
+ }
473
+
474
+
475
+ /**
476
+ * Person's name associated with this address. Character length
477
+ * and limitations: 32 single-byte alphanumeric characters
478
+ */
479
+ class AddressType
480
+ {
481
+
482
+ /**
483
+ * Person's name associated with this address. Character length
484
+ * and limitations: 32 single-byte alphanumeric characters
485
+ * @access public
486
+ * @var string
487
+ */
488
+ public $Name;
489
+
490
+ /**
491
+ * First street address. Character length and limitations: 300
492
+ * single-byte alphanumeric characters
493
+ * @access public
494
+ * @var string
495
+ */
496
+ public $Street1;
497
+
498
+ /**
499
+ * Second street address. Character length and limitations: 300
500
+ * single-byte alphanumeric characters
501
+ * @access public
502
+ * @var string
503
+ */
504
+ public $Street2;
505
+
506
+ /**
507
+ * Name of city. Character length and limitations: 120
508
+ * single-byte alphanumeric characters
509
+ * @access public
510
+ * @var string
511
+ */
512
+ public $CityName;
513
+
514
+ /**
515
+ * State or province. Character length and limitations: 120
516
+ * single-byte alphanumeric characters For Canada and the USA,
517
+ * StateOrProvince must be the standard 2-character
518
+ * abbreviation of a state or province. Canadian Provinces
519
+ * Alberta AB British_Columbia BC Manitoba MB New_Brunswick NB
520
+ * Newfoundland NF Northwest_Territories NT Nova_Scotia NS
521
+ * Nunavut NU Ontario ON Prince_Edward_Island PE Quebec QC
522
+ * Saskatchewan SK Yukon YK United States Alabama AL Alaska AK
523
+ * American_Samoa AS Arizona AZ Arkansas AR California CA
524
+ * Colorado CO Connecticut CT Delaware DE District_Of_Columbia
525
+ * DC Federated_States_Of_Micronesia FM Florida FL Georgia GA
526
+ * Guam GU Hawaii HI Idaho ID Illinois IL Indiana IN Iowa IA
527
+ * Kansas KS Kentucky KY Louisiana LA Maine ME Marshall_Islands
528
+ * MH Maryland MD Massachusetts MA Michigan MI Minnesota MN
529
+ * Mississippi MS Missouri MO Montana MT Nebraska NE Nevada NV
530
+ * New_Hampshire NH New_Jersey NJ New_Mexico NM New_York NY
531
+ * North_Carolina NC North_Dakota ND Northern_Mariana_Islands
532
+ * MP Ohio OH Oklahoma OK Oregon OR Palau PW Pennsylvania PA
533
+ * Puerto_Rico PR Rhode_Island RI South_Carolina SC
534
+ * South_Dakota SD Tennessee TN Texas TX Utah UT Vermont VT
535
+ * Virgin_Islands VI Virginia VA Washington WA West_Virginia WV
536
+ * Wisconsin WI Wyoming WY Armed_Forces_Americas AA
537
+ * Armed_Forces AE Armed_Forces_Pacific AP
538
+ * @access public
539
+ * @var string
540
+ */
541
+ public $StateOrProvince;
542
+
543
+ /**
544
+ * ISO 3166 standard country code Character limit: Two
545
+ * single-byte characters.
546
+ * @access public
547
+ * @var CountryCodeType
548
+ */
549
+ public $Country;
550
+
551
+ /**
552
+ * IMPORTANT: Do not set this element for SetExpressCheckout,
553
+ * DoExpressCheckoutPayment, DoDirectPayment,
554
+ * CreateRecurringPaymentsProfile or
555
+ * UpdateRecurringPaymentsProfile. This element should only be
556
+ * used in response elements and typically should not be used
557
+ * in creating request messages which specify the name of a
558
+ * country using the Country element (which refers to a
559
+ * 2-letter country code).
560
+ * @access public
561
+ * @var string
562
+ */
563
+ public $CountryName;
564
+
565
+ /**
566
+ * Telephone number associated with this address
567
+ * @access public
568
+ * @var string
569
+ */
570
+ public $Phone;
571
+
572
+ /**
573
+ *
574
+ * @access public
575
+ * @var string
576
+ */
577
+ public $PostalCode;
578
+
579
+ /**
580
+ * IMPORTANT: Do not set this element for SetExpressCheckout,
581
+ * DoExpressCheckoutPayment, DoDirectPayment,
582
+ * CreateRecurringPaymentsProfile, or
583
+ * UpdateRecurringPaymentsProfile.
584
+ * @access public
585
+ * @var string
586
+ */
587
+ public $AddressID;
588
+
589
+ /**
590
+ * IMPORTANT: Do not set this element for SetExpressCheckout,
591
+ * DoExpressCheckoutPayment, DoDirectPayment,
592
+ * CreateRecurringPaymentsProfile or
593
+ * UpdateRecurringPaymentsProfile.
594
+ * @access public
595
+ * @var AddressOwnerCodeType
596
+ */
597
+ public $AddressOwner;
598
+
599
+ /**
600
+ * IMPORTANT: Do not set this element for SetExpressCheckout,
601
+ * DoExpressCheckoutPayment, DoDirectPayment,
602
+ * CreateRecurringPaymentsProfile or
603
+ * UpdateRecurringPaymentsProfile.
604
+ * @access public
605
+ * @var string
606
+ */
607
+ public $ExternalAddressID;
608
+
609
+ /**
610
+ * IMPORTANT: Do not set this element for SetExpressCheckout,
611
+ * DoExpressCheckoutPayment, DoDirectPayment,
612
+ * CreateRecurringPaymentsProfile or
613
+ * UpdateRecurringPaymentsProfile. Only applicable to
614
+ * SellerPaymentAddress today. Seller's international name that
615
+ * is associated with the payment address.
616
+ * @access public
617
+ * @var string
618
+ */
619
+ public $InternationalName;
620
+
621
+ /**
622
+ * IMPORTANT: Do not set this element for SetExpressCheckout,
623
+ * DoExpressCheckoutPayment, DoDirectPayment,
624
+ * CreateRecurringPaymentsProfile or
625
+ * UpdateRecurringPaymentsProfile. Only applicable to
626
+ * SellerPaymentAddress today. International state and city for
627
+ * the seller's payment address.
628
+ * @access public
629
+ * @var string
630
+ */
631
+ public $InternationalStateAndCity;
632
+
633
+ /**
634
+ * IMPORTANT: Do not set this element for SetExpressCheckout,
635
+ * DoExpressCheckoutPayment, DoDirectPayment,
636
+ * CreateRecurringPaymentsProfile or
637
+ * UpdateRecurringPaymentsProfile. Only applicable to
638
+ * SellerPaymentAddress today. Seller's international street
639
+ * address that is associated with the payment address.
640
+ * @access public
641
+ * @var string
642
+ */
643
+ public $InternationalStreet;
644
+
645
+ /**
646
+ * Status of the address on file with PayPal. IMPORTANT: Do not
647
+ * set this element for SetExpressCheckout,
648
+ * DoExpressCheckoutPayment, DoDirectPayment,
649
+ * CreateRecurringPaymentsProfile or
650
+ * UpdateRecurringPaymentsProfile.
651
+ * @access public
652
+ * @var AddressStatusCodeType
653
+ */
654
+ public $AddressStatus;
655
+
656
+
657
+ public function toXMLString()
658
+ {
659
+ $str = '';
660
+ if ( $this->Name != null ) {
661
+ $str .= '<ebl:Name>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Name ) . '</ebl:Name>';
662
+ }
663
+ if ( $this->Street1 != null ) {
664
+ $str .= '<ebl:Street1>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Street1 ) . '</ebl:Street1>';
665
+ }
666
+ if ( $this->Street2 != null ) {
667
+ $str .= '<ebl:Street2>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Street2 ) . '</ebl:Street2>';
668
+ }
669
+ if ( $this->CityName != null ) {
670
+ $str .= '<ebl:CityName>' . PPUtils::escapeInvalidXmlCharsRegex( $this->CityName ) . '</ebl:CityName>';
671
+ }
672
+ if ( $this->StateOrProvince != null ) {
673
+ $str .= '<ebl:StateOrProvince>' . PPUtils::escapeInvalidXmlCharsRegex( $this->StateOrProvince ) . '</ebl:StateOrProvince>';
674
+ }
675
+ if ( $this->Country != null ) {
676
+ $str .= '<ebl:Country>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Country ) . '</ebl:Country>';
677
+ }
678
+ if ( $this->CountryName != null ) {
679
+ $str .= '<ebl:CountryName>' . PPUtils::escapeInvalidXmlCharsRegex( $this->CountryName ) . '</ebl:CountryName>';
680
+ }
681
+ if ( $this->Phone != null ) {
682
+ $str .= '<ebl:Phone>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Phone ) . '</ebl:Phone>';
683
+ }
684
+ if ( $this->PostalCode != null ) {
685
+ $str .= '<ebl:PostalCode>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PostalCode ) . '</ebl:PostalCode>';
686
+ }
687
+ if ( $this->AddressID != null ) {
688
+ $str .= '<ebl:AddressID>' . PPUtils::escapeInvalidXmlCharsRegex( $this->AddressID ) . '</ebl:AddressID>';
689
+ }
690
+ if ( $this->AddressOwner != null ) {
691
+ $str .= '<ebl:AddressOwner>' . PPUtils::escapeInvalidXmlCharsRegex( $this->AddressOwner ) . '</ebl:AddressOwner>';
692
+ }
693
+ if ( $this->ExternalAddressID != null ) {
694
+ $str .= '<ebl:ExternalAddressID>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ExternalAddressID ) . '</ebl:ExternalAddressID>';
695
+ }
696
+ if ( $this->InternationalName != null ) {
697
+ $str .= '<ebl:InternationalName>' . PPUtils::escapeInvalidXmlCharsRegex( $this->InternationalName ) . '</ebl:InternationalName>';
698
+ }
699
+ if ( $this->InternationalStateAndCity != null ) {
700
+ $str .= '<ebl:InternationalStateAndCity>' . PPUtils::escapeInvalidXmlCharsRegex( $this->InternationalStateAndCity ) . '</ebl:InternationalStateAndCity>';
701
+ }
702
+ if ( $this->InternationalStreet != null ) {
703
+ $str .= '<ebl:InternationalStreet>' . PPUtils::escapeInvalidXmlCharsRegex( $this->InternationalStreet ) . '</ebl:InternationalStreet>';
704
+ }
705
+ if ( $this->AddressStatus != null ) {
706
+ $str .= '<ebl:AddressStatus>' . PPUtils::escapeInvalidXmlCharsRegex( $this->AddressStatus ) . '</ebl:AddressStatus>';
707
+ }
708
+
709
+ return $str;
710
+ }
711
+
712
+
713
+ public function init( $arr = null )
714
+ {
715
+ if ( $arr != null ) {
716
+ foreach ( $arr as $arry ) {
717
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'name' ) {
718
+ $this->Name = $arry[ "text" ];
719
+ }
720
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'street1' ) {
721
+ $this->Street1 = $arry[ "text" ];
722
+ }
723
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'street2' ) {
724
+ $this->Street2 = $arry[ "text" ];
725
+ }
726
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'cityname' ) {
727
+ $this->CityName = $arry[ "text" ];
728
+ }
729
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'stateorprovince' ) {
730
+ $this->StateOrProvince = $arry[ "text" ];
731
+ }
732
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'country' ) {
733
+ $this->Country = $arry[ "text" ];
734
+ }
735
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'countryname' ) {
736
+ $this->CountryName = $arry[ "text" ];
737
+ }
738
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'phone' ) {
739
+ $this->Phone = $arry[ "text" ];
740
+ }
741
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'postalcode' ) {
742
+ $this->PostalCode = $arry[ "text" ];
743
+ }
744
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'addressid' ) {
745
+ $this->AddressID = $arry[ "text" ];
746
+ }
747
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'addressowner' ) {
748
+ $this->AddressOwner = $arry[ "text" ];
749
+ }
750
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'externaladdressid' ) {
751
+ $this->ExternalAddressID = $arry[ "text" ];
752
+ }
753
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'internationalname' ) {
754
+ $this->InternationalName = $arry[ "text" ];
755
+ }
756
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'internationalstateandcity' ) {
757
+ $this->InternationalStateAndCity = $arry[ "text" ];
758
+ }
759
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'internationalstreet' ) {
760
+ $this->InternationalStreet = $arry[ "text" ];
761
+ }
762
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'addressstatus' ) {
763
+ $this->AddressStatus = $arry[ "text" ];
764
+ }
765
+ }
766
+ }
767
+ }
768
+ }
769
+
770
+
771
+ /**
772
+ *
773
+ */
774
+ class PersonNameType
775
+ {
776
+
777
+ /**
778
+ *
779
+ * @access public
780
+ * @var string
781
+ */
782
+ public $Salutation;
783
+
784
+ /**
785
+ *
786
+ * @access public
787
+ * @var string
788
+ */
789
+ public $FirstName;
790
+
791
+ /**
792
+ *
793
+ * @access public
794
+ * @var string
795
+ */
796
+ public $MiddleName;
797
+
798
+ /**
799
+ *
800
+ * @access public
801
+ * @var string
802
+ */
803
+ public $LastName;
804
+
805
+ /**
806
+ *
807
+ * @access public
808
+ * @var string
809
+ */
810
+ public $Suffix;
811
+
812
+
813
+ public function toXMLString()
814
+ {
815
+ $str = '';
816
+ if ( $this->Salutation != null ) {
817
+ $str .= '<ebl:Salutation>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Salutation ) . '</ebl:Salutation>';
818
+ }
819
+ if ( $this->FirstName != null ) {
820
+ $str .= '<ebl:FirstName>' . PPUtils::escapeInvalidXmlCharsRegex( $this->FirstName ) . '</ebl:FirstName>';
821
+ }
822
+ if ( $this->MiddleName != null ) {
823
+ $str .= '<ebl:MiddleName>' . PPUtils::escapeInvalidXmlCharsRegex( $this->MiddleName ) . '</ebl:MiddleName>';
824
+ }
825
+ if ( $this->LastName != null ) {
826
+ $str .= '<ebl:LastName>' . PPUtils::escapeInvalidXmlCharsRegex( $this->LastName ) . '</ebl:LastName>';
827
+ }
828
+ if ( $this->Suffix != null ) {
829
+ $str .= '<ebl:Suffix>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Suffix ) . '</ebl:Suffix>';
830
+ }
831
+
832
+ return $str;
833
+ }
834
+
835
+
836
+ public function init( $arr = null )
837
+ {
838
+ if ( $arr != null ) {
839
+ foreach ( $arr as $arry ) {
840
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'salutation' ) {
841
+ $this->Salutation = $arry[ "text" ];
842
+ }
843
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'firstname' ) {
844
+ $this->FirstName = $arry[ "text" ];
845
+ }
846
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'middlename' ) {
847
+ $this->MiddleName = $arry[ "text" ];
848
+ }
849
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'lastname' ) {
850
+ $this->LastName = $arry[ "text" ];
851
+ }
852
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'suffix' ) {
853
+ $this->Suffix = $arry[ "text" ];
854
+ }
855
+ }
856
+ }
857
+ }
858
+ }
859
+
860
+
861
+ /**
862
+ *
863
+ */
864
+ class IncentiveAppliedToType
865
+ {
866
+
867
+ /**
868
+ *
869
+ * @access public
870
+ * @var string
871
+ */
872
+ public $BucketId;
873
+
874
+ /**
875
+ *
876
+ * @access public
877
+ * @var string
878
+ */
879
+ public $ItemId;
880
+
881
+ /**
882
+ *
883
+ * @access public
884
+ * @var BasicAmountType
885
+ */
886
+ public $IncentiveAmount;
887
+
888
+ /**
889
+ *
890
+ * @access public
891
+ * @var string
892
+ */
893
+ public $SubType;
894
+
895
+
896
+ public function init( $arr = null )
897
+ {
898
+ if ( $arr != null ) {
899
+ foreach ( $arr as $arry ) {
900
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'bucketid' ) {
901
+ $this->BucketId = $arry[ "text" ];
902
+ }
903
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'itemid' ) {
904
+ $this->ItemId = $arry[ "text" ];
905
+ }
906
+
907
+
908
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
909
+ if ( $arry[ "name" ] == 'incentiveamount' ) {
910
+ $tmp = array();
911
+ $atr = array();
912
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
913
+ $atr[ 0 ][ "name" ] = $key;
914
+ $atr[ 0 ][ "text" ] = $val;
915
+ }
916
+ $atr[ 1 ][ "name" ] = "value";
917
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
918
+ $this->IncentiveAmount = new BasicAmountType();
919
+ $this->IncentiveAmount->init( $atr );
920
+ }
921
+
922
+ }
923
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'subtype' ) {
924
+ $this->SubType = $arry[ "text" ];
925
+ }
926
+ }
927
+ }
928
+ }
929
+ }
930
+
931
+
932
+ /**
933
+ *
934
+ */
935
+ class IncentiveDetailType
936
+ {
937
+
938
+ /**
939
+ *
940
+ * @access public
941
+ * @var string
942
+ */
943
+ public $RedemptionCode;
944
+
945
+ /**
946
+ *
947
+ * @access public
948
+ * @var string
949
+ */
950
+ public $DisplayCode;
951
+
952
+ /**
953
+ *
954
+ * @access public
955
+ * @var string
956
+ */
957
+ public $ProgramId;
958
+
959
+ /**
960
+ *
961
+ * @access public
962
+ * @var IncentiveTypeCodeType
963
+ */
964
+ public $IncentiveType;
965
+
966
+ /**
967
+ *
968
+ * @access public
969
+ * @var string
970
+ */
971
+ public $IncentiveDescription;
972
+
973
+ /**
974
+ *
975
+ * @array
976
+ * @access public
977
+ * @var IncentiveAppliedToType
978
+ */
979
+ public $AppliedTo;
980
+
981
+ /**
982
+ *
983
+ * @access public
984
+ * @var string
985
+ */
986
+ public $Status;
987
+
988
+ /**
989
+ *
990
+ * @access public
991
+ * @var string
992
+ */
993
+ public $ErrorCode;
994
+
995
+
996
+ public function init( $arr = null )
997
+ {
998
+ if ( $arr != null ) {
999
+ foreach ( $arr as $arry ) {
1000
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'redemptioncode' ) {
1001
+ $this->RedemptionCode = $arry[ "text" ];
1002
+ }
1003
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'displaycode' ) {
1004
+ $this->DisplayCode = $arry[ "text" ];
1005
+ }
1006
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'programid' ) {
1007
+ $this->ProgramId = $arry[ "text" ];
1008
+ }
1009
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'incentivetype' ) {
1010
+ $this->IncentiveType = $arry[ "text" ];
1011
+ }
1012
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'incentivedescription' ) {
1013
+ $this->IncentiveDescription = $arry[ "text" ];
1014
+ }
1015
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) ) {
1016
+ $i = 0;
1017
+ while ( true ) {
1018
+ if ( $arry[ "name" ] == "appliedto[$i]" ) {
1019
+ $this->AppliedTo[ $i ] = new IncentiveAppliedToType();
1020
+ $this->AppliedTo[ $i ]->init( $arry[ "children" ] );
1021
+ } else {
1022
+ break;
1023
+ }
1024
+ $i++;
1025
+ }
1026
+ }
1027
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) && ( $arry[ "name" ] == "appliedto" ) ) {
1028
+ $this->AppliedTo = new IncentiveAppliedToType();
1029
+ $this->AppliedTo->init( $arry[ "children" ] );
1030
+ }
1031
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'status' ) {
1032
+ $this->Status = $arry[ "text" ];
1033
+ }
1034
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'errorcode' ) {
1035
+ $this->ErrorCode = $arry[ "text" ];
1036
+ }
1037
+ }
1038
+ }
1039
+ }
1040
+ }
1041
+
1042
+
1043
+ /**
1044
+ *
1045
+ */
1046
+ class IncentiveItemType
1047
+ {
1048
+
1049
+ /**
1050
+ *
1051
+ * @access public
1052
+ * @var string
1053
+ */
1054
+ public $ItemId;
1055
+
1056
+ /**
1057
+ *
1058
+ * @access public
1059
+ * @var dateTime
1060
+ */
1061
+ public $PurchaseTime;
1062
+
1063
+ /**
1064
+ *
1065
+ * @access public
1066
+ * @var string
1067
+ */
1068
+ public $ItemCategoryList;
1069
+
1070
+ /**
1071
+ *
1072
+ * @access public
1073
+ * @var BasicAmountType
1074
+ */
1075
+ public $ItemPrice;
1076
+
1077
+ /**
1078
+ *
1079
+ * @access public
1080
+ * @var integer
1081
+ */
1082
+ public $ItemQuantity;
1083
+
1084
+
1085
+ public function toXMLString()
1086
+ {
1087
+ $str = '';
1088
+ if ( $this->ItemId != null ) {
1089
+ $str .= '<ebl:ItemId>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ItemId ) . '</ebl:ItemId>';
1090
+ }
1091
+ if ( $this->PurchaseTime != null ) {
1092
+ $str .= '<ebl:PurchaseTime>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PurchaseTime ) . '</ebl:PurchaseTime>';
1093
+ }
1094
+ if ( $this->ItemCategoryList != null ) {
1095
+ $str .= '<ebl:ItemCategoryList>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ItemCategoryList ) . '</ebl:ItemCategoryList>';
1096
+ }
1097
+ if ( $this->ItemPrice != null ) {
1098
+ $str .= '<ebl:ItemPrice';
1099
+ $str .= $this->ItemPrice->toXMLString();
1100
+ $str .= '</ebl:ItemPrice>';
1101
+ }
1102
+ if ( $this->ItemQuantity != null ) {
1103
+ $str .= '<ebl:ItemQuantity>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ItemQuantity ) . '</ebl:ItemQuantity>';
1104
+ }
1105
+
1106
+ return $str;
1107
+ }
1108
+
1109
+
1110
+ }
1111
+
1112
+
1113
+ /**
1114
+ *
1115
+ */
1116
+ class IncentiveBucketType
1117
+ {
1118
+
1119
+ /**
1120
+ *
1121
+ * @array
1122
+ * @access public
1123
+ * @var IncentiveItemType
1124
+ */
1125
+ public $Items;
1126
+
1127
+ /**
1128
+ *
1129
+ * @access public
1130
+ * @var string
1131
+ */
1132
+ public $BucketId;
1133
+
1134
+ /**
1135
+ *
1136
+ * @access public
1137
+ * @var string
1138
+ */
1139
+ public $SellerId;
1140
+
1141
+ /**
1142
+ *
1143
+ * @access public
1144
+ * @var string
1145
+ */
1146
+ public $ExternalSellerId;
1147
+
1148
+ /**
1149
+ *
1150
+ * @access public
1151
+ * @var BasicAmountType
1152
+ */
1153
+ public $BucketSubtotalAmt;
1154
+
1155
+ /**
1156
+ *
1157
+ * @access public
1158
+ * @var BasicAmountType
1159
+ */
1160
+ public $BucketShippingAmt;
1161
+
1162
+ /**
1163
+ *
1164
+ * @access public
1165
+ * @var BasicAmountType
1166
+ */
1167
+ public $BucketInsuranceAmt;
1168
+
1169
+ /**
1170
+ *
1171
+ * @access public
1172
+ * @var BasicAmountType
1173
+ */
1174
+ public $BucketSalesTaxAmt;
1175
+
1176
+ /**
1177
+ *
1178
+ * @access public
1179
+ * @var BasicAmountType
1180
+ */
1181
+ public $BucketTotalAmt;
1182
+
1183
+
1184
+ public function toXMLString()
1185
+ {
1186
+ $str = '';
1187
+ if ( $this->Items != null ) {
1188
+ for ( $i = 0; $i < count( $this->Items ); $i++ ) {
1189
+ $str .= '<ebl:Items>';
1190
+ $str .= $this->Items[ $i ]->toXMLString();
1191
+ $str .= '</ebl:Items>';
1192
+ }
1193
+ }
1194
+ if ( $this->BucketId != null ) {
1195
+ $str .= '<ebl:BucketId>' . PPUtils::escapeInvalidXmlCharsRegex( $this->BucketId ) . '</ebl:BucketId>';
1196
+ }
1197
+ if ( $this->SellerId != null ) {
1198
+ $str .= '<ebl:SellerId>' . PPUtils::escapeInvalidXmlCharsRegex( $this->SellerId ) . '</ebl:SellerId>';
1199
+ }
1200
+ if ( $this->ExternalSellerId != null ) {
1201
+ $str .= '<ebl:ExternalSellerId>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ExternalSellerId ) . '</ebl:ExternalSellerId>';
1202
+ }
1203
+ if ( $this->BucketSubtotalAmt != null ) {
1204
+ $str .= '<ebl:BucketSubtotalAmt';
1205
+ $str .= $this->BucketSubtotalAmt->toXMLString();
1206
+ $str .= '</ebl:BucketSubtotalAmt>';
1207
+ }
1208
+ if ( $this->BucketShippingAmt != null ) {
1209
+ $str .= '<ebl:BucketShippingAmt';
1210
+ $str .= $this->BucketShippingAmt->toXMLString();
1211
+ $str .= '</ebl:BucketShippingAmt>';
1212
+ }
1213
+ if ( $this->BucketInsuranceAmt != null ) {
1214
+ $str .= '<ebl:BucketInsuranceAmt';
1215
+ $str .= $this->BucketInsuranceAmt->toXMLString();
1216
+ $str .= '</ebl:BucketInsuranceAmt>';
1217
+ }
1218
+ if ( $this->BucketSalesTaxAmt != null ) {
1219
+ $str .= '<ebl:BucketSalesTaxAmt';
1220
+ $str .= $this->BucketSalesTaxAmt->toXMLString();
1221
+ $str .= '</ebl:BucketSalesTaxAmt>';
1222
+ }
1223
+ if ( $this->BucketTotalAmt != null ) {
1224
+ $str .= '<ebl:BucketTotalAmt';
1225
+ $str .= $this->BucketTotalAmt->toXMLString();
1226
+ $str .= '</ebl:BucketTotalAmt>';
1227
+ }
1228
+
1229
+ return $str;
1230
+ }
1231
+
1232
+
1233
+ }
1234
+
1235
+
1236
+ /**
1237
+ *
1238
+ */
1239
+ class IncentiveRequestDetailsType
1240
+ {
1241
+
1242
+ /**
1243
+ *
1244
+ * @access public
1245
+ * @var string
1246
+ */
1247
+ public $RequestId;
1248
+
1249
+ /**
1250
+ *
1251
+ * @access public
1252
+ * @var IncentiveRequestCodeType
1253
+ */
1254
+ public $RequestType;
1255
+
1256
+ /**
1257
+ *
1258
+ * @access public
1259
+ * @var IncentiveRequestDetailLevelCodeType
1260
+ */
1261
+ public $RequestDetailLevel;
1262
+
1263
+
1264
+ public function toXMLString()
1265
+ {
1266
+ $str = '';
1267
+ if ( $this->RequestId != null ) {
1268
+ $str .= '<ebl:RequestId>' . PPUtils::escapeInvalidXmlCharsRegex( $this->RequestId ) . '</ebl:RequestId>';
1269
+ }
1270
+ if ( $this->RequestType != null ) {
1271
+ $str .= '<ebl:RequestType>' . PPUtils::escapeInvalidXmlCharsRegex( $this->RequestType ) . '</ebl:RequestType>';
1272
+ }
1273
+ if ( $this->RequestDetailLevel != null ) {
1274
+ $str .= '<ebl:RequestDetailLevel>' . PPUtils::escapeInvalidXmlCharsRegex( $this->RequestDetailLevel ) . '</ebl:RequestDetailLevel>';
1275
+ }
1276
+
1277
+ return $str;
1278
+ }
1279
+
1280
+
1281
+ }
1282
+
1283
+
1284
+ /**
1285
+ *
1286
+ */
1287
+ class GetIncentiveEvaluationRequestDetailsType
1288
+ {
1289
+
1290
+ /**
1291
+ *
1292
+ * @access public
1293
+ * @var string
1294
+ */
1295
+ public $ExternalBuyerId;
1296
+
1297
+ /**
1298
+ *
1299
+ * @array
1300
+ * @access public
1301
+ * @var string
1302
+ */
1303
+ public $IncentiveCodes;
1304
+
1305
+ /**
1306
+ *
1307
+ * @array
1308
+ * @access public
1309
+ * @var IncentiveApplyIndicationType
1310
+ */
1311
+ public $ApplyIndication;
1312
+
1313
+ /**
1314
+ *
1315
+ * @array
1316
+ * @access public
1317
+ * @var IncentiveBucketType
1318
+ */
1319
+ public $Buckets;
1320
+
1321
+ /**
1322
+ *
1323
+ * @access public
1324
+ * @var BasicAmountType
1325
+ */
1326
+ public $CartTotalAmt;
1327
+
1328
+ /**
1329
+ *
1330
+ * @access public
1331
+ * @var IncentiveRequestDetailsType
1332
+ */
1333
+ public $RequestDetails;
1334
+
1335
+
1336
+ public function toXMLString()
1337
+ {
1338
+ $str = '';
1339
+ if ( $this->ExternalBuyerId != null ) {
1340
+ $str .= '<ebl:ExternalBuyerId>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ExternalBuyerId ) . '</ebl:ExternalBuyerId>';
1341
+ }
1342
+ if ( $this->IncentiveCodes != null ) {
1343
+ for ( $i = 0; $i < count( $this->IncentiveCodes ); $i++ ) {
1344
+ $str .= '<ebl:IncentiveCodes>' . PPUtils::escapeInvalidXmlCharsRegex( $this->IncentiveCodes[ $i ] ) . '</ebl:IncentiveCodes>';
1345
+ }
1346
+ }
1347
+ if ( $this->ApplyIndication != null ) {
1348
+ for ( $i = 0; $i < count( $this->ApplyIndication ); $i++ ) {
1349
+ $str .= '<ebl:ApplyIndication>';
1350
+ $str .= $this->ApplyIndication[ $i ]->toXMLString();
1351
+ $str .= '</ebl:ApplyIndication>';
1352
+ }
1353
+ }
1354
+ if ( $this->Buckets != null ) {
1355
+ for ( $i = 0; $i < count( $this->Buckets ); $i++ ) {
1356
+ $str .= '<ebl:Buckets>';
1357
+ $str .= $this->Buckets[ $i ]->toXMLString();
1358
+ $str .= '</ebl:Buckets>';
1359
+ }
1360
+ }
1361
+ if ( $this->CartTotalAmt != null ) {
1362
+ $str .= '<ebl:CartTotalAmt';
1363
+ $str .= $this->CartTotalAmt->toXMLString();
1364
+ $str .= '</ebl:CartTotalAmt>';
1365
+ }
1366
+ if ( $this->RequestDetails != null ) {
1367
+ $str .= '<ebl:RequestDetails>';
1368
+ $str .= $this->RequestDetails->toXMLString();
1369
+ $str .= '</ebl:RequestDetails>';
1370
+ }
1371
+
1372
+ return $str;
1373
+ }
1374
+
1375
+
1376
+ }
1377
+
1378
+
1379
+ /**
1380
+ *
1381
+ */
1382
+ class GetIncentiveEvaluationResponseDetailsType
1383
+ {
1384
+
1385
+ /**
1386
+ *
1387
+ * @array
1388
+ * @access public
1389
+ * @var IncentiveDetailType
1390
+ */
1391
+ public $IncentiveDetails;
1392
+
1393
+ /**
1394
+ *
1395
+ * @access public
1396
+ * @var string
1397
+ */
1398
+ public $RequestId;
1399
+
1400
+
1401
+ public function init( $arr = null )
1402
+ {
1403
+ if ( $arr != null ) {
1404
+ foreach ( $arr as $arry ) {
1405
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) ) {
1406
+ $i = 0;
1407
+ while ( true ) {
1408
+ if ( $arry[ "name" ] == "incentivedetails[$i]" ) {
1409
+ $this->IncentiveDetails[ $i ] = new IncentiveDetailType();
1410
+ $this->IncentiveDetails[ $i ]->init( $arry[ "children" ] );
1411
+ } else {
1412
+ break;
1413
+ }
1414
+ $i++;
1415
+ }
1416
+ }
1417
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) && ( $arry[ "name" ] == "incentivedetails" ) ) {
1418
+ $this->IncentiveDetails = new IncentiveDetailType();
1419
+ $this->IncentiveDetails->init( $arry[ "children" ] );
1420
+ }
1421
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'requestid' ) {
1422
+ $this->RequestId = $arry[ "text" ];
1423
+ }
1424
+ }
1425
+ }
1426
+ }
1427
+ }
1428
+
1429
+
1430
+ /**
1431
+ * The total cost of the order to the customer. If shipping
1432
+ * cost and tax charges are known, include them in OrderTotal;
1433
+ * if not, OrderTotal should be the current sub-total of the
1434
+ * order. You must set the currencyID attribute to one of the
1435
+ * three-character currency codes for any of the supported
1436
+ * PayPal currencies. Limitations: Must not exceed $10,000 USD
1437
+ * in any currency. No currency symbol. Decimal separator must
1438
+ * be a period (.), and the thousands separator must be a comma
1439
+ * (,).
1440
+ */
1441
+ class SetExpressCheckoutRequestDetailsType
1442
+ {
1443
+
1444
+ /**
1445
+ * The total cost of the order to the customer. If shipping
1446
+ * cost and tax charges are known, include them in OrderTotal;
1447
+ * if not, OrderTotal should be the current sub-total of the
1448
+ * order. You must set the currencyID attribute to one of the
1449
+ * three-character currency codes for any of the supported
1450
+ * PayPal currencies. Limitations: Must not exceed $10,000 USD
1451
+ * in any currency. No currency symbol. Decimal separator must
1452
+ * be a period (.), and the thousands separator must be a comma
1453
+ * (,).
1454
+ * @access public
1455
+ * @var BasicAmountType
1456
+ */
1457
+ public $OrderTotal;
1458
+
1459
+ /**
1460
+ * URL to which the customer's browser is returned after
1461
+ * choosing to pay with PayPal. PayPal recommends that the
1462
+ * value of ReturnURL be the final review page on which the
1463
+ * customer confirms the order and payment. Required Character
1464
+ * length and limitations: no limit.
1465
+ * @access public
1466
+ * @var string
1467
+ */
1468
+ public $ReturnURL;
1469
+
1470
+ /**
1471
+ * URL to which the customer is returned if he does not approve
1472
+ * the use of PayPal to pay you. PayPal recommends that the
1473
+ * value of CancelURL be the original page on which the
1474
+ * customer chose to pay with PayPal. Required Character length
1475
+ * and limitations: no limit
1476
+ * @access public
1477
+ * @var string
1478
+ */
1479
+ public $CancelURL;
1480
+
1481
+ /**
1482
+ * Tracking URL for ebay. Required Character length and
1483
+ * limitations: no limit
1484
+ * @access public
1485
+ * @var string
1486
+ */
1487
+ public $TrackingImageURL;
1488
+
1489
+ /**
1490
+ * URL to which the customer's browser is returned after paying
1491
+ * with giropay online. Optional Character length and
1492
+ * limitations: no limit.
1493
+ * @access public
1494
+ * @var string
1495
+ */
1496
+ public $giropaySuccessURL;
1497
+
1498
+ /**
1499
+ * URL to which the customer's browser is returned after fail
1500
+ * to pay with giropay online. Optional Character length and
1501
+ * limitations: no limit.
1502
+ * @access public
1503
+ * @var string
1504
+ */
1505
+ public $giropayCancelURL;
1506
+
1507
+ /**
1508
+ * URL to which the customer's browser can be returned in the
1509
+ * mEFT done page. Optional Character length and limitations:
1510
+ * no limit.
1511
+ * @access public
1512
+ * @var string
1513
+ */
1514
+ public $BanktxnPendingURL;
1515
+
1516
+ /**
1517
+ * On your first invocation of SetExpressCheckoutRequest, the
1518
+ * value of this token is returned by
1519
+ * SetExpressCheckoutResponse. Optional Include this element
1520
+ * and its value only if you want to modify an existing
1521
+ * checkout session with another invocation of
1522
+ * SetExpressCheckoutRequest; for example, if you want the
1523
+ * customer to edit his shipping address on PayPal. Character
1524
+ * length and limitations: 20 single-byte characters
1525
+ * @access public
1526
+ * @var string
1527
+ */
1528
+ public $Token;
1529
+
1530
+ /**
1531
+ * The expected maximum total amount of the complete order,
1532
+ * including shipping cost and tax charges. Optional You must
1533
+ * set the currencyID attribute to one of the three-character
1534
+ * currency codes for any of the supported PayPal currencies.
1535
+ * Limitations: Must not exceed $10,000 USD in any currency. No
1536
+ * currency symbol. Decimal separator must be a period (.), and
1537
+ * the thousands separator must be a comma (,).
1538
+ * @access public
1539
+ * @var BasicAmountType
1540
+ */
1541
+ public $MaxAmount;
1542
+
1543
+ /**
1544
+ * Description of items the customer is purchasing. Optional
1545
+ * Character length and limitations: 127 single-byte
1546
+ * alphanumeric characters
1547
+ * @access public
1548
+ * @var string
1549
+ */
1550
+ public $OrderDescription;
1551
+
1552
+ /**
1553
+ * A free-form field for your own use, such as a tracking
1554
+ * number or other value you want PayPal to return on
1555
+ * GetExpressCheckoutDetailsResponse and
1556
+ * DoExpressCheckoutPaymentResponse. Optional Character length
1557
+ * and limitations: 256 single-byte alphanumeric characters
1558
+ * @access public
1559
+ * @var string
1560
+ */
1561
+ public $Custom;
1562
+
1563
+ /**
1564
+ * Your own unique invoice or tracking number. PayPal returns
1565
+ * this value to you on DoExpressCheckoutPaymentResponse.
1566
+ * Optional Character length and limitations: 127 single-byte
1567
+ * alphanumeric characters
1568
+ * @access public
1569
+ * @var string
1570
+ */
1571
+ public $InvoiceID;
1572
+
1573
+ /**
1574
+ * The value 1 indicates that you require that the customer's
1575
+ * shipping address on file with PayPal be a confirmed address.
1576
+ * Any value other than 1 indicates that the customer's
1577
+ * shipping address on file with PayPal need NOT be a confirmed
1578
+ * address. Setting this element overrides the setting you have
1579
+ * specified in the recipient's Merchant Account Profile.
1580
+ * Optional Character length and limitations: One single-byte
1581
+ * numeric character.
1582
+ * @access public
1583
+ * @var string
1584
+ */
1585
+ public $ReqConfirmShipping;
1586
+
1587
+ /**
1588
+ * The value 1 indicates that you require that the customer's
1589
+ * billing address on file. Setting this element overrides the
1590
+ * setting you have specified in Admin. Optional Character
1591
+ * length and limitations: One single-byte numeric character.
1592
+ * @access public
1593
+ * @var string
1594
+ */
1595
+ public $ReqBillingAddress;
1596
+
1597
+ /**
1598
+ * The billing address for the buyer. Optional If you include
1599
+ * the BillingAddress element, the AddressType elements are
1600
+ * required: Name Street1 CityName CountryCode Do not set set
1601
+ * the CountryName element.
1602
+ * @access public
1603
+ * @var AddressType
1604
+ */
1605
+ public $BillingAddress;
1606
+
1607
+ /**
1608
+ * The value 1 indicates that on the PayPal pages, no shipping
1609
+ * address fields should be displayed whatsoever. Optional
1610
+ * Character length and limitations: Four single-byte numeric
1611
+ * characters.
1612
+ * @access public
1613
+ * @var string
1614
+ */
1615
+ public $NoShipping;
1616
+
1617
+ /**
1618
+ * The value 1 indicates that the PayPal pages should display
1619
+ * the shipping address set by you in the Address element on
1620
+ * this SetExpressCheckoutRequest, not the shipping address on
1621
+ * file with PayPal for this customer. Displaying the PayPal
1622
+ * street address on file does not allow the customer to edit
1623
+ * that address. Optional Character length and limitations:
1624
+ * Four single-byte numeric characters.
1625
+ * @access public
1626
+ * @var string
1627
+ */
1628
+ public $AddressOverride;
1629
+
1630
+ /**
1631
+ * Locale of pages displayed by PayPal during Express Checkout.
1632
+ * Optional Character length and limitations: Five single-byte
1633
+ * alphabetic characters, upper- or lowercase. Allowable
1634
+ * values: AU or en_AUDE or de_DEFR or fr_FRGB or en_GBIT or
1635
+ * it_ITJP or ja_JPUS or en_US
1636
+ * @access public
1637
+ * @var string
1638
+ */
1639
+ public $LocaleCode;
1640
+
1641
+ /**
1642
+ * Sets the Custom Payment Page Style for payment pages
1643
+ * associated with this button/link. PageStyle corresponds to
1644
+ * the HTML variable page_style for customizing payment pages.
1645
+ * The value is the same as the Page Style Name you chose when
1646
+ * adding or editing the page style from the Profile subtab of
1647
+ * the My Account tab of your PayPal account. Optional
1648
+ * Character length and limitations: 30 single-byte alphabetic
1649
+ * characters.
1650
+ * @access public
1651
+ * @var string
1652
+ */
1653
+ public $PageStyle;
1654
+
1655
+ /**
1656
+ * A URL for the image you want to appear at the top left of
1657
+ * the payment page. The image has a maximum size of 750 pixels
1658
+ * wide by 90 pixels high. PayPal recommends that you provide
1659
+ * an image that is stored on a secure (https) server. Optional
1660
+ * Character length and limitations: 127
1661
+ * @access public
1662
+ * @var string
1663
+ */
1664
+ public $cppheaderimage;
1665
+
1666
+ /**
1667
+ * Sets the border color around the header of the payment page.
1668
+ * The border is a 2-pixel perimeter around the header space,
1669
+ * which is 750 pixels wide by 90 pixels high. Optional
1670
+ * Character length and limitations: Six character HTML
1671
+ * hexadecimal color code in ASCII
1672
+ * @access public
1673
+ * @var string
1674
+ */
1675
+ public $cppheaderbordercolor;
1676
+
1677
+ /**
1678
+ * Sets the background color for the header of the payment
1679
+ * page. Optional Character length and limitation: Six
1680
+ * character HTML hexadecimal color code in ASCII
1681
+ * @access public
1682
+ * @var string
1683
+ */
1684
+ public $cppheaderbackcolor;
1685
+
1686
+ /**
1687
+ * Sets the background color for the payment page. Optional
1688
+ * Character length and limitation: Six character HTML
1689
+ * hexadecimal color code in ASCII
1690
+ * @access public
1691
+ * @var string
1692
+ */
1693
+ public $cpppayflowcolor;
1694
+
1695
+ /**
1696
+ * Sets the cart gradient color for the Mini Cart on 1X flow.
1697
+ * Optional Character length and limitation: Six character HTML
1698
+ * hexadecimal color code in ASCII
1699
+ * @access public
1700
+ * @var string
1701
+ */
1702
+ public $cppcartbordercolor;
1703
+
1704
+ /**
1705
+ * A URL for the image you want to appear above the mini-cart.
1706
+ * The image has a maximum size of 190 pixels wide by 60 pixels
1707
+ * high. PayPal recommends that you provide an image that is
1708
+ * stored on a secure (https) server. Optional Character length
1709
+ * and limitations: 127
1710
+ * @access public
1711
+ * @var string
1712
+ */
1713
+ public $cpplogoimage;
1714
+
1715
+ /**
1716
+ * Customer's shipping address. Optional If you include a
1717
+ * shipping address and set the AddressOverride element on the
1718
+ * request, PayPal returns this same address in
1719
+ * GetExpressCheckoutDetailsResponse.
1720
+ * @access public
1721
+ * @var AddressType
1722
+ */
1723
+ public $Address;
1724
+
1725
+ /**
1726
+ * How you want to obtain payment. Required Authorization
1727
+ * indicates that this payment is a basic authorization subject
1728
+ * to settlement with PayPal Authorization and Capture. Order
1729
+ * indicates that this payment is is an order authorization
1730
+ * subject to settlement with PayPal Authorization and Capture.
1731
+ * Sale indicates that this is a final sale for which you are
1732
+ * requesting payment. IMPORTANT: You cannot set PaymentAction
1733
+ * to Sale or Order on SetExpressCheckoutRequest and then
1734
+ * change PaymentAction to Authorization on the final Express
1735
+ * Checkout API, DoExpressCheckoutPaymentRequest. Character
1736
+ * length and limit: Up to 13 single-byte alphabetic characters
1737
+ * @access public
1738
+ * @var PaymentActionCodeType
1739
+ */
1740
+ public $PaymentAction;
1741
+
1742
+ /**
1743
+ * This will indicate which flow you are choosing
1744
+ * (expresschecheckout or expresscheckout optional) Optional
1745
+ * None Sole indicates that you are in the ExpressO flow Mark
1746
+ * indicates that you are in the old express flow.
1747
+ * @access public
1748
+ * @var SolutionTypeType
1749
+ */
1750
+ public $SolutionType;
1751
+
1752
+ /**
1753
+ * This indicates Which page to display for ExpressO (Billing
1754
+ * or Login) Optional None Billing indicates that you are not a
1755
+ * paypal account holder Login indicates that you are a paypal
1756
+ * account holder
1757
+ * @access public
1758
+ * @var LandingPageType
1759
+ */
1760
+ public $LandingPage;
1761
+
1762
+ /**
1763
+ * Email address of the buyer as entered during checkout.
1764
+ * PayPal uses this value to pre-fill the PayPal membership
1765
+ * sign-up portion of the PayPal login page. Optional Character
1766
+ * length and limit: 127 single-byte alphanumeric characters
1767
+ * @access public
1768
+ * @var string
1769
+ */
1770
+ public $BuyerEmail;
1771
+
1772
+ /**
1773
+ *
1774
+ * @access public
1775
+ * @var ChannelType
1776
+ */
1777
+ public $ChannelType;
1778
+
1779
+ /**
1780
+ *
1781
+ * @array
1782
+ * @access public
1783
+ * @var BillingAgreementDetailsType
1784
+ */
1785
+ public $BillingAgreementDetails;
1786
+
1787
+ /**
1788
+ * Promo Code Optional List of promo codes supplied by
1789
+ * merchant. These promo codes enable the Merchant Services
1790
+ * Promotion Financing feature.
1791
+ * @array
1792
+ * @access public
1793
+ * @var string
1794
+ */
1795
+ public $PromoCodes;
1796
+
1797
+ /**
1798
+ * Default Funding option for PayLater Checkout button.
1799
+ * @access public
1800
+ * @var string
1801
+ */
1802
+ public $PayPalCheckOutBtnType;
1803
+
1804
+ /**
1805
+ *
1806
+ * @access public
1807
+ * @var ProductCategoryType
1808
+ */
1809
+ public $ProductCategory;
1810
+
1811
+ /**
1812
+ *
1813
+ * @access public
1814
+ * @var ShippingServiceCodeType
1815
+ */
1816
+ public $ShippingMethod;
1817
+
1818
+ /**
1819
+ * Date and time (in GMT in the format yyyy-MM-ddTHH:mm:ssZ) at
1820
+ * which address was changed by the user.
1821
+ * @access public
1822
+ * @var dateTime
1823
+ */
1824
+ public $ProfileAddressChangeDate;
1825
+
1826
+ /**
1827
+ * The value 1 indicates that the customer may enter a note to
1828
+ * the merchant on the PayPal page during checkout. The note is
1829
+ * returned in the GetExpressCheckoutDetails response and the
1830
+ * DoExpressCheckoutPayment response. Optional Character length
1831
+ * and limitations: One single-byte numeric character.
1832
+ * Allowable values: 0,1
1833
+ * @access public
1834
+ * @var string
1835
+ */
1836
+ public $AllowNote;
1837
+
1838
+ /**
1839
+ * Funding source preferences.
1840
+ * @access public
1841
+ * @var FundingSourceDetailsType
1842
+ */
1843
+ public $FundingSourceDetails;
1844
+
1845
+ /**
1846
+ * The label that needs to be displayed on the cancel links in
1847
+ * the PayPal hosted checkout pages. Optional Character length
1848
+ * and limit: 127 single-byte alphanumeric characters
1849
+ * @access public
1850
+ * @var string
1851
+ */
1852
+ public $BrandName;
1853
+
1854
+ /**
1855
+ * URL for PayPal to use to retrieve shipping, handling,
1856
+ * insurance, and tax details from your website. Optional
1857
+ * Character length and limitations: 2048 characters.
1858
+ * @access public
1859
+ * @var string
1860
+ */
1861
+ public $CallbackURL;
1862
+
1863
+ /**
1864
+ * Enhanced data for different industry segments. Optional
1865
+ * @access public
1866
+ * @var EnhancedCheckoutDataType
1867
+ */
1868
+ public $EnhancedCheckoutData;
1869
+
1870
+ /**
1871
+ * List of other payment methods the user can pay with.
1872
+ * Optional Refer to the OtherPaymentMethodDetailsType for more
1873
+ * details.
1874
+ * @array
1875
+ * @access public
1876
+ * @var OtherPaymentMethodDetailsType
1877
+ */
1878
+ public $OtherPaymentMethods;
1879
+
1880
+ /**
1881
+ * Details about the buyer's account. Optional Refer to the
1882
+ * BuyerDetailsType for more details.
1883
+ * @access public
1884
+ * @var BuyerDetailsType
1885
+ */
1886
+ public $BuyerDetails;
1887
+
1888
+ /**
1889
+ * Information about the payment.
1890
+ * @array
1891
+ * @access public
1892
+ * @var PaymentDetailsType
1893
+ */
1894
+ public $PaymentDetails;
1895
+
1896
+ /**
1897
+ * List of Fall Back Shipping options provided by merchant.
1898
+ * @array
1899
+ * @access public
1900
+ * @var ShippingOptionType
1901
+ */
1902
+ public $FlatRateShippingOptions;
1903
+
1904
+ /**
1905
+ * Information about the call back timeout override.
1906
+ * @access public
1907
+ * @var string
1908
+ */
1909
+ public $CallbackTimeout;
1910
+
1911
+ /**
1912
+ * Information about the call back version.
1913
+ * @access public
1914
+ * @var string
1915
+ */
1916
+ public $CallbackVersion;
1917
+
1918
+ /**
1919
+ * Information about the Customer service number.
1920
+ * @access public
1921
+ * @var string
1922
+ */
1923
+ public $CustomerServiceNumber;
1924
+
1925
+ /**
1926
+ * Information about the Gift message enable.
1927
+ * @access public
1928
+ * @var string
1929
+ */
1930
+ public $GiftMessageEnable;
1931
+
1932
+ /**
1933
+ * Information about the Gift receipt enable.
1934
+ * @access public
1935
+ * @var string
1936
+ */
1937
+ public $GiftReceiptEnable;
1938
+
1939
+ /**
1940
+ * Information about the Gift Wrap enable.
1941
+ * @access public
1942
+ * @var string
1943
+ */
1944
+ public $GiftWrapEnable;
1945
+
1946
+ /**
1947
+ * Information about the Gift Wrap name.
1948
+ * @access public
1949
+ * @var string
1950
+ */
1951
+ public $GiftWrapName;
1952
+
1953
+ /**
1954
+ * Information about the Gift Wrap amount.
1955
+ * @access public
1956
+ * @var BasicAmountType
1957
+ */
1958
+ public $GiftWrapAmount;
1959
+
1960
+ /**
1961
+ * Information about the Buyer email option enable .
1962
+ * @access public
1963
+ * @var string
1964
+ */
1965
+ public $BuyerEmailOptInEnable;
1966
+
1967
+ /**
1968
+ * Information about the survey enable.
1969
+ * @access public
1970
+ * @var string
1971
+ */
1972
+ public $SurveyEnable;
1973
+
1974
+ /**
1975
+ * Information about the survey question.
1976
+ * @access public
1977
+ * @var string
1978
+ */
1979
+ public $SurveyQuestion;
1980
+
1981
+ /**
1982
+ * Information about the survey choices for survey question.
1983
+ * @array
1984
+ * @access public
1985
+ * @var string
1986
+ */
1987
+ public $SurveyChoice;
1988
+
1989
+ /**
1990
+ *
1991
+ * @access public
1992
+ * @var TotalType
1993
+ */
1994
+ public $TotalType;
1995
+
1996
+ /**
1997
+ * Any message the seller would like to be displayed in the
1998
+ * Mini Cart for UX.
1999
+ * @access public
2000
+ * @var string
2001
+ */
2002
+ public $NoteToBuyer;
2003
+
2004
+ /**
2005
+ * Incentive Code Optional List of incentive codes supplied by
2006
+ * ebay/merchant.
2007
+ * @array
2008
+ * @access public
2009
+ * @var IncentiveInfoType
2010
+ */
2011
+ public $Incentives;
2012
+
2013
+ /**
2014
+ * Merchant specified flag which indicates whether to return
2015
+ * Funding Instrument Details in DoEC or not. Optional
2016
+ * @access public
2017
+ * @var string
2018
+ */
2019
+ public $ReqInstrumentDetails;
2020
+
2021
+ /**
2022
+ * This element contains information that allows the merchant
2023
+ * to request to opt into external remember me on behalf of the
2024
+ * buyer or to request login bypass using external remember me.
2025
+ * Note the opt-in details are silently ignored if the
2026
+ * ExternalRememberMeID is present.
2027
+ * @access public
2028
+ * @var ExternalRememberMeOptInDetailsType
2029
+ */
2030
+ public $ExternalRememberMeOptInDetails;
2031
+
2032
+ /**
2033
+ * An optional set of values related to flow-specific details.
2034
+ * @access public
2035
+ * @var FlowControlDetailsType
2036
+ */
2037
+ public $FlowControlDetails;
2038
+
2039
+ /**
2040
+ * An optional set of values related to display-specific
2041
+ * details.
2042
+ * @access public
2043
+ * @var DisplayControlDetailsType
2044
+ */
2045
+ public $DisplayControlDetails;
2046
+
2047
+ /**
2048
+ * An optional set of values related to tracking for external
2049
+ * partner.
2050
+ * @access public
2051
+ * @var ExternalPartnerTrackingDetailsType
2052
+ */
2053
+ public $ExternalPartnerTrackingDetails;
2054
+
2055
+ /**
2056
+ * Optional element that defines relationship between buckets
2057
+ * @array
2058
+ * @access public
2059
+ * @var CoupledBucketsType
2060
+ */
2061
+ public $CoupledBuckets;
2062
+
2063
+
2064
+ public function toXMLString()
2065
+ {
2066
+ $str = '';
2067
+ if ( $this->OrderTotal != null ) {
2068
+ $str .= '<ebl:OrderTotal';
2069
+ $str .= $this->OrderTotal->toXMLString();
2070
+ $str .= '</ebl:OrderTotal>';
2071
+ }
2072
+ if ( $this->ReturnURL != null ) {
2073
+ $str .= '<ebl:ReturnURL>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ReturnURL ) . '</ebl:ReturnURL>';
2074
+ }
2075
+ if ( $this->CancelURL != null ) {
2076
+ $str .= '<ebl:CancelURL>' . PPUtils::escapeInvalidXmlCharsRegex( $this->CancelURL ) . '</ebl:CancelURL>';
2077
+ }
2078
+ if ( $this->TrackingImageURL != null ) {
2079
+ $str .= '<ebl:TrackingImageURL>' . PPUtils::escapeInvalidXmlCharsRegex( $this->TrackingImageURL ) . '</ebl:TrackingImageURL>';
2080
+ }
2081
+ if ( $this->giropaySuccessURL != null ) {
2082
+ $str .= '<ebl:giropaySuccessURL>' . PPUtils::escapeInvalidXmlCharsRegex( $this->giropaySuccessURL ) . '</ebl:giropaySuccessURL>';
2083
+ }
2084
+ if ( $this->giropayCancelURL != null ) {
2085
+ $str .= '<ebl:giropayCancelURL>' . PPUtils::escapeInvalidXmlCharsRegex( $this->giropayCancelURL ) . '</ebl:giropayCancelURL>';
2086
+ }
2087
+ if ( $this->BanktxnPendingURL != null ) {
2088
+ $str .= '<ebl:BanktxnPendingURL>' . PPUtils::escapeInvalidXmlCharsRegex( $this->BanktxnPendingURL ) . '</ebl:BanktxnPendingURL>';
2089
+ }
2090
+ if ( $this->Token != null ) {
2091
+ $str .= '<ebl:Token>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Token ) . '</ebl:Token>';
2092
+ }
2093
+ if ( $this->MaxAmount != null ) {
2094
+ $str .= '<ebl:MaxAmount';
2095
+ $str .= $this->MaxAmount->toXMLString();
2096
+ $str .= '</ebl:MaxAmount>';
2097
+ }
2098
+ if ( $this->OrderDescription != null ) {
2099
+ $str .= '<ebl:OrderDescription>' . PPUtils::escapeInvalidXmlCharsRegex( $this->OrderDescription ) . '</ebl:OrderDescription>';
2100
+ }
2101
+ if ( $this->Custom != null ) {
2102
+ $str .= '<ebl:Custom>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Custom ) . '</ebl:Custom>';
2103
+ }
2104
+ if ( $this->InvoiceID != null ) {
2105
+ $str .= '<ebl:InvoiceID>' . PPUtils::escapeInvalidXmlCharsRegex( $this->InvoiceID ) . '</ebl:InvoiceID>';
2106
+ }
2107
+ if ( $this->ReqConfirmShipping != null ) {
2108
+ $str .= '<ebl:ReqConfirmShipping>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ReqConfirmShipping ) . '</ebl:ReqConfirmShipping>';
2109
+ }
2110
+ if ( $this->ReqBillingAddress != null ) {
2111
+ $str .= '<ebl:ReqBillingAddress>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ReqBillingAddress ) . '</ebl:ReqBillingAddress>';
2112
+ }
2113
+ if ( $this->BillingAddress != null ) {
2114
+ $str .= '<ebl:BillingAddress>';
2115
+ $str .= $this->BillingAddress->toXMLString();
2116
+ $str .= '</ebl:BillingAddress>';
2117
+ }
2118
+ if ( $this->NoShipping != null ) {
2119
+ $str .= '<ebl:NoShipping>' . PPUtils::escapeInvalidXmlCharsRegex( $this->NoShipping ) . '</ebl:NoShipping>';
2120
+ }
2121
+ if ( $this->AddressOverride != null ) {
2122
+ $str .= '<ebl:AddressOverride>' . PPUtils::escapeInvalidXmlCharsRegex( $this->AddressOverride ) . '</ebl:AddressOverride>';
2123
+ }
2124
+ if ( $this->LocaleCode != null ) {
2125
+ $str .= '<ebl:LocaleCode>' . PPUtils::escapeInvalidXmlCharsRegex( $this->LocaleCode ) . '</ebl:LocaleCode>';
2126
+ }
2127
+ if ( $this->PageStyle != null ) {
2128
+ $str .= '<ebl:PageStyle>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PageStyle ) . '</ebl:PageStyle>';
2129
+ }
2130
+ if ( $this->cppheaderimage != null ) {
2131
+ $str .= '<ebl:cpp-header-image>' . PPUtils::escapeInvalidXmlCharsRegex( $this->cppheaderimage ) . '</ebl:cpp-header-image>';
2132
+ }
2133
+ if ( $this->cppheaderbordercolor != null ) {
2134
+ $str .= '<ebl:cpp-header-border-color>' . PPUtils::escapeInvalidXmlCharsRegex( $this->cppheaderbordercolor ) . '</ebl:cpp-header-border-color>';
2135
+ }
2136
+ if ( $this->cppheaderbackcolor != null ) {
2137
+ $str .= '<ebl:cpp-header-back-color>' . PPUtils::escapeInvalidXmlCharsRegex( $this->cppheaderbackcolor ) . '</ebl:cpp-header-back-color>';
2138
+ }
2139
+ if ( $this->cpppayflowcolor != null ) {
2140
+ $str .= '<ebl:cpp-payflow-color>' . PPUtils::escapeInvalidXmlCharsRegex( $this->cpppayflowcolor ) . '</ebl:cpp-payflow-color>';
2141
+ }
2142
+ if ( $this->cppcartbordercolor != null ) {
2143
+ $str .= '<ebl:cpp-cart-border-color>' . PPUtils::escapeInvalidXmlCharsRegex( $this->cppcartbordercolor ) . '</ebl:cpp-cart-border-color>';
2144
+ }
2145
+ if ( $this->cpplogoimage != null ) {
2146
+ $str .= '<ebl:cpp-logo-image>' . PPUtils::escapeInvalidXmlCharsRegex( $this->cpplogoimage ) . '</ebl:cpp-logo-image>';
2147
+ }
2148
+ if ( $this->Address != null ) {
2149
+ $str .= '<ebl:Address>';
2150
+ $str .= $this->Address->toXMLString();
2151
+ $str .= '</ebl:Address>';
2152
+ }
2153
+ if ( $this->PaymentAction != null ) {
2154
+ $str .= '<ebl:PaymentAction>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PaymentAction ) . '</ebl:PaymentAction>';
2155
+ }
2156
+ if ( $this->SolutionType != null ) {
2157
+ $str .= '<ebl:SolutionType>' . PPUtils::escapeInvalidXmlCharsRegex( $this->SolutionType ) . '</ebl:SolutionType>';
2158
+ }
2159
+ if ( $this->LandingPage != null ) {
2160
+ $str .= '<ebl:LandingPage>' . PPUtils::escapeInvalidXmlCharsRegex( $this->LandingPage ) . '</ebl:LandingPage>';
2161
+ }
2162
+ if ( $this->BuyerEmail != null ) {
2163
+ $str .= '<ebl:BuyerEmail>' . PPUtils::escapeInvalidXmlCharsRegex( $this->BuyerEmail ) . '</ebl:BuyerEmail>';
2164
+ }
2165
+ if ( $this->ChannelType != null ) {
2166
+ $str .= '<ebl:ChannelType>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ChannelType ) . '</ebl:ChannelType>';
2167
+ }
2168
+ if ( $this->BillingAgreementDetails != null ) {
2169
+ for ( $i = 0; $i < count( $this->BillingAgreementDetails ); $i++ ) {
2170
+ $str .= '<ebl:BillingAgreementDetails>';
2171
+ $str .= $this->BillingAgreementDetails[ $i ]->toXMLString();
2172
+ $str .= '</ebl:BillingAgreementDetails>';
2173
+ }
2174
+ }
2175
+ if ( $this->PromoCodes != null ) {
2176
+ for ( $i = 0; $i < count( $this->PromoCodes ); $i++ ) {
2177
+ $str .= '<ebl:PromoCodes>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PromoCodes[ $i ] ) . '</ebl:PromoCodes>';
2178
+ }
2179
+ }
2180
+ if ( $this->PayPalCheckOutBtnType != null ) {
2181
+ $str .= '<ebl:PayPalCheckOutBtnType>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PayPalCheckOutBtnType ) . '</ebl:PayPalCheckOutBtnType>';
2182
+ }
2183
+ if ( $this->ProductCategory != null ) {
2184
+ $str .= '<ebl:ProductCategory>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ProductCategory ) . '</ebl:ProductCategory>';
2185
+ }
2186
+ if ( $this->ShippingMethod != null ) {
2187
+ $str .= '<ebl:ShippingMethod>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ShippingMethod ) . '</ebl:ShippingMethod>';
2188
+ }
2189
+ if ( $this->ProfileAddressChangeDate != null ) {
2190
+ $str .= '<ebl:ProfileAddressChangeDate>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ProfileAddressChangeDate ) . '</ebl:ProfileAddressChangeDate>';
2191
+ }
2192
+ if ( $this->AllowNote != null ) {
2193
+ $str .= '<ebl:AllowNote>' . PPUtils::escapeInvalidXmlCharsRegex( $this->AllowNote ) . '</ebl:AllowNote>';
2194
+ }
2195
+ if ( $this->FundingSourceDetails != null ) {
2196
+ $str .= '<ebl:FundingSourceDetails>';
2197
+ $str .= $this->FundingSourceDetails->toXMLString();
2198
+ $str .= '</ebl:FundingSourceDetails>';
2199
+ }
2200
+ if ( $this->BrandName != null ) {
2201
+ $str .= '<ebl:BrandName>' . PPUtils::escapeInvalidXmlCharsRegex( $this->BrandName ) . '</ebl:BrandName>';
2202
+ }
2203
+ if ( $this->CallbackURL != null ) {
2204
+ $str .= '<ebl:CallbackURL>' . PPUtils::escapeInvalidXmlCharsRegex( $this->CallbackURL ) . '</ebl:CallbackURL>';
2205
+ }
2206
+ if ( $this->EnhancedCheckoutData != null ) {
2207
+ $str .= '<ebl:EnhancedCheckoutData>';
2208
+ $str .= $this->EnhancedCheckoutData->toXMLString();
2209
+ $str .= '</ebl:EnhancedCheckoutData>';
2210
+ }
2211
+ if ( $this->OtherPaymentMethods != null ) {
2212
+ for ( $i = 0; $i < count( $this->OtherPaymentMethods ); $i++ ) {
2213
+ $str .= '<ebl:OtherPaymentMethods>';
2214
+ $str .= $this->OtherPaymentMethods[ $i ]->toXMLString();
2215
+ $str .= '</ebl:OtherPaymentMethods>';
2216
+ }
2217
+ }
2218
+ if ( $this->BuyerDetails != null ) {
2219
+ $str .= '<ebl:BuyerDetails>';
2220
+ $str .= $this->BuyerDetails->toXMLString();
2221
+ $str .= '</ebl:BuyerDetails>';
2222
+ }
2223
+ if ( $this->PaymentDetails != null ) {
2224
+ for ( $i = 0; $i < count( $this->PaymentDetails ); $i++ ) {
2225
+ $str .= '<ebl:PaymentDetails>';
2226
+ $str .= $this->PaymentDetails[ $i ]->toXMLString();
2227
+ $str .= '</ebl:PaymentDetails>';
2228
+ }
2229
+ }
2230
+ if ( $this->FlatRateShippingOptions != null ) {
2231
+ for ( $i = 0; $i < count( $this->FlatRateShippingOptions ); $i++ ) {
2232
+ $str .= '<ebl:FlatRateShippingOptions>';
2233
+ $str .= $this->FlatRateShippingOptions[ $i ]->toXMLString();
2234
+ $str .= '</ebl:FlatRateShippingOptions>';
2235
+ }
2236
+ }
2237
+ if ( $this->CallbackTimeout != null ) {
2238
+ $str .= '<ebl:CallbackTimeout>' . PPUtils::escapeInvalidXmlCharsRegex( $this->CallbackTimeout ) . '</ebl:CallbackTimeout>';
2239
+ }
2240
+ if ( $this->CallbackVersion != null ) {
2241
+ $str .= '<ebl:CallbackVersion>' . PPUtils::escapeInvalidXmlCharsRegex( $this->CallbackVersion ) . '</ebl:CallbackVersion>';
2242
+ }
2243
+ if ( $this->CustomerServiceNumber != null ) {
2244
+ $str .= '<ebl:CustomerServiceNumber>' . PPUtils::escapeInvalidXmlCharsRegex( $this->CustomerServiceNumber ) . '</ebl:CustomerServiceNumber>';
2245
+ }
2246
+ if ( $this->GiftMessageEnable != null ) {
2247
+ $str .= '<ebl:GiftMessageEnable>' . PPUtils::escapeInvalidXmlCharsRegex( $this->GiftMessageEnable ) . '</ebl:GiftMessageEnable>';
2248
+ }
2249
+ if ( $this->GiftReceiptEnable != null ) {
2250
+ $str .= '<ebl:GiftReceiptEnable>' . PPUtils::escapeInvalidXmlCharsRegex( $this->GiftReceiptEnable ) . '</ebl:GiftReceiptEnable>';
2251
+ }
2252
+ if ( $this->GiftWrapEnable != null ) {
2253
+ $str .= '<ebl:GiftWrapEnable>' . PPUtils::escapeInvalidXmlCharsRegex( $this->GiftWrapEnable ) . '</ebl:GiftWrapEnable>';
2254
+ }
2255
+ if ( $this->GiftWrapName != null ) {
2256
+ $str .= '<ebl:GiftWrapName>' . PPUtils::escapeInvalidXmlCharsRegex( $this->GiftWrapName ) . '</ebl:GiftWrapName>';
2257
+ }
2258
+ if ( $this->GiftWrapAmount != null ) {
2259
+ $str .= '<ebl:GiftWrapAmount';
2260
+ $str .= $this->GiftWrapAmount->toXMLString();
2261
+ $str .= '</ebl:GiftWrapAmount>';
2262
+ }
2263
+ if ( $this->BuyerEmailOptInEnable != null ) {
2264
+ $str .= '<ebl:BuyerEmailOptInEnable>' . PPUtils::escapeInvalidXmlCharsRegex( $this->BuyerEmailOptInEnable ) . '</ebl:BuyerEmailOptInEnable>';
2265
+ }
2266
+ if ( $this->SurveyEnable != null ) {
2267
+ $str .= '<ebl:SurveyEnable>' . PPUtils::escapeInvalidXmlCharsRegex( $this->SurveyEnable ) . '</ebl:SurveyEnable>';
2268
+ }
2269
+ if ( $this->SurveyQuestion != null ) {
2270
+ $str .= '<ebl:SurveyQuestion>' . PPUtils::escapeInvalidXmlCharsRegex( $this->SurveyQuestion ) . '</ebl:SurveyQuestion>';
2271
+ }
2272
+ if ( $this->SurveyChoice != null ) {
2273
+ for ( $i = 0; $i < count( $this->SurveyChoice ); $i++ ) {
2274
+ $str .= '<ebl:SurveyChoice>' . PPUtils::escapeInvalidXmlCharsRegex( $this->SurveyChoice[ $i ] ) . '</ebl:SurveyChoice>';
2275
+ }
2276
+ }
2277
+ if ( $this->TotalType != null ) {
2278
+ $str .= '<ebl:TotalType>' . PPUtils::escapeInvalidXmlCharsRegex( $this->TotalType ) . '</ebl:TotalType>';
2279
+ }
2280
+ if ( $this->NoteToBuyer != null ) {
2281
+ $str .= '<ebl:NoteToBuyer>' . PPUtils::escapeInvalidXmlCharsRegex( $this->NoteToBuyer ) . '</ebl:NoteToBuyer>';
2282
+ }
2283
+ if ( $this->Incentives != null ) {
2284
+ for ( $i = 0; $i < count( $this->Incentives ); $i++ ) {
2285
+ $str .= '<ebl:Incentives>';
2286
+ $str .= $this->Incentives[ $i ]->toXMLString();
2287
+ $str .= '</ebl:Incentives>';
2288
+ }
2289
+ }
2290
+ if ( $this->ReqInstrumentDetails != null ) {
2291
+ $str .= '<ebl:ReqInstrumentDetails>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ReqInstrumentDetails ) . '</ebl:ReqInstrumentDetails>';
2292
+ }
2293
+ if ( $this->ExternalRememberMeOptInDetails != null ) {
2294
+ $str .= '<ebl:ExternalRememberMeOptInDetails>';
2295
+ $str .= $this->ExternalRememberMeOptInDetails->toXMLString();
2296
+ $str .= '</ebl:ExternalRememberMeOptInDetails>';
2297
+ }
2298
+ if ( $this->FlowControlDetails != null ) {
2299
+ $str .= '<ebl:FlowControlDetails>';
2300
+ $str .= $this->FlowControlDetails->toXMLString();
2301
+ $str .= '</ebl:FlowControlDetails>';
2302
+ }
2303
+ if ( $this->DisplayControlDetails != null ) {
2304
+ $str .= '<ebl:DisplayControlDetails>';
2305
+ $str .= $this->DisplayControlDetails->toXMLString();
2306
+ $str .= '</ebl:DisplayControlDetails>';
2307
+ }
2308
+ if ( $this->ExternalPartnerTrackingDetails != null ) {
2309
+ $str .= '<ebl:ExternalPartnerTrackingDetails>';
2310
+ $str .= $this->ExternalPartnerTrackingDetails->toXMLString();
2311
+ $str .= '</ebl:ExternalPartnerTrackingDetails>';
2312
+ }
2313
+ if ( $this->CoupledBuckets != null ) {
2314
+ for ( $i = 0; $i < count( $this->CoupledBuckets ); $i++ ) {
2315
+ $str .= '<ebl:CoupledBuckets>';
2316
+ $str .= $this->CoupledBuckets[ $i ]->toXMLString();
2317
+ $str .= '</ebl:CoupledBuckets>';
2318
+ }
2319
+ }
2320
+
2321
+ return $str;
2322
+ }
2323
+
2324
+
2325
+ }
2326
+
2327
+
2328
+ /**
2329
+ * On your first invocation of
2330
+ * ExecuteCheckoutOperationsRequest, the value of this token is
2331
+ * returned by ExecuteCheckoutOperationsResponse. Optional
2332
+ * Include this element and its value only if you want to
2333
+ * modify an existing checkout session with another invocation
2334
+ * of ExecuteCheckoutOperationsRequest; for example, if you
2335
+ * want the customer to edit his shipping address on PayPal.
2336
+ * Character length and limitations: 20 single-byte characters
2337
+ */
2338
+ class ExecuteCheckoutOperationsRequestDetailsType
2339
+ {
2340
+
2341
+ /**
2342
+ * On your first invocation of
2343
+ * ExecuteCheckoutOperationsRequest, the value of this token is
2344
+ * returned by ExecuteCheckoutOperationsResponse. Optional
2345
+ * Include this element and its value only if you want to
2346
+ * modify an existing checkout session with another invocation
2347
+ * of ExecuteCheckoutOperationsRequest; for example, if you
2348
+ * want the customer to edit his shipping address on PayPal.
2349
+ * Character length and limitations: 20 single-byte characters
2350
+ * @access public
2351
+ * @var string
2352
+ */
2353
+ public $Token;
2354
+
2355
+ /**
2356
+ * All the Data required to initiate the checkout session is
2357
+ * passed in this element.
2358
+ * @access public
2359
+ * @var SetDataRequestType
2360
+ */
2361
+ public $SetDataRequest;
2362
+
2363
+ /**
2364
+ * If auto authorization is required, this should be passed in
2365
+ * with IsRequested set to yes.
2366
+ * @access public
2367
+ * @var AuthorizationRequestType
2368
+ */
2369
+ public $AuthorizationRequest;
2370
+
2371
+ /**
2372
+ * Constructor with arguments
2373
+ */
2374
+ public function __construct( $SetDataRequest = null )
2375
+ {
2376
+ $this->SetDataRequest = $SetDataRequest;
2377
+ }
2378
+
2379
+
2380
+ public function toXMLString()
2381
+ {
2382
+ $str = '';
2383
+ if ( $this->Token != null ) {
2384
+ $str .= '<ebl:Token>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Token ) . '</ebl:Token>';
2385
+ }
2386
+ if ( $this->SetDataRequest != null ) {
2387
+ $str .= '<ebl:SetDataRequest>';
2388
+ $str .= $this->SetDataRequest->toXMLString();
2389
+ $str .= '</ebl:SetDataRequest>';
2390
+ }
2391
+ if ( $this->AuthorizationRequest != null ) {
2392
+ $str .= '<ebl:AuthorizationRequest>';
2393
+ $str .= $this->AuthorizationRequest->toXMLString();
2394
+ $str .= '</ebl:AuthorizationRequest>';
2395
+ }
2396
+
2397
+ return $str;
2398
+ }
2399
+
2400
+
2401
+ }
2402
+
2403
+
2404
+ /**
2405
+ * Details about Billing Agreements requested to be created.
2406
+ */
2407
+ class SetDataRequestType
2408
+ {
2409
+
2410
+ /**
2411
+ * Details about Billing Agreements requested to be created.
2412
+ * @array
2413
+ * @access public
2414
+ * @var BillingApprovalDetailsType
2415
+ */
2416
+ public $BillingApprovalDetails;
2417
+
2418
+ /**
2419
+ * Only needed if Auto Authorization is requested. The
2420
+ * authentication session token will be passed in here.
2421
+ * @access public
2422
+ * @var BuyerDetailType
2423
+ */
2424
+ public $BuyerDetail;
2425
+
2426
+ /**
2427
+ * Requests for specific buyer information like Billing Address
2428
+ * to be returned through GetExpressCheckoutDetails should be
2429
+ * specified under this.
2430
+ * @access public
2431
+ * @var InfoSharingDirectivesType
2432
+ */
2433
+ public $InfoSharingDirectives;
2434
+
2435
+
2436
+ public function toXMLString()
2437
+ {
2438
+ $str = '';
2439
+ if ( $this->BillingApprovalDetails != null ) {
2440
+ for ( $i = 0; $i < count( $this->BillingApprovalDetails ); $i++ ) {
2441
+ $str .= '<ebl:BillingApprovalDetails>';
2442
+ $str .= $this->BillingApprovalDetails[ $i ]->toXMLString();
2443
+ $str .= '</ebl:BillingApprovalDetails>';
2444
+ }
2445
+ }
2446
+ if ( $this->BuyerDetail != null ) {
2447
+ $str .= '<ebl:BuyerDetail>';
2448
+ $str .= $this->BuyerDetail->toXMLString();
2449
+ $str .= '</ebl:BuyerDetail>';
2450
+ }
2451
+ if ( $this->InfoSharingDirectives != null ) {
2452
+ $str .= '<ebl:InfoSharingDirectives>';
2453
+ $str .= $this->InfoSharingDirectives->toXMLString();
2454
+ $str .= '</ebl:InfoSharingDirectives>';
2455
+ }
2456
+
2457
+ return $str;
2458
+ }
2459
+
2460
+
2461
+ }
2462
+
2463
+
2464
+ /**
2465
+ *
2466
+ */
2467
+ class AuthorizationRequestType
2468
+ {
2469
+
2470
+ /**
2471
+ *
2472
+ * @access public
2473
+ * @var boolean
2474
+ */
2475
+ public $IsRequested;
2476
+
2477
+ /**
2478
+ * Constructor with arguments
2479
+ */
2480
+ public function __construct( $IsRequested = null )
2481
+ {
2482
+ $this->IsRequested = $IsRequested;
2483
+ }
2484
+
2485
+
2486
+ public function toXMLString()
2487
+ {
2488
+ $str = '';
2489
+ if ( $this->IsRequested != null ) {
2490
+ $str .= '<ebl:IsRequested>' . PPUtils::escapeInvalidXmlCharsRegex( $this->IsRequested ) . '</ebl:IsRequested>';
2491
+ }
2492
+
2493
+ return $str;
2494
+ }
2495
+
2496
+
2497
+ }
2498
+
2499
+
2500
+ /**
2501
+ * The Type of Approval requested - Billing Agreement or
2502
+ * Profile
2503
+ */
2504
+ class BillingApprovalDetailsType
2505
+ {
2506
+
2507
+ /**
2508
+ * The Type of Approval requested - Billing Agreement or
2509
+ * Profile
2510
+ * @access public
2511
+ * @var ApprovalTypeType
2512
+ */
2513
+ public $ApprovalType;
2514
+
2515
+ /**
2516
+ * The Approval subtype - Must be MerchantInitiatedBilling for
2517
+ * BillingAgreement ApprovalType
2518
+ * @access public
2519
+ * @var ApprovalSubTypeType
2520
+ */
2521
+ public $ApprovalSubType;
2522
+
2523
+ /**
2524
+ * Description about the Order
2525
+ * @access public
2526
+ * @var OrderDetailsType
2527
+ */
2528
+ public $OrderDetails;
2529
+
2530
+ /**
2531
+ * Directives about the type of payment
2532
+ * @access public
2533
+ * @var PaymentDirectivesType
2534
+ */
2535
+ public $PaymentDirectives;
2536
+
2537
+ /**
2538
+ * Client may pass in its identification of this Billing
2539
+ * Agreement. It used for the client's tracking purposes.
2540
+ * @access public
2541
+ * @var string
2542
+ */
2543
+ public $Custom;
2544
+
2545
+ /**
2546
+ * Constructor with arguments
2547
+ */
2548
+ public function __construct( $ApprovalType = null )
2549
+ {
2550
+ $this->ApprovalType = $ApprovalType;
2551
+ }
2552
+
2553
+
2554
+ public function toXMLString()
2555
+ {
2556
+ $str = '';
2557
+ if ( $this->ApprovalType != null ) {
2558
+ $str .= '<ebl:ApprovalType>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ApprovalType ) . '</ebl:ApprovalType>';
2559
+ }
2560
+ if ( $this->ApprovalSubType != null ) {
2561
+ $str .= '<ebl:ApprovalSubType>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ApprovalSubType ) . '</ebl:ApprovalSubType>';
2562
+ }
2563
+ if ( $this->OrderDetails != null ) {
2564
+ $str .= '<ebl:OrderDetails>';
2565
+ $str .= $this->OrderDetails->toXMLString();
2566
+ $str .= '</ebl:OrderDetails>';
2567
+ }
2568
+ if ( $this->PaymentDirectives != null ) {
2569
+ $str .= '<ebl:PaymentDirectives>';
2570
+ $str .= $this->PaymentDirectives->toXMLString();
2571
+ $str .= '</ebl:PaymentDirectives>';
2572
+ }
2573
+ if ( $this->Custom != null ) {
2574
+ $str .= '<ebl:Custom>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Custom ) . '</ebl:Custom>';
2575
+ }
2576
+
2577
+ return $str;
2578
+ }
2579
+
2580
+
2581
+ }
2582
+
2583
+
2584
+ /**
2585
+ * If Billing Address should be returned in
2586
+ * GetExpressCheckoutDetails response, this parameter should be
2587
+ * set to yes here
2588
+ */
2589
+ class InfoSharingDirectivesType
2590
+ {
2591
+
2592
+ /**
2593
+ * If Billing Address should be returned in
2594
+ * GetExpressCheckoutDetails response, this parameter should be
2595
+ * set to yes here
2596
+ * @access public
2597
+ * @var string
2598
+ */
2599
+ public $ReqBillingAddress;
2600
+
2601
+
2602
+ public function toXMLString()
2603
+ {
2604
+ $str = '';
2605
+ if ( $this->ReqBillingAddress != null ) {
2606
+ $str .= '<ebl:ReqBillingAddress>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ReqBillingAddress ) . '</ebl:ReqBillingAddress>';
2607
+ }
2608
+
2609
+ return $str;
2610
+ }
2611
+
2612
+
2613
+ }
2614
+
2615
+
2616
+ /**
2617
+ * Description of the Order.
2618
+ */
2619
+ class OrderDetailsType
2620
+ {
2621
+
2622
+ /**
2623
+ * Description of the Order.
2624
+ * @access public
2625
+ * @var string
2626
+ */
2627
+ public $Description;
2628
+
2629
+ /**
2630
+ * Expected maximum amount that the merchant may pull using
2631
+ * DoReferenceTransaction
2632
+ * @access public
2633
+ * @var BasicAmountType
2634
+ */
2635
+ public $MaxAmount;
2636
+
2637
+
2638
+ public function toXMLString()
2639
+ {
2640
+ $str = '';
2641
+ if ( $this->Description != null ) {
2642
+ $str .= '<ebl:Description>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Description ) . '</ebl:Description>';
2643
+ }
2644
+ if ( $this->MaxAmount != null ) {
2645
+ $str .= '<ebl:MaxAmount';
2646
+ $str .= $this->MaxAmount->toXMLString();
2647
+ $str .= '</ebl:MaxAmount>';
2648
+ }
2649
+
2650
+ return $str;
2651
+ }
2652
+
2653
+
2654
+ }
2655
+
2656
+
2657
+ /**
2658
+ * Type of the Payment is it Instant or Echeck or Any.
2659
+ */
2660
+ class PaymentDirectivesType
2661
+ {
2662
+
2663
+ /**
2664
+ * Type of the Payment is it Instant or Echeck or Any.
2665
+ * @access public
2666
+ * @var MerchantPullPaymentCodeType
2667
+ */
2668
+ public $PaymentType;
2669
+
2670
+
2671
+ public function toXMLString()
2672
+ {
2673
+ $str = '';
2674
+ if ( $this->PaymentType != null ) {
2675
+ $str .= '<ebl:PaymentType>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PaymentType ) . '</ebl:PaymentType>';
2676
+ }
2677
+
2678
+ return $str;
2679
+ }
2680
+
2681
+
2682
+ }
2683
+
2684
+
2685
+ /**
2686
+ * Information that is used to indentify the Buyer. This is
2687
+ * used for auto authorization. Mandatory if Authorization is
2688
+ * requested.
2689
+ */
2690
+ class BuyerDetailType
2691
+ {
2692
+
2693
+ /**
2694
+ * Information that is used to indentify the Buyer. This is
2695
+ * used for auto authorization. Mandatory if Authorization is
2696
+ * requested.
2697
+ * @access public
2698
+ * @var IdentificationInfoType
2699
+ */
2700
+ public $IdentificationInfo;
2701
+
2702
+
2703
+ public function toXMLString()
2704
+ {
2705
+ $str = '';
2706
+ if ( $this->IdentificationInfo != null ) {
2707
+ $str .= '<ebl:IdentificationInfo>';
2708
+ $str .= $this->IdentificationInfo->toXMLString();
2709
+ $str .= '</ebl:IdentificationInfo>';
2710
+ }
2711
+
2712
+ return $str;
2713
+ }
2714
+
2715
+
2716
+ }
2717
+
2718
+
2719
+ /**
2720
+ * Mobile specific buyer identification.
2721
+ */
2722
+ class IdentificationInfoType
2723
+ {
2724
+
2725
+ /**
2726
+ * Mobile specific buyer identification.
2727
+ * @access public
2728
+ * @var MobileIDInfoType
2729
+ */
2730
+ public $MobileIDInfo;
2731
+
2732
+ /**
2733
+ * Contains login bypass information.
2734
+ * @access public
2735
+ * @var RememberMeIDInfoType
2736
+ */
2737
+ public $RememberMeIDInfo;
2738
+
2739
+ /**
2740
+ * Identity Access Token.
2741
+ * @access public
2742
+ * @var IdentityTokenInfoType
2743
+ */
2744
+ public $IdentityTokenInfo;
2745
+
2746
+
2747
+ public function toXMLString()
2748
+ {
2749
+ $str = '';
2750
+ if ( $this->MobileIDInfo != null ) {
2751
+ $str .= '<ebl:MobileIDInfo>';
2752
+ $str .= $this->MobileIDInfo->toXMLString();
2753
+ $str .= '</ebl:MobileIDInfo>';
2754
+ }
2755
+ if ( $this->RememberMeIDInfo != null ) {
2756
+ $str .= '<ebl:RememberMeIDInfo>';
2757
+ $str .= $this->RememberMeIDInfo->toXMLString();
2758
+ $str .= '</ebl:RememberMeIDInfo>';
2759
+ }
2760
+ if ( $this->IdentityTokenInfo != null ) {
2761
+ $str .= '<ebl:IdentityTokenInfo>';
2762
+ $str .= $this->IdentityTokenInfo->toXMLString();
2763
+ $str .= '</ebl:IdentityTokenInfo>';
2764
+ }
2765
+
2766
+ return $str;
2767
+ }
2768
+
2769
+
2770
+ }
2771
+
2772
+
2773
+ /**
2774
+ * The Session token returned during buyer authentication.
2775
+ */
2776
+ class MobileIDInfoType
2777
+ {
2778
+
2779
+ /**
2780
+ * The Session token returned during buyer authentication.
2781
+ * @access public
2782
+ * @var string
2783
+ */
2784
+ public $SessionToken;
2785
+
2786
+
2787
+ public function toXMLString()
2788
+ {
2789
+ $str = '';
2790
+ if ( $this->SessionToken != null ) {
2791
+ $str .= '<ebl:SessionToken>' . PPUtils::escapeInvalidXmlCharsRegex( $this->SessionToken ) . '</ebl:SessionToken>';
2792
+ }
2793
+
2794
+ return $str;
2795
+ }
2796
+
2797
+
2798
+ }
2799
+
2800
+
2801
+ /**
2802
+ * External remember-me ID returned by
2803
+ * GetExpressCheckoutDetails on successful opt-in. The
2804
+ * ExternalRememberMeID is a 17-character alphanumeric
2805
+ * (encrypted) string that identifies the buyer's remembered
2806
+ * login with a merchant and has meaning only to the merchant.
2807
+ * If present, requests that the web flow attempt bypass of
2808
+ * login.
2809
+ */
2810
+ class RememberMeIDInfoType
2811
+ {
2812
+
2813
+ /**
2814
+ * External remember-me ID returned by
2815
+ * GetExpressCheckoutDetails on successful opt-in. The
2816
+ * ExternalRememberMeID is a 17-character alphanumeric
2817
+ * (encrypted) string that identifies the buyer's remembered
2818
+ * login with a merchant and has meaning only to the merchant.
2819
+ * If present, requests that the web flow attempt bypass of
2820
+ * login.
2821
+ * @access public
2822
+ * @var string
2823
+ */
2824
+ public $ExternalRememberMeID;
2825
+
2826
+
2827
+ public function toXMLString()
2828
+ {
2829
+ $str = '';
2830
+ if ( $this->ExternalRememberMeID != null ) {
2831
+ $str .= '<ebl:ExternalRememberMeID>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ExternalRememberMeID ) . '</ebl:ExternalRememberMeID>';
2832
+ }
2833
+
2834
+ return $str;
2835
+ }
2836
+
2837
+
2838
+ }
2839
+
2840
+
2841
+ /**
2842
+ * Identity Access token from merchant
2843
+ */
2844
+ class IdentityTokenInfoType
2845
+ {
2846
+
2847
+ /**
2848
+ * Identity Access token from merchant
2849
+ * @access public
2850
+ * @var string
2851
+ */
2852
+ public $AccessToken;
2853
+
2854
+ /**
2855
+ * Constructor with arguments
2856
+ */
2857
+ public function __construct( $AccessToken = null )
2858
+ {
2859
+ $this->AccessToken = $AccessToken;
2860
+ }
2861
+
2862
+
2863
+ public function toXMLString()
2864
+ {
2865
+ $str = '';
2866
+ if ( $this->AccessToken != null ) {
2867
+ $str .= '<ebl:AccessToken>' . PPUtils::escapeInvalidXmlCharsRegex( $this->AccessToken ) . '</ebl:AccessToken>';
2868
+ }
2869
+
2870
+ return $str;
2871
+ }
2872
+
2873
+
2874
+ }
2875
+
2876
+
2877
+ /**
2878
+ * Allowable values: 0,1 The value 1 indicates that the
2879
+ * customer can accept push funding, and 0 means they cannot.
2880
+ * Optional Character length and limitations: One single-byte
2881
+ * numeric character.
2882
+ */
2883
+ class FundingSourceDetailsType
2884
+ {
2885
+
2886
+ /**
2887
+ * Allowable values: 0,1 The value 1 indicates that the
2888
+ * customer can accept push funding, and 0 means they cannot.
2889
+ * Optional Character length and limitations: One single-byte
2890
+ * numeric character.
2891
+ * @access public
2892
+ * @var string
2893
+ */
2894
+ public $AllowPushFunding;
2895
+
2896
+ /**
2897
+ * Allowable values: ELV, CreditCard, ChinaUnionPay, BML This
2898
+ * element could be used to specify the perered funding option
2899
+ * for a guest users. It has effect only if LandingPage element
2900
+ * is set to Billing. Otherwise it will be ignored.
2901
+ * @access public
2902
+ * @var UserSelectedFundingSourceType
2903
+ */
2904
+ public $UserSelectedFundingSource;
2905
+
2906
+
2907
+ public function toXMLString()
2908
+ {
2909
+ $str = '';
2910
+ if ( $this->AllowPushFunding != null ) {
2911
+ $str .= '<ebl:AllowPushFunding>' . PPUtils::escapeInvalidXmlCharsRegex( $this->AllowPushFunding ) . '</ebl:AllowPushFunding>';
2912
+ }
2913
+ if ( $this->UserSelectedFundingSource != null ) {
2914
+ $str .= '<ebl:UserSelectedFundingSource>' . PPUtils::escapeInvalidXmlCharsRegex( $this->UserSelectedFundingSource ) . '</ebl:UserSelectedFundingSource>';
2915
+ }
2916
+
2917
+ return $str;
2918
+ }
2919
+
2920
+
2921
+ }
2922
+
2923
+
2924
+ /**
2925
+ *
2926
+ */
2927
+ class BillingAgreementDetailsType
2928
+ {
2929
+
2930
+ /**
2931
+ *
2932
+ * @access public
2933
+ * @var BillingCodeType
2934
+ */
2935
+ public $BillingType;
2936
+
2937
+ /**
2938
+ * Only needed for AutoBill billinng type.
2939
+ * @access public
2940
+ * @var string
2941
+ */
2942
+ public $BillingAgreementDescription;
2943
+
2944
+ /**
2945
+ *
2946
+ * @access public
2947
+ * @var MerchantPullPaymentCodeType
2948
+ */
2949
+ public $PaymentType;
2950
+
2951
+ /**
2952
+ * Custom annotation field for your exclusive use.
2953
+ * @access public
2954
+ * @var string
2955
+ */
2956
+ public $BillingAgreementCustom;
2957
+
2958
+ /**
2959
+ * Constructor with arguments
2960
+ */
2961
+ public function __construct( $BillingType = null )
2962
+ {
2963
+ $this->BillingType = $BillingType;
2964
+ }
2965
+
2966
+
2967
+ public function toXMLString()
2968
+ {
2969
+ $str = '';
2970
+ if ( $this->BillingType != null ) {
2971
+ $str .= '<ebl:BillingType>' . PPUtils::escapeInvalidXmlCharsRegex( $this->BillingType ) . '</ebl:BillingType>';
2972
+ }
2973
+ if ( $this->BillingAgreementDescription != null ) {
2974
+ $str .= '<ebl:BillingAgreementDescription>' . PPUtils::escapeInvalidXmlCharsRegex( $this->BillingAgreementDescription ) . '</ebl:BillingAgreementDescription>';
2975
+ }
2976
+ if ( $this->PaymentType != null ) {
2977
+ $str .= '<ebl:PaymentType>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PaymentType ) . '</ebl:PaymentType>';
2978
+ }
2979
+ if ( $this->BillingAgreementCustom != null ) {
2980
+ $str .= '<ebl:BillingAgreementCustom>' . PPUtils::escapeInvalidXmlCharsRegex( $this->BillingAgreementCustom ) . '</ebl:BillingAgreementCustom>';
2981
+ }
2982
+
2983
+ return $str;
2984
+ }
2985
+
2986
+
2987
+ }
2988
+
2989
+
2990
+ /**
2991
+ * The timestamped token value that was returned by
2992
+ * SetExpressCheckoutResponse and passed on
2993
+ * GetExpressCheckoutDetailsRequest. Character length and
2994
+ * limitations: 20 single-byte characters
2995
+ */
2996
+ class GetExpressCheckoutDetailsResponseDetailsType
2997
+ {
2998
+
2999
+ /**
3000
+ * The timestamped token value that was returned by
3001
+ * SetExpressCheckoutResponse and passed on
3002
+ * GetExpressCheckoutDetailsRequest. Character length and
3003
+ * limitations: 20 single-byte characters
3004
+ * @access public
3005
+ * @var string
3006
+ */
3007
+ public $Token;
3008
+
3009
+ /**
3010
+ * Information about the payer
3011
+ * @access public
3012
+ * @var PayerInfoType
3013
+ */
3014
+ public $PayerInfo;
3015
+
3016
+ /**
3017
+ * A free-form field for your own use, as set by you in the
3018
+ * Custom element of SetExpressCheckoutRequest. Character
3019
+ * length and limitations: 256 single-byte alphanumeric
3020
+ * characters
3021
+ * @access public
3022
+ * @var string
3023
+ */
3024
+ public $Custom;
3025
+
3026
+ /**
3027
+ * Your own invoice or tracking number, as set by you in the
3028
+ * InvoiceID element of SetExpressCheckoutRequest. Character
3029
+ * length and limitations: 127 single-byte alphanumeric
3030
+ * characters
3031
+ * @access public
3032
+ * @var string
3033
+ */
3034
+ public $InvoiceID;
3035
+
3036
+ /**
3037
+ * Payer's contact telephone number. PayPal returns a contact
3038
+ * telephone number only if your Merchant account profile
3039
+ * settings require that the buyer enter one.
3040
+ * @access public
3041
+ * @var string
3042
+ */
3043
+ public $ContactPhone;
3044
+
3045
+ /**
3046
+ *
3047
+ * @access public
3048
+ * @var boolean
3049
+ */
3050
+ public $BillingAgreementAcceptedStatus;
3051
+
3052
+ /**
3053
+ *
3054
+ * @access public
3055
+ * @var string
3056
+ */
3057
+ public $RedirectRequired;
3058
+
3059
+ /**
3060
+ * Customer's billing address. Optional If you have credit card
3061
+ * mapped in your account then billing address of the credit
3062
+ * card is returned otherwise your primary address is returned
3063
+ * , PayPal returns this address in
3064
+ * GetExpressCheckoutDetailsResponse.
3065
+ * @access public
3066
+ * @var AddressType
3067
+ */
3068
+ public $BillingAddress;
3069
+
3070
+ /**
3071
+ * Text note entered by the buyer in PayPal flow.
3072
+ * @access public
3073
+ * @var string
3074
+ */
3075
+ public $Note;
3076
+
3077
+ /**
3078
+ * Returns the status of the EC checkout session. Values
3079
+ * include 'PaymentActionNotInitiated', 'PaymentActionFailed',
3080
+ * 'PaymentActionInProgress', 'PaymentCompleted'.
3081
+ * @access public
3082
+ * @var string
3083
+ */
3084
+ public $CheckoutStatus;
3085
+
3086
+ /**
3087
+ * PayPal may offer a discount or gift certificate to the
3088
+ * buyer, which will be represented by a negativeamount. If the
3089
+ * buyer has a negative balance, PayPal will add that amount to
3090
+ * the current charges, which will be represented as a positive
3091
+ * amount.
3092
+ * @access public
3093
+ * @var BasicAmountType
3094
+ */
3095
+ public $PayPalAdjustment;
3096
+
3097
+ /**
3098
+ * Information about the individual purchased items.
3099
+ * @array
3100
+ * @access public
3101
+ * @var PaymentDetailsType
3102
+ */
3103
+ public $PaymentDetails;
3104
+
3105
+ /**
3106
+ * Information about the user selected options.
3107
+ * @access public
3108
+ * @var UserSelectedOptionType
3109
+ */
3110
+ public $UserSelectedOptions;
3111
+
3112
+ /**
3113
+ * Information about the incentives that were applied from Ebay
3114
+ * RYP page and PayPal RYP page.
3115
+ * @array
3116
+ * @access public
3117
+ * @var IncentiveDetailsType
3118
+ */
3119
+ public $IncentiveDetails;
3120
+
3121
+ /**
3122
+ * Information about the Gift message.
3123
+ * @access public
3124
+ * @var string
3125
+ */
3126
+ public $GiftMessage;
3127
+
3128
+ /**
3129
+ * Information about the Gift receipt enable.
3130
+ * @access public
3131
+ * @var string
3132
+ */
3133
+ public $GiftReceiptEnable;
3134
+
3135
+ /**
3136
+ * Information about the Gift Wrap name.
3137
+ * @access public
3138
+ * @var string
3139
+ */
3140
+ public $GiftWrapName;
3141
+
3142
+ /**
3143
+ * Information about the Gift Wrap amount.
3144
+ * @access public
3145
+ * @var BasicAmountType
3146
+ */
3147
+ public $GiftWrapAmount;
3148
+
3149
+ /**
3150
+ * Information about the Buyer marketing email.
3151
+ * @access public
3152
+ * @var string
3153
+ */
3154
+ public $BuyerMarketingEmail;
3155
+
3156
+ /**
3157
+ * Information about the survey question.
3158
+ * @access public
3159
+ * @var string
3160
+ */
3161
+ public $SurveyQuestion;
3162
+
3163
+ /**
3164
+ * Information about the survey choice selected by the user.
3165
+ * @array
3166
+ * @access public
3167
+ * @var string
3168
+ */
3169
+ public $SurveyChoiceSelected;
3170
+
3171
+ /**
3172
+ * Contains payment request information about each bucket in
3173
+ * the cart.
3174
+ * @array
3175
+ * @access public
3176
+ * @var PaymentRequestInfoType
3177
+ */
3178
+ public $PaymentRequestInfo;
3179
+
3180
+ /**
3181
+ * Response information resulting from opt-in operation or
3182
+ * current login bypass status.
3183
+ * @access public
3184
+ * @var ExternalRememberMeStatusDetailsType
3185
+ */
3186
+ public $ExternalRememberMeStatusDetails;
3187
+
3188
+ /**
3189
+ * Response information resulting from opt-in operation or
3190
+ * current login bypass status.
3191
+ * @access public
3192
+ * @var RefreshTokenStatusDetailsType
3193
+ */
3194
+ public $RefreshTokenStatusDetails;
3195
+
3196
+
3197
+ public function init( $arr = null )
3198
+ {
3199
+ if ( $arr != null ) {
3200
+ foreach ( $arr as $arry ) {
3201
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'token' ) {
3202
+ $this->Token = $arry[ "text" ];
3203
+ }
3204
+
3205
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
3206
+ if ( $arry[ "name" ] == 'payerinfo' ) {
3207
+ $this->PayerInfo = new PayerInfoType();
3208
+ $this->PayerInfo->init( $arry[ "children" ] );
3209
+ }
3210
+
3211
+ }
3212
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'custom' ) {
3213
+ $this->Custom = $arry[ "text" ];
3214
+ }
3215
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'invoiceid' ) {
3216
+ $this->InvoiceID = $arry[ "text" ];
3217
+ }
3218
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'contactphone' ) {
3219
+ $this->ContactPhone = $arry[ "text" ];
3220
+ }
3221
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'billingagreementacceptedstatus' ) {
3222
+ $this->BillingAgreementAcceptedStatus = $arry[ "text" ];
3223
+ }
3224
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'redirectrequired' ) {
3225
+ $this->RedirectRequired = $arry[ "text" ];
3226
+ }
3227
+
3228
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
3229
+ if ( $arry[ "name" ] == 'billingaddress' ) {
3230
+ $this->BillingAddress = new AddressType();
3231
+ $this->BillingAddress->init( $arry[ "children" ] );
3232
+ }
3233
+
3234
+ }
3235
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'note' ) {
3236
+ $this->Note = $arry[ "text" ];
3237
+ }
3238
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'checkoutstatus' ) {
3239
+ $this->CheckoutStatus = $arry[ "text" ];
3240
+ }
3241
+
3242
+
3243
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
3244
+ if ( $arry[ "name" ] == 'paypaladjustment' ) {
3245
+ $tmp = array();
3246
+ $atr = array();
3247
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
3248
+ $atr[ 0 ][ "name" ] = $key;
3249
+ $atr[ 0 ][ "text" ] = $val;
3250
+ }
3251
+ $atr[ 1 ][ "name" ] = "value";
3252
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
3253
+ $this->PayPalAdjustment = new BasicAmountType();
3254
+ $this->PayPalAdjustment->init( $atr );
3255
+ }
3256
+
3257
+ }
3258
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) ) {
3259
+ $i = 0;
3260
+ while ( true ) {
3261
+ if ( $arry[ "name" ] == "paymentdetails[$i]" ) {
3262
+ $this->PaymentDetails[ $i ] = new PaymentDetailsType();
3263
+ $this->PaymentDetails[ $i ]->init( $arry[ "children" ] );
3264
+ } else {
3265
+ break;
3266
+ }
3267
+ $i++;
3268
+ }
3269
+ }
3270
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) && ( $arry[ "name" ] == "paymentdetails" ) ) {
3271
+ $this->PaymentDetails = new PaymentDetailsType();
3272
+ $this->PaymentDetails->init( $arry[ "children" ] );
3273
+ }
3274
+
3275
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
3276
+ if ( $arry[ "name" ] == 'userselectedoptions' ) {
3277
+ $this->UserSelectedOptions = new UserSelectedOptionType();
3278
+ $this->UserSelectedOptions->init( $arry[ "children" ] );
3279
+ }
3280
+
3281
+ }
3282
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) ) {
3283
+ $i = 0;
3284
+ while ( true ) {
3285
+ if ( $arry[ "name" ] == "incentivedetails[$i]" ) {
3286
+ $this->IncentiveDetails[ $i ] = new IncentiveDetailsType();
3287
+ $this->IncentiveDetails[ $i ]->init( $arry[ "children" ] );
3288
+ } else {
3289
+ break;
3290
+ }
3291
+ $i++;
3292
+ }
3293
+ }
3294
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) && ( $arry[ "name" ] == "incentivedetails" ) ) {
3295
+ $this->IncentiveDetails = new IncentiveDetailsType();
3296
+ $this->IncentiveDetails->init( $arry[ "children" ] );
3297
+ }
3298
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'giftmessage' ) {
3299
+ $this->GiftMessage = $arry[ "text" ];
3300
+ }
3301
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'giftreceiptenable' ) {
3302
+ $this->GiftReceiptEnable = $arry[ "text" ];
3303
+ }
3304
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'giftwrapname' ) {
3305
+ $this->GiftWrapName = $arry[ "text" ];
3306
+ }
3307
+
3308
+
3309
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
3310
+ if ( $arry[ "name" ] == 'giftwrapamount' ) {
3311
+ $tmp = array();
3312
+ $atr = array();
3313
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
3314
+ $atr[ 0 ][ "name" ] = $key;
3315
+ $atr[ 0 ][ "text" ] = $val;
3316
+ }
3317
+ $atr[ 1 ][ "name" ] = "value";
3318
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
3319
+ $this->GiftWrapAmount = new BasicAmountType();
3320
+ $this->GiftWrapAmount->init( $atr );
3321
+ }
3322
+
3323
+ }
3324
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'buyermarketingemail' ) {
3325
+ $this->BuyerMarketingEmail = $arry[ "text" ];
3326
+ }
3327
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'surveyquestion' ) {
3328
+ $this->SurveyQuestion = $arry[ "text" ];
3329
+ }
3330
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) ) {
3331
+ $i = 0;
3332
+ while ( true ) {
3333
+ if ( $arry[ "name" ] == "paymentrequestinfo[$i]" ) {
3334
+ $this->PaymentRequestInfo[ $i ] = new PaymentRequestInfoType();
3335
+ $this->PaymentRequestInfo[ $i ]->init( $arry[ "children" ] );
3336
+ } else {
3337
+ break;
3338
+ }
3339
+ $i++;
3340
+ }
3341
+ }
3342
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) && ( $arry[ "name" ] == "paymentrequestinfo" ) ) {
3343
+ $this->PaymentRequestInfo = new PaymentRequestInfoType();
3344
+ $this->PaymentRequestInfo->init( $arry[ "children" ] );
3345
+ }
3346
+
3347
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
3348
+ if ( $arry[ "name" ] == 'externalremembermestatusdetails' ) {
3349
+ $this->ExternalRememberMeStatusDetails = new ExternalRememberMeStatusDetailsType();
3350
+ $this->ExternalRememberMeStatusDetails->init( $arry[ "children" ] );
3351
+ }
3352
+
3353
+ }
3354
+
3355
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
3356
+ if ( $arry[ "name" ] == 'refreshtokenstatusdetails' ) {
3357
+ $this->RefreshTokenStatusDetails = new RefreshTokenStatusDetailsType();
3358
+ $this->RefreshTokenStatusDetails->init( $arry[ "children" ] );
3359
+ }
3360
+
3361
+ }
3362
+ }
3363
+ }
3364
+ }
3365
+ }
3366
+
3367
+
3368
+ /**
3369
+ *
3370
+ */
3371
+ class ExecuteCheckoutOperationsResponseDetailsType
3372
+ {
3373
+
3374
+ /**
3375
+ *
3376
+ * @access public
3377
+ * @var SetDataResponseType
3378
+ */
3379
+ public $SetDataResponse;
3380
+
3381
+ /**
3382
+ *
3383
+ * @access public
3384
+ * @var AuthorizationResponseType
3385
+ */
3386
+ public $AuthorizationResponse;
3387
+
3388
+
3389
+ public function init( $arr = null )
3390
+ {
3391
+ if ( $arr != null ) {
3392
+ foreach ( $arr as $arry ) {
3393
+
3394
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
3395
+ if ( $arry[ "name" ] == 'setdataresponse' ) {
3396
+ $this->SetDataResponse = new SetDataResponseType();
3397
+ $this->SetDataResponse->init( $arry[ "children" ] );
3398
+ }
3399
+
3400
+ }
3401
+
3402
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
3403
+ if ( $arry[ "name" ] == 'authorizationresponse' ) {
3404
+ $this->AuthorizationResponse = new AuthorizationResponseType();
3405
+ $this->AuthorizationResponse->init( $arry[ "children" ] );
3406
+ }
3407
+
3408
+ }
3409
+ }
3410
+ }
3411
+ }
3412
+ }
3413
+
3414
+
3415
+ /**
3416
+ * If Checkout session was initialized successfully, the
3417
+ * corresponding token is returned in this element.
3418
+ */
3419
+ class SetDataResponseType
3420
+ {
3421
+
3422
+ /**
3423
+ * If Checkout session was initialized successfully, the
3424
+ * corresponding token is returned in this element.
3425
+ * @access public
3426
+ * @var string
3427
+ */
3428
+ public $Token;
3429
+
3430
+ /**
3431
+ *
3432
+ * @array
3433
+ * @access public
3434
+ * @var ErrorType
3435
+ */
3436
+ public $SetDataError;
3437
+
3438
+
3439
+ public function init( $arr = null )
3440
+ {
3441
+ if ( $arr != null ) {
3442
+ foreach ( $arr as $arry ) {
3443
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'token' ) {
3444
+ $this->Token = $arry[ "text" ];
3445
+ }
3446
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) ) {
3447
+ $i = 0;
3448
+ while ( true ) {
3449
+ if ( $arry[ "name" ] == "setdataerror[$i]" ) {
3450
+ $this->SetDataError[ $i ] = new ErrorType();
3451
+ $this->SetDataError[ $i ]->init( $arry[ "children" ] );
3452
+ } else {
3453
+ break;
3454
+ }
3455
+ $i++;
3456
+ }
3457
+ }
3458
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) && ( $arry[ "name" ] == "setdataerror" ) ) {
3459
+ $this->SetDataError = new ErrorType();
3460
+ $this->SetDataError->init( $arry[ "children" ] );
3461
+ }
3462
+ }
3463
+ }
3464
+ }
3465
+ }
3466
+
3467
+
3468
+ /**
3469
+ * Status will denote whether Auto authorization was successful
3470
+ * or not.
3471
+ */
3472
+ class AuthorizationResponseType
3473
+ {
3474
+
3475
+ /**
3476
+ * Status will denote whether Auto authorization was successful
3477
+ * or not.
3478
+ * @access public
3479
+ * @var AckCodeType
3480
+ */
3481
+ public $Status;
3482
+
3483
+ /**
3484
+ *
3485
+ * @array
3486
+ * @access public
3487
+ * @var ErrorType
3488
+ */
3489
+ public $AuthorizationError;
3490
+
3491
+
3492
+ public function init( $arr = null )
3493
+ {
3494
+ if ( $arr != null ) {
3495
+ foreach ( $arr as $arry ) {
3496
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'status' ) {
3497
+ $this->Status = $arry[ "text" ];
3498
+ }
3499
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) ) {
3500
+ $i = 0;
3501
+ while ( true ) {
3502
+ if ( $arry[ "name" ] == "authorizationerror[$i]" ) {
3503
+ $this->AuthorizationError[ $i ] = new ErrorType();
3504
+ $this->AuthorizationError[ $i ]->init( $arry[ "children" ] );
3505
+ } else {
3506
+ break;
3507
+ }
3508
+ $i++;
3509
+ }
3510
+ }
3511
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) && ( $arry[ "name" ] == "authorizationerror" ) ) {
3512
+ $this->AuthorizationError = new ErrorType();
3513
+ $this->AuthorizationError->init( $arry[ "children" ] );
3514
+ }
3515
+ }
3516
+ }
3517
+ }
3518
+ }
3519
+
3520
+
3521
+ /**
3522
+ * How you want to obtain payment. Required Authorization
3523
+ * indicates that this payment is a basic authorization subject
3524
+ * to settlement with PayPal Authorization and Capture. Order
3525
+ * indicates that this payment is is an order authorization
3526
+ * subject to settlement with PayPal Authorization and Capture.
3527
+ * Sale indicates that this is a final sale for which you are
3528
+ * requesting payment. IMPORTANT: You cannot set PaymentAction
3529
+ * to Sale on SetExpressCheckoutRequest and then change
3530
+ * PaymentAction to Authorization on the final Express Checkout
3531
+ * API, DoExpressCheckoutPaymentRequest. Character length and
3532
+ * limit: Up to 13 single-byte alphabetic characters
3533
+ */
3534
+ class DoExpressCheckoutPaymentRequestDetailsType
3535
+ {
3536
+
3537
+ /**
3538
+ * How you want to obtain payment. Required Authorization
3539
+ * indicates that this payment is a basic authorization subject
3540
+ * to settlement with PayPal Authorization and Capture. Order
3541
+ * indicates that this payment is is an order authorization
3542
+ * subject to settlement with PayPal Authorization and Capture.
3543
+ * Sale indicates that this is a final sale for which you are
3544
+ * requesting payment. IMPORTANT: You cannot set PaymentAction
3545
+ * to Sale on SetExpressCheckoutRequest and then change
3546
+ * PaymentAction to Authorization on the final Express Checkout
3547
+ * API, DoExpressCheckoutPaymentRequest. Character length and
3548
+ * limit: Up to 13 single-byte alphabetic characters
3549
+ * @access public
3550
+ * @var PaymentActionCodeType
3551
+ */
3552
+ public $PaymentAction;
3553
+
3554
+ /**
3555
+ * The timestamped token value that was returned by
3556
+ * SetExpressCheckoutResponse and passed on
3557
+ * GetExpressCheckoutDetailsRequest. Required Character length
3558
+ * and limitations: 20 single-byte characters
3559
+ * @access public
3560
+ * @var string
3561
+ */
3562
+ public $Token;
3563
+
3564
+ /**
3565
+ * Encrypted PayPal customer account identification number as
3566
+ * returned by GetExpressCheckoutDetailsResponse. Required
3567
+ * Character length and limitations: 127 single-byte
3568
+ * characters.
3569
+ * @access public
3570
+ * @var string
3571
+ */
3572
+ public $PayerID;
3573
+
3574
+ /**
3575
+ * URL on Merchant site pertaining to this invoice. Optional
3576
+ * @access public
3577
+ * @var string
3578
+ */
3579
+ public $OrderURL;
3580
+
3581
+ /**
3582
+ * Information about the payment Required
3583
+ * @array
3584
+ * @access public
3585
+ * @var PaymentDetailsType
3586
+ */
3587
+ public $PaymentDetails;
3588
+
3589
+ /**
3590
+ * Flag to indicate if previously set promoCode shall be
3591
+ * overriden. Value 1 indicates overriding.
3592
+ * @access public
3593
+ * @var string
3594
+ */
3595
+ public $PromoOverrideFlag;
3596
+
3597
+ /**
3598
+ * Promotional financing code for item. Overrides any previous
3599
+ * PromoCode setting.
3600
+ * @access public
3601
+ * @var string
3602
+ */
3603
+ public $PromoCode;
3604
+
3605
+ /**
3606
+ * Contains data for enhanced data like Airline Itinerary Data.
3607
+ *
3608
+ * @access public
3609
+ * @var EnhancedDataType
3610
+ */
3611
+ public $EnhancedData;
3612
+
3613
+ /**
3614
+ * Soft Descriptor supported for Sale and Auth in DEC only. For
3615
+ * Order this will be ignored.
3616
+ * @access public
3617
+ * @var string
3618
+ */
3619
+ public $SoftDescriptor;
3620
+
3621
+ /**
3622
+ * Information about the user selected options.
3623
+ * @access public
3624
+ * @var UserSelectedOptionType
3625
+ */
3626
+ public $UserSelectedOptions;
3627
+
3628
+ /**
3629
+ * Information about the Gift message.
3630
+ * @access public
3631
+ * @var string
3632
+ */
3633
+ public $GiftMessage;
3634
+
3635
+ /**
3636
+ * Information about the Gift receipt enable.
3637
+ * @access public
3638
+ * @var string
3639
+ */
3640
+ public $GiftReceiptEnable;
3641
+
3642
+ /**
3643
+ * Information about the Gift Wrap name.
3644
+ * @access public
3645
+ * @var string
3646
+ */
3647
+ public $GiftWrapName;
3648
+
3649
+ /**
3650
+ * Information about the Gift Wrap amount.
3651
+ * @access public
3652
+ * @var BasicAmountType
3653
+ */
3654
+ public $GiftWrapAmount;
3655
+
3656
+ /**
3657
+ * Information about the Buyer marketing email.
3658
+ * @access public
3659
+ * @var string
3660
+ */
3661
+ public $BuyerMarketingEmail;
3662
+
3663
+ /**
3664
+ * Information about the survey question.
3665
+ * @access public
3666
+ * @var string
3667
+ */
3668
+ public $SurveyQuestion;
3669
+
3670
+ /**
3671
+ * Information about the survey choice selected by the user.
3672
+ * @array
3673
+ * @access public
3674
+ * @var string
3675
+ */
3676
+ public $SurveyChoiceSelected;
3677
+
3678
+ /**
3679
+ * An identification code for use by third-party applications
3680
+ * to identify transactions. Optional Character length and
3681
+ * limitations: 32 single-byte alphanumeric characters
3682
+ * @access public
3683
+ * @var string
3684
+ */
3685
+ public $ButtonSource;
3686
+
3687
+ /**
3688
+ * Merchant specified flag which indicates whether to create
3689
+ * billing agreement as part of DoEC or not. Optional
3690
+ * @access public
3691
+ * @var boolean
3692
+ */
3693
+ public $SkipBACreation;
3694
+
3695
+ /**
3696
+ * Optional element that defines relationship between buckets
3697
+ * @array
3698
+ * @access public
3699
+ * @var CoupledBucketsType
3700
+ */
3701
+ public $CoupledBuckets;
3702
+
3703
+
3704
+ public function toXMLString()
3705
+ {
3706
+ $str = '';
3707
+ if ( $this->PaymentAction != null ) {
3708
+ $str .= '<ebl:PaymentAction>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PaymentAction ) . '</ebl:PaymentAction>';
3709
+ }
3710
+ if ( $this->Token != null ) {
3711
+ $str .= '<ebl:Token>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Token ) . '</ebl:Token>';
3712
+ }
3713
+ if ( $this->PayerID != null ) {
3714
+ $str .= '<ebl:PayerID>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PayerID ) . '</ebl:PayerID>';
3715
+ }
3716
+ if ( $this->OrderURL != null ) {
3717
+ $str .= '<ebl:OrderURL>' . PPUtils::escapeInvalidXmlCharsRegex( $this->OrderURL ) . '</ebl:OrderURL>';
3718
+ }
3719
+ if ( $this->PaymentDetails != null ) {
3720
+ for ( $i = 0; $i < count( $this->PaymentDetails ); $i++ ) {
3721
+ $str .= '<ebl:PaymentDetails>';
3722
+ $str .= $this->PaymentDetails[ $i ]->toXMLString();
3723
+ $str .= '</ebl:PaymentDetails>';
3724
+ }
3725
+ }
3726
+ if ( $this->PromoOverrideFlag != null ) {
3727
+ $str .= '<ebl:PromoOverrideFlag>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PromoOverrideFlag ) . '</ebl:PromoOverrideFlag>';
3728
+ }
3729
+ if ( $this->PromoCode != null ) {
3730
+ $str .= '<ebl:PromoCode>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PromoCode ) . '</ebl:PromoCode>';
3731
+ }
3732
+ if ( $this->EnhancedData != null ) {
3733
+ $str .= '<ebl:EnhancedData>';
3734
+ $str .= $this->EnhancedData->toXMLString();
3735
+ $str .= '</ebl:EnhancedData>';
3736
+ }
3737
+ if ( $this->SoftDescriptor != null ) {
3738
+ $str .= '<ebl:SoftDescriptor>' . PPUtils::escapeInvalidXmlCharsRegex( $this->SoftDescriptor ) . '</ebl:SoftDescriptor>';
3739
+ }
3740
+ if ( $this->UserSelectedOptions != null ) {
3741
+ $str .= '<ebl:UserSelectedOptions>';
3742
+ $str .= $this->UserSelectedOptions->toXMLString();
3743
+ $str .= '</ebl:UserSelectedOptions>';
3744
+ }
3745
+ if ( $this->GiftMessage != null ) {
3746
+ $str .= '<ebl:GiftMessage>' . PPUtils::escapeInvalidXmlCharsRegex( $this->GiftMessage ) . '</ebl:GiftMessage>';
3747
+ }
3748
+ if ( $this->GiftReceiptEnable != null ) {
3749
+ $str .= '<ebl:GiftReceiptEnable>' . PPUtils::escapeInvalidXmlCharsRegex( $this->GiftReceiptEnable ) . '</ebl:GiftReceiptEnable>';
3750
+ }
3751
+ if ( $this->GiftWrapName != null ) {
3752
+ $str .= '<ebl:GiftWrapName>' . PPUtils::escapeInvalidXmlCharsRegex( $this->GiftWrapName ) . '</ebl:GiftWrapName>';
3753
+ }
3754
+ if ( $this->GiftWrapAmount != null ) {
3755
+ $str .= '<ebl:GiftWrapAmount';
3756
+ $str .= $this->GiftWrapAmount->toXMLString();
3757
+ $str .= '</ebl:GiftWrapAmount>';
3758
+ }
3759
+ if ( $this->BuyerMarketingEmail != null ) {
3760
+ $str .= '<ebl:BuyerMarketingEmail>' . PPUtils::escapeInvalidXmlCharsRegex( $this->BuyerMarketingEmail ) . '</ebl:BuyerMarketingEmail>';
3761
+ }
3762
+ if ( $this->SurveyQuestion != null ) {
3763
+ $str .= '<ebl:SurveyQuestion>' . PPUtils::escapeInvalidXmlCharsRegex( $this->SurveyQuestion ) . '</ebl:SurveyQuestion>';
3764
+ }
3765
+ if ( $this->SurveyChoiceSelected != null ) {
3766
+ for ( $i = 0; $i < count( $this->SurveyChoiceSelected ); $i++ ) {
3767
+ $str .= '<ebl:SurveyChoiceSelected>' . PPUtils::escapeInvalidXmlCharsRegex( $this->SurveyChoiceSelected[ $i ] ) . '</ebl:SurveyChoiceSelected>';
3768
+ }
3769
+ }
3770
+ if ( $this->ButtonSource != null ) {
3771
+ $str .= '<ebl:ButtonSource>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ButtonSource ) . '</ebl:ButtonSource>';
3772
+ }
3773
+ if ( $this->SkipBACreation != null ) {
3774
+ $str .= '<ebl:SkipBACreation>' . PPUtils::escapeInvalidXmlCharsRegex( $this->SkipBACreation ) . '</ebl:SkipBACreation>';
3775
+ }
3776
+ if ( $this->CoupledBuckets != null ) {
3777
+ for ( $i = 0; $i < count( $this->CoupledBuckets ); $i++ ) {
3778
+ $str .= '<ebl:CoupledBuckets>';
3779
+ $str .= $this->CoupledBuckets[ $i ]->toXMLString();
3780
+ $str .= '</ebl:CoupledBuckets>';
3781
+ }
3782
+ }
3783
+
3784
+ return $str;
3785
+ }
3786
+
3787
+
3788
+ }
3789
+
3790
+
3791
+ /**
3792
+ * The timestamped token value that was returned by
3793
+ * SetExpressCheckoutResponse and passed on
3794
+ * GetExpressCheckoutDetailsRequest. Character length and
3795
+ * limitations:20 single-byte characters
3796
+ */
3797
+ class DoExpressCheckoutPaymentResponseDetailsType
3798
+ {
3799
+
3800
+ /**
3801
+ * The timestamped token value that was returned by
3802
+ * SetExpressCheckoutResponse and passed on
3803
+ * GetExpressCheckoutDetailsRequest. Character length and
3804
+ * limitations:20 single-byte characters
3805
+ * @access public
3806
+ * @var string
3807
+ */
3808
+ public $Token;
3809
+
3810
+ /**
3811
+ * Information about the transaction
3812
+ * @array
3813
+ * @access public
3814
+ * @var PaymentInfoType
3815
+ */
3816
+ public $PaymentInfo;
3817
+
3818
+ /**
3819
+ *
3820
+ * @access public
3821
+ * @var string
3822
+ */
3823
+ public $BillingAgreementID;
3824
+
3825
+ /**
3826
+ *
3827
+ * @access public
3828
+ * @var string
3829
+ */
3830
+ public $RedirectRequired;
3831
+
3832
+ /**
3833
+ * Memo entered by sender in PayPal Review Page note field.
3834
+ * Optional Character length and limitations: 255 single-byte
3835
+ * alphanumeric characters
3836
+ * @access public
3837
+ * @var string
3838
+ */
3839
+ public $Note;
3840
+
3841
+ /**
3842
+ * Redirect back to PayPal, PayPal can host the success page.
3843
+ * @access public
3844
+ * @var string
3845
+ */
3846
+ public $SuccessPageRedirectRequested;
3847
+
3848
+ /**
3849
+ * Information about the user selected options.
3850
+ * @access public
3851
+ * @var UserSelectedOptionType
3852
+ */
3853
+ public $UserSelectedOptions;
3854
+
3855
+ /**
3856
+ * Information about Coupled Payment transactions.
3857
+ * @array
3858
+ * @access public
3859
+ * @var CoupledPaymentInfoType
3860
+ */
3861
+ public $CoupledPaymentInfo;
3862
+
3863
+
3864
+ public function init( $arr = null )
3865
+ {
3866
+ if ( $arr != null ) {
3867
+ foreach ( $arr as $arry ) {
3868
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'token' ) {
3869
+ $this->Token = $arry[ "text" ];
3870
+ }
3871
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) ) {
3872
+ $i = 0;
3873
+ while ( true ) {
3874
+ if ( $arry[ "name" ] == "paymentinfo[$i]" ) {
3875
+ $this->PaymentInfo[ $i ] = new PaymentInfoType();
3876
+ $this->PaymentInfo[ $i ]->init( $arry[ "children" ] );
3877
+ } else {
3878
+ break;
3879
+ }
3880
+ $i++;
3881
+ }
3882
+ }
3883
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) && ( $arry[ "name" ] == "paymentinfo" ) ) {
3884
+ $this->PaymentInfo = new PaymentInfoType();
3885
+ $this->PaymentInfo->init( $arry[ "children" ] );
3886
+ }
3887
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'billingagreementid' ) {
3888
+ $this->BillingAgreementID = $arry[ "text" ];
3889
+ }
3890
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'redirectrequired' ) {
3891
+ $this->RedirectRequired = $arry[ "text" ];
3892
+ }
3893
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'note' ) {
3894
+ $this->Note = $arry[ "text" ];
3895
+ }
3896
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'successpageredirectrequested' ) {
3897
+ $this->SuccessPageRedirectRequested = $arry[ "text" ];
3898
+ }
3899
+
3900
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
3901
+ if ( $arry[ "name" ] == 'userselectedoptions' ) {
3902
+ $this->UserSelectedOptions = new UserSelectedOptionType();
3903
+ $this->UserSelectedOptions->init( $arry[ "children" ] );
3904
+ }
3905
+
3906
+ }
3907
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) ) {
3908
+ $i = 0;
3909
+ while ( true ) {
3910
+ if ( $arry[ "name" ] == "coupledpaymentinfo[$i]" ) {
3911
+ $this->CoupledPaymentInfo[ $i ] = new CoupledPaymentInfoType();
3912
+ $this->CoupledPaymentInfo[ $i ]->init( $arry[ "children" ] );
3913
+ } else {
3914
+ break;
3915
+ }
3916
+ $i++;
3917
+ }
3918
+ }
3919
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) && ( $arry[ "name" ] == "coupledpaymentinfo" ) ) {
3920
+ $this->CoupledPaymentInfo = new CoupledPaymentInfoType();
3921
+ $this->CoupledPaymentInfo->init( $arry[ "children" ] );
3922
+ }
3923
+ }
3924
+ }
3925
+ }
3926
+ }
3927
+
3928
+
3929
+ /**
3930
+ * The authorization identification number you specified in the
3931
+ * request. Character length and limits: 19 single-byte
3932
+ * characters maximum
3933
+ */
3934
+ class DoCaptureResponseDetailsType
3935
+ {
3936
+
3937
+ /**
3938
+ * The authorization identification number you specified in the
3939
+ * request. Character length and limits: 19 single-byte
3940
+ * characters maximum
3941
+ * @access public
3942
+ * @var string
3943
+ */
3944
+ public $AuthorizationID;
3945
+
3946
+ /**
3947
+ * Information about the transaction
3948
+ * @access public
3949
+ * @var PaymentInfoType
3950
+ */
3951
+ public $PaymentInfo;
3952
+
3953
+ /**
3954
+ * Return msgsubid back to merchant
3955
+ * @access public
3956
+ * @var string
3957
+ */
3958
+ public $MsgSubID;
3959
+
3960
+
3961
+ public function init( $arr = null )
3962
+ {
3963
+ if ( $arr != null ) {
3964
+ foreach ( $arr as $arry ) {
3965
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'authorizationid' ) {
3966
+ $this->AuthorizationID = $arry[ "text" ];
3967
+ }
3968
+
3969
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
3970
+ if ( $arry[ "name" ] == 'paymentinfo' ) {
3971
+ $this->PaymentInfo = new PaymentInfoType();
3972
+ $this->PaymentInfo->init( $arry[ "children" ] );
3973
+ }
3974
+
3975
+ }
3976
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'msgsubid' ) {
3977
+ $this->MsgSubID = $arry[ "text" ];
3978
+ }
3979
+ }
3980
+ }
3981
+ }
3982
+ }
3983
+
3984
+
3985
+ /**
3986
+ * How you want to obtain payment. Required Authorization
3987
+ * indicates that this payment is a basic authorization subject
3988
+ * to settlement with PayPal Authorization and Capture. Sale
3989
+ * indicates that this is a final sale for which you are
3990
+ * requesting payment. NOTE: Order is not allowed for Direct
3991
+ * Payment. Character length and limit: Up to 13 single-byte
3992
+ * alphabetic characters
3993
+ */
3994
+ class DoDirectPaymentRequestDetailsType
3995
+ {
3996
+
3997
+ /**
3998
+ * How you want to obtain payment. Required Authorization
3999
+ * indicates that this payment is a basic authorization subject
4000
+ * to settlement with PayPal Authorization and Capture. Sale
4001
+ * indicates that this is a final sale for which you are
4002
+ * requesting payment. NOTE: Order is not allowed for Direct
4003
+ * Payment. Character length and limit: Up to 13 single-byte
4004
+ * alphabetic characters
4005
+ * @access public
4006
+ * @var PaymentActionCodeType
4007
+ */
4008
+ public $PaymentAction;
4009
+
4010
+ /**
4011
+ * Information about the payment Required
4012
+ * @access public
4013
+ * @var PaymentDetailsType
4014
+ */
4015
+ public $PaymentDetails;
4016
+
4017
+ /**
4018
+ * Information about the credit card to be charged. Required
4019
+ * @access public
4020
+ * @var CreditCardDetailsType
4021
+ */
4022
+ public $CreditCard;
4023
+
4024
+ /**
4025
+ * IP address of the payer's browser as recorded in its HTTP
4026
+ * request to your website. PayPal records this IP addresses as
4027
+ * a means to detect possible fraud. Required Character length
4028
+ * and limitations: 15 single-byte characters, including
4029
+ * periods, in dotted-quad format: ???.???.???.???
4030
+ * @access public
4031
+ * @var string
4032
+ */
4033
+ public $IPAddress;
4034
+
4035
+ /**
4036
+ * Your customer session identification token. PayPal records
4037
+ * this optional session identification token as an additional
4038
+ * means to detect possible fraud. Optional Character length
4039
+ * and limitations: 64 single-byte numeric characters
4040
+ * @access public
4041
+ * @var string
4042
+ */
4043
+ public $MerchantSessionId;
4044
+
4045
+ /**
4046
+ *
4047
+ * @access public
4048
+ * @var boolean
4049
+ */
4050
+ public $ReturnFMFDetails;
4051
+
4052
+
4053
+ public function toXMLString()
4054
+ {
4055
+ $str = '';
4056
+ if ( $this->PaymentAction != null ) {
4057
+ $str .= '<ebl:PaymentAction>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PaymentAction ) . '</ebl:PaymentAction>';
4058
+ }
4059
+ if ( $this->PaymentDetails != null ) {
4060
+ $str .= '<ebl:PaymentDetails>';
4061
+ $str .= $this->PaymentDetails->toXMLString();
4062
+ $str .= '</ebl:PaymentDetails>';
4063
+ }
4064
+ if ( $this->CreditCard != null ) {
4065
+ $str .= '<ebl:CreditCard>';
4066
+ $str .= $this->CreditCard->toXMLString();
4067
+ $str .= '</ebl:CreditCard>';
4068
+ }
4069
+ if ( $this->IPAddress != null ) {
4070
+ $str .= '<ebl:IPAddress>' . PPUtils::escapeInvalidXmlCharsRegex( $this->IPAddress ) . '</ebl:IPAddress>';
4071
+ }
4072
+ if ( $this->MerchantSessionId != null ) {
4073
+ $str .= '<ebl:MerchantSessionId>' . PPUtils::escapeInvalidXmlCharsRegex( $this->MerchantSessionId ) . '</ebl:MerchantSessionId>';
4074
+ }
4075
+ if ( $this->ReturnFMFDetails != null ) {
4076
+ $str .= '<ebl:ReturnFMFDetails>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ReturnFMFDetails ) . '</ebl:ReturnFMFDetails>';
4077
+ }
4078
+
4079
+ return $str;
4080
+ }
4081
+
4082
+
4083
+ }
4084
+
4085
+
4086
+ /**
4087
+ * Type of the payment Required
4088
+ */
4089
+ class CreateMobilePaymentRequestDetailsType
4090
+ {
4091
+
4092
+ /**
4093
+ * Type of the payment Required
4094
+ * @access public
4095
+ * @var MobilePaymentCodeType
4096
+ */
4097
+ public $PaymentType;
4098
+
4099
+ /**
4100
+ * How you want to obtain payment. Defaults to Sale. Optional
4101
+ * Authorization indicates that this payment is a basic
4102
+ * authorization subject to settlement with PayPal
4103
+ * Authorization and Capture. Sale indicates that this is a
4104
+ * final sale for which you are requesting payment.
4105
+ * @access public
4106
+ * @var PaymentActionCodeType
4107
+ */
4108
+ public $PaymentAction;
4109
+
4110
+ /**
4111
+ * Phone number of the user making the payment. Required
4112
+ * @access public
4113
+ * @var PhoneNumberType
4114
+ */
4115
+ public $SenderPhone;
4116
+
4117
+ /**
4118
+ * Type of recipient specified, i.e., phone number or email
4119
+ * address Required
4120
+ * @access public
4121
+ * @var MobileRecipientCodeType
4122
+ */
4123
+ public $RecipientType;
4124
+
4125
+ /**
4126
+ * Email address of the recipient
4127
+ * @access public
4128
+ * @var string
4129
+ */
4130
+ public $RecipientEmail;
4131
+
4132
+ /**
4133
+ * Phone number of the recipipent Required
4134
+ * @access public
4135
+ * @var PhoneNumberType
4136
+ */
4137
+ public $RecipientPhone;
4138
+
4139
+ /**
4140
+ * Amount of item before tax and shipping
4141
+ * @access public
4142
+ * @var BasicAmountType
4143
+ */
4144
+ public $ItemAmount;
4145
+
4146
+ /**
4147
+ * The tax charged on the transactionTax Optional
4148
+ * @access public
4149
+ * @var BasicAmountType
4150
+ */
4151
+ public $Tax;
4152
+
4153
+ /**
4154
+ * Per-transaction shipping charge Optional
4155
+ * @access public
4156
+ * @var BasicAmountType
4157
+ */
4158
+ public $Shipping;
4159
+
4160
+ /**
4161
+ * Name of the item being ordered Optional Character length and
4162
+ * limitations: 255 single-byte alphanumeric characters
4163
+ * @access public
4164
+ * @var string
4165
+ */
4166
+ public $ItemName;
4167
+
4168
+ /**
4169
+ * SKU of the item being ordered Optional Character length and
4170
+ * limitations: 255 single-byte alphanumeric characters
4171
+ * @access public
4172
+ * @var string
4173
+ */
4174
+ public $ItemNumber;
4175
+
4176
+ /**
4177
+ * Memo entered by sender in PayPal Website Payments note
4178
+ * field. Optional Character length and limitations: 255
4179
+ * single-byte alphanumeric characters
4180
+ * @access public
4181
+ * @var string
4182
+ */
4183
+ public $Note;
4184
+
4185
+ /**
4186
+ * Unique ID for the order. Required for non-P2P transactions
4187
+ * Optional Character length and limitations: 255 single-byte
4188
+ * alphanumeric characters
4189
+ * @access public
4190
+ * @var string
4191
+ */
4192
+ public $CustomID;
4193
+
4194
+ /**
4195
+ * Indicates whether the sender's phone number will be shared
4196
+ * with recipient Optional
4197
+ * @access public
4198
+ * @var integer
4199
+ */
4200
+ public $SharePhoneNumber;
4201
+
4202
+ /**
4203
+ * Indicates whether the sender's home address will be shared
4204
+ * with recipient Optional
4205
+ * @access public
4206
+ * @var integer
4207
+ */
4208
+ public $ShareHomeAddress;
4209
+
4210
+
4211
+ public function toXMLString()
4212
+ {
4213
+ $str = '';
4214
+ if ( $this->PaymentType != null ) {
4215
+ $str .= '<ebl:PaymentType>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PaymentType ) . '</ebl:PaymentType>';
4216
+ }
4217
+ if ( $this->PaymentAction != null ) {
4218
+ $str .= '<ebl:PaymentAction>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PaymentAction ) . '</ebl:PaymentAction>';
4219
+ }
4220
+ if ( $this->SenderPhone != null ) {
4221
+ $str .= '<ebl:SenderPhone>';
4222
+ $str .= $this->SenderPhone->toXMLString();
4223
+ $str .= '</ebl:SenderPhone>';
4224
+ }
4225
+ if ( $this->RecipientType != null ) {
4226
+ $str .= '<ebl:RecipientType>' . PPUtils::escapeInvalidXmlCharsRegex( $this->RecipientType ) . '</ebl:RecipientType>';
4227
+ }
4228
+ if ( $this->RecipientEmail != null ) {
4229
+ $str .= '<ebl:RecipientEmail>' . PPUtils::escapeInvalidXmlCharsRegex( $this->RecipientEmail ) . '</ebl:RecipientEmail>';
4230
+ }
4231
+ if ( $this->RecipientPhone != null ) {
4232
+ $str .= '<ebl:RecipientPhone>';
4233
+ $str .= $this->RecipientPhone->toXMLString();
4234
+ $str .= '</ebl:RecipientPhone>';
4235
+ }
4236
+ if ( $this->ItemAmount != null ) {
4237
+ $str .= '<ebl:ItemAmount';
4238
+ $str .= $this->ItemAmount->toXMLString();
4239
+ $str .= '</ebl:ItemAmount>';
4240
+ }
4241
+ if ( $this->Tax != null ) {
4242
+ $str .= '<ebl:Tax';
4243
+ $str .= $this->Tax->toXMLString();
4244
+ $str .= '</ebl:Tax>';
4245
+ }
4246
+ if ( $this->Shipping != null ) {
4247
+ $str .= '<ebl:Shipping';
4248
+ $str .= $this->Shipping->toXMLString();
4249
+ $str .= '</ebl:Shipping>';
4250
+ }
4251
+ if ( $this->ItemName != null ) {
4252
+ $str .= '<ebl:ItemName>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ItemName ) . '</ebl:ItemName>';
4253
+ }
4254
+ if ( $this->ItemNumber != null ) {
4255
+ $str .= '<ebl:ItemNumber>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ItemNumber ) . '</ebl:ItemNumber>';
4256
+ }
4257
+ if ( $this->Note != null ) {
4258
+ $str .= '<ebl:Note>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Note ) . '</ebl:Note>';
4259
+ }
4260
+ if ( $this->CustomID != null ) {
4261
+ $str .= '<ebl:CustomID>' . PPUtils::escapeInvalidXmlCharsRegex( $this->CustomID ) . '</ebl:CustomID>';
4262
+ }
4263
+ if ( $this->SharePhoneNumber != null ) {
4264
+ $str .= '<ebl:SharePhoneNumber>' . PPUtils::escapeInvalidXmlCharsRegex( $this->SharePhoneNumber ) . '</ebl:SharePhoneNumber>';
4265
+ }
4266
+ if ( $this->ShareHomeAddress != null ) {
4267
+ $str .= '<ebl:ShareHomeAddress>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ShareHomeAddress ) . '</ebl:ShareHomeAddress>';
4268
+ }
4269
+
4270
+ return $str;
4271
+ }
4272
+
4273
+
4274
+ }
4275
+
4276
+
4277
+ /**
4278
+ * Phone number for status inquiry
4279
+ */
4280
+ class GetMobileStatusRequestDetailsType
4281
+ {
4282
+
4283
+ /**
4284
+ * Phone number for status inquiry
4285
+ * @access public
4286
+ * @var PhoneNumberType
4287
+ */
4288
+ public $Phone;
4289
+
4290
+
4291
+ public function toXMLString()
4292
+ {
4293
+ $str = '';
4294
+ if ( $this->Phone != null ) {
4295
+ $str .= '<ebl:Phone>';
4296
+ $str .= $this->Phone->toXMLString();
4297
+ $str .= '</ebl:Phone>';
4298
+ }
4299
+
4300
+ return $str;
4301
+ }
4302
+
4303
+
4304
+ }
4305
+
4306
+
4307
+ /**
4308
+ * URL to which the customer's browser is returned after
4309
+ * choosing to login with PayPal. Required Character length and
4310
+ * limitations: no limit.
4311
+ */
4312
+ class SetAuthFlowParamRequestDetailsType
4313
+ {
4314
+
4315
+ /**
4316
+ * URL to which the customer's browser is returned after
4317
+ * choosing to login with PayPal. Required Character length and
4318
+ * limitations: no limit.
4319
+ * @access public
4320
+ * @var string
4321
+ */
4322
+ public $ReturnURL;
4323
+
4324
+ /**
4325
+ * URL to which the customer is returned if he does not approve
4326
+ * the use of PayPal login. Required Character length and
4327
+ * limitations: no limit
4328
+ * @access public
4329
+ * @var string
4330
+ */
4331
+ public $CancelURL;
4332
+
4333
+ /**
4334
+ * URL to which the customer's browser is returned after user
4335
+ * logs out from PayPal. Required Character length and
4336
+ * limitations: no limit.
4337
+ * @access public
4338
+ * @var string
4339
+ */
4340
+ public $LogoutURL;
4341
+
4342
+ /**
4343
+ * The type of the flow. Optional Character length and
4344
+ * limitations: 127 single-byte alphanumeric characters
4345
+ * @access public
4346
+ * @var string
4347
+ */
4348
+ public $InitFlowType;
4349
+
4350
+ /**
4351
+ * The used to decide SkipLogin allowed or not. Optional
4352
+ * Character length and limitations: 127 single-byte
4353
+ * alphanumeric characters
4354
+ * @access public
4355
+ * @var string
4356
+ */
4357
+ public $SkipLoginPage;
4358
+
4359
+ /**
4360
+ * The name of the field Merchant requires from PayPal after
4361
+ * user's login. Optional Character length and limitations: 256
4362
+ * single-byte alphanumeric characters
4363
+ * @access public
4364
+ * @var string
4365
+ */
4366
+ public $ServiceName1;
4367
+
4368
+ /**
4369
+ * Whether the field is required, opt-in or opt-out. Optional
4370
+ * Character length and limitations: 127 single-byte
4371
+ * alphanumeric characters
4372
+ * @access public
4373
+ * @var string
4374
+ */
4375
+ public $ServiceDefReq1;
4376
+
4377
+ /**
4378
+ * The name of the field Merchant requires from PayPal after
4379
+ * user's login. Optional Character length and limitations: 256
4380
+ * single-byte alphanumeric characters
4381
+ * @access public
4382
+ * @var string
4383
+ */
4384
+ public $ServiceName2;
4385
+
4386
+ /**
4387
+ * Whether the field is required, opt-in or opt-out. Optional
4388
+ * Character length and limitations: 127 single-byte
4389
+ * alphanumeric characters
4390
+ * @access public
4391
+ * @var string
4392
+ */
4393
+ public $ServiceDefReq2;
4394
+
4395
+ /**
4396
+ * Locale of pages displayed by PayPal during Authentication
4397
+ * Login. Optional Character length and limitations: Five
4398
+ * single-byte alphabetic characters, upper- or lowercase.
4399
+ * Allowable values: AU or en_AUDE or de_DEFR or fr_FRGB or
4400
+ * en_GBIT or it_ITJP or ja_JPUS or en_US
4401
+ * @access public
4402
+ * @var string
4403
+ */
4404
+ public $LocaleCode;
4405
+
4406
+ /**
4407
+ * Sets the Custom Payment Page Style for flow pages associated
4408
+ * with this button/link. PageStyle corresponds to the HTML
4409
+ * variable page_style for customizing flow pages. The value is
4410
+ * the same as the Page Style Name you chose when adding or
4411
+ * editing the page style from the Profile subtab of the My
4412
+ * Account tab of your PayPal account. Optional Character
4413
+ * length and limitations: 30 single-byte alphabetic
4414
+ * characters.
4415
+ * @access public
4416
+ * @var string
4417
+ */
4418
+ public $PageStyle;
4419
+
4420
+ /**
4421
+ * A URL for the image you want to appear at the top left of
4422
+ * the flow page. The image has a maximum size of 750 pixels
4423
+ * wide by 90 pixels high. PayPal recommends that you provide
4424
+ * an image that is stored on a secure (https) server. Optional
4425
+ * Character length and limitations: 127
4426
+ * @access public
4427
+ * @var string
4428
+ */
4429
+ public $cppheaderimage;
4430
+
4431
+ /**
4432
+ * Sets the border color around the header of the flow page.
4433
+ * The border is a 2-pixel perimeter around the header space,
4434
+ * which is 750 pixels wide by 90 pixels high. Optional
4435
+ * Character length and limitations: Six character HTML
4436
+ * hexadecimal color code in ASCII
4437
+ * @access public
4438
+ * @var string
4439
+ */
4440
+ public $cppheaderbordercolor;
4441
+
4442
+ /**
4443
+ * Sets the background color for the header of the flow page.
4444
+ * Optional Character length and limitation: Six character HTML
4445
+ * hexadecimal color code in ASCII
4446
+ * @access public
4447
+ * @var string
4448
+ */
4449
+ public $cppheaderbackcolor;
4450
+
4451
+ /**
4452
+ * Sets the background color for the payment page. Optional
4453
+ * Character length and limitation: Six character HTML
4454
+ * hexadecimal color code in ASCII
4455
+ * @access public
4456
+ * @var string
4457
+ */
4458
+ public $cpppayflowcolor;
4459
+
4460
+ /**
4461
+ * First Name of the user, this information is used if user
4462
+ * chooses to signup with PayPal. Optional Character length and
4463
+ * limitation: Six character HTML hexadecimal color code in
4464
+ * ASCII
4465
+ * @access public
4466
+ * @var string
4467
+ */
4468
+ public $FirstName;
4469
+
4470
+ /**
4471
+ * Last Name of the user, this information is used if user
4472
+ * chooses to signup with PayPal. Optional Character length and
4473
+ * limitation: Six character HTML hexadecimal color code in
4474
+ * ASCII
4475
+ * @access public
4476
+ * @var string
4477
+ */
4478
+ public $LastName;
4479
+
4480
+ /**
4481
+ * User address, this information is used when user chooses to
4482
+ * signup for PayPal. Optional If you include a shipping
4483
+ * address and set the AddressOverride element on the request,
4484
+ * PayPal returns this same address in
4485
+ * GetExpressCheckoutDetailsResponse.
4486
+ * @access public
4487
+ * @var AddressType
4488
+ */
4489
+ public $Address;
4490
+
4491
+
4492
+ public function toXMLString()
4493
+ {
4494
+ $str = '';
4495
+ if ( $this->ReturnURL != null ) {
4496
+ $str .= '<ebl:ReturnURL>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ReturnURL ) . '</ebl:ReturnURL>';
4497
+ }
4498
+ if ( $this->CancelURL != null ) {
4499
+ $str .= '<ebl:CancelURL>' . PPUtils::escapeInvalidXmlCharsRegex( $this->CancelURL ) . '</ebl:CancelURL>';
4500
+ }
4501
+ if ( $this->LogoutURL != null ) {
4502
+ $str .= '<ebl:LogoutURL>' . PPUtils::escapeInvalidXmlCharsRegex( $this->LogoutURL ) . '</ebl:LogoutURL>';
4503
+ }
4504
+ if ( $this->InitFlowType != null ) {
4505
+ $str .= '<ebl:InitFlowType>' . PPUtils::escapeInvalidXmlCharsRegex( $this->InitFlowType ) . '</ebl:InitFlowType>';
4506
+ }
4507
+ if ( $this->SkipLoginPage != null ) {
4508
+ $str .= '<ebl:SkipLoginPage>' . PPUtils::escapeInvalidXmlCharsRegex( $this->SkipLoginPage ) . '</ebl:SkipLoginPage>';
4509
+ }
4510
+ if ( $this->ServiceName1 != null ) {
4511
+ $str .= '<ebl:ServiceName1>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ServiceName1 ) . '</ebl:ServiceName1>';
4512
+ }
4513
+ if ( $this->ServiceDefReq1 != null ) {
4514
+ $str .= '<ebl:ServiceDefReq1>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ServiceDefReq1 ) . '</ebl:ServiceDefReq1>';
4515
+ }
4516
+ if ( $this->ServiceName2 != null ) {
4517
+ $str .= '<ebl:ServiceName2>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ServiceName2 ) . '</ebl:ServiceName2>';
4518
+ }
4519
+ if ( $this->ServiceDefReq2 != null ) {
4520
+ $str .= '<ebl:ServiceDefReq2>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ServiceDefReq2 ) . '</ebl:ServiceDefReq2>';
4521
+ }
4522
+ if ( $this->LocaleCode != null ) {
4523
+ $str .= '<ebl:LocaleCode>' . PPUtils::escapeInvalidXmlCharsRegex( $this->LocaleCode ) . '</ebl:LocaleCode>';
4524
+ }
4525
+ if ( $this->PageStyle != null ) {
4526
+ $str .= '<ebl:PageStyle>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PageStyle ) . '</ebl:PageStyle>';
4527
+ }
4528
+ if ( $this->cppheaderimage != null ) {
4529
+ $str .= '<ebl:cpp-header-image>' . PPUtils::escapeInvalidXmlCharsRegex( $this->cppheaderimage ) . '</ebl:cpp-header-image>';
4530
+ }
4531
+ if ( $this->cppheaderbordercolor != null ) {
4532
+ $str .= '<ebl:cpp-header-border-color>' . PPUtils::escapeInvalidXmlCharsRegex( $this->cppheaderbordercolor ) . '</ebl:cpp-header-border-color>';
4533
+ }
4534
+ if ( $this->cppheaderbackcolor != null ) {
4535
+ $str .= '<ebl:cpp-header-back-color>' . PPUtils::escapeInvalidXmlCharsRegex( $this->cppheaderbackcolor ) . '</ebl:cpp-header-back-color>';
4536
+ }
4537
+ if ( $this->cpppayflowcolor != null ) {
4538
+ $str .= '<ebl:cpp-payflow-color>' . PPUtils::escapeInvalidXmlCharsRegex( $this->cpppayflowcolor ) . '</ebl:cpp-payflow-color>';
4539
+ }
4540
+ if ( $this->FirstName != null ) {
4541
+ $str .= '<ebl:FirstName>' . PPUtils::escapeInvalidXmlCharsRegex( $this->FirstName ) . '</ebl:FirstName>';
4542
+ }
4543
+ if ( $this->LastName != null ) {
4544
+ $str .= '<ebl:LastName>' . PPUtils::escapeInvalidXmlCharsRegex( $this->LastName ) . '</ebl:LastName>';
4545
+ }
4546
+ if ( $this->Address != null ) {
4547
+ $str .= '<ebl:Address>';
4548
+ $str .= $this->Address->toXMLString();
4549
+ $str .= '</ebl:Address>';
4550
+ }
4551
+
4552
+ return $str;
4553
+ }
4554
+
4555
+
4556
+ }
4557
+
4558
+
4559
+ /**
4560
+ * The first name of the User. Character length and
4561
+ * limitations: 127 single-byte alphanumeric characters
4562
+ */
4563
+ class GetAuthDetailsResponseDetailsType
4564
+ {
4565
+
4566
+ /**
4567
+ * The first name of the User. Character length and
4568
+ * limitations: 127 single-byte alphanumeric characters
4569
+ * @access public
4570
+ * @var string
4571
+ */
4572
+ public $FirstName;
4573
+
4574
+ /**
4575
+ * The Last name of the user. Character length and limitations:
4576
+ * 127 single-byte alphanumeric characters
4577
+ * @access public
4578
+ * @var string
4579
+ */
4580
+ public $LastName;
4581
+
4582
+ /**
4583
+ * The email address of the user. Character length and
4584
+ * limitations: 256 single-byte alphanumeric characters.
4585
+ * @access public
4586
+ * @var string
4587
+ */
4588
+ public $Email;
4589
+
4590
+ /**
4591
+ * Encrypted PayPal customer account identification number.
4592
+ * Required Character length and limitations: 127 single-byte
4593
+ * characters.
4594
+ * @access public
4595
+ * @var string
4596
+ */
4597
+ public $PayerID;
4598
+
4599
+
4600
+ public function init( $arr = null )
4601
+ {
4602
+ if ( $arr != null ) {
4603
+ foreach ( $arr as $arry ) {
4604
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'firstname' ) {
4605
+ $this->FirstName = $arry[ "text" ];
4606
+ }
4607
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'lastname' ) {
4608
+ $this->LastName = $arry[ "text" ];
4609
+ }
4610
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'email' ) {
4611
+ $this->Email = $arry[ "text" ];
4612
+ }
4613
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'payerid' ) {
4614
+ $this->PayerID = $arry[ "text" ];
4615
+ }
4616
+ }
4617
+ }
4618
+ }
4619
+ }
4620
+
4621
+
4622
+ /**
4623
+ * URL to which the customer's browser is returned after
4624
+ * choosing to login with PayPal. Required Character length and
4625
+ * limitations: no limit.
4626
+ */
4627
+ class SetAccessPermissionsRequestDetailsType
4628
+ {
4629
+
4630
+ /**
4631
+ * URL to which the customer's browser is returned after
4632
+ * choosing to login with PayPal. Required Character length and
4633
+ * limitations: no limit.
4634
+ * @access public
4635
+ * @var string
4636
+ */
4637
+ public $ReturnURL;
4638
+
4639
+ /**
4640
+ * URL to which the customer is returned if he does not approve
4641
+ * the use of PayPal login. Required Character length and
4642
+ * limitations: no limit
4643
+ * @access public
4644
+ * @var string
4645
+ */
4646
+ public $CancelURL;
4647
+
4648
+ /**
4649
+ * URL to which the customer's browser is returned after user
4650
+ * logs out from PayPal. Required Character length and
4651
+ * limitations: no limit.
4652
+ * @access public
4653
+ * @var string
4654
+ */
4655
+ public $LogoutURL;
4656
+
4657
+ /**
4658
+ * The type of the flow. Optional Character length and
4659
+ * limitations: 127 single-byte alphanumeric characters
4660
+ * @access public
4661
+ * @var string
4662
+ */
4663
+ public $InitFlowType;
4664
+
4665
+ /**
4666
+ * The used to decide SkipLogin allowed or not. Optional
4667
+ * Character length and limitations: 127 single-byte
4668
+ * alphanumeric characters
4669
+ * @access public
4670
+ * @var string
4671
+ */
4672
+ public $SkipLoginPage;
4673
+
4674
+ /**
4675
+ * contains information about API Services
4676
+ * @array
4677
+ * @access public
4678
+ * @var string
4679
+ */
4680
+ public $RequiredAccessPermissions;
4681
+
4682
+ /**
4683
+ * contains information about API Services
4684
+ * @array
4685
+ * @access public
4686
+ * @var string
4687
+ */
4688
+ public $OptionalAccessPermissions;
4689
+
4690
+ /**
4691
+ * Locale of pages displayed by PayPal during Authentication
4692
+ * Login. Optional Character length and limitations: Five
4693
+ * single-byte alphabetic characters, upper- or lowercase.
4694
+ * Allowable values: AU or en_AUDE or de_DEFR or fr_FRGB or
4695
+ * en_GBIT or it_ITJP or ja_JPUS or en_US
4696
+ * @access public
4697
+ * @var string
4698
+ */
4699
+ public $LocaleCode;
4700
+
4701
+ /**
4702
+ * Sets the Custom Payment Page Style for flow pages associated
4703
+ * with this button/link. PageStyle corresponds to the HTML
4704
+ * variable page_style for customizing flow pages. The value is
4705
+ * the same as the Page Style Name you chose when adding or
4706
+ * editing the page style from the Profile subtab of the My
4707
+ * Account tab of your PayPal account. Optional Character
4708
+ * length and limitations: 30 single-byte alphabetic
4709
+ * characters.
4710
+ * @access public
4711
+ * @var string
4712
+ */
4713
+ public $PageStyle;
4714
+
4715
+ /**
4716
+ * A URL for the image you want to appear at the top left of
4717
+ * the flow page. The image has a maximum size of 750 pixels
4718
+ * wide by 90 pixels high. PayPal recommends that you provide
4719
+ * an image that is stored on a secure (https) server. Optional
4720
+ * Character length and limitations: 127
4721
+ * @access public
4722
+ * @var string
4723
+ */
4724
+ public $cppheaderimage;
4725
+
4726
+ /**
4727
+ * Sets the border color around the header of the flow page.
4728
+ * The border is a 2-pixel perimeter around the header space,
4729
+ * which is 750 pixels wide by 90 pixels high. Optional
4730
+ * Character length and limitations: Six character HTML
4731
+ * hexadecimal color code in ASCII
4732
+ * @access public
4733
+ * @var string
4734
+ */
4735
+ public $cppheaderbordercolor;
4736
+
4737
+ /**
4738
+ * Sets the background color for the header of the flow page.
4739
+ * Optional Character length and limitation: Six character HTML
4740
+ * hexadecimal color code in ASCII
4741
+ * @access public
4742
+ * @var string
4743
+ */
4744
+ public $cppheaderbackcolor;
4745
+
4746
+ /**
4747
+ * Sets the background color for the payment page. Optional
4748
+ * Character length and limitation: Six character HTML
4749
+ * hexadecimal color code in ASCII
4750
+ * @access public
4751
+ * @var string
4752
+ */
4753
+ public $cpppayflowcolor;
4754
+
4755
+ /**
4756
+ * First Name of the user, this information is used if user
4757
+ * chooses to signup with PayPal. Optional Character length and
4758
+ * limitation: Six character HTML hexadecimal color code in
4759
+ * ASCII
4760
+ * @access public
4761
+ * @var string
4762
+ */
4763
+ public $FirstName;
4764
+
4765
+ /**
4766
+ * Last Name of the user, this information is used if user
4767
+ * chooses to signup with PayPal. Optional Character length and
4768
+ * limitation: Six character HTML hexadecimal color code in
4769
+ * ASCII
4770
+ * @access public
4771
+ * @var string
4772
+ */
4773
+ public $LastName;
4774
+
4775
+ /**
4776
+ * User address, this information is used when user chooses to
4777
+ * signup for PayPal. Optional If you include a shipping
4778
+ * address and set the AddressOverride element on the request,
4779
+ * PayPal returns this same address in
4780
+ * GetExpressCheckoutDetailsResponse.
4781
+ * @access public
4782
+ * @var AddressType
4783
+ */
4784
+ public $Address;
4785
+
4786
+
4787
+ public function toXMLString()
4788
+ {
4789
+ $str = '';
4790
+ if ( $this->ReturnURL != null ) {
4791
+ $str .= '<ebl:ReturnURL>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ReturnURL ) . '</ebl:ReturnURL>';
4792
+ }
4793
+ if ( $this->CancelURL != null ) {
4794
+ $str .= '<ebl:CancelURL>' . PPUtils::escapeInvalidXmlCharsRegex( $this->CancelURL ) . '</ebl:CancelURL>';
4795
+ }
4796
+ if ( $this->LogoutURL != null ) {
4797
+ $str .= '<ebl:LogoutURL>' . PPUtils::escapeInvalidXmlCharsRegex( $this->LogoutURL ) . '</ebl:LogoutURL>';
4798
+ }
4799
+ if ( $this->InitFlowType != null ) {
4800
+ $str .= '<ebl:InitFlowType>' . PPUtils::escapeInvalidXmlCharsRegex( $this->InitFlowType ) . '</ebl:InitFlowType>';
4801
+ }
4802
+ if ( $this->SkipLoginPage != null ) {
4803
+ $str .= '<ebl:SkipLoginPage>' . PPUtils::escapeInvalidXmlCharsRegex( $this->SkipLoginPage ) . '</ebl:SkipLoginPage>';
4804
+ }
4805
+ if ( $this->RequiredAccessPermissions != null ) {
4806
+ for ( $i = 0; $i < count( $this->RequiredAccessPermissions ); $i++ ) {
4807
+ $str .= '<ebl:RequiredAccessPermissions>' . PPUtils::escapeInvalidXmlCharsRegex( $this->RequiredAccessPermissions[ $i ] ) . '</ebl:RequiredAccessPermissions>';
4808
+ }
4809
+ }
4810
+ if ( $this->OptionalAccessPermissions != null ) {
4811
+ for ( $i = 0; $i < count( $this->OptionalAccessPermissions ); $i++ ) {
4812
+ $str .= '<ebl:OptionalAccessPermissions>' . PPUtils::escapeInvalidXmlCharsRegex( $this->OptionalAccessPermissions[ $i ] ) . '</ebl:OptionalAccessPermissions>';
4813
+ }
4814
+ }
4815
+ if ( $this->LocaleCode != null ) {
4816
+ $str .= '<ebl:LocaleCode>' . PPUtils::escapeInvalidXmlCharsRegex( $this->LocaleCode ) . '</ebl:LocaleCode>';
4817
+ }
4818
+ if ( $this->PageStyle != null ) {
4819
+ $str .= '<ebl:PageStyle>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PageStyle ) . '</ebl:PageStyle>';
4820
+ }
4821
+ if ( $this->cppheaderimage != null ) {
4822
+ $str .= '<ebl:cpp-header-image>' . PPUtils::escapeInvalidXmlCharsRegex( $this->cppheaderimage ) . '</ebl:cpp-header-image>';
4823
+ }
4824
+ if ( $this->cppheaderbordercolor != null ) {
4825
+ $str .= '<ebl:cpp-header-border-color>' . PPUtils::escapeInvalidXmlCharsRegex( $this->cppheaderbordercolor ) . '</ebl:cpp-header-border-color>';
4826
+ }
4827
+ if ( $this->cppheaderbackcolor != null ) {
4828
+ $str .= '<ebl:cpp-header-back-color>' . PPUtils::escapeInvalidXmlCharsRegex( $this->cppheaderbackcolor ) . '</ebl:cpp-header-back-color>';
4829
+ }
4830
+ if ( $this->cpppayflowcolor != null ) {
4831
+ $str .= '<ebl:cpp-payflow-color>' . PPUtils::escapeInvalidXmlCharsRegex( $this->cpppayflowcolor ) . '</ebl:cpp-payflow-color>';
4832
+ }
4833
+ if ( $this->FirstName != null ) {
4834
+ $str .= '<ebl:FirstName>' . PPUtils::escapeInvalidXmlCharsRegex( $this->FirstName ) . '</ebl:FirstName>';
4835
+ }
4836
+ if ( $this->LastName != null ) {
4837
+ $str .= '<ebl:LastName>' . PPUtils::escapeInvalidXmlCharsRegex( $this->LastName ) . '</ebl:LastName>';
4838
+ }
4839
+ if ( $this->Address != null ) {
4840
+ $str .= '<ebl:Address>';
4841
+ $str .= $this->Address->toXMLString();
4842
+ $str .= '</ebl:Address>';
4843
+ }
4844
+
4845
+ return $str;
4846
+ }
4847
+
4848
+
4849
+ }
4850
+
4851
+
4852
+ /**
4853
+ * The first name of the User. Character length and
4854
+ * limitations: 127 single-byte alphanumeric characters
4855
+ */
4856
+ class GetAccessPermissionDetailsResponseDetailsType
4857
+ {
4858
+
4859
+ /**
4860
+ * The first name of the User. Character length and
4861
+ * limitations: 127 single-byte alphanumeric characters
4862
+ * @access public
4863
+ * @var string
4864
+ */
4865
+ public $FirstName;
4866
+
4867
+ /**
4868
+ * The Last name of the user. Character length and limitations:
4869
+ * 127 single-byte alphanumeric characters
4870
+ * @access public
4871
+ * @var string
4872
+ */
4873
+ public $LastName;
4874
+
4875
+ /**
4876
+ * The email address of the user. Character length and
4877
+ * limitations: 256 single-byte alphanumeric characters.
4878
+ * @access public
4879
+ * @var string
4880
+ */
4881
+ public $Email;
4882
+
4883
+ /**
4884
+ * contains information about API Services
4885
+ * @array
4886
+ * @access public
4887
+ * @var string
4888
+ */
4889
+ public $AccessPermissionName;
4890
+
4891
+ /**
4892
+ * contains information about API Services
4893
+ * @array
4894
+ * @access public
4895
+ * @var string
4896
+ */
4897
+ public $AccessPermissionStatus;
4898
+
4899
+ /**
4900
+ * Encrypted PayPal customer account identification number.
4901
+ * Required Character length and limitations: 127 single-byte
4902
+ * characters.
4903
+ * @access public
4904
+ * @var string
4905
+ */
4906
+ public $PayerID;
4907
+
4908
+
4909
+ public function init( $arr = null )
4910
+ {
4911
+ if ( $arr != null ) {
4912
+ foreach ( $arr as $arry ) {
4913
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'firstname' ) {
4914
+ $this->FirstName = $arry[ "text" ];
4915
+ }
4916
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'lastname' ) {
4917
+ $this->LastName = $arry[ "text" ];
4918
+ }
4919
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'email' ) {
4920
+ $this->Email = $arry[ "text" ];
4921
+ }
4922
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'payerid' ) {
4923
+ $this->PayerID = $arry[ "text" ];
4924
+ }
4925
+ }
4926
+ }
4927
+ }
4928
+ }
4929
+
4930
+
4931
+ /**
4932
+ *
4933
+ */
4934
+ class BAUpdateResponseDetailsType
4935
+ {
4936
+
4937
+ /**
4938
+ *
4939
+ * @access public
4940
+ * @var string
4941
+ */
4942
+ public $BillingAgreementID;
4943
+
4944
+ /**
4945
+ *
4946
+ * @access public
4947
+ * @var string
4948
+ */
4949
+ public $BillingAgreementDescription;
4950
+
4951
+ /**
4952
+ *
4953
+ * @access public
4954
+ * @var MerchantPullStatusCodeType
4955
+ */
4956
+ public $BillingAgreementStatus;
4957
+
4958
+ /**
4959
+ *
4960
+ * @access public
4961
+ * @var string
4962
+ */
4963
+ public $BillingAgreementCustom;
4964
+
4965
+ /**
4966
+ *
4967
+ * @access public
4968
+ * @var PayerInfoType
4969
+ */
4970
+ public $PayerInfo;
4971
+
4972
+ /**
4973
+ *
4974
+ * @access public
4975
+ * @var BasicAmountType
4976
+ */
4977
+ public $BillingAgreementMax;
4978
+
4979
+ /**
4980
+ * Customer's billing address. Optional If you have credit card
4981
+ * mapped in your account then billing address of the credit
4982
+ * card is returned otherwise your primary address is returned
4983
+ * , PayPal returns this address in BAUpdateResponseDetails.
4984
+ * @access public
4985
+ * @var AddressType
4986
+ */
4987
+ public $BillingAddress;
4988
+
4989
+
4990
+ public function init( $arr = null )
4991
+ {
4992
+ if ( $arr != null ) {
4993
+ foreach ( $arr as $arry ) {
4994
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'billingagreementid' ) {
4995
+ $this->BillingAgreementID = $arry[ "text" ];
4996
+ }
4997
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'billingagreementdescription' ) {
4998
+ $this->BillingAgreementDescription = $arry[ "text" ];
4999
+ }
5000
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'billingagreementstatus' ) {
5001
+ $this->BillingAgreementStatus = $arry[ "text" ];
5002
+ }
5003
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'billingagreementcustom' ) {
5004
+ $this->BillingAgreementCustom = $arry[ "text" ];
5005
+ }
5006
+
5007
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
5008
+ if ( $arry[ "name" ] == 'payerinfo' ) {
5009
+ $this->PayerInfo = new PayerInfoType();
5010
+ $this->PayerInfo->init( $arry[ "children" ] );
5011
+ }
5012
+
5013
+ }
5014
+
5015
+
5016
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
5017
+ if ( $arry[ "name" ] == 'billingagreementmax' ) {
5018
+ $tmp = array();
5019
+ $atr = array();
5020
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
5021
+ $atr[ 0 ][ "name" ] = $key;
5022
+ $atr[ 0 ][ "text" ] = $val;
5023
+ }
5024
+ $atr[ 1 ][ "name" ] = "value";
5025
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
5026
+ $this->BillingAgreementMax = new BasicAmountType();
5027
+ $this->BillingAgreementMax->init( $atr );
5028
+ }
5029
+
5030
+ }
5031
+
5032
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
5033
+ if ( $arry[ "name" ] == 'billingaddress' ) {
5034
+ $this->BillingAddress = new AddressType();
5035
+ $this->BillingAddress->init( $arry[ "children" ] );
5036
+ }
5037
+
5038
+ }
5039
+ }
5040
+ }
5041
+ }
5042
+ }
5043
+
5044
+
5045
+ /**
5046
+ * MerchantPullPaymentResponseType Response data from the
5047
+ * merchant pull.
5048
+ */
5049
+ class MerchantPullPaymentResponseType
5050
+ {
5051
+
5052
+ /**
5053
+ * information about the customer
5054
+ * @access public
5055
+ * @var PayerInfoType
5056
+ */
5057
+ public $PayerInfo;
5058
+
5059
+ /**
5060
+ * Information about the transaction
5061
+ * @access public
5062
+ * @var PaymentInfoType
5063
+ */
5064
+ public $PaymentInfo;
5065
+
5066
+ /**
5067
+ * Specific information about the preapproved payment
5068
+ * @access public
5069
+ * @var MerchantPullInfoType
5070
+ */
5071
+ public $MerchantPullInfo;
5072
+
5073
+
5074
+ public function init( $arr = null )
5075
+ {
5076
+ if ( $arr != null ) {
5077
+ foreach ( $arr as $arry ) {
5078
+
5079
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
5080
+ if ( $arry[ "name" ] == 'payerinfo' ) {
5081
+ $this->PayerInfo = new PayerInfoType();
5082
+ $this->PayerInfo->init( $arry[ "children" ] );
5083
+ }
5084
+
5085
+ }
5086
+
5087
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
5088
+ if ( $arry[ "name" ] == 'paymentinfo' ) {
5089
+ $this->PaymentInfo = new PaymentInfoType();
5090
+ $this->PaymentInfo->init( $arry[ "children" ] );
5091
+ }
5092
+
5093
+ }
5094
+
5095
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
5096
+ if ( $arry[ "name" ] == 'merchantpullinfo' ) {
5097
+ $this->MerchantPullInfo = new MerchantPullInfoType();
5098
+ $this->MerchantPullInfo->init( $arry[ "children" ] );
5099
+ }
5100
+
5101
+ }
5102
+ }
5103
+ }
5104
+ }
5105
+ }
5106
+
5107
+
5108
+ /**
5109
+ * MerchantPullInfoType Information about the merchant pull.
5110
+ */
5111
+ class MerchantPullInfoType
5112
+ {
5113
+
5114
+ /**
5115
+ * Current status of billing agreement
5116
+ * @access public
5117
+ * @var MerchantPullStatusCodeType
5118
+ */
5119
+ public $MpStatus;
5120
+
5121
+ /**
5122
+ * Monthly maximum payment amount
5123
+ * @access public
5124
+ * @var BasicAmountType
5125
+ */
5126
+ public $MpMax;
5127
+
5128
+ /**
5129
+ * The value of the mp_custom variable that you specified in a
5130
+ * FORM submission to PayPal during the creation or updating of
5131
+ * a customer billing agreement
5132
+ * @access public
5133
+ * @var string
5134
+ */
5135
+ public $MpCustom;
5136
+
5137
+ /**
5138
+ * The value of the mp_desc variable (description of goods or
5139
+ * services) associated with the billing agreement
5140
+ * @access public
5141
+ * @var string
5142
+ */
5143
+ public $Desc;
5144
+
5145
+ /**
5146
+ * Invoice value as set by BillUserRequest API call
5147
+ * @access public
5148
+ * @var string
5149
+ */
5150
+ public $Invoice;
5151
+
5152
+ /**
5153
+ * Custom field as set by BillUserRequest API call
5154
+ * @access public
5155
+ * @var string
5156
+ */
5157
+ public $Custom;
5158
+
5159
+ /**
5160
+ * Note: This field is no longer used and is always empty.
5161
+ * @access public
5162
+ * @var string
5163
+ */
5164
+ public $PaymentSourceID;
5165
+
5166
+
5167
+ public function init( $arr = null )
5168
+ {
5169
+ if ( $arr != null ) {
5170
+ foreach ( $arr as $arry ) {
5171
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'mpstatus' ) {
5172
+ $this->MpStatus = $arry[ "text" ];
5173
+ }
5174
+
5175
+
5176
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
5177
+ if ( $arry[ "name" ] == 'mpmax' ) {
5178
+ $tmp = array();
5179
+ $atr = array();
5180
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
5181
+ $atr[ 0 ][ "name" ] = $key;
5182
+ $atr[ 0 ][ "text" ] = $val;
5183
+ }
5184
+ $atr[ 1 ][ "name" ] = "value";
5185
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
5186
+ $this->MpMax = new BasicAmountType();
5187
+ $this->MpMax->init( $atr );
5188
+ }
5189
+
5190
+ }
5191
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'mpcustom' ) {
5192
+ $this->MpCustom = $arry[ "text" ];
5193
+ }
5194
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'desc' ) {
5195
+ $this->Desc = $arry[ "text" ];
5196
+ }
5197
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'invoice' ) {
5198
+ $this->Invoice = $arry[ "text" ];
5199
+ }
5200
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'custom' ) {
5201
+ $this->Custom = $arry[ "text" ];
5202
+ }
5203
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'paymentsourceid' ) {
5204
+ $this->PaymentSourceID = $arry[ "text" ];
5205
+ }
5206
+ }
5207
+ }
5208
+ }
5209
+ }
5210
+
5211
+
5212
+ /**
5213
+ * PaymentTransactionSearchResultType Results from a
5214
+ * PaymentTransaction search
5215
+ */
5216
+ class PaymentTransactionSearchResultType
5217
+ {
5218
+
5219
+ /**
5220
+ * The date and time (in UTC/GMT format) the transaction
5221
+ * occurred
5222
+ * @access public
5223
+ * @var dateTime
5224
+ */
5225
+ public $Timestamp;
5226
+
5227
+ /**
5228
+ * The time zone of the transaction
5229
+ * @access public
5230
+ * @var string
5231
+ */
5232
+ public $Timezone;
5233
+
5234
+ /**
5235
+ * The type of the transaction
5236
+ * @access public
5237
+ * @var string
5238
+ */
5239
+ public $Type;
5240
+
5241
+ /**
5242
+ * The email address of the payer
5243
+ * @access public
5244
+ * @var string
5245
+ */
5246
+ public $Payer;
5247
+
5248
+ /**
5249
+ * Display name of the payer
5250
+ * @access public
5251
+ * @var string
5252
+ */
5253
+ public $PayerDisplayName;
5254
+
5255
+ /**
5256
+ * The transaction ID of the seller
5257
+ * @access public
5258
+ * @var string
5259
+ */
5260
+ public $TransactionID;
5261
+
5262
+ /**
5263
+ * The status of the transaction
5264
+ * @access public
5265
+ * @var string
5266
+ */
5267
+ public $Status;
5268
+
5269
+ /**
5270
+ * The total gross amount charged, including any profile
5271
+ * shipping cost and taxes
5272
+ * @access public
5273
+ * @var BasicAmountType
5274
+ */
5275
+ public $GrossAmount;
5276
+
5277
+ /**
5278
+ * The fee that PayPal charged for the transaction
5279
+ * @access public
5280
+ * @var BasicAmountType
5281
+ */
5282
+ public $FeeAmount;
5283
+
5284
+ /**
5285
+ * The net amount of the transaction
5286
+ * @access public
5287
+ * @var BasicAmountType
5288
+ */
5289
+ public $NetAmount;
5290
+
5291
+
5292
+ public function init( $arr = null )
5293
+ {
5294
+ if ( $arr != null ) {
5295
+ foreach ( $arr as $arry ) {
5296
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'timestamp' ) {
5297
+ $this->Timestamp = $arry[ "text" ];
5298
+ }
5299
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'timezone' ) {
5300
+ $this->Timezone = $arry[ "text" ];
5301
+ }
5302
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'type' ) {
5303
+ $this->Type = $arry[ "text" ];
5304
+ }
5305
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'payer' ) {
5306
+ $this->Payer = $arry[ "text" ];
5307
+ }
5308
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'payerdisplayname' ) {
5309
+ $this->PayerDisplayName = $arry[ "text" ];
5310
+ }
5311
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'transactionid' ) {
5312
+ $this->TransactionID = $arry[ "text" ];
5313
+ }
5314
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'status' ) {
5315
+ $this->Status = $arry[ "text" ];
5316
+ }
5317
+
5318
+
5319
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
5320
+ if ( $arry[ "name" ] == 'grossamount' ) {
5321
+ $tmp = array();
5322
+ $atr = array();
5323
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
5324
+ $atr[ 0 ][ "name" ] = $key;
5325
+ $atr[ 0 ][ "text" ] = $val;
5326
+ }
5327
+ $atr[ 1 ][ "name" ] = "value";
5328
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
5329
+ $this->GrossAmount = new BasicAmountType();
5330
+ $this->GrossAmount->init( $atr );
5331
+ }
5332
+
5333
+ }
5334
+
5335
+
5336
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
5337
+ if ( $arry[ "name" ] == 'feeamount' ) {
5338
+ $tmp = array();
5339
+ $atr = array();
5340
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
5341
+ $atr[ 0 ][ "name" ] = $key;
5342
+ $atr[ 0 ][ "text" ] = $val;
5343
+ }
5344
+ $atr[ 1 ][ "name" ] = "value";
5345
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
5346
+ $this->FeeAmount = new BasicAmountType();
5347
+ $this->FeeAmount->init( $atr );
5348
+ }
5349
+
5350
+ }
5351
+
5352
+
5353
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
5354
+ if ( $arry[ "name" ] == 'netamount' ) {
5355
+ $tmp = array();
5356
+ $atr = array();
5357
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
5358
+ $atr[ 0 ][ "name" ] = $key;
5359
+ $atr[ 0 ][ "text" ] = $val;
5360
+ }
5361
+ $atr[ 1 ][ "name" ] = "value";
5362
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
5363
+ $this->NetAmount = new BasicAmountType();
5364
+ $this->NetAmount->init( $atr );
5365
+ }
5366
+
5367
+ }
5368
+ }
5369
+ }
5370
+ }
5371
+ }
5372
+
5373
+
5374
+ /**
5375
+ * MerchantPullPayment Parameters to make initiate a pull
5376
+ * payment
5377
+ */
5378
+ class MerchantPullPaymentType
5379
+ {
5380
+
5381
+ /**
5382
+ * The amount to charge to the customer. Required Only numeric
5383
+ * characters and a decimal separator are allowed. Limit: 10
5384
+ * single-byte characters, including two for decimals You must
5385
+ * set the currencyID attribute to one of the three-character
5386
+ * currency code for any of the supported PayPal currencies.
5387
+ * @access public
5388
+ * @var BasicAmountType
5389
+ */
5390
+ public $Amount;
5391
+
5392
+ /**
5393
+ * Preapproved Payments billing agreement identification number
5394
+ * between the PayPal customer and you. Required Character
5395
+ * limit: 19 single-byte alphanumeric characters. The format of
5396
+ * a billing agreement identification number is the
5397
+ * single-character prefix B, followed by a hyphen and an
5398
+ * alphanumeric character string: B-unique_alphanumeric_string
5399
+ * @access public
5400
+ * @var string
5401
+ */
5402
+ public $MpID;
5403
+
5404
+ /**
5405
+ * Specifies type of PayPal payment you require Optional
5406
+ * @access public
5407
+ * @var MerchantPullPaymentCodeType
5408
+ */
5409
+ public $PaymentType;
5410
+
5411
+ /**
5412
+ * Text entered by the customer in the Note field during
5413
+ * enrollment Optional
5414
+ * @access public
5415
+ * @var string
5416
+ */
5417
+ public $Memo;
5418
+
5419
+ /**
5420
+ * Subject line of confirmation email sent to recipient
5421
+ * Optional
5422
+ * @access public
5423
+ * @var string
5424
+ */
5425
+ public $EmailSubject;
5426
+
5427
+ /**
5428
+ * The tax charged on the transaction Optional
5429
+ * @access public
5430
+ * @var BasicAmountType
5431
+ */
5432
+ public $Tax;
5433
+
5434
+ /**
5435
+ * Per-transaction shipping charge Optional
5436
+ * @access public
5437
+ * @var BasicAmountType
5438
+ */
5439
+ public $Shipping;
5440
+
5441
+ /**
5442
+ * Per-transaction handling charge Optional
5443
+ * @access public
5444
+ * @var BasicAmountType
5445
+ */
5446
+ public $Handling;
5447
+
5448
+ /**
5449
+ * Name of purchased item Optional
5450
+ * @access public
5451
+ * @var string
5452
+ */
5453
+ public $ItemName;
5454
+
5455
+ /**
5456
+ * Reference number of purchased item Optional
5457
+ * @access public
5458
+ * @var string
5459
+ */
5460
+ public $ItemNumber;
5461
+
5462
+ /**
5463
+ * Your invoice number Optional
5464
+ * @access public
5465
+ * @var string
5466
+ */
5467
+ public $Invoice;
5468
+
5469
+ /**
5470
+ * Custom annotation field for tracking or other use Optional
5471
+ * @access public
5472
+ * @var string
5473
+ */
5474
+ public $Custom;
5475
+
5476
+ /**
5477
+ * An identification code for use by third-party applications
5478
+ * to identify transactions. Optional Character length and
5479
+ * limitations: 32 single-byte alphanumeric characters
5480
+ * @access public
5481
+ * @var string
5482
+ */
5483
+ public $ButtonSource;
5484
+
5485
+ /**
5486
+ * Passed in soft descriptor string to be appended. Optional
5487
+ * Character length and limitations: single-byte alphanumeric
5488
+ * characters
5489
+ * @access public
5490
+ * @var string
5491
+ */
5492
+ public $SoftDescriptor;
5493
+
5494
+
5495
+ public function toXMLString()
5496
+ {
5497
+ $str = '';
5498
+ if ( $this->Amount != null ) {
5499
+ $str .= '<ebl:Amount';
5500
+ $str .= $this->Amount->toXMLString();
5501
+ $str .= '</ebl:Amount>';
5502
+ }
5503
+ if ( $this->MpID != null ) {
5504
+ $str .= '<ebl:MpID>' . PPUtils::escapeInvalidXmlCharsRegex( $this->MpID ) . '</ebl:MpID>';
5505
+ }
5506
+ if ( $this->PaymentType != null ) {
5507
+ $str .= '<ebl:PaymentType>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PaymentType ) . '</ebl:PaymentType>';
5508
+ }
5509
+ if ( $this->Memo != null ) {
5510
+ $str .= '<ebl:Memo>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Memo ) . '</ebl:Memo>';
5511
+ }
5512
+ if ( $this->EmailSubject != null ) {
5513
+ $str .= '<ebl:EmailSubject>' . PPUtils::escapeInvalidXmlCharsRegex( $this->EmailSubject ) . '</ebl:EmailSubject>';
5514
+ }
5515
+ if ( $this->Tax != null ) {
5516
+ $str .= '<ebl:Tax';
5517
+ $str .= $this->Tax->toXMLString();
5518
+ $str .= '</ebl:Tax>';
5519
+ }
5520
+ if ( $this->Shipping != null ) {
5521
+ $str .= '<ebl:Shipping';
5522
+ $str .= $this->Shipping->toXMLString();
5523
+ $str .= '</ebl:Shipping>';
5524
+ }
5525
+ if ( $this->Handling != null ) {
5526
+ $str .= '<ebl:Handling';
5527
+ $str .= $this->Handling->toXMLString();
5528
+ $str .= '</ebl:Handling>';
5529
+ }
5530
+ if ( $this->ItemName != null ) {
5531
+ $str .= '<ebl:ItemName>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ItemName ) . '</ebl:ItemName>';
5532
+ }
5533
+ if ( $this->ItemNumber != null ) {
5534
+ $str .= '<ebl:ItemNumber>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ItemNumber ) . '</ebl:ItemNumber>';
5535
+ }
5536
+ if ( $this->Invoice != null ) {
5537
+ $str .= '<ebl:Invoice>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Invoice ) . '</ebl:Invoice>';
5538
+ }
5539
+ if ( $this->Custom != null ) {
5540
+ $str .= '<ebl:Custom>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Custom ) . '</ebl:Custom>';
5541
+ }
5542
+ if ( $this->ButtonSource != null ) {
5543
+ $str .= '<ebl:ButtonSource>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ButtonSource ) . '</ebl:ButtonSource>';
5544
+ }
5545
+ if ( $this->SoftDescriptor != null ) {
5546
+ $str .= '<ebl:SoftDescriptor>' . PPUtils::escapeInvalidXmlCharsRegex( $this->SoftDescriptor ) . '</ebl:SoftDescriptor>';
5547
+ }
5548
+
5549
+ return $str;
5550
+ }
5551
+
5552
+
5553
+ }
5554
+
5555
+
5556
+ /**
5557
+ * PaymentTransactionType Information about a PayPal payment
5558
+ * from the seller side
5559
+ */
5560
+ class PaymentTransactionType
5561
+ {
5562
+
5563
+ /**
5564
+ * Information about the recipient of the payment
5565
+ * @access public
5566
+ * @var ReceiverInfoType
5567
+ */
5568
+ public $ReceiverInfo;
5569
+
5570
+ /**
5571
+ * Information about the payer
5572
+ * @access public
5573
+ * @var PayerInfoType
5574
+ */
5575
+ public $PayerInfo;
5576
+
5577
+ /**
5578
+ * This field is for holding ReferenceId for shippment sent
5579
+ * from Merchant to the 3rd Party
5580
+ * @access public
5581
+ * @var string
5582
+ */
5583
+ public $TPLReferenceID;
5584
+
5585
+ /**
5586
+ * Information about the transaction
5587
+ * @access public
5588
+ * @var PaymentInfoType
5589
+ */
5590
+ public $PaymentInfo;
5591
+
5592
+ /**
5593
+ * Information about an individual item in the transaction
5594
+ * @access public
5595
+ * @var PaymentItemInfoType
5596
+ */
5597
+ public $PaymentItemInfo;
5598
+
5599
+ /**
5600
+ * Information about an individual Offer and Coupon information
5601
+ * in the transaction
5602
+ * @access public
5603
+ * @var OfferCouponInfoType
5604
+ */
5605
+ public $OfferCouponInfo;
5606
+
5607
+ /**
5608
+ * Information about Secondary Address
5609
+ * @access public
5610
+ * @var AddressType
5611
+ */
5612
+ public $SecondaryAddress;
5613
+
5614
+ /**
5615
+ * Information about the user selected options.
5616
+ * @access public
5617
+ * @var UserSelectedOptionType
5618
+ */
5619
+ public $UserSelectedOptions;
5620
+
5621
+ /**
5622
+ * Information about the Gift message.
5623
+ * @access public
5624
+ * @var string
5625
+ */
5626
+ public $GiftMessage;
5627
+
5628
+ /**
5629
+ * Information about the Gift receipt.
5630
+ * @access public
5631
+ * @var string
5632
+ */
5633
+ public $GiftReceipt;
5634
+
5635
+ /**
5636
+ * Information about the Gift Wrap name.
5637
+ * @access public
5638
+ * @var string
5639
+ */
5640
+ public $GiftWrapName;
5641
+
5642
+ /**
5643
+ * Information about the Gift Wrap amount.
5644
+ * @access public
5645
+ * @var BasicAmountType
5646
+ */
5647
+ public $GiftWrapAmount;
5648
+
5649
+ /**
5650
+ * Information about the Buyer email.
5651
+ * @access public
5652
+ * @var string
5653
+ */
5654
+ public $BuyerEmailOptIn;
5655
+
5656
+ /**
5657
+ * Information about the survey question.
5658
+ * @access public
5659
+ * @var string
5660
+ */
5661
+ public $SurveyQuestion;
5662
+
5663
+ /**
5664
+ * Information about the survey choice selected by the user.
5665
+ * @array
5666
+ * @access public
5667
+ * @var string
5668
+ */
5669
+ public $SurveyChoiceSelected;
5670
+
5671
+
5672
+ public function init( $arr = null )
5673
+ {
5674
+ if ( $arr != null ) {
5675
+ foreach ( $arr as $arry ) {
5676
+
5677
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
5678
+ if ( $arry[ "name" ] == 'receiverinfo' ) {
5679
+ $this->ReceiverInfo = new ReceiverInfoType();
5680
+ $this->ReceiverInfo->init( $arry[ "children" ] );
5681
+ }
5682
+
5683
+ }
5684
+
5685
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
5686
+ if ( $arry[ "name" ] == 'payerinfo' ) {
5687
+ $this->PayerInfo = new PayerInfoType();
5688
+ $this->PayerInfo->init( $arry[ "children" ] );
5689
+ }
5690
+
5691
+ }
5692
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'tplreferenceid' ) {
5693
+ $this->TPLReferenceID = $arry[ "text" ];
5694
+ }
5695
+
5696
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
5697
+ if ( $arry[ "name" ] == 'paymentinfo' ) {
5698
+ $this->PaymentInfo = new PaymentInfoType();
5699
+ $this->PaymentInfo->init( $arry[ "children" ] );
5700
+ }
5701
+
5702
+ }
5703
+
5704
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
5705
+ if ( $arry[ "name" ] == 'paymentiteminfo' ) {
5706
+ $this->PaymentItemInfo = new PaymentItemInfoType();
5707
+ $this->PaymentItemInfo->init( $arry[ "children" ] );
5708
+ }
5709
+
5710
+ }
5711
+
5712
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
5713
+ if ( $arry[ "name" ] == 'offercouponinfo' ) {
5714
+ $this->OfferCouponInfo = new OfferCouponInfoType();
5715
+ $this->OfferCouponInfo->init( $arry[ "children" ] );
5716
+ }
5717
+
5718
+ }
5719
+
5720
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
5721
+ if ( $arry[ "name" ] == 'secondaryaddress' ) {
5722
+ $this->SecondaryAddress = new AddressType();
5723
+ $this->SecondaryAddress->init( $arry[ "children" ] );
5724
+ }
5725
+
5726
+ }
5727
+
5728
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
5729
+ if ( $arry[ "name" ] == 'userselectedoptions' ) {
5730
+ $this->UserSelectedOptions = new UserSelectedOptionType();
5731
+ $this->UserSelectedOptions->init( $arry[ "children" ] );
5732
+ }
5733
+
5734
+ }
5735
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'giftmessage' ) {
5736
+ $this->GiftMessage = $arry[ "text" ];
5737
+ }
5738
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'giftreceipt' ) {
5739
+ $this->GiftReceipt = $arry[ "text" ];
5740
+ }
5741
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'giftwrapname' ) {
5742
+ $this->GiftWrapName = $arry[ "text" ];
5743
+ }
5744
+
5745
+
5746
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
5747
+ if ( $arry[ "name" ] == 'giftwrapamount' ) {
5748
+ $tmp = array();
5749
+ $atr = array();
5750
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
5751
+ $atr[ 0 ][ "name" ] = $key;
5752
+ $atr[ 0 ][ "text" ] = $val;
5753
+ }
5754
+ $atr[ 1 ][ "name" ] = "value";
5755
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
5756
+ $this->GiftWrapAmount = new BasicAmountType();
5757
+ $this->GiftWrapAmount->init( $atr );
5758
+ }
5759
+
5760
+ }
5761
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'buyeremailoptin' ) {
5762
+ $this->BuyerEmailOptIn = $arry[ "text" ];
5763
+ }
5764
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'surveyquestion' ) {
5765
+ $this->SurveyQuestion = $arry[ "text" ];
5766
+ }
5767
+ }
5768
+ }
5769
+ }
5770
+ }
5771
+
5772
+
5773
+ /**
5774
+ * ReceiverInfoType Receiver information.
5775
+ */
5776
+ class ReceiverInfoType
5777
+ {
5778
+
5779
+ /**
5780
+ * Email address or account ID of the payment recipient (the
5781
+ * seller). Equivalent to Receiver if payment is sent to
5782
+ * primary account. Character length and limitations: 127
5783
+ * single-byte alphanumeric characters
5784
+ * @access public
5785
+ * @var string
5786
+ */
5787
+ public $Business;
5788
+
5789
+ /**
5790
+ * Primary email address of the payment recipient (the seller).
5791
+ * If you are the recipient of the payment and the payment is
5792
+ * sent to your non-primary email address, the value of
5793
+ * Receiver is still your primary email address. Character
5794
+ * length and limitations: 127 single-byte alphanumeric
5795
+ * characters
5796
+ * @access public
5797
+ * @var string
5798
+ */
5799
+ public $Receiver;
5800
+
5801
+ /**
5802
+ * Unique account ID of the payment recipient (the seller).
5803
+ * This value is the same as the value of the recipient's
5804
+ * referral ID.
5805
+ * @access public
5806
+ * @var string
5807
+ */
5808
+ public $ReceiverID;
5809
+
5810
+
5811
+ public function init( $arr = null )
5812
+ {
5813
+ if ( $arr != null ) {
5814
+ foreach ( $arr as $arry ) {
5815
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'business' ) {
5816
+ $this->Business = $arry[ "text" ];
5817
+ }
5818
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'receiver' ) {
5819
+ $this->Receiver = $arry[ "text" ];
5820
+ }
5821
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'receiverid' ) {
5822
+ $this->ReceiverID = $arry[ "text" ];
5823
+ }
5824
+ }
5825
+ }
5826
+ }
5827
+ }
5828
+
5829
+
5830
+ /**
5831
+ * PayerInfoType Payer information
5832
+ */
5833
+ class PayerInfoType
5834
+ {
5835
+
5836
+ /**
5837
+ * Email address of payer Character length and limitations: 127
5838
+ * single-byte characters
5839
+ * @access public
5840
+ * @var string
5841
+ */
5842
+ public $Payer;
5843
+
5844
+ /**
5845
+ * Unique customer ID Character length and limitations: 17
5846
+ * single-byte characters
5847
+ * @access public
5848
+ * @var string
5849
+ */
5850
+ public $PayerID;
5851
+
5852
+ /**
5853
+ * Status of payer's email address
5854
+ * @access public
5855
+ * @var PayPalUserStatusCodeType
5856
+ */
5857
+ public $PayerStatus;
5858
+
5859
+ /**
5860
+ * Name of payer
5861
+ * @access public
5862
+ * @var PersonNameType
5863
+ */
5864
+ public $PayerName;
5865
+
5866
+ /**
5867
+ * Payment sender's country of residence using standard
5868
+ * two-character ISO 3166 country codes. Character length and
5869
+ * limitations: Two single-byte characters
5870
+ * @access public
5871
+ * @var CountryCodeType
5872
+ */
5873
+ public $PayerCountry;
5874
+
5875
+ /**
5876
+ * Payer's business name. Character length and limitations: 127
5877
+ * single-byte characters
5878
+ * @access public
5879
+ * @var string
5880
+ */
5881
+ public $PayerBusiness;
5882
+
5883
+ /**
5884
+ * Payer's business address
5885
+ * @access public
5886
+ * @var AddressType
5887
+ */
5888
+ public $Address;
5889
+
5890
+ /**
5891
+ * Business contact telephone number
5892
+ * @access public
5893
+ * @var string
5894
+ */
5895
+ public $ContactPhone;
5896
+
5897
+ /**
5898
+ * Details about payer's tax info. Refer to the
5899
+ * TaxIdDetailsType for more details.
5900
+ * @access public
5901
+ * @var TaxIdDetailsType
5902
+ */
5903
+ public $TaxIdDetails;
5904
+
5905
+ /**
5906
+ * Holds any enhanced information about the payer
5907
+ * @access public
5908
+ * @var EnhancedPayerInfoType
5909
+ */
5910
+ public $EnhancedPayerInfo;
5911
+
5912
+
5913
+ public function toXMLString()
5914
+ {
5915
+ $str = '';
5916
+ if ( $this->Payer != null ) {
5917
+ $str .= '<ebl:Payer>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Payer ) . '</ebl:Payer>';
5918
+ }
5919
+ if ( $this->PayerID != null ) {
5920
+ $str .= '<ebl:PayerID>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PayerID ) . '</ebl:PayerID>';
5921
+ }
5922
+ if ( $this->PayerStatus != null ) {
5923
+ $str .= '<ebl:PayerStatus>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PayerStatus ) . '</ebl:PayerStatus>';
5924
+ }
5925
+ if ( $this->PayerName != null ) {
5926
+ $str .= '<ebl:PayerName>';
5927
+ $str .= $this->PayerName->toXMLString();
5928
+ $str .= '</ebl:PayerName>';
5929
+ }
5930
+ if ( $this->PayerCountry != null ) {
5931
+ $str .= '<ebl:PayerCountry>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PayerCountry ) . '</ebl:PayerCountry>';
5932
+ }
5933
+ if ( $this->PayerBusiness != null ) {
5934
+ $str .= '<ebl:PayerBusiness>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PayerBusiness ) . '</ebl:PayerBusiness>';
5935
+ }
5936
+ if ( $this->Address != null ) {
5937
+ $str .= '<ebl:Address>';
5938
+ $str .= $this->Address->toXMLString();
5939
+ $str .= '</ebl:Address>';
5940
+ }
5941
+ if ( $this->ContactPhone != null ) {
5942
+ $str .= '<ebl:ContactPhone>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ContactPhone ) . '</ebl:ContactPhone>';
5943
+ }
5944
+ if ( $this->TaxIdDetails != null ) {
5945
+ $str .= '<ebl:TaxIdDetails>';
5946
+ $str .= $this->TaxIdDetails->toXMLString();
5947
+ $str .= '</ebl:TaxIdDetails>';
5948
+ }
5949
+ if ( $this->EnhancedPayerInfo != null ) {
5950
+ $str .= '<ebl:EnhancedPayerInfo>';
5951
+ $str .= $this->EnhancedPayerInfo->toXMLString();
5952
+ $str .= '</ebl:EnhancedPayerInfo>';
5953
+ }
5954
+
5955
+ return $str;
5956
+ }
5957
+
5958
+
5959
+ public function init( $arr = null )
5960
+ {
5961
+ if ( $arr != null ) {
5962
+ foreach ( $arr as $arry ) {
5963
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'payer' ) {
5964
+ $this->Payer = $arry[ "text" ];
5965
+ }
5966
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'payerid' ) {
5967
+ $this->PayerID = $arry[ "text" ];
5968
+ }
5969
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'payerstatus' ) {
5970
+ $this->PayerStatus = $arry[ "text" ];
5971
+ }
5972
+
5973
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
5974
+ if ( $arry[ "name" ] == 'payername' ) {
5975
+ $this->PayerName = new PersonNameType();
5976
+ $this->PayerName->init( $arry[ "children" ] );
5977
+ }
5978
+
5979
+ }
5980
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'payercountry' ) {
5981
+ $this->PayerCountry = $arry[ "text" ];
5982
+ }
5983
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'payerbusiness' ) {
5984
+ $this->PayerBusiness = $arry[ "text" ];
5985
+ }
5986
+
5987
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
5988
+ if ( $arry[ "name" ] == 'address' ) {
5989
+ $this->Address = new AddressType();
5990
+ $this->Address->init( $arry[ "children" ] );
5991
+ }
5992
+
5993
+ }
5994
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'contactphone' ) {
5995
+ $this->ContactPhone = $arry[ "text" ];
5996
+ }
5997
+
5998
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
5999
+ if ( $arry[ "name" ] == 'taxiddetails' ) {
6000
+ $this->TaxIdDetails = new TaxIdDetailsType();
6001
+ $this->TaxIdDetails->init( $arry[ "children" ] );
6002
+ }
6003
+
6004
+ }
6005
+
6006
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
6007
+ if ( $arry[ "name" ] == 'enhancedpayerinfo' ) {
6008
+ $this->EnhancedPayerInfo = new EnhancedPayerInfoType();
6009
+ $this->EnhancedPayerInfo->init( $arry[ "children" ] );
6010
+ }
6011
+
6012
+ }
6013
+ }
6014
+ }
6015
+ }
6016
+ }
6017
+
6018
+
6019
+ /**
6020
+ * InstrumentDetailsType Promotional Instrument Information.
6021
+ */
6022
+ class InstrumentDetailsType
6023
+ {
6024
+
6025
+ /**
6026
+ * This field holds the category of the instrument only when it
6027
+ * is promotional. Return value 1 represents BML.
6028
+ * @access public
6029
+ * @var string
6030
+ */
6031
+ public $InstrumentCategory;
6032
+
6033
+
6034
+ public function init( $arr = null )
6035
+ {
6036
+ if ( $arr != null ) {
6037
+ foreach ( $arr as $arry ) {
6038
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'instrumentcategory' ) {
6039
+ $this->InstrumentCategory = $arry[ "text" ];
6040
+ }
6041
+ }
6042
+ }
6043
+ }
6044
+ }
6045
+
6046
+
6047
+ /**
6048
+ * BMLOfferInfoType Specific information for BML.
6049
+ */
6050
+ class BMLOfferInfoType
6051
+ {
6052
+
6053
+ /**
6054
+ * Unique identification for merchant/buyer/offer combo.
6055
+ * @access public
6056
+ * @var string
6057
+ */
6058
+ public $OfferTrackingID;
6059
+
6060
+
6061
+ public function toXMLString()
6062
+ {
6063
+ $str = '';
6064
+ if ( $this->OfferTrackingID != null ) {
6065
+ $str .= '<ebl:OfferTrackingID>' . PPUtils::escapeInvalidXmlCharsRegex( $this->OfferTrackingID ) . '</ebl:OfferTrackingID>';
6066
+ }
6067
+
6068
+ return $str;
6069
+ }
6070
+
6071
+
6072
+ public function init( $arr = null )
6073
+ {
6074
+ if ( $arr != null ) {
6075
+ foreach ( $arr as $arry ) {
6076
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'offertrackingid' ) {
6077
+ $this->OfferTrackingID = $arry[ "text" ];
6078
+ }
6079
+ }
6080
+ }
6081
+ }
6082
+ }
6083
+
6084
+
6085
+ /**
6086
+ * OfferDetailsType Specific information for an offer.
6087
+ */
6088
+ class OfferDetailsType
6089
+ {
6090
+
6091
+ /**
6092
+ * Code used to identify the promotion offer.
6093
+ * @access public
6094
+ * @var string
6095
+ */
6096
+ public $OfferCode;
6097
+
6098
+ /**
6099
+ * Specific infromation for BML, Similar structure could be
6100
+ * added for sepcific promotion needs like CrossPromotions
6101
+ * @access public
6102
+ * @var BMLOfferInfoType
6103
+ */
6104
+ public $BMLOfferInfo;
6105
+
6106
+
6107
+ public function toXMLString()
6108
+ {
6109
+ $str = '';
6110
+ if ( $this->OfferCode != null ) {
6111
+ $str .= '<ebl:OfferCode>' . PPUtils::escapeInvalidXmlCharsRegex( $this->OfferCode ) . '</ebl:OfferCode>';
6112
+ }
6113
+ if ( $this->BMLOfferInfo != null ) {
6114
+ $str .= '<ebl:BMLOfferInfo>';
6115
+ $str .= $this->BMLOfferInfo->toXMLString();
6116
+ $str .= '</ebl:BMLOfferInfo>';
6117
+ }
6118
+
6119
+ return $str;
6120
+ }
6121
+
6122
+
6123
+ public function init( $arr = null )
6124
+ {
6125
+ if ( $arr != null ) {
6126
+ foreach ( $arr as $arry ) {
6127
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'offercode' ) {
6128
+ $this->OfferCode = $arry[ "text" ];
6129
+ }
6130
+
6131
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
6132
+ if ( $arry[ "name" ] == 'bmlofferinfo' ) {
6133
+ $this->BMLOfferInfo = new BMLOfferInfoType();
6134
+ $this->BMLOfferInfo->init( $arry[ "children" ] );
6135
+ }
6136
+
6137
+ }
6138
+ }
6139
+ }
6140
+ }
6141
+ }
6142
+
6143
+
6144
+ /**
6145
+ * PaymentInfoType Payment information.
6146
+ */
6147
+ class PaymentInfoType
6148
+ {
6149
+
6150
+ /**
6151
+ * A transaction identification number. Character length and
6152
+ * limits: 19 single-byte characters maximum
6153
+ * @access public
6154
+ * @var string
6155
+ */
6156
+ public $TransactionID;
6157
+
6158
+ /**
6159
+ * Its Ebay transaction id. EbayTransactionID will returned for
6160
+ * immediate pay item transaction in ECA
6161
+ * @access public
6162
+ * @var string
6163
+ */
6164
+ public $EbayTransactionID;
6165
+
6166
+ /**
6167
+ * Parent or related transaction identification number. This
6168
+ * field is populated for the following transaction types:
6169
+ * ReversalCapture of an authorized transaction.Reauthorization
6170
+ * of a transaction.Capture of an order. The value of
6171
+ * ParentTransactionID is the original OrderID.Authorization of
6172
+ * an order. The value of ParentTransactionID is the original
6173
+ * OrderID.Capture of an order authorization.Void of an order.
6174
+ * The value of ParentTransactionID is the original OrderID.
6175
+ * Character length and limits: 19 single-byte characters
6176
+ * maximum
6177
+ * @access public
6178
+ * @var string
6179
+ */
6180
+ public $ParentTransactionID;
6181
+
6182
+ /**
6183
+ * Receipt ID Character length and limitations: 16 digits in
6184
+ * xxxx-xxxx-xxxx-xxxx format
6185
+ * @access public
6186
+ * @var string
6187
+ */
6188
+ public $ReceiptID;
6189
+
6190
+ /**
6191
+ * The type of transaction cart: Transaction created via the
6192
+ * PayPal Shopping Cart feature or by Express Checkout with
6193
+ * multiple purchased item express-checkout: Transaction
6194
+ * created by Express Checkout with a single purchased items
6195
+ * send-money: Transaction created by customer from the Send
6196
+ * Money tab on the PayPal website. web-accept: Transaction
6197
+ * created by customer via Buy Now, Donation, or Auction Smart
6198
+ * Logos. subscr-*: Transaction created by customer via
6199
+ * Subscription. eot means "end of subscription term."
6200
+ * merch-pmt: preapproved payment. mass-pay: Transaction
6201
+ * created via MassPay. virtual-terminal: Transaction created
6202
+ * via merchant virtual terminal. credit: Transaction created
6203
+ * via merchant virtual terminal or API to credit a customer.
6204
+ * @access public
6205
+ * @var PaymentTransactionCodeType
6206
+ */
6207
+ public $TransactionType;
6208
+
6209
+ /**
6210
+ * The type of payment
6211
+ * @access public
6212
+ * @var PaymentCodeType
6213
+ */
6214
+ public $PaymentType;
6215
+
6216
+ /**
6217
+ * The type of funding source
6218
+ * @access public
6219
+ * @var RefundSourceCodeType
6220
+ */
6221
+ public $RefundSourceCodeType;
6222
+
6223
+ /**
6224
+ * eCheck latest expected clear date
6225
+ * @access public
6226
+ * @var dateTime
6227
+ */
6228
+ public $ExpectedeCheckClearDate;
6229
+
6230
+ /**
6231
+ * Date and time of payment
6232
+ * @access public
6233
+ * @var dateTime
6234
+ */
6235
+ public $PaymentDate;
6236
+
6237
+ /**
6238
+ * Full amount of the customer's payment, before transaction
6239
+ * fee is subtracted
6240
+ * @access public
6241
+ * @var BasicAmountType
6242
+ */
6243
+ public $GrossAmount;
6244
+
6245
+ /**
6246
+ * Transaction fee associated with the payment
6247
+ * @access public
6248
+ * @var BasicAmountType
6249
+ */
6250
+ public $FeeAmount;
6251
+
6252
+ /**
6253
+ * Amount deposited into the account's primary balance after a
6254
+ * currency conversion from automatic conversion through your
6255
+ * Payment Receiving Preferences or manual conversion through
6256
+ * manually accepting a payment. This amount is calculated
6257
+ * after fees and taxes have been assessed.
6258
+ * @access public
6259
+ * @var BasicAmountType
6260
+ */
6261
+ public $SettleAmount;
6262
+
6263
+ /**
6264
+ * Amount of tax for transaction
6265
+ * @access public
6266
+ * @var BasicAmountType
6267
+ */
6268
+ public $TaxAmount;
6269
+
6270
+ /**
6271
+ * Exchange rate for transaction
6272
+ * @access public
6273
+ * @var string
6274
+ */
6275
+ public $ExchangeRate;
6276
+
6277
+ /**
6278
+ * The status of the payment: None: No status Created: A
6279
+ * giropay payment has been initiated. Canceled-Reversal: A
6280
+ * reversal has been canceled. For example, you won a dispute
6281
+ * with the customer, and the funds for the transaction that
6282
+ * was reversed have been returned to you. Completed: The
6283
+ * payment has been completed, and the funds have been added
6284
+ * successfully to your account balance. Denied: You denied the
6285
+ * payment. This happens only if the payment was previously
6286
+ * pending because of possible reasons described for the
6287
+ * PendingReason element. Expired: This authorization has
6288
+ * expired and cannot be captured. Failed: The payment has
6289
+ * failed. This happens only if the payment was made from your
6290
+ * customer's bank account. In-Progress: The transaction is in
6291
+ * process of authorization and capture. Partially-Refunded:
6292
+ * The transaction has been partially refunded. Pending: The
6293
+ * payment is pending. See "PendingReason" for more
6294
+ * information. Refunded: You refunded the payment. Reversed: A
6295
+ * payment was reversed due to a chargeback or other type of
6296
+ * reversal. The funds have been removed from your account
6297
+ * balance and returned to the buyer. The reason for the
6298
+ * reversal is specified in the ReasonCode element. Processed:
6299
+ * A payment has been accepted. Voided: This authorization has
6300
+ * been voided. Completed-Funds-Held: The payment has been
6301
+ * completed, and the funds have been added successfully to
6302
+ * your pending balance. See the "HoldDecision" field for more
6303
+ * information.
6304
+ * @access public
6305
+ * @var PaymentStatusCodeType
6306
+ */
6307
+ public $PaymentStatus;
6308
+
6309
+ /**
6310
+ * The reason the payment is pending: none: No pending reason
6311
+ * address: The payment is pending because your customer did
6312
+ * not include a confirmed shipping address and your Payment
6313
+ * Receiving Preferences is set such that you want to manually
6314
+ * accept or deny each of these payments. To change your
6315
+ * preference, go to the Preferences section of your Profile.
6316
+ * authorization: You set PaymentAction to Authorization on
6317
+ * SetExpressCheckoutRequest and have not yet captured funds.
6318
+ * echeck: The payment is pending because it was made by an
6319
+ * eCheck that has not yet cleared. intl: The payment is
6320
+ * pending because you hold a non-U.S. account and do not have
6321
+ * a withdrawal mechanism. You must manually accept or deny
6322
+ * this payment from your Account Overview. multi-currency: You
6323
+ * do not have a balance in the currency sent, and you do not
6324
+ * have your Payment Receiving Preferences set to automatically
6325
+ * convert and accept this payment. You must manually accept or
6326
+ * deny this payment. unilateral: The payment is pending
6327
+ * because it was made to an email address that is not yet
6328
+ * registered or confirmed. upgrade: The payment is pending
6329
+ * because it was made via credit card and you must upgrade
6330
+ * your account to Business or Premier status in order to
6331
+ * receive the funds. upgrade can also mean that you have
6332
+ * reached the monthly limit for transactions on your account.
6333
+ * verify: The payment is pending because you are not yet
6334
+ * verified. You must verify your account before you can accept
6335
+ * this payment. other: The payment is pending for a reason
6336
+ * other than those listed above. For more information, contact
6337
+ * PayPal Customer Service.
6338
+ * @access public
6339
+ * @var PendingStatusCodeType
6340
+ */
6341
+ public $PendingReason;
6342
+
6343
+ /**
6344
+ * The reason for a reversal if TransactionType is reversal:
6345
+ * none: No reason code chargeback: A reversal has occurred on
6346
+ * this transaction due to a chargeback by your customer.
6347
+ * guarantee: A reversal has occurred on this transaction due
6348
+ * to your customer triggering a money-back guarantee.
6349
+ * buyer-complaint: A reversal has occurred on this transaction
6350
+ * due to a complaint about the transaction from your customer.
6351
+ * refund: A reversal has occurred on this transaction because
6352
+ * you have given the customer a refund. other: A reversal has
6353
+ * occurred on this transaction due to a reason not listed
6354
+ * above.
6355
+ * @access public
6356
+ * @var ReversalReasonCodeType
6357
+ */
6358
+ public $ReasonCode;
6359
+
6360
+ /**
6361
+ * HoldDecision is returned in the response only if
6362
+ * PaymentStatus is Completed-Funds-Held. The reason the funds
6363
+ * are kept in pending balance: newsellerpaymenthold: The
6364
+ * seller is new. paymenthold: A hold is placed on your
6365
+ * transaction due to a reason not listed above.
6366
+ * @access public
6367
+ * @var string
6368
+ */
6369
+ public $HoldDecision;
6370
+
6371
+ /**
6372
+ * Shipping method selected by the user during check-out.
6373
+ * @access public
6374
+ * @var string
6375
+ */
6376
+ public $ShippingMethod;
6377
+
6378
+ /**
6379
+ * Protection Eligibility for this Transaction - None, SPP or
6380
+ * ESPP
6381
+ * @access public
6382
+ * @var string
6383
+ */
6384
+ public $ProtectionEligibility;
6385
+
6386
+ /**
6387
+ * Protection Eligibility details for this Transaction
6388
+ * @access public
6389
+ * @var string
6390
+ */
6391
+ public $ProtectionEligibilityType;
6392
+
6393
+ /**
6394
+ * Receipt Reference Number for this Transaction
6395
+ * @access public
6396
+ * @var string
6397
+ */
6398
+ public $ReceiptReferenceNumber;
6399
+
6400
+ /**
6401
+ * The type of POS transaction F: Forced post transaction. POS
6402
+ * merchant can send transactions at a later point if
6403
+ * connectivity is lost. S: Single call checkout, and this is
6404
+ * to identify PayPal Lite API usage.
6405
+ * @access public
6406
+ * @var POSTransactionCodeType
6407
+ */
6408
+ public $POSTransactionType;
6409
+
6410
+ /**
6411
+ * Amount of shipping charged on transaction
6412
+ * @access public
6413
+ * @var string
6414
+ */
6415
+ public $ShipAmount;
6416
+
6417
+ /**
6418
+ * Amount of ship handling charged on transaction
6419
+ * @access public
6420
+ * @var string
6421
+ */
6422
+ public $ShipHandleAmount;
6423
+
6424
+ /**
6425
+ * Amount of shipping discount on transaction
6426
+ * @access public
6427
+ * @var string
6428
+ */
6429
+ public $ShipDiscount;
6430
+
6431
+ /**
6432
+ * Amount of Insurance amount on transaction
6433
+ * @access public
6434
+ * @var string
6435
+ */
6436
+ public $InsuranceAmount;
6437
+
6438
+ /**
6439
+ * Subject as entered in the transaction
6440
+ * @access public
6441
+ * @var string
6442
+ */
6443
+ public $Subject;
6444
+
6445
+ /**
6446
+ * StoreID as entered in the transaction
6447
+ * @access public
6448
+ * @var string
6449
+ */
6450
+ public $StoreID;
6451
+
6452
+ /**
6453
+ * TerminalID as entered in the transaction
6454
+ * @access public
6455
+ * @var string
6456
+ */
6457
+ public $TerminalID;
6458
+
6459
+ /**
6460
+ * Details about the seller. Optional
6461
+ * @access public
6462
+ * @var SellerDetailsType
6463
+ */
6464
+ public $SellerDetails;
6465
+
6466
+ /**
6467
+ * Unique identifier and mandatory for each bucket in case of
6468
+ * split payement
6469
+ * @access public
6470
+ * @var string
6471
+ */
6472
+ public $PaymentRequestID;
6473
+
6474
+ /**
6475
+ * Thes are filters that could result in accept/deny/pending
6476
+ * action.
6477
+ * @access public
6478
+ * @var FMFDetailsType
6479
+ */
6480
+ public $FMFDetails;
6481
+
6482
+ /**
6483
+ * This will be enhanced info for the payment: Example: UATP
6484
+ * details
6485
+ * @access public
6486
+ * @var EnhancedPaymentInfoType
6487
+ */
6488
+ public $EnhancedPaymentInfo;
6489
+
6490
+ /**
6491
+ * This will indicate the payment status for individual payment
6492
+ * request in case of split payment
6493
+ * @access public
6494
+ * @var ErrorType
6495
+ */
6496
+ public $PaymentError;
6497
+
6498
+ /**
6499
+ * Type of the payment instrument.
6500
+ * @access public
6501
+ * @var InstrumentDetailsType
6502
+ */
6503
+ public $InstrumentDetails;
6504
+
6505
+ /**
6506
+ * Offer Details.
6507
+ * @access public
6508
+ * @var OfferDetailsType
6509
+ */
6510
+ public $OfferDetails;
6511
+
6512
+
6513
+ public function init( $arr = null )
6514
+ {
6515
+ if ( $arr != null ) {
6516
+ foreach ( $arr as $arry ) {
6517
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'transactionid' ) {
6518
+ $this->TransactionID = $arry[ "text" ];
6519
+ }
6520
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'ebaytransactionid' ) {
6521
+ $this->EbayTransactionID = $arry[ "text" ];
6522
+ }
6523
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'parenttransactionid' ) {
6524
+ $this->ParentTransactionID = $arry[ "text" ];
6525
+ }
6526
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'receiptid' ) {
6527
+ $this->ReceiptID = $arry[ "text" ];
6528
+ }
6529
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'transactiontype' ) {
6530
+ $this->TransactionType = $arry[ "text" ];
6531
+ }
6532
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'paymenttype' ) {
6533
+ $this->PaymentType = $arry[ "text" ];
6534
+ }
6535
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'refundsourcecodetype' ) {
6536
+ $this->RefundSourceCodeType = $arry[ "text" ];
6537
+ }
6538
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'expectedecheckcleardate' ) {
6539
+ $this->ExpectedeCheckClearDate = $arry[ "text" ];
6540
+ }
6541
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'paymentdate' ) {
6542
+ $this->PaymentDate = $arry[ "text" ];
6543
+ }
6544
+
6545
+
6546
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
6547
+ if ( $arry[ "name" ] == 'grossamount' ) {
6548
+ $tmp = array();
6549
+ $atr = array();
6550
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
6551
+ $atr[ 0 ][ "name" ] = $key;
6552
+ $atr[ 0 ][ "text" ] = $val;
6553
+ }
6554
+ $atr[ 1 ][ "name" ] = "value";
6555
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
6556
+ $this->GrossAmount = new BasicAmountType();
6557
+ $this->GrossAmount->init( $atr );
6558
+ }
6559
+
6560
+ }
6561
+
6562
+
6563
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
6564
+ if ( $arry[ "name" ] == 'feeamount' ) {
6565
+ $tmp = array();
6566
+ $atr = array();
6567
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
6568
+ $atr[ 0 ][ "name" ] = $key;
6569
+ $atr[ 0 ][ "text" ] = $val;
6570
+ }
6571
+ $atr[ 1 ][ "name" ] = "value";
6572
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
6573
+ $this->FeeAmount = new BasicAmountType();
6574
+ $this->FeeAmount->init( $atr );
6575
+ }
6576
+
6577
+ }
6578
+
6579
+
6580
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
6581
+ if ( $arry[ "name" ] == 'settleamount' ) {
6582
+ $tmp = array();
6583
+ $atr = array();
6584
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
6585
+ $atr[ 0 ][ "name" ] = $key;
6586
+ $atr[ 0 ][ "text" ] = $val;
6587
+ }
6588
+ $atr[ 1 ][ "name" ] = "value";
6589
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
6590
+ $this->SettleAmount = new BasicAmountType();
6591
+ $this->SettleAmount->init( $atr );
6592
+ }
6593
+
6594
+ }
6595
+
6596
+
6597
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
6598
+ if ( $arry[ "name" ] == 'taxamount' ) {
6599
+ $tmp = array();
6600
+ $atr = array();
6601
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
6602
+ $atr[ 0 ][ "name" ] = $key;
6603
+ $atr[ 0 ][ "text" ] = $val;
6604
+ }
6605
+ $atr[ 1 ][ "name" ] = "value";
6606
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
6607
+ $this->TaxAmount = new BasicAmountType();
6608
+ $this->TaxAmount->init( $atr );
6609
+ }
6610
+
6611
+ }
6612
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'exchangerate' ) {
6613
+ $this->ExchangeRate = $arry[ "text" ];
6614
+ }
6615
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'paymentstatus' ) {
6616
+ $this->PaymentStatus = $arry[ "text" ];
6617
+ }
6618
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'pendingreason' ) {
6619
+ $this->PendingReason = $arry[ "text" ];
6620
+ }
6621
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'reasoncode' ) {
6622
+ $this->ReasonCode = $arry[ "text" ];
6623
+ }
6624
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'holddecision' ) {
6625
+ $this->HoldDecision = $arry[ "text" ];
6626
+ }
6627
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'shippingmethod' ) {
6628
+ $this->ShippingMethod = $arry[ "text" ];
6629
+ }
6630
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'protectioneligibility' ) {
6631
+ $this->ProtectionEligibility = $arry[ "text" ];
6632
+ }
6633
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'protectioneligibilitytype' ) {
6634
+ $this->ProtectionEligibilityType = $arry[ "text" ];
6635
+ }
6636
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'receiptreferencenumber' ) {
6637
+ $this->ReceiptReferenceNumber = $arry[ "text" ];
6638
+ }
6639
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'postransactiontype' ) {
6640
+ $this->POSTransactionType = $arry[ "text" ];
6641
+ }
6642
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'shipamount' ) {
6643
+ $this->ShipAmount = $arry[ "text" ];
6644
+ }
6645
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'shiphandleamount' ) {
6646
+ $this->ShipHandleAmount = $arry[ "text" ];
6647
+ }
6648
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'shipdiscount' ) {
6649
+ $this->ShipDiscount = $arry[ "text" ];
6650
+ }
6651
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'insuranceamount' ) {
6652
+ $this->InsuranceAmount = $arry[ "text" ];
6653
+ }
6654
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'subject' ) {
6655
+ $this->Subject = $arry[ "text" ];
6656
+ }
6657
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'storeid' ) {
6658
+ $this->StoreID = $arry[ "text" ];
6659
+ }
6660
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'terminalid' ) {
6661
+ $this->TerminalID = $arry[ "text" ];
6662
+ }
6663
+
6664
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
6665
+ if ( $arry[ "name" ] == 'sellerdetails' ) {
6666
+ $this->SellerDetails = new SellerDetailsType();
6667
+ $this->SellerDetails->init( $arry[ "children" ] );
6668
+ }
6669
+
6670
+ }
6671
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'paymentrequestid' ) {
6672
+ $this->PaymentRequestID = $arry[ "text" ];
6673
+ }
6674
+
6675
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
6676
+ if ( $arry[ "name" ] == 'fmfdetails' ) {
6677
+ $this->FMFDetails = new FMFDetailsType();
6678
+ $this->FMFDetails->init( $arry[ "children" ] );
6679
+ }
6680
+
6681
+ }
6682
+
6683
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
6684
+ if ( $arry[ "name" ] == 'enhancedpaymentinfo' ) {
6685
+ $this->EnhancedPaymentInfo = new EnhancedPaymentInfoType();
6686
+ $this->EnhancedPaymentInfo->init( $arry[ "children" ] );
6687
+ }
6688
+
6689
+ }
6690
+
6691
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
6692
+ if ( $arry[ "name" ] == 'paymenterror' ) {
6693
+ $this->PaymentError = new ErrorType();
6694
+ $this->PaymentError->init( $arry[ "children" ] );
6695
+ }
6696
+
6697
+ }
6698
+
6699
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
6700
+ if ( $arry[ "name" ] == 'instrumentdetails' ) {
6701
+ $this->InstrumentDetails = new InstrumentDetailsType();
6702
+ $this->InstrumentDetails->init( $arry[ "children" ] );
6703
+ }
6704
+
6705
+ }
6706
+
6707
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
6708
+ if ( $arry[ "name" ] == 'offerdetails' ) {
6709
+ $this->OfferDetails = new OfferDetailsType();
6710
+ $this->OfferDetails->init( $arry[ "children" ] );
6711
+ }
6712
+
6713
+ }
6714
+ }
6715
+ }
6716
+ }
6717
+ }
6718
+
6719
+
6720
+ /**
6721
+ * SubscriptionTermsType Terms of a PayPal subscription.
6722
+ */
6723
+ class SubscriptionTermsType
6724
+ {
6725
+
6726
+ /**
6727
+ *
6728
+ * @access public
6729
+ * @var BasicAmountType
6730
+ */
6731
+ public $Amount;
6732
+
6733
+
6734
+ public function init( $arr = null )
6735
+ {
6736
+ if ( $arr != null ) {
6737
+ foreach ( $arr as $arry ) {
6738
+
6739
+
6740
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
6741
+ if ( $arry[ "name" ] == 'amount' ) {
6742
+ $tmp = array();
6743
+ $atr = array();
6744
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
6745
+ $atr[ 0 ][ "name" ] = $key;
6746
+ $atr[ 0 ][ "text" ] = $val;
6747
+ }
6748
+ $atr[ 1 ][ "name" ] = "value";
6749
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
6750
+ $this->Amount = new BasicAmountType();
6751
+ $this->Amount->init( $atr );
6752
+ }
6753
+
6754
+ }
6755
+ }
6756
+ }
6757
+ }
6758
+ }
6759
+
6760
+
6761
+ /**
6762
+ * SubscriptionInfoType Information about a PayPal
6763
+ * Subscription.
6764
+ */
6765
+ class SubscriptionInfoType
6766
+ {
6767
+
6768
+ /**
6769
+ * ID generated by PayPal for the subscriber. Character length
6770
+ * and limitations: no limit
6771
+ * @access public
6772
+ * @var string
6773
+ */
6774
+ public $SubscriptionID;
6775
+
6776
+ /**
6777
+ * Subscription start date
6778
+ * @access public
6779
+ * @var dateTime
6780
+ */
6781
+ public $SubscriptionDate;
6782
+
6783
+ /**
6784
+ * Date when the subscription modification will be effective
6785
+ * @access public
6786
+ * @var dateTime
6787
+ */
6788
+ public $EffectiveDate;
6789
+
6790
+ /**
6791
+ * Date PayPal will retry a failed subscription payment
6792
+ * @access public
6793
+ * @var dateTime
6794
+ */
6795
+ public $RetryTime;
6796
+
6797
+ /**
6798
+ * Username generated by PayPal and given to subscriber to
6799
+ * access the subscription. Character length and limitations:
6800
+ * 64 alphanumeric single-byte characters
6801
+ * @access public
6802
+ * @var string
6803
+ */
6804
+ public $Username;
6805
+
6806
+ /**
6807
+ * Password generated by PayPal and given to subscriber to
6808
+ * access the subscription. For security, the value of the
6809
+ * password is hashed. Character length and limitations: 128
6810
+ * alphanumeric single-byte characters
6811
+ * @access public
6812
+ * @var string
6813
+ */
6814
+ public $Password;
6815
+
6816
+ /**
6817
+ * The number of payment installments that will occur at the
6818
+ * regular rate. Character length and limitations: no limit
6819
+ * @access public
6820
+ * @var string
6821
+ */
6822
+ public $Recurrences;
6823
+
6824
+ /**
6825
+ * Subscription duration and charges
6826
+ * @array
6827
+ * @access public
6828
+ * @var SubscriptionTermsType
6829
+ */
6830
+ public $Terms;
6831
+
6832
+
6833
+ public function init( $arr = null )
6834
+ {
6835
+ if ( $arr != null ) {
6836
+ foreach ( $arr as $arry ) {
6837
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'subscriptionid' ) {
6838
+ $this->SubscriptionID = $arry[ "text" ];
6839
+ }
6840
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'subscriptiondate' ) {
6841
+ $this->SubscriptionDate = $arry[ "text" ];
6842
+ }
6843
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'effectivedate' ) {
6844
+ $this->EffectiveDate = $arry[ "text" ];
6845
+ }
6846
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'retrytime' ) {
6847
+ $this->RetryTime = $arry[ "text" ];
6848
+ }
6849
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'username' ) {
6850
+ $this->Username = $arry[ "text" ];
6851
+ }
6852
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'password' ) {
6853
+ $this->Password = $arry[ "text" ];
6854
+ }
6855
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'recurrences' ) {
6856
+ $this->Recurrences = $arry[ "text" ];
6857
+ }
6858
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) ) {
6859
+ $i = 0;
6860
+ while ( true ) {
6861
+ if ( $arry[ "name" ] == "terms[$i]" ) {
6862
+ $this->Terms[ $i ] = new SubscriptionTermsType();
6863
+ $this->Terms[ $i ]->init( $arry[ "children" ] );
6864
+ } else {
6865
+ break;
6866
+ }
6867
+ $i++;
6868
+ }
6869
+ }
6870
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) && ( $arry[ "name" ] == "terms" ) ) {
6871
+ $this->Terms = new SubscriptionTermsType();
6872
+ $this->Terms->init( $arry[ "children" ] );
6873
+ }
6874
+ }
6875
+ }
6876
+ }
6877
+ }
6878
+
6879
+
6880
+ /**
6881
+ * AuctionInfoType Basic information about an auction.
6882
+ */
6883
+ class AuctionInfoType
6884
+ {
6885
+
6886
+ /**
6887
+ * Customer's auction ID
6888
+ * @access public
6889
+ * @var string
6890
+ */
6891
+ public $BuyerID;
6892
+
6893
+ /**
6894
+ * Auction's close date
6895
+ * @access public
6896
+ * @var dateTime
6897
+ */
6898
+ public $ClosingDate;
6899
+
6900
+
6901
+ public function init( $arr = null )
6902
+ {
6903
+ if ( $arr != null ) {
6904
+ foreach ( $arr as $arry ) {
6905
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'buyerid' ) {
6906
+ $this->BuyerID = $arry[ "text" ];
6907
+ }
6908
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'closingdate' ) {
6909
+ $this->ClosingDate = $arry[ "text" ];
6910
+ }
6911
+ }
6912
+ }
6913
+ }
6914
+ }
6915
+
6916
+
6917
+ /**
6918
+ * OptionType PayPal item options for shopping cart.
6919
+ */
6920
+ class OptionType
6921
+ {
6922
+
6923
+
6924
+ public function init( $arr = null )
6925
+ {
6926
+ if ( $arr != null ) {
6927
+ foreach ( $arr as $arry ) {
6928
+ }
6929
+ }
6930
+ }
6931
+ }
6932
+
6933
+
6934
+ /**
6935
+ * EbayItemPaymentDetailsItemType - Type declaration to be used
6936
+ * by other schemas. Information about an Ebay Payment Item.
6937
+ */
6938
+ class EbayItemPaymentDetailsItemType
6939
+ {
6940
+
6941
+ /**
6942
+ * Auction ItemNumber. Optional Character length and
6943
+ * limitations: 765 single-byte characters
6944
+ * @access public
6945
+ * @var string
6946
+ */
6947
+ public $ItemNumber;
6948
+
6949
+ /**
6950
+ * Auction Transaction ID. Optional Character length and
6951
+ * limitations: 255 single-byte characters
6952
+ * @access public
6953
+ * @var string
6954
+ */
6955
+ public $AuctionTransactionId;
6956
+
6957
+ /**
6958
+ * Ebay Order ID. Optional Character length and limitations: 64
6959
+ * single-byte characters
6960
+ * @access public
6961
+ * @var string
6962
+ */
6963
+ public $OrderId;
6964
+
6965
+ /**
6966
+ * Ebay Cart ID. Optional Character length and limitations: 64
6967
+ * single-byte characters
6968
+ * @access public
6969
+ * @var string
6970
+ */
6971
+ public $CartID;
6972
+
6973
+
6974
+ public function toXMLString()
6975
+ {
6976
+ $str = '';
6977
+ if ( $this->ItemNumber != null ) {
6978
+ $str .= '<ebl:ItemNumber>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ItemNumber ) . '</ebl:ItemNumber>';
6979
+ }
6980
+ if ( $this->AuctionTransactionId != null ) {
6981
+ $str .= '<ebl:AuctionTransactionId>' . PPUtils::escapeInvalidXmlCharsRegex( $this->AuctionTransactionId ) . '</ebl:AuctionTransactionId>';
6982
+ }
6983
+ if ( $this->OrderId != null ) {
6984
+ $str .= '<ebl:OrderId>' . PPUtils::escapeInvalidXmlCharsRegex( $this->OrderId ) . '</ebl:OrderId>';
6985
+ }
6986
+ if ( $this->CartID != null ) {
6987
+ $str .= '<ebl:CartID>' . PPUtils::escapeInvalidXmlCharsRegex( $this->CartID ) . '</ebl:CartID>';
6988
+ }
6989
+
6990
+ return $str;
6991
+ }
6992
+
6993
+
6994
+ public function init( $arr = null )
6995
+ {
6996
+ if ( $arr != null ) {
6997
+ foreach ( $arr as $arry ) {
6998
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'itemnumber' ) {
6999
+ $this->ItemNumber = $arry[ "text" ];
7000
+ }
7001
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'auctiontransactionid' ) {
7002
+ $this->AuctionTransactionId = $arry[ "text" ];
7003
+ }
7004
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'orderid' ) {
7005
+ $this->OrderId = $arry[ "text" ];
7006
+ }
7007
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'cartid' ) {
7008
+ $this->CartID = $arry[ "text" ];
7009
+ }
7010
+ }
7011
+ }
7012
+ }
7013
+ }
7014
+
7015
+
7016
+ /**
7017
+ * PaymentDetailsItemType Information about a Payment Item.
7018
+ */
7019
+ class PaymentDetailsItemType
7020
+ {
7021
+
7022
+ /**
7023
+ * Item name. Optional Character length and limitations: 127
7024
+ * single-byte characters
7025
+ * @access public
7026
+ * @var string
7027
+ */
7028
+ public $Name;
7029
+
7030
+ /**
7031
+ * Item number. Optional Character length and limitations: 127
7032
+ * single-byte characters
7033
+ * @access public
7034
+ * @var string
7035
+ */
7036
+ public $Number;
7037
+
7038
+ /**
7039
+ * Item quantity. Optional Character length and limitations:
7040
+ * Any positive integer
7041
+ * @access public
7042
+ * @var integer
7043
+ */
7044
+ public $Quantity;
7045
+
7046
+ /**
7047
+ * Item sales tax. Optional Character length and limitations:
7048
+ * any valid currency amount; currency code is set the same as
7049
+ * for OrderTotal.
7050
+ * @access public
7051
+ * @var BasicAmountType
7052
+ */
7053
+ public $Tax;
7054
+
7055
+ /**
7056
+ * Cost of item You must set the currencyID attribute to one of
7057
+ * the three-character currency codes for any of the supported
7058
+ * PayPal currencies. Optional Limitations: Must not exceed
7059
+ * $10,000 USD in any currency. No currency symbol. Decimal
7060
+ * separator must be a period (.), and the thousands separator
7061
+ * must be a comma (,).
7062
+ * @access public
7063
+ * @var BasicAmountType
7064
+ */
7065
+ public $Amount;
7066
+
7067
+ /**
7068
+ * Ebay specific details. Optional
7069
+ * @access public
7070
+ * @var EbayItemPaymentDetailsItemType
7071
+ */
7072
+ public $EbayItemPaymentDetailsItem;
7073
+
7074
+ /**
7075
+ * Promotional financing code for item. Part of the Merchant
7076
+ * Services Promotion Financing feature.
7077
+ * @access public
7078
+ * @var string
7079
+ */
7080
+ public $PromoCode;
7081
+
7082
+ /**
7083
+ *
7084
+ * @access public
7085
+ * @var ProductCategoryType
7086
+ */
7087
+ public $ProductCategory;
7088
+
7089
+ /**
7090
+ * Item description. Optional Character length and limitations:
7091
+ * 127 single-byte characters
7092
+ * @access public
7093
+ * @var string
7094
+ */
7095
+ public $Description;
7096
+
7097
+ /**
7098
+ * Information about the Item weight.
7099
+ * @access public
7100
+ * @var MeasureType
7101
+ */
7102
+ public $ItemWeight;
7103
+
7104
+ /**
7105
+ * Information about the Item length.
7106
+ * @access public
7107
+ * @var MeasureType
7108
+ */
7109
+ public $ItemLength;
7110
+
7111
+ /**
7112
+ * Information about the Item width.
7113
+ * @access public
7114
+ * @var MeasureType
7115
+ */
7116
+ public $ItemWidth;
7117
+
7118
+ /**
7119
+ * Information about the Item height.
7120
+ * @access public
7121
+ * @var MeasureType
7122
+ */
7123
+ public $ItemHeight;
7124
+
7125
+ /**
7126
+ * URL for the item. Optional Character length and limitations:
7127
+ * no limit.
7128
+ * @access public
7129
+ * @var string
7130
+ */
7131
+ public $ItemURL;
7132
+
7133
+ /**
7134
+ * Enhanced data for each item in the cart. Optional
7135
+ * @access public
7136
+ * @var EnhancedItemDataType
7137
+ */
7138
+ public $EnhancedItemData;
7139
+
7140
+ /**
7141
+ * Item category - physical or digital. Optional
7142
+ * @access public
7143
+ * @var ItemCategoryType
7144
+ */
7145
+ public $ItemCategory;
7146
+
7147
+
7148
+ public function toXMLString()
7149
+ {
7150
+ $str = '';
7151
+ if ( $this->Name != null ) {
7152
+ $str .= '<ebl:Name>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Name ) . '</ebl:Name>';
7153
+ }
7154
+ if ( $this->Number != null ) {
7155
+ $str .= '<ebl:Number>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Number ) . '</ebl:Number>';
7156
+ }
7157
+ if ( $this->Quantity != null ) {
7158
+ $str .= '<ebl:Quantity>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Quantity ) . '</ebl:Quantity>';
7159
+ }
7160
+ if ( $this->Tax != null ) {
7161
+ $str .= '<ebl:Tax';
7162
+ $str .= $this->Tax->toXMLString();
7163
+ $str .= '</ebl:Tax>';
7164
+ }
7165
+ if ( $this->Amount != null ) {
7166
+ $str .= '<ebl:Amount';
7167
+ $str .= $this->Amount->toXMLString();
7168
+ $str .= '</ebl:Amount>';
7169
+ }
7170
+ if ( $this->EbayItemPaymentDetailsItem != null ) {
7171
+ $str .= '<ebl:EbayItemPaymentDetailsItem>';
7172
+ $str .= $this->EbayItemPaymentDetailsItem->toXMLString();
7173
+ $str .= '</ebl:EbayItemPaymentDetailsItem>';
7174
+ }
7175
+ if ( $this->PromoCode != null ) {
7176
+ $str .= '<ebl:PromoCode>' . PPUtils::escapeInvalidXmlCharsRegex( $this->PromoCode ) . '</ebl:PromoCode>';
7177
+ }
7178
+ if ( $this->ProductCategory != null ) {
7179
+ $str .= '<ebl:ProductCategory>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ProductCategory ) . '</ebl:ProductCategory>';
7180
+ }
7181
+ if ( $this->Description != null ) {
7182
+ $str .= '<ebl:Description>' . PPUtils::escapeInvalidXmlCharsRegex( $this->Description ) . '</ebl:Description>';
7183
+ }
7184
+ if ( $this->ItemWeight != null ) {
7185
+ $str .= '<ebl:ItemWeight';
7186
+ $str .= $this->ItemWeight->toXMLString();
7187
+ $str .= '</ebl:ItemWeight>';
7188
+ }
7189
+ if ( $this->ItemLength != null ) {
7190
+ $str .= '<ebl:ItemLength';
7191
+ $str .= $this->ItemLength->toXMLString();
7192
+ $str .= '</ebl:ItemLength>';
7193
+ }
7194
+ if ( $this->ItemWidth != null ) {
7195
+ $str .= '<ebl:ItemWidth';
7196
+ $str .= $this->ItemWidth->toXMLString();
7197
+ $str .= '</ebl:ItemWidth>';
7198
+ }
7199
+ if ( $this->ItemHeight != null ) {
7200
+ $str .= '<ebl:ItemHeight';
7201
+ $str .= $this->ItemHeight->toXMLString();
7202
+ $str .= '</ebl:ItemHeight>';
7203
+ }
7204
+ if ( $this->ItemURL != null ) {
7205
+ $str .= '<ebl:ItemURL>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ItemURL ) . '</ebl:ItemURL>';
7206
+ }
7207
+ if ( $this->EnhancedItemData != null ) {
7208
+ $str .= '<ebl:EnhancedItemData>';
7209
+ $str .= $this->EnhancedItemData->toXMLString();
7210
+ $str .= '</ebl:EnhancedItemData>';
7211
+ }
7212
+ if ( $this->ItemCategory != null ) {
7213
+ $str .= '<ebl:ItemCategory>' . PPUtils::escapeInvalidXmlCharsRegex( $this->ItemCategory ) . '</ebl:ItemCategory>';
7214
+ }
7215
+
7216
+ return $str;
7217
+ }
7218
+
7219
+
7220
+ public function init( $arr = null )
7221
+ {
7222
+ if ( $arr != null ) {
7223
+ foreach ( $arr as $arry ) {
7224
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'name' ) {
7225
+ $this->Name = $arry[ "text" ];
7226
+ }
7227
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'number' ) {
7228
+ $this->Number = $arry[ "text" ];
7229
+ }
7230
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'quantity' ) {
7231
+ $this->Quantity = $arry[ "text" ];
7232
+ }
7233
+
7234
+
7235
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
7236
+ if ( $arry[ "name" ] == 'tax' ) {
7237
+ $tmp = array();
7238
+ $atr = array();
7239
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
7240
+ $atr[ 0 ][ "name" ] = $key;
7241
+ $atr[ 0 ][ "text" ] = $val;
7242
+ }
7243
+ $atr[ 1 ][ "name" ] = "value";
7244
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
7245
+ $this->Tax = new BasicAmountType();
7246
+ $this->Tax->init( $atr );
7247
+ }
7248
+
7249
+ }
7250
+
7251
+
7252
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
7253
+ if ( $arry[ "name" ] == 'amount' ) {
7254
+ $tmp = array();
7255
+ $atr = array();
7256
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
7257
+ $atr[ 0 ][ "name" ] = $key;
7258
+ $atr[ 0 ][ "text" ] = $val;
7259
+ }
7260
+ $atr[ 1 ][ "name" ] = "value";
7261
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
7262
+ $this->Amount = new BasicAmountType();
7263
+ $this->Amount->init( $atr );
7264
+ }
7265
+
7266
+ }
7267
+
7268
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
7269
+ if ( $arry[ "name" ] == 'ebayitempaymentdetailsitem' ) {
7270
+ $this->EbayItemPaymentDetailsItem = new EbayItemPaymentDetailsItemType();
7271
+ $this->EbayItemPaymentDetailsItem->init( $arry[ "children" ] );
7272
+ }
7273
+
7274
+ }
7275
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'promocode' ) {
7276
+ $this->PromoCode = $arry[ "text" ];
7277
+ }
7278
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'productcategory' ) {
7279
+ $this->ProductCategory = $arry[ "text" ];
7280
+ }
7281
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'description' ) {
7282
+ $this->Description = $arry[ "text" ];
7283
+ }
7284
+
7285
+
7286
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
7287
+ if ( $arry[ "name" ] == 'itemweight' ) {
7288
+ $tmp = array();
7289
+ $atr = array();
7290
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
7291
+ $atr[ 0 ][ "name" ] = $key;
7292
+ $atr[ 0 ][ "text" ] = $val;
7293
+ }
7294
+ $atr[ 1 ][ "name" ] = "value";
7295
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
7296
+ $this->ItemWeight = new MeasureType();
7297
+ $this->ItemWeight->init( $atr );
7298
+ }
7299
+
7300
+ }
7301
+
7302
+
7303
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
7304
+ if ( $arry[ "name" ] == 'itemlength' ) {
7305
+ $tmp = array();
7306
+ $atr = array();
7307
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
7308
+ $atr[ 0 ][ "name" ] = $key;
7309
+ $atr[ 0 ][ "text" ] = $val;
7310
+ }
7311
+ $atr[ 1 ][ "name" ] = "value";
7312
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
7313
+ $this->ItemLength = new MeasureType();
7314
+ $this->ItemLength->init( $atr );
7315
+ }
7316
+
7317
+ }
7318
+
7319
+
7320
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
7321
+ if ( $arry[ "name" ] == 'itemwidth' ) {
7322
+ $tmp = array();
7323
+ $atr = array();
7324
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
7325
+ $atr[ 0 ][ "name" ] = $key;
7326
+ $atr[ 0 ][ "text" ] = $val;
7327
+ }
7328
+ $atr[ 1 ][ "name" ] = "value";
7329
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
7330
+ $this->ItemWidth = new MeasureType();
7331
+ $this->ItemWidth->init( $atr );
7332
+ }
7333
+
7334
+ }
7335
+
7336
+
7337
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
7338
+ if ( $arry[ "name" ] == 'itemheight' ) {
7339
+ $tmp = array();
7340
+ $atr = array();
7341
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
7342
+ $atr[ 0 ][ "name" ] = $key;
7343
+ $atr[ 0 ][ "text" ] = $val;
7344
+ }
7345
+ $atr[ 1 ][ "name" ] = "value";
7346
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
7347
+ $this->ItemHeight = new MeasureType();
7348
+ $this->ItemHeight->init( $atr );
7349
+ }
7350
+
7351
+ }
7352
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'itemurl' ) {
7353
+ $this->ItemURL = $arry[ "text" ];
7354
+ }
7355
+
7356
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
7357
+ if ( $arry[ "name" ] == 'enhanceditemdata' ) {
7358
+ $this->EnhancedItemData = new EnhancedItemDataType();
7359
+ $this->EnhancedItemData->init( $arry[ "children" ] );
7360
+ }
7361
+
7362
+ }
7363
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'itemcategory' ) {
7364
+ $this->ItemCategory = $arry[ "text" ];
7365
+ }
7366
+ }
7367
+ }
7368
+ }
7369
+ }
7370
+
7371
+
7372
+ /**
7373
+ * PaymentItemType Information about a Payment Item.
7374
+ */
7375
+ class PaymentItemType
7376
+ {
7377
+
7378
+ /**
7379
+ * eBay Auction Transaction ID of the Item Optional Character
7380
+ * length and limitations: 255 single-byte characters
7381
+ * @access public
7382
+ * @var string
7383
+ */
7384
+ public $EbayItemTxnId;
7385
+
7386
+ /**
7387
+ * Item name set by you or entered by the customer. Character
7388
+ * length and limitations: 127 single-byte alphanumeric
7389
+ * characters
7390
+ * @access public
7391
+ * @var string
7392
+ */
7393
+ public $Name;
7394
+
7395
+ /**
7396
+ * Item number set by you. Character length and limitations:
7397
+ * 127 single-byte alphanumeric characters
7398
+ * @access public
7399
+ * @var string
7400
+ */
7401
+ public $Number;
7402
+
7403
+ /**
7404
+ * Quantity set by you or entered by the customer. Character
7405
+ * length and limitations: no limit
7406
+ * @access public
7407
+ * @var string
7408
+ */
7409
+ public $Quantity;
7410
+
7411
+ /**
7412
+ * Amount of tax charged on payment
7413
+ * @access public
7414
+ * @var string
7415
+ */
7416
+ public $SalesTax;
7417
+
7418
+ /**
7419
+ * Amount of shipping charged on payment
7420
+ * @access public
7421
+ * @var string
7422
+ */
7423
+ public $ShippingAmount;
7424
+
7425
+ /**
7426
+ * Amount of handling charged on payment
7427
+ * @access public
7428
+ * @var string
7429
+ */
7430
+ public $HandlingAmount;
7431
+
7432
+ /**
7433
+ * Invoice item details
7434
+ * @access public
7435
+ * @var InvoiceItemType
7436
+ */
7437
+ public $InvoiceItemDetails;
7438
+
7439
+ /**
7440
+ * Coupon ID Number
7441
+ * @access public
7442
+ * @var string
7443
+ */
7444
+ public $CouponID;
7445
+
7446
+ /**
7447
+ * Amount Value of The Coupon
7448
+ * @access public
7449
+ * @var string
7450
+ */
7451
+ public $CouponAmount;
7452
+
7453
+ /**
7454
+ * Currency of the Coupon Amount
7455
+ * @access public
7456
+ * @var string
7457
+ */
7458
+ public $CouponAmountCurrency;
7459
+
7460
+ /**
7461
+ * Amount of Discount on this Loyalty Card
7462
+ * @access public
7463
+ * @var string
7464
+ */
7465
+ public $LoyaltyCardDiscountAmount;
7466
+
7467
+ /**
7468
+ * Currency of the Discount
7469
+ * @access public
7470
+ * @var string
7471
+ */
7472
+ public $LoyaltyCardDiscountCurrency;
7473
+
7474
+ /**
7475
+ * Cost of item
7476
+ * @access public
7477
+ * @var BasicAmountType
7478
+ */
7479
+ public $Amount;
7480
+
7481
+ /**
7482
+ * Item options selected in PayPal shopping cart
7483
+ * @array
7484
+ * @access public
7485
+ * @var OptionType
7486
+ */
7487
+ public $Options;
7488
+
7489
+
7490
+ public function init( $arr = null )
7491
+ {
7492
+ if ( $arr != null ) {
7493
+ foreach ( $arr as $arry ) {
7494
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'ebayitemtxnid' ) {
7495
+ $this->EbayItemTxnId = $arry[ "text" ];
7496
+ }
7497
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'name' ) {
7498
+ $this->Name = $arry[ "text" ];
7499
+ }
7500
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'number' ) {
7501
+ $this->Number = $arry[ "text" ];
7502
+ }
7503
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'quantity' ) {
7504
+ $this->Quantity = $arry[ "text" ];
7505
+ }
7506
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'salestax' ) {
7507
+ $this->SalesTax = $arry[ "text" ];
7508
+ }
7509
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'shippingamount' ) {
7510
+ $this->ShippingAmount = $arry[ "text" ];
7511
+ }
7512
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'handlingamount' ) {
7513
+ $this->HandlingAmount = $arry[ "text" ];
7514
+ }
7515
+
7516
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
7517
+ if ( $arry[ "name" ] == 'invoiceitemdetails' ) {
7518
+ $this->InvoiceItemDetails = new InvoiceItemType();
7519
+ $this->InvoiceItemDetails->init( $arry[ "children" ] );
7520
+ }
7521
+
7522
+ }
7523
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'couponid' ) {
7524
+ $this->CouponID = $arry[ "text" ];
7525
+ }
7526
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'couponamount' ) {
7527
+ $this->CouponAmount = $arry[ "text" ];
7528
+ }
7529
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'couponamountcurrency' ) {
7530
+ $this->CouponAmountCurrency = $arry[ "text" ];
7531
+ }
7532
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'loyaltycarddiscountamount' ) {
7533
+ $this->LoyaltyCardDiscountAmount = $arry[ "text" ];
7534
+ }
7535
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'loyaltycarddiscountcurrency' ) {
7536
+ $this->LoyaltyCardDiscountCurrency = $arry[ "text" ];
7537
+ }
7538
+
7539
+
7540
+ if ( is_array( $arry[ "attributes" ] ) && ( $arry[ "attributes" ] ) != null ) {
7541
+ if ( $arry[ "name" ] == 'amount' ) {
7542
+ $tmp = array();
7543
+ $atr = array();
7544
+ foreach ( $arry[ "attributes" ] as $key => $val ) {
7545
+ $atr[ 0 ][ "name" ] = $key;
7546
+ $atr[ 0 ][ "text" ] = $val;
7547
+ }
7548
+ $atr[ 1 ][ "name" ] = "value";
7549
+ $atr[ 1 ][ "text" ] = $arry[ "text" ];
7550
+ $this->Amount = new BasicAmountType();
7551
+ $this->Amount->init( $atr );
7552
+ }
7553
+
7554
+ }
7555
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) ) {
7556
+ $i = 0;
7557
+ while ( true ) {
7558
+ if ( $arry[ "name" ] == "options[$i]" ) {
7559
+ $this->Options[ $i ] = new OptionType();
7560
+ $this->Options[ $i ]->init( $arry[ "children" ] );
7561
+ } else {
7562
+ break;
7563
+ }
7564
+ $i++;
7565
+ }
7566
+ }
7567
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) && ( $arry[ "name" ] == "options" ) ) {
7568
+ $this->Options = new OptionType();
7569
+ $this->Options->init( $arry[ "children" ] );
7570
+ }
7571
+ }
7572
+ }
7573
+ }
7574
+ }
7575
+
7576
+
7577
+ /**
7578
+ * PaymentItemInfoType Information about a PayPal item.
7579
+ */
7580
+ class PaymentItemInfoType
7581
+ {
7582
+
7583
+ /**
7584
+ * Invoice number you set in the original transaction.
7585
+ * Character length and limitations: 127 single-byte
7586
+ * alphanumeric characters
7587
+ * @access public
7588
+ * @var string
7589
+ */
7590
+ public $InvoiceID;
7591
+
7592
+ /**
7593
+ * Custom field you set in the original transaction. Character
7594
+ * length and limitations: 127 single-byte alphanumeric
7595
+ * characters
7596
+ * @access public
7597
+ * @var string
7598
+ */
7599
+ public $Custom;
7600
+
7601
+ /**
7602
+ * Memo entered by your customer in PayPal Website Payments
7603
+ * note field. Character length and limitations: 255
7604
+ * single-byte alphanumeric characters
7605
+ * @access public
7606
+ * @var string
7607
+ */
7608
+ public $Memo;
7609
+
7610
+ /**
7611
+ * Amount of tax charged on transaction
7612
+ * @access public
7613
+ * @var string
7614
+ */
7615
+ public $SalesTax;
7616
+
7617
+ /**
7618
+ * Details about the indivudal purchased item
7619
+ * @array
7620
+ * @access public
7621
+ * @var PaymentItemType
7622
+ */
7623
+ public $PaymentItem;
7624
+
7625
+ /**
7626
+ * Information about the transaction if it was created via
7627
+ * PayPal Subcriptions
7628
+ * @access public
7629
+ * @var SubscriptionInfoType
7630
+ */
7631
+ public $Subscription;
7632
+
7633
+ /**
7634
+ * Information about the transaction if it was created via an
7635
+ * auction
7636
+ * @access public
7637
+ * @var AuctionInfoType
7638
+ */
7639
+ public $Auction;
7640
+
7641
+
7642
+ public function init( $arr = null )
7643
+ {
7644
+ if ( $arr != null ) {
7645
+ foreach ( $arr as $arry ) {
7646
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'invoiceid' ) {
7647
+ $this->InvoiceID = $arry[ "text" ];
7648
+ }
7649
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'custom' ) {
7650
+ $this->Custom = $arry[ "text" ];
7651
+ }
7652
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'memo' ) {
7653
+ $this->Memo = $arry[ "text" ];
7654
+ }
7655
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'salestax' ) {
7656
+ $this->SalesTax = $arry[ "text" ];
7657
+ }
7658
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) ) {
7659
+ $i = 0;
7660
+ while ( true ) {
7661
+ if ( $arry[ "name" ] == "paymentitem[$i]" ) {
7662
+ $this->PaymentItem[ $i ] = new PaymentItemType();
7663
+ $this->PaymentItem[ $i ]->init( $arry[ "children" ] );
7664
+ } else {
7665
+ break;
7666
+ }
7667
+ $i++;
7668
+ }
7669
+ }
7670
+ if ( is_array( $arry[ "children" ] ) && ( ( $arry[ "children" ] ) != null ) && ( $arry[ "name" ] == "paymentitem" ) ) {
7671
+ $this->PaymentItem = new PaymentItemType();
7672
+ $this->PaymentItem->init( $arry[ "children" ] );
7673
+ }
7674
+
7675
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
7676
+ if ( $arry[ "name" ] == 'subscription' ) {
7677
+ $this->Subscription = new SubscriptionInfoType();
7678
+ $this->Subscription->init( $arry[ "children" ] );
7679
+ }
7680
+
7681
+ }
7682
+
7683
+ if ( is_array( $arry[ "children" ] ) && ( $arry[ "children" ] ) != null ) {
7684
+ if ( $arry[ "name" ] == 'auction' ) {
7685
+ $this->Auction = new AuctionInfoType();
7686
+ $this->Auction->init( $arry[ "children" ] );
7687
+ }
7688
+
7689
+ }
7690
+ }
7691
+ }
7692
+ }
7693
+ }
7694
+
7695
+
7696
+ /**
7697
+ * OffersAndCouponsInfoType Information about a Offers and
7698
+ * Coupons.
7699
+ */
7700
+ class OfferCouponInfoType
7701
+ {
7702
+
7703
+ /**
7704
+ * Type of the incentive
7705
+ * @access public
7706
+ * @var string
7707
+ */
7708
+ public $Type;
7709
+
7710
+ /**
7711
+ * ID of the Incentive used in transaction
7712
+ * @access public
7713
+ * @var string
7714
+ */
7715
+ public $ID;
7716
+
7717
+ /**
7718
+ * Amount used on transaction
7719
+ * @access public
7720
+ * @var string
7721
+ */
7722
+ public $Amount;
7723
+
7724
+ /**
7725
+ * Amount Currency
7726
+ * @access public
7727
+ * @var string
7728
+ */
7729
+ public $AmountCurrency;
7730
+
7731
+
7732
+ public function init( $arr = null )
7733
+ {
7734
+ if ( $arr != null ) {
7735
+ foreach ( $arr as $arry ) {
7736
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'type' ) {
7737
+ $this->Type = $arry[ "text" ];
7738
+ }
7739
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'id' ) {
7740
+ $this->ID = $arry[ "text" ];
7741
+ }
7742
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'amount' ) {
7743
+ $this->Amount = $arry[ "text" ];
7744
+ }
7745
+ if ( $arry != null && isset( $arry[ 'text' ] ) && $arry[ 'name' ] == 'amountcurrency' ) {
7746
+ $this->AmountCurrency = $arry[ "text" ];
7747
+ }
7748
+ }
7749
+ }
7750
+ }
7751
+ }
7752
+
7753
+
7754
+ /**
7755
+ * PaymentDetailsType Information about a payment. Used by DCC
7756
+ * and Express Checkout.
7757
+ */
7758
+ class PaymentDetailsType
7759
+ {
7760
+
7761
+ /**
7762
+ * Total of order, including shipping, handling, and tax. You
7763
+ * must set the currencyID attribute to one of the
7764
+ * three-character currency codes for any of the supported
7765
+ * PayPal currencies. Limitations: Must not exceed $10,000 USD
7766
+ * in any currency. No currency symbol. Decimal separator must
7767
+ * be a period (.), and the thousands separator must be a comma
7768
+ * (,).
7769
+ * @access public
7770
+ * @var BasicAmountType
7771
+ */
7772
+ public $OrderTotal;
7773
+
7774
+ /**
7775
+ * Sum of cost of all items in this order. You must set the
7776
+ * currencyID attribute to one of the three-character currency
7777
+ * codes for any of the supported PayPal currencies. Optional
7778
+ * separator must be a comma (,).
7779
+ * @access public
7780
+ * @var BasicAmountType
7781
+ */
7782
+ public $ItemTotal;
7783
+
7784
+ /**
7785
+ * Total shipping costs for this order. You must set the
7786
+ * currencyID attribute to one of the three-character currency
7787
+ * codes for any of the supported PayPal currencies. Optional
7788
+ * Limitations: Must not exceed $10,000 USD in any currency. No
7789
+ * currency symbol. Decimal separator must be a period (.), and
7790
+ * the thousands separator must be a comma (,).
7791
+ * @access public
7792
+ * @var BasicAmountType
7793
+ */
7794
+ public $ShippingTotal;
7795
+
7796
+ /**
7797
+ * Total handling costs for this order. You must set the
7798
+ * currencyID attribute to one of the three-character currency
7799
+ * codes for any of the supported PayPal currencies. Optional
7800
+ * Limitations: Must not exceed $10,000 USD in any currency. No
7801
+ * currency symbol. Decimal separator must be a period (.), and
7802
+ * the thousands separator must be a comma (,).
7803
+ * @access public
7804
+ * @var BasicAmountType
7805
+ */
7806
+ public $HandlingTotal;
7807
+
7808
+ /**
7809
+ * Sum of tax for all items in this order. You must set the
7810
+ * currencyID attribute to one of the three-character currency
7811
+ * codes for any of the supported PayPal currencies. Optional
7812
+ * Limitations: Must not exceed $10,000 USD in any