Forminator Payment, Quiz and Contact Form Plugin - Version 1.5.1

Version Description

  • Add: Release FREE on WordPress.org
  • Add: Import / Export feature
  • Fix: Cannot clear color settings
  • Fix: PHP notice on front-end
  • Fix: Form not displaying confirmation message and doesn't clear inputs when ajax disabled
  • Fix: Poll votes count setting doesn't work as expected
  • Fix: Margin in row when field(s) is/are hidden
  • Fix: Phone field formats validation check
  • Fix: Select drop-down is displayed twice and not showing any options
  • Fix: Multiple Choice field, undefined index error on front-end when Trello is active
  • Fix: File upload field throwing PHP error
  • Other minor enhancements/fixes
Download this release

Release Info

Developer jdailey
Plugin Icon 128x128 Forminator Payment, Quiz and Contact Form Plugin
Version 1.5.1
Comparing to
See all releases

Version 1.5.1

Files changed (147) hide show
  1. _src/js/index.js +1 -0
  2. _src/scss/admin.scss +42 -0
  3. _src/scss/forminator-ui/_actions.scss +88 -0
  4. _src/scss/forminator-ui/_animations.scss +39 -0
  5. _src/scss/forminator-ui/_boxes.scss +157 -0
  6. _src/scss/forminator-ui/_builder-actions.scss +135 -0
  7. _src/scss/forminator-ui/_builder.scss +835 -0
  8. _src/scss/forminator-ui/_buttons.scss +84 -0
  9. _src/scss/forminator-ui/_chips.scss +65 -0
  10. _src/scss/forminator-ui/_color-picker.scss +102 -0
  11. _src/scss/forminator-ui/_editor.scss +268 -0
  12. _src/scss/forminator-ui/_forms.scss +166 -0
  13. _src/scss/forminator-ui/_modals.scss +35 -0
  14. _src/scss/forminator-ui/_multi-answer.scss +255 -0
  15. _src/scss/forminator-ui/_multi-name.scss +83 -0
  16. _src/scss/forminator-ui/_multi-order.scss +61 -0
  17. _src/scss/forminator-ui/_multi-question.scss +91 -0
  18. _src/scss/forminator-ui/_multi-result.scss +83 -0
  19. _src/scss/forminator-ui/_multi-select.scss +76 -0
  20. _src/scss/forminator-ui/_multi-value.scss +120 -0
  21. _src/scss/forminator-ui/_multicheck.scss +56 -0
  22. _src/scss/forminator-ui/_page-poll.scss +12 -0
  23. _src/scss/forminator-ui/_page-quiz.scss +12 -0
  24. _src/scss/forminator-ui/_select.scss +36 -0
  25. _src/scss/forminator-ui/_summary.scss +16 -0
  26. _src/scss/forminator-ui/_tables.scss +135 -0
  27. _src/scss/forminator-ui/_utility.scss +76 -0
  28. _src/scss/overwrite-sui/_accordion.scss +68 -0
  29. _src/scss/overwrite-sui/_boxes.scss +52 -0
  30. _src/scss/overwrite-sui/_modals.scss +6 -0
  31. _src/scss/overwrite-sui/_notifications.scss +18 -0
  32. _src/scss/overwrite-sui/_pr-changes.scss +381 -0
  33. _src/scss/overwrite-sui/_sidenav.scss +22 -0
  34. _src/scss/overwrite-sui/_tables.scss +96 -0
  35. _src/scss/overwrite-sui/_toggles.scss +11 -0
  36. _src/scss/overwrite-sui/_variables.scss +8 -0
  37. addons/class-addon-autoload.php +91 -0
  38. addons/class-addon-default-holder.php +92 -0
  39. addons/pro/activecampaign/activecampaign.php +30 -0
  40. addons/pro/activecampaign/assets/icons/activecampaign.png +0 -0
  41. addons/pro/activecampaign/assets/icons/activecampaign@2x.png +0 -0
  42. addons/pro/activecampaign/assets/img/activecampaign.png +0 -0
  43. addons/pro/activecampaign/assets/img/activecampaign@2x.png +0 -0
  44. addons/pro/activecampaign/forminator-addon-activecampaign-exception.php +11 -0
  45. addons/pro/activecampaign/forminator-addon-activecampaign-form-hooks.php +746 -0
  46. addons/pro/activecampaign/forminator-addon-activecampaign-form-settings-exception.php +68 -0
  47. addons/pro/activecampaign/forminator-addon-activecampaign-form-settings.php +746 -0
  48. addons/pro/activecampaign/forminator-addon-activecampaign.php +477 -0
  49. addons/pro/activecampaign/lib/class-wp-activecampaign-api-exception.php +10 -0
  50. addons/pro/activecampaign/lib/class-wp-activecampaign-api-not-found-exception.php +10 -0
  51. addons/pro/activecampaign/lib/class-wp-activecampaign-api.php +496 -0
  52. addons/pro/activecampaign/views/form-settings/map-fields.php +78 -0
  53. addons/pro/activecampaign/views/form-settings/pick-name.php +34 -0
  54. addons/pro/activecampaign/views/form-settings/select-list.php +38 -0
  55. addons/pro/activecampaign/views/form-settings/setup-options.php +141 -0
  56. addons/pro/activecampaign/views/settings/setup-api-success.php +6 -0
  57. addons/pro/activecampaign/views/settings/setup-api.php +50 -0
  58. addons/pro/aweber/assets/icons/aweber.png +0 -0
  59. addons/pro/aweber/assets/icons/aweber@2x.png +0 -0
  60. addons/pro/aweber/assets/img/aweber.png +0 -0
  61. addons/pro/aweber/assets/img/aweber@2x.png +0 -0
  62. addons/pro/aweber/aweber.php +30 -0
  63. addons/pro/aweber/forminator-addon-aweber-exception.php +11 -0
  64. addons/pro/aweber/forminator-addon-aweber-form-hooks.php +792 -0
  65. addons/pro/aweber/forminator-addon-aweber-form-settings-exception.php +68 -0
  66. addons/pro/aweber/forminator-addon-aweber-form-settings.php +706 -0
  67. addons/pro/aweber/forminator-addon-aweber.php +611 -0
  68. addons/pro/aweber/lib/class-aweber-oauth.php +170 -0
  69. addons/pro/aweber/lib/class-wp-aweber-api-exception.php +10 -0
  70. addons/pro/aweber/lib/class-wp-aweber-api-not-found-exception.php +10 -0
  71. addons/pro/aweber/lib/class-wp-aweber-api.php +696 -0
  72. addons/pro/aweber/views/form-settings/map-fields.php +78 -0
  73. addons/pro/aweber/views/form-settings/pick-name.php +34 -0
  74. addons/pro/aweber/views/form-settings/setup-list.php +38 -0
  75. addons/pro/aweber/views/form-settings/setup-options.php +90 -0
  76. addons/pro/aweber/views/sections/authorize.php +78 -0
  77. addons/pro/aweber/views/settings/authorize.php +29 -0
  78. addons/pro/aweber/views/settings/success-authorize.php +7 -0
  79. addons/pro/aweber/views/settings/wait-authorize.php +22 -0
  80. addons/pro/campaignmonitor/assets/icons/campaignmonitor.png +0 -0
  81. addons/pro/campaignmonitor/assets/icons/campaignmonitor@2x.png +0 -0
  82. addons/pro/campaignmonitor/assets/img/campaignmonitor.png +0 -0
  83. addons/pro/campaignmonitor/assets/img/campaignmonitor@2x.png +0 -0
  84. addons/pro/campaignmonitor/campaignmonitor.php +30 -0
  85. addons/pro/campaignmonitor/forminator-addon-campaignmonitor-exception.php +11 -0
  86. addons/pro/campaignmonitor/forminator-addon-campaignmonitor-form-hooks.php +700 -0
  87. addons/pro/campaignmonitor/forminator-addon-campaignmonitor-form-settings-exception.php +68 -0
  88. addons/pro/campaignmonitor/forminator-addon-campaignmonitor-form-settings.php +690 -0
  89. addons/pro/campaignmonitor/forminator-addon-campaignmonitor.php +510 -0
  90. addons/pro/campaignmonitor/lib/class-wp-campaignmonitor-api-exception.php +10 -0
  91. addons/pro/campaignmonitor/lib/class-wp-campaignmonitor-api-not-found-exception.php +10 -0
  92. addons/pro/campaignmonitor/lib/class-wp-campaignmonitor-api.php +524 -0
  93. addons/pro/campaignmonitor/views/form-settings/map-fields.php +78 -0
  94. addons/pro/campaignmonitor/views/form-settings/pick-name.php +34 -0
  95. addons/pro/campaignmonitor/views/form-settings/setup-list.php +38 -0
  96. addons/pro/campaignmonitor/views/form-settings/setup-options.php +95 -0
  97. addons/pro/campaignmonitor/views/settings/setup-api-success.php +6 -0
  98. addons/pro/campaignmonitor/views/settings/setup-api.php +66 -0
  99. addons/pro/googlesheet/assets/icons/googlesheet.png +0 -0
  100. addons/pro/googlesheet/assets/icons/googlesheet@2x.png +0 -0
  101. addons/pro/googlesheet/assets/img/googlesheet.png +0 -0
  102. addons/pro/googlesheet/assets/img/googlesheet@2x.png +0 -0
  103. addons/pro/googlesheet/forminator-addon-googlesheet-exception.php +11 -0
  104. addons/pro/googlesheet/forminator-addon-googlesheet-form-hooks.php +798 -0
  105. addons/pro/googlesheet/forminator-addon-googlesheet-form-settings-exception.php +81 -0
  106. addons/pro/googlesheet/forminator-addon-googlesheet-form-settings.php +402 -0
  107. addons/pro/googlesheet/forminator-addon-googlesheet.php +684 -0
  108. addons/pro/googlesheet/googlesheet.php +50 -0
  109. addons/pro/googlesheet/lib/class-wp-googlesheet-client-logger.php +21 -0
  110. addons/pro/googlesheet/lib/external/Google/Auth/Abstract.php +38 -0
  111. addons/pro/googlesheet/lib/external/Google/Auth/AppIdentity.php +120 -0
  112. addons/pro/googlesheet/lib/external/Google/Auth/AssertionCredentials.php +136 -0
  113. addons/pro/googlesheet/lib/external/Google/Auth/ComputeEngine.php +146 -0
  114. addons/pro/googlesheet/lib/external/Google/Auth/Exception.php +24 -0
  115. addons/pro/googlesheet/lib/external/Google/Auth/LoginTicket.php +71 -0
  116. addons/pro/googlesheet/lib/external/Google/Auth/OAuth2.php +646 -0
  117. addons/pro/googlesheet/lib/external/Google/Auth/Simple.php +63 -0
  118. addons/pro/googlesheet/lib/external/Google/Cache/Abstract.php +53 -0
  119. addons/pro/googlesheet/lib/external/Google/Cache/Apc.php +113 -0
  120. addons/pro/googlesheet/lib/external/Google/Cache/Exception.php +24 -0
  121. addons/pro/googlesheet/lib/external/Google/Cache/File.php +209 -0
  122. addons/pro/googlesheet/lib/external/Google/Cache/Memcache.php +184 -0
  123. addons/pro/googlesheet/lib/external/Google/Cache/Null.php +57 -0
  124. addons/pro/googlesheet/lib/external/Google/Client.php +715 -0
  125. addons/pro/googlesheet/lib/external/Google/Collection.php +101 -0
  126. addons/pro/googlesheet/lib/external/Google/Config.php +456 -0
  127. addons/pro/googlesheet/lib/external/Google/Exception.php +20 -0
  128. addons/pro/googlesheet/lib/external/Google/Http/Batch.php +145 -0
  129. addons/pro/googlesheet/lib/external/Google/Http/CacheParser.php +185 -0
  130. addons/pro/googlesheet/lib/external/Google/Http/MediaFileUpload.php +341 -0
  131. addons/pro/googlesheet/lib/external/Google/Http/REST.php +178 -0
  132. addons/pro/googlesheet/lib/external/Google/Http/Request.php +504 -0
  133. addons/pro/googlesheet/lib/external/Google/IO/Abstract.php +339 -0
  134. addons/pro/googlesheet/lib/external/Google/IO/Curl.php +194 -0
  135. addons/pro/googlesheet/lib/external/Google/IO/Exception.php +69 -0
  136. addons/pro/googlesheet/lib/external/Google/IO/Stream.php +243 -0
  137. addons/pro/googlesheet/lib/external/Google/IO/cacerts.pem +2183 -0
  138. addons/pro/googlesheet/lib/external/Google/Logger/Abstract.php +408 -0
  139. addons/pro/googlesheet/lib/external/Google/Logger/Exception.php +24 -0
  140. addons/pro/googlesheet/lib/external/Google/Logger/File.php +158 -0
  141. addons/pro/googlesheet/lib/external/Google/Logger/Null.php +43 -0
  142. addons/pro/googlesheet/lib/external/Google/Logger/Psr.php +93 -0
  143. addons/pro/googlesheet/lib/external/Google/Model.php +295 -0
  144. addons/pro/googlesheet/lib/external/Google/Service.php +56 -0
  145. addons/pro/googlesheet/lib/external/Google/Service/AdExchangeBuyer.php +4555 -0
  146. addons/pro/googlesheet/lib/external/Google/Service/AdExchangeSeller.php +1711 -0
  147. addons/pro/googlesheet/lib/external/Google/Service/AdSense.php +2238 -0
_src/js/index.js ADDED
@@ -0,0 +1 @@
 
1
+ import '@wpmudev/shared-ui';
_src/scss/admin.scss ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Overwrite shared-ui variables
2
+ @import "overwrite-sui/variables";
3
+
4
+ // Import shared-ui
5
+ @import "~@wpmudev/shared-ui/scss/shared-ui.scss";
6
+
7
+ // Overwrite shared-ui elements
8
+ @import "overwrite-sui/boxes";
9
+ @import "overwrite-sui/modals";
10
+ @import "overwrite-sui/tables";
11
+ @import "overwrite-sui/sidenav";
12
+ @import "overwrite-sui/toggles";
13
+ @import "overwrite-sui/accordion";
14
+ @import "overwrite-sui/pr-changes";
15
+
16
+ // Forminator only components
17
+ @import "forminator-ui/boxes";
18
+ @import "forminator-ui/chips";
19
+ @import "forminator-ui/forms";
20
+ @import "forminator-ui/editor";
21
+ @import "forminator-ui/modals";
22
+ @import "forminator-ui/select";
23
+ @import "forminator-ui/tables";
24
+ @import "forminator-ui/builder";
25
+ @import "forminator-ui/buttons";
26
+ @import "forminator-ui/summary";
27
+ @import "forminator-ui/utility";
28
+ @import "forminator-ui/actions";
29
+ @import "forminator-ui/animations";
30
+ @import "forminator-ui/multi-name";
31
+ @import "forminator-ui/multicheck";
32
+ @import "forminator-ui/multi-order";
33
+ @import "forminator-ui/multi-value";
34
+ @import "forminator-ui/multi-answer";
35
+ @import "forminator-ui/multi-result";
36
+ @import "forminator-ui/color-picker";
37
+ @import "forminator-ui/multi-select";
38
+ @import "forminator-ui/builder-actions";
39
+ @import "forminator-ui/multi-question";
40
+
41
+ @import "forminator-ui/page-poll";
42
+ @import "forminator-ui/page-quiz";
_src/scss/forminator-ui/_actions.scss ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-form-actions {
4
+ display: flex;
5
+ flex: 1;
6
+ align-items: center;
7
+ justify-content: space-between;
8
+ margin: $sui-gutter 0;
9
+
10
+ .fui-bulk-actions {
11
+ display: flex;
12
+ align-items: center;
13
+
14
+ .sui-button {
15
+ margin-left: 15px;
16
+
17
+ @include media( max-width, md ) {
18
+ margin-left: 0;
19
+ margin-top: 15px;
20
+ }
21
+ }
22
+
23
+ @include media( max-width, md ) {
24
+ display: block;
25
+ margin-bottom: $sui-gutter-md;
26
+ }
27
+ }
28
+
29
+ &:first-child {
30
+ margin-top: 0;
31
+ }
32
+
33
+ &:last-child {
34
+ margin-bottom: 0;
35
+ }
36
+
37
+ @include media( max-width, md ) {
38
+ display: block;
39
+ margin: $sui-gutter-md 0;
40
+ }
41
+ }
42
+
43
+ .fui-form-element-actions {
44
+ display: flex;
45
+ flex: 1;
46
+ align-items: center;
47
+ justify-content: flex-end;
48
+
49
+ > form,
50
+ > .sui-button {
51
+ margin: 0 10px;
52
+
53
+ &:first-child {
54
+ margin-left: 0;
55
+ }
56
+
57
+ &:last-child {
58
+ margin-right: 0;
59
+ }
60
+ }
61
+ }
62
+
63
+ .fui-select-actions {
64
+ display: flex;
65
+
66
+ .select-container {
67
+ flex: 0 0 auto;
68
+ margin-right: 10px;
69
+
70
+ &:last-child {
71
+ margin-right: 0;
72
+
73
+ @include media( max-width, md ) {
74
+ margin-bottom: 0;
75
+ }
76
+ }
77
+
78
+ @include media( max-width, md ) {
79
+ margin-bottom: 10px;
80
+ margin-right: 0;
81
+ }
82
+ }
83
+
84
+ @include media( max-width, md ) {
85
+ display: block;
86
+ }
87
+ }
88
+ }
_src/scss/forminator-ui/_animations.scss ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @keyframes slideInUp {
2
+ from {
3
+ transform: translate3d(0, 100%, 0);
4
+ visibility: visible;
5
+ }
6
+ to {
7
+ transform: translate3d(0, 0, 0);
8
+ }
9
+ }
10
+
11
+ @keyframes slideInRight {
12
+ from {
13
+ transform: translate3d(100%, 0, 0);
14
+ visibility: visible;
15
+ }
16
+ to {
17
+ transform: translate3d(0, 0, 0);
18
+ }
19
+ }
20
+
21
+ @keyframes slideOutUp {
22
+ from {
23
+ transform: translate3d(0, 0, 0);
24
+ }
25
+ to {
26
+ visibility: hidden;
27
+ transform: translate3d(0, -100%, 0);
28
+ }
29
+ }
30
+
31
+ @keyframes slideOutRight {
32
+ from {
33
+ transform: translate3d(0, 0, 0);
34
+ }
35
+ to {
36
+ visibility: hidden;
37
+ transform: translate3d(100%, 0, 0);
38
+ }
39
+ }
_src/scss/forminator-ui/_boxes.scss ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .sui-box {
4
+
5
+ .sui-box-body {
6
+
7
+ .fui-wide {
8
+ display: block;
9
+ margin-right: -$sui-gutter;
10
+ margin-left: -$sui-gutter;
11
+
12
+ @include media( max-width, md ) {
13
+ margin-right: -$sui-gutter-md;
14
+ margin-left: -$sui-gutter-md;
15
+ }
16
+ }
17
+ }
18
+ }
19
+
20
+ .fui-box-gray {
21
+ @extend .sui-box;
22
+ padding: $sui-gutter/2;
23
+ background-color: palette( silver );
24
+ box-shadow: none;
25
+
26
+ @include media( max-width, md ) {
27
+ padding: $sui-gutter-md/2;
28
+ }
29
+ }
30
+
31
+ div.fui-toggle-content {
32
+ margin: $sui-gutter/2 0;
33
+
34
+ .sui-form-field {
35
+ margin-top: $sui-gutter/2;
36
+ margin-bottom: $sui-gutter/2;
37
+
38
+ &:first-child {
39
+ margin-top: 0;
40
+ }
41
+
42
+ &:last-child {
43
+ margin-bottom: 0;
44
+ }
45
+
46
+ @include media( max-width, md ) {
47
+ margin-top: $sui-gutter-md/2;
48
+ margin-bottom: $sui-gutter-md/2;
49
+ }
50
+ }
51
+
52
+ &:first-child {
53
+ margin-top: 0;
54
+
55
+ @include media( max-width, md ) {
56
+ margin-top: 0;
57
+ }
58
+ }
59
+
60
+ &:last-child {
61
+ margin-bottom: 0;
62
+
63
+ @include media( max-width, md ) {
64
+ margin-bottom: 0;
65
+ }
66
+ }
67
+
68
+ @include media( max-width, md ) {
69
+ margin: $sui-gutter-md/2 0;
70
+ }
71
+ }
72
+
73
+ .fui-box-entries-resume {
74
+ width: 100%;
75
+ display: table;
76
+ position: relative;
77
+ margin: 10px 0;
78
+
79
+ .fui-box-entries-field-title {
80
+ width: 180px;
81
+ display: table-cell;
82
+ padding-right: 20px;
83
+ color: $gray-alt;
84
+ font: 500 13px/22px $font;
85
+ letter-spacing: 0;
86
+ }
87
+
88
+ .fui-box-entries-field-content {
89
+ display: table-cell;
90
+ color: #888888;
91
+ font: 400 13px/22px $font;
92
+ letter-spacing: 0;
93
+ }
94
+
95
+ &:first-child {
96
+ margin-top: 0;
97
+ }
98
+
99
+ &:last-child {
100
+ margin-bottom: 0;
101
+ }
102
+
103
+ @include media( max-width, md ) {
104
+ display: block;
105
+ }
106
+ }
107
+
108
+ .fui-box-quiz-type {
109
+ height: 100%;
110
+ display: flex;
111
+
112
+ span {
113
+ display: block;
114
+ }
115
+
116
+ .fui-box-quiz-type-mask {
117
+ flex: 1;
118
+ border: 1px solid #E6E6E6;
119
+ border-radius: 4px;
120
+ }
121
+
122
+ .fui-box-quiz-type-header {
123
+ padding: $sui-gutter/2;
124
+ border-bottom: 1px solid #E6E6E6;
125
+ color: #434343;
126
+ font: 500 15px/30px $font;
127
+ }
128
+
129
+ .fui-box-quiz-type-body {
130
+ padding: $sui-gutter/2;
131
+ color: palette( gray, alt );
132
+ font: 400 13px/22px $font;
133
+ }
134
+ }
135
+
136
+ .fui-inner-title {
137
+ @extend .sui-box-title;
138
+ margin: $sui-gutter 0;
139
+ padding: 0 0 $sui-gutter/2;
140
+ border-bottom: 1px solid #EAEAEA;
141
+
142
+ &:first-child {
143
+ margin-top: 0;
144
+ }
145
+
146
+ &:last-child {
147
+ padding-bottom: 0;
148
+ margin-bottom: 0;
149
+ border-bottom: 0;
150
+ }
151
+
152
+ @include media( max-width, md ) {
153
+ margin: $sui-gutter-md 0;
154
+ padding: 0 0 $sui-gutter-md/2;
155
+ }
156
+ }
157
+ }
_src/scss/forminator-ui/_builder-actions.scss ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-builder {
4
+
5
+ // ACTION dragging
6
+ .fui-form-builder--dragging {
7
+ position: relative;
8
+
9
+ .fui-form-builder--drop-zone {
10
+ max-width: 100%;
11
+ max-height: 100%;
12
+ position: absolute;
13
+ top: 0;
14
+ right: 0;
15
+ bottom: 0;
16
+ left: 0;
17
+ border: 2px dashed #EAEAEA;
18
+ border-radius: $border-radius;
19
+ background-color: palette( silver, light );
20
+ transition: 0.2s ease;
21
+ }
22
+ }
23
+
24
+ .forminator-drop-full,
25
+ .forminator-drop-side-after,
26
+ .forminator-drop-side-before {
27
+
28
+ &:before {
29
+ content: " ";
30
+ position: relative;
31
+ border-radius: 2px;
32
+ background: palette( blue, soft );
33
+ }
34
+
35
+ &:after {
36
+ content: none;
37
+ }
38
+
39
+ &.forminator-drop-use {
40
+
41
+ &:before {
42
+ background: $blue;
43
+ }
44
+ }
45
+ }
46
+
47
+ .forminator-drop-full {
48
+ width: auto !important;
49
+ height: 0;
50
+ position: relative;
51
+ z-index: 2;
52
+
53
+ &:before {
54
+ height: 4px;
55
+ display: flex;
56
+ position: relative;
57
+ top: -2px;
58
+ }
59
+
60
+ }
61
+
62
+ .forminator-drop-side {
63
+
64
+ &-before,
65
+ &-after {
66
+ width: 0;
67
+ height: auto !important;
68
+ display: flex;
69
+ padding: 0;
70
+
71
+ &:before {
72
+ width: 4px;
73
+ height: auto;
74
+ display: block;
75
+ position: relative;
76
+ margin: 0 -2px;
77
+
78
+ @include media ( max-width, md ) {
79
+ width: auto;
80
+ height: 4px;
81
+ top: -2px;
82
+ }
83
+ }
84
+
85
+ @include media( max-width, md ) {
86
+ width: auto;
87
+ height: 0 !important;
88
+ padding: 0 40px;
89
+ }
90
+ }
91
+ }
92
+
93
+ .forminator-drop-view {
94
+ opacity: 0.8;
95
+ position: absolute;
96
+ z-index: 99990;
97
+ border: 2px dotted #88f;
98
+ }
99
+
100
+ .ui-draggable-handle {
101
+ cursor: move;
102
+ }
103
+ }
104
+
105
+ .forminator-buttons {
106
+ display: flex;
107
+ margin: 20px 0 0;
108
+
109
+ @include media( max-width, md ) {
110
+ flex-direction: column;
111
+ justify-content: flex-end;
112
+ }
113
+ }
114
+ }
115
+
116
+ @include body-class(false) {
117
+
118
+ > li.draggable-element {
119
+ min-width: 40px;
120
+ padding: 10px 15px;
121
+ border: 1px solid palette( silver, soft );
122
+ border-radius: 5px;
123
+ background: $white;
124
+ box-shadow: 0 3px 5px 0 rgba(0,0,0,0.05);
125
+ color: $black;
126
+ font: 400 10px/11px $font;
127
+ text-align: center;
128
+ list-style: none;
129
+ transform: rotateZ(-4deg);
130
+ }
131
+
132
+ > li.element-dragging {
133
+ cursor: move;
134
+ }
135
+ }
_src/scss/forminator-ui/_builder.scss ADDED
@@ -0,0 +1,835 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ &.fui-builder-page {
4
+
5
+ .sui-header,
6
+ #wpmudev-section,
7
+ .sui-footer {
8
+
9
+ @media (min-width: 783px) {
10
+ margin-right: calc(30px + #{$sui-gutter});
11
+ }
12
+
13
+ @media (min-width: 1201px) {
14
+ margin-right: calc(320px + #{$sui-gutter});
15
+ }
16
+ }
17
+
18
+ .sui-box-footer {
19
+ display: block;
20
+
21
+ .sui-button {
22
+ width: 100%;
23
+ display: flex;
24
+ flex-direction: column;
25
+ align-items: center;
26
+ justify-content: center;
27
+ margin: #{$sui-gutter-md / 2} 0;
28
+
29
+ .sui-loading,
30
+ .sui-loading-text {
31
+ flex: 0 0 auto;
32
+ }
33
+
34
+ .sui-loading {
35
+ width: 100%;
36
+ top: 50%;
37
+ left: 0;
38
+ transform: translateY(-50%);
39
+ }
40
+
41
+ &:first-child {
42
+ margin-top: 0;
43
+
44
+ @media (min-width: 783px) {
45
+ margin-left: 0;
46
+ }
47
+ }
48
+
49
+ &:last-child {
50
+ margin-bottom: 0;
51
+
52
+ @media (min-width: 783px) {
53
+ margin-right: 0;
54
+ }
55
+ }
56
+
57
+ @media (min-width: 783px) {
58
+ width: auto;
59
+ margin: 0 #{$sui-gutter / 2};
60
+ }
61
+ }
62
+
63
+ .sui-actions-right {
64
+ display: block;
65
+
66
+ .forminator-add-new-field {
67
+
68
+ @media ( min-width: 783px ) {
69
+ display: none;
70
+ }
71
+ }
72
+
73
+ @media (min-width: 783px) {
74
+ display: flex;
75
+ flex-wrap: wrap;
76
+ }
77
+ }
78
+
79
+ @media (min-width: 783px) {
80
+ display: flex;
81
+ flex-wrap: wrap;
82
+ }
83
+ }
84
+ }
85
+
86
+ .fui-builder {
87
+ margin: $sui-gutter 0;
88
+
89
+ .fui-form-builder,
90
+ .fui-form-builder-shadow {
91
+ display: block;
92
+
93
+ // Empty message
94
+ .fui-form-builder--empty {
95
+ min-height: 60px;
96
+ display: block;
97
+ margin: 0;
98
+ padding: $sui-gutter;
99
+ border: 2px dashed #EAEAEA;
100
+ border-radius: $border-radius;
101
+
102
+ p {
103
+ text-align: center;
104
+ }
105
+ }
106
+
107
+ // Builder grid
108
+ // The grid is based on 12 columns per row
109
+ .fui-form-builder--row {
110
+ display: flex;
111
+ flex-wrap: wrap;
112
+ position: relative;
113
+ margin: 0 0 10px;
114
+ padding: #{$sui-gutter/2} 0;
115
+ border: 1px dashed #EAEAEA;
116
+ border-radius: $border-radius;
117
+ background: $white;
118
+ transition: 0.3s ease;
119
+
120
+ .fui-form-builder--col {
121
+ display: block;
122
+ flex: 0 0 auto;
123
+ padding: 0 #{$sui-gutter/2};
124
+
125
+ @include media( max-width, md ) {
126
+ padding: #{$sui-gutter/2};
127
+ }
128
+ }
129
+
130
+ // 4 columns
131
+ .fui-form-builder--col-3 {
132
+ max-width: 25%;
133
+ flex-basis: 25%;
134
+
135
+ .sui-col-md-4,
136
+ .sui-col-md-6 {
137
+ width: 100%;
138
+ max-width: 100%;
139
+ flex-basis: 100%;
140
+ margin-bottom: #{$sui-gutter/2};
141
+
142
+ &:last-child {
143
+ margin-bottom: 0;
144
+ }
145
+ }
146
+
147
+ @include media( max-width, md ) {
148
+ max-width: 100%;
149
+ flex-basis: 100%;
150
+ }
151
+ }
152
+
153
+ // 3 columns
154
+ .fui-form-builder--col-4 {
155
+ max-width: 33.33%;
156
+ flex-basis: 33.33%;
157
+
158
+ .sui-col-md-4,
159
+ .sui-col-md-6 {
160
+ width: 100%;
161
+ max-width: 100%;
162
+ flex-basis: 100%;
163
+ margin-bottom: #{$sui-gutter/2};
164
+
165
+ &:last-child {
166
+ margin-bottom: 0;
167
+ }
168
+ }
169
+
170
+ @include media( max-width, md ) {
171
+ max-width: 100%;
172
+ flex-basis: 100%;
173
+ }
174
+ }
175
+
176
+ // 2 columns
177
+ .fui-form-builder--col-6 {
178
+ max-width: 50%;
179
+ flex-basis: 50%;
180
+
181
+ @include media( max-width, md ) {
182
+ max-width: 100%;
183
+ flex-basis: 100%;
184
+ }
185
+ }
186
+
187
+ // 12 column
188
+ .fui-form-builder--col-12 {
189
+ max-width: 100%;
190
+ flex-basis: 100%;
191
+ }
192
+
193
+ &:hover {
194
+ border-color: palette( silver, medium );
195
+ }
196
+
197
+ @include media( max-width, md ) {
198
+ padding: #{$sui-gutter/2} 0;
199
+ }
200
+ }
201
+
202
+ // Multi choices
203
+ // Simulate checked option for this field
204
+ .sui-multi-checkbox {
205
+
206
+ label:nth-child(2) {
207
+
208
+ input + span {
209
+ background-color: $blue;
210
+ color: $white;
211
+ }
212
+ }
213
+ }
214
+ }
215
+
216
+ .fui-form-builder {
217
+ position: relative;
218
+ }
219
+
220
+ .fui-form-builder-shadow {
221
+ display: none;
222
+ }
223
+
224
+ &:first-child {
225
+ margin-top: 0;
226
+
227
+ @include media( max-width, md ) {
228
+ margin-top: 0;
229
+ }
230
+ }
231
+
232
+ &:last-child {
233
+ margin-bottom: 0;
234
+
235
+ @include media( max-width, md ) {
236
+ margin-bottom: 0;
237
+ }
238
+ }
239
+
240
+ @include media( max-width, md ) {
241
+ margin: $sui-gutter-md 0;
242
+ }
243
+ }
244
+
245
+ .fui-builder-sidebar {
246
+ width: 100%;
247
+ height: auto;
248
+ pointer-events: none;
249
+ display: none;
250
+ flex-direction: column;
251
+ position: fixed;
252
+ z-index: 2;
253
+ top: 0;
254
+ bottom: 0;
255
+ left: 0;
256
+
257
+ * {
258
+ box-sizing: border-box;
259
+ font-variant-ligatures: none;
260
+ -webkit-font-variant-ligatures: none;
261
+ text-rendering: optimizeLegibility;
262
+ -moz-osx-font-smoothing: grayscale;
263
+ font-smoothing: antialiased;
264
+ -webkit-font-smoothing: antialiased;
265
+ text-shadow: rgba(0, 0, 0, .01) 0 0 1px;
266
+ }
267
+
268
+ .fui-sidebar-wrapper {
269
+ max-height: 100%;
270
+ opacity: 0;
271
+ pointer-events: auto;
272
+ display: flex;
273
+ flex: 1 1 auto;
274
+ flex-direction: column;
275
+ background: $white;
276
+ animation-duration: 1s;
277
+ animation-fill-mode: both;
278
+ transform-origin: center;
279
+ transform-style: preserve-3d;
280
+
281
+ // ANIMATE show
282
+ &.fui-show {
283
+ opacity: 1;
284
+ animation-name: slideInUp;
285
+
286
+ @media (min-width: 783px) {
287
+ animation-name: slideInRight;
288
+ }
289
+
290
+ // IE10+ CSS styles go here
291
+ @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
292
+ height: 100vh;
293
+ }
294
+ }
295
+
296
+ // ANIMATE hide
297
+ &.fui-hide {
298
+ opacity: 1;
299
+ animation-name: slideOutUp;
300
+
301
+ @media (min-width: 783px) {
302
+ animation-name: slideOutRight;
303
+ }
304
+ }
305
+
306
+ @media (min-width: 783px) {
307
+ box-shadow: -3px 0 10px 0 rgba(0,0,0,0.05);
308
+ }
309
+ }
310
+
311
+ .fui-sidebar-header {
312
+ @extend .sui-box-header;
313
+ padding: $sui-gutter;
314
+ border-bottom: 0;
315
+
316
+ .wpmudev-title {
317
+ @extend .sui-box-title;
318
+ }
319
+
320
+ .forminator-sidebar-close {
321
+ min-width: 40px;
322
+
323
+ @media (min-width: 783px) {
324
+ display: none;
325
+ }
326
+ }
327
+
328
+ @include media( max-width, md ) {
329
+ padding: $sui-gutter-md;
330
+ }
331
+ }
332
+
333
+ .wpmudev-sidebar--section {
334
+ overflow: hidden;
335
+ display: flex;
336
+ flex-direction: column;
337
+ flex: 1 1 auto;
338
+ margin: 0;
339
+ padding: 0;
340
+ border: 0;
341
+ background: transparent;
342
+
343
+ .wpmudev-sidebar--menu {
344
+ display: flex;
345
+ flex: 0 0 auto;
346
+ margin: 0;
347
+ padding: 0 $sui-gutter;
348
+ border: 0;
349
+ box-shadow: inset 0 -1px 0 0 rgba(0,0,0,0.1);
350
+
351
+ .wpmudev-menu--item {
352
+ display: block;
353
+ flex: 0 0 auto;
354
+ float: none;
355
+ margin: 0;
356
+ padding: 0;
357
+ border: 0;
358
+ border-radius: 0;
359
+ background: transparent;
360
+
361
+ &:before {
362
+ display: none;
363
+ }
364
+
365
+ a {
366
+ float: none;
367
+ display: block;
368
+ font: 500 12px/21px $font;
369
+
370
+ &, &:visited {
371
+ border-bottom: 3px solid transparent;
372
+ color: rgba(0,0,0,0.4);
373
+ }
374
+
375
+ &:hover, &:active, &:focus {
376
+ border-bottom-color: rgba(0,0,0,0.4);
377
+ outline: none;
378
+ box-shadow: none;
379
+ }
380
+ }
381
+
382
+ &.ui-state-active {
383
+
384
+ a {
385
+ pointer-events: none;
386
+
387
+ &, &:visited {
388
+ border-bottom-color: $black;
389
+ color: $black;
390
+ }
391
+ }
392
+
393
+ &:active, &:focus {
394
+ outline: none;
395
+ box-shadow: none;
396
+ }
397
+ }
398
+
399
+ &:not(:last-child) {
400
+ margin-right: 20px;
401
+ }
402
+ }
403
+
404
+ @include media( max-width, md ) {
405
+ padding: 0 $sui-gutter-md;
406
+ }
407
+ }
408
+
409
+ .wpmudev-sidebar--content {
410
+ overflow-x: hidden;
411
+ overflow-y: auto;
412
+ flex: 1 1 auto;
413
+ padding: 0;
414
+
415
+ .wpmudev-list--options {
416
+ display: flex;
417
+ flex-wrap: wrap;
418
+ margin: -10px;
419
+ padding: $sui-gutter;
420
+
421
+ li {
422
+ max-width: calc(50% - 20px);
423
+ overflow: hidden;
424
+ cursor: pointer;
425
+ flex: 0 0 auto;
426
+ flex-basis: calc(50% - 20px);
427
+ margin: 10px;
428
+ padding: 8px 4px 7px;
429
+ border: 1px solid #EAEAEA;
430
+ border-radius: $border-radius;
431
+ background: $white;
432
+ color: $black;
433
+ font: 500 10px/13px $font;
434
+ text-align: center;
435
+ text-overflow: ellipsis;
436
+ white-space: nowrap;
437
+
438
+ &:last-child {
439
+
440
+ @media ( max-width: 782px ) {
441
+ margin: 0;
442
+ }
443
+ }
444
+
445
+ @media ( max-width: 782px ) {
446
+ max-width: 100%;
447
+ display: block;
448
+ margin: 0 0 10px;
449
+ line-height: 23px;
450
+ }
451
+ }
452
+
453
+ @media ( max-width: 782px ) {
454
+ display: block;
455
+ margin: 0;
456
+ }
457
+
458
+ @include media( max-width, md ) {
459
+ padding: $sui-gutter-md;
460
+ }
461
+ }
462
+
463
+ .wpmudev-option {
464
+ display: block;
465
+ padding: 12px 20px 13px;
466
+
467
+ .wpmudev-option {
468
+ padding: 7px 0 8px;
469
+
470
+ .wpmudev-option {
471
+ padding: 0 !important;
472
+ }
473
+
474
+ &:first-child {
475
+ padding-top: 0;
476
+ }
477
+
478
+ &:last-child {
479
+ padding-bottom: 0;
480
+ }
481
+ }
482
+
483
+ .wpmudev-option--half {
484
+ display: flex;
485
+
486
+ .wpmudev-option {
487
+ margin: 0 10px;
488
+ padding: 0 !important;
489
+
490
+ &:first-child {
491
+ margin-left: 0;
492
+ }
493
+
494
+ &:last-child {
495
+ margin-right: 0;
496
+ }
497
+ }
498
+ }
499
+
500
+ &:first-child {
501
+ padding-top: 20px;
502
+ }
503
+
504
+ &:last-child {
505
+ padding-bottom: 20px;
506
+ }
507
+ }
508
+
509
+ .wpmudev-radio-tab-week {
510
+
511
+ .wpmudev-option {
512
+ margin-bottom: 10px;
513
+
514
+ &:last-child {
515
+ margin-bottom: 0;
516
+ }
517
+ }
518
+ }
519
+
520
+ .wpmudev-option--border {
521
+ display: block;
522
+ margin: 7px 0 8px;
523
+ }
524
+
525
+ &:only-child {
526
+ border-top: 1px solid rgba(0,0,0,0.1);
527
+ }
528
+ }
529
+ }
530
+
531
+ .wpmudev-options--wrap {
532
+ padding: $sui-gutter;
533
+
534
+ @include media( max-width, md ) {
535
+ padding: $sui-gutter-md;
536
+ }
537
+ }
538
+
539
+ .fui-row-double {
540
+ display: flex;
541
+ margin: 0 -#{$sui-gutter/4};
542
+
543
+ .sui-form-field {
544
+ flex: 1;
545
+ margin: 0;
546
+ padding: 0 $sui-gutter/4;
547
+ }
548
+ }
549
+
550
+ .fui-sidebar-footer {
551
+ display: block;
552
+ flex: 0 0 auto;
553
+ padding: 20px;
554
+ border-top: 1px solid rgba(0,0,0,0.1);
555
+ background: palette( silver, light );
556
+
557
+ .wpmudev-footer--buttons {
558
+ display: flex;
559
+ flex-direction: column-reverse;
560
+
561
+ .sui-button {
562
+ width: 100%;
563
+ margin: 5px 0;
564
+
565
+ &:first-child {
566
+ margin-bottom: 0;
567
+
568
+ @media (min-width: 783px) {
569
+ margin-left: 0;
570
+ }
571
+ }
572
+
573
+ &:last-child {
574
+ margin-top: 0;
575
+
576
+ @media (min-width: 783px) {
577
+ margin-right: 0;
578
+ }
579
+ }
580
+
581
+ @media (min-width: 783px) {
582
+ width: auto;
583
+ flex: 1;
584
+ margin: 0 10px;
585
+ }
586
+ }
587
+
588
+ @media (min-width: 783px) {
589
+ //flex-wrap: wrap;
590
+ flex-direction: row;
591
+ }
592
+ }
593
+
594
+ .wpmudev-footer--link {
595
+ margin: 15px 0;
596
+ font-size: 14px;
597
+ line-height: 18px;
598
+ text-align: center;
599
+
600
+ a {
601
+ color: palette( red, default );
602
+ border-bottom-color: palette( red, default );
603
+
604
+ &:hover, &:active, &:focus {
605
+ color: palette( red, default );
606
+ border-bottom-color: palette( red, default );
607
+ }
608
+ }
609
+
610
+ &:first-child {
611
+ margin-top: 0;
612
+ }
613
+
614
+ &:last-child {
615
+ margin-bottom: 0;
616
+ }
617
+ }
618
+ }
619
+
620
+ &.fui-active {
621
+ display: flex;
622
+ }
623
+
624
+ &:hover {
625
+
626
+ @media (min-width: 783px) {
627
+ right: 0;
628
+ }
629
+ }
630
+
631
+ @media (min-width: 783px) {
632
+ max-width: 320px;
633
+ //z-index: 2;
634
+ right: -260px;
635
+ left: auto;
636
+ padding-top: 32px;
637
+ transition: 0.3s right linear;
638
+ }
639
+
640
+ @media (min-width: 1201px) {
641
+ right: 0;
642
+ }
643
+ }
644
+
645
+ .fui-form-field {
646
+ padding: #{$sui-gutter/2};
647
+ border: 1px solid #EAEAEA;
648
+ border-radius: $border-radius;
649
+ background: $white;
650
+ transition: 0.3s ease;
651
+
652
+ * {
653
+ pointer-events: none;
654
+ }
655
+
656
+ h3, h4 {
657
+ margin: 0;
658
+ padding: 0;
659
+ }
660
+
661
+ hr {
662
+ margin-bottom: 0;
663
+ }
664
+
665
+ .sui-row {
666
+ margin-bottom: #{$sui-gutter/2};
667
+
668
+ .sui-col-md-6 {
669
+
670
+ &:last-child {
671
+
672
+ @include media( max-width, md ) {
673
+ margin-bottom: 0;
674
+ }
675
+ }
676
+
677
+ @include media( max-width, md ) {
678
+ margin-bottom: #{$sui-gutter/2};
679
+ }
680
+ }
681
+
682
+ &:last-child {
683
+ margin-bottom: 0;
684
+ }
685
+ }
686
+
687
+ .fui-extended-description {
688
+ display: flex;
689
+ }
690
+
691
+ &:hover, &.fui-active {
692
+ border-color: $blue;
693
+ }
694
+ }
695
+
696
+ .fui-conditions {
697
+ margin-top: #{$sui-gutter/2};
698
+
699
+ .fui-conditions--init {
700
+ display: flex;
701
+ align-items: center;
702
+
703
+ .select-container {
704
+ flex: 1;
705
+
706
+ @include media( max-width, md ) {
707
+ flex: 0 0 auto;
708
+ }
709
+ }
710
+
711
+ .sui-description {
712
+ flex: 0 0 auto;
713
+ margin: 0 5px;
714
+ color: palette( gray, light );
715
+
716
+ &:last-child {
717
+ margin-right: 0;
718
+
719
+ @include media( max-width, md ) {
720
+ margin-bottom: 0;
721
+ }
722
+ }
723
+
724
+ @include media( max-width, md ) {
725
+ margin: 5px 0;
726
+ }
727
+ }
728
+
729
+ @include media( max-width, md ) {
730
+ flex-direction: column;
731
+ align-items: unset;
732
+ }
733
+ }
734
+
735
+ .fui-conditions--list {
736
+ padding: #{$sui-gutter/2};
737
+ border-radius: $border-radius;
738
+ background-color: palette( silver, default );
739
+
740
+ .fui-conditions--rules {
741
+ margin: 0;
742
+ }
743
+
744
+ @include media( max-width, md ) {
745
+ padding: #{$sui-gutter/2};
746
+ }
747
+ }
748
+
749
+ .fui-conditions--rules {
750
+
751
+ .fui-conditions--rule {
752
+ display: flex;
753
+ align-items: center;
754
+ margin: 0 -5px #{$sui-gutter/2};
755
+
756
+ .sui-select + .select2,
757
+ .fui-conditions--action,
758
+ .fui-conditions--wrap-input,
759
+ .fui-conditions--wrap-values {
760
+ padding: 0 5px;
761
+
762
+ @include media( max-width, md ) {
763
+ padding: 0;
764
+ }
765
+ }
766
+
767
+ .sui-select + .select2,
768
+ .fui-conditions--action,
769
+ .fui-conditions--wrap-input,
770
+ .fui-conditions--wrap-values {
771
+ flex: 1;
772
+ }
773
+
774
+ .sui-select + .select2,
775
+ .fui-conditions--wrap-values {
776
+ max-width: 41.667%;
777
+
778
+ @include media( max-width, md ) {
779
+ max-width: 0;
780
+ }
781
+ }
782
+
783
+ .fui-conditions--wrap-values {
784
+
785
+ .sui-select + .select2 {
786
+ max-width: unset;
787
+ padding: 0;
788
+ }
789
+ }
790
+
791
+ .fui-conditions--wrap-delete {
792
+ flex: 0 0 auto;
793
+ }
794
+
795
+ @include media( max-width, md ) {
796
+ display: block;
797
+ margin: 0 #{$sui-gutter-md/2};
798
+ }
799
+ }
800
+ }
801
+
802
+ .sui-description {
803
+ margin: 0;
804
+ color: palette( gray, dark );
805
+
806
+ i {
807
+ margin-right: 6px;
808
+
809
+ &:before {
810
+ color: palette( yellow, default );
811
+ }
812
+ }
813
+ }
814
+
815
+ @include media( max-width, md ) {
816
+ margin-top: $sui-gutter-md/2;
817
+ }
818
+ }
819
+
820
+ .sui-box-header + .fui-conditions {
821
+ margin: 0;
822
+ }
823
+
824
+ .fui-flex-end {
825
+ align-self: flex-end;
826
+ }
827
+ }
828
+
829
+ // IE10+ CSS styles go here
830
+ #wpbody-content {
831
+
832
+ @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) {
833
+ width: 95%;
834
+ }
835
+ }
_src/scss/forminator-ui/_buttons.scss ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ %fui-button-clear {
4
+ display: flex;
5
+ align-items: center;
6
+ justify-content: center;
7
+ cursor: pointer;
8
+ margin: 0;
9
+ padding: 0;
10
+ border: 0;
11
+ background: transparent;
12
+ text-align: center;
13
+
14
+ i {
15
+ display: block;
16
+
17
+ &:before {
18
+ display: block;
19
+ transition: 0.3s ease;
20
+ }
21
+ }
22
+ }
23
+
24
+ .fui-button-preview {
25
+ width: 100%;
26
+ max-width: 100%;
27
+ cursor: pointer;
28
+ display: flex;
29
+ align-items: center;
30
+ padding: 0 8px 0 14px;
31
+ border: 1px solid $blue;
32
+ border-radius: 30px;
33
+ background: $blue;
34
+ color: $white;
35
+ font: 400 15px/28px $font;
36
+ letter-spacing: 0;
37
+ text-align: left;
38
+ transition: 0.3s ease;
39
+
40
+ span {
41
+ flex: 1;
42
+ margin-right: 5px;
43
+
44
+ @media (max-width: 1100px) {
45
+ display: none;
46
+ }
47
+ }
48
+
49
+ i {
50
+ display: block;
51
+ flex: 0 0 auto;
52
+ font-size: 18px;
53
+
54
+ &:before {
55
+ display: block;
56
+ color: $white;
57
+ }
58
+ }
59
+
60
+ &:hover, &:focus {
61
+ background: palette( blue, medium );
62
+ }
63
+
64
+ @media (max-width: 1100px) {
65
+ width: 40px;
66
+ height: 40px;
67
+ flex-direction: column;
68
+ justify-content: center;
69
+ position: fixed;
70
+ z-index: 1;
71
+ right: 20px;
72
+ bottom: 20px;
73
+ padding: 0;
74
+ border-radius: 80px;
75
+ box-shadow: 0 3px 5px rgba(0, 0, 0, 0.1);
76
+ }
77
+ }
78
+
79
+ .fui-button-icon {
80
+ @extend .sui-button;
81
+ width: 30px;
82
+ min-width: unset;
83
+ }
84
+ }
_src/scss/forminator-ui/_chips.scss ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-chips {
4
+ display: flex;
5
+
6
+ .fui-chips-item {
7
+ margin-right: 1px;
8
+
9
+ input {
10
+ @extend %sui-screen-reader-text;
11
+ }
12
+
13
+ span, i:before {
14
+ color: $gray;
15
+ }
16
+
17
+ span {
18
+ display: block;
19
+ padding: 9px 16px;
20
+ background: #F8F8F8;
21
+ font: 500 13px/22px $font;
22
+ letter-spacing: 0;
23
+ text-align: center;
24
+
25
+ i {
26
+ margin-right: 9px;
27
+ }
28
+ }
29
+
30
+ &:first-child {
31
+
32
+ span {
33
+ border-radius: 4px 0 0 4px;
34
+ }
35
+ }
36
+
37
+ &:last-child {
38
+ margin-right: 0;
39
+
40
+ span {
41
+ border-radius: 0 4px 4px 0;
42
+ }
43
+ }
44
+
45
+ &.current {
46
+
47
+ span, i:before {
48
+ color: $blue;
49
+ }
50
+
51
+ span {
52
+ background: palette( blue, soft );
53
+ }
54
+ }
55
+ }
56
+
57
+ @include media( max-width, md ) {
58
+ flex-direction: column;
59
+ }
60
+
61
+ @include media(min-width, md) {
62
+ flex-wrap: wrap;
63
+ }
64
+ }
65
+ }
_src/scss/forminator-ui/_color-picker.scss ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .wp-picker-container {
4
+ display: block;
5
+ position: relative;
6
+
7
+ .wp-color-result {
8
+ width: 30px;
9
+ height: 30px;
10
+ position: absolute;
11
+ z-index: 1;
12
+ top: 5px;
13
+ left: 5px;
14
+ margin: 0;
15
+ padding: 0;
16
+ border: 1px solid $form--input-border-color;
17
+ border-radius: $form--input-border-radius;
18
+ box-shadow: none;
19
+
20
+ .wp-color-result-text {
21
+ @extend %sui-screen-reader-text;
22
+ }
23
+ }
24
+
25
+ .wp-picker-input-wrap {
26
+ display: block;
27
+ position: relative;
28
+
29
+ label {
30
+ display: block;
31
+ }
32
+
33
+ .wp-color-picker {
34
+ @extend .sui-form-control;
35
+ margin: 0;
36
+ padding-left: 40px;
37
+ padding-right: 90px;
38
+ }
39
+
40
+ .wp-picker-clear {
41
+ @extend .sui-button;
42
+ position: absolute;
43
+ top: 5px;
44
+ right: 5px;
45
+
46
+ &, &:hover, &:active {
47
+ outline: none;
48
+ box-shadow: none;
49
+ }
50
+ }
51
+
52
+ &.hidden {
53
+ display: block;
54
+ }
55
+ }
56
+
57
+ .wp-picker-holder {
58
+ display: block;
59
+ margin: $sui-gutter/2 0 0;
60
+
61
+ .iris-picker {
62
+ width: auto !important;
63
+ height: auto !important;
64
+ padding: 10px;
65
+ padding-bottom: 10px !important;
66
+ border: 1px solid $form--input-border-color;
67
+ border-radius: $form--input-border-radius;
68
+ background-color: $form--input-bg-color;
69
+
70
+ .iris-square {
71
+ float: none;
72
+ }
73
+ }
74
+
75
+ .iris-border {
76
+
77
+ .iris-picker-inner {
78
+ display: flex;
79
+ position: relative;
80
+ top: auto;
81
+ right: auto;
82
+ bottom: auto;
83
+ left: auto;
84
+ }
85
+ }
86
+
87
+ @include media( max-width, md ) {
88
+ margin: $sui-gutter-md/2 0 0;
89
+ }
90
+ }
91
+
92
+ &.wp-picker-active {
93
+
94
+ .wp-picker-holder {
95
+
96
+ .iris-picker {
97
+ display: inline-flex !important;
98
+ }
99
+ }
100
+ }
101
+ }
102
+ }
_src/scss/forminator-ui/_editor.scss ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-editor {
4
+ position: relative;
5
+
6
+ .fui-editor-options {
7
+ position: absolute;
8
+ z-index: 2;
9
+ top: 34px;
10
+ left: 4px;
11
+
12
+ button {
13
+ width: 28px;
14
+ height: 26px;
15
+ cursor: pointer;
16
+ display: block;
17
+ margin: 2px;
18
+ padding: 2px 3px;
19
+ border: 1px solid transparent;
20
+ border-radius: 2px;
21
+ background-color: transparent;
22
+ color: $blue;
23
+ text-align: center;
24
+
25
+ i {
26
+ width: 20px;
27
+ height: 20px;
28
+ display: flex;
29
+ flex-direction: column;
30
+ align-items: center;
31
+ justify-content: center;
32
+
33
+ &:before {
34
+ display: block;
35
+ color: $blue;
36
+ }
37
+ }
38
+
39
+ &, &:hover, &:active {
40
+ outline: none;
41
+ box-shadow: none;
42
+ }
43
+
44
+ &:hover, &:active, &.current {
45
+ border-color: $blue;
46
+ }
47
+ }
48
+
49
+ ul {
50
+ width: 180px;
51
+ max-height: 260px;
52
+ overflow-y: auto;
53
+ display: none;
54
+ margin: 2px;
55
+ padding: 0 15px;
56
+ border: 1px solid #EAEAEA;
57
+ border-radius: 2px;
58
+ background: $white;
59
+
60
+ li {
61
+ margin: 0 -6px;
62
+ padding: 0;
63
+ border: 0;
64
+ color: palette( gray, dark );
65
+ font: 400 12px/16px $font;
66
+ letter-spacing: 0;
67
+
68
+ a, strong {
69
+ display: block;
70
+ padding: 6px;
71
+ }
72
+
73
+ a {
74
+ cursor: pointer;
75
+ border-radius: 2px;
76
+ color: $blue;
77
+ transition: 0.3s ease;
78
+
79
+ &:hover {
80
+ background-color: $blue;
81
+ color: $white;
82
+ }
83
+ }
84
+
85
+ strong {
86
+ margin: 4px 0;
87
+ }
88
+
89
+ &:first-child {
90
+ margin-top: 10px;
91
+ }
92
+
93
+ &:last-child {
94
+ margin-bottom: 10px;
95
+ }
96
+ }
97
+
98
+ &.current {
99
+ display: block;
100
+ }
101
+ }
102
+ }
103
+
104
+ .wp-editor-wrap {
105
+
106
+ .wp-editor-tools .wp-editor-tabs {
107
+ margin: 0 12px;
108
+
109
+ .wp-switch-editor {
110
+ height: 30px;
111
+ margin: 0;
112
+ padding: 3px 16px;
113
+ border: 1px solid palette( silver, light );
114
+ background-color: palette( silver, light );
115
+ color: palette( gray, light );
116
+ font: 500 12px/22px $font;
117
+ letter-spacing: 0px;
118
+ transition: 0.3s ease;
119
+ }
120
+
121
+ .switch-tmce {
122
+ border-radius: $border-radius $border-radius 0 0;
123
+ }
124
+
125
+ .switch-html {
126
+ border-radius: 0 $border-radius 0 0;
127
+ }
128
+ }
129
+
130
+ .wp-editor-tools .wp-editor-container {
131
+ border: 1px solid palette( silver, soft );
132
+ border-radius: $border-radius;
133
+ box-shadow: none;
134
+
135
+ div.mce-toolbar-grp {
136
+ margin: -1px -1px 0;
137
+ border: 1px solid palette( silver, soft );
138
+ border-radius: $border-radius $border-radius 0 0;
139
+ background-color: $white;
140
+
141
+ .mce-stack-layout {
142
+ padding-left: 35px;
143
+ }
144
+ }
145
+
146
+ textarea {
147
+ width: 100%;
148
+ margin: 0 0 -11px;
149
+ padding: 8px;
150
+ border: 0;
151
+ border-bottom: 1px solid palette( silver, soft );
152
+ border-radius: 0 0 $border-radius $border-radius;
153
+
154
+ &, &:hover, &:focus {
155
+ outline: none;
156
+ box-shadow: none;
157
+ border-bottom-color: palette( silver, soft );
158
+ }
159
+ }
160
+
161
+ .mce-statusbar {
162
+ border-radius: 0 0 $border-radius $border-radius;
163
+ }
164
+ }
165
+
166
+ .quicktags-toolbar {
167
+ margin: -1px -1px 0;
168
+ padding-left: 35px;
169
+ border: 1px solid palette( silver, soft );
170
+ border-radius: $border-radius $border-radius 0 0;
171
+ background-color: $white;
172
+
173
+ .ed_button {
174
+ min-width: 28px;
175
+ padding: 2px 3px;
176
+ border: 1px solid transparent;
177
+ background-color: transparent;
178
+ box-shadow: none;
179
+ color: palette( gray, dark );
180
+ font-size: 14px;
181
+ line-height: normal;
182
+ text-align: center;
183
+ transition: 0.2s ease;
184
+
185
+ &:hover, &:active {
186
+ outline: none;
187
+ border-color: #555D66;
188
+ }
189
+
190
+ &:hover {
191
+ background-color: #FAFAFA;
192
+ box-shadow: inset 0 1px 0 $white, 0 1px 0 rgba(0,0,0,0.08);
193
+ color: #23282D;
194
+ }
195
+
196
+ &:active {
197
+ background-color: #EBEBEB;
198
+ box-shadow: inset 0 2px 5px -3px rgba(0,0,0,0.3);
199
+ }
200
+ }
201
+ }
202
+
203
+ &.tmce-active .wp-editor-tools .wp-editor-tabs .switch-tmce,
204
+ &.html-active .wp-editor-tools .wp-editor-tabs .switch-html {
205
+ position: relative;
206
+ z-index: 1;
207
+ border-color: palette( silver, soft );
208
+ border-bottom-color: $white;
209
+ background-color: $white;
210
+ color: palette( gray, dark );
211
+ }
212
+ }
213
+
214
+ div.mce-tinymce {
215
+ box-shadow: none;
216
+ }
217
+
218
+ div.mce-panel {
219
+ background: transparent;
220
+ }
221
+
222
+ > textarea.sui-form-control {
223
+ padding-right: 38px;
224
+ }
225
+
226
+ &.fui-editor-button-top-right {
227
+
228
+ .fui-editor-options {
229
+ top: 4px;
230
+ left: auto;
231
+ right: 4px;
232
+
233
+ button {
234
+ margin-left: auto;
235
+
236
+ i:before {
237
+ color: palette(gray, light);
238
+ }
239
+
240
+ &:hover, &:active, &.current {
241
+ border-color: transparent;
242
+
243
+ i:before {
244
+ color: palette(gray, dark);
245
+ }
246
+ }
247
+ }
248
+ }
249
+ }
250
+ }
251
+
252
+ body#tinymce {
253
+ background-color: #FAFAFA;
254
+ }
255
+
256
+ #trello-card-name-settings,
257
+ #trello-card-description-settings {
258
+ position: relative;
259
+ }
260
+
261
+ #trello-card-name-settings {
262
+ z-index: 2;
263
+ }
264
+
265
+ #trello-card-description-settings {
266
+ z-index: 1;
267
+ }
268
+ }
_src/scss/forminator-ui/_forms.scss ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-browse {
4
+ display: flex;
5
+ align-items: center;
6
+ padding: 4px $sui-gutter/2;
7
+ border: 1px solid $form--input-border-color;
8
+ border-radius: 3px;
9
+ background: $form--input-bg-color;
10
+
11
+ input {
12
+ width: 100%;
13
+ pointer-events: none;
14
+ display: block;
15
+ margin: 0;
16
+ padding: 0;
17
+ border: 0;
18
+ background: transparent;
19
+ font-size: $font--size;
20
+ line-height: $form--input-line-height;
21
+ font-weight: $form--input-font-weight;
22
+ font-family: $font;
23
+ letter-spacing: -0.025em;
24
+
25
+ &, &:hover, &:focus {
26
+ box-shadow: none;
27
+ }
28
+
29
+ &::placeholder {
30
+ color: $form--input-placeholder-color;
31
+ }
32
+ }
33
+
34
+ .sui-button {
35
+ display: block;
36
+ }
37
+
38
+ .fui-browse-cell,
39
+ .fui-browse-cell-fit {
40
+ display: block;
41
+ margin-right: $sui-gutter/2;
42
+
43
+ &:last-child {
44
+ margin-right: 0;
45
+
46
+ @include media( max-width, md ) {
47
+ margin-right: 0;
48
+ }
49
+ }
50
+
51
+ @include media( max-width, md ) {
52
+ margin-right: $sui-gutter-md/2;
53
+ }
54
+ }
55
+
56
+ .fui-browse-cell {
57
+ flex: 1;
58
+
59
+ &-fit {
60
+ flex: 0 0 auto;
61
+ }
62
+ }
63
+
64
+ .fui-browse-delete {
65
+ display: none;
66
+
67
+ button {
68
+ width: 30px;
69
+ height: 30px;
70
+ cursor: pointer;
71
+ display: block;
72
+ margin: 0;
73
+ padding: 0;
74
+ border: 0;
75
+ text-align: center;
76
+
77
+ i {
78
+ display: block;
79
+
80
+ &:before {
81
+ display: block;
82
+ color: palette( red, default );
83
+ transition: 0.3s ease;
84
+ }
85
+ }
86
+
87
+ &, &:hover, &:focus {
88
+ background: transparent;
89
+ box-shadow: none;
90
+ }
91
+
92
+ &:hover, &:active {
93
+
94
+ i:before {
95
+ color: palette( red, default );
96
+ }
97
+ }
98
+ }
99
+ }
100
+
101
+ &.fui-browse-has-image {
102
+
103
+ .fui-browse-delete {
104
+ display: block;
105
+ }
106
+ }
107
+
108
+ @include media( max-width, md ) {
109
+ padding: 4px $sui-gutter-md/2;
110
+ }
111
+ }
112
+
113
+ .fui-browse-preview {
114
+ width: 40px;
115
+ height: 40px;
116
+ display: block;
117
+ border: 1px solid #EAEAEA;
118
+ border-radius: 3px;
119
+ background-color: palette( silver, soft );
120
+ background-image: linear-gradient(
121
+ 45deg,
122
+ #FAFAFA 25%,
123
+ transparent 25%,
124
+ transparent 75%,
125
+ #FAFAFA 75%,
126
+ #FAFAFA
127
+ ), linear-gradient(
128
+ 45deg,
129
+ #FAFAFA 25%,
130
+ transparent 25%,
131
+ transparent 75%,
132
+ #FAFAFA 75%,
133
+ #FAFAFA
134
+ );
135
+ background-size: 20px 20px;
136
+ background-position: 0 0, 10px 10px;
137
+
138
+ span {
139
+ width: 38px;
140
+ height: 38px;
141
+ display: block;
142
+ border-radius: 2px;
143
+ background-size: contain;
144
+ background-position: center;
145
+ background-repeat: no-repeat;
146
+ }
147
+ }
148
+
149
+ .fui-browse-group {
150
+ width: 100%;
151
+ display: flex;
152
+
153
+ .fui-browse {
154
+ flex: 1;
155
+ }
156
+
157
+ .fui-browse-preview {
158
+ flex: 0 0 auto;
159
+ margin-right: $sui-gutter/2;
160
+
161
+ @include media( max-width, md ) {
162
+ display: none;
163
+ }
164
+ }
165
+ }
166
+ }
_src/scss/forminator-ui/_modals.scss ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-loading-dialog {
4
+ text-align: center;
5
+
6
+ i {
7
+ width: 16px;
8
+ height: 16px;
9
+ display: inline-flex;
10
+ flex-direction: column;
11
+ align-items: center;
12
+ justify-content: center;
13
+ font-size: 16px;
14
+
15
+ &:before {
16
+ display: block;
17
+ }
18
+ }
19
+ }
20
+
21
+ .sui-dialog {
22
+
23
+ .sui-box-body {
24
+
25
+ .wpmudev-section--popup {
26
+ margin: $sui-gutter;
27
+ padding: $sui-gutter;
28
+
29
+ @include media( max-width, md ) {
30
+ padding: $sui-gutter-md;
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
_src/scss/forminator-ui/_multi-answer.scss ADDED
@@ -0,0 +1,255 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-multi-answer {
4
+ display: none;
5
+
6
+ .fui-answer {
7
+ width: 100%;
8
+ margin: $sui-gutter/2 0;
9
+ padding: $sui-gutter/2;
10
+ border: 1px solid #EAEAEA;
11
+ border-radius: 5px;
12
+ background: $white;
13
+
14
+ &:first-of-type {
15
+ margin-top: 0;
16
+
17
+ @include media( max-width, md ) {
18
+ margin-top: 0;
19
+ }
20
+ }
21
+
22
+ &:last-of-type {
23
+ margin-bottom: 0;
24
+
25
+ @include media( max-width, md ) {
26
+ margin-bottom: 0;
27
+ }
28
+ }
29
+
30
+ @include media( max-width, md ) {
31
+ margin: $sui-gutter-md/2 0;
32
+ padding: $sui-gutter-md/2;
33
+ }
34
+ }
35
+
36
+ .fui-answer-add-indicator {
37
+ margin: 0;
38
+ padding: 0;
39
+ border: 0;
40
+ }
41
+
42
+ .fui-answer-basics,
43
+ .fui-answer-extras {
44
+ display: flex;
45
+ margin-right: -#{$sui-gutter/3};
46
+ margin-left: -#{$sui-gutter/3};
47
+
48
+ .fui-answer-cell,
49
+ .fui-answer-cell-fit {
50
+ display: inline-flex;
51
+ padding: 0 #{$sui-gutter/3};
52
+
53
+ &.block {
54
+ display: block;
55
+ }
56
+
57
+ @include media( max-width, md ) {
58
+ padding: 0 #{$sui-gutter-md/3};
59
+ }
60
+ }
61
+
62
+ .fui-answer-cell {
63
+ flex: 1;
64
+
65
+ &-fit {
66
+ flex: 0 0 auto;
67
+ }
68
+ }
69
+
70
+ @include media( max-width, md ) {
71
+ margin-right: -#{$sui-gutter-md/3};
72
+ margin-left: -#{$sui-gutter-md/3};
73
+ }
74
+ }
75
+
76
+ .fui-answer-basics {
77
+
78
+ .fui-answer-move-indicator {
79
+ display: block;
80
+ margin: 5px 0;
81
+
82
+ i {
83
+ width: 30px;
84
+ height: 30px;
85
+ cursor: move;
86
+ display: flex;
87
+ flex-direction: column;
88
+ align-items: center;
89
+ justify-content: center;
90
+
91
+ &:before {
92
+ display: block;
93
+ }
94
+ }
95
+ }
96
+
97
+ .sui-dropdown {
98
+ margin: 5px 0;
99
+ }
100
+
101
+ .fui-answer-type-text {
102
+ position: relative;
103
+
104
+ .sui-form-control {
105
+ padding-right: 48px;
106
+ }
107
+
108
+ .fui-answer-delete {
109
+ width: 38px;
110
+ height: 38px;
111
+ @extend %fui-button-clear;
112
+ position: absolute;
113
+ top: 1px;
114
+ right: 1px;
115
+ margin: 0 $sui-gutter/3 0 0;
116
+
117
+ i {
118
+ display: block;
119
+ }
120
+
121
+ i:before {
122
+ display: block;
123
+ color: palette( red, default );
124
+ transition: 0.3s ease;
125
+ }
126
+
127
+ &:hover i:before {
128
+ color: palette( red, default );
129
+ }
130
+
131
+ @include media( max-width, md ) {
132
+ margin: 0 $sui-gutter-md/3 0 0;
133
+ }
134
+ }
135
+
136
+ + .sui-form-field {
137
+ margin-top: $sui-gutter/2;
138
+
139
+ @include media( max-width, md ) {
140
+ margin-top: $sui-gutter-md/2;
141
+ }
142
+ }
143
+ }
144
+
145
+ .fui-answer-open-indicator {
146
+ width: 30px;
147
+ height: 30px;
148
+ @extend %fui-button-clear;
149
+
150
+ i {
151
+ transition: 0.5s;
152
+ transform-origin: center;
153
+ }
154
+ }
155
+ }
156
+
157
+ .fui-answer-extras {
158
+ display: none;
159
+ margin-top: $sui-gutter/2;
160
+
161
+ .fui-answer-cell,
162
+ .fui-answer-cell-fit {
163
+
164
+ &:first-child {
165
+
166
+ @include media( max-width, md ) {
167
+ margin-top: 0;
168
+ }
169
+ }
170
+
171
+ &:last-child {
172
+
173
+ @include media( max-width, md ) {
174
+ margin-bottom: 0;
175
+ }
176
+ }
177
+
178
+ @include media( max-width, md ) {
179
+ margin-top: $sui-gutter-md/3;
180
+ margin-bottom: $sui-gutter-md/3;
181
+ }
182
+ }
183
+
184
+ .fui-answer-cell {
185
+
186
+ @include media( max-width, md ) {
187
+ flex: 0 0 auto;
188
+ }
189
+ }
190
+
191
+ .fui-answer-delete {
192
+ width: 30px;
193
+ height: 30px;
194
+ cursor: pointer;
195
+ margin: 0;
196
+ padding: 0;
197
+ border: 0;
198
+ background: transparent;
199
+
200
+ i:before {
201
+ color: palette( red, default );
202
+ transition: 0.3s ease;
203
+ }
204
+
205
+ &:hover, &:active {
206
+
207
+ i:before {
208
+ color: palette( red, default );
209
+ }
210
+ }
211
+ }
212
+
213
+ @include media( max-width, md ) {
214
+ align-items: unset;
215
+ flex-direction: column;
216
+ margin-top: $sui-gutter-md/2;
217
+ }
218
+ }
219
+
220
+ .fui-answer-open {
221
+
222
+ .fui-answer-basics {
223
+
224
+ .fui-answer-open-indicator i {
225
+ transform: rotate(180deg);
226
+ }
227
+ }
228
+
229
+ .fui-answer-extras {
230
+ display: flex;
231
+ }
232
+ }
233
+
234
+ &-empty {
235
+ padding: $sui-gutter;
236
+ border-radius: 5px;
237
+ background: #F8F8F8;
238
+
239
+ @include media( max-width, md ) {
240
+ padding: $sui-gutter-md;
241
+ }
242
+ }
243
+ }
244
+
245
+ .fui-has-answers {
246
+
247
+ .fui-multi-answer {
248
+ display: block;
249
+
250
+ &-empty {
251
+ display: none;
252
+ }
253
+ }
254
+ }
255
+ }
_src/scss/forminator-ui/_multi-name.scss ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-multi-name {
4
+ margin: 0;
5
+ padding: $sui-gutter/2;
6
+ border: 1px solid #EAEAEA;
7
+ border-radius: $border-radius;
8
+ background-color: palette( silver, light );
9
+
10
+ .fui-toggle-multi-name {
11
+ @extend .sui-toggle;
12
+
13
+ span {
14
+ @extend .sui-toggle-slider;
15
+ }
16
+ }
17
+
18
+ .fui-multi-name-action {
19
+ display: flex;
20
+ align-items: center;
21
+
22
+ .fui-multi-name-title {
23
+ flex: 1;
24
+ margin-right: $sui-gutter/2;
25
+
26
+ @include media( max-width, md ) {
27
+ margin-right: $sui-gutter-md/2;
28
+ }
29
+ }
30
+
31
+ .fui-open-indicator {
32
+ flex: 0 0 auto;
33
+
34
+ button {
35
+ @extend %fui-button-clear;
36
+ width: 20px;
37
+ height: 20px;
38
+ font-size: 16px;
39
+
40
+ i {
41
+ width: 20px;
42
+ height: 20px;
43
+ display: flex;
44
+ flex-direction: column;
45
+ align-items: center;
46
+ justify-content: center;
47
+ transition: 0.2s linear;
48
+ }
49
+ }
50
+ }
51
+ }
52
+
53
+ .fui-multi-name-content {
54
+ display: none;
55
+ margin-top: $sui-gutter/2;
56
+
57
+ @include media( max-width, md ) {
58
+ margin-top: $sui-gutter-md/2;
59
+ }
60
+ }
61
+
62
+ &.fui-open {
63
+
64
+ .fui-multi-name-action {
65
+
66
+ .fui-open-indicator {
67
+
68
+ button i {
69
+ transform: rotate(180deg);
70
+ }
71
+ }
72
+ }
73
+
74
+ .fui-multi-name-content {
75
+ display: block;
76
+ }
77
+ }
78
+
79
+ @include media( max-width, md ) {
80
+ padding: $sui-gutter-md/2;
81
+ }
82
+ }
83
+ }
_src/scss/forminator-ui/_multi-order.scss ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-multi-order {
4
+ display: block;
5
+ margin: 1px 0;
6
+ padding: $sui-gutter/2;
7
+ border: 1px solid palette( gray, lighter );
8
+ border-radius: 5px;
9
+ background: palette( silver, light );
10
+
11
+ .fui-item {
12
+ cursor: move;
13
+ display: block;
14
+ margin: $sui-gutter/3 0;
15
+ color: palette( gray, dark );
16
+ font: 500 15px/30px $font;
17
+ letter-spacing: -0.025em;
18
+
19
+ i:before {
20
+ display: block;
21
+ }
22
+
23
+ .fui-item-move-indicator {
24
+ margin-right: 4px;
25
+ font-size: 11px;
26
+ line-height: 18px;
27
+ }
28
+
29
+ &:first-child {
30
+ margin-top: 0;
31
+
32
+ @include media( max-width, md ) {
33
+ margin-top: 0;
34
+ }
35
+ }
36
+
37
+ &:last-child {
38
+ margin-bottom: 0;
39
+
40
+ @include media( max-width, md ) {
41
+ margin-bottom: 0;
42
+ }
43
+ }
44
+
45
+ @include media( max-width, md ) {
46
+ margin: $sui-gutter-md/3 0;
47
+ }
48
+ }
49
+
50
+ @include media( max-width, md ) {
51
+ padding: $sui-gutter-md/2;
52
+ }
53
+ }
54
+
55
+ .sui-form-field-error {
56
+
57
+ .fui-multi-order {
58
+ border-bottom: 2px solid palette( red, default );
59
+ }
60
+ }
61
+ }
_src/scss/forminator-ui/_multi-question.scss ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-multi-question {
4
+ display: none;
5
+ margin: 0;
6
+ padding: 0;
7
+ border: 0;
8
+
9
+ .fui-question {
10
+ margin: $sui-gutter 0 0;
11
+ padding: 0 0 $sui-gutter;
12
+ border-bottom: 1px solid #EAEAEA;
13
+
14
+ .fui-question-delete {
15
+ cursor: pointer;
16
+
17
+ i {
18
+
19
+ &:before {
20
+ color: palette( red, default );
21
+ transition: 0.3s ease;
22
+ }
23
+ }
24
+
25
+ &:hover {
26
+
27
+ i:before {
28
+ color: palette( red, default );
29
+ }
30
+ }
31
+ }
32
+
33
+ .fui-question-input {
34
+ display: block;
35
+ position: relative;
36
+
37
+ .sui-form-control {
38
+ padding-right: 38px;
39
+ }
40
+
41
+ .fui-question-delete {
42
+ display: block;
43
+ position: absolute;
44
+ right: 0;
45
+ bottom: 1px;
46
+
47
+ i {
48
+ width: 38px;
49
+ height: 38px;
50
+ display: block;
51
+ text-align: center;
52
+
53
+ &:before {
54
+ line-height: 38px;
55
+ }
56
+ }
57
+ }
58
+ }
59
+
60
+ &:first-child {
61
+ margin-top: 0;
62
+ }
63
+
64
+ &:last-child {
65
+ padding-bottom: 0;
66
+ border-bottom: 0;
67
+
68
+ @include media( max-width, md ) {
69
+ padding-bottom: 0;
70
+ border-bottom: 0;
71
+ }
72
+ }
73
+
74
+ @include media( max-width, md ) {
75
+ margin: $sui-gutter-md 0 0;
76
+ padding: 0 0 $sui-gutter-md;
77
+ }
78
+ }
79
+ }
80
+
81
+ .fui-has-questions {
82
+
83
+ .fui-multi-question-empty {
84
+ display: none;
85
+ }
86
+
87
+ .fui-multi-question {
88
+ display: block;
89
+ }
90
+ }
91
+ }
_src/scss/forminator-ui/_multi-result.scss ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-multi-result {
4
+ display: none;
5
+ margin: 0;
6
+ padding: 0;
7
+ border: 0;
8
+ list-style: none;
9
+
10
+ .fui-result {
11
+ display: block;
12
+ margin: 0 0 $sui-gutter;
13
+ padding: 0 0 $sui-gutter;
14
+ border: 0;
15
+ border-bottom: 1px solid #EAEAEA;
16
+ list-style: none;
17
+
18
+ &:last-child {
19
+ margin: 0;
20
+ padding: 0;
21
+ border-bottom: 0;
22
+
23
+ @include media( max-width, md ){
24
+ margin: 0;
25
+ padding: 0;
26
+ }
27
+ }
28
+
29
+ @include media( max-width, md ){
30
+ margin: 0 0 $sui-gutter-md;
31
+ padding: 0 0 $sui-gutter-md;
32
+ }
33
+ }
34
+
35
+ .fui-result-input {
36
+ display: block;
37
+ position: relative;
38
+
39
+ .sui-form-control {
40
+ padding-right: 48px;
41
+ }
42
+
43
+ .fui-result-delete {
44
+ width: 38px;
45
+ height: 38px;
46
+ @extend %fui-button-clear;
47
+ position: absolute;
48
+ top: 1px;
49
+ right: 1px;
50
+ margin: 0 $sui-gutter/3 0 0;
51
+
52
+ i {
53
+ display: block;
54
+ }
55
+
56
+ i:before {
57
+ display: block;
58
+ color: palette( red, default );
59
+ transition: 0.3s ease;
60
+ }
61
+
62
+ &:hover i:before {
63
+ color: palette( red, default );
64
+ }
65
+
66
+ @include media( max-width, md ) {
67
+ margin: 0 $sui-gutter-md/3 0 0;
68
+ }
69
+ }
70
+ }
71
+ }
72
+
73
+ .fui-has-results {
74
+
75
+ .fui-multi-result-empty {
76
+ display: none;
77
+ }
78
+
79
+ .fui-multi-result {
80
+ display: block;
81
+ }
82
+ }
83
+ }
_src/scss/forminator-ui/_multi-select.scss ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ // This styles work with Select2
4
+ .fui-multi-select {
5
+
6
+ + .select2 {
7
+ width: 100% !important;
8
+ display: block;
9
+
10
+ * {
11
+ display: block;
12
+ }
13
+
14
+ .fui-multi-select {
15
+ min-height: 40px;
16
+ margin: 0;
17
+ padding: 6px 14px;
18
+ border: 1px solid palette( gray, lighter );
19
+ border-radius: $border-radius;
20
+ background-color: palette( silver, light );
21
+
22
+ .select2-selection__rendered {
23
+ display: block;
24
+ margin: -2px;
25
+ padding: 0;
26
+
27
+ .select2-selection__clear {
28
+ display: none;
29
+ }
30
+
31
+ li {
32
+ display: inline-flex;
33
+ margin: 2px;
34
+ font: 500 15px/24px $font;
35
+
36
+ &:before, &:after {
37
+ content: none;
38
+ }
39
+ }
40
+
41
+ .select2-selection__choice {
42
+ padding: 0 8px;
43
+ border: 1px solid palette( gray, lighter );
44
+ border-radius: $border-radius;
45
+ background-color: palette( silver, light );
46
+ color: palette( gray, dark );
47
+ line-height: 24px;
48
+
49
+ .select2-selection__choice__remove {
50
+ margin-right: 4px;
51
+ color: palette( gray, medium );
52
+ transition: 0.2s ease;
53
+
54
+ &:hover {
55
+ color: palette( red, default );
56
+ }
57
+ }
58
+ }
59
+
60
+ .select2-search--inline {
61
+
62
+ .select2-search__field {
63
+ width: 100% !important;
64
+ display: block;
65
+ margin: 0;
66
+ padding: 0;
67
+ color: palette( gray, dark );
68
+ font: 500 15px/26px $font;
69
+ transition: 0.2s ease;
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }
_src/scss/forminator-ui/_multi-value.scss ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-multi-value {
4
+ display: none;
5
+ margin: 0;
6
+ padding: 0;
7
+ border: 0;
8
+
9
+ li {
10
+ display: flex;
11
+ margin: $sui-gutter/2 0;
12
+ padding: $sui-gutter/2;
13
+ border: 1px solid #EAEAEA;
14
+ border-radius: $border-radius;
15
+ background-color: $white;
16
+
17
+ .fui-move-indicator {
18
+ flex: 0 0 auto;
19
+ margin-top: 10px;
20
+ margin-right: $sui-gutter/2;
21
+
22
+ i {
23
+ width: 20px;
24
+ height: 20px;
25
+ cursor: move;
26
+ display: flex;
27
+ flex-direction: column;
28
+ align-items: center;
29
+ justify-content: center;
30
+ font-size: 14px;
31
+
32
+ &:before {
33
+ display: block;
34
+ }
35
+ }
36
+
37
+ @include media( max-width, md ) {
38
+ margin-right: $sui-gutter-md/2;
39
+ }
40
+ }
41
+
42
+ .fui-multi-value-settings {
43
+ flex: 1;
44
+
45
+ .fui-top-row {
46
+ position: relative;
47
+ margin: 0 0 5px;
48
+
49
+ .sui-form-control {
50
+ padding-right: 38px;
51
+ }
52
+
53
+ .fui-multi-value-delete {
54
+ position: absolute;
55
+ top: 9px;
56
+ right: 9px;
57
+
58
+ button {
59
+ @extend %fui-button-clear;
60
+ width: 20px;
61
+ height: 20px;
62
+
63
+ i:before {
64
+ color: palette( red, default );
65
+ transition: 0.3s ease;
66
+ }
67
+
68
+ &:hover i:before {
69
+ color: palette( red, default );
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }
75
+
76
+ &:first-child {
77
+ margin-top: 0;
78
+
79
+ @include media( max-width, md ) {
80
+ margin-top: 0;
81
+ }
82
+ }
83
+
84
+ &:last-child {
85
+ margin-bottom: 0;
86
+ padding: 0;
87
+ border: 0;
88
+ border-radius: 0;
89
+ background-color: transparent;
90
+
91
+ @include media( max-width, md ) {
92
+ margin-bottom: 0;
93
+ }
94
+ }
95
+
96
+ @include media( max-width, md ) {
97
+ margin: $sui-gutter-md/2 0;
98
+ }
99
+ }
100
+
101
+ &-empty {
102
+ display: block;
103
+ padding: $sui-gutter;
104
+ border: 0;
105
+ border-radius: $border-radius;
106
+ background: palette( silver, light );
107
+ }
108
+ }
109
+
110
+ .fui-has-values {
111
+
112
+ .fui-multi-value {
113
+ display: block;
114
+
115
+ &-empty {
116
+ display: none;
117
+ }
118
+ }
119
+ }
120
+ }
_src/scss/forminator-ui/_multicheck.scss ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-multicheck {
4
+ max-height: 180px;
5
+ overflow-y: auto;
6
+ margin: 0;
7
+ padding: 20px;
8
+ border: 1px solid #F2F2F2;
9
+ border-radius: 5px;
10
+ background: #F8F8F8;
11
+ list-style: none;
12
+
13
+ li {
14
+ margin: 10px 0;
15
+ padding: 0;
16
+ border: 0;
17
+
18
+ &:first-child {
19
+ margin-top: 0;
20
+ }
21
+
22
+ &:last-child {
23
+ margin-bottom: 0;
24
+ }
25
+ }
26
+ }
27
+
28
+ .fui-multicheck-actions {
29
+ display: flex;
30
+
31
+ .fui-multicheck-action-resume {
32
+ flex: 1;
33
+ margin-right: $sui-gutter/2;
34
+
35
+ @include media( max-width, md ) {
36
+ margin-right: 0;
37
+ }
38
+ }
39
+
40
+ .fui-multicheck-action-selectors {
41
+ flex: 0 0 auto;
42
+
43
+ @include media( max-width, md ) {
44
+ display: none;
45
+ }
46
+ }
47
+
48
+ + .fui-multicheck {
49
+ margin-top: 10px;
50
+ }
51
+
52
+ @include media( max-width, md ) {
53
+ display: block;
54
+ }
55
+ }
56
+ }
_src/scss/forminator-ui/_page-poll.scss ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .forminator-polls-content {
4
+
5
+ .sui-vertical-tabs {
6
+
7
+ li {
8
+ pointer-events: none;
9
+ }
10
+ }
11
+ }
12
+ }
_src/scss/forminator-ui/_page-quiz.scss ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .forminator-quizzes-content {
4
+
5
+ .sui-vertical-tabs {
6
+
7
+ li {
8
+ pointer-events: none;
9
+ }
10
+ }
11
+ }
12
+ }
_src/scss/forminator-ui/_select.scss ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-select-small {
4
+
5
+ .dropdown-handle {
6
+ width: 36px;
7
+ line-height: 27px;
8
+ }
9
+
10
+ .select-list-container {
11
+ padding-right: 36px;
12
+
13
+ .list-value,
14
+ .list-results {
15
+ font-size: 12px;
16
+ line-height: 16px;
17
+ }
18
+
19
+ .list-value {
20
+ padding: 6px 6px 6px 12px;
21
+ }
22
+
23
+ .list-results {
24
+ top: 31px;
25
+
26
+ li {
27
+ padding: 7px 6px;
28
+ }
29
+ }
30
+ }
31
+ }
32
+
33
+ select.fui-select-builder {
34
+ @extend %sui-screen-reader-text;
35
+ }
36
+ }
_src/scss/forminator-ui/_summary.scss ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-summary-alt {
4
+ background-image: url('../../assets/images/forminator-summary-alt@2x.png');
5
+ background-size: 128px 128px;
6
+
7
+ .sui-summary-image-space {
8
+ max-width: 128px;
9
+ min-height: 128px;
10
+ }
11
+
12
+ .sui-summary-segment {
13
+ width: calc(100% / 2 - 66px);
14
+ }
15
+ }
16
+ }
_src/scss/forminator-ui/_tables.scss ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-table {
4
+ @extend .sui-table;
5
+ border: 0;
6
+ border-radius: 0;
7
+
8
+ .fui-cell-title {
9
+ color: palette(gray, dark);
10
+ font-weight: 500;
11
+ }
12
+
13
+ .fui-table-action {
14
+ width: 40px;
15
+
16
+ &:last-child {
17
+ width: #{$sui-gutter - 1px + 5px + 30px};
18
+ }
19
+ }
20
+
21
+ &:before, &:after {
22
+ content: none;
23
+ }
24
+ }
25
+
26
+ .fui-table-accordion {
27
+ @extend .fui-table;
28
+ margin: 0;
29
+ }
30
+
31
+ .fui-table-toggle {
32
+ @extend .sui-table;
33
+
34
+ &.sui-accordion {
35
+ margin: $sui-gutter 0;
36
+ border: 1px solid palette( silver, soft );
37
+
38
+ &:before,
39
+ &:after {
40
+ content: none;
41
+ }
42
+
43
+ &:first-child {
44
+ margin-top: 0;
45
+ }
46
+
47
+ &:last-child {
48
+ margin-bottom: 0;
49
+ }
50
+ }
51
+ }
52
+
53
+ .fui-table-ghost,
54
+ .sui-accordion .sui-box .fui-table-ghost {
55
+ @extend .fui-table;
56
+ border: 0;
57
+
58
+ th, td {
59
+ padding: 0;
60
+ border-bottom: 0;
61
+ background-color: transparent;
62
+
63
+ &:first-child {
64
+ padding-left: 0;
65
+ }
66
+
67
+ &:last-child {
68
+ padding-right: 0;
69
+ }
70
+ }
71
+ }
72
+
73
+ .sui-box {
74
+
75
+ .sui-box-body {
76
+
77
+ + .fui-table {
78
+ margin-top: 0;
79
+ }
80
+ }
81
+ }
82
+
83
+ .fui-table-exports,
84
+ .sui-accordion .sui-box .sui-table.fui-table-exports {
85
+ border: 0;
86
+
87
+ &:before, &:after {
88
+ content: none;
89
+ }
90
+
91
+ td {
92
+
93
+ &:last-child {
94
+ text-align: right;
95
+ }
96
+ }
97
+
98
+ .fui-thead-gray {
99
+
100
+ th, td {
101
+ background-color: palette(gray, lighter);
102
+ }
103
+ }
104
+ }
105
+
106
+ .fui-table-listings {
107
+
108
+ &:after {
109
+ content: none;
110
+ }
111
+
112
+ tr:nth-last-child(2) td {
113
+ border-bottom: 0;
114
+ }
115
+ }
116
+
117
+ #fui-entries-table {
118
+
119
+ thead tr th,
120
+ tbody tr td {
121
+
122
+ &:first-child,
123
+ &:last-child {
124
+
125
+ @include media(max-width, md) {
126
+ display: table-cell;
127
+ }
128
+ }
129
+
130
+ @include media(max-width, md) {
131
+ display: none;
132
+ }
133
+ }
134
+ }
135
+ }
_src/scss/forminator-ui/_utility.scss ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .fui-image {
4
+ margin-top: $sui-gutter;
5
+ margin-bottom: $sui-gutter;
6
+
7
+ &:first-child {
8
+ margin-top: 0;
9
+ }
10
+
11
+ &:last-child {
12
+ margin-bottom: 0;
13
+ }
14
+
15
+ @include media( max-width, md ) {
16
+ margin-top: $sui-gutter-md;
17
+ margin-bottom: $sui-gutter-md;
18
+ }
19
+ }
20
+
21
+ .fui-limit-block-600 {
22
+ max-width: 600px;
23
+ }
24
+
25
+ .fui-limit-block-center {
26
+ display: block;
27
+ margin-right: auto;
28
+ margin-left: auto;
29
+ }
30
+
31
+ .fui-action-buttons {
32
+ display: flex;
33
+ flex: 1;
34
+ align-items: center;
35
+ justify-content: space-between;
36
+
37
+ .sui-button {
38
+ flex: 0 0 auto;
39
+ margin: 0 $sui-gutter/2;
40
+
41
+ &:first-child {
42
+ margin-left: 0;
43
+
44
+ @include media( max-width, md ) {
45
+ margin-top: 0;
46
+ }
47
+ }
48
+
49
+ &:last-child {
50
+ margin-right: 0;
51
+
52
+ @include media( max-width, md ) {
53
+ margin-bottom: 0;
54
+ }
55
+ }
56
+
57
+ @include media( max-width, md ) {
58
+ margin: $sui-gutter-md 0;
59
+ }
60
+ }
61
+
62
+ @include media( max-width, md ) {
63
+ display: block;
64
+ }
65
+ }
66
+
67
+ .fui-separator {
68
+ margin: $sui-gutter 0;
69
+ border-top: 1px solid palette(gray, lighter);
70
+ border-bottom: 1px solid $white;
71
+
72
+ @include media( max-width, md ) {
73
+ margin: $sui-gutter-md 0;
74
+ }
75
+ }
76
+ }
_src/scss/overwrite-sui/_accordion.scss ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .sui-accordion {
4
+
5
+ // FIX
6
+ // Prevent inner tables to be overwritten
7
+ // with accordion (parent) styles.
8
+ .sui-box .sui-table {
9
+
10
+ th, td {
11
+ padding: 20px $sui-gutter/2;
12
+
13
+ &:first-child {
14
+ padding-left: $sui-gutter;
15
+
16
+ @include media( max-width, md ) {
17
+ padding-left: $sui-gutter-md;
18
+ }
19
+ }
20
+
21
+ &:last-child {
22
+ padding-right: $sui-gutter;
23
+
24
+ @include media( max-width, md ) {
25
+ padding-right: $sui-gutter-md;
26
+ }
27
+ }
28
+
29
+ @include media( max-width, md ) {
30
+ padding: $sui-gutter-md $sui-gutter-md/2;
31
+ }
32
+ }
33
+ }
34
+ }
35
+
36
+ .sui-accordion-item-content {
37
+
38
+ .sui-box {
39
+ margin: 0 0 $sui-gutter;
40
+
41
+ &:last-child {
42
+ margin: 0;
43
+ }
44
+
45
+ @include media( max-width, md ) {
46
+ margin: 0 0 $sui-gutter-md;
47
+ }
48
+ }
49
+ }
50
+
51
+ .sui-accordion-item--open {
52
+
53
+ // FIX
54
+ // Prevent inner tables to be overwritten
55
+ // with accordion (parent) styles.
56
+ .sui-box .sui-table {
57
+
58
+ td {
59
+ background: transparent;
60
+ border-bottom: 1px solid $table--border-color;
61
+ }
62
+
63
+ tr:last-child td {
64
+ border-bottom: 0;
65
+ }
66
+ }
67
+ }
68
+ }
_src/scss/overwrite-sui/_boxes.scss ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .sui-box {
4
+
5
+ .sui-box-body {
6
+
7
+ .fui-form-intro {
8
+ display: flex;
9
+ align-items: center;
10
+
11
+ .fui-form-title {
12
+ flex: 0 0 auto;
13
+ margin: 0;
14
+ line-height: 30px;
15
+
16
+ + .fui-form-element-actions {
17
+ margin-left: $sui-gutter;
18
+
19
+ @include media( max-width, md ) {
20
+ margin-left: $sui-gutter-md;
21
+ }
22
+ }
23
+ }
24
+
25
+ @include media( max-width, md ) {
26
+ display: block;
27
+ }
28
+ }
29
+
30
+ .sui-box-settings-row {
31
+
32
+ .sui-box-settings-col-1 {
33
+ vertical-align: top;
34
+ }
35
+ }
36
+ }
37
+
38
+ .fui-box-buttons {
39
+ display: flex;
40
+ align-items: center;
41
+ justify-content: space-between;
42
+
43
+ .sui-button {
44
+ flex: 0 0 auto;
45
+ }
46
+
47
+ @include media( max-width, md ) {
48
+ display: block;
49
+ }
50
+ }
51
+ }
52
+ }
_src/scss/overwrite-sui/_modals.scss ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .sui-dialog {
4
+ z-index: 4;
5
+ }
6
+ }
_src/scss/overwrite-sui/_notifications.scss ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .sui-notice {
4
+ margin: $sui-gutter/2 0;
5
+
6
+ &:first-child {
7
+ margin-top: 0;
8
+ }
9
+
10
+ &:last-child {
11
+ margin-bottom: 0;
12
+ }
13
+
14
+ @include media( max-width, md ) {
15
+ margin: $sui-gutter-md/2 0;
16
+ }
17
+ }
18
+ }
_src/scss/overwrite-sui/_pr-changes.scss ADDED
@@ -0,0 +1,381 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // INCLUDED ON PULL REQUEST #97
2
+ // https://github.com/wpmudev/shared-ui/pull/97
3
+ @include body-class(true) {
4
+
5
+ .sui-insert-variables {
6
+
7
+ .sui-form-control {
8
+ padding-right: #{($form--input-height-base - 1px) + 14px};
9
+ }
10
+
11
+ .select-container {
12
+
13
+ .select-list-container {
14
+
15
+ li span {
16
+ pointer-events: none;
17
+ }
18
+ }
19
+ }
20
+
21
+ textarea.sui-form-control {
22
+
23
+ + .select-container {
24
+
25
+ .select-list-container .list-value {
26
+ border-color: transparent;
27
+
28
+ &:hover {
29
+ border-left-color: transparent;
30
+ background-color: transparent;
31
+ }
32
+ }
33
+
34
+ &.active .select-list-container .list-value {
35
+ border-left-color: transparent;
36
+ background-color: transparent;
37
+ }
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+ // INCLUDED ON PULL REQUEST #
44
+ // https://github.com/wpmudev/shared-ui/pull/
45
+ $ace-selector-background: palette(gray, default) !default;
46
+ $ace-selector-background-hover: palette(gray, dark) !default;
47
+ $ace-selector-color: $white !default;
48
+
49
+ @include body-class(true) {
50
+
51
+ .sui-ace-selectors {
52
+ display: flex;
53
+ flex-wrap: wrap;
54
+ margin-bottom: 15px;
55
+ margin-left: -5px;
56
+
57
+ .sui-selector {
58
+ height: 26px;
59
+ display: inline-flex;
60
+ flex: 0 0 auto;
61
+ margin: 0 0 5px 5px;
62
+ padding: 5px 12px;
63
+ border-radius: $border-radius;
64
+ background-color: $ace-selector-background;
65
+ font: 500 12px/16px $font;
66
+ letter-spacing: $font--letter-spacing;
67
+ transition: 0.3s ease;
68
+
69
+ &,
70
+ &:hover,
71
+ &:focus,
72
+ &:active,
73
+ &:visited {
74
+ border: 0;
75
+ outline: none;
76
+ box-shadow: none;
77
+ color: $ace-selector-color;
78
+ }
79
+
80
+ &:hover,
81
+ &:active {
82
+ background-color: $ace-selector-background-hover;
83
+ }
84
+ }
85
+
86
+ &:last-child {
87
+ margin: 0;
88
+ }
89
+ }
90
+ }
91
+
92
+ // INCLUDED ON PULL REQUEST #
93
+ // https://github.com/wpmudev/shared-ui/pull/
94
+ @include body-class(true) {
95
+
96
+ .sui-date {
97
+
98
+ .sui-button-icon {
99
+ position: absolute;
100
+ top: 5px;
101
+ right: 5px;
102
+
103
+ i {
104
+ position: unset;
105
+ top: auto;
106
+ right: auto;
107
+ }
108
+ }
109
+ }
110
+ }
111
+
112
+ // INCLUDED ON PULL REQUEST #
113
+ // https://github.com/wpmudev/shared-ui/pull/
114
+ @include body-class(true) {
115
+
116
+ .sui-table {
117
+
118
+ tbody tr {
119
+
120
+ td:last-child {
121
+
122
+ .sui-tooltip-top-left:after {
123
+ margin-right: -20px;
124
+ }
125
+ }
126
+ }
127
+ }
128
+ }
129
+
130
+ // INCLUDED ON PULL REQUEST #
131
+ // https://github.com/wpmudev/shared-ui/pull/
132
+ @include body-class(true) {
133
+
134
+ .sui-notice,
135
+ .sui-notice-top {
136
+
137
+ // NOTICE loading
138
+ &.sui-notice-loading {
139
+
140
+ p:first-of-type {
141
+ @include icon(before, loader, false);
142
+
143
+ &:before {
144
+ color: palette(gray, light);
145
+ animation: spin 1.3s linear infinite;
146
+ }
147
+ }
148
+ }
149
+ }
150
+ }
151
+
152
+ // INCLUDED ON PULL REQUEST #
153
+ // https://github.com/wpmudev/shared-ui/pull/
154
+ @include body-class(true) {
155
+
156
+ .sui-dialog-back {
157
+ @extend .sui-dialog-close;
158
+ @include icon(before, chevron-left, true);
159
+ }
160
+
161
+ .sui-dialog {
162
+
163
+ &.sui-dialog-special {
164
+
165
+ .sui-box-header,
166
+ .sui-box-body,
167
+ .sui-box-footer {
168
+ margin: 0;
169
+ border: 0;
170
+
171
+ .sui-box-content {
172
+ max-width: 600px;
173
+ display: block;
174
+ margin: 0 auto;
175
+ }
176
+ }
177
+
178
+ .sui-box-header,
179
+ .sui-box-body {
180
+ text-align: center;
181
+
182
+ p small {
183
+ color: palette(gray, light);
184
+ line-height: 22px;
185
+ }
186
+ }
187
+
188
+ .sui-box-header {
189
+ display: block;
190
+ position: relative;
191
+ margin: 35px 0 0;
192
+ padding: #{$sui-gutter * 2} $sui-gutter #{$sui-gutter / 2};
193
+
194
+ .sui-dialog-back,
195
+ .sui-dialog-close {
196
+ width: 30px;
197
+ height: 30px;
198
+ display: flex;
199
+ flex-direction: column;
200
+ align-items: center;
201
+ justify-content: center;
202
+ position: absolute;
203
+ top: #{$sui-gutter / 2};
204
+ margin: 0;
205
+ padding: 0;
206
+ border: 0;
207
+
208
+ &, &:before {
209
+ color: palette( gray, light );
210
+ font-size: 16px;
211
+ }
212
+
213
+ &:hover, &:focus {
214
+ outline: none;
215
+ }
216
+
217
+ @include media( max-width, md ) {
218
+ top: #{$sui-gutter-md / 2};
219
+ }
220
+ }
221
+
222
+ .sui-dialog-close {
223
+ right: #{$sui-gutter / 2};
224
+
225
+ @include media( max-width, md ) {
226
+ right: #{$sui-gutter-md / 2};
227
+ }
228
+ }
229
+
230
+ .sui-dialog-back {
231
+ left: #{$sui-gutter / 2};
232
+
233
+ @include media( max-width, md ) {
234
+ left: #{$sui-gutter-md / 2};
235
+ }
236
+ }
237
+
238
+ .sui-box-title {
239
+ margin: 0 0 20px;
240
+ color: palette(gray, dark);
241
+ font: bold 22px/30px $font--alt;
242
+
243
+ &:last-child {
244
+ margin: 0;
245
+ }
246
+ }
247
+
248
+ .sui-box-image {
249
+ width: 70px;
250
+ height: 70px;
251
+ display: block;
252
+ position: absolute;
253
+ top: -35px;
254
+ left: 50%;
255
+ margin-left: -35px;
256
+ border: 5px solid $white;
257
+ border-radius: 4px;
258
+ background-color: $white;
259
+
260
+ img {
261
+ display: block;
262
+ border-radius: 3px;
263
+ }
264
+
265
+ @include media( max-width, md ) {
266
+ display: none;
267
+ }
268
+ }
269
+
270
+ @include media( max-width, md ) {
271
+ margin: 0;
272
+ padding: #{$sui-gutter-md / 2} $sui-gutter-md;
273
+ }
274
+ }
275
+
276
+ .sui-box-body {
277
+ padding: #{$sui-gutter / 2} $sui-gutter;
278
+
279
+ .sui-table,
280
+ .sui-form-field {
281
+ text-align: left;
282
+ }
283
+
284
+ .sui-table {
285
+
286
+ th {
287
+ padding-top: 19px;
288
+ padding-bottom: 19px;
289
+ }
290
+
291
+ td {
292
+
293
+ .integrations-required-field {
294
+ color: #FF7F83;
295
+ font-weight: bold;
296
+ }
297
+
298
+ &:first-child {
299
+ color: palette(gray, dark);
300
+ font-weight: 500;
301
+ }
302
+ }
303
+ }
304
+
305
+ @include media( max-width, md ) {
306
+ padding: #{$sui-gutter-md / 2} $sui-gutter-md;
307
+ }
308
+ }
309
+
310
+ .sui-box-footer {
311
+ padding: #{$sui-gutter / 2} $sui-gutter $sui-gutter;
312
+
313
+ @include media( max-width, md ) {
314
+ padding: #{$sui-gutter-md / 2} $sui-gutter-md $sui-gutter-md;
315
+ }
316
+ }
317
+ }
318
+ }
319
+ }
320
+
321
+ // INCLUDED ON PULL REQUEST #
322
+ // https://github.com/wpmudev/shared-ui/pull/
323
+ @include body-class(true) {
324
+
325
+ .sui-button,
326
+ a.sui-button,
327
+ button.sui-button {
328
+ display: inline-flex;
329
+ align-items: center;
330
+ justify-content: center;
331
+
332
+ .sui-loading-text {
333
+ flex: 1;
334
+ }
335
+
336
+ i {
337
+ width: 16px;
338
+ height: 16px;
339
+ display: inline-flex;
340
+ flex-direction: column;
341
+ align-items: center;
342
+ justify-content: center;
343
+ font-size: 16px;
344
+
345
+ &:before {
346
+ display: block;
347
+ }
348
+ }
349
+ }
350
+ }
351
+
352
+ // INCLUDED ON PULL REQUEST #
353
+ // https://github.com/wpmudev/shared-ui/pull/
354
+ @include body-class(true) {
355
+
356
+ .sui-table {
357
+
358
+ &.fui-integrations-active {
359
+ border-left: 2px solid $blue;
360
+
361
+ th, td {
362
+
363
+ &:first-child {
364
+ padding-left: calc(#{$sui-gutter} - 2px);
365
+
366
+ @include media( max-width, md ) {
367
+ padding-left: 0;
368
+ }
369
+ }
370
+
371
+ &:last-child {
372
+ padding-right: calc(#{$sui-gutter} - 2px);
373
+
374
+ @include media( max-width, md ) {
375
+ padding-right: 0;
376
+ }
377
+ }
378
+ }
379
+ }
380
+ }
381
+ }
_src/scss/overwrite-sui/_sidenav.scss ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .sui-row-with-sidenav {
4
+
5
+ .sui-sidenav {
6
+
7
+ .sui-vertical-tabs {
8
+
9
+ .sui-vertical-tab {
10
+
11
+ &:not(.done):not(.current) i {
12
+ display: none;
13
+ }
14
+
15
+ &.done i:before {
16
+ color: $green;
17
+ }
18
+ }
19
+ }
20
+ }
21
+ }
22
+ }
_src/scss/overwrite-sui/_tables.scss ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .sui-table {
4
+
5
+ th .sui-checkbox {
6
+
7
+ .sui-description {
8
+ color: $table--th-color;
9
+ font-size: 13px;
10
+ font-weight: 500;
11
+ }
12
+ }
13
+
14
+ td {
15
+ line-height: 22px;
16
+
17
+ strong {
18
+ color: palette( gray, dark );
19
+ font-weight: 500;
20
+ }
21
+
22
+ @include media( max-width, md ) {
23
+ padding-top: calc(#{$sui-gutter-md}/2 - 1px);
24
+ padding-bottom: calc(#{$sui-gutter-md}/2 - 1px);
25
+ }
26
+ }
27
+
28
+ td.sui-table-image {
29
+ width: 25px;
30
+
31
+ .sui-image,
32
+ .sui-button-icon {
33
+ display: block;
34
+ }
35
+
36
+ &:first-child,
37
+ &:last-child {
38
+ width: calc( 25px + #{$sui-gutter} );
39
+
40
+ @include media( max-width, md ) {
41
+ width: calc( 25px + #{$sui-gutter-md} );
42
+ }
43
+ }
44
+ }
45
+
46
+ td.sui-table-action {
47
+ width: 35px;
48
+
49
+ .sui-image,
50
+ .sui-button-icon {
51
+ display: block;
52
+ }
53
+
54
+ &:first-child,
55
+ &:last-child {
56
+ width: calc( 35px + #{$sui-gutter} );
57
+
58
+ @include media( max-width, md ) {
59
+ width: calc( 35px + #{$sui-gutter-md} );
60
+ }
61
+ }
62
+ }
63
+
64
+ .sui-accordion-item-title {
65
+ font-size: 13px;
66
+
67
+ .sui-checkbox {
68
+ display: inline-flex;
69
+
70
+ span {
71
+ margin-top: 0;
72
+ }
73
+
74
+ + a {
75
+ margin-left: 6px;
76
+ }
77
+ }
78
+ }
79
+
80
+ &.fui-integrations-table {
81
+
82
+ td.sui-table-action {
83
+
84
+ &:last-child {
85
+ width: 55px;
86
+ padding-right: 20px;
87
+
88
+ @include media( max-width, md ) {
89
+ width: 55px;
90
+ padding-right: 20px;
91
+ }
92
+ }
93
+ }
94
+ }
95
+ }
96
+ }
_src/scss/overwrite-sui/_toggles.scss ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ @include body-class(true) {
2
+
3
+ .sui-toggle {
4
+ margin-right: 8px;
5
+ }
6
+
7
+ .sui-toggle-label {
8
+ margin-left: 0;
9
+ line-height: 16px;
10
+ }
11
+ }
_src/scss/overwrite-sui/_variables.scss ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ // Typography
2
+ $h2-line-height: 30px;
3
+
4
+ // Summary
5
+ $summary-image-default-url: '../../assets/img/forminator-summary@2x.png';
6
+ $summary-image-default-position: 3% 100%;
7
+ $summary-image-default-width: 172px;
8
+ $summary-image-default-height: 192px;
addons/class-addon-autoload.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once dirname( __FILE__ ) . '/class-addon-default-holder.php';
4
+
5
+ /**
6
+ * Class Forminator_Addon_Autoload
7
+ * Handling Autoloader
8
+ *
9
+ * @since 1.1
10
+ */
11
+ class Forminator_Addon_Autoload {
12
+
13
+ /**
14
+ * Pro addons list
15
+ *
16
+ * @since 1.1
17
+ * @var array
18
+ */
19
+ protected $pro_addons = array();
20
+
21
+ /**
22
+ * Forminator_Addon_Autoload constructor.
23
+ * Intialize with custom pro addons, or pass empty array otherwise
24
+ *
25
+ * @since 1.1
26
+ *
27
+ * @param array $pro_addons
28
+ */
29
+ public function __construct( $pro_addons = array() ) {
30
+ $this->pro_addons = $pro_addons;
31
+ }
32
+
33
+ /**
34
+ * Load Addons which lies in `addons/pro` directory
35
+ * And load placeholder for pro addons that are defined but not available in the pro directory
36
+ *
37
+ * @since 1.1
38
+ */
39
+ public function load() {
40
+ $pro_addons = $this->pro_addons;
41
+
42
+ $pro_addons_dir = dirname( __FILE__ ) . '/pro/';
43
+
44
+ /**
45
+ * Filter path of Pro addons directory located
46
+ *
47
+ * @since 1.1
48
+ *
49
+ * @param string $pro_addons_dir current dir path of pro addons
50
+ */
51
+ $pro_addons_dir = apply_filters( 'forminator_addon_pro_addons_dir', $pro_addons_dir );
52
+
53
+ // All of Forminator Official Addons must be registered here with fallback array
54
+ // fallback array will be used to display pro addons on the list of addons, without files on `/pro` being available
55
+ if ( empty( $pro_addons ) ) {
56
+ $pro_addons = forminator_get_pro_addon_list();
57
+ }
58
+ // Load Available Pro Addon
59
+ $directory = new DirectoryIterator( $pro_addons_dir );
60
+ foreach ( $directory as $d ) {
61
+ if ( $d->isDot() || $d->isFile() ) {
62
+ continue;
63
+ }
64
+ // take directory name as addon name
65
+ $addon_name = $d->getBasename();
66
+
67
+ // new Addon !
68
+ // valid addon is when addon have `addon_name.php` inside its addon directory
69
+ $addon_initiator = $d->getPathname() . DIRECTORY_SEPARATOR . $addon_name . '.php';
70
+ if ( ! file_exists( $addon_initiator ) ) {
71
+ continue;
72
+ }
73
+ /** @noinspection PhpIncludeInspection */
74
+ include_once $addon_initiator;
75
+ }
76
+
77
+ // Load unavailable Pro Addons
78
+ $pro_slugs = Forminator_Addon_Loader::get_instance()->get_addons()->get_slugs();
79
+ $unavailable_pros = array_diff( array_keys( $pro_addons ), $pro_slugs );
80
+
81
+ foreach ( $unavailable_pros as $unavailable_pro ) {
82
+ if ( array_key_exists( $unavailable_pro, $pro_addons ) ) {
83
+ $addon = new Forminator_Addon_Default_Holder();
84
+ $pro_addons[ $unavailable_pro ]['_slug'] = $unavailable_pro;
85
+
86
+ $addon->from_array( $pro_addons[ $unavailable_pro ] );
87
+ Forminator_Addon_Loader::get_instance()->register( $addon );
88
+ }
89
+ }
90
+ }
91
+ }
addons/class-addon-default-holder.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ /**
5
+ * Class Forminator_Addon_Default_Holder
6
+ * Placeholder for nonexistent PRO Addon
7
+ *
8
+ * @since 1.1
9
+ */
10
+ class Forminator_Addon_Default_Holder extends Forminator_Addon_Abstract {
11
+
12
+ private static $_instance = null;
13
+
14
+ protected $_slug = '';
15
+ protected $_version = '1.0';
16
+ protected $_min_forminator_version = PHP_INT_MAX; // make it un-activable
17
+ protected $_short_title = '';
18
+ protected $_title = '';
19
+ protected $_url = '';
20
+ protected $_image = '';
21
+ protected $_image_x2 = '';
22
+ protected $_icon = '';
23
+ protected $_icon_x2 = '';
24
+ protected $_full_path = '';
25
+
26
+ /**
27
+ * Get Instance
28
+ *
29
+ * @since 1.1
30
+ * @return self|null
31
+ */
32
+ public static function get_instance() {
33
+ if ( is_null( self::$_instance ) ) {
34
+ self::$_instance = new self();// @codeCoverageIgnore
35
+ }
36
+
37
+ return self::$_instance;
38
+ }
39
+
40
+
41
+ /**
42
+ * Dynamically set fields form array
43
+ *
44
+ * @since 1.1
45
+ *
46
+ * @param $properties
47
+ *
48
+ * @return $this
49
+ */
50
+ public function from_array( $properties ) {
51
+ foreach ( $properties as $field => $value ) {
52
+ if ( property_exists( $this, $field ) ) {
53
+ $this->$field = $value;
54
+ }
55
+ }
56
+
57
+ return $this;
58
+ }
59
+
60
+ /**
61
+ * Mark non existent addon as not connected always
62
+ *
63
+ * @since 1.1
64
+ * @return bool
65
+ */
66
+ public function is_connected() {
67
+ return false;
68
+ }
69
+
70
+ /**
71
+ * Mark non existent addon as form not connected always
72
+ *
73
+ * @since 1.1
74
+ *
75
+ * @param $form_id
76
+ *
77
+ * @return bool
78
+ */
79
+ public function is_form_connected( $form_id ) {
80
+ return false;
81
+ }
82
+
83
+ /**
84
+ * Make this not activable
85
+ *
86
+ * @since 1.1
87
+ * @return bool
88
+ */
89
+ public function check_is_activable() {
90
+ return false;
91
+ }
92
+ }
addons/pro/activecampaign/activecampaign.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Addon Name: Activecampaign
5
+ * Version: 1.0
6
+ * Plugin URI: https://premium.wpmudev.org/
7
+ * Description: Integrate Forminator Custom Forms with Activecampaign to get notified in real time.
8
+ * Author: WPMU DEV
9
+ * Author URI: http://premium.wpmudev.org
10
+ */
11
+
12
+ define( 'FORMINATOR_ADDON_ACTIVECAMPAIGN_VERSION', '1.0' );
13
+
14
+ function forminator_addon_activecampaign_url() {
15
+ return trailingslashit( forminator_plugin_url() . 'addons/pro/activecampaign' );
16
+ }
17
+
18
+ function forminator_addon_activecampaign_dir() {
19
+ return trailingslashit( dirname( __FILE__ ) );
20
+ }
21
+
22
+ function forminator_addon_activecampaign_assets_url() {
23
+ return trailingslashit( forminator_addon_activecampaign_url() . 'assets' );
24
+ }
25
+
26
+ require_once dirname( __FILE__ ) . '/forminator-addon-activecampaign.php';
27
+ require_once dirname( __FILE__ ) . '/forminator-addon-activecampaign-form-settings.php';
28
+ require_once dirname( __FILE__ ) . '/forminator-addon-activecampaign-form-hooks.php';
29
+ //Direct Load
30
+ Forminator_Addon_Loader::get_instance()->register( 'Forminator_Addon_Activecampaign' );
addons/pro/activecampaign/assets/icons/activecampaign.png ADDED
Binary file
addons/pro/activecampaign/assets/icons/activecampaign@2x.png ADDED
Binary file
addons/pro/activecampaign/assets/img/activecampaign.png ADDED
Binary file
addons/pro/activecampaign/assets/img/activecampaign@2x.png ADDED
Binary file
addons/pro/activecampaign/forminator-addon-activecampaign-exception.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Activecampaign_Exception
5
+ * Not Required but encouraged
6
+ *
7
+ * @since 1.0 Activecampaign Addon
8
+ */
9
+ class Forminator_Addon_Activecampaign_Exception extends Exception {
10
+
11
+ }
addons/pro/activecampaign/forminator-addon-activecampaign-form-hooks.php ADDED
@@ -0,0 +1,746 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Activecampaign_Form_Hooks
5
+ *
6
+ * @since 1.0 Activecampaign Addon
7
+ *
8
+ */
9
+ class Forminator_Addon_Activecampaign_Form_Hooks extends Forminator_Addon_Form_Hooks_Abstract {
10
+
11
+ /**
12
+ * Addon instance are auto available form abstract
13
+ * Its added here for development purpose,
14
+ * Auto-complete will resolve addon directly to `Activecampaign` instance instead of the abstract
15
+ * And its public properties can be exposed
16
+ *
17
+ * @since 1.0 Activecampaign Addon
18
+ * @var Forminator_Addon_Activecampaign
19
+ */
20
+ protected $addon;
21
+
22
+ /**
23
+ * Form Settings Instance
24
+ *
25
+ * @since 1.0 Activecampaign Addon
26
+ * @var Forminator_Addon_Activecampaign_Form_Settings | null
27
+ */
28
+ protected $form_settings_instance;
29
+
30
+ /**
31
+ * Forminator_Addon_Activecampaign_Form_Hooks constructor.
32
+ *
33
+ * @since 1.0 Activecampaign Addon
34
+ *
35
+ * @param Forminator_Addon_Abstract $addon
36
+ * @param $form_id
37
+ *
38
+ * @throws Forminator_Addon_Exception
39
+ */
40
+ public function __construct( Forminator_Addon_Abstract $addon, $form_id ) {
41
+ parent::__construct( $addon, $form_id );
42
+ $this->_submit_form_error_message = __( 'ActiveCampaign failed to process submitted data. Please check your form and try again', Forminator::DOMAIN );
43
+ }
44
+
45
+ /**
46
+ * Save status of request sent and received for each connected Active Campaign Connection
47
+ *
48
+ * @since 1.0 Activecampaign Addon
49
+ *
50
+ * @param array $submitted_data
51
+ *
52
+ * @return array
53
+ */
54
+ public function add_entry_fields( $submitted_data ) {
55
+
56
+ $form_id = $this->form_id;
57
+ $form_settings_instance = $this->form_settings_instance;
58
+
59
+ /**
60
+ * Filter ActiveCampaign submitted form data to be processed
61
+ *
62
+ * @since 1.2
63
+ *
64
+ * @param array $submitted_data
65
+ * @param int $form_id current Form ID
66
+ * @param Forminator_Addon_Activecampaign_Form_Settings $form_settings_instance ActiveCampaign Addon Form Settings instance
67
+ */
68
+ $submitted_data = apply_filters(
69
+ 'forminator_addon_activecampaign_form_submitted_data',
70
+ $submitted_data,
71
+ $form_id,
72
+ $form_settings_instance
73
+ );
74
+
75
+ forminator_addon_maybe_log( __METHOD__, $submitted_data );
76
+
77
+ $addon_setting_values = $this->form_settings_instance->get_form_settings_values();
78
+ $form_settings = $this->form_settings_instance->get_form_settings();
79
+
80
+ $data = array();
81
+
82
+ /**
83
+ * Fires before sending contact sync to Active Campaign
84
+ *
85
+ * @since 1.2
86
+ *
87
+ * @param int $form_id current Form ID
88
+ * @param array $submitted_data
89
+ * @param Forminator_Addon_Activecampaign_Form_Settings $form_settings_instance ActiveCampaign Addon Form Settings instance
90
+ */
91
+ do_action( 'forminator_addon_activecampaign_before_contact_sync', $form_id, $submitted_data, $form_settings_instance );
92
+
93
+ foreach ( $addon_setting_values as $key => $addon_setting_value ) {
94
+ // save it on entry field, with name `status-$MULTI_ID`, and value is the return result on sending data to active campaign
95
+ if ( $form_settings_instance->is_multi_form_settings_complete( $key ) ) {
96
+ // exec only on completed connection
97
+ $data[] = array(
98
+ 'name' => 'status-' . $key,
99
+ 'value' => $this->get_status_on_contact_sync( $key, $submitted_data, $addon_setting_value, $form_settings ),
100
+ );
101
+ }
102
+
103
+ }
104
+
105
+ $entry_fields = $data;
106
+ /**
107
+ * Filter ActiveCampaign entry fields to be saved to entry model
108
+ *
109
+ * @since 1.2
110
+ *
111
+ * @param array $entry_fields
112
+ * @param int $form_id current Form ID
113
+ * @param array $submitted_data
114
+ * @param Forminator_Addon_Activecampaign_Form_Settings $form_settings_instance ActiveCampaign Addon Form Settings instance
115
+ */
116
+ $data = apply_filters(
117
+ 'forminator_addon_activecampaign_entry_fields',
118
+ $entry_fields,
119
+ $form_id,
120
+ $submitted_data,
121
+ $form_settings_instance
122
+ );
123
+
124
+ return $data;
125
+
126
+ }
127
+
128
+ /**
129
+ * Get status on contact sync to ActiveCampaign
130
+ *
131
+ * @since 1.0 Activecampaign Addon
132
+ *
133
+ * @param $connection_id
134
+ * @param $submitted_data
135
+ * @param $connection_settings
136
+ * @param $form_settings
137
+ *
138
+ * @return array `is_sent` true means its success send data to ActiveCampaign, false otherwise
139
+ */
140
+ private function get_status_on_contact_sync( $connection_id, $submitted_data, $connection_settings, $form_settings ) {
141
+ // initialize as null
142
+ $ac_api = null;
143
+
144
+ $form_id = $this->form_id;
145
+ $form_settings_instance = $this->form_settings_instance;
146
+
147
+ //check required fields
148
+ try {
149
+ $ac_api = $this->addon->get_api();
150
+ $args = array();
151
+
152
+ if ( ! isset( $connection_settings['list_id'] ) ) {
153
+ throw new Forminator_Addon_Activecampaign_Exception( __( 'List ID not properly setup.', Forminator::DOMAIN ) );
154
+ }
155
+
156
+ $args[ 'p[' . $connection_settings['list_id'] . ']' ] = $connection_settings['list_id'];
157
+ // subscribed
158
+ $args[ 'status[' . $connection_settings['list_id'] . ']' ] = '1';
159
+
160
+ $fields_map = $connection_settings['fields_map'];
161
+
162
+ $email_element_id = $connection_settings['fields_map']['email'];
163
+ if ( ! isset( $submitted_data[ $email_element_id ] ) || empty( $submitted_data[ $email_element_id ] ) ) {
164
+ throw new Forminator_Addon_Activecampaign_Exception( __( 'Email on element %1$s not found or not filled on submitted data.', Forminator::DOMAIN ) );
165
+ }
166
+ $email = $submitted_data[ $email_element_id ];
167
+ $email = strtolower( trim( $email ) );
168
+ $args['email'] = $email;
169
+
170
+ // processed
171
+ unset( $fields_map['email'] );
172
+
173
+ $common_fields = array(
174
+ 'first_name',
175
+ 'last_name',
176
+ 'phone',
177
+ 'orgname',
178
+ );
179
+
180
+ foreach ( $common_fields as $common_field ) {
181
+ // not setup
182
+ if ( ! isset( $fields_map[ $common_field ] ) ) {
183
+ continue;
184
+ }
185
+
186
+ if ( ! empty( $fields_map[ $common_field ] ) ) {
187
+ $element_id = $fields_map[ $common_field ];
188
+ if ( isset( $submitted_data[ $element_id ] ) && ! empty( $submitted_data[ $element_id ] ) ) {
189
+ $element_value = $submitted_data[ $element_id ];
190
+ if ( is_array( $element_value ) ) {
191
+ $element_value = implode( ',', $element_value );
192
+ }
193
+ $args[ $common_field ] = $element_value;
194
+ }
195
+ }
196
+ // processed
197
+ unset( $fields_map[ $common_field ] );
198
+ }
199
+
200
+ // process rest extra fields if available
201
+ foreach ( $fields_map as $field_id => $element_id ) {
202
+ if ( ! empty( $element_id ) ) {
203
+ if ( isset( $submitted_data[ $element_id ] ) && ! empty( $submitted_data[ $element_id ] ) ) {
204
+ $element_value = $submitted_data[ $element_id ];
205
+ if ( is_array( $element_value ) ) {
206
+ $element_value = implode( ',', $element_value );
207
+ }
208
+ $args[ 'field[' . $field_id . ',0]' ] = $element_value;
209
+ }
210
+ }
211
+ }
212
+
213
+ // process tags
214
+ if ( isset( $connection_settings['tags'] ) && is_array( $connection_settings['tags'] ) ) {
215
+ $tags = array();
216
+ foreach ( $connection_settings['tags'] as $tag ) {
217
+ if ( stripos( $tag, '{' ) === 0
218
+ && stripos( $tag, '}' ) === ( strlen( $tag ) - 1 )
219
+ ) {
220
+ // translate to value
221
+ $element_id = str_ireplace( '{', '', $tag );
222
+ $element_id = str_ireplace( '}', '', $element_id );
223
+ if ( isset( $submitted_data[ $element_id ] ) && ! empty( $submitted_data[ $element_id ] ) ) {
224
+ $element_value = $submitted_data[ $element_id ];
225
+ if ( is_array( $element_value ) ) {
226
+ $element_value = implode( ',', $element_value );
227
+ }
228
+ $tags[] = $element_value;
229
+ }
230
+
231
+ } else {
232
+ $tags[] = $tag;
233
+ }
234
+ }
235
+ if ( ! empty( $tags ) ) {
236
+ $tags = implode( ',', $tags );
237
+ $args['tags'] = $tags;
238
+ }
239
+ }
240
+
241
+ if ( isset( $connection_settings['double_opt_form_id'] ) && ! empty( $connection_settings['double_opt_form_id'] ) ) {
242
+ $args['form'] = $connection_settings['double_opt_form_id'];
243
+ }
244
+
245
+ if ( isset( $connection_settings['instantresponders'] ) ) {
246
+ $instant_responders = filter_var( $connection_settings['instantresponders'], FILTER_VALIDATE_BOOLEAN );
247
+ if ( $instant_responders ) {
248
+ $args[ 'instantresponders[' . $connection_settings['list_id'] . ']' ] = '1';
249
+ }
250
+ }
251
+
252
+ if ( isset( $connection_settings['lastmessage'] ) ) {
253
+ $last_message = filter_var( $connection_settings['lastmessage'], FILTER_VALIDATE_BOOLEAN );
254
+ if ( $last_message ) {
255
+ $args[ 'lastmessage[' . $connection_settings['list_id'] . ']' ] = '1';
256
+ }
257
+ }
258
+
259
+ /**
260
+ * Filter arguments to passed on to Contact Sync Active Campaign API
261
+ *
262
+ * @since 1.2
263
+ *
264
+ * @param array $args
265
+ * @param int $form_id Current Form id
266
+ * @param string $connection_id ID of current connection
267
+ * @param array $submitted_data
268
+ * @param array $connection_settings current connection setting, contains options of like `name`, `list_id` etc
269
+ * @param array $form_settings Displayed Form settings
270
+ * @param Forminator_Addon_Activecampaign_Form_Settings $form_settings_instance ActiveCampaign Addon Form Settings instance
271
+ */
272
+ $args = apply_filters(
273
+ 'forminator_addon_activecampaign_contact_sync_args',
274
+ $args,
275
+ $form_id,
276
+ $connection_id,
277
+ $submitted_data,
278
+ $connection_settings,
279
+ $form_settings,
280
+ $form_settings_instance
281
+ );
282
+
283
+ $ac_api->contact_sync( $args );
284
+
285
+ forminator_addon_maybe_log( __METHOD__, 'Success Send Data' );
286
+
287
+ return array(
288
+ 'is_sent' => true,
289
+ 'connection_name' => $connection_settings['name'],
290
+ 'description' => __( 'Successfully send data to ActiveCampaign', Forminator::DOMAIN ),
291
+ 'data_sent' => $ac_api->get_last_data_sent(),
292
+ 'data_received' => $ac_api->get_last_data_received(),
293
+ 'url_request' => $ac_api->get_last_url_request(),
294
+ );
295
+
296
+ } catch ( Forminator_Addon_Activecampaign_Exception $e ) {
297
+ forminator_addon_maybe_log( __METHOD__, 'Failed to Send to ActiveCampaign' );
298
+
299
+ return array(
300
+ 'is_sent' => false,
301
+ 'description' => $e->getMessage(),
302
+ 'connection_name' => $connection_settings['name'],
303
+ 'data_sent' => ( ( $ac_api instanceof Forminator_Addon_Activecampaign_Wp_Api ) ? $ac_api->get_last_data_sent() : array() ),
304
+ 'data_received' => ( ( $ac_api instanceof Forminator_Addon_Activecampaign_Wp_Api ) ? $ac_api->get_last_data_received() : array() ),
305
+ 'url_request' => ( ( $ac_api instanceof Forminator_Addon_Activecampaign_Wp_Api ) ? $ac_api->get_last_url_request() : '' ),
306
+ );
307
+ }
308
+ }
309
+
310
+ /**
311
+ * It wil add new row on entry table of submission page, with couple of subentries
312
+ * subentries included are defined in @see Forminator_Addon_Activecampaign_Form_Hooks::get_additional_entry_item()
313
+ *
314
+ * @since 1.0 Activecampaign Addon
315
+ *
316
+ * @param Forminator_Form_Entry_Model $entry_model
317
+ * @param $addon_meta_data
318
+ *
319
+ * @return array
320
+ */
321
+ public function on_render_entry( Forminator_Form_Entry_Model $entry_model, $addon_meta_data ) {
322
+
323
+ $form_id = $this->form_id;
324
+ $form_settings_instance = $this->form_settings_instance;
325
+
326
+ /**
327
+ *
328
+ * Filter active campaign metadata that previously saved on db to be processed
329
+ *
330
+ * @since 1.2
331
+ *
332
+ * @param array $addon_meta_data
333
+ * @param int $form_id current Form ID
334
+ * @param Forminator_Addon_Activecampaign_Form_Settings $form_settings_instance ActiveCampaign Addon Form Settings instance
335
+ */
336
+ $addon_meta_data = apply_filters(
337
+ 'forminator_addon_activecampaign_metadata',
338
+ $addon_meta_data,
339
+ $form_id,
340
+ $form_settings_instance
341
+ );
342
+
343
+
344
+ $addon_meta_datas = $addon_meta_data;
345
+ if ( ! isset( $addon_meta_data[0] ) || ! is_array( $addon_meta_data[0] ) ) {
346
+ return array();
347
+ }
348
+
349
+ return $this->on_render_entry_multi_connection( $addon_meta_datas );
350
+
351
+ }
352
+
353
+ /**
354
+ * Loop through addon meta data on multiple active campaign(s)
355
+ *
356
+ * @since 1.0 Activecampaign Addon
357
+ *
358
+ * @param $addon_meta_datas
359
+ *
360
+ * @return array
361
+ */
362
+ private function on_render_entry_multi_connection( $addon_meta_datas ) {
363
+ $additional_entry_item = array();
364
+ foreach ( $addon_meta_datas as $addon_meta_data ) {
365
+ $additional_entry_item[] = $this->get_additional_entry_item( $addon_meta_data );
366
+ }
367
+
368
+ return $additional_entry_item;
369
+
370
+ }
371
+
372
+ /**
373
+ * Format additional entry item as label and value arrays
374
+ *
375
+ * - Integration Name : its defined by user when they adding Activecampaign integration on their form
376
+ * - Sent To Activecampaign : will be Yes/No value, that indicates whether sending data to Activecampaign was successful
377
+ * - Info : Text that are generated by addon when building and sending data to Activecampaign @see Forminator_Addon_Activecampaign_Form_Hooks::add_entry_fields()
378
+ * - Below subentries will be added if full log enabled, @see Forminator_Addon_Activecampaign::is_show_full_log() @see FORMINATOR_ADDON_ACTIVECAMPAIGN_SHOW_FULL_LOG
379
+ * - API URL : URL that wes requested when sending data to Activecampaign
380
+ * - Data sent to Activecampaign : encoded body request that was sent
381
+ * - Data received from Activecampaign : json encoded body response that was received
382
+ *
383
+ * @param $addon_meta_data
384
+ *
385
+ * @since 1.0 Activecampaign Addon
386
+ * @return array
387
+ */
388
+ private function get_additional_entry_item( $addon_meta_data ) {
389
+
390
+ if ( ! isset( $addon_meta_data['value'] ) || ! is_array( $addon_meta_data['value'] ) ) {
391
+ return array();
392
+ }
393
+ $status = $addon_meta_data['value'];
394
+ $additional_entry_item = array(
395
+ 'label' => __( 'ActiveCampaign Integration', Forminator::DOMAIN ),
396
+ 'value' => '',
397
+ );
398
+
399
+
400
+ $sub_entries = array();
401
+ if ( isset( $status['connection_name'] ) ) {
402
+ $sub_entries[] = array(
403
+ 'label' => __( 'Integration Name', Forminator::DOMAIN ),
404
+ 'value' => $status['connection_name'],
405
+ );
406
+ }
407
+
408
+ if ( isset( $status['is_sent'] ) ) {
409
+ $is_sent = true === $status['is_sent'] ? __( 'Yes', Forminator::DOMAIN ) : __( 'No', Forminator::DOMAIN );
410
+ $sub_entries[] = array(
411
+ 'label' => __( 'Sent To ActiveCampaign', Forminator::DOMAIN ),
412
+ 'value' => $is_sent,
413
+ );
414
+ }
415
+
416
+ if ( isset( $status['description'] ) ) {
417
+ $sub_entries[] = array(
418
+ 'label' => __( 'Info', Forminator::DOMAIN ),
419
+ 'value' => $status['description'],
420
+ );
421
+ }
422
+
423
+ if ( Forminator_Addon_Activecampaign::is_show_full_log() ) {
424
+ // too long to be added on entry data enable this with `define('FORMINATOR_ADDON_ACTIVECAMPAIGN_SHOW_FULL_LOG', true)`
425
+ if ( isset( $status['url_request'] ) ) {
426
+ $sub_entries[] = array(
427
+ 'label' => __( 'API URL', Forminator::DOMAIN ),
428
+ 'value' => $status['url_request'],
429
+ );
430
+ }
431
+
432
+ if ( isset( $status['data_sent'] ) ) {
433
+ $sub_entries[] = array(
434
+ 'label' => __( 'Data sent to ActiveCampaign', Forminator::DOMAIN ),
435
+ 'value' => '<pre class="sui-code-snippet">' . wp_json_encode( $status['data_sent'], JSON_PRETTY_PRINT ) . '</pre>',
436
+ );
437
+ }
438
+
439
+ if ( isset( $status['data_received'] ) ) {
440
+ $sub_entries[] = array(
441
+ 'label' => __( 'Data received from ActiveCampaign', Forminator::DOMAIN ),
442
+ 'value' => '<pre class="sui-code-snippet">' . wp_json_encode( $status['data_received'], JSON_PRETTY_PRINT ) . '</pre>',
443
+ );
444
+ }
445
+ }
446
+
447
+
448
+ $additional_entry_item['sub_entries'] = $sub_entries;
449
+
450
+ // return single array
451
+ return $additional_entry_item;
452
+ }
453
+
454
+ /**
455
+ * Activecampaign will add a column on the title/header row
456
+ * its called `Active Campaign Info` which can be translated on forminator lang
457
+ *
458
+ * @since 1.0 Activecampaign Addon
459
+ * @return array
460
+ */
461
+ public function on_export_render_title_row() {
462
+
463
+ $export_headers = array(
464
+ 'info' => __( 'ActiveCampaign Info', Forminator::DOMAIN ),
465
+ );
466
+
467
+ $form_id = $this->form_id;
468
+ $form_settings_instance = $this->form_settings_instance;
469
+
470
+ /**
471
+ * Filter Activecampaign headers on export file
472
+ *
473
+ * @since 1.2
474
+ *
475
+ * @param array $export_headers headers to be displayed on export file
476
+ * @param int $form_id current Form ID
477
+ * @param Forminator_Addon_Activecampaign_Form_Settings $form_settings_instance Activecampaign Form Settings instance
478
+ */
479
+ $export_headers = apply_filters(
480
+ 'forminator_addon_activecampaign_export_headers',
481
+ $export_headers,
482
+ $form_id,
483
+ $form_settings_instance
484
+ );
485
+
486
+ return $export_headers;
487
+ }
488
+
489
+ /**
490
+ * Activecampaign will add a column that give user information whether sending data to Activecampaign successfully or not
491
+ * It will only add one column even its multiple connection, every connection will be separated by comma
492
+ *
493
+ * @since 1.0 Activecampaign Addon
494
+ *
495
+ * @param Forminator_Form_Entry_Model $entry_model
496
+ * @param $addon_meta_data
497
+ *
498
+ * @return array
499
+ */
500
+ public function on_export_render_entry( Forminator_Form_Entry_Model $entry_model, $addon_meta_data ) {
501
+
502
+ $form_id = $this->form_id;
503
+ $form_settings_instance = $this->form_settings_instance;
504
+
505
+ /**
506
+ *
507
+ * Filter Activecampaign metadata that previously saved on db to be processed
508
+ *
509
+ * @since 1.2
510
+ *
511
+ * @param array $addon_meta_data
512
+ * @param int $form_id current Form ID
513
+ * @param Forminator_Addon_Activecampaign_Form_Settings $form_settings_instance Activecampaign Form Settings instance
514
+ */
515
+ $addon_meta_data = apply_filters(
516
+ 'forminator_addon_activecampaign_metadata',
517
+ $addon_meta_data,
518
+ $form_id,
519
+ $form_settings_instance
520
+ );
521
+
522
+ $export_columns = array(
523
+ 'info' => $this->get_from_addon_meta_data( $addon_meta_data, 'description', '' ),
524
+ );
525
+
526
+ /**
527
+ * Filter Activecampaign columns to be displayed on export submissions
528
+ *
529
+ * @since 1.2
530
+ *
531
+ * @param array $export_columns column to be exported
532
+ * @param int $form_id current Form ID
533
+ * @param Forminator_Form_Entry_Model $entry_model Form Entry Model
534
+ * @param array $addon_meta_data meta data saved by addon on entry fields
535
+ * @param Forminator_Addon_Activecampaign_Form_Settings $form_settings_instance Activecampaign Form Settings instance
536
+ */
537
+ $export_columns = apply_filters(
538
+ 'forminator_addon_activecampaign_export_columns',
539
+ $export_columns,
540
+ $form_id,
541
+ $entry_model,
542
+ $addon_meta_data,
543
+ $form_settings_instance
544
+ );
545
+
546
+ return $export_columns;
547
+ }
548
+
549
+ /**
550
+ * Get Addon meta data, will be recursive if meta data is multiple because of multiple connection added
551
+ *
552
+ * @since 1.0 Activecampaign Addon
553
+ *
554
+ * @param $addon_meta_data
555
+ * @param $key
556
+ * @param string $default
557
+ *
558
+ * @return string
559
+ */
560
+ private function get_from_addon_meta_data( $addon_meta_data, $key, $default = '' ) {
561
+ $addon_meta_datas = $addon_meta_data;
562
+ if ( ! isset( $addon_meta_data[0] ) || ! is_array( $addon_meta_data[0] ) ) {
563
+ return $default;
564
+ }
565
+
566
+ $addon_meta_data = $addon_meta_data[0];
567
+
568
+ // make sure its `status`, because we only add this
569
+ if ( 'status' !== $addon_meta_data['name'] ) {
570
+ if ( stripos( $addon_meta_data['name'], 'status-' ) === 0 ) {
571
+ $meta_data = array();
572
+ foreach ( $addon_meta_datas as $addon_meta_data ) {
573
+ // make it like single value so it will be processed like single meta data
574
+ $addon_meta_data['name'] = 'status';
575
+
576
+ // add it on an array for next recursive process
577
+ $meta_data[] = $this->get_from_addon_meta_data( array( $addon_meta_data ), $key, $default );
578
+ }
579
+
580
+ return implode( ', ', $meta_data );
581
+ }
582
+
583
+ return $default;
584
+
585
+ }
586
+
587
+ if ( ! isset( $addon_meta_data['value'] ) || ! is_array( $addon_meta_data['value'] ) ) {
588
+ return $default;
589
+ }
590
+ $status = $addon_meta_data['value'];
591
+ if ( isset( $status[ $key ] ) ) {
592
+ $connection_name = '';
593
+ if ( 'connection_name' !== $key ) {
594
+ if ( isset( $status['connection_name'] ) ) {
595
+ $connection_name = '[' . $status['connection_name'] . '] ';
596
+ }
597
+ }
598
+
599
+ return $connection_name . $status[ $key ];
600
+ }
601
+
602
+ return $default;
603
+ }
604
+
605
+ /**
606
+ * It will delete contact on ActiveCampaign list
607
+ *
608
+ * @since 1.0 ActiveCampaign Addon
609
+ *
610
+ * @param Forminator_Form_Entry_Model $entry_model
611
+ * @param array $addon_meta_data
612
+ *
613
+ * @return bool
614
+ */
615
+ public function on_before_delete_entry( Forminator_Form_Entry_Model $entry_model, $addon_meta_data ) {
616
+ // attach hook first
617
+ $form_id = $this->form_id;
618
+ $form_settings_instance = $this->form_settings_instance;
619
+
620
+ /**
621
+ *
622
+ * Filter ActiveCampaign addon metadata that previously saved on db to be processed
623
+ *
624
+ * @since 1.1
625
+ *
626
+ * @param array $addon_meta_data
627
+ * @param int $form_id current Form ID
628
+ * @param Forminator_Form_Entry_Model $entry_model Forminator Entry Model
629
+ * @param Forminator_Addon_Activecampaign_Form_Settings $form_settings_instance Activecampaign Form Settings instance
630
+ */
631
+ $addon_meta_data = apply_filters(
632
+ 'forminator_addon_activecampaign_metadata',
633
+ $addon_meta_data,
634
+ $form_id,
635
+ $entry_model,
636
+ $form_settings_instance
637
+ );
638
+
639
+ /**
640
+ * Fires when Activecampaign connected form delete a submission
641
+ *
642
+ * @since 1.1
643
+ *
644
+ * @param int $form_id current Form ID
645
+ * @param Forminator_Form_Entry_Model $entry_model Forminator Entry Model
646
+ * @param array $addon_meta_data addon meta data
647
+ * @param Forminator_Addon_Activecampaign_Form_Settings $form_settings_instance Activecampaign Form Settings instance
648
+ */
649
+ do_action(
650
+ 'forminator_addon_activecampaign_on_before_delete_submission',
651
+ $form_id,
652
+ $entry_model,
653
+ $addon_meta_data,
654
+ $form_settings_instance
655
+ );
656
+
657
+ if ( ! Forminator_Addon_Activecampaign::is_enable_delete_contact() ) {
658
+ // its disabled, go for it!
659
+ return true;
660
+ }
661
+ $ac_api = null;
662
+ try {
663
+ $subscriber_ids_to_delete = array();
664
+
665
+ if ( is_array( $addon_meta_data ) ) {
666
+ foreach ( $addon_meta_data as $addon_meta_datum ) {
667
+
668
+ /** data received reference
669
+ *
670
+ * data_received: {
671
+ * subscriber_id: 1,
672
+ * sendlast_should: 0,
673
+ * sendlast_did: 0,
674
+ * result_code: 1,
675
+ * result_message: Contact added,
676
+ * result_output: json
677
+ * }
678
+ */
679
+
680
+ if ( isset( $addon_meta_datum['value'] ) && is_array( $addon_meta_datum['value'] ) ) {
681
+ $addon_meta_datum_value = $addon_meta_datum['value'];
682
+ if ( isset( $addon_meta_datum_value['is_sent'] ) && $addon_meta_datum_value['is_sent'] ) {
683
+ if ( isset( $addon_meta_datum_value['data_received'] ) && is_object( $addon_meta_datum_value['data_received'] ) ) {
684
+ $addon_meta_datum_received = $addon_meta_datum_value['data_received'];
685
+ if ( isset( $addon_meta_datum_received->subscriber_id ) && ! empty( $addon_meta_datum_received->subscriber_id ) ) {
686
+ $subscriber_ids_to_delete [] = $addon_meta_datum_received->subscriber_id;
687
+ }
688
+ }
689
+ }
690
+ }
691
+
692
+ }
693
+ }
694
+
695
+ /**
696
+ * Filter subscriber ids to delete
697
+ *
698
+ * @since 1.2
699
+ *
700
+ * @param array $subscriber_ids_to_delete
701
+ * @param int $form_id current Form ID
702
+ * @param array $addon_meta_data addon meta data
703
+ * @param Forminator_Addon_Activecampaign_Form_Settings $form_settings_instance Activecampaign Form Settings instance
704
+ *
705
+ */
706
+ $subscriber_ids_to_delete = apply_filters(
707
+ 'forminator_addon_activecampaign_subscriber_ids_to_delete',
708
+ $subscriber_ids_to_delete,
709
+ $form_id,
710
+ $addon_meta_data,
711
+ $form_settings_instance
712
+ );
713
+
714
+ if ( ! empty( $subscriber_ids_to_delete ) ) {
715
+ $ac_api = $this->addon->get_api();
716
+ foreach ( $subscriber_ids_to_delete as $subscriber_id_to_delete ) {
717
+ $ac_api->contact_delete(
718
+ array(
719
+ 'id' => $subscriber_id_to_delete,
720
+ )
721
+ );
722
+ }
723
+ }
724
+
725
+ return true;
726
+
727
+ } catch ( Forminator_Addon_Activecampaign_Exception $e ) {
728
+ // handle all internal addon exceptions with `Forminator_Addon_Activecampaign_Exception`
729
+
730
+ // use wp_error, for future usage it can be returned to page entries
731
+ $wp_error = new WP_Error( 'forminator_addon_activecampaign_delete_contact', $e->getMessage() );
732
+ // handle this in addon by self, since page entries cant handle error messages on delete yet
733
+ wp_die(
734
+ esc_html( $wp_error->get_error_message() ),
735
+ esc_html( $this->addon->get_title() ),
736
+ array(
737
+ 'response' => 200,
738
+ 'back_link' => true,
739
+ )
740
+ );
741
+
742
+ return false;
743
+ }
744
+
745
+ }
746
+ }
addons/pro/activecampaign/forminator-addon-activecampaign-form-settings-exception.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Activecampaign_Form_Settings_Exception
5
+ * Wrapper of Form Settings Activecampaign Exception
6
+ *
7
+ * @since 1.0 Activecampaign Addon
8
+ */
9
+ class Forminator_Addon_Activecampaign_Form_Settings_Exception extends Forminator_Addon_Activecampaign_Exception {
10
+
11
+ /**
12
+ * Holder of input exceptions
13
+ *
14
+ * @since 1.0 Activecampaign Addon
15
+ * @var array
16
+ */
17
+ protected $input_exceptions = array();
18
+
19
+ /**
20
+ * Forminator_Addon_Activecampaign_Form_Settings_Exception constructor.
21
+ *
22
+ * Useful if input_id is needed for later.
23
+ * If no input_id needed, use @see Forminator_Addon_Activecampaign_Exception
24
+ *
25
+ * @since 1.0 Activecampaign Addon
26
+ *
27
+ * @param string $message
28
+ * @param string $input_id
29
+ */
30
+ public function __construct( $message = '', $input_id = '' ) {
31
+ parent::__construct( $message, 0 );
32
+ if ( ! empty( $input_id ) ) {
33
+ $this->add_input_exception( $message, $input_id );
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Set exception message for an input
39
+ *
40
+ * @since 1.0 Activecampaign Addon
41
+ *
42
+ * @param $message
43
+ * @param $input_id
44
+ */
45
+ public function add_input_exception( $message, $input_id ) {
46
+ $this->input_exceptions[ $input_id ] = $message;
47
+ }
48
+
49
+ /**
50
+ * Get all input exceptions
51
+ *
52
+ * @since 1.0 Activecampaign Addon
53
+ * @return array
54
+ */
55
+ public function get_input_exceptions() {
56
+ return $this->input_exceptions;
57
+ }
58
+
59
+ /**
60
+ * Check if there is input_exceptions_is_available
61
+ *
62
+ * @since 1.0 Activecampaign Addon
63
+ * @return bool
64
+ */
65
+ public function input_exceptions_is_available() {
66
+ return count( $this->input_exceptions ) > 0;
67
+ }
68
+ }
addons/pro/activecampaign/forminator-addon-activecampaign-form-settings.php ADDED
@@ -0,0 +1,746 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once dirname( __FILE__ ) . '/forminator-addon-activecampaign-form-settings-exception.php';
4
+
5
+ /**
6
+ * Class Forminator_Addon_Activecampaign_Form_Settings
7
+ * Handle how form settings displayed and saved
8
+ *
9
+ * @since 1.0 Activecampaign Addon
10
+ */
11
+ class Forminator_Addon_Activecampaign_Form_Settings extends Forminator_Addon_Form_Settings_Abstract {
12
+
13
+ /**
14
+ * @var Forminator_Addon_Activecampaign
15
+ * @since 1.0 Activecampaign Addon
16
+ */
17
+ protected $addon;
18
+
19
+ /**
20
+ * Forminator_Addon_Activecampaign_Form_Settings constructor.
21
+ *
22
+ * @since 1.0 Activecampaign Addon
23
+ *
24
+ * @param Forminator_Addon_Abstract $addon
25
+ * @param $form_id
26
+ *
27
+ * @throws Forminator_Addon_Exception
28
+ */
29
+ public function __construct( Forminator_Addon_Abstract $addon, $form_id ) {
30
+ parent::__construct( $addon, $form_id );
31
+
32
+ $this->_update_form_settings_error_message = __(
33
+ 'Sorry, we are failed to update settings for this form, please check your form and input then try again',
34
+ Forminator::DOMAIN
35
+ );
36
+ }
37
+
38
+ /**
39
+ * Activecampaign Form Settings wizard
40
+ *
41
+ * @since 1.0 Activecampaign Addon
42
+ * @return array
43
+ */
44
+ public function form_settings_wizards() {
45
+ // numerical array steps
46
+ return array(
47
+ array(
48
+ 'callback' => array( $this, 'pick_name' ),
49
+ 'is_completed' => array( $this, 'pick_name_is_completed' ),
50
+ ),
51
+ array(
52
+ 'callback' => array( $this, 'select_list' ),
53
+ 'is_completed' => array( $this, 'select_list_is_completed' ),
54
+ ),
55
+ array(
56
+ 'callback' => array( $this, 'map_fields' ),
57
+ 'is_completed' => array( $this, 'map_fields_is_completed' ),
58
+ ),
59
+ //todo: allow fe to support this
60
+ // array(
61
+ // 'callback' => array( $this, 'extra_field' ),
62
+ // 'is_completed' => array( $this, 'extra_field' ),
63
+ // ),
64
+ array(
65
+ 'callback' => array( $this, 'setup_options' ),
66
+ 'is_completed' => array( $this, 'setup_options_is_completed' ),
67
+ ),
68
+ );
69
+ }
70
+
71
+ /**
72
+ * Setup Connection Name
73
+ *
74
+ * @since 1.0 Activecampaign Addon
75
+ *
76
+ * @param $submitted_data
77
+ *
78
+ * @return array
79
+ */
80
+ public function pick_name( $submitted_data ) {
81
+ $template = forminator_addon_activecampaign_dir() . 'views/form-settings/pick-name.php';
82
+
83
+ $multi_id = $this->generate_multi_id();
84
+ if ( isset( $submitted_data['multi_id'] ) ) {
85
+ $multi_id = $submitted_data['multi_id'];
86
+ }
87
+
88
+ $template_params = array(
89
+ 'name' => $this->get_multi_id_form_settings_value( $multi_id, 'name', '' ),
90
+ 'name_error' => '',
91
+ 'multi_id' => $multi_id,
92
+ );
93
+
94
+ unset( $submitted_data['multi_id'] );
95
+
96
+ $is_submit = ! empty( $submitted_data );
97
+ $has_errors = false;
98
+ if ( $is_submit ) {
99
+ $name = isset( $submitted_data['name'] ) ? $submitted_data['name'] : '';
100
+ $template_params['name'] = $name;
101
+
102
+ try {
103
+ if ( empty( $name ) ) {
104
+ throw new Forminator_Addon_Activecampaign_Exception( __( 'Please pick valid name' ) );
105
+ }
106
+
107
+ $time_added = $this->get_multi_id_form_settings_value( $multi_id, 'time_added', time() );
108
+ $this->save_multi_id_form_setting_values(
109
+ $multi_id,
110
+ array(
111
+ 'name' => $name,
112
+ 'time_added' => $time_added,
113
+ )
114
+ );
115
+
116
+ } catch ( Forminator_Addon_Activecampaign_Exception $e ) {
117
+ $template_params['name_error'] = $e->getMessage();
118
+ $has_errors = true;
119
+ }
120
+ }
121
+
122
+ $buttons = array();
123
+ if ( $this->pick_name_is_completed( array( 'multi_id' => $multi_id ) ) ) {
124
+ $buttons['disconnect']['markup'] = Forminator_Addon_Abstract::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ),
125
+ 'sui-button-ghost sui-tooltip sui-tooltip-top-center forminator-addon-form-disconnect',
126
+ esc_html__( 'Disconnect this ActiveCampaign Integration from this Form.', Forminator::DOMAIN )
127
+ );
128
+ }
129
+
130
+ $buttons['next']['markup'] = '<div class="sui-actions-right">' .
131
+ Forminator_Addon_Abstract::get_button_markup( esc_html__( 'NEXT', Forminator::DOMAIN ), 'forminator-addon-next' ) .
132
+ '</div>';
133
+
134
+ return array(
135
+ 'html' => Forminator_Addon_Abstract::get_template( $template, $template_params ),
136
+ 'buttons' => $buttons,
137
+ 'redirect' => false,
138
+ 'has_errors' => $has_errors,
139
+ );
140
+ }
141
+
142
+ /**
143
+ * Check if pick name step completed
144
+ *
145
+ * @since 1.0 Activecampaign Addon
146
+ *
147
+ * @param $submitted_data
148
+ *
149
+ * @return bool
150
+ */
151
+ public function pick_name_is_completed( $submitted_data ) {
152
+ $multi_id = '';
153
+ if ( isset( $submitted_data['multi_id'] ) ) {
154
+ $multi_id = $submitted_data['multi_id'];
155
+ }
156
+
157
+ if ( empty( $multi_id ) ) {
158
+ return false;
159
+ }
160
+
161
+ $name = $this->get_multi_id_form_settings_value( $multi_id, 'name', '' );
162
+
163
+ if ( empty( $name ) ) {
164
+ return false;
165
+ }
166
+
167
+ return true;
168
+ }
169
+
170
+ /**
171
+ * Setup Contact List
172
+ *
173
+ * @since 1.0 Activecampaign Addon
174
+ *
175
+ * @param $submitted_data
176
+ *
177
+ * @return array
178
+ */
179
+ public function select_list( $submitted_data ) {
180
+ $template = forminator_addon_activecampaign_dir() . 'views/form-settings/select-list.php';
181
+
182
+ if ( ! isset( $submitted_data['multi_id'] ) ) {
183
+ return $this->get_force_closed_wizard( __( 'Please pick valid connection', Forminator::DOMAIN ) );
184
+ }
185
+
186
+ $multi_id = $submitted_data['multi_id'];
187
+ unset( $submitted_data['multi_id'] );
188
+
189
+ $template_params = array(
190
+ 'list_id' => $this->get_multi_id_form_settings_value( $multi_id, 'list_id', '' ),
191
+ 'list_id_error' => '',
192
+ 'multi_id' => $multi_id,
193
+ 'error_message' => '',
194
+ 'lists' => array(),
195
+ );
196
+
197
+
198
+ $is_submit = ! empty( $submitted_data );
199
+ $has_errors = false;
200
+
201
+ $lists = array();
202
+
203
+ try {
204
+
205
+ $ac_api = $this->addon->get_api();
206
+ $lists_request = $ac_api->get_lists();
207
+
208
+ foreach ( $lists_request as $key => $data ) {
209
+ if ( isset( $data->id ) && isset( $data->name ) ) {
210
+ $lists[ $data->id ] = $data->name;
211
+ }
212
+ }
213
+
214
+ if ( empty( $lists ) ) {
215
+ throw new Forminator_Addon_Activecampaign_Exception( __( 'No lists found on your ActiveCampaign account. Please create one.', Forminator::DOMAIN ) );
216
+ }
217
+
218
+ $template_params['lists'] = $lists;
219
+
220
+ } catch ( Forminator_Addon_Activecampaign_Exception $e ) {
221
+ $template_params['error_message'] = $e->getMessage();
222
+ $has_errors = true;
223
+ }
224
+
225
+ if ( $is_submit ) {
226
+ $list_id = isset( $submitted_data['list_id'] ) ? $submitted_data['list_id'] : '';
227
+ $template_params['list_id'] = $list_id;
228
+
229
+ try {
230
+ if ( empty( $list_id ) ) {
231
+ throw new Forminator_Addon_Activecampaign_Exception( __( 'Please pick valid list' ) );
232
+ }
233
+
234
+ // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
235
+ if ( ! in_array( $list_id, array_keys( $lists ) ) ) {
236
+ throw new Forminator_Addon_Activecampaign_Exception( __( 'Please pick valid list' ) );
237
+ }
238
+
239
+ $list_name = $lists[ $list_id ];
240
+
241
+ $this->save_multi_id_form_setting_values(
242
+ $multi_id,
243
+ array(
244
+ 'list_id' => $list_id,
245
+ 'list_name' => $list_name,
246
+ )
247
+ );
248
+
249
+ } catch ( Forminator_Addon_Activecampaign_Exception $e ) {
250
+ $template_params['list_id_error'] = $e->getMessage();
251
+ $has_errors = true;
252
+ }
253
+ }
254
+
255
+ $buttons = array();
256
+ if ( $this->pick_name_is_completed( array( 'multi_id' => $multi_id ) ) ) {
257
+ $buttons['disconnect']['markup'] = Forminator_Addon_Abstract::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ),
258
+ 'sui-button-ghost sui-tooltip sui-tooltip-top-center forminator-addon-form-disconnect',
259
+ esc_html__( 'Disconnect this ActiveCampaign Integration from this Form.', Forminator::DOMAIN )
260
+ );
261
+ }
262
+
263
+ $buttons['next']['markup'] = '<div class="sui-actions-right">' .
264
+ Forminator_Addon_Abstract::get_button_markup( esc_html__( 'NEXT', Forminator::DOMAIN ), 'forminator-addon-next' ) .
265
+ '</div>';
266
+
267
+ return array(
268
+ 'html' => Forminator_Addon_Abstract::get_template( $template, $template_params ),
269
+ 'buttons' => $buttons,
270
+ 'redirect' => false,
271
+ 'has_errors' => $has_errors,
272
+ 'has_back' => true,
273
+ );
274
+ }
275
+
276
+ /**
277
+ * Check if select contact list completed
278
+ *
279
+ * @since 1.0 Activecampaign Addon
280
+ *
281
+ * @param $submitted_data
282
+ *
283
+ * @return bool
284
+ */
285
+ public function select_list_is_completed( $submitted_data ) {
286
+ $multi_id = '';
287
+ if ( isset( $submitted_data['multi_id'] ) ) {
288
+ $multi_id = $submitted_data['multi_id'];
289
+ }
290
+
291
+ if ( empty( $multi_id ) ) {
292
+ return false;
293
+ }
294
+
295
+ $list_id = $this->get_multi_id_form_settings_value( $multi_id, 'list_id', '' );
296
+
297
+ if ( empty( $list_id ) ) {
298
+ return false;
299
+ }
300
+
301
+ return true;
302
+ }
303
+
304
+
305
+ /**
306
+ * Setup fields map
307
+ *
308
+ * @since 1.0 Activecampaign Addon
309
+ *
310
+ * @param $submitted_data
311
+ *
312
+ * @return array
313
+ */
314
+ public function map_fields( $submitted_data ) {
315
+ $template = forminator_addon_activecampaign_dir() . 'views/form-settings/map-fields.php';
316
+
317
+ if ( ! isset( $submitted_data['multi_id'] ) ) {
318
+ return $this->get_force_closed_wizard( __( 'Please pick valid connection', Forminator::DOMAIN ) );
319
+ }
320
+
321
+ $multi_id = $submitted_data['multi_id'];
322
+ unset( $submitted_data['multi_id'] );
323
+
324
+ // find type of email
325
+ $email_fields = array();
326
+ $forminator_field_element_ids = array();
327
+ foreach ( $this->form_fields as $form_field ) {
328
+ // collect element ids
329
+ $forminator_field_element_ids[] = $form_field['element_id'];
330
+ if ( 'email' === $form_field['type'] ) {
331
+ $email_fields[] = $form_field;
332
+ }
333
+ }
334
+
335
+ $template_params = array(
336
+ 'fields_map' => $this->get_multi_id_form_settings_value( $multi_id, 'fields_map', array() ),
337
+ 'multi_id' => $multi_id,
338
+ 'error_message' => '',
339
+ 'fields' => array(),
340
+ 'form_fields' => $this->form_fields,
341
+ 'email_fields' => $email_fields,
342
+ );
343
+
344
+ $is_submit = ! empty( $submitted_data );
345
+ $has_errors = false;
346
+
347
+ $fields = array(
348
+ 'email' => __( 'Email Address', Forminator::DOMAIN ),
349
+ 'first_name' => __( 'First Name', Forminator::DOMAIN ),
350
+ 'last_name' => __( 'Last Name', Forminator::DOMAIN ),
351
+ 'phone' => __( 'Phone', Forminator::DOMAIN ),
352
+ 'orgname' => __( 'Organization Name', Forminator::DOMAIN ),
353
+ );
354
+
355
+ $list_id = $this->get_multi_id_form_settings_value( $multi_id, 'list_id', 0 );
356
+
357
+ try {
358
+
359
+ $ac_api = $this->addon->get_api();
360
+ $list_detail = $ac_api->get_list( $list_id );
361
+
362
+ if ( ! isset( $list_detail->fields ) && ! is_array( $list_detail->fields ) ) {
363
+ throw new Forminator_Addon_Activecampaign_Exception( __( 'ActiveCampaign list\'s fields could not be found', Forminator::DOMAIN ) );
364
+ }
365
+
366
+ foreach ( $list_detail->fields as $field ) {
367
+ $fields[ $field->id ] = $field->title;
368
+ }
369
+
370
+ $template_params['fields'] = $fields;
371
+
372
+ } catch ( Forminator_Addon_Activecampaign_Exception $e ) {
373
+ $template_params['error_message'] = $e->getMessage();
374
+ $has_errors = true;
375
+ }
376
+
377
+ if ( $is_submit ) {
378
+ $fields_map = isset( $submitted_data['fields_map'] ) ? $submitted_data['fields_map'] : array();
379
+ $template_params['fields_map'] = $fields_map;
380
+
381
+ try {
382
+ if ( empty( $fields_map ) ) {
383
+ throw new Forminator_Addon_Activecampaign_Exception( __( 'Please assign fields.', Forminator::DOMAIN ) );
384
+ }
385
+
386
+ $input_exceptions = new Forminator_Addon_Activecampaign_Form_Settings_Exception();
387
+ if ( ! isset( $fields_map['email'] ) || empty( $fields_map['email'] ) ) {
388
+ $input_exceptions->add_input_exception( 'Please assign field for Email Address', 'email_error' );
389
+ }
390
+
391
+ $fields_map_to_save = array();
392
+ foreach ( $fields as $key => $title ) {
393
+ if ( isset( $fields_map[ $key ] ) && ! empty( $fields_map[ $key ] ) ) {
394
+ $element_id = $fields_map[ $key ];
395
+ if ( ! in_array( $element_id, $forminator_field_element_ids, true ) ) {
396
+ $input_exceptions->add_input_exception(
397
+ sprintf( __( 'Please assign valid field for %s', Forminator::DOMAIN ), $title ),
398
+ $key . '_error'
399
+ );
400
+ continue;
401
+ }
402
+
403
+ $fields_map_to_save[ $key ] = $fields_map[ $key ];
404
+ }
405
+ }
406
+
407
+ if ( $input_exceptions->input_exceptions_is_available() ) {
408
+ throw $input_exceptions;
409
+ }
410
+
411
+ $this->save_multi_id_form_setting_values( $multi_id, array( 'fields_map' => $fields_map ) );
412
+
413
+ } catch ( Forminator_Addon_Activecampaign_Form_Settings_Exception $e ) {
414
+ $template_params = array_merge( $template_params, $e->get_input_exceptions() );
415
+ $has_errors = true;
416
+ } catch ( Forminator_Addon_Activecampaign_Exception $e ) {
417
+ $template_params['error_message'] = $e->getMessage();
418
+ $has_errors = true;
419
+ }
420
+ }
421
+
422
+ $buttons = array();
423
+ if ( $this->pick_name_is_completed( array( 'multi_id' => $multi_id ) ) ) {
424
+ $buttons['disconnect']['markup'] = Forminator_Addon_Abstract::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ),
425
+ 'sui-button-ghost sui-tooltip sui-tooltip-top-center forminator-addon-form-disconnect',
426
+ esc_html__( 'Disconnect this ActiveCampaign Integration from this Form.', Forminator::DOMAIN )
427
+ );
428
+ }
429
+
430
+ $buttons['next']['markup'] = '<div class="sui-actions-right">' .
431
+ Forminator_Addon_Abstract::get_button_markup( esc_html__( 'NEXT', Forminator::DOMAIN ), 'forminator-addon-next' ) .
432
+ '</div>';
433
+
434
+ return array(
435
+ 'html' => Forminator_Addon_Abstract::get_template( $template, $template_params ),
436
+ 'buttons' => $buttons,
437
+ 'size' => 'normal',
438
+ 'redirect' => false,
439
+ 'has_errors' => $has_errors,
440
+ 'has_back' => true,
441
+ );
442
+ }
443
+
444
+ /**
445
+ * Check if fields mapped
446
+ *
447
+ * @since 1.0 Activecampaign Addon
448
+ *
449
+ * @param $submitted_data
450
+ *
451
+ * @return bool
452
+ */
453
+ public function map_fields_is_completed( $submitted_data ) {
454
+ $multi_id = '';
455
+ if ( isset( $submitted_data['multi_id'] ) ) {
456
+ $multi_id = $submitted_data['multi_id'];
457
+ }
458
+
459
+ if ( empty( $multi_id ) ) {
460
+ return false;
461
+ }
462
+
463
+ $fields_map = $this->get_multi_id_form_settings_value( $multi_id, 'fields_map', array() );
464
+
465
+ if ( empty( $fields_map ) || ! is_array( $fields_map ) || count( $fields_map ) < 1 ) {
466
+ return false;
467
+ }
468
+
469
+ if ( ! isset( $fields_map['email'] ) || empty( $fields_map['email'] ) ) {
470
+ return false;
471
+ }
472
+
473
+ return true;
474
+ }
475
+
476
+ /**
477
+ * Setup options
478
+ *
479
+ * Contains :
480
+ * - Double opt-in form,
481
+ * - tags,
482
+ * - instant-responder,
483
+ * - send last broadcast
484
+ *
485
+ * @since 1.0 Activecampaign Addon
486
+ *
487
+ * @param $submitted_data
488
+ *
489
+ * @return array
490
+ */
491
+ public function setup_options( $submitted_data ) {
492
+ $template = forminator_addon_activecampaign_dir() . 'views/form-settings/setup-options.php';
493
+
494
+ if ( ! isset( $submitted_data['multi_id'] ) ) {
495
+ return $this->get_force_closed_wizard( __( 'Please pick valid connection', Forminator::DOMAIN ) );
496
+ }
497
+
498
+ $multi_id = $submitted_data['multi_id'];
499
+ unset( $submitted_data['multi_id'] );
500
+
501
+ $forminator_form_element_ids = array();
502
+ foreach ( $this->form_fields as $field ) {
503
+ $forminator_form_element_ids[ $field['element_id'] ] = $field;
504
+ }
505
+
506
+ $template_params = array(
507
+ 'multi_id' => $multi_id,
508
+ 'error_message' => '',
509
+ 'forms' => array(),
510
+ 'double_opt_form_id' => $this->get_multi_id_form_settings_value( $multi_id, 'double_opt_form_id', '' ),
511
+ 'instantresponders' => $this->get_multi_id_form_settings_value( $multi_id, 'instantresponders', 0 ),
512
+ 'lastmessage' => $this->get_multi_id_form_settings_value( $multi_id, 'lastmessage', 0 ),
513
+ 'tags_fields' => array(),
514
+ 'tags_selected_fields' => array(),
515
+ );
516
+
517
+ $saved_tags = $this->get_multi_id_form_settings_value( $multi_id, 'tags', array() );
518
+
519
+ if ( isset( $submitted_data['tags'] ) && is_array( $submitted_data['tags'] ) ) {
520
+ $saved_tags = $submitted_data['tags'];
521
+
522
+ }
523
+ $tag_selected_fields = array();
524
+ foreach ( $saved_tags as $key => $saved_tag ) {
525
+ // using form data
526
+ if ( stripos( $saved_tag, '{' ) === 0
527
+ && stripos( $saved_tag, '}' ) === ( strlen( $saved_tag ) - 1 )
528
+ ) {
529
+ $element_id = str_ireplace( '{', '', $saved_tag );
530
+ $element_id = str_ireplace( '}', '', $element_id );
531
+ if ( in_array( $element_id, array_keys( $forminator_form_element_ids ), true ) ) {
532
+ $forminator_form_element_ids[ $element_id ]['field_label'] = $forminator_form_element_ids[ $element_id ]['field_label'] .
533
+ ' | ' . $forminator_form_element_ids[ $element_id ]['element_id'];
534
+ $forminator_form_element_ids[ $element_id ]['element_id'] = '{' . $forminator_form_element_ids[ $element_id ]['element_id'] . '}';
535
+
536
+
537
+ $tag_selected_fields[] = $forminator_form_element_ids[ $element_id ];
538
+ // let this go, its already selected.
539
+ unset( $forminator_form_element_ids[ $element_id ] );
540
+ } else {
541
+ // no more exist on element ids let it go
542
+ unset( $saved_tags[ $key ] );
543
+ }
544
+
545
+ } else {// free form type
546
+ $tag_selected_fields[] = array(
547
+ 'element_id' => $saved_tag,
548
+ 'field_label' => $saved_tag,
549
+ );
550
+ }
551
+ }
552
+
553
+ $template_params['tags_fields'] = $forminator_form_element_ids;
554
+ $template_params['tags_selected_fields'] = $tag_selected_fields;
555
+
556
+
557
+ $is_submit = ! empty( $submitted_data );
558
+ $has_errors = false;
559
+ $notification = array();
560
+ $is_close = false;
561
+
562
+ $forms = array();
563
+ try {
564
+ $api = $this->addon->get_api();
565
+ $forms_request = $api->get_forms();
566
+
567
+ foreach ( $forms_request as $data ) {
568
+ if ( isset( $data->id ) && isset( $data->name ) ) {
569
+ $forms[ $data->id ] = $data->name;
570
+ }
571
+ }
572
+ } catch ( Forminator_Addon_Activecampaign_Exception $e ) {
573
+ $forms = array();
574
+ }
575
+
576
+ $template_params['forms'] = $forms;
577
+
578
+ if ( $is_submit ) {
579
+ $double_opt_form_id = isset( $submitted_data['double_opt_form_id'] ) ? $submitted_data['double_opt_form_id'] : '';
580
+ $instantresponders = isset( $submitted_data['instantresponders'] ) ? (int) $submitted_data['instantresponders'] : 0;
581
+ $lastmessage = isset( $submitted_data['lastmessage'] ) ? (int) $submitted_data['lastmessage'] : 0;
582
+
583
+ try {
584
+ $input_exceptions = new Forminator_Addon_Activecampaign_Form_Settings_Exception();
585
+
586
+ // possible different type intended
587
+ // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
588
+ if ( ! empty( $double_opt_form_id ) && ! in_array( $double_opt_form_id, array_keys( $forms ) ) ) {
589
+ $input_exceptions->add_input_exception( __( 'Please pick valid ActiveCampaign Form', Forminator::DOMAIN ), 'double_opt_form_id_error' );
590
+ }
591
+
592
+ if ( $input_exceptions->input_exceptions_is_available() ) {
593
+ throw $input_exceptions;
594
+ }
595
+
596
+ $this->save_multi_id_form_setting_values(
597
+ $multi_id,
598
+ array(
599
+ 'tags' => $saved_tags,
600
+ 'double_opt_form_id' => $double_opt_form_id,
601
+ 'instantresponders' => $instantresponders,
602
+ 'lastmessage' => $lastmessage,
603
+ )
604
+ );
605
+
606
+ $notification = array(
607
+ 'type' => 'success',
608
+ 'text' => '<strong>' . $this->addon->get_title() . '</strong> ' . __( 'Successfully connected to your form' ),
609
+ );
610
+ $is_close = true;
611
+
612
+ } catch ( Forminator_Addon_Activecampaign_Form_Settings_Exception $e ) {
613
+ $template_params = array_merge( $template_params, $e->get_input_exceptions() );
614
+ $has_errors = true;
615
+ } catch ( Forminator_Addon_Activecampaign_Exception $e ) {
616
+ $template_params['error_message'] = $e->getMessage();
617
+ $has_errors = true;
618
+ }
619
+ }
620
+
621
+ $buttons = array();
622
+ if ( $this->pick_name_is_completed( array( 'multi_id' => $multi_id ) ) ) {
623
+ $buttons['disconnect']['markup'] = Forminator_Addon_Abstract::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ),
624
+ 'sui-button-ghost sui-tooltip sui-tooltip-top-center forminator-addon-form-disconnect',
625
+ esc_html__( 'Disconnect this ActiveCampaign Integration from this Form.', Forminator::DOMAIN )
626
+ );
627
+ }
628
+
629
+ $buttons['next']['markup'] = '<div class="sui-actions-right">' .
630
+ Forminator_Addon_Abstract::get_button_markup( esc_html__( 'SAVE', Forminator::DOMAIN ), 'sui-button-primary forminator-addon-finish' ) .
631
+ '</div>';
632
+
633
+ return array(
634
+ 'html' => Forminator_Addon_Abstract::get_template( $template, $template_params ),
635
+ 'buttons' => $buttons,
636
+ 'size' => 'normal',
637
+ 'redirect' => false,
638
+ 'has_errors' => $has_errors,
639
+ 'has_back' => true,
640
+ 'notification' => $notification,
641
+ 'is_close' => $is_close,
642
+ );
643
+ }
644
+
645
+ /**
646
+ * Check if setup options completed
647
+ *
648
+ * @since 1.0 Activecampaign Addon
649
+ *
650
+ * @param $submitted_data
651
+ *
652
+ * @return bool
653
+ */
654
+ public function setup_options_is_completed( $submitted_data ) {
655
+ // all settings here are optional, so it can be marked as completed
656
+ return true;
657
+ }
658
+
659
+ /**
660
+ * Generate multi id for multiple connection
661
+ *
662
+ * @since 1.0 Activecampaign Addon
663
+ * @return string
664
+ */
665
+ public function generate_multi_id() {
666
+ return uniqid( 'activecampaign_', true );
667
+ }
668
+
669
+
670
+ /**
671
+ * Override how multi connection displayed
672
+ *
673
+ * @since 1.0 Activecampaign Addon
674
+ * @return array
675
+ */
676
+ public function get_multi_ids() {
677
+ $multi_ids = array();
678
+ $form_settings_values = $this->get_form_settings_values();
679
+ foreach ( $form_settings_values as $key => $value ) {
680
+ // apply some sorting if applicable
681
+ $multi_ids[] = array(
682
+ 'id' => $key,
683
+ // use name that was added by user on creating connection
684
+ 'label' => isset( $value['name'] ) ? $value['name'] : $key,
685
+ );
686
+ }
687
+
688
+ /**
689
+ * Filter labels of multi_id on integrations tab
690
+ *
691
+ * @since 1.2
692
+ *
693
+ * @param array $multi_ids
694
+ * @param array $form_settings_values
695
+ */
696
+ $multi_ids = apply_filters( 'forminator_addon_activecampaign_multi_id_labels', $multi_ids, $form_settings_values );
697
+
698
+ return $multi_ids;
699
+ }
700
+
701
+ /**
702
+ * Disconnect a connection from current form
703
+ *
704
+ * @since 1.0 Activecampaign Addon
705
+ *
706
+ * @param array $submitted_data
707
+ */
708
+ public function disconnect_form( $submitted_data ) {
709
+ // only execute if multi_id provided on submitted data
710
+ if ( isset( $submitted_data['multi_id'] ) && ! empty( $submitted_data['multi_id'] ) ) {
711
+ $addon_form_settings = $this->get_form_settings_values();
712
+ unset( $addon_form_settings[ $submitted_data['multi_id'] ] );
713
+ $this->save_form_settings_values( $addon_form_settings );
714
+ }
715
+ }
716
+
717
+ /**
718
+ * Check if multi_id form settings values completed
719
+ *
720
+ * @since 1.0 Active Campaign Added
721
+ *
722
+ * @param $multi_id
723
+ *
724
+ * @return bool
725
+ */
726
+ public function is_multi_form_settings_complete( $multi_id ) {
727
+ $data = array( 'multi_id' => $multi_id );
728
+
729
+ if ( ! $this->pick_name_is_completed( $data ) ) {
730
+ return false;
731
+ }
732
+ if ( ! $this->select_list_is_completed( $data ) ) {
733
+ return false;
734
+ }
735
+
736
+ if ( ! $this->map_fields_is_completed( $data ) ) {
737
+ return false;
738
+ }
739
+
740
+ if ( ! $this->setup_options_is_completed( $data ) ) {
741
+ return false;
742
+ }
743
+
744
+ return true;
745
+ }
746
+ }
addons/pro/activecampaign/forminator-addon-activecampaign.php ADDED
@@ -0,0 +1,477 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once dirname( __FILE__ ) . '/forminator-addon-activecampaign-exception.php';
4
+ require_once dirname( __FILE__ ) . '/lib/class-wp-activecampaign-api.php';
5
+
6
+ /**
7
+ * Class Forminator_Addon_Activecampaign
8
+ * Activecampaign Addon Main Class
9
+ *
10
+ * @since 1.0 Activecampaign Addon
11
+ */
12
+ final class Forminator_Addon_Activecampaign extends Forminator_Addon_Abstract {
13
+
14
+ /**
15
+ * @var self|null
16
+ */
17
+ private static $_instance = null;
18
+
19
+ protected $_slug = 'activecampaign';
20
+ protected $_version = FORMINATOR_ADDON_ACTIVECAMPAIGN_VERSION;
21
+ protected $_min_forminator_version = '1.1';
22
+ protected $_short_title = 'ActiveCampaign';
23
+ protected $_title = 'ActiveCampaign';
24
+ protected $_url = 'https://premium.wpmudev.org';
25
+ protected $_full_path = __FILE__;
26
+
27
+ protected $_form_settings = 'Forminator_Addon_Activecampaign_Form_Settings';
28
+ protected $_form_hooks = 'Forminator_Addon_Activecampaign_Form_Hooks';
29
+
30
+ /**
31
+ * @var Forminator_Addon_Activecampaign_Wp_Api|null
32
+ */
33
+ private static $api = null;
34
+
35
+ public $connected_account = null;
36
+
37
+ /**
38
+ * Forminator_Addon_Activecampaign constructor.
39
+ *
40
+ * @since 1.0 Activecampaign Addon
41
+ */
42
+ public function __construct() {
43
+ // late init to allow translation
44
+ $this->_description = __( 'Get awesome by your form.', Forminator::DOMAIN );
45
+ $this->_activation_error_message = __( 'Sorry but we failed to activate Activecampaign Integration, don\'t hesitate to contact us', Forminator::DOMAIN );
46
+ $this->_deactivation_error_message = __( 'Sorry but we failed to deactivate Activecampaign Integration, please try again', Forminator::DOMAIN );
47
+
48
+ $this->_update_settings_error_message = __(
49
+ 'Sorry, we are failed to update settings, please check your form and try again',
50
+ Forminator::DOMAIN
51
+ );
52
+
53
+ $this->_icon = forminator_addon_activecampaign_assets_url() . 'icons/activecampaign.png';
54
+ $this->_icon_x2 = forminator_addon_activecampaign_assets_url() . 'icons/activecampaign@2x.png';
55
+ $this->_image = forminator_addon_activecampaign_assets_url() . 'img/activecampaign.png';
56
+ $this->_image_x2 = forminator_addon_activecampaign_assets_url() . 'img/activecampaign@2x.png';
57
+ }
58
+
59
+ /**
60
+ * Get Instance
61
+ *
62
+ * @since 1.0 Activecampaign Addon
63
+ * @return self|null
64
+ */
65
+ public static function get_instance() {
66
+ if ( is_null( self::$_instance ) ) {
67
+ self::$_instance = new self();
68
+ }
69
+
70
+ return self::$_instance;
71
+ }
72
+
73
+ /**
74
+ * Override on is_connected
75
+ *
76
+ * @since 1.0 Activecampaign Addon
77
+ *
78
+ * @return bool
79
+ */
80
+ public function is_connected() {
81
+ try {
82
+ // check if its active
83
+ if ( ! $this->is_active() ) {
84
+ throw new Forminator_Addon_Activecampaign_Exception( __( 'ActiveCampaign is not active', Forminator::DOMAIN ) );
85
+ }
86
+
87
+ // if user completed api setup
88
+ $is_connected = $this->is_api_completed();
89
+
90
+ } catch ( Forminator_Addon_Activecampaign_Exception $e ) {
91
+ $is_connected = false;
92
+ }
93
+
94
+ /**
95
+ * Filter connected status of active campaign
96
+ *
97
+ * @since 1.2
98
+ *
99
+ * @param bool $is_connected
100
+ */
101
+ $is_connected = apply_filters( 'forminator_addon_activecampaign_is_connected', $is_connected );
102
+
103
+ return $is_connected;
104
+ }
105
+
106
+ /**
107
+ * Check if Activecampaign is connected with current form
108
+ *
109
+ * @since 1.0 Activecampaign Addon
110
+ *
111
+ * @param $form_id
112
+ *
113
+ * @return bool
114
+ */
115
+ public function is_form_connected( $form_id ) {
116
+ try {
117
+ $form_settings_instance = null;
118
+ if ( ! $this->is_connected() ) {
119
+ throw new Forminator_Addon_Activecampaign_Exception( __( ' ActiveCampaign is not connected', Forminator::DOMAIN ) );
120
+ }
121
+
122
+ $form_settings_instance = $this->get_addon_form_settings( $form_id );
123
+ if ( ! $form_settings_instance instanceof Forminator_Addon_Activecampaign_Form_Settings ) {
124
+ throw new Forminator_Addon_Activecampaign_Exception( __( 'Invalid Form Settings of ActiveCampaign', Forminator::DOMAIN ) );
125
+ }
126
+
127
+ // Mark as active when there is at least one active connection
128
+ if ( false === $form_settings_instance->find_one_active_connection() ) {
129
+ throw new Forminator_Addon_Activecampaign_Exception( __( 'No active ActiveCampaign connection found in this form', Forminator::DOMAIN ) );
130
+ }
131
+
132
+ $is_form_connected = true;
133
+
134
+ } catch ( Forminator_Addon_Activecampaign_Exception $e ) {
135
+ $is_form_connected = false;
136
+ forminator_addon_maybe_log( __METHOD__, $e->getMessage() );
137
+ }
138
+
139
+ /**
140
+ * Filter connected status of ActiveCampaign with the form
141
+ *
142
+ * @since 1.2
143
+ *
144
+ * @param bool $is_form_connected
145
+ * @param int $form_id Current Form ID
146
+ * @param Forminator_Addon_Activecampaign_Form_Settings|null $form_settings_instance Instance of form settings, or null when unavailable
147
+ *
148
+ */
149
+ $is_form_connected = apply_filters( 'forminator_addon_activecampaign_is_form_connected', $is_form_connected, $form_id, $form_settings_instance );
150
+
151
+ return $is_form_connected;
152
+ }
153
+
154
+ /**
155
+ * Override settings available,
156
+ *
157
+ * @since 1.0 Activecampaign Addon
158
+ * @return bool
159
+ */
160
+ public function is_settings_available() {
161
+ return true;
162
+ }
163
+
164
+ /**
165
+ * Flag show full log on entries
166
+ *
167
+ * @since 1.0 Activecampaign Addon
168
+ * @return bool
169
+ */
170
+ public static function is_show_full_log() {
171
+ $show_full_log = false;
172
+ if ( defined( 'FORMINATOR_ADDON_ACTIVECAMPAIGN_SHOW_FULL_LOG' ) && FORMINATOR_ADDON_ACTIVECAMPAIGN_SHOW_FULL_LOG ) {
173
+ $show_full_log = true;
174
+ }
175
+
176
+ /**
177
+ * Filter Flag show full log on entries
178
+ *
179
+ * @since 1.2
180
+ *
181
+ * @params bool $show_full_log
182
+ */
183
+ $show_full_log = apply_filters( 'forminator_addon_activecampaign_show_full_log', $show_full_log );
184
+
185
+ return $show_full_log;
186
+ }
187
+
188
+ /**
189
+ * Flag enable delete contact before delete entries
190
+ *
191
+ * Its disabled by default
192
+ *
193
+ * @since 1.0 Activecampaign Addon
194
+ * @return bool
195
+ */
196
+ public static function is_enable_delete_contact() {
197
+ $enable_delete_contact = false;
198
+ if ( defined( 'FORMINATOR_ADDON_ACTIVECAMPAIGN_ENABLE_DELETE_CONTACT' ) && FORMINATOR_ADDON_ACTIVECAMPAIGN_ENABLE_DELETE_CONTACT ) {
199
+ $enable_delete_contact = true;
200
+ }
201
+
202
+ /**
203
+ * Filter Flag enable delete contact before delete entries
204
+ *
205
+ * @since 1.2
206
+ *
207
+ * @params bool $enable_delete_contact
208
+ */
209
+ $enable_delete_contact = apply_filters( 'forminator_addon_activecampaign_delete_contact', $enable_delete_contact );
210
+
211
+ return $enable_delete_contact;
212
+ }
213
+
214
+ /**
215
+ * Allow multiple connection on one form
216
+ *
217
+ * @since 1.0 Activecampaign Addon
218
+ * @return bool
219
+ */
220
+ public function is_allow_multi_on_form() {
221
+ return true;
222
+ }
223
+
224
+ /**
225
+ * Setting wizard of Active Campaign
226
+ *
227
+ * @since 1.0 Activecampaign Addon
228
+ * @return array
229
+ */
230
+ public function settings_wizards() {
231
+ return array(
232
+ array(
233
+ 'callback' => array( $this, 'setup_api' ),
234
+ 'is_completed' => array( $this, 'is_api_completed' ),
235
+ ),
236
+ );
237
+ }
238
+
239
+
240
+ /**
241
+ * Setup API Wizard
242
+ *
243
+ * @since 1.0 Active Campaign Addon
244
+ *
245
+ * @param $submitted_data
246
+ *
247
+ * @param int $form_id
248
+ *
249
+ * @return array
250
+ */
251
+ public function setup_api( $submitted_data, $form_id = 0 ) {
252
+ $settings_values = $this->get_settings_values();
253
+ $template = forminator_addon_activecampaign_dir() . 'views/settings/setup-api.php';
254
+ $template_success = forminator_addon_activecampaign_dir() . 'views/settings/setup-api-success.php';
255
+ $template_params = array(
256
+ 'error_message' => '',
257
+ 'api_url' => '',
258
+ 'api_url_error' => '',
259
+ 'api_key' => '',
260
+ 'api_key_error' => '',
261
+ );
262
+ $has_errors = false;
263
+ $show_success = false;
264
+ $is_submit = ! empty( $submitted_data );
265
+
266
+ foreach ( $template_params as $key => $value ) {
267
+ if ( isset( $submitted_data[ $key ] ) ) {
268
+ $template_params[ $key ] = $submitted_data[ $key ];
269
+ } elseif ( isset( $settings_values[ $key ] ) ) {
270
+ $template_params[ $key ] = $settings_values[ $key ];
271
+ }
272
+ }
273
+
274
+
275
+ if ( $is_submit ) {
276
+ $api_url = isset( $submitted_data['api_url'] ) ? $submitted_data['api_url'] : '';
277
+ $api_key = isset( $submitted_data['api_key'] ) ? $submitted_data['api_key'] : '';
278
+
279
+ try {
280
+ $api_url = $this->validate_api_url( $api_url );
281
+ } catch ( Forminator_Addon_Activecampaign_Exception $e ) {
282
+ $template_params['api_url_error'] = $e->getMessage();
283
+ $has_errors = true;
284
+ }
285
+
286
+ try {
287
+ $api_key = $this->validate_api_key( $api_key );
288
+ } catch ( Forminator_Addon_Activecampaign_Exception $e ) {
289
+ $template_params['api_key_error'] = $e->getMessage();
290
+ $has_errors = true;
291
+ }
292
+
293
+ if ( ! $has_errors ) {
294
+ // validate api
295
+ try {
296
+
297
+ $this->validate_api( $api_url, $api_key );
298
+
299
+ if ( ! forminator_addon_is_active( $this->_slug ) ) {
300
+ $activated = Forminator_Addon_Loader::get_instance()->activate_addon( $this->_slug );
301
+ if ( ! $activated ) {
302
+ throw new Forminator_Addon_Activecampaign_Exception( Forminator_Addon_Loader::get_instance()->get_last_error_message() );
303
+ }
304
+ }
305
+
306
+ $settings_values = array(
307
+ 'api_url' => $api_url,
308
+ 'api_key' => $api_key,
309
+ );
310
+ $this->save_settings_values( $settings_values );
311
+
312
+ // no form_id its on global settings
313
+ if ( empty( $form_id ) ) {
314
+ $show_success = true;
315
+ }
316
+ } catch ( Forminator_Addon_Activecampaign_Exception $e ) {
317
+ $template_params['error_message'] = $e->getMessage();
318
+ $has_errors = true;
319
+ }
320
+ }
321
+
322
+
323
+ }
324
+
325
+ if ( $show_success ) {
326
+ $template = $template_success;
327
+ }
328
+
329
+ $buttons = array();
330
+
331
+ if ( $show_success ) {
332
+ $buttons['close'] = array(
333
+ 'markup' => self::get_button_markup( esc_html__( 'CLOSE', Forminator::DOMAIN ), 'sui-button-ghost forminator-addon-close' ),
334
+ );
335
+ } else {
336
+ if ( $this->is_connected() ) {
337
+ $buttons['disconnect'] = array(
338
+ 'markup' => self::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ), 'sui-button-ghost forminator-addon-disconnect' ),
339
+ );
340
+ $buttons['submit'] = array(
341
+ 'markup' => '<div class="sui-actions-right">' .
342
+ self::get_button_markup( esc_html__( 'SAVE', Forminator::DOMAIN ), 'forminator-addon-connect' ) .
343
+ '</div>',
344
+ );
345
+ } else {
346
+ $buttons['submit'] = array(
347
+ 'markup' => '<div class="sui-actions-right">' .
348
+ self::get_button_markup( esc_html__( 'CONNECT', Forminator::DOMAIN ), 'forminator-addon-connect' ) .
349
+ '</div>',
350
+ );
351
+ }
352
+
353
+
354
+ }
355
+
356
+ return array(
357
+ 'html' => self::get_template( $template, $template_params ),
358
+ 'buttons' => $buttons,
359
+ 'redirect' => false,
360
+ 'has_errors' => $has_errors,
361
+ );
362
+ }
363
+
364
+ public function is_api_completed() {
365
+ $setting_values = $this->get_settings_values();
366
+
367
+ // check api_key and and api_url set up
368
+ return isset( $setting_values['api_key'] ) && $setting_values['api_key'] && isset( $setting_values['api_url'] ) && ! empty( $setting_values['api_url'] );
369
+ }
370
+
371
+ /**
372
+ * Validate API URL
373
+ *
374
+ * @since 1.0 Active Campaign
375
+ *
376
+ * @param string $api_url
377
+ *
378
+ * @return string
379
+ * @throws Forminator_Addon_Activecampaign_Exception
380
+ */
381
+ public function validate_api_url( $api_url ) {
382
+ if ( empty( $api_url ) ) {
383
+ throw new Forminator_Addon_Activecampaign_Exception( __( 'Please put a valid ActiveCampaign API URL', Forminator::DOMAIN ) );
384
+ }
385
+
386
+ $api_url = wp_http_validate_url( $api_url );
387
+ if ( false === $api_url ) {
388
+ throw new Forminator_Addon_Activecampaign_Exception( __( 'Please put a valid ActiveCampaign API URL', Forminator::DOMAIN ) );
389
+ }
390
+
391
+ return $api_url;
392
+ }
393
+
394
+ /**
395
+ * Validate API Key
396
+ *
397
+ * @since 1.0 Active Campaign
398
+ *
399
+ * @param string $api_key
400
+ *
401
+ * @return string
402
+ * @throws Forminator_Addon_Activecampaign_Exception
403
+ */
404
+ public function validate_api_key( $api_key ) {
405
+ if ( empty( $api_key ) ) {
406
+ throw new Forminator_Addon_Activecampaign_Exception( __( 'Please put a valid ActiveCampaign API Key', Forminator::DOMAIN ) );
407
+ }
408
+
409
+ return $api_key;
410
+ }
411
+
412
+ /**
413
+ * Validate API
414
+ *
415
+ * @since 1.0 Active Campaign Addon
416
+ *
417
+ * @param $api_url
418
+ * @param $api_key
419
+ *
420
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Exception
421
+ * @throws Forminator_Addon_Activecampaign_Exception
422
+ */
423
+ public function validate_api( $api_url, $api_key ) {
424
+ self::$api = null;
425
+ $api = $this->get_api( $api_url, $api_key );
426
+
427
+ $account_request = $api->get_account();
428
+
429
+ if ( ! isset( $account_request->account ) || empty( $account_request->account ) ) {
430
+ throw new Forminator_Addon_Activecampaign_Exception( __( 'Failed to get ActiveCampaign account info.', Forminator::DOMAIN ) );
431
+ }
432
+
433
+ $this->connected_account = $account_request->account;
434
+ }
435
+
436
+ /**
437
+ * Get API Instance
438
+ *
439
+ * @since 1.0 Active Campaign Addon
440
+ *
441
+ * @param null $api_url
442
+ * @param null $api_key
443
+ *
444
+ * @return Forminator_Addon_Activecampaign_Wp_Api
445
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Exception
446
+ */
447
+ public function get_api( $api_url = null, $api_key = null ) {
448
+ if ( is_null( self::$api ) ) {
449
+ if ( is_null( $api_key ) || is_null( $api_url ) ) {
450
+ $setting_values = $this->get_settings_values();
451
+ $api_key = '';
452
+ $api_url = '';
453
+ if ( isset( $setting_values['api_url'] ) ) {
454
+ $api_url = $setting_values['api_url'];
455
+ }
456
+
457
+ if ( isset( $setting_values['api_key'] ) ) {
458
+ $api_key = $setting_values['api_key'];
459
+ }
460
+
461
+ }
462
+ $api = new Forminator_Addon_Activecampaign_Wp_Api( $api_url, $api_key );
463
+ self::$api = $api;
464
+ }
465
+
466
+ return self::$api;
467
+ }
468
+
469
+ public function before_save_settings_values( $values ) {
470
+ if ( ! empty( $this->connected_account ) ) {
471
+ $values['connected_account'] = $this->connected_account;
472
+ }
473
+
474
+ return $values;
475
+ }
476
+
477
+ }
addons/pro/activecampaign/lib/class-wp-activecampaign-api-exception.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Activecampaign_Wp_Api_Exception
5
+ * Exception holder for Activecampaign wp api
6
+ *
7
+ * @since 1.0 Activecampaign Addon
8
+ */
9
+ class Forminator_Addon_Activecampaign_Wp_Api_Exception extends Forminator_Addon_Activecampaign_Exception {
10
+ }
addons/pro/activecampaign/lib/class-wp-activecampaign-api-not-found-exception.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Activecampaign_Wp_Api_Not_Found_Exception
5
+ * Exception holder for activecampaign wp api on 404 not found error status
6
+ *
7
+ * @since 1.0 Activecampaign Addon
8
+ */
9
+ class Forminator_Addon_Activecampaign_Wp_Api_Not_Found_Exception extends Forminator_Addon_Activecampaign_Wp_Api_Exception {
10
+ }
addons/pro/activecampaign/lib/class-wp-activecampaign-api.php ADDED
@@ -0,0 +1,496 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once dirname( __FILE__ ) . '/class-wp-activecampaign-api-exception.php';
4
+ require_once dirname( __FILE__ ) . '/class-wp-activecampaign-api-not-found-exception.php';
5
+
6
+ /**
7
+ * Class Forminator_Addon_Activecampaign_Wp_Api
8
+ */
9
+ class Forminator_Addon_Activecampaign_Wp_Api {
10
+
11
+ /**
12
+ * Activecampaign endpoint of api
13
+ *
14
+ * @var string
15
+ */
16
+ private $_endpoint = '';
17
+
18
+ /**
19
+ * Activecampaign API Key api
20
+ *
21
+ * @var string
22
+ */
23
+ private $_api_key = '';
24
+
25
+ /**
26
+ * Last data sent to activecampaign
27
+ *
28
+ * @since 1.0 Activecampaign Addon
29
+ * @var array
30
+ */
31
+ private $_last_data_sent = array();
32
+
33
+ /**
34
+ * Last data received from activecampaign
35
+ *
36
+ * @since 1.0 Activecampaign Addon
37
+ * @var array
38
+ */
39
+ private $_last_data_received = array();
40
+
41
+ /**
42
+ * Last URL requested
43
+ *
44
+ * @since 1.0 Activecampaign Addon
45
+ * @var string
46
+ */
47
+ private $_last_url_request = '';
48
+
49
+ /**
50
+ * Forminator_Addon_Activecampaign_Wp_Api constructor.
51
+ *
52
+ * @since 1.0 Activecampaign Addon
53
+ *
54
+ * @param string $_endpoint
55
+ *
56
+ * @param string $_api_key
57
+ *
58
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Exception
59
+ */
60
+ public function __construct( $_endpoint, $_api_key ) {
61
+ //prerequisites
62
+ if ( ! $_endpoint ) {
63
+ throw new Forminator_Addon_Activecampaign_Wp_Api_Exception( __( 'Missing required API URL', Forminator::DOMAIN ) );
64
+ }
65
+
66
+ if ( ! $_api_key ) {
67
+ throw new Forminator_Addon_Activecampaign_Wp_Api_Exception( __( 'Missing required API KEY', Forminator::DOMAIN ) );
68
+ }
69
+
70
+ $this->_endpoint = $_endpoint;
71
+ $this->_api_key = $_api_key;
72
+ }
73
+
74
+ /**
75
+ * Add custom user agent on request
76
+ *
77
+ * @since 1.0 Activecampaign Addon
78
+ *
79
+ * @param $user_agent
80
+ *
81
+ * @return string
82
+ */
83
+ public function filter_user_agent( $user_agent ) {
84
+ $user_agent .= ' ForminatorActivecampaign/' . FORMINATOR_ADDON_ACTIVECAMPAIGN_VERSION;
85
+
86
+ /**
87
+ * Filter user agent to be used by activecampaign api
88
+ *
89
+ * @since 1.1
90
+ *
91
+ * @param string $user_agent current user agent
92
+ */
93
+ $user_agent = apply_filters( 'forminator_addon_activecampaign_api_user_agent', $user_agent );
94
+
95
+ return $user_agent;
96
+ }
97
+
98
+ /**
99
+ * HTTP Request
100
+ *
101
+ * @since 1.0 Activecampaign Addon
102
+ *
103
+ * @param string $verb
104
+ * @param $path
105
+ * @param array $args
106
+ *
107
+ * @return array|mixed|object
108
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Exception
109
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Not_Found_Exception
110
+ */
111
+ private function _request( $verb = 'GET', $path, $args = array() ) {
112
+ // Adding extra user agent for wp remote request
113
+ add_filter( 'http_headers_useragent', array( $this, 'filter_user_agent' ) );
114
+
115
+ $url = trailingslashit( $this->_endpoint ) . $path;
116
+
117
+ /**
118
+ * Filter activecampaign url to be used on sending api request
119
+ *
120
+ * @since 1.1
121
+ *
122
+ * @param string $url full url with scheme
123
+ * @param string $verb `GET` `POST` `PUT` `DELETE` `PATCH`
124
+ * @param string $path requested path resource
125
+ * @param array $args argument sent to this function
126
+ */
127
+ $url = apply_filters( 'forminator_addon_activecampaign_api_url', $url, $verb, $path, $args );
128
+
129
+ $this->_last_url_request = $url;
130
+
131
+ $headers = array(
132
+ 'Content-Type' => 'application/x-www-form-urlencoded',
133
+ );
134
+
135
+ /**
136
+ * Filter activecampaign headers to sent on api request
137
+ *
138
+ * @since 1.1
139
+ *
140
+ * @param array $headers
141
+ * @param string $verb `GET` `POST` `PUT` `DELETE` `PATCH`
142
+ * @param string $path requested path resource
143
+ * @param array $args argument sent to this function
144
+ */
145
+ $headers = apply_filters( 'forminator_addon_activecampaign_api_request_headers', $headers, $verb, $path, $args );
146
+
147
+ $_args = array(
148
+ 'method' => $verb,
149
+ 'headers' => $headers,
150
+ );
151
+
152
+ $request_data = $args;
153
+ /**
154
+ * Filter activecampaign request data to be used on sending api request
155
+ *
156
+ * @since 1.1
157
+ *
158
+ * @param array $request_data it will be `http_build_query`-ed when `GET` or `wp_json_encode`-ed otherwise
159
+ * @param string $verb `GET` `POST` `PUT` `DELETE` `PATCH`
160
+ * @param string $path requested path resource
161
+ */
162
+ $args = apply_filters( 'forminator_addon_activecampaign_api_request_data', $request_data, $verb, $path );
163
+
164
+ if ( 'GET' === $verb ) {
165
+ $url .= ( '?' . http_build_query( $args ) );
166
+ } else {
167
+ $_args['body'] = $args;
168
+ }
169
+
170
+ $this->_last_data_sent = $args;
171
+
172
+ $res = wp_remote_request( $url, $_args );
173
+ $wp_response = $res;
174
+
175
+ remove_filter( 'http_headers_useragent', array( $this, 'filter_user_agent' ) );
176
+
177
+ if ( is_wp_error( $res ) || ! $res ) {
178
+ forminator_addon_maybe_log( __METHOD__, $res );
179
+ throw new Forminator_Addon_Activecampaign_Wp_Api_Exception(
180
+ __( 'Failed to process request, make sure your API URL and API KEY are correct and your server has internet connection.', Forminator::DOMAIN )
181
+ );
182
+ }
183
+
184
+ if ( isset( $res['response']['code'] ) ) {
185
+ $status_code = $res['response']['code'];
186
+ $msg = '';
187
+ if ( $status_code > 400 ) {
188
+ if ( isset( $res['response']['message'] ) ) {
189
+ $msg = $res['response']['message'];
190
+ }
191
+
192
+ if ( 404 === $status_code ) {
193
+ throw new Forminator_Addon_Activecampaign_Wp_Api_Not_Found_Exception( sprintf( __( 'Failed to processing request : %s', Forminator::DOMAIN ), $msg ) );
194
+ }
195
+ // /* translators: ... */
196
+ throw new Forminator_Addon_Activecampaign_Wp_Api_Exception( sprintf( __( 'Failed to processing request : %s', Forminator::DOMAIN ), $msg ) );
197
+ }
198
+ }
199
+
200
+ $body = wp_remote_retrieve_body( $res );
201
+
202
+ // probably silent mode
203
+ if ( ! empty( $body ) ) {
204
+ $res = json_decode( $body );
205
+
206
+ // auto validate
207
+ if ( ! empty( $res ) ) {
208
+ if ( ! isset( $res->result_code ) || 1 !== $res->result_code ) {
209
+ $message = '';
210
+ if ( isset( $res->result_message ) && ! empty( $res->result_message ) ) {
211
+ $message = ' ' . $res->result_message;
212
+ }
213
+ throw new Forminator_Addon_Activecampaign_Wp_Api_Exception( sprintf( __( 'Failed to get ActiveCampaign data.%1$s', Forminator::DOMAIN ), $message ) );
214
+ }
215
+ }
216
+ }
217
+
218
+ $response = $res;
219
+ /**
220
+ * Filter activecampaign api response returned to addon
221
+ *
222
+ * @since 1.1
223
+ *
224
+ * @param mixed $response original wp remote request response or decoded body if available
225
+ * @param string $body original content of http response's body
226
+ * @param array|WP_Error $wp_response original wp remote request response
227
+ */
228
+ $res = apply_filters( 'forminator_addon_activecampaign_api_response', $response, $body, $wp_response );
229
+
230
+ $this->_last_data_received = $res;
231
+
232
+ forminator_addon_maybe_log( $res );
233
+
234
+ return $res;
235
+ }
236
+
237
+
238
+ /**
239
+ * Send data to activecampaign API URL
240
+ *
241
+ * @since 1.0 Activecampaign Addon
242
+ *
243
+ * @param $args
244
+ *
245
+ * @return array|mixed|object
246
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Exception
247
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Not_Found_Exception
248
+ */
249
+ public function post_( $args ) {
250
+
251
+ return $this->_request(
252
+ 'POST',
253
+ '',
254
+ $args
255
+ );
256
+ }
257
+
258
+ /**
259
+ * Get Account Detail
260
+ *
261
+ * @since 1.0 Activecampaign Addon
262
+ *
263
+ * @return array|mixed|object
264
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Exception
265
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Not_Found_Exception
266
+ */
267
+ public function get_account() {
268
+
269
+ return $this->_request(
270
+ 'GET',
271
+ '/admin/api.php',
272
+ array(
273
+ 'api_action' => 'account_view',
274
+ 'api_key' => $this->_api_key,
275
+ 'api_output' => 'json',
276
+ )
277
+ );
278
+ }
279
+
280
+ /**
281
+ * Get Lists
282
+ *
283
+ * @since 1.0 Activecampaign Addon
284
+ *
285
+ * @param array $args
286
+ *
287
+ * @return array|mixed|object
288
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Exception
289
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Not_Found_Exception
290
+ */
291
+ public function get_lists( $args = array() ) {
292
+
293
+ $default_args = array(
294
+ 'api_action' => 'list_list',
295
+ 'api_key' => $this->_api_key,
296
+ 'api_output' => 'json',
297
+ 'ids' => 'all',
298
+ 'global_fields' => 0,
299
+ 'full' => 1,
300
+ );
301
+
302
+ $args = array_merge( $default_args, $args );
303
+
304
+ $request_data = $this->_request(
305
+ 'GET',
306
+ '/admin/api.php',
307
+ $args
308
+ );
309
+
310
+ return self::get_collection_from_request_result( $request_data );
311
+ }
312
+
313
+ /**
314
+ * Get List Detail
315
+ *
316
+ * @param $id
317
+ * @param array $args
318
+ *
319
+ * @return array|mixed|object
320
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Exception
321
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Not_Found_Exception
322
+ */
323
+ public function get_list( $id, $args = array() ) {
324
+ $default_args = array(
325
+ 'api_action' => 'list_view',
326
+ 'api_key' => $this->_api_key,
327
+ 'api_output' => 'json',
328
+ 'id' => $id,
329
+ );
330
+
331
+ $args = array_merge( $default_args, $args );
332
+
333
+ return $this->_request(
334
+ 'GET',
335
+ '/admin/api.php',
336
+ $args
337
+ );
338
+ }
339
+
340
+ /**
341
+ * Get created Forms
342
+ *
343
+ * @param array $args
344
+ *
345
+ * @return array|mixed|object
346
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Exception
347
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Not_Found_Exception
348
+ */
349
+ public function get_forms( $args = array() ) {
350
+ $default_args = array(
351
+ 'api_action' => 'form_getforms',
352
+ 'api_key' => $this->_api_key,
353
+ 'api_output' => 'json',
354
+ );
355
+
356
+ $args = array_merge( $default_args, $args );
357
+
358
+ $request_data = $this->_request(
359
+ 'GET',
360
+ '/admin/api.php',
361
+ $args
362
+ );
363
+
364
+ return self::get_collection_from_request_result( $request_data );
365
+ }
366
+
367
+ /**
368
+ * Sync Contact
369
+ *
370
+ * Add or edit a contact based on their email address.
371
+ * Instead of calling contact_view to check if the contact exists, and then calling contact_add or
372
+ * contact_edit, you can make just one call and include only the information you want added or updated.
373
+ *
374
+ * @param array $args
375
+ *
376
+ * @return array|mixed|object
377
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Exception
378
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Not_Found_Exception
379
+ */
380
+ public function contact_sync( $args = array() ) {
381
+ $query_args = array(
382
+ 'api_action' => 'contact_sync',
383
+ 'api_key' => $this->_api_key,
384
+ 'api_output' => 'json',
385
+ );
386
+
387
+ $default_args = array(
388
+ 'email' => '',
389
+ );
390
+
391
+ $args = array_merge( $default_args, $args );
392
+
393
+ if ( empty( $args['email'] ) ) {
394
+ throw new Forminator_Addon_Activecampaign_Wp_Api_Exception( __( 'Required email parameter not set', Forminator::DOMAIN ) );
395
+ }
396
+
397
+ return $this->_request(
398
+ 'POST',
399
+ '/admin/api.php' . ( '?' . http_build_query( $query_args ) ),
400
+ $args
401
+ );
402
+
403
+ }
404
+
405
+ /**
406
+ * Delete Contact
407
+ *
408
+ * Allows you to delete an existing contact from the ActiveCampaign system.
409
+ *
410
+ * @param array $args
411
+ *
412
+ * @return array|mixed|object
413
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Exception
414
+ * @throws Forminator_Addon_Activecampaign_Wp_Api_Not_Found_Exception
415
+ */
416
+ public function contact_delete( $args = array() ) {
417
+ $default_args = array(
418
+ 'api_action' => 'contact_delete',
419
+ 'api_key' => $this->_api_key,
420
+ 'api_output' => 'json',
421
+ 'id' => '',
422
+ );
423
+
424
+ $args = array_merge( $default_args, $args );
425
+
426
+ if ( empty( $args['id'] ) ) {
427
+ throw new Forminator_Addon_Activecampaign_Wp_Api_Exception( __( 'Required id parameter not set for contact_delete.', Forminator::DOMAIN ) );
428
+ }
429
+
430
+ return $this->_request(
431
+ 'GET',
432
+ '/admin/api.php',
433
+ $args
434
+ );
435
+
436
+ }
437
+
438
+ /**
439
+ * Get last data sent
440
+ *
441
+ * @since 1.0 Activecampaign Addon
442
+ *
443
+ * @return array
444
+ */
445
+ public function get_last_data_sent() {
446
+ return $this->_last_data_sent;
447
+ }
448
+
449
+ /**
450
+ * Get last data received
451
+ *
452
+ * @since 1.0 Activecampaign Addon
453
+ *
454
+ * @return array
455
+ */
456
+ public function get_last_data_received() {
457
+ return $this->_last_data_received;
458
+ }
459
+
460
+ /**
461
+ * Get last data received
462
+ *
463
+ * @since 1.0 Activecampaign Addon
464
+ *
465
+ * @return string
466
+ */
467
+ public function get_last_url_request() {
468
+ return $this->_last_url_request;
469
+ }
470
+
471
+ /**
472
+ * Get data collection form request result
473
+ *
474
+ * @param $request_data
475
+ *
476
+ * @return array
477
+ */
478
+ public static function get_collection_from_request_result( $request_data ) {
479
+ $collection = array();
480
+ $request_data = (array) $request_data;
481
+ foreach ( $request_data as $key => $data ) {
482
+ /**
483
+ * result_code 1
484
+ * result_message Success: Something is returned
485
+ * result_output json
486
+ */
487
+ if ( stripos( $key, 'result_' ) !== false ) {
488
+ continue;
489
+ }
490
+
491
+ $collection[ $key ] = $data;
492
+ }
493
+
494
+ return $collection;
495
+ }
496
+ }
addons/pro/activecampaign/views/form-settings/map-fields.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'error_message' => '',
5
+ 'multi_id' => '',
6
+ 'fields_map' => array(),
7
+ 'fields' => array(),
8
+ 'form_fields' => array(),
9
+ 'email_fields' => array(),
10
+ );
11
+ /** @var array $template_vars */
12
+ foreach ( $template_vars as $key => $val ) {
13
+ $vars[ $key ] = $val;
14
+ }
15
+
16
+ ?>
17
+ <div class="integration-header">
18
+ <h3 class="sui-box-title" id="dialogTitle2"><?php echo esc_html( __( 'Assign Fields', Forminator::DOMAIN ) ); ?></h3>
19
+ <p><?php esc_html_e( 'Match up your form fields with your campaign fields to make sure we\'re sending data to the right place.', Forminator::DOMAIN ); ?></p>
20
+ <?php if ( ! empty( $vars['error_message'] ) ) : ?>
21
+ <span class="sui-notice sui-notice-error"><p><?php echo esc_html( $vars['error_message'] ); ?></p></span>
22
+ <?php endif; ?>
23
+ </div>
24
+ <form>
25
+ <table class="sui-table">
26
+ <thead>
27
+ <tr>
28
+ <th><?php esc_html_e( 'ActiveCampaign Field', Forminator::DOMAIN ); ?></th>
29
+ <th><?php esc_html_e( 'Forminator Field', Forminator::DOMAIN ); ?></th>
30
+ </tr>
31
+ </thead>
32
+ <tbody>
33
+ <?php foreach ( $vars['fields'] as $key => $field_title ) : ?>
34
+ <tr>
35
+ <td>
36
+ <?php echo esc_html( $field_title ); ?>
37
+ <?php if ( 'email' === $key ) : ?>
38
+ <span class="integrations-required-field">*</span>
39
+ <?php endif; ?>
40
+ </td>
41
+ <td>
42
+ <?php
43
+ $forminator_fields = $vars['form_fields'];
44
+ if ( 'email' === $key ) {
45
+ $forminator_fields = $vars['email_fields'];
46
+ }
47
+ $current_error = '';
48
+ $current_selected = '';
49
+ if ( isset( $vars[ $key . '_error' ] ) && ! empty( $vars[ $key . '_error' ] ) ) {
50
+ $current_error = $vars[ $key . '_error' ];
51
+ }
52
+ if ( isset( $vars['fields_map'][ $key ] ) && ! empty( $vars['fields_map'][ $key ] ) ) {
53
+ $current_selected = $vars['fields_map'][ $key ];
54
+ }
55
+ ?>
56
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $current_error ) ? 'sui-form-field-error' : '' ); ?>">
57
+ <label>
58
+ <select class="sui-select" name="fields_map[<?php echo esc_attr( $key ); ?>]">
59
+ <option value="">Please Select A Field</option>
60
+ <?php foreach ( $forminator_fields as $forminator_field ) : ?>
61
+ <option value="<?php echo esc_attr( $forminator_field['element_id'] ); ?>"
62
+ <?php selected( $current_selected, $forminator_field['element_id'] ); ?>>
63
+ <?php echo esc_html( $forminator_field['field_label'] . ' | ' . $forminator_field['element_id'] ); ?>
64
+ </option>
65
+ <?php endforeach; ?>
66
+ </select>
67
+ </label>
68
+ <?php if ( ! empty( $current_error ) ) : ?>
69
+ <span class="sui-error-message"><?php echo esc_html( $current_error ); ?></span>
70
+ <?php endif; ?>
71
+ </div>
72
+ </td>
73
+ </tr>
74
+ <?php endforeach; ?>
75
+ </tbody>
76
+ </table>
77
+ <input type="hidden" name="multi_id" value="<?php echo esc_attr( $vars['multi_id'] ); ?>">
78
+ </form>
addons/pro/activecampaign/views/form-settings/pick-name.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'error_message' => '',
5
+ 'name' => '',
6
+ 'name_error' => '',
7
+ 'multi_id' => '',
8
+ );
9
+ /** @var array $template_vars */
10
+ foreach ( $template_vars as $key => $val ) {
11
+ $vars[ $key ] = $val;
12
+ }
13
+
14
+ ?>
15
+ <div class="integration-header">
16
+ <h3 class="sui-box-title" id="dialogTitle2"><?php echo esc_html( __( 'Setup Name', Forminator::DOMAIN ) ); ?></h3>
17
+ <p><?php esc_html_e( 'Setup friendly name for this integration, so it will easily identified by you. ', Forminator::DOMAIN ); ?></p>
18
+ <?php if ( ! empty( $vars['error_message'] ) ) : ?>
19
+ <span class="sui-notice sui-notice-error"><p><?php echo esc_html( $vars['error_message'] ); ?></p></span>
20
+ <?php endif; ?>
21
+ </div>
22
+ <form>
23
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['name_error'] ) ? 'sui-form-field-error' : '' ); ?>">
24
+ <label class="sui-label"><?php esc_html_e( 'Name', Forminator::DOMAIN ); ?></label>
25
+ <input
26
+ class="sui-form-control"
27
+ name="name" placeholder="<?php echo esc_attr( __( 'Friendly Name', Forminator::DOMAIN ) ); ?>"
28
+ value="<?php echo esc_attr( $vars['name'] ); ?>">
29
+ <?php if ( ! empty( $vars['name_error'] ) ) : ?>
30
+ <span class="sui-error-message"><?php echo esc_html( $vars['name_error'] ); ?></span>
31
+ <?php endif; ?>
32
+ </div>
33
+ <input type="hidden" name="multi_id" value="<?php echo esc_attr( $vars['multi_id'] ); ?>">
34
+ </form>
addons/pro/activecampaign/views/form-settings/select-list.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'error_message' => '',
5
+ 'list_id' => '',
6
+ 'list_id_error' => '',
7
+ 'multi_id' => '',
8
+ 'lists' => array(),
9
+ );
10
+ /** @var array $template_vars */
11
+ foreach ( $template_vars as $key => $val ) {
12
+ $vars[ $key ] = $val;
13
+ }
14
+
15
+ ?>
16
+ <div class="integration-header">
17
+ <h3 class="sui-box-title" id="dialogTitle2"><?php echo esc_html( __( 'Choose Contact List', Forminator::DOMAIN ) ); ?></h3>
18
+ <p><?php esc_html_e( 'Pick ActiveCampaign List for new contacts to be added to.', Forminator::DOMAIN ); ?></p>
19
+ <?php if ( ! empty( $vars['error_message'] ) ) : ?>
20
+ <span class="sui-notice sui-notice-error"><p><?php echo esc_html( $vars['error_message'] ); ?></p></span>
21
+ <?php endif; ?>
22
+ </div>
23
+ <form>
24
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['list_id_error'] ) ? 'sui-form-field-error' : '' ); ?>">
25
+ <label class="sui-label"><?php esc_html_e( 'List', Forminator::DOMAIN ); ?>
26
+ <select name="list_id" class="sui-select sui-form-control">
27
+ <option><?php esc_html_e( 'Please select a list', Forminator::DOMAIN ); ?></option>
28
+ <?php foreach ( $vars['lists'] as $list_id => $list_name ) : ?>
29
+ <option value="<?php echo esc_attr( $list_id ); ?>" <?php selected( $vars['list_id'], $list_id ); ?>><?php echo esc_html( $list_name ); ?></option>
30
+ <?php endforeach; ?>
31
+ </select>
32
+ <?php if ( ! empty( $vars['list_id_error'] ) ) : ?>
33
+ <span class="sui-error-message"><?php echo esc_html( $vars['list_id_error'] ); ?></span>
34
+ <?php endif; ?>
35
+ </label>
36
+ </div>
37
+ <input type="hidden" name="multi_id" value="<?php echo esc_attr( $vars['multi_id'] ); ?>">
38
+ </form>
addons/pro/activecampaign/views/form-settings/setup-options.php ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'error_message' => '',
5
+ 'multi_id' => '',
6
+ 'tags_error' => '',
7
+ 'forms' => array(),
8
+ 'double_opt_form_id' => '',
9
+ 'double_opt_form_id_error' => '',
10
+ 'instantresponders' => 0,
11
+ 'instantresponders_error' => '',
12
+ 'lastmessage' => 0,
13
+ 'lastmessage_error' => '',
14
+ 'tags_fields' => array(),
15
+ 'tags_selected_fields' => array(),
16
+ );
17
+ /** @var array $template_vars */
18
+ foreach ( $template_vars as $key => $val ) {
19
+ $vars[ $key ] = $val;
20
+ }
21
+
22
+ ?>
23
+ <div class="integration-header">
24
+ <h3 class="sui-box-title" id="dialogTitle2"><?php echo esc_html( __( 'Additional Options', Forminator::DOMAIN ) ); ?></h3>
25
+ <p><?php esc_html_e( 'Configure additional options for ActiveCampaign integration.', Forminator::DOMAIN ); ?></p>
26
+ <?php if ( ! empty( $vars['error_message'] ) ) : ?>
27
+ <span class="sui-notice sui-notice-error"><p><?php echo esc_html( $vars['error_message'] ); ?></p></span>
28
+ <?php endif; ?>
29
+ </div>
30
+
31
+ <form>
32
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['tags_error'] ) ? 'sui-form-field-error' : '' ); ?>">
33
+ <label class="sui-label" for="tags"><?php esc_html_e( 'Tags', Forminator::DOMAIN ); ?></label>
34
+ <select class="sui-select fui-multi-select" name="tags[]" id="tags"
35
+ multiple="multiple"
36
+ data-reorder="1"
37
+ data-tags="true"
38
+ data-token-separators="[',']"
39
+ data-placeholder=""
40
+ data-allow-clear="false">
41
+ <?php foreach ( $vars['tags_selected_fields'] as $forminator_field ) : ?>
42
+ <option
43
+ value="<?php echo esc_attr( $forminator_field['element_id'] ); ?>"
44
+ selected="selected"
45
+ ><?php echo esc_html( $forminator_field['field_label'] ); ?></option>
46
+ <?php endforeach; ?>
47
+ <?php foreach ( $vars['tags_fields'] as $forminator_field ) : ?>
48
+ <option
49
+ value="{<?php echo esc_attr( $forminator_field['element_id'] ); ?>}"
50
+ ><?php echo esc_html( $forminator_field['field_label'] . ' | ' . $forminator_field['element_id'] ); ?></option>
51
+ <?php endforeach; ?>
52
+ </select>
53
+ <?php if ( ! empty( $vars['tags_error'] ) ) : ?>
54
+ <span class="sui-error-message"><?php echo esc_html( $vars['tags_error'] ); ?></span>
55
+ <?php endif; ?>
56
+ <span class="sui-description">
57
+ <?php esc_html_e( 'Tags for contact that sent to ActiveCampaign.', Forminator::DOMAIN ); ?>
58
+ </span>
59
+ </div>
60
+
61
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['double_opt_form_id_error'] ) ? 'sui-form-field-error' : '' ); ?>">
62
+ <label class="sui-label" for="double_opt_form_id"><?php esc_html_e( 'Double Opt-In Form', Forminator::DOMAIN ); ?></label>
63
+ <select name="double_opt_form_id" id="double_opt_form_id" class="sui-select sui-form-control">
64
+ <option value=""><?php esc_html_e( 'No form selected', Forminator::DOMAIN ); ?></option>
65
+ <?php foreach ( $vars['forms'] as $form_id => $form_name ) : ?>
66
+ <option value="<?php echo esc_attr( $form_id ); ?>" <?php selected( $form_id, $vars['double_opt_form_id'] ); ?>><?php echo esc_html( $form_name ); ?></option>
67
+ <?php endforeach; ?>
68
+ </select>
69
+ <?php if ( ! empty( $vars['double_opt_form_id_error'] ) ) : ?>
70
+ <span class="sui-error-message"><?php echo esc_html( $vars['double_opt_form_id_error'] ); ?></span>
71
+ <?php endif; ?>
72
+ <span class="sui-description">
73
+ <?php
74
+ esc_html_e(
75
+ 'Select which ActiveCampaign form will be used when adding to ActiveCampaign to send the opt-in email. You can read more information ',
76
+ Forminator::DOMAIN );
77
+ ?>
78
+ <a href="https://help.activecampaign.com/hc/en-us/articles/115000839230-How-do-I-enable-double-opt-in-confirmation-" target="_blank">here</a>.
79
+ </span>
80
+ </div>
81
+
82
+ <div class="sui-row">
83
+ <div class="sui-col-md-6">
84
+
85
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['instantresponders_error'] ) ? 'sui-form-field-error' : '' ); ?>">
86
+ <label class="sui-toggle">
87
+
88
+ <input type="checkbox"
89
+ name="instantresponders"
90
+ id="instantresponders"
91
+ value="1"
92
+ <?php checked( 1, $vars['instantresponders'] ); ?>>
93
+ <span class="sui-toggle-slider"></span>
94
+ </label>
95
+ <label class="sui-toggle-label" for="instantresponders"><?php esc_html_e( 'Enable Instant Responders', Forminator::DOMAIN ); ?></label>
96
+ <?php if ( ! empty( $vars['instantresponders_error'] ) ) : ?>
97
+ <span class="sui-error-message"><?php echo esc_html( $vars['instantresponders_error'] ); ?></span>
98
+ <?php endif; ?>
99
+ <span class="sui-description">
100
+ <?php
101
+ esc_html_e(
102
+ 'When the instant responders option is enabled, ActiveCampaign will send any instant responders setup when the contact is added to the list.
103
+ This option is not available to users on a free trial.',
104
+ Forminator::DOMAIN
105
+ );
106
+ ?>
107
+ </span>
108
+ </div>
109
+
110
+ </div>
111
+ <div class="sui-col-md-6">
112
+
113
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['lastmessage_error'] ) ? 'sui-form-field-error' : '' ); ?>">
114
+ <label class="sui-toggle">
115
+ <input type="checkbox"
116
+ name="lastmessage"
117
+ id="lastmessage"
118
+ value="1"
119
+ <?php checked( 1, $vars['lastmessage'] ); ?>>
120
+ <span class="sui-toggle-slider"></span>
121
+ </label>
122
+ <label class="sui-toggle-label" for="lastmessage"><?php esc_html_e( 'Send last broadcast campaign', Forminator::DOMAIN ); ?></label>
123
+ <?php if ( ! empty( $vars['lastmessage_error'] ) ) : ?>
124
+ <span class="sui-error-message"><?php echo esc_html( $vars['lastmessage_error'] ); ?></span>
125
+ <?php endif; ?>
126
+ <span class="sui-description">
127
+ <?php
128
+ esc_html_e(
129
+ 'When the send last broadcast campaign option is enabled, ActiveCampaign will send the last campaign sent out to the list to the contact being added.
130
+ This option is not available to users on a free trial.',
131
+ Forminator::DOMAIN
132
+ );
133
+ ?>
134
+ </span>
135
+ </div>
136
+
137
+ </div>
138
+ </div>
139
+
140
+ <input type="hidden" name="multi_id" value="<?php echo esc_attr( $vars['multi_id'] ); ?>">
141
+ </form>
addons/pro/activecampaign/views/settings/setup-api-success.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <div class="integration-header">
2
+ <h3 class="sui-box-title" id="dialogTitle2">
3
+ <?php echo esc_html( sprintf( __( '%1$s Added', Forminator::DOMAIN ), 'ActiveCampaign' ) ); ?>
4
+ </h3>
5
+ <p><?php esc_html_e( 'You can now go to your forms and assign them to this integration', Forminator::DOMAIN ); ?></p>
6
+ </div>
addons/pro/activecampaign/views/settings/setup-api.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'error_message' => '',
5
+ 'api_url' => '',
6
+ 'api_url_error' => '',
7
+ 'api_key' => '',
8
+ 'api_key_error' => '',
9
+ );
10
+ /** @var array $template_vars */
11
+ foreach ( $template_vars as $key => $val ) {
12
+ $vars[ $key ] = $val;
13
+ }
14
+
15
+ ?>
16
+ <div class="integration-header">
17
+ <h3 class="sui-box-title" id="dialogTitle2"><?php echo esc_html( sprintf( __( 'Configure %1$s API', Forminator::DOMAIN ), 'ActiveCampaign' ) ); ?></h3>
18
+ <p><?php esc_html_e( 'Setup ActiveCampaign API Access.', Forminator::DOMAIN ); ?></p>
19
+ <?php if ( ! empty( $vars['error_message'] ) ) : ?>
20
+ <span class="sui-notice sui-notice-error"><p><?php echo esc_html( $vars['error_message'] ); ?></p></span>
21
+ <?php endif; ?>
22
+ </div>
23
+ <form>
24
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['api_url_error'] ) ? 'sui-form-field' : '' ); ?>">
25
+ <label class="sui-label"><?php esc_html_e( 'API URL', Forminator::DOMAIN ); ?></label>
26
+ <div class="sui-field-with-icon">
27
+ <input
28
+ class="sui-form-control"
29
+ name="api_url" placeholder="<?php echo esc_attr( sprintf( __( 'Enter %1$s API URL', Forminator::DOMAIN ), 'ActiveCampaign' ) ); ?>"
30
+ value="<?php echo esc_attr( $vars['api_url'] ); ?>">
31
+ <i class="sui-icon-link" aria-hidden="true"></i>
32
+ </div>
33
+ <?php if ( ! empty( $vars['api_url_error'] ) ) : ?>
34
+ <span class="sui-error-message"><?php echo esc_html( $vars['api_url_error'] ); ?></span>
35
+ <?php endif; ?>
36
+ </div>
37
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['api_key_error'] ) ? 'sui-form-field' : '' ); ?>">
38
+ <label class="sui-label"><?php esc_html_e( 'API KEY', Forminator::DOMAIN ); ?></label>
39
+ <div class="sui-field-with-icon">
40
+ <input
41
+ class="sui-form-control"
42
+ name="api_key" placeholder="<?php echo esc_attr( sprintf( __( 'Enter %1$s API Key', Forminator::DOMAIN ), 'ActiveCampaign' ) ); ?>"
43
+ value="<?php echo esc_attr( $vars['api_key'] ); ?>">
44
+ <i class="sui-icon-key" aria-hidden="true"></i>
45
+ </div>
46
+ <?php if ( ! empty( $vars['api_key_error'] ) ) : ?>
47
+ <span class="sui-error-message"><?php echo esc_html( $vars['api_key_error'] ); ?></span>
48
+ <?php endif; ?>
49
+ </div>
50
+ </form>
addons/pro/aweber/assets/icons/aweber.png ADDED
Binary file
addons/pro/aweber/assets/icons/aweber@2x.png ADDED
Binary file
addons/pro/aweber/assets/img/aweber.png ADDED
Binary file
addons/pro/aweber/assets/img/aweber@2x.png ADDED
Binary file
addons/pro/aweber/aweber.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Addon Name: Aweber
5
+ * Version: 1.0
6
+ * Plugin URI: https://premium.wpmudev.org/
7
+ * Description: Integrate Forminator Custom Forms with Aweber to get notified in real time.
8
+ * Author: WPMU DEV
9
+ * Author URI: http://premium.wpmudev.org
10
+ */
11
+
12
+ define( 'FORMINATOR_ADDON_AWEBER_VERSION', '1.0' );
13
+
14
+ function forminator_addon_aweber_url() {
15
+ return trailingslashit( forminator_plugin_url() . 'addons/pro/aweber' );
16
+ }
17
+
18
+ function forminator_addon_aweber_dir() {
19
+ return trailingslashit( dirname( __FILE__ ) );
20
+ }
21
+
22
+ function forminator_addon_aweber_assets_url() {
23
+ return trailingslashit( forminator_addon_aweber_url() . 'assets' );
24
+ }
25
+
26
+ require_once dirname( __FILE__ ) . '/forminator-addon-aweber.php';
27
+ require_once dirname( __FILE__ ) . '/forminator-addon-aweber-form-settings.php';
28
+ require_once dirname( __FILE__ ) . '/forminator-addon-aweber-form-hooks.php';
29
+ //Direct Load
30
+ Forminator_Addon_Loader::get_instance()->register( 'Forminator_Addon_Aweber' );
addons/pro/aweber/forminator-addon-aweber-exception.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Aweber_Exception
5
+ * Not Required but encouraged
6
+ *
7
+ * @since 1.0 Aweber Addon
8
+ */
9
+ class Forminator_Addon_Aweber_Exception extends Exception {
10
+
11
+ }
addons/pro/aweber/forminator-addon-aweber-form-hooks.php ADDED
@@ -0,0 +1,792 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Aweber_Form_Hooks
5
+ *
6
+ * @since 1.0 Aweber Addon
7
+ *
8
+ */
9
+ class Forminator_Addon_Aweber_Form_Hooks extends Forminator_Addon_Form_Hooks_Abstract {
10
+
11
+ /**
12
+ * Addon instance are auto available form abstract
13
+ * Its added here for development purpose,
14
+ * Auto-complete will resolve addon directly to `Aweber` instance instead of the abstract
15
+ * And its public properties can be exposed
16
+ *
17
+ * @since 1.0 Aweber Addon
18
+ * @var Forminator_Addon_Aweber
19
+ */
20
+ protected $addon;
21
+
22
+ /**
23
+ * Form Settings Instance
24
+ *
25
+ * @since 1.0 Aweber Addon
26
+ * @var Forminator_Addon_Aweber_Form_Settings | null
27
+ */
28
+ protected $form_settings_instance;
29
+
30
+ /**
31
+ * Forminator_Addon_Aweber_Form_Hooks constructor.
32
+ *
33
+ * @since 1.0 Aweber Addon
34
+ *
35
+ * @param Forminator_Addon_Abstract $addon
36
+ * @param $form_id
37
+ *
38
+ * @throws Forminator_Addon_Exception
39
+ */
40
+ public function __construct( Forminator_Addon_Abstract $addon, $form_id ) {
41
+ parent::__construct( $addon, $form_id );
42
+ $this->_submit_form_error_message = __( 'AWeber failed to process submitted data. Please check your form and try again', Forminator::DOMAIN );
43
+ }
44
+
45
+ /**
46
+ * Save status of request sent and received for each connected AWeber Connection
47
+ *
48
+ * @since 1.0 AWeber Addon
49
+ *
50
+ * @param array $submitted_data
51
+ * @param array $form_entry_fields
52
+ *
53
+ * @return array
54
+ */
55
+ public function add_entry_fields( $submitted_data, $form_entry_fields = array() ) {
56
+
57
+ $form_id = $this->form_id;
58
+ $form_settings_instance = $this->form_settings_instance;
59
+
60
+ /**
61
+ * Filter AWeber submitted form data to be processed
62
+ *
63
+ * @since 1.3
64
+ *
65
+ * @param array $submitted_data
66
+ * @param int $form_id current Form ID
67
+ * @param Forminator_Addon_Aweber_Form_Settings $form_settings_instance AWeber Addon Form Settings instance
68
+ */
69
+ $submitted_data = apply_filters(
70
+ 'forminator_addon_aweber_form_submitted_data',
71
+ $submitted_data,
72
+ $form_id,
73
+ $form_settings_instance
74
+ );
75
+
76
+ $addon_setting_values = $this->form_settings_instance->get_form_settings_values();
77
+
78
+ $data = array();
79
+
80
+ /**
81
+ * Fires before adding subscriber to AWeber
82
+ *
83
+ * @since 1.3
84
+ *
85
+ * @param int $form_id current Form ID
86
+ * @param array $submitted_data
87
+ * @param Forminator_Addon_Aweber_Form_Settings $form_settings_instance AWeber Addon Form Settings instance
88
+ */
89
+ do_action( 'forminator_addon_aweber_before_add_subscriber', $form_id, $submitted_data, $form_settings_instance );
90
+
91
+ foreach ( $addon_setting_values as $key => $addon_setting_value ) {
92
+ // save it on entry field, with name `status-$MULTI_ID`, and value is the return result on sending data to aweber
93
+ if ( $form_settings_instance->is_multi_form_settings_complete( $key ) ) {
94
+ // exec only on completed connection
95
+ $data[] = array(
96
+ 'name' => 'status-' . $key,
97
+ 'value' => $this->get_status_on_add_subscriber( $key, $submitted_data, $addon_setting_value, $form_entry_fields ),
98
+ );
99
+ }
100
+
101
+ }
102
+
103
+ $entry_fields = $data;
104
+ /**
105
+ * Filter AWeber entry fields to be saved to entry model
106
+ *
107
+ * @since 1.3
108
+ *
109
+ * @param array $entry_fields
110
+ * @param int $form_id current Form ID
111
+ * @param array $submitted_data
112
+ * @param Forminator_Addon_Aweber_Form_Settings $form_settings_instance AWeber Addon Form Settings instance
113
+ */
114
+ $data = apply_filters(
115
+ 'forminator_addon_aweber_entry_fields',
116
+ $entry_fields,
117
+ $form_id,
118
+ $submitted_data,
119
+ $form_settings_instance
120
+ );
121
+
122
+ return $data;
123
+
124
+ }
125
+
126
+ /**
127
+ * Get status on add subscriber to AWeber
128
+ *
129
+ * @since 1.0 AWeber Addon
130
+ *
131
+ * @param $connection_id
132
+ * @param $submitted_data
133
+ * @param $connection_settings
134
+ * @param $form_entry_fields
135
+ *
136
+ * @return array `is_sent` true means its success send data to AWeber, false otherwise
137
+ */
138
+ private function get_status_on_add_subscriber( $connection_id, $submitted_data, $connection_settings, $form_entry_fields ) {
139
+ // initialize as null
140
+ $api = null;
141
+
142
+ $form_id = $this->form_id;
143
+ $form_settings_instance = $this->form_settings_instance;
144
+ $form_settings = $this->form_settings_instance->get_form_settings();
145
+
146
+ //check required fields
147
+ try {
148
+ $api = $this->addon->get_api();
149
+ $args = array();
150
+
151
+ if ( ! isset( $connection_settings['list_id'] ) ) {
152
+ throw new Forminator_Addon_Aweber_Exception( __( 'List ID not properly setup.', Forminator::DOMAIN ) );
153
+ }
154
+
155
+ $list_id = $connection_settings['list_id'];
156
+
157
+ $fields_map = $connection_settings['fields_map'];
158
+ $fields_mapper = $connection_settings['fields_mapper'];
159
+
160
+ $email_element_id = $connection_settings['fields_map']['default_field_email'];
161
+ if ( ! isset( $submitted_data[ $email_element_id ] ) || empty( $submitted_data[ $email_element_id ] ) ) {
162
+ throw new Forminator_Addon_Aweber_Exception(
163
+ sprintf(
164
+ __( 'Email Address on element %1$s not found or not filled on submitted data.', Forminator::DOMAIN ),
165
+ $email_element_id
166
+ )
167
+ );
168
+ }
169
+ $email = $submitted_data[ $email_element_id ];
170
+ $email = strtolower( trim( $email ) );
171
+ $args['email'] = $email;
172
+
173
+ //find existing subscriber first
174
+ /**
175
+ * Filter arguments to passed on to Find Subscriber AWeber API
176
+ *
177
+ * @since 1.3
178
+ *
179
+ * @param array $args
180
+ * @param int $form_id Current Form id
181
+ * @param string $connection_id ID of current connection
182
+ * @param array $submitted_data
183
+ * @param array $connection_settings current connection setting, contains options of like `name`, `list_id` etc
184
+ * @param array $form_entry_fields default entry fields of form
185
+ * @param array $form_settings Displayed Form settings
186
+ * @param Forminator_Addon_Aweber_Form_Settings $form_settings_instance AWeber Addon Form Settings instance
187
+ */
188
+ $args = apply_filters(
189
+ 'forminator_addon_aweber_find_subscriber_args',
190
+ $args,
191
+ $form_id,
192
+ $connection_id,
193
+ $submitted_data,
194
+ $connection_settings,
195
+ $form_entry_fields,
196
+ $form_settings,
197
+ $form_settings_instance
198
+ );
199
+
200
+ $subscriber_is_exist = false;
201
+ $existing_subscriber = null;
202
+
203
+ $existing_subscriber_request = $api->find_account_list_subscriber( $this->addon->get_account_id(), $list_id, $args );
204
+
205
+ if ( isset( $existing_subscriber_request->entries ) && is_array( $existing_subscriber_request->entries ) ) {
206
+ $existing_subscriber_entries = $existing_subscriber_request->entries;
207
+ if ( isset( $existing_subscriber_entries[0] ) ) {
208
+ $existing_subscriber = $existing_subscriber_entries[0];
209
+ if ( isset( $existing_subscriber->id ) ) {
210
+ $subscriber_is_exist = true;
211
+ // https://labs.aweber.com/docs/reference/1.0#subscriber_entry
212
+ // you can not modify or delete Subscribers with a status of 'unconfirmed'.
213
+ if ( isset( $existing_subscriber->status ) && 'unconfirmed' === $existing_subscriber->status ) {
214
+ throw new Forminator_Addon_Aweber_Exception( __( 'Unconfirmed subscriber can\'t be modified.', Forminator::DOMAIN ) );
215
+ }
216
+ }
217
+
218
+ }
219
+ }
220
+
221
+ // processed
222
+ unset( $fields_map['default_field_email'] );
223
+
224
+ $name_element_id = $connection_settings['fields_map']['default_field_name'];
225
+
226
+ if ( isset( $submitted_data[ $name_element_id ] ) && ! empty( $submitted_data[ $name_element_id ] ) ) {
227
+ $name = $submitted_data[ $name_element_id ];
228
+ $args['name'] = $name;
229
+ }
230
+ // processed
231
+ unset( $fields_map['default_field_name'] );
232
+
233
+ $custom_fields = array();
234
+ // process rest extra fields if available
235
+ foreach ( $fields_map as $field_id => $element_id ) {
236
+ if ( ! empty( $element_id ) ) {
237
+ if ( isset( $submitted_data[ $element_id ] ) && ! empty( $submitted_data[ $element_id ] ) ) {
238
+ $element_value = $submitted_data[ $element_id ];
239
+ if ( is_array( $element_value ) ) {
240
+ $element_value = implode( ',', $element_value );
241
+ }
242
+ if ( isset( $fields_mapper[ $field_id ] ) ) {
243
+ $custom_fields[ $fields_mapper[ $field_id ] ] = $element_value;
244
+ }
245
+ }
246
+ }
247
+ }
248
+ if ( ! empty( $custom_fields ) ) {
249
+ $args['custom_fields'] = $custom_fields;
250
+ }
251
+
252
+ if ( isset( $connection_settings['ad_tracking'] ) && ! empty( $connection_settings['ad_tracking'] ) ) {
253
+ $ad_tracking = $connection_settings['ad_tracking'];
254
+
255
+ // disable all_fields here
256
+ $ad_tracking = str_ireplace( '{all_fields}', '', $ad_tracking );
257
+ $ad_tracking = forminator_addon_replace_custom_vars( $ad_tracking, $submitted_data, $this->custom_form, $form_entry_fields, false );
258
+
259
+ /**
260
+ * Filter `ad_tracking` to passed onto API
261
+ *
262
+ * @since 1.2
263
+ *
264
+ * @param string $card_name
265
+ * @param int $form_id Current Form id
266
+ * @param string $connection_id ID of current connection
267
+ * @param array $submitted_data
268
+ * @param array $connection_settings current connection setting, contains options of like `name`, `list_id` etc
269
+ * @param array $form_entry_fields default entry fields of form
270
+ * @param array $form_settings Displayed Form settings
271
+ * @param Forminator_Addon_Aweber_Form_Settings $form_settings_instance AWeber Addon Form Settings instance
272
+ */
273
+ $ad_tracking = apply_filters(
274
+ 'forminator_addon_aweber_subscriber_ad_tracking',
275
+ $ad_tracking,
276
+ $form_id,
277
+ $connection_id,
278
+ $submitted_data,
279
+ $connection_settings,
280
+ $form_entry_fields,
281
+ $form_settings,
282
+ $form_settings_instance
283
+ );
284
+
285
+ if ( ! empty( $ad_tracking ) && is_string( $ad_tracking ) ) {
286
+ if ( strlen( $ad_tracking ) > 20 ) {
287
+ // 20 chars max
288
+ $ad_tracking = substr( $ad_tracking, 0, 20 );
289
+ }
290
+ $args['ad_tracking'] = $ad_tracking;
291
+ }
292
+
293
+ }
294
+
295
+ if ( isset( $connection_settings['tags'] ) && ! empty( $connection_settings['tags'] ) ) {
296
+ $tags = array();
297
+ foreach ( $connection_settings['tags'] as $tag ) {
298
+ if ( stripos( $tag, '{' ) === 0
299
+ && stripos( $tag, '}' ) === ( strlen( $tag ) - 1 )
300
+ ) {
301
+ // translate to value
302
+ $element_id = str_ireplace( '{', '', $tag );
303
+ $element_id = str_ireplace( '}', '', $element_id );
304
+ if ( isset( $submitted_data[ $element_id ] ) && ! empty( $submitted_data[ $element_id ] ) ) {
305
+ $element_value = $submitted_data[ $element_id ];
306
+ if ( is_array( $element_value ) ) {
307
+ $element_value = implode( ',', $element_value );
308
+ }
309
+ $tags[] = strtolower( $element_value );
310
+ }
311
+
312
+ } else {
313
+ $tags[] = strtolower( $tag );
314
+ }
315
+ }
316
+
317
+ /**
318
+ * Filter `tags` to passed onto API
319
+ *
320
+ * @since 1.2
321
+ *
322
+ * @param string $card_name
323
+ * @param int $form_id Current Form id
324
+ * @param string $connection_id ID of current connection
325
+ * @param array $submitted_data
326
+ * @param array $connection_settings current connection setting, contains options of like `name`, `list_id` etc
327
+ * @param array $form_entry_fields default entry fields of form
328
+ * @param array $form_settings Displayed Form settings
329
+ * @param Forminator_Addon_Aweber_Form_Settings $form_settings_instance AWeber Addon Form Settings instance
330
+ */
331
+ $tags = apply_filters(
332
+ 'forminator_addon_aweber_subscriber_tags',
333
+ $tags,
334
+ $form_id,
335
+ $connection_id,
336
+ $submitted_data,
337
+ $connection_settings,
338
+ $form_entry_fields,
339
+ $form_settings,
340
+ $form_settings_instance
341
+ );
342
+
343
+ if ( ! empty( $tags ) ) {
344
+ sort( $tags );
345
+ $args['tags'] = $tags;
346
+ }
347
+
348
+ }
349
+
350
+ $ip_address = Forminator_Geo::get_user_ip();
351
+
352
+ /**
353
+ * Filter `ip_address` to passed onto API
354
+ *
355
+ * @since 1.2
356
+ *
357
+ * @param string $card_name
358
+ * @param int $form_id Current Form id
359
+ * @param string $connection_id ID of current connection
360
+ * @param array $submitted_data
361
+ * @param array $connection_settings current connection setting, contains options of like `name`, `list_id` etc
362
+ * @param array $form_entry_fields default entry fields of form
363
+ * @param array $form_settings Displayed Form settings
364
+ * @param Forminator_Addon_Aweber_Form_Settings $form_settings_instance AWeber Addon Form Settings instance
365
+ */
366
+ $ip_address = apply_filters(
367
+ 'forminator_addon_aweber_subscriber_ip_address',
368
+ $ip_address,
369
+ $form_id,
370
+ $connection_id,
371
+ $submitted_data,
372
+ $connection_settings,
373
+ $form_entry_fields,
374
+ $form_settings,
375
+ $form_settings_instance
376
+ );
377
+
378
+ $args['ip_address'] = $ip_address;
379
+
380
+
381
+ if ( ! $subscriber_is_exist ) {
382
+ /**
383
+ * Filter arguments to passed on to Add Subscriber AWeber API
384
+ *
385
+ * @since 1.3
386
+ *
387
+ * @param array $args
388
+ * @param int $form_id Current Form id
389
+ * @param string $connection_id ID of current connection
390
+ * @param array $submitted_data
391
+ * @param array $connection_settings current connection setting, contains options of like `name`, `list_id` etc
392
+ * @param array $form_entry_fields default entry fields of form
393
+ * @param array $form_settings Displayed Form settings
394
+ * @param Forminator_Addon_Aweber_Form_Settings $form_settings_instance AWeber Addon Form Settings instance
395
+ */
396
+ $args = apply_filters(
397
+ 'forminator_addon_aweber_add_subscriber_args',
398
+ $args,
399
+ $form_id,
400
+ $connection_id,
401
+ $submitted_data,
402
+ $connection_settings,
403
+ $form_entry_fields,
404
+ $form_settings,
405
+ $form_settings_instance
406
+ );
407
+ $api->add_account_list_subscriber( $this->addon->get_account_id(), $list_id, $args );
408
+ } else {
409
+ /**
410
+ * This will only update information
411
+ * subscribed, unconfirmed, unsubscribed status wont be updated
412
+ * use hooks @see forminator_addon_aweber_update_subscriber_args, if needed
413
+ */
414
+ // update if exist
415
+ $current_tags = array();
416
+ if ( isset( $existing_subscriber->tags ) && is_array( $existing_subscriber->tags ) ) {
417
+ $current_tags = $existing_subscriber->tags;
418
+ }
419
+
420
+ if ( ! isset( $args['tags'] ) ) {
421
+ $args['tags'] = array();
422
+ }
423
+
424
+ $add_tags = array_diff( $args['tags'], $current_tags );
425
+ $remove_tags = array_diff( $current_tags, $args['tags'] );
426
+
427
+ sort( $add_tags );
428
+ sort( $remove_tags );
429
+
430
+ $new_tags = array(
431
+ 'add' => $add_tags,
432
+ 'remove' => $remove_tags,
433
+ );
434
+
435
+
436
+ $args['tags'] = $new_tags;
437
+
438
+ /**
439
+ * Filter arguments to passed on to Add Subscriber AWeber API
440
+ *
441
+ * @since 1.3
442
+ *
443
+ * @param array $args
444
+ * @param int $form_id Current Form id
445
+ * @param string $connection_id ID of current connection
446
+ * @param array $submitted_data
447
+ * @param array $connection_settings current connection setting, contains options of like `name`, `list_id` etc
448
+ * @param array $form_entry_fields default entry fields of form
449
+ * @param array $form_settings Displayed Form settings
450
+ * @param Forminator_Addon_Aweber_Form_Settings $form_settings_instance AWeber Addon Form Settings instance
451
+ */
452
+ $args = apply_filters(
453
+ 'forminator_addon_aweber_update_subscriber_args',
454
+ $args,
455
+ $form_id,
456
+ $connection_id,
457
+ $submitted_data,
458
+ $connection_settings,
459
+ $form_entry_fields,
460
+ $form_settings,
461
+ $form_settings_instance
462
+ );
463
+ $api->update_account_list_subscriber( $this->addon->get_account_id(), $list_id, $existing_subscriber->id, $args );
464
+ }
465
+
466
+ return array(
467
+ 'is_sent' => true,
468
+ 'connection_name' => $connection_settings['name'],
469
+ 'description' => __( 'Successfully send data to AWeber', Forminator::DOMAIN ),
470
+ 'data_sent' => $api->get_last_data_sent(),
471
+ 'data_received' => $api->get_last_data_received(),
472
+ 'url_request' => $api->get_last_url_request(),
473
+ 'list_id' => $list_id, // for delete reference
474
+ );
475
+
476
+ } catch ( Forminator_Addon_Aweber_Exception $e ) {
477
+ $addon_entry_fields = array(
478
+ 'is_sent' => false,
479
+ 'description' => $e->getMessage(),
480
+ 'connection_name' => $connection_settings['name'],
481
+ 'data_sent' => ( ( $api instanceof Forminator_Addon_Aweber_Wp_Api ) ? $api->get_last_data_sent() : array() ),
482
+ 'data_received' => ( ( $api instanceof Forminator_Addon_Aweber_Wp_Api ) ? $api->get_last_data_received() : array() ),
483
+ 'url_request' => ( ( $api instanceof Forminator_Addon_Aweber_Wp_Api ) ? $api->get_last_url_request() : '' ),
484
+ );
485
+
486
+ return $addon_entry_fields;
487
+ }
488
+ }
489
+
490
+ /**
491
+ * It wil add new row on entry table of submission page, with couple of subentries
492
+ * subentries included are defined in @see Forminator_Addon_Aweber_Form_Hooks::get_additional_entry_item()
493
+ *
494
+ * @since 1.0 AWeber Addon
495
+ *
496
+ * @param Forminator_Form_Entry_Model $entry_model
497
+ * @param $addon_meta_data
498
+ *
499
+ * @return array
500
+ */
501
+ public function on_render_entry( Forminator_Form_Entry_Model $entry_model, $addon_meta_data ) {
502
+
503
+ $form_id = $this->form_id;
504
+ $form_settings_instance = $this->form_settings_instance;
505
+
506
+ /**
507
+ *
508
+ * Filter active metadata that previously saved on db to be processed
509
+ *
510
+ * @since 1.3
511
+ *
512
+ * @param array $addon_meta_data
513
+ * @param int $form_id current Form ID
514
+ * @param Forminator_Addon_Aweber_Form_Settings $form_settings_instance AWeber Addon Form Settings instance
515
+ */
516
+ $addon_meta_data = apply_filters(
517
+ 'forminator_addon_aweber_metadata',
518
+ $addon_meta_data,
519
+ $form_id,
520
+ $form_settings_instance
521
+ );
522
+
523
+ $addon_meta_datas = $addon_meta_data;
524
+ if ( ! isset( $addon_meta_data[0] ) || ! is_array( $addon_meta_data[0] ) ) {
525
+ return array();
526
+ }
527
+
528
+ return $this->on_render_entry_multi_connection( $addon_meta_datas );
529
+
530
+ }
531
+
532
+ /**
533
+ * Loop through addon meta data on multiple AWeber(s)
534
+ *
535
+ * @since 1.0 AWeber Addon
536
+ *
537
+ * @param $addon_meta_datas
538
+ *
539
+ * @return array
540
+ */
541
+ private function on_render_entry_multi_connection( $addon_meta_datas ) {
542
+ $additional_entry_item = array();
543
+ foreach ( $addon_meta_datas as $addon_meta_data ) {
544
+ $additional_entry_item[] = $this->get_additional_entry_item( $addon_meta_data );
545
+ }
546
+
547
+ return $additional_entry_item;
548
+
549
+ }
550
+
551
+ /**
552
+ * Format additional entry item as label and value arrays
553
+ *
554
+ * - Integration Name : its defined by user when they adding AWeber integration on their form
555
+ * - Sent To AWeber : will be Yes/No value, that indicates whether sending data to AWeber was successful
556
+ * - Info : Text that are generated by addon when building and sending data to AWeber @see Forminator_Addon_Aweber_Form_Hooks::add_entry_fields()
557
+ * - Below subentries will be added if full log enabled, @see Forminator_Addon_Aweber::is_show_full_log() @see FORMINATOR_ADDON_AWEBER_SHOW_FULL_LOG
558
+ * - API URL : URL that wes requested when sending data to AWeber
559
+ * - Data sent to AWeber : encoded body request that was sent
560
+ * - Data received from AWeber : json encoded body response that was received
561
+ *
562
+ * @param $addon_meta_data
563
+ *
564
+ * @since 1.0 AWeber Addon
565
+ * @return array
566
+ */
567
+ private function get_additional_entry_item( $addon_meta_data ) {
568
+
569
+ if ( ! isset( $addon_meta_data['value'] ) || ! is_array( $addon_meta_data['value'] ) ) {
570
+ return array();
571
+ }
572
+ $status = $addon_meta_data['value'];
573
+ $additional_entry_item = array(
574
+ 'label' => __( 'AWeber Integration', Forminator::DOMAIN ),
575
+ 'value' => '',
576
+ );
577
+
578
+
579
+ $sub_entries = array();
580
+ if ( isset( $status['connection_name'] ) ) {
581
+ $sub_entries[] = array(
582
+ 'label' => __( 'Integration Name', Forminator::DOMAIN ),
583
+ 'value' => $status['connection_name'],
584
+ );
585
+ }
586
+
587
+ if ( isset( $status['is_sent'] ) ) {
588
+ $is_sent = true === $status['is_sent'] ? __( 'Yes', Forminator::DOMAIN ) : __( 'No', Forminator::DOMAIN );
589
+ $sub_entries[] = array(
590
+ 'label' => __( 'Sent To AWeber', Forminator::DOMAIN ),
591
+ 'value' => $is_sent,
592
+ );
593
+ }
594
+
595
+ if ( isset( $status['description'] ) ) {
596
+ $sub_entries[] = array(
597
+ 'label' => __( 'Info', Forminator::DOMAIN ),
598
+ 'value' => $status['description'],
599
+ );
600
+ }
601
+
602
+ if ( Forminator_Addon_Aweber::is_show_full_log() ) {
603
+ // too long to be added on entry data enable this with `define('FORMINATOR_ADDON_AWEBER_SHOW_FULL_LOG', true)`
604
+ if ( isset( $status['url_request'] ) ) {
605
+ $sub_entries[] = array(
606
+ 'label' => __( 'API URL', Forminator::DOMAIN ),
607
+ 'value' => $status['url_request'],
608
+ );
609
+ }
610
+
611
+ if ( isset( $status['data_sent'] ) ) {
612
+ $sub_entries[] = array(
613
+ 'label' => __( 'Data sent to AWeber', Forminator::DOMAIN ),
614
+ 'value' => '<pre class="sui-code-snippet">' . wp_json_encode( $status['data_sent'], JSON_PRETTY_PRINT ) . '</pre>',
615
+ );
616
+ }
617
+
618
+ if ( isset( $status['data_received'] ) ) {
619
+ $sub_entries[] = array(
620
+ 'label' => __( 'Data received from AWeber', Forminator::DOMAIN ),
621
+ 'value' => '<pre class="sui-code-snippet">' . wp_json_encode( $status['data_received'], JSON_PRETTY_PRINT ) . '</pre>',
622
+ );
623
+ }
624
+ }
625
+
626
+ $additional_entry_item['sub_entries'] = $sub_entries;
627
+
628
+ // return single array
629
+ return $additional_entry_item;
630
+ }
631
+
632
+ /**
633
+ * AWeber will add a column on the title/header row
634
+ * its called `AWeber Info` which can be translated on forminator lang
635
+ *
636
+ * @since 1.0 AWeber Addon
637
+ * @return array
638
+ */
639
+ public function on_export_render_title_row() {
640
+
641
+ $export_headers = array(
642
+ 'info' => __( 'AWeber Info', Forminator::DOMAIN ),
643
+ );
644
+
645
+ $form_id = $this->form_id;
646
+ $form_settings_instance = $this->form_settings_instance;
647
+
648
+ /**
649
+ * Filter AWeber headers on export file
650
+ *
651
+ * @since 1.3
652
+ *
653
+ * @param array $export_headers headers to be displayed on export file
654
+ * @param int $form_id current Form ID
655
+ * @param Forminator_Addon_Aweber_Form_Settings $form_settings_instance AWeber Addon Form Settings instance
656
+ */
657
+ $export_headers = apply_filters(
658
+ 'forminator_addon_aweber_export_headers',
659
+ $export_headers,
660
+ $form_id,
661
+ $form_settings_instance
662
+ );
663
+
664
+ return $export_headers;
665
+ }
666
+
667
+ /**
668
+ * AWeber will add a column that give user information whether sending data to AWeber successfully or not
669
+ * It will only add one column even its multiple connection, every connection will be separated by comma
670
+ *
671
+ * @since 1.0 AWeber Addon
672
+ *
673
+ * @param Forminator_Form_Entry_Model $entry_model
674
+ * @param $addon_meta_data
675
+ *
676
+ * @return array
677
+ */
678
+ public function on_export_render_entry( Forminator_Form_Entry_Model $entry_model, $addon_meta_data ) {
679
+
680
+ $form_id = $this->form_id;
681
+ $form_settings_instance = $this->form_settings_instance;
682
+
683
+ /**
684
+ *
685
+ * Filter AWeber metadata that previously saved on db to be processed
686
+ *
687
+ * @since 1.3
688
+ *
689
+ * @param array $addon_meta_data
690
+ * @param int $form_id current Form ID
691
+ * @param Forminator_Addon_Aweber_Form_Settings $form_settings_instance AWeber Form Settings instance
692
+ */
693
+ $addon_meta_data = apply_filters(
694
+ 'forminator_addon_aweber_metadata',
695
+ $addon_meta_data,
696
+ $form_id,
697
+ $form_settings_instance
698
+ );
699
+
700
+ $export_columns = array(
701
+ 'info' => $this->get_from_addon_meta_data( $addon_meta_data, 'description', '' ),
702
+ );
703
+
704
+ /**
705
+ * Filter AWeber columns to be displayed on export submissions
706
+ *
707
+ * @since 1.3
708
+ *
709
+ * @param array $export_columns column to be exported
710
+ * @param int $form_id current Form ID
711
+ * @param Forminator_Form_Entry_Model $entry_model Form Entry Model
712
+ * @param array $addon_meta_data meta data saved by addon on entry fields
713
+ * @param Forminator_Addon_Aweber_Form_Settings $form_settings_instance AWeber Addon Form Settings instance
714
+ */
715
+ $export_columns = apply_filters(
716
+ 'forminator_addon_aweber_export_columns',
717
+ $export_columns,
718
+ $form_id,
719
+ $entry_model,
720
+ $addon_meta_data,
721
+ $form_settings_instance
722
+ );
723
+
724
+ return $export_columns;
725
+ }
726
+
727
+ /**
728
+ * Get Addon meta data, will be recursive if meta data is multiple because of multiple connection added
729
+ *
730
+ * @since 1.0 AWeber Addon
731
+ *
732
+ * @param $addon_meta_data
733
+ * @param $key
734
+ * @param string $default
735
+ *
736
+ * @return string
737
+ */
738
+ private function get_from_addon_meta_data( $addon_meta_data, $key, $default = '' ) {
739
+ $addon_meta_datas = $addon_meta_data;
740
+ if ( ! isset( $addon_meta_data[0] ) || ! is_array( $addon_meta_data[0] ) ) {
741
+ return $default;
742
+ }
743
+
744
+ $addon_meta_data = $addon_meta_data[0];
745
+
746
+ // make sure its `status`, because we only add this
747
+ if ( 'status' !== $addon_meta_data['name'] ) {
748
+ if ( stripos( $addon_meta_data['name'], 'status-' ) === 0 ) {
749
+ $meta_data = array();
750
+ foreach ( $addon_meta_datas as $addon_meta_data ) {
751
+ // make it like single value so it will be processed like single meta data
752
+ $addon_meta_data['name'] = 'status';
753
+
754
+ // add it on an array for next recursive process
755
+ $meta_data[] = $this->get_from_addon_meta_data( array( $addon_meta_data ), $key, $default );
756
+ }
757
+
758
+ return implode( ', ', $meta_data );
759
+ }
760
+
761
+ return $default;
762
+
763
+ }
764
+
765
+ if ( ! isset( $addon_meta_data['value'] ) || ! is_array( $addon_meta_data['value'] ) ) {
766
+ return $default;
767
+ }
768
+ $status = $addon_meta_data['value'];
769
+ if ( isset( $status[ $key ] ) ) {
770
+ $connection_name = '';
771
+ if ( 'connection_name' !== $key ) {
772
+ if ( isset( $status['connection_name'] ) ) {
773
+ $connection_name = '[' . $status['connection_name'] . '] ';
774
+ }
775
+ }
776
+
777
+ return $connection_name . $status[ $key ];
778
+ }
779
+
780
+ return $default;
781
+ }
782
+
783
+ // /**
784
+ // * DELETE NOT SUPPORTED HERE, BECAUSE AWEBER API NOT RETURNING SUBSCRIBER ID ON CREATE SUBSCRIBER
785
+ // *
786
+ // * @param Forminator_Form_Entry_Model $entry_model
787
+ // * @param $addon_meta_data
788
+ // */
789
+ // public function on_before_delete_entry( Forminator_Form_Entry_Model $entry_model, $addon_meta_data ) {
790
+ // parent::on_before_delete_entry( $entry_model, $addon_meta_data );
791
+ // }
792
+ }
addons/pro/aweber/forminator-addon-aweber-form-settings-exception.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Aweber_Form_Settings_Exception
5
+ * Wrapper of Form Settings Aweber Exception
6
+ *
7
+ * @since 1.0 Aweber Addon
8
+ */
9
+ class Forminator_Addon_Aweber_Form_Settings_Exception extends Forminator_Addon_Aweber_Exception {
10
+
11
+ /**
12
+ * Holder of input exceptions
13
+ *
14
+ * @since 1.0 Aweber Addon
15
+ * @var array
16
+ */
17
+ protected $input_exceptions = array();
18
+
19
+ /**
20
+ * Forminator_Addon_Aweber_Form_Settings_Exception constructor.
21
+ *
22
+ * Useful if input_id is needed for later.
23
+ * If no input_id needed, use @see Forminator_Addon_Aweber_Exception
24
+ *
25
+ * @since 1.0 Aweber Addon
26
+ *
27
+ * @param string $message
28
+ * @param string $input_id
29
+ */
30
+ public function __construct( $message = '', $input_id = '' ) {
31
+ parent::__construct( $message, 0 );
32
+ if ( ! empty( $input_id ) ) {
33
+ $this->add_input_exception( $message, $input_id );
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Set exception message for an input
39
+ *
40
+ * @since 1.0 Aweber Addon
41
+ *
42
+ * @param $message
43
+ * @param $input_id
44
+ */
45
+ public function add_input_exception( $message, $input_id ) {
46
+ $this->input_exceptions[ $input_id ] = $message;
47
+ }
48
+
49
+ /**
50
+ * Get all input exceptions
51
+ *
52
+ * @since 1.0 Aweber Addon
53
+ * @return array
54
+ */
55
+ public function get_input_exceptions() {
56
+ return $this->input_exceptions;
57
+ }
58
+
59
+ /**
60
+ * Check if there is input_exceptions_is_available
61
+ *
62
+ * @since 1.0 Aweber Addon
63
+ * @return bool
64
+ */
65
+ public function input_exceptions_is_available() {
66
+ return count( $this->input_exceptions ) > 0;
67
+ }
68
+ }
addons/pro/aweber/forminator-addon-aweber-form-settings.php ADDED
@@ -0,0 +1,706 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once dirname( __FILE__ ) . '/forminator-addon-aweber-form-settings-exception.php';
4
+
5
+ /**
6
+ * Class Forminator_Addon_Aweber_Form_Settings
7
+ * Handle how form settings displayed and saved
8
+ *
9
+ * @since 1.0 Aweber Addon
10
+ */
11
+ class Forminator_Addon_Aweber_Form_Settings extends Forminator_Addon_Form_Settings_Abstract {
12
+
13
+ /**
14
+ * @var Forminator_Addon_Aweber
15
+ * @since 1.0 Aweber Addon
16
+ */
17
+ protected $addon;
18
+
19
+ /**
20
+ * Forminator_Addon_Aweber_Form_Settings constructor.
21
+ *
22
+ * @since 1.0 Aweber Addon
23
+ *
24
+ * @param Forminator_Addon_Abstract $addon
25
+ * @param $form_id
26
+ *
27
+ * @throws Forminator_Addon_Exception
28
+ */
29
+ public function __construct( Forminator_Addon_Abstract $addon, $form_id ) {
30
+ parent::__construct( $addon, $form_id );
31
+
32
+ $this->_update_form_settings_error_message = __(
33
+ 'Sorry, we are failed to update settings for this form, please check your form and input then try again',
34
+ Forminator::DOMAIN
35
+ );
36
+ }
37
+
38
+ /**
39
+ * Aweber Form Settings wizard
40
+ *
41
+ * @since 1.0 Aweber Addon
42
+ * @return array
43
+ */
44
+ public function form_settings_wizards() {
45
+ // numerical array steps
46
+ return array(
47
+ array(
48
+ 'callback' => array( $this, 'pick_name' ),
49
+ 'is_completed' => array( $this, 'pick_name_is_completed' ),
50
+ ),
51
+ array(
52
+ 'callback' => array( $this, 'setup_list' ),
53
+ 'is_completed' => array( $this, 'setup_list_is_completed' ),
54
+ ),
55
+ array(
56
+ 'callback' => array( $this, 'map_fields' ),
57
+ 'is_completed' => array( $this, 'map_fields_is_completed' ),
58
+ ),
59
+ //todo: allow fe to support this
60
+ // array(
61
+ // 'callback' => array( $this, 'extra_field' ),
62
+ // 'is_completed' => array( $this, 'extra_field' ),
63
+ // ),
64
+ array(
65
+ 'callback' => array( $this, 'setup_options' ),
66
+ 'is_completed' => array( $this, 'setup_options_is_completed' ),
67
+ ),
68
+ );
69
+ }
70
+
71
+ /**
72
+ * Setup Connection Name
73
+ *
74
+ * @since 1.0 AWeber Addon
75
+ *
76
+ * @param $submitted_data
77
+ *
78
+ * @return array
79
+ */
80
+ public function pick_name( $submitted_data ) {
81
+ $template = forminator_addon_aweber_dir() . 'views/form-settings/pick-name.php';
82
+
83
+ $multi_id = $this->generate_multi_id();
84
+ if ( isset( $submitted_data['multi_id'] ) ) {
85
+ $multi_id = $submitted_data['multi_id'];
86
+ }
87
+
88
+ $template_params = array(
89
+ 'name' => $this->get_multi_id_form_settings_value( $multi_id, 'name', '' ),
90
+ 'name_error' => '',
91
+ 'multi_id' => $multi_id,
92
+ );
93
+
94
+ unset( $submitted_data['multi_id'] );
95
+
96
+ $is_submit = ! empty( $submitted_data );
97
+ $has_errors = false;
98
+ if ( $is_submit ) {
99
+ $name = isset( $submitted_data['name'] ) ? $submitted_data['name'] : '';
100
+ $template_params['name'] = $name;
101
+
102
+ try {
103
+
104
+ if ( empty( $name ) ) {
105
+ throw new Forminator_Addon_Aweber_Exception( __( 'Please pick valid name' ) );
106
+ }
107
+
108
+ $time_added = $this->get_multi_id_form_settings_value( $multi_id, 'time_added', time() );
109
+ $this->save_multi_id_form_setting_values(
110
+ $multi_id,
111
+ array(
112
+ 'name' => $name,
113
+ 'time_added' => $time_added,
114
+ )
115
+ );
116
+
117
+ } catch ( Forminator_Addon_Aweber_Exception $e ) {
118
+ $template_params['name_error'] = $e->getMessage();
119
+ $has_errors = true;
120
+ }
121
+ }
122
+
123
+ $buttons = array();
124
+ if ( $this->pick_name_is_completed( array( 'multi_id' => $multi_id ) ) ) {
125
+ $buttons['disconnect']['markup'] = Forminator_Addon_Abstract::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ),
126
+ 'sui-button-ghost sui-tooltip sui-tooltip-top-center forminator-addon-form-disconnect',
127
+ esc_html__( 'Disconnect this AWeber Integration from this Form.', Forminator::DOMAIN )
128
+ );
129
+ }
130
+
131
+ $buttons['next']['markup'] = '<div class="sui-actions-right">' .
132
+ Forminator_Addon_Abstract::get_button_markup( esc_html__( 'NEXT', Forminator::DOMAIN ), 'forminator-addon-next' ) .
133
+ '</div>';
134
+
135
+ return array(
136
+ 'html' => Forminator_Addon_Abstract::get_template( $template, $template_params ),
137
+ 'buttons' => $buttons,
138
+ 'redirect' => false,
139
+ 'has_errors' => $has_errors,
140
+ );
141
+ }
142
+
143
+ /**
144
+ * Check if pick name step completed
145
+ *
146
+ * @since 1.0 AWeber Addon
147
+ *
148
+ * @param $submitted_data
149
+ *
150
+ * @return bool
151
+ */
152
+ public function pick_name_is_completed( $submitted_data ) {
153
+ $multi_id = '';
154
+ if ( isset( $submitted_data['multi_id'] ) ) {
155
+ $multi_id = $submitted_data['multi_id'];
156
+ }
157
+
158
+ if ( empty( $multi_id ) ) {
159
+ return false;
160
+ }
161
+
162
+ $name = $this->get_multi_id_form_settings_value( $multi_id, 'name', '' );
163
+
164
+ if ( empty( $name ) ) {
165
+ return false;
166
+ }
167
+
168
+ return true;
169
+ }
170
+
171
+ /**
172
+ * Setup List
173
+ *
174
+ * @since 1.0 AWeber Addon
175
+ *
176
+ * @param $submitted_data
177
+ *
178
+ * @return array
179
+ */
180
+ public function setup_list( $submitted_data ) {
181
+ $template = forminator_addon_aweber_dir() . 'views/form-settings/setup-list.php';
182
+
183
+ if ( ! isset( $submitted_data['multi_id'] ) ) {
184
+ return $this->get_force_closed_wizard( __( 'Please pick valid connection', Forminator::DOMAIN ) );
185
+ }
186
+
187
+ $multi_id = $submitted_data['multi_id'];
188
+ unset( $submitted_data['multi_id'] );
189
+
190
+ $template_params = array(
191
+ 'list_id' => $this->get_multi_id_form_settings_value( $multi_id, 'list_id', '' ),
192
+ 'list_name' => $this->get_multi_id_form_settings_value( $multi_id, 'list_name', '' ),
193
+ 'list_id_error' => '',
194
+ 'multi_id' => $multi_id,
195
+ 'error_message' => '',
196
+ );
197
+
198
+
199
+ $is_submit = ! empty( $submitted_data );
200
+ $has_errors = false;
201
+
202
+ $lists = array();
203
+
204
+ try {
205
+
206
+ $api = $this->addon->get_api();
207
+ $lists_request = $api->get_account_lists( $this->addon->get_account_id() );
208
+
209
+ if ( ! is_object( $lists_request ) || ! isset( $lists_request->entries ) || ! is_array( $lists_request->entries ) || empty( $lists_request->entries ) ) {
210
+ throw new Forminator_Addon_Aweber_Exception( __( 'No lists found on your AWeber. Please create one.', Forminator::DOMAIN ) );
211
+ }
212
+
213
+ foreach ( $lists_request->entries as $entry ) {
214
+ $lists[ $entry->id ] = $entry->name;
215
+ }
216
+
217
+ $template_params['lists'] = $lists;
218
+
219
+ } catch ( Forminator_Addon_Aweber_Exception $e ) {
220
+ $template_params['error_message'] = $e->getMessage();
221
+ $has_errors = true;
222
+ }
223
+
224
+ if ( $is_submit ) {
225
+ $list_id = isset( $submitted_data['list_id'] ) ? $submitted_data['list_id'] : '';
226
+ $template_params['list_id'] = $list_id;
227
+
228
+ try {
229
+
230
+ if ( empty( $list_id ) ) {
231
+ throw new Forminator_Addon_Aweber_Exception( __( 'Please pick valid list' ) );
232
+ }
233
+
234
+ // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
235
+ if ( ! in_array( $list_id, array_keys( $lists ) ) ) {
236
+ throw new Forminator_Addon_Aweber_Exception( __( 'Please pick valid list' ) );
237
+ }
238
+
239
+ $list_name = $lists[ $list_id ];
240
+
241
+ $this->save_multi_id_form_setting_values(
242
+ $multi_id,
243
+ array(
244
+ 'list_id' => $list_id,
245
+ 'list_name' => $list_name,
246
+ )
247
+ );
248
+
249
+ } catch ( Forminator_Addon_Aweber_Exception $e ) {
250
+ $template_params['list_id_error'] = $e->getMessage();
251
+ $has_errors = true;
252
+ }
253
+ }
254
+
255
+ $buttons = array();
256
+ if ( $this->pick_name_is_completed( array( 'multi_id' => $multi_id ) ) ) {
257
+ $buttons['disconnect']['markup'] = Forminator_Addon_Abstract::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ),
258
+ 'sui-button-ghost sui-tooltip sui-tooltip-top-center forminator-addon-form-disconnect',
259
+ esc_html__( 'Disconnect this AWeber Integration from this Form.', Forminator::DOMAIN )
260
+ );
261
+ }
262
+
263
+ $buttons['next']['markup'] = '<div class="sui-actions-right">' .
264
+ Forminator_Addon_Abstract::get_button_markup( esc_html__( 'NEXT', Forminator::DOMAIN ), 'forminator-addon-next' ) .
265
+ '</div>';
266
+
267
+ return array(
268
+ 'html' => Forminator_Addon_Abstract::get_template( $template, $template_params ),
269
+ 'buttons' => $buttons,
270
+ 'redirect' => false,
271
+ 'has_errors' => $has_errors,
272
+ 'has_back' => true,
273
+ );
274
+ }
275
+
276
+ /**
277
+ * Check if setup list completed
278
+ *
279
+ * @since 1.0 AWeber Addon
280
+ *
281
+ * @param $submitted_data
282
+ *
283
+ * @return bool
284
+ */
285
+ public function setup_list_is_completed( $submitted_data ) {
286
+ $multi_id = '';
287
+ if ( isset( $submitted_data['multi_id'] ) ) {
288
+ $multi_id = $submitted_data['multi_id'];
289
+ }
290
+
291
+ if ( empty( $multi_id ) ) {
292
+ return false;
293
+ }
294
+
295
+ $list_id = $this->get_multi_id_form_settings_value( $multi_id, 'list_id', '' );
296
+
297
+ if ( empty( $list_id ) ) {
298
+ return false;
299
+ }
300
+
301
+ return true;
302
+ }
303
+
304
+ /**
305
+ * Setup fields map
306
+ *
307
+ * @since 1.0 AWeber Addon
308
+ *
309
+ * @param $submitted_data
310
+ *
311
+ * @return array
312
+ */
313
+ public function map_fields( $submitted_data ) {
314
+ $template = forminator_addon_aweber_dir() . 'views/form-settings/map-fields.php';
315
+
316
+ if ( ! isset( $submitted_data['multi_id'] ) ) {
317
+ return $this->get_force_closed_wizard( __( 'Please pick valid connection', Forminator::DOMAIN ) );
318
+ }
319
+
320
+ $multi_id = $submitted_data['multi_id'];
321
+ unset( $submitted_data['multi_id'] );
322
+
323
+ // find type of email
324
+ $email_fields = array();
325
+ $forminator_field_element_ids = array();
326
+ foreach ( $this->form_fields as $form_field ) {
327
+ // collect element ids
328
+ $forminator_field_element_ids[] = $form_field['element_id'];
329
+ if ( 'email' === $form_field['type'] ) {
330
+ $email_fields[] = $form_field;
331
+ }
332
+ }
333
+
334
+ $template_params = array(
335
+ 'fields_map' => $this->get_multi_id_form_settings_value( $multi_id, 'fields_map', array() ),
336
+ 'multi_id' => $multi_id,
337
+ 'error_message' => '',
338
+ 'fields' => array(),
339
+ 'form_fields' => $this->form_fields,
340
+ 'email_fields' => $email_fields,
341
+ );
342
+
343
+ $is_submit = ! empty( $submitted_data );
344
+ $has_errors = false;
345
+
346
+ $fields = array(
347
+ 'default_field_email' => __( 'Email Address', Forminator::DOMAIN ),
348
+ 'default_field_name' => __( 'Name', Forminator::DOMAIN ),
349
+ );
350
+
351
+ $list_id = $this->get_multi_id_form_settings_value( $multi_id, 'list_id', 0 );
352
+
353
+ try {
354
+
355
+ $api = $this->addon->get_api();
356
+ $list_custom_fields_request = $api->get_account_list_custom_fields( $this->addon->get_account_id(), $list_id );
357
+
358
+ if ( ! is_object( $list_custom_fields_request ) || ! isset( $list_custom_fields_request->entries ) || ! is_array( $list_custom_fields_request->entries ) ) {
359
+ throw new Forminator_Addon_Aweber_Exception( __( 'Failed to get Custom Fields on the list.', Forminator::DOMAIN ) );
360
+ }
361
+
362
+ foreach ( $list_custom_fields_request->entries as $entry ) {
363
+ $fields[ $entry->id ] = $entry->name;
364
+ }
365
+
366
+ $template_params['fields'] = $fields;
367
+
368
+ } catch ( Forminator_Addon_Aweber_Exception $e ) {
369
+ $template_params['error_message'] = $e->getMessage();
370
+ $has_errors = true;
371
+ }
372
+
373
+ if ( $is_submit ) {
374
+ $fields_map = isset( $submitted_data['fields_map'] ) ? $submitted_data['fields_map'] : array();
375
+ $template_params['fields_map'] = $fields_map;
376
+
377
+ try {
378
+ if ( empty( $fields_map ) ) {
379
+ throw new Forminator_Addon_Aweber_Exception( __( 'Please assign fields.', Forminator::DOMAIN ) );
380
+ }
381
+
382
+ $input_exceptions = new Forminator_Addon_Aweber_Form_Settings_Exception();
383
+ if ( ! isset( $fields_map['default_field_email'] ) || empty( $fields_map['default_field_email'] ) ) {
384
+ $input_exceptions->add_input_exception( 'Please assign field for Email Address', 'default_field_email_error' );
385
+ }
386
+
387
+
388
+ $fields_map_to_save = array();
389
+ foreach ( $fields as $key => $title ) {
390
+ if ( isset( $fields_map[ $key ] ) && ! empty( $fields_map[ $key ] ) ) {
391
+ $element_id = $fields_map[ $key ];
392
+ if ( ! in_array( $element_id, $forminator_field_element_ids, true ) ) {
393
+ $input_exceptions->add_input_exception(
394
+ sprintf( __( 'Please assign valid field for %s', Forminator::DOMAIN ), $title ),
395
+ $key . '_error'
396
+ );
397
+ continue;
398
+ }
399
+
400
+ $fields_map_to_save[ $key ] = $fields_map[ $key ];
401
+ }
402
+ }
403
+
404
+ if ( $input_exceptions->input_exceptions_is_available() ) {
405
+ throw $input_exceptions;
406
+ }
407
+
408
+ $this->save_multi_id_form_setting_values(
409
+ $multi_id,
410
+ array(
411
+ 'fields_map' => $fields_map,
412
+ 'fields_mapper' => $fields,
413
+ )
414
+ );
415
+
416
+ } catch ( Forminator_Addon_Aweber_Form_Settings_Exception $e ) {
417
+ $template_params = array_merge( $template_params, $e->get_input_exceptions() );
418
+ $has_errors = true;
419
+ } catch ( Forminator_Addon_Aweber_Exception $e ) {
420
+ $template_params['error_message'] = $e->getMessage();
421
+ $has_errors = true;
422
+ }
423
+ }
424
+
425
+ $buttons = array();
426
+ if ( $this->pick_name_is_completed( array( 'multi_id' => $multi_id ) ) ) {
427
+ $buttons['disconnect']['markup'] = Forminator_Addon_Abstract::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ),
428
+ 'sui-button-ghost sui-tooltip sui-tooltip-top-center forminator-addon-form-disconnect',
429
+ esc_html__( 'Disconnect this AWeber Integration from this Form.', Forminator::DOMAIN )
430
+ );
431
+ }
432
+
433
+ $buttons['next']['markup'] = '<div class="sui-actions-right">' .
434
+ Forminator_Addon_Abstract::get_button_markup( esc_html__( 'NEXT', Forminator::DOMAIN ), 'forminator-addon-next' ) .
435
+ '</div>';
436
+
437
+ return array(
438
+ 'html' => Forminator_Addon_Abstract::get_template( $template, $template_params ),
439
+ 'buttons' => $buttons,
440
+ 'size' => 'normal',
441
+ 'redirect' => false,
442
+ 'has_errors' => $has_errors,
443
+ 'has_back' => true,
444
+ );
445
+ }
446
+
447
+ /**
448
+ * Check if fields mapped
449
+ *
450
+ * @since 1.0 AWeber Addon
451
+ *
452
+ * @param $submitted_data
453
+ *
454
+ * @return bool
455
+ */
456
+ public function map_fields_is_completed( $submitted_data ) {
457
+ $multi_id = '';
458
+ if ( isset( $submitted_data['multi_id'] ) ) {
459
+ $multi_id = $submitted_data['multi_id'];
460
+ }
461
+
462
+ if ( empty( $multi_id ) ) {
463
+ return false;
464
+ }
465
+
466
+ $fields_map = $this->get_multi_id_form_settings_value( $multi_id, 'fields_map', array() );
467
+ $fields_mapper = $this->get_multi_id_form_settings_value( $multi_id, 'fields_mapper', array() );
468
+
469
+ if ( empty( $fields_map ) || ! is_array( $fields_map ) || count( $fields_map ) < 1 ) {
470
+ return false;
471
+ }
472
+ if ( empty( $fields_mapper ) || ! is_array( $fields_mapper ) || count( $fields_mapper ) < 1 ) {
473
+ return false;
474
+ }
475
+
476
+ if ( ! isset( $fields_map['default_field_email'] ) || empty( $fields_map['default_field_email'] ) ) {
477
+ return false;
478
+ }
479
+
480
+ return true;
481
+ }
482
+
483
+ /**
484
+ * Setup options
485
+ *
486
+ * Contains :
487
+ * - ad_tracking
488
+ * - misc_notes
489
+ * - tags
490
+ *
491
+ * @since 1.0 Campaign Monitor Addon
492
+ *
493
+ * @param $submitted_data
494
+ *
495
+ * @return array
496
+ */
497
+ public function setup_options( $submitted_data ) {
498
+ $template = forminator_addon_aweber_dir() . 'views/form-settings/setup-options.php';
499
+
500
+ if ( ! isset( $submitted_data['multi_id'] ) ) {
501
+ return $this->get_force_closed_wizard( __( 'Please pick valid connection', Forminator::DOMAIN ) );
502
+ }
503
+
504
+ $multi_id = $submitted_data['multi_id'];
505
+ unset( $submitted_data['multi_id'] );
506
+
507
+ $forminator_form_element_ids = array();
508
+ foreach ( $this->form_fields as $field ) {
509
+ $forminator_form_element_ids[ $field['element_id'] ] = $field;
510
+ }
511
+
512
+ $template_params = array(
513
+ 'multi_id' => $multi_id,
514
+ 'error_message' => '',
515
+ 'ad_tracking' => $this->get_multi_id_form_settings_value( $multi_id, 'ad_tracking', 'FORMINATOR {form_name}' ),
516
+ 'fields' => $this->form_fields,
517
+ 'tags_fields' => array(),
518
+ 'tags_selected_fields' => array(),
519
+ );
520
+
521
+ $saved_tags = $this->get_multi_id_form_settings_value( $multi_id, 'tags', array() );
522
+
523
+ if ( isset( $submitted_data['tags'] ) && is_array( $submitted_data['tags'] ) ) {
524
+ $saved_tags = $submitted_data['tags'];
525
+
526
+ }
527
+ $tag_selected_fields = array();
528
+ foreach ( $saved_tags as $key => $saved_tag ) {
529
+ // using form data
530
+ if ( stripos( $saved_tag, '{' ) === 0
531
+ && stripos( $saved_tag, '}' ) === ( strlen( $saved_tag ) - 1 )
532
+ ) {
533
+ $element_id = str_ireplace( '{', '', $saved_tag );
534
+ $element_id = str_ireplace( '}', '', $element_id );
535
+ if ( in_array( $element_id, array_keys( $forminator_form_element_ids ), true ) ) {
536
+ $forminator_form_element_ids[ $element_id ]['field_label'] = $forminator_form_element_ids[ $element_id ]['field_label'] .
537
+ ' | ' . $forminator_form_element_ids[ $element_id ]['element_id'];
538
+ $forminator_form_element_ids[ $element_id ]['element_id'] = '{' . $forminator_form_element_ids[ $element_id ]['element_id'] . '}';
539
+
540
+
541
+ $tag_selected_fields[] = $forminator_form_element_ids[ $element_id ];
542
+ // let this go, its already selected.
543
+ unset( $forminator_form_element_ids[ $element_id ] );
544
+ } else {
545
+ // no more exist on element ids let it go
546
+ unset( $saved_tags[ $key ] );
547
+ }
548
+
549
+ } else {// free form type
550
+ $tag_selected_fields[] = array(
551
+ 'element_id' => $saved_tag,
552
+ 'field_label' => $saved_tag,
553
+ );
554
+ }
555
+ }
556
+
557
+ $template_params['tags_fields'] = $forminator_form_element_ids;
558
+ $template_params['tags_selected_fields'] = $tag_selected_fields;
559
+
560
+ $is_submit = ! empty( $submitted_data );
561
+ $has_errors = false;
562
+ $notification = array();
563
+ $is_close = false;
564
+
565
+ if ( $is_submit ) {
566
+ $ad_tracking = isset( $submitted_data['ad_tracking'] ) ? $submitted_data['ad_tracking'] : '';
567
+
568
+ try {
569
+
570
+ $this->save_multi_id_form_setting_values(
571
+ $multi_id,
572
+ array(
573
+ 'ad_tracking' => $ad_tracking,
574
+ 'tags' => $saved_tags,
575
+ )
576
+ );
577
+
578
+ $notification = array(
579
+ 'type' => 'success',
580
+ 'text' => '<strong>' . $this->addon->get_title() . '</strong> ' . __( 'Successfully connected to your form' ),
581
+ );
582
+ $is_close = true;
583
+
584
+ } catch ( Forminator_Addon_Aweber_Form_Settings_Exception $e ) {
585
+ $template_params = array_merge( $template_params, $e->get_input_exceptions() );
586
+ $has_errors = true;
587
+ } catch ( Forminator_Addon_Aweber_Exception $e ) {
588
+ $template_params['error_message'] = $e->getMessage();
589
+ $has_errors = true;
590
+ }
591
+ }
592
+
593
+ $buttons = array();
594
+ if ( $this->pick_name_is_completed( array( 'multi_id' => $multi_id ) ) ) {
595
+ $buttons['disconnect']['markup'] = Forminator_Addon_Abstract::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ),
596
+ 'sui-button-ghost sui-tooltip sui-tooltip-top-center forminator-addon-form-disconnect',
597
+ esc_html__( 'Disconnect this Campaign Monitor Integration from this Form.', Forminator::DOMAIN )
598
+ );
599
+ }
600
+
601
+ $buttons['next']['markup'] = '<div class="sui-actions-right">' .
602
+ Forminator_Addon_Abstract::get_button_markup( esc_html__( 'SAVE', Forminator::DOMAIN ), 'sui-button-primary forminator-addon-finish' ) .
603
+ '</div>';
604
+
605
+ return array(
606
+ 'html' => Forminator_Addon_Abstract::get_template( $template, $template_params ),
607
+ 'buttons' => $buttons,
608
+ 'size' => 'normal',
609
+ 'redirect' => false,
610
+ 'has_errors' => $has_errors,
611
+ 'has_back' => true,
612
+ 'notification' => $notification,
613
+ 'is_close' => $is_close,
614
+ );
615
+ }
616
+
617
+ /**
618
+ * Check if setup options completed
619
+ *
620
+ * @since 1.0 AWeber Addon
621
+ *
622
+ * @param $submitted_data
623
+ *
624
+ * @return bool
625
+ */
626
+ public function setup_options_is_completed( $submitted_data ) {
627
+ // all settings here are optional, so it can be marked as completed
628
+ return true;
629
+ }
630
+
631
+ /**
632
+ * Check if multi_id form settings values completed
633
+ *
634
+ * @since 1.0 Aweber Added
635
+ *
636
+ * @param $multi_id
637
+ *
638
+ * @return bool
639
+ */
640
+ public function is_multi_form_settings_complete( $multi_id ) {
641
+ $data = array( 'multi_id' => $multi_id );
642
+
643
+ if ( ! $this->pick_name_is_completed( $data ) ) {
644
+ return false;
645
+ }
646
+ if ( ! $this->setup_list_is_completed( $data ) ) {
647
+ return false;
648
+ }
649
+
650
+ if ( ! $this->map_fields_is_completed( $data ) ) {
651
+ return false;
652
+ }
653
+
654
+ if ( ! $this->setup_options_is_completed( $data ) ) {
655
+ return false;
656
+ }
657
+
658
+ return true;
659
+ }
660
+
661
+ /**
662
+ * Generate multi id for multiple connection
663
+ *
664
+ * @since 1.0 Aweber Addon
665
+ * @return string
666
+ */
667
+ public function generate_multi_id() {
668
+ return uniqid( 'aweber_', true );
669
+ }
670
+
671
+
672
+ /**
673
+ * Override how multi connection displayed
674
+ *
675
+ * @since 1.0 Aweber Addon
676
+ * @return array
677
+ */
678
+ public function get_multi_ids() {
679
+ $multi_ids = array();
680
+ foreach ( $this->get_form_settings_values() as $key => $value ) {
681
+ $multi_ids[] = array(
682
+ 'id' => $key,
683
+ // use name that was added by user on creating connection
684
+ 'label' => isset( $value['name'] ) ? $value['name'] : $key,
685
+ );
686
+ }
687
+
688
+ return $multi_ids;
689
+ }
690
+
691
+ /**
692
+ * Disconnect a connection from current form
693
+ *
694
+ * @since 1.0 Aweber Addon
695
+ *
696
+ * @param array $submitted_data
697
+ */
698
+ public function disconnect_form( $submitted_data ) {
699
+ // only execute if multi_id provided on submitted data
700
+ if ( isset( $submitted_data['multi_id'] ) && ! empty( $submitted_data['multi_id'] ) ) {
701
+ $addon_form_settings = $this->get_form_settings_values();
702
+ unset( $addon_form_settings[ $submitted_data['multi_id'] ] );
703
+ $this->save_form_settings_values( $addon_form_settings );
704
+ }
705
+ }
706
+ }
addons/pro/aweber/forminator-addon-aweber.php ADDED
@@ -0,0 +1,611 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once dirname( __FILE__ ) . '/forminator-addon-aweber-exception.php';
4
+ require_once dirname( __FILE__ ) . '/lib/class-wp-aweber-api.php';
5
+
6
+ /**
7
+ * Class Forminator_Addon_Aweber
8
+ * Aweber Addon Main Class
9
+ *
10
+ * @since 1.0 Aweber Addon
11
+ */
12
+ final class Forminator_Addon_Aweber extends Forminator_Addon_Abstract {
13
+
14
+ /**
15
+ * @var self|null
16
+ */
17
+ private static $_instance = null;
18
+
19
+ protected $_slug = 'aweber';
20
+ protected $_version = FORMINATOR_ADDON_AWEBER_VERSION;
21
+ protected $_min_forminator_version = '1.1';
22
+ protected $_short_title = 'AWeber';
23
+ protected $_title = 'AWeber';
24
+ protected $_url = 'https://premium.wpmudev.org';
25
+ protected $_full_path = __FILE__;
26
+
27
+ protected $_form_settings = 'Forminator_Addon_Aweber_Form_Settings';
28
+ protected $_form_hooks = 'Forminator_Addon_Aweber_Form_Hooks';
29
+
30
+ private $_app_id = 'd806984a';
31
+
32
+ /**
33
+ * Connected Account Info
34
+ *
35
+ * @var integer
36
+ */
37
+ private $_account_id = 0;
38
+
39
+ /**
40
+ * API Adapter
41
+ *
42
+ * @var Forminator_Addon_Aweber_Wp_Api
43
+ */
44
+ private static $api;
45
+
46
+ /**
47
+ * Forminator_Addon_Aweber constructor.
48
+ *
49
+ * @since 1.0 Aweber Addon
50
+ */
51
+ public function __construct() {
52
+ // late init to allow translation
53
+ $this->_description = __( 'Get awesome by your form.', Forminator::DOMAIN );
54
+ $this->_activation_error_message = __( 'Sorry but we failed to activate AWeber Integration, don\'t hesitate to contact us', Forminator::DOMAIN );
55
+ $this->_deactivation_error_message = __( 'Sorry but we failed to deactivate AWeber Integration, please try again', Forminator::DOMAIN );
56
+
57
+ $this->_update_settings_error_message = __(
58
+ 'Sorry, we are failed to update settings, please check your form and try again',
59
+ Forminator::DOMAIN
60
+ );
61
+
62
+ $this->_icon = forminator_addon_aweber_assets_url() . 'icons/aweber.png';
63
+ $this->_icon_x2 = forminator_addon_aweber_assets_url() . 'icons/aweber@2x.png';
64
+ $this->_image = forminator_addon_aweber_assets_url() . 'img/aweber.png';
65
+ $this->_image_x2 = forminator_addon_aweber_assets_url() . 'img/aweber@2x.png';
66
+ }
67
+
68
+ /**
69
+ * Get Instance
70
+ *
71
+ * @since 1.0 Aweber Addon
72
+ * @return self|null
73
+ */
74
+ public static function get_instance() {
75
+ if ( is_null( self::$_instance ) ) {
76
+ self::$_instance = new self();
77
+ }
78
+
79
+ return self::$_instance;
80
+ }
81
+
82
+ /**
83
+ * Override on is_connected
84
+ *
85
+ * @since 1.0 Aweber Addon
86
+ *
87
+ * @return bool
88
+ */
89
+ public function is_connected() {
90
+ try {
91
+ // check if its active
92
+ if ( ! $this->is_active() ) {
93
+ throw new Forminator_Addon_Aweber_Exception( __( 'AWeber is not active', Forminator::DOMAIN ) );
94
+ }
95
+
96
+ // if user completed api setup
97
+ $is_connected = false;
98
+ $setting_values = $this->get_settings_values();
99
+ // if user completed api setup
100
+ if ( isset( $setting_values['account_id'] ) && ! empty( $setting_values['account_id'] ) ) {
101
+ $is_connected = true;
102
+ }
103
+
104
+ } catch ( Forminator_Addon_Aweber_Exception $e ) {
105
+ $is_connected = false;
106
+ }
107
+
108
+ /**
109
+ * Filter connected status of Aweber
110
+ *
111
+ * @since 1.0
112
+ *
113
+ * @param bool $is_connected
114
+ */
115
+ $is_connected = apply_filters( 'forminator_addon_aweber_is_connected', $is_connected );
116
+
117
+ return $is_connected;
118
+ }
119
+
120
+ /**
121
+ * Check if Aweber is connected with current form
122
+ *
123
+ * @since 1.0 Aweber Addon
124
+ *
125
+ * @param $form_id
126
+ *
127
+ * @return bool
128
+ */
129
+ public function is_form_connected( $form_id ) {
130
+ try {
131
+ $form_settings_instance = null;
132
+ if ( ! $this->is_connected() ) {
133
+ throw new Forminator_Addon_Aweber_Exception( __( ' AWeber is not connected', Forminator::DOMAIN ) );
134
+ }
135
+
136
+ $form_settings_instance = $this->get_addon_form_settings( $form_id );
137
+ if ( ! $form_settings_instance instanceof Forminator_Addon_Aweber_Form_Settings ) {
138
+ throw new Forminator_Addon_Aweber_Exception( __( 'Invalid Form Settings of AWeber', Forminator::DOMAIN ) );
139
+ }
140
+
141
+ // Mark as active when there is at least one active connection
142
+ if ( false === $form_settings_instance->find_one_active_connection() ) {
143
+ throw new Forminator_Addon_Aweber_Exception( __( 'No active AWeber connection found in this form', Forminator::DOMAIN ) );
144
+ }
145
+
146
+ $is_form_connected = true;
147
+
148
+ } catch ( Forminator_Addon_Aweber_Exception $e ) {
149
+ $is_form_connected = false;
150
+ }
151
+
152
+ /**
153
+ * Filter connected status of Aweber with the form
154
+ *
155
+ * @since 1.0
156
+ *
157
+ * @param bool $is_form_connected
158
+ * @param int $form_id Current Form ID
159
+ * @param Forminator_Addon_Aweber_Form_Settings|null $form_settings_instance Instance of form settings, or null when unavailable
160
+ *
161
+ */
162
+ $is_form_connected = apply_filters( 'forminator_addon_aweber_is_form_connected', $is_form_connected, $form_id, $form_settings_instance );
163
+
164
+ return $is_form_connected;
165
+ }
166
+
167
+ /**
168
+ * Override settings available,
169
+ *
170
+ * @since 1.0 Aweber Addon
171
+ * @return bool
172
+ */
173
+ public function is_settings_available() {
174
+ return true;
175
+ }
176
+
177
+ /**
178
+ * Flag show full log on entries
179
+ *
180
+ * @since 1.0 Aweber Addon
181
+ * @return bool
182
+ */
183
+ public static function is_show_full_log() {
184
+ $show_full_log = false;
185
+ if ( defined( 'FORMINATOR_ADDON_AWEBER_SHOW_FULL_LOG' ) && FORMINATOR_ADDON_AWEBER_SHOW_FULL_LOG ) {
186
+ $show_full_log = true;
187
+ }
188
+
189
+ /**
190
+ * Filter Flag show full log on entries
191
+ *
192
+ * @since 1.2
193
+ *
194
+ * @params bool $show_full_log
195
+ */
196
+ $show_full_log = apply_filters( 'forminator_addon_aweber_show_full_log', $show_full_log );
197
+
198
+ return $show_full_log;
199
+ }
200
+
201
+ /**
202
+ * Allow multiple connection on one form
203
+ *
204
+ * @since 1.0 Aweber Addon
205
+ * @return bool
206
+ */
207
+ public function is_allow_multi_on_form() {
208
+ return true;
209
+ }
210
+
211
+ /**
212
+ * Settings wizard
213
+ *
214
+ * @since 1.0 AWeber Addon
215
+ * @return array
216
+ */
217
+ public function settings_wizards() {
218
+ return array(
219
+ array(
220
+ 'callback' => array( $this, 'authorize_access' ),
221
+ 'is_completed' => array( $this, 'authorize_access_is_completed' ),
222
+ ),
223
+ array(
224
+ 'callback' => array( $this, 'wait_authorize_access' ),
225
+ 'is_completed' => array( $this, 'is_authorized' ),
226
+ ),
227
+ );
228
+ }
229
+
230
+ /**
231
+ * Authorize Access wizard
232
+ *
233
+ * @since 1.0 AWeber Addon
234
+ * @return array
235
+ */
236
+ public function authorize_access() {
237
+ $template = forminator_addon_aweber_dir() . 'views/settings/authorize.php';
238
+
239
+ $buttons = array();
240
+
241
+ $template_params = array(
242
+ 'account_id' => $this->_account_id,
243
+ 'auth_url' => $this->get_auth_url(),
244
+ 'is_connected' => $this->is_connected(),
245
+ );
246
+
247
+ return array(
248
+ 'html' => self::get_template( $template, $template_params ),
249
+ 'buttons' => $buttons,
250
+ 'redirect' => false,
251
+ 'has_errors' => false,
252
+ );
253
+ }
254
+
255
+ /**
256
+ * Wait Authorize Access wizard
257
+ *
258
+ * @since 1.0 AWeber Addon
259
+ * @return array
260
+ */
261
+ public function wait_authorize_access() {
262
+ $template = forminator_addon_aweber_dir() . 'views/settings/wait-authorize.php';
263
+ $template_success = forminator_addon_aweber_dir() . 'views/settings/success-authorize.php';
264
+
265
+ $buttons = array();
266
+
267
+ $is_poll = true;
268
+
269
+ $template_params = array(
270
+ 'account_id' => $this->_account_id,
271
+ 'auth_url' => $this->get_auth_url(),
272
+ );
273
+
274
+ if ( $this->_account_id ) {
275
+ $is_poll = false;
276
+ $template = $template_success;
277
+ }
278
+
279
+ return array(
280
+ 'html' => self::get_template( $template, $template_params ),
281
+ 'buttons' => $buttons,
282
+ 'is_poll' => $is_poll,
283
+ 'redirect' => false,
284
+ 'has_errors' => false,
285
+ );
286
+ }
287
+
288
+ /**
289
+ * Authorized Callback
290
+ *
291
+ * @since 1.0 AWeber Addon
292
+ *
293
+ * @param $submitted_data
294
+ *
295
+ * @return bool
296
+ */
297
+ public function is_authorized( $submitted_data ) {
298
+ $setting_values = $this->get_settings_values();
299
+
300
+ // check account_id there
301
+ return isset( $setting_values['account_id'] ) && ! empty( $setting_values['account_id'] );
302
+ }
303
+
304
+ /**
305
+ * Pseudo step
306
+ *
307
+ * @since 1.0 AWeber Addon
308
+ * @return bool
309
+ */
310
+ public function authorize_access_is_completed() {
311
+ return true;
312
+ }
313
+
314
+ /**
315
+ * Register a page for redirect url of AWeber auth
316
+ *
317
+ * @since 1.0 AWeber Addon
318
+ *
319
+ * @return array
320
+ */
321
+ public function register_integration_sections() {
322
+ return array(
323
+ 'authorize' => array( $this, 'authorize_page_callback' ),
324
+ );
325
+ }
326
+
327
+ /**
328
+ * AWeber Authorize Page
329
+ *
330
+ * @since 1.0 AWeber Addon
331
+ *
332
+ * @param $query_args
333
+ *
334
+ * @return string
335
+ */
336
+ public function authorize_page_callback( $query_args ) {
337
+ $template = forminator_addon_aweber_dir() . 'views/sections/authorize.php';
338
+ $template_params = array(
339
+ 'error_message' => '',
340
+ 'is_close' => false,
341
+ );
342
+
343
+ if ( isset( $query_args['authorization_code'] ) && ! empty( $query_args['authorization_code'] ) ) {
344
+ try {
345
+ $authorization_code = $query_args['authorization_code'];
346
+
347
+ $split_codes = explode( '|', $authorization_code );
348
+
349
+ //https://labs.aweber.com/docs/authentication#distributed-app
350
+ //the authorization code is an application key, application secret, request token, token secret, and oauth_verifier, delimited by pipes (|).
351
+ if ( ! is_array( $split_codes ) || 5 !== count( $split_codes ) ) {
352
+ new Forminator_Addon_Aweber_Exception( __( 'Invalid Authorization Code', Forminator::DOMAIN ) );
353
+ }
354
+
355
+ $application_key = $split_codes[0];
356
+ $application_secret = $split_codes[1];
357
+ $request_token = $split_codes[2];
358
+ $token_secret = $split_codes[3];
359
+ $oauth_verifier = $split_codes[4];
360
+
361
+ $this->validate_access_token( $application_key, $application_secret, $request_token, $token_secret, $oauth_verifier );
362
+ $this->_account_id = $this->get_validated_account_id();
363
+
364
+ if ( ! $this->is_active() ) {
365
+ $activated = Forminator_Addon_Loader::get_instance()->activate_addon( $this->_slug );
366
+ if ( ! $activated ) {
367
+ $last_message = Forminator_Addon_Loader::get_instance()->get_last_error_message();
368
+ throw new Forminator_Addon_Aweber_Exception( $last_message );
369
+ }
370
+ }
371
+
372
+ $this->save_settings_values(
373
+ array(
374
+ 'application_key' => $application_key,
375
+ 'application_secret' => $application_secret,
376
+ 'oauth_token' => $this->get_api()->get_oauth_token(),
377
+ 'oauth_token_secret' => $this->get_api()->get_oauth_token_secret(),
378
+ )
379
+ );
380
+ $template_params['is_close'] = true;
381
+ } catch ( Forminator_Addon_Aweber_Exception $e ) {
382
+ $template_params['error_message'] = $e->getMessage();
383
+ }
384
+
385
+ }
386
+
387
+ return self::get_template( $template, $template_params );
388
+ }
389
+
390
+ /**
391
+ * Get AWeber Auth URL
392
+ *
393
+ * @since 1.1 AWeber Addon
394
+ *
395
+ * @param string $return_url
396
+ *
397
+ * @return string
398
+ */
399
+ public function get_auth_url( $return_url = '' ) {
400
+ $app_id = $this->get_app_id();
401
+
402
+ $authorize_url = 'https://auth.aweber.com/1.0/oauth/authorize_app/' . trim( $app_id );
403
+
404
+ if ( ! $return_url ) {
405
+ $return_url = forminator_addon_integration_section_admin_url( $this->_slug, 'authorize', true );
406
+ }
407
+ $return_url = rawurlencode( $return_url );
408
+
409
+ $auth_params = array(
410
+ 'oauth_callback' => $return_url, // un-official https://labs.aweber.com/getting_started/public#1
411
+ );
412
+
413
+ /**
414
+ * Filter params used to authorize AWeber user
415
+ *
416
+ * @since 1.3
417
+ *
418
+ * @param array $auth_params
419
+ */
420
+ $auth_params = apply_filters( 'forminator_addon_aweber_authorize_params', $auth_params );
421
+
422
+ $authorize_url = add_query_arg( $auth_params, $authorize_url );
423
+
424
+ return $authorize_url;
425
+ }
426
+
427
+ /**
428
+ * Get AWeber APP ID
429
+ *
430
+ * @see https://labs.aweber.com/docs/authentication
431
+ *
432
+ * @since 1.0 AWeber Addon
433
+ *
434
+ * @return string;
435
+ */
436
+ public function get_app_id() {
437
+ $app_id = $this->_app_id;
438
+ // check override by config constant
439
+ if ( defined( 'FORMINATOR_ADDON_AWEBER_APP_ID' ) && FORMINATOR_ADDON_AWEBER_APP_ID ) {
440
+ $app_id = FORMINATOR_ADDON_AWEBER_APP_ID;
441
+ }
442
+
443
+ /**
444
+ * Filter APP ID used for API request(s) of AWeber
445
+ *
446
+ * @since 1.2
447
+ *
448
+ * @param string $app_id
449
+ */
450
+ $app_id = apply_filters( 'forminator_addon_aweber_app_id', $app_id );
451
+
452
+ return $app_id;
453
+ }
454
+
455
+ /**
456
+ * Get API Instance
457
+ *
458
+ * @since 1.0
459
+ *
460
+ * @param array|null $api_credentials
461
+ *
462
+ * @return Forminator_Addon_Aweber_Wp_Api
463
+ * @throws Forminator_Addon_Aweber_Wp_Api_Exception
464
+ */
465
+ public function get_api( $api_credentials = null ) {
466
+ if ( is_null( self::$api ) ) {
467
+ if ( is_null( $api_credentials ) ) {
468
+ $api_credentials = array();
469
+ $setting_values = $this->get_settings_values();
470
+ $api_credentials_keys = array(
471
+ 'application_key',
472
+ 'application_secret',
473
+ 'oauth_token',
474
+ 'oauth_token_secret',
475
+ );
476
+
477
+ foreach ( $api_credentials_keys as $api_credentials_key ) {
478
+ $api_credentials[ $api_credentials_key ] = isset( $setting_values[ $api_credentials_key ] ) ? $setting_values[ $api_credentials_key ] : '';
479
+ }
480
+ }
481
+
482
+ $_application_key = isset( $api_credentials['application_key'] ) ? $api_credentials['application_key'] : '';
483
+ $_application_secret = isset( $api_credentials['application_secret'] ) ? $api_credentials['application_secret'] : '';
484
+ $_oauth_token = isset( $api_credentials['oauth_token'] ) ? $api_credentials['oauth_token'] : '';
485
+ $_oauth_token_secret = isset( $api_credentials['oauth_token_secret'] ) ? $api_credentials['oauth_token_secret'] : '';
486
+
487
+ $api = new Forminator_Addon_Aweber_Wp_Api( $_application_key, $_application_secret, $_oauth_token, $_oauth_token_secret );
488
+ self::$api = $api;
489
+ }
490
+
491
+ return self::$api;
492
+ }
493
+
494
+ /**
495
+ * Validate Access Token
496
+ *
497
+ * @param $application_key
498
+ * @param $application_secret
499
+ * @param $request_token
500
+ * @param $token_secret
501
+ * @param $oauth_verifier
502
+ *
503
+ * @throws Forminator_Addon_Aweber_Wp_Api_Exception
504
+ * @throws Forminator_Addon_Aweber_Wp_Api_Not_Found_Exception
505
+ */
506
+ public function validate_access_token( $application_key, $application_secret, $request_token, $token_secret, $oauth_verifier ) {
507
+ // reinit api
508
+ self::$api = null;
509
+
510
+ //get access_token
511
+ $api = $this->get_api(
512
+ array(
513
+ 'application_key' => $application_key,
514
+ 'application_secret' => $application_secret,
515
+ 'oauth_token' => $request_token,
516
+ 'oauth_token_secret' => $token_secret,
517
+ )
518
+ );
519
+ $access_tokens = $api->get_access_token( $oauth_verifier );
520
+
521
+ // reinit api with new access token open success for future usage
522
+ self::$api = null;
523
+
524
+ $this->get_api(
525
+ array(
526
+ 'application_key' => $application_key,
527
+ 'application_secret' => $application_secret,
528
+ 'oauth_token' => $access_tokens->oauth_token,
529
+ 'oauth_token_secret' => $access_tokens->oauth_token_secret,
530
+ )
531
+ );
532
+ }
533
+
534
+ /**
535
+ * Get validated account_id
536
+ *
537
+ * @return integer
538
+ * @throws Forminator_Addon_Aweber_Exception
539
+ * @throws Forminator_Addon_Aweber_Wp_Api_Exception
540
+ * @throws Forminator_Addon_Aweber_Wp_Api_Not_Found_Exception
541
+ */
542
+ public function get_validated_account_id() {
543
+ $api = $this->get_api();
544
+
545
+ $accounts = $api->get_accounts();
546
+ if ( ! isset( $accounts->entries ) ) {
547
+ throw new Forminator_Addon_Aweber_Exception( __( 'Failed to get AWeber account information', Forminator::DOMAIN ) );
548
+ }
549
+
550
+ $entries = $accounts->entries;
551
+ if ( ! isset( $entries[0] ) ) {
552
+ throw new Forminator_Addon_Aweber_Exception( __( 'Failed to get AWeber account information', Forminator::DOMAIN ) );
553
+ }
554
+
555
+ $first_entry = $entries[0];
556
+ $account_id = $first_entry->id;
557
+
558
+ /**
559
+ * Filter validated account_id
560
+ *
561
+ * @since 1.3
562
+ *
563
+ * @param integer $account_id
564
+ * @param object $accounts
565
+ * @param Forminator_Addon_Aweber_Wp_Api $api
566
+ */
567
+ $account_id = apply_filters( 'forminator_addon_aweber_validated_account_id', $account_id, $accounts, $api );
568
+
569
+ return $account_id;
570
+ }
571
+
572
+ /**
573
+ * set account_id on class if exist on settings
574
+ *
575
+ * @param $values
576
+ *
577
+ * @return mixed
578
+ */
579
+ public function before_get_settings_values( $values ) {
580
+ if ( is_array( $values ) && isset( $values['account_id'] ) ) {
581
+ $this->_account_id = $values['account_id'];
582
+ }
583
+
584
+ return $values;
585
+ }
586
+
587
+ /**
588
+ * set account_id on class if exist on settings
589
+ *
590
+ * @param $values
591
+ *
592
+ * @return mixed
593
+ */
594
+ public function before_save_settings_values( $values ) {
595
+ if ( ! empty( $this->_account_id ) ) {
596
+ $values['account_id'] = $this->_account_id;
597
+ }
598
+
599
+ return $values;
600
+ }
601
+
602
+ /**
603
+ * Get connected account id
604
+ *
605
+ * @return int
606
+ */
607
+ public function get_account_id() {
608
+ return $this->_account_id;
609
+ }
610
+
611
+ }
addons/pro/aweber/lib/class-aweber-oauth.php ADDED
@@ -0,0 +1,170 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Aweber_Oauth
5
+ * Helpers for OAuth
6
+ */
7
+ class Forminator_Addon_Aweber_Oauth {
8
+
9
+ /**
10
+ * Create Signature Base
11
+ *
12
+ * @since 1.0
13
+ *
14
+ * @param mixed $method String name of HTTP method, such as "GET"
15
+ * @param mixed $url URL where this request will go
16
+ * @param mixed $data Array of params for this request. This should
17
+ * include ALL oauth properties except for the signature.
18
+ *
19
+ * @return string
20
+ */
21
+ public static function create_signature_base( $method, $url, $data ) {
22
+ $request_method = $method;
23
+ $request_url = $url;
24
+ $request_data = $data;
25
+
26
+ $method = rawurlencode( strtoupper( $method ) );
27
+ $query = wp_parse_url( $url, PHP_URL_QUERY );
28
+ if ( $query ) {
29
+ $parts = explode( '?', $url, 2 );
30
+ $url = array_shift( $parts );
31
+ $items = explode( '&', $query );
32
+ foreach ( $items as $item ) {
33
+ list( $key, $value ) = explode( '=', $item );
34
+ $data[ rawurldecode( $key ) ] = rawurldecode( $value );
35
+ }
36
+ }
37
+ $url = rawurlencode( $url );
38
+ $data = rawurlencode( self::collapse_data_for_signature( $data ) );
39
+
40
+ $signature_base = $method . '&' . $url . '&' . $data;
41
+
42
+ /**
43
+ * Filter Signature Base that will be used to sign AWeber request
44
+ *
45
+ * @since 1.3
46
+ *
47
+ * @param string $signature_base
48
+ * @param string $request_method
49
+ * @param string $request_url
50
+ * @param array $request_data
51
+ */
52
+ $signature_base = apply_filters( 'forminator_addon_aweber_oauth_signature_base', $signature_base, $request_method, $request_url, $request_data );
53
+
54
+ return $signature_base;
55
+ }
56
+
57
+ /**
58
+ * collapse data for signature
59
+ *
60
+ * @since 1.0
61
+ *
62
+ * Turns an array of request data into a string, as used by the oauth
63
+ * signature
64
+ *
65
+ * @param mixed $data
66
+ *
67
+ * @return string
68
+ */
69
+ public static function collapse_data_for_signature( $data ) {
70
+ ksort( $data );
71
+ $collapse = '';
72
+ foreach ( $data as $key => $val ) {
73
+ if ( ! empty( $collapse ) ) {
74
+ $collapse .= '&';
75
+ }
76
+ $collapse .= $key . '=' . rawurlencode( $val );
77
+ }
78
+
79
+ return $collapse;
80
+ }
81
+
82
+ /**
83
+ * Creates a signature on the signature base and the signature key
84
+ *
85
+ * @since 1.0
86
+ *
87
+ * @param mixed $base Base string of data to sign
88
+ * @param mixed $key Key to sign the data with
89
+ *
90
+ * @access public
91
+ * @return string The signature
92
+ */
93
+ public static function create_signature( $base, $key ) {
94
+
95
+ $signature = base64_encode( hash_hmac( 'sha1', $base, $key, true ) );//phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
96
+
97
+ /**
98
+ * Signature that will be used on AWeber oauth_signature
99
+ *
100
+ * @since 1.3
101
+ *
102
+ * @param string $signature
103
+ * @param string $base
104
+ * @param string $key
105
+ */
106
+ $signature = apply_filters( 'forminator_addon_aweber_oauth_signature', $signature, $base, $key );
107
+
108
+ return $signature;
109
+ }
110
+
111
+ /**
112
+ * Creates a key that will be used to sign our signature. Signatures
113
+ * are signed with the consumerSecret for this consumer application and
114
+ * the token secret of the user that the application is acting on behalf
115
+ * of.
116
+ *
117
+ * @since 1.0
118
+ *
119
+ * @param $application_key
120
+ * @param $oauth_token_secret
121
+ *
122
+ * @return string
123
+ */
124
+ public static function create_signature_key( $application_key, $oauth_token_secret ) {
125
+ $signature_key = $application_key . '&' . $oauth_token_secret;
126
+
127
+ /**
128
+ * Signature that will be used on AWeber oauth_signature
129
+ *
130
+ * @since 1.3
131
+ *
132
+ * @param string $signature_key
133
+ * @param string $application_key
134
+ * @param string $oauth_token_secret
135
+ */
136
+ $signature_key = apply_filters( 'forminator_addon_aweber_oauth_signature_key', $signature_key, $application_key, $oauth_token_secret );
137
+
138
+ return $signature_key;
139
+ }
140
+
141
+ /**
142
+ * Generate oauth_nonce
143
+ *
144
+ * @since 1.0
145
+ *
146
+ * @param int $timestamp
147
+ *
148
+ * @return string
149
+ */
150
+ public static function generate_oauth_nonce( $timestamp = 0 ) {
151
+ if ( ! $timestamp ) {
152
+ $timestamp = time();
153
+ }
154
+
155
+ $oauth_nonce = md5( $timestamp . '-' . wp_rand( 10000, 99999 ) . '-' . uniqid() );
156
+
157
+ /**
158
+ * Filter required oauth_nonce data of AWeber that need to be send on API Request
159
+ *
160
+ * @since 1.3
161
+ *
162
+ * @param string $oauth_nonce
163
+ * @param int $timestamp current timestamp for future reference
164
+ */
165
+ $oauth_nonce = apply_filters( 'forminator_addon_aweber_oauth_nonce', $oauth_nonce, $timestamp );
166
+
167
+
168
+ return $oauth_nonce;
169
+ }
170
+ }
addons/pro/aweber/lib/class-wp-aweber-api-exception.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Aweber_Wp_Api_Exception
5
+ * Exception holder for Aweber wp api
6
+ *
7
+ * @since 1.0 Aweber Addon
8
+ */
9
+ class Forminator_Addon_Aweber_Wp_Api_Exception extends Forminator_Addon_Aweber_Exception {
10
+ }
addons/pro/aweber/lib/class-wp-aweber-api-not-found-exception.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Aweber_Wp_Api_Not_Found_Exception
5
+ * Exception holder for aweber wp api on 404 not found error status
6
+ *
7
+ * @since 1.0 Aweber Addon
8
+ */
9
+ class Forminator_Addon_Aweber_Wp_Api_Not_Found_Exception extends Forminator_Addon_Aweber_Wp_Api_Exception {
10
+ }
addons/pro/aweber/lib/class-wp-aweber-api.php ADDED
@@ -0,0 +1,696 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once dirname( __FILE__ ) . '/class-aweber-oauth.php';
4
+ require_once dirname( __FILE__ ) . '/class-wp-aweber-api-exception.php';
5
+ require_once dirname( __FILE__ ) . '/class-wp-aweber-api-not-found-exception.php';
6
+
7
+ /**
8
+ * Class Forminator_Addon_Aweber_Wp_Api
9
+ */
10
+ class Forminator_Addon_Aweber_Wp_Api {
11
+
12
+ /**
13
+ * Instances of aweber api
14
+ *
15
+ * @var array
16
+ */
17
+ private static $_instances = array();
18
+
19
+ private static $_access_token_url = 'https://auth.aweber.com/1.0/oauth/access_token';
20
+ private static $_api_base_url = 'https://api.aweber.com/1.0/';
21
+
22
+ const OAUTH_VERSION = '1.0';
23
+
24
+ private $_application_key = '';
25
+ private $_application_secret = '';
26
+ private $_oauth_token = '';
27
+ private $_oauth_token_secret = '';
28
+
29
+ /**
30
+ * Last data sent to aweber
31
+ *
32
+ * @since 1.0 Aweber Addon
33
+ * @var array
34
+ */
35
+ private $_last_data_sent = array();
36
+
37
+ /**
38
+ * Last data received from aweber
39
+ *
40
+ * @since 1.0 Aweber Addon
41
+ * @var array
42
+ */
43
+ private $_last_data_received = array();
44
+
45
+ /**
46
+ * Last URL requested
47
+ *
48
+ * @since 1.0 Aweber Addon
49
+ * @var string
50
+ */
51
+ private $_last_url_request = '';
52
+
53
+ /**
54
+ * Forminator_Addon_Aweber_Wp_Api constructor.
55
+ *
56
+ * @since 1.0 Aweber Addon
57
+ *
58
+ * @param $_application_key
59
+ * @param $_application_secret
60
+ *
61
+ * @param $_oauth_token
62
+ * @param $_oauth_token_secret
63
+ *
64
+ * @throws Forminator_Addon_Aweber_Wp_Api_Exception
65
+ */
66
+ public function __construct( $_application_key, $_application_secret, $_oauth_token, $_oauth_token_secret ) {
67
+ //prerequisites
68
+ if ( ! $_application_key || ! $_application_secret || ! $_oauth_token || ! $_oauth_token_secret ) {
69
+ throw new Forminator_Addon_Aweber_Wp_Api_Exception( __( 'Missing required API Credentials', Forminator::DOMAIN ) );
70
+ }
71
+
72
+ $this->_application_key = $_application_key;
73
+ $this->_application_secret = $_application_secret;
74
+ $this->_oauth_token = $_oauth_token;
75
+ $this->_oauth_token_secret = $_oauth_token_secret;
76
+ }
77
+
78
+ /**
79
+ * Get singleton
80
+ *
81
+ * @since 1.0 Aweber Addon
82
+ *
83
+ * @param $_application_key
84
+ * @param $_application_secret
85
+ *
86
+ * @param $_oauth_token
87
+ * @param $_oauth_token_secret
88
+ *
89
+ * @return Forminator_Addon_Aweber_Wp_Api|null
90
+ * @throws Forminator_Addon_Aweber_Wp_Api_Exception
91
+ */
92
+ public static function get_instance( $_application_key, $_application_secret, $_oauth_token, $_oauth_token_secret ) {
93
+ $args = func_get_args();
94
+ $args = implode( '|', $args );
95
+ $instance_key = md5( $args );
96
+ if ( ! isset( self::$_instances[ $instance_key ] ) ) {
97
+ self::$_instances[ $instance_key ] = new self( $_application_key, $_application_secret, $_oauth_token, $_oauth_token_secret );
98
+ }
99
+
100
+ return self::$_instances[ $instance_key ];
101
+ }
102
+
103
+ /**
104
+ * Add custom user agent on request
105
+ *
106
+ * @since 1.0 Aweber Addon
107
+ *
108
+ * @param $user_agent
109
+ *
110
+ * @return string
111
+ */
112
+ public function filter_user_agent( $user_agent ) {
113
+ $user_agent .= ' ForminatorAweber/' . FORMINATOR_ADDON_AWEBER_VERSION;
114
+
115
+ /**
116
+ * Filter user agent to be used by aweber api
117
+ *
118
+ * @since 1.1
119
+ *
120
+ * @param string $user_agent current user agent
121
+ */
122
+ $user_agent = apply_filters( 'forminator_addon_aweber_api_user_agent', $user_agent );
123
+
124
+ return $user_agent;
125
+ }
126
+
127
+ /**
128
+ * HTTP Request
129
+ *
130
+ * @since 1.0 Aweber Addon
131
+ *
132
+ * @param string $verb
133
+ * @param $url
134
+ * @param array $args
135
+ *
136
+ * @param array $headers
137
+ *
138
+ * @return array|mixed|object
139
+ * @throws Forminator_Addon_Aweber_Wp_Api_Exception
140
+ * @throws Forminator_Addon_Aweber_Wp_Api_Not_Found_Exception
141
+ */
142
+ private function _request( $verb = 'GET', $url, $args = array(), $headers = array() ) {
143
+ // Adding extra user agent for wp remote request
144
+ add_filter( 'http_headers_useragent', array( $this, 'filter_user_agent' ) );
145
+
146
+ /**
147
+ * Filter aweber url to be used on sending api request
148
+ *
149
+ * @since 1.1
150
+ *
151
+ * @param string $url full url with scheme
152
+ * @param string $verb `GET` `POST` `PUT` `DELETE` `PATCH`
153
+ * @param string $path requested path resource
154
+ * @param array $args argument sent to this function
155
+ */
156
+ $url = apply_filters( 'forminator_addon_aweber_api_url', $url, $verb, $args );
157
+
158
+ /**
159
+ * Filter aweber headers to sent on api request
160
+ *
161
+ * @since 1.1
162
+ *
163
+ * @param array $headers
164
+ * @param string $verb `GET` `POST` `PUT` `DELETE` `PATCH`
165
+ * @param string $url full url with scheme
166
+ * @param array $args argument sent to this function
167
+ */
168
+ $headers = apply_filters( 'forminator_addon_aweber_api_request_headers', $headers, $verb, $url, $args );
169
+
170
+ $_args = array(
171
+ 'method' => $verb,
172
+ 'headers' => $headers,
173
+ );
174
+
175
+ $request_data = $args;
176
+ ksort( $request_data );
177
+
178
+ /**
179
+ * Filter aweber request data to be used on sending api request
180
+ *
181
+ * @since 1.1
182
+ *
183
+ * @param array $request_data
184
+ * @param string $verb `GET` `POST` `PUT` `DELETE` `PATCH`
185
+ * @param string $url full url with scheme
186
+ */
187
+ $args = apply_filters( 'forminator_addon_aweber_api_request_data', $request_data, $verb, $url );
188
+
189
+ // $oauth_url_params doesnt need to be included
190
+ $this->_last_url_request = $url;
191
+
192
+ if ( 'PATCH' === $verb ) {
193
+ $oauth_url_params = $this->get_prepared_request( $verb, $url, array() );
194
+ $url .= ( '?' . http_build_query( $oauth_url_params ) );
195
+ $_args['body'] = wp_json_encode( $args );
196
+ } else {
197
+ # WARNING: If not being sent as json, non-primitive items in data must be json serialized in GET and POST.
198
+ foreach ( $args as $key => $value ) {
199
+ if ( is_array( $value ) ) {
200
+ $args[ $key ] = wp_json_encode( $value );
201
+ }
202
+ }
203
+ if ( 'POST' === $verb ) {
204
+ $_args['body'] = $this->get_prepared_request( $verb, $url, $args );
205
+ } else {
206
+ $oauth_url_params = $this->get_prepared_request( $verb, $url, $args );
207
+ $url .= ( '?' . http_build_query( $oauth_url_params ) );
208
+ }
209
+ }
210
+
211
+ $this->_last_data_sent = $args;
212
+
213
+ /**
214
+ * Filter aweber wp_remote_request args
215
+ *
216
+ * @since 1.1
217
+ *
218
+ * @param array $_args
219
+ */
220
+ $_args = apply_filters( 'forminator_addon_aweber_api_remote_request_args', $_args );
221
+
222
+ $res = wp_remote_request( $url, $_args );
223
+ $wp_response = $res;
224
+
225
+ remove_filter( 'http_headers_useragent', array( $this, 'filter_user_agent' ) );
226
+
227
+ if ( is_wp_error( $res ) || ! $res ) {
228
+ throw new Forminator_Addon_Aweber_Wp_Api_Exception(
229
+ __( 'Failed to process request, make sure your API URL is correct and your server has internet connection.', Forminator::DOMAIN )
230
+ );
231
+ }
232
+
233
+ if ( isset( $res['response']['code'] ) ) {
234
+ $status_code = $res['response']['code'];
235
+ $msg = '';
236
+ if ( $status_code >= 400 ) {
237
+
238
+ if ( isset( $res['response']['message'] ) ) {
239
+ $msg = $res['response']['message'];
240
+ }
241
+
242
+ $body_json = wp_remote_retrieve_body( $res );
243
+
244
+ $res_json = json_decode( $body_json );
245
+ if ( ! is_null( $res_json ) && is_object( $res_json ) && isset( $res_json->error ) && isset( $res_json->error->message ) ) {
246
+ $msg = $res_json->error->message;
247
+ }
248
+
249
+ if ( 404 === $status_code ) {
250
+ throw new Forminator_Addon_Aweber_Wp_Api_Not_Found_Exception( sprintf( __( 'Failed to processing request : %s', Forminator::DOMAIN ), $msg ) );
251
+ }
252
+ // /* translators: ... */
253
+ throw new Forminator_Addon_Aweber_Wp_Api_Exception( sprintf( __( 'Failed to processing request : %s', Forminator::DOMAIN ), $msg ) );
254
+ }
255
+ }
256
+
257
+ $body = wp_remote_retrieve_body( $res );
258
+
259
+ // probably silent mode
260
+ if ( ! empty( $body ) ) {
261
+ $res = json_decode( $body );
262
+ // fallback to parse args when fail
263
+ if ( empty( $res ) ) {
264
+ $res = wp_parse_args( $body, array() );
265
+
266
+ //json-ify to make same format as json response (which is object not array)
267
+ $res = wp_json_encode( $res );
268
+ $res = json_decode( $res );
269
+ }
270
+ }
271
+
272
+ $response = $res;
273
+ /**
274
+ * Filter aweber api response returned to addon
275
+ *
276
+ * @since 1.1
277
+ *
278
+ * @param mixed $response original wp remote request response or decoded body if available
279
+ * @param string $body original content of http response's body
280
+ * @param array|WP_Error $wp_response original wp remote request response
281
+ */
282
+ $res = apply_filters( 'forminator_addon_aweber_api_response', $response, $body, $wp_response );
283
+
284
+ $this->_last_data_received = $res;
285
+
286
+ return $res;
287
+ }
288
+
289
+
290
+ /**
291
+ * Get Oauth Request data of AWeber that need to be send on API Request
292
+ *
293
+ * @since 1.0 Aweber Addon
294
+ * @return array
295
+ */
296
+ public function get_oauth_request_data() {
297
+ $timestamp = time();
298
+ $oauth_request_data = array(
299
+ 'oauth_token' => $this->get_oauth_token(),
300
+ 'oauth_consumer_key' => $this->_application_key,
301
+ 'oauth_version' => self::OAUTH_VERSION,
302
+ 'oauth_timestamp' => $timestamp,
303
+ 'oauth_signature_method' => 'HMAC-SHA1',
304
+ 'oauth_nonce' => Forminator_Addon_Aweber_Oauth::generate_oauth_nonce( $timestamp ),
305
+ );
306
+
307
+ /**
308
+ * Filter required Oauth Request data of AWeber that need to be send on API Request
309
+ *
310
+ * @since 1.3
311
+ *
312
+ * @param array $oauth_request_data default oauth request data
313
+ * @param int $timestamp current timestamp for future reference
314
+ */
315
+ $oauth_request_data = apply_filters( 'forminator_addon_aweber_oauth_request_data', $oauth_request_data, $timestamp );
316
+
317
+ return $oauth_request_data;
318
+ }
319
+
320
+ /**
321
+ * Sign Aweber API request
322
+ *
323
+ * @since 1.0 Aweber Addon
324
+ *
325
+ * @param $method
326
+ * @param $url
327
+ * @param $data
328
+ *
329
+ * @return mixed
330
+ */
331
+ public function get_signed_request( $method, $url, $data ) {
332
+ $application_secret = $this->_application_secret;
333
+ $oauth_token_secret = $this->get_oauth_token_secret();
334
+
335
+ $base = Forminator_Addon_Aweber_Oauth::create_signature_base( $method, $url, $data );
336
+ $key = Forminator_Addon_Aweber_Oauth::create_signature_key( $application_secret, $oauth_token_secret );
337
+ $data['oauth_signature'] = Forminator_Addon_Aweber_Oauth::create_signature( $base, $key );
338
+ $signed_request = $data;
339
+
340
+ /**
341
+ * Filter signed request
342
+ *
343
+ * @since 1.3
344
+ *
345
+ * @param array $signed_request
346
+ * @param string $method
347
+ * @param string $url
348
+ * @param array $data
349
+ * @param string $application_secret
350
+ * @param string $oauth_token_secret
351
+ */
352
+ $signed_request = apply_filters( 'forminator_addon_aweber_oauth_signed_request', $signed_request, $method, $url, $data, $application_secret, $oauth_token_secret );
353
+
354
+ return $signed_request;
355
+ }
356
+
357
+ /**
358
+ * prepare Request
359
+ *
360
+ * @since 1.0 Aweber Addon
361
+ *
362
+ * @param mixed $method HTTP method
363
+ * @param mixed $url URL for the request
364
+ * @param mixed $data The data to generate oauth data and be signed
365
+ *
366
+ * @return array
367
+ */
368
+ public function get_prepared_request( $method, $url, $data ) {
369
+ $oauth_data = $this->get_oauth_request_data();
370
+ $data = array_merge( $data, $oauth_data );
371
+ $data = $this->get_signed_request( $method, $url, $data );
372
+ $prepared_request_data = $data;
373
+
374
+ /**
375
+ * Filter prepared request data, Oauth data added and signed
376
+ *
377
+ * @since 1.3
378
+ *
379
+ * @param array $prepared_request_data
380
+ * @param string $method
381
+ * @param string $url
382
+ * @param array $data
383
+ */
384
+ $prepared_request_data = apply_filters( 'forminator_addon_aweber_oauth_prepared_request', $prepared_request_data, $method, $url, $data );
385
+
386
+
387
+ return $prepared_request_data;
388
+ }
389
+
390
+ /**
391
+ * Get Access Token
392
+ *
393
+ * @since 1.0 Aweber Addon
394
+ *
395
+ * @param $oauth_verifier
396
+ * @param array $args
397
+ *
398
+ * @return object contains oauth_token and oauth_token_secret
399
+ *
400
+ * @throws Forminator_Addon_Aweber_Wp_Api_Exception
401
+ * @throws Forminator_Addon_Aweber_Wp_Api_Not_Found_Exception
402
+ */
403
+ public function get_access_token( $oauth_verifier, $args = array() ) {
404
+ $default_args = array(
405
+ 'oauth_verifier' => $oauth_verifier,
406
+ );
407
+
408
+ $args = array_merge( $default_args, $args );
409
+
410
+ $access_tokens = $this->_request( 'POST', self::$_access_token_url, $args );
411
+
412
+ if ( ! is_object( $access_tokens ) ) {
413
+ throw new Forminator_Addon_Aweber_Wp_Api_Exception( __( 'Invalid access token', Forminator::DOMAIN ) );
414
+ }
415
+
416
+ if ( ! isset( $access_tokens->oauth_token_secret ) || ! isset( $access_tokens->oauth_token ) ) {
417
+ throw new Forminator_Addon_Aweber_Wp_Api_Exception( __( 'Invalid access token', Forminator::DOMAIN ) );
418
+ }
419
+
420
+ return $access_tokens;
421
+ }
422
+
423
+ /**
424
+ * Get related accounts
425
+ *
426
+ * @since 1.0 Aweber Addon
427
+ *
428
+ * @param array $args
429
+ *
430
+ * @return array|mixed|object
431
+ * @throws Forminator_Addon_Aweber_Wp_Api_Exception
432
+ * @throws Forminator_Addon_Aweber_Wp_Api_Not_Found_Exception
433
+ */
434
+ public function get_accounts( $args = array() ) {
435
+ $default_args = array();
436
+ $args = array_merge( $default_args, $args );
437
+
438
+ return $this->_request( 'GET', $this->get_api_url( 'accounts' ), $args );
439
+ }
440
+
441
+ /**
442
+ * Get lists on an account
443
+ *
444
+ * @since 1.0 Aweber Addon
445
+ *
446
+ * @param $account_id
447
+ * @param array $args
448
+ *
449
+ * @return array|mixed|object
450
+ * @throws Forminator_Addon_Aweber_Wp_Api_Exception
451
+ * @throws Forminator_Addon_Aweber_Wp_Api_Not_Found_Exception
452
+ */
453
+ public function get_account_lists( $account_id, $args = array() ) {
454
+ $default_args = array();
455
+ $args = array_merge( $default_args, $args );
456
+
457
+ return $this->_request( 'GET', $this->get_api_url( 'accounts/' . rawurlencode( trim( $account_id ) ) . '/lists' ), $args );
458
+ }
459
+
460
+ /**
461
+ * Get Custom Fields on the list
462
+ *
463
+ * @since 1.0 Aweber Addon
464
+ *
465
+ * @param $account_id
466
+ * @param $list_id
467
+ * @param array $args
468
+ *
469
+ * @return array|mixed|object
470
+ * @throws Forminator_Addon_Aweber_Wp_Api_Exception
471
+ * @throws Forminator_Addon_Aweber_Wp_Api_Not_Found_Exception
472
+ */
473
+ public function get_account_list_custom_fields( $account_id, $list_id, $args = array() ) {
474
+ $default_args = array();
475
+ $args = array_merge( $default_args, $args );
476
+
477
+ return $this->_request(
478
+ 'GET',
479
+ $this->get_api_url(
480
+ 'accounts/' .
481
+ rawurlencode( trim( $account_id ) ) .
482
+ '/lists/' .
483
+ rawurlencode( trim( $list_id ) ) . '/custom_fields'
484
+ ),
485
+ $args
486
+ );
487
+ }
488
+
489
+ /**
490
+ * Add subscriber to account list
491
+ *
492
+ * @since 1.0 Aweber Addon
493
+ *
494
+ * @param $account_id
495
+ * @param $list_id
496
+ * @param array $args
497
+ *
498
+ * @return array|mixed|object
499
+ * @throws Forminator_Addon_Aweber_Wp_Api_Exception
500
+ * @throws Forminator_Addon_Aweber_Wp_Api_Not_Found_Exception
501
+ */
502
+ public function add_account_list_subscriber( $account_id, $list_id, $args = array() ) {
503
+ $default_args = array(
504
+ 'ws.op' => 'create',
505
+ 'email' => '',
506
+ );
507
+ $args = array_merge( $default_args, $args );
508
+
509
+ if ( empty( $args['email'] ) ) {
510
+ throw new Forminator_Addon_Aweber_Wp_Api_Exception( __( 'Email is required on add AWeber subscriber.', Forminator::DOMAIN ) );
511
+ }
512
+
513
+ return $this->_request(
514
+ 'POST',
515
+ $this->get_api_url(
516
+ 'accounts/' .
517
+ rawurlencode( trim( $account_id ) ) .
518
+ '/lists/' .
519
+ rawurlencode( trim( $list_id ) ) . '/subscribers'
520
+ ),
521
+ $args
522
+ );
523
+ }
524
+
525
+ /**
526
+ * Update subscriber to account list
527
+ *
528
+ * @since 1.0 Aweber Addon
529
+ *
530
+ * @param $account_id
531
+ * @param $list_id
532
+ * @param $subscriber_id
533
+ * @param array $args
534
+ *
535
+ * @return array|mixed|object
536
+ * @throws Forminator_Addon_Aweber_Wp_Api_Exception
537
+ * @throws Forminator_Addon_Aweber_Wp_Api_Not_Found_Exception
538
+ */
539
+ public function update_account_list_subscriber( $account_id, $list_id, $subscriber_id, $args = array() ) {
540
+ $default_args = array(
541
+ 'email' => '',
542
+ );
543
+ $args = array_merge( $default_args, $args );
544
+
545
+ if ( empty( $args['email'] ) ) {
546
+ throw new Forminator_Addon_Aweber_Wp_Api_Exception( __( 'Email is required on update AWeber subscriber.', Forminator::DOMAIN ) );
547
+ }
548
+
549
+ return $this->_request(
550
+ 'PATCH',
551
+ $this->get_api_url(
552
+ 'accounts/' .
553
+ rawurlencode( trim( $account_id ) ) .
554
+ '/lists/' .
555
+ rawurlencode( trim( $list_id ) ) .
556
+ '/subscribers/' .
557
+ rawurlencode( trim( $subscriber_id ) )
558
+ ),
559
+ $args,
560
+ array(
561
+ 'Content-Type' => 'application/json',
562
+ )
563
+ );
564
+ }
565
+
566
+ /**
567
+ * GET subscriber on account list
568
+ *
569
+ * @since 1.0 Aweber Addon
570
+ *
571
+ * @param $account_id
572
+ * @param $list_id
573
+ * @param array $args
574
+ *
575
+ * @return array|mixed|object
576
+ * @throws Forminator_Addon_Aweber_Wp_Api_Exception
577
+ * @throws Forminator_Addon_Aweber_Wp_Api_Not_Found_Exception
578
+ */
579
+ public function find_account_list_subscriber( $account_id, $list_id, $args = array() ) {
580
+ $default_args = array(
581
+ 'ws.op' => 'find',
582
+ );
583
+ $args = array_merge( $default_args, $args );
584
+
585
+ return $this->_request(
586
+ 'GET',
587
+ $this->get_api_url(
588
+ 'accounts/' .
589
+ rawurlencode( trim( $account_id ) ) .
590
+ '/lists/' .
591
+ rawurlencode( trim( $list_id ) ) . '/subscribers'
592
+ ),
593
+ $args
594
+ );
595
+ }
596
+
597
+ /**
598
+ * Get url for get access token
599
+ *
600
+ * @since 1.0 Aweber Addon
601
+ * @return string
602
+ */
603
+ public function get_access_token_url() {
604
+ $access_token_url = self::$_access_token_url;
605
+
606
+ /**
607
+ * Filter access_token_url
608
+ *
609
+ * @since 1.3
610
+ *
611
+ * @param string $access_token_url
612
+ */
613
+ $access_token_url = apply_filters( 'forminator_addon_aweber_oauth_access_token_url', $access_token_url );
614
+
615
+ return $access_token_url;
616
+ }
617
+
618
+ /**
619
+ * Get API URL
620
+ *
621
+ * @param $path
622
+ *
623
+ * @return string
624
+ */
625
+ public function get_api_url( $path ) {
626
+ $api_base_url = self::$_api_base_url;
627
+ $api_url = trailingslashit( $api_base_url ) . $path;
628
+
629
+ /**
630
+ * Filter api_url to send request
631
+ *
632
+ * @since 1.3
633
+ *
634
+ * @param string $api_url
635
+ * @param string $api_base_url
636
+ * @param string $path
637
+ */
638
+ $api_url = apply_filters( 'forminator_addon_aweber_oauth_api_url', $api_url, $api_base_url, $path );
639
+
640
+ return $api_url;
641
+ }
642
+
643
+ /**
644
+ * Get Oauth Token
645
+ *
646
+ * @since 1.0 Aweber Addon
647
+ * @return string
648
+ */
649
+ public function get_oauth_token() {
650
+ return $this->_oauth_token;
651
+ }
652
+
653
+ /**
654
+ * Get Oauth Token Secret
655
+ *
656
+ * @since 1.0 Aweber Addon
657
+ * @return string
658
+ */
659
+ public function get_oauth_token_secret() {
660
+ return $this->_oauth_token_secret;
661
+ }
662
+
663
+ /**
664
+ * Get last data sent
665
+ *
666
+ * @since 1.0 Aweber Addon
667
+ *
668
+ * @return array
669
+ */
670
+ public function get_last_data_sent() {
671
+ return $this->_last_data_sent;
672
+ }
673
+
674
+ /**
675
+ * Get last data received
676
+ *
677
+ * @since 1.0 Aweber Addon
678
+ *
679
+ * @return array
680
+ */
681
+ public function get_last_data_received() {
682
+ return $this->_last_data_received;
683
+ }
684
+
685
+ /**
686
+ * Get last data received
687
+ *
688
+ * @since 1.0 Aweber Addon
689
+ *
690
+ * @return string
691
+ */
692
+ public function get_last_url_request() {
693
+ return $this->_last_url_request;
694
+ }
695
+
696
+ }
addons/pro/aweber/views/form-settings/map-fields.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'error_message' => '',
5
+ 'multi_id' => '',
6
+ 'fields_map' => array(),
7
+ 'fields' => array(),
8
+ 'form_fields' => array(),
9
+ 'email_fields' => array(),
10
+ );
11
+ /** @var array $template_vars */
12
+ foreach ( $template_vars as $key => $val ) {
13
+ $vars[ $key ] = $val;
14
+ }
15
+
16
+ ?>
17
+ <div class="integration-header">
18
+ <h3 class="sui-box-title" id="dialogTitle2"><?php echo esc_html( __( 'Assign Fields', Forminator::DOMAIN ) ); ?></h3>
19
+ <p><?php esc_html_e( 'Match up your form fields with your AWeber fields to make sure we\'re sending data to the right place.', Forminator::DOMAIN ); ?></p>
20
+ <?php if ( ! empty( $vars['error_message'] ) ) : ?>
21
+ <span class="sui-notice sui-notice-error"><p><?php echo esc_html( $vars['error_message'] ); ?></p></span>
22
+ <?php endif; ?>
23
+ </div>
24
+ <form>
25
+ <table class="sui-table">
26
+ <thead>
27
+ <tr>
28
+ <th><?php esc_html_e( 'AWeber Field', Forminator::DOMAIN ); ?></th>
29
+ <th><?php esc_html_e( 'Forminator Field', Forminator::DOMAIN ); ?></th>
30
+ </tr>
31
+ </thead>
32
+ <tbody>
33
+ <?php foreach ( $vars['fields'] as $key => $field_title ) : ?>
34
+ <tr>
35
+ <td>
36
+ <?php echo esc_html( $field_title ); ?>
37
+ <?php if ( 'default_field_email' === $key ) : ?>
38
+ <span class="integrations-required-field">*</span>
39
+ <?php endif; ?>
40
+ </td>
41
+ <td>
42
+ <?php
43
+ $forminator_fields = $vars['form_fields'];
44
+ if ( 'default_field_email' === $key ) {
45
+ $forminator_fields = $vars['email_fields'];
46
+ }
47
+ $current_error = '';
48
+ $current_selected = '';
49
+ if ( isset( $vars[ $key . '_error' ] ) && ! empty( $vars[ $key . '_error' ] ) ) {
50
+ $current_error = $vars[ $key . '_error' ];
51
+ }
52
+ if ( isset( $vars['fields_map'][ $key ] ) && ! empty( $vars['fields_map'][ $key ] ) ) {
53
+ $current_selected = $vars['fields_map'][ $key ];
54
+ }
55
+ ?>
56
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $current_error ) ? 'sui-form-field-error' : '' ); ?>">
57
+ <label>
58
+ <select class="sui-select" name="fields_map[<?php echo esc_attr( $key ); ?>]">
59
+ <option value="">None</option>
60
+ <?php foreach ( $forminator_fields as $forminator_field ) : ?>
61
+ <option value="<?php echo esc_attr( $forminator_field['element_id'] ); ?>"
62
+ <?php selected( $current_selected, $forminator_field['element_id'] ); ?>>
63
+ <?php echo esc_html( $forminator_field['field_label'] . ' | ' . $forminator_field['element_id'] ); ?>
64
+ </option>
65
+ <?php endforeach; ?>
66
+ </select>
67
+ </label>
68
+ <?php if ( ! empty( $current_error ) ) : ?>
69
+ <span class="sui-error-message"><?php echo esc_html( $current_error ); ?></span>
70
+ <?php endif; ?>
71
+ </div>
72
+ </td>
73
+ </tr>
74
+ <?php endforeach; ?>
75
+ </tbody>
76
+ </table>
77
+ <input type="hidden" name="multi_id" value="<?php echo esc_attr( $vars['multi_id'] ); ?>">
78
+ </form>
addons/pro/aweber/views/form-settings/pick-name.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'error_message' => '',
5
+ 'name' => '',
6
+ 'name_error' => '',
7
+ 'multi_id' => '',
8
+ );
9
+ /** @var array $template_vars */
10
+ foreach ( $template_vars as $key => $val ) {
11
+ $vars[ $key ] = $val;
12
+ }
13
+
14
+ ?>
15
+ <div class="integration-header">
16
+ <h3 class="sui-box-title" id="dialogTitle2"><?php echo esc_html( __( 'Setup Name', Forminator::DOMAIN ) ); ?></h3>
17
+ <p><?php esc_html_e( 'Setup friendly name for this integration, so it will be easily identified by you. ', Forminator::DOMAIN ); ?></p>
18
+ <?php if ( ! empty( $vars['error_message'] ) ) : ?>
19
+ <span class="sui-notice sui-notice-error"><p><?php echo esc_html( $vars['error_message'] ); ?></p></span>
20
+ <?php endif; ?>
21
+ </div>
22
+ <form>
23
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['name_error'] ) ? 'sui-form-field-error' : '' ); ?>">
24
+ <label class="sui-label"><?php esc_html_e( 'Name', Forminator::DOMAIN ); ?></label>
25
+ <input
26
+ class="sui-form-control"
27
+ name="name" placeholder="<?php echo esc_attr( __( 'Friendly Name', Forminator::DOMAIN ) ); ?>"
28
+ value="<?php echo esc_attr( $vars['name'] ); ?>">
29
+ <?php if ( ! empty( $vars['name_error'] ) ) : ?>
30
+ <span class="sui-error-message"><?php echo esc_html( $vars['name_error'] ); ?></span>
31
+ <?php endif; ?>
32
+ </div>
33
+ <input type="hidden" name="multi_id" value="<?php echo esc_attr( $vars['multi_id'] ); ?>">
34
+ </form>
addons/pro/aweber/views/form-settings/setup-list.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'error_message' => '',
5
+ 'list_id' => '',
6
+ 'list_id_error' => '',
7
+ 'multi_id' => '',
8
+ 'lists' => array(),
9
+ );
10
+ /** @var array $template_vars */
11
+ foreach ( $template_vars as $key => $val ) {
12
+ $vars[ $key ] = $val;
13
+ }
14
+
15
+ ?>
16
+ <div class="integration-header">
17
+ <h3 class="sui-box-title" id="dialogTitle2"><?php echo esc_html( __( 'Choose List', Forminator::DOMAIN ) ); ?></h3>
18
+ <p><?php esc_html_e( 'Pick AWeber List for new subscriber to be added to.', Forminator::DOMAIN ); ?></p>
19
+ <?php if ( ! empty( $vars['error_message'] ) ) : ?>
20
+ <span class="sui-notice sui-notice-error"><p><?php echo esc_html( $vars['error_message'] ); ?></p></span>
21
+ <?php endif; ?>
22
+ </div>
23
+ <form>
24
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['list_id_error'] ) ? 'sui-form-field-error' : '' ); ?>">
25
+ <label class="sui-label"><?php esc_html_e( 'List', Forminator::DOMAIN ); ?>
26
+ <select name="list_id" class="sui-select sui-form-control">
27
+ <option><?php esc_html_e( 'Please select a list', Forminator::DOMAIN ); ?></option>
28
+ <?php foreach ( $vars['lists'] as $list_id => $list_name ) : ?>
29
+ <option value="<?php echo esc_attr( $list_id ); ?>" <?php selected( $vars['list_id'], $list_id ); ?>><?php echo esc_html( $list_name ); ?></option>
30
+ <?php endforeach; ?>
31
+ </select>
32
+ <?php if ( ! empty( $vars['list_id_error'] ) ) : ?>
33
+ <span class="sui-error-message"><?php echo esc_html( $vars['list_id_error'] ); ?></span>
34
+ <?php endif; ?>
35
+ </label>
36
+ </div>
37
+ <input type="hidden" name="multi_id" value="<?php echo esc_attr( $vars['multi_id'] ); ?>">
38
+ </form>
addons/pro/aweber/views/form-settings/setup-options.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'error_message' => '',
5
+ 'multi_id' => '',
6
+ 'ad_tracking' => '',
7
+ 'ad_tracking_error' => '',
8
+ 'tags_fields' => array(),
9
+ 'tags_selected_fields' => array(),
10
+ 'fields' => array(),
11
+ 'tags_error' => '',
12
+ );
13
+ /** @var array $template_vars */
14
+ foreach ( $template_vars as $key => $val ) {
15
+ $vars[ $key ] = $val;
16
+ }
17
+
18
+ ?>
19
+ <div class="integration-header">
20
+ <h3 class="sui-box-title" id="dialogTitle2"><?php echo esc_html( __( 'Additional Options', Forminator::DOMAIN ) ); ?></h3>
21
+ <p><?php esc_html_e( 'Configure additional options for AWeber integration.', Forminator::DOMAIN ); ?></p>
22
+ <?php if ( ! empty( $vars['error_message'] ) ) : ?>
23
+ <span class="sui-notice sui-notice-error"><p><?php echo esc_html( $vars['error_message'] ); ?></p></span>
24
+ <?php endif; ?>
25
+ </div>
26
+
27
+ <form>
28
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['ad_tracking_error'] ) ? 'sui-form-field-error' : '' ); ?>">
29
+
30
+ <label class="sui-label"><?php esc_html_e( 'Ad Tracking', Forminator::DOMAIN ); ?></label>
31
+
32
+ <div class="sui-insert-variables">
33
+
34
+ <input id="ad_tracking"
35
+ class="sui-form-control"
36
+ name="ad_tracking"
37
+ placeholder="<?php echo esc_attr( __( 'Ad Tracking', Forminator::DOMAIN ) ); ?>"
38
+ value="<?php echo esc_attr( $vars['ad_tracking'] ); ?>">
39
+
40
+ <select data-textarea-id="ad_tracking">
41
+ <?php foreach ( $vars['fields'] as $field ) : ?>
42
+ <option value="{<?php echo esc_attr( $field['element_id'] ); ?>}" data-content="{<?php echo esc_attr( $field['element_id'] ); ?>}"><?php echo esc_html( $field['field_label'] ); ?></option>
43
+ <?php endforeach; ?>
44
+ </select>
45
+
46
+ </div>
47
+
48
+ <?php if ( ! empty( $vars['ad_tracking_error'] ) ) : ?>
49
+ <span class="sui-error-message"><?php echo esc_html( $vars['ad_tracking_error'] ); ?></span>
50
+ <?php endif; ?>
51
+ <span class="sui-description">
52
+ <?php esc_html_e( 'Use 20 or fewer characters to label subscribers based on how they signed up. Find complete article', Forminator::DOMAIN ); ?>
53
+ <a href="https://help.aweber.com/hc/en-us/articles/204028836-What-is-Ad-Tracking-" target="_blank"><?php esc_html_e( 'here', Forminator::DOMAIN ); ?></a>.
54
+ </span>
55
+
56
+ </div>
57
+
58
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['tags_error'] ) ? 'sui-form-field-error' : '' ); ?>">
59
+ <label class="sui-label" for="tags"><?php esc_html_e( 'Tags', Forminator::DOMAIN ); ?></label>
60
+ <select class="sui-select fui-multi-select" name="tags[]" id="tags"
61
+ multiple="multiple"
62
+ data-reorder="1"
63
+ data-tags="true"
64
+ data-token-separators="[',']"
65
+ data-placeholder=""
66
+ data-allow-clear="false">
67
+ <?php foreach ( $vars['tags_selected_fields'] as $forminator_field ) : ?>
68
+ <option
69
+ value="<?php echo esc_attr( $forminator_field['element_id'] ); ?>"
70
+ selected="selected"
71
+ ><?php echo esc_html( $forminator_field['field_label'] ); ?></option>
72
+ <?php endforeach; ?>
73
+ <?php foreach ( $vars['tags_fields'] as $forminator_field ) : ?>
74
+ <option
75
+ value="{<?php echo esc_attr( $forminator_field['element_id'] ); ?>}"
76
+ ><?php echo esc_html( $forminator_field['field_label'] . ' | ' . $forminator_field['element_id'] ); ?></option>
77
+ <?php endforeach; ?>
78
+ </select>
79
+ <?php if ( ! empty( $vars['tags_error'] ) ) : ?>
80
+ <span class="sui-error-message"><?php echo esc_html( $vars['tags_error'] ); ?></span>
81
+ <?php endif; ?>
82
+ <span class="sui-description">
83
+ <?php esc_html_e( 'Available fields value or free text can be used as tags. Have a campaign that’s triggered when a subscriber is tagged? Enter the appropriate tag to add the subscriber to the campaign, and they will immediately begin receiving your messages. More info about AWeber subscriber tags can be found ',
84
+ Forminator::DOMAIN ); ?>
85
+ <a href="https://help.aweber.com/hc/en-us/articles/212677877-How-do-I-use-Tags-with-Campaigns-" target="_blank"><?php esc_html_e( 'here', Forminator::DOMAIN ); ?></a>.
86
+ </span>
87
+ </div>
88
+
89
+ <input type="hidden" name="multi_id" value="<?php echo esc_attr( $vars['multi_id'] ); ?>">
90
+ </form>
addons/pro/aweber/views/sections/authorize.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'error_message' => '',
5
+ 'is_close' => false,
6
+ );
7
+ /** @var array $template_vars */
8
+ foreach ( $template_vars as $key => $val ) {
9
+ $vars[ $key ] = $val;
10
+ }
11
+ ?>
12
+
13
+ <div id="forminator-integrations" class="wpmudev-settings--box">
14
+ <div class="sui-box">
15
+ <div class="sui-box-header">
16
+ <h2 class="sui-box-title"><?php esc_html_e( "Authorizing AWeber", Forminator::DOMAIN ); ?></h2>
17
+ </div>
18
+ <div class="sui-box-body">
19
+ <?php if ( ! empty( $vars['error_message'] ) ) : ?>
20
+ <span class="sui-notice sui-notice-error"><p><?php echo esc_html( $vars['error_message'] ); ?></p></span>
21
+ <?php elseif ( $vars['is_close'] ): ?>
22
+ <span class="sui-notice sui-notice-success">
23
+ <p>
24
+ <?php
25
+ esc_html_e( 'Successfully authorized AWeber, you can go back to integration settings.',
26
+ Forminator::DOMAIN
27
+ );
28
+ ?>
29
+ </p>
30
+ </span>
31
+ <?php else : ?>
32
+ <span class="sui-notice sui-notice-loading">
33
+ <p><?php esc_html_e( 'Please Wait...', Forminator::DOMAIN ); ?></p>
34
+ </span>
35
+ <?php endif; ?>
36
+ </div>
37
+ </div>
38
+ </div>
39
+
40
+ <script>
41
+ // SO.
42
+ function getHashParams() {
43
+
44
+ var hashParams = {};
45
+ var e,
46
+ a = /\+/g, // Regex for replacing addition symbol with a space
47
+ r = /([^&;=]+)=?([^&;]*)/g,
48
+ d = function (s) {
49
+ return decodeURIComponent(s.replace(a, " "));
50
+ },
51
+ q = window.location.hash.substring(1);
52
+
53
+ while (e = r.exec(q))
54
+ hashParams[d(e[1])] = d(e[2]);
55
+
56
+ return hashParams;
57
+ }
58
+
59
+ (function ($) {
60
+ $(document).ready(function (e) {
61
+ <?php if ($vars['is_close']): ?>
62
+
63
+ setTimeout(function () {
64
+ window.close();
65
+ }, 3000);
66
+
67
+ <?php endif; ?>
68
+ var hash_params = getHashParams();
69
+ if (typeof hash_params.token !== 'undefined') {
70
+ var current_href = window.location.href;
71
+ current_href = current_href.replace(window.location.hash, '');
72
+
73
+ window.location.href = current_href + '&token=' + hash_params.token;
74
+ }
75
+ });
76
+
77
+ })(jQuery);
78
+ </script>
addons/pro/aweber/views/settings/authorize.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'account_id' => 0,
5
+ 'auth_url' => '',
6
+ 'is_connected' => false,
7
+ );
8
+ /** @var array $template_vars */
9
+ foreach ( $template_vars as $key => $val ) {
10
+ $vars[ $key ] = $val;
11
+ }
12
+ ?>
13
+ <div class="integration-header">
14
+ <h3 class="sui-box-title" id="dialogTitle2"><?php echo esc_html( sprintf( __( 'Connect %1$s', Forminator::DOMAIN ), 'AWeber' ) ); ?></h3>
15
+ <?php if ( ! empty( $vars['account_id'] ) ) : ?>
16
+ <span class="sui-notice sui-notice-success">
17
+ <p><?php esc_html_e( 'Your AWeber account is already authorized.', Forminator::DOMAIN ); ?> </p>
18
+ </span>
19
+ <?php else : ?>
20
+ <p><?php esc_html_e( 'Authorize Forminator to connect with your AWeber account in order to send data from your forms.', Forminator::DOMAIN ); ?></p>
21
+ <?php endif ?>
22
+ </div>
23
+ <?php if ( empty( $vars['account_id'] ) ) : ?>
24
+ <a href="<?php echo esc_attr( $vars['auth_url'] ); ?>" target="_blank" class="sui-button sui-button-primary forminator-addon-connect"><?php esc_html_e( 'AUTHORIZE', Forminator::DOMAIN ); ?></a>
25
+ <?php endif ?>
26
+ <?php if ( $vars['is_connected'] ) : ?>
27
+ <button class="sui-button sui-button-ghost forminator-addon-disconnect"><?php esc_html_e( 'DISCONNECT', Forminator::DOMAIN ); ?></button>
28
+ <?php endif ?>
29
+
addons/pro/aweber/views/settings/success-authorize.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <div class="integration-header">
2
+ <h3 class="sui-box-title" id="dialogTitle2">
3
+ <?php echo esc_html( sprintf( __( '%1$s Added', Forminator::DOMAIN ), 'AWeber' ) ); ?>
4
+ </h3>
5
+ <p><?php esc_html_e( 'You can now go to your forms and assign them to this integration', Forminator::DOMAIN ); ?></p>
6
+ </div>
7
+ <button class="sui-button forminator-addon-close"><?php esc_html_e( 'CLOSE', Forminator::DOMAIN ); ?></button>
addons/pro/aweber/views/settings/wait-authorize.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'account_id' => 0,
5
+ 'auth_url' => '',
6
+ );
7
+ /** @var array $template_vars */
8
+ foreach ( $template_vars as $key => $val ) {
9
+ $vars[ $key ] = $val;
10
+ }
11
+ ?>
12
+ <div class="integration-header">
13
+ <h3 class="sui-box-title" id="dialogTitle2"></h3>
14
+ <p class="" aria-label="Loading content">
15
+ <i class="sui-icon-loader sui-loading" aria-hidden="true"></i>
16
+ </p>
17
+ <p><?php esc_html_e( 'We are waiting for authorization from AWeber...', Forminator::DOMAIN ); ?></p>
18
+ </div>
19
+ <?php if ( empty( $vars['account_id'] ) ) : ?>
20
+ <a href="<?php echo esc_attr( $vars['auth_url'] ); ?>" target="_blank" class="sui-button disable-loader"><?php esc_html_e( 'RETRY', Forminator::DOMAIN ); ?></a>
21
+ <?php endif ?>
22
+
addons/pro/campaignmonitor/assets/icons/campaignmonitor.png ADDED
Binary file
addons/pro/campaignmonitor/assets/icons/campaignmonitor@2x.png ADDED
Binary file
addons/pro/campaignmonitor/assets/img/campaignmonitor.png ADDED
Binary file
addons/pro/campaignmonitor/assets/img/campaignmonitor@2x.png ADDED
Binary file
addons/pro/campaignmonitor/campaignmonitor.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Addon Name: Campaignmonitor
5
+ * Version: 1.0
6
+ * Plugin URI: https://premium.wpmudev.org/
7
+ * Description: Integrate Forminator Custom Forms with Campaignmonitor to get notified in real time.
8
+ * Author: WPMU DEV
9
+ * Author URI: http://premium.wpmudev.org
10
+ */
11
+
12
+ define( 'FORMINATOR_ADDON_CAMPAIGNMONITOR_VERSION', '1.0' );
13
+
14
+ function forminator_addon_campaignmonitor_url() {
15
+ return trailingslashit( forminator_plugin_url() . 'addons/pro/campaignmonitor' );
16
+ }
17
+
18
+ function forminator_addon_campaignmonitor_dir() {
19
+ return trailingslashit( dirname( __FILE__ ) );
20
+ }
21
+
22
+ function forminator_addon_campaignmonitor_assets_url() {
23
+ return trailingslashit( forminator_addon_campaignmonitor_url() . 'assets' );
24
+ }
25
+
26
+ require_once dirname( __FILE__ ) . '/forminator-addon-campaignmonitor.php';
27
+ require_once dirname( __FILE__ ) . '/forminator-addon-campaignmonitor-form-settings.php';
28
+ require_once dirname( __FILE__ ) . '/forminator-addon-campaignmonitor-form-hooks.php';
29
+ //Direct Load
30
+ Forminator_Addon_Loader::get_instance()->register( 'Forminator_Addon_Campaignmonitor' );
addons/pro/campaignmonitor/forminator-addon-campaignmonitor-exception.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Campaignmonitor_Exception
5
+ * Not Required but encouraged
6
+ *
7
+ * @since 1.0 Campaignmonitor Addon
8
+ */
9
+ class Forminator_Addon_Campaignmonitor_Exception extends Exception {
10
+
11
+ }
addons/pro/campaignmonitor/forminator-addon-campaignmonitor-form-hooks.php ADDED
@@ -0,0 +1,700 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Campaignmonitor_Form_Hooks
5
+ *
6
+ * @since 1.0 Campaignmonitor Addon
7
+ *
8
+ */
9
+ class Forminator_Addon_Campaignmonitor_Form_Hooks extends Forminator_Addon_Form_Hooks_Abstract {
10
+
11
+ /**
12
+ * Addon instance are auto available form abstract
13
+ * Its added here for development purpose,
14
+ * Auto-complete will resolve addon directly to `Campaignmonitor` instance instead of the abstract
15
+ * And its public properties can be exposed
16
+ *
17
+ * @since 1.0 Campaignmonitor Addon
18
+ * @var Forminator_Addon_Campaignmonitor
19
+ */
20
+ protected $addon;
21
+
22
+ /**
23
+ * Form Settings Instance
24
+ *
25
+ * @since 1.0 Campaignmonitor Addon
26
+ * @var Forminator_Addon_Campaignmonitor_Form_Settings | null
27
+ */
28
+ protected $form_settings_instance;
29
+
30
+ /**
31
+ * Forminator_Addon_Campaignmonitor_Form_Hooks constructor.
32
+ *
33
+ * @since 1.0 Campaignmonitor Addon
34
+ *
35
+ * @param Forminator_Addon_Abstract $addon
36
+ * @param $form_id
37
+ *
38
+ * @throws Forminator_Addon_Exception
39
+ */
40
+ public function __construct( Forminator_Addon_Abstract $addon, $form_id ) {
41
+ parent::__construct( $addon, $form_id );
42
+ $this->_submit_form_error_message = __( 'Campaign Monitor failed to process submitted data. Please check your form and try again', Forminator::DOMAIN );
43
+ }
44
+
45
+ /**
46
+ * Save status of request sent and received for each connected Campaign Monitor Connection
47
+ *
48
+ * @since 1.0 Campaign Monitor Addon
49
+ *
50
+ * @param array $submitted_data
51
+ *
52
+ * @return array
53
+ */
54
+ public function add_entry_fields( $submitted_data ) {
55
+
56
+ $form_id = $this->form_id;
57
+ $form_settings_instance = $this->form_settings_instance;
58
+
59
+ /**
60
+ * Filter Campaign Monitor submitted form data to be processed
61
+ *
62
+ * @since 1.3
63
+ *
64
+ * @param array $submitted_data
65
+ * @param int $form_id current Form ID
66
+ * @param Forminator_Addon_Campaignmonitor_Form_Settings $form_settings_instance Campaign Monitor Addon Form Settings instance
67
+ */
68
+ $submitted_data = apply_filters(
69
+ 'forminator_addon_campaignmonitor_form_submitted_data',
70
+ $submitted_data,
71
+ $form_id,
72
+ $form_settings_instance
73
+ );
74
+
75
+ forminator_addon_maybe_log( __METHOD__, $submitted_data );
76
+
77
+ $addon_setting_values = $this->form_settings_instance->get_form_settings_values();
78
+ $form_settings = $this->form_settings_instance->get_form_settings();
79
+
80
+ $data = array();
81
+
82
+ /**
83
+ * Fires before adding subscriber to Campaign Monitor
84
+ *
85
+ * @since 1.3
86
+ *
87
+ * @param int $form_id current Form ID
88
+ * @param array $submitted_data
89
+ * @param Forminator_Addon_Campaignmonitor_Form_Settings $form_settings_instance Campaign Monitor Addon Form Settings instance
90
+ */
91
+ do_action( 'forminator_addon_campaignmonitor_before_add_subscriber', $form_id, $submitted_data, $form_settings_instance );
92
+
93
+ foreach ( $addon_setting_values as $key => $addon_setting_value ) {
94
+ // save it on entry field, with name `status-$MULTI_ID`, and value is the return result on sending data to campaign monitor
95
+ if ( $form_settings_instance->is_multi_form_settings_complete( $key ) ) {
96
+ // exec only on completed connection
97
+ $data[] = array(
98
+ 'name' => 'status-' . $key,
99
+ 'value' => $this->get_status_on_add_subscriber( $key, $submitted_data, $addon_setting_value, $form_settings ),
100
+ );
101
+ }
102
+
103
+ }
104
+
105
+ $entry_fields = $data;
106
+ /**
107
+ * Filter Campaign Monitor entry fields to be saved to entry model
108
+ *
109
+ * @since 1.3
110
+ *
111
+ * @param array $entry_fields
112
+ * @param int $form_id current Form ID
113
+ * @param array $submitted_data
114
+ * @param Forminator_Addon_Campaignmonitor_Form_Settings $form_settings_instance Campaign Monitor Addon Form Settings instance
115
+ */
116
+ $data = apply_filters(
117
+ 'forminator_addon_campaignmonitor_entry_fields',
118
+ $entry_fields,
119
+ $form_id,
120
+ $submitted_data,
121
+ $form_settings_instance
122
+ );
123
+
124
+ return $data;
125
+
126
+ }
127
+
128
+ /**
129
+ * Get status on add subscriber to Campaign Monitor
130
+ *
131
+ * @since 1.0 ampaign Monitor Addon
132
+ *
133
+ * @param $connection_id
134
+ * @param $submitted_data
135
+ * @param $connection_settings
136
+ * @param $form_settings
137
+ *
138
+ * @return array `is_sent` true means its success send data to ampaign Monitor, false otherwise
139
+ */
140
+ private function get_status_on_add_subscriber( $connection_id, $submitted_data, $connection_settings, $form_settings ) {
141
+ // initialize as null
142
+ $api = null;
143
+
144
+ $form_id = $this->form_id;
145
+ $form_settings_instance = $this->form_settings_instance;
146
+
147
+ //check required fields
148
+ try {
149
+ $api = $this->addon->get_api();
150
+ $args = array();
151
+
152
+ if ( ! isset( $connection_settings['list_id'] ) ) {
153
+ throw new Forminator_Addon_Campaignmonitor_Exception( __( 'List ID not properly setup.', Forminator::DOMAIN ) );
154
+ }
155
+
156
+ $list_id = $connection_settings['list_id'];
157
+
158
+ $fields_map = $connection_settings['fields_map'];
159
+
160
+ $email_element_id = $connection_settings['fields_map']['default_field_email'];
161
+ if ( ! isset( $submitted_data[ $email_element_id ] ) || empty( $submitted_data[ $email_element_id ] ) ) {
162
+ throw new Forminator_Addon_Campaignmonitor_Exception(
163
+ sprintf(
164
+ __( 'Email Address on element %1$s not found or not filled on submitted data.', Forminator::DOMAIN ),
165
+ $email_element_id
166
+ )
167
+ );
168
+ }
169
+ $email = $submitted_data[ $email_element_id ];
170
+ $email = strtolower( trim( $email ) );
171
+
172
+ // processed
173
+ unset( $fields_map['default_field_email'] );
174
+
175
+ $name_element_id = $connection_settings['fields_map']['default_field_name'];
176
+ if ( ! isset( $submitted_data[ $name_element_id ] ) || empty( $submitted_data[ $name_element_id ] ) ) {
177
+ throw new Forminator_Addon_Campaignmonitor_Exception(
178
+ sprintf(
179
+ __( 'Name on element %1$s not found or not filled on submitted data.', Forminator::DOMAIN ),
180
+ $name_element_id
181
+ )
182
+ );
183
+ }
184
+ $name = $submitted_data[ $name_element_id ];
185
+ $args['Name'] = $name;
186
+
187
+ // processed
188
+ unset( $fields_map['default_field_name'] );
189
+
190
+ $custom_fields = array();
191
+ // process rest extra fields if available
192
+ foreach ( $fields_map as $field_id => $element_id ) {
193
+ if ( ! empty( $element_id ) ) {
194
+ if ( isset( $submitted_data[ $element_id ] ) && ! empty( $submitted_data[ $element_id ] ) ) {
195
+ $element_value = $submitted_data[ $element_id ];
196
+ if ( is_array( $element_value ) ) {
197
+ $element_value = implode( ',', $element_value );
198
+ }
199
+ $custom_fields[] = array(
200
+ 'Key' => $field_id,
201
+ 'Value' => $element_value,
202
+ );
203
+ }
204
+ }
205
+ }
206
+ $args['CustomFields'] = $custom_fields;
207
+
208
+ if ( isset( $connection_settings['resubscribe'] ) ) {
209
+ $resubscribe = filter_var( $connection_settings['resubscribe'], FILTER_VALIDATE_BOOLEAN );
210
+ $args['Resubscribe'] = $resubscribe;
211
+ }
212
+
213
+ if ( isset( $connection_settings['restart_subscription_based_autoresponders'] ) ) {
214
+ $restart_subscription_based_autoresponders = filter_var( $connection_settings['restart_subscription_based_autoresponders'], FILTER_VALIDATE_BOOLEAN );
215
+ $args['RestartSubscriptionBasedAutoresponders'] = $restart_subscription_based_autoresponders;
216
+ }
217
+
218
+ if ( isset( $connection_settings['consent_to_track'] ) ) {
219
+ $consent_to_track = $connection_settings['consent_to_track'];
220
+ $args['ConsentToTrack'] = $consent_to_track;
221
+ }
222
+
223
+ /**
224
+ * Filter arguments to passed on to Add Subscriber Campaign Monitor API
225
+ *
226
+ * @since 1.3
227
+ *
228
+ * @param array $args
229
+ * @param int $form_id Current Form id
230
+ * @param string $connection_id ID of current connection
231
+ * @param array $submitted_data
232
+ * @param array $connection_settings current connection setting, contains options of like `name`, `list_id` etc
233
+ * @param array $form_settings Displayed Form settings
234
+ * @param Forminator_Addon_Campaignmonitor_Form_Settings $form_settings_instance Campaign Monitor Addon Form Settings instance
235
+ */
236
+ $args = apply_filters(
237
+ 'forminator_addon_campaignmonitor_add_subscriber_args',
238
+ $args,
239
+ $form_id,
240
+ $connection_id,
241
+ $submitted_data,
242
+ $connection_settings,
243
+ $form_settings,
244
+ $form_settings_instance
245
+ );
246
+
247
+ $api->add_subscriber( $list_id, $email, $args );
248
+
249
+ forminator_addon_maybe_log( __METHOD__, 'Success Send Data' );
250
+ forminator_addon_maybe_log( __METHOD__, $api->get_last_data_received() );
251
+
252
+ return array(
253
+ 'is_sent' => true,
254
+ 'connection_name' => $connection_settings['name'],
255
+ 'description' => __( 'Successfully send data to Campaign Monitor', Forminator::DOMAIN ),
256
+ 'data_sent' => $api->get_last_data_sent(),
257
+ 'data_received' => $api->get_last_data_received(),
258
+ 'url_request' => $api->get_last_url_request(),
259
+ 'subscriber_email' => $api->get_last_data_received(), // for delete reference
260
+ 'list_id' => $list_id, // for delete reference
261
+ );
262
+
263
+ } catch ( Forminator_Addon_Campaignmonitor_Exception $e ) {
264
+ forminator_addon_maybe_log( __METHOD__, 'Failed to Send to Campaign Monitor' );
265
+
266
+ return array(
267
+ 'is_sent' => false,
268
+ 'description' => $e->getMessage(),
269
+ 'connection_name' => $connection_settings['name'],
270
+ 'data_sent' => ( ( $api instanceof Forminator_Addon_Campaignmonitor_Wp_Api ) ? $api->get_last_data_sent() : array() ),
271
+ 'data_received' => ( ( $api instanceof Forminator_Addon_Campaignmonitor_Wp_Api ) ? $api->get_last_data_received() : array() ),
272
+ 'url_request' => ( ( $api instanceof Forminator_Addon_Campaignmonitor_Wp_Api ) ? $api->get_last_url_request() : '' ),
273
+ );
274
+ }
275
+ }
276
+
277
+ /**
278
+ * It wil add new row on entry table of submission page, with couple of subentries
279
+ * subentries included are defined in @see Forminator_Addon_Campaignmonitor_Form_Hooks::get_additional_entry_item()
280
+ *
281
+ * @since 1.0 Campaign Monitor Addon
282
+ *
283
+ * @param Forminator_Form_Entry_Model $entry_model
284
+ * @param $addon_meta_data
285
+ *
286
+ * @return array
287
+ */
288
+ public function on_render_entry( Forminator_Form_Entry_Model $entry_model, $addon_meta_data ) {
289
+
290
+ $form_id = $this->form_id;
291
+ $form_settings_instance = $this->form_settings_instance;
292
+
293
+ /**
294
+ *
295
+ * Filter active metadata that previously saved on db to be processed
296
+ *
297
+ * @since 1.3
298
+ *
299
+ * @param array $addon_meta_data
300
+ * @param int $form_id current Form ID
301
+ * @param Forminator_Addon_Campaignmonitor_Form_Settings $form_settings_instance Campaign Monitor Addon Form Settings instance
302
+ */
303
+ $addon_meta_data = apply_filters(
304
+ 'forminator_addon_campaignmonitor_metadata',
305
+ $addon_meta_data,
306
+ $form_id,
307
+ $form_settings_instance
308
+ );
309
+
310
+ $addon_meta_datas = $addon_meta_data;
311
+ if ( ! isset( $addon_meta_data[0] ) || ! is_array( $addon_meta_data[0] ) ) {
312
+ return array();
313
+ }
314
+
315
+ return $this->on_render_entry_multi_connection( $addon_meta_datas );
316
+
317
+ }
318
+
319
+ /**
320
+ * Loop through addon meta data on multiple campaign monitor(s)
321
+ *
322
+ * @since 1.0 Campaign Monitor Addon
323
+ *
324
+ * @param $addon_meta_datas
325
+ *
326
+ * @return array
327
+ */
328
+ private function on_render_entry_multi_connection( $addon_meta_datas ) {
329
+ $additional_entry_item = array();
330
+ foreach ( $addon_meta_datas as $addon_meta_data ) {
331
+ $additional_entry_item[] = $this->get_additional_entry_item( $addon_meta_data );
332
+ }
333
+
334
+ return $additional_entry_item;
335
+
336
+ }
337
+
338
+ /**
339
+ * Format additional entry item as label and value arrays
340
+ *
341
+ * - Integration Name : its defined by user when they adding Campaign Monitor integration on their form
342
+ * - Sent To Campaign Monitor : will be Yes/No value, that indicates whether sending data to Campaign Monitor was successful
343
+ * - Info : Text that are generated by addon when building and sending data to Campaign Monitor @see Forminator_Addon_Campaignmonitor_Form_Hooks::add_entry_fields()
344
+ * - Below subentries will be added if full log enabled, @see Forminator_Addon_Campaignmonitor::is_show_full_log() @see FORMINATOR_ADDON_CAMPAIGNMONITOR_SHOW_FULL_LOG
345
+ * - API URL : URL that wes requested when sending data to Campaign Monitor
346
+ * - Data sent to Campaign Monitor : encoded body request that was sent
347
+ * - Data received from Campaign Monitor : json encoded body response that was received
348
+ *
349
+ * @param $addon_meta_data
350
+ *
351
+ * @since 1.0 Campaign Monitor Addon
352
+ * @return array
353
+ */
354
+ private function get_additional_entry_item( $addon_meta_data ) {
355
+
356
+ if ( ! isset( $addon_meta_data['value'] ) || ! is_array( $addon_meta_data['value'] ) ) {
357
+ return array();
358
+ }
359
+ $status = $addon_meta_data['value'];
360
+ $additional_entry_item = array(
361
+ 'label' => __( 'Campaign Monitor Integration', Forminator::DOMAIN ),
362
+ 'value' => '',
363
+ );
364
+
365
+
366
+ $sub_entries = array();
367
+ if ( isset( $status['connection_name'] ) ) {
368
+ $sub_entries[] = array(
369
+ 'label' => __( 'Integration Name', Forminator::DOMAIN ),
370
+ 'value' => $status['connection_name'],
371
+ );
372
+ }
373
+
374
+ if ( isset( $status['is_sent'] ) ) {
375
+ $is_sent = true === $status['is_sent'] ? __( 'Yes', Forminator::DOMAIN ) : __( 'No', Forminator::DOMAIN );
376
+ $sub_entries[] = array(
377
+ 'label' => __( 'Sent To Campaign Monitor', Forminator::DOMAIN ),
378
+ 'value' => $is_sent,
379
+ );
380
+ }
381
+
382
+ if ( isset( $status['description'] ) ) {
383
+ $sub_entries[] = array(
384
+ 'label' => __( 'Info', Forminator::DOMAIN ),
385
+ 'value' => $status['description'],
386
+ );
387
+ }
388
+
389
+ if ( Forminator_Addon_Campaignmonitor::is_show_full_log() ) {
390
+ // too long to be added on entry data enable this with `define('FORMINATOR_ADDON_CAMPAIGNMONITOR_SHOW_FULL_LOG', true)`
391
+ if ( isset( $status['url_request'] ) ) {
392
+ $sub_entries[] = array(
393
+ 'label' => __( 'API URL', Forminator::DOMAIN ),
394
+ 'value' => $status['url_request'],
395
+ );
396
+ }
397
+
398
+ if ( isset( $status['data_sent'] ) ) {
399
+ $sub_entries[] = array(
400
+ 'label' => __( 'Data sent to Campaign Monitor', Forminator::DOMAIN ),
401
+ 'value' => '<pre class="sui-code-snippet">' . wp_json_encode( $status['data_sent'], JSON_PRETTY_PRINT ) . '</pre>',
402
+ );
403
+ }
404
+
405
+ if ( isset( $status['data_received'] ) ) {
406
+ $sub_entries[] = array(
407
+ 'label' => __( 'Data received from Campaign Monitor', Forminator::DOMAIN ),
408
+ 'value' => '<pre class="sui-code-snippet">' . wp_json_encode( $status['data_received'], JSON_PRETTY_PRINT ) . '</pre>',
409
+ );
410
+ }
411
+ }
412
+
413
+ $additional_entry_item['sub_entries'] = $sub_entries;
414
+
415
+ // return single array
416
+ return $additional_entry_item;
417
+ }
418
+
419
+ /**
420
+ * Campaign Monitor will add a column on the title/header row
421
+ * its called `Campaign Monitor Info` which can be translated on forminator lang
422
+ *
423
+ * @since 1.0 Campaign Monitor Addon
424
+ * @return array
425
+ */
426
+ public function on_export_render_title_row() {
427
+
428
+ $export_headers = array(
429
+ 'info' => __( 'Campaign Monitor Info', Forminator::DOMAIN ),
430
+ );
431
+
432
+ $form_id = $this->form_id;
433
+ $form_settings_instance = $this->form_settings_instance;
434
+
435
+ /**
436
+ * Filter Campaign Monitor headers on export file
437
+ *
438
+ * @since 1.3
439
+ *
440
+ * @param array $export_headers headers to be displayed on export file
441
+ * @param int $form_id current Form ID
442
+ * @param Forminator_Addon_Campaignmonitor_Form_Settings $form_settings_instance Campaign Monitor Addon Form Settings instance
443
+ */
444
+ $export_headers = apply_filters(
445
+ 'forminator_addon_campaignmonitor_export_headers',
446
+ $export_headers,
447
+ $form_id,
448
+ $form_settings_instance
449
+ );
450
+
451
+ return $export_headers;
452
+ }
453
+
454
+ /**
455
+ * Campaign Monitor will add a column that give user information whether sending data to Campaign Monitor successfully or not
456
+ * It will only add one column even its multiple connection, every connection will be separated by comma
457
+ *
458
+ * @since 1.0 Campaign Monitor Addon
459
+ *
460
+ * @param Forminator_Form_Entry_Model $entry_model
461
+ * @param $addon_meta_data
462
+ *
463
+ * @return array
464
+ */
465
+ public function on_export_render_entry( Forminator_Form_Entry_Model $entry_model, $addon_meta_data ) {
466
+
467
+ $form_id = $this->form_id;
468
+ $form_settings_instance = $this->form_settings_instance;
469
+
470
+ /**
471
+ *
472
+ * Filter Campaign Monitor metadata that previously saved on db to be processed
473
+ *
474
+ * @since 1.3
475
+ *
476
+ * @param array $addon_meta_data
477
+ * @param int $form_id current Form ID
478
+ * @param Forminator_Addon_Campaignmonitor_Form_Settings $form_settings_instance Campaign Monitor Addon Form Settings instance
479
+ */
480
+ $addon_meta_data = apply_filters(
481
+ 'forminator_addon_campaignmonitor_metadata',
482
+ $addon_meta_data,
483
+ $form_id,
484
+ $form_settings_instance
485
+ );
486
+
487
+ $export_columns = array(
488
+ 'info' => $this->get_from_addon_meta_data( $addon_meta_data, 'description', '' ),
489
+ );
490
+
491
+ /**
492
+ * Filter Campaign Monitor columns to be displayed on export submissions
493
+ *
494
+ * @since 1.3
495
+ *
496
+ * @param array $export_columns column to be exported
497
+ * @param int $form_id current Form ID
498
+ * @param Forminator_Form_Entry_Model $entry_model Form Entry Model
499
+ * @param array $addon_meta_data meta data saved by addon on entry fields
500
+ * @param Forminator_Addon_Campaignmonitor_Form_Settings $form_settings_instance Campaign Monitor Addon Form Settings instance
501
+ */
502
+ $export_columns = apply_filters(
503
+ 'forminator_addon_campaignmonitor_export_columns',
504
+ $export_columns,
505
+ $form_id,
506
+ $entry_model,
507
+ $addon_meta_data,
508
+ $form_settings_instance
509
+ );
510
+
511
+ return $export_columns;
512
+ }
513
+
514
+ /**
515
+ * Get Addon meta data, will be recursive if meta data is multiple because of multiple connection added
516
+ *
517
+ * @since 1.0 Campaign Monitor Addon
518
+ *
519
+ * @param $addon_meta_data
520
+ * @param $key
521
+ * @param string $default
522
+ *
523
+ * @return string
524
+ */
525
+ private function get_from_addon_meta_data( $addon_meta_data, $key, $default = '' ) {
526
+ $addon_meta_datas = $addon_meta_data;
527
+ if ( ! isset( $addon_meta_data[0] ) || ! is_array( $addon_meta_data[0] ) ) {
528
+ return $default;
529
+ }
530
+
531
+ $addon_meta_data = $addon_meta_data[0];
532
+
533
+ // make sure its `status`, because we only add this
534
+ if ( 'status' !== $addon_meta_data['name'] ) {
535
+ if ( stripos( $addon_meta_data['name'], 'status-' ) === 0 ) {
536
+ $meta_data = array();
537
+ foreach ( $addon_meta_datas as $addon_meta_data ) {
538
+ // make it like single value so it will be processed like single meta data
539
+ $addon_meta_data['name'] = 'status';
540
+
541
+ // add it on an array for next recursive process
542
+ $meta_data[] = $this->get_from_addon_meta_data( array( $addon_meta_data ), $key, $default );
543
+ }
544
+
545
+ return implode( ', ', $meta_data );
546
+ }
547
+
548
+ return $default;
549
+
550
+ }
551
+
552
+ if ( ! isset( $addon_meta_data['value'] ) || ! is_array( $addon_meta_data['value'] ) ) {
553
+ return $default;
554
+ }
555
+ $status = $addon_meta_data['value'];
556
+ if ( isset( $status[ $key ] ) ) {
557
+ $connection_name = '';
558
+ if ( 'connection_name' !== $key ) {
559
+ if ( isset( $status['connection_name'] ) ) {
560
+ $connection_name = '[' . $status['connection_name'] . '] ';
561
+ }
562
+ }
563
+
564
+ return $connection_name . $status[ $key ];
565
+ }
566
+
567
+ return $default;
568
+ }
569
+
570
+ /**
571
+ * It will delete subscriber on Campaign Monitor from list
572
+ *
573
+ * @since 1.0 Campaign Monitor Addon
574
+ *
575
+ * @param Forminator_Form_Entry_Model $entry_model
576
+ * @param array $addon_meta_data
577
+ *
578
+ * @return bool
579
+ */
580
+ public function on_before_delete_entry( Forminator_Form_Entry_Model $entry_model, $addon_meta_data ) {
581
+ // attach hook first
582
+ $form_id = $this->form_id;
583
+ $form_settings_instance = $this->form_settings_instance;
584
+
585
+ /**
586
+ *
587
+ * Filter Campaign Monitor addon metadata that previously saved on db to be processed
588
+ *
589
+ * @since 1.1
590
+ *
591
+ * @param array $addon_meta_data
592
+ * @param int $form_id current Form ID
593
+ * @param Forminator_Form_Entry_Model $entry_model Forminator Entry Model
594
+ * @param Forminator_Addon_Campaignmonitor_Form_Settings $form_settings_instance Campaign Monitor Addon Form Settings instance
595
+ */
596
+ $addon_meta_data = apply_filters(
597
+ 'forminator_addon_campaignmonitor_metadata',
598
+ $addon_meta_data,
599
+ $form_id,
600
+ $entry_model,
601
+ $form_settings_instance
602
+ );
603
+
604
+ /**
605
+ * Fires when Campaign Monitor connected form delete a submission
606
+ *
607
+ * @since 1.1
608
+ *
609
+ * @param int $form_id current Form ID
610
+ * @param Forminator_Form_Entry_Model $entry_model Forminator Entry Model
611
+ * @param array $addon_meta_data addon meta data
612
+ * @param Forminator_Addon_Campaignmonitor_Form_Settings $form_settings_instance Campaign Monitor Addon Form Settings instance
613
+ */
614
+ do_action(
615
+ 'forminator_addon_campaignmonitor_on_before_delete_submission',
616
+ $form_id,
617
+ $entry_model,
618
+ $addon_meta_data,
619
+ $form_settings_instance
620
+ );
621
+
622
+ if ( ! Forminator_Addon_Campaignmonitor::is_enable_delete_subscriber() ) {
623
+ // its disabled, go for it!
624
+ return true;
625
+ }
626
+ $api = null;
627
+ try {
628
+ $subscribers_to_delete = array();
629
+
630
+ if ( is_array( $addon_meta_data ) ) {
631
+ foreach ( $addon_meta_data as $addon_meta_datum ) {
632
+
633
+ if ( isset( $addon_meta_datum['value'] ) && is_array( $addon_meta_datum['value'] ) ) {
634
+ $addon_meta_datum_value = $addon_meta_datum['value'];
635
+ if ( isset( $addon_meta_datum_value['is_sent'] ) && $addon_meta_datum_value['is_sent'] ) {
636
+ if ( isset( $addon_meta_datum_value['list_id'] ) && ! empty( $addon_meta_datum_value['list_id'] )
637
+ && isset( $addon_meta_datum_value['subscriber_email'] )
638
+ && ! empty( $addon_meta_datum_value['subscriber_email'] ) ) {
639
+ $subscribers_to_delete[] = array(
640
+ 'list_id' => $addon_meta_datum_value['list_id'],
641
+ 'email' => $addon_meta_datum_value['subscriber_email'],
642
+ );
643
+ }
644
+ }
645
+ }
646
+
647
+ }
648
+ }
649
+
650
+ /**
651
+ * Filter subscribers to delete
652
+ *
653
+ * @since 1.3
654
+ *
655
+ * @param array $subscriber_ids_to_delete
656
+ * @param int $form_id current Form ID
657
+ * @param array $addon_meta_data addon meta data
658
+ * @param Forminator_Addon_Campaignmonitor_Form_Settings $form_settings_instance Campaign Monitor Addon Form Settings instance
659
+ *
660
+ */
661
+ $subscribers_to_delete = apply_filters(
662
+ 'forminator_addon_campaignmonitor_subscribers_to_delete',
663
+ $subscribers_to_delete,
664
+ $form_id,
665
+ $addon_meta_data,
666
+ $form_settings_instance
667
+ );
668
+
669
+ if ( ! empty( $subscribers_to_delete ) ) {
670
+ $api = $this->addon->get_api();
671
+ foreach ( $subscribers_to_delete as $subscriber ) {
672
+
673
+ if ( isset( $subscriber['list_id'] ) && isset( $subscriber['email'] ) ) {
674
+ $api->delete_subscriber( $subscriber['list_id'], $subscriber['email'] );
675
+ }
676
+ }
677
+ }
678
+
679
+ return true;
680
+
681
+ } catch ( Forminator_Addon_Campaignmonitor_Exception $e ) {
682
+ // handle all internal addon exceptions with `Forminator_Addon_Campaignmonitor_Exception`
683
+
684
+ // use wp_error, for future usage it can be returned to page entries
685
+ $wp_error = new WP_Error( 'forminator_addon_campaignmonitor_delete_subscriber', $e->getMessage() );
686
+ // handle this in addon by self, since page entries cant handle error messages on delete yet
687
+ wp_die(
688
+ esc_html( $wp_error->get_error_message() ),
689
+ esc_html( $this->addon->get_title() ),
690
+ array(
691
+ 'response' => 200,
692
+ 'back_link' => true,
693
+ )
694
+ );
695
+
696
+ return false;
697
+ }
698
+
699
+ }
700
+ }
addons/pro/campaignmonitor/forminator-addon-campaignmonitor-form-settings-exception.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Campaignmonitor_Form_Settings_Exception
5
+ * Wrapper of Form Settings Campaignmonitor Exception
6
+ *
7
+ * @since 1.0 Campaignmonitor Addon
8
+ */
9
+ class Forminator_Addon_Campaignmonitor_Form_Settings_Exception extends Forminator_Addon_Campaignmonitor_Exception {
10
+
11
+ /**
12
+ * Holder of input exceptions
13
+ *
14
+ * @since 1.0 Campaignmonitor Addon
15
+ * @var array
16
+ */
17
+ protected $input_exceptions = array();
18
+
19
+ /**
20
+ * Forminator_Addon_Campaignmonitor_Form_Settings_Exception constructor.
21
+ *
22
+ * Useful if input_id is needed for later.
23
+ * If no input_id needed, use @see Forminator_Addon_Campaignmonitor_Exception
24
+ *
25
+ * @since 1.0 Campaignmonitor Addon
26
+ *
27
+ * @param string $message
28
+ * @param string $input_id
29
+ */
30
+ public function __construct( $message = '', $input_id = '' ) {
31
+ parent::__construct( $message, 0 );
32
+ if ( ! empty( $input_id ) ) {
33
+ $this->add_input_exception( $message, $input_id );
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Set exception message for an input
39
+ *
40
+ * @since 1.0 Campaignmonitor Addon
41
+ *
42
+ * @param $message
43
+ * @param $input_id
44
+ */
45
+ public function add_input_exception( $message, $input_id ) {
46
+ $this->input_exceptions[ $input_id ] = $message;
47
+ }
48
+
49
+ /**
50
+ * Get all input exceptions
51
+ *
52
+ * @since 1.0 Campaignmonitor Addon
53
+ * @return array
54
+ */
55
+ public function get_input_exceptions() {
56
+ return $this->input_exceptions;
57
+ }
58
+
59
+ /**
60
+ * Check if there is input_exceptions_is_available
61
+ *
62
+ * @since 1.0 Campaignmonitor Addon
63
+ * @return bool
64
+ */
65
+ public function input_exceptions_is_available() {
66
+ return count( $this->input_exceptions ) > 0;
67
+ }
68
+ }
addons/pro/campaignmonitor/forminator-addon-campaignmonitor-form-settings.php ADDED
@@ -0,0 +1,690 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once dirname( __FILE__ ) . '/forminator-addon-campaignmonitor-form-settings-exception.php';
4
+
5
+ /**
6
+ * Class Forminator_Addon_Campaignmonitor_Form_Settings
7
+ * Handle how form settings displayed and saved
8
+ *
9
+ * @since 1.0 Campaignmonitor Addon
10
+ */
11
+ class Forminator_Addon_Campaignmonitor_Form_Settings extends Forminator_Addon_Form_Settings_Abstract {
12
+
13
+ /**
14
+ * @var Forminator_Addon_Campaignmonitor
15
+ * @since 1.0 Campaignmonitor Addon
16
+ */
17
+ protected $addon;
18
+
19
+ /**
20
+ * Forminator_Addon_Campaignmonitor_Form_Settings constructor.
21
+ *
22
+ * @since 1.0 Campaignmonitor Addon
23
+ *
24
+ * @param Forminator_Addon_Abstract $addon
25
+ * @param $form_id
26
+ *
27
+ * @throws Forminator_Addon_Exception
28
+ */
29
+ public function __construct( Forminator_Addon_Abstract $addon, $form_id ) {
30
+ parent::__construct( $addon, $form_id );
31
+
32
+ $this->_update_form_settings_error_message = __(
33
+ 'Sorry, we are failed to update settings for this form, please check your form and input then try again',
34
+ Forminator::DOMAIN
35
+ );
36
+ }
37
+
38
+ /**
39
+ * Campaignmonitor Form Settings wizard
40
+ *
41
+ * @since 1.0 Campaignmonitor Addon
42
+ * @return array
43
+ */
44
+ public function form_settings_wizards() {
45
+ // numerical array steps
46
+ return array(
47
+ array(
48
+ 'callback' => array( $this, 'pick_name' ),
49
+ 'is_completed' => array( $this, 'pick_name_is_completed' ),
50
+ ),
51
+ array(
52
+ 'callback' => array( $this, 'setup_list' ),
53
+ 'is_completed' => array( $this, 'setup_list_is_completed' ),
54
+ ),
55
+ array(
56
+ 'callback' => array( $this, 'map_fields' ),
57
+ 'is_completed' => array( $this, 'map_fields_is_completed' ),
58
+ ),
59
+ //todo: allow fe to support this
60
+ // array(
61
+ // 'callback' => array( $this, 'extra_field' ),
62
+ // 'is_completed' => array( $this, 'extra_field' ),
63
+ // ),
64
+ array(
65
+ 'callback' => array( $this, 'setup_options' ),
66
+ 'is_completed' => array( $this, 'setup_options_is_completed' ),
67
+ ),
68
+ );
69
+ }
70
+
71
+ /**
72
+ * Setup Connection Name
73
+ *
74
+ * @since 1.0 Campaign Monitor Addon
75
+ *
76
+ * @param $submitted_data
77
+ *
78
+ * @return array
79
+ */
80
+ public function pick_name( $submitted_data ) {
81
+ $template = forminator_addon_campaignmonitor_dir() . 'views/form-settings/pick-name.php';
82
+
83
+ $multi_id = $this->generate_multi_id();
84
+ if ( isset( $submitted_data['multi_id'] ) ) {
85
+ $multi_id = $submitted_data['multi_id'];
86
+ }
87
+
88
+ $template_params = array(
89
+ 'name' => $this->get_multi_id_form_settings_value( $multi_id, 'name', '' ),
90
+ 'name_error' => '',
91
+ 'multi_id' => $multi_id,
92
+ );
93
+
94
+ unset( $submitted_data['multi_id'] );
95
+
96
+ $is_submit = ! empty( $submitted_data );
97
+ $has_errors = false;
98
+ if ( $is_submit ) {
99
+ $name = isset( $submitted_data['name'] ) ? $submitted_data['name'] : '';
100
+ $template_params['name'] = $name;
101
+
102
+ try {
103
+
104
+ if ( empty( $name ) ) {
105
+ throw new Forminator_Addon_Campaignmonitor_Exception( __( 'Please pick valid name' ) );
106
+ }
107
+
108
+ $time_added = $this->get_multi_id_form_settings_value( $multi_id, 'time_added', time() );
109
+ $this->save_multi_id_form_setting_values(
110
+ $multi_id,
111
+ array(
112
+ 'name' => $name,
113
+ 'time_added' => $time_added,
114
+ )
115
+ );
116
+
117
+ } catch ( Forminator_Addon_Campaignmonitor_Exception $e ) {
118
+ $template_params['name_error'] = $e->getMessage();
119
+ $has_errors = true;
120
+ }
121
+ }
122
+
123
+ $buttons = array();
124
+ if ( $this->pick_name_is_completed( array( 'multi_id' => $multi_id ) ) ) {
125
+ $buttons['disconnect']['markup'] = Forminator_Addon_Abstract::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ),
126
+ 'sui-button-ghost sui-tooltip sui-tooltip-top-center forminator-addon-form-disconnect',
127
+ esc_html__( 'Disconnect this Campaign Monitor Integration from this Form.', Forminator::DOMAIN )
128
+ );
129
+ }
130
+
131
+ $buttons['next']['markup'] = '<div class="sui-actions-right">' .
132
+ Forminator_Addon_Abstract::get_button_markup( esc_html__( 'NEXT', Forminator::DOMAIN ), 'forminator-addon-next' ) .
133
+ '</div>';
134
+
135
+ return array(
136
+ 'html' => Forminator_Addon_Abstract::get_template( $template, $template_params ),
137
+ 'buttons' => $buttons,
138
+ 'redirect' => false,
139
+ 'has_errors' => $has_errors,
140
+ );
141
+ }
142
+
143
+ /**
144
+ * Check if pick name step completed
145
+ *
146
+ * @since 1.0 Campaign Monitor Addon
147
+ *
148
+ * @param $submitted_data
149
+ *
150
+ * @return bool
151
+ */
152
+ public function pick_name_is_completed( $submitted_data ) {
153
+ $multi_id = '';
154
+ if ( isset( $submitted_data['multi_id'] ) ) {
155
+ $multi_id = $submitted_data['multi_id'];
156
+ }
157
+
158
+ if ( empty( $multi_id ) ) {
159
+ return false;
160
+ }
161
+
162
+ $name = $this->get_multi_id_form_settings_value( $multi_id, 'name', '' );
163
+
164
+ if ( empty( $name ) ) {
165
+ return false;
166
+ }
167
+
168
+ return true;
169
+ }
170
+
171
+ /**
172
+ * Setup List
173
+ *
174
+ * @since 1.0 Campaign Monitor Addon
175
+ *
176
+ * @param $submitted_data
177
+ *
178
+ * @return array
179
+ */
180
+ public function setup_list( $submitted_data ) {
181
+ $template = forminator_addon_campaignmonitor_dir() . 'views/form-settings/setup-list.php';
182
+
183
+ if ( ! isset( $submitted_data['multi_id'] ) ) {
184
+ return $this->get_force_closed_wizard( __( 'Please pick valid connection', Forminator::DOMAIN ) );
185
+ }
186
+
187
+ $multi_id = $submitted_data['multi_id'];
188
+ unset( $submitted_data['multi_id'] );
189
+
190
+ $template_params = array(
191
+ 'list_id' => $this->get_multi_id_form_settings_value( $multi_id, 'list_id', '' ),
192
+ 'list_name' => $this->get_multi_id_form_settings_value( $multi_id, 'list_name', '' ),
193
+ 'list_id_error' => '',
194
+ 'multi_id' => $multi_id,
195
+ 'error_message' => '',
196
+ );
197
+
198
+
199
+ $is_submit = ! empty( $submitted_data );
200
+ $has_errors = false;
201
+
202
+ $lists = array();
203
+
204
+ try {
205
+
206
+ $api = $this->addon->get_api();
207
+ $lists_request = $api->get_client_lists( $this->addon->get_client_id() );
208
+
209
+ foreach ( $lists_request as $key => $data ) {
210
+ if ( isset( $data->ListID ) && isset( $data->Name ) ) { //phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
211
+ $lists[ $data->ListID ] = $data->Name; //phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
212
+ }
213
+ }
214
+
215
+ if ( empty( $lists ) ) {
216
+ throw new Forminator_Addon_Campaignmonitor_Exception( __( 'No lists found on your Campaign Monitor. Please create one.', Forminator::DOMAIN ) );
217
+ }
218
+
219
+ $template_params['lists'] = $lists;
220
+
221
+ } catch ( Forminator_Addon_Campaignmonitor_Exception $e ) {
222
+ $template_params['error_message'] = $e->getMessage();
223
+ $has_errors = true;
224
+ }
225
+
226
+ if ( $is_submit ) {
227
+ $list_id = isset( $submitted_data['list_id'] ) ? $submitted_data['list_id'] : '';
228
+ $template_params['list_id'] = $list_id;
229
+
230
+ try {
231
+
232
+ if ( empty( $list_id ) ) {
233
+ throw new Forminator_Addon_Campaignmonitor_Exception( __( 'Please pick valid list' ) );
234
+ }
235
+
236
+ // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
237
+ if ( ! in_array( $list_id, array_keys( $lists ) ) ) {
238
+ throw new Forminator_Addon_Campaignmonitor_Exception( __( 'Please pick valid list' ) );
239
+ }
240
+
241
+ $list_name = $lists[ $list_id ];
242
+
243
+ $this->save_multi_id_form_setting_values(
244
+ $multi_id,
245
+ array(
246
+ 'list_id' => $list_id,
247
+ 'list_name' => $list_name,
248
+ )
249
+ );
250
+
251
+ } catch ( Forminator_Addon_Campaignmonitor_Exception $e ) {
252
+ $template_params['list_id_error'] = $e->getMessage();
253
+ $has_errors = true;
254
+ }
255
+ }
256
+
257
+ $buttons = array();
258
+ if ( $this->pick_name_is_completed( array( 'multi_id' => $multi_id ) ) ) {
259
+ $buttons['disconnect']['markup'] = Forminator_Addon_Abstract::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ),
260
+ 'sui-button-ghost sui-tooltip sui-tooltip-top-center forminator-addon-form-disconnect',
261
+ esc_html__( 'Disconnect this Campaign Monitor Integration from this Form.', Forminator::DOMAIN )
262
+ );
263
+ }
264
+
265
+ $buttons['next']['markup'] = '<div class="sui-actions-right">' .
266
+ Forminator_Addon_Abstract::get_button_markup( esc_html__( 'NEXT', Forminator::DOMAIN ), 'forminator-addon-next' ) .
267
+ '</div>';
268
+
269
+ return array(
270
+ 'html' => Forminator_Addon_Abstract::get_template( $template, $template_params ),
271
+ 'buttons' => $buttons,
272
+ 'redirect' => false,
273
+ 'has_errors' => $has_errors,
274
+ 'has_back' => true,
275
+ );
276
+ }
277
+
278
+ /**
279
+ * Check if setup list completed
280
+ *
281
+ * @since 1.0 Campaign Monitor Addon
282
+ *
283
+ * @param $submitted_data
284
+ *
285
+ * @return bool
286
+ */
287
+ public function setup_list_is_completed( $submitted_data ) {
288
+ $multi_id = '';
289
+ if ( isset( $submitted_data['multi_id'] ) ) {
290
+ $multi_id = $submitted_data['multi_id'];
291
+ }
292
+
293
+ if ( empty( $multi_id ) ) {
294
+ return false;
295
+ }
296
+
297
+ $list_id = $this->get_multi_id_form_settings_value( $multi_id, 'list_id', '' );
298
+
299
+ if ( empty( $list_id ) ) {
300
+ return false;
301
+ }
302
+
303
+ return true;
304
+ }
305
+
306
+ /**
307
+ * Setup fields map
308
+ *
309
+ * @since 1.0 Campaignmonitor Addon
310
+ *
311
+ * @param $submitted_data
312
+ *
313
+ * @return array
314
+ */
315
+ public function map_fields( $submitted_data ) {
316
+ $template = forminator_addon_campaignmonitor_dir() . 'views/form-settings/map-fields.php';
317
+
318
+ if ( ! isset( $submitted_data['multi_id'] ) ) {
319
+ return $this->get_force_closed_wizard( __( 'Please pick valid connection', Forminator::DOMAIN ) );
320
+ }
321
+
322
+ $multi_id = $submitted_data['multi_id'];
323
+ unset( $submitted_data['multi_id'] );
324
+
325
+ // find type of email
326
+ $email_fields = array();
327
+ $forminator_field_element_ids = array();
328
+ foreach ( $this->form_fields as $form_field ) {
329
+ // collect element ids
330
+ $forminator_field_element_ids[] = $form_field['element_id'];
331
+ if ( 'email' === $form_field['type'] ) {
332
+ $email_fields[] = $form_field;
333
+ }
334
+ }
335
+
336
+ $template_params = array(
337
+ 'fields_map' => $this->get_multi_id_form_settings_value( $multi_id, 'fields_map', array() ),
338
+ 'multi_id' => $multi_id,
339
+ 'error_message' => '',
340
+ 'fields' => array(),
341
+ 'form_fields' => $this->form_fields,
342
+ 'email_fields' => $email_fields,
343
+ );
344
+
345
+ $is_submit = ! empty( $submitted_data );
346
+ $has_errors = false;
347
+
348
+ $fields = array(
349
+ 'default_field_email' => __( 'Email Address', Forminator::DOMAIN ),
350
+ 'default_field_name' => __( 'Name', Forminator::DOMAIN ),
351
+ );
352
+
353
+ $list_id = $this->get_multi_id_form_settings_value( $multi_id, 'list_id', 0 );
354
+
355
+ try {
356
+
357
+ $api = $this->addon->get_api();
358
+ $list_custom_fields = $api->get_list_custom_field( $list_id );
359
+
360
+ if ( ! is_array( $list_custom_fields ) ) {
361
+ throw new Forminator_Addon_Campaignmonitor_Exception( __( 'Campaign Monitor list\'s custom fields could not be found', Forminator::DOMAIN ) );
362
+ }
363
+
364
+ foreach ( $list_custom_fields as $field ) {
365
+ $field_key = $field->Key; //phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
366
+ if ( stripos( $field_key, '[' ) === 0 ) {
367
+ $field_key = substr( $field_key, 1 );
368
+ }
369
+ if ( strripos( $field_key, ']' ) === ( strlen( $field_key ) - 1 ) ) {
370
+ $field_key = substr( $field_key, 0, strlen( $field_key ) - 1 );
371
+ }
372
+ $fields[ $field_key ] = $field->FieldName; //phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
373
+ }
374
+
375
+ $template_params['fields'] = $fields;
376
+
377
+ } catch ( Forminator_Addon_Campaignmonitor_Exception $e ) {
378
+ $template_params['error_message'] = $e->getMessage();
379
+ $has_errors = true;
380
+ }
381
+
382
+ if ( $is_submit ) {
383
+ $fields_map = isset( $submitted_data['fields_map'] ) ? $submitted_data['fields_map'] : array();
384
+ $template_params['fields_map'] = $fields_map;
385
+
386
+ try {
387
+ if ( empty( $fields_map ) ) {
388
+ throw new Forminator_Addon_Campaignmonitor_Exception( __( 'Please assign fields.', Forminator::DOMAIN ) );
389
+ }
390
+
391
+ $input_exceptions = new Forminator_Addon_Campaignmonitor_Form_Settings_Exception();
392
+ if ( ! isset( $fields_map['default_field_email'] ) || empty( $fields_map['default_field_email'] ) ) {
393
+ $input_exceptions->add_input_exception( 'Please assign field for Email Address', 'default_field_email_error' );
394
+ }
395
+
396
+ if ( ! isset( $fields_map['default_field_name'] ) || empty( $fields_map['default_field_name'] ) ) {
397
+ $input_exceptions->add_input_exception( 'Please assign field for Name', 'default_field_name_error' );
398
+ }
399
+
400
+ $fields_map_to_save = array();
401
+ foreach ( $fields as $key => $title ) {
402
+ if ( isset( $fields_map[ $key ] ) && ! empty( $fields_map[ $key ] ) ) {
403
+ $element_id = $fields_map[ $key ];
404
+ if ( ! in_array( $element_id, $forminator_field_element_ids, true ) ) {
405
+ $input_exceptions->add_input_exception(
406
+ sprintf( __( 'Please assign valid field for %s', Forminator::DOMAIN ), $title ),
407
+ $key . '_error'
408
+ );
409
+ continue;
410
+ }
411
+
412
+ $fields_map_to_save[ $key ] = $fields_map[ $key ];
413
+ }
414
+ }
415
+
416
+ if ( $input_exceptions->input_exceptions_is_available() ) {
417
+ throw $input_exceptions;
418
+ }
419
+
420
+ $this->save_multi_id_form_setting_values( $multi_id, array( 'fields_map' => $fields_map ) );
421
+
422
+ } catch ( Forminator_Addon_Campaignmonitor_Form_Settings_Exception $e ) {
423
+ $template_params = array_merge( $template_params, $e->get_input_exceptions() );
424
+ $has_errors = true;
425
+ } catch ( Forminator_Addon_Campaignmonitor_Exception $e ) {
426
+ $template_params['error_message'] = $e->getMessage();
427
+ $has_errors = true;
428
+ }
429
+ }
430
+
431
+ $buttons = array();
432
+ if ( $this->pick_name_is_completed( array( 'multi_id' => $multi_id ) ) ) {
433
+ $buttons['disconnect']['markup'] = Forminator_Addon_Abstract::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ),
434
+ 'sui-button-ghost sui-tooltip sui-tooltip-top-center forminator-addon-form-disconnect',
435
+ esc_html__( 'Disconnect this Campaign Monitor Integration from this Form.', Forminator::DOMAIN )
436
+ );
437
+ }
438
+
439
+ $buttons['next']['markup'] = '<div class="sui-actions-right">' .
440
+ Forminator_Addon_Abstract::get_button_markup( esc_html__( 'NEXT', Forminator::DOMAIN ), 'forminator-addon-next' ) .
441
+ '</div>';
442
+
443
+ return array(
444
+ 'html' => Forminator_Addon_Abstract::get_template( $template, $template_params ),
445
+ 'buttons' => $buttons,
446
+ 'size' => 'normal',
447
+ 'redirect' => false,
448
+ 'has_errors' => $has_errors,
449
+ 'has_back' => true,
450
+ );
451
+ }
452
+
453
+ /**
454
+ * Check if fields mapped
455
+ *
456
+ * @since 1.0 Campaign Monitor Addon
457
+ *
458
+ * @param $submitted_data
459
+ *
460
+ * @return bool
461
+ */
462
+ public function map_fields_is_completed( $submitted_data ) {
463
+ $multi_id = '';
464
+ if ( isset( $submitted_data['multi_id'] ) ) {
465
+ $multi_id = $submitted_data['multi_id'];
466
+ }
467
+
468
+ if ( empty( $multi_id ) ) {
469
+ return false;
470
+ }
471
+
472
+ $fields_map = $this->get_multi_id_form_settings_value( $multi_id, 'fields_map', array() );
473
+
474
+ if ( empty( $fields_map ) || ! is_array( $fields_map ) || count( $fields_map ) < 1 ) {
475
+ return false;
476
+ }
477
+
478
+ if ( ! isset( $fields_map['default_field_email'] ) || empty( $fields_map['default_field_email'] ) ) {
479
+ return false;
480
+ }
481
+
482
+ if ( ! isset( $fields_map['default_field_name'] ) || empty( $fields_map['default_field_name'] ) ) {
483
+ return false;
484
+ }
485
+
486
+ return true;
487
+ }
488
+
489
+ /**
490
+ * Setup options
491
+ *
492
+ * Contains :
493
+ * - Resubscribe
494
+ * - RestartSubscriptionBasedAutoresponders
495
+ * - ConsentToTrack
496
+ *
497
+ * @since 1.0 Campaign Monitor Addon
498
+ *
499
+ * @param $submitted_data
500
+ *
501
+ * @return array
502
+ */
503
+ public function setup_options( $submitted_data ) {
504
+ $template = forminator_addon_campaignmonitor_dir() . 'views/form-settings/setup-options.php';
505
+
506
+ if ( ! isset( $submitted_data['multi_id'] ) ) {
507
+ return $this->get_force_closed_wizard( __( 'Please pick valid connection', Forminator::DOMAIN ) );
508
+ }
509
+
510
+ $multi_id = $submitted_data['multi_id'];
511
+ unset( $submitted_data['multi_id'] );
512
+
513
+ $forminator_form_element_ids = array();
514
+ foreach ( $this->form_fields as $field ) {
515
+ $forminator_form_element_ids[ $field['element_id'] ] = $field;
516
+ }
517
+
518
+ $template_params = array(
519
+ 'multi_id' => $multi_id,
520
+ 'error_message' => '',
521
+ 'resubscribe' => $this->get_multi_id_form_settings_value( $multi_id, 'resubscribe', false ),
522
+ 'restart_subscription_based_autoresponders' => $this->get_multi_id_form_settings_value( $multi_id, 'restart_subscription_based_autoresponders', false ),
523
+ 'consent_to_track' => $this->get_multi_id_form_settings_value( $multi_id, 'consent_to_track', 'Unchanged' ),
524
+ );
525
+
526
+ $is_submit = ! empty( $submitted_data );
527
+ $has_errors = false;
528
+ $notification = array();
529
+ $is_close = false;
530
+
531
+ if ( $is_submit ) {
532
+ $resubscribe = isset( $submitted_data['resubscribe'] ) ? (int) $submitted_data['resubscribe'] : 0;
533
+ $restart_subscription_based_autoresponders = isset( $submitted_data['restart_subscription_based_autoresponders'] ) ? (int) $submitted_data['restart_subscription_based_autoresponders'] : 0;
534
+ $consent_to_track = isset( $submitted_data['consent_to_track'] ) ? $submitted_data['consent_to_track'] : 'Unchanged';
535
+
536
+ try {
537
+ $input_exceptions = new Forminator_Addon_Campaignmonitor_Form_Settings_Exception();
538
+
539
+ $available_consents = array(
540
+ 'Yes',
541
+ 'No',
542
+ 'Unchanged',
543
+ );
544
+
545
+ if ( ! in_array( $consent_to_track, $available_consents, true ) ) {
546
+ $input_exceptions->add_input_exception( __( 'Please pick valid Consent To Track options', Forminator::DOMAIN ), 'consent_to_track_error' );
547
+ }
548
+
549
+ if ( $input_exceptions->input_exceptions_is_available() ) {
550
+ throw $input_exceptions;
551
+ }
552
+
553
+ $this->save_multi_id_form_setting_values(
554
+ $multi_id,
555
+ array(
556
+ 'resubscribe' => (bool) $resubscribe,
557
+ 'restart_subscription_based_autoresponders' => (bool) $restart_subscription_based_autoresponders,
558
+ 'consent_to_track' => $consent_to_track,
559
+ )
560
+ );
561
+
562
+ $notification = array(
563
+ 'type' => 'success',
564
+ 'text' => '<strong>' . $this->addon->get_title() . '</strong> ' . __( 'Successfully connected to your form' ),
565
+ );
566
+ $is_close = true;
567
+
568
+ } catch ( Forminator_Addon_Campaignmonitor_Form_Settings_Exception $e ) {
569
+ $template_params = array_merge( $template_params, $e->get_input_exceptions() );
570
+ $has_errors = true;
571
+ } catch ( Forminator_Addon_Campaignmonitor_Form_Settings_Exception $e ) {
572
+ $template_params['error_message'] = $e->getMessage();
573
+ $has_errors = true;
574
+ }
575
+ }
576
+
577
+ $buttons = array();
578
+ if ( $this->pick_name_is_completed( array( 'multi_id' => $multi_id ) ) ) {
579
+ $buttons['disconnect']['markup'] = Forminator_Addon_Abstract::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ),
580
+ 'sui-button-ghost sui-tooltip sui-tooltip-top-center forminator-addon-form-disconnect',
581
+ esc_html__( 'Disconnect this Campaign Monitor Integration from this Form.', Forminator::DOMAIN )
582
+ );
583
+ }
584
+
585
+ $buttons['next']['markup'] = '<div class="sui-actions-right">' .
586
+ Forminator_Addon_Abstract::get_button_markup( esc_html__( 'SAVE', Forminator::DOMAIN ), 'sui-button-primary forminator-addon-finish' ) .
587
+ '</div>';
588
+
589
+ return array(
590
+ 'html' => Forminator_Addon_Abstract::get_template( $template, $template_params ),
591
+ 'buttons' => $buttons,
592
+ 'size' => 'normal',
593
+ 'redirect' => false,
594
+ 'has_errors' => $has_errors,
595
+ 'has_back' => true,
596
+ 'notification' => $notification,
597
+ 'is_close' => $is_close,
598
+ );
599
+ }
600
+
601
+ /**
602
+ * Check if setup options completed
603
+ *
604
+ * @since 1.0 Campaign Monitor Addon
605
+ *
606
+ * @param $submitted_data
607
+ *
608
+ * @return bool
609
+ */
610
+ public function setup_options_is_completed( $submitted_data ) {
611
+ // all settings here are optional, so it can be marked as completed
612
+ return true;
613
+ }
614
+
615
+ /**
616
+ * Check if multi_id form settings values completed
617
+ *
618
+ * @since 1.0 Campaign Monitor Added
619
+ *
620
+ * @param $multi_id
621
+ *
622
+ * @return bool
623
+ */
624
+ public function is_multi_form_settings_complete( $multi_id ) {
625
+ $data = array( 'multi_id' => $multi_id );
626
+
627
+ if ( ! $this->pick_name_is_completed( $data ) ) {
628
+ return false;
629
+ }
630
+ if ( ! $this->setup_list_is_completed( $data ) ) {
631
+ return false;
632
+ }
633
+
634
+ if ( ! $this->map_fields_is_completed( $data ) ) {
635
+ return false;
636
+ }
637
+
638
+ if ( ! $this->setup_options_is_completed( $data ) ) {
639
+ return false;
640
+ }
641
+
642
+ return true;
643
+ }
644
+
645
+ /**
646
+ * Generate multi id for multiple connection
647
+ *
648
+ * @since 1.0 Campaignmonitor Addon
649
+ * @return string
650
+ */
651
+ public function generate_multi_id() {
652
+ return uniqid( 'campaignmonitor_', true );
653
+ }
654
+
655
+
656
+ /**
657
+ * Override how multi connection displayed
658
+ *
659
+ * @since 1.0 Campaignmonitor Addon
660
+ * @return array
661
+ */
662
+ public function get_multi_ids() {
663
+ $multi_ids = array();
664
+ foreach ( $this->get_form_settings_values() as $key => $value ) {
665
+ $multi_ids[] = array(
666
+ 'id' => $key,
667
+ // use name that was added by user on creating connection
668
+ 'label' => isset( $value['name'] ) ? $value['name'] : $key,
669
+ );
670
+ }
671
+
672
+ return $multi_ids;
673
+ }
674
+
675
+ /**
676
+ * Disconnect a connection from current form
677
+ *
678
+ * @since 1.0 Campaignmonitor Addon
679
+ *
680
+ * @param array $submitted_data
681
+ */
682
+ public function disconnect_form( $submitted_data ) {
683
+ // only execute if multi_id provided on submitted data
684
+ if ( isset( $submitted_data['multi_id'] ) && ! empty( $submitted_data['multi_id'] ) ) {
685
+ $addon_form_settings = $this->get_form_settings_values();
686
+ unset( $addon_form_settings[ $submitted_data['multi_id'] ] );
687
+ $this->save_form_settings_values( $addon_form_settings );
688
+ }
689
+ }
690
+ }
addons/pro/campaignmonitor/forminator-addon-campaignmonitor.php ADDED
@@ -0,0 +1,510 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once dirname( __FILE__ ) . '/forminator-addon-campaignmonitor-exception.php';
4
+ require_once dirname( __FILE__ ) . '/lib/class-wp-campaignmonitor-api.php';
5
+
6
+ /**
7
+ * Class Forminator_Addon_Campaignmonitor
8
+ * Campaignmonitor Addon Main Class
9
+ *
10
+ * @since 1.0 Campaignmonitor Addon
11
+ */
12
+ final class Forminator_Addon_Campaignmonitor extends Forminator_Addon_Abstract {
13
+
14
+ /**
15
+ * @var self|null
16
+ */
17
+ private static $_instance = null;
18
+
19
+ protected $_slug = 'campaignmonitor';
20
+ protected $_version = FORMINATOR_ADDON_CAMPAIGNMONITOR_VERSION;
21
+ protected $_min_forminator_version = '1.1';
22
+ protected $_short_title = 'Campaign Monitor';
23
+ protected $_title = 'Campaign Monitor';
24
+ protected $_url = 'https://premium.wpmudev.org';
25
+ protected $_full_path = __FILE__;
26
+
27
+ protected $_form_settings = 'Forminator_Addon_Campaignmonitor_Form_Settings';
28
+ protected $_form_hooks = 'Forminator_Addon_Campaignmonitor_Form_Hooks';
29
+
30
+ /**
31
+ * Campaign Monitor API
32
+ *
33
+ * @var Forminator_Addon_Campaignmonitor_Wp_Api|null
34
+ */
35
+ private static $api = null;
36
+
37
+ /**
38
+ * Forminator_Addon_Campaignmonitor constructor.
39
+ *
40
+ * @since 1.0 Campaignmonitor Addon
41
+ */
42
+ public function __construct() {
43
+ // late init to allow translation
44
+ $this->_description = __( 'Get awesome by your form.', Forminator::DOMAIN );
45
+ $this->_activation_error_message = __( 'Sorry but we failed to activate Campaign Monitor Integration, don\'t hesitate to contact us', Forminator::DOMAIN );
46
+ $this->_deactivation_error_message = __( 'Sorry but we failed to deactivate Campaign Monitor Integration, please try again', Forminator::DOMAIN );
47
+
48
+ $this->_update_settings_error_message = __(
49
+ 'Sorry, we are failed to update settings, please check your form and try again',
50
+ Forminator::DOMAIN
51
+ );
52
+
53
+ $this->_icon = forminator_addon_campaignmonitor_assets_url() . 'icons/campaignmonitor.png';
54
+ $this->_icon_x2 = forminator_addon_campaignmonitor_assets_url() . 'icons/campaignmonitor@2x.png';
55
+ $this->_image = forminator_addon_campaignmonitor_assets_url() . 'img/campaignmonitor.png';
56
+ $this->_image_x2 = forminator_addon_campaignmonitor_assets_url() . 'img/campaignmonitor@2x.png';
57
+ }
58
+
59
+ /**
60
+ * Get Instance
61
+ *
62
+ * @since 1.0 Campaignmonitor Addon
63
+ * @return self|null
64
+ */
65
+ public static function get_instance() {
66
+ if ( is_null( self::$_instance ) ) {
67
+ self::$_instance = new self();
68
+ }
69
+
70
+ return self::$_instance;
71
+ }
72
+
73
+ /**
74
+ * Override on is_connected
75
+ *
76
+ * @since 1.0 Campaignmonitor Addon
77
+ *
78
+ * @return bool
79
+ */
80
+ public function is_connected() {
81
+ try {
82
+ // check if its active
83
+ if ( ! $this->is_active() ) {
84
+ throw new Forminator_Addon_Campaignmonitor_Exception( __( 'Campaign Monitor is not active', Forminator::DOMAIN ) );
85
+ }
86
+
87
+ // if user completed api setup
88
+ $is_connected = $this->is_api_completed();
89
+
90
+ } catch ( Forminator_Addon_Campaignmonitor_Exception $e ) {
91
+ $is_connected = false;
92
+ }
93
+
94
+ /**
95
+ * Filter connected status of Campaign Monitor
96
+ *
97
+ * @since 1.3
98
+ *
99
+ * @param bool $is_connected
100
+ */
101
+ $is_connected = apply_filters( 'forminator_addon_campaignmonitor_is_connected', $is_connected );
102
+
103
+ return $is_connected;
104
+ }
105
+
106
+ /**
107
+ * Check if Campaignmonitor is connected with current form
108
+ *
109
+ * @since 1.0 Campaignmonitor Addon
110
+ *
111
+ * @param $form_id
112
+ *
113
+ * @return bool
114
+ */
115
+ public function is_form_connected( $form_id ) {
116
+ try {
117
+ $form_settings_instance = null;
118
+ if ( ! $this->is_connected() ) {
119
+ throw new Forminator_Addon_Campaignmonitor_Exception( __( ' Campaign Monitor is not connected', Forminator::DOMAIN ) );
120
+ }
121
+
122
+ $form_settings_instance = $this->get_addon_form_settings( $form_id );
123
+ if ( ! $form_settings_instance instanceof Forminator_Addon_Campaignmonitor_Form_Settings ) {
124
+ throw new Forminator_Addon_Campaignmonitor_Exception( __( 'Invalid Form Settings of Campaign Monitor', Forminator::DOMAIN ) );
125
+ }
126
+
127
+ // Mark as active when there is at least one active connection
128
+ if ( false === $form_settings_instance->find_one_active_connection() ) {
129
+ throw new Forminator_Addon_Campaignmonitor_Exception( __( 'No active Campaign Monitor connection found in this form', Forminator::DOMAIN ) );
130
+ }
131
+
132
+ $is_form_connected = true;
133
+
134
+ } catch ( Forminator_Addon_Campaignmonitor_Exception $e ) {
135
+ $is_form_connected = false;
136
+ forminator_addon_maybe_log( __METHOD__, $e->getMessage() );
137
+ }
138
+
139
+ /**
140
+ * Filter connected status of Campaign Monitor with the form
141
+ *
142
+ * @since 1.3
143
+ *
144
+ * @param bool $is_form_connected
145
+ * @param int $form_id Current Form ID
146
+ * @param Forminator_Addon_Campaignmonitor_Form_Settings|null $form_settings_instance Instance of form settings, or null when unavailable
147
+ *
148
+ */
149
+ $is_form_connected = apply_filters( 'forminator_addon_campaignmonitor_is_form_connected', $is_form_connected, $form_id, $form_settings_instance );
150
+
151
+ return $is_form_connected;
152
+ }
153
+
154
+ /**
155
+ * Override settings available,
156
+ *
157
+ * @since 1.0 Campaignmonitor Addon
158
+ * @return bool
159
+ */
160
+ public function is_settings_available() {
161
+ return true;
162
+ }
163
+
164
+ /**
165
+ * Flag show full log on entries
166
+ *
167
+ * @since 1.0 Campaignmonitor Addon
168
+ * @return bool
169
+ */
170
+ public static function is_show_full_log() {
171
+ $show_full_log = false;
172
+ if ( defined( 'FORMINATOR_ADDON_CAMPAIGNMONITOR_SHOW_FULL_LOG' ) && FORMINATOR_ADDON_CAMPAIGNMONITOR_SHOW_FULL_LOG ) {
173
+ $show_full_log = true;
174
+ }
175
+
176
+ /**
177
+ * Filter Flag show full log on entries
178
+ *
179
+ * @since 1.3
180
+ *
181
+ * @params bool $show_full_log
182
+ */
183
+ $show_full_log = apply_filters( 'forminator_addon_campaignmonitor_show_full_log', $show_full_log );
184
+
185
+ return $show_full_log;
186
+ }
187
+
188
+ /**
189
+ * Flag delete subscriber on delete submission
190
+ *
191
+ * @since 1.0 Campaignmonitor Addon
192
+ * @return bool
193
+ */
194
+ public static function is_enable_delete_subscriber() {
195
+ $delete_subscriber = false;
196
+ if ( defined( 'FORMINATOR_ADDON_CAMPAIGNMONITOR_ENABLE_DELETE_SUBSCRIBER' ) && FORMINATOR_ADDON_CAMPAIGNMONITOR_ENABLE_DELETE_SUBSCRIBER ) {
197
+ $delete_subscriber = true;
198
+ }
199
+
200
+ /**
201
+ * Filter Flag delete subscriber on delete submission
202
+ *
203
+ * @since 1.3
204
+ *
205
+ * @params bool $delete_subscriber
206
+ */
207
+ $delete_subscriber = apply_filters( 'forminator_addon_campaignmonitor_enable_delete_subscriber', $delete_subscriber );
208
+
209
+ return $delete_subscriber;
210
+ }
211
+
212
+ /**
213
+ * Allow multiple connection on one form
214
+ *
215
+ * @since 1.0 Campaignmonitor Addon
216
+ * @return bool
217
+ */
218
+ public function is_allow_multi_on_form() {
219
+ return true;
220
+ }
221
+
222
+ /**
223
+ * Setting wizard of Campaign Monitor
224
+ *
225
+ * @since 1.0 Campaign Monitor Addon
226
+ * @return array
227
+ */
228
+ public function settings_wizards() {
229
+ return array(
230
+ array(
231
+ 'callback' => array( $this, 'setup_api' ),
232
+ 'is_completed' => array( $this, 'is_api_completed' ),
233
+ ),
234
+ );
235
+ }
236
+
237
+
238
+ /**
239
+ * Setup API Wizard
240
+ *
241
+ * @since 1.0 Campaign Monitor Addon
242
+ *
243
+ * @param $submitted_data
244
+ * @param int $form_id
245
+ *
246
+ * @return array
247
+ */
248
+ public function setup_api( $submitted_data, $form_id = 0 ) {
249
+ $settings_values = $this->get_settings_values();
250
+
251
+ $template = forminator_addon_campaignmonitor_dir() . 'views/settings/setup-api.php';
252
+ $template_success = forminator_addon_campaignmonitor_dir() . 'views/settings/setup-api-success.php';
253
+
254
+ $template_params = array(
255
+ 'error_message' => '',
256
+ 'api_key' => '',
257
+ 'client_id' => '',
258
+ 'api_key_error' => '',
259
+ 'client_id_error' => '',
260
+ 'client_name' => '',
261
+ );
262
+
263
+ $has_errors = false;
264
+ $show_success = false;
265
+ $is_submit = ! empty( $submitted_data );
266
+
267
+ foreach ( $template_params as $key => $value ) {
268
+ if ( isset( $submitted_data[ $key ] ) ) {
269
+ $template_params[ $key ] = $submitted_data[ $key ];
270
+ } elseif ( isset( $settings_values[ $key ] ) ) {
271
+ $template_params[ $key ] = $settings_values[ $key ];
272
+ }
273
+ }
274
+
275
+ if ( $is_submit ) {
276
+ $api_key = isset( $submitted_data['api_key'] ) ? $submitted_data['api_key'] : '';
277
+ $client_id = isset( $submitted_data['client_id'] ) ? $submitted_data['client_id'] : '';
278
+
279
+ try {
280
+ $api_key = $this->validate_api_key( $api_key );
281
+ } catch ( Forminator_Addon_Campaignmonitor_Exception $e ) {
282
+ $template_params['api_key_error'] = $e->getMessage();
283
+ $has_errors = true;
284
+ }
285
+
286
+ if ( ! $has_errors ) {
287
+ // validate api
288
+ try {
289
+
290
+ $this->validate_api( $api_key );
291
+
292
+ $client_details = null;
293
+
294
+ if ( ! empty( $client_id ) ) {
295
+ $client_details = $this->validate_client( $api_key, $client_id );
296
+ } else {
297
+ //find first client
298
+ $clients = $this->get_api( $api_key )->get_clients();
299
+ if ( is_array( $clients ) ) {
300
+ if ( isset( $clients[0] ) ) {
301
+ $client = $clients[0];
302
+ if ( isset( $client->ClientID ) ) { //phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
303
+ $client_id = $client->ClientID; //phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
304
+ $client_details = $this->validate_client( $api_key, $client_id );
305
+ }
306
+ }
307
+ }
308
+ }
309
+
310
+ if ( ! isset( $client_details->BasicDetails ) //phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
311
+ || ! isset( $client_details->BasicDetails->ClientID ) //phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
312
+ || ! isset( $client_details->BasicDetails->CompanyName ) ) { //phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
313
+ throw new Forminator_Addon_Campaignmonitor_Exception( __( 'Could not find client details, please try again', Forminator::DOMAIN ) );
314
+ }
315
+
316
+ $client_name = $client_details->BasicDetails->CompanyName; //phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
317
+
318
+ if ( ! forminator_addon_is_active( $this->_slug ) ) {
319
+ $activated = Forminator_Addon_Loader::get_instance()->activate_addon( $this->_slug );
320
+ if ( ! $activated ) {
321
+ throw new Forminator_Addon_Campaignmonitor_Exception( Forminator_Addon_Loader::get_instance()->get_last_error_message() );
322
+ }
323
+ }
324
+
325
+ $settings_values = array(
326
+ 'api_key' => $api_key,
327
+ 'client_id' => $client_id,
328
+ 'client_name' => $client_name,
329
+ );
330
+ $this->save_settings_values( $settings_values );
331
+
332
+ // no form_id its on global settings
333
+ if ( empty( $form_id ) ) {
334
+ $show_success = true;
335
+ }
336
+ } catch ( Forminator_Addon_Campaignmonitor_Exception $e ) {
337
+ $template_params['error_message'] = $e->getMessage();
338
+ $has_errors = true;
339
+ }
340
+ }
341
+
342
+ }
343
+
344
+ if ( $show_success ) {
345
+ $template = $template_success;
346
+ }
347
+
348
+ $buttons = array();
349
+
350
+ if ( $show_success ) {
351
+ $buttons['close'] = array(
352
+ 'markup' => self::get_button_markup( esc_html__( 'CLOSE', Forminator::DOMAIN ), 'sui-button-ghost forminator-addon-close' ),
353
+ );
354
+ } else {
355
+ if ( $this->is_connected() ) {
356
+ $buttons['disconnect'] = array(
357
+ 'markup' => self::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ), 'sui-button-ghost forminator-addon-disconnect' ),
358
+ );
359
+ $buttons['submit'] = array(
360
+ 'markup' => '<div class="sui-actions-right">' .
361
+ self::get_button_markup( esc_html__( 'SAVE', Forminator::DOMAIN ), 'forminator-addon-connect' ) .
362
+ '</div>',
363
+ );
364
+ } else {
365
+ $buttons['submit'] = array(
366
+ 'markup' => '<div class="sui-actions-right">' .
367
+ self::get_button_markup( esc_html__( 'CONNECT', Forminator::DOMAIN ), 'forminator-addon-connect' ) .
368
+ '</div>',
369
+ );
370
+ }
371
+
372
+
373
+ }
374
+
375
+ return array(
376
+ 'html' => self::get_template( $template, $template_params ),
377
+ 'buttons' => $buttons,
378
+ 'redirect' => false,
379
+ 'has_errors' => $has_errors,
380
+ );
381
+ }
382
+
383
+ /**
384
+ * Check Api settings Completed
385
+ *
386
+ * @since 1.o Campaign Monitor
387
+ * @return bool
388
+ */
389
+ public function is_api_completed() {
390
+ $setting_values = $this->get_settings_values();
391
+
392
+ // check api_key set up
393
+ return ( isset( $setting_values['api_key'] ) && ! empty( $setting_values['api_key'] ) );
394
+ }
395
+
396
+ /**
397
+ * Get API Instance
398
+ *
399
+ * @since 1.0 Campaign Monitor Addon
400
+ *
401
+ * @param null $api_key
402
+ *
403
+ * @return Forminator_Addon_Campaignmonitor_Wp_Api
404
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Exception
405
+ */
406
+ public function get_api( $api_key = null ) {
407
+ if ( is_null( self::$api ) ) {
408
+ if ( is_null( $api_key ) ) {
409
+ $setting_values = $this->get_settings_values();
410
+ $api_key = '';
411
+ if ( isset( $setting_values['api_key'] ) ) {
412
+ $api_key = $setting_values['api_key'];
413
+ }
414
+
415
+ }
416
+ $api = Forminator_Addon_Campaignmonitor_Wp_Api::get_instance( $api_key );
417
+ self::$api = $api;
418
+ }
419
+
420
+ return self::$api;
421
+ }
422
+
423
+ /**
424
+ * Validate API Key
425
+ *
426
+ * @since 1.0 Campaign Monitor
427
+ *
428
+ * @param string $api_key
429
+ *
430
+ * @return string
431
+ * @throws Forminator_Addon_Campaignmonitor_Exception
432
+ */
433
+ public function validate_api_key( $api_key ) {
434
+ if ( empty( $api_key ) ) {
435
+ throw new Forminator_Addon_Campaignmonitor_Exception( __( 'Please put a valid Campaign Monitor API Key', Forminator::DOMAIN ) );
436
+ }
437
+
438
+ return $api_key;
439
+ }
440
+
441
+ /**
442
+ * Validate API
443
+ *
444
+ * @since 1.0 Campaign Monitor Addon
445
+ *
446
+ * @param $api_key
447
+ *
448
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Exception
449
+ * @throws Forminator_Addon_Campaignmonitor_Exception
450
+ */
451
+ public function validate_api( $api_key ) {
452
+ self::$api = null;
453
+ $api = $this->get_api( $api_key );
454
+
455
+ $system_date = $api->get_system_date();
456
+
457
+ if ( ! isset( $system_date->SystemDate ) || empty( $system_date->SystemDate ) ) { //phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
458
+ throw new Forminator_Addon_Campaignmonitor_Exception( __( 'Failed to get validate API.', Forminator::DOMAIN ) );
459
+ }
460
+ }
461
+
462
+ /**
463
+ * Validate Client
464
+ *
465
+ * @since 1.0 Campaign Monitor Addon
466
+ *
467
+ * @param $api_key
468
+ * @param $client_id
469
+ *
470
+ * @return array|mixed|object
471
+ * @throws Forminator_Addon_Campaignmonitor_Exception
472
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Exception
473
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Not_Found_Exception
474
+ */
475
+ public function validate_client( $api_key, $client_id ) {
476
+ self::$api = null;
477
+ $api = $this->get_api( $api_key );
478
+
479
+ $client_details = $api->get_client( $client_id );
480
+
481
+ return $client_details;
482
+
483
+ }
484
+
485
+ /**
486
+ * Get Client ID
487
+ *
488
+ * @since 1.0 Campaign Monitor Addon
489
+ * @return string
490
+ */
491
+ public function get_client_id() {
492
+ $settings_values = $this->get_settings_values();
493
+ $client_id = '';
494
+ if ( isset( $settings_values ['client_id'] ) ) {
495
+ $client_id = $settings_values ['client_id'];
496
+ }
497
+
498
+ /**
499
+ * Filter Campaign Monitor client id used
500
+ *
501
+ * @since 1.3
502
+ *
503
+ * @param string $client_id
504
+ */
505
+ $client_id = apply_filters( 'forminator_addon_campaignmonitor_client_id', $client_id );
506
+
507
+ return $client_id;
508
+ }
509
+
510
+ }
addons/pro/campaignmonitor/lib/class-wp-campaignmonitor-api-exception.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Campaignmonitor_Wp_Api_Exception
5
+ * Exception holder for Campaignmonitor wp api
6
+ *
7
+ * @since 1.0 Campaignmonitor Addon
8
+ */
9
+ class Forminator_Addon_Campaignmonitor_Wp_Api_Exception extends Forminator_Addon_Campaignmonitor_Exception {
10
+ }
addons/pro/campaignmonitor/lib/class-wp-campaignmonitor-api-not-found-exception.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Campaignmonitor_Wp_Api_Not_Found_Exception
5
+ * Exception holder for campaignmonitor wp api on 404 not found error status
6
+ *
7
+ * @since 1.0 Campaignmonitor Addon
8
+ */
9
+ class Forminator_Addon_Campaignmonitor_Wp_Api_Not_Found_Exception extends Forminator_Addon_Campaignmonitor_Wp_Api_Exception {
10
+ }
addons/pro/campaignmonitor/lib/class-wp-campaignmonitor-api.php ADDED
@@ -0,0 +1,524 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once dirname( __FILE__ ) . '/class-wp-campaignmonitor-api-exception.php';
4
+ require_once dirname( __FILE__ ) . '/class-wp-campaignmonitor-api-not-found-exception.php';
5
+
6
+ /**
7
+ * Class Forminator_Addon_Campaignmonitor_Wp_Api
8
+ */
9
+ class Forminator_Addon_Campaignmonitor_Wp_Api {
10
+
11
+ /**
12
+ * Instances of campaignmonitor api
13
+ *
14
+ * @var array
15
+ */
16
+ private static $_instances = array();
17
+
18
+ /**
19
+ * Campaignmonitor api key
20
+ *
21
+ * @var string
22
+ */
23
+ private $_api_key = '';
24
+
25
+ /**
26
+ * Last data sent to campaignmonitor
27
+ *
28
+ * @since 1.0 Campaignmonitor Addon
29
+ * @var array
30
+ */
31
+ private $_last_data_sent = array();
32
+
33
+ /**
34
+ * Last data received from campaignmonitor
35
+ *
36
+ * @since 1.0 Campaignmonitor Addon
37
+ * @var array
38
+ */
39
+ private $_last_data_received = array();
40
+
41
+ /**
42
+ * Last URL requested
43
+ *
44
+ * @since 1.0 Campaignmonitor Addon
45
+ * @var string
46
+ */
47
+ private $_last_url_request = '';
48
+
49
+
50
+ /**
51
+ * Base API Endpoint
52
+ *
53
+ * @var string
54
+ */
55
+ private $_endpoint = 'https://api.createsend.com/api/v3.2/';
56
+
57
+ /**
58
+ * Forminator_Addon_Campaignmonitor_Wp_Api constructor.
59
+ *
60
+ * @since 1.0 Campaignmonitor Addon
61
+ *
62
+ * @param $api_key
63
+ *
64
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Exception
65
+ */
66
+ public function __construct( $api_key ) {
67
+ //prerequisites
68
+ if ( ! $api_key ) {
69
+ throw new Forminator_Addon_Campaignmonitor_Wp_Api_Exception( __( 'Missing required API Key', Forminator::DOMAIN ) );
70
+ }
71
+
72
+ $this->_api_key = $api_key;
73
+ }
74
+
75
+ /**
76
+ * Get singleton
77
+ *
78
+ * @since 1.0 Campaignmonitor Addon
79
+ *
80
+ * @param string $api_key
81
+ *
82
+ * @return Forminator_Addon_Campaignmonitor_Wp_Api|null
83
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Exception
84
+ */
85
+ public static function get_instance( $api_key ) {
86
+ if ( ! isset( self::$_instances[ md5( $api_key ) ] ) ) {
87
+ self::$_instances[ md5( $api_key ) ] = new self( $api_key );
88
+ }
89
+
90
+ return self::$_instances[ md5( $api_key ) ];
91
+ }
92
+
93
+ /**
94
+ * Add custom user agent on request
95
+ *
96
+ * @since 1.0 Campaignmonitor Addon
97
+ *
98
+ * @param $user_agent
99
+ *
100
+ * @return string
101
+ */
102
+ public function filter_user_agent( $user_agent ) {
103
+ $user_agent .= ' ForminatorCampaignmonitor/' . FORMINATOR_ADDON_CAMPAIGNMONITOR_VERSION;
104
+
105
+ /**
106
+ * Filter user agent to be used by campaignmonitor api
107
+ *
108
+ * @since 1.1
109
+ *
110
+ * @param string $user_agent current user agent
111
+ */
112
+ $user_agent = apply_filters( 'forminator_addon_campaignmonitor_api_user_agent', $user_agent );
113
+
114
+ return $user_agent;
115
+ }
116
+
117
+ /**
118
+ * HTTP Request
119
+ *
120
+ * @since 1.0 Campaignmonitor Addon
121
+ *
122
+ * @param string $verb
123
+ * @param $path
124
+ * @param array $args
125
+ *
126
+ * @return array|mixed|object
127
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Exception
128
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Not_Found_Exception
129
+ */
130
+ private function _request( $verb = 'GET', $path, $args = array() ) {
131
+ // Adding extra user agent for wp remote request
132
+ add_filter( 'http_headers_useragent', array( $this, 'filter_user_agent' ) );
133
+
134
+ $url = trailingslashit( $this->_endpoint ) . $path;
135
+
136
+ /**
137
+ * Filter campaignmonitor url to be used on sending api request
138
+ *
139
+ * @since 1.1
140
+ *
141
+ * @param string $url full url with scheme
142
+ * @param string $verb `GET` `POST` `PUT` `DELETE` `PATCH`
143
+ * @param string $path requested path resource
144
+ * @param array $args argument sent to this function
145
+ */
146
+ $url = apply_filters( 'forminator_addon_campaignmonitor_api_url', $url, $verb, $path, $args );
147
+
148
+ $this->_last_url_request = $url;
149
+
150
+ $encoded_auth = base64_encode( $this->_api_key . ':forminator-no_pass' ); //phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
151
+ $headers = array(
152
+ 'Authorization' => 'Basic ' . $encoded_auth,
153
+ );
154
+
155
+ /**
156
+ * Filter campaignmonitor headers to sent on api request
157
+ *
158
+ * @since 1.1
159
+ *
160
+ * @param array $headers
161
+ * @param string $verb `GET` `POST` `PUT` `DELETE` `PATCH`
162
+ * @param string $path requested path resource
163
+ * @param array $args argument sent to this function
164
+ */
165
+ $headers = apply_filters( 'forminator_addon_campaignmonitor_api_request_headers', $headers, $verb, $path, $args );
166
+
167
+ $_args = array(
168
+ 'method' => $verb,
169
+ 'headers' => $headers,
170
+ );
171
+
172
+ $request_data = $args;
173
+ /**
174
+ * Filter campaignmonitor request data to be used on sending api request
175
+ *
176
+ * @since 1.1
177
+ *
178
+ * @param array $request_data it will be `http_build_query`-ed when `GET` or `wp_json_encode`-ed otherwise
179
+ * @param string $verb `GET` `POST` `PUT` `DELETE` `PATCH`
180
+ * @param string $path requested path resource
181
+ */
182
+ $args = apply_filters( 'forminator_addon_campaignmonitor_api_request_data', $request_data, $verb, $path );
183
+
184
+ if ( 'GET' === $verb || 'DELETE' === $verb ) {
185
+ $url .= ( '?' . http_build_query( $args ) );
186
+ } else {
187
+ $_args['body'] = wp_json_encode( $args );
188
+ }
189
+
190
+ $this->_last_data_sent = $args;
191
+
192
+ $res = wp_remote_request( $url, $_args );
193
+ $wp_response = $res;
194
+
195
+ remove_filter( 'http_headers_useragent', array( $this, 'filter_user_agent' ) );
196
+
197
+ if ( is_wp_error( $res ) || ! $res ) {
198
+ forminator_addon_maybe_log( __METHOD__, $res );
199
+ throw new Forminator_Addon_Campaignmonitor_Wp_Api_Exception(
200
+ __( 'Failed to process request, make sure your Webhook URL is correct and your server has internet connection.', Forminator::DOMAIN )
201
+ );
202
+ }
203
+
204
+ if ( isset( $res['response']['code'] ) ) {
205
+ $status_code = $res['response']['code'];
206
+ $msg = '';
207
+ if ( $status_code >= 400 ) {
208
+ if ( isset( $res['response']['message'] ) ) {
209
+ $msg = $res['response']['message'];
210
+ }
211
+
212
+ $body_json = wp_remote_retrieve_body( $res );
213
+ $res_json = json_decode( $body_json );
214
+ if ( ! is_null( $res_json ) && is_object( $res_json ) && isset( $res_json->Message ) ) {//phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
215
+ $msg = $res_json->Message;//phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
216
+ }
217
+
218
+ if ( 404 === $status_code ) {
219
+ throw new Forminator_Addon_Campaignmonitor_Wp_Api_Not_Found_Exception( sprintf( __( 'Failed to processing request : %s', Forminator::DOMAIN ), $msg ) );
220
+ }
221
+ // /* translators: ... */
222
+ throw new Forminator_Addon_Campaignmonitor_Wp_Api_Exception( sprintf( __( 'Failed to processing request : %s', Forminator::DOMAIN ), $msg ) );
223
+ }
224
+ }
225
+
226
+ $body = wp_remote_retrieve_body( $res );
227
+
228
+ // probably silent mode
229
+ if ( ! empty( $body ) ) {
230
+ $res = json_decode( $body );
231
+ }
232
+
233
+ $response = $res;
234
+ /**
235
+ * Filter campaignmonitor api response returned to addon
236
+ *
237
+ * @since 1.1
238
+ *
239
+ * @param mixed $response original wp remote request response or decoded body if available
240
+ * @param string $body original content of http response's body
241
+ * @param array|WP_Error $wp_response original wp remote request response
242
+ */
243
+ $res = apply_filters( 'forminator_addon_campaignmonitor_api_response', $response, $body, $wp_response );
244
+
245
+ $this->_last_data_received = $res;
246
+
247
+ forminator_addon_maybe_log( $res );
248
+
249
+ return $res;
250
+ }
251
+
252
+
253
+ /**
254
+ * Send data to static webhook campaignmonitor URL
255
+ *
256
+ * @since 1.0 Campaignmonitor Addon
257
+ *
258
+ * @param $args
259
+ *
260
+ * @return array|mixed|object
261
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Exception
262
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Not_Found_Exception
263
+ */
264
+ public function post_( $args ) {
265
+
266
+ return $this->_request(
267
+ 'POST',
268
+ '',
269
+ $args
270
+ );
271
+ }
272
+
273
+ /**
274
+ * Get Primary Contact
275
+ *
276
+ * @since 1.0 Campaignmonitor Addon
277
+ *
278
+ * @param array $args
279
+ *
280
+ * @return array|mixed|object
281
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Exception
282
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Not_Found_Exception
283
+ */
284
+ public function get_primary_contact( $args = array() ) {
285
+ $default_args = array();
286
+
287
+ $args = array_merge( $default_args, $args );
288
+
289
+ return $this->_request(
290
+ 'GET',
291
+ 'primarycontact.json',
292
+ $args
293
+ );
294
+ }
295
+
296
+ /**
297
+ * Get Current Data on Campaign Monitor
298
+ *
299
+ * @since 1.0 Campaignmonitor Addon
300
+ *
301
+ * @param array $args
302
+ *
303
+ * @return array|mixed|object
304
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Exception
305
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Not_Found_Exception
306
+ */
307
+ public function get_system_date( $args = array() ) {
308
+ $default_args = array();
309
+
310
+ $args = array_merge( $default_args, $args );
311
+
312
+ return $this->_request(
313
+ 'GET',
314
+ 'systemdate.json',
315
+ $args
316
+ );
317
+ }
318
+
319
+ /**
320
+ * Get List Detail
321
+ *
322
+ * @since 1.0 Campaignmonitor Addon
323
+ *
324
+ * @param $list_id
325
+ * @param array $args
326
+ *
327
+ * @return array|mixed|object
328
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Exception
329
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Not_Found_Exception
330
+ */
331
+ public function get_list( $list_id, $args = array() ) {
332
+ $default_args = array();
333
+
334
+ $args = array_merge( $default_args, $args );
335
+
336
+ return $this->_request(
337
+ 'GET',
338
+ 'lists/' . rawurlencode( trim( $list_id ) ) . '.json',
339
+ $args
340
+ );
341
+ }
342
+
343
+ /**
344
+ * Get Lists on a Client
345
+ *
346
+ * @since 1.0 Campaignmonitor Addon
347
+ *
348
+ * @param $client_id
349
+ * @param array $args
350
+ *
351
+ * @return array|mixed|object
352
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Exception
353
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Not_Found_Exception
354
+ */
355
+ public function get_client_lists( $client_id, $args = array() ) {
356
+ $default_args = array();
357
+
358
+ $args = array_merge( $default_args, $args );
359
+
360
+ return $this->_request(
361
+ 'GET',
362
+ 'clients/' . rawurlencode( trim( $client_id ) ) . '/lists.json',
363
+ $args
364
+ );
365
+ }
366
+
367
+ /**
368
+ * Get Clients
369
+ *
370
+ * @since 1.0 Campaignmonitor Addon
371
+ *
372
+ * @param array $args
373
+ *
374
+ * @return array|mixed|object
375
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Exception
376
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Not_Found_Exception
377
+ */
378
+ public function get_clients( $args = array() ) {
379
+ $default_args = array();
380
+
381
+ $args = array_merge( $default_args, $args );
382
+
383
+ return $this->_request(
384
+ 'GET',
385
+ 'clients.json',
386
+ $args
387
+ );
388
+ }
389
+
390
+ /**
391
+ * Get Client Details
392
+ *
393
+ * @since 1.0 Campaignmonitor Addon
394
+ *
395
+ * @param $client_id
396
+ * @param array $args
397
+ *
398
+ * @return array|mixed|object
399
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Exception
400
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Not_Found_Exception
401
+ */
402
+ public function get_client( $client_id, $args = array() ) {
403
+ $default_args = array();
404
+
405
+ $args = array_merge( $default_args, $args );
406
+
407
+ return $this->_request(
408
+ 'GET',
409
+ 'clients/' . rawurlencode( trim( $client_id ) ) . '.json',
410
+ $args
411
+ );
412
+ }
413
+
414
+ /**
415
+ * Get Custom Fields on Lists
416
+ *
417
+ * @since 1.0 Campaignmonitor Addon
418
+ *
419
+ * @param $list_id
420
+ * @param array $args
421
+ *
422
+ * @return array|mixed|object
423
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Exception
424
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Not_Found_Exception
425
+ */
426
+ public function get_list_custom_field( $list_id, $args = array() ) {
427
+ $default_args = array();
428
+
429
+ $args = array_merge( $default_args, $args );
430
+
431
+ return $this->_request(
432
+ 'GET',
433
+ 'lists/' . rawurlencode( trim( $list_id ) ) . '/customfields.json',
434
+ $args
435
+ );
436
+ }
437
+
438
+ /**
439
+ * Add Subscriber to the list
440
+ *
441
+ * @since 1.0 Campaignmonitor Addon
442
+ *
443
+ * @param $list_id
444
+ * @param $email_address
445
+ * @param array $args
446
+ *
447
+ * @return array|mixed|object
448
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Exception
449
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Not_Found_Exception
450
+ */
451
+ public function add_subscriber( $list_id, $email_address, $args = array() ) {
452
+ $default_args = array(
453
+ 'EmailAddress' => $email_address,
454
+ );
455
+
456
+ $args = array_merge( $default_args, $args );
457
+
458
+ return $this->_request(
459
+ 'POST',
460
+ 'subscribers/' . rawurlencode( trim( $list_id ) ) . '.json',
461
+ $args
462
+ );
463
+ }
464
+
465
+ /**
466
+ * Delete Subscriber from the list
467
+ *
468
+ * @since 1.0 Campaignmonitor Addon
469
+ *
470
+ * @param $list_id
471
+ * @param $email_address
472
+ * @param array $args
473
+ *
474
+ * @return array|mixed|object
475
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Exception
476
+ * @throws Forminator_Addon_Campaignmonitor_Wp_Api_Not_Found_Exception
477
+ */
478
+ public function delete_subscriber( $list_id, $email_address, $args = array() ) {
479
+ $default_args = array(
480
+ 'email' => $email_address,
481
+ );
482
+
483
+ $args = array_merge( $default_args, $args );
484
+
485
+ return $this->_request(
486
+ 'DELETE',
487
+ 'subscribers/' . rawurlencode( trim( $list_id ) ) . '.json',
488
+ $args
489
+ );
490
+ }
491
+
492
+ /**
493
+ * Get last data sent
494
+ *
495
+ * @since 1.0 Campaignmonitor Addon
496
+ *
497
+ * @return array
498
+ */
499
+ public function get_last_data_sent() {
500
+ return $this->_last_data_sent;
501
+ }
502
+
503
+ /**
504
+ * Get last data received
505
+ *
506
+ * @since 1.0 Campaignmonitor Addon
507
+ *
508
+ * @return array
509
+ */
510
+ public function get_last_data_received() {
511
+ return $this->_last_data_received;
512
+ }
513
+
514
+ /**
515
+ * Get last data received
516
+ *
517
+ * @since 1.0 Campaignmonitor Addon
518
+ *
519
+ * @return string
520
+ */
521
+ public function get_last_url_request() {
522
+ return $this->_last_url_request;
523
+ }
524
+ }
addons/pro/campaignmonitor/views/form-settings/map-fields.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'error_message' => '',
5
+ 'multi_id' => '',
6
+ 'fields_map' => array(),
7
+ 'fields' => array(),
8
+ 'form_fields' => array(),
9
+ 'email_fields' => array(),
10
+ );
11
+ /** @var array $template_vars */
12
+ foreach ( $template_vars as $key => $val ) {
13
+ $vars[ $key ] = $val;
14
+ }
15
+
16
+ ?>
17
+ <div class="integration-header">
18
+ <h3 class="sui-box-title" id="dialogTitle2"><?php echo esc_html( __( 'Assign Fields', Forminator::DOMAIN ) ); ?></h3>
19
+ <p><?php esc_html_e( 'Match up your form fields with your Campaign Monitor fields to make sure we\'re sending data to the right place.', Forminator::DOMAIN ); ?></p>
20
+ <?php if ( ! empty( $vars['error_message'] ) ) : ?>
21
+ <span class="sui-notice sui-notice-error"><p><?php echo esc_html( $vars['error_message'] ); ?></p></span>
22
+ <?php endif; ?>
23
+ </div>
24
+ <form>
25
+ <table class="sui-table">
26
+ <thead>
27
+ <tr>
28
+ <th><?php esc_html_e( 'Campaign Monitor Field', Forminator::DOMAIN ); ?></th>
29
+ <th><?php esc_html_e( 'Forminator Field', Forminator::DOMAIN ); ?></th>
30
+ </tr>
31
+ </thead>
32
+ <tbody>
33
+ <?php foreach ( $vars['fields'] as $key => $field_title ) : ?>
34
+ <tr>
35
+ <td>
36
+ <?php echo esc_html( $field_title ); ?>
37
+ <?php if ( 'default_field_email' === $key || 'default_field_name' === $key ) : ?>
38
+ <span class="integrations-required-field">*</span>
39
+ <?php endif; ?>
40
+ </td>
41
+ <td>
42
+ <?php
43
+ $forminator_fields = $vars['form_fields'];
44
+ if ( 'default_field_email' === $key ) {
45
+ $forminator_fields = $vars['email_fields'];
46
+ }
47
+ $current_error = '';
48
+ $current_selected = '';
49
+ if ( isset( $vars[ $key . '_error' ] ) && ! empty( $vars[ $key . '_error' ] ) ) {
50
+ $current_error = $vars[ $key . '_error' ];
51
+ }
52
+ if ( isset( $vars['fields_map'][ $key ] ) && ! empty( $vars['fields_map'][ $key ] ) ) {
53
+ $current_selected = $vars['fields_map'][ $key ];
54
+ }
55
+ ?>
56
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $current_error ) ? 'sui-form-field-error' : '' ); ?>">
57
+ <label>
58
+ <select class="sui-select" name="fields_map[<?php echo esc_attr( $key ); ?>]">
59
+ <option value="">None</option>
60
+ <?php foreach ( $forminator_fields as $forminator_field ) : ?>
61
+ <option value="<?php echo esc_attr( $forminator_field['element_id'] ); ?>"
62
+ <?php selected( $current_selected, $forminator_field['element_id'] ); ?>>
63
+ <?php echo esc_html( $forminator_field['field_label'] . ' | ' . $forminator_field['element_id'] ); ?>
64
+ </option>
65
+ <?php endforeach; ?>
66
+ </select>
67
+ </label>
68
+ <?php if ( ! empty( $current_error ) ) : ?>
69
+ <span class="sui-error-message"><?php echo esc_html( $current_error ); ?></span>
70
+ <?php endif; ?>
71
+ </div>
72
+ </td>
73
+ </tr>
74
+ <?php endforeach; ?>
75
+ </tbody>
76
+ </table>
77
+ <input type="hidden" name="multi_id" value="<?php echo esc_attr( $vars['multi_id'] ); ?>">
78
+ </form>
addons/pro/campaignmonitor/views/form-settings/pick-name.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'error_message' => '',
5
+ 'name' => '',
6
+ 'name_error' => '',
7
+ 'multi_id' => '',
8
+ );
9
+ /** @var array $template_vars */
10
+ foreach ( $template_vars as $key => $val ) {
11
+ $vars[ $key ] = $val;
12
+ }
13
+
14
+ ?>
15
+ <div class="integration-header">
16
+ <h3 class="sui-box-title" id="dialogTitle2"><?php echo esc_html( __( 'Setup Name', Forminator::DOMAIN ) ); ?></h3>
17
+ <p><?php esc_html_e( 'Setup friendly name for this integration, so it will be easily identified by you. ', Forminator::DOMAIN ); ?></p>
18
+ <?php if ( ! empty( $vars['error_message'] ) ) : ?>
19
+ <span class="sui-notice sui-notice-error"><p><?php echo esc_html( $vars['error_message'] ); ?></p></span>
20
+ <?php endif; ?>
21
+ </div>
22
+ <form>
23
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['name_error'] ) ? 'sui-form-field-error' : '' ); ?>">
24
+ <label class="sui-label"><?php esc_html_e( 'Name', Forminator::DOMAIN ); ?></label>
25
+ <input
26
+ class="sui-form-control"
27
+ name="name" placeholder="<?php echo esc_attr( __( 'Friendly Name', Forminator::DOMAIN ) ); ?>"
28
+ value="<?php echo esc_attr( $vars['name'] ); ?>">
29
+ <?php if ( ! empty( $vars['name_error'] ) ) : ?>
30
+ <span class="sui-error-message"><?php echo esc_html( $vars['name_error'] ); ?></span>
31
+ <?php endif; ?>
32
+ </div>
33
+ <input type="hidden" name="multi_id" value="<?php echo esc_attr( $vars['multi_id'] ); ?>">
34
+ </form>
addons/pro/campaignmonitor/views/form-settings/setup-list.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'error_message' => '',
5
+ 'list_id' => '',
6
+ 'list_id_error' => '',
7
+ 'multi_id' => '',
8
+ 'lists' => array(),
9
+ );
10
+ /** @var array $template_vars */
11
+ foreach ( $template_vars as $key => $val ) {
12
+ $vars[ $key ] = $val;
13
+ }
14
+
15
+ ?>
16
+ <div class="integration-header">
17
+ <h3 class="sui-box-title" id="dialogTitle2"><?php echo esc_html( __( 'Choose List', Forminator::DOMAIN ) ); ?></h3>
18
+ <p><?php esc_html_e( 'Pick Campaign Monitor List for new subscriber to be added to.', Forminator::DOMAIN ); ?></p>
19
+ <?php if ( ! empty( $vars['error_message'] ) ) : ?>
20
+ <span class="sui-notice sui-notice-error"><p><?php echo esc_html( $vars['error_message'] ); ?></p></span>
21
+ <?php endif; ?>
22
+ </div>
23
+ <form>
24
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['list_id_error'] ) ? 'sui-form-field-error' : '' ); ?>">
25
+ <label class="sui-label"><?php esc_html_e( 'List', Forminator::DOMAIN ); ?>
26
+ <select name="list_id" class="sui-select sui-form-control">
27
+ <option><?php esc_html_e( 'Please select a list', Forminator::DOMAIN ); ?></option>
28
+ <?php foreach ( $vars['lists'] as $list_id => $list_name ) : ?>
29
+ <option value="<?php echo esc_attr( $list_id ); ?>" <?php selected( $vars['list_id'], $list_id ); ?>><?php echo esc_html( $list_name ); ?></option>
30
+ <?php endforeach; ?>
31
+ </select>
32
+ <?php if ( ! empty( $vars['list_id_error'] ) ) : ?>
33
+ <span class="sui-error-message"><?php echo esc_html( $vars['list_id_error'] ); ?></span>
34
+ <?php endif; ?>
35
+ </label>
36
+ </div>
37
+ <input type="hidden" name="multi_id" value="<?php echo esc_attr( $vars['multi_id'] ); ?>">
38
+ </form>
addons/pro/campaignmonitor/views/form-settings/setup-options.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'error_message' => '',
5
+ 'multi_id' => '',
6
+ 'resubscribe' => 0,
7
+ 'resubscribe_error' => '',
8
+ 'restart_subscription_based_autoresponders' => 0,
9
+ 'restart_subscription_based_autoresponders_error' => '',
10
+ 'consent_to_track' => 'Unchanged',
11
+ 'consent_to_track_error' => '',
12
+ );
13
+ /** @var array $template_vars */
14
+ foreach ( $template_vars as $key => $val ) {
15
+ $vars[ $key ] = $val;
16
+ }
17
+
18
+ ?>
19
+ <div class="integration-header">
20
+ <h3 class="sui-box-title" id="dialogTitle2"><?php echo esc_html( __( 'Additional Options', Forminator::DOMAIN ) ); ?></h3>
21
+ <p><?php esc_html_e( 'Configure additional options for Campaign Monitor integration.', Forminator::DOMAIN ); ?></p>
22
+ <?php if ( ! empty( $vars['error_message'] ) ) : ?>
23
+ <span class="sui-notice sui-notice-error"><p><?php echo esc_html( $vars['error_message'] ); ?></p></span>
24
+ <?php endif; ?>
25
+ </div>
26
+
27
+ <form>
28
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['resubscribe_error'] ) ? 'sui-form-field-error' : '' ); ?>">
29
+ <label class="sui-toggle">
30
+ <input type="checkbox"
31
+ name="resubscribe"
32
+ id="resubscribe"
33
+ value="1"
34
+ <?php checked( true, $vars['resubscribe'] ); ?>>
35
+ <span class="sui-toggle-slider"></span>
36
+ </label>
37
+ <label class="sui-toggle-label" for="resubscribe"><?php esc_html_e( 'Re-subscribe', Forminator::DOMAIN ); ?></label>
38
+ <?php if ( ! empty( $vars['resubscribe_error'] ) ) : ?>
39
+ <span class="sui-error-message"><?php echo esc_html( $vars['resubscribe_error'] ); ?></span>
40
+ <?php endif; ?>
41
+ <span class="sui-description">
42
+ <?php
43
+ esc_html_e(
44
+ 'If the subscriber is in an inactive state or has previously been unsubscribed or added to the suppression list and you enabled Re-subscribe, they will be re-added to the list. Therefore, this options should be used with caution and only where suitable. If Re-subscribe is disabled, the subscriber will not be re-added to the active list.',
45
+ Forminator::DOMAIN
46
+ );
47
+ ?>
48
+ </span>
49
+ </div>
50
+
51
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['restart_subscription_based_autoresponders_error'] ) ? 'sui-form-field-error' : '' ); ?>">
52
+ <label class="sui-toggle">
53
+ <input type="checkbox"
54
+ name="restart_subscription_based_autoresponders"
55
+ id="restart_subscription_based_autoresponders"
56
+ value="1"
57
+ <?php checked( true, $vars['restart_subscription_based_autoresponders'] ); ?>>
58
+ <span class="sui-toggle-slider"></span>
59
+ </label>
60
+ <label class="sui-toggle-label" for="restart_subscription_based_autoresponders"><?php esc_html_e( 'Restart Subscription based Autoresponders', Forminator::DOMAIN ); ?></label>
61
+ <?php if ( ! empty( $vars['restart_subscription_based_autoresponders_error'] ) ) : ?>
62
+ <span class="sui-error-message"><?php echo esc_html( $vars['restart_subscription_based_autoresponders_error'] ); ?></span>
63
+ <?php endif; ?>
64
+ <span class="sui-description">
65
+ <?php
66
+ esc_html_e(
67
+ 'By default, resubscribed subscribers will not restart any automated workflows, but they will receive any remaining emails. However, if you enable the Restart Subscription based Autoresponders, any sequences will be restarted. Restart Subscription based Autoresponders only affects resubscribing subscribers.',
68
+ Forminator::DOMAIN
69
+ );
70
+ ?>
71
+ </span>
72
+ </div>
73
+
74
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['consent_to_track_error'] ) ? 'sui-form-field-error' : '' ); ?>">
75
+ <label class="sui-label" for="consent_to_track"><?php esc_html_e( 'Consent to Track', Forminator::DOMAIN ); ?></label>
76
+ <select name="consent_to_track" id="consent_to_track" class="sui-select sui-form-control">
77
+ <option value="Unchanged" <?php selected( 'Unchanged', $vars['consent_to_track'] ); ?>>Unchanged</option>
78
+ <option value="Yes" <?php selected( 'Yes', $vars['consent_to_track'] ); ?>>Yes</option>
79
+ <option value="No" <?php selected( 'No', $vars['consent_to_track'] ); ?>>No</option>
80
+ </select>
81
+ <?php if ( ! empty( $vars['consent_to_track_error'] ) ) : ?>
82
+ <span class="sui-error-message"><?php echo esc_html( $vars['consent_to_track_error'] ); ?></span>
83
+ <?php endif; ?>
84
+ <span class="sui-description">
85
+ <?php
86
+ esc_html_e(
87
+ 'Whether or not the subscriber has consented to having their email opens and clicks tracked. This value applies to all subscribers with the same email address, within the same client. If an email address has no value stored for Consent to Track, it is assumed that the subscriber has given consent. You can find more information ',
88
+ Forminator::DOMAIN );
89
+ ?>
90
+ <a href="https://help.campaignmonitor.com/gdpr-faqs" target="_blank">here</a>.
91
+ </span>
92
+ </div>
93
+
94
+ <input type="hidden" name="multi_id" value="<?php echo esc_attr( $vars['multi_id'] ); ?>">
95
+ </form>
addons/pro/campaignmonitor/views/settings/setup-api-success.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <div class="integration-header">
2
+ <h3 class="sui-box-title" id="dialogTitle2">
3
+ <?php echo esc_html( sprintf( __( '%1$s Added', Forminator::DOMAIN ), 'Campaign Monitor' ) ); ?>
4
+ </h3>
5
+ <p><?php esc_html_e( 'You can now go to your forms and assign them to this integration', Forminator::DOMAIN ); ?></p>
6
+ </div>
addons/pro/campaignmonitor/views/settings/setup-api.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // defaults
3
+ $vars = array(
4
+ 'error_message' => '',
5
+ 'api_key' => '',
6
+ 'api_key_error' => '',
7
+ 'client_id' => '',
8
+ 'client_id_error' => '',
9
+ 'client_name' => '',
10
+ );
11
+ /** @var array $template_vars */
12
+ foreach ( $template_vars as $key => $val ) {
13
+ $vars[ $key ] = $val;
14
+ }
15
+
16
+ ?>
17
+ <div class="integration-header">
18
+ <h3 class="sui-box-title" id="dialogTitle2"><?php echo esc_html( sprintf( __( 'Configure %1$s API', Forminator::DOMAIN ), 'Campaign Monitor' ) ); ?></h3>
19
+ <p><?php esc_html_e( 'Setup Campaign Monitor API Access.', Forminator::DOMAIN ); ?></p>
20
+ <?php if ( ! empty( $vars['client_name'] ) ) : ?>
21
+ <span class="sui-notice sui-notice-success"><p><?php esc_html_e( 'Campaign Monitor Integrations currently connected to API Client : ', Forminator::DOMAIN ); ?>
22
+ <strong><?php echo esc_html( $vars['client_name'] ); ?></strong></p></span>
23
+ <?php endif; ?>
24
+ <?php if ( ! empty( $vars['error_message'] ) ) : ?>
25
+ <span class="sui-notice sui-notice-error"><p><?php echo esc_html( $vars['error_message'] ); ?></p></span>
26
+ <?php endif; ?>
27
+ </div>
28
+ <form>
29
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['api_key_error'] ) ? 'sui-form-field' : '' ); ?>">
30
+ <label class="sui-label"><?php esc_html_e( 'API KEY', Forminator::DOMAIN ); ?></label>
31
+ <div class="sui-field-with-icon">
32
+ <input
33
+ class="sui-form-control"
34
+ name="api_key" placeholder="<?php echo esc_attr( sprintf( __( 'Enter %1$s API Key', Forminator::DOMAIN ), 'Campaign Monitor' ) ); ?>"
35
+ value="<?php echo esc_attr( $vars['api_key'] ); ?>">
36
+ <i class="sui-icon-key" aria-hidden="true"></i>
37
+ </div>
38
+ <?php if ( ! empty( $vars['api_key_error'] ) ) : ?>
39
+ <span class="sui-error-message"><?php echo esc_html( $vars['api_key_error'] ); ?></span>
40
+ <?php endif; ?>
41
+ <span class="sui-description">
42
+ <?php esc_html_e( 'To obtain Campaign Monitor API Credentials, follow these steps :', Forminator::DOMAIN ); ?>
43
+ <ol class="instructions" id="apikey-instructions">
44
+ <li><?php echo __( 'Login to your Campaign Monitor account <a href="https://login.createsend.com/l" target="_blank">here</a>.', Forminator::DOMAIN ); //wpcs: xss ok. ?></li>
45
+ <li><?php echo __( 'Go to Account Settings, then navigate to <strong>API Keys</strong> section.', Forminator::DOMAIN ); //wpcs: xss ok. ?></li>
46
+ <li><?php echo __( 'Click on <strong>Show API Key</strong>, select and copy on the shown up value.', Forminator::DOMAIN ); //wpcs: xss ok. ?></li>
47
+ </ol>
48
+ </span>
49
+ </div>
50
+
51
+ <div class="sui-form-field <?php echo esc_attr( ! empty( $vars['client_id_error'] ) ? 'sui-form-field' : '' ); ?>">
52
+ <label class="sui-label"><?php esc_html_e( 'Client ID', Forminator::DOMAIN ); ?></label>
53
+ <input
54
+ class="sui-form-control"
55
+ name="client_id" placeholder="<?php echo esc_attr( sprintf( __( 'Enter %1$s Client ID', Forminator::DOMAIN ), 'Campaign Monitor' ) ); ?>"
56
+ value="<?php echo esc_attr( $vars['client_id'] ); ?>">
57
+ <?php if ( ! empty( $vars['client_id_error'] ) ) : ?>
58
+ <span class="sui-error-message"><?php echo esc_html( $vars['client_id_error'] ); ?></span>
59
+ <?php endif; ?>
60
+ <span class="sui-description">
61
+ <?php echo __( 'Client ID is optional, unless you are on <strong>Agency-Mode</strong>, then you can find your desired Client ID on the <strong>Account Settings</strong> > <strong>API Keys</strong>',
62
+ Forminator::DOMAIN ); //wpcs: xss ok. ?>
63
+ </span>
64
+ </div>
65
+
66
+ </form>
addons/pro/googlesheet/assets/icons/googlesheet.png ADDED
Binary file
addons/pro/googlesheet/assets/icons/googlesheet@2x.png ADDED
Binary file
addons/pro/googlesheet/assets/img/googlesheet.png ADDED
Binary file
addons/pro/googlesheet/assets/img/googlesheet@2x.png ADDED
Binary file
addons/pro/googlesheet/forminator-addon-googlesheet-exception.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Googlesheet_Exception
5
+ * Not Required but encouraged
6
+ *
7
+ * @since 1.0 Googlesheet Addon
8
+ */
9
+ class Forminator_Addon_Googlesheet_Exception extends Exception {
10
+
11
+ }
addons/pro/googlesheet/forminator-addon-googlesheet-form-hooks.php ADDED
@@ -0,0 +1,798 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Googlesheet_Form_Hooks
5
+ *
6
+ * @since 1.0 Googlesheet Addon
7
+ *
8
+ */
9
+ class Forminator_Addon_Googlesheet_Form_Hooks extends Forminator_Addon_Form_Hooks_Abstract {
10
+
11
+ /**
12
+ * Addon instance are auto available form abstract
13
+ * Its added here for development purpose,
14
+ * Auto-complete will resolve addon directly to `Googlesheet` instance instead of the abstract
15
+ * And its public properties can be exposed
16
+ *
17
+ * @since 1.0 Googlesheet Addon
18
+ * @var Forminator_Addon_Googlesheet
19
+ */
20
+ protected $addon;
21
+
22
+ /**
23
+ * Form Settings Instance
24
+ *
25
+ * @since 1.0 Googlesheet Addon
26
+ * @var Forminator_Addon_Googlesheet_Form_Settings | null
27
+ */
28
+ protected $form_settings_instance;
29
+
30
+ /**
31
+ * Forminator_Addon_Googlesheet_Form_Hooks constructor.
32
+ *
33
+ * @since 1.0 Googlesheet Addon
34
+ *
35
+ * @param Forminator_Addon_Abstract $addon
36
+ * @param $form_id
37
+ *
38
+ * @throws Forminator_Addon_Exception
39
+ */
40
+ public function __construct( Forminator_Addon_Abstract $addon, $form_id ) {
41
+ parent::__construct( $addon, $form_id );
42
+ $this->_submit_form_error_message = __( 'Googlesheet failed to process submitted data. Please check your form and try again', Forminator::DOMAIN );
43
+ }
44
+
45
+ /**
46
+ * Save status of request sent and received for each connected Googlesheet
47
+ *
48
+ * @since 1.0 Googlesheet Addon
49
+ *
50
+ * @param array $submitted_data
51
+ * @param array $form_entry_fields
52
+ *
53
+ * @return array
54
+ */
55
+ public function add_entry_fields( $submitted_data, $form_entry_fields = array() ) {
56
+
57
+ $form_id = $this->form_id;
58
+ $form_settings_instance = $this->form_settings_instance;
59
+
60
+ /**
61
+ * Filter Googlesheet submitted form data to be processed
62
+ *
63
+ * @since 1.2
64
+ *
65
+ * @param array $submitted_data
66
+ * @param array $form_entry_fields
67
+ * @param int $form_id current Form ID
68
+ * @param Forminator_Addon_Googlesheet_Form_Settings $form_settings_instance Googlesheet Addon Form Settings instance
69
+ */
70
+ $submitted_data = apply_filters(
71
+ 'forminator_addon_googlesheet_form_submitted_data',
72
+ $submitted_data,
73
+ $form_entry_fields,
74
+ $form_id,
75
+ $form_settings_instance
76
+ );
77
+
78
+ /**
79
+ * Filter current form entry fields data to be processed by Googlesheet
80
+ *
81
+ * @since 1.2
82
+ *
83
+ * @param array $form_entry_fields
84
+ * @param array $submitted_data
85
+ * @param int $form_id current Form ID
86
+ * @param Forminator_Addon_Googlesheet_Form_Settings $form_settings_instance Googlesheet Addon Form Settings instance
87
+ */
88
+ $form_entry_fields = apply_filters(
89
+ 'forminator_addon_googlesheet_form_entry_fields',
90
+ $form_entry_fields,
91
+ $submitted_data,
92
+ $form_id,
93
+ $form_settings_instance
94
+ );
95
+
96
+ forminator_addon_maybe_log( __METHOD__, $submitted_data );
97
+
98
+ $addon_setting_values = $this->form_settings_instance->get_form_settings_values();
99
+
100
+ $data = array();
101
+
102
+ /**
103
+ * Fires before create row on Googlesheet
104
+ *
105
+ * @since 1.2
106
+ *
107
+ * @param int $form_id current Form ID
108
+ * @param array $submitted_data
109
+ * @param Forminator_Addon_Googlesheet_Form_Settings $form_settings_instance Googlesheet Addon Form Settings instance
110
+ */
111
+ do_action( 'forminator_addon_googlesheet_before_create_row', $form_id, $submitted_data, $form_settings_instance );
112
+
113
+ foreach ( $addon_setting_values as $key => $addon_setting_value ) {
114
+ // save it on entry field, with name `status-$MULTI_ID`, and value is the return result on sending data to Googlesheet
115
+ if ( $form_settings_instance->is_multi_form_settings_complete( $key ) ) {
116
+ // exec only on completed connection
117
+ $data[] = array(
118
+ 'name' => 'status-' . $key,
119
+ 'value' => $this->get_status_on_create_row( $key, $submitted_data, $addon_setting_value, $form_entry_fields ),
120
+ );
121
+ }
122
+
123
+ }
124
+
125
+ $entry_fields = $data;
126
+ /**
127
+ * Filter Googlesheet entry fields to be saved to entry model
128
+ *
129
+ * @since 1.2
130
+ *
131
+ * @param array $entry_fields
132
+ * @param int $form_id current Form ID
133
+ * @param array $submitted_data
134
+ * @param array $form_entry_fields
135
+ * @param Forminator_Addon_Googlesheet_Form_Settings $form_settings_instance Googlesheet Addon Form Settings instance
136
+ */
137
+ $data = apply_filters(
138
+ 'forminator_addon_googlesheet_entry_fields',
139
+ $entry_fields,
140
+ $form_id,
141
+ $submitted_data,
142
+ $form_entry_fields,
143
+ $form_settings_instance
144
+ );
145
+
146
+ return $data;
147
+
148
+ }
149
+
150
+ /**
151
+ * Get status on create Googlesheet row
152
+ *
153
+ * @since 1.0 Googlesheet Addon
154
+ *
155
+ * @param string $connection_id
156
+ * @param array $submitted_data
157
+ * @param array $connection_settings
158
+ * @param array $form_entry_fields
159
+ *
160
+ * @return array `is_sent` true means its success send data to Googlesheet, false otherwise
161
+ */
162
+ public function get_status_on_create_row( $connection_id, $submitted_data, $connection_settings, $form_entry_fields ) {
163
+ // initialize as null
164
+ $api = null;
165
+
166
+ $form_id = $this->form_id;
167
+ $form_settings_instance = $this->form_settings_instance;
168
+
169
+ try {
170
+ /**
171
+ * Fires before checking and modifying headers row of googlesheet
172
+ *
173
+ * @since 1.2
174
+ *
175
+ * @param array $connection_settings
176
+ * @param int $form_id current Form ID
177
+ * @param array $submitted_data
178
+ * @param array $form_entry_fields
179
+ * @param Forminator_Addon_Googlesheet_Form_Settings $form_settings_instance Googlesheet Addon Form Settings instance
180
+ */
181
+ do_action( 'forminator_addon_googlesheet_before_prepare_sheet_headers', $connection_settings, $form_id, $submitted_data, $form_entry_fields, $form_settings_instance );
182
+
183
+ // prepare headers
184
+ $header_fields = $this->get_sheet_headers( $connection_settings['file_id'] );
185
+
186
+ /**
187
+ * Filter Sheet headers fields that will be used to map the entrt rows
188
+ *
189
+ * @since 1.2
190
+ *
191
+ * @param array $header_fields sheet headers
192
+ * @param array $connection_settings
193
+ * @param int $form_id current Form ID
194
+ * @param array $submitted_data
195
+ * @param array $form_entry_fields
196
+ * @param Forminator_Addon_Googlesheet_Form_Settings $form_settings_instance Googlesheet Addon Form Settings instance
197
+ */
198
+ $header_fields = apply_filters(
199
+ 'forminator_addon_googlesheet_sheet_headers',
200
+ $header_fields,
201
+ $connection_settings,
202
+ $form_id,
203
+ $submitted_data,
204
+ $form_entry_fields,
205
+ $form_settings_instance
206
+ );
207
+
208
+ /**
209
+ * Fires after headers row of googlesheet checked and modified
210
+ *
211
+ * @since 1.2
212
+ *
213
+ * @param array $header_fields sheet headers
214
+ * @param array $connection_settings
215
+ * @param int $form_id current Form ID
216
+ * @param array $submitted_data
217
+ * @param array $form_entry_fields
218
+ * @param Forminator_Addon_Googlesheet_Form_Settings $form_settings_instance Googlesheet Addon Form Settings instance
219
+ */
220
+ do_action( 'forminator_addon_googlesheet_after_prepare_sheet_headers', $header_fields, $connection_settings, $form_id, $submitted_data, $form_entry_fields, $form_settings_instance );
221
+
222
+ // all avail fields on library
223
+ $fields = forminator_fields_to_array();
224
+ $field_types = array_keys( $fields );
225
+
226
+ $values = array();
227
+ foreach ( $header_fields as $element_id => $header_field ) {
228
+ $field_type = '';
229
+
230
+ foreach ( $field_types as $type ) {
231
+ if ( false !== stripos( $element_id, $type . '-' ) ) {
232
+ $field_type = $type;
233
+ }
234
+ }
235
+
236
+ $meta_value = array();
237
+ // take from entry fields (to be saved)
238
+ if ( isset( $form_entry_fields[ $element_id ] ) ) {
239
+ $meta_value = $form_entry_fields[ $element_id ];
240
+ } elseif ( isset( $submitted_data[ $element_id ] ) ) {
241
+ // fallback to submitted_data
242
+ $meta_value = $submitted_data[ $element_id ];
243
+ }
244
+ $form_value = Forminator_Form_Entry_Model::meta_value_to_string( $field_type, $meta_value, false );
245
+
246
+ $value = new Google_Service_Sheets_ExtendedValue();
247
+ $cell_data = new Google_Service_Sheets_CellData();
248
+ $value->setStringValue( $form_value );
249
+ $cell_data->setUserEnteredValue( $value );
250
+ $values[] = $cell_data;
251
+ }
252
+
253
+ // Build the RowData
254
+ $row_data = new Google_Service_Sheets_RowData();
255
+ $row_data->setValues( $values );
256
+
257
+ // Prepare the request
258
+ $append_request = new Google_Service_Sheets_AppendCellsRequest();
259
+ $append_request->setSheetId( 0 );
260
+ $append_request->setRows( $row_data );
261
+ $append_request->setFields( 'userEnteredValue' );
262
+
263
+ // Set the request
264
+ $request = new Google_Service_Sheets_Request();
265
+ $request->setAppendCells( $append_request );
266
+ // Add the request to the requests array
267
+ $requests = array();
268
+ $requests[] = $request;
269
+
270
+ // Prepare the update
271
+ $batch_update_request = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest(
272
+ array(
273
+
274
+ 'requests' => $requests,
275
+ )
276
+ );
277
+
278
+ $google_client = $this->addon->get_google_client();
279
+ $google_client->setAccessToken( $this->addon->get_client_access_token() );
280
+ $spreadsheet_service = new Google_Service_Sheets( $google_client );
281
+ $spreadsheet_service->spreadsheets->batchUpdate( $connection_settings['file_id'], $batch_update_request );
282
+
283
+ if ( $google_client->getAccessToken() !== $this->addon->get_client_access_token() ) {
284
+ $this->addon->update_client_access_token( $google_client->getAccessToken() );
285
+ }
286
+ forminator_addon_maybe_log( __METHOD__, 'Success Send Data' );
287
+
288
+ return array(
289
+ 'is_sent' => true,
290
+ 'connection_name' => $connection_settings['name'],
291
+ 'description' => __( 'Successfully send data to Googlesheet', Forminator::DOMAIN ),
292
+ );
293
+
294
+ } catch ( Google_Exception $e ) {
295
+ forminator_addon_maybe_log( __METHOD__, 'Failed to Send to Googlesheet' );
296
+
297
+ return array(
298
+ 'is_sent' => false,
299
+ 'description' => $e->getMessage(),
300
+ 'connection_name' => $connection_settings['name'],
301
+ );
302
+ } catch ( Forminator_Addon_Googlesheet_Exception $e ) {
303
+ forminator_addon_maybe_log( __METHOD__, 'Failed to Send to Googlesheet' );
304
+
305
+ return array(
306
+ 'is_sent' => false,
307
+ 'description' => $e->getMessage(),
308
+ 'connection_name' => $connection_settings['name'],
309
+ );
310
+ }
311
+ }
312
+
313
+ /**
314
+ * Prepare headers of spreadsheet
315
+ *
316
+ * @param $file_id
317
+ *
318
+ * @return array
319
+ * @throws Forminator_Addon_Googlesheet_Exception
320
+ */
321
+ public function get_sheet_headers( $file_id ) {
322
+ $form_fields = $this->form_settings_instance->get_form_fields();
323
+
324
+ $google_client = $this->addon->get_google_client();
325
+ $google_client->setAccessToken( $this->addon->get_client_access_token() );
326
+
327
+ $spreadsheet_service = new Google_Service_Sheets( $google_client );
328
+ $spreadsheet = $spreadsheet_service->spreadsheets->get( $file_id );
329
+ $sheets = $spreadsheet->getSheets();
330
+
331
+ if ( ! isset( $sheets[0] ) || ! isset( $sheets[0]->properties ) ) {
332
+ throw new Forminator_Addon_Googlesheet_Exception( __( 'No sheet found', Forminator::DOMAIN ) );
333
+ }
334
+ $sheet_id = $sheets[0]->properties->sheetId;
335
+
336
+ if ( ! isset( $sheets[0]->properties->title ) || empty( $sheets[0]->properties->title ) ) {
337
+ throw new Forminator_Addon_Googlesheet_Exception( __( 'Sheet title not found', Forminator::DOMAIN ) );
338
+ }
339
+
340
+ if ( ! isset( $sheets[0]->properties->gridProperties ) || ! isset( $sheets[0]->properties->gridProperties->columnCount ) ) {
341
+ throw new Forminator_Addon_Googlesheet_Exception( __( 'Failed to get column count of the sheet', Forminator::DOMAIN ) );
342
+ }
343
+
344
+ $sheet_title = $sheets[0]->properties->title;
345
+ $sheet_column_count = $sheets[0]->properties->gridProperties->columnCount;
346
+
347
+ $headers_range = $sheet_title . '!' . '1:1';
348
+ $header_rows = $spreadsheet_service->spreadsheets_values->get(
349
+ $spreadsheet->getSpreadsheetId(),
350
+ $headers_range
351
+ );
352
+
353
+ $values = $header_rows->getValues();
354
+
355
+ forminator_addon_maybe_log( __METHOD__, '$sheet_column_count', $sheet_column_count );
356
+
357
+ $header_fields = array();
358
+
359
+ $column_number = 1;
360
+ $columns_filled = 0;
361
+ if ( isset( $values[0] ) && is_array( $values[0] ) ) {
362
+ foreach ( $values[0] as $value ) {
363
+ $key_range = $sheet_title . '!' . self::column_number_to_letter( $column_number ) . '1';
364
+ // forminator header field format = 'FIELD-label|field-id'
365
+ $header_values = explode( '|', $value );
366
+ $element_id = end( $header_values );
367
+ $header_fields[ $element_id ] = array(
368
+ 'range' => $key_range,
369
+ 'value' => $value,
370
+ );
371
+ $column_number ++;
372
+ $columns_filled ++;
373
+ }
374
+ }
375
+
376
+ $new_column_count = 0;
377
+ $update_bodies = array();
378
+ foreach ( $form_fields as $form_field ) {
379
+ $element_id = $form_field['element_id'];
380
+ $expected_header_value = $form_field['field_label'] . '|' . $element_id;
381
+ if ( ! in_array( $element_id, array_keys( $header_fields ), true ) ) {
382
+ //add
383
+ $new_range = $sheet_title . '!' . self::column_number_to_letter( $column_number ) . '1';
384
+
385
+ // update headers map
386
+ $header_fields[ $element_id ] = array(
387
+ 'range' => $new_range,
388
+ 'value' => $expected_header_value,
389
+ );
390
+
391
+ // increment for next usage
392
+ $column_number ++;
393
+ $update_body = new Google_Service_Sheets_ValueRange();
394
+ $update_body->setRange( $new_range );
395
+ $update_body->setValues( array( array( $expected_header_value ) ) );
396
+ $update_bodies[] = $update_body;
397
+ $new_column_count ++;
398
+ } else {
399
+ $header_field = $header_fields[ $element_id ];
400
+ if ( $expected_header_value !== $header_field['value'] ) {
401
+ // update headers map
402
+ $header_fields[ $element_id ]['value'] = $expected_header_value;
403
+
404
+ // update sheet
405
+ $update_body = new Google_Service_Sheets_ValueRange();
406
+ $update_body->setRange( $header_field['range'] );
407
+ $update_body->setValues( array( array( $expected_header_value ) ) );
408
+ $update_bodies[] = $update_body;
409
+ }
410
+ }
411
+ }
412
+
413
+ //calc column to be added
414
+ $total_column_needed = $columns_filled + $new_column_count;
415
+ $new_column_needed = $total_column_needed - $sheet_column_count;
416
+ if ( $new_column_needed > 0 ) {
417
+ $dimension_range = new Google_Service_Sheets_DimensionRange();
418
+ $dimension_range->setSheetId( 0 );
419
+ $dimension_range->setDimension( 'COLUMNS' );
420
+ $dimension_range->setStartIndex( $sheet_column_count );
421
+ $dimension_range->setEndIndex( $total_column_needed );
422
+
423
+ $insert_dimension = new Google_Service_Sheets_InsertDimensionRequest();
424
+ $insert_dimension->setRange( $dimension_range );
425
+ $insert_dimension->setInheritFromBefore( true );
426
+
427
+ $request = new Google_Service_Sheets_Request();
428
+ $request->setInsertDimension( $insert_dimension );
429
+
430
+ $request_body = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest();
431
+ $request_body->setRequests( array( $request ) );
432
+
433
+ $spreadsheet_service->spreadsheets->batchUpdate( $file_id, $request_body );
434
+ }
435
+ if ( ! empty( $update_bodies ) ) {
436
+ $request_body = new Google_Service_Sheets_BatchUpdateValuesRequest();
437
+ $request_body->setData( $update_bodies );
438
+ $request_body->setValueInputOption( 'RAW' );
439
+ $spreadsheet_service->spreadsheets_values->batchUpdate( $file_id, $request_body );
440
+ }
441
+
442
+ $grid_properties = new Google_Service_Sheets_GridProperties();
443
+ $grid_properties->setFrozenRowCount( 1 );
444
+
445
+ $sheet_properties = new Google_Service_Sheets_SheetProperties();
446
+ $sheet_properties->setSheetId( 0 );
447
+ $sheet_properties->setGridProperties( $grid_properties );
448
+
449
+ $update_properties = new Google_Service_Sheets_UpdateSheetPropertiesRequest();
450
+ $update_properties->setProperties( $sheet_properties );
451
+ $update_properties->setFields( 'gridProperties(frozenRowCount)' );
452
+
453
+ $request = new Google_Service_Sheets_Request();
454
+ $request->setUpdateSheetProperties( $update_properties );
455
+
456
+ $request_body = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest();
457
+ $request_body->setRequests( array( $request ) );
458
+
459
+ $spreadsheet_service->spreadsheets->batchUpdate( $file_id, $request_body );
460
+
461
+ if ( $google_client->getAccessToken() !== $this->addon->get_client_access_token() ) {
462
+ $this->addon->update_client_access_token( $google_client->getAccessToken() );
463
+ }
464
+
465
+ return $header_fields;
466
+
467
+ }
468
+
469
+ /**
470
+ * It wil add new row on entry table of submission page, with couple of subentries
471
+ * subentries included are defined in @see Forminator_Addon_Googlesheet_Form_Hooks::get_additional_entry_item()
472
+ *
473
+ * @since 1.0 Googlesheet Addon
474
+ *
475
+ * @param Forminator_Form_Entry_Model $entry_model
476
+ * @param $addon_meta_data
477
+ *
478
+ * @return array
479
+ */
480
+ public function on_render_entry( Forminator_Form_Entry_Model $entry_model, $addon_meta_data ) {
481
+
482
+ $form_id = $this->form_id;
483
+ $form_settings_instance = $this->form_settings_instance;
484
+
485
+ /**
486
+ *
487
+ * Filter Googlesheet metadata that previously saved on db to be processed
488
+ *
489
+ * @since 1.2
490
+ *
491
+ * @param array $addon_meta_data
492
+ * @param int $form_id current Form ID
493
+ * @param Forminator_Addon_Googlesheet_Form_Settings $form_settings_instance Googlesheet Addon Form Settings instance
494
+ */
495
+ $addon_meta_data = apply_filters(
496
+ 'forminator_addon_googlesheet_metadata',
497
+ $addon_meta_data,
498
+ $form_id,
499
+ $form_settings_instance
500
+ );
501
+
502
+
503
+ $addon_meta_datas = $addon_meta_data;
504
+ if ( ! isset( $addon_meta_data[0] ) || ! is_array( $addon_meta_data[0] ) ) {
505
+ return array();
506
+ }
507
+
508
+ return $this->on_render_entry_multi_connection( $addon_meta_datas );
509
+
510
+ }
511
+
512
+ /**
513
+ * Loop through addon meta data on multiple Googlesheet setup(s)
514
+ *
515
+ * @since 1.0 Googlesheet Addon
516
+ *
517
+ * @param $addon_meta_datas
518
+ *
519
+ * @return array
520
+ */
521
+ private function on_render_entry_multi_connection( $addon_meta_datas ) {
522
+ $additional_entry_item = array();
523
+ foreach ( $addon_meta_datas as $addon_meta_data ) {
524
+ $additional_entry_item[] = $this->get_additional_entry_item( $addon_meta_data );
525
+ }
526
+
527
+ return $additional_entry_item;
528
+
529
+ }
530
+
531
+ /**
532
+ * Format additional entry item as label and value arrays
533
+ *
534
+ * - Integration Name : its defined by user when they adding Googlesheet integration on their form
535
+ * - Sent To Googlesheet : will be Yes/No value, that indicates whether sending data to Googlesheet API was successful
536
+ * - Info : Text that are generated by addon when building and sending data to Googlesheet @see Forminator_Addon_Googlesheet_Form_Hooks::add_entry_fields()
537
+ *
538
+ * @param $addon_meta_data
539
+ *
540
+ * @since 1.0 Googlesheet Addon
541
+ * @return array
542
+ */
543
+ private function get_additional_entry_item( $addon_meta_data ) {
544
+
545
+ if ( ! isset( $addon_meta_data['value'] ) || ! is_array( $addon_meta_data['value'] ) ) {
546
+ return array();
547
+ }
548
+ $status = $addon_meta_data['value'];
549
+ $additional_entry_item = array(
550
+ 'label' => __( 'Google Sheets Integration', Forminator::DOMAIN ),
551
+ 'value' => '',
552
+ );
553
+
554
+
555
+ $sub_entries = array();
556
+ if ( isset( $status['connection_name'] ) ) {
557
+ $sub_entries[] = array(
558
+ 'label' => __( 'Integration Name', Forminator::DOMAIN ),
559
+ 'value' => $status['connection_name'],
560
+ );
561
+ }
562
+
563
+ if ( isset( $status['is_sent'] ) ) {
564
+ $is_sent = true === $status['is_sent'] ? __( 'Yes', Forminator::DOMAIN ) : __( 'No', Forminator::DOMAIN );
565
+ $sub_entries[] = array(
566
+ 'label' => __( 'Sent To Google Sheets', Forminator::DOMAIN ),
567
+ 'value' => $is_sent,
568
+ );
569
+ }
570
+
571
+ if ( isset( $status['description'] ) ) {
572
+ $sub_entries[] = array(
573
+ 'label' => __( 'Info', Forminator::DOMAIN ),
574
+ 'value' => $status['description'],
575
+ );
576
+ }
577
+
578
+ $additional_entry_item['sub_entries'] = $sub_entries;
579
+
580
+ // return single array
581
+ return $additional_entry_item;
582
+ }
583
+
584
+ /**
585
+ * Googlesheet will add a column on the title/header row
586
+ * its called `Googlesheet Info` which can be translated on forminator lang
587
+ *
588
+ * @since 1.0 Googlesheet Addon
589
+ * @return array
590
+ */
591
+ public function on_export_render_title_row() {
592
+
593
+ $export_headers = array(
594
+ 'info' => __( 'Google Sheets Info', Forminator::DOMAIN ),
595
+ );
596
+
597
+ $form_id = $this->form_id;
598
+ $form_settings_instance = $this->form_settings_instance;
599
+
600
+ /**
601
+ * Filter Googlesheet headers on export file
602
+ *
603
+ * @since 1.2
604
+ *
605
+ * @param array $export_headers headers to be displayed on export file
606
+ * @param int $form_id current Form ID
607
+ * @param Forminator_Addon_Googlesheet_Form_Settings $form_settings_instance Googlesheet Addon Form Settings instance
608
+ */
609
+ $export_headers = apply_filters(
610
+ 'forminator_addon_googlesheet_export_headers',
611
+ $export_headers,
612
+ $form_id,
613
+ $form_settings_instance
614
+ );
615
+
616
+ return $export_headers;
617
+ }
618
+
619
+ /**
620
+ * Googlesheet will add a column that give user information whether sending data to Googlesheet successfully or not
621
+ * It will only add one column even its multiple connection, every connection will be separated by comma
622
+ *
623
+ * @since 1.0 Googlesheet Addon
624
+ *
625
+ * @param Forminator_Form_Entry_Model $entry_model
626
+ * @param $addon_meta_data
627
+ *
628
+ * @return array
629
+ */
630
+ public function on_export_render_entry( Forminator_Form_Entry_Model $entry_model, $addon_meta_data ) {
631
+
632
+ $form_id = $this->form_id;
633
+ $form_settings_instance = $this->form_settings_instance;
634
+
635
+ /**
636
+ *
637
+ * Filter Googlesheet metadata that previously saved on db to be processed
638
+ *
639
+ * @since 1.2
640
+ *
641
+ * @param array $addon_meta_data
642
+ * @param int $form_id current Form ID
643
+ * @param Forminator_Addon_Googlesheet_Form_Settings $form_settings_instance Googlesheet Addon Form Settings instance
644
+ */
645
+ $addon_meta_data = apply_filters(
646
+ 'forminator_addon_googlesheet_metadata',
647
+ $addon_meta_data,
648
+ $form_id,
649
+ $form_settings_instance
650
+ );
651
+
652
+ $export_columns = array(
653
+ 'info' => $this->get_from_addon_meta_data( $addon_meta_data, 'description', '' ),
654
+ );
655
+
656
+ /**
657
+ * Filter Googlesheet columns to be displayed on export submissions
658
+ *
659
+ * @since 1.2
660
+ *
661
+ * @param array $export_columns column to be exported
662
+ * @param int $form_id current Form ID
663
+ * @param Forminator_Form_Entry_Model $entry_model Form Entry Model
664
+ * @param array $addon_meta_data meta data saved by addon on entry fields
665
+ * @param Forminator_Addon_Googlesheet_Form_Settings $form_settings_instance Googlesheet Addon Form Settings instance
666
+ */
667
+ $export_columns = apply_filters(
668
+ 'forminator_addon_googlesheet_export_columns',
669
+ $export_columns,
670
+ $form_id,
671
+ $entry_model,
672
+ $addon_meta_data,
673
+ $form_settings_instance
674
+ );
675
+
676
+ return $export_columns;
677
+ }
678
+
679
+ /**
680
+ * Get Addon meta data, will be recursive if meta data is multiple because of multiple connection added
681
+ *
682
+ * @since 1.0 Googlesheet Addon
683
+ *
684
+ * @param $addon_meta_data
685
+ * @param $key
686
+ * @param string $default
687
+ *
688
+ * @return string
689
+ */
690
+ private function get_from_addon_meta_data( $addon_meta_data, $key, $default = '' ) {
691
+ $addon_meta_datas = $addon_meta_data;
692
+ if ( ! isset( $addon_meta_data[0] ) || ! is_array( $addon_meta_data[0] ) ) {
693
+ return $default;
694
+ }
695
+
696
+ $addon_meta_data = $addon_meta_data[0];
697
+
698
+ // make sure its `status`, because we only add this
699
+ if ( 'status' !== $addon_meta_data['name'] ) {
700
+ if ( stripos( $addon_meta_data['name'], 'status-' ) === 0 ) {
701
+ $meta_data = array();
702
+ foreach ( $addon_meta_datas as $addon_meta_data ) {
703
+ // make it like single value so it will be processed like single meta data
704
+ $addon_meta_data['name'] = 'status';
705
+
706
+ // add it on an array for next recursive process
707
+ $meta_data[] = $this->get_from_addon_meta_data( array( $addon_meta_data ), $key, $default );
708
+ }
709
+
710
+ return implode( ', ', $meta_data );
711
+ }
712
+
713
+ return $default;
714
+
715
+ }
716
+
717
+ if ( ! isset( $addon_meta_data['value'] ) || ! is_array( $addon_meta_data['value'] ) ) {
718
+ return $default;
719
+ }
720
+ $status = $addon_meta_data['value'];
721
+ if ( isset( $status[ $key ] ) ) {
722
+ $connection_name = '';
723
+ if ( 'connection_name' !== $key ) {
724
+ if ( isset( $status['connection_name'] ) ) {
725
+ $connection_name = '[' . $status['connection_name'] . '] ';
726
+ }
727
+ }
728
+
729
+ return $connection_name . $status[ $key ];
730
+ }
731
+
732
+ return $default;
733
+ }
734
+
735
+ /**
736
+ * Convert column number to letter format for spreadsheet
737
+ *
738
+ * start from 1
739
+ *
740
+ * @param $int
741
+ *
742
+ * @return string
743
+ */
744
+ public static function column_number_to_letter( $int ) {
745
+ $chars = array(
746
+ 'A',
747
+ 'B',
748
+ 'C',
749
+ 'D',
750
+ 'E',
751
+ 'F',
752
+ 'G',
753
+ 'H',
754
+ 'I',
755
+ 'J',
756
+ 'K',
757
+ 'L',
758
+ 'M',
759
+ 'N',
760
+ 'O',
761
+ 'P',
762
+ 'Q',
763
+ 'R',
764
+ 'S',
765
+ 'T',
766
+ 'U',
767
+ 'V',
768
+ 'W',
769
+ 'X',
770
+ 'Y',
771
+ 'Z',
772
+ );
773
+
774
+ /**
775
+ * 1 = A
776
+ * 27 = AA
777
+ */
778
+ $base = 26;
779
+ $temp_number = $int;
780
+ $output_column_name = '';
781
+ while ( $temp_number > 0 ) {
782
+ $position = $temp_number % $base;
783
+ if ( 0 === $position ) {
784
+ $output_column_name = 'Z' . $output_column_name;
785
+ } else {
786
+ if ( $position > 0 ) {
787
+ $output_column_name = $chars[ $position - 1 ] . $output_column_name;
788
+ } else {
789
+ $output_column_name = $chars[0] . $output_column_name;
790
+ }
791
+ }
792
+ $temp_number --;
793
+ $temp_number = floor( $temp_number / $base );
794
+ }
795
+
796
+ return $output_column_name;
797
+ }
798
+ }
addons/pro/googlesheet/forminator-addon-googlesheet-form-settings-exception.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class Forminator_Addon_Googlesheet_Form_Settings_Exception
5
+ * Wrapper of Form Settings Googlesheet Exception
6
+ *
7
+ * @since 1.0 Googlesheet Addon
8
+ */
9
+ class Forminator_Addon_Googlesheet_Form_Settings_Exception extends Forminator_Addon_Googlesheet_Exception {
10
+
11
+ /**
12
+ * Holder of input exceptions
13
+ *
14
+ * @since 1.0 Googlesheet Addon
15
+ * @var array
16
+ */
17
+ protected $input_exceptions = array();
18
+
19
+ /**
20
+ * Forminator_Addon_Googlesheet_Form_Settings_Exception constructor.
21
+ *
22
+ * Useful if input_id is needed for later.
23
+ * If no input_id needed, use @see Forminator_Addon_Googlesheet_Exception
24
+ *
25
+ * @since 1.0 Googlesheet Addon
26
+ *
27
+ * @param string $message
28
+ * @param string $input_id
29
+ */
30
+ public function __construct( $message = '', $input_id = '' ) {
31
+ parent::__construct( $message, 0 );
32
+ if ( ! empty( $input_id ) ) {
33
+ $this->add_input_exception( $message, $input_id );
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Set exception message for an input
39
+ *
40
+ * @since 1.0 Googlesheet Addon
41
+ *
42
+ * @param $message
43
+ * @param $input_id
44
+ */
45
+ public function add_input_exception( $message, $input_id ) {
46
+ $this->input_exceptions[ $input_id ] = $message;
47
+ }
48
+
49
+ /**
50
+ * Get all input exceptions
51
+ *
52
+ * @since 1.0 Googlesheet Addon
53
+ * @return array
54
+ */
55
+ public function get_input_exceptions() {
56
+ return $this->input_exceptions;
57
+ }
58
+
59
+ /**
60
+ * Check if there is input_exceptions_is_available
61
+ *
62
+ * @since 1.0 Googlesheet Addon
63
+ * @return bool
64
+ */
65
+ public function input_exceptions_is_available() {
66
+ return count( $this->input_exceptions ) > 0;
67
+ }
68
+
69
+ /**
70
+ * Check if there is input_exception for $input_id
71
+ *
72
+ * @since 1.0 Googlesheet Addon
73
+ *
74
+ * @param $input_id
75
+ *
76
+ * @return bool
77
+ */
78
+ public function input_exception_is_available( $input_id ) {
79
+ return isset( $this->input_exceptions[ $input_id ] );
80
+ }
81
+ }
addons/pro/googlesheet/forminator-addon-googlesheet-form-settings.php ADDED
@@ -0,0 +1,402 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once dirname( __FILE__ ) . '/forminator-addon-googlesheet-form-settings-exception.php';
4
+
5
+ /**
6
+ * Class Forminator_Addon_Googlesheet_Form_Settings
7
+ * Handle how form settings displayed and saved
8
+ *
9
+ * @since 1.0 Googlesheet Addon
10
+ */
11
+ class Forminator_Addon_Googlesheet_Form_Settings extends Forminator_Addon_Form_Settings_Abstract {
12
+
13
+ /**
14
+ * @var Forminator_Addon_Googlesheet
15
+ * @since 1.0 Googlesheet Addon
16
+ */
17
+ protected $addon;
18
+
19
+ /**
20
+ * Forminator_Addon_Googlesheet_Form_Settings constructor.
21
+ *
22
+ * @since 1.0 Googlesheet Addon
23
+ *
24
+ * @param Forminator_Addon_Abstract $addon
25
+ * @param $form_id
26
+ *
27
+ * @throws Forminator_Addon_Exception
28
+ */
29
+ public function __construct( Forminator_Addon_Abstract $addon, $form_id ) {
30
+ parent::__construct( $addon, $form_id );
31
+
32
+ $this->_update_form_settings_error_message = __(
33
+ 'Sorry, we are failed to update settings for this form, please check your form and input then try again',
34
+ Forminator::DOMAIN
35
+ );
36
+ }
37
+
38
+ /**
39
+ * Googlesheet Form Settings wizard
40
+ *
41
+ * @since 1.0 Googlesheet Addon
42
+ * @return array
43
+ */
44
+ public function form_settings_wizards() {
45
+ // numerical array steps
46
+ return array(
47
+ array(
48
+ 'callback' => array( $this, 'pick_name' ),
49
+ 'is_completed' => array( $this, 'pick_name_is_completed' ),
50
+ ),
51
+ array(
52
+ 'callback' => array( $this, 'setup_sheet' ),
53
+ 'is_completed' => array( $this, 'setup_sheet_is_completed' ),
54
+ ),
55
+ );
56
+ }
57
+
58
+ /**
59
+ * Setup Connection Name
60
+ *
61
+ * @since 1.0 Googlesheet Addon
62
+ *
63
+ * @param $submitted_data
64
+ *
65
+ * @return array
66
+ */
67
+ public function pick_name( $submitted_data ) {
68
+ $template = forminator_addon_googlesheet_dir() . 'views/form-settings/pick-name.php';
69
+
70
+ $multi_id = $this->generate_multi_id();
71
+ if ( isset( $submitted_data['multi_id'] ) ) {
72
+ $multi_id = $submitted_data['multi_id'];
73
+ }
74
+
75
+ $template_params = array(
76
+ 'name' => $this->get_multi_id_form_settings_value( $multi_id, 'name', '' ),
77
+ 'file_id' => $this->get_multi_id_form_settings_value( $multi_id, 'file_id', '' ),
78
+ 'name_error' => '',
79
+ 'multi_id' => $multi_id,
80
+ );
81
+
82
+ unset( $submitted_data['multi_id'] );
83
+
84
+ $is_submit = ! empty( $submitted_data );
85
+ $has_errors = false;
86
+ if ( $is_submit ) {
87
+ $name = isset( $submitted_data['name'] ) ? $submitted_data['name'] : '';
88
+ $template_params['name'] = $name;
89
+
90
+ try {
91
+ if ( empty( $name ) ) {
92
+ throw new Forminator_Addon_Googlesheet_Exception( __( 'Please pick valid name' ) );
93
+ }
94
+
95
+ $time_added = $this->get_multi_id_form_settings_value( $multi_id, 'time_added', time() );
96
+ $this->save_multi_id_form_setting_values(
97
+ $multi_id,
98
+ array(
99
+ 'name' => $name,
100
+ 'time_added' => $time_added,
101
+ )
102
+ );
103
+
104
+ } catch ( Forminator_Addon_Googlesheet_Exception $e ) {
105
+ $template_params['name_error'] = $e->getMessage();
106
+ $has_errors = true;
107
+ }
108
+ }
109
+
110
+ $buttons = array();
111
+ if ( $this->pick_name_is_completed( array( 'multi_id' => $multi_id ) ) ) {
112
+ $buttons['disconnect']['markup'] = Forminator_Addon_Abstract::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ),
113
+ 'sui-button-ghost sui-tooltip sui-tooltip-top-center forminator-addon-form-disconnect',
114
+ esc_html__( 'Disconnect this Google Sheets Integration from this Form.', Forminator::DOMAIN )
115
+ );
116
+ }
117
+
118
+ $buttons['next']['markup'] = '<div class="sui-actions-right">' .
119
+ Forminator_Addon_Abstract::get_button_markup( esc_html__( 'NEXT', Forminator::DOMAIN ), 'forminator-addon-next' ) .
120
+ '</div>';
121
+
122
+ return array(
123
+ 'html' => Forminator_Addon_Abstract::get_template( $template, $template_params ),
124
+ 'buttons' => $buttons,
125
+ 'redirect' => false,
126
+ 'has_errors' => $has_errors,
127
+ );
128
+ }
129
+
130
+ /**
131
+ * Check if pick name step completed
132
+ *
133
+ * @since 1.0 Googlesheet Addon
134
+ *
135
+ * @param $submitted_data
136
+ *
137
+ * @return bool
138
+ */
139
+ public function pick_name_is_completed( $submitted_data ) {
140
+ $multi_id = '';
141
+ if ( isset( $submitted_data['multi_id'] ) ) {
142
+ $multi_id = $submitted_data['multi_id'];
143
+ }
144
+
145
+ if ( empty( $multi_id ) ) {
146
+ return false;
147
+ }
148
+
149
+ $name = $this->get_multi_id_form_settings_value( $multi_id, 'name', '' );
150
+
151
+ if ( empty( $name ) ) {
152
+ return false;
153
+ }
154
+
155
+ return true;
156
+ }
157
+
158
+ /**
159
+ * Setup Contact List
160
+ *
161
+ * @since 1.0 Googlesheet Addon
162
+ *
163
+ * @param $submitted_data
164
+ *
165
+ * @return array
166
+ */
167
+ public function setup_sheet( $submitted_data ) {
168
+ $template = forminator_addon_googlesheet_dir() . 'views/form-settings/setup-sheet.php';
169
+
170
+ if ( ! isset( $submitted_data['multi_id'] ) ) {
171
+ return $this->get_force_closed_wizard( __( 'Please pick valid connection', Forminator::DOMAIN ) );
172
+ }
173
+
174
+ $multi_id = $submitted_data['multi_id'];
175
+ unset( $submitted_data['multi_id'] );
176
+
177
+ $template_params = array(
178
+ 'folder_id' => $this->get_multi_id_form_settings_value( $multi_id, 'folder_id', '' ),
179
+ 'file_name' => $this->get_multi_id_form_settings_value( $multi_id, 'file_name', '' ),
180
+ 'spreadsheet_id' => $this->get_multi_id_form_settings_value( $multi_id, 'spreadsheet_id', '' ),
181
+ 'file_id' => $this->get_multi_id_form_settings_value( $multi_id, 'file_id', '' ),
182
+ 'error_message' => '',
183
+ 'multi_id' => $multi_id,
184
+ );
185
+
186
+
187
+ $is_submit = ! empty( $submitted_data );
188
+ $has_errors = false;
189
+ $notification = array();
190
+ $is_close = false;
191
+
192
+ if ( $is_submit ) {
193
+ $folder_id = isset( $submitted_data['folder_id'] ) ? $submitted_data['folder_id'] : '';
194
+ $template_params['folder_id'] = $folder_id;
195
+ $file_name = isset( $submitted_data['file_name'] ) ? $submitted_data['file_name'] : '';
196
+ $template_params['file_name'] = $file_name;
197
+
198
+ try {
199
+ $input_exceptions = new Forminator_Addon_Googlesheet_Form_Settings_Exception();
200
+ if ( empty( $file_name ) ) {
201
+ $input_exceptions->add_input_exception( __( 'Please put valid spread sheet name', Forminator::DOMAIN ), 'file_name_error' );
202
+ }
203
+
204
+ $google_client = $this->addon->get_google_client();
205
+ $google_client->setAccessToken( $this->addon->get_client_access_token() );
206
+
207
+
208
+ if ( ! empty( $folder_id ) ) {
209
+ $drive = new Google_Service_Drive( $google_client );
210
+ try {
211
+ $folder = $drive->files->get( $folder_id );
212
+
213
+ // its from API var
214
+ // phpcs:ignore WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
215
+ if ( Forminator_Addon_Googlesheet::MIME_TYPE_GOOGLE_DRIVE_FOLDER !== $folder->mimeType ) {
216
+ $input_exceptions->add_input_exception( __( 'Its not a folder, please put valid Folder ID.', Forminator::DOMAIN ), 'folder_id_error' );
217
+ }
218
+
219
+ } catch ( Google_Exception $google_exception ) {
220
+ // catch 404
221
+ if ( false !== stripos( $google_exception->getMessage(), 'File not found' ) ) {
222
+ $input_exceptions->add_input_exception( __( 'Folder not found, please put Folder ID.', Forminator::DOMAIN ), 'folder_id_error' );
223
+ } else {
224
+ throw $google_exception;
225
+ }
226
+ }
227
+ }
228
+
229
+ if ( $input_exceptions->input_exceptions_is_available() ) {
230
+ throw $input_exceptions;
231
+ }
232
+
233
+ $file = new Google_Service_Drive_DriveFile();
234
+ $file->setMimeType( Forminator_Addon_Googlesheet::MIME_TYPE_GOOGLE_SPREADSHEET );
235
+ $file->setName( $file_name );
236
+
237
+
238
+ if ( ! empty( $folder_id ) ) {
239
+ $file->setParents( array( $folder_id ) );
240
+ }
241
+
242
+ $drive = new Google_Service_Drive( $google_client );
243
+ $new_sheet = $drive->files->create( $file );
244
+
245
+ $this->save_multi_id_form_setting_values(
246
+ $multi_id,
247
+ array(
248
+ 'folder_id' => $folder_id,
249
+ 'file_name' => $file_name,
250
+ 'file_id' => $new_sheet->getId(),
251
+ )
252
+ );
253
+
254
+ $notification = array(
255
+ 'type' => 'success',
256
+ 'text' => '<strong>' . $this->addon->get_title() . '</strong> ' . __( 'Successfully created spreadsheet and connected to your form' ),
257
+ );
258
+ $is_close = true;
259
+
260
+
261
+ } catch ( Forminator_Addon_Googlesheet_Form_Settings_Exception $e ) {
262
+ $input_errors = $e->get_input_exceptions();
263
+ $template_params = array_merge( $template_params, $input_errors );
264
+ $has_errors = true;
265
+ } catch ( Forminator_Addon_Googlesheet_Exception $e ) {
266
+ $template_params['error_message'] = $e->getMessage();
267
+ $has_errors = true;
268
+ } catch ( Google_Exception $e ) {
269
+ $template_params['error_message'] = $e->getMessage();
270
+ $has_errors = true;
271
+ }
272
+ }
273
+
274
+ $buttons = array();
275
+ if ( $this->pick_name_is_completed( array( 'multi_id' => $multi_id ) ) ) {
276
+ $buttons['disconnect']['markup'] = Forminator_Addon_Abstract::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ),
277
+ 'sui-button-ghost sui-tooltip sui-tooltip-top-center forminator-addon-form-disconnect',
278
+ esc_html__( 'Disconnect this Google Sheets Integration from this Form.', Forminator::DOMAIN )
279
+ );
280
+ }
281
+
282
+ $buttons['next']['markup'] = '<div class="sui-actions-right">' .
283
+ Forminator_Addon_Abstract::get_button_markup( esc_html__( 'CREATE', Forminator::DOMAIN ), 'forminator-addon-next' ) .
284
+ '</div>';
285
+
286
+ return array(
287
+ 'html' => Forminator_Addon_Abstract::get_template( $template, $template_params ),
288
+ 'buttons' => $buttons,
289
+ 'redirect' => false,
290
+ 'has_errors' => $has_errors,
291
+ 'has_back' => true,
292
+ 'notification' => $notification,
293
+ 'is_close' => $is_close,
294
+ 'size' => 'normal',
295
+ );
296
+ }
297
+
298
+ /**
299
+ * Check if select contact list completed
300
+ *
301
+ * @since 1.0 Googlesheet Addon
302
+ *
303
+ * @param $submitted_data
304
+ *
305
+ * @return bool
306
+ */
307
+ public function setup_sheet_is_completed( $submitted_data ) {
308
+ $multi_id = '';
309
+ if ( isset( $submitted_data['multi_id'] ) ) {
310
+ $multi_id = $submitted_data['multi_id'];
311
+ }
312
+
313
+ if ( empty( $multi_id ) ) {
314
+ return false;
315
+ }
316
+
317
+ $file_name = $this->get_multi_id_form_settings_value( $multi_id, 'file_name', '' );
318
+
319
+ if ( empty( $file_name ) ) {
320
+ return false;
321
+ }
322
+
323
+ $file_id = $this->get_multi_id_form_settings_value( $multi_id, 'file_id', '' );
324
+
325
+ if ( empty( $file_id ) ) {
326
+ return false;
327
+ }
328
+
329
+ return true;
330
+ }
331
+
332
+ /**
333
+ * Generate multi id for multiple connection
334
+ *
335
+ * @since 1.0 Googlesheet Addon
336
+ * @return string
337
+ */
338
+ public function generate_multi_id() {
339
+ return uniqid( 'googlesheet_', true );
340
+ }
341
+
342
+
343
+ /**
344
+ * Override how multi connection displayed
345
+ *
346
+ * @since 1.0 Googlesheet Addon
347
+ * @return array
348
+ */
349
+ public function get_multi_ids() {
350
+ $multi_ids = array();
351
+ foreach ( $this->get_form_settings_values() as $key => $value ) {
352
+ $multi_ids[] = array(
353
+ 'id' => $key,
354
+ // use name that was added by user on creating connection
355
+ 'label' => isset( $value['name'] ) ? $value['name'] : $key,
356
+ );
357
+ }
358
+
359
+ return $multi_ids;
360
+ }
361
+
362
+ /**
363
+ * Disconnect a connection from current form
364
+ *
365
+ * @since 1.0 Googlesheet Addon
366
+ *
367
+ * @param array $submitted_data
368
+ */
369
+ public function disconnect_form( $submitted_data ) {
370
+ // only execute if multi_id provided on submitted data
371
+ if ( isset( $submitted_data['multi_id'] ) && ! empty( $submitted_data['multi_id'] ) ) {
372
+ $addon_form_settings = $this->get_form_settings_values();
373
+ unset( $addon_form_settings[ $submitted_data['multi_id'] ] );
374
+ $this->save_form_settings_values( $addon_form_settings );
375
+ }
376
+ }
377
+
378
+ /**
379
+ * Check if multi_id form settings values completed
380
+ *
381
+ * Override when needed
382
+ *
383
+ * @since 1.0 Googlesheet Addon
384
+ *
385
+ * @param $multi_id
386
+ *
387
+ * @return bool
388
+ */
389
+ public function is_multi_form_settings_complete( $multi_id ) {
390
+ $data = array( 'multi_id' => $multi_id );
391
+
392
+ if ( ! $this->pick_name_is_completed( $data ) ) {
393
+ return false;
394
+ }
395
+
396
+ if ( ! $this->setup_sheet_is_completed( $data ) ) {
397
+ return false;
398
+ }
399
+
400
+ return true;
401
+ }
402
+ }
addons/pro/googlesheet/forminator-addon-googlesheet.php ADDED
@@ -0,0 +1,684 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once dirname( __FILE__ ) . '/forminator-addon-googlesheet-exception.php';
4
+
5
+ /**
6
+ * Class Forminator_Addon_Googlesheet
7
+ * Googlesheet Addon Main Class
8
+ *
9
+ * @since 1.0 Googlesheet Addon
10
+ */
11
+ final class Forminator_Addon_Googlesheet extends Forminator_Addon_Abstract {
12
+
13
+ /**
14
+ * @var self|null
15
+ */
16
+ private static $_instance = null;
17
+
18
+ protected $_slug = 'googlesheet';
19
+ protected $_version = FORMINATOR_ADDON_GOOGLESHEET_VERSION;
20
+ protected $_min_forminator_version = '1.1';
21
+ protected $_short_title = 'Google Sheets';
22
+ protected $_title = 'Google Sheets';
23
+ protected $_url = 'https://premium.wpmudev.org';
24
+ protected $_full_path = __FILE__;
25
+
26
+ protected $_form_settings = 'Forminator_Addon_Googlesheet_Form_Settings';
27
+ protected $_form_hooks = 'Forminator_Addon_Googlesheet_Form_Hooks';
28
+
29
+ private $_token = '';
30
+
31
+ const MIME_TYPE_GOOGLE_DRIVE_FOLDER = 'application/vnd.google-apps.folder';
32
+ const MIME_TYPE_GOOGLE_SPREADSHEET = 'application/vnd.google-apps.spreadsheet';
33
+
34
+ /**
35
+ * Forminator_Addon_Googlesheet constructor.
36
+ *
37
+ * @since 1.0 Googlesheet Addon
38
+ */
39
+ public function __construct() {
40
+ // late init to allow translation
41
+ $this->_description = __( 'Get awesome by your form.', Forminator::DOMAIN );
42
+ $this->_activation_error_message = __( 'Sorry but we failed to activate Googlesheet Integration, don\'t hesitate to contact us', Forminator::DOMAIN );
43
+ $this->_deactivation_error_message = __( 'Sorry but we failed to deactivate Googlesheet Integration, please try again', Forminator::DOMAIN );
44
+
45
+ $this->_update_settings_error_message = __(
46
+ 'Sorry, we are failed to update settings, please check your form and try again',
47
+ Forminator::DOMAIN
48
+ );
49
+
50
+ $this->_icon = forminator_addon_googlesheet_assets_url() . 'icons/googlesheet.png';
51
+ $this->_icon_x2 = forminator_addon_googlesheet_assets_url() . 'icons/googlesheet@2x.png';
52
+ $this->_image = forminator_addon_googlesheet_assets_url() . 'img/googlesheet.png';
53
+ $this->_image_x2 = forminator_addon_googlesheet_assets_url() . 'img/googlesheet@2x.png';
54
+ }
55
+
56
+ /**
57
+ * Get Instance
58
+ *
59
+ * @since 1.0 Googlesheet Addon
60
+ * @return self|null
61
+ */
62
+ public static function get_instance() {
63
+ if ( is_null( self::$_instance ) ) {
64
+ self::$_instance = new self();
65
+ }
66
+
67
+ return self::$_instance;
68
+ }
69
+
70
+ /**
71
+ * Override on is_connected
72
+ *
73
+ * @since 1.0 Googlesheet Addon
74
+ *
75
+ * @return bool
76
+ */
77
+ public function is_connected() {
78
+ try {
79
+ // check if its active
80
+ if ( ! $this->is_active() ) {
81
+ throw new Forminator_Addon_Googlesheet_Exception( __( 'Google Sheets is not active', Forminator::DOMAIN ) );
82
+ }
83
+
84
+ $is_connected = false;
85
+ $setting_values = $this->get_settings_values();
86
+ // if user completed api setup
87
+ if ( isset( $setting_values['token'] ) && ! empty( $setting_values['token'] ) ) {
88
+ $is_connected = true;
89
+ }
90
+
91
+ } catch ( Forminator_Addon_Googlesheet_Exception $e ) {
92
+ $is_connected = false;
93
+ }
94
+
95
+ /**
96
+ * Filter connected status of Google Sheet
97
+ *
98
+ * @since 1.2
99
+ *
100
+ * @param bool $is_connected
101
+ */
102
+ $is_connected = apply_filters( 'forminator_addon_googlesheet_is_connected', $is_connected );
103
+
104
+ return $is_connected;
105
+ }
106
+
107
+ /**
108
+ * Check if Googlesheet is connected with current form
109
+ *
110
+ * @since 1.0 Googlesheet Addon
111
+ *
112
+ * @param $form_id
113
+ *
114
+ * @return bool
115
+ */
116
+ public function is_form_connected( $form_id ) {
117
+ try {
118
+ $form_settings_instance = null;
119
+ if ( ! $this->is_connected() ) {
120
+ throw new Forminator_Addon_Googlesheet_Exception( __( 'GoogleSheet is not connected', Forminator::DOMAIN ) );
121
+ }
122
+
123
+ $form_settings_instance = $this->get_addon_form_settings( $form_id );
124
+ if ( ! $form_settings_instance instanceof Forminator_Addon_Googlesheet_Form_Settings ) {
125
+ throw new Forminator_Addon_Googlesheet_Exception( __( 'Invalid Form Settings of GoogleSheet', Forminator::DOMAIN ) );
126
+ }
127
+
128
+ // Mark as active when there is at least one active connection
129
+ if ( false === $form_settings_instance->find_one_active_connection() ) {
130
+ throw new Forminator_Addon_Googlesheet_Exception( __( 'No active GoogleSheet connection found in this form', Forminator::DOMAIN ) );
131
+ }
132
+
133
+ $is_form_connected = true;
134
+
135
+ } catch ( Forminator_Addon_Googlesheet_Exception $e ) {
136
+ $is_form_connected = false;
137
+ }
138
+
139
+ /**
140
+ * Filter connected status GoogleSheet with the form
141
+ *
142
+ * @since 1.0
143
+ *
144
+ * @param bool $is_form_connected
145
+ * @param int $form_id Current Form ID
146
+ * @param Forminator_Addon_Googlesheet_Form_Settings|null $form_settings_instance Instance of form settings, or null when unavailable
147
+ *
148
+ */
149
+ $is_form_connected = apply_filters( 'forminator_addon_googlesheet_is_form_connected', $is_form_connected, $form_id, $form_settings_instance );
150
+
151
+ return $is_form_connected;
152
+ }
153
+
154
+ /**
155
+ * Override settings available,
156
+ *
157
+ * @since 1.0 Googlesheet Addon
158
+ * @return bool
159
+ */
160
+ public function is_settings_available() {
161
+ return true;
162
+ }
163
+
164
+ /**
165
+ * Flag show full log on entries
166
+ *
167
+ * @since 1.0 Googlesheet Addon
168
+ * @return bool
169
+ */
170
+ public static function is_show_full_log() {
171
+ $show_full_log = false;
172
+ if ( defined( 'FORMINATOR_ADDON_GOOGLESHEET_SHOW_FULL_LOG' ) && FORMINATOR_ADDON_GOOGLESHEET_SHOW_FULL_LOG ) {
173
+ $show_full_log = true;
174
+ }
175
+
176
+ /**
177
+ * Filter Flag show full log on entries
178
+ *
179
+ * @since 1.2
180
+ *
181
+ * @params bool $show_full_log
182
+ */
183
+ $show_full_log = apply_filters( 'forminator_addon_googlesheet_show_full_log', $show_full_log );
184
+
185
+ return $show_full_log;
186
+ }
187
+
188
+ /**
189
+ * Allow multiple connection on one form
190
+ *
191
+ * @since 1.0 Googlesheet Addon
192
+ * @return bool
193
+ */
194
+ public function is_allow_multi_on_form() {
195
+ return true;
196
+ }
197
+
198
+ /**
199
+ * Settings wizard
200
+ *
201
+ * @since 1.0 Googlesheet Addon
202
+ * @return array
203
+ */
204
+ public function settings_wizards() {
205
+ return array(
206
+ array(
207
+ 'callback' => array( $this, 'setup_client_id' ),
208
+ 'is_completed' => array( $this, 'setup_client_id_is_completed' ),
209
+ ),
210
+ array(
211
+ 'callback' => array( $this, 'authorize_access' ),
212
+ 'is_completed' => array( $this, 'authorize_access_is_completed' ),
213
+ ),
214
+ array(
215
+ 'callback' => array( $this, 'wait_authorize_access' ),
216
+ 'is_completed' => array( $this, 'is_authorized' ),
217
+ ),
218
+ );
219
+ }
220
+
221
+ /**
222
+ * Authorize Access wizard
223
+ *
224
+ * @since 1.0 Googlesheet Addon
225
+ *
226
+ * @param $submitted_data
227
+ *
228
+ * @return array
229
+ */
230
+ public function setup_client_id( $submitted_data ) {
231
+ $settings_values = $this->get_settings_values();
232
+ $template = forminator_addon_googlesheet_dir() . 'views/settings/setup-client.php';
233
+
234
+ $buttons = array();
235
+ if ( $this->is_connected() ) {
236
+ $buttons['disconnect'] = array(
237
+ 'markup' => self::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ), 'sui-button-ghost forminator-addon-disconnect' ),
238
+ );
239
+ $buttons['next']['markup'] = '<div class="sui-actions-right">' .
240
+ Forminator_Addon_Mailchimp::get_button_markup( esc_html__( 'RE-AUTHORIZE', Forminator::DOMAIN ), 'forminator-addon-next' ) .
241
+ '</div>';
242
+ } else {
243
+ $buttons['next']['markup'] = '<div class="sui-actions-right">' .
244
+ Forminator_Addon_Mailchimp::get_button_markup( esc_html__( 'NEXT', Forminator::DOMAIN ), 'forminator-addon-next' ) .
245
+ '</div>';
246
+ }
247
+
248
+ $template_params = array(
249
+ 'token' => $this->_token,
250
+ 'client_id' => '',
251
+ 'client_id_error' => '',
252
+ 'client_secret' => '',
253
+ 'client_secret_error' => '',
254
+ 'error_message' => '',
255
+ 'redirect_url' => forminator_addon_integration_section_admin_url( $this->_slug, 'authorize', false ),
256
+ );
257
+
258
+ $has_errors = false;
259
+ $is_submit = ! empty( $submitted_data );
260
+
261
+ foreach ( $template_params as $key => $value ) {
262
+ if ( isset( $submitted_data[ $key ] ) ) {
263
+ $template_params[ $key ] = $submitted_data[ $key ];
264
+ } elseif ( isset( $settings_values[ $key ] ) ) {
265
+ $template_params[ $key ] = $settings_values[ $key ];
266
+ }
267
+ }
268
+
269
+ if ( empty( $template_params['client_id'] ) ) {
270
+ $saved_client_id = $this->get_client_id();
271
+ if ( ! empty( $saved_client_id ) ) {
272
+ $template_params['client_id'] = $saved_client_id;
273
+ }
274
+ }
275
+
276
+ if ( empty( $template_params['client_secret'] ) ) {
277
+ $saved_client_secret = $this->get_client_secret();
278
+
279
+ if ( ! empty( $saved_client_secret ) ) {
280
+ $template_params['client_secret'] = $saved_client_secret;
281
+ }
282
+ }
283
+
284
+
285
+ if ( $is_submit ) {
286
+ $client_id = isset( $submitted_data['client_id'] ) ? $submitted_data['client_id'] : '';
287
+ $client_secret = isset( $submitted_data['client_secret'] ) ? $submitted_data['client_secret'] : '';
288
+
289
+ if ( empty( $client_id ) ) {
290
+ $template_params['client_id_error'] = __( 'Please input valid Client ID', Forminator::DOMAIN );
291
+ $has_errors = true;
292
+ }
293
+
294
+ if ( empty( $client_secret ) ) {
295
+ $template_params['client_secret_error'] = __( 'Please input valid Client Secret', Forminator::DOMAIN );
296
+ $has_errors = true;
297
+ }
298
+
299
+ if ( ! $has_errors ) {
300
+ // validate api
301
+ try {
302
+ if ( $this->get_client_id() !== $client_id || $this->get_client_secret() !== $client_secret ) {
303
+ // reset connection!
304
+ $settings_values = array();
305
+ }
306
+ $settings_values['client_id'] = $client_id;
307
+ $settings_values['client_secret'] = $client_secret;
308
+
309
+ $this->save_settings_values( $settings_values );
310
+
311
+ } catch ( Forminator_Addon_Googlesheet_Exception $e ) {
312
+ $template_params['error_message'] = $e->getMessage();
313
+ $has_errors = true;
314
+ }
315
+ }
316
+
317
+
318
+ }
319
+
320
+ return array(
321
+ 'html' => self::get_template( $template, $template_params ),
322
+ 'buttons' => $buttons,
323
+ 'redirect' => false,
324
+ 'has_errors' => $has_errors,
325
+ 'size' => 'normal',
326
+ );
327
+ }
328
+
329
+ /**
330
+ * Setup client id is complete
331
+ *
332
+ * @param $submitted_data
333
+ *
334
+ * @return bool
335
+ */
336
+ public function setup_client_id_is_completed( $submitted_data ) {
337
+ $client_id = $this->get_client_id();
338
+ $client_secret = $this->get_client_secret();
339
+
340
+ if ( ! empty( $client_id ) && ! empty( $client_secret ) ) {
341
+ return true;
342
+ }
343
+
344
+ return false;
345
+ }
346
+
347
+ /**
348
+ * Authorize Access wizard
349
+ *
350
+ * @since 1.0 Google Sheet Addon
351
+ * @return array
352
+ */
353
+ public function authorize_access() {
354
+
355
+ $template = forminator_addon_googlesheet_dir() . 'views/settings/authorize.php';
356
+
357
+ $buttons = array();
358
+ if ( $this->is_connected() ) {
359
+ $buttons['disconnect'] = array(
360
+ 'markup' => self::get_button_markup( esc_html__( 'DISCONNECT', Forminator::DOMAIN ), 'sui-button-ghost forminator-addon-disconnect' ),
361
+ );
362
+ }
363
+
364
+
365
+ $template_params = array(
366
+ 'auth_url' => $this->get_auth_url(),
367
+ 'token' => $this->_token,
368
+ );
369
+
370
+ return array(
371
+ 'html' => self::get_template( $template, $template_params ),
372
+ 'buttons' => $buttons,
373
+ 'redirect' => false,
374
+ 'has_errors' => false,
375
+ );
376
+ }
377
+
378
+ public function authorize_access_is_completed() {
379
+ return true;
380
+ }
381
+
382
+ /**
383
+ * Wait Authorize Access wizard
384
+ *
385
+ * @since 1.0 Googlesheet Addon
386
+ * @return array
387
+ */
388
+ public function wait_authorize_access() {
389
+ $template = forminator_addon_googlesheet_dir() . 'views/settings/wait-authorize.php';
390
+ $template_success = forminator_addon_googlesheet_dir() . 'views/settings/success-authorize.php';
391
+
392
+ $buttons = array();
393
+
394
+ $is_poll = true;
395
+
396
+ $template_params = array(
397
+ 'token' => $this->_token,
398
+ 'auth_url' => $this->get_auth_url(),
399
+ );
400
+
401
+ if ( $this->_token ) {
402
+ $buttons['close'] = array(
403
+ 'markup' => self::get_button_markup( esc_html__( 'CLOSE', Forminator::DOMAIN ), 'sui-button-ghost forminator-addon-close' ),
404
+ );
405
+ $is_poll = false;
406
+
407
+ $template = $template_success;
408
+ }
409
+
410
+ return array(
411
+ 'html' => self::get_template( $template, $template_params ),
412
+ 'buttons' => $buttons,
413
+ 'is_poll' => $is_poll,
414
+ 'redirect' => false,
415
+ 'has_errors' => false,
416
+ );
417
+ }
418
+
419
+ /**
420
+ * Authorized Callback
421
+ *
422
+ * @since 1.0 Googlesheet Addon
423
+ *
424
+ * @param $submitted_data
425
+ *
426
+ * @return bool
427
+ */
428
+ public function is_authorized( $submitted_data ) {
429
+ $setting_values = $this->get_settings_values();
430
+
431
+ // check api_key and and api_url set up
432
+ return isset( $setting_values['token'] ) && ! empty( $setting_values['token'] );
433
+ }
434
+
435
+ /**
436
+ * Get Auth Url
437
+ *
438
+ * @return string
439
+ */
440
+ public function get_auth_url() {
441
+ $google_client = $this->get_google_client();
442
+ $auth_url = $google_client->createAuthUrl();
443
+
444
+ return $auth_url;
445
+ }
446
+
447
+ /**
448
+ * Get Client ID
449
+ *
450
+ * @since 1.0 Googlesheet Addon
451
+ * @return string
452
+ */
453
+ public function get_client_id() {
454
+ $settings_values = $this->get_settings_values();
455
+ $client_id = '';
456
+ if ( isset( $settings_values ['client_id'] ) ) {
457
+ $client_id = $settings_values ['client_id'];
458
+ }
459
+
460
+ /**
461
+ * Filter client id used
462
+ *
463
+ * @since 1.2
464
+ *
465
+ * @param string $client_id
466
+ */
467
+ $client_id = apply_filters( 'forminator_addon_googlesheet_client_id', $client_id );
468
+
469
+ return $client_id;
470
+ }
471
+
472
+ /**
473
+ * Get Client secret
474
+ *
475
+ * @since 1.0 Googlesheet Addon
476
+ * @return string
477
+ */
478
+ public function get_client_secret() {
479
+ $settings_values = $this->get_settings_values();
480
+ $client_secret = '';
481
+ if ( isset( $settings_values ['client_secret'] ) ) {
482
+ $client_secret = $settings_values ['client_secret'];
483
+ }
484
+
485
+ /**
486
+ * Filter client secret used
487
+ *
488
+ * @since 1.2
489
+ *
490
+ * @param string $client_secret
491
+ */
492
+ $client_secret = apply_filters( 'forminator_addon_googlesheet_client_secret', $client_secret );
493
+
494
+ return $client_secret;
495
+ }
496
+
497
+ /**
498
+ * Get Access Token
499
+ *
500
+ * @since 1.0 Googlesheet Addon
501
+ * @return string
502
+ */
503
+ public function get_client_access_token() {
504
+ $settings_values = $this->get_settings_values();
505
+ $token = '';
506
+ if ( isset( $settings_values ['token'] ) ) {
507
+ $token = $settings_values ['token'];
508
+ }
509
+
510
+ /**
511
+ * Filter access_token used
512
+ *
513
+ * @since 1.2
514
+ *
515
+ * @param string $token (json encoded)
516
+ */
517
+ $token = apply_filters( 'forminator_addon_googlesheet_client_access_token', $token );
518
+
519
+ return $token;
520
+ }
521
+
522
+ /**
523
+ * Update Access Token
524
+ *
525
+ * @since 1.0 Googlesheet Addon
526
+ *
527
+ * @param $access_token
528
+ *
529
+ * @return string
530
+ */
531
+ public function update_client_access_token( $access_token ) {
532
+ $settings_values = $this->get_settings_values();
533
+ $settings_values ['token'] = $access_token;
534
+ $this->save_settings_values( $settings_values );
535
+ }
536
+
537
+ /**
538
+ * Register a page for redirect url of Goolge auth
539
+ *
540
+ * @since 1.0 Googlesheet Addon
541
+ *
542
+ * @return array
543
+ */
544
+ public function register_integration_sections() {
545
+ return array(
546
+ 'authorize' => array( $this, 'authorize_page_callback' ),
547
+ );
548
+ }
549
+
550
+
551
+ /**
552
+ * Googlesheet Authorize Page
553
+ *
554
+ * @since 1.0 Googlesheet Addon
555
+ *
556
+ * @param $query_args
557
+ *
558
+ * @return string
559
+ */
560
+ public function authorize_page_callback( $query_args ) {
561
+ $settings = $this->get_settings_values();
562
+ $template = forminator_addon_googlesheet_dir() . 'views/sections/authorize.php';
563
+ $template_params = array(
564
+ 'error_message' => '',
565
+ 'is_close' => false,
566
+ );
567
+
568
+ if ( isset( $query_args['code'] ) ) {
569
+ try {
570
+ $google_client = $this->get_google_client();
571
+ $google_client->authenticate( $query_args['code'] );
572
+ $token = $google_client->getAccessToken();
573
+ if ( empty( $token ) ) {
574
+ throw new Forminator_Addon_Googlesheet_Exception( __( 'Failed to get token', Forminator::DOMAIN ) );
575
+ }
576
+
577
+ if ( ! $this->is_active() ) {
578
+ $activated = Forminator_Addon_Loader::get_instance()->activate_addon( $this->_slug );
579
+ if ( ! $activated ) {
580
+ $last_message = Forminator_Addon_Loader::get_instance()->get_last_error_message();
581
+ throw new Forminator_Addon_Googlesheet_Exception( $last_message );
582
+ }
583
+ }
584
+
585
+ $settings['token'] = $token;
586
+ $this->save_settings_values( $settings );
587
+ $template_params['is_close'] = true;
588
+ } catch ( Exception $e ) {
589
+ // catch all exception
590
+ $template_params['error_message'] = $e->getMessage();
591
+ }
592
+
593
+ }
594
+
595
+ return self::get_template( $template, $template_params );
596
+ }
597
+
598
+ /**
599
+ * Get Google_Client Object
600
+ *
601
+ * @since 1.0 Googlesheet Addon
602
+ * @return Google_Client
603
+ */
604
+ public function get_google_client() {
605
+ spl_autoload_register( 'forminator_addon_googlesheet_google_api_client_autoload' );
606
+ $redirect_url = forminator_addon_integration_section_admin_url( $this->_slug, 'authorize', false );
607
+ $client_id = $this->get_client_id();
608
+ $client_secret = $this->get_client_secret();
609
+ $scopes = array(
610
+ Google_Service_Sheets::SPREADSHEETS,
611
+ Google_Service_Sheets::DRIVE,
612
+ );
613
+
614
+ $config = new Google_Config();
615
+ $config->setLoggerClass( 'Forminator_Addon_Wp_Googlesheet_Client_Logger' );
616
+ $google_client = new Google_Client( $config );
617
+ $google_client->setApplicationName( __( 'Forminator Pro', Forminator::DOMAIN ) );
618
+ $google_client->setClientId( $client_id );
619
+ $google_client->setClientSecret( $client_secret );
620
+ $google_client->setScopes( $scopes );
621
+ $google_client->setRedirectUri( $redirect_url );
622
+ $google_client->setAccessType( 'offline' );
623
+ $google_client->setApprovalPrompt( 'force' );
624
+
625
+ /**
626
+ * Filter Google API Client used through out cycle
627
+ *
628
+ * @since 1.2
629
+ *
630
+ * @param Google_Client $google_client
631
+ * @param string $client_id
632
+ * @param string $client_secret
633
+ * @param array $scopes
634
+ * @param string $redirect_url
635
+ */
636
+ $google_client = apply_filters( 'forminator_addon_googlesheet_google_client', $google_client, $client_id, $client_secret, $scopes, $redirect_url );
637
+
638
+ return $google_client;
639
+ }
640
+
641
+ /**
642
+ * Before get Setting Values
643
+ *
644
+ * @since 1.0 Google Sheet Addon
645
+ *
646
+ * @param $values
647
+ *
648
+ * @return mixed
649
+ */
650
+ public function before_get_settings_values( $values ) {
651
+ if ( isset( $values['token'] ) ) {
652
+ $this->_token = $values['token'];
653
+ forminator_addon_maybe_log( __METHOD__, $this->_token );
654
+ }
655
+
656
+ return $values;
657
+ }
658
+
659
+ /**
660
+ * Revoke token on Google before deactivate
661
+ *
662
+ * @since 1.0 Google Sheet Addon
663
+ * @return bool
664
+ */
665
+ public function deactivate() {
666
+ try {
667
+ $google_client = $this->get_google_client();
668
+ $google_client->setAccessToken( $this->get_client_access_token() );
669
+ $revoked = $google_client->revokeToken();
670
+
671
+ if ( ! $revoked ) {
672
+ throw new Forminator_Addon_Googlesheet_Exception( __( 'Failed to revoke access token', Forminator::DOMAIN ) );
673
+ }
674
+ $this->_token = '';
675
+ } catch ( Forminator_Addon_Googlesheet_Exception $e ) {
676
+ $this->_deactivation_error_message = $e->getMessage();
677
+
678
+ return false;
679
+ }
680
+
681
+ return true;
682
+ }
683
+
684
+ }
addons/pro/googlesheet/googlesheet.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Addon Name: Googlesheet
5
+ * Version: 1.0
6
+ * Plugin URI: https://premium.wpmudev.org/
7
+ * Description: Integrate Forminator Custom Forms with Googlesheet to get notified in real time.
8
+ * Author: WPMU DEV
9
+ * Author URI: http://premium.wpmudev.org
10
+ */
11
+
12
+ define( 'FORMINATOR_ADDON_GOOGLESHEET_VERSION', '1.0' );
13
+
14
+ function forminator_addon_googlesheet_url() {
15
+ return trailingslashit( forminator_plugin_url() . 'addons/pro/googlesheet' );
16
+ }
17
+
18
+ function forminator_addon_googlesheet_dir() {
19
+ return trailingslashit( dirname( __FILE__ ) );
20
+ }
21
+
22
+ function forminator_addon_googlesheet_assets_url() {
23
+ return trailingslashit( forminator_addon_googlesheet_url() . 'assets' );
24
+ }
25
+
26
+ function forminator_addon_googlesheet_google_api_client_autoload( $class_name ) {
27
+ $class_path = explode( '_', $class_name );
28
+ if ( 'Google' !== $class_path[0] ) {
29
+ return;
30
+ }
31
+ // Drop 'Google', and maximum class file path depth in this project is 3.
32
+ $google_api_client_path = dirname( __FILE__ ) . '/lib/Google';
33
+ $class_path = array_slice( $class_path, 1, 2 );
34
+ $file_path = $google_api_client_path . '/' . implode( '/', $class_path ) . '.php';
35
+
36
+ if ( file_exists( $file_path ) ) {
37
+ /** @noinspection PhpIncludeInspection */
38
+ require_once $file_path;
39
+ }
40
+ }
41
+
42
+ // only enable autoload when needed to avoid further conflicts
43
+ //spl_autoload_register( 'forminator_addon_googlesheet_google_api_client_autoload' );
44
+
45
+ require_once dirname( __FILE__ ) . '/forminator-addon-googlesheet.php';
46
+ require_once dirname( __FILE__ ) . '/forminator-addon-googlesheet-form-settings.php';
47
+ require_once dirname( __FILE__ ) . '/forminator-addon-googlesheet-form-hooks.php';
48
+ require_once dirname( __FILE__ ) . '/lib/class-wp-googlesheet-client-logger.php';
49
+ //Direct Load
50
+ Forminator_Addon_Loader::get_instance()->register( 'Forminator_Addon_Googlesheet' );
addons/pro/googlesheet/lib/class-wp-googlesheet-client-logger.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if ( ! class_exists( 'Google_Logger_Abstract' ) ) {
4
+ require_once dirname( __FILE__ ) . '/external/Google/Logger/Abstract.php';
5
+ }
6
+
7
+
8
+ /**
9
+ * Class Forminator_Addon_Wp_Googlesheet_Client_Logger
10
+ */
11
+ class Forminator_Addon_Wp_Googlesheet_Client_Logger extends Google_Logger_Abstract {
12
+
13
+ /**
14
+ * Writes a message to the current log implementation.
15
+ *
16
+ * @param string $message The message
17
+ */
18
+ protected function write( $message ) {
19
+ forminator_addon_maybe_log( $message );
20
+ }
21
+ }
addons/pro/googlesheet/lib/external/Google/Auth/Abstract.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * Abstract class for the Authentication in the API client
24
+ * @author Chris Chabot <chabotc@google.com>
25
+ *
26
+ */
27
+ abstract class Google_Auth_Abstract
28
+ {
29
+ /**
30
+ * An utility function that first calls $this->auth->sign($request) and then
31
+ * executes makeRequest() on that signed request. Used for when a request
32
+ * should be authenticated
33
+ * @param Google_Http_Request $request
34
+ * @return Google_Http_Request $request
35
+ */
36
+ abstract public function authenticatedRequest(Google_Http_Request $request);
37
+ abstract public function sign(Google_Http_Request $request);
38
+ }
addons/pro/googlesheet/lib/external/Google/Auth/AppIdentity.php ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2014 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /*
19
+ * WARNING - this class depends on the Google App Engine PHP library
20
+ * which is 5.3 and above only, so if you include this in a PHP 5.2
21
+ * setup or one without 5.3 things will blow up.
22
+ */
23
+ use google\appengine\api\app_identity\AppIdentityService;
24
+
25
+ if (!class_exists('Google_Client')) {
26
+ require_once dirname(__FILE__) . '/../autoload.php';
27
+ }
28
+
29
+ /**
30
+ * Authentication via the Google App Engine App Identity service.
31
+ */
32
+ class Google_Auth_AppIdentity extends Google_Auth_Abstract
33
+ {
34
+ const CACHE_PREFIX = "Google_Auth_AppIdentity::";
35
+ private $client;
36
+ private $token = false;
37
+ private $tokenScopes = false;
38
+
39
+ public function __construct(Google_Client $client, $config = null)
40
+ {
41
+ $this->client = $client;
42
+ }
43
+
44
+ /**
45
+ * Retrieve an access token for the scopes supplied.
46
+ */
47
+ public function authenticateForScope($scopes)
48
+ {
49
+ if ($this->token && $this->tokenScopes == $scopes) {
50
+ return $this->token;
51
+ }
52
+
53
+ $cacheKey = self::CACHE_PREFIX;
54
+ if (is_string($scopes)) {
55
+ $cacheKey .= $scopes;
56
+ } else if (is_array($scopes)) {
57
+ $cacheKey .= implode(":", $scopes);
58
+ }
59
+
60
+ $this->token = $this->client->getCache()->get($cacheKey);
61
+ if (!$this->token) {
62
+ $this->retrieveToken($scopes, $cacheKey);
63
+ } else if ($this->token['expiration_time'] < time()) {
64
+ $this->client->getCache()->delete($cacheKey);
65
+ $this->retrieveToken($scopes, $cacheKey);
66
+ }
67
+
68
+ $this->tokenScopes = $scopes;
69
+ return $this->token;
70
+ }
71
+
72
+ /**
73
+ * Retrieve a new access token and store it in cache
74
+ * @param mixed $scopes
75
+ * @param string $cacheKey
76
+ */
77
+ private function retrieveToken($scopes, $cacheKey)
78
+ {
79
+ $this->token = AppIdentityService::getAccessToken($scopes);
80
+ if ($this->token) {
81
+ $this->client->getCache()->set(
82
+ $cacheKey,
83
+ $this->token
84
+ );
85
+ }
86
+ }
87
+
88
+ /**
89
+ * Perform an authenticated / signed apiHttpRequest.
90
+ * This function takes the apiHttpRequest, calls apiAuth->sign on it
91
+ * (which can modify the request in what ever way fits the auth mechanism)
92
+ * and then calls apiCurlIO::makeRequest on the signed request
93
+ *
94
+ * @param Google_Http_Request $request
95
+ * @return Google_Http_Request The resulting HTTP response including the
96
+ * responseHttpCode, responseHeaders and responseBody.
97
+ */
98
+ public function authenticatedRequest(Google_Http_Request $request)
99
+ {
100
+ $request = $this->sign($request);
101
+ return $this->client->getIo()->makeRequest($request);
102
+ }
103
+
104
+ public function sign(Google_Http_Request $request)
105
+ {
106
+ if (!$this->token) {
107
+ // No token, so nothing to do.
108
+ return $request;
109
+ }
110
+
111
+ $this->client->getLogger()->debug('App Identity authentication');
112
+
113
+ // Add the OAuth2 header to the request
114
+ $request->setRequestHeaders(
115
+ array('Authorization' => 'Bearer ' . $this->token['access_token'])
116
+ );
117
+
118
+ return $request;
119
+ }
120
+ }
addons/pro/googlesheet/lib/external/Google/Auth/AssertionCredentials.php ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2012 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * Credentials object used for OAuth 2.0 Signed JWT assertion grants.
24
+ */
25
+ class Google_Auth_AssertionCredentials
26
+ {
27
+ const MAX_TOKEN_LIFETIME_SECS = 3600;
28
+
29
+ public $serviceAccountName;
30
+ public $scopes;
31
+ public $privateKey;
32
+ public $privateKeyPassword;
33
+ public $assertionType;
34
+ public $sub;
35
+ /**
36
+ * @deprecated
37
+ * @link http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06
38
+ */
39
+ public $prn;
40
+ private $useCache;
41
+
42
+ /**
43
+ * @param $serviceAccountName
44
+ * @param $scopes array List of scopes
45
+ * @param $privateKey
46
+ * @param string $privateKeyPassword
47
+ * @param string $assertionType
48
+ * @param bool|string $sub The email address of the user for which the
49
+ * application is requesting delegated access.
50
+ * @param bool useCache Whether to generate a cache key and allow
51
+ * automatic caching of the generated token.
52
+ */
53
+ public function __construct(
54
+ $serviceAccountName,
55
+ $scopes,
56
+ $privateKey,
57
+ $privateKeyPassword = 'notasecret',
58
+ $assertionType = 'http://oauth.net/grant_type/jwt/1.0/bearer',
59
+ $sub = false,
60
+ $useCache = true
61
+ ) {
62
+ $this->serviceAccountName = $serviceAccountName;
63
+ $this->scopes = is_string($scopes) ? $scopes : implode(' ', $scopes);
64
+ $this->privateKey = $privateKey;
65
+ $this->privateKeyPassword = $privateKeyPassword;
66
+ $this->assertionType = $assertionType;
67
+ $this->sub = $sub;
68
+ $this->prn = $sub;
69
+ $this->useCache = $useCache;
70
+ }
71
+
72
+ /**
73
+ * Generate a unique key to represent this credential.
74
+ * @return string
75
+ */
76
+ public function getCacheKey()
77
+ {
78
+ if (!$this->useCache) {
79
+ return false;
80
+ }
81
+ $h = $this->sub;
82
+ $h .= $this->assertionType;
83
+ $h .= $this->privateKey;
84
+ $h .= $this->scopes;
85
+ $h .= $this->serviceAccountName;
86
+ return md5($h);
87
+ }
88
+
89
+ public function generateAssertion()
90
+ {
91
+ $now = time();
92
+
93
+ $jwtParams = array(
94
+ 'aud' => Google_Auth_OAuth2::OAUTH2_TOKEN_URI,
95
+ 'scope' => $this->scopes,
96
+ 'iat' => $now,
97
+ 'exp' => $now + self::MAX_TOKEN_LIFETIME_SECS,
98
+ 'iss' => $this->serviceAccountName,
99
+ );
100
+
101
+ if ($this->sub !== false) {
102
+ $jwtParams['sub'] = $this->sub;
103
+ } else if ($this->prn !== false) {
104
+ $jwtParams['prn'] = $this->prn;
105
+ }
106
+
107
+ return $this->makeSignedJwt($jwtParams);
108
+ }
109
+
110
+ /**
111
+ * Creates a signed JWT.
112
+ * @param array $payload
113
+ * @return string The signed JWT.
114
+ */
115
+ private function makeSignedJwt($payload)
116
+ {
117
+ $header = array('typ' => 'JWT', 'alg' => 'RS256');
118
+
119
+ $payload = json_encode($payload);
120
+ // Handle some overzealous escaping in PHP json that seemed to cause some errors
121
+ // with claimsets.
122
+ $payload = str_replace('\/', '/', $payload);
123
+
124
+ $segments = array(
125
+ Google_Utils::urlSafeB64Encode(json_encode($header)),
126
+ Google_Utils::urlSafeB64Encode($payload)
127
+ );
128
+
129
+ $signingInput = implode('.', $segments);
130
+ $signer = new Google_Signer_P12($this->privateKey, $this->privateKeyPassword);
131
+ $signature = $signer->sign($signingInput);
132
+ $segments[] = Google_Utils::urlSafeB64Encode($signature);
133
+
134
+ return implode(".", $segments);
135
+ }
136
+ }
addons/pro/googlesheet/lib/external/Google/Auth/ComputeEngine.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2014 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * Authentication via built-in Compute Engine service accounts.
24
+ * The instance must be pre-configured with a service account
25
+ * and the appropriate scopes.
26
+ * @author Jonathan Parrott <jon.wayne.parrott@gmail.com>
27
+ */
28
+ class Google_Auth_ComputeEngine extends Google_Auth_Abstract
29
+ {
30
+ const METADATA_AUTH_URL =
31
+ 'http://metadata/computeMetadata/v1/instance/service-accounts/default/token';
32
+ private $client;
33
+ private $token;
34
+
35
+ public function __construct(Google_Client $client, $config = null)
36
+ {
37
+ $this->client = $client;
38
+ }
39
+
40
+ /**
41
+ * Perform an authenticated / signed apiHttpRequest.
42
+ * This function takes the apiHttpRequest, calls apiAuth->sign on it
43
+ * (which can modify the request in what ever way fits the auth mechanism)
44
+ * and then calls apiCurlIO::makeRequest on the signed request
45
+ *
46
+ * @param Google_Http_Request $request
47
+ * @return Google_Http_Request The resulting HTTP response including the
48
+ * responseHttpCode, responseHeaders and responseBody.
49
+ */
50
+ public function authenticatedRequest(Google_Http_Request $request)
51
+ {
52
+ $request = $this->sign($request);
53
+ return $this->client->getIo()->makeRequest($request);
54
+ }
55
+
56
+ /**
57
+ * @param string $token
58
+ * @throws Google_Auth_Exception
59
+ */
60
+ public function setAccessToken($token)
61
+ {
62
+ $token = json_decode($token, true);
63
+ if ($token == null) {
64
+ throw new Google_Auth_Exception('Could not json decode the token');
65
+ }
66
+ if (! isset($token['access_token'])) {
67
+ throw new Google_Auth_Exception("Invalid token format");
68
+ }
69
+ $token['created'] = time();
70
+ $this->token = $token;
71
+ }
72
+
73
+ public function getAccessToken()
74
+ {
75
+ return json_encode($this->token);
76
+ }
77
+
78
+ /**
79
+ * Acquires a new access token from the compute engine metadata server.
80
+ * @throws Google_Auth_Exception
81
+ */
82
+ public function acquireAccessToken()
83
+ {
84
+ $request = new Google_Http_Request(
85
+ self::METADATA_AUTH_URL,
86
+ 'GET',
87
+ array(
88
+ 'Metadata-Flavor' => 'Google'
89
+ )
90
+ );
91
+ $request->disableGzip();
92
+ $response = $this->client->getIo()->makeRequest($request);
93
+
94
+ if ($response->getResponseHttpCode() == 200) {
95
+ $this->setAccessToken($response->getResponseBody());
96
+ $this->token['created'] = time();
97
+ return $this->getAccessToken();
98
+ } else {
99
+ throw new Google_Auth_Exception(
100
+ sprintf(
101
+ "Error fetching service account access token, message: '%s'",
102
+ $response->getResponseBody()
103
+ ),
104
+ $response->getResponseHttpCode()
105
+ );
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Include an accessToken in a given apiHttpRequest.
111
+ * @param Google_Http_Request $request
112
+ * @return Google_Http_Request
113
+ * @throws Google_Auth_Exception
114
+ */
115
+ public function sign(Google_Http_Request $request)
116
+ {
117
+ if ($this->isAccessTokenExpired()) {
118
+ $this->acquireAccessToken();
119
+ }
120
+
121
+ $this->client->getLogger()->debug('Compute engine service account authentication');
122
+
123
+ $request->setRequestHeaders(
124
+ array('Authorization' => 'Bearer ' . $this->token['access_token'])
125
+ );
126
+
127
+ return $request;
128
+ }
129
+
130
+ /**
131
+ * Returns if the access_token is expired.
132
+ * @return bool Returns True if the access_token is expired.
133
+ */
134
+ public function isAccessTokenExpired()
135
+ {
136
+ if (!$this->token || !isset($this->token['created'])) {
137
+ return true;
138
+ }
139
+
140
+ // If the token is set to expire in the next 30 seconds.
141
+ $expired = ($this->token['created']
142
+ + ($this->token['expires_in'] - 30)) < time();
143
+
144
+ return $expired;
145
+ }
146
+ }
addons/pro/googlesheet/lib/external/Google/Auth/Exception.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2013 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ class Google_Auth_Exception extends Google_Exception
23
+ {
24
+ }
addons/pro/googlesheet/lib/external/Google/Auth/LoginTicket.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * Class to hold information about an authenticated login.
24
+ *
25
+ * @author Brian Eaton <beaton@google.com>
26
+ */
27
+ class Google_Auth_LoginTicket
28
+ {
29
+ const USER_ATTR = "sub";
30
+
31
+ // Information from id token envelope.
32
+ private $envelope;
33
+
34
+ // Information from id token payload.
35
+ private $payload;
36
+
37
+ /**
38
+ * Creates a user based on the supplied token.
39
+ *
40
+ * @param string $envelope Header from a verified authentication token.
41
+ * @param string $payload Information from a verified authentication token.
42
+ */
43
+ public function __construct($envelope, $payload)
44
+ {
45
+ $this->envelope = $envelope;
46
+ $this->payload = $payload;
47
+ }
48
+
49
+ /**
50
+ * Returns the numeric identifier for the user.
51
+ * @throws Google_Auth_Exception
52
+ * @return
53
+ */
54
+ public function getUserId()
55
+ {
56
+ if (array_key_exists(self::USER_ATTR, $this->payload)) {
57
+ return $this->payload[self::USER_ATTR];
58
+ }
59
+ throw new Google_Auth_Exception("No user_id in token");
60
+ }
61
+
62
+ /**
63
+ * Returns attributes from the login ticket. This can contain
64
+ * various information about the user session.
65
+ * @return array
66
+ */
67
+ public function getAttributes()
68
+ {
69
+ return array("envelope" => $this->envelope, "payload" => $this->payload);
70
+ }
71
+ }
addons/pro/googlesheet/lib/external/Google/Auth/OAuth2.php ADDED
@@ -0,0 +1,646 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2008 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * Authentication class that deals with the OAuth 2 web-server authentication flow
24
+ *
25
+ */
26
+ class Google_Auth_OAuth2 extends Google_Auth_Abstract
27
+ {
28
+ const OAUTH2_REVOKE_URI = 'https://accounts.google.com/o/oauth2/revoke';
29
+ const OAUTH2_TOKEN_URI = 'https://accounts.google.com/o/oauth2/token';
30
+ const OAUTH2_AUTH_URL = 'https://accounts.google.com/o/oauth2/auth';
31
+ const CLOCK_SKEW_SECS = 300; // five minutes in seconds
32
+ const AUTH_TOKEN_LIFETIME_SECS = 300; // five minutes in seconds
33
+ const MAX_TOKEN_LIFETIME_SECS = 86400; // one day in seconds
34
+ const OAUTH2_ISSUER = 'accounts.google.com';
35
+ const OAUTH2_ISSUER_HTTPS = 'https://accounts.google.com';
36
+
37
+ /** @var Google_Auth_AssertionCredentials $assertionCredentials */
38
+ private $assertionCredentials;
39
+
40
+ /**
41
+ * @var string The state parameters for CSRF and other forgery protection.
42
+ */
43
+ private $state;
44
+
45
+ /**
46
+ * @var array The token bundle.
47
+ */
48
+ private $token = array();
49
+
50
+ /**
51
+ * @var Google_Client the base client
52
+ */
53
+ private $client;
54
+
55
+ /**
56
+ * Instantiates the class, but does not initiate the login flow, leaving it
57
+ * to the discretion of the caller.
58
+ */
59
+ public function __construct(Google_Client $client)
60
+ {
61
+ $this->client = $client;
62
+ }
63
+
64
+ /**
65
+ * Perform an authenticated / signed apiHttpRequest.
66
+ * This function takes the apiHttpRequest, calls apiAuth->sign on it
67
+ * (which can modify the request in what ever way fits the auth mechanism)
68
+ * and then calls apiCurlIO::makeRequest on the signed request
69
+ *
70
+ * @param Google_Http_Request $request
71
+ * @return Google_Http_Request The resulting HTTP response including the
72
+ * responseHttpCode, responseHeaders and responseBody.
73
+ */
74
+ public function authenticatedRequest(Google_Http_Request $request)
75
+ {
76
+ $request = $this->sign($request);
77
+ return $this->client->getIo()->makeRequest($request);
78
+ }
79
+
80
+ /**
81
+ * @param string $code
82
+ * @param boolean $crossClient
83
+ * @throws Google_Auth_Exception
84
+ * @return string
85
+ */
86
+ public function authenticate($code, $crossClient = false)
87
+ {
88
+ if (strlen($code) == 0) {
89
+ throw new Google_Auth_Exception("Invalid code");
90
+ }
91
+
92
+ $arguments = array(
93
+ 'code' => $code,
94
+ 'grant_type' => 'authorization_code',
95
+ 'client_id' => $this->client->getClassConfig($this, 'client_id'),
96
+ 'client_secret' => $this->client->getClassConfig($this, 'client_secret')
97
+ );
98
+
99
+ if ($crossClient !== true) {
100
+ $arguments['redirect_uri'] = $this->client->getClassConfig($this, 'redirect_uri');
101
+ }
102
+
103
+ // We got here from the redirect from a successful authorization grant,
104
+ // fetch the access token
105
+ $request = new Google_Http_Request(
106
+ self::OAUTH2_TOKEN_URI,
107
+ 'POST',
108
+ array(),
109
+ $arguments
110
+ );
111
+ $request->disableGzip();
112
+ $response = $this->client->getIo()->makeRequest($request);
113
+
114
+ if ($response->getResponseHttpCode() == 200) {
115
+ $this->setAccessToken($response->getResponseBody());
116
+ $this->token['created'] = time();
117
+ return $this->getAccessToken();
118
+ } else {
119
+ $decodedResponse = json_decode($response->getResponseBody(), true);
120
+ if ($decodedResponse != null && $decodedResponse['error']) {
121
+ $errorText = $decodedResponse['error'];
122
+ if (isset($decodedResponse['error_description'])) {
123
+ $errorText .= ": " . $decodedResponse['error_description'];
124
+ }
125
+ }
126
+ throw new Google_Auth_Exception(
127
+ sprintf(
128
+ "Error fetching OAuth2 access token, message: '%s'",
129
+ $errorText
130
+ ),
131
+ $response->getResponseHttpCode()
132
+ );
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Create a URL to obtain user authorization.
138
+ * The authorization endpoint allows the user to first
139
+ * authenticate, and then grant/deny the access request.
140
+ * @param string $scope The scope is expressed as a list of space-delimited strings.
141
+ * @return string
142
+ */
143
+ public function createAuthUrl($scope)
144
+ {
145
+ $params = array(
146
+ 'response_type' => 'code',
147
+ 'redirect_uri' => $this->client->getClassConfig($this, 'redirect_uri'),
148
+ 'client_id' => $this->client->getClassConfig($this, 'client_id'),
149
+ 'scope' => $scope,
150
+ 'access_type' => $this->client->getClassConfig($this, 'access_type'),
151
+ );
152
+
153
+ // Prefer prompt to approval prompt.
154
+ if ($this->client->getClassConfig($this, 'prompt')) {
155
+ $params = $this->maybeAddParam($params, 'prompt');
156
+ } else {
157
+ $params = $this->maybeAddParam($params, 'approval_prompt');
158
+ }
159
+ $params = $this->maybeAddParam($params, 'login_hint');
160
+ $params = $this->maybeAddParam($params, 'hd');
161
+ $params = $this->maybeAddParam($params, 'openid.realm');
162
+ $params = $this->maybeAddParam($params, 'include_granted_scopes');
163
+
164
+ // If the list of scopes contains plus.login, add request_visible_actions
165
+ // to auth URL.
166
+ $rva = $this->client->getClassConfig($this, 'request_visible_actions');
167
+ if (strpos($scope, 'plus.login') && strlen($rva) > 0) {
168
+ $params['request_visible_actions'] = $rva;
169
+ }
170
+
171
+ if (isset($this->state)) {
172
+ $params['state'] = $this->state;
173
+ }
174
+
175
+ return self::OAUTH2_AUTH_URL . "?" . http_build_query($params, '', '&');
176
+ }
177
+
178
+ /**
179
+ * @param string $token
180
+ * @throws Google_Auth_Exception
181
+ */
182
+ public function setAccessToken($token)
183
+ {
184
+ $token = json_decode($token, true);
185
+ if ($token == null) {
186
+ throw new Google_Auth_Exception('Could not json decode the token');
187
+ }
188
+ if (! isset($token['access_token'])) {
189
+ throw new Google_Auth_Exception("Invalid token format");
190
+ }
191
+ $this->token = $token;
192
+ }
193
+
194
+ public function getAccessToken()
195
+ {
196
+ return json_encode($this->token);
197
+ }
198
+
199
+ public function getRefreshToken()
200
+ {
201
+ if (array_key_exists('refresh_token', $this->token)) {
202
+ return $this->token['refresh_token'];
203
+ } else {
204
+ return null;
205
+ }
206
+ }
207
+
208
+ public function setState($state)
209
+ {
210
+ $this->state = $state;
211
+ }
212
+
213
+ public function setAssertionCredentials(Google_Auth_AssertionCredentials $creds)
214
+ {
215
+ $this->assertionCredentials = $creds;
216
+ }
217
+
218
+ /**
219
+ * Include an accessToken in a given apiHttpRequest.
220
+ * @param Google_Http_Request $request
221
+ * @return Google_Http_Request
222
+ * @throws Google_Auth_Exception
223
+ */
224
+ public function sign(Google_Http_Request $request)
225
+ {
226
+ // add the developer key to the request before signing it
227
+ if ($this->client->getClassConfig($this, 'developer_key')) {
228
+ $request->setQueryParam('key', $this->client->getClassConfig($this, 'developer_key'));
229
+ }
230
+
231
+ // Cannot sign the request without an OAuth access token.
232
+ if (null == $this->token && null == $this->assertionCredentials) {
233
+ return $request;
234
+ }
235
+
236
+ // Check if the token is set to expire in the next 30 seconds
237
+ // (or has already expired).
238
+ if ($this->isAccessTokenExpired()) {
239
+ if ($this->assertionCredentials) {
240
+ $this->refreshTokenWithAssertion();
241
+ } else {
242
+ $this->client->getLogger()->debug('OAuth2 access token expired');
243
+ if (! array_key_exists('refresh_token', $this->token)) {
244
+ $error = "The OAuth 2.0 access token has expired,"
245
+ ." and a refresh token is not available. Refresh tokens"
246
+ ." are not returned for responses that were auto-approved.";
247
+
248
+ $this->client->getLogger()->error($error);
249
+ throw new Google_Auth_Exception($error);
250
+ }
251
+ $this->refreshToken($this->token['refresh_token']);
252
+ }
253
+ }
254
+
255
+ $this->client->getLogger()->debug('OAuth2 authentication');
256
+
257
+ // Add the OAuth2 header to the request
258
+ $request->setRequestHeaders(
259
+ array('Authorization' => 'Bearer ' . $this->token['access_token'])
260
+ );
261
+
262
+ return $request;
263
+ }
264
+
265
+ /**
266
+ * Fetches a fresh access token with the given refresh token.
267
+ * @param string $refreshToken
268
+ * @return void
269
+ */
270
+ public function refreshToken($refreshToken)
271
+ {
272
+ $this->refreshTokenRequest(
273
+ array(
274
+ 'client_id' => $this->client->getClassConfig($this, 'client_id'),
275
+ 'client_secret' => $this->client->getClassConfig($this, 'client_secret'),
276
+ 'refresh_token' => $refreshToken,
277
+ 'grant_type' => 'refresh_token'
278
+ )
279
+ );
280
+ }
281
+
282
+ /**
283
+ * Fetches a fresh access token with a given assertion token.
284
+ * @param Google_Auth_AssertionCredentials $assertionCredentials optional.
285
+ * @return void
286
+ */
287
+ public function refreshTokenWithAssertion($assertionCredentials = null)
288
+ {
289
+ if (!$assertionCredentials) {
290
+ $assertionCredentials = $this->assertionCredentials;
291
+ }
292
+
293
+ $cacheKey = $assertionCredentials->getCacheKey();
294
+
295
+ if ($cacheKey) {
296
+ // We can check whether we have a token available in the
297
+ // cache. If it is expired, we can retrieve a new one from
298
+ // the assertion.
299
+ $token = $this->client->getCache()->get($cacheKey);
300
+ if ($token) {
301
+ $this->setAccessToken($token);
302
+ }
303
+ if (!$this->isAccessTokenExpired()) {
304
+ return;
305
+ }
306
+ }
307
+
308
+ $this->client->getLogger()->debug('OAuth2 access token expired');
309
+ $this->refreshTokenRequest(
310
+ array(
311
+ 'grant_type' => 'assertion',
312
+ 'assertion_type' => $assertionCredentials->assertionType,
313
+ 'assertion' => $assertionCredentials->generateAssertion(),
314
+ )
315
+ );
316
+
317
+ if ($cacheKey) {
318
+ // Attempt to cache the token.
319
+ $this->client->getCache()->set(
320
+ $cacheKey,
321
+ $this->getAccessToken()
322
+ );
323
+ }
324
+ }
325
+
326
+ private function refreshTokenRequest($params)
327
+ {
328
+ if (isset($params['assertion'])) {
329
+ $this->client->getLogger()->info(
330
+ 'OAuth2 access token refresh with Signed JWT assertion grants.'
331
+ );
332
+ } else {
333
+ $this->client->getLogger()->info('OAuth2 access token refresh');
334
+ }
335
+
336
+ $http = new Google_Http_Request(
337
+ self::OAUTH2_TOKEN_URI,
338
+ 'POST',
339
+ array(),
340
+ $params
341
+ );
342
+ $http->disableGzip();
343
+ $request = $this->client->getIo()->makeRequest($http);
344
+
345
+ $code = $request->getResponseHttpCode();
346
+ $body = $request->getResponseBody();
347
+ if (200 == $code) {
348
+ $token = json_decode($body, true);
349
+ if ($token == null) {
350
+ throw new Google_Auth_Exception("Could not json decode the access token");
351
+ }
352
+
353
+ if (! isset($token['access_token']) || ! isset($token['expires_in'])) {
354
+ throw new Google_Auth_Exception("Invalid token format");
355
+ }
356
+
357
+ if (isset($token['id_token'])) {
358
+ $this->token['id_token'] = $token['id_token'];
359
+ }
360
+ $this->token['access_token'] = $token['access_token'];
361
+ $this->token['expires_in'] = $token['expires_in'];
362
+ $this->token['created'] = time();
363
+ } else {
364
+ throw new Google_Auth_Exception("Error refreshing the OAuth2 token, message: '$body'", $code);
365
+ }
366
+ }
367
+
368
+ /**
369
+ * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
370
+ * token, if a token isn't provided.
371
+ * @throws Google_Auth_Exception
372
+ * @param string|null $token The token (access token or a refresh token) that should be revoked.
373
+ * @return boolean Returns True if the revocation was successful, otherwise False.
374
+ */
375
+ public function revokeToken($token = null)
376
+ {
377
+ if (!$token) {
378
+ if (!$this->token) {
379
+ // Not initialized, no token to actually revoke
380
+ return false;
381
+ } elseif (array_key_exists('refresh_token', $this->token)) {
382
+ $token = $this->token['refresh_token'];
383
+ } else {
384
+ $token = $this->token['access_token'];
385
+ }
386
+ }
387
+ $request = new Google_Http_Request(
388
+ self::OAUTH2_REVOKE_URI,
389
+ 'POST',
390
+ array(),
391
+ "token=$token"
392
+ );
393
+ $request->disableGzip();
394
+ $response = $this->client->getIo()->makeRequest($request);
395
+ $code = $response->getResponseHttpCode();
396
+ if ($code == 200) {
397
+ $this->token = null;
398
+ return true;
399
+ }
400
+
401
+ return false;
402
+ }
403
+
404
+ /**
405
+ * Returns if the access_token is expired.
406
+ * @return bool Returns True if the access_token is expired.
407
+ */
408
+ public function isAccessTokenExpired()
409
+ {
410
+ if (!$this->token || !isset($this->token['created'])) {
411
+ return true;
412
+ }
413
+
414
+ // If the token is set to expire in the next 30 seconds.
415
+ $expired = ($this->token['created']
416
+ + ($this->token['expires_in'] - 30)) < time();
417
+
418
+ return $expired;
419
+ }
420
+
421
+ // Gets federated sign-on certificates to use for verifying identity tokens.
422
+ // Returns certs as array structure, where keys are key ids, and values
423
+ // are PEM encoded certificates.
424
+ private function getFederatedSignOnCerts()
425
+ {
426
+ return $this->retrieveCertsFromLocation(
427
+ $this->client->getClassConfig($this, 'federated_signon_certs_url')
428
+ );
429
+ }
430
+
431
+ /**
432
+ * Retrieve and cache a certificates file.
433
+ *
434
+ * @param $url string location
435
+ * @throws Google_Auth_Exception
436
+ * @return array certificates
437
+ */
438
+ public function retrieveCertsFromLocation($url)
439
+ {
440
+ // If we're retrieving a local file, just grab it.
441
+ if ("http" != substr($url, 0, 4)) {
442
+ $file = file_get_contents($url);
443
+ if ($file) {
444
+ return json_decode($file, true);
445
+ } else {
446
+ throw new Google_Auth_Exception(
447
+ "Failed to retrieve verification certificates: '" .
448
+ $url . "'."
449
+ );
450
+ }
451
+ }
452
+
453
+ // This relies on makeRequest caching certificate responses.
454
+ $request = $this->client->getIo()->makeRequest(
455
+ new Google_Http_Request(
456
+ $url
457
+ )
458
+ );
459
+ if ($request->getResponseHttpCode() == 200) {
460
+ $certs = json_decode($request->getResponseBody(), true);
461
+ if ($certs) {
462
+ return $certs;
463
+ }
464
+ }
465
+ throw new Google_Auth_Exception(
466
+ "Failed to retrieve verification certificates: '" .
467
+ $request->getResponseBody() . "'.",
468
+ $request->getResponseHttpCode()
469
+ );
470
+ }
471
+
472
+ /**
473
+ * Verifies an id token and returns the authenticated apiLoginTicket.
474
+ * Throws an exception if the id token is not valid.
475
+ * The audience parameter can be used to control which id tokens are
476
+ * accepted. By default, the id token must have been issued to this OAuth2 client.
477
+ *
478
+ * @param $id_token
479
+ * @param $audience
480
+ * @return Google_Auth_LoginTicket
481
+ */
482
+ public function verifyIdToken($id_token = null, $audience = null)
483
+ {
484
+ if (!$id_token) {
485
+ $id_token = $this->token['id_token'];
486
+ }
487
+ $certs = $this->getFederatedSignonCerts();
488
+ if (!$audience) {
489
+ $audience = $this->client->getClassConfig($this, 'client_id');
490
+ }
491
+
492
+ return $this->verifySignedJwtWithCerts(
493
+ $id_token,
494
+ $certs,
495
+ $audience,
496
+ array(self::OAUTH2_ISSUER, self::OAUTH2_ISSUER_HTTPS)
497
+ );
498
+ }
499
+
500
+ /**
501
+ * Verifies the id token, returns the verified token contents.
502
+ *
503
+ * @param $jwt string the token
504
+ * @param $certs array of certificates
505
+ * @param $required_audience string the expected consumer of the token
506
+ * @param [$issuer] the expected issues, defaults to Google
507
+ * @param [$max_expiry] the max lifetime of a token, defaults to MAX_TOKEN_LIFETIME_SECS
508
+ * @throws Google_Auth_Exception
509
+ * @return mixed token information if valid, false if not
510
+ */
511
+ public function verifySignedJwtWithCerts(
512
+ $jwt,
513
+ $certs,
514
+ $required_audience,
515
+ $issuer = null,
516
+ $max_expiry = null
517
+ ) {
518
+ if (!$max_expiry) {
519
+ // Set the maximum time we will accept a token for.
520
+ $max_expiry = self::MAX_TOKEN_LIFETIME_SECS;
521
+ }
522
+
523
+ $segments = explode(".", $jwt);
524
+ if (count($segments) != 3) {
525
+ throw new Google_Auth_Exception("Wrong number of segments in token: $jwt");
526
+ }
527
+ $signed = $segments[0] . "." . $segments[1];
528
+ $signature = Google_Utils::urlSafeB64Decode($segments[2]);
529
+
530
+ // Parse envelope.
531
+ $envelope = json_decode(Google_Utils::urlSafeB64Decode($segments[0]), true);
532
+ if (!$envelope) {
533
+ throw new Google_Auth_Exception("Can't parse token envelope: " . $segments[0]);
534
+ }
535
+
536
+ // Parse token
537
+ $json_body = Google_Utils::urlSafeB64Decode($segments[1]);
538
+ $payload = json_decode($json_body, true);
539
+ if (!$payload) {
540
+ throw new Google_Auth_Exception("Can't parse token payload: " . $segments[1]);
541
+ }
542
+
543
+ // Check signature
544
+ $verified = false;
545
+ foreach ($certs as $keyName => $pem) {
546
+ $public_key = new Google_Verifier_Pem($pem);
547
+ if ($public_key->verify($signed, $signature)) {
548
+ $verified = true;
549
+ break;
550
+ }
551
+ }
552
+
553
+ if (!$verified) {
554
+ throw new Google_Auth_Exception("Invalid token signature: $jwt");
555
+ }
556
+
557
+ // Check issued-at timestamp
558
+ $iat = 0;
559
+ if (array_key_exists("iat", $payload)) {
560
+ $iat = $payload["iat"];
561
+ }
562
+ if (!$iat) {
563
+ throw new Google_Auth_Exception("No issue time in token: $json_body");
564
+ }
565
+ $earliest = $iat - self::CLOCK_SKEW_SECS;
566
+
567
+ // Check expiration timestamp
568
+ $now = time();
569
+ $exp = 0;
570
+ if (array_key_exists("exp", $payload)) {
571
+ $exp = $payload["exp"];
572
+ }
573
+ if (!$exp) {
574
+ throw new Google_Auth_Exception("No expiration time in token: $json_body");
575
+ }
576
+ if ($exp >= $now + $max_expiry) {
577
+ throw new Google_Auth_Exception(
578
+ sprintf("Expiration time too far in future: %s", $json_body)
579
+ );
580
+ }
581
+
582
+ $latest = $exp + self::CLOCK_SKEW_SECS;
583
+ if ($now < $earliest) {
584
+ throw new Google_Auth_Exception(
585
+ sprintf(
586
+ "Token used too early, %s < %s: %s",
587
+ $now,
588
+ $earliest,
589
+ $json_body
590
+ )
591
+ );
592
+ }
593
+ if ($now > $latest) {
594
+ throw new Google_Auth_Exception(
595
+ sprintf(
596
+ "Token used too late, %s > %s: %s",
597
+ $now,
598
+ $latest,
599
+ $json_body
600
+ )
601
+ );
602
+ }
603
+
604
+ // support HTTP and HTTPS issuers
605
+ // @see https://developers.google.com/identity/sign-in/web/backend-auth
606
+ $iss = $payload['iss'];
607
+ if ($issuer && !in_array($iss, (array) $issuer)) {
608
+ throw new Google_Auth_Exception(
609
+ sprintf(
610
+ "Invalid issuer, %s not in %s: %s",
611
+ $iss,
612
+ "[".implode(",", (array) $issuer)."]",
613
+ $json_body
614
+ )
615
+ );
616
+ }
617
+
618
+ // Check audience
619
+ $aud = $payload["aud"];
620
+ if ($aud != $required_audience) {
621
+ throw new Google_Auth_Exception(
622
+ sprintf(
623
+ "Wrong recipient, %s != %s:",
624
+ $aud,
625
+ $required_audience,
626
+ $json_body
627
+ )
628
+ );
629
+ }
630
+
631
+ // All good.
632
+ return new Google_Auth_LoginTicket($envelope, $payload);
633
+ }
634
+
635
+ /**
636
+ * Add a parameter to the auth params if not empty string.
637
+ */
638
+ private function maybeAddParam($params, $name)
639
+ {
640
+ $param = $this->client->getClassConfig($this, $name);
641
+ if ($param != '') {
642
+ $params[$name] = $param;
643
+ }
644
+ return $params;
645
+ }
646
+ }
addons/pro/googlesheet/lib/external/Google/Auth/Simple.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * Simple API access implementation. Can either be used to make requests
24
+ * completely unauthenticated, or by using a Simple API Access developer
25
+ * key.
26
+ */
27
+ class Google_Auth_Simple extends Google_Auth_Abstract
28
+ {
29
+ private $client;
30
+
31
+ public function __construct(Google_Client $client, $config = null)
32
+ {
33
+ $this->client = $client;
34
+ }
35
+
36
+ /**
37
+ * Perform an authenticated / signed apiHttpRequest.
38
+ * This function takes the apiHttpRequest, calls apiAuth->sign on it
39
+ * (which can modify the request in what ever way fits the auth mechanism)
40
+ * and then calls apiCurlIO::makeRequest on the signed request
41
+ *
42
+ * @param Google_Http_Request $request
43
+ * @return Google_Http_Request The resulting HTTP response including the
44
+ * responseHttpCode, responseHeaders and responseBody.
45
+ */
46
+ public function authenticatedRequest(Google_Http_Request $request)
47
+ {
48
+ $request = $this->sign($request);
49
+ return $this->io->makeRequest($request);
50
+ }
51
+
52
+ public function sign(Google_Http_Request $request)
53
+ {
54
+ $key = $this->client->getClassConfig($this, 'developer_key');
55
+ if ($key) {
56
+ $this->client->getLogger()->debug(
57
+ 'Simple API Access developer key authentication'
58
+ );
59
+ $request->setQueryParam('key', $key);
60
+ }
61
+ return $request;
62
+ }
63
+ }
addons/pro/googlesheet/lib/external/Google/Cache/Abstract.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2008 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Abstract storage class
20
+ *
21
+ * @author Chris Chabot <chabotc@google.com>
22
+ */
23
+ abstract class Google_Cache_Abstract
24
+ {
25
+
26
+ abstract public function __construct(Google_Client $client);
27
+
28
+ /**
29
+ * Retrieves the data for the given key, or false if they
30
+ * key is unknown or expired
31
+ *
32
+ * @param String $key The key who's data to retrieve
33
+ * @param boolean|int $expiration Expiration time in seconds
34
+ *
35
+ */
36
+ abstract public function get($key, $expiration = false);
37
+
38
+ /**
39
+ * Store the key => $value set. The $value is serialized
40
+ * by this function so can be of any type
41
+ *
42
+ * @param string $key Key of the data
43
+ * @param string $value data
44
+ */
45
+ abstract public function set($key, $value);
46
+
47
+ /**
48
+ * Removes the key/data pair for the given $key
49
+ *
50
+ * @param String $key
51
+ */
52
+ abstract public function delete($key);
53
+ }
addons/pro/googlesheet/lib/external/Google/Cache/Apc.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * A persistent storage class based on the APC cache, which is not
24
+ * really very persistent, as soon as you restart your web server
25
+ * the storage will be wiped, however for debugging and/or speed
26
+ * it can be useful, and cache is a lot cheaper then storage.
27
+ *
28
+ * @author Chris Chabot <chabotc@google.com>
29
+ */
30
+ class Google_Cache_Apc extends Google_Cache_Abstract
31
+ {
32
+ /**
33
+ * @var Google_Client the current client
34
+ */
35
+ private $client;
36
+
37
+ public function __construct(Google_Client $client)
38
+ {
39
+ if (! function_exists('apc_add') ) {
40
+ $error = "Apc functions not available";
41
+
42
+ $client->getLogger()->error($error);
43
+ throw new Google_Cache_Exception($error);
44
+ }
45
+
46
+ $this->client = $client;
47
+ }
48
+
49
+ /**
50
+ * @inheritDoc
51
+ */
52
+ public function get($key, $expiration = false)
53
+ {
54
+ $ret = apc_fetch($key);
55
+ if ($ret === false) {
56
+ $this->client->getLogger()->debug(
57
+ 'APC cache miss',
58
+ array('key' => $key)
59
+ );
60
+ return false;
61
+ }
62
+ if (is_numeric($expiration) && (time() - $ret['time'] > $expiration)) {
63
+ $this->client->getLogger()->debug(
64
+ 'APC cache miss (expired)',
65
+ array('key' => $key, 'var' => $ret)
66
+ );
67
+ $this->delete($key);
68
+ return false;
69
+ }
70
+
71
+ $this->client->getLogger()->debug(
72
+ 'APC cache hit',
73
+ array('key' => $key, 'var' => $ret)
74
+ );
75
+
76
+ return $ret['data'];
77
+ }
78
+
79
+ /**
80
+ * @inheritDoc
81
+ */
82
+ public function set($key, $value)
83
+ {
84
+ $var = array('time' => time(), 'data' => $value);
85
+ $rc = apc_store($key, $var);
86
+
87
+ if ($rc == false) {
88
+ $this->client->getLogger()->error(
89
+ 'APC cache set failed',
90
+ array('key' => $key, 'var' => $var)
91
+ );
92
+ throw new Google_Cache_Exception("Couldn't store data");
93
+ }
94
+
95
+ $this->client->getLogger()->debug(
96
+ 'APC cache set',
97
+ array('key' => $key, 'var' => $var)
98
+ );
99
+ }
100
+
101
+ /**
102
+ * @inheritDoc
103
+ * @param String $key
104
+ */
105
+ public function delete($key)
106
+ {
107
+ $this->client->getLogger()->debug(
108
+ 'APC cache delete',
109
+ array('key' => $key)
110
+ );
111
+ apc_delete($key);
112
+ }
113
+ }
addons/pro/googlesheet/lib/external/Google/Cache/Exception.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2013 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ class Google_Cache_Exception extends Google_Exception
23
+ {
24
+ }
addons/pro/googlesheet/lib/external/Google/Cache/File.php ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2008 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /*
23
+ * This class implements a basic on disk storage. While that does
24
+ * work quite well it's not the most elegant and scalable solution.
25
+ * It will also get you into a heap of trouble when you try to run
26
+ * this in a clustered environment.
27
+ *
28
+ * @author Chris Chabot <chabotc@google.com>
29
+ */
30
+ class Google_Cache_File extends Google_Cache_Abstract
31
+ {
32
+ const MAX_LOCK_RETRIES = 10;
33
+ private $path;
34
+ private $fh;
35
+
36
+ /**
37
+ * @var Google_Client the current client
38
+ */
39
+ private $client;
40
+
41
+ public function __construct(Google_Client $client)
42
+ {
43
+ $this->client = $client;
44
+ $this->path = $this->client->getClassConfig($this, 'directory');
45
+ }
46
+
47
+ public function get($key, $expiration = false)
48
+ {
49
+ $storageFile = $this->getCacheFile($key);
50
+ $data = false;
51
+
52
+ if (!file_exists($storageFile)) {
53
+ $this->client->getLogger()->debug(
54
+ 'File cache miss',
55
+ array('key' => $key, 'file' => $storageFile)
56
+ );
57
+ return false;
58
+ }
59
+
60
+ if ($expiration) {
61
+ $mtime = filemtime($storageFile);
62
+ if ((time() - $mtime) >= $expiration) {
63
+ $this->client->getLogger()->debug(
64
+ 'File cache miss (expired)',
65
+ array('key' => $key, 'file' => $storageFile)
66
+ );
67
+ $this->delete($key);
68
+ return false;
69
+ }
70
+ }
71
+
72
+ if ($this->acquireReadLock($storageFile)) {
73
+ if (filesize($storageFile) > 0) {
74
+ $data = fread($this->fh, filesize($storageFile));
75
+ $data = unserialize($data);
76
+ } else {
77
+ $this->client->getLogger()->debug(
78
+ 'Cache file was empty',
79
+ array('file' => $storageFile)
80
+ );
81
+ }
82
+ $this->unlock($storageFile);
83
+ }
84
+
85
+ $this->client->getLogger()->debug(
86
+ 'File cache hit',
87
+ array('key' => $key, 'file' => $storageFile, 'var' => $data)
88
+ );
89
+
90
+ return $data;
91
+ }
92
+
93
+ public function set($key, $value)
94
+ {
95
+ $storageFile = $this->getWriteableCacheFile($key);
96
+ if ($this->acquireWriteLock($storageFile)) {
97
+ // We serialize the whole request object, since we don't only want the
98
+ // responseContent but also the postBody used, headers, size, etc.
99
+ $data = serialize($value);
100
+ $result = fwrite($this->fh, $data);
101
+ $this->unlock($storageFile);
102
+
103
+ $this->client->getLogger()->debug(
104
+ 'File cache set',
105
+ array('key' => $key, 'file' => $storageFile, 'var' => $value)
106
+ );
107
+ } else {
108
+ $this->client->getLogger()->notice(
109
+ 'File cache set failed',
110
+ array('key' => $key, 'file' => $storageFile)
111
+ );
112
+ }
113
+ }
114
+
115
+ public function delete($key)
116
+ {
117
+ $file = $this->getCacheFile($key);
118
+ if (file_exists($file) && !unlink($file)) {
119
+ $this->client->getLogger()->error(
120
+ 'File cache delete failed',
121
+ array('key' => $key, 'file' => $file)
122
+ );
123
+ throw new Google_Cache_Exception("Cache file could not be deleted");
124
+ }
125
+
126
+ $this->client->getLogger()->debug(
127
+ 'File cache delete',
128
+ array('key' => $key, 'file' => $file)
129
+ );
130
+ }
131
+
132
+ private function getWriteableCacheFile($file)
133
+ {
134
+ return $this->getCacheFile($file, true);
135
+ }
136
+
137
+ private function getCacheFile($file, $forWrite = false)
138
+ {
139
+ return $this->getCacheDir($file, $forWrite) . '/' . md5($file);
140
+ }
141
+
142
+ private function getCacheDir($file, $forWrite)
143
+ {
144
+ // use the first 2 characters of the hash as a directory prefix
145
+ // this should prevent slowdowns due to huge directory listings
146
+ // and thus give some basic amount of scalability
147
+ $storageDir = $this->path . '/' . substr(md5($file), 0, 2);
148
+ if ($forWrite && ! is_dir($storageDir)) {
149
+ if (! mkdir($storageDir, 0700, true)) {
150
+ $this->client->getLogger()->error(
151
+ 'File cache creation failed',
152
+ array('dir' => $storageDir)
153
+ );
154
+ throw new Google_Cache_Exception("Could not create storage directory: $storageDir");
155
+ }
156
+ }
157
+ return $storageDir;
158
+ }
159
+
160
+ private function acquireReadLock($storageFile)
161
+ {
162
+ return $this->acquireLock(LOCK_SH, $storageFile);
163
+ }
164
+
165
+ private function acquireWriteLock($storageFile)
166
+ {
167
+ $rc = $this->acquireLock(LOCK_EX, $storageFile);
168
+ if (!$rc) {
169
+ $this->client->getLogger()->notice(
170
+ 'File cache write lock failed',
171
+ array('file' => $storageFile)
172
+ );
173
+ $this->delete($storageFile);
174
+ }
175
+ return $rc;
176
+ }
177
+
178
+ private function acquireLock($type, $storageFile)
179
+ {
180
+ $mode = $type == LOCK_EX ? "w" : "r";
181
+ $this->fh = fopen($storageFile, $mode);
182
+ if (!$this->fh) {
183
+ $this->client->getLogger()->error(
184
+ 'Failed to open file during lock acquisition',
185
+ array('file' => $storageFile)
186
+ );
187
+ return false;
188
+ }
189
+ if ($type == LOCK_EX) {
190
+ chmod($storageFile, 0600);
191
+ }
192
+ $count = 0;
193
+ while (!flock($this->fh, $type | LOCK_NB)) {
194
+ // Sleep for 10ms.
195
+ usleep(10000);
196
+ if (++$count < self::MAX_LOCK_RETRIES) {
197
+ return false;
198
+ }
199
+ }
200
+ return true;
201
+ }
202
+
203
+ public function unlock($storageFile)
204
+ {
205
+ if ($this->fh) {
206
+ flock($this->fh, LOCK_UN);
207
+ }
208
+ }
209
+ }
addons/pro/googlesheet/lib/external/Google/Cache/Memcache.php ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2008 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * A persistent storage class based on the memcache, which is not
24
+ * really very persistent, as soon as you restart your memcache daemon
25
+ * the storage will be wiped.
26
+ *
27
+ * Will use either the memcache or memcached extensions, preferring
28
+ * memcached.
29
+ *
30
+ * @author Chris Chabot <chabotc@google.com>
31
+ */
32
+ class Google_Cache_Memcache extends Google_Cache_Abstract
33
+ {
34
+ private $connection = false;
35
+ private $mc = false;
36
+ private $host;
37
+ private $port;
38
+
39
+ /**
40
+ * @var Google_Client the current client
41
+ */
42
+ private $client;
43
+
44
+ public function __construct(Google_Client $client)
45
+ {
46
+ if (!function_exists('memcache_connect') && !class_exists("Memcached")) {
47
+ $error = "Memcache functions not available";
48
+
49
+ $client->getLogger()->error($error);
50
+ throw new Google_Cache_Exception($error);
51
+ }
52
+
53
+ $this->client = $client;
54
+
55
+ if ($client->isAppEngine()) {
56
+ // No credentials needed for GAE.
57
+ $this->mc = new Memcached();
58
+ $this->connection = true;
59
+ } else {
60
+ $this->host = $client->getClassConfig($this, 'host');
61
+ $this->port = $client->getClassConfig($this, 'port');
62
+ if (empty($this->host) || (empty($this->port) && (string) $this->port != "0")) {
63
+ $error = "You need to supply a valid memcache host and port";
64
+
65
+ $client->getLogger()->error($error);
66
+ throw new Google_Cache_Exception($error);
67
+ }
68
+ }
69
+ }
70
+
71
+ /**
72
+ * @inheritDoc
73
+ */
74
+ public function get($key, $expiration = false)
75
+ {
76
+ $this->connect();
77
+ $ret = false;
78
+ if ($this->mc) {
79
+ $ret = $this->mc->get($key);
80
+ } else {
81
+ $ret = memcache_get($this->connection, $key);
82
+ }
83
+ if ($ret === false) {
84
+ $this->client->getLogger()->debug(
85
+ 'Memcache cache miss',
86
+ array('key' => $key)
87
+ );
88
+ return false;
89
+ }
90
+ if (is_numeric($expiration) && (time() - $ret['time'] > $expiration)) {
91
+ $this->client->getLogger()->debug(
92
+ 'Memcache cache miss (expired)',
93
+ array('key' => $key, 'var' => $ret)
94
+ );
95
+ $this->delete($key);
96
+ return false;
97
+ }
98
+
99
+ $this->client->getLogger()->debug(
100
+ 'Memcache cache hit',
101
+ array('key' => $key, 'var' => $ret)
102
+ );
103
+
104
+ return $ret['data'];
105
+ }
106
+
107
+ /**
108
+ * @inheritDoc
109
+ * @param string $key
110
+ * @param string $value
111
+ * @throws Google_Cache_Exception
112
+ */
113
+ public function set($key, $value)
114
+ {
115
+ $this->connect();
116
+ // we store it with the cache_time default expiration so objects will at
117
+ // least get cleaned eventually.
118
+ $data = array('time' => time(), 'data' => $value);
119
+ $rc = false;
120
+ if ($this->mc) {
121
+ $rc = $this->mc->set($key, $data);
122
+ } else {
123
+ $rc = memcache_set($this->connection, $key, $data, false);
124
+ }
125
+ if ($rc == false) {
126
+ $this->client->getLogger()->error(
127
+ 'Memcache cache set failed',
128
+ array('key' => $key, 'var' => $data)
129
+ );
130
+
131
+ throw new Google_Cache_Exception("Couldn't store data in cache");
132
+ }
133
+
134
+ $this->client->getLogger()->debug(
135
+ 'Memcache cache set',
136
+ array('key' => $key, 'var' => $data)
137
+ );
138
+ }
139
+
140
+ /**
141
+ * @inheritDoc
142
+ * @param String $key
143
+ */
144
+ public function delete($key)
145
+ {
146
+ $this->connect();
147
+ if ($this->mc) {
148
+ $this->mc->delete($key, 0);
149
+ } else {
150
+ memcache_delete($this->connection, $key, 0);
151
+ }
152
+
153
+ $this->client->getLogger()->debug(
154
+ 'Memcache cache delete',
155
+ array('key' => $key)
156
+ );
157
+ }
158
+
159
+ /**
160
+ * Lazy initialiser for memcache connection. Uses pconnect for to take
161
+ * advantage of the persistence pool where possible.
162
+ */
163
+ private function connect()
164
+ {
165
+ if ($this->connection) {
166
+ return;
167
+ }
168
+
169
+ if (class_exists("Memcached")) {
170
+ $this->mc = new Memcached();
171
+ $this->mc->addServer($this->host, $this->port);
172
+ $this->connection = true;
173
+ } else {
174
+ $this->connection = memcache_pconnect($this->host, $this->port);
175
+ }
176
+
177
+ if (! $this->connection) {
178
+ $error = "Couldn't connect to memcache server";
179
+
180
+ $this->client->getLogger()->error($error);
181
+ throw new Google_Cache_Exception($error);
182
+ }
183
+ }
184
+ }
addons/pro/googlesheet/lib/external/Google/Cache/Null.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2014 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * A blank storage class, for cases where caching is not
24
+ * required.
25
+ */
26
+ class Google_Cache_Null extends Google_Cache_Abstract
27
+ {
28
+ public function __construct(Google_Client $client)
29
+ {
30
+
31
+ }
32
+
33
+ /**
34
+ * @inheritDoc
35
+ */
36
+ public function get($key, $expiration = false)
37
+ {
38
+ return false;
39
+ }
40
+
41
+ /**
42
+ * @inheritDoc
43
+ */
44
+ public function set($key, $value)
45
+ {
46
+ // Nop.
47
+ }
48
+
49
+ /**
50
+ * @inheritDoc
51
+ * @param String $key
52
+ */
53
+ public function delete($key)
54
+ {
55
+ // Nop.
56
+ }
57
+ }
addons/pro/googlesheet/lib/external/Google/Client.php ADDED
@@ -0,0 +1,715 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/autoload.php';
20
+ }
21
+
22
+ /**
23
+ * The Google API Client
24
+ * https://github.com/google/google-api-php-client
25
+ */
26
+ class Google_Client
27
+ {
28
+ const LIBVER = "1.1.5";
29
+ const USER_AGENT_SUFFIX = "google-api-php-client/";
30
+ /**
31
+ * @var Google_Auth_Abstract $auth
32
+ */
33
+ private $auth;
34
+
35
+ /**
36
+ * @var Google_IO_Abstract $io
37
+ */
38
+ private $io;
39
+
40
+ /**
41
+ * @var Google_Cache_Abstract $cache
42
+ */
43
+ private $cache;
44
+
45
+ /**
46
+ * @var Google_Config $config
47
+ */
48
+ private $config;
49
+
50
+ /**
51
+ * @var Google_Logger_Abstract $logger
52
+ */
53
+ private $logger;
54
+
55
+ /**
56
+ * @var boolean $deferExecution
57
+ */
58
+ private $deferExecution = false;
59
+
60
+ /** @var array $scopes */
61
+ // Scopes requested by the client
62
+ protected $requestedScopes = array();
63
+
64
+ // definitions of services that are discovered.
65
+ protected $services = array();
66
+
67
+ // Used to track authenticated state, can't discover services after doing authenticate()
68
+ private $authenticated = false;
69
+
70
+ /**
71
+ * Construct the Google Client.
72
+ *
73
+ * @param $config Google_Config or string for the ini file to load
74
+ */
75
+ public function __construct($config = null)
76
+ {
77
+ if (is_string($config) && strlen($config)) {
78
+ $config = new Google_Config($config);
79
+ } else if ( !($config instanceof Google_Config)) {
80
+ $config = new Google_Config();
81
+
82
+ if ($this->isAppEngine()) {
83
+ // Automatically use Memcache if we're in AppEngine.
84
+ $config->setCacheClass('Google_Cache_Memcache');
85
+ }
86
+
87
+ if (version_compare(phpversion(), "5.3.4", "<=") || $this->isAppEngine()) {
88
+ // Automatically disable compress.zlib, as currently unsupported.
89
+ $config->setClassConfig('Google_Http_Request', 'disable_gzip', true);
90
+ }
91
+ }
92
+
93
+ if ($config->getIoClass() == Google_Config::USE_AUTO_IO_SELECTION) {
94
+ if (function_exists('curl_version') && function_exists('curl_exec')
95
+ && !$this->isAppEngine()) {
96
+ $config->setIoClass("Google_IO_Curl");
97
+ } else {
98
+ $config->setIoClass("Google_IO_Stream");
99
+ }
100
+ }
101
+
102
+ $this->config = $config;
103
+ }
104
+
105
+ /**
106
+ * Get a string containing the version of the library.
107
+ *
108
+ * @return string
109
+ */
110
+ public function getLibraryVersion()
111
+ {
112
+ return self::LIBVER;
113
+ }
114
+
115
+ /**
116
+ * Attempt to exchange a code for an valid authentication token.
117
+ * If $crossClient is set to true, the request body will not include
118
+ * the request_uri argument
119
+ * Helper wrapped around the OAuth 2.0 implementation.
120
+ *
121
+ * @param $code string code from accounts.google.com
122
+ * @param $crossClient boolean, whether this is a cross-client authentication
123
+ * @return string token
124
+ */
125
+ public function authenticate($code, $crossClient = false)
126
+ {
127
+ $this->authenticated = true;
128
+ return $this->getAuth()->authenticate($code, $crossClient);
129
+ }
130
+
131
+ /**
132
+ * Loads a service account key and parameters from a JSON
133
+ * file from the Google Developer Console. Uses that and the
134
+ * given array of scopes to return an assertion credential for
135
+ * use with refreshTokenWithAssertionCredential.
136
+ *
137
+ * @param string $jsonLocation File location of the project-key.json.
138
+ * @param array $scopes The scopes to assert.
139
+ * @return Google_Auth_AssertionCredentials.
140
+ * @
141
+ */
142
+ public function loadServiceAccountJson($jsonLocation, $scopes)
143
+ {
144
+ $data = json_decode(file_get_contents($jsonLocation));
145
+ if (isset($data->type) && $data->type == 'service_account') {
146
+ // Service Account format.
147
+ $cred = new Google_Auth_AssertionCredentials(
148
+ $data->client_email,
149
+ $scopes,
150
+ $data->private_key
151
+ );
152
+ return $cred;
153
+ } else {
154
+ throw new Google_Exception("Invalid service account JSON file.");
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Set the auth config from the JSON string provided.
160
+ * This structure should match the file downloaded from
161
+ * the "Download JSON" button on in the Google Developer
162
+ * Console.
163
+ * @param string $json the configuration json
164
+ * @throws Google_Exception
165
+ */
166
+ public function setAuthConfig($json)
167
+ {
168
+ $data = json_decode($json);
169
+ $key = isset($data->installed) ? 'installed' : 'web';
170
+ if (!isset($data->$key)) {
171
+ throw new Google_Exception("Invalid client secret JSON file.");
172
+ }
173
+ $this->setClientId($data->$key->client_id);
174
+ $this->setClientSecret($data->$key->client_secret);
175
+ if (isset($data->$key->redirect_uris)) {
176
+ $this->setRedirectUri($data->$key->redirect_uris[0]);
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Set the auth config from the JSON file in the path
182
+ * provided. This should match the file downloaded from
183
+ * the "Download JSON" button on in the Google Developer
184
+ * Console.
185
+ * @param string $file the file location of the client json
186
+ */
187
+ public function setAuthConfigFile($file)
188
+ {
189
+ $this->setAuthConfig(file_get_contents($file));
190
+ }
191
+
192
+ /**
193
+ * @throws Google_Auth_Exception
194
+ * @return array
195
+ * @visible For Testing
196
+ */
197
+ public function prepareScopes()
198
+ {
199
+ if (empty($this->requestedScopes)) {
200
+ throw new Google_Auth_Exception("No scopes specified");
201
+ }
202
+ $scopes = implode(' ', $this->requestedScopes);
203
+ return $scopes;
204
+ }
205
+
206
+ /**
207
+ * Set the OAuth 2.0 access token using the string that resulted from calling createAuthUrl()
208
+ * or Google_Client#getAccessToken().
209
+ * @param string $accessToken JSON encoded string containing in the following format:
210
+ * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
211
+ * "expires_in":3600, "id_token":"TOKEN", "created":1320790426}
212
+ */
213
+ public function setAccessToken($accessToken)
214
+ {
215
+ if ($accessToken == 'null') {
216
+ $accessToken = null;
217
+ }
218
+ $this->getAuth()->setAccessToken($accessToken);
219
+ }
220
+
221
+
222
+
223
+ /**
224
+ * Set the authenticator object
225
+ * @param Google_Auth_Abstract $auth
226
+ */
227
+ public function setAuth(Google_Auth_Abstract $auth)
228
+ {
229
+ $this->config->setAuthClass(get_class($auth));
230
+ $this->auth = $auth;
231
+ }
232
+
233
+ /**
234
+ * Set the IO object
235
+ * @param Google_IO_Abstract $io
236
+ */
237
+ public function setIo(Google_IO_Abstract $io)
238
+ {
239
+ $this->config->setIoClass(get_class($io));
240
+ $this->io = $io;
241
+ }
242
+
243
+ /**
244
+ * Set the Cache object
245
+ * @param Google_Cache_Abstract $cache
246
+ */
247
+ public function setCache(Google_Cache_Abstract $cache)
248
+ {
249
+ $this->config->setCacheClass(get_class($cache));
250
+ $this->cache = $cache;
251
+ }
252
+
253
+ /**
254
+ * Set the Logger object
255
+ * @param Google_Logger_Abstract $logger
256
+ */
257
+ public function setLogger(Google_Logger_Abstract $logger)
258
+ {
259
+ $this->config->setLoggerClass(get_class($logger));
260
+ $this->logger = $logger;
261
+ }
262
+
263
+ /**
264
+ * Construct the OAuth 2.0 authorization request URI.
265
+ * @return string
266
+ */
267
+ public function createAuthUrl()
268
+ {
269
+ $scopes = $this->prepareScopes();
270
+ return $this->getAuth()->createAuthUrl($scopes);
271
+ }
272
+
273
+ /**
274
+ * Get the OAuth 2.0 access token.
275
+ * @return string $accessToken JSON encoded string in the following format:
276
+ * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer",
277
+ * "expires_in":3600,"id_token":"TOKEN", "created":1320790426}
278
+ */
279
+ public function getAccessToken()
280
+ {
281
+ $token = $this->getAuth()->getAccessToken();
282
+ // The response is json encoded, so could be the string null.
283
+ // It is arguable whether this check should be here or lower
284
+ // in the library.
285
+ return (null == $token || 'null' == $token || '[]' == $token) ? null : $token;
286
+ }
287
+
288
+ /**
289
+ * Get the OAuth 2.0 refresh token.
290
+ * @return string $refreshToken refresh token or null if not available
291
+ */
292
+ public function getRefreshToken()
293
+ {
294
+ return $this->getAuth()->getRefreshToken();
295
+ }
296
+
297
+ /**
298
+ * Returns if the access_token is expired.
299
+ * @return bool Returns True if the access_token is expired.
300
+ */
301
+ public function isAccessTokenExpired()
302
+ {
303
+ return $this->getAuth()->isAccessTokenExpired();
304
+ }
305
+
306
+ /**
307
+ * Set OAuth 2.0 "state" parameter to achieve per-request customization.
308
+ * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.1.2.2
309
+ * @param string $state
310
+ */
311
+ public function setState($state)
312
+ {
313
+ $this->getAuth()->setState($state);
314
+ }
315
+
316
+ /**
317
+ * @param string $accessType Possible values for access_type include:
318
+ * {@code "offline"} to request offline access from the user.
319
+ * {@code "online"} to request online access from the user.
320
+ */
321
+ public function setAccessType($accessType)
322
+ {
323
+ $this->config->setAccessType($accessType);
324
+ }
325
+
326
+ /**
327
+ * @param string $approvalPrompt Possible values for approval_prompt include:
328
+ * {@code "force"} to force the approval UI to appear. (This is the default value)
329
+ * {@code "auto"} to request auto-approval when possible.
330
+ */
331
+ public function setApprovalPrompt($approvalPrompt)
332
+ {
333
+ $this->config->setApprovalPrompt($approvalPrompt);
334
+ }
335
+
336
+ /**
337
+ * Set the login hint, email address or sub id.
338
+ * @param string $loginHint
339
+ */
340
+ public function setLoginHint($loginHint)
341
+ {
342
+ $this->config->setLoginHint($loginHint);
343
+ }
344
+
345
+ /**
346
+ * Set the application name, this is included in the User-Agent HTTP header.
347
+ * @param string $applicationName
348
+ */
349
+ public function setApplicationName($applicationName)
350
+ {
351
+ $this->config->setApplicationName($applicationName);
352
+ }
353
+
354
+ /**
355
+ * Set the OAuth 2.0 Client ID.
356
+ * @param string $clientId
357
+ */
358
+ public function setClientId($clientId)
359
+ {
360
+ $this->config->setClientId($clientId);
361
+ }
362
+
363
+ /**
364
+ * Set the OAuth 2.0 Client Secret.
365
+ * @param string $clientSecret
366
+ */
367
+ public function setClientSecret($clientSecret)
368
+ {
369
+ $this->config->setClientSecret($clientSecret);
370
+ }
371
+
372
+ /**
373
+ * Set the OAuth 2.0 Redirect URI.
374
+ * @param string $redirectUri
375
+ */
376
+ public function setRedirectUri($redirectUri)
377
+ {
378
+ $this->config->setRedirectUri($redirectUri);
379
+ }
380
+
381
+ /**
382
+ * If 'plus.login' is included in the list of requested scopes, you can use
383
+ * this method to define types of app activities that your app will write.
384
+ * You can find a list of available types here:
385
+ * @link https://developers.google.com/+/api/moment-types
386
+ *
387
+ * @param array $requestVisibleActions Array of app activity types
388
+ */
389
+ public function setRequestVisibleActions($requestVisibleActions)
390
+ {
391
+ if (is_array($requestVisibleActions)) {
392
+ $requestVisibleActions = join(" ", $requestVisibleActions);
393
+ }
394
+ $this->config->setRequestVisibleActions($requestVisibleActions);
395
+ }
396
+
397
+ /**
398
+ * Set the developer key to use, these are obtained through the API Console.
399
+ * @see http://code.google.com/apis/console-help/#generatingdevkeys
400
+ * @param string $developerKey
401
+ */
402
+ public function setDeveloperKey($developerKey)
403
+ {
404
+ $this->config->setDeveloperKey($developerKey);
405
+ }
406
+
407
+ /**
408
+ * Set the hd (hosted domain) parameter streamlines the login process for
409
+ * Google Apps hosted accounts. By including the domain of the user, you
410
+ * restrict sign-in to accounts at that domain.
411
+ * @param $hd string - the domain to use.
412
+ */
413
+ public function setHostedDomain($hd)
414
+ {
415
+ $this->config->setHostedDomain($hd);
416
+ }
417
+
418
+ /**
419
+ * Set the prompt hint. Valid values are none, consent and select_account.
420
+ * If no value is specified and the user has not previously authorized
421
+ * access, then the user is shown a consent screen.
422
+ * @param $prompt string
423
+ */
424
+ public function setPrompt($prompt)
425
+ {
426
+ $this->config->setPrompt($prompt);
427
+ }
428
+
429
+ /**
430
+ * openid.realm is a parameter from the OpenID 2.0 protocol, not from OAuth
431
+ * 2.0. It is used in OpenID 2.0 requests to signify the URL-space for which
432
+ * an authentication request is valid.
433
+ * @param $realm string - the URL-space to use.
434
+ */
435
+ public function setOpenidRealm($realm)
436
+ {
437
+ $this->config->setOpenidRealm($realm);
438
+ }
439
+
440
+ /**
441
+ * If this is provided with the value true, and the authorization request is
442
+ * granted, the authorization will include any previous authorizations
443
+ * granted to this user/application combination for other scopes.
444
+ * @param $include boolean - the URL-space to use.
445
+ */
446
+ public function setIncludeGrantedScopes($include)
447
+ {
448
+ $this->config->setIncludeGrantedScopes($include);
449
+ }
450
+
451
+ /**
452
+ * Fetches a fresh OAuth 2.0 access token with the given refresh token.
453
+ * @param string $refreshToken
454
+ */
455
+ public function refreshToken($refreshToken)
456
+ {
457
+ $this->getAuth()->refreshToken($refreshToken);
458
+ }
459
+
460
+ /**
461
+ * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
462
+ * token, if a token isn't provided.
463
+ * @throws Google_Auth_Exception
464
+ * @param string|null $token The token (access token or a refresh token) that should be revoked.
465
+ * @return boolean Returns True if the revocation was successful, otherwise False.
466
+ */
467
+ public function revokeToken($token = null)
468
+ {
469
+ return $this->getAuth()->revokeToken($token);
470
+ }
471
+
472
+ /**
473
+ * Verify an id_token. This method will verify the current id_token, if one
474
+ * isn't provided.
475
+ * @throws Google_Auth_Exception
476
+ * @param string|null $token The token (id_token) that should be verified.
477
+ * @return Google_Auth_LoginTicket Returns an apiLoginTicket if the verification was
478
+ * successful.
479
+ */
480
+ public function verifyIdToken($token = null)
481
+ {
482
+ return $this->getAuth()->verifyIdToken($token);
483
+ }
484
+
485
+ /**
486
+ * Verify a JWT that was signed with your own certificates.
487
+ *
488
+ * @param $id_token string The JWT token
489
+ * @param $cert_location array of certificates
490
+ * @param $audience string the expected consumer of the token
491
+ * @param $issuer string the expected issuer, defaults to Google
492
+ * @param [$max_expiry] the max lifetime of a token, defaults to MAX_TOKEN_LIFETIME_SECS
493
+ * @return mixed token information if valid, false if not
494
+ */
495
+ public function verifySignedJwt($id_token, $cert_location, $audience, $issuer, $max_expiry = null)
496
+ {
497
+ $auth = new Google_Auth_OAuth2($this);
498
+ $certs = $auth->retrieveCertsFromLocation($cert_location);
499
+ return $auth->verifySignedJwtWithCerts($id_token, $certs, $audience, $issuer, $max_expiry);
500
+ }
501
+
502
+ /**
503
+ * @param $creds Google_Auth_AssertionCredentials
504
+ */
505
+ public function setAssertionCredentials(Google_Auth_AssertionCredentials $creds)
506
+ {
507
+ $this->getAuth()->setAssertionCredentials($creds);
508
+ }
509
+
510
+ /**
511
+ * Set the scopes to be requested. Must be called before createAuthUrl().
512
+ * Will remove any previously configured scopes.
513
+ * @param array $scopes, ie: array('https://www.googleapis.com/auth/plus.login',
514
+ * 'https://www.googleapis.com/auth/moderator')
515
+ */
516
+ public function setScopes($scopes)
517
+ {
518
+ $this->requestedScopes = array();
519
+ $this->addScope($scopes);
520
+ }
521
+
522
+ /**
523
+ * This functions adds a scope to be requested as part of the OAuth2.0 flow.
524
+ * Will append any scopes not previously requested to the scope parameter.
525
+ * A single string will be treated as a scope to request. An array of strings
526
+ * will each be appended.
527
+ * @param $scope_or_scopes string|array e.g. "profile"
528
+ */
529
+ public function addScope($scope_or_scopes)
530
+ {
531
+ if (is_string($scope_or_scopes) && !in_array($scope_or_scopes, $this->requestedScopes)) {
532
+ $this->requestedScopes[] = $scope_or_scopes;
533
+ } else if (is_array($scope_or_scopes)) {
534
+ foreach ($scope_or_scopes as $scope) {
535
+ $this->addScope($scope);
536
+ }
537
+ }
538
+ }
539
+
540
+ /**
541
+ * Returns the list of scopes requested by the client
542
+ * @return array the list of scopes
543
+ *
544
+ */
545
+ public function getScopes()
546
+ {
547
+ return $this->requestedScopes;
548
+ }
549
+
550
+ /**
551
+ * Declare whether batch calls should be used. This may increase throughput
552
+ * by making multiple requests in one connection.
553
+ *
554
+ * @param boolean $useBatch True if the batch support should
555
+ * be enabled. Defaults to False.
556
+ */
557
+ public function setUseBatch($useBatch)
558
+ {
559
+ // This is actually an alias for setDefer.
560
+ $this->setDefer($useBatch);
561
+ }
562
+
563
+ /**
564
+ * Declare whether making API calls should make the call immediately, or
565
+ * return a request which can be called with ->execute();
566
+ *
567
+ * @param boolean $defer True if calls should not be executed right away.
568
+ */
569
+ public function setDefer($defer)
570
+ {
571
+ $this->deferExecution = $defer;
572
+ }
573
+
574
+ /**
575
+ * Helper method to execute deferred HTTP requests.
576
+ *
577
+ * @param $request Google_Http_Request|Google_Http_Batch
578
+ * @throws Google_Exception
579
+ * @return object of the type of the expected class or array.
580
+ */
581
+ public function execute($request)
582
+ {
583
+ if ($request instanceof Google_Http_Request) {
584
+ $request->setUserAgent(
585
+ $this->getApplicationName()
586
+ . " " . self::USER_AGENT_SUFFIX
587
+ . $this->getLibraryVersion()
588
+ );
589
+ if (!$this->getClassConfig("Google_Http_Request", "disable_gzip")) {
590
+ $request->enableGzip();
591
+ }
592
+ $request->maybeMoveParametersToBody();
593
+ return Google_Http_REST::execute($this, $request);
594
+ } else if ($request instanceof Google_Http_Batch) {
595
+ return $request->execute();
596
+ } else {
597
+ throw new Google_Exception("Do not know how to execute this type of object.");
598
+ }
599
+ }
600
+
601
+ /**
602
+ * Whether or not to return raw requests
603
+ * @return boolean
604
+ */
605
+ public function shouldDefer()
606
+ {
607
+ return $this->deferExecution;
608
+ }
609
+
610
+ /**
611
+ * @return Google_Auth_Abstract Authentication implementation
612
+ */
613
+ public function getAuth()
614
+ {
615
+ if (!isset($this->auth)) {
616
+ $class = $this->config->getAuthClass();
617
+ $this->auth = new $class($this);
618
+ }
619
+ return $this->auth;
620
+ }
621
+
622
+ /**
623
+ * @return Google_IO_Abstract IO implementation
624
+ */
625
+ public function getIo()
626
+ {
627
+ if (!isset($this->io)) {
628
+ $class = $this->config->getIoClass();
629
+ $this->io = new $class($this);
630
+ }
631
+ return $this->io;
632
+ }
633
+
634
+ /**
635
+ * @return Google_Cache_Abstract Cache implementation
636
+ */
637
+ public function getCache()
638
+ {
639
+ if (!isset($this->cache)) {
640
+ $class = $this->config->getCacheClass();
641
+ $this->cache = new $class($this);
642
+ }
643
+ return $this->cache;
644
+ }
645
+
646
+ /**
647
+ * @return Google_Logger_Abstract Logger implementation
648
+ */
649
+ public function getLogger()
650
+ {
651
+ if (!isset($this->logger)) {
652
+ $class = $this->config->getLoggerClass();
653
+ $this->logger = new $class($this);
654
+ }
655
+ return $this->logger;
656
+ }
657
+
658
+ /**
659
+ * Retrieve custom configuration for a specific class.
660
+ * @param $class string|object - class or instance of class to retrieve
661
+ * @param $key string optional - key to retrieve
662
+ * @return array
663
+ */
664
+ public function getClassConfig($class, $key = null)
665
+ {
666
+ if (!is_string($class)) {
667
+ $class = get_class($class);
668
+ }
669
+ return $this->config->getClassConfig($class, $key);
670
+ }
671
+
672
+ /**
673
+ * Set configuration specific to a given class.
674
+ * $config->setClassConfig('Google_Cache_File',
675
+ * array('directory' => '/tmp/cache'));
676
+ * @param $class string|object - The class name for the configuration
677
+ * @param $config string key or an array of configuration values
678
+ * @param $value string optional - if $config is a key, the value
679
+ *
680
+ */
681
+ public function setClassConfig($class, $config, $value = null)
682
+ {
683
+ if (!is_string($class)) {
684
+ $class = get_class($class);
685
+ }
686
+ $this->config->setClassConfig($class, $config, $value);
687
+
688
+ }
689
+
690
+ /**
691
+ * @return string the base URL to use for calls to the APIs
692
+ */
693
+ public function getBasePath()
694
+ {
695
+ return $this->config->getBasePath();
696
+ }
697
+
698
+ /**
699
+ * @return string the name of the application
700
+ */
701
+ public function getApplicationName()
702
+ {
703
+ return $this->config->getApplicationName();
704
+ }
705
+
706
+ /**
707
+ * Are we running in Google AppEngine?
708
+ * return bool
709
+ */
710
+ public function isAppEngine()
711
+ {
712
+ return (isset($_SERVER['SERVER_SOFTWARE']) &&
713
+ strpos($_SERVER['SERVER_SOFTWARE'], 'Google App Engine') !== false);
714
+ }
715
+ }
addons/pro/googlesheet/lib/external/Google/Collection.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ if (!class_exists('Google_Client')) {
4
+ require_once dirname(__FILE__) . '/autoload.php';
5
+ }
6
+
7
+ /**
8
+ * Extension to the regular Google_Model that automatically
9
+ * exposes the items array for iteration, so you can just
10
+ * iterate over the object rather than a reference inside.
11
+ */
12
+ class Google_Collection extends Google_Model implements Iterator, Countable
13
+ {
14
+ protected $collection_key = 'items';
15
+
16
+ public function rewind()
17
+ {
18
+ if (isset($this->modelData[$this->collection_key])
19
+ && is_array($this->modelData[$this->collection_key])) {
20
+ reset($this->modelData[$this->collection_key]);
21
+ }
22
+ }
23
+
24
+ public function current()
25
+ {
26
+ $this->coerceType($this->key());
27
+ if (is_array($this->modelData[$this->collection_key])) {
28
+ return current($this->modelData[$this->collection_key]);
29
+ }
30
+ }
31
+
32
+ public function key()
33
+ {
34
+ if (isset($this->modelData[$this->collection_key])
35
+ && is_array($this->modelData[$this->collection_key])) {
36
+ return key($this->modelData[$this->collection_key]);
37
+ }
38
+ }
39
+
40
+ public function next()
41
+ {
42
+ return next($this->modelData[$this->collection_key]);
43
+ }
44
+
45
+ public function valid()
46
+ {
47
+ $key = $this->key();
48
+ return $key !== null && $key !== false;
49
+ }
50
+
51
+ public function count()
52
+ {
53
+ if (!isset($this->modelData[$this->collection_key])) {
54
+ return 0;
55
+ }
56
+ return count($this->modelData[$this->collection_key]);
57
+ }
58
+
59
+ public function offsetExists($offset)
60
+ {
61
+ if (!is_numeric($offset)) {
62
+ return parent::offsetExists($offset);
63
+ }
64
+ return isset($this->modelData[$this->collection_key][$offset]);
65
+ }
66
+
67
+ public function offsetGet($offset)
68
+ {
69
+ if (!is_numeric($offset)) {
70
+ return parent::offsetGet($offset);
71
+ }
72
+ $this->coerceType($offset);
73
+ return $this->modelData[$this->collection_key][$offset];
74
+ }
75
+
76
+ public function offsetSet($offset, $value)
77
+ {
78
+ if (!is_numeric($offset)) {
79
+ return parent::offsetSet($offset, $value);
80
+ }
81
+ $this->modelData[$this->collection_key][$offset] = $value;
82
+ }
83
+
84
+ public function offsetUnset($offset)
85
+ {
86
+ if (!is_numeric($offset)) {
87
+ return parent::offsetUnset($offset);
88
+ }
89
+ unset($this->modelData[$this->collection_key][$offset]);
90
+ }
91
+
92
+ private function coerceType($offset)
93
+ {
94
+ $typeKey = $this->keyType($this->collection_key);
95
+ if (isset($this->$typeKey) && !is_object($this->modelData[$this->collection_key][$offset])) {
96
+ $type = $this->$typeKey;
97
+ $this->modelData[$this->collection_key][$offset] =
98
+ new $type($this->modelData[$this->collection_key][$offset]);
99
+ }
100
+ }
101
+ }
addons/pro/googlesheet/lib/external/Google/Config.php ADDED
@@ -0,0 +1,456 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * A class to contain the library configuration for the Google API client.
20
+ */
21
+ class Google_Config
22
+ {
23
+ const GZIP_DISABLED = true;
24
+ const GZIP_ENABLED = false;
25
+ const GZIP_UPLOADS_ENABLED = true;
26
+ const GZIP_UPLOADS_DISABLED = false;
27
+ const USE_AUTO_IO_SELECTION = "auto";
28
+ const TASK_RETRY_NEVER = 0;
29
+ const TASK_RETRY_ONCE = 1;
30
+ const TASK_RETRY_ALWAYS = -1;
31
+ protected $configuration;
32
+
33
+ /**
34
+ * Create a new Google_Config. Can accept an ini file location with the
35
+ * local configuration. For example:
36
+ * application_name="My App"
37
+ *
38
+ * @param [$ini_file_location] - optional - The location of the ini file to load
39
+ */
40
+ public function __construct($ini_file_location = null)
41
+ {
42
+ $this->configuration = array(
43
+ // The application_name is included in the User-Agent HTTP header.
44
+ 'application_name' => '',
45
+
46
+ // Which Authentication, Storage and HTTP IO classes to use.
47
+ 'auth_class' => 'Google_Auth_OAuth2',
48
+ 'io_class' => self::USE_AUTO_IO_SELECTION,
49
+ 'cache_class' => 'Google_Cache_File',
50
+ 'logger_class' => 'Google_Logger_Null',
51
+
52
+ // Don't change these unless you're working against a special development
53
+ // or testing environment.
54
+ 'base_path' => 'https://www.googleapis.com',
55
+
56
+ // Definition of class specific values, like file paths and so on.
57
+ 'classes' => array(
58
+ 'Google_IO_Abstract' => array(
59
+ 'request_timeout_seconds' => 100,
60
+ ),
61
+ 'Google_IO_Curl' => array(
62
+ 'disable_proxy_workaround' => false,
63
+ 'options' => null,
64
+ ),
65
+ 'Google_Logger_Abstract' => array(
66
+ 'level' => 'debug',
67
+ 'log_format' => "[%datetime%] %level%: %message% %context%\n",
68
+ 'date_format' => 'd/M/Y:H:i:s O',
69
+ 'allow_newlines' => true
70
+ ),
71
+ 'Google_Logger_File' => array(
72
+ 'file' => 'php://stdout',
73
+ 'mode' => 0640,
74
+ 'lock' => false,
75
+ ),
76
+ 'Google_Http_Request' => array(
77
+ // Disable the use of gzip on calls if set to true. Defaults to false.
78
+ 'disable_gzip' => self::GZIP_ENABLED,
79
+
80
+ // We default gzip to disabled on uploads even if gzip is otherwise
81
+ // enabled, due to some issues seen with small packet sizes for uploads.
82
+ // Please test with this option before enabling gzip for uploads in
83
+ // a production environment.
84
+ 'enable_gzip_for_uploads' => self::GZIP_UPLOADS_DISABLED,
85
+ ),
86
+ // If you want to pass in OAuth 2.0 settings, they will need to be
87
+ // structured like this.
88
+ 'Google_Auth_OAuth2' => array(
89
+ // Keys for OAuth 2.0 access, see the API console at
90
+ // https://developers.google.com/console
91
+ 'client_id' => '',
92
+ 'client_secret' => '',
93
+ 'redirect_uri' => '',
94
+
95
+ // Simple API access key, also from the API console. Ensure you get
96
+ // a Server key, and not a Browser key.
97
+ 'developer_key' => '',
98
+
99
+ // Other parameters.
100
+ 'hd' => '',
101
+ 'prompt' => '',
102
+ 'openid.realm' => '',
103
+ 'include_granted_scopes' => '',
104
+ 'login_hint' => '',
105
+ 'request_visible_actions' => '',
106
+ 'access_type' => 'online',
107
+ 'approval_prompt' => 'auto',
108
+ 'federated_signon_certs_url' =>
109
+ 'https://www.googleapis.com/oauth2/v1/certs',
110
+ ),
111
+ 'Google_Task_Runner' => array(
112
+ // Delays are specified in seconds
113
+ 'initial_delay' => 1,
114
+ 'max_delay' => 60,
115
+ // Base number for exponential backoff
116
+ 'factor' => 2,
117
+ // A random number between -jitter and jitter will be added to the
118
+ // factor on each iteration to allow for better distribution of
119
+ // retries.
120
+ 'jitter' => .5,
121
+ // Maximum number of retries allowed
122
+ 'retries' => 0
123
+ ),
124
+ 'Google_Service_Exception' => array(
125
+ 'retry_map' => array(
126
+ '500' => self::TASK_RETRY_ALWAYS,
127
+ '503' => self::TASK_RETRY_ALWAYS,
128
+ 'rateLimitExceeded' => self::TASK_RETRY_ALWAYS,
129
+ 'userRateLimitExceeded' => self::TASK_RETRY_ALWAYS
130
+ )
131
+ ),
132
+ 'Google_IO_Exception' => array(
133
+ 'retry_map' => !extension_loaded('curl') ? array() : array(
134
+ CURLE_COULDNT_RESOLVE_HOST => self::TASK_RETRY_ALWAYS,
135
+ CURLE_COULDNT_CONNECT => self::TASK_RETRY_ALWAYS,
136
+ CURLE_OPERATION_TIMEOUTED => self::TASK_RETRY_ALWAYS,
137
+ CURLE_SSL_CONNECT_ERROR => self::TASK_RETRY_ALWAYS,
138
+ CURLE_GOT_NOTHING => self::TASK_RETRY_ALWAYS
139
+ )
140
+ ),
141
+ // Set a default directory for the file cache.
142
+ 'Google_Cache_File' => array(
143
+ 'directory' => sys_get_temp_dir() . '/Google_Client'
144
+ )
145
+ ),
146
+ );
147
+ if ($ini_file_location) {
148
+ $ini = parse_ini_file($ini_file_location, true);
149
+ if (is_array($ini) && count($ini)) {
150
+ $merged_configuration = $ini + $this->configuration;
151
+ if (isset($ini['classes']) && isset($this->configuration['classes'])) {
152
+ $merged_configuration['classes'] = $ini['classes'] + $this->configuration['classes'];
153
+ }
154
+ $this->configuration = $merged_configuration;
155
+ }
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Set configuration specific to a given class.
161
+ * $config->setClassConfig('Google_Cache_File',
162
+ * array('directory' => '/tmp/cache'));
163
+ * @param $class string The class name for the configuration
164
+ * @param $config string key or an array of configuration values
165
+ * @param $value string optional - if $config is a key, the value
166
+ */
167
+ public function setClassConfig($class, $config, $value = null)
168
+ {
169
+ if (!is_array($config)) {
170
+ if (!isset($this->configuration['classes'][$class])) {
171
+ $this->configuration['classes'][$class] = array();
172
+ }
173
+ $this->configuration['classes'][$class][$config] = $value;
174
+ } else {
175
+ $this->configuration['classes'][$class] = $config;
176
+ }
177
+ }
178
+
179
+ public function getClassConfig($class, $key = null)
180
+ {
181
+ if (!isset($this->configuration['classes'][$class])) {
182
+ return null;
183
+ }
184
+ if ($key === null) {
185
+ return $this->configuration['classes'][$class];
186
+ } else {
187
+ return $this->configuration['classes'][$class][$key];
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Return the configured cache class.
193
+ * @return string
194
+ */
195
+ public function getCacheClass()
196
+ {
197
+ return $this->configuration['cache_class'];
198
+ }
199
+
200
+ /**
201
+ * Return the configured logger class.
202
+ * @return string
203
+ */
204
+ public function getLoggerClass()
205
+ {
206
+ return $this->configuration['logger_class'];
207
+ }
208
+
209
+ /**
210
+ * Return the configured Auth class.
211
+ * @return string
212
+ */
213
+ public function getAuthClass()
214
+ {
215
+ return $this->configuration['auth_class'];
216
+ }
217
+
218
+ /**
219
+ * Set the auth class.
220
+ *
221
+ * @param $class string the class name to set
222
+ */
223
+ public function setAuthClass($class)
224
+ {
225
+ $prev = $this->configuration['auth_class'];
226
+ if (!isset($this->configuration['classes'][$class]) &&
227
+ isset($this->configuration['classes'][$prev])) {
228
+ $this->configuration['classes'][$class] =
229
+ $this->configuration['classes'][$prev];
230
+ }
231
+ $this->configuration['auth_class'] = $class;
232
+ }
233
+
234
+ /**
235
+ * Set the IO class.
236
+ *
237
+ * @param $class string the class name to set
238
+ */
239
+ public function setIoClass($class)
240
+ {
241
+ $prev = $this->configuration['io_class'];
242
+ if (!isset($this->configuration['classes'][$class]) &&
243
+ isset($this->configuration['classes'][$prev])) {
244
+ $this->configuration['classes'][$class] =
245
+ $this->configuration['classes'][$prev];
246
+ }
247
+ $this->configuration['io_class'] = $class;
248
+ }
249
+
250
+ /**
251
+ * Set the cache class.
252
+ *
253
+ * @param $class string the class name to set
254
+ */
255
+ public function setCacheClass($class)
256
+ {
257
+ $prev = $this->configuration['cache_class'];
258
+ if (!isset($this->configuration['classes'][$class]) &&
259
+ isset($this->configuration['classes'][$prev])) {
260
+ $this->configuration['classes'][$class] =
261
+ $this->configuration['classes'][$prev];
262
+ }
263
+ $this->configuration['cache_class'] = $class;
264
+ }
265
+
266
+ /**
267
+ * Set the logger class.
268
+ *
269
+ * @param $class string the class name to set
270
+ */
271
+ public function setLoggerClass($class)
272
+ {
273
+ $prev = $this->configuration['logger_class'];
274
+ if (!isset($this->configuration['classes'][$class]) &&
275
+ isset($this->configuration['classes'][$prev])) {
276
+ $this->configuration['classes'][$class] =
277
+ $this->configuration['classes'][$prev];
278
+ }
279
+ $this->configuration['logger_class'] = $class;
280
+ }
281
+
282
+ /**
283
+ * Return the configured IO class.
284
+ *
285
+ * @return string
286
+ */
287
+ public function getIoClass()
288
+ {
289
+ return $this->configuration['io_class'];
290
+ }
291
+
292
+ /**
293
+ * Set the application name, this is included in the User-Agent HTTP header.
294
+ * @param string $name
295
+ */
296
+ public function setApplicationName($name)
297
+ {
298
+ $this->configuration['application_name'] = $name;
299
+ }
300
+
301
+ /**
302
+ * @return string the name of the application
303
+ */
304
+ public function getApplicationName()
305
+ {
306
+ return $this->configuration['application_name'];
307
+ }
308
+
309
+ /**
310
+ * Set the client ID for the auth class.
311
+ * @param $clientId string - the API console client ID
312
+ */
313
+ public function setClientId($clientId)
314
+ {
315
+ $this->setAuthConfig('client_id', $clientId);
316
+ }
317
+
318
+ /**
319
+ * Set the client secret for the auth class.
320
+ * @param $secret string - the API console client secret
321
+ */
322
+ public function setClientSecret($secret)
323
+ {
324
+ $this->setAuthConfig('client_secret', $secret);
325
+ }
326
+
327
+ /**
328
+ * Set the redirect uri for the auth class. Note that if using the
329
+ * Javascript based sign in flow, this should be the string 'postmessage'.
330
+ *
331
+ * @param $uri string - the URI that users should be redirected to
332
+ */
333
+ public function setRedirectUri($uri)
334
+ {
335
+ $this->setAuthConfig('redirect_uri', $uri);
336
+ }
337
+
338
+ /**
339
+ * Set the app activities for the auth class.
340
+ * @param $rva string a space separated list of app activity types
341
+ */
342
+ public function setRequestVisibleActions($rva)
343
+ {
344
+ $this->setAuthConfig('request_visible_actions', $rva);
345
+ }
346
+
347
+ /**
348
+ * Set the the access type requested (offline or online.)
349
+ * @param $access string - the access type
350
+ */
351
+ public function setAccessType($access)
352
+ {
353
+ $this->setAuthConfig('access_type', $access);
354
+ }
355
+
356
+ /**
357
+ * Set when to show the approval prompt (auto or force)
358
+ * @param $approval string - the approval request
359
+ */
360
+ public function setApprovalPrompt($approval)
361
+ {
362
+ $this->setAuthConfig('approval_prompt', $approval);
363
+ }
364
+
365
+ /**
366
+ * Set the login hint (email address or sub identifier)
367
+ * @param $hint string
368
+ */
369
+ public function setLoginHint($hint)
370
+ {
371
+ $this->setAuthConfig('login_hint', $hint);
372
+ }
373
+
374
+ /**
375
+ * Set the developer key for the auth class. Note that this is separate value
376
+ * from the client ID - if it looks like a URL, its a client ID!
377
+ * @param $key string - the API console developer key
378
+ */
379
+ public function setDeveloperKey($key)
380
+ {
381
+ $this->setAuthConfig('developer_key', $key);
382
+ }
383
+
384
+ /**
385
+ * Set the hd (hosted domain) parameter streamlines the login process for
386
+ * Google Apps hosted accounts. By including the domain of the user, you
387
+ * restrict sign-in to accounts at that domain.
388
+ *
389
+ * This should not be used to ensure security on your application - check
390
+ * the hd values within an id token (@see Google_Auth_LoginTicket) after sign
391
+ * in to ensure that the user is from the domain you were expecting.
392
+ *
393
+ * @param $hd string - the domain to use.
394
+ */
395
+ public function setHostedDomain($hd)
396
+ {
397
+ $this->setAuthConfig('hd', $hd);
398
+ }
399
+
400
+ /**
401
+ * Set the prompt hint. Valid values are none, consent and select_account.
402
+ * If no value is specified and the user has not previously authorized
403
+ * access, then the user is shown a consent screen.
404
+ * @param $prompt string
405
+ */
406
+ public function setPrompt($prompt)
407
+ {
408
+ $this->setAuthConfig('prompt', $prompt);
409
+ }
410
+
411
+ /**
412
+ * openid.realm is a parameter from the OpenID 2.0 protocol, not from OAuth
413
+ * 2.0. It is used in OpenID 2.0 requests to signify the URL-space for which
414
+ * an authentication request is valid.
415
+ * @param $realm string - the URL-space to use.
416
+ */
417
+ public function setOpenidRealm($realm)
418
+ {
419
+ $this->setAuthConfig('openid.realm', $realm);
420
+ }
421
+
422
+ /**
423
+ * If this is provided with the value true, and the authorization request is
424
+ * granted, the authorization will include any previous authorizations
425
+ * granted to this user/application combination for other scopes.
426
+ * @param $include boolean - the URL-space to use.
427
+ */
428
+ public function setIncludeGrantedScopes($include)
429
+ {
430
+ $this->setAuthConfig(
431
+ 'include_granted_scopes',
432
+ $include ? "true" : "false"
433
+ );
434
+ }
435
+
436
+ /**
437
+ * @return string the base URL to use for API calls
438
+ */
439
+ public function getBasePath()
440
+ {
441
+ return $this->configuration['base_path'];
442
+ }
443
+
444
+ /**
445
+ * Set the auth configuration for the current auth class.
446
+ * @param $key - the key to set
447
+ * @param $value - the parameter value
448
+ */
449
+ private function setAuthConfig($key, $value)
450
+ {
451
+ if (!isset($this->configuration['classes'][$this->getAuthClass()])) {
452
+ $this->configuration['classes'][$this->getAuthClass()] = array();
453
+ }
454
+ $this->configuration['classes'][$this->getAuthClass()][$key] = $value;
455
+ }
456
+ }
addons/pro/googlesheet/lib/external/Google/Exception.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2013 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ class Google_Exception extends Exception
19
+ {
20
+ }
addons/pro/googlesheet/lib/external/Google/Http/Batch.php ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2012 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * Class to handle batched requests to the Google API service.
24
+ */
25
+ class Google_Http_Batch
26
+ {
27
+ /** @var string Multipart Boundary. */
28
+ private $boundary;
29
+
30
+ /** @var array service requests to be executed. */
31
+ private $requests = array();
32
+
33
+ /** @var Google_Client */
34
+ private $client;
35
+
36
+ private $expected_classes = array();
37
+
38
+ private $root_url;
39
+
40
+ private $batch_path;
41
+
42
+ public function __construct(Google_Client $client, $boundary = false, $rootUrl = '', $batchPath = '')
43
+ {
44
+ $this->client = $client;
45
+ $this->root_url = rtrim($rootUrl ? $rootUrl : $this->client->getBasePath(), '/');
46
+ $this->batch_path = $batchPath ? $batchPath : 'batch';
47
+ $this->expected_classes = array();
48
+ $boundary = (false == $boundary) ? mt_rand() : $boundary;
49
+ $this->boundary = str_replace('"', '', $boundary);
50
+ }
51
+
52
+ public function add(Google_Http_Request $request, $key = false)
53
+ {
54
+ if (false == $key) {
55
+ $key = mt_rand();
56
+ }
57
+
58
+ $this->requests[$key] = $request;
59
+ }
60
+
61
+ public function execute()
62
+ {
63
+ $body = '';
64
+
65
+ /** @var Google_Http_Request $req */
66
+ foreach ($this->requests as $key => $req) {
67
+ $body .= "--{$this->boundary}\n";
68
+ $body .= $req->toBatchString($key) . "\n\n";
69
+ $this->expected_classes["response-" . $key] = $req->getExpectedClass();
70
+ }
71
+
72
+ $body .= "--{$this->boundary}--";
73
+
74
+ $url = $this->root_url . '/' . $this->batch_path;
75
+ $httpRequest = new Google_Http_Request($url, 'POST');
76
+ $httpRequest->setRequestHeaders(
77
+ array('Content-Type' => 'multipart/mixed; boundary=' . $this->boundary)
78
+ );
79
+
80
+ $httpRequest->setPostBody($body);
81
+ $response = $this->client->getIo()->makeRequest($httpRequest);
82
+
83
+ return $this->parseResponse($response);
84
+ }
85
+
86
+ public function parseResponse(Google_Http_Request $response)
87
+ {
88
+ $contentType = $response->getResponseHeader('content-type');
89
+ $contentType = explode(';', $contentType);
90
+ $boundary = false;
91
+ foreach ($contentType as $part) {
92
+ $part = (explode('=', $part, 2));
93
+ if (isset($part[0]) && 'boundary' == trim($part[0])) {
94
+ $boundary = $part[1];
95
+ }
96
+ }
97
+
98
+ $body = $response->getResponseBody();
99
+ if ($body) {
100
+ $body = str_replace("--$boundary--", "--$boundary", $body);
101
+ $parts = explode("--$boundary", $body);
102
+ $responses = array();
103
+
104
+ foreach ($parts as $part) {
105
+ $part = trim($part);
106
+ if (!empty($part)) {
107
+ list($metaHeaders, $part) = explode("\r\n\r\n", $part, 2);
108
+ $metaHeaders = $this->client->getIo()->getHttpResponseHeaders($metaHeaders);
109
+
110
+ $status = substr($part, 0, strpos($part, "\n"));
111
+ $status = explode(" ", $status);
112
+ $status = $status[1];
113
+
114
+ list($partHeaders, $partBody) = $this->client->getIo()->ParseHttpResponse($part, false);
115
+ $response = new Google_Http_Request("");
116
+ $response->setResponseHttpCode($status);
117
+ $response->setResponseHeaders($partHeaders);
118
+ $response->setResponseBody($partBody);
119
+
120
+ // Need content id.
121
+ $key = $metaHeaders['content-id'];
122
+
123
+ if (isset($this->expected_classes[$key]) &&
124
+ strlen($this->expected_classes[$key]) > 0) {
125
+ $class = $this->expected_classes[$key];
126
+ $response->setExpectedClass($class);
127
+ }
128
+
129
+ try {
130
+ $response = Google_Http_REST::decodeHttpResponse($response, $this->client);
131
+ $responses[$key] = $response;
132
+ } catch (Google_Service_Exception $e) {
133
+ // Store the exception as the response, so successful responses
134
+ // can be processed.
135
+ $responses[$key] = $e;
136
+ }
137
+ }
138
+ }
139
+
140
+ return $responses;
141
+ }
142
+
143
+ return null;
144
+ }
145
+ }
addons/pro/googlesheet/lib/external/Google/Http/CacheParser.php ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2012 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * Implement the caching directives specified in rfc2616. This
24
+ * implementation is guided by the guidance offered in rfc2616-sec13.
25
+ */
26
+ class Google_Http_CacheParser
27
+ {
28
+ public static $CACHEABLE_HTTP_METHODS = array('GET', 'HEAD');
29
+ public static $CACHEABLE_STATUS_CODES = array('200', '203', '300', '301');
30
+
31
+ /**
32
+ * Check if an HTTP request can be cached by a private local cache.
33
+ *
34
+ * @static
35
+ * @param Google_Http_Request $resp
36
+ * @return bool True if the request is cacheable.
37
+ * False if the request is uncacheable.
38
+ */
39
+ public static function isRequestCacheable(Google_Http_Request $resp)
40
+ {
41
+ $method = $resp->getRequestMethod();
42
+ if (! in_array($method, self::$CACHEABLE_HTTP_METHODS)) {
43
+ return false;
44
+ }
45
+
46
+ // Don't cache authorized requests/responses.
47
+ // [rfc2616-14.8] When a shared cache receives a request containing an
48
+ // Authorization field, it MUST NOT return the corresponding response
49
+ // as a reply to any other request...
50
+ if ($resp->getRequestHeader("authorization")) {
51
+ return false;
52
+ }
53
+
54
+ return true;
55
+ }
56
+
57
+ /**
58
+ * Check if an HTTP response can be cached by a private local cache.
59
+ *
60
+ * @static
61
+ * @param Google_Http_Request $resp
62
+ * @return bool True if the response is cacheable.
63
+ * False if the response is un-cacheable.
64
+ */
65
+ public static function isResponseCacheable(Google_Http_Request $resp)
66
+ {
67
+ // First, check if the HTTP request was cacheable before inspecting the
68
+ // HTTP response.
69
+ if (false == self::isRequestCacheable($resp)) {
70
+ return false;
71
+ }
72
+
73
+ $code = $resp->getResponseHttpCode();
74
+ if (! in_array($code, self::$CACHEABLE_STATUS_CODES)) {
75
+ return false;
76
+ }
77
+
78
+ // The resource is uncacheable if the resource is already expired and
79
+ // the resource doesn't have an ETag for revalidation.
80
+ $etag = $resp->getResponseHeader("etag");
81
+ if (self::isExpired($resp) && $etag == false) {
82
+ return false;
83
+ }
84
+
85
+ // [rfc2616-14.9.2] If [no-store is] sent in a response, a cache MUST NOT
86
+ // store any part of either this response or the request that elicited it.
87
+ $cacheControl = $resp->getParsedCacheControl();
88
+ if (isset($cacheControl['no-store'])) {
89
+ return false;
90
+ }
91
+
92
+ // Pragma: no-cache is an http request directive, but is occasionally
93
+ // used as a response header incorrectly.
94
+ $pragma = $resp->getResponseHeader('pragma');
95
+ if ($pragma == 'no-cache' || strpos($pragma, 'no-cache') !== false) {
96
+ return false;
97
+ }
98
+
99
+ // [rfc2616-14.44] Vary: * is extremely difficult to cache. "It implies that
100
+ // a cache cannot determine from the request headers of a subsequent request
101
+ // whether this response is the appropriate representation."
102
+ // Given this, we deem responses with the Vary header as uncacheable.
103
+ $vary = $resp->getResponseHeader('vary');
104
+ if ($vary) {
105
+ return false;
106
+ }
107
+
108
+ return true;
109
+ }
110
+
111
+ /**
112
+ * @static
113
+ * @param Google_Http_Request $resp
114
+ * @return bool True if the HTTP response is considered to be expired.
115
+ * False if it is considered to be fresh.
116
+ */
117
+ public static function isExpired(Google_Http_Request $resp)
118
+ {
119
+ // HTTP/1.1 clients and caches MUST treat other invalid date formats,
120
+ // especially including the value “0”, as in the past.
121
+ $parsedExpires = false;
122
+ $responseHeaders = $resp->getResponseHeaders();
123
+
124
+ if (isset($responseHeaders['expires'])) {
125
+ $rawExpires = $responseHeaders['expires'];
126
+ // Check for a malformed expires header first.
127
+ if (empty($rawExpires) || (is_numeric($rawExpires) && $rawExpires <= 0)) {
128
+ return true;
129
+ }
130
+
131
+ // See if we can parse the expires header.
132
+ $parsedExpires = strtotime($rawExpires);
133
+ if (false == $parsedExpires || $parsedExpires <= 0) {
134
+ return true;
135
+ }
136
+ }
137
+
138
+ // Calculate the freshness of an http response.
139
+ $freshnessLifetime = false;
140
+ $cacheControl = $resp->getParsedCacheControl();
141
+ if (isset($cacheControl['max-age'])) {
142
+ $freshnessLifetime = $cacheControl['max-age'];
143
+ }
144
+
145
+ $rawDate = $resp->getResponseHeader('date');
146
+ $parsedDate = strtotime($rawDate);
147
+
148
+ if (empty($rawDate) || false == $parsedDate) {
149
+ // We can't default this to now, as that means future cache reads
150
+ // will always pass with the logic below, so we will require a
151
+ // date be injected if not supplied.
152
+ throw new Google_Exception("All cacheable requests must have creation dates.");
153
+ }
154
+
155
+ if (false == $freshnessLifetime && isset($responseHeaders['expires'])) {
156
+ $freshnessLifetime = $parsedExpires - $parsedDate;
157
+ }
158
+
159
+ if (false == $freshnessLifetime) {
160
+ return true;
161
+ }
162
+
163
+ // Calculate the age of an http response.
164
+ $age = max(0, time() - $parsedDate);
165
+ if (isset($responseHeaders['age'])) {
166
+ $age = max($age, strtotime($responseHeaders['age']));
167
+ }
168
+
169
+ return $freshnessLifetime <= $age;
170
+ }
171
+
172
+ /**
173
+ * Determine if a cache entry should be revalidated with by the origin.
174
+ *
175
+ * @param Google_Http_Request $response
176
+ * @return bool True if the entry is expired, else return false.
177
+ */
178
+ public static function mustRevalidate(Google_Http_Request $response)
179
+ {
180
+ // [13.3] When a cache has a stale entry that it would like to use as a
181
+ // response to a client's request, it first has to check with the origin
182
+ // server to see if its cached entry is still usable.
183
+ return self::isExpired($response);
184
+ }
185
+ }
addons/pro/googlesheet/lib/external/Google/Http/MediaFileUpload.php ADDED
@@ -0,0 +1,341 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright 2012 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * Manage large file uploads, which may be media but can be any type
24
+ * of sizable data.
25
+ */
26
+ class Google_Http_MediaFileUpload
27
+ {
28
+ const UPLOAD_MEDIA_TYPE = 'media';
29
+ const UPLOAD_MULTIPART_TYPE = 'multipart';
30
+ const UPLOAD_RESUMABLE_TYPE = 'resumable';
31
+
32
+ /** @var string $mimeType */
33
+ private $mimeType;
34
+
35
+ /** @var string $data */
36
+ private $data;
37
+
38
+ /** @var bool $resumable */
39
+ private $resumable;
40
+
41
+ /** @var int $chunkSize */
42
+ private $chunkSize;
43
+
44
+ /** @var int $size */
45
+ private $size;
46
+
47
+ /** @var string $resumeUri */
48
+ private $resumeUri;
49
+
50
+ /** @var int $progress */
51
+ private $progress;
52
+
53
+ /** @var Google_Client */
54
+ private $client;
55
+
56
+ /** @var Google_Http_Request */
57
+ private $request;
58
+
59
+ /** @var string */
60
+ private $boundary;
61
+
62
+ /**
63
+ * Result code from last HTTP call
64
+ * @var int
65
+ */
66
+ private $httpResultCode;
67
+
68
+ /**
69
+ * @param $mimeType string
70
+ * @param $data string The bytes you want to upload.
71
+ * @param $resumable bool
72
+ * @param bool $chunkSize File will be uploaded in chunks of this many bytes.
73
+ * only used if resumable=True
74
+ */
75
+ public function __construct(
76
+ Google_Client $client,
77
+ Google_Http_Request $request,
78
+ $mimeType,
79
+ $data,
80
+ $resumable = false,
81
+ $chunkSize = false,
82
+ $boundary = false
83
+ ) {
84
+ $this->client = $client;
85
+ $this->request = $request;
86
+ $this->mimeType = $mimeType;
87
+ $this->data = $data;
88
+ $this->size = strlen($this->data);
89
+ $this->resumable = $resumable;
90
+ if (!$chunkSize) {
91
+ $chunkSize = 256 * 1024;
92
+ }
93
+ $this->chunkSize = $chunkSize;
94
+ $this->progress = 0;
95
+ $this->boundary = $boundary;
96
+
97
+ // Process Media Request
98
+ $this->process();
99
+ }
100
+
101
+ /**
102
+ * Set the size of the file that is being uploaded.
103
+ * @param $size - int file size in bytes
104
+ */
105
+ public function setFileSize($size)
106
+ {
107
+ $this->size = $size;
108
+ }
109
+
110
+ /**
111
+ * Return the progress on the upload
112
+ * @return int progress in bytes uploaded.
113
+ */
114
+ public function getProgress()
115
+ {
116
+ return $this->progress;
117
+ }
118
+
119
+ /**
120
+ * Return the HTTP result code from the last call made.
121
+ * @return int code
122
+ */
123
+ public function getHttpResultCode()
124
+ {
125
+ return $this->httpResultCode;
126
+ }
127
+
128
+ /**
129
+ * Sends a PUT-Request to google drive and parses the response,
130
+ * setting the appropiate variables from the response()
131
+ *
132
+ * @param Google_Http_Request $httpRequest the Reuqest which will be send
133
+ *
134
+ * @return false|mixed false when the upload is unfinished or the decoded http response
135
+ *
136
+ */
137
+ private function makePutRequest(Google_Http_Request $httpRequest)
138
+ {
139
+ if ($this->client->getClassConfig("Google_Http_Request", "enable_gzip_for_uploads")) {
140
+ $httpRequest->enableGzip();
141
+ } else {
142
+ $httpRequest->disableGzip();
143
+ }
144
+
145
+ $response = $this->client->getIo()->makeRequest($httpRequest);
146
+ $response->setExpectedClass($this->request->getExpectedClass());
147
+ $code = $response->getResponseHttpCode();
148
+ $this->httpResultCode = $code;
149
+
150
+ if (308 == $code) {
151
+ // Track the amount uploaded.
152
+ $range = explode('-', $response->getResponseHeader('range'));
153
+ $this->progress = $range[1] + 1;
154
+
155
+ // Allow for changing upload URLs.
156
+ $location = $response->getResponseHeader('location');
157
+ if ($location) {
158
+ $this->resumeUri = $location;
159
+ }
160
+
161
+ // No problems, but upload not complete.
162
+ return false;
163
+ } else {
164
+ return Google_Http_REST::decodeHttpResponse($response, $this->client);
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Send the next part of the file to upload.
170
+ * @param [$chunk] the next set of bytes to send. If false will used $data passed
171
+ * at construct time.
172
+ */
173
+ public function nextChunk($chunk = false)
174
+ {
175
+ if (false == $this->resumeUri) {
176
+ $this->resumeUri = $this->fetchResumeUri();
177
+ }
178
+
179
+ if (false == $chunk) {
180
+ $chunk = substr($this->data, $this->progress, $this->chunkSize);
181
+ }
182
+ $lastBytePos = $this->progress + strlen($chunk) - 1;
183
+ $headers = array(
184
+ 'content-range' => "bytes $this->progress-$lastBytePos/$this->size",
185
+ 'content-type' => $this->request->getRequestHeader('content-type'),
186
+ 'content-length' => $this->chunkSize,
187
+ 'expect' => '',
188
+ );
189
+
190
+ $httpRequest = new Google_Http_Request(
191
+ $this->resumeUri,
192
+ 'PUT',
193
+ $headers,
194
+ $chunk
195
+ );
196
+ return $this->makePutRequest($httpRequest);
197
+ }
198
+
199
+ /**
200
+ * Resume a previously unfinished upload
201
+ * @param $resumeUri the resume-URI of the unfinished, resumable upload.
202
+ */
203
+ public function resume($resumeUri)
204
+ {
205
+ $this->resumeUri = $resumeUri;
206
+ $headers = array(
207
+ 'content-range' => "bytes */$this->size",
208
+ 'content-length' => 0,
209
+ );
210
+ $httpRequest = new Google_Http_Request(
211
+ $this->resumeUri,
212
+ 'PUT',
213
+ $headers
214
+ );
215
+ return $this->makePutRequest($httpRequest);
216
+ }
217
+
218
+ /**
219
+ * @return array|bool
220
+ * @visible for testing
221
+ */
222
+ private function process()
223
+ {
224
+ $postBody = false;
225
+ $contentType = false;
226
+
227
+ $meta = $this->request->getPostBody();
228
+ $meta = is_string($meta) ? json_decode($meta, true) : $meta;
229
+
230
+ $uploadType = $this->getUploadType($meta);
231
+ $this->request->setQueryParam('uploadType', $uploadType);
232
+ $this->transformToUploadUrl();
233
+ $mimeType = $this->mimeType ?
234
+ $this->mimeType :
235
+ $this->request->getRequestHeader('content-type');
236
+
237
+ if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) {
238
+ $contentType = $mimeType;
239
+ $postBody = is_string($meta) ? $meta : json_encode($meta);
240
+ } else if (self::UPLOAD_MEDIA_TYPE == $uploadType) {
241
+ $contentType = $mimeType;
242
+ $postBody = $this->data;
243
+ } else if (self::UPLOAD_MULTIPART_TYPE == $uploadType) {
244
+ // This is a multipart/related upload.
245
+ $boundary = $this->boundary ? $this->boundary : mt_rand();
246
+ $boundary = str_replace('"', '', $boundary);
247
+ $contentType = 'multipart/related; boundary=' . $boundary;
248
+ $related = "--$boundary\r\n";
249
+ $related .= "Content-Type: application/json; charset=UTF-8\r\n";
250
+ $related .= "\r\n" . json_encode($meta) . "\r\n";
251
+ $related .= "--$boundary\r\n";
252
+ $related .= "Content-Type: $mimeType\r\n";
253
+ $related .= "Content-Transfer-Encoding: base64\r\n";
254
+ $related .= "\r\n" . base64_encode($this->data) . "\r\n";
255
+ $related .= "--$boundary--";
256
+ $postBody = $related;
257
+ }
258
+
259
+ $this->request->setPostBody($postBody);
260
+
261
+ if (isset($contentType) && $contentType) {
262
+ $contentTypeHeader['content-type'] = $contentType;
263
+ $this->request->setRequestHeaders($contentTypeHeader);
264
+ }
265
+ }
266
+
267
+ private function transformToUploadUrl()
268
+ {
269
+ $base = $this->request->getBaseComponent();
270
+ $this->request->setBaseComponent($base . '/upload');
271
+ }
272
+
273
+ /**
274
+ * Valid upload types:
275
+ * - resumable (UPLOAD_RESUMABLE_TYPE)
276
+ * - media (UPLOAD_MEDIA_TYPE)
277
+ * - multipart (UPLOAD_MULTIPART_TYPE)
278
+ * @param $meta
279
+ * @return string
280
+ * @visible for testing
281
+ */
282
+ public function getUploadType($meta)
283
+ {
284
+ if ($this->resumable) {
285
+ return self::UPLOAD_RESUMABLE_TYPE;
286
+ }
287
+
288
+ if (false == $meta && $this->data) {
289
+ return self::UPLOAD_MEDIA_TYPE;
290
+ }
291
+
292
+ return self::UPLOAD_MULTIPART_TYPE;
293
+ }
294
+
295
+ public function getResumeUri()
296
+ {
297
+ return ( $this->resumeUri !== null ? $this->resumeUri : $this->fetchResumeUri() );
298
+ }
299
+
300
+ private function fetchResumeUri()
301
+ {
302
+ $result = null;
303
+ $body = $this->request->getPostBody();
304
+ if ($body) {
305
+ $headers = array(
306
+ 'content-type' => 'application/json; charset=UTF-8',
307
+ 'content-length' => Google_Utils::getStrLen($body),
308
+ 'x-upload-content-type' => $this->mimeType,
309
+ 'x-upload-content-length' => $this->size,
310
+ 'expect' => '',
311
+ );
312
+ $this->request->setRequestHeaders($headers);
313
+ }
314
+
315
+ $response = $this->client->getIo()->makeRequest($this->request);
316
+ $location = $response->getResponseHeader('location');
317
+ $code = $response->getResponseHttpCode();
318
+
319
+ if (200 == $code && true == $location) {
320
+ return $location;
321
+ }
322
+ $message = $code;
323
+ $body = @json_decode($response->getResponseBody());
324
+ if (!empty($body->error->errors) ) {
325
+ $message .= ': ';
326
+ foreach ($body->error->errors as $error) {
327
+ $message .= "{$error->domain}, {$error->message};";
328
+ }
329
+ $message = rtrim($message, ';');
330
+ }
331
+
332
+ $error = "Failed to start the resumable upload (HTTP {$message})";
333
+ $this->client->getLogger()->error($error);
334
+ throw new Google_Exception($error);
335
+ }
336
+
337
+ public function setChunkSize($chunkSize)
338
+ {
339
+ $this->chunkSize = $chunkSize;
340
+ }
341
+ }
addons/pro/googlesheet/lib/external/Google/Http/REST.php ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * This class implements the RESTful transport of apiServiceRequest()'s
24
+ */
25
+ class Google_Http_REST
26
+ {
27
+ /**
28
+ * Executes a Google_Http_Request and (if applicable) automatically retries
29
+ * when errors occur.
30
+ *
31
+ * @param Google_Client $client
32
+ * @param Google_Http_Request $req
33
+ * @return array decoded result
34
+ * @throws Google_Service_Exception on server side error (ie: not authenticated,
35
+ * invalid or malformed post body, invalid url)
36
+ */
37
+ public static function execute(Google_Client $client, Google_Http_Request $req)
38
+ {
39
+ $runner = new Google_Task_Runner(
40
+ $client,
41
+ sprintf('%s %s', $req->getRequestMethod(), $req->getUrl()),
42
+ array(get_class(), 'doExecute'),
43
+ array($client, $req)
44
+ );
45
+
46
+ return $runner->run();
47
+ }
48
+
49
+ /**
50
+ * Executes a Google_Http_Request
51
+ *
52
+ * @param Google_Client $client
53
+ * @param Google_Http_Request $req
54
+ * @return array decoded result
55
+ * @throws Google_Service_Exception on server side error (ie: not authenticated,
56
+ * invalid or malformed post body, invalid url)
57
+ */
58
+ public static function doExecute(Google_Client $client, Google_Http_Request $req)
59
+ {
60
+ $httpRequest = $client->getIo()->makeRequest($req);
61
+ $httpRequest->setExpectedClass($req->getExpectedClass());
62
+ return self::decodeHttpResponse($httpRequest, $client);
63
+ }
64
+
65
+ /**
66
+ * Decode an HTTP Response.
67
+ * @static
68
+ * @throws Google_Service_Exception
69
+ * @param Google_Http_Request $response The http response to be decoded.
70
+ * @param Google_Client $client
71
+ * @return mixed|null
72
+ */
73
+ public static function decodeHttpResponse($response, Google_Client $client = null)
74
+ {
75
+ $code = $response->getResponseHttpCode();
76
+ $body = $response->getResponseBody();
77
+ $decoded = null;
78
+
79
+ if ((intVal($code)) >= 300) {
80
+ $decoded = json_decode($body, true);
81
+ $err = 'Error calling ' . $response->getRequestMethod() . ' ' . $response->getUrl();
82
+ if (isset($decoded['error']) &&
83
+ isset($decoded['error']['message']) &&
84
+ isset($decoded['error']['code'])) {
85
+ // if we're getting a json encoded error definition, use that instead of the raw response
86
+ // body for improved readability
87
+ $err .= ": ({$decoded['error']['code']}) {$decoded['error']['message']}";
88
+ } else {
89
+ $err .= ": ($code) $body";
90
+ }
91
+
92
+ $errors = null;
93
+ // Specific check for APIs which don't return error details, such as Blogger.
94
+ if (isset($decoded['error']) && isset($decoded['error']['errors'])) {
95
+ $errors = $decoded['error']['errors'];
96
+ }
97
+
98
+ $map = null;
99
+ if ($client) {
100
+ $client->getLogger()->error(
101
+ $err,
102
+ array('code' => $code, 'errors' => $errors)
103
+ );
104
+
105
+ $map = $client->getClassConfig(
106
+ 'Google_Service_Exception',
107
+ 'retry_map'
108
+ );
109
+ }
110
+ throw new Google_Service_Exception($err, $code, null, $errors, $map);
111
+ }
112
+
113
+ // Only attempt to decode the response, if the response code wasn't (204) 'no content'
114
+ if ($code != '204') {
115
+ if ($response->getExpectedRaw()) {
116
+ return $body;
117
+ }
118
+
119
+ $decoded = json_decode($body, true);
120
+ if ($decoded === null || $decoded === "") {
121
+ $error = "Invalid json in service response: $body";
122
+ if ($client) {
123
+ $client->getLogger()->error($error);
124
+ }
125
+ throw new Google_Service_Exception($error);
126
+ }
127
+
128
+ if ($response->getExpectedClass()) {
129
+ $class = $response->getExpectedClass();
130
+ $decoded = new $class($decoded);
131
+ }
132
+ }
133
+ return $decoded;
134
+ }
135
+
136
+ /**
137
+ * Parse/expand request parameters and create a fully qualified
138
+ * request uri.
139
+ * @static
140
+ * @param string $servicePath
141
+ * @param string $restPath
142
+ * @param array $params
143
+ * @return string $requestUrl
144
+ */
145
+ public static function createRequestUri($servicePath, $restPath, $params)
146
+ {
147
+ $requestUrl = $servicePath . $restPath;
148
+ $uriTemplateVars = array();
149
+ $queryVars = array();
150
+ foreach ($params as $paramName => $paramSpec) {
151
+ if ($paramSpec['type'] == 'boolean') {
152
+ $paramSpec['value'] = ($paramSpec['value']) ? 'true' : 'false';
153
+ }
154
+ if ($paramSpec['location'] == 'path') {
155
+ $uriTemplateVars[$paramName] = $paramSpec['value'];
156
+ } else if ($paramSpec['location'] == 'query') {
157
+ if (isset($paramSpec['repeated']) && is_array($paramSpec['value'])) {
158
+ foreach ($paramSpec['value'] as $value) {
159
+ $queryVars[] = $paramName . '=' . rawurlencode(rawurldecode($value));
160
+ }
161
+ } else {
162
+ $queryVars[] = $paramName . '=' . rawurlencode(rawurldecode($paramSpec['value']));
163
+ }
164
+ }
165
+ }
166
+
167
+ if (count($uriTemplateVars)) {
168
+ $uriTemplateParser = new Google_Utils_URITemplate();
169
+ $requestUrl = $uriTemplateParser->parse($requestUrl, $uriTemplateVars);
170
+ }
171
+
172
+ if (count($queryVars)) {
173
+ $requestUrl .= '?' . implode($queryVars, '&');
174
+ }
175
+
176
+ return $requestUrl;
177
+ }
178
+ }
addons/pro/googlesheet/lib/external/Google/Http/Request.php ADDED
@@ -0,0 +1,504 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * HTTP Request to be executed by IO classes. Upon execution, the
24
+ * responseHttpCode, responseHeaders and responseBody will be filled in.
25
+ *
26
+ * @author Chris Chabot <chabotc@google.com>
27
+ * @author Chirag Shah <chirags@google.com>
28
+ *
29
+ */
30
+ class Google_Http_Request
31
+ {
32
+ const GZIP_UA = " (gzip)";
33
+
34
+ private $batchHeaders = array(
35
+ 'Content-Type' => 'application/http',
36
+ 'Content-Transfer-Encoding' => 'binary',
37
+ 'MIME-Version' => '1.0',
38
+ );
39
+
40
+ protected $queryParams;
41
+ protected $requestMethod;
42
+ protected $requestHeaders;
43
+ protected $baseComponent = null;
44
+ protected $path;
45
+ protected $postBody;
46
+ protected $userAgent;
47
+ protected $canGzip = null;
48
+
49
+ protected $responseHttpCode;
50
+ protected $responseHeaders;
51
+ protected $responseBody;
52
+
53
+ protected $expectedClass;
54
+ protected $expectedRaw = false;
55
+
56
+ public $accessKey;
57
+
58
+ public function __construct(
59
+ $url,
60
+ $method = 'GET',
61
+ $headers = array(),
62
+ $postBody = null
63
+ ) {
64
+ $this->setUrl($url);
65
+ $this->setRequestMethod($method);
66
+ $this->setRequestHeaders($headers);
67
+ $this->setPostBody($postBody);
68
+ }
69
+
70
+ /**
71
+ * Misc function that returns the base url component of the $url
72
+ * used by the OAuth signing class to calculate the base string
73
+ * @return string The base url component of the $url.
74
+ */
75
+ public function getBaseComponent()
76
+ {
77
+ return $this->baseComponent;
78
+ }
79
+
80
+ /**
81
+ * Set the base URL that path and query parameters will be added to.
82
+ * @param $baseComponent string
83
+ */
84
+ public function setBaseComponent($baseComponent)
85
+ {
86
+ $this->baseComponent = rtrim($baseComponent, '/');
87
+ }
88
+
89
+ /**
90
+ * Enable support for gzipped responses with this request.
91
+ */
92
+ public function enableGzip()
93
+ {
94
+ $this->setRequestHeaders(array("Accept-Encoding" => "gzip"));
95
+ $this->canGzip = true;
96
+ $this->setUserAgent($this->userAgent);
97
+ }
98
+
99
+ /**
100
+ * Disable support for gzip responses with this request.
101
+ */
102
+ public function disableGzip()
103
+ {
104
+ if (
105
+ isset($this->requestHeaders['accept-encoding']) &&
106
+ $this->requestHeaders['accept-encoding'] == "gzip"
107
+ ) {
108
+ unset($this->requestHeaders['accept-encoding']);
109
+ }
110
+ $this->canGzip = false;
111
+ $this->userAgent = str_replace(self::GZIP_UA, "", $this->userAgent);
112
+ }
113
+
114
+ /**
115
+ * Can this request accept a gzip response?
116
+ * @return bool
117
+ */
118
+ public function canGzip()
119
+ {
120
+ return $this->canGzip;
121
+ }
122
+
123
+ /**
124
+ * Misc function that returns an array of the query parameters of the current
125
+ * url used by the OAuth signing class to calculate the signature
126
+ * @return array Query parameters in the query string.
127
+ */
128
+ public function getQueryParams()
129
+ {
130
+ return $this->queryParams;
131
+ }
132
+
133
+ /**
134
+ * Set a new query parameter.
135
+ * @param $key - string to set, does not need to be URL encoded
136
+ * @param $value - string to set, does not need to be URL encoded
137
+ */
138
+ public function setQueryParam($key, $value)
139
+ {
140
+ $this->queryParams[$key] = $value;
141
+ }
142
+
143
+ /**
144
+ * @return string HTTP Response Code.
145
+ */
146
+ public function getResponseHttpCode()
147
+ {
148
+ return (int) $this->responseHttpCode;
149
+ }
150
+
151
+ /**
152
+ * @param int $responseHttpCode HTTP Response Code.
153
+ */
154
+ public function setResponseHttpCode($responseHttpCode)
155
+ {
156
+ $this->responseHttpCode = $responseHttpCode;
157
+ }
158
+
159
+ /**
160
+ * @return $responseHeaders (array) HTTP Response Headers.
161
+ */
162
+ public function getResponseHeaders()
163
+ {
164
+ return $this->responseHeaders;
165
+ }
166
+
167
+ /**
168
+ * @return string HTTP Response Body
169
+ */
170
+ public function getResponseBody()
171
+ {
172
+ return $this->responseBody;
173
+ }
174
+
175
+ /**
176
+ * Set the class the response to this request should expect.
177
+ *
178
+ * @param $class string the class name
179
+ */
180
+ public function setExpectedClass($class)
181
+ {
182
+ $this->expectedClass = $class;
183
+ }
184
+
185
+ /**
186
+ * Retrieve the expected class the response should expect.
187
+ * @return string class name
188
+ */
189
+ public function getExpectedClass()
190
+ {
191
+ return $this->expectedClass;
192
+ }
193
+
194
+ /**
195
+ * Enable expected raw response
196
+ */
197
+ public function enableExpectedRaw()
198
+ {
199
+ $this->expectedRaw = true;
200
+ }
201
+
202
+ /**
203
+ * Disable expected raw response
204
+ */
205
+ public function disableExpectedRaw()
206
+ {
207
+ $this->expectedRaw = false;
208
+ }
209
+
210
+ /**
211
+ * Expected raw response or not.
212
+ * @return boolean expected raw response
213
+ */
214
+ public function getExpectedRaw()
215
+ {
216
+ return $this->expectedRaw;
217
+ }
218
+
219
+ /**
220
+ * @param array $headers The HTTP response headers
221
+ * to be normalized.
222
+ */
223
+ public function setResponseHeaders($headers)
224
+ {
225
+ $headers = Google_Utils::normalize($headers);
226
+ if ($this->responseHeaders) {
227
+ $headers = array_merge($this->responseHeaders, $headers);
228
+ }
229
+
230
+ $this->responseHeaders = $headers;
231
+ }
232
+
233
+ /**
234
+ * @param string $key
235
+ * @return array|boolean Returns the requested HTTP header or
236
+ * false if unavailable.
237
+ */
238
+ public function getResponseHeader($key)
239
+ {
240
+ return isset($this->responseHeaders[$key])
241
+ ? $this->responseHeaders[$key]
242
+ : false;
243
+ }
244
+
245
+ /**
246
+ * @param string $responseBody The HTTP response body.
247
+ */
248
+ public function setResponseBody($responseBody)
249
+ {
250
+ $this->responseBody = $responseBody;
251
+ }
252
+
253
+ /**
254
+ * @return string $url The request URL.
255
+ */
256
+ public function getUrl()
257
+ {
258
+ return $this->baseComponent . $this->path .
259
+ (count($this->queryParams) ?
260
+ "?" . $this->buildQuery($this->queryParams) :
261
+ '');
262
+ }
263
+
264
+ /**
265
+ * @return string $method HTTP Request Method.
266
+ */
267
+ public function getRequestMethod()
268
+ {
269
+ return $this->requestMethod;
270
+ }
271
+
272
+ /**
273
+ * @return array $headers HTTP Request Headers.
274
+ */
275
+ public function getRequestHeaders()
276
+ {
277
+ return $this->requestHeaders;
278
+ }
279
+
280
+ /**
281
+ * @param string $key
282
+ * @return array|boolean Returns the requested HTTP header or
283
+ * false if unavailable.
284
+ */
285
+ public function getRequestHeader($key)
286
+ {
287
+ return isset($this->requestHeaders[$key])
288
+ ? $this->requestHeaders[$key]
289
+ : false;
290
+ }
291
+
292
+ /**
293
+ * @return string $postBody HTTP Request Body.
294
+ */
295
+ public function getPostBody()
296
+ {
297
+ return $this->postBody;
298
+ }
299
+
300
+ /**
301
+ * @param string $url the url to set
302
+ */
303
+ public function setUrl($url)
304
+ {
305
+ if (substr($url, 0, 4) != 'http') {
306
+ // Force the path become relative.
307
+ if (substr($url, 0, 1) !== '/') {
308
+ $url = '/' . $url;
309
+ }
310
+ }
311
+ $parts = parse_url($url);
312
+ if (isset($parts['host'])) {
313
+ $this->baseComponent = sprintf(
314
+ "%s%s%s",
315
+ isset($parts['scheme']) ? $parts['scheme'] . "://" : '',
316
+ isset($parts['host']) ? $parts['host'] : '',
317
+ isset($parts['port']) ? ":" . $parts['port'] : ''
318
+ );
319
+ }
320
+ $this->path = isset($parts['path']) ? $parts['path'] : '';
321
+ $this->queryParams = array();
322
+ if (isset($parts['query'])) {
323
+ $this->queryParams = $this->parseQuery($parts['query']);
324
+ }
325
+ }
326
+
327
+ /**
328
+ * @param string $method Set he HTTP Method and normalize
329
+ * it to upper-case, as required by HTTP.
330
+ *
331
+ */
332
+ public function setRequestMethod($method)
333
+ {
334
+ $this->requestMethod = strtoupper($method);
335
+ }
336
+
337
+ /**
338
+ * @param array $headers The HTTP request headers
339
+ * to be set and normalized.
340
+ */
341
+ public function setRequestHeaders($headers)
342
+ {
343
+ $headers = Google_Utils::normalize($headers);
344
+ if ($this->requestHeaders) {
345
+ $headers = array_merge($this->requestHeaders, $headers);
346
+ }
347
+ $this->requestHeaders = $headers;
348
+ }
349
+
350
+ /**
351
+ * @param string $postBody the postBody to set
352
+ */
353
+ public function setPostBody($postBody)
354
+ {
355
+ $this->postBody = $postBody;
356
+ }
357
+
358
+ /**
359
+ * Set the User-Agent Header.
360
+ * @param string $userAgent The User-Agent.
361
+ */
362
+ public function setUserAgent($userAgent)
363
+ {
364
+ $this->userAgent = $userAgent;
365
+ if ($this->canGzip) {
366
+ $this->userAgent = $userAgent . self::GZIP_UA;
367
+ }
368
+ }
369
+
370
+ /**
371
+ * @return string The User-Agent.
372
+ */
373
+ public function getUserAgent()
374
+ {
375
+ return $this->userAgent;
376
+ }
377
+
378
+ /**
379
+ * Returns a cache key depending on if this was an OAuth signed request
380
+ * in which case it will use the non-signed url and access key to make this
381
+ * cache key unique per authenticated user, else use the plain request url
382
+ * @return string The md5 hash of the request cache key.
383
+ */
384
+ public function getCacheKey()
385
+ {
386
+ $key = $this->getUrl();
387
+
388
+ if (isset($this->accessKey)) {
389
+ $key .= $this->accessKey;
390
+ }
391
+
392
+ if (isset($this->requestHeaders['authorization'])) {
393
+ $key .= $this->requestHeaders['authorization'];
394
+ }
395
+
396
+ return md5($key);
397
+ }
398
+
399
+ public function getParsedCacheControl()
400
+ {
401
+ $parsed = array();
402
+ $rawCacheControl = $this->getResponseHeader('cache-control');
403
+ if ($rawCacheControl) {
404
+ $rawCacheControl = str_replace(', ', '&', $rawCacheControl);
405
+ parse_str($rawCacheControl, $parsed);
406
+ }
407
+
408
+ return $parsed;
409
+ }
410
+
411
+ /**
412
+ * @param string $id
413
+ * @return string A string representation of the HTTP Request.
414
+ */
415
+ public function toBatchString($id)
416
+ {
417
+ $str = '';
418
+ $path = parse_url($this->getUrl(), PHP_URL_PATH) . "?" .
419
+ http_build_query($this->queryParams);
420
+ $str .= $this->getRequestMethod() . ' ' . $path . " HTTP/1.1\n";
421
+
422
+ foreach ($this->getRequestHeaders() as $key => $val) {
423
+ $str .= $key . ': ' . $val . "\n";
424
+ }
425
+
426
+ if ($this->getPostBody()) {
427
+ $str .= "\n";
428
+ $str .= $this->getPostBody();
429
+ }
430
+
431
+ $headers = '';
432
+ foreach ($this->batchHeaders as $key => $val) {
433
+ $headers .= $key . ': ' . $val . "\n";
434
+ }
435
+
436
+ $headers .= "Content-ID: $id\n";
437
+ $str = $headers . "\n" . $str;
438
+
439
+ return $str;
440
+ }
441
+
442
+ /**
443
+ * Our own version of parse_str that allows for multiple variables
444
+ * with the same name.
445
+ * @param $string - the query string to parse
446
+ */
447
+ private function parseQuery($string)
448
+ {
449
+ $return = array();
450
+ $parts = explode("&", $string);
451
+ foreach ($parts as $part) {
452
+ list($key, $value) = explode('=', $part, 2);
453
+ $value = urldecode($value);
454
+ if (isset($return[$key])) {
455
+ if (!is_array($return[$key])) {
456
+ $return[$key] = array($return[$key]);
457
+ }
458
+ $return[$key][] = $value;
459
+ } else {
460
+ $return[$key] = $value;
461
+ }
462
+ }
463
+ return $return;
464
+ }
465
+
466
+ /**
467
+ * A version of build query that allows for multiple
468
+ * duplicate keys.
469
+ * @param $parts array of key value pairs
470
+ */
471
+ private function buildQuery($parts)
472
+ {
473
+ $return = array();
474
+ foreach ($parts as $key => $value) {
475
+ if (is_array($value)) {
476
+ foreach ($value as $v) {
477
+ $return[] = urlencode($key) . "=" . urlencode($v);
478
+ }
479
+ } else {
480
+ $return[] = urlencode($key) . "=" . urlencode($value);
481
+ }
482
+ }
483
+ return implode('&', $return);
484
+ }
485
+
486
+ /**
487
+ * If we're POSTing and have no body to send, we can send the query
488
+ * parameters in there, which avoids length issues with longer query
489
+ * params.
490
+ */
491
+ public function maybeMoveParametersToBody()
492
+ {
493
+ if ($this->getRequestMethod() == "POST" && empty($this->postBody)) {
494
+ $this->setRequestHeaders(
495
+ array(
496
+ "content-type" =>
497
+ "application/x-www-form-urlencoded; charset=UTF-8"
498
+ )
499
+ );
500
+ $this->setPostBody($this->buildQuery($this->queryParams));
501
+ $this->queryParams = array();
502
+ }
503
+ }
504
+ }
addons/pro/googlesheet/lib/external/Google/IO/Abstract.php ADDED
@@ -0,0 +1,339 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2013 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Abstract IO base class
20
+ */
21
+
22
+ if (!class_exists('Google_Client')) {
23
+ require_once dirname(__FILE__) . '/../autoload.php';
24
+ }
25
+
26
+ abstract class Google_IO_Abstract
27
+ {
28
+ const UNKNOWN_CODE = 0;
29
+ const FORM_URLENCODED = 'application/x-www-form-urlencoded';
30
+ private static $CONNECTION_ESTABLISHED_HEADERS = array(
31
+ "HTTP/1.0 200 Connection established\r\n\r\n",
32
+ "HTTP/1.1 200 Connection established\r\n\r\n",
33
+ );
34
+ private static $ENTITY_HTTP_METHODS = array("POST" => null, "PUT" => null);
35
+ private static $HOP_BY_HOP = array(
36
+ 'connection' => true,
37
+ 'keep-alive' => true,
38
+ 'proxy-authenticate' => true,
39
+ 'proxy-authorization' => true,
40
+ 'te' => true,
41
+ 'trailers' => true,
42
+ 'transfer-encoding' => true,
43
+ 'upgrade' => true
44
+ );
45
+
46
+
47
+ /** @var Google_Client */
48
+ protected $client;
49
+
50
+ public function __construct(Google_Client $client)
51
+ {
52
+ $this->client = $client;
53
+ $timeout = $client->getClassConfig('Google_IO_Abstract', 'request_timeout_seconds');
54
+ if ($timeout > 0) {
55
+ $this->setTimeout($timeout);
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Executes a Google_Http_Request
61
+ * @param Google_Http_Request $request the http request to be executed
62
+ * @return array containing response headers, body, and http code
63
+ * @throws Google_IO_Exception on curl or IO error
64
+ */
65
+ abstract public function executeRequest(Google_Http_Request $request);
66
+
67
+ /**
68
+ * Set options that update the transport implementation's behavior.
69
+ * @param $options
70
+ */
71
+ abstract public function setOptions($options);
72
+
73
+ /**
74
+ * Set the maximum request time in seconds.
75
+ * @param $timeout in seconds
76
+ */
77
+ abstract public function setTimeout($timeout);
78
+
79
+ /**
80
+ * Get the maximum request time in seconds.
81
+ * @return timeout in seconds
82
+ */
83
+ abstract public function getTimeout();
84
+
85
+ /**
86
+ * Test for the presence of a cURL header processing bug
87
+ *
88
+ * The cURL bug was present in versions prior to 7.30.0 and caused the header
89
+ * length to be miscalculated when a "Connection established" header added by
90
+ * some proxies was present.
91
+ *
92
+ * @return boolean
93
+ */
94
+ abstract protected function needsQuirk();
95
+
96
+ /**
97
+ * @visible for testing.
98
+ * Cache the response to an HTTP request if it is cacheable.
99
+ * @param Google_Http_Request $request
100
+ * @return bool Returns true if the insertion was successful.
101
+ * Otherwise, return false.
102
+ */
103
+ public function setCachedRequest(Google_Http_Request $request)
104
+ {
105
+ // Determine if the request is cacheable.
106
+ if (Google_Http_CacheParser::isResponseCacheable($request)) {
107
+ $this->client->getCache()->set($request->getCacheKey(), $request);
108
+ return true;
109
+ }
110
+
111
+ return false;
112
+ }
113
+
114
+ /**
115
+ * Execute an HTTP Request
116
+ *
117
+ * @param Google_Http_Request $request the http request to be executed
118
+ * @return Google_Http_Request http request with the response http code,
119
+ * response headers and response body filled in
120
+ * @throws Google_IO_Exception on curl or IO error
121
+ */
122
+ public function makeRequest(Google_Http_Request $request)
123
+ {
124
+ // First, check to see if we have a valid cached version.
125
+ $cached = $this->getCachedRequest($request);
126
+ if ($cached !== false && $cached instanceof Google_Http_Request) {
127
+ if (!$this->checkMustRevalidateCachedRequest($cached, $request)) {
128
+ return $cached;
129
+ }
130
+ }
131
+
132
+ if (array_key_exists($request->getRequestMethod(), self::$ENTITY_HTTP_METHODS)) {
133
+ $request = $this->processEntityRequest($request);
134
+ }
135
+
136
+ list($responseData, $responseHeaders, $respHttpCode) = $this->executeRequest($request);
137
+
138
+ if ($respHttpCode == 304 && $cached) {
139
+ // If the server responded NOT_MODIFIED, return the cached request.
140
+ $this->updateCachedRequest($cached, $responseHeaders);
141
+ return $cached;
142
+ }
143
+
144
+ if (!isset($responseHeaders['Date']) && !isset($responseHeaders['date'])) {
145
+ $responseHeaders['date'] = date("r");
146
+ }
147
+
148
+ $request->setResponseHttpCode($respHttpCode);
149
+ $request->setResponseHeaders($responseHeaders);
150
+ $request->setResponseBody($responseData);
151
+ // Store the request in cache (the function checks to see if the request
152
+ // can actually be cached)
153
+ $this->setCachedRequest($request);
154
+ return $request;
155
+ }
156
+
157
+ /**
158
+ * @visible for testing.
159
+ * @param Google_Http_Request $request
160
+ * @return Google_Http_Request|bool Returns the cached object or
161
+ * false if the operation was unsuccessful.
162
+ */
163
+ public function getCachedRequest(Google_Http_Request $request)
164
+ {
165
+ if (false === Google_Http_CacheParser::isRequestCacheable($request)) {
166
+ return false;
167
+ }
168
+
169
+ return $this->client->getCache()->get($request->getCacheKey());
170
+ }
171
+
172
+ /**
173
+ * @visible for testing
174
+ * Process an http request that contains an enclosed entity.
175
+ * @param Google_Http_Request $request
176
+ * @return Google_Http_Request Processed request with the enclosed entity.
177
+ */
178
+ public function processEntityRequest(Google_Http_Request $request)
179
+ {
180
+ $postBody = $request->getPostBody();
181
+ $contentType = $request->getRequestHeader("content-type");
182
+
183
+ // Set the default content-type as application/x-www-form-urlencoded.
184
+ if (false == $contentType) {
185
+ $contentType = self::FORM_URLENCODED;
186
+ $request->setRequestHeaders(array('content-type' => $contentType));
187
+ }
188
+
189
+ // Force the payload to match the content-type asserted in the header.
190
+ if ($contentType == self::FORM_URLENCODED && is_array($postBody)) {
191
+ $postBody = http_build_query($postBody, '', '&');
192
+ $request->setPostBody($postBody);
193
+ }
194
+
195
+ // Make sure the content-length header is set.
196
+ if (!$postBody || is_string($postBody)) {
197
+ $postsLength = strlen($postBody);
198
+ $request->setRequestHeaders(array('content-length' => $postsLength));
199
+ }
200
+
201
+ return $request;
202
+ }
203
+
204
+ /**
205
+ * Check if an already cached request must be revalidated, and if so update
206
+ * the request with the correct ETag headers.
207
+ * @param Google_Http_Request $cached A previously cached response.
208
+ * @param Google_Http_Request $request The outbound request.
209
+ * return bool If the cached object needs to be revalidated, false if it is
210
+ * still current and can be re-used.
211
+ */
212
+ protected function checkMustRevalidateCachedRequest($cached, $request)
213
+ {
214
+ if (Google_Http_CacheParser::mustRevalidate($cached)) {
215
+ $addHeaders = array();
216
+ if ($cached->getResponseHeader('etag')) {
217
+ // [13.3.4] If an entity tag has been provided by the origin server,
218
+ // we must use that entity tag in any cache-conditional request.
219
+ $addHeaders['If-None-Match'] = $cached->getResponseHeader('etag');
220
+ } elseif ($cached->getResponseHeader('date')) {
221
+ $addHeaders['If-Modified-Since'] = $cached->getResponseHeader('date');
222
+ }
223
+
224
+ $request->setRequestHeaders($addHeaders);
225
+ return true;
226
+ } else {
227
+ return false;
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Update a cached request, using the headers from the last response.
233
+ * @param Google_Http_Request $cached A previously cached response.
234
+ * @param mixed Associative array of response headers from the last request.
235
+ */
236
+ protected function updateCachedRequest($cached, $responseHeaders)
237
+ {
238
+ $hopByHop = self::$HOP_BY_HOP;
239
+ if (!empty($responseHeaders['connection'])) {
240
+ $connectionHeaders = array_map(
241
+ 'strtolower',
242
+ array_filter(
243
+ array_map('trim', explode(',', $responseHeaders['connection']))
244
+ )
245
+ );
246
+ $hopByHop += array_fill_keys($connectionHeaders, true);
247
+ }
248
+
249
+ $endToEnd = array_diff_key($responseHeaders, $hopByHop);
250
+ $cached->setResponseHeaders($endToEnd);
251
+ }
252
+
253
+ /**
254
+ * Used by the IO lib and also the batch processing.
255
+ *
256
+ * @param $respData
257
+ * @param $headerSize
258
+ * @return array
259
+ */
260
+ public function parseHttpResponse($respData, $headerSize)
261
+ {
262
+ // check proxy header
263
+ foreach (self::$CONNECTION_ESTABLISHED_HEADERS as $established_header) {
264
+ if (stripos($respData, $established_header) !== false) {
265
+ // existed, remove it
266
+ $respData = str_ireplace($established_header, '', $respData);
267
+ // Subtract the proxy header size unless the cURL bug prior to 7.30.0
268
+ // is present which prevented the proxy header size from being taken into
269
+ // account.
270
+ if (!$this->needsQuirk()) {
271
+ $headerSize -= strlen($established_header);
272
+ }
273
+ break;
274
+ }
275
+ }
276
+
277
+ if ($headerSize) {
278
+ $responseBody = substr($respData, $headerSize);
279
+ $responseHeaders = substr($respData, 0, $headerSize);
280
+ } else {
281
+ $responseSegments = explode("\r\n\r\n", $respData, 2);
282
+ $responseHeaders = $responseSegments[0];
283
+ $responseBody = isset($responseSegments[1]) ? $responseSegments[1] :
284
+ null;
285
+ }
286
+
287
+ $responseHeaders = $this->getHttpResponseHeaders($responseHeaders);
288
+ return array($responseHeaders, $responseBody);
289
+ }
290
+
291
+ /**
292
+ * Parse out headers from raw headers
293
+ * @param rawHeaders array or string
294
+ * @return array
295
+ */
296
+ public function getHttpResponseHeaders($rawHeaders)
297
+ {
298
+ if (is_array($rawHeaders)) {
299
+ return $this->parseArrayHeaders($rawHeaders);
300
+ } else {
301
+ return $this->parseStringHeaders($rawHeaders);
302
+ }
303
+ }
304
+
305
+ private function parseStringHeaders($rawHeaders)
306
+ {
307
+ $headers = array();
308
+ $responseHeaderLines = explode("\r\n", $rawHeaders);
309
+ foreach ($responseHeaderLines as $headerLine) {
310
+ if ($headerLine && strpos($headerLine, ':') !== false) {
311
+ list($header, $value) = explode(': ', $headerLine, 2);
312
+ $header = strtolower($header);
313
+ if (isset($headers[$header])) {
314
+ $headers[$header] .= "\n" . $value;
315
+ } else {
316
+ $headers[$header] = $value;
317
+ }
318
+ }
319
+ }
320
+ return $headers;
321
+ }
322
+
323
+ private function parseArrayHeaders($rawHeaders)
324
+ {
325
+ $header_count = count($rawHeaders);
326
+ $headers = array();
327
+
328
+ for ($i = 0; $i < $header_count; $i++) {
329
+ $header = $rawHeaders[$i];
330
+ // Times will have colons in - so we just want the first match.
331
+ $header_parts = explode(': ', $header, 2);
332
+ if (count($header_parts) == 2) {
333
+ $headers[strtolower($header_parts[0])] = $header_parts[1];
334
+ }
335
+ }
336
+
337
+ return $headers;
338
+ }
339
+ }
addons/pro/googlesheet/lib/external/Google/IO/Curl.php ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2014 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Curl based implementation of Google_IO.
20
+ *
21
+ * @author Stuart Langley <slangley@google.com>
22
+ */
23
+
24
+ if (!class_exists('Google_Client')) {
25
+ require_once dirname(__FILE__) . '/../autoload.php';
26
+ }
27
+
28
+ class Google_IO_Curl extends Google_IO_Abstract
29
+ {
30
+ // cURL hex representation of version 7.30.0
31
+ const NO_QUIRK_VERSION = 0x071E00;
32
+
33
+ private $options = array();
34
+
35
+ /** @var bool $disableProxyWorkaround */
36
+ private $disableProxyWorkaround;
37
+
38
+ public function __construct(Google_Client $client)
39
+ {
40
+ if (!extension_loaded('curl')) {
41
+ $error = 'The cURL IO handler requires the cURL extension to be enabled';
42
+ $client->getLogger()->critical($error);
43
+ throw new Google_IO_Exception($error);
44
+ }
45
+
46
+ parent::__construct($client);
47
+
48
+ $this->disableProxyWorkaround = $this->client->getClassConfig(
49
+ 'Google_IO_Curl',
50
+ 'disable_proxy_workaround'
51
+ );
52
+ }
53
+
54
+ /**
55
+ * Execute an HTTP Request
56
+ *
57
+ * @param Google_Http_Request $request the http request to be executed
58
+ * @return array containing response headers, body, and http code
59
+ * @throws Google_IO_Exception on curl or IO error
60
+ */
61
+ public function executeRequest(Google_Http_Request $request)
62
+ {
63
+ $curl = curl_init();
64
+
65
+ if ($request->getPostBody()) {
66
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $request->getPostBody());
67
+ }
68
+
69
+ $requestHeaders = $request->getRequestHeaders();
70
+ if ($requestHeaders && is_array($requestHeaders)) {
71
+ $curlHeaders = array();
72
+ foreach ($requestHeaders as $k => $v) {
73
+ $curlHeaders[] = "$k: $v";
74
+ }
75
+ curl_setopt($curl, CURLOPT_HTTPHEADER, $curlHeaders);
76
+ }
77
+ curl_setopt($curl, CURLOPT_URL, $request->getUrl());
78
+
79
+ curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $request->getRequestMethod());
80
+ curl_setopt($curl, CURLOPT_USERAGENT, $request->getUserAgent());
81
+
82
+ curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
83
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
84
+
85
+ // The SSL version will be determined by the underlying library
86
+ // @see https://github.com/google/google-api-php-client/pull/644
87
+ //curl_setopt($curl, CURLOPT_SSLVERSION, 1);
88
+
89
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
90
+ curl_setopt($curl, CURLOPT_HEADER, true);
91
+
92
+ if ($request->canGzip()) {
93
+ curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate');
94
+ }
95
+
96
+ $options = $this->client->getClassConfig('Google_IO_Curl', 'options');
97
+ if (is_array($options)) {
98
+ $this->setOptions($options);
99
+ }
100
+
101
+ foreach ($this->options as $key => $var) {
102
+ curl_setopt($curl, $key, $var);
103
+ }
104
+
105
+ if (!isset($this->options[CURLOPT_CAINFO])) {
106
+ curl_setopt($curl, CURLOPT_CAINFO, dirname(__FILE__) . '/cacerts.pem');
107
+ }
108
+
109
+ $this->client->getLogger()->debug(
110
+ 'cURL request',
111
+ array(
112
+ 'url' => $request->getUrl(),
113
+ 'method' => $request->getRequestMethod(),
114
+ 'headers' => $requestHeaders,
115
+ 'body' => $request->getPostBody()
116
+ )
117
+ );
118
+
119
+ $response = curl_exec($curl);
120
+ if ($response === false) {
121
+ $error = curl_error($curl);
122
+ $code = curl_errno($curl);
123
+ $map = $this->client->getClassConfig('Google_IO_Exception', 'retry_map');
124
+
125
+ $this->client->getLogger()->error('cURL ' . $error);
126
+ throw new Google_IO_Exception($error, $code, null, $map);
127
+ }
128
+ $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
129
+
130
+ list($responseHeaders, $responseBody) = $this->parseHttpResponse($response, $headerSize);
131
+ $responseCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
132
+
133
+ $this->client->getLogger()->debug(
134
+ 'cURL response',
135
+ array(
136
+ 'code' => $responseCode,
137
+ 'headers' => $responseHeaders,
138
+ 'body' => $responseBody,
139
+ )
140
+ );
141
+
142
+ return array($responseBody, $responseHeaders, $responseCode);
143
+ }
144
+
145
+ /**
146
+ * Set options that update the transport implementation's behavior.
147
+ * @param $options
148
+ */
149
+ public function setOptions($options)
150
+ {
151
+ $this->options = $options + $this->options;
152
+ }
153
+
154
+ /**
155
+ * Set the maximum request time in seconds.
156
+ * @param $timeout in seconds
157
+ */
158
+ public function setTimeout($timeout)
159
+ {
160
+ // Since this timeout is really for putting a bound on the time
161
+ // we'll set them both to the same. If you need to specify a longer
162
+ // CURLOPT_TIMEOUT, or a higher CONNECTTIMEOUT, the best thing to
163
+ // do is use the setOptions method for the values individually.
164
+ $this->options[CURLOPT_CONNECTTIMEOUT] = $timeout;
165
+ $this->options[CURLOPT_TIMEOUT] = $timeout;
166
+ }
167
+
168
+ /**
169
+ * Get the maximum request time in seconds.
170
+ * @return timeout in seconds
171
+ */
172
+ public function getTimeout()
173
+ {
174
+ return $this->options[CURLOPT_TIMEOUT];
175
+ }
176
+
177
+ /**
178
+ * Test for the presence of a cURL header processing bug
179
+ *
180
+ * {@inheritDoc}
181
+ *
182
+ * @return boolean
183
+ */
184
+ protected function needsQuirk()
185
+ {
186
+ if ($this->disableProxyWorkaround) {
187
+ return false;
188
+ }
189
+
190
+ $ver = curl_version();
191
+ $versionNum = $ver['version_number'];
192
+ return $versionNum < Google_IO_Curl::NO_QUIRK_VERSION;
193
+ }
194
+ }
addons/pro/googlesheet/lib/external/Google/IO/Exception.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2013 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ class Google_IO_Exception extends Google_Exception implements Google_Task_Retryable
23
+ {
24
+ /**
25
+ * @var array $retryMap Map of errors with retry counts.
26
+ */
27
+ private $retryMap = array();
28
+
29
+ /**
30
+ * Creates a new IO exception with an optional retry map.
31
+ *
32
+ * @param string $message
33
+ * @param int $code
34
+ * @param Exception|null $previous
35
+ * @param array|null $retryMap Map of errors with retry counts.
36
+ */
37
+ public function __construct(
38
+ $message,
39
+ $code = 0,
40
+ Exception $previous = null,
41
+ array $retryMap = null
42
+ ) {
43
+ if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
44
+ parent::__construct($message, $code, $previous);
45
+ } else {
46
+ parent::__construct($message, $code);
47
+ }
48
+
49
+ if (is_array($retryMap)) {
50
+ $this->retryMap = $retryMap;
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Gets the number of times the associated task can be retried.
56
+ *
57
+ * NOTE: -1 is returned if the task can be retried indefinitely
58
+ *
59
+ * @return integer
60
+ */
61
+ public function allowedRetries()
62
+ {
63
+ if (isset($this->retryMap[$this->code])) {
64
+ return $this->retryMap[$this->code];
65
+ }
66
+
67
+ return 0;
68
+ }
69
+ }
addons/pro/googlesheet/lib/external/Google/IO/Stream.php ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2013 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Http Streams based implementation of Google_IO.
20
+ *
21
+ * @author Stuart Langley <slangley@google.com>
22
+ */
23
+
24
+ if (!class_exists('Google_Client')) {
25
+ require_once dirname(__FILE__) . '/../autoload.php';
26
+ }
27
+
28
+ class Google_IO_Stream extends Google_IO_Abstract
29
+ {
30
+ const TIMEOUT = "timeout";
31
+ const ZLIB = "compress.zlib://";
32
+ private $options = array();
33
+ private $trappedErrorNumber;
34
+ private $trappedErrorString;
35
+
36
+ private static $DEFAULT_HTTP_CONTEXT = array(
37
+ "follow_location" => 0,
38
+ "ignore_errors" => 1,
39
+ );
40
+
41
+ private static $DEFAULT_SSL_CONTEXT = array(
42
+ "verify_peer" => true,
43
+ );
44
+
45
+ public function __construct(Google_Client $client)
46
+ {
47
+ if (!ini_get('allow_url_fopen')) {
48
+ $error = 'The stream IO handler requires the allow_url_fopen runtime ' .
49
+ 'configuration to be enabled';
50
+ $client->getLogger()->critical($error);
51
+ throw new Google_IO_Exception($error);
52
+ }
53
+
54
+ parent::__construct($client);
55
+ }
56
+
57
+ /**
58
+ * Execute an HTTP Request
59
+ *
60
+ * @param Google_Http_Request $request the http request to be executed
61
+ * @return array containing response headers, body, and http code
62
+ * @throws Google_IO_Exception on curl or IO error
63
+ */
64
+ public function executeRequest(Google_Http_Request $request)
65
+ {
66
+ $default_options = stream_context_get_options(stream_context_get_default());
67
+
68
+ $requestHttpContext = array_key_exists('http', $default_options) ?
69
+ $default_options['http'] : array();
70
+
71
+ if ($request->getPostBody()) {
72
+ $requestHttpContext["content"] = $request->getPostBody();
73
+ }
74
+
75
+ $requestHeaders = $request->getRequestHeaders();
76
+ if ($requestHeaders && is_array($requestHeaders)) {
77
+ $headers = "";
78
+ foreach ($requestHeaders as $k => $v) {
79
+ $headers .= "$k: $v\r\n";
80
+ }
81
+ $requestHttpContext["header"] = $headers;
82
+ }
83
+
84
+ $requestHttpContext["method"] = $request->getRequestMethod();
85
+ $requestHttpContext["user_agent"] = $request->getUserAgent();
86
+
87
+ $requestSslContext = array_key_exists('ssl', $default_options) ?
88
+ $default_options['ssl'] : array();
89
+
90
+ if (!$this->client->isAppEngine() && !array_key_exists("cafile", $requestSslContext)) {
91
+ $requestSslContext["cafile"] = dirname(__FILE__) . '/cacerts.pem';
92
+ }
93
+
94
+ $options = array(
95
+ "http" => array_merge(
96
+ self::$DEFAULT_HTTP_CONTEXT,
97
+ $requestHttpContext
98
+ ),
99
+ "ssl" => array_merge(
100
+ self::$DEFAULT_SSL_CONTEXT,
101
+ $requestSslContext
102
+ )
103
+ );
104
+
105
+ $context = stream_context_create($options);
106
+
107
+ $url = $request->getUrl();
108
+
109
+ if ($request->canGzip()) {
110
+ $url = self::ZLIB . $url;
111
+ }
112
+
113
+ $this->client->getLogger()->debug(
114
+ 'Stream request',
115
+ array(
116
+ 'url' => $url,
117
+ 'method' => $request->getRequestMethod(),
118
+ 'headers' => $requestHeaders,
119
+ 'body' => $request->getPostBody()
120
+ )
121
+ );
122
+
123
+ // We are trapping any thrown errors in this method only and
124
+ // throwing an exception.
125
+ $this->trappedErrorNumber = null;
126
+ $this->trappedErrorString = null;
127
+
128
+ // START - error trap.
129
+ set_error_handler(array($this, 'trapError'));
130
+ $fh = fopen($url, 'r', false, $context);
131
+ restore_error_handler();
132
+ // END - error trap.
133
+
134
+ if ($this->trappedErrorNumber) {
135
+ $error = sprintf(
136
+ "HTTP Error: Unable to connect: '%s'",
137
+ $this->trappedErrorString
138
+ );
139
+
140
+ $this->client->getLogger()->error('Stream ' . $error);
141
+ throw new Google_IO_Exception($error, $this->trappedErrorNumber);
142
+ }
143
+
144
+ $response_data = false;
145
+ $respHttpCode = self::UNKNOWN_CODE;
146
+ if ($fh) {
147
+ if (isset($this->options[self::TIMEOUT])) {
148
+ stream_set_timeout($fh, $this->options[self::TIMEOUT]);
149
+ }
150
+
151
+ $response_data = stream_get_contents($fh);
152
+ fclose($fh);
153
+
154
+ $respHttpCode = $this->getHttpResponseCode($http_response_header);
155
+ }
156
+
157
+ if (false === $response_data) {
158
+ $error = sprintf(
159
+ "HTTP Error: Unable to connect: '%s'",
160
+ $respHttpCode
161
+ );
162
+
163
+ $this->client->getLogger()->error('Stream ' . $error);
164
+ throw new Google_IO_Exception($error, $respHttpCode);
165
+ }
166
+
167
+ $responseHeaders = $this->getHttpResponseHeaders($http_response_header);
168
+
169
+ $this->client->getLogger()->debug(
170
+ 'Stream response',
171
+ array(
172
+ 'code' => $respHttpCode,
173
+ 'headers' => $responseHeaders,
174
+ 'body' => $response_data,
175
+ )
176
+ );
177
+
178
+ return array($response_data, $responseHeaders, $respHttpCode);
179
+ }
180
+
181
+ /**
182
+ * Set options that update the transport implementation's behavior.
183
+ * @param $options
184
+ */
185
+ public function setOptions($options)
186
+ {
187
+ $this->options = $options + $this->options;
188
+ }
189
+
190
+ /**
191
+ * Method to handle errors, used for error handling around
192
+ * stream connection methods.
193
+ */
194
+ public function trapError($errno, $errstr)
195
+ {
196
+ $this->trappedErrorNumber = $errno;
197
+ $this->trappedErrorString = $errstr;
198
+ }
199
+
200
+ /**
201
+ * Set the maximum request time in seconds.
202
+ * @param $timeout in seconds
203
+ */
204
+ public function setTimeout($timeout)
205
+ {
206
+ $this->options[self::TIMEOUT] = $timeout;
207
+ }
208
+
209
+ /**
210
+ * Get the maximum request time in seconds.
211
+ * @return timeout in seconds
212
+ */
213
+ public function getTimeout()
214
+ {
215
+ return $this->options[self::TIMEOUT];
216
+ }
217
+
218
+ /**
219
+ * Test for the presence of a cURL header processing bug
220
+ *
221
+ * {@inheritDoc}
222
+ *
223
+ * @return boolean
224
+ */
225
+ protected function needsQuirk()
226
+ {
227
+ return false;
228
+ }
229
+
230
+ protected function getHttpResponseCode($response_headers)
231
+ {
232
+ $header_count = count($response_headers);
233
+
234
+ for ($i = 0; $i < $header_count; $i++) {
235
+ $header = $response_headers[$i];
236
+ if (strncasecmp("HTTP", $header, strlen("HTTP")) == 0) {
237
+ $response = explode(' ', $header);
238
+ return $response[1];
239
+ }
240
+ }
241
+ return self::UNKNOWN_CODE;
242
+ }
243
+ }
addons/pro/googlesheet/lib/external/Google/IO/cacerts.pem ADDED
@@ -0,0 +1,2183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Issuer: CN=GTE CyberTrust Global Root O=GTE Corporation OU=GTE CyberTrust Solutions, Inc.
2
+ # Subject: CN=GTE CyberTrust Global Root O=GTE Corporation OU=GTE CyberTrust Solutions, Inc.
3
+ # Label: "GTE CyberTrust Global Root"
4
+ # Serial: 421
5
+ # MD5 Fingerprint: ca:3d:d3:68:f1:03:5c:d0:32:fa:b8:2b:59:e8:5a:db
6
+ # SHA1 Fingerprint: 97:81:79:50:d8:1c:96:70:cc:34:d8:09:cf:79:44:31:36:7e:f4:74
7
+ # SHA256 Fingerprint: a5:31:25:18:8d:21:10:aa:96:4b:02:c7:b7:c6:da:32:03:17:08:94:e5:fb:71:ff:fb:66:67:d5:e6:81:0a:36
8
+ -----BEGIN CERTIFICATE-----
9
+ MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD
10
+ VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv
11
+ bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv
12
+ b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV
13
+ UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU
14
+ cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds
15
+ b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH
16
+ iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS
17
+ r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4
18
+ 04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r
19
+ GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9
20
+ 3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P
21
+ lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/
22
+ -----END CERTIFICATE-----
23
+
24
+ # Issuer: CN=Thawte Server CA O=Thawte Consulting cc OU=Certification Services Division
25
+ # Subject: CN=Thawte Server CA O=Thawte Consulting cc OU=Certification Services Division
26
+ # Label: "Thawte Server CA"
27
+ # Serial: 1
28
+ # MD5 Fingerprint: c5:70:c4:a2:ed:53:78:0c:c8:10:53:81:64:cb:d0:1d
29
+ # SHA1 Fingerprint: 23:e5:94:94:51:95:f2:41:48:03:b4:d5:64:d2:a3:a3:f5:d8:8b:8c
30
+ # SHA256 Fingerprint: b4:41:0b:73:e2:e6:ea:ca:47:fb:c4:2f:8f:a4:01:8a:f4:38:1d:c5:4c:fa:a8:44:50:46:1e:ed:09:45:4d:e9
31
+ -----BEGIN CERTIFICATE-----
32
+ MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx
33
+ FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
34
+ VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
35
+ biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm
36
+ MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx
37
+ MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT
38
+ DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3
39
+ dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl
40
+ cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3
41
+ DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD
42
+ gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91
43
+ yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX
44
+ L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj
45
+ EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG
46
+ 7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e
47
+ QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ
48
+ qdq5snUb9kLy78fyGPmJvKP/iiMucEc=
49
+ -----END CERTIFICATE-----
50
+
51
+ # Issuer: CN=Thawte Premium Server CA O=Thawte Consulting cc OU=Certification Services Division
52
+ # Subject: CN=Thawte Premium Server CA O=Thawte Consulting cc OU=Certification Services Division
53
+ # Label: "Thawte Premium Server CA"
54
+ # Serial: 1
55
+ # MD5 Fingerprint: 06:9f:69:79:16:66:90:02:1b:8c:8c:a2:c3:07:6f:3a
56
+ # SHA1 Fingerprint: 62:7f:8d:78:27:65:63:99:d2:7d:7f:90:44:c9:fe:b3:f3:3e:fa:9a
57
+ # SHA256 Fingerprint: ab:70:36:36:5c:71:54:aa:29:c2:c2:9f:5d:41:91:16:3b:16:2a:22:25:01:13:57:d5:6d:07:ff:a7:bc:1f:72
58
+ -----BEGIN CERTIFICATE-----
59
+ MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx
60
+ FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
61
+ VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
62
+ biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy
63
+ dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t
64
+ MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB
65
+ MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG
66
+ A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp
67
+ b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl
68
+ cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv
69
+ bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE
70
+ VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ
71
+ ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR
72
+ uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
73
+ 9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI
74
+ hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM
75
+ pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg==
76
+ -----END CERTIFICATE-----
77
+
78
+ # Issuer: O=Equifax OU=Equifax Secure Certificate Authority
79
+ # Subject: O=Equifax OU=Equifax Secure Certificate Authority
80
+ # Label: "Equifax Secure CA"
81
+ # Serial: 903804111
82
+ # MD5 Fingerprint: 67:cb:9d:c0:13:24:8a:82:9b:b2:17:1e:d1:1b:ec:d4
83
+ # SHA1 Fingerprint: d2:32:09:ad:23:d3:14:23:21:74:e4:0d:7f:9d:62:13:97:86:63:3a
84
+ # SHA256 Fingerprint: 08:29:7a:40:47:db:a2:36:80:c7:31:db:6e:31:76:53:ca:78:48:e1:be:bd:3a:0b:01:79:a7:07:f9:2c:f1:78
85
+ -----BEGIN CERTIFICATE-----
86
+ MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
87
+ UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
88
+ dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
89
+ MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
90
+ dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
91
+ AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
92
+ BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
93
+ cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
94
+ AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
95
+ MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
96
+ aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
97
+ ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
98
+ IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
99
+ MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
100
+ A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
101
+ 7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
102
+ 1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
103
+ -----END CERTIFICATE-----
104
+
105
+ # Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority
106
+ # Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority
107
+ # Label: "Verisign Class 3 Public Primary Certification Authority"
108
+ # Serial: 149843929435818692848040365716851702463
109
+ # MD5 Fingerprint: 10:fc:63:5d:f6:26:3e:0d:f3:25:be:5f:79:cd:67:67
110
+ # SHA1 Fingerprint: 74:2c:31:92:e6:07:e4:24:eb:45:49:54:2b:e1:bb:c5:3e:61:74:e2
111
+ # SHA256 Fingerprint: e7:68:56:34:ef:ac:f6:9a:ce:93:9a:6b:25:5b:7b:4f:ab:ef:42:93:5b:50:a2:65:ac:b5:cb:60:27:e4:4e:70
112
+ -----BEGIN CERTIFICATE-----
113
+ MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
114
+ A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
115
+ cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
116
+ MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
117
+ BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
118
+ YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
119
+ ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
120
+ BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
121
+ I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
122
+ CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
123
+ lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
124
+ AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
125
+ -----END CERTIFICATE-----
126
+
127
+ # Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority - G2/(c) 1998 VeriSign, Inc. - For authorized use only/VeriSign Trust Network
128
+ # Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority - G2/(c) 1998 VeriSign, Inc. - For authorized use only/VeriSign Trust Network
129
+ # Label: "Verisign Class 3 Public Primary Certification Authority - G2"
130
+ # Serial: 167285380242319648451154478808036881606
131
+ # MD5 Fingerprint: a2:33:9b:4c:74:78:73:d4:6c:e7:c1:f3:8d:cb:5c:e9
132
+ # SHA1 Fingerprint: 85:37:1c:a6:e5:50:14:3d:ce:28:03:47:1b:de:3a:09:e8:f8:77:0f
133
+ # SHA256 Fingerprint: 83:ce:3c:12:29:68:8a:59:3d:48:5f:81:97:3c:0f:91:95:43:1e:da:37:cc:5e:36:43:0e:79:c7:a8:88:63:8b
134
+ -----BEGIN CERTIFICATE-----
135
+ MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
136
+ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
137
+ c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
138
+ MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
139
+ emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
140
+ DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
141
+ FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg
142
+ UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
143
+ YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
144
+ MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
145
+ AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4
146
+ pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0
147
+ 13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID
148
+ AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk
149
+ U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i
150
+ F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY
151
+ oJ2daZH9
152
+ -----END CERTIFICATE-----
153
+
154
+ # Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA
155
+ # Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA
156
+ # Label: "GlobalSign Root CA"
157
+ # Serial: 4835703278459707669005204
158
+ # MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a
159
+ # SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c
160
+ # SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99
161
+ -----BEGIN CERTIFICATE-----
162
+ MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
163
+ A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
164
+ b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
165
+ MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
166
+ YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
167
+ aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
168
+ jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
169
+ xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
170
+ 1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
171
+ snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
172
+ U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
173
+ 9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
174
+ BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
175
+ AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
176
+ yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
177
+ 38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
178
+ AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
179
+ DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
180
+ HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
181
+ -----END CERTIFICATE-----
182
+
183
+ # Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2
184
+ # Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2
185
+ # Label: "GlobalSign Root CA - R2"
186
+ # Serial: 4835703278459682885658125
187
+ # MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30
188
+ # SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe
189
+ # SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e
190
+ -----BEGIN CERTIFICATE-----
191
+ MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
192
+ A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
193
+ Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
194
+ MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
195
+ A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
196
+ hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
197
+ v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
198
+ eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
199
+ tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
200
+ C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
201
+ zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
202
+ mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
203
+ V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
204
+ bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
205
+ 3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
206
+ J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
207
+ 291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
208
+ ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
209
+ AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
210
+ TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
211
+ -----END CERTIFICATE-----
212
+
213
+ # Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 1 Policy Validation Authority
214
+ # Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 1 Policy Validation Authority
215
+ # Label: "ValiCert Class 1 VA"
216
+ # Serial: 1
217
+ # MD5 Fingerprint: 65:58:ab:15:ad:57:6c:1e:a8:a7:b5:69:ac:bf:ff:eb
218
+ # SHA1 Fingerprint: e5:df:74:3c:b6:01:c4:9b:98:43:dc:ab:8c:e8:6a:81:10:9f:e4:8e
219
+ # SHA256 Fingerprint: f4:c1:49:55:1a:30:13:a3:5b:c7:bf:fe:17:a7:f3:44:9b:c1:ab:5b:5a:0a:e7:4b:06:c2:3b:90:00:4c:01:04
220
+ -----BEGIN CERTIFICATE-----
221
+ MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
222
+ IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
223
+ BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
224
+ aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
225
+ 9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIyMjM0OFoXDTE5MDYy
226
+ NTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
227
+ azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
228
+ YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
229
+ Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
230
+ cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9Y
231
+ LqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIiGQj4/xEjm84H9b9pGib+
232
+ TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCmDuJWBQ8Y
233
+ TfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0
234
+ LBwGlN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLW
235
+ I8sogTLDAHkY7FkXicnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPw
236
+ nXS3qT6gpf+2SQMT2iLM7XGCK5nPOrf1LXLI
237
+ -----END CERTIFICATE-----
238
+
239
+ # Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 2 Policy Validation Authority
240
+ # Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 2 Policy Validation Authority
241
+ # Label: "ValiCert Class 2 VA"
242
+ # Serial: 1
243
+ # MD5 Fingerprint: a9:23:75:9b:ba:49:36:6e:31:c2:db:f2:e7:66:ba:87
244
+ # SHA1 Fingerprint: 31:7a:2a:d0:7f:2b:33:5e:f5:a1:c3:4e:4b:57:e8:b7:d8:f1:fc:a6
245
+ # SHA256 Fingerprint: 58:d0:17:27:9c:d4:dc:63:ab:dd:b1:96:a6:c9:90:6c:30:c4:e0:87:83:ea:e8:c1:60:99:54:d6:93:55:59:6b
246
+ -----BEGIN CERTIFICATE-----
247
+ MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
248
+ IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
249
+ BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
250
+ aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
251
+ 9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
252
+ NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
253
+ azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
254
+ YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
255
+ Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
256
+ cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
257
+ dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
258
+ WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
259
+ v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
260
+ UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
261
+ IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
262
+ W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
263
+ -----END CERTIFICATE-----
264
+
265
+ # Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 3 Policy Validation Authority
266
+ # Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 3 Policy Validation Authority
267
+ # Label: "RSA Root Certificate 1"
268
+ # Serial: 1
269
+ # MD5 Fingerprint: a2:6f:53:b7:ee:40:db:4a:68:e7:fa:18:d9:10:4b:72
270
+ # SHA1 Fingerprint: 69:bd:8c:f4:9c:d3:00:fb:59:2e:17:93:ca:55:6a:f3:ec:aa:35:fb
271
+ # SHA256 Fingerprint: bc:23:f9:8a:31:3c:b9:2d:e3:bb:fc:3a:5a:9f:44:61:ac:39:49:4c:4a:e1:5a:9e:9d:f1:31:e9:9b:73:01:9a
272
+ -----BEGIN CERTIFICATE-----
273
+ MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
274
+ IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
275
+ BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
276
+ aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
277
+ 9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMjIzM1oXDTE5MDYy
278
+ NjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
279
+ azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
280
+ YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
281
+ Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
282
+ cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjmFGWHOjVsQaBalfD
283
+ cnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td3zZxFJmP3MKS8edgkpfs
284
+ 2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89HBFx1cQqY
285
+ JJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliE
286
+ Zwgs3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJ
287
+ n0WuPIqpsHEzXcjFV9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/A
288
+ PhmcGcwTTYJBtYze4D1gCCAPRX5ron+jjBXu
289
+ -----END CERTIFICATE-----
290
+
291
+ # Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
292
+ # Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
293
+ # Label: "Verisign Class 3 Public Primary Certification Authority - G3"
294
+ # Serial: 206684696279472310254277870180966723415
295
+ # MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09
296
+ # SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6
297
+ # SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44
298
+ -----BEGIN CERTIFICATE-----
299
+ MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
300
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
301
+ cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
302
+ LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
303
+ aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
304
+ dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
305
+ VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
306
+ aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
307
+ bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
308
+ IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
309
+ LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b
310
+ N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t
311
+ KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu
312
+ kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm
313
+ CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ
314
+ Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu
315
+ imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te
316
+ 2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe
317
+ DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
318
+ /Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p
319
+ F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt
320
+ TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
321
+ -----END CERTIFICATE-----
322
+
323
+ # Issuer: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
324
+ # Subject: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
325
+ # Label: "Verisign Class 4 Public Primary Certification Authority - G3"
326
+ # Serial: 314531972711909413743075096039378935511
327
+ # MD5 Fingerprint: db:c8:f2:27:2e:b1:ea:6a:29:23:5d:fe:56:3e:33:df
328
+ # SHA1 Fingerprint: c8:ec:8c:87:92:69:cb:4b:ab:39:e9:8d:7e:57:67:f3:14:95:73:9d
329
+ # SHA256 Fingerprint: e3:89:36:0d:0f:db:ae:b3:d2:50:58:4b:47:30:31:4e:22:2f:39:c1:56:a0:20:14:4e:8d:96:05:61:79:15:06
330
+ -----BEGIN CERTIFICATE-----
331
+ MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
332
+ CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
333
+ cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
334
+ LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
335
+ aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
336
+ dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
337
+ VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
338
+ aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
339
+ bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
340
+ IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
341
+ LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1
342
+ GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ
343
+ +mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd
344
+ U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm
345
+ NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY
346
+ ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/
347
+ ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1
348
+ CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq
349
+ g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
350
+ fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c
351
+ 2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/
352
+ bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
353
+ -----END CERTIFICATE-----
354
+
355
+ # Issuer: CN=Entrust.net Secure Server Certification Authority O=Entrust.net OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
356
+ # Subject: CN=Entrust.net Secure Server Certification Authority O=Entrust.net OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
357
+ # Label: "Entrust.net Secure Server CA"
358
+ # Serial: 927650371
359
+ # MD5 Fingerprint: df:f2:80:73:cc:f1:e6:61:73:fc:f5:42:e9:c5:7c:ee
360
+ # SHA1 Fingerprint: 99:a6:9b:e6:1a:fe:88:6b:4d:2b:82:00:7c:b8:54:fc:31:7e:15:39
361
+ # SHA256 Fingerprint: 62:f2:40:27:8c:56:4c:4d:d8:bf:7d:9d:4f:6f:36:6e:a8:94:d2:2f:5f:34:d9:89:a9:83:ac:ec:2f:ff:ed:50
362
+ -----BEGIN CERTIFICATE-----
363
+ MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC
364
+ VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u
365
+ ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc
366
+ KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u
367
+ ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1
368
+ MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE
369
+ ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j
370
+ b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF
371
+ bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg
372
+ U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA
373
+ A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/
374
+ I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3
375
+ wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC
376
+ AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb
377
+ oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5
378
+ BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p
379
+ dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk
380
+ MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp
381
+ b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu
382
+ dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0
383
+ MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi
384
+ E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa
385
+ MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI
386
+ hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN
387
+ 95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd
388
+ 2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
389
+ -----END CERTIFICATE-----
390
+
391
+ # Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
392
+ # Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
393
+ # Label: "Entrust.net Premium 2048 Secure Server CA"
394
+ # Serial: 946059622
395
+ # MD5 Fingerprint: ba:21:ea:20:d6:dd:db:8f:c1:57:8b:40:ad:a1:fc:fc
396
+ # SHA1 Fingerprint: 80:1d:62:d0:7b:44:9d:5c:5c:03:5c:98:ea:61:fa:44:3c:2a:58:fe
397
+ # SHA256 Fingerprint: d1:c3:39:ea:27:84:eb:87:0f:93:4f:c5:63:4e:4a:a9:ad:55:05:01:64:01:f2:64:65:d3:7a:57:46:63:35:9f
398
+ -----BEGIN CERTIFICATE-----
399
+ MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
400
+ RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
401
+ bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
402
+ IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
403
+ ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy
404
+ MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
405
+ LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
406
+ YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
407
+ A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
408
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
409
+ K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
410
+ sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
411
+ MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
412
+ XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
413
+ HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
414
+ 4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA
415
+ vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G
416
+ CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA
417
+ WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo
418
+ oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ
419
+ h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18
420
+ f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN
421
+ B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy
422
+ vUxFnmG6v4SBkgPR0ml8xQ==
423
+ -----END CERTIFICATE-----
424
+
425
+ # Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust
426
+ # Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust
427
+ # Label: "Baltimore CyberTrust Root"
428
+ # Serial: 33554617
429
+ # MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4
430
+ # SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74
431
+ # SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb
432
+ -----BEGIN CERTIFICATE-----
433
+ MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
434
+ RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
435
+ VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
436
+ DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
437
+ ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
438
+ VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
439
+ mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
440
+ IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
441
+ mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
442
+ XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
443
+ dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
444
+ jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
445
+ BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
446
+ DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
447
+ 9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
448
+ jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
449
+ Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
450
+ ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
451
+ R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
452
+ -----END CERTIFICATE-----
453
+
454
+ # Issuer: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc.
455
+ # Subject: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc.
456
+ # Label: "Equifax Secure Global eBusiness CA"
457
+ # Serial: 1
458
+ # MD5 Fingerprint: 8f:5d:77:06:27:c4:98:3c:5b:93:78:e7:d7:7d:9b:cc
459
+ # SHA1 Fingerprint: 7e:78:4a:10:1c:82:65:cc:2d:e1:f1:6d:47:b4:40:ca:d9:0a:19:45
460
+ # SHA256 Fingerprint: 5f:0b:62:ea:b5:e3:53:ea:65:21:65:16:58:fb:b6:53:59:f4:43:28:0a:4a:fb:d1:04:d7:7d:10:f9:f0:4c:07
461
+ -----BEGIN CERTIFICATE-----
462
+ MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc
463
+ MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT
464
+ ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw
465
+ MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj
466
+ dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l
467
+ c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC
468
+ UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc
469
+ 58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/
470
+ o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH
471
+ MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr
472
+ aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA
473
+ A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA
474
+ Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv
475
+ 8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
476
+ -----END CERTIFICATE-----
477
+
478
+ # Issuer: CN=Equifax Secure eBusiness CA-1 O=Equifax Secure Inc.
479
+ # Subject: CN=Equifax Secure eBusiness CA-1 O=Equifax Secure Inc.
480
+ # Label: "Equifax Secure eBusiness CA 1"
481
+ # Serial: 4
482
+ # MD5 Fingerprint: 64:9c:ef:2e:44:fc:c6:8f:52:07:d0:51:73:8f:cb:3d
483
+ # SHA1 Fingerprint: da:40:18:8b:91:89:a3:ed:ee:ae:da:97:fe:2f:9d:f5:b7:d1:8a:41
484
+ # SHA256 Fingerprint: cf:56:ff:46:a4:a1:86:10:9d:d9:65:84:b5:ee:b5:8a:51:0c:42:75:b0:e5:f9:4f:40:bb:ae:86:5e:19:f6:73
485
+ -----BEGIN CERTIFICATE-----
486
+ MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc
487
+ MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT
488
+ ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw
489
+ MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j
490
+ LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ
491
+ KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo
492
+ RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu
493
+ WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw
494
+ Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD
495
+ AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK
496
+ eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM
497
+ zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+
498
+ WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN
499
+ /Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ==
500
+ -----END CERTIFICATE-----
501
+
502
+ # Issuer: O=Equifax Secure OU=Equifax Secure eBusiness CA-2
503
+ # Subject: O=Equifax Secure OU=Equifax Secure eBusiness CA-2
504
+ # Label: "Equifax Secure eBusiness CA 2"
505
+ # Serial: 930140085
506
+ # MD5 Fingerprint: aa:bf:bf:64:97:da:98:1d:6f:c6:08:3a:95:70:33:ca
507
+ # SHA1 Fingerprint: 39:4f:f6:85:0b:06:be:52:e5:18:56:cc:10:e1:80:e8:82:b3:85:cc
508
+ # SHA256 Fingerprint: 2f:27:4e:48:ab:a4:ac:7b:76:59:33:10:17:75:50:6d:c3:0e:e3:8e:f6:ac:d5:c0:49:32:cf:e0:41:23:42:20
509
+ -----BEGIN CERTIFICATE-----
510
+ MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
511
+ UzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2Vj
512
+ dXJlIGVCdXNpbmVzcyBDQS0yMB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0
513
+ NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkVxdWlmYXggU2VjdXJlMSYwJAYD
514
+ VQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCBnzANBgkqhkiG9w0B
515
+ AQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn2Z0G
516
+ vxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/
517
+ BPO3QSQ5BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0C
518
+ AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEX
519
+ MBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJl
520
+ IGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTkw
521
+ NjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9euSBIplBq
522
+ y/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQF
523
+ MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
524
+ A4GBAAyGgq3oThr1jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy
525
+ 0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1
526
+ E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUmV+GRMOrN
527
+ -----END CERTIFICATE-----
528
+
529
+ # Issuer: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network
530
+ # Subject: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network
531
+ # Label: "AddTrust Low-Value Services Root"
532
+ # Serial: 1
533
+ # MD5 Fingerprint: 1e:42:95:02:33:92:6b:b9:5f:c0:7f:da:d6:b2:4b:fc
534
+ # SHA1 Fingerprint: cc:ab:0e:a0:4c:23:01:d6:69:7b:dd:37:9f:cd:12:eb:24:e3:94:9d
535
+ # SHA256 Fingerprint: 8c:72:09:27:9a:c0:4e:27:5e:16:d0:7f:d3:b7:75:e8:01:54:b5:96:80:46:e3:1f:52:dd:25:76:63:24:e9:a7
536
+ -----BEGIN CERTIFICATE-----
537
+ MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU
538
+ MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
539
+ b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw
540
+ MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
541
+ QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD
542
+ VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA
543
+ A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul
544
+ CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n
545
+ tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl
546
+ dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch
547
+ PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC
548
+ +Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O
549
+ BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E
550
+ BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl
551
+ MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk
552
+ ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB
553
+ IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X
554
+ 7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz
555
+ 43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY
556
+ eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl
557
+ pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA
558
+ WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=
559
+ -----END CERTIFICATE-----
560
+
561
+ # Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network
562
+ # Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network
563
+ # Label: "AddTrust External Root"
564
+ # Serial: 1
565
+ # MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f
566
+ # SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68
567
+ # SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2
568
+ -----BEGIN CERTIFICATE-----
569
+ MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
570
+ MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
571
+ IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
572
+ MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
573
+ FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
574
+ bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
575
+ dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
576
+ H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
577
+ uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
578
+ mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
579
+ a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
580
+ E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
581
+ WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
582
+ VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
583
+ Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
584
+ cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
585
+ IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
586
+ AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
587
+ YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
588
+ 6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
589
+ Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
590
+ c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
591
+ mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
592
+ -----END CERTIFICATE-----
593
+
594
+ # Issuer: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network
595
+ # Subject: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network
596
+ # Label: "AddTrust Public Services Root"
597
+ # Serial: 1
598
+ # MD5 Fingerprint: c1:62:3e:23:c5:82:73:9c:03:59:4b:2b:e9:77:49:7f
599
+ # SHA1 Fingerprint: 2a:b6:28:48:5e:78:fb:f3:ad:9e:79:10:dd:6b:df:99:72:2c:96:e5
600
+ # SHA256 Fingerprint: 07:91:ca:07:49:b2:07:82:aa:d3:c7:d7:bd:0c:df:c9:48:58:35:84:3e:b2:d7:99:60:09:ce:43:ab:6c:69:27
601
+ -----BEGIN CERTIFICATE-----
602
+ MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU
603
+ MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
604
+ b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx
605
+ MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB
606
+ ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV
607
+ BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC
608
+ AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV
609
+ 6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX
610
+ GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP
611
+ dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH
612
+ 1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF
613
+ 62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW
614
+ BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw
615
+ AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL
616
+ MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU
617
+ cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv
618
+ b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6
619
+ IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/
620
+ iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao
621
+ GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh
622
+ 4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm
623
+ XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY=
624
+ -----END CERTIFICATE-----
625
+
626
+ # Issuer: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network
627
+ # Subject: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network
628
+ # Label: "AddTrust Qualified Certificates Root"
629
+ # Serial: 1
630
+ # MD5 Fingerprint: 27:ec:39:47:cd:da:5a:af:e2:9a:01:65:21:a9:4c:bb
631
+ # SHA1 Fingerprint: 4d:23:78:ec:91:95:39:b5:00:7f:75:8f:03:3b:21:1e:c5:4d:8b:cf
632
+ # SHA256 Fingerprint: 80:95:21:08:05:db:4b:bc:35:5e:44:28:d8:fd:6e:c2:cd:e3:ab:5f:b9:7a:99:42:98:8e:b8:f4:dc:d0:60:16
633
+ -----BEGIN CERTIFICATE-----
634
+ MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU
635
+ MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
636
+ b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1
637
+ MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK
638
+ EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh
639
+ BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B
640
+ AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq
641
+ xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G
642
+ 87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i
643
+ 2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U
644
+ WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1
645
+ 0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G
646
+ A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T
647
+ AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr
648
+ pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL
649
+ ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm
650
+ aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv
651
+ hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm
652
+ hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X
653
+ dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3
654
+ P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y
655
+ iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no
656
+ xqE=
657
+ -----END CERTIFICATE-----
658
+
659
+ # Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
660
+ # Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
661
+ # Label: "Entrust Root Certification Authority"
662
+ # Serial: 1164660820
663
+ # MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4
664
+ # SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9
665
+ # SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c
666
+ -----BEGIN CERTIFICATE-----
667
+ MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
668
+ VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
669
+ Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
670
+ KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
671
+ cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
672
+ NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
673
+ NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
674
+ ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
675
+ BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
676
+ KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
677
+ Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
678
+ 4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
679
+ KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
680
+ rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
681
+ 94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
682
+ sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
683
+ gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
684
+ kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
685
+ vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
686
+ A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
687
+ O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
688
+ AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
689
+ 9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
690
+ eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
691
+ 0vdXcDazv/wor3ElhVsT/h5/WrQ8
692
+ -----END CERTIFICATE-----
693
+
694
+ # Issuer: CN=GeoTrust Global CA O=GeoTrust Inc.
695
+ # Subject: CN=GeoTrust Global CA O=GeoTrust Inc.
696
+ # Label: "GeoTrust Global CA"
697
+ # Serial: 144470
698
+ # MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5
699
+ # SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12
700
+ # SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a
701
+ -----BEGIN CERTIFICATE-----
702
+ MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
703
+ MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
704
+ YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
705
+ EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
706
+ R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
707
+ 9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
708
+ fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
709
+ iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
710
+ 1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
711
+ bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
712
+ MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
713
+ ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
714
+ uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
715
+ Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
716
+ tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
717
+ PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
718
+ hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
719
+ 5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
720
+ -----END CERTIFICATE-----
721
+
722
+ # Issuer: CN=GeoTrust Global CA 2 O=GeoTrust Inc.
723
+ # Subject: CN=GeoTrust Global CA 2 O=GeoTrust Inc.
724
+ # Label: "GeoTrust Global CA 2"
725
+ # Serial: 1
726
+ # MD5 Fingerprint: 0e:40:a7:6c:de:03:5d:8f:d1:0f:e4:d1:8d:f9:6c:a9
727
+ # SHA1 Fingerprint: a9:e9:78:08:14:37:58:88:f2:05:19:b0:6d:2b:0d:2b:60:16:90:7d
728
+ # SHA256 Fingerprint: ca:2d:82:a0:86:77:07:2f:8a:b6:76:4f:f0:35:67:6c:fe:3e:5e:32:5e:01:21:72:df:3f:92:09:6d:b7:9b:85
729
+ -----BEGIN CERTIFICATE-----
730
+ MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW
731
+ MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs
732
+ IENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG
733
+ EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg
734
+ R2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A
735
+ PRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8
736
+ Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL
737
+ TytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL
738
+ 5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7
739
+ S4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe
740
+ 2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
741
+ FHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap
742
+ EBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td
743
+ EPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv
744
+ /NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN
745
+ A0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0
746
+ abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF
747
+ I8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz
748
+ 4iIprn2DQKi6bA==
749
+ -----END CERTIFICATE-----
750
+
751
+ # Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc.
752
+ # Subject: CN=GeoTrust Universal CA O=GeoTrust Inc.
753
+ # Label: "GeoTrust Universal CA"
754
+ # Serial: 1
755
+ # MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48
756
+ # SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79
757
+ # SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12
758
+ -----BEGIN CERTIFICATE-----
759
+ MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW
760
+ MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy
761
+ c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE
762
+ BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0
763
+ IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV
764
+ VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8
765
+ cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT
766
+ QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh
767
+ F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v
768
+ c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w
769
+ mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd
770
+ VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX
771
+ teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ
772
+ f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe
773
+ Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+
774
+ nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB
775
+ /wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY
776
+ MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
777
+ 9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
778
+ aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX
779
+ IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn
780
+ ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z
781
+ uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN
782
+ Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja
783
+ QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW
784
+ koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9
785
+ ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt
786
+ DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm
787
+ bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw=
788
+ -----END CERTIFICATE-----
789
+
790
+ # Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc.
791
+ # Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc.
792
+ # Label: "GeoTrust Universal CA 2"
793
+ # Serial: 1
794
+ # MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7
795
+ # SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79
796
+ # SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b
797
+ -----BEGIN CERTIFICATE-----
798
+ MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW
799
+ MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy
800
+ c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD
801
+ VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1
802
+ c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
803
+ AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81
804
+ WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG
805
+ FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq
806
+ XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL
807
+ se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb
808
+ KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd
809
+ IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73
810
+ y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt
811
+ hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc
812
+ QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4
813
+ Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV
814
+ HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV
815
+ HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ
816
+ KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z
817
+ dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ
818
+ L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr
819
+ Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo
820
+ ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY
821
+ T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz
822
+ GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m
823
+ 1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV
824
+ OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH
825
+ 6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX
826
+ QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
827
+ -----END CERTIFICATE-----
828
+
829
+ # Issuer: CN=America Online Root Certification Authority 1 O=America Online Inc.
830
+ # Subject: CN=America Online Root Certification Authority 1 O=America Online Inc.
831
+ # Label: "America Online Root Certification Authority 1"
832
+ # Serial: 1
833
+ # MD5 Fingerprint: 14:f1:08:ad:9d:fa:64:e2:89:e7:1c:cf:a8:ad:7d:5e
834
+ # SHA1 Fingerprint: 39:21:c1:15:c1:5d:0e:ca:5c:cb:5b:c4:f0:7d:21:d8:05:0b:56:6a
835
+ # SHA256 Fingerprint: 77:40:73:12:c6:3a:15:3d:5b:c0:0b:4e:51:75:9c:df:da:c2:37:dc:2a:33:b6:79:46:e9:8e:9b:fa:68:0a:e3
836
+ -----BEGIN CERTIFICATE-----
837
+ MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc
838
+ MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP
839
+ bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2
840
+ MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft
841
+ ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg
842
+ Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
843
+ ADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lk
844
+ hsmj76CGv2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym
845
+ 1BW32J/X3HGrfpq/m44zDyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsW
846
+ OqMFf6Dch9Wc/HKpoH145LcxVR5lu9RhsCFg7RAycsWSJR74kEoYeEfffjA3PlAb
847
+ 2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP8c9GsEsPPt2IYriMqQko
848
+ O3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0TAQH/BAUw
849
+ AwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAU
850
+ AK3Zo/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
851
+ BQUAA4IBAQB8itEfGDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkF
852
+ Zu90821fnZmv9ov761KyBZiibyrFVL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAb
853
+ LjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft3OJvx8Fi8eNy1gTIdGcL+oir
854
+ oQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43gKd8hdIaC2y+C
855
+ MMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds
856
+ sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7
857
+ -----END CERTIFICATE-----
858
+
859
+ # Issuer: CN=America Online Root Certification Authority 2 O=America Online Inc.
860
+ # Subject: CN=America Online Root Certification Authority 2 O=America Online Inc.
861
+ # Label: "America Online Root Certification Authority 2"
862
+ # Serial: 1
863
+ # MD5 Fingerprint: d6:ed:3c:ca:e2:66:0f:af:10:43:0d:77:9b:04:09:bf
864
+ # SHA1 Fingerprint: 85:b5:ff:67:9b:0c:79:96:1f:c8:6e:44:22:00:46:13:db:17:92:84
865
+ # SHA256 Fingerprint: 7d:3b:46:5a:60:14:e5:26:c0:af:fc:ee:21:27:d2:31:17:27:ad:81:1c:26:84:2d:00:6a:f3:73:06:cc:80:bd
866
+ -----BEGIN CERTIFICATE-----
867
+ MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc
868
+ MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP
869
+ bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2
870
+ MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft
871
+ ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg
872
+ Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
873
+ ADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC
874
+ 206B89enfHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFci
875
+ KtZHgVdEglZTvYYUAQv8f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2
876
+ JxhP7JsowtS013wMPgwr38oE18aO6lhOqKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9
877
+ BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JNRvCAOVIyD+OEsnpD8l7e
878
+ Xz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0gBe4lL8B
879
+ PeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67
880
+ Xnfn6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEq
881
+ Z8A9W6Wa6897GqidFEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZ
882
+ o2C7HK2JNDJiuEMhBnIMoVxtRsX6Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3
883
+ +L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnjB453cMor9H124HhnAgMBAAGj
884
+ YzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3OpaaEg5+31IqEj
885
+ FNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE
886
+ AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmn
887
+ xPBUlgtk87FYT15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2
888
+ LHo1YGwRgJfMqZJS5ivmae2p+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzccc
889
+ obGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXgJXUjhx5c3LqdsKyzadsXg8n33gy8
890
+ CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//ZoyzH1kUQ7rVyZ2OuMe
891
+ IjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgOZtMA
892
+ DjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2F
893
+ AjgQ5ANh1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUX
894
+ Om/9riW99XJZZLF0KjhfGEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPb
895
+ AZO1XB4Y3WRayhgoPmMEEf0cjQAPuDffZ4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQl
896
+ Zvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuPcX/9XhmgD0uRuMRUvAaw
897
+ RY8mkaKO/qk=
898
+ -----END CERTIFICATE-----
899
+
900
+ # Issuer: CN=AAA Certificate Services O=Comodo CA Limited
901
+ # Subject: CN=AAA Certificate Services O=Comodo CA Limited
902
+ # Label: "Comodo AAA Services root"
903
+ # Serial: 1
904
+ # MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0
905
+ # SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49
906
+ # SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4
907
+ -----BEGIN CERTIFICATE-----
908
+ MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
909
+ MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
910
+ GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
911
+ YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
912
+ MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
913
+ BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
914
+ GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
915
+ ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
916
+ BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
917
+ 3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
918
+ YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
919
+ rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
920
+ ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
921
+ oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
922
+ MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
923
+ QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
924
+ b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
925
+ AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
926
+ GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
927
+ Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
928
+ G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
929
+ l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
930
+ smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
931
+ -----END CERTIFICATE-----
932
+
933
+ # Issuer: CN=Secure Certificate Services O=Comodo CA Limited
934
+ # Subject: CN=Secure Certificate Services O=Comodo CA Limited
935
+ # Label: "Comodo Secure Services root"
936
+ # Serial: 1
937
+ # MD5 Fingerprint: d3:d9:bd:ae:9f:ac:67:24:b3:c8:1b:52:e1:b9:a9:bd
938
+ # SHA1 Fingerprint: 4a:65:d5:f4:1d:ef:39:b8:b8:90:4a:4a:d3:64:81:33:cf:c7:a1:d1
939
+ # SHA256 Fingerprint: bd:81:ce:3b:4f:65:91:d1:1a:67:b5:fc:7a:47:fd:ef:25:52:1b:f9:aa:4e:18:b9:e3:df:2e:34:a7:80:3b:e8
940
+ -----BEGIN CERTIFICATE-----
941
+ MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb
942
+ MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
943
+ GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp
944
+ ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow
945
+ fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
946
+ A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV
947
+ BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB
948
+ BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM
949
+ cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S
950
+ HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996
951
+ CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk
952
+ 3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz
953
+ 6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV
954
+ HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
955
+ EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv
956
+ Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw
957
+ Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww
958
+ DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0
959
+ 5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj
960
+ Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI
961
+ gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ
962
+ aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl
963
+ izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk=
964
+ -----END CERTIFICATE-----
965
+
966
+ # Issuer: CN=Trusted Certificate Services O=Comodo CA Limited
967
+ # Subject: CN=Trusted Certificate Services O=Comodo CA Limited
968
+ # Label: "Comodo Trusted Services root"
969
+ # Serial: 1
970
+ # MD5 Fingerprint: 91:1b:3f:6e:cd:9e:ab:ee:07:fe:1f:71:d2:b3:61:27
971
+ # SHA1 Fingerprint: e1:9f:e3:0e:8b:84:60:9e:80:9b:17:0d:72:a8:c5:ba:6e:14:09:bd
972
+ # SHA256 Fingerprint: 3f:06:e5:56:81:d4:96:f5:be:16:9e:b5:38:9f:9f:2b:8f:f6:1e:17:08:df:68:81:72:48:49:cd:5d:27:cb:69
973
+ -----BEGIN CERTIFICATE-----
974
+ MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb
975
+ MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
976
+ GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0
977
+ aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla
978
+ MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
979
+ BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD
980
+ VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B
981
+ AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW
982
+ fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt
983
+ TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL
984
+ fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW
985
+ 1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7
986
+ kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G
987
+ A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD
988
+ VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v
989
+ ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo
990
+ dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu
991
+ Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/
992
+ HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32
993
+ pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS
994
+ jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+
995
+ xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn
996
+ dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi
997
+ -----END CERTIFICATE-----
998
+
999
+ # Issuer: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com
1000
+ # Subject: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com
1001
+ # Label: "UTN DATACorp SGC Root CA"
1002
+ # Serial: 91374294542884689855167577680241077609
1003
+ # MD5 Fingerprint: b3:a5:3e:77:21:6d:ac:4a:c0:c9:fb:d5:41:3d:ca:06
1004
+ # SHA1 Fingerprint: 58:11:9f:0e:12:82:87:ea:50:fd:d9:87:45:6f:4f:78:dc:fa:d6:d4
1005
+ # SHA256 Fingerprint: 85:fb:2f:91:dd:12:27:5a:01:45:b6:36:53:4f:84:02:4a:d6:8b:69:b8:ee:88:68:4f:f7:11:37:58:05:b3:48
1006
+ -----BEGIN CERTIFICATE-----
1007
+ MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB
1008
+ kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
1009
+ Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
1010
+ dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw
1011
+ IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG
1012
+ EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD
1013
+ VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu
1014
+ dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN
1015
+ BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6
1016
+ E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ
1017
+ D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK
1018
+ 4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq
1019
+ lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW
1020
+ bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB
1021
+ o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT
1022
+ MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js
1023
+ LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr
1024
+ BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB
1025
+ AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft
1026
+ Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj
1027
+ j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH
1028
+ KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv
1029
+ 2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3
1030
+ mfnGV/TJVTl4uix5yaaIK/QI
1031
+ -----END CERTIFICATE-----
1032
+
1033
+ # Issuer: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com
1034
+ # Subject: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com
1035
+ # Label: "UTN USERFirst Hardware Root CA"
1036
+ # Serial: 91374294542884704022267039221184531197
1037
+ # MD5 Fingerprint: 4c:56:41:e5:0d:bb:2b:e8:ca:a3:ed:18:08:ad:43:39
1038
+ # SHA1 Fingerprint: 04:83:ed:33:99:ac:36:08:05:87:22:ed:bc:5e:46:00:e3:be:f9:d7
1039
+ # SHA256 Fingerprint: 6e:a5:47:41:d0:04:66:7e:ed:1b:48:16:63:4a:a3:a7:9e:6e:4b:96:95:0f:82:79:da:fc:8d:9b:d8:81:21:37
1040
+ -----BEGIN CERTIFICATE-----
1041
+ MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB
1042
+ lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
1043
+ Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
1044
+ dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt
1045
+ SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG
1046
+ A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe
1047
+ MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v
1048
+ d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh
1049
+ cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn
1050
+ 0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ
1051
+ M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a
1052
+ MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd
1053
+ oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI
1054
+ DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy
1055
+ oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
1056
+ VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0
1057
+ dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy
1058
+ bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF
1059
+ BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
1060
+ //bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli
1061
+ CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE
1062
+ CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t
1063
+ 3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS
1064
+ KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA==
1065
+ -----END CERTIFICATE-----
1066
+
1067
+ # Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
1068
+ # Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
1069
+ # Label: "XRamp Global CA Root"
1070
+ # Serial: 107108908803651509692980124233745014957
1071
+ # MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1
1072
+ # SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6
1073
+ # SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2
1074
+ -----BEGIN CERTIFICATE-----
1075
+ MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB
1076
+ gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk
1077
+ MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY
1078
+ UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx
1079
+ NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3
1080
+ dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy
1081
+ dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
1082
+ dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6
1083
+ 38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP
1084
+ KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q
1085
+ DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4
1086
+ qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa
1087
+ JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi
1088
+ PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P
1089
+ BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs
1090
+ jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0
1091
+ eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD
1092
+ ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR
1093
+ vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
1094
+ qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa
1095
+ IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy
1096
+ i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ
1097
+ O+7ETPTsJ3xCwnR8gooJybQDJbw=
1098
+ -----END CERTIFICATE-----
1099
+
1100
+ # Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
1101
+ # Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
1102
+ # Label: "Go Daddy Class 2 CA"
1103
+ # Serial: 0
1104
+ # MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67
1105
+ # SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4
1106
+ # SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4
1107
+ -----BEGIN CERTIFICATE-----
1108
+ MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
1109
+ MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
1110
+ YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
1111
+ MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
1112
+ ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
1113
+ MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
1114
+ ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
1115
+ PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
1116
+ wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
1117
+ EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
1118
+ avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
1119
+ YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
1120
+ sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
1121
+ /t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
1122
+ IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
1123
+ YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
1124
+ ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
1125
+ OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
1126
+ TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
1127
+ HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
1128
+ dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
1129
+ ReYNnyicsbkqWletNw+vHX/bvZ8=
1130
+ -----END CERTIFICATE-----
1131
+
1132
+ # Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
1133
+ # Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
1134
+ # Label: "Starfield Class 2 CA"
1135
+ # Serial: 0
1136
+ # MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24
1137
+ # SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a
1138
+ # SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58
1139
+ -----BEGIN CERTIFICATE-----
1140
+ MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
1141
+ MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
1142
+ U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
1143
+ NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
1144
+ ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
1145
+ ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
1146
+ DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
1147
+ 8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
1148
+ +lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
1149
+ X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
1150
+ K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
1151
+ 1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
1152
+ A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
1153
+ zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
1154
+ YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
1155
+ bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
1156
+ DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
1157
+ L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
1158
+ eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
1159
+ xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
1160
+ VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
1161
+ WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
1162
+ -----END CERTIFICATE-----
1163
+
1164
+ # Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
1165
+ # Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
1166
+ # Label: "StartCom Certification Authority"
1167
+ # Serial: 1
1168
+ # MD5 Fingerprint: 22:4d:8f:8a:fc:f7:35:c2:bb:57:34:90:7b:8b:22:16
1169
+ # SHA1 Fingerprint: 3e:2b:f7:f2:03:1b:96:f3:8c:e6:c4:d8:a8:5d:3e:2d:58:47:6a:0f
1170
+ # SHA256 Fingerprint: c7:66:a9:be:f2:d4:07:1c:86:3a:31:aa:49:20:e8:13:b2:d1:98:60:8c:b7:b7:cf:e2:11:43:b8:36:df:09:ea
1171
+ -----BEGIN CERTIFICATE-----
1172
+ MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
1173
+ MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
1174
+ Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
1175
+ dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9
1176
+ MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
1177
+ U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
1178
+ cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
1179
+ A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
1180
+ pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
1181
+ OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
1182
+ Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
1183
+ Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
1184
+ HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
1185
+ Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
1186
+ +2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
1187
+ Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
1188
+ Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
1189
+ 26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
1190
+ AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
1191
+ FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j
1192
+ ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js
1193
+ LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM
1194
+ BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0
1195
+ Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy
1196
+ dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh
1197
+ cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh
1198
+ YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg
1199
+ dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp
1200
+ bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ
1201
+ YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT
1202
+ TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ
1203
+ 9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8
1204
+ jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW
1205
+ FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz
1206
+ ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1
1207
+ ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L
1208
+ EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu
1209
+ L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
1210
+ yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC
1211
+ O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V
1212
+ um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh
1213
+ NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14=
1214
+ -----END CERTIFICATE-----
1215
+
1216
+ # Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
1217
+ # Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
1218
+ # Label: "DigiCert Assured ID Root CA"
1219
+ # Serial: 17154717934120587862167794914071425081
1220
+ # MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72
1221
+ # SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43
1222
+ # SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c
1223
+ -----BEGIN CERTIFICATE-----
1224
+ MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
1225
+ MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
1226
+ d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
1227
+ b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
1228
+ EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
1229
+ cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
1230
+ MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
1231
+ JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
1232
+ mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
1233
+ wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
1234
+ VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
1235
+ AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
1236
+ AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
1237
+ BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
1238
+ pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
1239
+ dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
1240
+ fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
1241
+ NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
1242
+ H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
1243
+ +o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
1244
+ -----END CERTIFICATE-----
1245
+
1246
+ # Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com
1247
+ # Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com
1248
+ # Label: "DigiCert Global Root CA"
1249
+ # Serial: 10944719598952040374951832963794454346
1250
+ # MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e
1251
+ # SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36
1252
+ # SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61
1253
+ -----BEGIN CERTIFICATE-----
1254
+ MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
1255
+ MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
1256
+ d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
1257
+ QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
1258
+ MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
1259
+ b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
1260
+ 9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
1261
+ CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
1262
+ nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
1263
+ 43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
1264
+ T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
1265
+ gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
1266
+ BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
1267
+ TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
1268
+ DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
1269
+ hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
1270
+ 06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
1271
+ PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
1272
+ YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
1273
+ CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
1274
+ -----END CERTIFICATE-----
1275
+
1276
+ # Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com
1277
+ # Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com
1278
+ # Label: "DigiCert High Assurance EV Root CA"
1279
+ # Serial: 3553400076410547919724730734378100087
1280
+ # MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a
1281
+ # SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25
1282
+ # SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf
1283
+ -----BEGIN CERTIFICATE-----
1284
+ MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
1285
+ MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
1286
+ d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
1287
+ ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
1288
+ MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
1289
+ LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
1290
+ RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
1291
+ +9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
1292
+ PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
1293
+ xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
1294
+ Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
1295
+ hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
1296
+ EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
1297
+ MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
1298
+ FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
1299
+ nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
1300
+ eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
1301
+ hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
1302
+ Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
1303
+ vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
1304
+ +OkuE6N36B9K
1305
+ -----END CERTIFICATE-----
1306
+
1307
+ # Issuer: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc.
1308
+ # Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc.
1309
+ # Label: "GeoTrust Primary Certification Authority"
1310
+ # Serial: 32798226551256963324313806436981982369
1311
+ # MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf
1312
+ # SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96
1313
+ # SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c
1314
+ -----BEGIN CERTIFICATE-----
1315
+ MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY
1316
+ MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
1317
+ R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx
1318
+ MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
1319
+ Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp
1320
+ ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
1321
+ AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9
1322
+ AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA
1323
+ ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0
1324
+ 7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W
1325
+ kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI
1326
+ mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
1327
+ A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ
1328
+ KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1
1329
+ 6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl
1330
+ 4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K
1331
+ oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj
1332
+ UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU
1333
+ AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
1334
+ -----END CERTIFICATE-----
1335
+
1336
+ # Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only
1337
+ # Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only
1338
+ # Label: "thawte Primary Root CA"
1339
+ # Serial: 69529181992039203566298953787712940909
1340
+ # MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12
1341
+ # SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81
1342
+ # SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f
1343
+ -----BEGIN CERTIFICATE-----
1344
+ MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
1345
+ qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
1346
+ Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
1347
+ MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
1348
+ BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
1349
+ NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
1350
+ LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
1351
+ A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
1352
+ IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
1353
+ SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
1354
+ W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
1355
+ 3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
1356
+ 6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
1357
+ Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
1358
+ NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
1359
+ MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
1360
+ r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
1361
+ DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
1362
+ YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
1363
+ xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
1364
+ /qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
1365
+ LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
1366
+ jVaMaA==
1367
+ -----END CERTIFICATE-----
1368
+
1369
+ # Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only
1370
+ # Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only
1371
+ # Label: "VeriSign Class 3 Public Primary Certification Authority - G5"
1372
+ # Serial: 33037644167568058970164719475676101450
1373
+ # MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c
1374
+ # SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5
1375
+ # SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df
1376
+ -----BEGIN CERTIFICATE-----
1377
+ MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
1378
+ yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
1379
+ ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
1380
+ U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
1381
+ ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
1382
+ aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
1383
+ MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
1384
+ ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
1385
+ biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
1386
+ U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
1387
+ aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
1388
+ nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
1389
+ t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
1390
+ SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
1391
+ BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
1392
+ rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
1393
+ NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
1394
+ BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
1395
+ BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
1396
+ aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
1397
+ MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
1398
+ p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
1399
+ 5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
1400
+ WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
1401
+ 4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
1402
+ hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
1403
+ -----END CERTIFICATE-----
1404
+
1405
+ # Issuer: CN=COMODO Certification Authority O=COMODO CA Limited
1406
+ # Subject: CN=COMODO Certification Authority O=COMODO CA Limited
1407
+ # Label: "COMODO Certification Authority"
1408
+ # Serial: 104350513648249232941998508985834464573
1409
+ # MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75
1410
+ # SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b
1411
+ # SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66
1412
+ -----BEGIN CERTIFICATE-----
1413
+ MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB
1414
+ gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
1415
+ A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
1416
+ BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw
1417
+ MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
1418
+ YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P
1419
+ RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0
1420
+ aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3
1421
+ UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI
1422
+ 2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8
1423
+ Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp
1424
+ +2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+
1425
+ DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O
1426
+ nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW
1427
+ /zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g
1428
+ PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u
1429
+ QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY
1430
+ SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv
1431
+ IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
1432
+ RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4
1433
+ zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd
1434
+ BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB
1435
+ ZQ==
1436
+ -----END CERTIFICATE-----
1437
+
1438
+ # Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C.
1439
+ # Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C.
1440
+ # Label: "Network Solutions Certificate Authority"
1441
+ # Serial: 116697915152937497490437556386812487904
1442
+ # MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e
1443
+ # SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce
1444
+ # SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c
1445
+ -----BEGIN CERTIFICATE-----
1446
+ MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi
1447
+ MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
1448
+ MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp
1449
+ dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV
1450
+ UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO
1451
+ ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG
1452
+ SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz
1453
+ c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP
1454
+ OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl
1455
+ mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF
1456
+ BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4
1457
+ qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw
1458
+ gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB
1459
+ BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu
1460
+ bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp
1461
+ dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8
1462
+ 6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/
1463
+ h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH
1464
+ /nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
1465
+ wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN
1466
+ pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
1467
+ -----END CERTIFICATE-----
1468
+
1469
+ # Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited
1470
+ # Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited
1471
+ # Label: "COMODO ECC Certification Authority"
1472
+ # Serial: 41578283867086692638256921589707938090
1473
+ # MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23
1474
+ # SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11
1475
+ # SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7
1476
+ -----BEGIN CERTIFICATE-----
1477
+ MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
1478
+ MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
1479
+ BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
1480
+ IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw
1481
+ MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
1482
+ ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N
1483
+ T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv
1484
+ biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR
1485
+ FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J
1486
+ cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW
1487
+ BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
1488
+ BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
1489
+ fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
1490
+ GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
1491
+ -----END CERTIFICATE-----
1492
+
1493
+ # Issuer: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA
1494
+ # Subject: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA
1495
+ # Label: "TC TrustCenter Class 2 CA II"
1496
+ # Serial: 941389028203453866782103406992443
1497
+ # MD5 Fingerprint: ce:78:33:5c:59:78:01:6e:18:ea:b9:36:a0:b9:2e:23
1498
+ # SHA1 Fingerprint: ae:50:83:ed:7c:f4:5c:bc:8f:61:c6:21:fe:68:5d:79:42:21:15:6e
1499
+ # SHA256 Fingerprint: e6:b8:f8:76:64:85:f8:07:ae:7f:8d:ac:16:70:46:1f:07:c0:a1:3e:ef:3a:1f:f7:17:53:8d:7a:ba:d3:91:b4
1500
+ -----BEGIN CERTIFICATE-----
1501
+ MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjEL
1502
+ MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
1503
+ BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
1504
+ Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYwMTEyMTQzODQzWhcNMjUxMjMxMjI1
1505
+ OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
1506
+ SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UEAxMc
1507
+ VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
1508
+ ggEPADCCAQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jf
1509
+ tMjWQ+nEdVl//OEd+DFwIxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKg
1510
+ uNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2J
1511
+ XjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQXa7pIXSSTYtZgo+U4+lK
1512
+ 8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7uSNQZu+99
1513
+ 5OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1Ud
1514
+ EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3
1515
+ kUrL84J6E1wIqzCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy
1516
+ dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6
1517
+ Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz
1518
+ JTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290
1519
+ Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
1520
+ TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iS
1521
+ GNn3Bzn1LL4GdXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprt
1522
+ ZjluS5TmVfwLG4t3wVMTZonZKNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8
1523
+ au0WOB9/WIFaGusyiC2y8zl3gK9etmF1KdsjTYjKUCjLhdLTEKJZbtOTVAB6okaV
1524
+ hgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kPJOzHdiEoZa5X6AeI
1525
+ dUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfkvQ==
1526
+ -----END CERTIFICATE-----
1527
+
1528
+ # Issuer: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA
1529
+ # Subject: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA
1530
+ # Label: "TC TrustCenter Class 3 CA II"
1531
+ # Serial: 1506523511417715638772220530020799
1532
+ # MD5 Fingerprint: 56:5f:aa:80:61:12:17:f6:67:21:e6:2b:6d:61:56:8e
1533
+ # SHA1 Fingerprint: 80:25:ef:f4:6e:70:c8:d4:72:24:65:84:fe:40:3b:8a:8d:6a:db:f5
1534
+ # SHA256 Fingerprint: 8d:a0:84:fc:f9:9c:e0:77:22:f8:9b:32:05:93:98:06:fa:5c:b8:11:e1:c8:13:f6:a1:08:c7:d3:36:b3:40:8e
1535
+ -----BEGIN CERTIFICATE-----
1536
+ MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL
1537
+ MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
1538
+ BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
1539
+ Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1
1540
+ OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
1541
+ SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc
1542
+ VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
1543
+ ggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW
1544
+ Ht4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q
1545
+ Vl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2
1546
+ 1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq
1547
+ ukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1
1548
+ Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud
1549
+ EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX
1550
+ XAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy
1551
+ dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6
1552
+ Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz
1553
+ JTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290
1554
+ Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
1555
+ TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN
1556
+ irTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8
1557
+ TtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6
1558
+ g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB
1559
+ 95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj
1560
+ S+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A==
1561
+ -----END CERTIFICATE-----
1562
+
1563
+ # Issuer: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA
1564
+ # Subject: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA
1565
+ # Label: "TC TrustCenter Universal CA I"
1566
+ # Serial: 601024842042189035295619584734726
1567
+ # MD5 Fingerprint: 45:e1:a5:72:c5:a9:36:64:40:9e:f5:e4:58:84:67:8c
1568
+ # SHA1 Fingerprint: 6b:2f:34:ad:89:58:be:62:fd:b0:6b:5c:ce:bb:9d:d9:4f:4e:39:f3
1569
+ # SHA256 Fingerprint: eb:f3:c0:2a:87:89:b1:fb:7d:51:19:95:d6:63:b7:29:06:d9:13:ce:0d:5e:10:56:8a:8a:77:e2:58:61:67:e7
1570
+ -----BEGIN CERTIFICATE-----
1571
+ MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTEL
1572
+ MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV
1573
+ BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1
1574
+ c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcNMDYwMzIyMTU1NDI4WhcNMjUxMjMx
1575
+ MjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIg
1576
+ R21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYwJAYD
1577
+ VQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcN
1578
+ AQEBBQADggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSR
1579
+ JJZ4Hgmgm5qVSkr1YnwCqMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3T
1580
+ fCZdzHd55yx4Oagmcw6iXSVphU9VDprvxrlE4Vc93x9UIuVvZaozhDrzznq+VZeu
1581
+ jRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtwag+1m7Z3W0hZneTvWq3z
1582
+ wZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9OgdwZu5GQ
1583
+ fezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYD
1584
+ VR0jBBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAO
1585
+ BgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0G
1586
+ CSqGSIb3DQEBBQUAA4IBAQAo0uCG1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X1
1587
+ 7caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/CyvwbZ71q+s2IhtNerNXxTPqYn
1588
+ 8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3ghUJGooWMNjs
1589
+ ydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT
1590
+ ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/
1591
+ 2TYcuiUaUj0a7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY
1592
+ -----END CERTIFICATE-----
1593
+
1594
+ # Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc
1595
+ # Subject: CN=Cybertrust Global Root O=Cybertrust, Inc
1596
+ # Label: "Cybertrust Global Root"
1597
+ # Serial: 4835703278459682877484360
1598
+ # MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1
1599
+ # SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6
1600
+ # SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3
1601
+ -----BEGIN CERTIFICATE-----
1602
+ MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG
1603
+ A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh
1604
+ bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE
1605
+ ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS
1606
+ b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5
1607
+ 7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS
1608
+ J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y
1609
+ HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP
1610
+ t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz
1611
+ FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY
1612
+ XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/
1613
+ MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw
1614
+ hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js
1615
+ MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA
1616
+ A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj
1617
+ Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx
1618
+ XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o
1619
+ omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc
1620
+ A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW
1621
+ WL1WMRJOEcgh4LMRkWXbtKaIOM5V
1622
+ -----END CERTIFICATE-----
1623
+
1624
+ # Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only
1625
+ # Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only
1626
+ # Label: "GeoTrust Primary Certification Authority - G3"
1627
+ # Serial: 28809105769928564313984085209975885599
1628
+ # MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05
1629
+ # SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd
1630
+ # SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4
1631
+ -----BEGIN CERTIFICATE-----
1632
+ MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB
1633
+ mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
1634
+ MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
1635
+ eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
1636
+ cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ
1637
+ BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
1638
+ MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0
1639
+ BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
1640
+ LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz
1641
+ +uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm
1642
+ hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn
1643
+ 5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W
1644
+ JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL
1645
+ DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC
1646
+ huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
1647
+ HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB
1648
+ AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB
1649
+ zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN
1650
+ kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
1651
+ AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH
1652
+ SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G
1653
+ spki4cErx5z481+oghLrGREt
1654
+ -----END CERTIFICATE-----
1655
+
1656
+ # Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only
1657
+ # Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only
1658
+ # Label: "thawte Primary Root CA - G2"
1659
+ # Serial: 71758320672825410020661621085256472406
1660
+ # MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f
1661
+ # SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12
1662
+ # SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57
1663
+ -----BEGIN CERTIFICATE-----
1664
+ MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL
1665
+ MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp
1666
+ IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi
1667
+ BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw
1668
+ MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
1669
+ d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig
1670
+ YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v
1671
+ dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/
1672
+ BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6
1673
+ papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E
1674
+ BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K
1675
+ DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3
1676
+ KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox
1677
+ XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
1678
+ -----END CERTIFICATE-----
1679
+
1680
+ # Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only
1681
+ # Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only
1682
+ # Label: "thawte Primary Root CA - G3"
1683
+ # Serial: 127614157056681299805556476275995414779
1684
+ # MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31
1685
+ # SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2
1686
+ # SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c
1687
+ -----BEGIN CERTIFICATE-----
1688
+ MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB
1689
+ rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
1690
+ Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
1691
+ MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
1692
+ BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa
1693
+ Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl
1694
+ LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u
1695
+ MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl
1696
+ ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz
1697
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm
1698
+ gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8
1699
+ YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf
1700
+ b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9
1701
+ 9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S
1702
+ zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk
1703
+ OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
1704
+ HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA
1705
+ 2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW
1706
+ oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
1707
+ t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c
1708
+ KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM
1709
+ m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu
1710
+ MdRAGmI0Nj81Aa6sY6A=
1711
+ -----END CERTIFICATE-----
1712
+
1713
+ # Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only
1714
+ # Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only
1715
+ # Label: "GeoTrust Primary Certification Authority - G2"
1716
+ # Serial: 80682863203381065782177908751794619243
1717
+ # MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a
1718
+ # SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0
1719
+ # SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66
1720
+ -----BEGIN CERTIFICATE-----
1721
+ MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL
1722
+ MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj
1723
+ KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2
1724
+ MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
1725
+ eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV
1726
+ BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw
1727
+ NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV
1728
+ BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
1729
+ MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL
1730
+ So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal
1731
+ tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
1732
+ BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG
1733
+ CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT
1734
+ qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz
1735
+ rD6ogRLQy7rQkgu2npaqBA+K
1736
+ -----END CERTIFICATE-----
1737
+
1738
+ # Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only
1739
+ # Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only
1740
+ # Label: "VeriSign Universal Root Certification Authority"
1741
+ # Serial: 85209574734084581917763752644031726877
1742
+ # MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19
1743
+ # SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54
1744
+ # SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c
1745
+ -----BEGIN CERTIFICATE-----
1746
+ MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB
1747
+ vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
1748
+ ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp
1749
+ U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W
1750
+ ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
1751
+ Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX
1752
+ MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0
1753
+ IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y
1754
+ IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh
1755
+ bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
1756
+ AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF
1757
+ 9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH
1758
+ H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H
1759
+ LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN
1760
+ /BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT
1761
+ rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud
1762
+ EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw
1763
+ WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs
1764
+ exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
1765
+ DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4
1766
+ sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+
1767
+ seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz
1768
+ 4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+
1769
+ BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR
1770
+ lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3
1771
+ 7M2CYfE45k+XmCpajQ==
1772
+ -----END CERTIFICATE-----
1773
+
1774
+ # Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only
1775
+ # Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only
1776
+ # Label: "VeriSign Class 3 Public Primary Certification Authority - G4"
1777
+ # Serial: 63143484348153506665311985501458640051
1778
+ # MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41
1779
+ # SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a
1780
+ # SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79
1781
+ -----BEGIN CERTIFICATE-----
1782
+ MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL
1783
+ MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
1784
+ ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln
1785
+ biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
1786
+ U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
1787
+ aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG
1788
+ A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp
1789
+ U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg
1790
+ SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln
1791
+ biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
1792
+ IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm
1793
+ GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve
1794
+ fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw
1795
+ AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ
1796
+ aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj
1797
+ aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW
1798
+ kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC
1799
+ 4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga
1800
+ FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
1801
+ -----END CERTIFICATE-----
1802
+
1803
+ # Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority
1804
+ # Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority
1805
+ # Label: "Verisign Class 3 Public Primary Certification Authority"
1806
+ # Serial: 80507572722862485515306429940691309246
1807
+ # MD5 Fingerprint: ef:5a:f1:33:ef:f1:cd:bb:51:02:ee:12:14:4b:96:c4
1808
+ # SHA1 Fingerprint: a1:db:63:93:91:6f:17:e4:18:55:09:40:04:15:c7:02:40:b0:ae:6b
1809
+ # SHA256 Fingerprint: a4:b6:b3:99:6f:c2:f3:06:b3:fd:86:81:bd:63:41:3d:8c:50:09:cc:4f:a3:29:c2:cc:f0:e2:fa:1b:14:03:05
1810
+ -----BEGIN CERTIFICATE-----
1811
+ MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkG
1812
+ A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
1813
+ cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
1814
+ MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
1815
+ BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
1816
+ YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
1817
+ ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
1818
+ BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
1819
+ I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
1820
+ CSqGSIb3DQEBBQUAA4GBABByUqkFFBkyCEHwxWsKzH4PIRnN5GfcX6kb5sroc50i
1821
+ 2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWXbj9T/UWZYB2oK0z5XqcJ
1822
+ 2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/D/xwzoiQ
1823
+ -----END CERTIFICATE-----
1824
+
1825
+ # Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3
1826
+ # Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3
1827
+ # Label: "GlobalSign Root CA - R3"
1828
+ # Serial: 4835703278459759426209954
1829
+ # MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28
1830
+ # SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad
1831
+ # SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b
1832
+ -----BEGIN CERTIFICATE-----
1833
+ MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
1834
+ A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
1835
+ Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
1836
+ MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
1837
+ A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
1838
+ hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
1839
+ RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
1840
+ gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
1841
+ KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
1842
+ QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
1843
+ XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
1844
+ DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
1845
+ LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
1846
+ RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
1847
+ jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
1848
+ 6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
1849
+ mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
1850
+ Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
1851
+ WD9f
1852
+ -----END CERTIFICATE-----
1853
+
1854
+ # Issuer: CN=TC TrustCenter Universal CA III O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA
1855
+ # Subject: CN=TC TrustCenter Universal CA III O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA
1856
+ # Label: "TC TrustCenter Universal CA III"
1857
+ # Serial: 2010889993983507346460533407902964
1858
+ # MD5 Fingerprint: 9f:dd:db:ab:ff:8e:ff:45:21:5f:f0:6c:9d:8f:fe:2b
1859
+ # SHA1 Fingerprint: 96:56:cd:7b:57:96:98:95:d0:e1:41:46:68:06:fb:b8:c6:11:06:87
1860
+ # SHA256 Fingerprint: 30:9b:4a:87:f6:ca:56:c9:31:69:aa:a9:9c:6d:98:88:54:d7:89:2b:d5:43:7e:2d:07:b2:9c:be:da:55:d3:5d
1861
+ -----BEGIN CERTIFICATE-----
1862
+ MIID4TCCAsmgAwIBAgIOYyUAAQACFI0zFQLkbPQwDQYJKoZIhvcNAQEFBQAwezEL
1863
+ MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV
1864
+ BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEoMCYGA1UEAxMfVEMgVHJ1
1865
+ c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJSTAeFw0wOTA5MDkwODE1MjdaFw0yOTEy
1866
+ MzEyMzU5NTlaMHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNUQyBUcnVzdENlbnRl
1867
+ ciBHbWJIMSQwIgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0ExKDAm
1868
+ BgNVBAMTH1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUkwggEiMA0GCSqG
1869
+ SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDC2pxisLlxErALyBpXsq6DFJmzNEubkKLF
1870
+ 5+cvAqBNLaT6hdqbJYUtQCggbergvbFIgyIpRJ9Og+41URNzdNW88jBmlFPAQDYv
1871
+ DIRlzg9uwliT6CwLOunBjvvya8o84pxOjuT5fdMnnxvVZ3iHLX8LR7PH6MlIfK8v
1872
+ zArZQe+f/prhsq75U7Xl6UafYOPfjdN/+5Z+s7Vy+EutCHnNaYlAJ/Uqwa1D7KRT
1873
+ yGG299J5KmcYdkhtWyUB0SbFt1dpIxVbYYqt8Bst2a9c8SaQaanVDED1M4BDj5yj
1874
+ dipFtK+/fz6HP3bFzSreIMUWWMv5G/UPyw0RUmS40nZid4PxWJ//AgMBAAGjYzBh
1875
+ MB8GA1UdIwQYMBaAFFbn4VslQ4Dg9ozhcbyO5YAvxEjiMA8GA1UdEwEB/wQFMAMB
1876
+ Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRW5+FbJUOA4PaM4XG8juWAL8RI
1877
+ 4jANBgkqhkiG9w0BAQUFAAOCAQEAg8ev6n9NCjw5sWi+e22JLumzCecYV42Fmhfz
1878
+ dkJQEw/HkG8zrcVJYCtsSVgZ1OK+t7+rSbyUyKu+KGwWaODIl0YgoGhnYIg5IFHY
1879
+ aAERzqf2EQf27OysGh+yZm5WZ2B6dF7AbZc2rrUNXWZzwCUyRdhKBgePxLcHsU0G
1880
+ DeGl6/R1yrqc0L2z0zIkTO5+4nYES0lT2PLpVDP85XEfPRRclkvxOvIAu2y0+pZV
1881
+ CIgJwcyRGSmwIC3/yzikQOEXvnlhgP8HA4ZMTnsGnxGGjYnuJ8Tb4rwZjgvDwxPH
1882
+ LQNjO9Po5KIqwoIIlBZU8O8fJ5AluA0OKBtHd0e9HKgl8ZS0Zg==
1883
+ -----END CERTIFICATE-----
1884
+
1885
+ # Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
1886
+ # Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
1887
+ # Label: "Go Daddy Root Certificate Authority - G2"
1888
+ # Serial: 0
1889
+ # MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01
1890
+ # SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b
1891
+ # SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da
1892
+ -----BEGIN CERTIFICATE-----
1893
+ MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
1894
+ EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
1895
+ EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
1896
+ ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
1897
+ NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
1898
+ EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
1899
+ AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
1900
+ DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
1901
+ E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
1902
+ /PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
1903
+ DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
1904
+ GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
1905
+ tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
1906
+ AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
1907
+ FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
1908
+ WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
1909
+ 9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
1910
+ gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
1911
+ 2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
1912
+ LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
1913
+ 4uJEvlz36hz1
1914
+ -----END CERTIFICATE-----
1915
+
1916
+ # Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
1917
+ # Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
1918
+ # Label: "Starfield Root Certificate Authority - G2"
1919
+ # Serial: 0
1920
+ # MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96
1921
+ # SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e
1922
+ # SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5
1923
+ -----BEGIN CERTIFICATE-----
1924
+ MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
1925
+ EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
1926
+ HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
1927
+ ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
1928
+ MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
1929
+ b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
1930
+ aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
1931
+ Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
1932
+ ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
1933
+ nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
1934
+ HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
1935
+ Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
1936
+ dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
1937
+ HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
1938
+ BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
1939
+ CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
1940
+ sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
1941
+ 4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
1942
+ 8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
1943
+ pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
1944
+ mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
1945
+ -----END CERTIFICATE-----
1946
+
1947
+ # Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.
1948
+ # Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.
1949
+ # Label: "Starfield Services Root Certificate Authority - G2"
1950
+ # Serial: 0
1951
+ # MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2
1952
+ # SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f
1953
+ # SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5
1954
+ -----BEGIN CERTIFICATE-----
1955
+ MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
1956
+ EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
1957
+ HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
1958
+ ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
1959
+ MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
1960
+ VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
1961
+ ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
1962
+ dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
1963
+ hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
1964
+ OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
1965
+ 8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
1966
+ Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
1967
+ hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
1968
+ 6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
1969
+ DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
1970
+ AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
1971
+ bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
1972
+ ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
1973
+ qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
1974
+ iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
1975
+ 0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
1976
+ sSi6
1977
+ -----END CERTIFICATE-----
1978
+
1979
+ # Issuer: CN=AffirmTrust Commercial O=AffirmTrust
1980
+ # Subject: CN=AffirmTrust Commercial O=AffirmTrust
1981
+ # Label: "AffirmTrust Commercial"
1982
+ # Serial: 8608355977964138876
1983
+ # MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7
1984
+ # SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7
1985
+ # SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7
1986
+ -----BEGIN CERTIFICATE-----
1987
+ MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE
1988
+ BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
1989
+ dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL
1990
+ MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
1991
+ cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
1992
+ AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP
1993
+ Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr
1994
+ ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL
1995
+ MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1
1996
+ yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr
1997
+ VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/
1998
+ nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
1999
+ KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG
2000
+ XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj
2001
+ vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt
2002
+ Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g
2003
+ N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC
2004
+ nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
2005
+ -----END CERTIFICATE-----
2006
+
2007
+ # Issuer: CN=AffirmTrust Networking O=AffirmTrust
2008
+ # Subject: CN=AffirmTrust Networking O=AffirmTrust
2009
+ # Label: "AffirmTrust Networking"
2010
+ # Serial: 8957382827206547757
2011
+ # MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f
2012
+ # SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f
2013
+ # SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b
2014
+ -----BEGIN CERTIFICATE-----
2015
+ MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE
2016
+ BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
2017
+ dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL
2018
+ MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
2019
+ cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
2020
+ AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y
2021
+ YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua
2022
+ kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL
2023
+ QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp
2024
+ 6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG
2025
+ yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i
2026
+ QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
2027
+ KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO
2028
+ tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu
2029
+ QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ
2030
+ Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u
2031
+ olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48
2032
+ x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
2033
+ -----END CERTIFICATE-----
2034
+
2035
+ # Issuer: CN=AffirmTrust Premium O=AffirmTrust
2036
+ # Subject: CN=AffirmTrust Premium O=AffirmTrust
2037
+ # Label: "AffirmTrust Premium"
2038
+ # Serial: 7893706540734352110
2039
+ # MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57
2040
+ # SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27
2041
+ # SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a
2042
+ -----BEGIN CERTIFICATE-----
2043
+ MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE
2044
+ BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz
2045
+ dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG
2046
+ A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U
2047
+ cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf
2048
+ qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ
2049
+ JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ
2050
+ +jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS
2051
+ s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5
2052
+ HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7
2053
+ 70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG
2054
+ V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S
2055
+ qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S
2056
+ 5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia
2057
+ C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX
2058
+ OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE
2059
+ FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
2060
+ BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2
2061
+ KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
2062
+ Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B
2063
+ 8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ
2064
+ MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc
2065
+ 0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ
2066
+ u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF
2067
+ u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH
2068
+ YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8
2069
+ GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO
2070
+ RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e
2071
+ KeC2uAloGRwYQw==
2072
+ -----END CERTIFICATE-----
2073
+
2074
+ # Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust
2075
+ # Subject: CN=AffirmTrust Premium ECC O=AffirmTrust
2076
+ # Label: "AffirmTrust Premium ECC"
2077
+ # Serial: 8401224907861490260
2078
+ # MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d
2079
+ # SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb
2080
+ # SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23
2081
+ -----BEGIN CERTIFICATE-----
2082
+ MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC
2083
+ VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ
2084
+ cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ
2085
+ BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt
2086
+ VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D
2087
+ 0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9
2088
+ ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G
2089
+ A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G
2090
+ A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs
2091
+ aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I
2092
+ flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==
2093
+ -----END CERTIFICATE-----
2094
+
2095
+ # Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
2096
+ # Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
2097
+ # Label: "StartCom Certification Authority"
2098
+ # Serial: 45
2099
+ # MD5 Fingerprint: c9:3b:0d:84:41:fc:a4:76:79:23:08:57:de:10:19:16
2100
+ # SHA1 Fingerprint: a3:f1:33:3f:e2:42:bf:cf:c5:d1:4e:8f:39:42:98:40:68:10:d1:a0
2101
+ # SHA256 Fingerprint: e1:78:90:ee:09:a3:fb:f4:f4:8b:9c:41:4a:17:d6:37:b7:a5:06:47:e9:bc:75:23:22:72:7f:cc:17:42:a9:11
2102
+ -----BEGIN CERTIFICATE-----
2103
+ MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW
2104
+ MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
2105
+ Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
2106
+ dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9
2107
+ MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
2108
+ U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
2109
+ cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
2110
+ A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
2111
+ pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
2112
+ OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
2113
+ Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
2114
+ Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
2115
+ HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
2116
+ Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
2117
+ +2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
2118
+ Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
2119
+ Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
2120
+ 26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
2121
+ AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
2122
+ VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul
2123
+ F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC
2124
+ ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w
2125
+ ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk
2126
+ aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0
2127
+ YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg
2128
+ c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0
2129
+ aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93
2130
+ d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG
2131
+ CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1
2132
+ dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF
2133
+ wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS
2134
+ Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst
2135
+ 0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc
2136
+ pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl
2137
+ CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF
2138
+ P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK
2139
+ 1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm
2140
+ KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE
2141
+ JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ
2142
+ 8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm
2143
+ fyWl8kgAwKQB2j8=
2144
+ -----END CERTIFICATE-----
2145
+
2146
+ # Issuer: CN=StartCom Certification Authority G2 O=StartCom Ltd.
2147
+ # Subject: CN=StartCom Certification Authority G2 O=StartCom Ltd.
2148
+ # Label: "StartCom Certification Authority G2"
2149
+ # Serial: 59
2150
+ # MD5 Fingerprint: 78:4b:fb:9e:64:82:0a:d3:b8:4c:62:f3:64:f2:90:64
2151
+ # SHA1 Fingerprint: 31:f1:fd:68:22:63:20:ee:c6:3b:3f:9d:ea:4a:3e:53:7c:7c:39:17
2152
+ # SHA256 Fingerprint: c7:ba:65:67:de:93:a7:98:ae:1f:aa:79:1e:71:2d:37:8f:ae:1f:93:c4:39:7f:ea:44:1b:b7:cb:e6:fd:59:95
2153
+ -----BEGIN CERTIFICATE-----
2154
+ MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW
2155
+ MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm
2156
+ aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1
2157
+ OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG
2158
+ A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G
2159
+ CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ
2160
+ JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD
2161
+ vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo
2162
+ D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/
2163
+ Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW
2164
+ RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK
2165
+ HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN
2166
+ nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM
2167
+ 0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i
2168
+ UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9
2169
+ Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg
2170
+ TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
2171
+ AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL
2172
+ BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K
2173
+ 2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX
2174
+ UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl
2175
+ 6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK
2176
+ 9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ
2177
+ HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI
2178
+ wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY
2179
+ XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l
2180
+ IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo
2181
+ hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr
2182
+ so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI
2183
+ -----END CERTIFICATE-----
addons/pro/googlesheet/lib/external/Google/Logger/Abstract.php ADDED
@@ -0,0 +1,408 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2014 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * Abstract logging class based on the PSR-3 standard.
24
+ *
25
+ * NOTE: We don't implement `Psr\Log\LoggerInterface` because we need to
26
+ * maintain PHP 5.2 support.
27
+ *
28
+ * @see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md
29
+ */
30
+ abstract class Google_Logger_Abstract
31
+ {
32
+ /**
33
+ * Default log format
34
+ */
35
+ const DEFAULT_LOG_FORMAT = "[%datetime%] %level%: %message% %context%\n";
36
+ /**
37
+ * Default date format
38
+ *
39
+ * Example: 16/Nov/2014:03:26:16 -0500
40
+ */
41
+ const DEFAULT_DATE_FORMAT = 'd/M/Y:H:i:s O';
42
+
43
+ /**
44
+ * System is unusable
45
+ */
46
+ const EMERGENCY = 'emergency';
47
+ /**
48
+ * Action must be taken immediately
49
+ *
50
+ * Example: Entire website down, database unavailable, etc. This should
51
+ * trigger the SMS alerts and wake you up.
52
+ */
53
+ const ALERT = 'alert';
54
+ /**
55
+ * Critical conditions
56
+ *
57
+ * Example: Application component unavailable, unexpected exception.
58
+ */
59
+ const CRITICAL = 'critical';
60
+ /**
61
+ * Runtime errors that do not require immediate action but should typically
62
+ * be logged and monitored.
63
+ */
64
+ const ERROR = 'error';
65
+ /**
66
+ * Exceptional occurrences that are not errors.
67
+ *
68
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
69
+ * that are not necessarily wrong.
70
+ */
71
+ const WARNING = 'warning';
72
+ /**
73
+ * Normal but significant events.
74
+ */
75
+ const NOTICE = 'notice';
76
+ /**
77
+ * Interesting events.
78
+ *
79
+ * Example: User logs in, SQL logs.
80
+ */
81
+ const INFO = 'info';
82
+ /**
83
+ * Detailed debug information.
84
+ */
85
+ const DEBUG = 'debug';
86
+
87
+ /**
88
+ * @var array $levels Logging levels
89
+ */
90
+ protected static $levels = array(
91
+ self::EMERGENCY => 600,
92
+ self::ALERT => 550,
93
+ self::CRITICAL => 500,
94
+ self::ERROR => 400,
95
+ self::WARNING => 300,
96
+ self::NOTICE => 250,
97
+ self::INFO => 200,
98
+ self::DEBUG => 100,
99
+ );
100
+
101
+ /**
102
+ * @var integer $level The minimum logging level
103
+ */
104
+ protected $level = self::DEBUG;
105
+
106
+ /**
107
+ * @var string $logFormat The current log format
108
+ */
109
+ protected $logFormat = self::DEFAULT_LOG_FORMAT;
110
+ /**
111
+ * @var string $dateFormat The current date format
112
+ */
113
+ protected $dateFormat = self::DEFAULT_DATE_FORMAT;
114
+
115
+ /**
116
+ * @var boolean $allowNewLines If newlines are allowed
117
+ */
118
+ protected $allowNewLines = false;
119
+
120
+ /**
121
+ * @param Google_Client $client The current Google client
122
+ */
123
+ public function __construct(Google_Client $client)
124
+ {
125
+ $this->setLevel(
126
+ $client->getClassConfig('Google_Logger_Abstract', 'level')
127
+ );
128
+
129
+ $format = $client->getClassConfig('Google_Logger_Abstract', 'log_format');
130
+ $this->logFormat = $format ? $format : self::DEFAULT_LOG_FORMAT;
131
+
132
+ $format = $client->getClassConfig('Google_Logger_Abstract', 'date_format');
133
+ $this->dateFormat = $format ? $format : self::DEFAULT_DATE_FORMAT;
134
+
135
+ $this->allowNewLines = (bool) $client->getClassConfig(
136
+ 'Google_Logger_Abstract',
137
+ 'allow_newlines'
138
+ );
139
+ }
140
+
141
+ /**
142
+ * Sets the minimum logging level that this logger handles.
143
+ *
144
+ * @param integer $level
145
+ */
146
+ public function setLevel($level)
147
+ {
148
+ $this->level = $this->normalizeLevel($level);
149
+ }
150
+
151
+ /**
152
+ * Checks if the logger should handle messages at the provided level.
153
+ *
154
+ * @param integer $level
155
+ * @return boolean
156
+ */
157
+ public function shouldHandle($level)
158
+ {
159
+ return $this->normalizeLevel($level) >= $this->level;
160
+ }
161
+
162
+ /**
163
+ * System is unusable.
164
+ *
165
+ * @param string $message The log message
166
+ * @param array $context The log context
167
+ */
168
+ public function emergency($message, array $context = array())
169
+ {
170
+ $this->log(self::EMERGENCY, $message, $context);
171
+ }
172
+
173
+ /**
174
+ * Action must be taken immediately.
175
+ *
176
+ * Example: Entire website down, database unavailable, etc. This should
177
+ * trigger the SMS alerts and wake you up.
178
+ *
179
+ * @param string $message The log message
180
+ * @param array $context The log context
181
+ */
182
+ public function alert($message, array $context = array())
183
+ {
184
+ $this->log(self::ALERT, $message, $context);
185
+ }
186
+
187
+ /**
188
+ * Critical conditions.
189
+ *
190
+ * Example: Application component unavailable, unexpected exception.
191
+ *
192
+ * @param string $message The log message
193
+ * @param array $context The log context
194
+ */
195
+ public function critical($message, array $context = array())
196
+ {
197
+ $this->log(self::CRITICAL, $message, $context);
198
+ }
199
+
200
+ /**
201
+ * Runtime errors that do not require immediate action but should typically
202
+ * be logged and monitored.
203
+ *
204
+ * @param string $message The log message
205
+ * @param array $context The log context
206
+ */
207
+ public function error($message, array $context = array())
208
+ {
209
+ $this->log(self::ERROR, $message, $context);
210
+ }
211
+
212
+ /**
213
+ * Exceptional occurrences that are not errors.
214
+ *
215
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
216
+ * that are not necessarily wrong.
217
+ *
218
+ * @param string $message The log message
219
+ * @param array $context The log context
220
+ */
221
+ public function warning($message, array $context = array())
222
+ {
223
+ $this->log(self::WARNING, $message, $context);
224
+ }
225
+
226
+ /**
227
+ * Normal but significant events.
228
+ *
229
+ * @param string $message The log message
230
+ * @param array $context The log context
231
+ */
232
+ public function notice($message, array $context = array())
233
+ {
234
+ $this->log(self::NOTICE, $message, $context);
235
+ }
236
+
237
+ /**
238
+ * Interesting events.
239
+ *
240
+ * Example: User logs in, SQL logs.
241
+ *
242
+ * @param string $message The log message
243
+ * @param array $context The log context
244
+ */
245
+ public function info($message, array $context = array())
246
+ {
247
+ $this->log(self::INFO, $message, $context);
248
+ }
249
+
250
+ /**
251
+ * Detailed debug information.
252
+ *
253
+ * @param string $message The log message
254
+ * @param array $context The log context
255
+ */
256
+ public function debug($message, array $context = array())
257
+ {
258
+ $this->log(self::DEBUG, $message, $context);
259
+ }
260
+
261
+ /**
262
+ * Logs with an arbitrary level.
263
+ *
264
+ * @param mixed $level The log level
265
+ * @param string $message The log message
266
+ * @param array $context The log context
267
+ */
268
+ public function log($level, $message, array $context = array())
269
+ {
270
+ if (!$this->shouldHandle($level)) {
271
+ return false;
272
+ }
273
+
274
+ $levelName = is_int($level) ? array_search($level, self::$levels) : $level;
275
+ $message = $this->interpolate(
276
+ array(
277
+ 'message' => $message,
278
+ 'context' => $context,
279
+ 'level' => strtoupper($levelName),
280
+ 'datetime' => new DateTime(),
281
+ )
282
+ );
283
+
284
+ $this->write($message);
285
+ }
286
+
287
+ /**
288
+ * Interpolates log variables into the defined log format.
289
+ *
290
+ * @param array $variables The log variables.
291
+ * @return string
292
+ */
293
+ protected function interpolate(array $variables = array())
294
+ {
295
+ $template = $this->logFormat;
296
+
297
+ if (!$variables['context']) {
298
+ $template = str_replace('%context%', '', $template);
299
+ unset($variables['context']);
300
+ } else {
301
+ $this->reverseJsonInContext($variables['context']);
302
+ }
303
+
304
+ foreach ($variables as $key => $value) {
305
+ if (strpos($template, '%'. $key .'%') !== false) {
306
+ $template = str_replace(
307
+ '%' . $key . '%',
308
+ $this->export($value),
309
+ $template
310
+ );
311
+ }
312
+ }
313
+
314
+ return $template;
315
+ }
316
+
317
+ /**
318
+ * Reverses JSON encoded PHP arrays and objects so that they log better.
319
+ *
320
+ * @param array $context The log context
321
+ */
322
+ protected function reverseJsonInContext(array &$context)
323
+ {
324
+ if (!$context) {
325
+ return;
326
+ }
327
+
328
+ foreach ($context as $key => $val) {
329
+ if (!$val || !is_string($val) || !($val[0] == '{' || $val[0] == '[')) {
330
+ continue;
331
+ }
332
+
333
+ $json = @json_decode($val);
334
+ if (is_object($json) || is_array($json)) {
335
+ $context[$key] = $json;
336
+ }
337
+ }
338
+ }
339
+
340
+ /**
341
+ * Exports a PHP value for logging to a string.
342
+ *
343
+ * @param mixed $value The value to
344
+ */
345
+ protected function export($value)
346
+ {
347
+ if (is_string($value)) {
348
+ if ($this->allowNewLines) {
349
+ return $value;
350
+ }
351
+
352
+ return preg_replace('/[\r\n]+/', ' ', $value);
353
+ }
354
+
355
+ if (is_resource($value)) {
356
+ return sprintf(
357
+ 'resource(%d) of type (%s)',
358
+ $value,
359
+ get_resource_type($value)
360
+ );
361
+ }
362
+
363
+ if ($value instanceof DateTime) {
364
+ return $value->format($this->dateFormat);
365
+ }
366
+
367
+ if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
368
+ $options = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE;
369
+
370
+ if ($this->allowNewLines) {
371
+ $options |= JSON_PRETTY_PRINT;
372
+ }
373
+
374
+ return @json_encode($value, $options);
375
+ }
376
+
377
+ return str_replace('\\/', '/', @json_encode($value));
378
+ }
379
+
380
+ /**
381
+ * Converts a given log level to the integer form.
382
+ *
383
+ * @param mixed $level The logging level
384
+ * @return integer $level The normalized level
385
+ * @throws Google_Logger_Exception If $level is invalid
386
+ */
387
+ protected function normalizeLevel($level)
388
+ {
389
+ if (is_int($level) && array_search($level, self::$levels) !== false) {
390
+ return $level;
391
+ }
392
+
393
+ if (is_string($level) && isset(self::$levels[$level])) {
394
+ return self::$levels[$level];
395
+ }
396
+
397
+ throw new Google_Logger_Exception(
398
+ sprintf("Unknown LogLevel: '%s'", $level)
399
+ );
400
+ }
401
+
402
+ /**
403
+ * Writes a message to the current log implementation.
404
+ *
405
+ * @param string $message The message
406
+ */
407
+ abstract protected function write($message);
408
+ }
addons/pro/googlesheet/lib/external/Google/Logger/Exception.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2014 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ class Google_Logger_Exception extends Google_Exception
23
+ {
24
+ }
addons/pro/googlesheet/lib/external/Google/Logger/File.php ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2014 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * File logging class based on the PSR-3 standard.
24
+ *
25
+ * This logger writes to a PHP stream resource.
26
+ */
27
+ class Google_Logger_File extends Google_Logger_Abstract
28
+ {
29
+ /**
30
+ * @var string|resource $file Where logs are written
31
+ */
32
+ private $file;
33
+ /**
34
+ * @var integer $mode The mode to use if the log file needs to be created
35
+ */
36
+ private $mode = 0640;
37
+ /**
38
+ * @var boolean $lock If a lock should be attempted before writing to the log
39
+ */
40
+ private $lock = false;
41
+
42
+ /**
43
+ * @var integer $trappedErrorNumber Trapped error number
44
+ */
45
+ private $trappedErrorNumber;
46
+ /**
47
+ * @var string $trappedErrorString Trapped error string
48
+ */
49
+ private $trappedErrorString;
50
+
51
+ /**
52
+ * {@inheritdoc}
53
+ */
54
+ public function __construct(Google_Client $client)
55
+ {
56
+ parent::__construct($client);
57
+
58
+ $file = $client->getClassConfig('Google_Logger_File', 'file');
59
+ if (!is_string($file) && !is_resource($file)) {
60
+ throw new Google_Logger_Exception(
61
+ 'File logger requires a filename or a valid file pointer'
62
+ );
63
+ }
64
+
65
+ $mode = $client->getClassConfig('Google_Logger_File', 'mode');
66
+ if (!$mode) {
67
+ $this->mode = $mode;
68
+ }
69
+
70
+ $this->lock = (bool) $client->getClassConfig('Google_Logger_File', 'lock');
71
+ $this->file = $file;
72
+ }
73
+
74
+ /**
75
+ * {@inheritdoc}
76
+ */
77
+ protected function write($message)
78
+ {
79
+ if (is_string($this->file)) {
80
+ $this->open();
81
+ } elseif (!is_resource($this->file)) {
82
+ throw new Google_Logger_Exception('File pointer is no longer available');
83
+ }
84
+
85
+ if ($this->lock) {
86
+ flock($this->file, LOCK_EX);
87
+ }
88
+
89
+ fwrite($this->file, (string) $message);
90
+
91
+ if ($this->lock) {
92
+ flock($this->file, LOCK_UN);
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Opens the log for writing.
98
+ *
99
+ * @return resource
100
+ */
101
+ private function open()
102
+ {
103
+ // Used for trapping `fopen()` errors.
104
+ $this->trappedErrorNumber = null;
105
+ $this->trappedErrorString = null;
106
+
107
+ $old = set_error_handler(array($this, 'trapError'));
108
+
109
+ $needsChmod = !file_exists($this->file);
110
+ $fh = fopen($this->file, 'a');
111
+
112
+ restore_error_handler();
113
+
114
+ // Handles trapped `fopen()` errors.
115
+ if ($this->trappedErrorNumber) {
116
+ throw new Google_Logger_Exception(
117
+ sprintf(
118
+ "Logger Error: '%s'",
119
+ $this->trappedErrorString
120
+ ),
121
+ $this->trappedErrorNumber
122
+ );
123
+ }
124
+
125
+ if ($needsChmod) {
126
+ @chmod($this->file, $this->mode & ~umask());
127
+ }
128
+
129
+ return $this->file = $fh;
130
+ }
131
+
132
+ /**
133
+ * Closes the log stream resource.
134
+ */
135
+ private function close()
136
+ {
137
+ if (is_resource($this->file)) {
138
+ fclose($this->file);
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Traps `fopen()` errors.
144
+ *
145
+ * @param integer $errno The error number
146
+ * @param string $errstr The error string
147
+ */
148
+ private function trapError($errno, $errstr)
149
+ {
150
+ $this->trappedErrorNumber = $errno;
151
+ $this->trappedErrorString = $errstr;
152
+ }
153
+
154
+ public function __destruct()
155
+ {
156
+ $this->close();
157
+ }
158
+ }
addons/pro/googlesheet/lib/external/Google/Logger/Null.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2014 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * Null logger based on the PSR-3 standard.
24
+ *
25
+ * This logger simply discards all messages.
26
+ */
27
+ class Google_Logger_Null extends Google_Logger_Abstract
28
+ {
29
+ /**
30
+ * {@inheritdoc}
31
+ */
32
+ public function shouldHandle($level)
33
+ {
34
+ return false;
35
+ }
36
+
37
+ /**
38
+ * {@inheritdoc}
39
+ */
40
+ protected function write($message, array $context = array())
41
+ {
42
+ }
43
+ }
addons/pro/googlesheet/lib/external/Google/Logger/Psr.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2014 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ if (!class_exists('Google_Client')) {
19
+ require_once dirname(__FILE__) . '/../autoload.php';
20
+ }
21
+
22
+ /**
23
+ * Psr logging class based on the PSR-3 standard.
24
+ *
25
+ * This logger will delegate all logging to a PSR-3 compatible logger specified
26
+ * with the `Google_Logger_Psr::setLogger()` method.
27
+ */
28
+ class Google_Logger_Psr extends Google_Logger_Abstract
29
+ {
30
+ /**
31
+ * @param Psr\Log\LoggerInterface $logger The PSR-3 logger
32
+ */
33
+ private $logger;
34
+
35
+ /**
36
+ * @param Google_Client $client The current Google client
37
+ * @param Psr\Log\LoggerInterface $logger PSR-3 logger where logging will be delegated.
38
+ */
39
+ public function __construct(Google_Client $client, /*Psr\Log\LoggerInterface*/ $logger = null)
40
+ {
41
+ parent::__construct($client);
42
+
43
+ if ($logger) {
44
+ $this->setLogger($logger);
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Sets the PSR-3 logger where logging will be delegated.
50
+ *
51
+ * NOTE: The `$logger` should technically implement
52
+ * `Psr\Log\LoggerInterface`, but we don't explicitly require this so that
53
+ * we can be compatible with PHP 5.2.
54
+ *
55
+ * @param Psr\Log\LoggerInterface $logger The PSR-3 logger
56
+ */
57
+ public function setLogger(/*Psr\Log\LoggerInterface*/ $logger)
58
+ {
59
+ $this->logger = $logger;
60
+ }
61
+
62
+ /**
63
+ * {@inheritdoc}
64
+ */
65
+ public function shouldHandle($level)
66
+ {
67
+ return isset($this->logger) && parent::shouldHandle($level);
68
+ }
69
+
70
+ /**
71
+ * {@inheritdoc}
72
+ */
73
+ public function log($level, $message, array $context = array())
74
+ {
75
+ if (!$this->shouldHandle($level)) {
76
+ return false;
77
+ }
78
+
79
+ if ($context) {
80
+ $this->reverseJsonInContext($context);
81
+ }
82
+
83
+ $levelName = is_int($level) ? array_search($level, self::$levels) : $level;
84
+ $this->logger->log($levelName, $message, $context);
85
+ }
86
+
87
+ /**
88
+ * {@inheritdoc}
89
+ */
90
+ protected function write($message, array $context = array())
91
+ {
92
+ }
93
+ }
addons/pro/googlesheet/lib/external/Google/Model.php ADDED
@@ -0,0 +1,295 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2011 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * This class defines attributes, valid values, and usage which is generated
20
+ * from a given json schema.
21
+ * http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5
22
+ *
23
+ */
24
+ class Google_Model implements ArrayAccess
25
+ {
26
+ /**
27
+ * If you need to specify a NULL JSON value, use Google_Model::NULL_VALUE
28
+ * instead - it will be replaced when converting to JSON with a real null.
29
+ */
30
+ const NULL_VALUE = "{}gapi-php-null";
31
+ protected $internal_gapi_mappings = array();
32
+ protected $modelData = array();
33
+ protected $processed = array();
34
+
35
+ /**
36
+ * Polymorphic - accepts a variable number of arguments dependent
37
+ * on the type of the model subclass.
38
+ */
39
+ final public function __construct()
40
+ {
41
+ if (func_num_args() == 1 && is_array(func_get_arg(0))) {
42
+ // Initialize the model with the array's contents.
43
+ $array = func_get_arg(0);
44
+ $this->mapTypes($array);
45
+ }
46
+ $this->gapiInit();
47
+ }
48
+
49
+ /**
50
+ * Getter that handles passthrough access to the data array, and lazy object creation.
51
+ * @param string $key Property name.
52
+ * @return mixed The value if any, or null.
53
+ */
54
+ public function __get($key)
55
+ {
56
+ $keyTypeName = $this->keyType($key);
57
+ $keyDataType = $this->dataType($key);
58
+ if (isset($this->$keyTypeName) && !isset($this->processed[$key])) {
59
+ if (isset($this->modelData[$key])) {
60
+ $val = $this->modelData[$key];
61
+ } else if (isset($this->$keyDataType) &&
62
+ ($this->$keyDataType == 'array' || $this->$keyDataType == 'map')) {
63
+ $val = array();
64
+ } else {
65
+ $val = null;
66
+ }
67
+
68
+ if ($this->isAssociativeArray($val)) {
69
+ if (isset($this->$keyDataType) && 'map' == $this->$keyDataType) {
70
+ foreach ($val as $arrayKey => $arrayItem) {
71
+ $this->modelData[$key][$arrayKey] =
72
+ $this->createObjectFromName($keyTypeName, $arrayItem);
73
+ }
74
+ } else {
75
+ $this->modelData[$key] = $this->createObjectFromName($keyTypeName, $val);
76
+ }
77
+ } else if (is_array($val)) {
78
+ $arrayObject = array();
79
+ foreach ($val as $arrayIndex => $arrayItem) {
80
+ $arrayObject[$arrayIndex] =
81
+ $this->createObjectFromName($keyTypeName, $arrayItem);
82
+ }
83
+ $this->modelData[$key] = $arrayObject;
84
+ }
85
+ $this->processed[$key] = true;
86
+ }
87
+
88
+ return isset($this->modelData[$key]) ? $this->modelData[$key] : null;
89
+ }
90
+
91
+ /**
92
+ * Initialize this object's properties from an array.
93
+ *
94
+ * @param array $array Used to seed this object's properties.
95
+ * @return void
96
+ */
97
+ protected function mapTypes($array)
98
+ {
99
+ // Hard initialise simple types, lazy load more complex ones.
100
+ foreach ($array as $key => $val) {
101
+ if ( !property_exists($this, $this->keyType($key)) &&
102
+ property_exists($this, $key)) {
103
+ $this->$key = $val;
104
+ unset($array[$key]);
105
+ } elseif (property_exists($this, $camelKey = Google_Utils::camelCase($key))) {
106
+ // This checks if property exists as camelCase, leaving it in array as snake_case
107
+ // in case of backwards compatibility issues.
108
+ $this->$camelKey = $val;
109
+ }
110
+ }
111
+ $this->modelData = $array;
112
+ }
113
+
114
+ /**
115
+ * Blank initialiser to be used in subclasses to do post-construction initialisation - this
116
+ * avoids the need for subclasses to have to implement the variadics handling in their
117
+ * constructors.
118
+ */
119
+ protected function gapiInit()
120
+ {
121
+ return;
122
+ }
123
+
124
+ /**
125
+ * Create a simplified object suitable for straightforward
126
+ * conversion to JSON. This is relatively expensive
127
+ * due to the usage of reflection, but shouldn't be called
128
+ * a whole lot, and is the most straightforward way to filter.
129
+ */
130
+ public function toSimpleObject()
131
+ {
132
+ $object = new stdClass();
133
+
134
+ // Process all other data.
135
+ foreach ($this->modelData as $key => $val) {
136
+ $result = $this->getSimpleValue($val);
137
+ if ($result !== null) {
138
+ $object->$key = $this->nullPlaceholderCheck($result);
139
+ }
140
+ }
141
+
142
+ // Process all public properties.
143
+ $reflect = new ReflectionObject($this);
144
+ $props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC);
145
+ foreach ($props as $member) {
146
+ $name = $member->getName();
147
+ $result = $this->getSimpleValue($this->$name);
148
+ if ($result !== null) {
149
+ $name = $this->getMappedName($name);
150
+ $object->$name = $this->nullPlaceholderCheck($result);
151
+ }
152
+ }
153
+
154
+ return $object;
155
+ }
156
+
157
+ /**
158
+ * Handle different types of values, primarily
159
+ * other objects and map and array data types.
160
+ */
161
+ private function getSimpleValue($value)
162
+ {
163
+ if ($value instanceof Google_Model) {
164
+ return $value->toSimpleObject();
165
+ } else if (is_array($value)) {
166
+ $return = array();
167
+ foreach ($value as $key => $a_value) {
168
+ $a_value = $this->getSimpleValue($a_value);
169
+ if ($a_value !== null) {
170
+ $key = $this->getMappedName($key);
171
+ $return[$key] = $this->nullPlaceholderCheck($a_value);
172
+ }
173
+ }
174
+ return $return;
175
+ }
176
+ return $value;
177
+ }
178
+
179
+ /**
180
+ * Check whether the value is the null placeholder and return true null.
181
+ */
182
+ private function nullPlaceholderCheck($value)
183
+ {
184
+ if ($value === self::NULL_VALUE) {
185
+ return null;
186
+ }
187
+ return $value;
188
+ }
189
+
190
+ /**
191
+ * If there is an internal name mapping, use that.
192
+ */
193
+ private function getMappedName($key)
194
+ {
195
+ if (isset($this->internal_gapi_mappings) &&
196
+ isset($this->internal_gapi_mappings[$key])) {
197
+ $key = $this->internal_gapi_mappings[$key];
198
+ }
199
+ return $key;
200
+ }
201
+
202
+ /**
203
+ * Returns true only if the array is associative.
204
+ * @param array $array
205
+ * @return bool True if the array is associative.
206
+ */
207
+ protected function isAssociativeArray($array)
208
+ {
209
+ if (!is_array($array)) {
210
+ return false;
211
+ }
212
+ $keys = array_keys($array);
213
+ foreach ($keys as $key) {
214
+ if (is_string($key)) {
215
+ return true;
216
+ }
217
+ }
218
+ return false;
219
+ }
220
+
221
+ /**
222
+ * Given a variable name, discover its type.
223
+ *
224
+ * @param $name
225
+ * @param $item
226
+ * @return object The object from the item.
227
+ */
228
+ private function createObjectFromName($name, $item)
229
+ {
230
+ $type = $this->$name;
231
+ return new $type($item);
232
+ }
233
+
234
+ /**
235
+ * Verify if $obj is an array.
236
+ * @throws Google_Exception Thrown if $obj isn't an array.
237
+ * @param array $obj Items that should be validated.
238
+ * @param string $method Method expecting an array as an argument.
239
+ */
240
+ public function assertIsArray($obj, $method)
241
+ {
242
+ if ($obj && !is_array($obj)) {
243
+ throw new Google_Exception(
244
+ "Incorrect parameter type passed to $method(). Expected an array."
245
+ );
246
+ }
247
+ }
248
+
249
+ public function offsetExists($offset)
250
+ {
251
+ return isset($this->$offset) || isset($this->modelData[$offset]);
252
+ }
253
+
254
+ public function offsetGet($offset)
255
+ {
256
+ return isset($this->$offset) ?
257
+ $this->$offset :
258
+ $this->__get($offset);
259
+ }
260
+
261
+ public function offsetSet($offset, $value)
262
+ {
263
+ if (property_exists($this, $offset)) {
264
+ $this->$offset = $value;
265
+ } else {
266
+ $this->modelData[$offset] = $value;
267
+ $this->processed[$offset] = true;
268
+ }
269
+ }
270
+
271
+ public function offsetUnset($offset)
272
+ {
273
+ unset($this->modelData[$offset]);
274
+ }
275
+
276
+ protected function keyType($key)
277
+ {
278
+ return $key . "Type";
279
+ }
280
+
281
+ protected function dataType($key)
282
+ {
283
+ return $key . "DataType";
284
+ }
285
+
286
+ public function __isset($key)
287
+ {
288
+ return isset($this->modelData[$key]);
289
+ }
290
+
291
+ public function __unset($key)
292
+ {
293
+ unset($this->modelData[$key]);
294
+ }
295
+ }
addons/pro/googlesheet/lib/external/Google/Service.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ class Google_Service
19
+ {
20
+ public $batchPath;
21
+ public $rootUrl;
22
+ public $version;
23
+ public $servicePath;
24
+ public $availableScopes;
25
+ public $resource;
26
+ private $client;
27
+
28
+ public function __construct(Google_Client $client)
29
+ {
30
+ $this->client = $client;
31
+ }
32
+
33
+ /**
34
+ * Return the associated Google_Client class.
35
+ * @return Google_Client
36
+ */
37
+ public function getClient()
38
+ {
39
+ return $this->client;
40
+ }
41
+
42
+ /**
43
+ * Create a new HTTP Batch handler for this service
44
+ *
45
+ * @return Google_Http_Batch
46
+ */
47
+ public function createBatch()
48
+ {
49
+ return new Google_Http_Batch(
50
+ $this->client,
51
+ false,
52
+ $this->rootUrl,
53
+ $this->batchPath
54
+ );
55
+ }
56
+ }
addons/pro/googlesheet/lib/external/Google/Service/AdExchangeBuyer.php ADDED
@@ -0,0 +1,4555 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
+ * use this file except in compliance with the License. You may obtain a copy of
5
+ * the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ * License for the specific language governing permissions and limitations under
13
+ * the License.
14
+ */
15
+
16
+ /**
17
+ * Service definition for AdExchangeBuyer (v1.4).
18
+ *
19
+ * <p>
20
+ * Accesses your bidding-account information, submits creatives for validation,
21
+ * finds available direct deals, and retrieves performance reports.</p>
22
+ *
23
+ * <p>
24
+ * For more information about this service, see the API
25
+ * <a href="https://developers.google.com/ad-exchange/buyer-rest" target="_blank">Documentation</a>
26
+ * </p>
27
+ *
28
+ * @author Google, Inc.
29
+ */
30
+ class Google_Service_AdExchangeBuyer extends Google_Service
31
+ {
32
+ /** Manage your Ad Exchange buyer account configuration. */
33
+ const ADEXCHANGE_BUYER =
34
+ "https://www.googleapis.com/auth/adexchange.buyer";
35
+
36
+ public $accounts;
37
+ public $billingInfo;
38
+ public $budget;
39
+ public $creatives;
40
+ public $marketplacedeals;
41
+ public $marketplacenotes;
42
+ public $performanceReport;
43
+ public $pretargetingConfig;
44
+ public $products;
45
+ public $proposals;
46
+
47
+
48
+ /**
49
+ * Constructs the internal representation of the AdExchangeBuyer service.
50
+ *
51
+ * @param Google_Client $client
52
+ */
53
+ public function __construct(Google_Client $client)
54
+ {
55
+ parent::__construct($client);
56
+ $this->rootUrl = 'https://www.googleapis.com/';
57
+ $this->servicePath = 'adexchangebuyer/v1.4/';
58
+ $this->version = 'v1.4';
59
+ $this->serviceName = 'adexchangebuyer';
60
+
61
+ $this->accounts = new Google_Service_AdExchangeBuyer_Accounts_Resource(
62
+ $this,
63
+ $this->serviceName,
64
+ 'accounts',
65
+ array(
66
+ 'methods' => array(
67
+ 'get' => array(
68
+ 'path' => 'accounts/{id}',
69
+ 'httpMethod' => 'GET',
70
+ 'parameters' => array(
71
+ 'id' => array(
72
+ 'location' => 'path',
73
+ 'type' => 'integer',
74
+ 'required' => true,
75
+ ),
76
+ ),
77
+ ),'list' => array(
78
+ 'path' => 'accounts',
79
+ 'httpMethod' => 'GET',
80
+ 'parameters' => array(),
81
+ ),'patch' => array(
82
+ 'path' => 'accounts/{id}',
83
+ 'httpMethod' => 'PATCH',
84
+ 'parameters' => array(
85
+ 'id' => array(
86
+ 'location' => 'path',
87
+ 'type' => 'integer',
88
+ 'required' => true,
89
+ ),
90
+ ),
91
+ ),'update' => array(
92
+ 'path' => 'accounts/{id}',
93
+ 'httpMethod' => 'PUT',
94
+ 'parameters' => array(
95
+ 'id' => array(
96
+ 'location' => 'path',
97
+ 'type' => 'integer',
98
+ 'required' => true,
99
+ ),
100
+ ),
101
+ ),
102
+ )
103
+ )
104
+ );
105
+ $this->billingInfo = new Google_Service_AdExchangeBuyer_BillingInfo_Resource(
106
+ $this,
107
+ $this->serviceName,
108
+ 'billingInfo',
109
+ array(
110
+ 'methods' => array(
111
+ 'get' => array(
112
+ 'path' => 'billinginfo/{accountId}',
113
+ 'httpMethod' => 'GET',
114
+ 'parameters' => array(
115
+ 'accountId' => array(
116
+ 'location' => 'path',
117
+ 'type' => 'integer',
118
+ 'required' => true,
119
+ ),
120
+ ),
121
+ ),'list' => array(
122
+ 'path' => 'billinginfo',
123
+ 'httpMethod' => 'GET',
124
+ 'parameters' => array(),
125
+ ),
126
+ )
127
+ )
128
+ );
129
+ $this->budget = new Google_Service_AdExchangeBuyer_Budget_Resource(
130
+ $this,
131
+ $this->serviceName,
132
+ 'budget',
133
+ array(
134
+ 'methods' => array(
135
+ 'get' => array(
136
+ 'path' => 'billinginfo/{accountId}/{billingId}',
137
+ 'httpMethod' => 'GET',
138
+ 'parameters' => array(
139
+ 'accountId' => array(
140
+ 'location' => 'path',
141
+ 'type' => 'string',
142
+ 'required' => true,
143
+ ),
144
+ 'billingId' => array(
145
+ 'location' => 'path',
146
+ 'type' => 'string',
147
+ 'required' => true,
148
+ ),
149
+ ),
150
+ ),'patch' => array(
151
+ 'path' => 'billinginfo/{accountId}/{billingId}',
152
+ 'httpMethod' => 'PATCH',
153
+ 'parameters' => array(
154
+ 'accountId' => array(
155
+ 'location' => 'path',
156
+ 'type' => 'string',
157
+ 'required' => true,
158
+ ),
159
+ 'billingId' => array(
160
+ 'location' => 'path',
161
+ 'type' => 'string',
162
+ 'required' => true,
163
+ ),
164
+ ),
165
+ ),'update' => array(
166
+ 'path' => 'billinginfo/{accountId}/{billingId}',
167
+ 'httpMethod' => 'PUT',
168
+ 'parameters' => array(
169
+ 'accountId' => array(
170
+ 'location' => 'path',
171
+ 'type' => 'string',
172
+ 'required' => true,
173
+ ),
174
+ 'billingId' => array(
175
+ 'location' => 'path',
176
+ 'type' => 'string',
177
+ 'required' => true,
178
+ ),
179
+ ),
180
+ ),
181
+ )
182
+ )
183
+ );
184
+ $this->creatives = new Google_Service_AdExchangeBuyer_Creatives_Resource(
185
+ $this,
186
+ $this->serviceName,
187
+ 'creatives',
188
+ array(
189
+ 'methods' => array(
190
+ 'addDeal' => array(
191
+ 'path' => 'creatives/{accountId}/{buyerCreativeId}/addDeal/{dealId}',
192
+ 'httpMethod' => 'POST',
193
+ 'parameters' => array(
194
+ 'accountId' => array(
195
+ 'location' => 'path',
196
+ 'type' => 'integer',
197
+ 'required' => true,
198
+ ),
199
+ 'buyerCreativeId' => array(
200
+ 'location' => 'path',
201
+ 'type' => 'string',
202
+ 'required' => true,
203
+ ),
204
+ 'dealId' => array(
205
+ 'location' => 'path',
206
+ 'type' => 'string',
207
+ 'required' => true,
208
+ ),
209
+ ),
210
+ ),'get' => array(
211
+ 'path' => 'creatives/{accountId}/{buyerCreativeId}',
212
+ 'httpMethod' => 'GET',
213
+ 'parameters' => array(
214
+ 'accountId' => array(
215
+ 'location' => 'path',
216
+ 'type' => 'integer',
217
+ 'required' => true,
218
+ ),
219
+ 'buyerCreativeId' => array(
220
+ 'location' => 'path',
221
+ 'type' => 'string',
222
+ 'required' => true,
223
+ ),
224
+ ),
225
+ ),'insert' => array(
226
+ 'path' => 'creatives',
227
+ 'httpMethod' => 'POST',
228
+ 'parameters' => array(),
229
+ ),'list' => array(
230
+ 'path' => 'creatives',
231
+ 'httpMethod' => 'GET',
232
+ 'parameters' => array(
233
+ 'accountId' => array(
234
+ 'location' => 'query',
235
+ 'type' => 'integer',
236
+ 'repeated' => true,
237
+ ),
238
+ 'buyerCreativeId' => array(
239
+ 'location' => 'query',
240
+ 'type' => 'string',
241
+ 'repeated' => true,
242
+ ),
243
+ 'dealsStatusFilter' => array(
244
+ 'location' => 'query',
245
+ 'type' => 'string',
246
+ ),
247
+ 'maxResults' => array(
248
+ 'location' => 'query',
249
+ 'type' => 'integer',
250
+ ),
251
+ 'openAuctionStatusFilter' => array(
252
+ 'location' => 'query',
253
+ 'type' => 'string',
254
+ ),
255
+ 'pageToken' => array(
256
+ 'location' => 'query',
257
+ 'type' => 'string',
258
+ ),
259
+ ),
260
+ ),'removeDeal' => array(
261
+ 'path' => 'creatives/{accountId}/{buyerCreativeId}/removeDeal/{dealId}',
262
+ 'httpMethod' => 'POST',
263
+ 'parameters' => array(
264
+ 'accountId' => array(
265
+ 'location' => 'path',
266
+ 'type' => 'integer',
267
+ 'required' => true,
268
+ ),
269
+ 'buyerCreativeId' => array(
270
+ 'location' => 'path',
271
+ 'type' => 'string',
272
+ 'required' => true,
273
+ ),
274
+ 'dealId' => array(
275
+ 'location' => 'path',
276
+ 'type' => 'string',
277
+ 'required' => true,
278
+ ),
279
+ ),
280
+ ),
281
+ )
282
+ )
283
+ );
284
+ $this->marketplacedeals = new Google_Service_AdExchangeBuyer_Marketplacedeals_Resource(
285
+ $this,
286
+ $this->serviceName,
287
+ 'marketplacedeals',
288
+ array(
289
+ 'methods' => array(
290
+ 'delete' => array(
291
+ 'path' => 'proposals/{proposalId}/deals/delete',
292
+ 'httpMethod' => 'POST',
293
+ 'parameters' => array(
294
+ 'proposalId' => array(
295
+ 'location' => 'path',
296
+ 'type' => 'string',
297
+ 'required' => true,
298
+ ),
299
+ ),
300
+ ),'insert' => array(
301
+ 'path' => 'proposals/{proposalId}/deals/insert',
302
+ 'httpMethod' => 'POST',
303
+ 'parameters' => array(
304
+ 'proposalId' => array(
305
+ 'location' => 'path',
306
+ 'type' => 'string',
307
+ 'required' => true,
308
+ ),
309
+ ),
310
+ ),'list' => array(
311
+ 'path' => 'proposals/{proposalId}/deals',
312
+ 'httpMethod' => 'GET',
313
+ 'parameters' => array(
314
+ 'proposalId' => array(
315
+ 'location' => 'path',
316
+ 'type' => 'string',
317
+ 'required' => true,
318
+ ),
319
+ ),
320
+ ),'update' => array(
321
+ 'path' => 'proposals/{proposalId}/deals/update',
322
+ 'httpMethod' => 'POST',
323
+ 'parameters' => array(
324
+ 'proposalId' => array(
325
+ 'location' => 'path',
326
+ 'type' => 'string',
327
+ 'required' => true,
328
+ ),
329
+ ),
330
+ ),
331
+ )
332
+ )
333
+ );
334
+ $this->marketplacenotes = new Google_Service_AdExchangeBuyer_Marketplacenotes_Resource(
335
+ $this,
336
+ $this->serviceName,
337
+ 'marketplacenotes',
338
+ array(
339
+ 'methods' => array(
340
+ 'insert' => array(
341
+ 'path' => 'proposals/{proposalId}/notes/insert',
342
+ 'httpMethod' => 'POST',
343
+ 'parameters' => array(
344
+ 'proposalId' => array(
345
+ 'location' => 'path',
346
+ 'type' => 'string',
347
+ 'required' => true,
348
+ ),
349
+ ),
350
+ ),'list' => array(
351
+ 'path' => 'proposals/{proposalId}/notes',
352
+ 'httpMethod' => 'GET',
353
+ 'parameters' => array(
354
+ 'proposalId' => array(
355
+ 'location' => 'path',
356
+ 'type' => 'string',
357
+ 'required' => true,
358
+ ),
359
+ ),
360
+ ),
361
+ )
362
+ )
363
+ );
364
+ $this->performanceReport = new Google_Service_AdExchangeBuyer_PerformanceReport_Resource(
365
+ $this,
366
+ $this->serviceName,
367
+ 'performanceReport',
368
+ array(
369
+ 'methods' => array(
370
+ 'list' => array(
371
+ 'path' => 'performancereport',
372
+ 'httpMethod' => 'GET',
373
+ 'parameters' => array(
374
+ 'accountId' => array(
375
+ 'location' => 'query',
376
+ 'type' => 'string',
377
+ 'required' => true,
378
+ ),
379
+ 'endDateTime' => array(
380
+ 'location' => 'query',
381
+ 'type' => 'string',
382
+ 'required' => true,
383
+ ),
384
+ 'startDateTime' => array(
385
+ 'location' => 'query',
386
+ 'type' => 'string',
387
+ 'required' => true,
388
+ ),
389
+ 'maxResults' => array(
390
+ 'location' => 'query',
391
+ 'type' => 'integer',
392
+ ),
393
+ 'pageToken' => array(
394
+ 'location' => 'query',
395
+ 'type' => 'string',
396
+ ),
397
+ ),
398
+ ),
399
+ )
400
+ )
401
+ );
402
+ $this->pretargetingConfig = new Google_Service_AdExchangeBuyer_PretargetingConfig_Resource(
403
+ $this,
404
+ $this->serviceName,
405
+ 'pretargetingConfig',
406
+ array(
407
+ 'methods' => array(
408
+ 'delete' => array(
409
+ 'path' => 'pretargetingconfigs/{accountId}/{configId}',
410
+ 'httpMethod' => 'DELETE',
411
+ 'parameters' => array(
412
+ 'accountId' => array(
413
+ 'location' => 'path',
414
+ 'type' => 'string',
415
+ 'required' => true,
416
+ ),
417
+ 'configId' => array(
418
+ 'location' => 'path',
419
+ 'type' => 'string',
420
+ 'required' => true,
421
+ ),
422
+ ),
423
+ ),'get' => array(
424
+ 'path' => 'pretargetingconfigs/{accountId}/{configId}',
425
+ 'httpMethod' => 'GET',
426
+ 'parameters' => array(
427
+ 'accountId' => array(
428
+ 'location' => 'path',
429
+ 'type' => 'string',
430
+ 'required' => true,
431
+ ),
432
+ 'configId' => array(
433
+ 'location' => 'path',
434
+ 'type' => 'string',
435
+ 'required' => true,
436
+ ),
437
+ ),
438
+ ),'insert' => array(
439
+ 'path' => 'pretargetingconfigs/{accountId}',
440
+ 'httpMethod' => 'POST',
441
+ 'parameters' => array(
442
+ 'accountId' => array(
443
+ 'location' => 'path',
444
+ 'type' => 'string',
445
+ 'required' => true,
446
+ ),
447
+ ),
448
+ ),'list' => array(
449
+ 'path' => 'pretargetingconfigs/{accountId}',
450
+ 'httpMethod' => 'GET',
451
+ 'parameters' => array(
452
+ 'accountId' => array(
453
+ 'location' => 'path',
454
+ 'type' => 'string',
455
+ 'required' => true,
456
+ ),
457
+ ),
458
+ ),'patch' => array(
459
+ 'path' => 'pretargetingconfigs/{accountId}/{configId}',
460
+ 'httpMethod' => 'PATCH',
461
+ 'parameters' => array(
462
+ 'accountId' => array(
463
+ 'location' => 'path',
464
+ 'type' => 'string',
465
+ 'required' => true,
466
+ ),
467
+ 'configId' => array(
468
+ 'location' => 'path',
469
+ 'type' => 'string',
470
+ 'required' => true,
471
+ ),
472
+ ),
473
+ ),'update' => array(
474
+ 'path' => 'pretargetingconfigs/{accountId}/{configId}',
475
+ 'httpMethod' => 'PUT',
476
+ 'parameters' => array(
477
+ 'accountId' => array(
478
+ 'location' => 'path',
479
+ 'type' => 'string',
480
+ 'required' => true,
481
+ ),
482
+ 'configId' => array(
483
+ 'location' => 'path',
484
+ 'type' => 'string',
485
+ 'required' => true,
486
+ ),
487
+ ),
488
+ ),
489
+ )
490
+ )
491
+ );
492
+ $this->products = new Google_Service_AdExchangeBuyer_Products_Resource(
493
+ $this,
494
+ $this->serviceName,
495
+ 'products',
496
+ array(
497
+ 'methods' => array(
498
+ 'get' => array(
499
+ 'path' => 'products/{productId}',
500
+ 'httpMethod' => 'GET',
501
+ 'parameters' => array(
502
+ 'productId' => array(
503
+ 'location' => 'path',
504
+ 'type' => 'string',
505
+ 'required' => true,
506
+ ),
507
+ ),
508
+ ),'search' => array(
509
+ 'path' => 'products/search',
510
+ 'httpMethod' => 'GET',
511
+ 'parameters' => array(
512
+ 'pqlQuery' => array(
513
+ 'location' => 'query',
514
+ 'type' => 'string',
515
+ ),
516
+ ),
517
+ ),
518
+ )
519
+ )
520
+ );
521
+ $this->proposals = new Google_Service_AdExchangeBuyer_Proposals_Resource(
522
+ $this,
523
+ $this->serviceName,
524
+ 'proposals',
525
+ array(
526
+ 'methods' => array(
527
+ 'get' => array(
528
+ 'path' => 'proposals/{proposalId}',
529
+ 'httpMethod' => 'GET',
530
+ 'parameters' => array(
531
+ 'proposalId' => array(
532
+ 'location' => 'path',
533
+ 'type' => 'string',
534
+ 'required' => true,
535
+ ),
536
+ ),
537
+ ),'insert' => array(
538
+ 'path' => 'proposals/insert',
539
+ 'httpMethod' => 'POST',
540
+ 'parameters' => array(),
541
+ ),'patch' => array(
542
+ 'path' => 'proposals/{proposalId}/{revisionNumber}/{updateAction}',
543
+ 'httpMethod' => 'PATCH',
544
+ 'parameters' => array(
545
+ 'proposalId' => array(
546
+ 'location' => 'path',
547
+ 'type' => 'string',
548
+ 'required' => true,
549
+ ),
550
+ 'revisionNumber' => array(
551
+ 'location' => 'path',
552
+ 'type' => 'string',
553
+ 'required' => true,
554
+ ),
555
+ 'updateAction' => array(
556
+ 'location' => 'path',
557
+ 'type' => 'string',
558
+ 'required' => true,
559
+ ),
560
+ ),
561
+ ),'search' => array(
562
+ 'path' => 'proposals/search',
563
+ 'httpMethod' => 'GET',
564
+ 'parameters' => array(
565
+ 'pqlQuery' => array(
566
+ 'location' => 'query',
567
+ 'type' => 'string',
568
+ ),
569
+ ),
570
+ ),'update' => array(
571
+ 'path' => 'proposals/{proposalId}/{revisionNumber}/{updateAction}',
572
+ 'httpMethod' => 'PUT',
573
+ 'parameters' => array(
574
+ 'proposalId' => array(
575
+ 'location' => 'path',
576
+ 'type' => 'string',
577
+ 'required' => true,
578
+ ),
579
+ 'revisionNumber' => array(
580
+ 'location' => 'path',
581
+ 'type' => 'string',
582
+ 'required' => true,
583
+ ),
584
+ 'updateAction' => array(
585
+ 'location' => 'path',
586
+ 'type' => 'string',
587
+ 'required' => true,
588
+ ),
589
+ ),
590
+ ),
591
+ )
592
+ )
593
+ );
594
+ }
595
+ }
596
+
597
+
598
+ /**
599
+ * The "accounts" collection of methods.
600
+ * Typical usage is:
601
+ * <code>
602
+ * $adexchangebuyerService = new Google_Service_AdExchangeBuyer(...);
603
+ * $accounts = $adexchangebuyerService->accounts;
604
+ * </code>
605
+ */
606
+ class Google_Service_AdExchangeBuyer_Accounts_Resource extends Google_Service_Resource
607
+ {
608
+
609
+ /**
610
+ * Gets one account by ID. (accounts.get)
611
+ *
612
+ * @param int $id The account id
613
+ * @param array $optParams Optional parameters.
614
+ * @return Google_Service_AdExchangeBuyer_Account
615
+ */
616
+ public function get($id, $optParams = array())
617
+ {
618
+ $params = array('id' => $id);
619
+ $params = array_merge($params, $optParams);
620
+ return $this->call('get', array($params), "Google_Service_AdExchangeBuyer_Account");
621
+ }
622
+
623
+ /**
624
+ * Retrieves the authenticated user's list of accounts. (accounts.listAccounts)
625
+ *
626
+ * @param array $optParams Optional parameters.
627
+ * @return Google_Service_AdExchangeBuyer_AccountsList
628
+ */
629
+ public function listAccounts($optParams = array())
630
+ {
631
+ $params = array();
632
+ $params = array_merge($params, $optParams);
633
+ return $this->call('list', array($params), "Google_Service_AdExchangeBuyer_AccountsList");
634
+ }
635
+
636
+ /**
637
+ * Updates an existing account. This method supports patch semantics.
638
+ * (accounts.patch)
639
+ *
640
+ * @param int $id The account id
641
+ * @param Google_Account $postBody
642
+ * @param array $optParams Optional parameters.
643
+ * @return Google_Service_AdExchangeBuyer_Account
644
+ */
645
+ public function patch($id, Google_Service_AdExchangeBuyer_Account $postBody, $optParams = array())
646
+ {
647
+ $params = array('id' => $id, 'postBody' => $postBody);
648
+ $params = array_merge($params, $optParams);
649
+ return $this->call('patch', array($params), "Google_Service_AdExchangeBuyer_Account");
650
+ }
651
+
652
+ /**
653
+ * Updates an existing account. (accounts.update)
654
+ *
655
+ * @param int $id The account id
656
+ * @param Google_Account $postBody
657
+ * @param array $optParams Optional parameters.
658
+ * @return Google_Service_AdExchangeBuyer_Account
659
+ */
660
+ public function update($id, Google_Service_AdExchangeBuyer_Account $postBody, $optParams = array())
661
+ {
662
+ $params = array('id' => $id, 'postBody' => $postBody);
663
+ $params = array_merge($params, $optParams);
664
+ return $this->call('update', array($params), "Google_Service_AdExchangeBuyer_Account");
665
+ }
666
+ }
667
+
668
+ /**
669
+ * The "billingInfo" collection of methods.
670
+ * Typical usage is:
671
+ * <code>
672
+ * $adexchangebuyerService = new Google_Service_AdExchangeBuyer(...);
673
+ * $billingInfo = $adexchangebuyerService->billingInfo;
674
+ * </code>
675
+ */
676
+ class Google_Service_AdExchangeBuyer_BillingInfo_Resource extends Google_Service_Resource
677
+ {
678
+
679
+ /**
680
+ * Returns the billing information for one account specified by account ID.
681
+ * (billingInfo.get)
682
+ *
683
+ * @param int $accountId The account id.
684
+ * @param array $optParams Optional parameters.
685
+ * @return Google_Service_AdExchangeBuyer_BillingInfo
686
+ */
687
+ public function get($accountId, $optParams = array())
688
+ {
689
+ $params = array('accountId' => $accountId);
690
+ $params = array_merge($params, $optParams);
691
+ return $this->call('get', array($params), "Google_Service_AdExchangeBuyer_BillingInfo");
692
+ }
693
+
694
+ /**
695
+ * Retrieves a list of billing information for all accounts of the authenticated
696
+ * user. (billingInfo.listBillingInfo)
697
+ *
698
+ * @param array $optParams Optional parameters.
699
+ * @return Google_Service_AdExchangeBuyer_BillingInfoList
700
+ */
701
+ public function listBillingInfo($optParams = array())
702
+ {
703
+ $params = array();
704
+ $params = array_merge($params, $optParams);
705
+ return $this->call('list', array($params), "Google_Service_AdExchangeBuyer_BillingInfoList");
706
+ }
707
+ }
708
+
709
+ /**
710
+ * The "budget" collection of methods.
711
+ * Typical usage is:
712
+ * <code>
713
+ * $adexchangebuyerService = new Google_Service_AdExchangeBuyer(...);
714
+ * $budget = $adexchangebuyerService->budget;
715
+ * </code>
716
+ */
717
+ class Google_Service_AdExchangeBuyer_Budget_Resource extends Google_Service_Resource
718
+ {
719
+
720
+ /**
721
+ * Returns the budget information for the adgroup specified by the accountId and
722
+ * billingId. (budget.get)
723
+ *
724
+ * @param string $accountId The account id to get the budget information for.
725
+ * @param string $billingId The billing id to get the budget information for.
726
+ * @param array $optParams Optional parameters.
727
+ * @return Google_Service_AdExchangeBuyer_Budget
728
+ */
729
+ public function get($accountId, $billingId, $optParams = array())
730
+ {
731
+ $params = array('accountId' => $accountId, 'billingId' => $billingId);
732
+ $params = array_merge($params, $optParams);
733
+ return $this->call('get', array($params), "Google_Service_AdExchangeBuyer_Budget");
734
+ }
735
+
736
+ /**
737
+ * Updates the budget amount for the budget of the adgroup specified by the
738
+ * accountId and billingId, with the budget amount in the request. This method
739
+ * supports patch semantics. (budget.patch)
740
+ *
741
+ * @param string $accountId The account id associated with the budget being
742
+ * updated.
743
+ * @param string $billingId The billing id associated with the budget being
744
+ * updated.
745
+ * @param Google_Budget $postBody
746
+ * @param array $optParams Optional parameters.
747
+ * @return Google_Service_AdExchangeBuyer_Budget
748
+ */
749
+ public function patch($accountId, $billingId, Google_Service_AdExchangeBuyer_Budget $postBody, $optParams = array())
750
+ {
751
+ $params = array('accountId' => $accountId, 'billingId' => $billingId, 'postBody' => $postBody);
752
+ $params = array_merge($params, $optParams);
753
+ return $this->call('patch', array($params), "Google_Service_AdExchangeBuyer_Budget");
754
+ }
755
+
756
+ /**
757
+ * Updates the budget amount for the budget of the adgroup specified by the
758
+ * accountId and billingId, with the budget amount in the request.
759
+ * (budget.update)
760
+ *
761
+ * @param string $accountId The account id associated with the budget being
762
+ * updated.
763
+ * @param string $billingId The billing id associated with the budget being
764
+ * updated.
765
+ * @param Google_Budget $postBody
766
+ * @param array $optParams Optional parameters.
767
+ * @return Google_Service_AdExchangeBuyer_Budget
768
+ */
769
+ public function update($accountId, $billingId, Google_Service_AdExchangeBuyer_Budget $postBody, $optParams = array())
770
+ {
771
+ $params = array('accountId' => $accountId, 'billingId' => $billingId, 'postBody' => $postBody);
772
+ $params = array_merge($params, $optParams);
773
+ return $this->call('update', array($params), "Google_Service_AdExchangeBuyer_Budget");
774
+ }
775
+ }
776
+
777
+ /**
778
+ * The "creatives" collection of methods.
779
+ * Typical usage is:
780
+ * <code>
781
+ * $adexchangebuyerService = new Google_Service_AdExchangeBuyer(...);
782
+ * $creatives = $adexchangebuyerService->creatives;
783
+ * </code>
784
+ */
785
+ class Google_Service_AdExchangeBuyer_Creatives_Resource extends Google_Service_Resource
786
+ {
787
+
788
+ /**
789
+ * Add a deal id association for the creative. (creatives.addDeal)
790
+ *
791
+ * @param int $accountId The id for the account that will serve this creative.
792
+ * @param string $buyerCreativeId The buyer-specific id for this creative.
793
+ * @param string $dealId The id of the deal id to associate with this creative.
794
+ * @param array $optParams Optional parameters.
795
+ */
796
+ public function addDeal($accountId, $buyerCreativeId, $dealId, $optParams = array())
797
+ {
798
+ $params = array('accountId' => $accountId, 'buyerCreativeId' => $buyerCreativeId, 'dealId' => $dealId);
799
+ $params = array_merge($params, $optParams);
800
+ return $this->call('addDeal', array($params));
801
+ }
802
+
803
+ /**
804
+ * Gets the status for a single creative. A creative will be available 30-40
805
+ * minutes after submission. (creatives.get)
806
+ *
807
+ * @param int $accountId The id for the account that will serve this creative.
808
+ * @param string $buyerCreativeId The buyer-specific id for this creative.
809
+ * @param array $optParams Optional parameters.
810
+ * @return Google_Service_AdExchangeBuyer_Creative
811
+ */
812
+ public function get($accountId, $buyerCreativeId, $optParams = array())
813
+ {
814
+ $params = array('accountId' => $accountId, 'buyerCreativeId' => $buyerCreativeId);
815
+ $params = array_merge($params, $optParams);
816
+ return $this->call('get', array($params), "Google_Service_AdExchangeBuyer_Creative");
817
+ }
818
+
819
+ /**
820
+ * Submit a new creative. (creatives.insert)
821
+ *
822
+ * @param Google_Creative $postBody
823
+ * @param array $optParams Optional parameters.
824
+ * @return Google_Service_AdExchangeBuyer_Creative
825
+ */
826
+ public function insert(Google_Service_AdExchangeBuyer_Creative $postBody, $optParams = array())
827
+ {
828
+ $params = array('postBody' => $postBody);
829
+ $params = array_merge($params, $optParams);
830
+ return $this->call('insert', array($params), "Google_Service_AdExchangeBuyer_Creative");
831
+ }
832
+
833
+ /**
834
+ * Retrieves a list of the authenticated user's active creatives. A creative
835
+ * will be available 30-40 minutes after submission. (creatives.listCreatives)
836
+ *
837
+ * @param array $optParams Optional parameters.
838
+ *
839
+ * @opt_param int accountId When specified, only creatives for the given account
840
+ * ids are returned.
841
+ * @opt_param string buyerCreativeId When specified, only creatives for the
842
+ * given buyer creative ids are returned.
843
+ * @opt_param string dealsStatusFilter When specified, only creatives having the
844
+ * given deals status are returned.
845
+ * @opt_param string maxResults Maximum number of entries returned on one result
846
+ * page. If not set, the default is 100. Optional.
847
+ * @opt_param string openAuctionStatusFilter When specified, only creatives
848
+ * having the given open auction status are returned.
849
+ * @opt_param string pageToken A continuation token, used to page through ad
850
+ * clients. To retrieve the next page, set this parameter to the value of
851
+ * "nextPageToken" from the previous response. Optional.
852
+ * @return Google_Service_AdExchangeBuyer_CreativesList
853
+ */
854
+ public function listCreatives($optParams = array())
855
+ {
856
+ $params = array();
857
+ $params = array_merge($params, $optParams);
858
+ return $this->call('list', array($params), "Google_Service_AdExchangeBuyer_CreativesList");
859
+ }
860
+
861
+ /**
862
+ * Remove a deal id associated with the creative. (creatives.removeDeal)
863
+ *
864
+ * @param int $accountId The id for the account that will serve this creative.
865
+ * @param string $buyerCreativeId The buyer-specific id for this creative.
866
+ * @param string $dealId The id of the deal id to disassociate with this
867
+ * creative.
868
+ * @param array $optParams Optional parameters.
869
+ */
870
+ public function removeDeal($accountId, $buyerCreativeId, $dealId, $optParams = array())
871
+ {
872
+ $params = array('accountId' => $accountId, 'buyerCreativeId' => $buyerCreativeId, 'dealId' => $dealId);
873
+ $params = array_merge($params, $optParams);
874
+ return $this->call('removeDeal', array($params));
875
+ }
876
+ }
877
+
878
+ /**
879
+ * The "marketplacedeals" collection of methods.
880
+ * Typical usage is:
881
+ * <code>
882
+ * $adexchangebuyerService = new Google_Service_AdExchangeBuyer(...);
883
+ * $marketplacedeals = $adexchangebuyerService->marketplacedeals;
884
+ * </code>
885
+ */
886
+ class Google_Service_AdExchangeBuyer_Marketplacedeals_Resource extends Google_Service_Resource
887
+ {
888
+
889
+ /**
890
+ * Delete the specified deals from the proposal (marketplacedeals.delete)
891
+ *
892
+ * @param string $proposalId The proposalId to delete deals from.
893
+ * @param Google_DeleteOrderDealsRequest $postBody
894
+ * @param array $optParams Optional parameters.
895
+ * @return Google_Service_AdExchangeBuyer_DeleteOrderDealsResponse
896
+ */
897
+ public function delete($proposalId, Google_Service_AdExchangeBuyer_DeleteOrderDealsRequest $postBody, $optParams = array())
898
+ {
899
+ $params = array('proposalId' => $proposalId, 'postBody' => $postBody);
900
+ $params = array_merge($params, $optParams);
901
+ return $this->call('delete', array($params), "Google_Service_AdExchangeBuyer_DeleteOrderDealsResponse");
902
+ }
903
+
904
+ /**
905
+ * Add new deals for the specified proposal (marketplacedeals.insert)
906
+ *
907
+ * @param string $proposalId proposalId for which deals need to be added.
908
+ * @param Google_AddOrderDealsRequest $postBody
909
+ * @param array $optParams Optional parameters.
910
+ * @return Google_Service_AdExchangeBuyer_AddOrderDealsResponse
911
+ */
912
+ public function insert($proposalId, Google_Service_AdExchangeBuyer_AddOrderDealsRequest $postBody, $optParams = array())
913
+ {
914
+ $params = array('proposalId' => $proposalId, 'postBody' => $postBody);
915
+ $params = array_merge($params, $optParams);
916
+ return $this->call('insert', array($params), "Google_Service_AdExchangeBuyer_AddOrderDealsResponse");
917
+ }
918
+
919
+ /**
920
+ * List all the deals for a given proposal
921
+ * (marketplacedeals.listMarketplacedeals)
922
+ *
923
+ * @param string $proposalId The proposalId to get deals for.
924
+ * @param array $optParams Optional parameters.
925
+ * @return Google_Service_AdExchangeBuyer_GetOrderDealsResponse
926
+ */
927
+ public function listMarketplacedeals($proposalId, $optParams = array())
928
+ {
929
+ $params = array('proposalId' => $proposalId);
930
+ $params = array_merge($params, $optParams);
931
+ return $this->call('list', array($params), "Google_Service_AdExchangeBuyer_GetOrderDealsResponse");
932
+ }
933
+
934
+ /**
935
+ * Replaces all the deals in the proposal with the passed in deals
936
+ * (marketplacedeals.update)
937
+ *
938
+ * @param string $proposalId The proposalId to edit deals on.
939
+ * @param Google_EditAllOrderDealsRequest $postBody
940
+ * @param array $optParams Optional parameters.
941
+ * @return Google_Service_AdExchangeBuyer_EditAllOrderDealsResponse
942
+ */
943
+ public function update($proposalId, Google_Service_AdExchangeBuyer_EditAllOrderDealsRequest $postBody, $optParams = array())
944
+ {
945
+ $params = array('proposalId' => $proposalId, 'postBody' => $postBody);
946
+ $params = array_merge($params, $optParams);
947
+ return $this->call('update', array($params), "Google_Service_AdExchangeBuyer_EditAllOrderDealsResponse");
948
+ }
949
+ }
950
+
951
+ /**
952
+ * The "marketplacenotes" collection of methods.
953
+ * Typical usage is:
954
+ * <code>
955
+ * $adexchangebuyerService = new Google_Service_AdExchangeBuyer(...);
956
+ * $marketplacenotes = $adexchangebuyerService->marketplacenotes;
957
+ * </code>
958
+ */
959
+ class Google_Service_AdExchangeBuyer_Marketplacenotes_Resource extends Google_Service_Resource
960
+ {
961
+
962
+ /**
963
+ * Add notes to the proposal (marketplacenotes.insert)
964
+ *
965
+ * @param string $proposalId The proposalId to add notes for.
966
+ * @param Google_AddOrderNotesRequest $postBody
967
+ * @param array $optParams Optional parameters.
968
+ * @return Google_Service_AdExchangeBuyer_AddOrderNotesResponse
969
+ */
970
+ public function insert($proposalId, Google_Service_AdExchangeBuyer_AddOrderNotesRequest $postBody, $optParams = array())
971
+ {
972
+ $params = array('proposalId' => $proposalId, 'postBody' => $postBody);
973
+ $params = array_merge($params, $optParams);
974
+ return $this->call('insert', array($params), "Google_Service_AdExchangeBuyer_AddOrderNotesResponse");
975
+ }
976
+
977
+ /**
978
+ * Get all the notes associated with a proposal
979
+ * (marketplacenotes.listMarketplacenotes)
980
+ *
981
+ * @param string $proposalId The proposalId to get notes for.
982
+ * @param array $optParams Optional parameters.
983
+ * @return Google_Service_AdExchangeBuyer_GetOrderNotesResponse
984
+ */
985
+ public function listMarketplacenotes($proposalId, $optParams = array())
986
+ {
987
+ $params = array('proposalId' => $proposalId);
988
+ $params = array_merge($params, $optParams);
989
+ return $this->call('list', array($params), "Google_Service_AdExchangeBuyer_GetOrderNotesResponse");
990
+ }
991
+ }
992
+
993
+ /**
994
+ * The "performanceReport" collection of methods.
995
+ * Typical usage is:
996
+ * <code>
997
+ * $adexchangebuyerService = new Google_Service_AdExchangeBuyer(...);
998
+ * $performanceReport = $adexchangebuyerService->performanceReport;
999
+ * </code>
1000
+ */
1001
+ class Google_Service_AdExchangeBuyer_PerformanceReport_Resource extends Google_Service_Resource
1002
+ {
1003
+
1004
+ /**
1005
+ * Retrieves the authenticated user's list of performance metrics.
1006
+ * (performanceReport.listPerformanceReport)
1007
+ *
1008
+ * @param string $accountId The account id to get the reports.
1009
+ * @param string $endDateTime The end time of the report in ISO 8601 timestamp
1010
+ * format using UTC.
1011
+ * @param string $startDateTime The start time of the report in ISO 8601
1012
+ * timestamp format using UTC.
1013
+ * @param array $optParams Optional parameters.
1014
+ *
1015
+ * @opt_param string maxResults Maximum number of entries returned on one result
1016
+ * page. If not set, the default is 100. Optional.
1017
+ * @opt_param string pageToken A continuation token, used to page through
1018
+ * performance reports. To retrieve the next page, set this parameter to the
1019
+ * value of "nextPageToken" from the previous response. Optional.
1020
+ * @return Google_Service_AdExchangeBuyer_PerformanceReportList
1021
+ */
1022
+ public function listPerformanceReport($accountId, $endDateTime, $startDateTime, $optParams = array())
1023
+ {
1024
+ $params = array('accountId' => $accountId, 'endDateTime' => $endDateTime, 'startDateTime' => $startDateTime);
1025
+ $params = array_merge($params, $optParams);
1026
+ return $this->call('list', array($params), "Google_Service_AdExchangeBuyer_PerformanceReportList");
1027
+ }
1028
+ }
1029
+
1030
+ /**
1031
+ * The "pretargetingConfig" collection of methods.
1032
+ * Typical usage is:
1033
+ * <code>
1034
+ * $adexchangebuyerService = new Google_Service_AdExchangeBuyer(...);
1035
+ * $pretargetingConfig = $adexchangebuyerService->pretargetingConfig;
1036
+ * </code>
1037
+ */
1038
+ class Google_Service_AdExchangeBuyer_PretargetingConfig_Resource extends Google_Service_Resource
1039
+ {
1040
+
1041
+ /**
1042
+ * Deletes an existing pretargeting config. (pretargetingConfig.delete)
1043
+ *
1044
+ * @param string $accountId The account id to delete the pretargeting config
1045
+ * for.
1046
+ * @param string $configId The specific id of the configuration to delete.
1047
+ * @param array $optParams Optional parameters.
1048
+ */
1049
+ public function delete($accountId, $configId, $optParams = array())
1050
+ {
1051
+ $params = array('accountId' => $accountId, 'configId' => $configId);
1052
+ $params = array_merge($params, $optParams);
1053
+ return $this->call('delete', array($params));
1054
+ }
1055
+
1056
+ /**
1057
+ * Gets a specific pretargeting configuration (pretargetingConfig.get)
1058
+ *
1059
+ * @param string $accountId The account id to get the pretargeting config for.
1060
+ * @param string $configId The specific id of the configuration to retrieve.
1061
+ * @param array $optParams Optional parameters.
1062
+ * @return Google_Service_AdExchangeBuyer_PretargetingConfig
1063
+ */
1064
+ public function get($accountId, $configId, $optParams = array())
1065
+ {
1066
+ $params = array('accountId' => $accountId, 'configId' => $configId);
1067
+ $params = array_merge($params, $optParams);
1068
+ return $this->call('get', array($params), "Google_Service_AdExchangeBuyer_PretargetingConfig");
1069
+ }
1070
+
1071
+ /**
1072
+ * Inserts a new pretargeting configuration. (pretargetingConfig.insert)
1073
+ *
1074
+ * @param string $accountId The account id to insert the pretargeting config
1075
+ * for.
1076
+ * @param Google_PretargetingConfig $postBody
1077
+ * @param array $optParams Optional parameters.
1078
+ * @return Google_Service_AdExchangeBuyer_PretargetingConfig
1079
+ */
1080
+ public function insert($accountId, Google_Service_AdExchangeBuyer_PretargetingConfig $postBody, $optParams = array())
1081
+ {
1082
+ $params = array('accountId' => $accountId, 'postBody' => $postBody);
1083
+ $params = array_merge($params, $optParams);
1084
+ return $this->call('insert', array($params), "Google_Service_AdExchangeBuyer_PretargetingConfig");
1085
+ }
1086
+
1087
+ /**
1088
+ * Retrieves a list of the authenticated user's pretargeting configurations.
1089
+ * (pretargetingConfig.listPretargetingConfig)
1090
+ *
1091
+ * @param string $accountId The account id to get the pretargeting configs for.
1092
+ * @param array $optParams Optional parameters.
1093
+ * @return Google_Service_AdExchangeBuyer_PretargetingConfigList
1094
+ */
1095
+ public function listPretargetingConfig($accountId, $optParams = array())
1096
+ {
1097
+ $params = array('accountId' => $accountId);
1098
+ $params = array_merge($params, $optParams);
1099
+ return $this->call('list', array($params), "Google_Service_AdExchangeBuyer_PretargetingConfigList");
1100
+ }
1101
+
1102
+ /**
1103
+ * Updates an existing pretargeting config. This method supports patch
1104
+ * semantics. (pretargetingConfig.patch)
1105
+ *
1106
+ * @param string $accountId The account id to update the pretargeting config
1107
+ * for.
1108
+ * @param string $configId The specific id of the configuration to update.
1109
+ * @param Google_PretargetingConfig $postBody
1110
+ * @param array $optParams Optional parameters.
1111
+ * @return Google_Service_AdExchangeBuyer_PretargetingConfig
1112
+ */
1113
+ public function patch($accountId, $configId, Google_Service_AdExchangeBuyer_PretargetingConfig $postBody, $optParams = array())
1114
+ {
1115
+ $params = array('accountId' => $accountId, 'configId' => $configId, 'postBody' => $postBody);
1116
+ $params = array_merge($params, $optParams);
1117
+ return $this->call('patch', array($params), "Google_Service_AdExchangeBuyer_PretargetingConfig");
1118
+ }
1119
+
1120
+ /**
1121
+ * Updates an existing pretargeting config. (pretargetingConfig.update)
1122
+ *
1123
+ * @param string $accountId The account id to update the pretargeting config
1124
+ * for.
1125
+ * @param string $configId The specific id of the configuration to update.
1126
+ * @param Google_PretargetingConfig $postBody
1127
+ * @param array $optParams Optional parameters.
1128
+ * @return Google_Service_AdExchangeBuyer_PretargetingConfig
1129
+ */
1130
+ public function update($accountId, $configId, Google_Service_AdExchangeBuyer_PretargetingConfig $postBody, $optParams = array())
1131
+ {
1132
+ $params = array('accountId' => $accountId, 'configId' => $configId, 'postBody' => $postBody);
1133
+ $params = array_merge($params, $optParams);
1134
+ return $this->call('update', array($params), "Google_Service_AdExchangeBuyer_PretargetingConfig");
1135
+ }
1136
+ }
1137
+
1138
+ /**
1139
+ * The "products" collection of methods.
1140
+ * Typical usage is:
1141
+ * <code>
1142
+ * $adexchangebuyerService = new Google_Service_AdExchangeBuyer(...);
1143
+ * $products = $adexchangebuyerService->products;
1144
+ * </code>
1145
+ */
1146
+ class Google_Service_AdExchangeBuyer_Products_Resource extends Google_Service_Resource
1147
+ {
1148
+
1149
+ /**
1150
+ * Gets the requested product by id. (products.get)
1151
+ *
1152
+ * @param string $productId The id for the product to get the head revision for.
1153
+ * @param array $optParams Optional parameters.
1154
+ * @return Google_Service_AdExchangeBuyer_Product
1155
+ */
1156
+ public function get($productId, $optParams = array())
1157
+ {
1158
+ $params = array('productId' => $productId);
1159
+ $params = array_merge($params, $optParams);
1160
+ return $this->call('get', array($params), "Google_Service_AdExchangeBuyer_Product");
1161
+ }
1162
+
1163
+ /**
1164
+ * Gets the requested product. (products.search)
1165
+ *
1166
+ * @param array $optParams Optional parameters.
1167
+ *
1168
+ * @opt_param string pqlQuery The pql query used to query for products.
1169
+ * @return Google_Service_AdExchangeBuyer_GetOffersResponse
1170
+ */
1171
+ public function search($optParams = array())
1172
+ {
1173
+ $params = array();
1174
+ $params = array_merge($params, $optParams);
1175
+ return $this->call('search', array($params), "Google_Service_AdExchangeBuyer_GetOffersResponse");
1176
+ }
1177
+ }
1178
+
1179
+ /**
1180
+ * The "proposals" collection of methods.
1181
+ * Typical usage is:
1182
+ * <code>
1183
+ * $adexchangebuyerService = new Google_Service_AdExchangeBuyer(...);
1184
+ * $proposals = $adexchangebuyerService->proposals;
1185
+ * </code>
1186
+ */
1187
+ class Google_Service_AdExchangeBuyer_Proposals_Resource extends Google_Service_Resource
1188
+ {
1189
+
1190
+ /**
1191
+ * Get a proposal given its id (proposals.get)
1192
+ *
1193
+ * @param string $proposalId Id of the proposal to retrieve.
1194
+ * @param array $optParams Optional parameters.
1195
+ * @return Google_Service_AdExchangeBuyer_Proposal
1196
+ */
1197
+ public function get($proposalId, $optParams = array())
1198
+ {
1199
+ $params = array('proposalId' => $proposalId);
1200
+ $params = array_merge($params, $optParams);
1201
+ return $this->call('get', array($params), "Google_Service_AdExchangeBuyer_Proposal");
1202
+ }
1203
+
1204
+ /**
1205
+ * Create the given list of proposals (proposals.insert)
1206
+ *
1207
+ * @param Google_CreateOrdersRequest $postBody
1208
+ * @param array $optParams Optional parameters.
1209
+ * @return Google_Service_AdExchangeBuyer_CreateOrdersResponse
1210
+ */
1211
+ public function insert(Google_Service_AdExchangeBuyer_CreateOrdersRequest $postBody, $optParams = array())
1212
+ {
1213
+ $params = array('postBody' => $postBody);
1214
+ $params = array_merge($params, $optParams);
1215
+ return $this->call('insert', array($params), "Google_Service_AdExchangeBuyer_CreateOrdersResponse");
1216
+ }
1217
+
1218
+ /**
1219
+ * Update the given proposal. This method supports patch semantics.
1220
+ * (proposals.patch)
1221
+ *
1222
+ * @param string $proposalId The proposal id to update.
1223
+ * @param string $revisionNumber The last known revision number to update. If
1224
+ * the head revision in the marketplace database has since changed, an error
1225
+ * will be thrown. The caller should then fetch the latest proposal at head
1226
+ * revision and retry the update at that revision.
1227
+ * @param string $updateAction The proposed action to take on the proposal.
1228
+ * @param Google_Proposal $postBody
1229
+ * @param array $optParams Optional parameters.
1230
+ * @return Google_Service_AdExchangeBuyer_Proposal
1231
+ */
1232
+ public function patch($proposalId, $revisionNumber, $updateAction, Google_Service_AdExchangeBuyer_Proposal $postBody, $optParams = array())
1233
+ {
1234
+ $params = array('proposalId' => $proposalId, 'revisionNumber' => $revisionNumber, 'updateAction' => $updateAction, 'postBody' => $postBody);
1235
+ $params = array_merge($params, $optParams);
1236
+ return $this->call('patch', array($params), "Google_Service_AdExchangeBuyer_Proposal");
1237
+ }
1238
+
1239
+ /**
1240
+ * Search for proposals using pql query (proposals.search)
1241
+ *
1242
+ * @param array $optParams Optional parameters.
1243
+ *
1244
+ * @opt_param string pqlQuery Query string to retrieve specific proposals.
1245
+ * @return Google_Service_AdExchangeBuyer_GetOrdersResponse
1246
+ */
1247
+ public function search($optParams = array())
1248
+ {
1249
+ $params = array();
1250
+ $params = array_merge($params, $optParams);
1251
+ return $this->call('search', array($params), "Google_Service_AdExchangeBuyer_GetOrdersResponse");
1252
+ }
1253
+
1254
+ /**
1255
+ * Update the given proposal (proposals.update)
1256
+ *
1257
+ * @param string $proposalId The proposal id to update.
1258
+ * @param string $revisionNumber The last known revision number to update. If
1259
+ * the head revision in the marketplace database has since changed, an error
1260
+ * will be thrown. The caller should then fetch the latest proposal at head
1261
+ * revision and retry the update at that revision.
1262
+ * @param string $updateAction The proposed action to take on the proposal.
1263
+ * @param Google_Proposal $postBody
1264
+ * @param array $optParams Optional parameters.
1265
+ * @return Google_Service_AdExchangeBuyer_Proposal
1266
+ */
1267
+ public function update($proposalId, $revisionNumber, $updateAction, Google_Service_AdExchangeBuyer_Proposal $postBody, $optParams = array())
1268
+ {
1269
+ $params = array('proposalId' => $proposalId, 'revisionNumber' => $revisionNumber, 'updateAction' => $updateAction, 'postBody' => $postBody);
1270
+ $params = array_merge($params, $optParams);
1271
+ return $this->call('update', array($params), "Google_Service_AdExchangeBuyer_Proposal");
1272
+ }
1273
+ }
1274
+
1275
+
1276
+
1277
+
1278
+ class Google_Service_AdExchangeBuyer_Account extends Google_Collection
1279
+ {
1280
+ protected $collection_key = 'bidderLocation';
1281
+ protected $internal_gapi_mappings = array(
1282
+ );
1283
+ protected $bidderLocationType = 'Google_Service_AdExchangeBuyer_AccountBidderLocation';
1284
+ protected $bidderLocationDataType = 'array';
1285
+ public $cookieMatchingNid;
1286
+ public $cookieMatchingUrl;
1287
+ public $id;
1288
+ public $kind;
1289
+ public $maximumActiveCreatives;
1290
+ public $maximumTotalQps;
1291
+ public $numberActiveCreatives;
1292
+
1293
+
1294
+ public function setBidderLocation($bidderLocation)
1295
+ {
1296
+ $this->bidderLocation = $bidderLocation;
1297
+ }
1298
+ public function getBidderLocation()
1299
+ {
1300
+ return $this->bidderLocation;
1301
+ }
1302
+ public function setCookieMatchingNid($cookieMatchingNid)
1303
+ {
1304
+ $this->cookieMatchingNid = $cookieMatchingNid;
1305
+ }
1306
+ public function getCookieMatchingNid()
1307
+ {
1308
+ return $this->cookieMatchingNid;
1309
+ }
1310
+ public function setCookieMatchingUrl($cookieMatchingUrl)
1311
+ {
1312
+ $this->cookieMatchingUrl = $cookieMatchingUrl;
1313
+ }
1314
+ public function getCookieMatchingUrl()
1315
+ {
1316
+ return $this->cookieMatchingUrl;
1317
+ }
1318
+ public function setId($id)
1319
+ {
1320
+ $this->id = $id;
1321
+ }
1322
+ public function getId()
1323
+ {
1324
+ return $this->id;
1325
+ }
1326
+ public function setKind($kind)
1327
+ {
1328
+ $this->kind = $kind;
1329
+ }
1330
+ public function getKind()
1331
+ {
1332
+ return $this->kind;
1333
+ }
1334
+ public function setMaximumActiveCreatives($maximumActiveCreatives)
1335
+ {
1336
+ $this->maximumActiveCreatives = $maximumActiveCreatives;
1337
+ }
1338
+ public function getMaximumActiveCreatives()
1339
+ {
1340
+ return $this->maximumActiveCreatives;
1341
+ }
1342
+ public function setMaximumTotalQps($maximumTotalQps)
1343
+ {
1344
+ $this->maximumTotalQps = $maximumTotalQps;
1345
+ }
1346
+ public function getMaximumTotalQps()
1347
+ {
1348
+ return $this->maximumTotalQps;
1349
+ }
1350
+ public function setNumberActiveCreatives($numberActiveCreatives)
1351
+ {
1352
+ $this->numberActiveCreatives = $numberActiveCreatives;
1353
+ }
1354
+ public function getNumberActiveCreatives()
1355
+ {
1356
+ return $this->numberActiveCreatives;
1357
+ }
1358
+ }
1359
+
1360
+ class Google_Service_AdExchangeBuyer_AccountBidderLocation extends Google_Model
1361
+ {
1362
+ protected $internal_gapi_mappings = array(
1363
+ );
1364
+ public $maximumQps;
1365
+ public $region;
1366
+ public $url;
1367
+
1368
+
1369
+ public function setMaximumQps($maximumQps)
1370
+ {
1371
+ $this->maximumQps = $maximumQps;
1372
+ }
1373
+ public function getMaximumQps()
1374
+ {
1375
+ return $this->maximumQps;
1376
+ }
1377
+ public function setRegion($region)
1378
+ {
1379
+ $this->region = $region;
1380
+ }
1381
+ public function getRegion()
1382
+ {
1383
+ return $this->region;
1384
+ }
1385
+ public function setUrl($url)
1386
+ {
1387
+ $this->url = $url;
1388
+ }
1389
+ public function getUrl()
1390
+ {
1391
+ return $this->url;
1392
+ }
1393
+ }
1394
+
1395
+ class Google_Service_AdExchangeBuyer_AccountsList extends Google_Collection
1396
+ {
1397
+ protected $collection_key = 'items';
1398
+ protected $internal_gapi_mappings = array(
1399
+ );
1400
+ protected $itemsType = 'Google_Service_AdExchangeBuyer_Account';
1401
+ protected $itemsDataType = 'array';
1402
+ public $kind;
1403
+
1404
+
1405
+ public function setItems($items)
1406
+ {
1407
+ $this->items = $items;
1408
+ }
1409
+ public function getItems()
1410
+ {
1411
+ return $this->items;
1412
+ }
1413
+ public function setKind($kind)
1414
+ {
1415
+ $this->kind = $kind;
1416
+ }
1417
+ public function getKind()
1418
+ {
1419
+ return $this->kind;
1420
+ }
1421
+ }
1422
+
1423
+ class Google_Service_AdExchangeBuyer_AddOrderDealsRequest extends Google_Collection
1424
+ {
1425
+ protected $collection_key = 'deals';
1426
+ protected $internal_gapi_mappings = array(
1427
+ );
1428
+ protected $dealsType = 'Google_Service_AdExchangeBuyer_MarketplaceDeal';
1429
+ protected $dealsDataType = 'array';
1430
+ public $proposalRevisionNumber;
1431
+ public $updateAction;
1432
+
1433
+
1434
+ public function setDeals($deals)
1435
+ {
1436
+ $this->deals = $deals;
1437
+ }
1438
+ public function getDeals()
1439
+ {
1440
+ return $this->deals;
1441
+ }
1442
+ public function setProposalRevisionNumber($proposalRevisionNumber)
1443
+ {
1444
+ $this->proposalRevisionNumber = $proposalRevisionNumber;
1445
+ }
1446
+ public function getProposalRevisionNumber()
1447
+ {
1448
+ return $this->proposalRevisionNumber;
1449
+ }
1450
+ public function setUpdateAction($updateAction)
1451
+ {
1452
+ $this->updateAction = $updateAction;
1453
+ }
1454
+ public function getUpdateAction()
1455
+ {
1456
+ return $this->updateAction;
1457
+ }
1458
+ }
1459
+
1460
+ class Google_Service_AdExchangeBuyer_AddOrderDealsResponse extends Google_Collection
1461
+ {
1462
+ protected $collection_key = 'deals';
1463
+ protected $internal_gapi_mappings = array(
1464
+ );
1465
+ protected $dealsType = 'Google_Service_AdExchangeBuyer_MarketplaceDeal';
1466
+ protected $dealsDataType = 'array';
1467
+ public $proposalRevisionNumber;
1468
+
1469
+
1470
+ public function setDeals($deals)
1471
+ {
1472
+ $this->deals = $deals;
1473
+ }
1474
+ public function getDeals()
1475
+ {
1476
+ return $this->deals;
1477
+ }
1478
+ public function setProposalRevisionNumber($proposalRevisionNumber)
1479
+ {
1480
+ $this->proposalRevisionNumber = $proposalRevisionNumber;
1481
+ }
1482
+ public function getProposalRevisionNumber()
1483
+ {
1484
+ return $this->proposalRevisionNumber;
1485
+ }
1486
+ }
1487
+
1488
+ class Google_Service_AdExchangeBuyer_AddOrderNotesRequest extends Google_Collection
1489
+ {
1490
+ protected $collection_key = 'notes';
1491
+ protected $internal_gapi_mappings = array(
1492
+ );
1493
+ protected $notesType = 'Google_Service_AdExchangeBuyer_MarketplaceNote';
1494
+ protected $notesDataType = 'array';
1495
+
1496
+
1497
+ public function setNotes($notes)
1498
+ {
1499
+ $this->notes = $notes;
1500
+ }
1501
+ public function getNotes()
1502
+ {
1503
+ return $this->notes;
1504
+ }
1505
+ }
1506
+
1507
+ class Google_Service_AdExchangeBuyer_AddOrderNotesResponse extends Google_Collection
1508
+ {
1509
+ protected $collection_key = 'notes';
1510
+ protected $internal_gapi_mappings = array(
1511
+ );
1512
+ protected $notesType = 'Google_Service_AdExchangeBuyer_MarketplaceNote';
1513
+ protected $notesDataType = 'array';
1514
+
1515
+
1516
+ public function setNotes($notes)
1517
+ {
1518
+ $this->notes = $notes;
1519
+ }
1520
+ public function getNotes()
1521
+ {
1522
+ return $this->notes;
1523
+ }
1524
+ }
1525
+
1526
+ class Google_Service_AdExchangeBuyer_BillingInfo extends Google_Collection
1527
+ {
1528
+ protected $collection_key = 'billingId';
1529
+ protected $internal_gapi_mappings = array(
1530
+ );
1531
+ public $accountId;
1532
+ public $accountName;
1533
+ public $billingId;
1534
+ public $kind;
1535
+
1536
+
1537
+ public function setAccountId($accountId)
1538
+ {
1539
+ $this->accountId = $accountId;
1540
+ }
1541
+ public function getAccountId()
1542
+ {
1543
+ return $this->accountId;
1544
+ }
1545
+ public function setAccountName($accountName)
1546
+ {
1547
+ $this->accountName = $accountName;
1548
+ }
1549
+ public function getAccountName()
1550
+ {
1551
+ return $this->accountName;
1552
+ }
1553
+ public function setBillingId($billingId)
1554
+ {
1555
+ $this->billingId = $billingId;
1556
+ }
1557
+ public function getBillingId()
1558
+ {
1559
+ return $this->billingId;
1560
+ }
1561
+ public function setKind($kind)
1562
+ {
1563
+ $this->kind = $kind;
1564
+ }
1565
+ public function getKind()
1566
+ {
1567
+ return $this->kind;
1568
+ }
1569
+ }
1570
+
1571
+ class Google_Service_AdExchangeBuyer_BillingInfoList extends Google_Collection
1572
+ {
1573
+ protected $collection_key = 'items';
1574
+ protected $internal_gapi_mappings = array(
1575
+ );
1576
+ protected $itemsType = 'Google_Service_AdExchangeBuyer_BillingInfo';
1577
+ protected $itemsDataType = 'array';
1578
+ public $kind;
1579
+
1580
+
1581
+ public function setItems($items)
1582
+ {
1583
+ $this->items = $items;
1584
+ }
1585
+ public function getItems()
1586
+ {
1587
+ return $this->items;
1588
+ }
1589
+ public function setKind($kind)
1590
+ {
1591
+ $this->kind = $kind;
1592
+ }
1593
+ public function getKind()
1594
+ {
1595
+ return $this->kind;
1596
+ }
1597
+ }
1598
+
1599
+ class Google_Service_AdExchangeBuyer_Budget extends Google_Model
1600
+ {
1601
+ protected $internal_gapi_mappings = array(
1602
+ );
1603
+ public $accountId;
1604
+ public $billingId;
1605
+ public $budgetAmount;
1606
+ public $currencyCode;
1607
+ public $id;
1608
+ public $kind;
1609
+
1610
+
1611
+ public function setAccountId($accountId)
1612
+ {
1613
+ $this->accountId = $accountId;
1614
+ }
1615
+ public function getAccountId()
1616
+ {
1617
+ return $this->accountId;
1618
+ }
1619
+ public function setBillingId($billingId)
1620
+ {
1621
+ $this->billingId = $billingId;
1622
+ }
1623
+ public function getBillingId()
1624
+ {
1625
+ return $this->billingId;
1626
+ }
1627
+ public function setBudgetAmount($budgetAmount)
1628
+ {
1629
+ $this->budgetAmount = $budgetAmount;
1630
+ }
1631
+ public function getBudgetAmount()
1632
+ {
1633
+ return $this->budgetAmount;
1634
+ }
1635
+ public function setCurrencyCode($currencyCode)
1636
+ {
1637
+ $this->currencyCode = $currencyCode;
1638
+ }
1639
+ public function getCurrencyCode()
1640
+ {
1641
+ return $this->currencyCode;
1642
+ }
1643
+ public function setId($id)
1644
+ {
1645
+ $this->id = $id;
1646
+ }
1647
+ public function getId()
1648
+ {
1649
+ return $this->id;
1650
+ }
1651
+ public function setKind($kind)
1652
+ {
1653
+ $this->kind = $kind;
1654
+ }
1655
+ public function getKind()
1656
+ {
1657
+ return $this->kind;
1658
+ }
1659
+ }
1660
+
1661
+ class Google_Service_AdExchangeBuyer_Buyer extends Google_Model
1662
+ {
1663
+ protected $internal_gapi_mappings = array(
1664
+ );
1665
+ public $accountId;
1666
+
1667
+
1668
+ public function setAccountId($accountId)
1669
+ {
1670
+ $this->accountId = $accountId;
1671
+ }
1672
+ public function getAccountId()
1673
+ {
1674
+ return $this->accountId;
1675
+ }
1676
+ }
1677
+
1678
+ class Google_Service_AdExchangeBuyer_ContactInformation extends Google_Model
1679
+ {
1680
+ protected $internal_gapi_mappings = array(
1681
+ );
1682
+ public $email;
1683
+ public $name;
1684
+
1685
+
1686
+ public function setEmail($email)
1687
+ {
1688
+ $this->email = $email;
1689
+ }
1690
+ public function getEmail()
1691
+ {
1692
+ return $this->email;
1693
+ }
1694
+ public function setName($name)
1695
+ {
1696
+ $this->name = $name;
1697
+ }
1698
+ public function getName()
1699
+ {
1700
+ return $this->name;
1701
+ }
1702
+ }
1703
+
1704
+ class Google_Service_AdExchangeBuyer_CreateOrdersRequest extends Google_Collection
1705
+ {
1706
+ protected $collection_key = 'proposals';
1707
+ protected $internal_gapi_mappings = array(
1708
+ );
1709
+ protected $proposalsType = 'Google_Service_AdExchangeBuyer_Proposal';
1710
+ protected $proposalsDataType = 'array';
1711
+ public $webPropertyCode;
1712
+
1713
+
1714
+ public function setProposals($proposals)
1715
+ {
1716
+ $this->proposals = $proposals;
1717
+ }
1718
+ public function getProposals()
1719
+ {
1720
+ return $this->proposals;
1721
+ }
1722
+ public function setWebPropertyCode($webPropertyCode)
1723
+ {
1724
+ $this->webPropertyCode = $webPropertyCode;
1725
+ }
1726
+ public function getWebPropertyCode()
1727
+ {
1728
+ return $this->webPropertyCode;
1729
+ }
1730
+ }
1731
+
1732
+ class Google_Service_AdExchangeBuyer_CreateOrdersResponse extends Google_Collection
1733
+ {
1734
+ protected $collection_key = 'proposals';
1735
+ protected $internal_gapi_mappings = array(
1736
+ );
1737
+ protected $proposalsType = 'Google_Service_AdExchangeBuyer_Proposal';
1738
+ protected $proposalsDataType = 'array';
1739
+
1740
+
1741
+ public function setProposals($proposals)
1742
+ {
1743
+ $this->proposals = $proposals;
1744
+ }
1745
+ public function getProposals()
1746
+ {
1747
+ return $this->proposals;
1748
+ }
1749
+ }
1750
+
1751
+ class Google_Service_AdExchangeBuyer_Creative extends Google_Collection
1752
+ {
1753
+ protected $collection_key = 'vendorType';
1754
+ protected $internal_gapi_mappings = array(
1755
+ "hTMLSnippet" => "HTMLSnippet",
1756
+ );
1757
+ public $hTMLSnippet;
1758
+ public $accountId;
1759
+ public $advertiserId;
1760
+ public $advertiserName;
1761
+ public $agencyId;
1762
+ public $apiUploadTimestamp;
1763
+ public $attribute;
1764
+ public $buyerCreativeId;
1765
+ public $clickThroughUrl;
1766
+ protected $correctionsType = 'Google_Service_AdExchangeBuyer_CreativeCorrections';
1767
+ protected $correctionsDataType = 'array';
1768
+ public $dealsStatus;
1769
+ protected $filteringReasonsType = 'Google_Service_AdExchangeBuyer_CreativeFilteringReasons';
1770
+ protected $filteringReasonsDataType = '';
1771
+ public $height;
1772
+ public $impressionTrackingUrl;
1773
+ public $kind;
1774
+ protected $nativeAdType = 'Google_Service_AdExchangeBuyer_CreativeNativeAd';
1775
+ protected $nativeAdDataType = '';
1776
+ public $openAuctionStatus;
1777
+ public $productCategories;
1778
+ public $restrictedCategories;
1779
+ public $sensitiveCategories;
1780
+ protected $servingRestrictionsType = 'Google_Service_AdExchangeBuyer_CreativeServingRestrictions';
1781
+ protected $servingRestrictionsDataType = 'array';
1782
+ public $vendorType;
1783
+ public $version;
1784
+ public $videoURL;
1785
+ public $width;
1786
+
1787
+
1788
+ public function setHTMLSnippet($hTMLSnippet)
1789
+ {
1790
+ $this->hTMLSnippet = $hTMLSnippet;
1791
+ }
1792
+ public function getHTMLSnippet()
1793
+ {
1794
+ return $this->hTMLSnippet;
1795
+ }
1796
+ public function setAccountId($accountId)
1797
+ {
1798
+ $this->accountId = $accountId;
1799
+ }
1800
+ public function getAccountId()
1801
+ {
1802
+ return $this->accountId;
1803
+ }
1804
+ public function setAdvertiserId($advertiserId)
1805
+ {
1806
+ $this->advertiserId = $advertiserId;
1807
+ }
1808
+ public function getAdvertiserId()
1809
+ {
1810
+ return $this->advertiserId;
1811
+ }
1812
+ public function setAdvertiserName($advertiserName)
1813
+ {
1814
+ $this->advertiserName = $advertiserName;
1815
+ }
1816
+ public function getAdvertiserName()
1817
+ {
1818
+ return $this->advertiserName;
1819
+ }
1820
+ public function setAgencyId($agencyId)
1821
+ {
1822
+ $this->agencyId = $agencyId;
1823
+ }
1824
+ public function getAgencyId()
1825
+ {
1826
+ return $this->agencyId;
1827
+ }
1828
+ public function setApiUploadTimestamp($apiUploadTimestamp)
1829
+ {
1830
+ $this->apiUploadTimestamp = $apiUploadTimestamp;
1831
+ }
1832
+ public function getApiUploadTimestamp()
1833
+ {
1834
+ return $this->apiUploadTimestamp;
1835
+ }
1836
+ public function setAttribute($attribute)
1837
+ {
1838
+ $this->attribute = $attribute;
1839
+ }
1840
+ public function getAttribute()
1841
+ {
1842
+ return $this->attribute;
1843
+ }
1844
+ public function setBuyerCreativeId($buyerCreativeId)
1845
+ {
1846
+ $this->buyerCreativeId = $buyerCreativeId;
1847
+ }
1848
+ public function getBuyerCreativeId()
1849
+ {
1850
+ return $this->buyerCreativeId;
1851
+ }
1852
+ public function setClickThroughUrl($clickThroughUrl)
1853
+ {
1854
+ $this->clickThroughUrl = $clickThroughUrl;
1855
+ }
1856
+ public function getClickThroughUrl()
1857
+ {
1858
+ return $this->clickThroughUrl;
1859
+ }
1860
+ public function setCorrections($corrections)
1861
+ {
1862
+ $this->corrections = $corrections;
1863
+ }
1864
+ public function getCorrections()
1865
+ {
1866
+ return $this->corrections;
1867
+ }
1868
+ public function setDealsStatus($dealsStatus)
1869
+ {
1870
+ $this->dealsStatus = $dealsStatus;
1871
+ }
1872
+ public function getDealsStatus()
1873
+ {
1874
+ return $this->dealsStatus;
1875
+ }
1876
+ public function setFilteringReasons(Google_Service_AdExchangeBuyer_CreativeFilteringReasons $filteringReasons)
1877
+ {
1878
+ $this->filteringReasons = $filteringReasons;
1879
+ }
1880
+ public function getFilteringReasons()
1881
+ {
1882
+ return $this->filteringReasons;
1883
+ }
1884
+ public function setHeight($height)
1885
+ {
1886
+ $this->height = $height;
1887
+ }
1888
+ public function getHeight()
1889
+ {
1890
+ return $this->height;
1891
+ }
1892
+ public function setImpressionTrackingUrl($impressionTrackingUrl)
1893
+ {
1894
+ $this->impressionTrackingUrl = $impressionTrackingUrl;
1895
+ }
1896
+ public function getImpressionTrackingUrl()
1897
+ {
1898
+ return $this->impressionTrackingUrl;
1899
+ }
1900
+ public function setKind($kind)
1901
+ {
1902
+ $this->kind = $kind;
1903
+ }
1904
+ public function getKind()
1905
+ {
1906
+ return $this->kind;
1907
+ }
1908
+ public function setNativeAd(Google_Service_AdExchangeBuyer_CreativeNativeAd $nativeAd)
1909
+ {
1910
+ $this->nativeAd = $nativeAd;
1911
+ }
1912
+ public function getNativeAd()
1913
+ {
1914
+ return $this->nativeAd;
1915
+ }
1916
+ public function setOpenAuctionStatus($openAuctionStatus)
1917
+ {
1918
+ $this->openAuctionStatus = $openAuctionStatus;
1919
+ }
1920
+ public function getOpenAuctionStatus()
1921
+ {
1922
+ return $this->openAuctionStatus;
1923
+ }
1924
+ public function setProductCategories($productCategories)
1925
+ {
1926
+ $this->productCategories = $productCategories;
1927
+ }
1928
+ public function getProductCategories()
1929
+ {
1930
+ return $this->productCategories;
1931
+ }
1932
+ public function setRestrictedCategories($restrictedCategories)
1933
+ {
1934
+ $this->restrictedCategories = $restrictedCategories;
1935
+ }
1936
+ public function getRestrictedCategories()
1937
+ {
1938
+ return $this->restrictedCategories;
1939
+ }
1940
+ public function setSensitiveCategories($sensitiveCategories)
1941
+ {
1942
+ $this->sensitiveCategories = $sensitiveCategories;
1943
+ }
1944
+ public function getSensitiveCategories()
1945
+ {
1946
+ return $this->sensitiveCategories;
1947
+ }
1948
+ public function setServingRestrictions($servingRestrictions)
1949
+ {
1950
+ $this->servingRestrictions = $servingRestrictions;
1951
+ }
1952
+ public function getServingRestrictions()
1953
+ {
1954
+ return $this->servingRestrictions;
1955
+ }
1956
+ public function setVendorType($vendorType)
1957
+ {
1958
+ $this->vendorType = $vendorType;
1959
+ }
1960
+ public function getVendorType()
1961
+ {
1962
+ return $this->vendorType;
1963
+ }
1964
+ public function setVersion($version)
1965
+ {
1966
+ $this->version = $version;
1967
+ }
1968
+ public function getVersion()
1969
+ {
1970
+ return $this->version;
1971
+ }
1972
+ public function setVideoURL($videoURL)
1973
+ {
1974
+ $this->videoURL = $videoURL;
1975
+ }
1976
+ public function getVideoURL()
1977
+ {
1978
+ return $this->videoURL;
1979
+ }
1980
+ public function setWidth($width)
1981
+ {
1982
+ $this->width = $width;
1983
+ }
1984
+ public function getWidth()
1985
+ {
1986
+ return $this->width;
1987
+ }
1988
+ }
1989
+
1990
+ class Google_Service_AdExchangeBuyer_CreativeCorrections extends Google_Collection
1991
+ {
1992
+ protected $collection_key = 'details';
1993
+ protected $internal_gapi_mappings = array(
1994
+ );
1995
+ public $details;
1996
+ public $reason;
1997
+
1998
+
1999
+ public function setDetails($details)
2000
+ {
2001
+ $this->details = $details;
2002
+ }
2003
+ public function getDetails()
2004
+ {
2005
+ return $this->details;
2006
+ }
2007
+ public function setReason($reason)
2008
+ {
2009
+ $this->reason = $reason;
2010
+ }
2011
+ public function getReason()
2012
+ {
2013
+ return $this->reason;
2014
+ }
2015
+ }
2016
+
2017
+ class Google_Service_AdExchangeBuyer_CreativeFilteringReasons extends Google_Collection
2018
+ {
2019
+ protected $collection_key = 'reasons';
2020
+ protected $internal_gapi_mappings = array(
2021
+ );
2022
+ public $date;
2023
+ protected $reasonsType = 'Google_Service_AdExchangeBuyer_CreativeFilteringReasonsReasons';
2024
+ protected $reasonsDataType = 'array';
2025
+
2026
+
2027
+ public function setDate($date)
2028
+ {
2029
+ $this->date = $date;
2030
+ }
2031
+ public function getDate()
2032
+ {
2033
+ return $this->date;
2034
+ }
2035
+ public function setReasons($reasons)
2036
+ {
2037
+ $this->reasons = $reasons;
2038
+ }
2039
+ public function getReasons()
2040
+ {
2041
+ return $this->reasons;
2042
+ }
2043
+ }
2044
+
2045
+ class Google_Service_AdExchangeBuyer_CreativeFilteringReasonsReasons extends Google_Model
2046
+ {
2047
+ protected $internal_gapi_mappings = array(
2048
+ );
2049
+ public $filteringCount;
2050
+ public $filteringStatus;
2051
+
2052
+
2053
+ public function setFilteringCount($filteringCount)
2054
+ {
2055
+ $this->filteringCount = $filteringCount;
2056
+ }
2057
+ public function getFilteringCount()
2058
+ {
2059
+ return $this->filteringCount;
2060
+ }
2061
+ public function setFilteringStatus($filteringStatus)
2062
+ {
2063
+ $this->filteringStatus = $filteringStatus;
2064
+ }
2065
+ public function getFilteringStatus()
2066
+ {
2067
+ return $this->filteringStatus;
2068
+ }
2069
+ }
2070
+
2071
+ class Google_Service_AdExchangeBuyer_CreativeNativeAd extends Google_Collection
2072
+ {
2073
+ protected $collection_key = 'impressionTrackingUrl';
2074
+ protected $internal_gapi_mappings = array(
2075
+ );
2076
+ public $advertiser;
2077
+ protected $appIconType = 'Google_Service_AdExchangeBuyer_CreativeNativeAdAppIcon';
2078
+ protected $appIconDataType = '';
2079
+ public $body;
2080
+ public $callToAction;
2081
+ public $clickTrackingUrl;
2082
+ public $headline;
2083
+ protected $imageType = 'Google_Service_AdExchangeBuyer_CreativeNativeAdImage';
2084
+ protected $imageDataType = '';
2085
+ public $impressionTrackingUrl;
2086
+ protected $logoType = 'Google_Service_AdExchangeBuyer_CreativeNativeAdLogo';
2087
+ protected $logoDataType = '';
2088
+ public $price;
2089
+ public $starRating;
2090
+ public $store;
2091
+
2092
+
2093
+ public function setAdvertiser($advertiser)
2094
+ {
2095
+ $this->advertiser = $advertiser;
2096
+ }
2097
+ public function getAdvertiser()
2098
+ {
2099
+ return $this->advertiser;
2100
+ }
2101
+ public function setAppIcon(Google_Service_AdExchangeBuyer_CreativeNativeAdAppIcon $appIcon)
2102
+ {
2103
+ $this->appIcon = $appIcon;
2104
+ }
2105
+ public function getAppIcon()
2106
+ {
2107
+ return $this->appIcon;
2108
+ }
2109
+ public function setBody($body)
2110
+ {
2111
+ $this->body = $body;
2112
+ }
2113
+ public function getBody()
2114
+ {
2115
+ return $this->body;
2116
+ }
2117
+ public function setCallToAction($callToAction)
2118
+ {
2119
+ $this->callToAction = $callToAction;
2120
+ }
2121
+ public function getCallToAction()
2122
+ {
2123
+ return $this->callToAction;
2124
+ }
2125
+ public function setClickTrackingUrl($clickTrackingUrl)
2126
+ {
2127
+ $this->clickTrackingUrl = $clickTrackingUrl;
2128
+ }
2129
+ public function getClickTrackingUrl()
2130
+ {
2131
+ return $this->clickTrackingUrl;
2132
+ }
2133
+ public function setHeadline($headline)
2134
+ {
2135
+ $this->headline = $headline;
2136
+ }
2137
+ public function getHeadline()
2138
+ {
2139
+ return $this->headline;
2140
+ }
2141
+ public function setImage(Google_Service_AdExchangeBuyer_CreativeNativeAdImage $image)
2142
+ {
2143
+ $this->image = $image;
2144
+ }
2145
+ public function getImage()
2146
+ {
2147
+ return $this->image;
2148
+ }
2149
+ public function setImpressionTrackingUrl($impressionTrackingUrl)
2150
+ {
2151
+ $this->impressionTrackingUrl = $impressionTrackingUrl;
2152
+ }
2153
+ public function getImpressionTrackingUrl()
2154
+ {
2155
+ return $this->impressionTrackingUrl;
2156
+ }
2157
+ public function setLogo(Google_Service_AdExchangeBuyer_CreativeNativeAdLogo $logo)
2158
+ {
2159
+ $this->logo = $logo;
2160
+ }
2161
+ public function getLogo()
2162
+ {
2163
+ return $this->logo;
2164
+ }
2165
+ public function setPrice($price)
2166
+ {
2167
+ $this->price = $price;
2168
+ }
2169
+ public function getPrice()
2170
+ {
2171
+ return $this->price;
2172
+ }
2173
+ public function setStarRating($starRating)
2174
+ {
2175
+ $this->starRating = $starRating;
2176
+ }
2177
+ public function getStarRating()
2178
+ {
2179
+ return $this->starRating;
2180
+ }
2181
+ public function setStore($store)
2182
+ {
2183
+ $this->store = $store;
2184
+ }
2185
+ public function getStore()
2186
+ {
2187
+ return $this->store;
2188
+ }
2189
+ }
2190
+
2191
+ class Google_Service_AdExchangeBuyer_CreativeNativeAdAppIcon extends Google_Model
2192
+ {
2193
+ protected $internal_gapi_mappings = array(
2194
+ );
2195
+ public $height;
2196
+ public $url;
2197
+ public $width;
2198
+
2199
+
2200
+ public function setHeight($height)
2201
+ {
2202
+ $this->height = $height;
2203
+ }
2204
+ public function getHeight()
2205
+ {
2206
+ return $this->height;
2207
+ }
2208
+ public function setUrl($url)
2209
+ {
2210
+ $this->url = $url;
2211
+ }
2212
+ public function getUrl()
2213
+ {
2214
+ return $this->url;
2215
+ }
2216
+ public function setWidth($width)
2217
+ {
2218
+ $this->width = $width;
2219
+ }
2220
+ public function getWidth()
2221
+ {
2222
+ return $this->width;
2223
+ }
2224
+ }
2225
+
2226
+ class Google_Service_AdExchangeBuyer_CreativeNativeAdImage extends Google_Model
2227
+ {
2228
+ protected $internal_gapi_mappings = array(
2229
+ );
2230
+ public $height;
2231
+ public $url;
2232
+ public $width;
2233
+
2234
+
2235
+ public function setHeight($height)
2236
+ {
2237
+ $this->height = $height;
2238
+ }
2239
+ public function getHeight()
2240
+ {
2241
+ return $this->height;
2242
+ }
2243
+ public function setUrl($url)
2244
+ {
2245
+ $this->url = $url;
2246
+ }
2247
+ public function getUrl()
2248
+ {
2249
+ return $this->url;
2250
+ }
2251
+ public function setWidth($width)
2252
+ {
2253
+ $this->width = $width;
2254
+ }
2255
+ public function getWidth()
2256
+ {
2257
+ return $this->width;
2258
+ }
2259
+ }
2260
+
2261
+ class Google_Service_AdExchangeBuyer_CreativeNativeAdLogo extends Google_Model
2262
+ {
2263
+ protected $internal_gapi_mappings = array(
2264
+ );
2265
+ public $height;
2266
+ public $url;
2267
+ public $width;
2268
+
2269
+
2270
+ public function setHeight($height)
2271
+ {
2272
+ $this->height = $height;
2273
+ }
2274
+ public function getHeight()
2275
+ {
2276
+ return $this->height;
2277
+ }
2278
+ public function setUrl($url)
2279
+ {
2280
+ $this->url = $url;
2281
+ }
2282
+ public function getUrl()
2283
+ {
2284
+ return $this->url;
2285
+ }
2286
+ public function setWidth($width)
2287
+ {
2288
+ $this->width = $width;
2289
+ }
2290
+ public function getWidth()
2291
+ {
2292
+ return $this->width;
2293
+ }
2294
+ }
2295
+
2296
+ class Google_Service_AdExchangeBuyer_CreativeServingRestrictions extends Google_Collection
2297
+ {
2298
+ protected $collection_key = 'disapprovalReasons';
2299
+ protected $internal_gapi_mappings = array(
2300
+ );
2301
+ protected $contextsType = 'Google_Service_AdExchangeBuyer_CreativeServingRestrictionsContexts';
2302
+ protected $contextsDataType = 'array';
2303
+ protected $disapprovalReasonsType = 'Google_Service_AdExchangeBuyer_CreativeServingRestrictionsDisapprovalReasons';
2304
+ protected $disapprovalReasonsDataType = 'array';
2305
+ public $reason;
2306
+
2307
+
2308
+ public function setContexts($contexts)
2309
+ {
2310
+ $this->contexts = $contexts;
2311
+ }
2312
+ public function getContexts()
2313
+ {
2314
+ return $this->contexts;
2315
+ }
2316
+ public function setDisapprovalReasons($disapprovalReasons)
2317
+ {
2318
+ $this->disapprovalReasons = $disapprovalReasons;
2319
+ }
2320
+ public function getDisapprovalReasons()
2321
+ {
2322
+ return $this->disapprovalReasons;
2323
+ }
2324
+ public function setReason($reason)
2325
+ {
2326
+ $this->reason = $reason;
2327
+ }
2328
+ public function getReason()
2329
+ {
2330
+ return $this->reason;
2331
+ }
2332
+ }
2333
+
2334
+ class Google_Service_AdExchangeBuyer_CreativeServingRestrictionsContexts extends Google_Collection
2335
+ {
2336
+ protected $collection_key = 'platform';
2337
+ protected $internal_gapi_mappings = array(
2338
+ );
2339
+ public $auctionType;
2340
+ public $contextType;
2341
+ public $geoCriteriaId;
2342
+ public $platform;
2343
+
2344
+
2345
+ public function setAuctionType($auctionType)
2346
+ {
2347
+ $this->auctionType = $auctionType;
2348
+ }
2349
+ public function getAuctionType()
2350
+ {
2351
+ return $this->auctionType;
2352
+ }
2353
+ public function setContextType($contextType)
2354
+ {
2355
+ $this->contextType = $contextType;
2356
+ }
2357
+ public function getContextType()
2358
+ {
2359
+ return $this->contextType;
2360
+ }
2361
+ public function setGeoCriteriaId($geoCriteriaId)
2362
+ {
2363
+ $this->geoCriteriaId = $geoCriteriaId;
2364
+ }
2365
+ public function getGeoCriteriaId()
2366
+ {
2367
+ return $this->geoCriteriaId;
2368
+ }
2369
+ public function setPlatform($platform)
2370
+ {
2371
+ $this->platform = $platform;
2372
+ }
2373
+ public function getPlatform()
2374
+ {
2375
+ return $this->platform;
2376
+ }
2377
+ }
2378
+
2379
+ class Google_Service_AdExchangeBuyer_CreativeServingRestrictionsDisapprovalReasons extends Google_Collection
2380
+ {
2381
+ protected $collection_key = 'details';
2382
+ protected $internal_gapi_mappings = array(
2383
+ );
2384
+ public $details;
2385
+ public $reason;
2386
+
2387
+
2388
+ public function setDetails($details)
2389
+ {
2390
+ $this->details = $details;
2391
+ }
2392
+ public function getDetails()
2393
+ {
2394
+ return $this->details;
2395
+ }
2396
+ public function setReason($reason)
2397
+ {
2398
+ $this->reason = $reason;
2399
+ }
2400
+ public function getReason()
2401
+ {
2402
+ return $this->reason;
2403
+ }
2404
+ }
2405
+
2406
+ class Google_Service_AdExchangeBuyer_CreativesList extends Google_Collection
2407
+ {
2408
+ protected $collection_key = 'items';
2409
+ protected $internal_gapi_mappings = array(
2410
+ );
2411
+ protected $itemsType = 'Google_Service_AdExchangeBuyer_Creative';
2412
+ protected $itemsDataType = 'array';
2413
+ public $kind;
2414
+ public $nextPageToken;
2415
+
2416
+
2417
+ public function setItems($items)
2418
+ {
2419
+ $this->items = $items;
2420
+ }
2421
+ public function getItems()
2422
+ {
2423
+ return $this->items;
2424
+ }
2425
+ public function setKind($kind)
2426
+ {
2427
+ $this->kind = $kind;
2428
+ }
2429
+ public function getKind()
2430
+ {
2431
+ return $this->kind;
2432
+ }
2433
+ public function setNextPageToken($nextPageToken)
2434
+ {
2435
+ $this->nextPageToken = $nextPageToken;
2436
+ }
2437
+ public function getNextPageToken()
2438
+ {
2439
+ return $this->nextPageToken;
2440
+ }
2441
+ }
2442
+
2443
+ class Google_Service_AdExchangeBuyer_DealTerms extends Google_Model
2444
+ {
2445
+ protected $internal_gapi_mappings = array(
2446
+ );
2447
+ public $brandingType;
2448
+ public $description;
2449
+ protected $estimatedGrossSpendType = 'Google_Service_AdExchangeBuyer_Price';
2450
+ protected $estimatedGrossSpendDataType = '';
2451
+ public $estimatedImpressionsPerDay;
2452
+ protected $guaranteedFixedPriceTermsType = 'Google_Service_AdExchangeBuyer_DealTermsGuaranteedFixedPriceTerms';
2453
+ protected $guaranteedFixedPriceTermsDataType = '';
2454
+ protected $nonGuaranteedAuctionTermsType = 'Google_Service_AdExchangeBuyer_DealTermsNonGuaranteedAuctionTerms';
2455
+ protected $nonGuaranteedAuctionTermsDataType = '';
2456
+ protected $nonGuaranteedFixedPriceTermsType = 'Google_Service_AdExchangeBuyer_DealTermsNonGuaranteedFixedPriceTerms';
2457
+ protected $nonGuaranteedFixedPriceTermsDataType = '';
2458
+
2459
+
2460
+ public function setBrandingType($brandingType)
2461
+ {
2462
+ $this->brandingType = $brandingType;
2463
+ }
2464
+ public function getBrandingType()
2465
+ {
2466
+ return $this->brandingType;
2467
+ }
2468
+ public function setDescription($description)
2469
+ {
2470
+ $this->description = $description;
2471
+ }
2472
+ public function getDescription()
2473
+ {
2474
+ return $this->description;
2475
+ }
2476
+ public function setEstimatedGrossSpend(Google_Service_AdExchangeBuyer_Price $estimatedGrossSpend)
2477
+ {
2478
+ $this->estimatedGrossSpend = $estimatedGrossSpend;
2479
+ }
2480
+ public function getEstimatedGrossSpend()
2481
+ {
2482
+ return $this->estimatedGrossSpend;
2483
+ }
2484
+ public function setEstimatedImpressionsPerDay($estimatedImpressionsPerDay)
2485
+ {
2486
+ $this->estimatedImpressionsPerDay = $estimatedImpressionsPerDay;
2487
+ }
2488
+ public function getEstimatedImpressionsPerDay()
2489
+ {
2490
+ return $this->estimatedImpressionsPerDay;
2491
+ }
2492
+ public function setGuaranteedFixedPriceTerms(Google_Service_AdExchangeBuyer_DealTermsGuaranteedFixedPriceTerms $guaranteedFixedPriceTerms)
2493
+ {
2494
+ $this->guaranteedFixedPriceTerms = $guaranteedFixedPriceTerms;
2495
+ }
2496
+ public function getGuaranteedFixedPriceTerms()
2497
+ {
2498
+ return $this->guaranteedFixedPriceTerms;
2499
+ }
2500
+ public function setNonGuaranteedAuctionTerms(Google_Service_AdExchangeBuyer_DealTermsNonGuaranteedAuctionTerms $nonGuaranteedAuctionTerms)
2501
+ {
2502
+ $this->nonGuaranteedAuctionTerms = $nonGuaranteedAuctionTerms;
2503
+ }
2504
+ public function getNonGuaranteedAuctionTerms()
2505
+ {
2506
+ return $this->nonGuaranteedAuctionTerms;
2507
+ }
2508
+ public function setNonGuaranteedFixedPriceTerms(Google_Service_AdExchangeBuyer_DealTermsNonGuaranteedFixedPriceTerms $nonGuaranteedFixedPriceTerms)
2509
+ {
2510
+ $this->nonGuaranteedFixedPriceTerms = $nonGuaranteedFixedPriceTerms;
2511
+ }
2512
+ public function getNonGuaranteedFixedPriceTerms()
2513
+ {
2514
+ return $this->nonGuaranteedFixedPriceTerms;
2515
+ }
2516
+ }
2517
+
2518
+ class Google_Service_AdExchangeBuyer_DealTermsGuaranteedFixedPriceTerms extends Google_Collection
2519
+ {
2520
+ protected $collection_key = 'fixedPrices';
2521
+ protected $internal_gapi_mappings = array(
2522
+ );
2523
+ protected $fixedPricesType = 'Google_Service_AdExchangeBuyer_PricePerBuyer';
2524
+ protected $fixedPricesDataType = 'array';
2525
+ public $guaranteedImpressions;
2526
+ public $guaranteedLooks;
2527
+
2528
+
2529
+ public function setFixedPrices($fixedPrices)
2530
+ {
2531
+ $this->fixedPrices = $fixedPrices;
2532
+ }
2533
+ public function getFixedPrices()
2534
+ {
2535
+ return $this->fixedPrices;
2536
+ }
2537
+ public function setGuaranteedImpressions($guaranteedImpressions)
2538
+ {
2539
+ $this->guaranteedImpressions = $guaranteedImpressions;
2540
+ }
2541
+ public function getGuaranteedImpressions()
2542
+ {
2543
+ return $this->guaranteedImpressions;
2544
+ }
2545
+ public function setGuaranteedLooks($guaranteedLooks)
2546
+ {
2547
+ $this->guaranteedLooks = $guaranteedLooks;
2548
+ }
2549
+ public function getGuaranteedLooks()
2550
+ {
2551
+ return $this->guaranteedLooks;
2552
+ }
2553
+ }
2554
+
2555
+ class Google_Service_AdExchangeBuyer_DealTermsNonGuaranteedAuctionTerms extends Google_Collection
2556
+ {
2557
+ protected $collection_key = 'reservePricePerBuyers';
2558
+ protected $internal_gapi_mappings = array(
2559
+ );
2560
+ public $privateAuctionId;
2561
+ protected $reservePricePerBuyersType = 'Google_Service_AdExchangeBuyer_PricePerBuyer';
2562
+ protected $reservePricePerBuyersDataType = 'array';
2563
+
2564
+
2565
+ public function setPrivateAuctionId($privateAuctionId)
2566
+ {
2567
+ $this->privateAuctionId = $privateAuctionId;
2568
+ }
2569
+ public function getPrivateAuctionId()
2570
+ {
2571
+ return $this->privateAuctionId;
2572
+ }
2573
+ public function setReservePricePerBuyers($reservePricePerBuyers)
2574
+ {
2575
+ $this->reservePricePerBuyers = $reservePricePerBuyers;
2576
+ }
2577
+ public function getReservePricePerBuyers()
2578
+ {
2579
+ return $this->reservePricePerBuyers;
2580
+ }
2581
+ }
2582
+
2583
+ class Google_Service_AdExchangeBuyer_DealTermsNonGuaranteedFixedPriceTerms extends Google_Collection
2584
+ {
2585
+ protected $collection_key = 'fixedPrices';
2586
+ protected $internal_gapi_mappings = array(
2587
+ );
2588
+ protected $fixedPricesType = 'Google_Service_AdExchangeBuyer_PricePerBuyer';
2589
+ protected $fixedPricesDataType = 'array';
2590
+
2591
+
2592
+ public function setFixedPrices($fixedPrices)
2593
+ {
2594
+ $this->fixedPrices = $fixedPrices;
2595
+ }
2596
+ public function getFixedPrices()
2597
+ {
2598
+ return $this->fixedPrices;
2599
+ }
2600
+ }
2601
+
2602
+ class Google_Service_AdExchangeBuyer_DeleteOrderDealsRequest extends Google_Collection
2603
+ {
2604
+ protected $collection_key = 'dealIds';
2605
+ protected $internal_gapi_mappings = array(
2606
+ );
2607
+ public $dealIds;
2608
+ public $proposalRevisionNumber;
2609
+ public $updateAction;
2610
+
2611
+
2612
+ public function setDealIds($dealIds)
2613
+ {
2614
+ $this->dealIds = $dealIds;
2615
+ }
2616
+ public function getDealIds()
2617
+ {
2618
+ return $this->dealIds;
2619
+ }
2620
+ public function setProposalRevisionNumber($proposalRevisionNumber)
2621
+ {
2622
+ $this->proposalRevisionNumber = $proposalRevisionNumber;
2623
+ }
2624
+ public function getProposalRevisionNumber()
2625
+ {
2626
+ return $this->proposalRevisionNumber;
2627
+ }
2628
+ public function setUpdateAction($updateAction)
2629
+ {
2630
+ $this->updateAction = $updateAction;
2631
+ }
2632
+ public function getUpdateAction()
2633
+ {
2634
+ return $this->updateAction;
2635
+ }
2636
+ }
2637
+
2638
+ class Google_Service_AdExchangeBuyer_DeleteOrderDealsResponse extends Google_Collection
2639
+ {
2640
+ protected $collection_key = 'deals';
2641
+ protected $internal_gapi_mappings = array(
2642
+ );
2643
+ protected $dealsType = 'Google_Service_AdExchangeBuyer_MarketplaceDeal';
2644
+ protected $dealsDataType = 'array';
2645
+ public $proposalRevisionNumber;
2646
+
2647
+
2648
+ public function setDeals($deals)
2649
+ {
2650
+ $this->deals = $deals;
2651
+ }
2652
+ public function getDeals()
2653
+ {
2654
+ return $this->deals;
2655
+ }
2656
+ public function setProposalRevisionNumber($proposalRevisionNumber)
2657
+ {
2658
+ $this->proposalRevisionNumber = $proposalRevisionNumber;
2659
+ }
2660
+ public function getProposalRevisionNumber()
2661
+ {
2662
+ return $this->proposalRevisionNumber;
2663
+ }
2664
+ }
2665
+
2666
+ class Google_Service_AdExchangeBuyer_DeliveryControl extends Google_Collection
2667
+ {
2668
+ protected $collection_key = 'frequencyCaps';
2669
+ protected $internal_gapi_mappings = array(
2670
+ );
2671
+ public $creativeBlockingLevel;
2672
+ public $deliveryRateType;
2673
+ protected $frequencyCapsType = 'Google_Service_AdExchangeBuyer_DeliveryControlFrequencyCap';
2674
+ protected $frequencyCapsDataType = 'array';
2675
+
2676
+
2677
+ public function setCreativeBlockingLevel($creativeBlockingLevel)
2678
+ {
2679
+ $this->creativeBlockingLevel = $creativeBlockingLevel;
2680
+ }
2681
+ public function getCreativeBlockingLevel()
2682
+ {
2683
+ return $this->creativeBlockingLevel;
2684
+ }
2685
+ public function setDeliveryRateType($deliveryRateType)
2686
+ {
2687
+ $this->deliveryRateType = $deliveryRateType;
2688
+ }
2689
+ public function getDeliveryRateType()
2690
+ {
2691
+ return $this->deliveryRateType;
2692
+ }
2693
+ public function setFrequencyCaps($frequencyCaps)
2694
+ {
2695
+ $this->frequencyCaps = $frequencyCaps;
2696
+ }
2697
+ public function getFrequencyCaps()
2698
+ {
2699
+ return $this->frequencyCaps;
2700
+ }
2701
+ }
2702
+
2703
+ class Google_Service_AdExchangeBuyer_DeliveryControlFrequencyCap extends Google_Model
2704
+ {
2705
+ protected $internal_gapi_mappings = array(
2706
+ );
2707
+ public $maxImpressions;
2708
+ public $numTimeUnits;
2709
+ public $timeUnitType;
2710
+
2711
+
2712
+ public function setMaxImpressions($maxImpressions)
2713
+ {
2714
+ $this->maxImpressions = $maxImpressions;
2715
+ }
2716
+ public function getMaxImpressions()
2717
+ {
2718
+ return $this->maxImpressions;
2719
+ }
2720
+ public function setNumTimeUnits($numTimeUnits)
2721
+ {
2722
+ $this->numTimeUnits = $numTimeUnits;
2723
+ }
2724
+ public function getNumTimeUnits()
2725
+ {
2726
+ return $this->numTimeUnits;
2727
+ }
2728
+ public function setTimeUnitType($timeUnitType)
2729
+ {
2730
+ $this->timeUnitType = $timeUnitType;
2731
+ }
2732
+ public function getTimeUnitType()
2733
+ {
2734
+ return $this->timeUnitType;
2735
+ }
2736
+ }
2737
+
2738
+ class Google_Service_AdExchangeBuyer_EditAllOrderDealsRequest extends Google_Collection
2739
+ {
2740
+ protected $collection_key = 'deals';
2741
+ protected $internal_gapi_mappings = array(
2742
+ );
2743
+ protected $dealsType = 'Google_Service_AdExchangeBuyer_MarketplaceDeal';
2744
+ protected $dealsDataType = 'array';
2745
+ protected $proposalType = 'Google_Service_AdExchangeBuyer_Proposal';
2746
+ protected $proposalDataType = '';
2747
+ public $proposalRevisionNumber;
2748
+ public $updateAction;
2749
+
2750
+
2751
+ public function setDeals($deals)
2752
+ {
2753
+ $this->deals = $deals;
2754
+ }
2755
+ public function getDeals()
2756
+ {
2757
+ return $this->deals;
2758
+ }
2759
+ public function setProposal(Google_Service_AdExchangeBuyer_Proposal $proposal)
2760
+ {
2761
+ $this->proposal = $proposal;
2762
+ }
2763
+ public function getProposal()
2764
+ {
2765
+ return $this->proposal;
2766
+ }
2767
+ public function setProposalRevisionNumber($proposalRevisionNumber)
2768
+ {
2769
+ $this->proposalRevisionNumber = $proposalRevisionNumber;
2770
+ }
2771
+ public function getProposalRevisionNumber()
2772
+ {
2773
+ return $this->proposalRevisionNumber;
2774
+ }
2775
+ public function setUpdateAction($updateAction)
2776
+ {
2777
+ $this->updateAction = $updateAction;
2778
+ }
2779
+ public function getUpdateAction()
2780
+ {
2781
+ return $this->updateAction;
2782
+ }
2783
+ }
2784
+
2785
+ class Google_Service_AdExchangeBuyer_EditAllOrderDealsResponse extends Google_Collection
2786
+ {
2787
+ protected $collection_key = 'deals';
2788
+ protected $internal_gapi_mappings = array(
2789
+ );
2790
+ protected $dealsType = 'Google_Service_AdExchangeBuyer_MarketplaceDeal';
2791
+ protected $dealsDataType = 'array';
2792
+
2793
+
2794
+ public function setDeals($deals)
2795
+ {
2796
+ $this->deals = $deals;
2797
+ }
2798
+ public function getDeals()
2799
+ {
2800
+ return $this->deals;
2801
+ }
2802
+ }
2803
+
2804
+ class Google_Service_AdExchangeBuyer_GetOffersResponse extends Google_Collection
2805
+ {
2806
+ protected $collection_key = 'products';
2807
+ protected $internal_gapi_mappings = array(
2808
+ );
2809
+ protected $productsType = 'Google_Service_AdExchangeBuyer_Product';
2810
+ protected $productsDataType = 'array';
2811
+
2812
+
2813
+ public function setProducts($products)
2814
+ {
2815
+ $this->products = $products;
2816
+ }
2817
+ public function getProducts()
2818
+ {
2819
+ return $this->products;
2820
+ }
2821
+ }
2822
+
2823
+ class Google_Service_AdExchangeBuyer_GetOrderDealsResponse extends Google_Collection
2824
+ {
2825
+ protected $collection_key = 'deals';
2826
+ protected $internal_gapi_mappings = array(
2827
+ );
2828
+ protected $dealsType = 'Google_Service_AdExchangeBuyer_MarketplaceDeal';
2829
+ protected $dealsDataType = 'array';
2830
+
2831
+
2832
+ public function setDeals($deals)
2833
+ {
2834
+ $this->deals = $deals;
2835
+ }
2836
+ public function getDeals()
2837
+ {
2838
+ return $this->deals;
2839
+ }
2840
+ }
2841
+
2842
+ class Google_Service_AdExchangeBuyer_GetOrderNotesResponse extends Google_Collection
2843
+ {
2844
+ protected $collection_key = 'notes';
2845
+ protected $internal_gapi_mappings = array(
2846
+ );
2847
+ protected $notesType = 'Google_Service_AdExchangeBuyer_MarketplaceNote';
2848
+ protected $notesDataType = 'array';
2849
+
2850
+
2851
+ public function setNotes($notes)
2852
+ {
2853
+ $this->notes = $notes;
2854
+ }
2855
+ public function getNotes()
2856
+ {
2857
+ return $this->notes;
2858
+ }
2859
+ }
2860
+
2861
+ class Google_Service_AdExchangeBuyer_GetOrdersResponse extends Google_Collection
2862
+ {
2863
+ protected $collection_key = 'proposals';
2864
+ protected $internal_gapi_mappings = array(
2865
+ );
2866
+ protected $proposalsType = 'Google_Service_AdExchangeBuyer_Proposal';
2867
+ protected $proposalsDataType = 'array';
2868
+
2869
+
2870
+ public function setProposals($proposals)
2871
+ {
2872
+ $this->proposals = $proposals;
2873
+ }
2874
+ public function getProposals()
2875
+ {
2876
+ return $this->proposals;
2877
+ }
2878
+ }
2879
+
2880
+ class Google_Service_AdExchangeBuyer_MarketplaceDeal extends Google_Collection
2881
+ {
2882
+ protected $collection_key = 'sharedTargetings';
2883
+ protected $internal_gapi_mappings = array(
2884
+ );
2885
+ protected $buyerPrivateDataType = 'Google_Service_AdExchangeBuyer_PrivateData';
2886
+ protected $buyerPrivateDataDataType = '';
2887
+ public $creationTimeMs;
2888
+ public $creativePreApprovalPolicy;
2889
+ public $dealId;
2890
+ protected $deliveryControlType = 'Google_Service_AdExchangeBuyer_DeliveryControl';
2891
+ protected $deliveryControlDataType = '';
2892
+ public $externalDealId;
2893
+ public $flightEndTimeMs;
2894
+ public $flightStartTimeMs;
2895
+ public $inventoryDescription;
2896
+ public $kind;
2897
+ public $lastUpdateTimeMs;
2898
+ public $name;
2899
+ public $productId;
2900
+ public $productRevisionNumber;
2901
+ public $proposalId;
2902
+ protected $sellerContactsType = 'Google_Service_AdExchangeBuyer_ContactInformation';
2903
+ protected $sellerContactsDataType = 'array';
2904
+ protected $sharedTargetingsType = 'Google_Service_AdExchangeBuyer_SharedTargeting';
2905
+ protected $sharedTargetingsDataType = 'array';
2906
+ public $syndicationProduct;
2907
+ protected $termsType = 'Google_Service_AdExchangeBuyer_DealTerms';
2908
+ protected $termsDataType = '';
2909
+ public $webPropertyCode;
2910
+
2911
+
2912
+ public function setBuyerPrivateData(Google_Service_AdExchangeBuyer_PrivateData $buyerPrivateData)
2913
+ {
2914
+ $this->buyerPrivateData = $buyerPrivateData;
2915
+ }
2916
+ public function getBuyerPrivateData()
2917
+ {
2918
+ return $this->buyerPrivateData;
2919
+ }
2920
+ public function setCreationTimeMs($creationTimeMs)
2921
+ {
2922
+ $this->creationTimeMs = $creationTimeMs;
2923
+ }
2924
+ public function getCreationTimeMs()
2925
+ {
2926
+ return $this->creationTimeMs;
2927
+ }
2928
+ public function setCreativePreApprovalPolicy($creativePreApprovalPolicy)
2929
+ {
2930
+ $this->creativePreApprovalPolicy = $creativePreApprovalPolicy;
2931
+ }
2932
+ public function getCreativePreApprovalPolicy()
2933
+ {
2934
+ return $this->creativePreApprovalPolicy;
2935
+ }
2936
+ public function setDealId($dealId)
2937
+ {
2938
+ $this->dealId = $dealId;
2939
+ }
2940
+ public function getDealId()
2941
+ {
2942
+ return $this->dealId;
2943
+ }
2944
+ public function setDeliveryControl(Google_Service_AdExchangeBuyer_DeliveryControl $deliveryControl)
2945
+ {
2946
+ $this->deliveryControl = $deliveryControl;
2947
+ }
2948
+ public function getDeliveryControl()
2949
+ {
2950
+ return $this->deliveryControl;
2951
+ }
2952
+ public function setExternalDealId($externalDealId)
2953
+ {
2954
+ $this->externalDealId = $externalDealId;
2955
+ }
2956
+ public function getExternalDealId()
2957
+ {
2958
+ return $this->externalDealId;
2959
+ }
2960
+ public function setFlightEndTimeMs($flightEndTimeMs)
2961
+ {
2962
+ $this->flightEndTimeMs = $flightEndTimeMs;
2963
+ }
2964
+ public function getFlightEndTimeMs()
2965
+ {
2966
+ return $this->flightEndTimeMs;
2967
+ }
2968
+ public function setFlightStartTimeMs($flightStartTimeMs)
2969
+ {
2970
+ $this->flightStartTimeMs = $flightStartTimeMs;
2971
+ }
2972
+ public function getFlightStartTimeMs()
2973
+ {
2974
+ return $this->flightStartTimeMs;
2975
+ }
2976
+ public function setInventoryDescription($inventoryDescription)
2977
+ {
2978
+ $this->inventoryDescription = $inventoryDescription;
2979
+ }
2980
+ public function getInventoryDescription()
2981
+ {
2982
+ return $this->inventoryDescription;
2983
+ }
2984
+ public function setKind($kind)
2985
+ {
2986
+ $this->kind = $kind;
2987
+ }
2988
+ public function getKind()
2989
+ {
2990
+ return $this->kind;
2991
+ }
2992
+ public function setLastUpdateTimeMs($lastUpdateTimeMs)
2993
+ {
2994
+ $this->lastUpdateTimeMs = $lastUpdateTimeMs;
2995
+ }
2996
+ public function getLastUpdateTimeMs()
2997
+ {
2998
+ return $this->lastUpdateTimeMs;
2999
+ }
3000
+ public function setName($name)
3001
+ {
3002
+ $this->name = $name;
3003
+ }
3004
+ public function getName()
3005
+ {
3006
+ return $this->name;
3007
+ }
3008
+ public function setProductId($productId)
3009
+ {
3010
+ $this->productId = $productId;
3011
+ }
3012
+ public function getProductId()
3013
+ {
3014
+ return $this->productId;
3015
+ }
3016
+ public function setProductRevisionNumber($productRevisionNumber)
3017
+ {
3018
+ $this->productRevisionNumber = $productRevisionNumber;
3019
+ }
3020
+ public function getProductRevisionNumber()
3021
+ {
3022
+ return $this->productRevisionNumber;
3023
+ }
3024
+ public function setProposalId($proposalId)
3025
+ {
3026
+ $this->proposalId = $proposalId;
3027
+ }
3028
+ public function getProposalId()
3029
+ {
3030
+ return $this->proposalId;
3031
+ }
3032
+ public function setSellerContacts($sellerContacts)
3033
+ {
3034
+ $this->sellerContacts = $sellerContacts;
3035
+ }
3036
+ public function getSellerContacts()
3037
+ {
3038
+ return $this->sellerContacts;
3039
+ }
3040
+ public function setSharedTargetings($sharedTargetings)
3041
+ {
3042
+ $this->sharedTargetings = $sharedTargetings;
3043
+ }
3044
+ public function getSharedTargetings()
3045
+ {
3046
+ return $this->sharedTargetings;
3047
+ }
3048
+ public function setSyndicationProduct($syndicationProduct)
3049
+ {
3050
+ $this->syndicationProduct = $syndicationProduct;
3051
+ }
3052
+ public function getSyndicationProduct()
3053
+ {
3054
+ return $this->syndicationProduct;
3055
+ }
3056
+ public function setTerms(Google_Service_AdExchangeBuyer_DealTerms $terms)
3057
+ {
3058
+ $this->terms = $terms;
3059
+ }
3060
+ public function getTerms()
3061
+ {
3062
+ return $this->terms;
3063
+ }
3064
+ public function setWebPropertyCode($webPropertyCode)
3065
+ {
3066
+ $this->webPropertyCode = $webPropertyCode;
3067
+ }
3068
+ public function getWebPropertyCode()
3069
+ {
3070
+ return $this->webPropertyCode;
3071
+ }
3072
+ }
3073
+
3074
+ class Google_Service_AdExchangeBuyer_MarketplaceDealParty extends Google_Model
3075
+ {
3076
+ protected $internal_gapi_mappings = array(
3077
+ );
3078
+ protected $buyerType = 'Google_Service_AdExchangeBuyer_Buyer';
3079
+ protected $buyerDataType = '';
3080
+ protected $sellerType = 'Google_Service_AdExchangeBuyer_Seller';
3081
+ protected $sellerDataType = '';
3082
+
3083
+
3084
+ public function setBuyer(Google_Service_AdExchangeBuyer_Buyer $buyer)
3085
+ {
3086
+ $this->buyer = $buyer;
3087
+ }
3088
+ public function getBuyer()
3089
+ {
3090
+ return $this->buyer;
3091
+ }
3092
+ public function setSeller(Google_Service_AdExchangeBuyer_Seller $seller)
3093
+ {
3094
+ $this->seller = $seller;
3095
+ }
3096
+ public function getSeller()
3097
+ {
3098
+ return $this->seller;
3099
+ }
3100
+ }
3101
+
3102
+ class Google_Service_AdExchangeBuyer_MarketplaceLabel extends Google_Model
3103
+ {
3104
+ protected $internal_gapi_mappings = array(
3105
+ );
3106
+ public $accountId;
3107
+ public $createTimeMs;
3108
+ protected $deprecatedMarketplaceDealPartyType = 'Google_Service_AdExchangeBuyer_MarketplaceDealParty';
3109
+ protected $deprecatedMarketplaceDealPartyDataType = '';
3110
+ public $label;
3111
+
3112
+
3113
+ public function setAccountId($accountId)
3114
+ {
3115
+ $this->accountId = $accountId;
3116
+ }
3117
+ public function getAccountId()
3118
+ {
3119
+ return $this->accountId;
3120
+ }
3121
+ public function setCreateTimeMs($createTimeMs)
3122
+ {
3123
+ $this->createTimeMs = $createTimeMs;
3124
+ }
3125
+ public function getCreateTimeMs()
3126
+ {
3127
+ return $this->createTimeMs;
3128
+ }
3129
+ public function setDeprecatedMarketplaceDealParty(Google_Service_AdExchangeBuyer_MarketplaceDealParty $deprecatedMarketplaceDealParty)
3130
+ {
3131
+ $this->deprecatedMarketplaceDealParty = $deprecatedMarketplaceDealParty;
3132
+ }
3133
+ public function getDeprecatedMarketplaceDealParty()
3134
+ {
3135
+ return $this->deprecatedMarketplaceDealParty;
3136
+ }
3137
+ public function setLabel($label)
3138
+ {
3139
+ $this->label = $label;
3140
+ }
3141
+ public function getLabel()
3142
+ {
3143
+ return $this->label;
3144
+ }
3145
+ }
3146
+
3147
+ class Google_Service_AdExchangeBuyer_MarketplaceNote extends Google_Model
3148
+ {
3149
+ protected $internal_gapi_mappings = array(
3150
+ );
3151
+ public $creatorRole;
3152
+ public $dealId;
3153
+ public $kind;
3154
+ public $note;
3155
+ public $noteId;
3156
+ public $proposalId;
3157
+ public $proposalRevisionNumber;
3158
+ public $timestampMs;
3159
+
3160
+
3161
+ public function setCreatorRole($creatorRole)
3162
+ {
3163
+ $this->creatorRole = $creatorRole;
3164
+ }
3165
+ public function getCreatorRole()
3166
+ {
3167
+ return $this->creatorRole;
3168
+ }
3169
+ public function setDealId($dealId)
3170
+ {
3171
+ $this->dealId = $dealId;
3172
+ }
3173
+ public function getDealId()
3174
+ {
3175
+ return $this->dealId;
3176
+ }
3177
+ public function setKind($kind)
3178
+ {
3179
+ $this->kind = $kind;
3180
+ }
3181
+ public function getKind()
3182
+ {
3183
+ return $this->kind;
3184
+ }
3185
+ public function setNote($note)
3186
+ {
3187
+ $this->note = $note;
3188
+ }
3189
+ public function getNote()
3190
+ {
3191
+ return $this->note;
3192
+ }
3193
+ public function setNoteId($noteId)
3194
+ {
3195
+ $this->noteId = $noteId;
3196
+ }
3197
+ public function getNoteId()
3198
+ {
3199
+ return $this->noteId;
3200
+ }
3201
+ public function setProposalId($proposalId)
3202
+ {
3203
+ $this->proposalId = $proposalId;
3204
+ }
3205
+ public function getProposalId()
3206
+ {
3207
+ return $this->proposalId;
3208
+ }
3209
+ public function setProposalRevisionNumber($proposalRevisionNumber)
3210
+ {
3211
+ $this->proposalRevisionNumber = $proposalRevisionNumber;
3212
+ }
3213
+ public function getProposalRevisionNumber()
3214
+ {
3215
+ return $this->proposalRevisionNumber;
3216
+ }
3217
+ public function setTimestampMs($timestampMs)
3218
+ {
3219
+ $this->timestampMs = $timestampMs;
3220
+ }
3221
+ public function getTimestampMs()
3222
+ {
3223
+ return $this->timestampMs;
3224
+ }
3225
+ }
3226
+
3227
+ class Google_Service_AdExchangeBuyer_PerformanceReport extends Google_Collection
3228
+ {
3229
+ protected $collection_key = 'hostedMatchStatusRate';
3230
+ protected $internal_gapi_mappings = array(
3231
+ );
3232
+ public $bidRate;
3233
+ public $bidRequestRate;
3234
+ public $calloutStatusRate;
3235
+ public $cookieMatcherStatusRate;
3236
+ public $creativeStatusRate;
3237
+ public $filteredBidRate;
3238
+ public $hostedMatchStatusRate;
3239
+ public $inventoryMatchRate;
3240
+ public $kind;
3241
+ public $latency50thPercentile;
3242
+ public $latency85thPercentile;
3243
+ public $latency95thPercentile;
3244
+ public $noQuotaInRegion;
3245
+ public $outOfQuota;
3246
+ public $pixelMatchRequests;
3247
+ public $pixelMatchResponses;
3248
+ public $quotaConfiguredLimit;
3249
+ public $quotaThrottledLimit;
3250
+ public $region;
3251
+ public $successfulRequestRate;
3252
+ public $timestamp;
3253
+ public $unsuccessfulRequestRate;
3254
+
3255
+
3256
+ public function setBidRate($bidRate)
3257
+ {
3258
+ $this->bidRate = $bidRate;
3259
+ }
3260
+ public function getBidRate()
3261
+ {
3262
+ return $this->bidRate;
3263
+ }
3264
+ public function setBidRequestRate($bidRequestRate)
3265
+ {
3266
+ $this->bidRequestRate = $bidRequestRate;
3267
+ }
3268
+ public function getBidRequestRate()
3269
+ {
3270
+ return $this->bidRequestRate;
3271
+ }
3272
+ public function setCalloutStatusRate($calloutStatusRate)
3273
+ {
3274
+ $this->calloutStatusRate = $calloutStatusRate;
3275
+ }
3276
+ public function getCalloutStatusRate()
3277
+ {
3278
+ return $this->calloutStatusRate;
3279
+ }
3280
+ public function setCookieMatcherStatusRate($cookieMatcherStatusRate)
3281
+ {
3282
+ $this->cookieMatcherStatusRate = $cookieMatcherStatusRate;
3283
+ }
3284
+ public function getCookieMatcherStatusRate()
3285
+ {
3286
+ return $this->cookieMatcherStatusRate;
3287
+ }
3288
+ public function setCreativeStatusRate($creativeStatusRate)
3289
+ {
3290
+ $this->creativeStatusRate = $creativeStatusRate;
3291
+ }
3292
+ public function getCreativeStatusRate()
3293
+ {
3294
+ return $this->creativeStatusRate;
3295
+ }
3296
+ public function setFilteredBidRate($filteredBidRate)
3297
+ {
3298
+ $this->filteredBidRate = $filteredBidRate;
3299
+ }
3300
+ public function getFilteredBidRate()
3301
+ {
3302
+ return $this->filteredBidRate;
3303
+ }
3304
+ public function setHostedMatchStatusRate($hostedMatchStatusRate)
3305
+ {
3306
+ $this->hostedMatchStatusRate = $hostedMatchStatusRate;
3307
+ }
3308
+ public function getHostedMatchStatusRate()
3309
+ {
3310
+ return $this->hostedMatchStatusRate;
3311
+ }
3312
+ public function setInventoryMatchRate($inventoryMatchRate)
3313
+ {
3314
+ $this->inventoryMatchRate = $inventoryMatchRate;
3315
+ }
3316
+ public function getInventoryMatchRate()
3317
+ {
3318
+ return $this->inventoryMatchRate;
3319
+ }
3320
+ public function setKind($kind)
3321
+ {
3322
+ $this->kind = $kind;
3323
+ }
3324
+ public function getKind()
3325
+ {
3326
+ return $this->kind;
3327
+ }
3328
+ public function setLatency50thPercentile($latency50thPercentile)
3329
+ {
3330
+ $this->latency50thPercentile = $latency50thPercentile;
3331
+ }
3332
+ public function getLatency50thPercentile()
3333
+ {
3334
+ return $this->latency50thPercentile;
3335
+ }
3336
+ public function setLatency85thPercentile($latency85thPercentile)
3337
+ {
3338
+ $this->latency85thPercentile = $latency85thPercentile;
3339
+ }
3340
+ public function getLatency85thPercentile()
3341
+ {
3342
+ return $this->latency85thPercentile;
3343
+ }
3344
+ public function setLatency95thPercentile($latency95thPercentile)
3345
+ {
3346
+ $this->latency95thPercentile = $latency95thPercentile;
3347
+ }
3348
+ public function getLatency95thPercentile()
3349
+ {
3350
+ return $this->latency95thPercentile;
3351
+ }
3352
+ public function setNoQuotaInRegion($noQuotaInRegion)
3353
+ {
3354
+ $this->noQuotaInRegion = $noQuotaInRegion;
3355
+ }
3356
+ public function getNoQuotaInRegion()
3357
+ {
3358
+ return $this->noQuotaInRegion;
3359
+ }
3360
+ public function setOutOfQuota($outOfQuota)
3361
+ {
3362
+ $this->outOfQuota = $outOfQuota;
3363
+ }
3364
+ public function getOutOfQuota()
3365
+ {
3366
+ return $this->outOfQuota;
3367
+ }
3368
+ public function setPixelMatchRequests($pixelMatchRequests)
3369
+ {
3370
+ $this->pixelMatchRequests = $pixelMatchRequests;
3371
+ }
3372
+ public function getPixelMatchRequests()
3373
+ {
3374
+ return $this->pixelMatchRequests;
3375
+ }
3376
+ public function setPixelMatchResponses($pixelMatchResponses)
3377
+ {
3378
+ $this->pixelMatchResponses = $pixelMatchResponses;
3379
+ }
3380
+ public function getPixelMatchResponses()
3381
+ {
3382
+ return $this->pixelMatchResponses;
3383
+ }
3384
+ public function setQuotaConfiguredLimit($quotaConfiguredLimit)
3385
+ {
3386
+ $this->quotaConfiguredLimit = $quotaConfiguredLimit;
3387
+ }
3388
+ public function getQuotaConfiguredLimit()
3389
+ {
3390
+ return $this->quotaConfiguredLimit;
3391
+ }
3392
+ public function setQuotaThrottledLimit($quotaThrottledLimit)
3393
+ {
3394
+ $this->quotaThrottledLimit = $quotaThrottledLimit;
3395
+ }
3396
+ public function getQuotaThrottledLimit()
3397
+ {
3398
+ return $this->quotaThrottledLimit;
3399
+ }
3400
+ public function setRegion($region)
3401
+ {
3402
+ $this->region = $region;
3403
+ }
3404
+ public function getRegion()
3405
+ {
3406
+ return $this->region;
3407
+ }
3408
+ public function setSuccessfulRequestRate($successfulRequestRate)
3409
+ {
3410
+ $this->successfulRequestRate = $successfulRequestRate;
3411
+ }
3412
+ public function getSuccessfulRequestRate()
3413
+ {
3414
+ return $this->successfulRequestRate;
3415
+ }
3416
+ public function setTimestamp($timestamp)
3417
+ {
3418
+ $this->timestamp = $timestamp;
3419
+ }
3420
+ public function getTimestamp()
3421
+ {
3422
+ return $this->timestamp;
3423
+ }
3424
+ public function setUnsuccessfulRequestRate($unsuccessfulRequestRate)
3425
+ {
3426
+ $this->unsuccessfulRequestRate = $unsuccessfulRequestRate;
3427
+ }
3428
+ public function getUnsuccessfulRequestRate()
3429
+ {
3430
+ return $this->unsuccessfulRequestRate;
3431
+ }
3432
+ }
3433
+
3434
+ class Google_Service_AdExchangeBuyer_PerformanceReportList extends Google_Collection
3435
+ {
3436
+ protected $collection_key = 'performanceReport';
3437
+ protected $internal_gapi_mappings = array(
3438
+ );
3439
+ public $kind;
3440
+ protected $performanceReportType = 'Google_Service_AdExchangeBuyer_PerformanceReport';
3441
+ protected $performanceReportDataType = 'array';
3442
+
3443
+
3444
+ public function setKind($kind)
3445
+ {
3446
+ $this->kind = $kind;
3447
+ }
3448
+ public function getKind()
3449
+ {
3450
+ return $this->kind;
3451
+ }
3452
+ public function setPerformanceReport($performanceReport)
3453
+ {
3454
+ $this->performanceReport = $performanceReport;
3455
+ }
3456
+ public function getPerformanceReport()
3457
+ {
3458
+ return $this->performanceReport;
3459
+ }
3460
+ }
3461
+
3462
+ class Google_Service_AdExchangeBuyer_PretargetingConfig extends Google_Collection
3463
+ {
3464
+ protected $collection_key = 'videoPlayerSizes';
3465
+ protected $internal_gapi_mappings = array(
3466
+ );
3467
+ public $billingId;
3468
+ public $configId;
3469
+ public $configName;
3470
+ public $creativeType;
3471
+ protected $dimensionsType = 'Google_Service_AdExchangeBuyer_PretargetingConfigDimensions';
3472
+ protected $dimensionsDataType = 'array';
3473
+ public $excludedContentLabels;
3474
+ public $excludedGeoCriteriaIds;
3475
+ protected $excludedPlacementsType = 'Google_Service_AdExchangeBuyer_PretargetingConfigExcludedPlacements';
3476
+ protected $excludedPlacementsDataType = 'array';
3477
+ public $excludedUserLists;
3478
+ public $excludedVerticals;
3479
+ public $geoCriteriaIds;
3480
+ public $isActive;
3481
+ public $kind;
3482
+ public $languages;
3483
+ public $mobileCarriers;
3484
+ public $mobileDevices;
3485
+ public $mobileOperatingSystemVersions;
3486
+ protected $placementsType = 'Google_Service_AdExchangeBuyer_PretargetingConfigPlacements';
3487
+ protected $placementsDataType = 'array';
3488
+ public $platforms;
3489
+ public $supportedCreativeAttributes;
3490
+ public $userLists;
3491
+ public $vendorTypes;
3492
+ public $verticals;
3493
+ protected $videoPlayerSizesType = 'Google_Service_AdExchangeBuyer_PretargetingConfigVideoPlayerSizes';
3494
+ protected $videoPlayerSizesDataType = 'array';
3495
+
3496
+
3497
+ public function setBillingId($billingId)
3498
+ {
3499
+ $this->billingId = $billingId;
3500
+ }
3501
+ public function getBillingId()
3502
+ {
3503
+ return $this->billingId;
3504
+ }
3505
+ public function setConfigId($configId)
3506
+ {
3507
+ $this->configId = $configId;
3508
+ }
3509
+ public function getConfigId()
3510
+ {
3511
+ return $this->configId;
3512
+ }
3513
+ public function setConfigName($configName)
3514
+ {
3515
+ $this->configName = $configName;
3516
+ }
3517
+ public function getConfigName()
3518
+ {
3519
+ return $this->configName;
3520
+ }
3521
+ public function setCreativeType($creativeType)
3522
+ {
3523
+ $this->creativeType = $creativeType;
3524
+ }
3525
+ public function getCreativeType()
3526
+ {
3527
+ return $this->creativeType;
3528
+ }
3529
+ public function setDimensions($dimensions)
3530
+ {
3531
+ $this->dimensions = $dimensions;
3532
+ }
3533
+ public function getDimensions()
3534
+ {
3535
+ return $this->dimensions;
3536
+ }
3537
+ public function setExcludedContentLabels($excludedContentLabels)
3538
+ {
3539
+ $this->excludedContentLabels = $excludedContentLabels;
3540
+ }
3541
+ public function getExcludedContentLabels()
3542
+ {
3543
+ return $this->excludedContentLabels;
3544
+ }
3545
+ public function setExcludedGeoCriteriaIds($excludedGeoCriteriaIds)
3546
+ {
3547
+ $this->excludedGeoCriteriaIds = $excludedGeoCriteriaIds;
3548
+ }
3549
+ public function getExcludedGeoCriteriaIds()
3550
+ {
3551
+ return $this->excludedGeoCriteriaIds;
3552
+ }
3553
+ public function setExcludedPlacements($excludedPlacements)
3554
+ {
3555
+ $this->excludedPlacements = $excludedPlacements;
3556
+ }
3557
+ public function getExcludedPlacements()
3558
+ {
3559
+ return $this->excludedPlacements;
3560
+ }
3561
+ public function setExcludedUserLists($excludedUserLists)
3562
+ {
3563
+ $this->excludedUserLists = $excludedUserLists;
3564
+ }
3565
+ public function getExcludedUserLists()
3566
+ {
3567
+ return $this->excludedUserLists;
3568
+ }
3569
+ public function setExcludedVerticals($excludedVerticals)
3570
+ {
3571
+ $this->excludedVerticals = $excludedVerticals;
3572
+ }
3573
+ public function getExcludedVerticals()
3574
+ {
3575
+ return $this->excludedVerticals;
3576
+ }
3577
+ public function setGeoCriteriaIds($geoCriteriaIds)
3578
+ {
3579
+ $this->geoCriteriaIds = $geoCriteriaIds;
3580
+ }
3581
+ public function getGeoCriteriaIds()
3582
+ {
3583
+ return $this->geoCriteriaIds;
3584
+ }
3585
+ public function setIsActive($isActive)
3586
+ {
3587
+ $this->isActive = $isActive;
3588
+ }
3589
+ public function getIsActive()
3590
+ {
3591
+ return $this->isActive;
3592
+ }
3593
+ public function setKind($kind)
3594
+ {
3595
+ $this->kind = $kind;
3596
+ }
3597
+ public function getKind()
3598
+ {
3599
+ return $this->kind;
3600
+ }
3601
+ public function setLanguages($languages)
3602
+ {
3603
+ $this->languages = $languages;
3604
+ }
3605
+ public function getLanguages()
3606
+ {
3607
+ return $this->languages;
3608
+ }
3609
+ public function setMobileCarriers($mobileCarriers)
3610
+ {
3611
+ $this->mobileCarriers = $mobileCarriers;
3612
+ }
3613
+ public function getMobileCarriers()
3614
+ {
3615
+ return $this->mobileCarriers;
3616
+ }
3617
+ public function setMobileDevices($mobileDevices)
3618
+ {
3619
+ $this->mobileDevices = $mobileDevices;
3620
+ }
3621
+ public function getMobileDevices()
3622
+ {
3623
+ return $this->mobileDevices;
3624
+ }
3625
+ public function setMobileOperatingSystemVersions($mobileOperatingSystemVersions)
3626
+ {
3627
+ $this->mobileOperatingSystemVersions = $mobileOperatingSystemVersions;
3628
+ }
3629
+ public function getMobileOperatingSystemVersions()
3630
+ {
3631
+ return $this->mobileOperatingSystemVersions;
3632
+ }
3633
+ public function setPlacements($placements)
3634
+ {
3635
+ $this->placements = $placements;
3636
+ }
3637
+ public function getPlacements()
3638
+ {
3639
+ return $this->placements;
3640
+ }
3641
+ public function setPlatforms($platforms)
3642
+ {
3643
+ $this->platforms = $platforms;
3644
+ }
3645
+ public function getPlatforms()
3646
+ {
3647
+ return $this->platforms;
3648
+ }
3649
+ public function setSupportedCreativeAttributes($supportedCreativeAttributes)
3650
+ {
3651
+ $this->supportedCreativeAttributes = $supportedCreativeAttributes;
3652
+ }
3653
+ public function getSupportedCreativeAttributes()
3654
+ {
3655
+ return $this->supportedCreativeAttributes;
3656
+ }
3657
+ public function setUserLists($userLists)
3658
+ {
3659
+ $this->userLists = $userLists;
3660
+ }
3661
+ public function getUserLists()
3662
+ {
3663
+ return $this->userLists;
3664
+ }
3665
+ public function setVendorTypes($vendorTypes)
3666
+ {
3667
+ $this->vendorTypes = $vendorTypes;
3668
+ }
3669
+ public function getVendorTypes()
3670
+ {
3671
+ return $this->vendorTypes;
3672
+ }
3673
+ public function setVerticals($verticals)
3674
+ {
3675
+ $this->verticals = $verticals;
3676
+ }
3677
+ public function getVerticals()
3678
+ {
3679
+ return $this->verticals;
3680
+ }
3681
+ public function setVideoPlayerSizes($videoPlayerSizes)
3682
+ {
3683
+ $this->videoPlayerSizes = $videoPlayerSizes;
3684
+ }
3685
+ public function getVideoPlayerSizes()
3686
+ {
3687
+ return $this->videoPlayerSizes;
3688
+ }
3689
+ }
3690
+
3691
+ class Google_Service_AdExchangeBuyer_PretargetingConfigDimensions extends Google_Model
3692
+ {
3693
+ protected $internal_gapi_mappings = array(
3694
+ );
3695
+ public $height;
3696
+ public $width;
3697
+
3698
+
3699
+ public function setHeight($height)
3700
+ {
3701
+ $this->height = $height;
3702
+ }
3703
+ public function getHeight()
3704
+ {
3705
+ return $this->height;
3706
+ }
3707
+ public function setWidth($width)
3708
+ {
3709
+ $this->width = $width;
3710
+ }
3711
+ public function getWidth()
3712
+ {
3713
+ return $this->width;
3714
+ }
3715
+ }
3716
+
3717
+ class Google_Service_AdExchangeBuyer_PretargetingConfigExcludedPlacements extends Google_Model
3718
+ {
3719
+ protected $internal_gapi_mappings = array(
3720
+ );
3721
+ public $token;
3722
+ public $type;
3723
+
3724
+
3725
+ public function setToken($token)
3726
+ {
3727
+ $this->token = $token;
3728
+ }
3729
+ public function getToken()
3730
+ {
3731
+ return $this->token;
3732
+ }
3733
+ public function setType($type)
3734
+ {
3735
+ $this->type = $type;
3736
+ }
3737
+ public function getType()
3738
+ {
3739
+ return $this->type;
3740
+ }
3741
+ }
3742
+
3743
+ class Google_Service_AdExchangeBuyer_PretargetingConfigList extends Google_Collection
3744
+ {
3745
+ protected $collection_key = 'items';
3746
+ protected $internal_gapi_mappings = array(
3747
+ );
3748
+ protected $itemsType = 'Google_Service_AdExchangeBuyer_PretargetingConfig';
3749
+ protected $itemsDataType = 'array';
3750
+ public $kind;
3751
+
3752
+
3753
+ public function setItems($items)
3754
+ {
3755
+ $this->items = $items;
3756
+ }
3757
+ public function getItems()
3758
+ {
3759
+ return $this->items;
3760
+ }
3761
+ public function setKind($kind)
3762
+ {
3763
+ $this->kind = $kind;
3764
+ }
3765
+ public function getKind()
3766
+ {
3767
+ return $this->kind;
3768
+ }
3769
+ }
3770
+
3771
+ class Google_Service_AdExchangeBuyer_PretargetingConfigPlacements extends Google_Model
3772
+ {
3773
+ protected $internal_gapi_mappings = array(
3774
+ );
3775
+ public $token;
3776
+ public $type;
3777
+
3778
+
3779
+ public function setToken($token)
3780
+ {
3781
+ $this->token = $token;
3782
+ }
3783
+ public function getToken()
3784
+ {
3785
+ return $this->token;
3786
+ }
3787
+ public function setType($type)
3788
+ {
3789
+ $this->type = $type;
3790
+ }
3791
+ public function getType()
3792
+ {
3793
+ return $this->type;
3794
+ }
3795
+ }
3796
+
3797
+ class Google_Service_AdExchangeBuyer_PretargetingConfigVideoPlayerSizes extends Google_Model
3798
+ {
3799
+ protected $internal_gapi_mappings = array(
3800
+ );
3801
+ public $aspectRatio;
3802
+ public $minHeight;
3803
+ public $minWidth;
3804
+
3805
+
3806
+ public function setAspectRatio($aspectRatio)
3807
+ {
3808
+ $this->aspectRatio = $aspectRatio;
3809
+ }
3810
+ public function getAspectRatio()
3811
+ {
3812
+ return $this->aspectRatio;
3813
+ }
3814
+ public function setMinHeight($minHeight)
3815
+ {
3816
+ $this->minHeight = $minHeight;
3817
+ }
3818
+ public function getMinHeight()
3819
+ {
3820
+ return $this->minHeight;
3821
+ }
3822
+ public function setMinWidth($minWidth)
3823
+ {
3824
+ $this->minWidth = $minWidth;
3825
+ }
3826
+ public function getMinWidth()
3827
+ {
3828
+ return $this->minWidth;
3829
+ }
3830
+ }
3831
+
3832
+ class Google_Service_AdExchangeBuyer_Price extends Google_Model
3833
+ {
3834
+ protected $internal_gapi_mappings = array(
3835
+ );
3836
+ public $amountMicros;
3837
+ public $currencyCode;
3838
+ public $pricingType;
3839
+
3840
+
3841
+ public function setAmountMicros($amountMicros)
3842
+ {
3843
+ $this->amountMicros = $amountMicros;
3844
+ }
3845
+ public function getAmountMicros()
3846
+ {
3847
+ return $this->amountMicros;
3848
+ }
3849
+ public function setCurrencyCode($currencyCode)
3850
+ {
3851
+ $this->currencyCode = $currencyCode;
3852
+ }
3853
+ public function getCurrencyCode()
3854
+ {
3855
+ return $this->currencyCode;
3856
+ }
3857
+ public function setPricingType($pricingType)
3858
+ {
3859
+ $this->pricingType = $pricingType;
3860
+ }
3861
+ public function getPricingType()
3862
+ {
3863
+ return $this->pricingType;
3864
+ }
3865
+ }
3866
+
3867
+ class Google_Service_AdExchangeBuyer_PricePerBuyer extends Google_Model
3868
+ {
3869
+ protected $internal_gapi_mappings = array(
3870
+ );
3871
+ protected $buyerType = 'Google_Service_AdExchangeBuyer_Buyer';
3872
+ protected $buyerDataType = '';
3873
+ protected $priceType = 'Google_Service_AdExchangeBuyer_Price';
3874
+ protected $priceDataType = '';
3875
+
3876
+
3877
+ public function setBuyer(Google_Service_AdExchangeBuyer_Buyer $buyer)
3878
+ {
3879
+ $this->buyer = $buyer;
3880
+ }
3881
+ public function getBuyer()
3882
+ {
3883
+ return $this->buyer;
3884
+ }
3885
+ public function setPrice(Google_Service_AdExchangeBuyer_Price $price)
3886
+ {
3887
+ $this->price = $price;
3888
+ }
3889
+ public function getPrice()
3890
+ {
3891
+ return $this->price;
3892
+ }
3893
+ }
3894
+
3895
+ class Google_Service_AdExchangeBuyer_PrivateData extends Google_Model
3896
+ {
3897
+ protected $internal_gapi_mappings = array(
3898
+ );
3899
+ public $referenceId;
3900
+ public $referencePayload;
3901
+
3902
+
3903
+ public function setReferenceId($referenceId)
3904
+ {
3905
+ $this->referenceId = $referenceId;
3906
+ }
3907
+ public function getReferenceId()
3908
+ {
3909
+ return $this->referenceId;
3910
+ }
3911
+ public function setReferencePayload($referencePayload)
3912
+ {
3913
+ $this->referencePayload = $referencePayload;
3914
+ }
3915
+ public function getReferencePayload()
3916
+ {
3917
+ return $this->referencePayload;
3918
+ }
3919
+ }
3920
+
3921
+ class Google_Service_AdExchangeBuyer_Product extends Google_Collection
3922
+ {
3923
+ protected $collection_key = 'sharedTargetings';
3924
+ protected $internal_gapi_mappings = array(
3925
+ );
3926
+ public $creationTimeMs;
3927
+ protected $creatorContactsType = 'Google_Service_AdExchangeBuyer_ContactInformation';
3928
+ protected $creatorContactsDataType = 'array';
3929
+ public $flightEndTimeMs;
3930
+ public $flightStartTimeMs;
3931
+ public $hasCreatorSignedOff;
3932
+ public $inventorySource;
3933
+ public $kind;
3934
+ protected $labelsType = 'Google_Service_AdExchangeBuyer_MarketplaceLabel';
3935
+ protected $labelsDataType = 'array';
3936
+ public $lastUpdateTimeMs;
3937
+ public $name;
3938
+ public $productId;
3939
+ public $revisionNumber;
3940
+ protected $sellerType = 'Google_Service_AdExchangeBuyer_Seller';
3941
+ protected $sellerDataType = '';
3942
+ protected $sharedTargetingsType = 'Google_Service_AdExchangeBuyer_SharedTargeting';
3943
+ protected $sharedTargetingsDataType = 'array';
3944
+ public $state;
3945
+ public $syndicationProduct;
3946
+ protected $termsType = 'Google_Service_AdExchangeBuyer_DealTerms';
3947
+ protected $termsDataType = '';
3948
+ public $webPropertyCode;
3949
+
3950
+
3951
+ public function setCreationTimeMs($creationTimeMs)
3952
+ {
3953
+ $this->creationTimeMs = $creationTimeMs;
3954
+ }
3955
+ public function getCreationTimeMs()
3956
+ {
3957
+ return $this->creationTimeMs;
3958
+ }
3959
+ public function setCreatorContacts($creatorContacts)
3960
+ {
3961
+ $this->creatorContacts = $creatorContacts;
3962
+ }
3963
+ public function getCreatorContacts()
3964
+ {
3965
+ return $this->creatorContacts;
3966
+ }
3967
+ public function setFlightEndTimeMs($flightEndTimeMs)
3968
+ {
3969
+ $this->flightEndTimeMs = $flightEndTimeMs;
3970
+ }
3971
+ public function getFlightEndTimeMs()
3972
+ {
3973
+ return $this->flightEndTimeMs;
3974
+ }
3975
+ public function setFlightStartTimeMs($flightStartTimeMs)
3976
+ {
3977
+ $this->flightStartTimeMs = $flightStartTimeMs;
3978
+ }
3979
+ public function getFlightStartTimeMs()
3980
+ {
3981
+ return $this->flightStartTimeMs;
3982
+ }
3983
+ public function setHasCreatorSignedOff($hasCreatorSignedOff)
3984
+ {
3985
+ $this->hasCreatorSignedOff = $hasCreatorSignedOff;
3986
+ }
3987
+ public function getHasCreatorSignedOff()
3988
+ {
3989
+ return $this->hasCreatorSignedOff;
3990
+ }
3991
+ public function setInventorySource($inventorySource)
3992
+ {
3993
+ $this->inventorySource = $inventorySource;
3994
+ }
3995
+ public function getInventorySource()
3996
+ {
3997
+ return $this->inventorySource;
3998
+ }
3999
+ public function setKind($kind)
4000
+ {
4001
+ $this->kind = $kind;
4002
+ }
4003
+ public function getKind()
4004
+ {
4005
+ return $this->kind;
4006
+ }
4007
+ public function setLabels($labels)
4008
+ {
4009
+ $this->labels = $labels;
4010
+ }
4011
+ public function getLabels()
4012
+ {
4013
+ return $this->labels;
4014
+ }
4015
+ public function setLastUpdateTimeMs($lastUpdateTimeMs)
4016
+ {
4017
+ $this->lastUpdateTimeMs = $lastUpdateTimeMs;
4018
+ }
4019
+ public function getLastUpdateTimeMs()
4020
+ {
4021
+ return $this->lastUpdateTimeMs;
4022
+ }
4023
+ public function setName($name)
4024
+ {
4025
+ $this->name = $name;
4026
+ }
4027
+ public function getName()
4028
+ {
4029
+ return $this->name;
4030
+ }
4031
+ public function setProductId($productId)
4032
+ {
4033
+ $this->productId = $productId;
4034
+ }
4035
+ public function getProductId()
4036
+ {
4037
+ return $this->productId;
4038
+ }
4039
+ public function setRevisionNumber($revisionNumber)
4040
+ {
4041
+ $this->revisionNumber = $revisionNumber;
4042
+ }
4043
+ public function getRevisionNumber()
4044
+ {
4045
+ return $this->revisionNumber;
4046
+ }
4047
+ public function setSeller(Google_Service_AdExchangeBuyer_Seller $seller)
4048
+ {
4049
+ $this->seller = $seller;
4050
+ }
4051
+ public function getSeller()
4052
+ {
4053
+ return $this->seller;
4054
+ }
4055
+ public function setSharedTargetings($sharedTargetings)
4056
+ {
4057
+ $this->sharedTargetings = $sharedTargetings;
4058
+ }
4059
+ public function getSharedTargetings()
4060
+ {
4061
+ return $this->sharedTargetings;
4062
+ }
4063
+ public function setState($state)
4064
+ {
4065
+ $this->state = $state;
4066
+ }
4067
+ public function getState()
4068
+ {
4069
+ return $this->state;
4070
+ }
4071
+ public function setSyndicationProduct($syndicationProduct)
4072
+ {
4073
+ $this->syndicationProduct = $syndicationProduct;
4074
+ }
4075
+ public function getSyndicationProduct()
4076
+ {
4077
+ return $this->syndicationProduct;
4078
+ }
4079
+ public function setTerms(Google_Service_AdExchangeBuyer_DealTerms $terms)
4080
+ {
4081
+ $this->terms = $terms;
4082
+ }
4083
+ public function getTerms()
4084
+ {
4085
+ return $this->terms;
4086
+ }
4087
+ public function setWebPropertyCode($webPropertyCode)
4088
+ {
4089
+ $this->webPropertyCode = $webPropertyCode;
4090
+ }
4091
+ public function getWebPropertyCode()
4092
+ {
4093
+ return $this->webPropertyCode;
4094
+ }
4095
+ }
4096
+
4097
+ class Google_Service_AdExchangeBuyer_Proposal extends Google_Collection
4098
+ {
4099
+ protected $collection_key = 'sellerContacts';
4100
+ protected $internal_gapi_mappings = array(
4101
+ );
4102
+ protected $billedBuyerType = 'Google_Service_AdExchangeBuyer_Buyer';
4103
+ protected $billedBuyerDataType = '';
4104
+ protected $buyerType = 'Google_Service_AdExchangeBuyer_Buyer';
4105
+ protected $buyerDataType = '';
4106
+ protected $buyerContactsType = 'Google_Service_AdExchangeBuyer_ContactInformation';
4107
+ protected $buyerContactsDataType = 'array';
4108
+ protected $buyerPrivateDataType = 'Google_Service_AdExchangeBuyer_PrivateData';
4109
+ protected $buyerPrivateDataDataType = '';
4110
+ public $hasBuyerSignedOff;
4111
+ public $hasSellerSignedOff;
4112
+ public $inventorySource;
4113
+ public $isRenegotiating;
4114
+ public $isSetupComplete;
4115
+ public $kind;
4116
+ protected $labelsType = 'Google_Service_AdExchangeBuyer_MarketplaceLabel';
4117
+ protected $labelsDataType = 'array';
4118
+ public $lastUpdaterOrCommentorRole;
4119
+ public $lastUpdaterRole;
4120
+ public $name;
4121
+ public $originatorRole;
4122
+ public $proposalId;
4123
+ public $proposalState;
4124
+ public $revisionNumber;
4125
+ public $revisionTimeMs;
4126
+ protected $sellerType = 'Google_Service_AdExchangeBuyer_Seller';
4127
+ protected $sellerDataType = '';
4128
+ protected $sellerContactsType = 'Google_Service_AdExchangeBuyer_ContactInformation';
4129
+ protected $sellerContactsDataType = 'array';
4130
+
4131
+
4132
+ public function setBilledBuyer(Google_Service_AdExchangeBuyer_Buyer $billedBuyer)
4133
+ {
4134
+ $this->billedBuyer = $billedBuyer;
4135
+ }
4136
+ public function getBilledBuyer()
4137
+ {
4138
+ return $this->billedBuyer;
4139
+ }
4140
+ public function setBuyer(Google_Service_AdExchangeBuyer_Buyer $buyer)
4141
+ {
4142
+ $this->buyer = $buyer;
4143
+ }
4144
+ public function getBuyer()
4145
+ {
4146
+ return $this->buyer;
4147
+ }
4148
+ public function setBuyerContacts($buyerContacts)
4149
+ {
4150
+ $this->buyerContacts = $buyerContacts;
4151
+ }
4152
+ public function getBuyerContacts()
4153
+ {
4154
+ return $this->buyerContacts;
4155
+ }
4156
+ public function setBuyerPrivateData(Google_Service_AdExchangeBuyer_PrivateData $buyerPrivateData)
4157
+ {
4158
+ $this->buyerPrivateData = $buyerPrivateData;
4159
+ }
4160
+ public function getBuyerPrivateData()
4161
+ {
4162
+ return $this->buyerPrivateData;
4163
+ }
4164
+ public function setHasBuyerSignedOff($hasBuyerSignedOff)
4165
+ {
4166
+ $this->hasBuyerSignedOff = $hasBuyerSignedOff;
4167
+ }
4168
+ public function getHasBuyerSignedOff()
4169
+ {
4170
+ return $this->hasBuyerSignedOff;
4171
+ }
4172
+ public function setHasSellerSignedOff($hasSellerSignedOff)
4173
+ {
4174
+ $this->hasSellerSignedOff = $hasSellerSignedOff;
4175
+ }
4176
+ public function getHasSellerSignedOff()
4177
+ {
4178
+ return $this->hasSellerSignedOff;
4179
+ }
4180
+ public function setInventorySource($inventorySource)
4181
+ {
4182
+ $this->inventorySource = $inventorySource;
4183
+ }
4184
+ public function getInventorySource()
4185
+ {
4186
+ return $this->inventorySource;
4187
+ }
4188
+ public function setIsRenegotiating($isRenegotiating)
4189
+ {
4190
+ $this->isRenegotiating = $isRenegotiating;
4191
+ }
4192
+ public function getIsRenegotiating()
4193
+ {
4194
+ return $this->isRenegotiating;
4195
+ }
4196
+ public function setIsSetupComplete($isSetupComplete)
4197
+ {
4198
+ $this->isSetupComplete = $isSetupComplete;
4199
+ }
4200
+ public function getIsSetupComplete()
4201
+ {
4202
+ return $this->isSetupComplete;
4203
+ }
4204
+ public function setKind($kind)
4205
+ {
4206
+ $this->kind = $kind;
4207
+ }
4208
+ public function getKind()
4209
+ {
4210
+ return $this->kind;
4211
+ }
4212
+ public function setLabels($labels)
4213
+ {
4214
+ $this->labels = $labels;
4215
+ }
4216
+ public function getLabels()
4217
+ {
4218
+ return $this->labels;
4219
+ }
4220
+ public function setLastUpdaterOrCommentorRole($lastUpdaterOrCommentorRole)
4221
+ {
4222
+ $this->lastUpdaterOrCommentorRole = $lastUpdaterOrCommentorRole;
4223
+ }
4224
+ public function getLastUpdaterOrCommentorRole()
4225
+ {
4226
+ return $this->lastUpdaterOrCommentorRole;
4227
+ }
4228
+ public function setLastUpdaterRole($lastUpdaterRole)
4229
+ {
4230
+ $this->lastUpdaterRole = $lastUpdaterRole;
4231
+ }
4232
+ public function getLastUpdaterRole()
4233
+ {
4234
+ return $this->lastUpdaterRole;
4235
+ }
4236
+ public function setName($name)
4237
+ {
4238
+ $this->name = $name;
4239
+ }
4240
+ public function getName()
4241
+ {
4242
+ return $this->name;
4243
+ }
4244
+ public function setOriginatorRole($originatorRole)
4245
+ {
4246
+ $this->originatorRole = $originatorRole;
4247
+ }
4248
+ public function getOriginatorRole()
4249
+ {
4250
+ return $this->originatorRole;
4251
+ }
4252
+ public function setProposalId($proposalId)
4253
+ {
4254
+ $this->proposalId = $proposalId;
4255
+ }
4256
+ public function getProposalId()
4257
+ {
4258
+ return $this->proposalId;
4259
+ }
4260
+ public function setProposalState($proposalState)
4261
+ {
4262
+ $this->proposalState = $proposalState;
4263
+ }
4264
+ public function getProposalState()
4265
+ {
4266
+ return $this->proposalState;
4267
+ }
4268
+ public function setRevisionNumber($revisionNumber)
4269
+ {
4270
+ $this->revisionNumber = $revisionNumber;
4271
+ }
4272
+ public function getRevisionNumber()
4273
+ {
4274
+ return $this->revisionNumber;
4275
+ }
4276
+ public function setRevisionTimeMs($revisionTimeMs)
4277
+ {
4278
+ $this->revisionTimeMs = $revisionTimeMs;
4279
+ }
4280
+ public function getRevisionTimeMs()
4281
+ {
4282
+ return $this->revisionTimeMs;
4283
+ }
4284
+ public function setSeller(Google_Service_AdExchangeBuyer_Seller $seller)
4285
+ {
4286
+ $this->seller = $seller;
4287
+ }
4288
+ public function getSeller()
4289
+ {
4290
+ return $this->seller;
4291
+ }
4292
+ public function setSellerContacts($sellerContacts)
4293
+ {
4294
+ $this->sellerContacts = $sellerContacts;
4295
+ }
4296
+ public function getSellerContacts()
4297
+ {
4298
+ return $this->sellerContacts;
4299
+ }
4300
+ }
4301
+
4302
+ class Google_Service_AdExchangeBuyer_Seller extends Google_Model
4303
+ {
4304
+ protected $internal_gapi_mappings = array(
4305
+ );
4306
+ public $accountId;
4307
+ public $subAccountId;
4308
+
4309
+
4310
+ public function setAccountId($accountId)
4311
+ {
4312
+ $this->accountId = $accountId;
4313
+ }
4314
+ public function getAccountId()
4315
+ {
4316
+ return $this->accountId;
4317
+ }
4318
+ public function setSubAccountId($subAccountId)
4319
+ {
4320
+ $this->subAccountId = $subAccountId;
4321
+ }
4322
+ public function getSubAccountId()
4323
+ {
4324
+ return $this->subAccountId;
4325
+ }
4326
+ }
4327
+
4328
+ class Google_Service_AdExchangeBuyer_SharedTargeting extends Google_Collection
4329
+ {
4330
+ protected $collection_key = 'inclusions';
4331
+ protected $internal_gapi_mappings = array(
4332
+ );
4333
+ protected $exclusionsType = 'Google_Service_AdExchangeBuyer_TargetingValue';
4334
+ protected $exclusionsDataType = 'array';
4335
+ protected $inclusionsType = 'Google_Service_AdExchangeBuyer_TargetingValue';
4336
+ protected $inclusionsDataType = 'array';
4337
+ public $key;
4338
+
4339
+
4340
+ public function setExclusions($exclusions)
4341
+ {
4342
+ $this->exclusions = $exclusions;
4343
+ }
4344
+ public function getExclusions()
4345
+ {
4346
+ return $this->exclusions;
4347
+ }
4348
+ public function setInclusions($inclusions)
4349
+ {
4350
+ $this->inclusions = $inclusions;
4351
+ }
4352
+ public function getInclusions()
4353
+ {
4354
+ return $this->inclusions;
4355
+ }
4356
+ public function setKey($key)
4357
+ {
4358
+ $this->key = $key;
4359
+ }
4360
+ public function getKey()
4361
+ {
4362
+ return $this->key;
4363
+ }
4364
+ }
4365
+
4366
+ class Google_Service_AdExchangeBuyer_TargetingValue extends Google_Model
4367
+ {
4368
+ protected $internal_gapi_mappings = array(
4369
+ );
4370
+ protected $creativeSizeValueType = 'Google_Service_AdExchangeBuyer_TargetingValueCreativeSize';
4371
+ protected $creativeSizeValueDataType = '';
4372
+ protected $dayPartTargetingValueType = 'Google_Service_AdExchangeBuyer_TargetingValueDayPartTargeting';
4373
+ protected $dayPartTargetingValueDataType = '';
4374
+ public $longValue;
4375
+ public $stringValue;
4376
+
4377
+
4378
+ public function setCreativeSizeValue(Google_Service_AdExchangeBuyer_TargetingValueCreativeSize $creativeSizeValue)
4379
+ {
4380
+ $this->creativeSizeValue = $creativeSizeValue;
4381
+ }
4382
+ public function getCreativeSizeValue()
4383
+ {
4384
+ return $this->creativeSizeValue;
4385
+ }
4386
+ public function setDayPartTargetingValue(Google_Service_AdExchangeBuyer_TargetingValueDayPartTargeting $dayPartTargetingValue)
4387
+ {
4388
+ $this->dayPartTargetingValue = $dayPartTargetingValue;
4389
+ }
4390
+ public function getDayPartTargetingValue()
4391
+ {
4392
+ return $this->dayPartTargetingValue;
4393
+ }
4394
+ public function setLongValue($longValue)
4395
+ {
4396
+ $this->longValue = $longValue;
4397
+ }
4398
+ public function getLongValue()
4399
+ {
4400
+ return $this->longValue;
4401
+ }
4402
+ public function setStringValue($stringValue)
4403
+ {
4404
+ $this->stringValue = $stringValue;
4405
+ }
4406
+ public function getStringValue()
4407
+ {
4408
+ return $this->stringValue;
4409
+ }
4410
+ }
4411
+
4412
+ class Google_Service_AdExchangeBuyer_TargetingValueCreativeSize extends Google_Collection
4413
+ {
4414
+ protected $collection_key = 'companionSizes';
4415
+ protected $internal_gapi_mappings = array(
4416
+ );
4417
+ protected $companionSizesType = 'Google_Service_AdExchangeBuyer_TargetingValueSize';
4418
+ protected $companionSizesDataType = 'array';
4419
+ public $creativeSizeType;
4420
+ protected $sizeType = 'Google_Service_AdExchangeBuyer_TargetingValueSize';
4421
+ protected $sizeDataType = '';
4422
+
4423
+
4424
+ public function setCompanionSizes($companionSizes)
4425
+ {
4426
+ $this->companionSizes = $companionSizes;
4427
+ }
4428
+ public function getCompanionSizes()
4429
+ {
4430
+ return $this->companionSizes;
4431
+ }
4432
+ public function setCreativeSizeType($creativeSizeType)
4433
+ {
4434
+ $this->creativeSizeType = $creativeSizeType;
4435
+ }
4436
+ public function getCreativeSizeType()
4437
+ {
4438
+ return $this->creativeSizeType;
4439
+ }
4440
+ public function setSize(Google_Service_AdExchangeBuyer_TargetingValueSize $size)
4441
+ {
4442
+ $this->size = $size;
4443
+ }
4444
+ public function getSize()
4445
+ {
4446
+ return $this->size;
4447
+ }
4448
+ }
4449
+
4450
+ class Google_Service_AdExchangeBuyer_TargetingValueDayPartTargeting extends Google_Collection
4451
+ {
4452
+ protected $collection_key = 'dayParts';
4453
+ protected $internal_gapi_mappings = array(
4454
+ );
4455
+ protected $dayPartsType = 'Google_Service_AdExchangeBuyer_TargetingValueDayPartTargetingDayPart';
4456
+ protected $dayPartsDataType = 'array';
4457
+ public $timeZoneType;
4458
+
4459
+
4460
+ public function setDayParts($dayParts)
4461
+ {
4462
+ $this->dayParts = $dayParts;
4463
+ }
4464
+ public function getDayParts()
4465
+ {
4466
+ return $this->dayParts;
4467
+ }
4468
+ public function setTimeZoneType($timeZoneType)
4469
+ {
4470
+ $this->timeZoneType = $timeZoneType;
4471
+ }
4472
+ public function getTimeZoneType()
4473
+ {
4474
+ return $this->timeZoneType;
4475
+ }
4476
+ }
4477
+
4478
+ class Google_Service_AdExchangeBuyer_TargetingValueDayPartTargetingDayPart extends Google_Model
4479
+ {
4480
+ protected $internal_gapi_mappings = array(
4481
+ );
4482
+ public $dayOfWeek;
4483
+ public $endHour;
4484
+ public $endMinute;
4485
+ public $startHour;
4486
+ public $startMinute;
4487
+
4488
+
4489
+ public function setDayOfWeek($dayOfWeek)
4490
+ {
4491
+ $this->dayOfWeek = $dayOfWeek;
4492
+ }
4493
+ public function getDayOfWeek()
4494
+ {
4495
+ return $this->dayOfWeek;
4496
+ }
4497
+ public function setEndHour($endHour)
4498
+ {
4499
+ $this->endHour = $endHour;
4500
+ }
4501
+ public function getEndHour()
4502
+ {
4503
+ return $this->endHour;
4504
+ }
4505
+ public function setEndMinute($endMinute)
4506
+ {
4507
+ $this->endMinute = $endMinute;
4508
+ }
4509
+ public function getEndMinute()
4510
+ {
4511
+ return $this->endMinute;
4512
+ }
4513
+ public function setStartHour($startHour)
4514
+ {
4515
+ $this->startHour = $startHour;
4516
+ }
4517
+ public function getStartHour()
4518
+ {
4519
+ return $this->startHour;
4520
+ }
4521
+ public function setStartMinute($startMinute)
4522
+ {
4523
+ $this->startMinute = $startMinute;
4524
+ }
4525
+ public function getStartMinute()
4526
+ {
4527
+ return $this->startMinute;
4528
+ }
4529
+ }
4530
+
4531
+ class Google_Service_AdExchangeBuyer_TargetingValueSize extends Google_Model
4532
+ {
4533
+ protected $internal_gapi_mappings = array(
4534
+ );
4535
+ public $height;
4536
+ public $width;
4537
+
4538
+
4539
+ public function setHeight($height)
4540
+ {
4541
+ $this->height = $height;
4542
+ }
4543
+ public function getHeight()
4544
+ {
4545
+ return $this->height;
4546
+ }
4547
+ public function setWidth($width)
4548
+ {
4549
+ $this->width = $width;
4550
+ }
4551
+ public function getWidth()
4552
+ {
4553
+ return $this->width;
4554
+ }
4555
+ }
addons/pro/googlesheet/lib/external/Google/Service/AdExchangeSeller.php ADDED
@@ -0,0 +1,1711 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
+ * use this file except in compliance with the License. You may obtain a copy of
5
+ * the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ * License for the specific language governing permissions and limitations under
13
+ * the License.
14
+ */
15
+
16
+ /**
17
+ * Service definition for AdExchangeSeller (v2.0).
18
+ *
19
+ * <p>
20
+ * Gives Ad Exchange seller users access to their inventory and the ability to
21
+ * generate reports</p>
22
+ *
23
+ * <p>
24
+ * For more information about this service, see the API
25
+ * <a href="https://developers.google.com/ad-exchange/seller-rest/" target="_blank">Documentation</a>
26
+ * </p>
27
+ *
28
+ * @author Google, Inc.
29
+ */
30
+ class Google_Service_AdExchangeSeller extends Google_Service
31
+ {
32
+ /** View and manage your Ad Exchange data. */
33
+ const ADEXCHANGE_SELLER =
34
+ "https://www.googleapis.com/auth/adexchange.seller";
35
+ /** View your Ad Exchange data. */
36
+ const ADEXCHANGE_SELLER_READONLY =
37
+ "https://www.googleapis.com/auth/adexchange.seller.readonly";
38
+
39
+ public $accounts;
40
+ public $accounts_adclients;
41
+ public $accounts_alerts;
42
+ public $accounts_customchannels;
43
+ public $accounts_metadata_dimensions;
44
+ public $accounts_metadata_metrics;
45
+ public $accounts_preferreddeals;
46
+ public $accounts_reports;
47
+ public $accounts_reports_saved;
48
+ public $accounts_urlchannels;
49
+
50
+
51
+ /**
52
+ * Constructs the internal representation of the AdExchangeSeller service.
53
+ *
54
+ * @param Google_Client $client
55
+ */
56
+ public function __construct(Google_Client $client)
57
+ {
58
+ parent::__construct($client);
59
+ $this->rootUrl = 'https://www.googleapis.com/';
60
+ $this->servicePath = 'adexchangeseller/v2.0/';
61
+ $this->version = 'v2.0';
62
+ $this->serviceName = 'adexchangeseller';
63
+
64
+ $this->accounts = new Google_Service_AdExchangeSeller_Accounts_Resource(
65
+ $this,
66
+ $this->serviceName,
67
+ 'accounts',
68
+ array(
69
+ 'methods' => array(
70
+ 'get' => array(
71
+ 'path' => 'accounts/{accountId}',
72
+ 'httpMethod' => 'GET',
73
+ 'parameters' => array(
74
+ 'accountId' => array(
75
+ 'location' => 'path',
76
+ 'type' => 'string',
77
+ 'required' => true,
78
+ ),
79
+ ),
80
+ ),'list' => array(
81
+ 'path' => 'accounts',
82
+ 'httpMethod' => 'GET',
83
+ 'parameters' => array(
84
+ 'maxResults' => array(
85
+ 'location' => 'query',
86
+ 'type' => 'integer',
87
+ ),
88
+ 'pageToken' => array(
89
+ 'location' => 'query',
90
+ 'type' => 'string',
91
+ ),
92
+ ),
93
+ ),
94
+ )
95
+ )
96
+ );
97
+ $this->accounts_adclients = new Google_Service_AdExchangeSeller_AccountsAdclients_Resource(
98
+ $this,
99
+ $this->serviceName,
100
+ 'adclients',
101
+ array(
102
+ 'methods' => array(
103
+ 'list' => array(
104
+ 'path' => 'accounts/{accountId}/adclients',
105
+ 'httpMethod' => 'GET',
106
+ 'parameters' => array(
107
+ 'accountId' => array(
108
+ 'location' => 'path',
109
+ 'type' => 'string',
110
+ 'required' => true,
111
+ ),
112
+ 'maxResults' => array(
113
+ 'location' => 'query',
114
+ 'type' => 'integer',
115
+ ),
116
+ 'pageToken' => array(
117
+ 'location' => 'query',
118
+ 'type' => 'string',
119
+ ),
120
+ ),
121
+ ),
122
+ )
123
+ )
124
+ );
125
+ $this->accounts_alerts = new Google_Service_AdExchangeSeller_AccountsAlerts_Resource(
126
+ $this,
127
+ $this->serviceName,
128
+ 'alerts',
129
+ array(
130
+ 'methods' => array(
131
+ 'list' => array(
132
+ 'path' => 'accounts/{accountId}/alerts',
133
+ 'httpMethod' => 'GET',
134
+ 'parameters' => array(
135
+ 'accountId' => array(
136
+ 'location' => 'path',
137
+ 'type' => 'string',
138
+ 'required' => true,
139
+ ),
140
+ 'locale' => array(
141
+ 'location' => 'query',
142
+ 'type' => 'string',
143
+ ),
144
+ ),
145
+ ),
146
+ )
147
+ )
148
+ );
149
+ $this->accounts_customchannels = new Google_Service_AdExchangeSeller_AccountsCustomchannels_Resource(
150
+ $this,
151
+ $this->serviceName,
152
+ 'customchannels',
153
+ array(
154
+ 'methods' => array(
155
+ 'get' => array(
156
+ 'path' => 'accounts/{accountId}/adclients/{adClientId}/customchannels/{customChannelId}',
157
+ 'httpMethod' => 'GET',
158
+ 'parameters' => array(
159
+ 'accountId' => array(
160
+ 'location' => 'path',
161
+ 'type' => 'string',
162
+ 'required' => true,
163
+ ),
164
+ 'adClientId' => array(
165
+ 'location' => 'path',
166
+ 'type' => 'string',
167
+ 'required' => true,
168
+ ),
169
+ 'customChannelId' => array(
170
+ 'location' => 'path',
171
+ 'type' => 'string',
172
+ 'required' => true,
173
+ ),
174
+ ),
175
+ ),'list' => array(
176
+ 'path' => 'accounts/{accountId}/adclients/{adClientId}/customchannels',
177
+ 'httpMethod' => 'GET',
178
+ 'parameters' => array(
179
+ 'accountId' => array(
180
+ 'location' => 'path',
181
+ 'type' => 'string',
182
+ 'required' => true,
183
+ ),
184
+ 'adClientId' => array(
185
+ 'location' => 'path',
186
+ 'type' => 'string',
187
+ 'required' => true,
188
+ ),
189
+ 'maxResults' => array(
190
+ 'location' => 'query',
191
+ 'type' => 'integer',
192
+ ),
193
+ 'pageToken' => array(
194
+ 'location' => 'query',
195
+ 'type' => 'string',
196
+ ),
197
+ ),
198
+ ),
199
+ )
200
+ )
201
+ );
202
+ $this->accounts_metadata_dimensions = new Google_Service_AdExchangeSeller_AccountsMetadataDimensions_Resource(
203
+ $this,
204
+ $this->serviceName,
205
+ 'dimensions',
206
+ array(
207
+ 'methods' => array(
208
+ 'list' => array(
209
+ 'path' => 'accounts/{accountId}/metadata/dimensions',
210
+ 'httpMethod' => 'GET',
211
+ 'parameters' => array(
212
+ 'accountId' => array(
213
+ 'location' => 'path',
214
+ 'type' => 'string',
215
+ 'required' => true,
216
+ ),
217
+ ),
218
+ ),
219
+ )
220
+ )
221
+ );
222
+ $this->accounts_metadata_metrics = new Google_Service_AdExchangeSeller_AccountsMetadataMetrics_Resource(
223
+ $this,
224
+ $this->serviceName,
225
+ 'metrics',
226
+ array(
227
+ 'methods' => array(
228
+ 'list' => array(
229
+ 'path' => 'accounts/{accountId}/metadata/metrics',
230
+ 'httpMethod' => 'GET',
231
+ 'parameters' => array(
232
+ 'accountId' => array(
233
+ 'location' => 'path',
234
+ 'type' => 'string',
235
+ 'required' => true,
236
+ ),
237
+ ),
238
+ ),
239
+ )
240
+ )
241
+ );
242
+ $this->accounts_preferreddeals = new Google_Service_AdExchangeSeller_AccountsPreferreddeals_Resource(
243
+ $this,
244
+ $this->serviceName,
245
+ 'preferreddeals',
246
+ array(
247
+ 'methods' => array(
248
+ 'get' => array(
249
+ 'path' => 'accounts/{accountId}/preferreddeals/{dealId}',
250
+ 'httpMethod' => 'GET',
251
+ 'parameters' => array(
252
+ 'accountId' => array(
253
+ 'location' => 'path',
254
+ 'type' => 'string',
255
+ 'required' => true,
256
+ ),
257
+ 'dealId' => array(
258
+ 'location' => 'path',
259
+ 'type' => 'string',
260
+ 'required' => true,
261
+ ),
262
+ ),
263
+ ),'list' => array(
264
+ 'path' => 'accounts/{accountId}/preferreddeals',
265
+ 'httpMethod' => 'GET',
266
+ 'parameters' => array(
267
+ 'accountId' => array(
268
+ 'location' => 'path',
269
+ 'type' => 'string',
270
+ 'required' => true,
271
+ ),
272
+ ),
273
+ ),
274
+ )
275
+ )
276
+ );
277
+ $this->accounts_reports = new Google_Service_AdExchangeSeller_AccountsReports_Resource(
278
+ $this,
279
+ $this->serviceName,
280
+ 'reports',
281
+ array(
282
+ 'methods' => array(
283
+ 'generate' => array(
284
+ 'path' => 'accounts/{accountId}/reports',
285
+ 'httpMethod' => 'GET',
286
+ 'parameters' => array(
287
+ 'accountId' => array(
288
+ 'location' => 'path',
289
+ 'type' => 'string',
290
+ 'required' => true,
291
+ ),
292
+ 'startDate' => array(
293
+ 'location' => 'query',
294
+ 'type' => 'string',
295
+ 'required' => true,
296
+ ),
297
+ 'endDate' => array(
298
+ 'location' => 'query',
299
+ 'type' => 'string',
300
+ 'required' => true,
301
+ ),
302
+ 'dimension' => array(
303
+ 'location' => 'query',
304
+ 'type' => 'string',
305
+ 'repeated' => true,
306
+ ),
307
+ 'filter' => array(
308
+ 'location' => 'query',
309
+ 'type' => 'string',
310
+ 'repeated' => true,
311
+ ),
312
+ 'locale' => array(
313
+ 'location' => 'query',
314
+ 'type' => 'string',
315
+ ),
316
+ 'maxResults' => array(
317
+ 'location' => 'query',
318
+ 'type' => 'integer',
319
+ ),
320
+ 'metric' => array(
321
+ 'location' => 'query',
322
+ 'type' => 'string',
323
+ 'repeated' => true,
324
+ ),
325
+ 'sort' => array(
326
+ 'location' => 'query',
327
+ 'type' => 'string',
328
+ 'repeated' => true,
329
+ ),
330
+ 'startIndex' => array(
331
+ 'location' => 'query',
332
+ 'type' => 'integer',
333
+ ),
334
+ ),
335
+ ),
336
+ )
337
+ )
338
+ );
339
+ $this->accounts_reports_saved = new Google_Service_AdExchangeSeller_AccountsReportsSaved_Resource(
340
+ $this,
341
+ $this->serviceName,
342
+ 'saved',
343
+ array(
344
+ 'methods' => array(
345
+ 'generate' => array(
346
+ 'path' => 'accounts/{accountId}/reports/{savedReportId}',
347
+ 'httpMethod' => 'GET',
348
+ 'parameters' => array(
349
+ 'accountId' => array(
350
+ 'location' => 'path',
351
+ 'type' => 'string',
352
+ 'required' => true,
353
+ ),
354
+ 'savedReportId' => array(
355
+ 'location' => 'path',
356
+ 'type' => 'string',
357
+ 'required' => true,
358
+ ),
359
+ 'locale' => array(
360
+ 'location' => 'query',
361
+ 'type' => 'string',
362
+ ),
363
+ 'maxResults' => array(
364
+ 'location' => 'query',
365
+ 'type' => 'integer',
366
+ ),
367
+ 'startIndex' => array(
368
+ 'location' => 'query',
369
+ 'type' => 'integer',
370
+ ),
371
+ ),
372
+ ),'list' => array(
373
+ 'path' => 'accounts/{accountId}/reports/saved',
374
+ 'httpMethod' => 'GET',
375
+ 'parameters' => array(
376
+ 'accountId' => array(
377
+ 'location' => 'path',
378
+ 'type' => 'string',
379
+ 'required' => true,
380
+ ),
381
+ 'maxResults' => array(
382
+ 'location' => 'query',
383
+ 'type' => 'integer',
384
+ ),
385
+ 'pageToken' => array(
386
+ 'location' => 'query',
387
+ 'type' => 'string',
388
+ ),
389
+ ),
390
+ ),
391
+ )
392
+ )
393
+ );
394
+ $this->accounts_urlchannels = new Google_Service_AdExchangeSeller_AccountsUrlchannels_Resource(
395
+ $this,
396
+ $this->serviceName,
397
+ 'urlchannels',
398
+ array(
399
+ 'methods' => array(
400
+ 'list' => array(
401
+ 'path' => 'accounts/{accountId}/adclients/{adClientId}/urlchannels',
402
+ 'httpMethod' => 'GET',
403
+ 'parameters' => array(
404
+ 'accountId' => array(
405
+ 'location' => 'path',
406
+ 'type' => 'string',
407
+ 'required' => true,
408
+ ),
409
+ 'adClientId' => array(
410
+ 'location' => 'path',
411
+ 'type' => 'string',
412
+ 'required' => true,
413
+ ),
414
+ 'maxResults' => array(
415
+ 'location' => 'query',
416
+ 'type' => 'integer',
417
+ ),
418
+ 'pageToken' => array(
419
+ 'location' => 'query',
420
+ 'type' => 'string',
421
+ ),
422
+ ),
423
+ ),
424
+ )
425
+ )
426
+ );
427
+ }
428
+ }
429
+
430
+
431
+ /**
432
+ * The "accounts" collection of methods.
433
+ * Typical usage is:
434
+ * <code>
435
+ * $adexchangesellerService = new Google_Service_AdExchangeSeller(...);
436
+ * $accounts = $adexchangesellerService->accounts;
437
+ * </code>
438
+ */
439
+ class Google_Service_AdExchangeSeller_Accounts_Resource extends Google_Service_Resource
440
+ {
441
+
442
+ /**
443
+ * Get information about the selected Ad Exchange account. (accounts.get)
444
+ *
445
+ * @param string $accountId Account to get information about. Tip: 'myaccount'
446
+ * is a valid ID.
447
+ * @param array $optParams Optional parameters.
448
+ * @return Google_Service_AdExchangeSeller_Account
449
+ */
450
+ public function get($accountId, $optParams = array())
451
+ {
452
+ $params = array('accountId' => $accountId);
453
+ $params = array_merge($params, $optParams);
454
+ return $this->call('get', array($params), "Google_Service_AdExchangeSeller_Account");
455
+ }
456
+
457
+ /**
458
+ * List all accounts available to this Ad Exchange account.
459
+ * (accounts.listAccounts)
460
+ *
461
+ * @param array $optParams Optional parameters.
462
+ *
463
+ * @opt_param int maxResults The maximum number of accounts to include in the
464
+ * response, used for paging.
465
+ * @opt_param string pageToken A continuation token, used to page through
466
+ * accounts. To retrieve the next page, set this parameter to the value of
467
+ * "nextPageToken" from the previous response.
468
+ * @return Google_Service_AdExchangeSeller_Accounts
469
+ */
470
+ public function listAccounts($optParams = array())
471
+ {
472
+ $params = array();
473
+ $params = array_merge($params, $optParams);
474
+ return $this->call('list', array($params), "Google_Service_AdExchangeSeller_Accounts");
475
+ }
476
+ }
477
+
478
+ /**
479
+ * The "adclients" collection of methods.
480
+ * Typical usage is:
481
+ * <code>
482
+ * $adexchangesellerService = new Google_Service_AdExchangeSeller(...);
483
+ * $adclients = $adexchangesellerService->adclients;
484
+ * </code>
485
+ */
486
+ class Google_Service_AdExchangeSeller_AccountsAdclients_Resource extends Google_Service_Resource
487
+ {
488
+
489
+ /**
490
+ * List all ad clients in this Ad Exchange account.
491
+ * (adclients.listAccountsAdclients)
492
+ *
493
+ * @param string $accountId Account to which the ad client belongs.
494
+ * @param array $optParams Optional parameters.
495
+ *
496
+ * @opt_param string maxResults The maximum number of ad clients to include in
497
+ * the response, used for paging.
498
+ * @opt_param string pageToken A continuation token, used to page through ad
499
+ * clients. To retrieve the next page, set this parameter to the value of
500
+ * "nextPageToken" from the previous response.
501
+ * @return Google_Service_AdExchangeSeller_AdClients
502
+ */
503
+ public function listAccountsAdclients($accountId, $optParams = array())
504
+ {
505
+ $params = array('accountId' => $accountId);
506
+ $params = array_merge($params, $optParams);
507
+ return $this->call('list', array($params), "Google_Service_AdExchangeSeller_AdClients");
508
+ }
509
+ }
510
+ /**
511
+ * The "alerts" collection of methods.
512
+ * Typical usage is:
513
+ * <code>
514
+ * $adexchangesellerService = new Google_Service_AdExchangeSeller(...);
515
+ * $alerts = $adexchangesellerService->alerts;
516
+ * </code>
517
+ */
518
+ class Google_Service_AdExchangeSeller_AccountsAlerts_Resource extends Google_Service_Resource
519
+ {
520
+
521
+ /**
522
+ * List the alerts for this Ad Exchange account. (alerts.listAccountsAlerts)
523
+ *
524
+ * @param string $accountId Account owning the alerts.
525
+ * @param array $optParams Optional parameters.
526
+ *
527
+ * @opt_param string locale The locale to use for translating alert messages.
528
+ * The account locale will be used if this is not supplied. The AdSense default
529
+ * (English) will be used if the supplied locale is invalid or unsupported.
530
+ * @return Google_Service_AdExchangeSeller_Alerts
531
+ */
532
+ public function listAccountsAlerts($accountId, $optParams = array())
533
+ {
534
+ $params = array('accountId' => $accountId);
535
+ $params = array_merge($params, $optParams);
536
+ return $this->call('list', array($params), "Google_Service_AdExchangeSeller_Alerts");
537
+ }
538
+ }
539
+ /**
540
+ * The "customchannels" collection of methods.
541
+ * Typical usage is:
542
+ * <code>
543
+ * $adexchangesellerService = new Google_Service_AdExchangeSeller(...);
544
+ * $customchannels = $adexchangesellerService->customchannels;
545
+ * </code>
546
+ */
547
+ class Google_Service_AdExchangeSeller_AccountsCustomchannels_Resource extends Google_Service_Resource
548
+ {
549
+
550
+ /**
551
+ * Get the specified custom channel from the specified ad client.
552
+ * (customchannels.get)
553
+ *
554
+ * @param string $accountId Account to which the ad client belongs.
555
+ * @param string $adClientId Ad client which contains the custom channel.
556
+ * @param string $customChannelId Custom channel to retrieve.
557
+ * @param array $optParams Optional parameters.
558
+ * @return Google_Service_AdExchangeSeller_CustomChannel
559
+ */
560
+ public function get($accountId, $adClientId, $customChannelId, $optParams = array())
561
+ {
562
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId, 'customChannelId' => $customChannelId);
563
+ $params = array_merge($params, $optParams);
564
+ return $this->call('get', array($params), "Google_Service_AdExchangeSeller_CustomChannel");
565
+ }
566
+
567
+ /**
568
+ * List all custom channels in the specified ad client for this Ad Exchange
569
+ * account. (customchannels.listAccountsCustomchannels)
570
+ *
571
+ * @param string $accountId Account to which the ad client belongs.
572
+ * @param string $adClientId Ad client for which to list custom channels.
573
+ * @param array $optParams Optional parameters.
574
+ *
575
+ * @opt_param string maxResults The maximum number of custom channels to include
576
+ * in the response, used for paging.
577
+ * @opt_param string pageToken A continuation token, used to page through custom
578
+ * channels. To retrieve the next page, set this parameter to the value of
579
+ * "nextPageToken" from the previous response.
580
+ * @return Google_Service_AdExchangeSeller_CustomChannels
581
+ */
582
+ public function listAccountsCustomchannels($accountId, $adClientId, $optParams = array())
583
+ {
584
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId);
585
+ $params = array_merge($params, $optParams);
586
+ return $this->call('list', array($params), "Google_Service_AdExchangeSeller_CustomChannels");
587
+ }
588
+ }
589
+ /**
590
+ * The "metadata" collection of methods.
591
+ * Typical usage is:
592
+ * <code>
593
+ * $adexchangesellerService = new Google_Service_AdExchangeSeller(...);
594
+ * $metadata = $adexchangesellerService->metadata;
595
+ * </code>
596
+ */
597
+ class Google_Service_AdExchangeSeller_AccountsMetadata_Resource extends Google_Service_Resource
598
+ {
599
+ }
600
+
601
+ /**
602
+ * The "dimensions" collection of methods.
603
+ * Typical usage is:
604
+ * <code>
605
+ * $adexchangesellerService = new Google_Service_AdExchangeSeller(...);
606
+ * $dimensions = $adexchangesellerService->dimensions;
607
+ * </code>
608
+ */
609
+ class Google_Service_AdExchangeSeller_AccountsMetadataDimensions_Resource extends Google_Service_Resource
610
+ {
611
+
612
+ /**
613
+ * List the metadata for the dimensions available to this AdExchange account.
614
+ * (dimensions.listAccountsMetadataDimensions)
615
+ *
616
+ * @param string $accountId Account with visibility to the dimensions.
617
+ * @param array $optParams Optional parameters.
618
+ * @return Google_Service_AdExchangeSeller_Metadata
619
+ */
620
+ public function listAccountsMetadataDimensions($accountId, $optParams = array())
621
+ {
622
+ $params = array('accountId' => $accountId);
623
+ $params = array_merge($params, $optParams);
624
+ return $this->call('list', array($params), "Google_Service_AdExchangeSeller_Metadata");
625
+ }
626
+ }
627
+ /**
628
+ * The "metrics" collection of methods.
629
+ * Typical usage is:
630
+ * <code>
631
+ * $adexchangesellerService = new Google_Service_AdExchangeSeller(...);
632
+ * $metrics = $adexchangesellerService->metrics;
633
+ * </code>
634
+ */
635
+ class Google_Service_AdExchangeSeller_AccountsMetadataMetrics_Resource extends Google_Service_Resource
636
+ {
637
+
638
+ /**
639
+ * List the metadata for the metrics available to this AdExchange account.
640
+ * (metrics.listAccountsMetadataMetrics)
641
+ *
642
+ * @param string $accountId Account with visibility to the metrics.
643
+ * @param array $optParams Optional parameters.
644
+ * @return Google_Service_AdExchangeSeller_Metadata
645
+ */
646
+ public function listAccountsMetadataMetrics($accountId, $optParams = array())
647
+ {
648
+ $params = array('accountId' => $accountId);
649
+ $params = array_merge($params, $optParams);
650
+ return $this->call('list', array($params), "Google_Service_AdExchangeSeller_Metadata");
651
+ }
652
+ }
653
+ /**
654
+ * The "preferreddeals" collection of methods.
655
+ * Typical usage is:
656
+ * <code>
657
+ * $adexchangesellerService = new Google_Service_AdExchangeSeller(...);
658
+ * $preferreddeals = $adexchangesellerService->preferreddeals;
659
+ * </code>
660
+ */
661
+ class Google_Service_AdExchangeSeller_AccountsPreferreddeals_Resource extends Google_Service_Resource
662
+ {
663
+
664
+ /**
665
+ * Get information about the selected Ad Exchange Preferred Deal.
666
+ * (preferreddeals.get)
667
+ *
668
+ * @param string $accountId Account owning the deal.
669
+ * @param string $dealId Preferred deal to get information about.
670
+ * @param array $optParams Optional parameters.
671
+ * @return Google_Service_AdExchangeSeller_PreferredDeal
672
+ */
673
+ public function get($accountId, $dealId, $optParams = array())
674
+ {
675
+ $params = array('accountId' => $accountId, 'dealId' => $dealId);
676
+ $params = array_merge($params, $optParams);
677
+ return $this->call('get', array($params), "Google_Service_AdExchangeSeller_PreferredDeal");
678
+ }
679
+
680
+ /**
681
+ * List the preferred deals for this Ad Exchange account.
682
+ * (preferreddeals.listAccountsPreferreddeals)
683
+ *
684
+ * @param string $accountId Account owning the deals.
685
+ * @param array $optParams Optional parameters.
686
+ * @return Google_Service_AdExchangeSeller_PreferredDeals
687
+ */
688
+ public function listAccountsPreferreddeals($accountId, $optParams = array())
689
+ {
690
+ $params = array('accountId' => $accountId);
691
+ $params = array_merge($params, $optParams);
692
+ return $this->call('list', array($params), "Google_Service_AdExchangeSeller_PreferredDeals");
693
+ }
694
+ }
695
+ /**
696
+ * The "reports" collection of methods.
697
+ * Typical usage is:
698
+ * <code>
699
+ * $adexchangesellerService = new Google_Service_AdExchangeSeller(...);
700
+ * $reports = $adexchangesellerService->reports;
701
+ * </code>
702
+ */
703
+ class Google_Service_AdExchangeSeller_AccountsReports_Resource extends Google_Service_Resource
704
+ {
705
+
706
+ /**
707
+ * Generate an Ad Exchange report based on the report request sent in the query
708
+ * parameters. Returns the result as JSON; to retrieve output in CSV format
709
+ * specify "alt=csv" as a query parameter. (reports.generate)
710
+ *
711
+ * @param string $accountId Account which owns the generated report.
712
+ * @param string $startDate Start of the date range to report on in "YYYY-MM-DD"
713
+ * format, inclusive.
714
+ * @param string $endDate End of the date range to report on in "YYYY-MM-DD"
715
+ * format, inclusive.
716
+ * @param array $optParams Optional parameters.
717
+ *
718
+ * @opt_param string dimension Dimensions to base the report on.
719
+ * @opt_param string filter Filters to be run on the report.
720
+ * @opt_param string locale Optional locale to use for translating report output
721
+ * to a local language. Defaults to "en_US" if not specified.
722
+ * @opt_param string maxResults The maximum number of rows of report data to
723
+ * return.
724
+ * @opt_param string metric Numeric columns to include in the report.
725
+ * @opt_param string sort The name of a dimension or metric to sort the
726
+ * resulting report on, optionally prefixed with "+" to sort ascending or "-" to
727
+ * sort descending. If no prefix is specified, the column is sorted ascending.
728
+ * @opt_param string startIndex Index of the first row of report data to return.
729
+ * @return Google_Service_AdExchangeSeller_Report
730
+ */
731
+ public function generate($accountId, $startDate, $endDate, $optParams = array())
732
+ {
733
+ $params = array('accountId' => $accountId, 'startDate' => $startDate, 'endDate' => $endDate);
734
+ $params = array_merge($params, $optParams);
735
+ return $this->call('generate', array($params), "Google_Service_AdExchangeSeller_Report");
736
+ }
737
+ }
738
+
739
+ /**
740
+ * The "saved" collection of methods.
741
+ * Typical usage is:
742
+ * <code>
743
+ * $adexchangesellerService = new Google_Service_AdExchangeSeller(...);
744
+ * $saved = $adexchangesellerService->saved;
745
+ * </code>
746
+ */
747
+ class Google_Service_AdExchangeSeller_AccountsReportsSaved_Resource extends Google_Service_Resource
748
+ {
749
+
750
+ /**
751
+ * Generate an Ad Exchange report based on the saved report ID sent in the query
752
+ * parameters. (saved.generate)
753
+ *
754
+ * @param string $accountId Account owning the saved report.
755
+ * @param string $savedReportId The saved report to retrieve.
756
+ * @param array $optParams Optional parameters.
757
+ *
758
+ * @opt_param string locale Optional locale to use for translating report output
759
+ * to a local language. Defaults to "en_US" if not specified.
760
+ * @opt_param int maxResults The maximum number of rows of report data to
761
+ * return.
762
+ * @opt_param int startIndex Index of the first row of report data to return.
763
+ * @return Google_Service_AdExchangeSeller_Report
764
+ */
765
+ public function generate($accountId, $savedReportId, $optParams = array())
766
+ {
767
+ $params = array('accountId' => $accountId, 'savedReportId' => $savedReportId);
768
+ $params = array_merge($params, $optParams);
769
+ return $this->call('generate', array($params), "Google_Service_AdExchangeSeller_Report");
770
+ }
771
+
772
+ /**
773
+ * List all saved reports in this Ad Exchange account.
774
+ * (saved.listAccountsReportsSaved)
775
+ *
776
+ * @param string $accountId Account owning the saved reports.
777
+ * @param array $optParams Optional parameters.
778
+ *
779
+ * @opt_param int maxResults The maximum number of saved reports to include in
780
+ * the response, used for paging.
781
+ * @opt_param string pageToken A continuation token, used to page through saved
782
+ * reports. To retrieve the next page, set this parameter to the value of
783
+ * "nextPageToken" from the previous response.
784
+ * @return Google_Service_AdExchangeSeller_SavedReports
785
+ */
786
+ public function listAccountsReportsSaved($accountId, $optParams = array())
787
+ {
788
+ $params = array('accountId' => $accountId);
789
+ $params = array_merge($params, $optParams);
790
+ return $this->call('list', array($params), "Google_Service_AdExchangeSeller_SavedReports");
791
+ }
792
+ }
793
+ /**
794
+ * The "urlchannels" collection of methods.
795
+ * Typical usage is:
796
+ * <code>
797
+ * $adexchangesellerService = new Google_Service_AdExchangeSeller(...);
798
+ * $urlchannels = $adexchangesellerService->urlchannels;
799
+ * </code>
800
+ */
801
+ class Google_Service_AdExchangeSeller_AccountsUrlchannels_Resource extends Google_Service_Resource
802
+ {
803
+
804
+ /**
805
+ * List all URL channels in the specified ad client for this Ad Exchange
806
+ * account. (urlchannels.listAccountsUrlchannels)
807
+ *
808
+ * @param string $accountId Account to which the ad client belongs.
809
+ * @param string $adClientId Ad client for which to list URL channels.
810
+ * @param array $optParams Optional parameters.
811
+ *
812
+ * @opt_param string maxResults The maximum number of URL channels to include in
813
+ * the response, used for paging.
814
+ * @opt_param string pageToken A continuation token, used to page through URL
815
+ * channels. To retrieve the next page, set this parameter to the value of
816
+ * "nextPageToken" from the previous response.
817
+ * @return Google_Service_AdExchangeSeller_UrlChannels
818
+ */
819
+ public function listAccountsUrlchannels($accountId, $adClientId, $optParams = array())
820
+ {
821
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId);
822
+ $params = array_merge($params, $optParams);
823
+ return $this->call('list', array($params), "Google_Service_AdExchangeSeller_UrlChannels");
824
+ }
825
+ }
826
+
827
+
828
+
829
+
830
+ class Google_Service_AdExchangeSeller_Account extends Google_Model
831
+ {
832
+ protected $internal_gapi_mappings = array(
833
+ );
834
+ public $id;
835
+ public $kind;
836
+ public $name;
837
+
838
+
839
+ public function setId($id)
840
+ {
841
+ $this->id = $id;
842
+ }
843
+ public function getId()
844
+ {
845
+ return $this->id;
846
+ }
847
+ public function setKind($kind)
848
+ {
849
+ $this->kind = $kind;
850
+ }
851
+ public function getKind()
852
+ {
853
+ return $this->kind;
854
+ }
855
+ public function setName($name)
856
+ {
857
+ $this->name = $name;
858
+ }
859
+ public function getName()
860
+ {
861
+ return $this->name;
862
+ }
863
+ }
864
+
865
+ class Google_Service_AdExchangeSeller_Accounts extends Google_Collection
866
+ {
867
+ protected $collection_key = 'items';
868
+ protected $internal_gapi_mappings = array(
869
+ );
870
+ public $etag;
871
+ protected $itemsType = 'Google_Service_AdExchangeSeller_Account';
872
+ protected $itemsDataType = 'array';
873
+ public $kind;
874
+ public $nextPageToken;
875
+
876
+
877
+ public function setEtag($etag)
878
+ {
879
+ $this->etag = $etag;
880
+ }
881
+ public function getEtag()
882
+ {
883
+ return $this->etag;
884
+ }
885
+ public function setItems($items)
886
+ {
887
+ $this->items = $items;
888
+ }
889
+ public function getItems()
890
+ {
891
+ return $this->items;
892
+ }
893
+ public function setKind($kind)
894
+ {
895
+ $this->kind = $kind;
896
+ }
897
+ public function getKind()
898
+ {
899
+ return $this->kind;
900
+ }
901
+ public function setNextPageToken($nextPageToken)
902
+ {
903
+ $this->nextPageToken = $nextPageToken;
904
+ }
905
+ public function getNextPageToken()
906
+ {
907
+ return $this->nextPageToken;
908
+ }
909
+ }
910
+
911
+ class Google_Service_AdExchangeSeller_AdClient extends Google_Model
912
+ {
913
+ protected $internal_gapi_mappings = array(
914
+ );
915
+ public $arcOptIn;
916
+ public $id;
917
+ public $kind;
918
+ public $productCode;
919
+ public $supportsReporting;
920
+
921
+
922
+ public function setArcOptIn($arcOptIn)
923
+ {
924
+ $this->arcOptIn = $arcOptIn;
925
+ }
926
+ public function getArcOptIn()
927
+ {
928
+ return $this->arcOptIn;
929
+ }
930
+ public function setId($id)
931
+ {
932
+ $this->id = $id;
933
+ }
934
+ public function getId()
935
+ {
936
+ return $this->id;
937
+ }
938
+ public function setKind($kind)
939
+ {
940
+ $this->kind = $kind;
941
+ }
942
+ public function getKind()
943
+ {
944
+ return $this->kind;
945
+ }
946
+ public function setProductCode($productCode)
947
+ {
948
+ $this->productCode = $productCode;
949
+ }
950
+ public function getProductCode()
951
+ {
952
+ return $this->productCode;
953
+ }
954
+ public function setSupportsReporting($supportsReporting)
955
+ {
956
+ $this->supportsReporting = $supportsReporting;
957
+ }
958
+ public function getSupportsReporting()
959
+ {
960
+ return $this->supportsReporting;
961
+ }
962
+ }
963
+
964
+ class Google_Service_AdExchangeSeller_AdClients extends Google_Collection
965
+ {
966
+ protected $collection_key = 'items';
967
+ protected $internal_gapi_mappings = array(
968
+ );
969
+ public $etag;
970
+ protected $itemsType = 'Google_Service_AdExchangeSeller_AdClient';
971
+ protected $itemsDataType = 'array';
972
+ public $kind;
973
+ public $nextPageToken;
974
+
975
+
976
+ public function setEtag($etag)
977
+ {
978
+ $this->etag = $etag;
979
+ }
980
+ public function getEtag()
981
+ {
982
+ return $this->etag;
983
+ }
984
+ public function setItems($items)
985
+ {
986
+ $this->items = $items;
987
+ }
988
+ public function getItems()
989
+ {
990
+ return $this->items;
991
+ }
992
+ public function setKind($kind)
993
+ {
994
+ $this->kind = $kind;
995
+ }
996
+ public function getKind()
997
+ {
998
+ return $this->kind;
999
+ }
1000
+ public function setNextPageToken($nextPageToken)
1001
+ {
1002
+ $this->nextPageToken = $nextPageToken;
1003
+ }
1004
+ public function getNextPageToken()
1005
+ {
1006
+ return $this->nextPageToken;
1007
+ }
1008
+ }
1009
+
1010
+ class Google_Service_AdExchangeSeller_Alert extends Google_Model
1011
+ {
1012
+ protected $internal_gapi_mappings = array(
1013
+ );
1014
+ public $id;
1015
+ public $kind;
1016
+ public $message;
1017
+ public $severity;
1018
+ public $type;
1019
+
1020
+
1021
+ public function setId($id)
1022
+ {
1023
+ $this->id = $id;
1024
+ }
1025
+ public function getId()
1026
+ {
1027
+ return $this->id;
1028
+ }
1029
+ public function setKind($kind)
1030
+ {
1031
+ $this->kind = $kind;
1032
+ }
1033
+ public function getKind()
1034
+ {
1035
+ return $this->kind;
1036
+ }
1037
+ public function setMessage($message)
1038
+ {
1039
+ $this->message = $message;
1040
+ }
1041
+ public function getMessage()
1042
+ {
1043
+ return $this->message;
1044
+ }
1045
+ public function setSeverity($severity)
1046
+ {
1047
+ $this->severity = $severity;
1048
+ }
1049
+ public function getSeverity()
1050
+ {
1051
+ return $this->severity;
1052
+ }
1053
+ public function setType($type)
1054
+ {
1055
+ $this->type = $type;
1056
+ }
1057
+ public function getType()
1058
+ {
1059
+ return $this->type;
1060
+ }
1061
+ }
1062
+
1063
+ class Google_Service_AdExchangeSeller_Alerts extends Google_Collection
1064
+ {
1065
+ protected $collection_key = 'items';
1066
+ protected $internal_gapi_mappings = array(
1067
+ );
1068
+ protected $itemsType = 'Google_Service_AdExchangeSeller_Alert';
1069
+ protected $itemsDataType = 'array';
1070
+ public $kind;
1071
+
1072
+
1073
+ public function setItems($items)
1074
+ {
1075
+ $this->items = $items;
1076
+ }
1077
+ public function getItems()
1078
+ {
1079
+ return $this->items;
1080
+ }
1081
+ public function setKind($kind)
1082
+ {
1083
+ $this->kind = $kind;
1084
+ }
1085
+ public function getKind()
1086
+ {
1087
+ return $this->kind;
1088
+ }
1089
+ }
1090
+
1091
+ class Google_Service_AdExchangeSeller_CustomChannel extends Google_Model
1092
+ {
1093
+ protected $internal_gapi_mappings = array(
1094
+ );
1095
+ public $code;
1096
+ public $id;
1097
+ public $kind;
1098
+ public $name;
1099
+ protected $targetingInfoType = 'Google_Service_AdExchangeSeller_CustomChannelTargetingInfo';
1100
+ protected $targetingInfoDataType = '';
1101
+
1102
+
1103
+ public function setCode($code)
1104
+ {
1105
+ $this->code = $code;
1106
+ }
1107
+ public function getCode()
1108
+ {
1109
+ return $this->code;
1110
+ }
1111
+ public function setId($id)
1112
+ {
1113
+ $this->id = $id;
1114
+ }
1115
+ public function getId()
1116
+ {
1117
+ return $this->id;
1118
+ }
1119
+ public function setKind($kind)
1120
+ {
1121
+ $this->kind = $kind;
1122
+ }
1123
+ public function getKind()
1124
+ {
1125
+ return $this->kind;
1126
+ }
1127
+ public function setName($name)
1128
+ {
1129
+ $this->name = $name;
1130
+ }
1131
+ public function getName()
1132
+ {
1133
+ return $this->name;
1134
+ }
1135
+ public function setTargetingInfo(Google_Service_AdExchangeSeller_CustomChannelTargetingInfo $targetingInfo)
1136
+ {
1137
+ $this->targetingInfo = $targetingInfo;
1138
+ }
1139
+ public function getTargetingInfo()
1140
+ {
1141
+ return $this->targetingInfo;
1142
+ }
1143
+ }
1144
+
1145
+ class Google_Service_AdExchangeSeller_CustomChannelTargetingInfo extends Google_Model
1146
+ {
1147
+ protected $internal_gapi_mappings = array(
1148
+ );
1149
+ public $adsAppearOn;
1150
+ public $description;
1151
+ public $location;
1152
+ public $siteLanguage;
1153
+
1154
+
1155
+ public function setAdsAppearOn($adsAppearOn)
1156
+ {
1157
+ $this->adsAppearOn = $adsAppearOn;
1158
+ }
1159
+ public function getAdsAppearOn()
1160
+ {
1161
+ return $this->adsAppearOn;
1162
+ }
1163
+ public function setDescription($description)
1164
+ {
1165
+ $this->description = $description;
1166
+ }
1167
+ public function getDescription()
1168
+ {
1169
+ return $this->description;
1170
+ }
1171
+ public function setLocation($location)
1172
+ {
1173
+ $this->location = $location;
1174
+ }
1175
+ public function getLocation()
1176
+ {
1177
+ return $this->location;
1178
+ }
1179
+ public function setSiteLanguage($siteLanguage)
1180
+ {
1181
+ $this->siteLanguage = $siteLanguage;
1182
+ }
1183
+ public function getSiteLanguage()
1184
+ {
1185
+ return $this->siteLanguage;
1186
+ }
1187
+ }
1188
+
1189
+ class Google_Service_AdExchangeSeller_CustomChannels extends Google_Collection
1190
+ {
1191
+ protected $collection_key = 'items';
1192
+ protected $internal_gapi_mappings = array(
1193
+ );
1194
+ public $etag;
1195
+ protected $itemsType = 'Google_Service_AdExchangeSeller_CustomChannel';
1196
+ protected $itemsDataType = 'array';
1197
+ public $kind;
1198
+ public $nextPageToken;
1199
+
1200
+
1201
+ public function setEtag($etag)
1202
+ {
1203
+ $this->etag = $etag;
1204
+ }
1205
+ public function getEtag()
1206
+ {
1207
+ return $this->etag;
1208
+ }
1209
+ public function setItems($items)
1210
+ {
1211
+ $this->items = $items;
1212
+ }
1213
+ public function getItems()
1214
+ {
1215
+ return $this->items;
1216
+ }
1217
+ public function setKind($kind)
1218
+ {
1219
+ $this->kind = $kind;
1220
+ }
1221
+ public function getKind()
1222
+ {
1223
+ return $this->kind;
1224
+ }
1225
+ public function setNextPageToken($nextPageToken)
1226
+ {
1227
+ $this->nextPageToken = $nextPageToken;
1228
+ }
1229
+ public function getNextPageToken()
1230
+ {
1231
+ return $this->nextPageToken;
1232
+ }
1233
+ }
1234
+
1235
+ class Google_Service_AdExchangeSeller_Metadata extends Google_Collection
1236
+ {
1237
+ protected $collection_key = 'items';
1238
+ protected $internal_gapi_mappings = array(
1239
+ );
1240
+ protected $itemsType = 'Google_Service_AdExchangeSeller_ReportingMetadataEntry';
1241
+ protected $itemsDataType = 'array';
1242
+ public $kind;
1243
+
1244
+
1245
+ public function setItems($items)
1246
+ {
1247
+ $this->items = $items;
1248
+ }
1249
+ public function getItems()
1250
+ {
1251
+ return $this->items;
1252
+ }
1253
+ public function setKind($kind)
1254
+ {
1255
+ $this->kind = $kind;
1256
+ }
1257
+ public function getKind()
1258
+ {
1259
+ return $this->kind;
1260
+ }
1261
+ }
1262
+
1263
+ class Google_Service_AdExchangeSeller_PreferredDeal extends Google_Model
1264
+ {
1265
+ protected $internal_gapi_mappings = array(
1266
+ );
1267
+ public $advertiserName;
1268
+ public $buyerNetworkName;
1269
+ public $currencyCode;
1270
+ public $endTime;
1271
+ public $fixedCpm;
1272
+ public $id;
1273
+ public $kind;
1274
+ public $startTime;
1275
+
1276
+
1277
+ public function setAdvertiserName($advertiserName)
1278
+ {
1279
+ $this->advertiserName = $advertiserName;
1280
+ }
1281
+ public function getAdvertiserName()
1282
+ {
1283
+ return $this->advertiserName;
1284
+ }
1285
+ public function setBuyerNetworkName($buyerNetworkName)
1286
+ {
1287
+ $this->buyerNetworkName = $buyerNetworkName;
1288
+ }
1289
+ public function getBuyerNetworkName()
1290
+ {
1291
+ return $this->buyerNetworkName;
1292
+ }
1293
+ public function setCurrencyCode($currencyCode)
1294
+ {
1295
+ $this->currencyCode = $currencyCode;
1296
+ }
1297
+ public function getCurrencyCode()
1298
+ {
1299
+ return $this->currencyCode;
1300
+ }
1301
+ public function setEndTime($endTime)
1302
+ {
1303
+ $this->endTime = $endTime;
1304
+ }
1305
+ public function getEndTime()
1306
+ {
1307
+ return $this->endTime;
1308
+ }
1309
+ public function setFixedCpm($fixedCpm)
1310
+ {
1311
+ $this->fixedCpm = $fixedCpm;
1312
+ }
1313
+ public function getFixedCpm()
1314
+ {
1315
+ return $this->fixedCpm;
1316
+ }
1317
+ public function setId($id)
1318
+ {
1319
+ $this->id = $id;
1320
+ }
1321
+ public function getId()
1322
+ {
1323
+ return $this->id;
1324
+ }
1325
+ public function setKind($kind)
1326
+ {
1327
+ $this->kind = $kind;
1328
+ }
1329
+ public function getKind()
1330
+ {
1331
+ return $this->kind;
1332
+ }
1333
+ public function setStartTime($startTime)
1334
+ {
1335
+ $this->startTime = $startTime;
1336
+ }
1337
+ public function getStartTime()
1338
+ {
1339
+ return $this->startTime;
1340
+ }
1341
+ }
1342
+
1343
+ class Google_Service_AdExchangeSeller_PreferredDeals extends Google_Collection
1344
+ {
1345
+ protected $collection_key = 'items';
1346
+ protected $internal_gapi_mappings = array(
1347
+ );
1348
+ protected $itemsType = 'Google_Service_AdExchangeSeller_PreferredDeal';
1349
+ protected $itemsDataType = 'array';
1350
+ public $kind;
1351
+
1352
+
1353
+ public function setItems($items)
1354
+ {
1355
+ $this->items = $items;
1356
+ }
1357
+ public function getItems()
1358
+ {
1359
+ return $this->items;
1360
+ }
1361
+ public function setKind($kind)
1362
+ {
1363
+ $this->kind = $kind;
1364
+ }
1365
+ public function getKind()
1366
+ {
1367
+ return $this->kind;
1368
+ }
1369
+ }
1370
+
1371
+ class Google_Service_AdExchangeSeller_Report extends Google_Collection
1372
+ {
1373
+ protected $collection_key = 'warnings';
1374
+ protected $internal_gapi_mappings = array(
1375
+ );
1376
+ public $averages;
1377
+ protected $headersType = 'Google_Service_AdExchangeSeller_ReportHeaders';
1378
+ protected $headersDataType = 'array';
1379
+ public $kind;
1380
+ public $rows;
1381
+ public $totalMatchedRows;
1382
+ public $totals;
1383
+ public $warnings;
1384
+
1385
+
1386
+ public function setAverages($averages)
1387
+ {
1388
+ $this->averages = $averages;
1389
+ }
1390
+ public function getAverages()
1391
+ {
1392
+ return $this->averages;
1393
+ }
1394
+ public function setHeaders($headers)
1395
+ {
1396
+ $this->headers = $headers;
1397
+ }
1398
+ public function getHeaders()
1399
+ {
1400
+ return $this->headers;
1401
+ }
1402
+ public function setKind($kind)
1403
+ {
1404
+ $this->kind = $kind;
1405
+ }
1406
+ public function getKind()
1407
+ {
1408
+ return $this->kind;
1409
+ }
1410
+ public function setRows($rows)
1411
+ {
1412
+ $this->rows = $rows;
1413
+ }
1414
+ public function getRows()
1415
+ {
1416
+ return $this->rows;
1417
+ }
1418
+ public function setTotalMatchedRows($totalMatchedRows)
1419
+ {
1420
+ $this->totalMatchedRows = $totalMatchedRows;
1421
+ }
1422
+ public function getTotalMatchedRows()
1423
+ {
1424
+ return $this->totalMatchedRows;
1425
+ }
1426
+ public function setTotals($totals)
1427
+ {
1428
+ $this->totals = $totals;
1429
+ }
1430
+ public function getTotals()
1431
+ {
1432
+ return $this->totals;
1433
+ }
1434
+ public function setWarnings($warnings)
1435
+ {
1436
+ $this->warnings = $warnings;
1437
+ }
1438
+ public function getWarnings()
1439
+ {
1440
+ return $this->warnings;
1441
+ }
1442
+ }
1443
+
1444
+ class Google_Service_AdExchangeSeller_ReportHeaders extends Google_Model
1445
+ {
1446
+ protected $internal_gapi_mappings = array(
1447
+ );
1448
+ public $currency;
1449
+ public $name;
1450
+ public $type;
1451
+
1452
+
1453
+ public function setCurrency($currency)
1454
+ {
1455
+ $this->currency = $currency;
1456
+ }
1457
+ public function getCurrency()
1458
+ {
1459
+ return $this->currency;
1460
+ }
1461
+ public function setName($name)
1462
+ {
1463
+ $this->name = $name;
1464
+ }
1465
+ public function getName()
1466
+ {
1467
+ return $this->name;
1468
+ }
1469
+ public function setType($type)
1470
+ {
1471
+ $this->type = $type;
1472
+ }
1473
+ public function getType()
1474
+ {
1475
+ return $this->type;
1476
+ }
1477
+ }
1478
+
1479
+ class Google_Service_AdExchangeSeller_ReportingMetadataEntry extends Google_Collection
1480
+ {
1481
+ protected $collection_key = 'supportedProducts';
1482
+ protected $internal_gapi_mappings = array(
1483
+ );
1484
+ public $compatibleDimensions;
1485
+ public $compatibleMetrics;
1486
+ public $id;
1487
+ public $kind;
1488
+ public $requiredDimensions;
1489
+ public $requiredMetrics;
1490
+ public $supportedProducts;
1491
+
1492
+
1493
+ public function setCompatibleDimensions($compatibleDimensions)
1494
+ {
1495
+ $this->compatibleDimensions = $compatibleDimensions;
1496
+ }
1497
+ public function getCompatibleDimensions()
1498
+ {
1499
+ return $this->compatibleDimensions;
1500
+ }
1501
+ public function setCompatibleMetrics($compatibleMetrics)
1502
+ {
1503
+ $this->compatibleMetrics = $compatibleMetrics;
1504
+ }
1505
+ public function getCompatibleMetrics()
1506
+ {
1507
+ return $this->compatibleMetrics;
1508
+ }
1509
+ public function setId($id)
1510
+ {
1511
+ $this->id = $id;
1512
+ }
1513
+ public function getId()
1514
+ {
1515
+ return $this->id;
1516
+ }
1517
+ public function setKind($kind)
1518
+ {
1519
+ $this->kind = $kind;
1520
+ }
1521
+ public function getKind()
1522
+ {
1523
+ return $this->kind;
1524
+ }
1525
+ public function setRequiredDimensions($requiredDimensions)
1526
+ {
1527
+ $this->requiredDimensions = $requiredDimensions;
1528
+ }
1529
+ public function getRequiredDimensions()
1530
+ {
1531
+ return $this->requiredDimensions;
1532
+ }
1533
+ public function setRequiredMetrics($requiredMetrics)
1534
+ {
1535
+ $this->requiredMetrics = $requiredMetrics;
1536
+ }
1537
+ public function getRequiredMetrics()
1538
+ {
1539
+ return $this->requiredMetrics;
1540
+ }
1541
+ public function setSupportedProducts($supportedProducts)
1542
+ {
1543
+ $this->supportedProducts = $supportedProducts;
1544
+ }
1545
+ public function getSupportedProducts()
1546
+ {
1547
+ return $this->supportedProducts;
1548
+ }
1549
+ }
1550
+
1551
+ class Google_Service_AdExchangeSeller_SavedReport extends Google_Model
1552
+ {
1553
+ protected $internal_gapi_mappings = array(
1554
+ );
1555
+ public $id;
1556
+ public $kind;
1557
+ public $name;
1558
+
1559
+
1560
+ public function setId($id)
1561
+ {
1562
+ $this->id = $id;
1563
+ }
1564
+ public function getId()
1565
+ {
1566
+ return $this->id;
1567
+ }
1568
+ public function setKind($kind)
1569
+ {
1570
+ $this->kind = $kind;
1571
+ }
1572
+ public function getKind()
1573
+ {
1574
+ return $this->kind;
1575
+ }
1576
+ public function setName($name)
1577
+ {
1578
+ $this->name = $name;
1579
+ }
1580
+ public function getName()
1581
+ {
1582
+ return $this->name;
1583
+ }
1584
+ }
1585
+
1586
+ class Google_Service_AdExchangeSeller_SavedReports extends Google_Collection
1587
+ {
1588
+ protected $collection_key = 'items';
1589
+ protected $internal_gapi_mappings = array(
1590
+ );
1591
+ public $etag;
1592
+ protected $itemsType = 'Google_Service_AdExchangeSeller_SavedReport';
1593
+ protected $itemsDataType = 'array';
1594
+ public $kind;
1595
+ public $nextPageToken;
1596
+
1597
+
1598
+ public function setEtag($etag)
1599
+ {
1600
+ $this->etag = $etag;
1601
+ }
1602
+ public function getEtag()
1603
+ {
1604
+ return $this->etag;
1605
+ }
1606
+ public function setItems($items)
1607
+ {
1608
+ $this->items = $items;
1609
+ }
1610
+ public function getItems()
1611
+ {
1612
+ return $this->items;
1613
+ }
1614
+ public function setKind($kind)
1615
+ {
1616
+ $this->kind = $kind;
1617
+ }
1618
+ public function getKind()
1619
+ {
1620
+ return $this->kind;
1621
+ }
1622
+ public function setNextPageToken($nextPageToken)
1623
+ {
1624
+ $this->nextPageToken = $nextPageToken;
1625
+ }
1626
+ public function getNextPageToken()
1627
+ {
1628
+ return $this->nextPageToken;
1629
+ }
1630
+ }
1631
+
1632
+ class Google_Service_AdExchangeSeller_UrlChannel extends Google_Model
1633
+ {
1634
+ protected $internal_gapi_mappings = array(
1635
+ );
1636
+ public $id;
1637
+ public $kind;
1638
+ public $urlPattern;
1639
+
1640
+
1641
+ public function setId($id)
1642
+ {
1643
+ $this->id = $id;
1644
+ }
1645
+ public function getId()
1646
+ {
1647
+ return $this->id;
1648
+ }
1649
+ public function setKind($kind)
1650
+ {
1651
+ $this->kind = $kind;
1652
+ }
1653
+ public function getKind()
1654
+ {
1655
+ return $this->kind;
1656
+ }
1657
+ public function setUrlPattern($urlPattern)
1658
+ {
1659
+ $this->urlPattern = $urlPattern;
1660
+ }
1661
+ public function getUrlPattern()
1662
+ {
1663
+ return $this->urlPattern;
1664
+ }
1665
+ }
1666
+
1667
+ class Google_Service_AdExchangeSeller_UrlChannels extends Google_Collection
1668
+ {
1669
+ protected $collection_key = 'items';
1670
+ protected $internal_gapi_mappings = array(
1671
+ );
1672
+ public $etag;
1673
+ protected $itemsType = 'Google_Service_AdExchangeSeller_UrlChannel';
1674
+ protected $itemsDataType = 'array';
1675
+ public $kind;
1676
+ public $nextPageToken;
1677
+
1678
+
1679
+ public function setEtag($etag)
1680
+ {
1681
+ $this->etag = $etag;
1682
+ }
1683
+ public function getEtag()
1684
+ {
1685
+ return $this->etag;
1686
+ }
1687
+ public function setItems($items)
1688
+ {
1689
+ $this->items = $items;
1690
+ }
1691
+ public function getItems()
1692
+ {
1693
+ return $this->items;
1694
+ }
1695
+ public function setKind($kind)
1696
+ {
1697
+ $this->kind = $kind;
1698
+ }
1699
+ public function getKind()
1700
+ {
1701
+ return $this->kind;
1702
+ }
1703
+ public function setNextPageToken($nextPageToken)
1704
+ {
1705
+ $this->nextPageToken = $nextPageToken;
1706
+ }
1707
+ public function getNextPageToken()
1708
+ {
1709
+ return $this->nextPageToken;
1710
+ }
1711
+ }
addons/pro/googlesheet/lib/external/Google/Service/AdSense.php ADDED
@@ -0,0 +1,3594 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
4
+ * use this file except in compliance with the License. You may obtain a copy of
5
+ * the License at
6
+ *
7
+ * http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software
10
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12
+ * License for the specific language governing permissions and limitations under
13
+ * the License.
14
+ */
15
+
16
+ /**
17
+ * Service definition for AdSense (v1.4).
18
+ *
19
+ * <p>
20
+ * Gives AdSense publishers access to their inventory and the ability to
21
+ * generate reports</p>
22
+ *
23
+ * <p>
24
+ * For more information about this service, see the API
25
+ * <a href="https://developers.google.com/adsense/management/" target="_blank">Documentation</a>
26
+ * </p>
27
+ *
28
+ * @author Google, Inc.
29
+ */
30
+ class Google_Service_AdSense extends Google_Service
31
+ {
32
+ /** View and manage your AdSense data. */
33
+ const ADSENSE =
34
+ "https://www.googleapis.com/auth/adsense";
35
+ /** View your AdSense data. */
36
+ const ADSENSE_READONLY =
37
+ "https://www.googleapis.com/auth/adsense.readonly";
38
+
39
+ public $accounts;
40
+ public $accounts_adclients;
41
+ public $accounts_adunits;
42
+ public $accounts_adunits_customchannels;
43
+ public $accounts_alerts;
44
+ public $accounts_customchannels;
45
+ public $accounts_customchannels_adunits;
46
+ public $accounts_payments;
47
+ public $accounts_reports;
48
+ public $accounts_reports_saved;
49
+ public $accounts_savedadstyles;
50
+ public $accounts_urlchannels;
51
+ public $adclients;
52
+ public $adunits;
53
+ public $adunits_customchannels;
54
+ public $alerts;
55
+ public $customchannels;
56
+ public $customchannels_adunits;
57
+ public $metadata_dimensions;
58
+ public $metadata_metrics;
59
+ public $payments;
60
+ public $reports;
61
+ public $reports_saved;
62
+ public $savedadstyles;
63
+ public $urlchannels;
64
+
65
+
66
+ /**
67
+ * Constructs the internal representation of the AdSense service.
68
+ *
69
+ * @param Google_Client $client
70
+ */
71
+ public function __construct(Google_Client $client)
72
+ {
73
+ parent::__construct($client);
74
+ $this->rootUrl = 'https://www.googleapis.com/';
75
+ $this->servicePath = 'adsense/v1.4/';
76
+ $this->version = 'v1.4';
77
+ $this->serviceName = 'adsense';
78
+
79
+ $this->accounts = new Google_Service_AdSense_Accounts_Resource(
80
+ $this,
81
+ $this->serviceName,
82
+ 'accounts',
83
+ array(
84
+ 'methods' => array(
85
+ 'get' => array(
86
+ 'path' => 'accounts/{accountId}',
87
+ 'httpMethod' => 'GET',
88
+ 'parameters' => array(
89
+ 'accountId' => array(
90
+ 'location' => 'path',
91
+ 'type' => 'string',
92
+ 'required' => true,
93
+ ),
94
+ 'tree' => array(
95
+ 'location' => 'query',
96
+ 'type' => 'boolean',
97
+ ),
98
+ ),
99
+ ),'list' => array(
100
+ 'path' => 'accounts',
101
+ 'httpMethod' => 'GET',
102
+ 'parameters' => array(
103
+ 'maxResults' => array(
104
+ 'location' => 'query',
105
+ 'type' => 'integer',
106
+ ),
107
+ 'pageToken' => array(
108
+ 'location' => 'query',
109
+ 'type' => 'string',
110
+ ),
111
+ ),
112
+ ),
113
+ )
114
+ )
115
+ );
116
+ $this->accounts_adclients = new Google_Service_AdSense_AccountsAdclients_Resource(
117
+ $this,
118
+ $this->serviceName,
119
+ 'adclients',
120
+ array(
121
+ 'methods' => array(
122
+ 'list' => array(
123
+ 'path' => 'accounts/{accountId}/adclients',
124
+ 'httpMethod' => 'GET',
125
+ 'parameters' => array(
126
+ 'accountId' => array(
127
+ 'location' => 'path',
128
+ 'type' => 'string',
129
+ 'required' => true,
130
+ ),
131
+ 'maxResults' => array(
132
+ 'location' => 'query',
133
+ 'type' => 'integer',
134
+ ),
135
+ 'pageToken' => array(
136
+ 'location' => 'query',
137
+ 'type' => 'string',
138
+ ),
139
+ ),
140
+ ),
141
+ )
142
+ )
143
+ );
144
+ $this->accounts_adunits = new Google_Service_AdSense_AccountsAdunits_Resource(
145
+ $this,
146
+ $this->serviceName,
147
+ 'adunits',
148
+ array(
149
+ 'methods' => array(
150
+ 'get' => array(
151
+ 'path' => 'accounts/{accountId}/adclients/{adClientId}/adunits/{adUnitId}',
152
+ 'httpMethod' => 'GET',
153
+ 'parameters' => array(
154
+ 'accountId' => array(
155
+ 'location' => 'path',
156
+ 'type' => 'string',
157
+ 'required' => true,
158
+ ),
159
+ 'adClientId' => array(
160
+ 'location' => 'path',
161
+ 'type' => 'string',
162
+ 'required' => true,
163
+ ),
164
+ 'adUnitId' => array(
165
+ 'location' => 'path',
166
+ 'type' => 'string',
167
+ 'required' => true,
168
+ ),
169
+ ),
170
+ ),'getAdCode' => array(
171
+ 'path' => 'accounts/{accountId}/adclients/{adClientId}/adunits/{adUnitId}/adcode',
172
+ 'httpMethod' => 'GET',
173
+ 'parameters' => array(
174
+ 'accountId' => array(
175
+ 'location' => 'path',
176
+ 'type' => 'string',
177
+ 'required' => true,
178
+ ),
179
+ 'adClientId' => array(
180
+ 'location' => 'path',
181
+ 'type' => 'string',
182
+ 'required' => true,
183
+ ),
184
+ 'adUnitId' => array(
185
+ 'location' => 'path',
186
+ 'type' => 'string',
187
+ 'required' => true,
188
+ ),
189
+ ),
190
+ ),'list' => array(
191
+ 'path' => 'accounts/{accountId}/adclients/{adClientId}/adunits',
192
+ 'httpMethod' => 'GET',
193
+ 'parameters' => array(
194
+ 'accountId' => array(
195
+ 'location' => 'path',
196
+ 'type' => 'string',
197
+ 'required' => true,
198
+ ),
199
+ 'adClientId' => array(
200
+ 'location' => 'path',
201
+ 'type' => 'string',
202
+ 'required' => true,
203
+ ),
204
+ 'includeInactive' => array(
205
+ 'location' => 'query',
206
+ 'type' => 'boolean',
207
+ ),
208
+ 'maxResults' => array(
209
+ 'location' => 'query',
210
+ 'type' => 'integer',
211
+ ),
212
+ 'pageToken' => array(
213
+ 'location' => 'query',
214
+ 'type' => 'string',
215
+ ),
216
+ ),
217
+ ),
218
+ )
219
+ )
220
+ );
221
+ $this->accounts_adunits_customchannels = new Google_Service_AdSense_AccountsAdunitsCustomchannels_Resource(
222
+ $this,
223
+ $this->serviceName,
224
+ 'customchannels',
225
+ array(
226
+ 'methods' => array(
227
+ 'list' => array(
228
+ 'path' => 'accounts/{accountId}/adclients/{adClientId}/adunits/{adUnitId}/customchannels',
229
+ 'httpMethod' => 'GET',
230
+ 'parameters' => array(
231
+ 'accountId' => array(
232
+ 'location' => 'path',
233
+ 'type' => 'string',
234
+ 'required' => true,
235
+ ),
236
+ 'adClientId' => array(
237
+ 'location' => 'path',
238
+ 'type' => 'string',
239
+ 'required' => true,
240
+ ),
241
+ 'adUnitId' => array(
242
+ 'location' => 'path',
243
+ 'type' => 'string',
244
+ 'required' => true,
245
+ ),
246
+ 'maxResults' => array(
247
+ 'location' => 'query',
248
+ 'type' => 'integer',
249
+ ),
250
+ 'pageToken' => array(
251
+ 'location' => 'query',
252
+ 'type' => 'string',
253
+ ),
254
+ ),
255
+ ),
256
+ )
257
+ )
258
+ );
259
+ $this->accounts_alerts = new Google_Service_AdSense_AccountsAlerts_Resource(
260
+ $this,
261
+ $this->serviceName,
262
+ 'alerts',
263
+ array(
264
+ 'methods' => array(
265
+ 'delete' => array(
266
+ 'path' => 'accounts/{accountId}/alerts/{alertId}',
267
+ 'httpMethod' => 'DELETE',
268
+ 'parameters' => array(
269
+ 'accountId' => array(
270
+ 'location' => 'path',
271
+ 'type' => 'string',
272
+ 'required' => true,
273
+ ),
274
+ 'alertId' => array(
275
+ 'location' => 'path',
276
+ 'type' => 'string',
277
+ 'required' => true,
278
+ ),
279
+ ),
280
+ ),'list' => array(
281
+ 'path' => 'accounts/{accountId}/alerts',
282
+ 'httpMethod' => 'GET',
283
+ 'parameters' => array(
284
+ 'accountId' => array(
285
+ 'location' => 'path',
286
+ 'type' => 'string',
287
+ 'required' => true,
288
+ ),
289
+ 'locale' => array(
290
+ 'location' => 'query',
291
+ 'type' => 'string',
292
+ ),
293
+ ),
294
+ ),
295
+ )
296
+ )
297
+ );
298
+ $this->accounts_customchannels = new Google_Service_AdSense_AccountsCustomchannels_Resource(
299
+ $this,
300
+ $this->serviceName,
301
+ 'customchannels',
302
+ array(
303
+ 'methods' => array(
304
+ 'get' => array(
305
+ 'path' => 'accounts/{accountId}/adclients/{adClientId}/customchannels/{customChannelId}',
306
+ 'httpMethod' => 'GET',
307
+ 'parameters' => array(
308
+ 'accountId' => array(
309
+ 'location' => 'path',
310
+ 'type' => 'string',
311
+ 'required' => true,
312
+ ),
313
+ 'adClientId' => array(
314
+ 'location' => 'path',
315
+ 'type' => 'string',
316
+ 'required' => true,
317
+ ),
318
+ 'customChannelId' => array(
319
+ 'location' => 'path',
320
+ 'type' => 'string',
321
+ 'required' => true,
322
+ ),
323
+ ),
324
+ ),'list' => array(
325
+ 'path' => 'accounts/{accountId}/adclients/{adClientId}/customchannels',
326
+ 'httpMethod' => 'GET',
327
+ 'parameters' => array(
328
+ 'accountId' => array(
329
+ 'location' => 'path',
330
+ 'type' => 'string',
331
+ 'required' => true,
332
+ ),
333
+ 'adClientId' => array(
334
+ 'location' => 'path',
335
+ 'type' => 'string',
336
+ 'required' => true,
337
+ ),
338
+ 'maxResults' => array(
339
+ 'location' => 'query',
340
+ 'type' => 'integer',
341
+ ),
342
+ 'pageToken' => array(
343
+ 'location' => 'query',
344
+ 'type' => 'string',
345
+ ),
346
+ ),
347
+ ),
348
+ )
349
+ )
350
+ );
351
+ $this->accounts_customchannels_adunits = new Google_Service_AdSense_AccountsCustomchannelsAdunits_Resource(
352
+ $this,
353
+ $this->serviceName,
354
+ 'adunits',
355
+ array(
356
+ 'methods' => array(
357
+ 'list' => array(
358
+ 'path' => 'accounts/{accountId}/adclients/{adClientId}/customchannels/{customChannelId}/adunits',
359
+ 'httpMethod' => 'GET',
360
+ 'parameters' => array(
361
+ 'accountId' => array(
362
+ 'location' => 'path',
363
+ 'type' => 'string',
364
+ 'required' => true,
365
+ ),
366
+ 'adClientId' => array(
367
+ 'location' => 'path',
368
+ 'type' => 'string',
369
+ 'required' => true,
370
+ ),
371
+ 'customChannelId' => array(
372
+ 'location' => 'path',
373
+ 'type' => 'string',
374
+ 'required' => true,
375
+ ),
376
+ 'includeInactive' => array(
377
+ 'location' => 'query',
378
+ 'type' => 'boolean',
379
+ ),
380
+ 'maxResults' => array(
381
+ 'location' => 'query',
382
+ 'type' => 'integer',
383
+ ),
384
+ 'pageToken' => array(
385
+ 'location' => 'query',
386
+ 'type' => 'string',
387
+ ),
388
+ ),
389
+ ),
390
+ )
391
+ )
392
+ );
393
+ $this->accounts_payments = new Google_Service_AdSense_AccountsPayments_Resource(
394
+ $this,
395
+ $this->serviceName,
396
+ 'payments',
397
+ array(
398
+ 'methods' => array(
399
+ 'list' => array(
400
+ 'path' => 'accounts/{accountId}/payments',
401
+ 'httpMethod' => 'GET',
402
+ 'parameters' => array(
403
+ 'accountId' => array(
404
+ 'location' => 'path',
405
+ 'type' => 'string',
406
+ 'required' => true,
407
+ ),
408
+ ),
409
+ ),
410
+ )
411
+ )
412
+ );
413
+ $this->accounts_reports = new Google_Service_AdSense_AccountsReports_Resource(
414
+ $this,
415
+ $this->serviceName,
416
+ 'reports',
417
+ array(
418
+ 'methods' => array(
419
+ 'generate' => array(
420
+ 'path' => 'accounts/{accountId}/reports',
421
+ 'httpMethod' => 'GET',
422
+ 'parameters' => array(
423
+ 'accountId' => array(
424
+ 'location' => 'path',
425
+ 'type' => 'string',
426
+ 'required' => true,
427
+ ),
428
+ 'startDate' => array(
429
+ 'location' => 'query',
430
+ 'type' => 'string',
431
+ 'required' => true,
432
+ ),
433
+ 'endDate' => array(
434
+ 'location' => 'query',
435
+ 'type' => 'string',
436
+ 'required' => true,
437
+ ),
438
+ 'currency' => array(
439
+ 'location' => 'query',
440
+ 'type' => 'string',
441
+ ),
442
+ 'dimension' => array(
443
+ 'location' => 'query',
444
+ 'type' => 'string',
445
+ 'repeated' => true,
446
+ ),
447
+ 'filter' => array(
448
+ 'location' => 'query',
449
+ 'type' => 'string',
450
+ 'repeated' => true,
451
+ ),
452
+ 'locale' => array(
453
+ 'location' => 'query',
454
+ 'type' => 'string',
455
+ ),
456
+ 'maxResults' => array(
457
+ 'location' => 'query',
458
+ 'type' => 'integer',
459
+ ),
460
+ 'metric' => array(
461
+ 'location' => 'query',
462
+ 'type' => 'string',
463
+ 'repeated' => true,
464
+ ),
465
+ 'sort' => array(
466
+ 'location' => 'query',
467
+ 'type' => 'string',
468
+ 'repeated' => true,
469
+ ),
470
+ 'startIndex' => array(
471
+ 'location' => 'query',
472
+ 'type' => 'integer',
473
+ ),
474
+ 'useTimezoneReporting' => array(
475
+ 'location' => 'query',
476
+ 'type' => 'boolean',
477
+ ),
478
+ ),
479
+ ),
480
+ )
481
+ )
482
+ );
483
+ $this->accounts_reports_saved = new Google_Service_AdSense_AccountsReportsSaved_Resource(
484
+ $this,
485
+ $this->serviceName,
486
+ 'saved',
487
+ array(
488
+ 'methods' => array(
489
+ 'generate' => array(
490
+ 'path' => 'accounts/{accountId}/reports/{savedReportId}',
491
+ 'httpMethod' => 'GET',
492
+ 'parameters' => array(
493
+ 'accountId' => array(
494
+ 'location' => 'path',
495
+ 'type' => 'string',
496
+ 'required' => true,
497
+ ),
498
+ 'savedReportId' => array(
499
+ 'location' => 'path',
500
+ 'type' => 'string',
501
+ 'required' => true,
502
+ ),
503
+ 'locale' => array(
504
+ 'location' => 'query',
505
+ 'type' => 'string',
506
+ ),
507
+ 'maxResults' => array(
508
+ 'location' => 'query',
509
+ 'type' => 'integer',
510
+ ),
511
+ 'startIndex' => array(
512
+ 'location' => 'query',
513
+ 'type' => 'integer',
514
+ ),
515
+ ),
516
+ ),'list' => array(
517
+ 'path' => 'accounts/{accountId}/reports/saved',
518
+ 'httpMethod' => 'GET',
519
+ 'parameters' => array(
520
+ 'accountId' => array(
521
+ 'location' => 'path',
522
+ 'type' => 'string',
523
+ 'required' => true,
524
+ ),
525
+ 'maxResults' => array(
526
+ 'location' => 'query',
527
+ 'type' => 'integer',
528
+ ),
529
+ 'pageToken' => array(
530
+ 'location' => 'query',
531
+ 'type' => 'string',
532
+ ),
533
+ ),
534
+ ),
535
+ )
536
+ )
537
+ );
538
+ $this->accounts_savedadstyles = new Google_Service_AdSense_AccountsSavedadstyles_Resource(
539
+ $this,
540
+ $this->serviceName,
541
+ 'savedadstyles',
542
+ array(
543
+ 'methods' => array(
544
+ 'get' => array(
545
+ 'path' => 'accounts/{accountId}/savedadstyles/{savedAdStyleId}',
546
+ 'httpMethod' => 'GET',
547
+ 'parameters' => array(
548
+ 'accountId' => array(
549
+ 'location' => 'path',
550
+ 'type' => 'string',
551
+ 'required' => true,
552
+ ),
553
+ 'savedAdStyleId' => array(
554
+ 'location' => 'path',
555
+ 'type' => 'string',
556
+ 'required' => true,
557
+ ),
558
+ ),
559
+ ),'list' => array(
560
+ 'path' => 'accounts/{accountId}/savedadstyles',
561
+ 'httpMethod' => 'GET',
562
+ 'parameters' => array(
563
+ 'accountId' => array(
564
+ 'location' => 'path',
565
+ 'type' => 'string',
566
+ 'required' => true,
567
+ ),
568
+ 'maxResults' => array(
569
+ 'location' => 'query',
570
+ 'type' => 'integer',
571
+ ),
572
+ 'pageToken' => array(
573
+ 'location' => 'query',
574
+ 'type' => 'string',
575
+ ),
576
+ ),
577
+ ),
578
+ )
579
+ )
580
+ );
581
+ $this->accounts_urlchannels = new Google_Service_AdSense_AccountsUrlchannels_Resource(
582
+ $this,
583
+ $this->serviceName,
584
+ 'urlchannels',
585
+ array(
586
+ 'methods' => array(
587
+ 'list' => array(
588
+ 'path' => 'accounts/{accountId}/adclients/{adClientId}/urlchannels',
589
+ 'httpMethod' => 'GET',
590
+ 'parameters' => array(
591
+ 'accountId' => array(
592
+ 'location' => 'path',
593
+ 'type' => 'string',
594
+ 'required' => true,
595
+ ),
596
+ 'adClientId' => array(
597
+ 'location' => 'path',
598
+ 'type' => 'string',
599
+ 'required' => true,
600
+ ),
601
+ 'maxResults' => array(
602
+ 'location' => 'query',
603
+ 'type' => 'integer',
604
+ ),
605
+ 'pageToken' => array(
606
+ 'location' => 'query',
607
+ 'type' => 'string',
608
+ ),
609
+ ),
610
+ ),
611
+ )
612
+ )
613
+ );
614
+ $this->adclients = new Google_Service_AdSense_Adclients_Resource(
615
+ $this,
616
+ $this->serviceName,
617
+ 'adclients',
618
+ array(
619
+ 'methods' => array(
620
+ 'list' => array(
621
+ 'path' => 'adclients',
622
+ 'httpMethod' => 'GET',
623
+ 'parameters' => array(
624
+ 'maxResults' => array(
625
+ 'location' => 'query',
626
+ 'type' => 'integer',
627
+ ),
628
+ 'pageToken' => array(
629
+ 'location' => 'query',
630
+ 'type' => 'string',
631
+ ),
632
+ ),
633
+ ),
634
+ )
635
+ )
636
+ );
637
+ $this->adunits = new Google_Service_AdSense_Adunits_Resource(
638
+ $this,
639
+ $this->serviceName,
640
+ 'adunits',
641
+ array(
642
+ 'methods' => array(
643
+ 'get' => array(
644
+ 'path' => 'adclients/{adClientId}/adunits/{adUnitId}',
645
+ 'httpMethod' => 'GET',
646
+ 'parameters' => array(
647
+ 'adClientId' => array(
648
+ 'location' => 'path',
649
+ 'type' => 'string',
650
+ 'required' => true,
651
+ ),
652
+ 'adUnitId' => array(
653
+ 'location' => 'path',
654
+ 'type' => 'string',
655
+ 'required' => true,
656
+ ),
657
+ ),
658
+ ),'getAdCode' => array(
659
+ 'path' => 'adclients/{adClientId}/adunits/{adUnitId}/adcode',
660
+ 'httpMethod' => 'GET',
661
+ 'parameters' => array(
662
+ 'adClientId' => array(
663
+ 'location' => 'path',
664
+ 'type' => 'string',
665
+ 'required' => true,
666
+ ),
667
+ 'adUnitId' => array(
668
+ 'location' => 'path',
669
+ 'type' => 'string',
670
+ 'required' => true,
671
+ ),
672
+ ),
673
+ ),'list' => array(
674
+ 'path' => 'adclients/{adClientId}/adunits',
675
+ 'httpMethod' => 'GET',
676
+ 'parameters' => array(
677
+ 'adClientId' => array(
678
+ 'location' => 'path',
679
+ 'type' => 'string',
680
+ 'required' => true,
681
+ ),
682
+ 'includeInactive' => array(
683
+ 'location' => 'query',
684
+ 'type' => 'boolean',
685
+ ),
686
+ 'maxResults' => array(
687
+ 'location' => 'query',
688
+ 'type' => 'integer',
689
+ ),
690
+ 'pageToken' => array(
691
+ 'location' => 'query',
692
+ 'type' => 'string',
693
+ ),
694
+ ),
695
+ ),
696
+ )
697
+ )
698
+ );
699
+ $this->adunits_customchannels = new Google_Service_AdSense_AdunitsCustomchannels_Resource(
700
+ $this,
701
+ $this->serviceName,
702
+ 'customchannels',
703
+ array(
704
+ 'methods' => array(
705
+ 'list' => array(
706
+ 'path' => 'adclients/{adClientId}/adunits/{adUnitId}/customchannels',
707
+ 'httpMethod' => 'GET',
708
+ 'parameters' => array(
709
+ 'adClientId' => array(
710
+ 'location' => 'path',
711
+ 'type' => 'string',
712
+ 'required' => true,
713
+ ),
714
+ 'adUnitId' => array(
715
+ 'location' => 'path',
716
+ 'type' => 'string',
717
+ 'required' => true,
718
+ ),
719
+ 'maxResults' => array(
720
+ 'location' => 'query',
721
+ 'type' => 'integer',
722
+ ),
723
+ 'pageToken' => array(
724
+ 'location' => 'query',
725
+ 'type' => 'string',
726
+ ),
727
+ ),
728
+ ),
729
+ )
730
+ )
731
+ );
732
+ $this->alerts = new Google_Service_AdSense_Alerts_Resource(
733
+ $this,
734
+ $this->serviceName,
735
+ 'alerts',
736
+ array(
737
+ 'methods' => array(
738
+ 'delete' => array(
739
+ 'path' => 'alerts/{alertId}',
740
+ 'httpMethod' => 'DELETE',
741
+ 'parameters' => array(
742
+ 'alertId' => array(
743
+ 'location' => 'path',
744
+ 'type' => 'string',
745
+ 'required' => true,
746
+ ),
747
+ ),
748
+ ),'list' => array(
749
+ 'path' => 'alerts',
750
+ 'httpMethod' => 'GET',
751
+ 'parameters' => array(
752
+ 'locale' => array(
753
+ 'location' => 'query',
754
+ 'type' => 'string',
755
+ ),
756
+ ),
757
+ ),
758
+ )
759
+ )
760
+ );
761
+ $this->customchannels = new Google_Service_AdSense_Customchannels_Resource(
762
+ $this,
763
+ $this->serviceName,
764
+ 'customchannels',
765
+ array(
766
+ 'methods' => array(
767
+ 'get' => array(
768
+ 'path' => 'adclients/{adClientId}/customchannels/{customChannelId}',
769
+ 'httpMethod' => 'GET',
770
+ 'parameters' => array(
771
+ 'adClientId' => array(
772
+ 'location' => 'path',
773
+ 'type' => 'string',
774
+ 'required' => true,
775
+ ),
776
+ 'customChannelId' => array(
777
+ 'location' => 'path',
778
+ 'type' => 'string',
779
+ 'required' => true,
780
+ ),
781
+ ),
782
+ ),'list' => array(
783
+ 'path' => 'adclients/{adClientId}/customchannels',
784
+ 'httpMethod' => 'GET',
785
+ 'parameters' => array(
786
+ 'adClientId' => array(
787
+ 'location' => 'path',
788
+ 'type' => 'string',
789
+ 'required' => true,
790
+ ),
791
+ 'maxResults' => array(
792
+ 'location' => 'query',
793
+ 'type' => 'integer',
794
+ ),
795
+ 'pageToken' => array(
796
+ 'location' => 'query',
797
+ 'type' => 'string',
798
+ ),
799
+ ),
800
+ ),
801
+ )
802
+ )
803
+ );
804
+ $this->customchannels_adunits = new Google_Service_AdSense_CustomchannelsAdunits_Resource(
805
+ $this,
806
+ $this->serviceName,
807
+ 'adunits',
808
+ array(
809
+ 'methods' => array(
810
+ 'list' => array(
811
+ 'path' => 'adclients/{adClientId}/customchannels/{customChannelId}/adunits',
812
+ 'httpMethod' => 'GET',
813
+ 'parameters' => array(
814
+ 'adClientId' => array(
815
+ 'location' => 'path',
816
+ 'type' => 'string',
817
+ 'required' => true,
818
+ ),
819
+ 'customChannelId' => array(
820
+ 'location' => 'path',
821
+ 'type' => 'string',
822
+ 'required' => true,
823
+ ),
824
+ 'includeInactive' => array(
825
+ 'location' => 'query',
826
+ 'type' => 'boolean',
827
+ ),
828
+ 'maxResults' => array(
829
+ 'location' => 'query',
830
+ 'type' => 'integer',
831
+ ),
832
+ 'pageToken' => array(
833
+ 'location' => 'query',
834
+ 'type' => 'string',
835
+ ),
836
+ ),
837
+ ),
838
+ )
839
+ )
840
+ );
841
+ $this->metadata_dimensions = new Google_Service_AdSense_MetadataDimensions_Resource(
842
+ $this,
843
+ $this->serviceName,
844
+ 'dimensions',
845
+ array(
846
+ 'methods' => array(
847
+ 'list' => array(
848
+ 'path' => 'metadata/dimensions',
849
+ 'httpMethod' => 'GET',
850
+ 'parameters' => array(),
851
+ ),
852
+ )
853
+ )
854
+ );
855
+ $this->metadata_metrics = new Google_Service_AdSense_MetadataMetrics_Resource(
856
+ $this,
857
+ $this->serviceName,
858
+ 'metrics',
859
+ array(
860
+ 'methods' => array(
861
+ 'list' => array(
862
+ 'path' => 'metadata/metrics',
863
+ 'httpMethod' => 'GET',
864
+ 'parameters' => array(),
865
+ ),
866
+ )
867
+ )
868
+ );
869
+ $this->payments = new Google_Service_AdSense_Payments_Resource(
870
+ $this,
871
+ $this->serviceName,
872
+ 'payments',
873
+ array(
874
+ 'methods' => array(
875
+ 'list' => array(
876
+ 'path' => 'payments',
877
+ 'httpMethod' => 'GET',
878
+ 'parameters' => array(),
879
+ ),
880
+ )
881
+ )
882
+ );
883
+ $this->reports = new Google_Service_AdSense_Reports_Resource(
884
+ $this,
885
+ $this->serviceName,
886
+ 'reports',
887
+ array(
888
+ 'methods' => array(
889
+ 'generate' => array(
890
+ 'path' => 'reports',
891
+ 'httpMethod' => 'GET',
892
+ 'parameters' => array(
893
+ 'startDate' => array(
894
+ 'location' => 'query',
895
+ 'type' => 'string',
896
+ 'required' => true,
897
+ ),
898
+ 'endDate' => array(
899
+ 'location' => 'query',
900
+ 'type' => 'string',
901
+ 'required' => true,
902
+ ),
903
+ 'accountId' => array(
904
+ 'location' => 'query',
905
+ 'type' => 'string',
906
+ 'repeated' => true,
907
+ ),
908
+ 'currency' => array(
909
+ 'location' => 'query',
910
+ 'type' => 'string',
911
+ ),
912
+ 'dimension' => array(
913
+ 'location' => 'query',
914
+ 'type' => 'string',
915
+ 'repeated' => true,
916
+ ),
917
+ 'filter' => array(
918
+ 'location' => 'query',
919
+ 'type' => 'string',
920
+ 'repeated' => true,
921
+ ),
922
+ 'locale' => array(
923
+ 'location' => 'query',
924
+ 'type' => 'string',
925
+ ),
926
+ 'maxResults' => array(
927
+ 'location' => 'query',
928
+ 'type' => 'integer',
929
+ ),
930
+ 'metric' => array(
931
+ 'location' => 'query',
932
+ 'type' => 'string',
933
+ 'repeated' => true,
934
+ ),
935
+ 'sort' => array(
936
+ 'location' => 'query',
937
+ 'type' => 'string',
938
+ 'repeated' => true,
939
+ ),
940
+ 'startIndex' => array(
941
+ 'location' => 'query',
942
+ 'type' => 'integer',
943
+ ),
944
+ 'useTimezoneReporting' => array(
945
+ 'location' => 'query',
946
+ 'type' => 'boolean',
947
+ ),
948
+ ),
949
+ ),
950
+ )
951
+ )
952
+ );
953
+ $this->reports_saved = new Google_Service_AdSense_ReportsSaved_Resource(
954
+ $this,
955
+ $this->serviceName,
956
+ 'saved',
957
+ array(
958
+ 'methods' => array(
959
+ 'generate' => array(
960
+ 'path' => 'reports/{savedReportId}',
961
+ 'httpMethod' => 'GET',
962
+ 'parameters' => array(
963
+ 'savedReportId' => array(
964
+ 'location' => 'path',
965
+ 'type' => 'string',
966
+ 'required' => true,
967
+ ),
968
+ 'locale' => array(
969
+ 'location' => 'query',
970
+ 'type' => 'string',
971
+ ),
972
+ 'maxResults' => array(
973
+ 'location' => 'query',
974
+ 'type' => 'integer',
975
+ ),
976
+ 'startIndex' => array(
977
+ 'location' => 'query',
978
+ 'type' => 'integer',
979
+ ),
980
+ ),
981
+ ),'list' => array(
982
+ 'path' => 'reports/saved',
983
+ 'httpMethod' => 'GET',
984
+ 'parameters' => array(
985
+ 'maxResults' => array(
986
+ 'location' => 'query',
987
+ 'type' => 'integer',
988
+ ),
989
+ 'pageToken' => array(
990
+ 'location' => 'query',
991
+ 'type' => 'string',
992
+ ),
993
+ ),
994
+ ),
995
+ )
996
+ )
997
+ );
998
+ $this->savedadstyles = new Google_Service_AdSense_Savedadstyles_Resource(
999
+ $this,
1000
+ $this->serviceName,
1001
+ 'savedadstyles',
1002
+ array(
1003
+ 'methods' => array(
1004
+ 'get' => array(
1005
+ 'path' => 'savedadstyles/{savedAdStyleId}',
1006
+ 'httpMethod' => 'GET',
1007
+ 'parameters' => array(
1008
+ 'savedAdStyleId' => array(
1009
+ 'location' => 'path',
1010
+ 'type' => 'string',
1011
+ 'required' => true,
1012
+ ),
1013
+ ),
1014
+ ),'list' => array(
1015
+ 'path' => 'savedadstyles',
1016
+ 'httpMethod' => 'GET',
1017
+ 'parameters' => array(
1018
+ 'maxResults' => array(
1019
+ 'location' => 'query',
1020
+ 'type' => 'integer',
1021
+ ),
1022
+ 'pageToken' => array(
1023
+ 'location' => 'query',
1024
+ 'type' => 'string',
1025
+ ),
1026
+ ),
1027
+ ),
1028
+ )
1029
+ )
1030
+ );
1031
+ $this->urlchannels = new Google_Service_AdSense_Urlchannels_Resource(
1032
+ $this,
1033
+ $this->serviceName,
1034
+ 'urlchannels',
1035
+ array(
1036
+ 'methods' => array(
1037
+ 'list' => array(
1038
+ 'path' => 'adclients/{adClientId}/urlchannels',
1039
+ 'httpMethod' => 'GET',
1040
+ 'parameters' => array(
1041
+ 'adClientId' => array(
1042
+ 'location' => 'path',
1043
+ 'type' => 'string',
1044
+ 'required' => true,
1045
+ ),
1046
+ 'maxResults' => array(
1047
+ 'location' => 'query',
1048
+ 'type' => 'integer',
1049
+ ),
1050
+ 'pageToken' => array(
1051
+ 'location' => 'query',
1052
+ 'type' => 'string',
1053
+ ),
1054
+ ),
1055
+ ),
1056
+ )
1057
+ )
1058
+ );
1059
+ }
1060
+ }
1061
+
1062
+
1063
+ /**
1064
+ * The "accounts" collection of methods.
1065
+ * Typical usage is:
1066
+ * <code>
1067
+ * $adsenseService = new Google_Service_AdSense(...);
1068
+ * $accounts = $adsenseService->accounts;
1069
+ * </code>
1070
+ */
1071
+ class Google_Service_AdSense_Accounts_Resource extends Google_Service_Resource
1072
+ {
1073
+
1074
+ /**
1075
+ * Get information about the selected AdSense account. (accounts.get)
1076
+ *
1077
+ * @param string $accountId Account to get information about.
1078
+ * @param array $optParams Optional parameters.
1079
+ *
1080
+ * @opt_param bool tree Whether the tree of sub accounts should be returned.
1081
+ * @return Google_Service_AdSense_Account
1082
+ */
1083
+ public function get($accountId, $optParams = array())
1084
+ {
1085
+ $params = array('accountId' => $accountId);
1086
+ $params = array_merge($params, $optParams);
1087
+ return $this->call('get', array($params), "Google_Service_AdSense_Account");
1088
+ }
1089
+
1090
+ /**
1091
+ * List all accounts available to this AdSense account. (accounts.listAccounts)
1092
+ *
1093
+ * @param array $optParams Optional parameters.
1094
+ *
1095
+ * @opt_param int maxResults The maximum number of accounts to include in the
1096
+ * response, used for paging.
1097
+ * @opt_param string pageToken A continuation token, used to page through
1098
+ * accounts. To retrieve the next page, set this parameter to the value of
1099
+ * "nextPageToken" from the previous response.
1100
+ * @return Google_Service_AdSense_Accounts
1101
+ */
1102
+ public function listAccounts($optParams = array())
1103
+ {
1104
+ $params = array();
1105
+ $params = array_merge($params, $optParams);
1106
+ return $this->call('list', array($params), "Google_Service_AdSense_Accounts");
1107
+ }
1108
+ }
1109
+
1110
+ /**
1111
+ * The "adclients" collection of methods.
1112
+ * Typical usage is:
1113
+ * <code>
1114
+ * $adsenseService = new Google_Service_AdSense(...);
1115
+ * $adclients = $adsenseService->adclients;
1116
+ * </code>
1117
+ */
1118
+ class Google_Service_AdSense_AccountsAdclients_Resource extends Google_Service_Resource
1119
+ {
1120
+
1121
+ /**
1122
+ * List all ad clients in the specified account.
1123
+ * (adclients.listAccountsAdclients)
1124
+ *
1125
+ * @param string $accountId Account for which to list ad clients.
1126
+ * @param array $optParams Optional parameters.
1127
+ *
1128
+ * @opt_param int maxResults The maximum number of ad clients to include in the
1129
+ * response, used for paging.
1130
+ * @opt_param string pageToken A continuation token, used to page through ad
1131
+ * clients. To retrieve the next page, set this parameter to the value of
1132
+ * "nextPageToken" from the previous response.
1133
+ * @return Google_Service_AdSense_AdClients
1134
+ */
1135
+ public function listAccountsAdclients($accountId, $optParams = array())
1136
+ {
1137
+ $params = array('accountId' => $accountId);
1138
+ $params = array_merge($params, $optParams);
1139
+ return $this->call('list', array($params), "Google_Service_AdSense_AdClients");
1140
+ }
1141
+ }
1142
+ /**
1143
+ * The "adunits" collection of methods.
1144
+ * Typical usage is:
1145
+ * <code>
1146
+ * $adsenseService = new Google_Service_AdSense(...);
1147
+ * $adunits = $adsenseService->adunits;
1148
+ * </code>
1149
+ */
1150
+ class Google_Service_AdSense_AccountsAdunits_Resource extends Google_Service_Resource
1151
+ {
1152
+
1153
+ /**
1154
+ * Gets the specified ad unit in the specified ad client for the specified
1155
+ * account. (adunits.get)
1156
+ *
1157
+ * @param string $accountId Account to which the ad client belongs.
1158
+ * @param string $adClientId Ad client for which to get the ad unit.
1159
+ * @param string $adUnitId Ad unit to retrieve.
1160
+ * @param array $optParams Optional parameters.
1161
+ * @return Google_Service_AdSense_AdUnit
1162
+ */
1163
+ public function get($accountId, $adClientId, $adUnitId, $optParams = array())
1164
+ {
1165
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId, 'adUnitId' => $adUnitId);
1166
+ $params = array_merge($params, $optParams);
1167
+ return $this->call('get', array($params), "Google_Service_AdSense_AdUnit");
1168
+ }
1169
+
1170
+ /**
1171
+ * Get ad code for the specified ad unit. (adunits.getAdCode)
1172
+ *
1173
+ * @param string $accountId Account which contains the ad client.
1174
+ * @param string $adClientId Ad client with contains the ad unit.
1175
+ * @param string $adUnitId Ad unit to get the code for.
1176
+ * @param array $optParams Optional parameters.
1177
+ * @return Google_Service_AdSense_AdCode
1178
+ */
1179
+ public function getAdCode($accountId, $adClientId, $adUnitId, $optParams = array())
1180
+ {
1181
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId, 'adUnitId' => $adUnitId);
1182
+ $params = array_merge($params, $optParams);
1183
+ return $this->call('getAdCode', array($params), "Google_Service_AdSense_AdCode");
1184
+ }
1185
+
1186
+ /**
1187
+ * List all ad units in the specified ad client for the specified account.
1188
+ * (adunits.listAccountsAdunits)
1189
+ *
1190
+ * @param string $accountId Account to which the ad client belongs.
1191
+ * @param string $adClientId Ad client for which to list ad units.
1192
+ * @param array $optParams Optional parameters.
1193
+ *
1194
+ * @opt_param bool includeInactive Whether to include inactive ad units.
1195
+ * Default: true.
1196
+ * @opt_param int maxResults The maximum number of ad units to include in the
1197
+ * response, used for paging.
1198
+ * @opt_param string pageToken A continuation token, used to page through ad
1199
+ * units. To retrieve the next page, set this parameter to the value of
1200
+ * "nextPageToken" from the previous response.
1201
+ * @return Google_Service_AdSense_AdUnits
1202
+ */
1203
+ public function listAccountsAdunits($accountId, $adClientId, $optParams = array())
1204
+ {
1205
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId);
1206
+ $params = array_merge($params, $optParams);
1207
+ return $this->call('list', array($params), "Google_Service_AdSense_AdUnits");
1208
+ }
1209
+ }
1210
+
1211
+ /**
1212
+ * The "customchannels" collection of methods.
1213
+ * Typical usage is:
1214
+ * <code>
1215
+ * $adsenseService = new Google_Service_AdSense(...);
1216
+ * $customchannels = $adsenseService->customchannels;
1217
+ * </code>
1218
+ */
1219
+ class Google_Service_AdSense_AccountsAdunitsCustomchannels_Resource extends Google_Service_Resource
1220
+ {
1221
+
1222
+ /**
1223
+ * List all custom channels which the specified ad unit belongs to.
1224
+ * (customchannels.listAccountsAdunitsCustomchannels)
1225
+ *
1226
+ * @param string $accountId Account to which the ad client belongs.
1227
+ * @param string $adClientId Ad client which contains the ad unit.
1228
+ * @param string $adUnitId Ad unit for which to list custom channels.
1229
+ * @param array $optParams Optional parameters.
1230
+ *
1231
+ * @opt_param int maxResults The maximum number of custom channels to include in
1232
+ * the response, used for paging.
1233
+ * @opt_param string pageToken A continuation token, used to page through custom
1234
+ * channels. To retrieve the next page, set this parameter to the value of
1235
+ * "nextPageToken" from the previous response.
1236
+ * @return Google_Service_AdSense_CustomChannels
1237
+ */
1238
+ public function listAccountsAdunitsCustomchannels($accountId, $adClientId, $adUnitId, $optParams = array())
1239
+ {
1240
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId, 'adUnitId' => $adUnitId);
1241
+ $params = array_merge($params, $optParams);
1242
+ return $this->call('list', array($params), "Google_Service_AdSense_CustomChannels");
1243
+ }
1244
+ }
1245
+ /**
1246
+ * The "alerts" collection of methods.
1247
+ * Typical usage is:
1248
+ * <code>
1249
+ * $adsenseService = new Google_Service_AdSense(...);
1250
+ * $alerts = $adsenseService->alerts;
1251
+ * </code>
1252
+ */
1253
+ class Google_Service_AdSense_AccountsAlerts_Resource extends Google_Service_Resource
1254
+ {
1255
+
1256
+ /**
1257
+ * Dismiss (delete) the specified alert from the specified publisher AdSense
1258
+ * account. (alerts.delete)
1259
+ *
1260
+ * @param string $accountId Account which contains the ad unit.
1261
+ * @param string $alertId Alert to delete.
1262
+ * @param array $optParams Optional parameters.
1263
+ */
1264
+ public function delete($accountId, $alertId, $optParams = array())
1265
+ {
1266
+ $params = array('accountId' => $accountId, 'alertId' => $alertId);
1267
+ $params = array_merge($params, $optParams);
1268
+ return $this->call('delete', array($params));
1269
+ }
1270
+
1271
+ /**
1272
+ * List the alerts for the specified AdSense account.
1273
+ * (alerts.listAccountsAlerts)
1274
+ *
1275
+ * @param string $accountId Account for which to retrieve the alerts.
1276
+ * @param array $optParams Optional parameters.
1277
+ *
1278
+ * @opt_param string locale The locale to use for translating alert messages.
1279
+ * The account locale will be used if this is not supplied. The AdSense default
1280
+ * (English) will be used if the supplied locale is invalid or unsupported.
1281
+ * @return Google_Service_AdSense_Alerts
1282
+ */
1283
+ public function listAccountsAlerts($accountId, $optParams = array())
1284
+ {
1285
+ $params = array('accountId' => $accountId);
1286
+ $params = array_merge($params, $optParams);
1287
+ return $this->call('list', array($params), "Google_Service_AdSense_Alerts");
1288
+ }
1289
+ }
1290
+ /**
1291
+ * The "customchannels" collection of methods.
1292
+ * Typical usage is:
1293
+ * <code>
1294
+ * $adsenseService = new Google_Service_AdSense(...);
1295
+ * $customchannels = $adsenseService->customchannels;
1296
+ * </code>
1297
+ */
1298
+ class Google_Service_AdSense_AccountsCustomchannels_Resource extends Google_Service_Resource
1299
+ {
1300
+
1301
+ /**
1302
+ * Get the specified custom channel from the specified ad client for the
1303
+ * specified account. (customchannels.get)
1304
+ *
1305
+ * @param string $accountId Account to which the ad client belongs.
1306
+ * @param string $adClientId Ad client which contains the custom channel.
1307
+ * @param string $customChannelId Custom channel to retrieve.
1308
+ * @param array $optParams Optional parameters.
1309
+ * @return Google_Service_AdSense_CustomChannel
1310
+ */
1311
+ public function get($accountId, $adClientId, $customChannelId, $optParams = array())
1312
+ {
1313
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId, 'customChannelId' => $customChannelId);
1314
+ $params = array_merge($params, $optParams);
1315
+ return $this->call('get', array($params), "Google_Service_AdSense_CustomChannel");
1316
+ }
1317
+
1318
+ /**
1319
+ * List all custom channels in the specified ad client for the specified
1320
+ * account. (customchannels.listAccountsCustomchannels)
1321
+ *
1322
+ * @param string $accountId Account to which the ad client belongs.
1323
+ * @param string $adClientId Ad client for which to list custom channels.
1324
+ * @param array $optParams Optional parameters.
1325
+ *
1326
+ * @opt_param int maxResults The maximum number of custom channels to include in
1327
+ * the response, used for paging.
1328
+ * @opt_param string pageToken A continuation token, used to page through custom
1329
+ * channels. To retrieve the next page, set this parameter to the value of
1330
+ * "nextPageToken" from the previous response.
1331
+ * @return Google_Service_AdSense_CustomChannels
1332
+ */
1333
+ public function listAccountsCustomchannels($accountId, $adClientId, $optParams = array())
1334
+ {
1335
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId);
1336
+ $params = array_merge($params, $optParams);
1337
+ return $this->call('list', array($params), "Google_Service_AdSense_CustomChannels");
1338
+ }
1339
+ }
1340
+
1341
+ /**
1342
+ * The "adunits" collection of methods.
1343
+ * Typical usage is:
1344
+ * <code>
1345
+ * $adsenseService = new Google_Service_AdSense(...);
1346
+ * $adunits = $adsenseService->adunits;
1347
+ * </code>
1348
+ */
1349
+ class Google_Service_AdSense_AccountsCustomchannelsAdunits_Resource extends Google_Service_Resource
1350
+ {
1351
+
1352
+ /**
1353
+ * List all ad units in the specified custom channel.
1354
+ * (adunits.listAccountsCustomchannelsAdunits)
1355
+ *
1356
+ * @param string $accountId Account to which the ad client belongs.
1357
+ * @param string $adClientId Ad client which contains the custom channel.
1358
+ * @param string $customChannelId Custom channel for which to list ad units.
1359
+ * @param array $optParams Optional parameters.
1360
+ *
1361
+ * @opt_param bool includeInactive Whether to include inactive ad units.
1362
+ * Default: true.
1363
+ * @opt_param int maxResults The maximum number of ad units to include in the
1364
+ * response, used for paging.
1365
+ * @opt_param string pageToken A continuation token, used to page through ad
1366
+ * units. To retrieve the next page, set this parameter to the value of
1367
+ * "nextPageToken" from the previous response.
1368
+ * @return Google_Service_AdSense_AdUnits
1369
+ */
1370
+ public function listAccountsCustomchannelsAdunits($accountId, $adClientId, $customChannelId, $optParams = array())
1371
+ {
1372
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId, 'customChannelId' => $customChannelId);
1373
+ $params = array_merge($params, $optParams);
1374
+ return $this->call('list', array($params), "Google_Service_AdSense_AdUnits");
1375
+ }
1376
+ }
1377
+ /**
1378
+ * The "payments" collection of methods.
1379
+ * Typical usage is:
1380
+ * <code>
1381
+ * $adsenseService = new Google_Service_AdSense(...);
1382
+ * $payments = $adsenseService->payments;
1383
+ * </code>
1384
+ */
1385
+ class Google_Service_AdSense_AccountsPayments_Resource extends Google_Service_Resource
1386
+ {
1387
+
1388
+ /**
1389
+ * List the payments for the specified AdSense account.
1390
+ * (payments.listAccountsPayments)
1391
+ *
1392
+ * @param string $accountId Account for which to retrieve the payments.
1393
+ * @param array $optParams Optional parameters.
1394
+ * @return Google_Service_AdSense_Payments
1395
+ */
1396
+ public function listAccountsPayments($accountId, $optParams = array())
1397
+ {
1398
+ $params = array('accountId' => $accountId);
1399
+ $params = array_merge($params, $optParams);
1400
+ return $this->call('list', array($params), "Google_Service_AdSense_Payments");
1401
+ }
1402
+ }
1403
+ /**
1404
+ * The "reports" collection of methods.
1405
+ * Typical usage is:
1406
+ * <code>
1407
+ * $adsenseService = new Google_Service_AdSense(...);
1408
+ * $reports = $adsenseService->reports;
1409
+ * </code>
1410
+ */
1411
+ class Google_Service_AdSense_AccountsReports_Resource extends Google_Service_Resource
1412
+ {
1413
+
1414
+ /**
1415
+ * Generate an AdSense report based on the report request sent in the query
1416
+ * parameters. Returns the result as JSON; to retrieve output in CSV format
1417
+ * specify "alt=csv" as a query parameter. (reports.generate)
1418
+ *
1419
+ * @param string $accountId Account upon which to report.
1420
+ * @param string $startDate Start of the date range to report on in "YYYY-MM-DD"
1421
+ * format, inclusive.
1422
+ * @param string $endDate End of the date range to report on in "YYYY-MM-DD"
1423
+ * format, inclusive.
1424
+ * @param array $optParams Optional parameters.
1425
+ *
1426
+ * @opt_param string currency Optional currency to use when reporting on
1427
+ * monetary metrics. Defaults to the account's currency if not set.
1428
+ * @opt_param string dimension Dimensions to base the report on.
1429
+ * @opt_param string filter Filters to be run on the report.
1430
+ * @opt_param string locale Optional locale to use for translating report output
1431
+ * to a local language. Defaults to "en_US" if not specified.
1432
+ * @opt_param int maxResults The maximum number of rows of report data to
1433
+ * return.
1434
+ * @opt_param string metric Numeric columns to include in the report.
1435
+ * @opt_param string sort The name of a dimension or metric to sort the
1436
+ * resulting report on, optionally prefixed with "+" to sort ascending or "-" to
1437
+ * sort descending. If no prefix is specified, the column is sorted ascending.
1438
+ * @opt_param int startIndex Index of the first row of report data to return.
1439
+ * @opt_param bool useTimezoneReporting Whether the report should be generated
1440
+ * in the AdSense account's local timezone. If false default PST/PDT timezone
1441
+ * will be used.
1442
+ * @return Google_Service_AdSense_AdsenseReportsGenerateResponse
1443
+ */
1444
+ public function generate($accountId, $startDate, $endDate, $optParams = array())
1445
+ {
1446
+ $params = array('accountId' => $accountId, 'startDate' => $startDate, 'endDate' => $endDate);
1447
+ $params = array_merge($params, $optParams);
1448
+ return $this->call('generate', array($params), "Google_Service_AdSense_AdsenseReportsGenerateResponse");
1449
+ }
1450
+ }
1451
+
1452
+ /**
1453
+ * The "saved" collection of methods.
1454
+ * Typical usage is:
1455
+ * <code>
1456
+ * $adsenseService = new Google_Service_AdSense(...);
1457
+ * $saved = $adsenseService->saved;
1458
+ * </code>
1459
+ */
1460
+ class Google_Service_AdSense_AccountsReportsSaved_Resource extends Google_Service_Resource
1461
+ {
1462
+
1463
+ /**
1464
+ * Generate an AdSense report based on the saved report ID sent in the query
1465
+ * parameters. (saved.generate)
1466
+ *
1467
+ * @param string $accountId Account to which the saved reports belong.
1468
+ * @param string $savedReportId The saved report to retrieve.
1469
+ * @param array $optParams Optional parameters.
1470
+ *
1471
+ * @opt_param string locale Optional locale to use for translating report output
1472
+ * to a local language. Defaults to "en_US" if not specified.
1473
+ * @opt_param int maxResults The maximum number of rows of report data to
1474
+ * return.
1475
+ * @opt_param int startIndex Index of the first row of report data to return.
1476
+ * @return Google_Service_AdSense_AdsenseReportsGenerateResponse
1477
+ */
1478
+ public function generate($accountId, $savedReportId, $optParams = array())
1479
+ {
1480
+ $params = array('accountId' => $accountId, 'savedReportId' => $savedReportId);
1481
+ $params = array_merge($params, $optParams);
1482
+ return $this->call('generate', array($params), "Google_Service_AdSense_AdsenseReportsGenerateResponse");
1483
+ }
1484
+
1485
+ /**
1486
+ * List all saved reports in the specified AdSense account.
1487
+ * (saved.listAccountsReportsSaved)
1488
+ *
1489
+ * @param string $accountId Account to which the saved reports belong.
1490
+ * @param array $optParams Optional parameters.
1491
+ *
1492
+ * @opt_param int maxResults The maximum number of saved reports to include in
1493
+ * the response, used for paging.
1494
+ * @opt_param string pageToken A continuation token, used to page through saved
1495
+ * reports. To retrieve the next page, set this parameter to the value of
1496
+ * "nextPageToken" from the previous response.
1497
+ * @return Google_Service_AdSense_SavedReports
1498
+ */
1499
+ public function listAccountsReportsSaved($accountId, $optParams = array())
1500
+ {
1501
+ $params = array('accountId' => $accountId);
1502
+ $params = array_merge($params, $optParams);
1503
+ return $this->call('list', array($params), "Google_Service_AdSense_SavedReports");
1504
+ }
1505
+ }
1506
+ /**
1507
+ * The "savedadstyles" collection of methods.
1508
+ * Typical usage is:
1509
+ * <code>
1510
+ * $adsenseService = new Google_Service_AdSense(...);
1511
+ * $savedadstyles = $adsenseService->savedadstyles;
1512
+ * </code>
1513
+ */
1514
+ class Google_Service_AdSense_AccountsSavedadstyles_Resource extends Google_Service_Resource
1515
+ {
1516
+
1517
+ /**
1518
+ * List a specific saved ad style for the specified account. (savedadstyles.get)
1519
+ *
1520
+ * @param string $accountId Account for which to get the saved ad style.
1521
+ * @param string $savedAdStyleId Saved ad style to retrieve.
1522
+ * @param array $optParams Optional parameters.
1523
+ * @return Google_Service_AdSense_SavedAdStyle
1524
+ */
1525
+ public function get($accountId, $savedAdStyleId, $optParams = array())
1526
+ {
1527
+ $params = array('accountId' => $accountId, 'savedAdStyleId' => $savedAdStyleId);
1528
+ $params = array_merge($params, $optParams);
1529
+ return $this->call('get', array($params), "Google_Service_AdSense_SavedAdStyle");
1530
+ }
1531
+
1532
+ /**
1533
+ * List all saved ad styles in the specified account.
1534
+ * (savedadstyles.listAccountsSavedadstyles)
1535
+ *
1536
+ * @param string $accountId Account for which to list saved ad styles.
1537
+ * @param array $optParams Optional parameters.
1538
+ *
1539
+ * @opt_param int maxResults The maximum number of saved ad styles to include in
1540
+ * the response, used for paging.
1541
+ * @opt_param string pageToken A continuation token, used to page through saved
1542
+ * ad styles. To retrieve the next page, set this parameter to the value of
1543
+ * "nextPageToken" from the previous response.
1544
+ * @return Google_Service_AdSense_SavedAdStyles
1545
+ */
1546
+ public function listAccountsSavedadstyles($accountId, $optParams = array())
1547
+ {
1548
+ $params = array('accountId' => $accountId);
1549
+ $params = array_merge($params, $optParams);
1550
+ return $this->call('list', array($params), "Google_Service_AdSense_SavedAdStyles");
1551
+ }
1552
+ }
1553
+ /**
1554
+ * The "urlchannels" collection of methods.
1555
+ * Typical usage is:
1556
+ * <code>
1557
+ * $adsenseService = new Google_Service_AdSense(...);
1558
+ * $urlchannels = $adsenseService->urlchannels;
1559
+ * </code>
1560
+ */
1561
+ class Google_Service_AdSense_AccountsUrlchannels_Resource extends Google_Service_Resource
1562
+ {
1563
+
1564
+ /**
1565
+ * List all URL channels in the specified ad client for the specified account.
1566
+ * (urlchannels.listAccountsUrlchannels)
1567
+ *
1568
+ * @param string $accountId Account to which the ad client belongs.
1569
+ * @param string $adClientId Ad client for which to list URL channels.
1570
+ * @param array $optParams Optional parameters.
1571
+ *
1572
+ * @opt_param int maxResults The maximum number of URL channels to include in
1573
+ * the response, used for paging.
1574
+ * @opt_param string pageToken A continuation token, used to page through URL
1575
+ * channels. To retrieve the next page, set this parameter to the value of
1576
+ * "nextPageToken" from the previous response.
1577
+ * @return Google_Service_AdSense_UrlChannels
1578
+ */
1579
+ public function listAccountsUrlchannels($accountId, $adClientId, $optParams = array())
1580
+ {
1581
+ $params = array('accountId' => $accountId, 'adClientId' => $adClientId);
1582
+ $params = array_merge($params, $optParams);
1583
+ return $this->call('list', array($params), "Google_Service_AdSense_UrlChannels");
1584
+ }
1585
+ }
1586
+
1587
+ /**
1588
+ * The "adclients" collection of methods.
1589
+ * Typical usage is:
1590
+ * <code>
1591
+ * $adsenseService = new Google_Service_AdSense(...);
1592
+ * $adclients = $adsenseService->adclients;
1593
+ * </code>
1594
+ */
1595
+ class Google_Service_AdSense_Adclients_Resource extends Google_Service_Resource
1596
+ {
1597
+
1598
+ /**
1599
+ * List all ad clients in this AdSense account. (adclients.listAdclients)
1600
+ *
1601
+ * @param array $optParams Optional parameters.
1602
+ *
1603
+ * @opt_param int maxResults The maximum number of ad clients to include in the
1604
+ * response, used for paging.
1605
+ * @opt_param string pageToken A continuation token, used to page through ad
1606
+ * clients. To retrieve the next page, set this parameter to the value of
1607
+ * "nextPageToken" from the previous response.
1608
+ * @return Google_Service_AdSense_AdClients
1609
+ */
1610
+ public function listAdclients($optParams = array())
1611
+ {
1612
+ $params = array();
1613
+ $params = array_merge($params, $optParams);
1614
+ return $this->call('list', array($params), "Google_Service_AdSense_AdClients");
1615
+ }
1616
+ }
1617
+
1618
+ /**
1619
+ * The "adunits" collection of methods.
1620
+ * Typical usage is:
1621
+ * <code>
1622
+ * $adsenseService = new Google_Service_AdSense(...);
1623
+ * $adunits = $adsenseService->adunits;
1624
+ * </code>
1625
+ */
1626
+ class Google_Service_AdSense_Adunits_Resource extends Google_Service_Resource
1627
+ {
1628
+
1629
+ /**
1630
+ * Gets the specified ad unit in the specified ad client. (adunits.get)
1631
+ *
1632
+ * @param string $adClientId Ad client for which to get the ad unit.
1633
+ * @param string $adUnitId Ad unit to retrieve.
1634
+ * @param array $optParams Optional parameters.
1635
+ * @return Google_Service_AdSense_AdUnit
1636
+ */
1637
+ public function get($adClientId, $adUnitId, $optParams = array())
1638
+ {
1639
+ $params = array('adClientId' => $adClientId, 'adUnitId' => $adUnitId);
1640
+ $params = array_merge($params, $optParams);
1641
+ return $this->call('get', array($params), "Google_Service_AdSense_AdUnit");
1642
+ }
1643
+
1644
+ /**
1645
+ * Get ad code for the specified ad unit. (adunits.getAdCode)
1646
+ *
1647
+ * @param string $adClientId Ad client with contains the ad unit.
1648
+ * @param string $adUnitId Ad unit to get the code for.
1649
+ * @param array $optParams Optional parameters.
1650
+ * @return Google_Service_AdSense_AdCode
1651
+ */
1652
+ public function getAdCode($adClientId, $adUnitId, $optParams = array())
1653
+ {
1654
+ $params = array('adClientId' => $adClientId, 'adUnitId' => $adUnitId);
1655
+ $params = array_merge($params, $optParams);
1656
+ return $this->call('getAdCode', array($params), "Google_Service_AdSense_AdCode");
1657
+ }
1658
+
1659
+ /**
1660
+ * List all ad units in the specified ad client for this AdSense account.
1661
+ * (adunits.listAdunits)
1662
+ *
1663
+ * @param string $adClientId Ad client for which to list ad units.
1664
+ * @param array $optParams Optional parameters.
1665
+ *
1666
+ * @opt_param bool includeInactive Whether to include inactive ad units.
1667
+ * Default: true.
1668
+ * @opt_param int maxResults The maximum number of ad units to include in the
1669
+ * response, used for paging.
1670
+ * @opt_param string pageToken A continuation token, used to page through ad
1671
+ * units. To retrieve the next page, set this parameter to the value of
1672
+ * "nextPageToken" from the previous response.
1673
+ * @return Google_Service_AdSense_AdUnits
1674
+ */
1675
+ public function listAdunits($adClientId, $optParams = array())
1676
+ {
1677
+ $params = array('adClientId' => $adClientId);
1678
+ $params = array_merge($params, $optParams);
1679
+ return $this->call('list', array($params), "Google_Service_AdSense_AdUnits");
1680
+ }
1681
+ }
1682
+
1683
+ /**
1684
+ * The "customchannels" collection of methods.
1685
+ * Typical usage is:
1686
+ * <code>
1687
+ * $adsenseService = new Google_Service_AdSense(...);
1688
+ * $customchannels = $adsenseService->customchannels;
1689
+ * </code>
1690
+ */
1691
+ class Google_Service_AdSense_AdunitsCustomchannels_Resource extends Google_Service_Resource
1692
+ {
1693
+
1694
+ /**
1695
+ * List all custom channels which the specified ad unit belongs to.
1696
+ * (customchannels.listAdunitsCustomchannels)
1697
+ *
1698
+ * @param string $adClientId Ad client which contains the ad unit.
1699
+ * @param string $adUnitId Ad unit for which to list custom channels.
1700
+ * @param array $optParams Optional parameters.
1701
+ *
1702
+ * @opt_param int maxResults The maximum number of custom channels to include in
1703
+ * the response, used for paging.
1704
+ * @opt_param string pageToken A continuation token, used to page through custom
1705
+ * channels. To retrieve the next page, set this parameter to the value of
1706
+ * "nextPageToken" from the previous response.
1707
+ * @return Google_Service_AdSense_CustomChannels
1708
+ */
1709
+ public function listAdunitsCustomchannels($adClientId, $adUnitId, $optParams = array())
1710
+ {
1711
+ $params = array('adClientId' => $adClientId, 'adUnitId' => $adUnitId);
1712
+ $params = array_merge($params, $optParams);
1713
+ return $this->call('list', array($params), "Google_Service_AdSense_CustomChannels");
1714
+ }
1715
+ }
1716
+
1717
+ /**
1718
+ * The "alerts" collection of methods.
1719
+ * Typical usage is:
1720
+ * <code>
1721
+ * $adsenseService = new Google_Service_AdSense(...);
1722
+ * $alerts = $adsenseService->alerts;
1723
+ * </code>
1724
+ */
1725
+ class Google_Service_AdSense_Alerts_Resource extends Google_Service_Resource
1726
+ {
1727
+
1728
+ /**
1729
+ * Dismiss (delete) the specified alert from the publisher's AdSense account.
1730
+ * (alerts.delete)
1731
+ *
1732
+ * @param string $alertId Alert to delete.
1733
+ * @param array $optParams Optional parameters.
1734
+ */
1735
+ public function delete($alertId, $optParams = array())
1736
+ {
1737
+ $params = array('alertId' => $alertId);
1738
+ $params = array_merge($params, $optParams);
1739
+ return $this->call('delete', array($params));
1740
+ }
1741
+
1742
+ /**
1743
+ * List the alerts for this AdSense account. (alerts.listAlerts)
1744
+ *
1745
+ * @param array $optParams Optional parameters.
1746
+ *
1747
+ * @opt_param string locale The locale to use for translating alert messages.
1748
+ * The account locale will be used if this is not supplied. The AdSense default
1749
+ * (English) will be used if the supplied locale is invalid or unsupported.
1750
+ * @return Google_Service_AdSense_Alerts
1751
+ */
1752
+ public function listAlerts($optParams = array())
1753
+ {
1754
+ $params = array();
1755
+ $params = array_merge($params, $optParams);
1756
+ return $this->call('list', array($params), "Google_Service_AdSense_Alerts");
1757
+ }
1758
+ }
1759
+
1760
+ /**
1761
+ * The "customchannels" collection of methods.
1762
+ * Typical usage is:
1763
+ * <code>
1764
+ * $adsenseService = new Google_Service_AdSense(...);
1765
+ * $customchannels = $adsenseService->customchannels;
1766
+ * </code>
1767
+ */
1768
+ class Google_Service_AdSense_Customchannels_Resource extends Google_Service_Resource
1769
+ {
1770
+
1771
+ /**
1772
+ * Get the specified custom channel from the specified ad client.
1773
+ * (customchannels.get)
1774
+ *
1775
+ * @param string $adClientId Ad client which contains the custom channel.
1776
+ * @param string $customChannelId Custom channel to retrieve.
1777
+ * @param array $optParams Optional parameters.
1778
+ * @return Google_Service_AdSense_CustomChannel
1779
+ */
1780
+ public function get($adClientId, $customChannelId, $optParams = array())
1781
+ {
1782
+ $params = array('adClientId' => $adClientId, 'customChannelId' => $customChannelId);
1783
+ $params = array_merge($params, $optParams);
1784
+ return $this->call('get', array($params), "Google_Service_AdSense_CustomChannel");
1785
+ }
1786
+
1787
+ /**
1788
+ * List all custom channels in the specified ad client for this AdSense account.
1789
+ * (customchannels.listCustomchannels)
1790
+ *
1791
+ * @param string $adClientId Ad client for which to list custom channels.
1792
+ * @param array $optParams Optional parameters.
1793
+ *
1794
+ * @opt_param int maxResults The maximum number of custom channels to include in
1795
+ * the response, used for paging.
1796
+ * @opt_param string pageToken A continuation token, used to page through custom
1797
+ * channels. To retrieve the next page, set this parameter to the value of
1798
+ * "nextPageToken" from the previous response.
1799
+ * @return Google_Service_AdSense_CustomChannels
1800
+ */
1801
+ public function listCustomchannels($adClientId, $optParams = array())
1802
+ {
1803
+ $params = array('adClientId' => $adClientId);
1804
+ $params = array_merge($params, $optParams);
1805
+ return $this->call('list', array($params), "Google_Service_AdSense_CustomChannels");
1806
+ }
1807
+ }
1808
+
1809
+ /**
1810
+ * The "adunits" collection of methods.
1811
+ * Typical usage is:
1812
+ * <code>
1813
+ * $adsenseService = new Google_Service_AdSense(...);
1814
+ * $adunits = $adsenseService->adunits;
1815
+ * </code>
1816
+ */
1817
+ class Google_Service_AdSense_CustomchannelsAdunits_Resource extends Google_Service_Resource
1818
+ {
1819
+
1820
+ /**
1821
+ * List all ad units in the specified custom channel.
1822
+ * (adunits.listCustomchannelsAdunits)
1823
+ *
1824
+ * @param string $adClientId Ad client which contains the custom channel.
1825
+ * @param string $customChannelId Custom channel for which to list ad units.
1826
+ * @param array $optParams Optional parameters.
1827
+ *
1828
+ * @opt_param bool includeInactive Whether to include inactive ad units.
1829
+ * Default: true.
1830
+ * @opt_param int maxResults The maximum number of ad units to include in the
1831
+ * response, used for paging.
1832
+ * @opt_param string pageToken A continuation token, used to page through ad
1833
+ * units. To retrieve the next page, set this parameter to the value of
1834
+ * "nextPageToken" from the previous response.
1835
+ * @return Google_Service_AdSense_AdUnits
1836
+ */
1837
+ public function listCustomchannelsAdunits($adClientId, $customChannelId, $optParams = array())
1838
+ {
1839
+ $params = array('adClientId' => $adClientId, 'customChannelId' => $customChannelId);
1840
+ $params = array_merge($params, $optParams);
1841
+ return $this->call('list', array($params), "Google_Service_AdSense_AdUnits");
1842
+ }
1843
+ }
1844
+
1845
+ /**
1846
+ * The "metadata" collection of methods.
1847
+ * Typical usage is:
1848
+ * <code>
1849
+ * $adsenseService = new Google_Service_AdSense(...);
1850
+ * $metadata = $adsenseService->metadata;
1851
+ * </code>
1852
+ */
1853
+ class Google_Service_AdSense_Metadata_Resource extends Google_Service_Resource
1854
+ {
1855
+ }
1856
+
1857
+ /**
1858
+ * The "dimensions" collection of methods.
1859
+ * Typical usage is:
1860
+ * <code>
1861
+ * $adsenseService = new Google_Service_AdSense(...);
1862
+ * $dimensions = $adsenseService->dimensions;
1863
+ * </code>
1864
+ */
1865
+ class Google_Service_AdSense_MetadataDimensions_Resource extends Google_Service_Resource
1866
+ {
1867
+
1868
+ /**
1869
+ * List the metadata for the dimensions available to this AdSense account.
1870
+ * (dimensions.listMetadataDimensions)
1871
+ *
1872
+ * @param array $optParams Optional parameters.
1873
+ * @return Google_Service_AdSense_Metadata
1874
+ */
1875
+ public function listMetadataDimensions($optParams = array())
1876
+ {
1877
+ $params = array();
1878
+ $params = array_merge($params, $optParams);
1879
+ return $this->call('list', array($params), "Google_Service_AdSense_Metadata");
1880
+ }
1881
+ }
1882
+ /**
1883
+ * The "metrics" collection of methods.
1884
+ * Typical usage is:
1885
+ * <code>
1886
+ * $adsenseService = new Google_Service_AdSense(...);
1887
+ * $metrics = $adsenseService->metrics;
1888
+ * </code>
1889
+ */
1890
+ class Google_Service_AdSense_MetadataMetrics_Resource extends Google_Service_Resource
1891
+ {
1892
+
1893
+ /**
1894
+ * List the metadata for the metrics available to this AdSense account.
1895
+ * (metrics.listMetadataMetrics)
1896
+ *
1897
+ * @param array $optParams Optional parameters.
1898
+ * @return Google_Service_AdSense_Metadata
1899
+ */
1900
+ public function listMetadataMetrics($optParams = array())
1901
+ {
1902
+ $params = array();
1903
+ $params = array_merge($params, $optParams);
1904
+ return $this->call('list', array($params), "Google_Service_AdSense_Metadata");
1905
+ }
1906
+ }
1907
+
1908
+ /**
1909
+ * The "payments" collection of methods.
1910
+ * Typical usage is:
1911
+ * <code>
1912
+ * $adsenseService = new Google_Service_AdSense(...);
1913
+ * $payments = $adsenseService->payments;
1914
+ * </code>
1915
+ */
1916
+ class Google_Service_AdSense_Payments_Resource extends Google_Service_Resource
1917
+ {
1918
+
1919
+ /**
1920
+ * List the payments for this AdSense account. (payments.listPayments)
1921
+ *
1922
+ * @param array $optParams Optional parameters.
1923
+ * @return Google_Service_AdSense_Payments
1924
+ */
1925
+ public function listPayments($optParams = array())
1926
+ {
1927
+ $params = array();
1928
+ $params = array_merge($params, $optParams);
1929
+ return $this->call('list', array($params), "Google_Service_AdSense_Payments");
1930
+ }
1931
+ }
1932
+
1933
+ /**
1934
+ * The "reports" collection of methods.
1935
+ * Typical usage is:
1936
+ * <code>
1937
+ * $adsenseService = new Google_Service_AdSense(...);
1938
+ * $reports = $adsenseService->reports;
1939
+ * </code>
1940
+ */
1941
+ class Google_Service_AdSense_Reports_Resource extends Google_Service_Resource
1942
+ {
1943
+
1944
+ /**
1945
+ * Generate an AdSense report based on the report request sent in the query
1946
+ * parameters. Returns the result as JSON; to retrieve output in CSV format
1947
+ * specify "alt=csv" as a query parameter. (reports.generate)
1948
+ *
1949
+ * @param string $startDate Start of the date range to report on in "YYYY-MM-DD"
1950
+ * format, inclusive.
1951
+ * @param string $endDate End of the date range to report on in "YYYY-MM-DD"
1952
+ * format, inclusive.
1953
+ * @param array $optParams Optional parameters.
1954
+ *
1955
+ * @opt_param string accountId Accounts upon which to report.
1956
+ * @opt_param string currency Optional currency to use when reporting on
1957
+ * monetary metrics. Defaults to the account's currency if not set.
1958
+ * @opt_param string dimension Dimensions to base the report on.
1959
+ * @opt_param string filter Filters to be run on the report.
1960
+ * @opt_param string locale Optional locale to use for translating report output
1961
+ * to a local language. Defaults to "en_US" if not specified.
1962
+ * @opt_param int maxResults The maximum number of rows of report data to
1963
+ * return.
1964
+ * @opt_param string metric Numeric columns to include in the report.
1965
+ * @opt_param string sort The name of a dimension or metric to sort the
1966
+ * resulting report on, optionally prefixed with "+" to sort ascending or "-" to
1967
+ * sort descending. If no prefix is specified, the column is sorted ascending.
1968
+ * @opt_param int startIndex Index of the first row of report data to return.
1969
+ * @opt_param bool useTimezoneReporting Whether the report should be generated
1970
+ * in the AdSense account's local timezone. If false default PST/PDT timezone
1971
+ * will be used.
1972
+ * @return Google_Service_AdSense_AdsenseReportsGenerateResponse
1973
+ */
1974
+ public function generate($startDate, $endDate, $optParams = array())
1975
+ {
1976
+ $params = array('startDate' => $startDate, 'endDate' => $endDate);
1977
+ $params = array_merge($params, $optParams);
1978
+ return $this->call('generate', array($params), "Google_Service_AdSense_AdsenseReportsGenerateResponse");
1979
+ }
1980
+ }
1981
+
1982
+ /**
1983
+ * The "saved" collection of methods.
1984
+ * Typical usage is:
1985
+ * <code>
1986
+ * $adsenseService = new Google_Service_AdSense(...);
1987
+ * $saved = $adsenseService->saved;
1988
+ * </code>
1989
+ */
1990
+ class Google_Service_AdSense_ReportsSaved_Resource extends Google_Service_Resource
1991
+ {
1992
+
1993
+ /**
1994
+ * Generate an AdSense report based on the saved report ID sent in the query
1995
+ * parameters. (saved.generate)
1996
+ *
1997
+ * @param string $savedReportId The saved report to retrieve.
1998
+ * @param array $optParams Optional parameters.
1999
+ *
2000
+ * @opt_param string locale Optional locale to use for translating report output
2001
+ * to a local language. Defaults to "en_US" if not specified.
2002
+ * @opt_param int maxResults The maximum number of rows of report data to
2003
+ * return.
2004
+ * @opt_param int startIndex Index of the first row of report data to return.
2005
+ * @return Google_Service_AdSense_AdsenseReportsGenerateResponse
2006
+ */
2007
+ public function generate($savedReportId, $optParams = array())
2008
+ {
2009
+ $params = array('savedReportId' => $savedReportId);
2010
+ $params = array_merge($params, $optParams);
2011
+ return $this->call('generate', array($params), "Google_Service_AdSense_AdsenseReportsGenerateResponse");
2012
+ }
2013
+
2014
+ /**
2015
+ * List all saved reports in this AdSense account. (saved.listReportsSaved)
2016
+ *
2017
+ * @param array $optParams Optional parameters.
2018
+ *
2019
+ * @opt_param int maxResults The maximum number of saved reports to include in
2020
+ * the response, used for paging.
2021
+ * @opt_param string pageToken A continuation token, used to page through saved
2022
+ * reports. To retrieve the next page, set this parameter to the value of
2023
+ * "nextPageToken" from the previous response.
2024
+ * @return Google_Service_AdSense_SavedReports
2025
+ */
2026
+ public function listReportsSaved($optParams = array())
2027
+ {
2028
+ $params = array();
2029
+ $params = array_merge($params, $optParams);
2030
+ return $this->call('list', array($params), "Google_Service_AdSense_SavedReports");
2031
+ }
2032
+ }
2033
+
2034
+ /**
2035
+ * The "savedadstyles" collection of methods.
2036
+ * Typical usage is:
2037
+ * <code>
2038
+ * $adsenseService = new Google_Service_AdSense(...);
2039
+ * $savedadstyles = $adsenseService->savedadstyles;
2040
+ * </code>
2041
+ */
2042
+ class Google_Service_AdSense_Savedadstyles_Resource extends Google_Service_Resource
2043
+ {
2044
+
2045
+ /**
2046
+ * Get a specific saved ad style from the user's account. (savedadstyles.get)
2047
+ *
2048
+ * @param string $savedAdStyleId Saved ad style to retrieve.
2049
+ * @param array $optParams Optional parameters.
2050
+ * @return Google_Service_AdSense_SavedAdStyle
2051
+ */
2052
+ public function get($savedAdStyleId, $optParams = array())
2053
+ {
2054
+ $params = array('savedAdStyleId' => $savedAdStyleId);
2055
+ $params = array_merge($params, $optParams);
2056
+ return $this->call('get', array($params), "Google_Service_AdSense_SavedAdStyle");
2057
+ }
2058
+
2059
+ /**
2060
+ * List all saved ad styles in the user's account.
2061
+ * (savedadstyles.listSavedadstyles)
2062
+ *
2063
+ * @param array $optParams Optional parameters.
2064
+ *
2065
+ * @opt_param int maxResults The maximum number of saved ad styles to include in
2066
+ * the response, used for paging.
2067
+ * @opt_param string pageToken A continuation token, used to page through saved
2068
+ * ad styles. To retrieve the next page, set this parameter to the value of
2069
+ * "nextPageToken" from the previous response.
2070
+ * @return Google_Service_AdSense_SavedAdStyles
2071
+ */
2072
+ public function listSavedadstyles($optParams = array())
2073
+ {
2074
+ $params = array();
2075
+ $params = array_merge($params, $optParams);
2076
+ return $this->call('list', array($params), "Google_Service_AdSense_SavedAdStyles");
2077
+ }
2078
+ }
2079
+
2080
+ /**
2081
+ * The "urlchannels" collection of methods.
2082
+ * Typical usage is:
2083
+ * <code>
2084
+ * $adsenseService = new Google_Service_AdSense(...);
2085
+ * $urlchannels = $adsenseService->urlchannels;
2086
+ * </code>
2087
+ */
2088
+ class Google_Service_AdSense_Urlchannels_Resource extends Google_Service_Resource
2089
+ {
2090
+
2091
+ /**
2092
+ * List all URL channels in the specified ad client for this AdSense account.
2093
+ * (urlchannels.listUrlchannels)
2094
+ *
2095
+ * @param string $adClientId Ad client for which to list URL channels.
2096
+ * @param array $optParams Optional parameters.
2097
+ *
2098
+ * @opt_param int maxResults The maximum number of URL channels to include in
2099
+ * the response, used for paging.
2100
+ * @opt_param string pageToken A continuation token, used to page through URL
2101
+ * channels. To retrieve the next page, set this parameter to the value of
2102
+ * "nextPageToken" from the previous response.
2103
+ * @return Google_Service_AdSense_UrlChannels
2104
+ */
2105
+ public function listUrlchannels($adClientId, $optParams = array())
2106
+ {
2107
+ $params = array('adClientId' => $adClientId);
2108
+ $params = array_merge($params, $optParams);
2109
+ return $this->call('list', array($params), "Google_Service_AdSense_UrlChannels");
2110
+ }
2111
+ }
2112
+
2113
+
2114
+
2115
+
2116
+ class Google_Service_AdSense_Account extends Google_Collection
2117
+ {
2118
+ protected $collection_key = 'subAccounts';
2119
+ protected $internal_gapi_mappings = array(
2120
+ "creationTime" => "creation_time",
2121
+ );
2122
+ public $creationTime;
2123
+ public $id;
2124
+ public $kind;
2125
+ public $name;
2126
+ public $premium;
2127
+ protected $subAccountsType = 'Google_Service_AdSense_Account';
2128
+ protected $subAccountsDataType = 'array';
2129
+ public $timezone;
2130
+
2131
+
2132
+ public function setCreationTime($creationTime)
2133
+ {
2134
+ $this->creationTime = $creationTime;
2135
+ }
2136
+ public function getCreationTime()
2137
+ {
2138
+ return $this->creationTime;
2139
+ }
2140
+ public function setId($id)
2141
+ {
2142
+ $this->id = $id;
2143
+ }
2144
+ public function getId()
2145
+ {
2146
+ return $this->id;
2147
+ }
2148
+ public function setKind($kind)
2149
+ {
2150
+ $this->kind = $kind;
2151
+ }
2152
+ public function getKind()
2153
+ {
2154
+ return $this->kind;
2155
+ }
2156
+ public function setName($name)
2157
+ {
2158
+ $this->name = $name;
2159
+ }
2160
+ public function getName()
2161
+ {
2162
+ return $this->name;
2163
+ }
2164
+ public function setPremium($premium)
2165
+ {
2166
+ $this->premium = $premium;
2167
+ }
2168
+ public function getPremium()
2169
+ {
2170
+ return $this->premium;
2171
+ }
2172
+ public function setSubAccounts($subAccounts)
2173
+ {
2174
+ $this->subAccounts = $subAccounts;
2175
+ }
2176
+ public function getSubAccounts()
2177
+ {
2178
+ return $this->subAccounts;
2179
+ }
2180
+ public function setTimezone($timezone)
2181
+ {
2182
+ $this->timezone = $timezone;
2183
+ }
2184
+ public function getTimezone()
2185
+ {
2186
+ return $this->timezone;
2187
+ }
2188
+ }
2189
+
2190
+ class Google_Service_AdSense_Accounts extends Google_Collection
2191
+ {
2192
+ protected $collection_key = 'items';
2193
+ protected $internal_gapi_mappings = array(
2194
+ );
2195
+ public $etag;
2196
+ protected $itemsType = 'Google_Service_AdSense_Account';
2197
+ protected $itemsDataType = 'array';
2198
+ public $kind;
2199
+ public $nextPageToken;
2200
+
2201
+
2202
+ public function setEtag($etag)
2203
+ {
2204
+ $this->etag = $etag;
2205
+ }
2206
+ public function getEtag()
2207
+ {
2208
+ return $this->etag;
2209
+ }
2210
+ public function setItems($items)
2211
+ {
2212
+ $this->items = $items;
2213
+ }
2214
+ public function getItems()
2215
+ {
2216
+ return $this->items;
2217
+ }
2218
+ public function setKind($kind)
2219
+ {
2220
+ $this->kind = $kind;
2221
+ }
2222
+ public function getKind()
2223
+ {
2224
+ return $this->kind;
2225
+ }
2226
+ public function setNextPageToken($nextPageToken)
2227
+ {
2228
+ $this->nextPageToken = $nextPageToken;
2229
+ }
2230
+ public function getNextPageToken()
2231
+ {
2232
+ return $this->nextPageToken;
2233
+ }
2234
+ }
2235
+
2236
+ class Google_Service_AdSense_AdClient extends Google_Model
2237
+ {
2238
+ protected $internal_gapi_m