Version Description
(16.07.2020) = * Fixed: Minor bugs
Download this release
Release Info
Developer | alexkovalevv |
Plugin | Disable admin notices individually |
Version | 1.2.0 |
Comparing to | |
See all releases |
Code changes from version 1.1.3 to 1.2.0
- admin/assets/css/settings.css +177 -0
- admin/assets/css/settings.less +212 -0
- admin/boot.php +48 -48
- admin/options.php +88 -52
- admin/pages/class-pages-edit-admin-bar.php +147 -0
- admin/pages/class-pages-edit-redirects.php +164 -0
- admin/pages/class-pages-license.php +103 -0
- admin/pages/class-pages-more-features.php +0 -27
- admin/pages/{class-pages-notices.php → class-pages-settings.php} +39 -4
- admin/pages/class-pages.php +25 -0
- disable-admin-notices.php +59 -40
- includes/class-plugin.php +18 -10
- includes/classes/class-configurate-notices.php +94 -101
- includes/function.php +117 -0
- libs/factory/core/includes/class-factory-plugin-base.php +1 -1
- libs/factory/core/includes/premium/class-factory-manager.php +2 -2
- libs/factory/core/includes/updates/class-factory-upgrader.php +1 -1
- libs/factory/freemius/boot.php +52 -0
- libs/factory/freemius/includes/class-freemius-api.php +416 -0
- libs/factory/freemius/includes/entities/class-freemius-entity.php +178 -0
- libs/factory/freemius/includes/entities/class-freemius-license.php +376 -0
- libs/factory/freemius/includes/entities/class-freemius-plugin.php +114 -0
- libs/factory/freemius/includes/entities/class-freemius-scope.php +34 -0
- libs/factory/freemius/includes/entities/class-freemius-site.php +147 -0
- libs/factory/freemius/includes/entities/class-freemius-user.php +80 -0
- libs/factory/freemius/includes/entities/index.php +2 -0
- libs/factory/freemius/includes/index.php +2 -0
- libs/factory/freemius/includes/licensing/class-freemius-provider.php +772 -0
- libs/factory/freemius/includes/licensing/index.php +2 -0
- libs/factory/freemius/includes/sdk/Exceptions/ArgumentNotExistException.php +9 -0
- libs/factory/freemius/includes/sdk/Exceptions/EmptyArgumentException.php +9 -0
- libs/factory/freemius/includes/sdk/Exceptions/Exception.php +74 -0
- libs/factory/freemius/includes/sdk/Exceptions/InvalidArgumentException.php +8 -0
- libs/factory/freemius/includes/sdk/Exceptions/OAuthException.php +12 -0
- libs/factory/freemius/includes/sdk/Exceptions/index.php +3 -0
- libs/factory/freemius/includes/sdk/FreemiusBase.php +215 -0
- libs/factory/freemius/includes/sdk/FreemiusWordPress.php +704 -0
- libs/factory/freemius/includes/sdk/LICENSE.txt +340 -0
- libs/factory/freemius/includes/sdk/index.php +3 -0
- libs/factory/freemius/includes/updates/class-freemius-repository.php +123 -0
- libs/factory/freemius/includes/updates/index.php +2 -0
- libs/factory/freemius/index.php +2 -0
- libs/factory/pages/templates/assets/css/impressive.page.template.css +2 -1
- readme.txt +8 -1
admin/assets/css/settings.css
ADDED
@@ -0,0 +1,177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#WBCR .factory-checkbox.wdanpro-checkbox-premium-label:after,
|
2 |
+
#WBCR .wdanpro-radio-premium-label .factory-compact_panel:after {
|
3 |
+
display: inline-block;
|
4 |
+
position: relative;
|
5 |
+
content: 'PRO';
|
6 |
+
background: #ff5722;
|
7 |
+
border-radius: 4px;
|
8 |
+
color: #fff;
|
9 |
+
font-size: 10px;
|
10 |
+
line-height: 1;
|
11 |
+
font-style: normal;
|
12 |
+
padding: 4px 6px;
|
13 |
+
margin-left: 4px;
|
14 |
+
vertical-align: top;
|
15 |
+
top: -8px;
|
16 |
+
left: -10px;
|
17 |
+
right: auto;
|
18 |
+
z-index: 11;
|
19 |
+
}
|
20 |
+
#WBCR .wdanpro-radio-premium-label .factory-compact_panel:after {
|
21 |
+
position: absolute;
|
22 |
+
top: -10px;
|
23 |
+
right: -10px;
|
24 |
+
left: auto;
|
25 |
+
}
|
26 |
+
#WBCR .factory-checkbox-disabled input,
|
27 |
+
#WBCR .factory-checkbox-disabled button,
|
28 |
+
#WBCR .wdanpro-radio-premium-label .factory-compact_panel {
|
29 |
+
pointer-events: none;
|
30 |
+
cursor: not-allowed;
|
31 |
+
opacity: 0.65;
|
32 |
+
filter: alpha(opacity=65);
|
33 |
+
-webkit-box-shadow: none;
|
34 |
+
box-shadow: none;
|
35 |
+
}
|
36 |
+
#WBCR .wrdan-premium-fake-content {
|
37 |
+
position: relative;
|
38 |
+
padding: 15px;
|
39 |
+
}
|
40 |
+
#WBCR .wdan-premium-info {
|
41 |
+
position: absolute;
|
42 |
+
top: 50px;
|
43 |
+
left: 50%;
|
44 |
+
margin-left: -250px;
|
45 |
+
max-width: 500px;
|
46 |
+
z-index: 999;
|
47 |
+
}
|
48 |
+
#WBCR .wdan-premium-info h3 {
|
49 |
+
font-size: 32px;
|
50 |
+
font-weight: 300;
|
51 |
+
color: inherit;
|
52 |
+
margin: 40px 0 10px;
|
53 |
+
line-height: 1.2;
|
54 |
+
}
|
55 |
+
#WBCR .wdan-premium-info p {
|
56 |
+
font-size: 16px;
|
57 |
+
font-weight: 400;
|
58 |
+
color: #a4afb7;
|
59 |
+
margin-bottom: 40px;
|
60 |
+
}
|
61 |
+
#WBCR .wdan-premium-layer {
|
62 |
+
position: absolute;
|
63 |
+
top: 0;
|
64 |
+
left: 0;
|
65 |
+
right: 0;
|
66 |
+
bottom: 0;
|
67 |
+
opacity: 0.9;
|
68 |
+
background: #fff;
|
69 |
+
}
|
70 |
+
#WBCR .wdan-button {
|
71 |
+
font-family: Roboto, Arial, Helvetica, Verdana, sans-serif;
|
72 |
+
font-weight: 500;
|
73 |
+
text-transform: uppercase;
|
74 |
+
outline: none;
|
75 |
+
border: none;
|
76 |
+
text-decoration: none;
|
77 |
+
-webkit-border-radius: 3px;
|
78 |
+
border-radius: 3px;
|
79 |
+
-webkit-transition-property: background, color, opacity, -webkit-box-shadow;
|
80 |
+
transition-property: background, color, opacity, -webkit-box-shadow;
|
81 |
+
-o-transition-property: background, color, box-shadow, opacity;
|
82 |
+
transition-property: background, color, box-shadow, opacity;
|
83 |
+
transition-property: background, color, box-shadow, opacity, -webkit-box-shadow;
|
84 |
+
-webkit-transition-duration: 0.3s;
|
85 |
+
-o-transition-duration: 0.3s;
|
86 |
+
transition-duration: 0.3s;
|
87 |
+
}
|
88 |
+
#WBCR .wdan-button:hover {
|
89 |
+
border: none;
|
90 |
+
}
|
91 |
+
#WBCR .wdan-button:not([disabled]) {
|
92 |
+
cursor: pointer;
|
93 |
+
}
|
94 |
+
#WBCR .wdan-button:not(.wdan-button-state) .wdan-state-icon {
|
95 |
+
display: none;
|
96 |
+
}
|
97 |
+
#WBCR .wdan-button.wdan-button-success {
|
98 |
+
color: #fff;
|
99 |
+
}
|
100 |
+
#WBCR .wdan-button.wdan-button-success[disabled] {
|
101 |
+
background-color: #c2cbd2;
|
102 |
+
}
|
103 |
+
#WBCR .wdan-button.wdan-button-success:not([disabled]) {
|
104 |
+
background-color: #39b54a;
|
105 |
+
}
|
106 |
+
#WBCR .wdan-button.wdan-button-success:not([disabled]):hover {
|
107 |
+
opacity: 0.85;
|
108 |
+
-webkit-box-shadow: 0 0 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2);
|
109 |
+
box-shadow: 0 0 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2);
|
110 |
+
}
|
111 |
+
#WBCR .wdan-button.wdan-button-success:not([disabled]):active {
|
112 |
+
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.19), 0 3px 3px rgba(0, 0, 0, 0.1);
|
113 |
+
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.19), 0 3px 3px rgba(0, 0, 0, 0.1);
|
114 |
+
}
|
115 |
+
#WBCR .wdan-button.wdan-button-warning {
|
116 |
+
background-color: #a4afb7;
|
117 |
+
color: #fff;
|
118 |
+
}
|
119 |
+
#WBCR .wdan-button.wdan-button-warning[disabled] {
|
120 |
+
background-color: #c2cbd2;
|
121 |
+
}
|
122 |
+
#WBCR .wdan-button.wdan-button-warning:not([disabled]):hover {
|
123 |
+
background-color: #b01b1b;
|
124 |
+
opacity: 0.85;
|
125 |
+
-webkit-box-shadow: 0 0 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2);
|
126 |
+
box-shadow: 0 0 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2);
|
127 |
+
}
|
128 |
+
#WBCR .wdan-button.wdan-button-warning:not([disabled]):active {
|
129 |
+
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.19), 0 3px 3px rgba(0, 0, 0, 0.1);
|
130 |
+
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.19), 0 3px 3px rgba(0, 0, 0, 0.1);
|
131 |
+
}
|
132 |
+
#WBCR .wdan-button.wdan-button-danger {
|
133 |
+
background-color: #d72b3f;
|
134 |
+
color: #fff;
|
135 |
+
}
|
136 |
+
#WBCR .wdan-button.wdan-button-danger[disabled] {
|
137 |
+
background-color: #c2cbd2;
|
138 |
+
}
|
139 |
+
#WBCR .wdan-button.wdan-button-danger:not([disabled]):hover {
|
140 |
+
opacity: 0.85;
|
141 |
+
-webkit-box-shadow: 0 0 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2);
|
142 |
+
box-shadow: 0 0 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2);
|
143 |
+
}
|
144 |
+
#WBCR .wdan-button.wdan-button-danger:not([disabled]):active {
|
145 |
+
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.19), 0 3px 3px rgba(0, 0, 0, 0.1);
|
146 |
+
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.19), 0 3px 3px rgba(0, 0, 0, 0.1);
|
147 |
+
}
|
148 |
+
#WBCR .wdan-button.wdan-edit-template {
|
149 |
+
display: inline-block;
|
150 |
+
margin-top: 15px;
|
151 |
+
color: #fff;
|
152 |
+
}
|
153 |
+
#WBCR .wdan-button.wdan-button-default {
|
154 |
+
background-color: #a4afb7;
|
155 |
+
color: #fff;
|
156 |
+
font-size: 11px;
|
157 |
+
padding: 7px 21px;
|
158 |
+
}
|
159 |
+
#WBCR .wdan-button.wdan-button-default:hover {
|
160 |
+
background-color: #6d7882;
|
161 |
+
-webkit-box-shadow: 0 0 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2);
|
162 |
+
box-shadow: 0 0 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2);
|
163 |
+
}
|
164 |
+
#WBCR .wdan-button.wdan-button-default:active {
|
165 |
+
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.19), 0 3px 3px rgba(0, 0, 0, 0.1);
|
166 |
+
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.19), 0 3px 3px rgba(0, 0, 0, 0.1);
|
167 |
+
}
|
168 |
+
#WBCR .wdan-button.wdan-button-default:visited {
|
169 |
+
color: #fff;
|
170 |
+
}
|
171 |
+
#WBCR .wdan-button.wdan-button-go-pro {
|
172 |
+
background-color: #ff5722;
|
173 |
+
}
|
174 |
+
#WBCR .wdan-button i {
|
175 |
+
margin-right: 10px;
|
176 |
+
}
|
177 |
+
/*# sourceMappingURL=settings.css.map */
|
admin/assets/css/settings.less
ADDED
@@ -0,0 +1,212 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#WBCR {
|
2 |
+
.factory-checkbox.wdanpro-checkbox-premium-label:after,
|
3 |
+
.wdanpro-radio-premium-label .factory-compact_panel:after {
|
4 |
+
display: inline-block;
|
5 |
+
position: relative;
|
6 |
+
content: 'PRO';
|
7 |
+
background: #ff5722;
|
8 |
+
border-radius: 4px;
|
9 |
+
color: #fff;
|
10 |
+
font-size: 10px;
|
11 |
+
line-height: 1;
|
12 |
+
font-style: normal;
|
13 |
+
padding: 4px 6px;
|
14 |
+
margin-left: 4px;
|
15 |
+
vertical-align: top;
|
16 |
+
top: -8px;
|
17 |
+
left: -10px;
|
18 |
+
right: auto;
|
19 |
+
z-index: 11;
|
20 |
+
}
|
21 |
+
|
22 |
+
.wdanpro-radio-premium-label .factory-compact_panel:after {
|
23 |
+
position: absolute;
|
24 |
+
top: -10px;
|
25 |
+
right: -10px;
|
26 |
+
left: auto;
|
27 |
+
}
|
28 |
+
|
29 |
+
.factory-checkbox-disabled input,
|
30 |
+
.factory-checkbox-disabled button,
|
31 |
+
.wdanpro-radio-premium-label .factory-compact_panel {
|
32 |
+
pointer-events: none;
|
33 |
+
cursor: not-allowed;
|
34 |
+
opacity: 0.65;
|
35 |
+
filter: alpha(opacity=65);
|
36 |
+
-webkit-box-shadow: none;
|
37 |
+
box-shadow: none;
|
38 |
+
}
|
39 |
+
|
40 |
+
.wrdan-premium-fake-content {
|
41 |
+
position: relative;
|
42 |
+
padding: 15px;
|
43 |
+
|
44 |
+
}
|
45 |
+
|
46 |
+
.wdan-premium-info {
|
47 |
+
position: absolute;
|
48 |
+
top: 50px;
|
49 |
+
left: 50%;
|
50 |
+
margin-left: -250px;
|
51 |
+
max-width: 500px;
|
52 |
+
z-index: 999;
|
53 |
+
|
54 |
+
h3 {
|
55 |
+
font-size: 32px;
|
56 |
+
font-weight: 300;
|
57 |
+
color: inherit;
|
58 |
+
margin: 40px 0 10px;
|
59 |
+
line-height: 1.2;
|
60 |
+
}
|
61 |
+
|
62 |
+
p {
|
63 |
+
font-size: 16px;
|
64 |
+
font-weight: 400;
|
65 |
+
color: #a4afb7;
|
66 |
+
margin-bottom: 40px;
|
67 |
+
}
|
68 |
+
}
|
69 |
+
|
70 |
+
.wdan-premium-layer {
|
71 |
+
position: absolute;
|
72 |
+
top: 0;
|
73 |
+
left: 0;
|
74 |
+
right: 0;
|
75 |
+
bottom: 0;
|
76 |
+
opacity: 0.9;
|
77 |
+
background: #fff;
|
78 |
+
|
79 |
+
|
80 |
+
}
|
81 |
+
|
82 |
+
.wdan-button {
|
83 |
+
font-family: Roboto, Arial, Helvetica, Verdana, sans-serif;
|
84 |
+
font-weight: 500;
|
85 |
+
text-transform: uppercase;
|
86 |
+
outline: none;
|
87 |
+
border: none;
|
88 |
+
text-decoration: none;
|
89 |
+
-webkit-border-radius: 3px;
|
90 |
+
border-radius: 3px;
|
91 |
+
-webkit-transition-property: background, color, opacity, -webkit-box-shadow;
|
92 |
+
transition-property: background, color, opacity, -webkit-box-shadow;
|
93 |
+
-o-transition-property: background, color, box-shadow, opacity;
|
94 |
+
transition-property: background, color, box-shadow, opacity;
|
95 |
+
transition-property: background, color, box-shadow, opacity, -webkit-box-shadow;
|
96 |
+
-webkit-transition-duration: .3s;
|
97 |
+
-o-transition-duration: .3s;
|
98 |
+
transition-duration: .3s
|
99 |
+
}
|
100 |
+
|
101 |
+
.wdan-button:hover {
|
102 |
+
border: none
|
103 |
+
}
|
104 |
+
|
105 |
+
.wdan-button:not([disabled]) {
|
106 |
+
cursor: pointer
|
107 |
+
}
|
108 |
+
|
109 |
+
.wdan-button:not(.wdan-button-state) .wdan-state-icon {
|
110 |
+
display: none
|
111 |
+
}
|
112 |
+
|
113 |
+
.wdan-button.wdan-button-success {
|
114 |
+
color: #fff
|
115 |
+
}
|
116 |
+
|
117 |
+
.wdan-button.wdan-button-success[disabled] {
|
118 |
+
background-color: #c2cbd2
|
119 |
+
}
|
120 |
+
|
121 |
+
.wdan-button.wdan-button-success:not([disabled]) {
|
122 |
+
background-color: #39b54a
|
123 |
+
}
|
124 |
+
|
125 |
+
.wdan-button.wdan-button-success:not([disabled]):hover {
|
126 |
+
opacity: .85;
|
127 |
+
-webkit-box-shadow: 0 0 2px rgba(0, 0, 0, .12), 0 2px 2px rgba(0, 0, 0, .2);
|
128 |
+
box-shadow: 0 0 2px rgba(0, 0, 0, .12), 0 2px 2px rgba(0, 0, 0, .2)
|
129 |
+
}
|
130 |
+
|
131 |
+
.wdan-button.wdan-button-success:not([disabled]):active {
|
132 |
+
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .19), 0 3px 3px rgba(0, 0, 0, .1);
|
133 |
+
box-shadow: 0 5px 10px rgba(0, 0, 0, .19), 0 3px 3px rgba(0, 0, 0, .1)
|
134 |
+
}
|
135 |
+
|
136 |
+
.wdan-button.wdan-button-warning {
|
137 |
+
background-color: #a4afb7;
|
138 |
+
color: #fff
|
139 |
+
}
|
140 |
+
|
141 |
+
.wdan-button.wdan-button-warning[disabled] {
|
142 |
+
background-color: #c2cbd2
|
143 |
+
}
|
144 |
+
|
145 |
+
.wdan-button.wdan-button-warning:not([disabled]):hover {
|
146 |
+
background-color: #b01b1b;
|
147 |
+
opacity: .85;
|
148 |
+
-webkit-box-shadow: 0 0 2px rgba(0, 0, 0, .12), 0 2px 2px rgba(0, 0, 0, .2);
|
149 |
+
box-shadow: 0 0 2px rgba(0, 0, 0, .12), 0 2px 2px rgba(0, 0, 0, .2)
|
150 |
+
}
|
151 |
+
|
152 |
+
.wdan-button.wdan-button-warning:not([disabled]):active {
|
153 |
+
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .19), 0 3px 3px rgba(0, 0, 0, .1);
|
154 |
+
box-shadow: 0 5px 10px rgba(0, 0, 0, .19), 0 3px 3px rgba(0, 0, 0, .1)
|
155 |
+
}
|
156 |
+
|
157 |
+
.wdan-button.wdan-button-danger {
|
158 |
+
background-color: #d72b3f;
|
159 |
+
color: #fff
|
160 |
+
}
|
161 |
+
|
162 |
+
.wdan-button.wdan-button-danger[disabled] {
|
163 |
+
background-color: #c2cbd2
|
164 |
+
}
|
165 |
+
|
166 |
+
.wdan-button.wdan-button-danger:not([disabled]):hover {
|
167 |
+
opacity: .85;
|
168 |
+
-webkit-box-shadow: 0 0 2px rgba(0, 0, 0, .12), 0 2px 2px rgba(0, 0, 0, .2);
|
169 |
+
box-shadow: 0 0 2px rgba(0, 0, 0, .12), 0 2px 2px rgba(0, 0, 0, .2)
|
170 |
+
}
|
171 |
+
|
172 |
+
.wdan-button.wdan-button-danger:not([disabled]):active {
|
173 |
+
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .19), 0 3px 3px rgba(0, 0, 0, .1);
|
174 |
+
box-shadow: 0 5px 10px rgba(0, 0, 0, .19), 0 3px 3px rgba(0, 0, 0, .1)
|
175 |
+
}
|
176 |
+
|
177 |
+
.wdan-button.wdan-edit-template {
|
178 |
+
display: inline-block;
|
179 |
+
margin-top: 15px;
|
180 |
+
color: #fff
|
181 |
+
}
|
182 |
+
|
183 |
+
.wdan-button.wdan-button-default {
|
184 |
+
background-color: #a4afb7;
|
185 |
+
color: #fff;
|
186 |
+
font-size: 11px;
|
187 |
+
padding: 7px 21px
|
188 |
+
}
|
189 |
+
|
190 |
+
.wdan-button.wdan-button-default:hover {
|
191 |
+
background-color: #6d7882;
|
192 |
+
-webkit-box-shadow: 0 0 2px rgba(0, 0, 0, .12), 0 2px 2px rgba(0, 0, 0, .2);
|
193 |
+
box-shadow: 0 0 2px rgba(0, 0, 0, .12), 0 2px 2px rgba(0, 0, 0, .2)
|
194 |
+
}
|
195 |
+
|
196 |
+
.wdan-button.wdan-button-default:active {
|
197 |
+
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .19), 0 3px 3px rgba(0, 0, 0, .1);
|
198 |
+
box-shadow: 0 5px 10px rgba(0, 0, 0, .19), 0 3px 3px rgba(0, 0, 0, .1)
|
199 |
+
}
|
200 |
+
|
201 |
+
.wdan-button.wdan-button-default:visited {
|
202 |
+
color: #fff
|
203 |
+
}
|
204 |
+
|
205 |
+
.wdan-button.wdan-button-go-pro {
|
206 |
+
background-color: #ff5722
|
207 |
+
}
|
208 |
+
|
209 |
+
.wdan-button i {
|
210 |
+
margin-right: 10px
|
211 |
+
}
|
212 |
+
}
|
admin/boot.php
CHANGED
@@ -11,24 +11,24 @@
|
|
11 |
*/
|
12 |
|
13 |
// Exit if accessed directly
|
14 |
-
if( !defined('ABSPATH') ) {
|
15 |
exit;
|
16 |
}
|
17 |
|
18 |
-
if( !defined('LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON') ) {
|
19 |
-
add_filter('plugin_row_meta', function ($links, $file) {
|
20 |
-
if( $file == WDN_PLUGIN_BASE ) {
|
21 |
$url = 'https://clearfy.pro';
|
22 |
|
23 |
-
if( get_locale() == 'ru_RU' ) {
|
24 |
$url = 'https://ru.clearfy.pro';
|
25 |
}
|
26 |
-
$url
|
27 |
-
$links[] = '<a href="' . $url . '" style="color: #FF5722;font-weight: bold;" target="_blank">' . __('Get ultimate plugin free', 'disable-admin-notices') . '</a>';
|
28 |
}
|
29 |
|
30 |
return $links;
|
31 |
-
}, 10, 2);
|
32 |
|
33 |
/**
|
34 |
* Изменяем ссылку по умолчанию на собственную в виджете "Голосу за нас".
|
@@ -44,13 +44,13 @@ if( !defined('LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON') ) {
|
|
44 |
*
|
45 |
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
|
46 |
*/
|
47 |
-
add_filter('wbcr_factory_pages_429_imppage_rating_widget_url', function ($page_url, $plugin_name) {
|
48 |
-
if( $plugin_name == WDN_Plugin::app()->getPluginName() ) {
|
49 |
return 'https://goo.gl/68ucHp';
|
50 |
}
|
51 |
|
52 |
return $page_url;
|
53 |
-
}, 10, 2);
|
54 |
|
55 |
/**
|
56 |
* Удаляем лишние виджеты из правого сайдбара в интерфейсе плагина
|
@@ -59,15 +59,15 @@ if( !defined('LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON') ) {
|
|
59 |
* - Виджет с рейтингом
|
60 |
* - Виджет с маркерами информации
|
61 |
*/
|
62 |
-
add_filter('wbcr/factory/pages/impressive/widgets', function ($widgets, $position, $plugin) {
|
63 |
-
if( WDN_Plugin::app()->getPluginName() == $plugin->getPluginName() && 'right' == $position ) {
|
64 |
-
unset($widgets['business_suggetion']);
|
65 |
-
unset($widgets['rating_widget']);
|
66 |
-
unset($widgets['info_widget']);
|
67 |
}
|
68 |
|
69 |
return $widgets;
|
70 |
-
}, 20, 3);
|
71 |
} else {
|
72 |
/**
|
73 |
* Регистрируем опции плагина в Clearfy, чтобы тот мог совершать манипуляции с опциями этого плагина.
|
@@ -76,45 +76,45 @@ if( !defined('LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON') ) {
|
|
76 |
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
|
77 |
* @since 1.0
|
78 |
*/
|
79 |
-
add_filter("wbcr_clearfy_group_options", function ($options) {
|
80 |
$options[] = [
|
81 |
-
'name'
|
82 |
-
'title'
|
83 |
-
'tags'
|
84 |
-
'values' => ['hide_admin_notices' => 'only_selected']
|
85 |
];
|
86 |
$options[] = [
|
87 |
-
'name'
|
88 |
-
'title' => __('Enable hidden notices in adminbar', 'disable-admin-notices'),
|
89 |
-
'tags'
|
90 |
];
|
91 |
|
92 |
return $options;
|
93 |
-
});
|
|
|
94 |
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
|
106 |
-
|
107 |
|
108 |
-
|
109 |
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
|
118 |
-
|
119 |
-
|
120 |
-
}
|
11 |
*/
|
12 |
|
13 |
// Exit if accessed directly
|
14 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
15 |
exit;
|
16 |
}
|
17 |
|
18 |
+
if ( ! defined( 'LOADING_DISABLE_ADMIN_NOTICES_AS_ADDON' ) ) {
|
19 |
+
add_filter( 'plugin_row_meta', function ( $links, $file ) {
|
20 |
+
if ( $file == WDN_PLUGIN_BASE ) {
|
21 |
$url = 'https://clearfy.pro';
|
22 |
|
23 |
+
if ( get_locale() == 'ru_RU' ) {
|
24 |
$url = 'https://ru.clearfy.pro';
|
25 |
}
|
26 |
+
$url .= '?utm_source=wordpress.org&utm_campaign=' . WDN_Plugin::app()->getPluginName();
|
27 |
+
$links[] = '<a href="' . $url . '" style="color: #FF5722;font-weight: bold;" target="_blank">' . __( 'Get ultimate plugin free', 'disable-admin-notices' ) . '</a>';
|
28 |
}
|
29 |
|
30 |
return $links;
|
31 |
+
}, 10, 2 );
|
32 |
|
33 |
/**
|
34 |
* Изменяем ссылку по умолчанию на собственную в виджете "Голосу за нас".
|
44 |
*
|
45 |
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
|
46 |
*/
|
47 |
+
add_filter( 'wbcr_factory_pages_429_imppage_rating_widget_url', function ( $page_url, $plugin_name ) {
|
48 |
+
if ( $plugin_name == WDN_Plugin::app()->getPluginName() ) {
|
49 |
return 'https://goo.gl/68ucHp';
|
50 |
}
|
51 |
|
52 |
return $page_url;
|
53 |
+
}, 10, 2 );
|
54 |
|
55 |
/**
|
56 |
* Удаляем лишние виджеты из правого сайдбара в интерфейсе плагина
|
59 |
* - Виджет с рейтингом
|
60 |
* - Виджет с маркерами информации
|
61 |
*/
|
62 |
+
add_filter( 'wbcr/factory/pages/impressive/widgets', function ( $widgets, $position, $plugin ) {
|
63 |
+
if ( WDN_Plugin::app()->getPluginName() == $plugin->getPluginName() && 'right' == $position ) {
|
64 |
+
unset( $widgets['business_suggetion'] );
|
65 |
+
unset( $widgets['rating_widget'] );
|
66 |
+
unset( $widgets['info_widget'] );
|
67 |
}
|
68 |
|
69 |
return $widgets;
|
70 |
+
}, 20, 3 );
|
71 |
} else {
|
72 |
/**
|
73 |
* Регистрируем опции плагина в Clearfy, чтобы тот мог совершать манипуляции с опциями этого плагина.
|
76 |
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
|
77 |
* @since 1.0
|
78 |
*/
|
79 |
+
add_filter( "wbcr_clearfy_group_options", function ( $options ) {
|
80 |
$options[] = [
|
81 |
+
'name' => 'hide_admin_notices',
|
82 |
+
'title' => __( 'Hide admin notices', 'disable-admin-notices' ),
|
83 |
+
'tags' => [],
|
84 |
+
'values' => [ 'hide_admin_notices' => 'only_selected' ]
|
85 |
];
|
86 |
$options[] = [
|
87 |
+
'name' => 'show_notices_in_adminbar',
|
88 |
+
'title' => __( 'Enable hidden notices in adminbar', 'disable-admin-notices' ),
|
89 |
+
'tags' => []
|
90 |
];
|
91 |
|
92 |
return $options;
|
93 |
+
} );
|
94 |
+
}
|
95 |
|
96 |
+
/**
|
97 |
+
* Print admin notice: "Would you like to send them for spam checking?"
|
98 |
+
*
|
99 |
+
* If user clicked button "Yes, do it", plugin will exec action,
|
100 |
+
* that put all unapproved comments to spam check queue.
|
101 |
+
*/
|
102 |
+
add_action( 'wbcr/factory/admin_notices', function ( $notices, $plugin_name ) {
|
103 |
+
if ( $plugin_name != WDN_Plugin::app()->getPluginName() ) {
|
104 |
+
return $notices;
|
105 |
+
}
|
106 |
|
107 |
+
$page_url = 'https://clearfy.pro/disable-admin-notices/';
|
108 |
|
109 |
+
$notice_text = sprintf( __( 'Thanks for using the Disable admin notices plugin! If you need support or all the features of the plugin, please buy the pro version <a class="button" href="%s">Get PRO</a>' ), $page_url );
|
110 |
|
111 |
+
$notices[] = [
|
112 |
+
'id' => 'wdan_get_premium',
|
113 |
+
'type' => 'success',
|
114 |
+
'dismissible' => true,
|
115 |
+
'dismiss_expires' => 0,
|
116 |
+
'text' => '<p><strong>Disable Admin Notices Individually:</strong><br>' . $notice_text . '</p>'
|
117 |
+
];
|
118 |
|
119 |
+
return $notices;
|
120 |
+
}, 10, 2 );
|
|
admin/options.php
CHANGED
@@ -21,9 +21,9 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
21 |
* Эта функция используется для общей страницы настроек текущего плагина,
|
22 |
* а также для раширения настроек в плагине Clearfy.
|
23 |
*
|
24 |
-
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
|
25 |
-
* @since 1.0
|
26 |
* @return array Возвращает группу зарегистрируемых опций
|
|
|
|
|
27 |
*/
|
28 |
function wbcr_dan_get_plugin_options() {
|
29 |
$options = [];
|
@@ -33,32 +33,43 @@ function wbcr_dan_get_plugin_options() {
|
|
33 |
'html' => '<div class="wbcr-factory-page-group-header">' . '<strong>' . __( 'Admin notifications, Update nags', 'disable-admin-notices' ) . '</strong>' . '<p>' . __( 'Do you know the situation, when some plugin offers you to update to premium, to collect technical data and shows many annoying notices? You are close these notices every now and again but they newly appears and interfere your work with WordPress. Even worse, some plugin’s authors delete “close” button from notices and they shows in your admin panel forever.', 'disable-admin-notices' ) . '</p>' . '</div>'
|
34 |
];
|
35 |
|
36 |
-
$
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
'data' => [
|
42 |
-
[
|
43 |
-
'all',
|
44 |
-
__( 'All notices', 'disable-admin-notices' ),
|
45 |
-
__( 'Hide all notices globally.', 'disable-admin-notices' )
|
46 |
-
],
|
47 |
-
[
|
48 |
-
'only_selected',
|
49 |
-
__( 'Only selected', 'disable-admin-notices' ),
|
50 |
-
__( 'Hide selected notices only. You will see the link "Hide notification forever" in each notice. Push it and they will not bother you anymore.', 'disable-admin-notices' )
|
51 |
-
],
|
52 |
-
[
|
53 |
-
'not_hide',
|
54 |
-
__( "Don't nide", 'disable-admin-notices' ),
|
55 |
-
__( 'Do not hide notices and do not show “Hide notification forever” link for admin.', 'disable-admin-notices' )
|
56 |
-
]
|
57 |
],
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
'all' => [
|
63 |
'show' => '.factory-control-hide_admin_notices_user_roles',
|
64 |
'hide' => '.factory-control-reset_notices_button'
|
@@ -73,6 +84,30 @@ function wbcr_dan_get_plugin_options() {
|
|
73 |
]
|
74 |
];
|
75 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
/*$options[] = array(
|
77 |
'type' => 'dropdown',
|
78 |
'name' => 'hide_admin_notices_for',
|
@@ -130,8 +165,8 @@ function wbcr_dan_get_plugin_options() {
|
|
130 |
* Это необходимо для того, чтобы не создавать отдельную страницу в плагине Clearfy, \
|
131 |
* с настройками этого плагина, потому что это ухудшает юзабилити.
|
132 |
*
|
133 |
-
* @param array
|
134 |
-
* @param Wbcr_FactoryPages429_ImpressiveThemplate $page
|
135 |
*
|
136 |
* @return mixed Отсортированный массив с группой опций
|
137 |
*/
|
@@ -158,10 +193,11 @@ add_filter( 'wbcr_clr_additionally_form_options', 'wbcr_dan_additionally_form_op
|
|
158 |
* Эта модикация является не стандартной, поэтому мы не можете реалировать ее
|
159 |
* через фреймворк.
|
160 |
*
|
161 |
-
* @
|
|
|
162 |
* @since 1.0
|
163 |
*
|
164 |
-
* @
|
165 |
*/
|
166 |
function wbcr_dan_reset_notices_button( $html_builder ) {
|
167 |
global $wpdb;
|
@@ -184,33 +220,33 @@ function wbcr_dan_reset_notices_button( $html_builder ) {
|
|
184 |
}
|
185 |
|
186 |
?>
|
187 |
-
|
188 |
-
|
189 |
<?= __( 'Reset hidden notices for', 'disable-admin-notices' ); ?>
|
190 |
-
|
191 |
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAQAAABKmM6bAAAAUUlEQVQIHU3BsQ1AQABA0X/komIrnQHYwyhqQ1hBo9KZRKL9CBfeAwy2ri42JA4mPQ9rJ6OVt0BisFM3Po7qbEliru7m/FkY+TN64ZVxEzh4ndrMN7+Z+jXCAAAAAElFTkSuQmCC" alt="">
|
192 |
</span>
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
<?php wp_nonce_field( $form_name, 'wbcr_dan_reset_nonce' ); ?>
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
<?php if ( $reseted ): ?>
|
208 |
-
|
209 |
<?php endif; ?>
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
<?php
|
215 |
}
|
216 |
|
21 |
* Эта функция используется для общей страницы настроек текущего плагина,
|
22 |
* а также для раширения настроек в плагине Clearfy.
|
23 |
*
|
|
|
|
|
24 |
* @return array Возвращает группу зарегистрируемых опций
|
25 |
+
* @since 1.0
|
26 |
+
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
|
27 |
*/
|
28 |
function wbcr_dan_get_plugin_options() {
|
29 |
$options = [];
|
33 |
'html' => '<div class="wbcr-factory-page-group-header">' . '<strong>' . __( 'Admin notifications, Update nags', 'disable-admin-notices' ) . '</strong>' . '<p>' . __( 'Do you know the situation, when some plugin offers you to update to premium, to collect technical data and shows many annoying notices? You are close these notices every now and again but they newly appears and interfere your work with WordPress. Even worse, some plugin’s authors delete “close” button from notices and they shows in your admin panel forever.', 'disable-admin-notices' ) . '</p>' . '</div>'
|
34 |
];
|
35 |
|
36 |
+
$hide_admin_notices_data = [
|
37 |
+
[
|
38 |
+
'not_hide',
|
39 |
+
__( "Don't hide", 'disable-admin-notices' ),
|
40 |
+
__( 'Do not hide notices and do not show “Hide notification forever” link for admin.', 'disable-admin-notices' )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
],
|
42 |
+
[
|
43 |
+
'all',
|
44 |
+
__( 'All notices', 'disable-admin-notices' ),
|
45 |
+
__( 'Hide all notices globally.', 'disable-admin-notices' ) . sprintf( __( 'Watch the <a href="%s" target="_blank">video</a> to find out how it works .', 'disable-admin-notices' ), 'https://youtu.be/_Lv5i4P3Gqs' )
|
46 |
+
],
|
47 |
+
[
|
48 |
+
'only_selected',
|
49 |
+
__( 'Only selected', 'disable-admin-notices' ),
|
50 |
+
__( 'Hide selected notices only. You will see the link "Hide notification forever" in each notice. Push it and they will not bother you anymore.', 'disable-admin-notices' ) . sprintf( __( 'Watch the <a href="%s" target="_blank">video</a> to find out how it works .', 'disable-admin-notices' ), 'https://youtu.be/HazI81AsHuY' )
|
51 |
+
]
|
52 |
+
];
|
53 |
+
|
54 |
+
if ( ! defined( 'WCL_PLUGIN_ACTIVE' ) ) {
|
55 |
+
$hide_admin_notices_data[] = [
|
56 |
+
'compact_panel',
|
57 |
+
__( 'Compact panel', 'disable-admin-notices' ),
|
58 |
+
__( 'Collapse all notifications in one line (panel with notification counters), to see the notifications, you will need to click this panel.', 'disable-admin-notices' ) . sprintf( __( 'Watch the <a href="%s" target="_blank">video</a> to find out how it works .', 'disable-admin-notices' ), 'https://youtu.be/437u1Js2o2M' )
|
59 |
+
];
|
60 |
+
}
|
61 |
+
|
62 |
+
$options[] = [
|
63 |
+
'type' => 'dropdown',
|
64 |
+
'name' => 'hide_admin_notices',
|
65 |
+
'way' => 'buttons',
|
66 |
+
'title' => __( 'Hide admin notices', 'disable-admin-notices' ),
|
67 |
+
'data' => $hide_admin_notices_data,
|
68 |
+
'layout' => [ 'hint-type' => 'icon', 'hint-icon-color' => 'green' ],
|
69 |
+
'hint' => __( 'Some plugins shows notifications about premium version, data collecting or promote their services. Even if you push close button (that sometimes are impossible), notices are shows again in some time. This option allows you to control notices. Hide them all or each individually. Some plugins shows notifications about premium version, data collecting or promote their services. Even if you push close button (that sometimes are impossible), notices are shows again in some time. This option allows you to control notices. Hide them all or each individually.', 'disable-admin-notices' ),
|
70 |
+
'default' => 'only_selected',
|
71 |
+
'cssClass' => ! ( WDN_Plugin::app()->premium->is_activate() && WDN_Plugin::app()->premium->is_install_package() ) ? [ 'wdanpro-radio-premium-label' ] : [],
|
72 |
+
'events' => [
|
73 |
'all' => [
|
74 |
'show' => '.factory-control-hide_admin_notices_user_roles',
|
75 |
'hide' => '.factory-control-reset_notices_button'
|
84 |
]
|
85 |
];
|
86 |
|
87 |
+
if ( ! defined( 'WCL_PLUGIN_ACTIVE' ) ) {
|
88 |
+
$options[] = [
|
89 |
+
'type' => 'checkbox',
|
90 |
+
'way' => 'buttons',
|
91 |
+
'name' => 'disable_updates_nags_for_plugins',
|
92 |
+
'title' => __( 'Disable plugins updates nags', 'disable-admin-notices' ),
|
93 |
+
'layout' => [ 'hint-type' => 'icon', 'hint-icon-color' => 'grey' ],
|
94 |
+
'hint' => __( 'Disable plugins updates nags', 'disable-admin-notices' ),
|
95 |
+
'cssClass' => ! ( WDN_Plugin::app()->premium->is_activate() && WDN_Plugin::app()->premium->is_install_package() ) ? [ 'factory-checkbox-disabled wdanpro-checkbox-premium-label' ] : [],
|
96 |
+
'default' => false
|
97 |
+
];
|
98 |
+
|
99 |
+
$options[] = [
|
100 |
+
'type' => 'checkbox',
|
101 |
+
'way' => 'buttons',
|
102 |
+
'name' => 'disable_updates_nags_for_core',
|
103 |
+
'title' => __( 'Disable core updates nags', 'disable-admin-notices' ),
|
104 |
+
'layout' => [ 'hint-type' => 'icon', 'hint-icon-color' => 'grey' ],
|
105 |
+
'hint' => __( 'Disable core updates nags', 'disable-admin-notices' ),
|
106 |
+
'cssClass' => ! ( WDN_Plugin::app()->premium->is_activate() && WDN_Plugin::app()->premium->is_install_package() ) ? [ 'factory-checkbox-disabled wdanpro-checkbox-premium-label' ] : [],
|
107 |
+
'default' => false
|
108 |
+
];
|
109 |
+
}
|
110 |
+
|
111 |
/*$options[] = array(
|
112 |
'type' => 'dropdown',
|
113 |
'name' => 'hide_admin_notices_for',
|
165 |
* Это необходимо для того, чтобы не создавать отдельную страницу в плагине Clearfy, \
|
166 |
* с настройками этого плагина, потому что это ухудшает юзабилити.
|
167 |
*
|
168 |
+
* @param array $form Массив с группой настроек, страницы "Дополнительно" в плагине Clearfy
|
169 |
+
* @param Wbcr_FactoryPages429_ImpressiveThemplate $page Экземпляр страницы
|
170 |
*
|
171 |
* @return mixed Отсортированный массив с группой опций
|
172 |
*/
|
193 |
* Эта модикация является не стандартной, поэтому мы не можете реалировать ее
|
194 |
* через фреймворк.
|
195 |
*
|
196 |
+
* @param @param $html_builder Wbcr_FactoryForms427_Html
|
197 |
+
*
|
198 |
* @since 1.0
|
199 |
*
|
200 |
+
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
|
201 |
*/
|
202 |
function wbcr_dan_reset_notices_button( $html_builder ) {
|
203 |
global $wpdb;
|
220 |
}
|
221 |
|
222 |
?>
|
223 |
+
<div class="form-group form-group-checkbox factory-control-reset_notices_button">
|
224 |
+
<label for="wbcr_clearfy_reset_notices_button" class="col-sm-4 control-label">
|
225 |
<?= __( 'Reset hidden notices for', 'disable-admin-notices' ); ?>
|
226 |
+
<span class="factory-hint-icon factory-hint-icon-grey" data-toggle="factory-tooltip" data-placement="right" title="" data-original-title="<?php _e( 'Push reset hidden notices if you need to show hidden notices again.', 'disable-admin-notices' ) ?>">
|
227 |
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAQAAABKmM6bAAAAUUlEQVQIHU3BsQ1AQABA0X/komIrnQHYwyhqQ1hBo9KZRKL9CBfeAwy2ri42JA4mPQ9rJ6OVt0BisFM3Po7qbEliru7m/FkY+TN64ZVxEzh4ndrMN7+Z+jXCAAAAAElFTkSuQmCC" alt="">
|
228 |
</span>
|
229 |
+
</label>
|
230 |
+
<div class="control-group col-sm-8">
|
231 |
+
<div class="factory-checkbox factory-from-control-checkbox factory-buttons-way btn-group">
|
232 |
+
<form method="post">
|
233 |
<?php wp_nonce_field( $form_name, 'wbcr_dan_reset_nonce' ); ?>
|
234 |
+
<p>
|
235 |
+
<input type="radio" name="wbcr_dan_reset_for_users" value="current_user" checked/> <?= __( 'current user', 'disable-admin-notices' ); ?>
|
236 |
+
</p>
|
237 |
+
<p>
|
238 |
+
<input type="radio" name="wbcr_dan_reset_for_users" value="all"/> <?= __( 'all users', 'disable-admin-notices' ); ?>
|
239 |
+
</p>
|
240 |
+
<p>
|
241 |
+
<input type="submit" name="wbcr_dan_reset_action" value="<?= __( 'Reset notices', 'disable-admin-notices' ); ?>" class="button button-default"/>
|
242 |
+
</p>
|
243 |
<?php if ( $reseted ): ?>
|
244 |
+
<div style="color:green;margin-top:5px;"><?php _e( 'Hidden notices are successfully reset, now you can see them again!', 'disable-admin-notices' ) ?></div>
|
245 |
<?php endif; ?>
|
246 |
+
</form>
|
247 |
+
</div>
|
248 |
+
</div>
|
249 |
+
</div>
|
250 |
<?php
|
251 |
}
|
252 |
|
admin/pages/class-pages-edit-admin-bar.php
ADDED
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Exit if accessed directly
|
4 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
+
exit;
|
6 |
+
}
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Страница общих настроек для этого плагина.
|
10 |
+
*
|
11 |
+
* Не поддерживает режим работы с мультисаймами.
|
12 |
+
*
|
13 |
+
* @author Alexander Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
|
14 |
+
* @copyright (c) 2019 Webraftic Ltd
|
15 |
+
* @version 1.0
|
16 |
+
*/
|
17 |
+
class WDAN_Edit_Admin_Bar extends Wbcr_FactoryClearfy221_PageBase {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* {@inheritDoc}
|
21 |
+
*
|
22 |
+
* @var string
|
23 |
+
*/
|
24 |
+
public $id = "wdanp-edit-admin-bar";
|
25 |
+
|
26 |
+
/**
|
27 |
+
* {@inheritDoc}
|
28 |
+
*
|
29 |
+
* @var string
|
30 |
+
*/
|
31 |
+
public $type = "page";
|
32 |
+
|
33 |
+
/**
|
34 |
+
* {@inheritDoc}
|
35 |
+
*
|
36 |
+
* @var string
|
37 |
+
*/
|
38 |
+
public $page_menu_dashicon = 'dashicons-hidden';
|
39 |
+
|
40 |
+
/**
|
41 |
+
* {@inheritDoc}
|
42 |
+
*
|
43 |
+
* @since 2.0.5 - добавлен
|
44 |
+
* @var bool
|
45 |
+
*/
|
46 |
+
public $show_right_sidebar_in_options = false;
|
47 |
+
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @param WDN_Plugin $plugin
|
51 |
+
*/
|
52 |
+
public function __construct( $plugin ) {
|
53 |
+
$this->menu_title = __( 'Hide adminbar items', 'disable-admin-notices' );
|
54 |
+
$this->page_menu_short_description = __( 'You can hide an annoying adminbar menu', 'disable-admin-notices' );
|
55 |
+
|
56 |
+
parent::__construct( $plugin );
|
57 |
+
|
58 |
+
$this->plugin = $plugin;
|
59 |
+
|
60 |
+
add_action( 'wp_before_admin_bar_render', [ $this, 'remove_from_admin_bar' ], 999 );
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Requests assets (js and css) for the page.
|
65 |
+
*
|
66 |
+
* @param Wbcr_Factory429_ScriptList $scripts
|
67 |
+
* @param Wbcr_Factory429_StyleList $styles
|
68 |
+
*
|
69 |
+
* @return void
|
70 |
+
* @see Wbcr_FactoryPages429_AdminPage
|
71 |
+
*
|
72 |
+
*/
|
73 |
+
public function assets( $scripts, $styles ) {
|
74 |
+
parent::assets( $scripts, $styles );
|
75 |
+
|
76 |
+
$this->styles->add( WDN_PLUGIN_URL . '/admin/assets/css/settings.css' );
|
77 |
+
}
|
78 |
+
|
79 |
+
public function remove_from_admin_bar() {
|
80 |
+
global $wp_admin_bar;
|
81 |
+
|
82 |
+
if ( empty( $wp_admin_bar ) ) {
|
83 |
+
return;
|
84 |
+
}
|
85 |
+
|
86 |
+
$hidden_items = $this->plugin->getPopulateOption( 'hidden_adminbar_items', [] );
|
87 |
+
|
88 |
+
$nodes = [];
|
89 |
+
foreach ( $wp_admin_bar->get_nodes() as $node ) {
|
90 |
+
if ( false === $node->parent && ! empty( $node->title ) ) {
|
91 |
+
if ( "updates" === $node->id ) {
|
92 |
+
$node->title = "Updates";
|
93 |
+
}
|
94 |
+
if ( "comments" === $node->id ) {
|
95 |
+
$node->title = "Comments";
|
96 |
+
}
|
97 |
+
$nodes[ $node->id ] = strip_tags( $node->title );
|
98 |
+
}
|
99 |
+
}
|
100 |
+
|
101 |
+
$this->plugin->updatePopulateOption( 'adminbar_items', $nodes );
|
102 |
+
}
|
103 |
+
|
104 |
+
public function showPageContent() {
|
105 |
+
$all_items = $this->plugin->getPopulateOption( 'adminbar_items', [] );
|
106 |
+
$hidden_items = $this->plugin->getPopulateOption( 'hidden_adminbar_items', [] );
|
107 |
+
|
108 |
+
?>
|
109 |
+
|
110 |
+
<div class="wrdan-premium-fake-content">
|
111 |
+
<div class="wdan-premium-info">
|
112 |
+
<h3>Hide admin bar items (menu) PRO</h3>
|
113 |
+
<p>This function allows you to disable annoying menu items in the admin bar. Some plugins take up space
|
114 |
+
in
|
115 |
+
the admin bar to insert their ads. Just get rid of this ad with the premium features of our
|
116 |
+
plugin.</p>
|
117 |
+
<a class="wdan-button wdan-button-default wdan-button-go-pro" target="_blank" href="https://clearfy.pro/disable-admin-notices/">Go
|
118 |
+
Pro</a>
|
119 |
+
</div>
|
120 |
+
<div class="wdan-premium-layer"></div>
|
121 |
+
|
122 |
+
<h4>Disable adminbar items</h4>
|
123 |
+
<table class="wp-list-table widefat fixed striped">
|
124 |
+
<tr>
|
125 |
+
<th><strong>Menu title</strong></th>
|
126 |
+
<th style="width:100px;"><strong>Action</strong></th>
|
127 |
+
</tr>
|
128 |
+
<?php foreach ( (array) $all_items as $ID => $title ): ?>
|
129 |
+
|
130 |
+
<tr>
|
131 |
+
<td><?php echo $title; ?></td>
|
132 |
+
<td>
|
133 |
+
<?php if ( ! isset( $hidden_items[ $ID ] ) ): ?>
|
134 |
+
<a style="color:#e66113;" href="<?php echo wp_nonce_url( $this->getActionUrl( 'disable-adminbar-item', [ 'id' => $ID ] ), 'disable_adminbar_item_' . $ID ); ?>">Disable</a>
|
135 |
+
<?php else: ?>
|
136 |
+
<a style="color:#428bca;" href="<?php echo wp_nonce_url( $this->getActionUrl( 'enable-adminbar-item', [ 'id' => $ID ] ), 'enable_adminbar_item_' . $ID ); ?>">Enable</a>
|
137 |
+
<?php endif; ?>
|
138 |
+
</td>
|
139 |
+
</tr>
|
140 |
+
<?php endforeach; ?>
|
141 |
+
</table>
|
142 |
+
</div>
|
143 |
+
|
144 |
+
<?php
|
145 |
+
}
|
146 |
+
|
147 |
+
}
|
admin/pages/class-pages-edit-redirects.php
ADDED
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Exit if accessed directly
|
4 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
5 |
+
exit;
|
6 |
+
}
|
7 |
+
|
8 |
+
/**
|
9 |
+
* Страница общих настроек для этого плагина.
|
10 |
+
*
|
11 |
+
* Не поддерживает режим работы с мультисаймами.
|
12 |
+
*
|
13 |
+
* @author Alexander Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
|
14 |
+
* @copyright (c) 2019 Webraftic Ltd
|
15 |
+
* @version 1.0
|
16 |
+
*/
|
17 |
+
class WDAN_Block_Ad_Redirects extends Wbcr_FactoryClearfy221_PageBase {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* {@inheritDoc}
|
21 |
+
*
|
22 |
+
* @var string
|
23 |
+
*/
|
24 |
+
public $id = "wdanp-edit-redirects";
|
25 |
+
|
26 |
+
/**
|
27 |
+
* {@inheritDoc}
|
28 |
+
*
|
29 |
+
* @var string
|
30 |
+
*/
|
31 |
+
public $type = "page";
|
32 |
+
|
33 |
+
/**
|
34 |
+
* {@inheritDoc}
|
35 |
+
*
|
36 |
+
* @var string
|
37 |
+
*/
|
38 |
+
public $page_menu_dashicon = 'dashicons dashicons-undo';
|
39 |
+
|
40 |
+
/**
|
41 |
+
* {@inheritDoc}
|
42 |
+
*
|
43 |
+
* @since 2.0.5 - добавлен
|
44 |
+
* @var bool
|
45 |
+
*/
|
46 |
+
public $show_right_sidebar_in_options = false;
|
47 |
+
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @param WDN_Plugin $plugin
|
51 |
+
*/
|
52 |
+
public function __construct( $plugin ) {
|
53 |
+
$this->menu_title = __( 'Block ad redirects', 'disable-admin-notices' );
|
54 |
+
$this->page_menu_short_description = __( 'Break advertising redirects', 'disable-admin-notices' );
|
55 |
+
|
56 |
+
parent::__construct( $plugin );
|
57 |
+
|
58 |
+
$this->plugin = $plugin;
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Requests assets (js and css) for the page.
|
63 |
+
*
|
64 |
+
* @param Wbcr_Factory429_ScriptList $scripts
|
65 |
+
* @param Wbcr_Factory429_StyleList $styles
|
66 |
+
*
|
67 |
+
* @return void
|
68 |
+
* @see Wbcr_FactoryPages429_AdminPage
|
69 |
+
*
|
70 |
+
*/
|
71 |
+
public function assets( $scripts, $styles ) {
|
72 |
+
parent::assets( $scripts, $styles );
|
73 |
+
|
74 |
+
$this->styles->add( WDN_PLUGIN_URL . '/admin/assets/css/settings.css' );
|
75 |
+
}
|
76 |
+
|
77 |
+
public function get_break_redirects() {
|
78 |
+
return [];
|
79 |
+
}
|
80 |
+
|
81 |
+
public function showPageContent() {
|
82 |
+
$redirects = $this->get_break_redirects();
|
83 |
+
?>
|
84 |
+
|
85 |
+
<div class="wrdan-premium-fake-content">
|
86 |
+
<div class="wdan-premium-info">
|
87 |
+
<h3>Block Ad redirects PRO</h3>
|
88 |
+
<p>This feature will be useful to you to break advertising redirects. Some plugins, when updating or
|
89 |
+
during
|
90 |
+
installation, may redirect you to their page with advertisements or news. If plugins do this too
|
91 |
+
often,
|
92 |
+
it can be a headache for you. Break these redirects with our premium features.</p>
|
93 |
+
<a class="wdan-button wdan-button-default wdan-button-go-pro" target="_blank" href="https://clearfy.pro/disable-admin-notices/">
|
94 |
+
Go Pro
|
95 |
+
</a>
|
96 |
+
</div>
|
97 |
+
<div class="wdan-premium-layer"></div>
|
98 |
+
|
99 |
+
<h4>Block ad redirects</h4>
|
100 |
+
<form method="post">
|
101 |
+
<label for="wdnpro-redirect-url">Enter url for block:</label><br>
|
102 |
+
<input id="wdnpro-redirect-url" style="width:400px;" type="text" name="wdnpro_redirect_url">
|
103 |
+
<input type="submit" name="wdnpro_add_block" class="button" value="Add block">
|
104 |
+
</form>
|
105 |
+
<br>
|
106 |
+
<table class="wp-list-table widefat fixed striped">
|
107 |
+
<tr>
|
108 |
+
<th>Url</th>
|
109 |
+
<th style="width:200px;">Action</th>
|
110 |
+
</tr>
|
111 |
+
<tr>
|
112 |
+
<td>
|
113 |
+
https://site.com/wp-admin/?page=plugin-name&ads=redirect
|
114 |
+
</td>
|
115 |
+
<td>
|
116 |
+
<a style="color:#428bca;" href="#">Unblock</a>
|
117 |
+
</td>
|
118 |
+
</tr>
|
119 |
+
<tr>
|
120 |
+
<td>
|
121 |
+
https://site.com/wp-admin/?page=plugin-name&ads=redirect
|
122 |
+
</td>
|
123 |
+
<td>
|
124 |
+
<a style="color:#428bca;" href="#">Unblock</a>
|
125 |
+
</td>
|
126 |
+
</tr>
|
127 |
+
<tr>
|
128 |
+
<td>
|
129 |
+
https://site.com/wp-admin/?page=plugin-name&ads=redirect
|
130 |
+
</td>
|
131 |
+
<td>
|
132 |
+
<a style="color:#428bca;" href="#">Unblock</a>
|
133 |
+
</td>
|
134 |
+
</tr>
|
135 |
+
<tr>
|
136 |
+
<td>
|
137 |
+
https://site.com/wp-admin/?page=plugin-name&ads=redirect
|
138 |
+
</td>
|
139 |
+
<td>
|
140 |
+
<a style="color:#428bca;" href="#">Unblock</a>
|
141 |
+
</td>
|
142 |
+
</tr>
|
143 |
+
<tr>
|
144 |
+
<td>
|
145 |
+
https://site.com/wp-admin/?page=plugin-name&ads=redirect
|
146 |
+
</td>
|
147 |
+
<td>
|
148 |
+
<a style="color:#428bca;" href="#">Unblock</a>
|
149 |
+
</td>
|
150 |
+
</tr>
|
151 |
+
<tr>
|
152 |
+
<td>
|
153 |
+
https://site.com/wp-admin/?page=plugin-name&ads=redirect
|
154 |
+
</td>
|
155 |
+
<td>
|
156 |
+
<a style="color:#428bca;" href="#">Unblock</a>
|
157 |
+
</td>
|
158 |
+
</tr>
|
159 |
+
</table>
|
160 |
+
</div>
|
161 |
+
<?php
|
162 |
+
}
|
163 |
+
|
164 |
+
}
|
admin/pages/class-pages-license.php
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Exit if accessed directly
|
3 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
4 |
+
exit;
|
5 |
+
}
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Страница лицензирования плагина.
|
9 |
+
*
|
10 |
+
* Поддерживает режим работы с мультисаймами. Вы можете увидеть эту страницу в панели настройки сети.
|
11 |
+
*
|
12 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
|
13 |
+
*
|
14 |
+
* @copyright (c) 2018 Webraftic Ltd
|
15 |
+
*/
|
16 |
+
class WDN_LicensePage extends Wbcr_FactoryClearfy221_LicensePage {
|
17 |
+
|
18 |
+
/**
|
19 |
+
* {@inheritdoc}
|
20 |
+
*
|
21 |
+
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
|
22 |
+
* @since 1.6.0
|
23 |
+
* @var string
|
24 |
+
*/
|
25 |
+
public $id = 'wdn_license';
|
26 |
+
|
27 |
+
/**
|
28 |
+
* {@inheritdoc}
|
29 |
+
*
|
30 |
+
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
|
31 |
+
* @since 1.6.0
|
32 |
+
* @var string
|
33 |
+
*/
|
34 |
+
public $page_parent_page;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* WCL_LicensePage constructor.
|
38 |
+
*
|
39 |
+
* @param \Wbcr_Factory429_Plugin $plugin
|
40 |
+
*
|
41 |
+
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
|
42 |
+
*
|
43 |
+
*/
|
44 |
+
public function __construct( Wbcr_Factory429_Plugin $plugin ) {
|
45 |
+
$this->menu_title = __( 'License', 'robin-image-optimizer' );
|
46 |
+
$this->page_menu_short_description = __( 'Product activation', 'robin-image-optimizer' );
|
47 |
+
$this->plan_name = __( 'Disable admin notices premium', 'robin-image-optimizer' );
|
48 |
+
|
49 |
+
/*if ( defined( 'WIO_PLUGIN_ACTIVE' ) && ! wrio_is_clearfy_license_activate() ) {
|
50 |
+
$this->page_parent_page = 'none';
|
51 |
+
}*/
|
52 |
+
|
53 |
+
parent::__construct( $plugin );
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Adds a new plugin card to license components page
|
57 |
+
*
|
58 |
+
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
|
59 |
+
* @since 1.6.2
|
60 |
+
*/
|
61 |
+
/*add_filter( 'wbcr/clearfy/license/list_components', function ( $components ) {
|
62 |
+
$title = 'Free';
|
63 |
+
$icon = 'clearfy-premium-icon-256x256--lock.png';
|
64 |
+
|
65 |
+
if ( $this->is_premium ) {
|
66 |
+
$title = 'Premium';
|
67 |
+
$icon = 'clearfy-premium-icon-256x256--default.png';
|
68 |
+
}
|
69 |
+
|
70 |
+
$components[] = [
|
71 |
+
'name' => 'clearfy',
|
72 |
+
'title' => sprintf( __( 'Clearfy [%s]', 'clearfy' ), $title ),
|
73 |
+
'type' => 'internal',
|
74 |
+
'build' => $this->is_premium ? 'premium' : 'free',
|
75 |
+
'key' => $this->get_hidden_license_key(),
|
76 |
+
'plan' => $this->get_plan(),
|
77 |
+
'expiration_days' => $this->get_expiration_days(),
|
78 |
+
'quota' => $this->is_premium ? $this->premium_license->get_count_active_sites() . ' ' . __( 'of', 'clearfy' ) . ' ' . $this->premium_license->get_sites_quota() : null,
|
79 |
+
'subscription' => $this->is_premium && $this->premium_has_subscription ? sprintf( __( 'Automatic renewal, every %s', '' ), esc_attr( $this->get_billing_cycle_readable() ) ) : null,
|
80 |
+
'url' => 'https://clearfy.pro/',
|
81 |
+
'icon' => WCL_PLUGIN_URL . '/admin/assets/img/' . $icon,
|
82 |
+
'description' => __( 'Public License is a GPLv3 compatible license allowing you to change and use this version of the plugin for free. Please keep in mind this license covers only free edition of the plugin. Premium versions are distributed with other type of a license.', 'clearfy' ),
|
83 |
+
'license_page_id' => 'clearfy_license'
|
84 |
+
];
|
85 |
+
|
86 |
+
return $components;
|
87 |
+
} );*/
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* {@inheritdoc}
|
92 |
+
*
|
93 |
+
* @return string
|
94 |
+
* @since 1.6.0
|
95 |
+
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
|
96 |
+
*/
|
97 |
+
/*public function get_plan_description() {
|
98 |
+
$description = '<p style="font-size: 16px;">' . __( '<b>Clearfy Business</b> is a paid package of components for the popular free WordPress plugin named Clearfy. You get access to all paid components at one price.', 'clearfy' ) . '</p>';
|
99 |
+
$description .= '<p style="font-size: 16px;">' . __( 'Paid license guarantees that you can download and update existing and future paid components of the plugin.', 'clearfy' ) . '</p>';
|
100 |
+
|
101 |
+
return $description;
|
102 |
+
}*/
|
103 |
+
}
|
admin/pages/class-pages-more-features.php
DELETED
@@ -1,27 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* Рекламная страница.
|
4 |
-
*
|
5 |
-
* Используется для рекламы плагина Clearfy. Пользователь может изучить все возможности плагина Clearfy
|
6 |
-
* и перейти на лендинг плагина, чтобы скачать и попробовать его.
|
7 |
-
*
|
8 |
-
* Может быть использована только, если этот плагин используется как отдельный плагин, а не как аддон
|
9 |
-
* для плагина Clearfy. Если плагин загружен, как аддон для Clearfy, эта страница не будет подключена.
|
10 |
-
*
|
11 |
-
* НЕ поддерживает режим работы с мультисаймами!
|
12 |
-
*
|
13 |
-
* Github: https://github.com/alexkovalevv
|
14 |
-
*
|
15 |
-
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
|
16 |
-
* @copyright (c) 2018 Webraftic Ltd
|
17 |
-
* @version 1.0
|
18 |
-
*/
|
19 |
-
|
20 |
-
// Exit if accessed directly
|
21 |
-
if ( ! defined( 'ABSPATH' ) ) {
|
22 |
-
exit;
|
23 |
-
}
|
24 |
-
|
25 |
-
class WDN_MoreFeaturesPage extends Wbcr_FactoryClearfy221_MoreFeaturesPage {
|
26 |
-
|
27 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/pages/{class-pages-notices.php → class-pages-settings.php}
RENAMED
@@ -19,21 +19,21 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
19 |
exit;
|
20 |
}
|
21 |
|
22 |
-
class
|
23 |
|
24 |
/**
|
25 |
* {@inheritDoc}
|
26 |
*
|
27 |
* @var string
|
28 |
*/
|
29 |
-
public $id = "
|
30 |
|
31 |
/**
|
32 |
* {@inheritDoc}
|
33 |
*
|
34 |
* @var string
|
35 |
*/
|
36 |
-
public $page_menu_dashicon = 'dashicons-
|
37 |
|
38 |
/**
|
39 |
* {@inheritDoc}
|
@@ -50,12 +50,27 @@ class WDN_NoticesPage extends Wbcr_FactoryClearfy221_PageBase {
|
|
50 |
*/
|
51 |
public $show_right_sidebar_in_options = true;
|
52 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
|
54 |
/**
|
55 |
* @param Wbcr_Factory429_Plugin $plugin
|
56 |
*/
|
57 |
public function __construct( Wbcr_Factory429_Plugin $plugin ) {
|
58 |
-
$this->menu_title
|
|
|
59 |
|
60 |
$this->internal = false;
|
61 |
$this->menu_target = 'options-general.php';
|
@@ -66,6 +81,26 @@ class WDN_NoticesPage extends Wbcr_FactoryClearfy221_PageBase {
|
|
66 |
$this->plugin = $plugin;
|
67 |
}
|
68 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
/**
|
70 |
* {@inheritDoc}
|
71 |
*
|
19 |
exit;
|
20 |
}
|
21 |
|
22 |
+
class WDN_Settings_Page extends Wbcr_FactoryClearfy221_PageBase {
|
23 |
|
24 |
/**
|
25 |
* {@inheritDoc}
|
26 |
*
|
27 |
* @var string
|
28 |
*/
|
29 |
+
public $id = "wdan_settings";
|
30 |
|
31 |
/**
|
32 |
* {@inheritDoc}
|
33 |
*
|
34 |
* @var string
|
35 |
*/
|
36 |
+
public $page_menu_dashicon = 'dashicons-admin-generic';
|
37 |
|
38 |
/**
|
39 |
* {@inheritDoc}
|
50 |
*/
|
51 |
public $show_right_sidebar_in_options = true;
|
52 |
|
53 |
+
/**
|
54 |
+
* {@inheritDoc}
|
55 |
+
*
|
56 |
+
* @since 1.1.3 - Added
|
57 |
+
* @var bool - true show, false hide
|
58 |
+
*/
|
59 |
+
public $show_search_options_form = false;
|
60 |
+
|
61 |
+
/**
|
62 |
+
* {@inheritDoc}
|
63 |
+
* @var int
|
64 |
+
*/
|
65 |
+
public $page_menu_position = 100;
|
66 |
+
|
67 |
|
68 |
/**
|
69 |
* @param Wbcr_Factory429_Plugin $plugin
|
70 |
*/
|
71 |
public function __construct( Wbcr_Factory429_Plugin $plugin ) {
|
72 |
+
$this->menu_title = __( 'Hide admin notices', 'disable-admin-notices' );
|
73 |
+
$this->page_menu_short_description = __( 'General settings', 'disable-admin-notices' );
|
74 |
|
75 |
$this->internal = false;
|
76 |
$this->menu_target = 'options-general.php';
|
81 |
$this->plugin = $plugin;
|
82 |
}
|
83 |
|
84 |
+
public function getPageTitle() {
|
85 |
+
return __( 'Settings', 'disable-admin-notices' );
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Requests assets (js and css) for the page.
|
90 |
+
*
|
91 |
+
* @param Wbcr_Factory429_ScriptList $scripts
|
92 |
+
* @param Wbcr_Factory429_StyleList $styles
|
93 |
+
*
|
94 |
+
* @return void
|
95 |
+
* @see Wbcr_FactoryPages429_AdminPage
|
96 |
+
*
|
97 |
+
*/
|
98 |
+
public function assets( $scripts, $styles ) {
|
99 |
+
parent::assets( $scripts, $styles );
|
100 |
+
|
101 |
+
$this->styles->add( WDN_PLUGIN_URL . '/admin/assets/css/settings.css' );
|
102 |
+
}
|
103 |
+
|
104 |
/**
|
105 |
* {@inheritDoc}
|
106 |
*
|
admin/pages/class-pages.php
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Страница общих настроек для этого плагина.
|
4 |
+
*
|
5 |
+
* Может быть использована только, если этот плагин используется как отдельный плагин, а не как аддон
|
6 |
+
* дя плагина Clearfy. Если плагин загружен, как аддон для Clearfy, эта страница не будет подключена.
|
7 |
+
*
|
8 |
+
* Поддерживает режим работы с мультисаймами. Вы можете увидеть эту страницу в панели настройки сети.
|
9 |
+
*
|
10 |
+
* Github: https://github.com/alexkovalevv
|
11 |
+
*
|
12 |
+
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
|
13 |
+
* @copyright (c) 2018 Webraftic Ltd
|
14 |
+
* @version 1.0
|
15 |
+
*/
|
16 |
+
|
17 |
+
// Exit if accessed directly
|
18 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
19 |
+
exit;
|
20 |
+
}
|
21 |
+
|
22 |
+
class WDN_Page extends Wbcr_FactoryClearfy221_PageBase {
|
23 |
+
|
24 |
+
|
25 |
+
}
|
disable-admin-notices.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
* Plugin URI: https://webcraftic.com
|
5 |
* Description: Disable admin notices plugin gives you the option to hide updates warnings and inline notices in the admin panel.
|
6 |
* Author: Webcraftic <wordpress.webraftic@gmail.com>
|
7 |
-
* Version: 1.1
|
8 |
* Text Domain: disable-admin-notices
|
9 |
* Domain Path: /languages/
|
10 |
* Author URI: https://webcraftic.com
|
@@ -25,7 +25,7 @@
|
|
25 |
*/
|
26 |
|
27 |
// Exit if accessed directly
|
28 |
-
if( !defined('ABSPATH') ) {
|
29 |
exit;
|
30 |
}
|
31 |
|
@@ -37,53 +37,72 @@ if( !defined('ABSPATH') ) {
|
|
37 |
* -----------------------------------------------------------------------------
|
38 |
*/
|
39 |
|
40 |
-
require_once(dirname(__FILE__) . '/libs/factory/core/includes/class-factory-requirements.php');
|
41 |
|
42 |
// @formatter:off
|
43 |
$wdan_plugin_info = array(
|
44 |
-
'prefix'
|
45 |
-
'plugin_name'
|
46 |
-
'plugin_title'
|
47 |
|
48 |
// PLUGIN SUPPORT
|
49 |
-
'support_details'
|
50 |
-
'url'
|
51 |
'pages_map' => array(
|
52 |
'support' => 'support', // {site}/support
|
53 |
-
'docs'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
)
|
55 |
),
|
56 |
-
|
57 |
// PLUGIN ADVERTS
|
58 |
-
'render_adverts'
|
59 |
-
'adverts_settings'
|
60 |
'dashboard_widget' => false, // show dashboard widget (default: false)
|
61 |
-
'right_sidebar'
|
62 |
-
'notice'
|
63 |
),
|
64 |
|
65 |
// FRAMEWORK MODULES
|
66 |
'load_factory_modules' => array(
|
67 |
-
array('libs/factory/bootstrap', 'factory_bootstrap_430', 'admin'),
|
68 |
-
array('libs/factory/forms', 'factory_forms_427', 'admin'),
|
69 |
-
array('libs/factory/pages', 'factory_pages_429', 'admin'),
|
70 |
-
array('libs/factory/clearfy', 'factory_clearfy_221', 'all'),
|
71 |
-
array('libs/factory/
|
|
|
72 |
)
|
73 |
);
|
74 |
|
75 |
-
$wdan_compatibility = new Wbcr_Factory429_Requirements(__FILE__, array_merge($wdan_plugin_info, array(
|
76 |
-
'plugin_already_activate'
|
77 |
-
'required_php_version'
|
78 |
-
'required_wp_version'
|
79 |
'required_clearfy_check_component' => false
|
80 |
-
)));
|
|
|
|
|
81 |
|
82 |
/**
|
83 |
* If the plugin is compatible, then it will continue its work, otherwise it will be stopped,
|
84 |
* and the user will throw a warning.
|
85 |
*/
|
86 |
-
if(
|
87 |
return;
|
88 |
}
|
89 |
|
@@ -96,11 +115,11 @@ if( !$wdan_compatibility->check() ) {
|
|
96 |
*/
|
97 |
|
98 |
// This plugin is activated
|
99 |
-
define('WDN_PLUGIN_ACTIVE', true);
|
100 |
-
define('WDN_PLUGIN_VERSION', $wdan_compatibility->get_plugin_version());
|
101 |
-
define('WDN_PLUGIN_DIR', dirname(__FILE__));
|
102 |
-
define('WDN_PLUGIN_BASE', plugin_basename(__FILE__));
|
103 |
-
define('WDN_PLUGIN_URL', plugins_url(null, __FILE__));
|
104 |
|
105 |
|
106 |
|
@@ -110,24 +129,24 @@ define('WDN_PLUGIN_URL', plugins_url(null, __FILE__));
|
|
110 |
* -----------------------------------------------------------------------------
|
111 |
*/
|
112 |
|
113 |
-
require_once(WDN_PLUGIN_DIR . '/libs/factory/core/boot.php');
|
114 |
-
require_once(WDN_PLUGIN_DIR . '/includes/class-plugin.php');
|
115 |
|
116 |
try {
|
117 |
-
new WDN_Plugin(__FILE__, array_merge($wdan_plugin_info, array(
|
118 |
-
'plugin_version'
|
119 |
'plugin_text_domain' => $wdan_compatibility->get_text_domain(),
|
120 |
-
)));
|
121 |
} catch( Exception $e ) {
|
122 |
// Plugin wasn't initialized due to an error
|
123 |
-
define('WDN_PLUGIN_THROW_ERROR', true);
|
124 |
|
125 |
-
$wdan_plugin_error_func = function () use ($e) {
|
126 |
-
$error = sprintf("The %s plugin has stopped. <b>Error:</b> %s Code: %s", 'Webcraftic Disable Admin Notices', $e->getMessage(), $e->getCode());
|
127 |
echo '<div class="notice notice-error"><p>' . $error . '</p></div>';
|
128 |
};
|
129 |
|
130 |
-
add_action('admin_notices', $wdan_plugin_error_func);
|
131 |
-
add_action('network_admin_notices', $wdan_plugin_error_func);
|
132 |
}
|
133 |
// @formatter:on
|
4 |
* Plugin URI: https://webcraftic.com
|
5 |
* Description: Disable admin notices plugin gives you the option to hide updates warnings and inline notices in the admin panel.
|
6 |
* Author: Webcraftic <wordpress.webraftic@gmail.com>
|
7 |
+
* Version: 1.2.1
|
8 |
* Text Domain: disable-admin-notices
|
9 |
* Domain Path: /languages/
|
10 |
* Author URI: https://webcraftic.com
|
25 |
*/
|
26 |
|
27 |
// Exit if accessed directly
|
28 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
29 |
exit;
|
30 |
}
|
31 |
|
37 |
* -----------------------------------------------------------------------------
|
38 |
*/
|
39 |
|
40 |
+
require_once( dirname( __FILE__ ) . '/libs/factory/core/includes/class-factory-requirements.php' );
|
41 |
|
42 |
// @formatter:off
|
43 |
$wdan_plugin_info = array(
|
44 |
+
'prefix' => 'wbcr_dan_',
|
45 |
+
'plugin_name' => 'wbcr_dan',
|
46 |
+
'plugin_title' => __( 'Webcraftic disable admin notices', 'disable-admin-notices' ),
|
47 |
|
48 |
// PLUGIN SUPPORT
|
49 |
+
'support_details' => array(
|
50 |
+
'url' => 'https://clearfy.pro/',
|
51 |
'pages_map' => array(
|
52 |
'support' => 'support', // {site}/support
|
53 |
+
'docs' => 'docs', // {site}/docs,
|
54 |
+
'pricing' => 'disable-admin-notices'
|
55 |
+
)
|
56 |
+
),
|
57 |
+
// PLUGIN PREMIUM SETTINGS
|
58 |
+
'has_premium' => true,
|
59 |
+
'license_settings' => array(
|
60 |
+
'provider' => 'freemius',
|
61 |
+
'slug' => 'disable-admin-notices-premium',
|
62 |
+
'plugin_id' => '6456',
|
63 |
+
'public_key' => 'pk_0570ec3c1b4100b9c9a0cbfe80f9f',
|
64 |
+
'price' => 29,
|
65 |
+
'has_updates' => true,
|
66 |
+
'updates_settings' => array(
|
67 |
+
'maybe_rollback' => true,
|
68 |
+
'rollback_settings' => array(
|
69 |
+
'prev_stable_version' => '0.0.0'
|
70 |
+
)
|
71 |
)
|
72 |
),
|
|
|
73 |
// PLUGIN ADVERTS
|
74 |
+
'render_adverts' => true,
|
75 |
+
'adverts_settings' => array(
|
76 |
'dashboard_widget' => false, // show dashboard widget (default: false)
|
77 |
+
'right_sidebar' => true, // show adverts sidebar (default: false)
|
78 |
+
'notice' => false, // show notice message (default: false)
|
79 |
),
|
80 |
|
81 |
// FRAMEWORK MODULES
|
82 |
'load_factory_modules' => array(
|
83 |
+
array( 'libs/factory/bootstrap', 'factory_bootstrap_430', 'admin' ),
|
84 |
+
array( 'libs/factory/forms', 'factory_forms_427', 'admin' ),
|
85 |
+
array( 'libs/factory/pages', 'factory_pages_429', 'admin' ),
|
86 |
+
array( 'libs/factory/clearfy', 'factory_clearfy_221', 'all' ),
|
87 |
+
array( 'libs/factory/freemius', 'factory_freemius_117', 'all' ),
|
88 |
+
array( 'libs/factory/adverts', 'factory_adverts_109', 'admin' )
|
89 |
)
|
90 |
);
|
91 |
|
92 |
+
$wdan_compatibility = new Wbcr_Factory429_Requirements( __FILE__, array_merge( $wdan_plugin_info, array(
|
93 |
+
'plugin_already_activate' => defined( 'WDN_PLUGIN_ACTIVE' ),
|
94 |
+
'required_php_version' => '5.4',
|
95 |
+
'required_wp_version' => '4.2.0',
|
96 |
'required_clearfy_check_component' => false
|
97 |
+
) ) );
|
98 |
+
|
99 |
+
|
100 |
|
101 |
/**
|
102 |
* If the plugin is compatible, then it will continue its work, otherwise it will be stopped,
|
103 |
* and the user will throw a warning.
|
104 |
*/
|
105 |
+
if ( ! $wdan_compatibility->check() ) {
|
106 |
return;
|
107 |
}
|
108 |
|
115 |
*/
|
116 |
|
117 |
// This plugin is activated
|
118 |
+
define( 'WDN_PLUGIN_ACTIVE', true );
|
119 |
+
define( 'WDN_PLUGIN_VERSION', $wdan_compatibility->get_plugin_version() );
|
120 |
+
define( 'WDN_PLUGIN_DIR', dirname( __FILE__ ) );
|
121 |
+
define( 'WDN_PLUGIN_BASE', plugin_basename( __FILE__ ) );
|
122 |
+
define( 'WDN_PLUGIN_URL', plugins_url( null, __FILE__ ) );
|
123 |
|
124 |
|
125 |
|
129 |
* -----------------------------------------------------------------------------
|
130 |
*/
|
131 |
|
132 |
+
require_once( WDN_PLUGIN_DIR . '/libs/factory/core/boot.php' );
|
133 |
+
require_once( WDN_PLUGIN_DIR . '/includes/class-plugin.php' );
|
134 |
|
135 |
try {
|
136 |
+
new WDN_Plugin( __FILE__, array_merge( $wdan_plugin_info, array(
|
137 |
+
'plugin_version' => WDN_PLUGIN_VERSION,
|
138 |
'plugin_text_domain' => $wdan_compatibility->get_text_domain(),
|
139 |
+
) ) );
|
140 |
} catch( Exception $e ) {
|
141 |
// Plugin wasn't initialized due to an error
|
142 |
+
define( 'WDN_PLUGIN_THROW_ERROR', true );
|
143 |
|
144 |
+
$wdan_plugin_error_func = function () use ( $e ) {
|
145 |
+
$error = sprintf( "The %s plugin has stopped. <b>Error:</b> %s Code: %s", 'Webcraftic Disable Admin Notices', $e->getMessage(), $e->getCode() );
|
146 |
echo '<div class="notice notice-error"><p>' . $error . '</p></div>';
|
147 |
};
|
148 |
|
149 |
+
add_action( 'admin_notices', $wdan_plugin_error_func );
|
150 |
+
add_action( 'network_admin_notices', $wdan_plugin_error_func );
|
151 |
}
|
152 |
// @formatter:on
|
includes/class-plugin.php
CHANGED
@@ -26,7 +26,7 @@ class WDN_Plugin extends Wbcr_Factory429_Plugin {
|
|
26 |
|
27 |
/**
|
28 |
* @param string $plugin_path
|
29 |
-
* @param array
|
30 |
*
|
31 |
* @throws Exception
|
32 |
*/
|
@@ -51,28 +51,36 @@ class WDN_Plugin extends Wbcr_Factory429_Plugin {
|
|
51 |
}
|
52 |
|
53 |
private function registerPages() {
|
54 |
-
|
55 |
-
|
|
|
|
|
|
|
56 |
}
|
57 |
|
58 |
-
self::app()->registerPage( '
|
59 |
-
self::app()->registerPage( 'WDN_MoreFeaturesPage', WDN_PLUGIN_DIR . '/admin/pages/class-pages-more-features.php' );
|
60 |
}
|
61 |
|
62 |
private function admin_scripts() {
|
63 |
require( WDN_PLUGIN_DIR . '/admin/options.php' );
|
64 |
|
65 |
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
66 |
-
|
67 |
-
|
68 |
}
|
69 |
|
70 |
-
|
71 |
-
|
|
|
|
|
|
|
|
|
|
|
72 |
}
|
73 |
|
74 |
private function global_scripts() {
|
75 |
-
|
|
|
76 |
new WDN_ConfigHideNotices( self::$app );
|
77 |
}
|
78 |
}
|
26 |
|
27 |
/**
|
28 |
* @param string $plugin_path
|
29 |
+
* @param array $data
|
30 |
*
|
31 |
* @throws Exception
|
32 |
*/
|
51 |
}
|
52 |
|
53 |
private function registerPages() {
|
54 |
+
self::app()->registerPage( 'WDN_Settings_Page', WDN_PLUGIN_DIR . '/admin/pages/class-pages-settings.php' );
|
55 |
+
|
56 |
+
if ( ! ( $this->premium->is_activate() && $this->premium->is_install_package() ) ) {
|
57 |
+
self::app()->registerPage( 'WDAN_Block_Ad_Redirects', WDN_PLUGIN_DIR . '/admin/pages/class-pages-edit-redirects.php' );
|
58 |
+
self::app()->registerPage( 'WDAN_Edit_Admin_Bar', WDN_PLUGIN_DIR . '/admin/pages/class-pages-edit-admin-bar.php' );
|
59 |
}
|
60 |
|
61 |
+
self::app()->registerPage( 'WDN_LicensePage', WDN_PLUGIN_DIR . '/admin/pages/class-pages-license.php' );
|
|
|
62 |
}
|
63 |
|
64 |
private function admin_scripts() {
|
65 |
require( WDN_PLUGIN_DIR . '/admin/options.php' );
|
66 |
|
67 |
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
|
68 |
+
require_once( WDN_PLUGIN_DIR . '/admin/ajax/hide-notice.php' );
|
69 |
+
require_once( WDN_PLUGIN_DIR . '/admin/ajax/restore-notice.php' );
|
70 |
}
|
71 |
|
72 |
+
require_once( WDN_PLUGIN_DIR . '/admin/boot.php' );
|
73 |
+
require_once( WDN_PLUGIN_DIR . '/admin/pages/class-pages-edit-admin-bar.php' );
|
74 |
+
require_once( WDN_PLUGIN_DIR . '/admin/pages/class-pages-edit-redirects.php' );
|
75 |
+
|
76 |
+
add_action( 'plugins_loaded', function () {
|
77 |
+
$this->registerPages();
|
78 |
+
}, 30 );
|
79 |
}
|
80 |
|
81 |
private function global_scripts() {
|
82 |
+
require_once( WDN_PLUGIN_DIR . '/includes/function.php' );
|
83 |
+
require_once( WDN_PLUGIN_DIR . '/includes/classes/class-configurate-notices.php' );
|
84 |
new WDN_ConfigHideNotices( self::$app );
|
85 |
}
|
86 |
}
|
includes/classes/class-configurate-notices.php
CHANGED
@@ -11,109 +11,104 @@
|
|
11 |
*/
|
12 |
|
13 |
// Exit if accessed directly
|
14 |
-
if( !defined('ABSPATH') ) {
|
15 |
exit;
|
16 |
}
|
17 |
|
18 |
class WDN_ConfigHideNotices extends Wbcr_FactoryClearfy221_Configurate {
|
19 |
|
20 |
-
public function registerActionsAndFilters()
|
21 |
-
|
22 |
-
|
23 |
-
$hide_notices_type = $this->getPopulateOption('hide_admin_notices');
|
24 |
|
25 |
-
if( $hide_notices_type
|
26 |
-
add_action('admin_print_scripts', [$this, 'catchNotices'], 999);
|
27 |
|
28 |
-
if( empty($hide_notices_type) || $hide_notices_type == 'only_selected' ) {
|
29 |
-
add_action('admin_head', [$this, 'printNotices'], 999);
|
30 |
}
|
31 |
|
32 |
-
if( !empty($hide_notices_type) ) {
|
33 |
-
add_action('admin_bar_menu', [$this, 'notificationsPanel'], 999);
|
34 |
-
add_action('admin_enqueue_scripts', [$this, 'notificationsPanelStyles']);
|
35 |
}
|
36 |
}
|
37 |
}
|
38 |
}
|
39 |
|
40 |
-
public function printNotices()
|
41 |
-
|
42 |
-
|
43 |
-
add_action('network_admin_notices', [$this, 'noticesCollection']);
|
44 |
} else {
|
45 |
-
add_action('admin_notices', [$this, 'noticesCollection']);
|
46 |
}
|
47 |
}
|
48 |
|
49 |
|
50 |
-
public function notificationsPanelStyles()
|
51 |
-
|
52 |
-
if( !$this->getPopulateOption('show_notices_in_adminbar', false) && current_user_can('manage_network') ) {
|
53 |
return;
|
54 |
}
|
55 |
|
56 |
-
wp_enqueue_style('wbcr-notification-panel-styles', WDN_PLUGIN_URL . '/admin/assets/css/notifications-panel.css', [], $this->plugin->getPluginVersion());
|
57 |
-
wp_enqueue_script('wbcr-notification-panel-scripts', WDN_PLUGIN_URL . '/admin/assets/js/notifications-panel.js', [], $this->plugin->getPluginVersion());
|
58 |
}
|
59 |
|
60 |
-
public function notificationsPanel(&$wp_admin_bar)
|
61 |
-
|
62 |
-
if( !$this->getPopulateOption('show_notices_in_adminbar', false) ) {
|
63 |
return;
|
64 |
}
|
65 |
|
66 |
-
if( current_user_can('manage_options') || current_user_can('manage_network') ) {
|
67 |
$titles = [];
|
68 |
|
69 |
-
$notifications = get_user_meta(get_current_user_id(), WDN_Plugin::app()->getOptionName('hidden_notices'), true);
|
70 |
|
71 |
-
if( empty($notifications) ) {
|
72 |
return;
|
73 |
}
|
74 |
|
75 |
-
$cont_notifications = sizeof($notifications);
|
76 |
|
77 |
// Add top menu
|
78 |
-
$wp_admin_bar->add_menu([
|
79 |
-
'id'
|
80 |
'parent' => 'top-secondary',
|
81 |
-
'title'
|
82 |
-
'href'
|
83 |
-
]);
|
84 |
|
85 |
// loop
|
86 |
-
if( !empty($notifications) ) {
|
87 |
$i = 0;
|
88 |
-
foreach($notifications as $notice_id => $message) {
|
89 |
-
$message = $this->getExcerpt(stripslashes($message), 0, 350);
|
90 |
$message .= '<div class="wbcr-han-panel-restore-notify-line">';
|
91 |
-
$message .= '<a href="#" data-nonce="' . wp_create_nonce($this->plugin->getPluginName() . '_ajax_restore_notice_nonce');
|
92 |
-
$message .= '" data-notice-id="' . esc_attr($notice_id) . '" class="wbcr-han-panel-restore-notify-link">';
|
93 |
-
$message .= __('Restore notice', 'clearfy') . (isset($titles[$notice_id]) ? ' (' . $titles[$notice_id] . ')' : '');
|
94 |
$message .= '</a></div>';
|
95 |
|
96 |
-
$wp_admin_bar->add_menu([
|
97 |
-
'id'
|
98 |
'parent' => 'wbcr-han-notify-panel',
|
99 |
-
'title'
|
100 |
-
'href'
|
101 |
-
'meta'
|
102 |
'class' => ''
|
103 |
]
|
104 |
-
]);
|
105 |
|
106 |
-
$i++;
|
107 |
}
|
108 |
}
|
109 |
}
|
110 |
}
|
111 |
|
112 |
-
public function noticesCollection()
|
113 |
-
{
|
114 |
global $wbcr_dan_plugin_all_notices;
|
115 |
|
116 |
-
if( empty($wbcr_dan_plugin_all_notices) ) {
|
117 |
return;
|
118 |
}
|
119 |
?>
|
@@ -201,20 +196,19 @@ class WDN_ConfigHideNotices extends Wbcr_FactoryClearfy221_Configurate {
|
|
201 |
});
|
202 |
</script>
|
203 |
<?php
|
204 |
-
foreach($wbcr_dan_plugin_all_notices as $val) {
|
205 |
echo $val;
|
206 |
}
|
207 |
}
|
208 |
|
209 |
-
public function catchNotices()
|
210 |
-
{
|
211 |
global $wbcr_dan_plugin_all_notices;
|
212 |
|
213 |
try {
|
214 |
-
if( is_multisite() && is_network_admin() ) {
|
215 |
-
$wp_filter_admin_notices = &$this->getWPFilter('network_admin_notices');
|
216 |
} else {
|
217 |
-
$wp_filter_admin_notices = &$this->getWPFilter('admin_notices');
|
218 |
}
|
219 |
//todo: Доработать all admin notices
|
220 |
|
@@ -222,16 +216,16 @@ class WDN_ConfigHideNotices extends Wbcr_FactoryClearfy221_Configurate {
|
|
222 |
$wp_filter_admin_notices = null;
|
223 |
}
|
224 |
|
225 |
-
$hide_notices_type = $this->getPopulateOption('hide_admin_notices');
|
226 |
|
227 |
-
if( empty($hide_notices_type) || $hide_notices_type == 'only_selected' ) {
|
228 |
-
$get_hidden_notices = get_user_meta(get_current_user_id(), WDN_Plugin::app()->getOptionName('hidden_notices'), true);
|
229 |
|
230 |
$content = [];
|
231 |
-
foreach((array)$wp_filter_admin_notices as $filters) {
|
232 |
-
foreach($filters as $callback_name => $callback) {
|
233 |
|
234 |
-
if( 'usof_hide_admin_notices_start' == $callback_name || 'usof_hide_admin_notices_end' == $callback_name ) {
|
235 |
continue;
|
236 |
}
|
237 |
|
@@ -239,69 +233,69 @@ class WDN_ConfigHideNotices extends Wbcr_FactoryClearfy221_Configurate {
|
|
239 |
|
240 |
// #CLRF-140 fix bug for php7
|
241 |
// when the developers forgot to delete the argument in the function of implementing the notification.
|
242 |
-
$args
|
243 |
-
$accepted_args = isset($callback['accepted_args']) && !empty($callback['accepted_args']) ? $callback['accepted_args'] : 0;
|
244 |
|
245 |
-
if( $accepted_args > 0 ) {
|
246 |
-
for($i = 0; $i < (int)$accepted_args; $i++) {
|
247 |
$args[] = null;
|
248 |
}
|
249 |
}
|
250 |
//===========
|
251 |
|
252 |
-
call_user_func_array($callback['function'], $args);
|
253 |
$cont = ob_get_clean();
|
254 |
|
255 |
-
if( empty($cont) ) {
|
256 |
continue;
|
257 |
}
|
258 |
|
259 |
-
$salt
|
260 |
-
$uniq_id1 = md5($cont . $salt);
|
261 |
-
$uniq_id2 = md5($callback_name . $salt);
|
262 |
|
263 |
-
if( is_array($callback['function']) && sizeof($callback['function']) == 2 ) {
|
264 |
$class = $callback['function'][0];
|
265 |
-
if( is_object($class) ) {
|
266 |
-
$class_name
|
267 |
$method_name = $callback['function'][1];
|
268 |
-
$uniq_id2
|
269 |
}
|
270 |
}
|
271 |
|
272 |
//838339d1a188e17fec838c2df3058603
|
273 |
//838339d1a188e17fec838c2df3058603
|
274 |
-
if( !empty($get_hidden_notices) ) {
|
275 |
|
276 |
$skip_notice = true;
|
277 |
-
foreach((array)$get_hidden_notices as $key => $notice) {
|
278 |
-
$splited_notice_id = explode('_', $key);
|
279 |
-
if( empty($splited_notice_id) || sizeof($splited_notice_id) < 2 ) {
|
280 |
continue;
|
281 |
}
|
282 |
$compare_notice_id_1 = $splited_notice_id[0];
|
283 |
$compare_notice_id_2 = $splited_notice_id[1];
|
284 |
|
285 |
-
if( $compare_notice_id_1 == $uniq_id1 || $compare_notice_id_2 == $uniq_id2 ) {
|
286 |
$skip_notice = false;
|
287 |
}
|
288 |
}
|
289 |
|
290 |
-
if(
|
291 |
continue;
|
292 |
}
|
293 |
}
|
294 |
|
295 |
-
$hide_link = '<a href="#" data-nonce="' . wp_create_nonce($this->plugin->getPluginName() . '_ajax_hide_notices_nonce') . '" data-notice-id="' . $uniq_id1 . '_' . $uniq_id2 . '" class="wbcr-dan-hide-notice-link">[' . __('Hide notification forever', 'disable-admin-notices') . ']</a>';
|
296 |
|
297 |
// Fix for Woocommerce membership
|
298 |
-
if( $cont != '<div class="js-wc-memberships-admin-notice-placeholder"></div>' ) {
|
299 |
-
$cont = preg_replace('/<(script|style)([^>]+)?>(.*?)<\/(script|style)>/is', '', $cont);
|
300 |
-
$cont = rtrim(trim($cont));
|
301 |
-
$cont = preg_replace('/^(<div[^>]+>)(.*?)(<\/div>)$/is', '$1<div class="wbcr-dan-hide-notices">$2' . $hide_link . '</div>$3', $cont);
|
302 |
}
|
303 |
|
304 |
-
if( empty($cont) ) {
|
305 |
continue;
|
306 |
}
|
307 |
$content[] = $cont;
|
@@ -311,6 +305,7 @@ class WDN_ConfigHideNotices extends Wbcr_FactoryClearfy221_Configurate {
|
|
311 |
$wbcr_dan_plugin_all_notices = $content;
|
312 |
}
|
313 |
|
|
|
314 |
try {
|
315 |
$wp_filter_user_admin_notices = &$this->getWPFilter('user_admin_notices');
|
316 |
} catch( Exception $e ) {
|
@@ -402,13 +397,12 @@ class WDN_ConfigHideNotices extends Wbcr_FactoryClearfy221_Configurate {
|
|
402 |
*
|
403 |
* @return String excerpt
|
404 |
*/
|
405 |
-
public function getExcerpt($str, $startPos = 0, $maxLength = 100)
|
406 |
-
|
407 |
-
|
408 |
-
$
|
409 |
-
$
|
410 |
-
$excerpt
|
411 |
-
$excerpt .= '...';
|
412 |
} else {
|
413 |
$excerpt = $str;
|
414 |
}
|
@@ -427,17 +421,16 @@ class WDN_ConfigHideNotices extends Wbcr_FactoryClearfy221_Configurate {
|
|
427 |
* @return array $wp_filter callbacks array by link
|
428 |
* @throws Exception if key not exists
|
429 |
*/
|
430 |
-
private function &getWPFilter($key)
|
431 |
-
{
|
432 |
global $wp_version, $wp_filter;
|
433 |
|
434 |
-
if( !isset($wp_filter[$key]) ) {
|
435 |
-
throw new Exception('key not exists');
|
436 |
}
|
437 |
-
if( version_compare($wp_version, '4.7.0', '>=') ) {
|
438 |
-
return $wp_filter[$key]->callbacks;
|
439 |
} else {
|
440 |
-
return $wp_filter[$key];
|
441 |
}
|
442 |
}
|
443 |
}
|
11 |
*/
|
12 |
|
13 |
// Exit if accessed directly
|
14 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
15 |
exit;
|
16 |
}
|
17 |
|
18 |
class WDN_ConfigHideNotices extends Wbcr_FactoryClearfy221_Configurate {
|
19 |
|
20 |
+
public function registerActionsAndFilters() {
|
21 |
+
if ( is_admin() ) {
|
22 |
+
$hide_notices_type = $this->getPopulateOption( 'hide_admin_notices' );
|
|
|
23 |
|
24 |
+
if ( 'not_hide' !== $hide_notices_type && 'compact_panel' !== $hide_notices_type ) {
|
25 |
+
add_action( 'admin_print_scripts', [ $this, 'catchNotices' ], 999 );
|
26 |
|
27 |
+
if ( empty( $hide_notices_type ) || $hide_notices_type == 'only_selected' ) {
|
28 |
+
add_action( 'admin_head', [ $this, 'printNotices' ], 999 );
|
29 |
}
|
30 |
|
31 |
+
if ( ! empty( $hide_notices_type ) ) {
|
32 |
+
add_action( 'admin_bar_menu', [ $this, 'notificationsPanel' ], 999 );
|
33 |
+
add_action( 'admin_enqueue_scripts', [ $this, 'notificationsPanelStyles' ] );
|
34 |
}
|
35 |
}
|
36 |
}
|
37 |
}
|
38 |
|
39 |
+
public function printNotices() {
|
40 |
+
if ( is_multisite() && is_network_admin() ) {
|
41 |
+
add_action( 'network_admin_notices', [ $this, 'noticesCollection' ] );
|
|
|
42 |
} else {
|
43 |
+
add_action( 'admin_notices', [ $this, 'noticesCollection' ] );
|
44 |
}
|
45 |
}
|
46 |
|
47 |
|
48 |
+
public function notificationsPanelStyles() {
|
49 |
+
if ( ! $this->getPopulateOption( 'show_notices_in_adminbar', false ) && current_user_can( 'manage_network' ) ) {
|
|
|
50 |
return;
|
51 |
}
|
52 |
|
53 |
+
wp_enqueue_style( 'wbcr-notification-panel-styles', WDN_PLUGIN_URL . '/admin/assets/css/notifications-panel.css', [], $this->plugin->getPluginVersion() );
|
54 |
+
wp_enqueue_script( 'wbcr-notification-panel-scripts', WDN_PLUGIN_URL . '/admin/assets/js/notifications-panel.js', [], $this->plugin->getPluginVersion() );
|
55 |
}
|
56 |
|
57 |
+
public function notificationsPanel( &$wp_admin_bar ) {
|
58 |
+
if ( ! $this->getPopulateOption( 'show_notices_in_adminbar', false ) ) {
|
|
|
59 |
return;
|
60 |
}
|
61 |
|
62 |
+
if ( current_user_can( 'manage_options' ) || current_user_can( 'manage_network' ) ) {
|
63 |
$titles = [];
|
64 |
|
65 |
+
$notifications = get_user_meta( get_current_user_id(), WDN_Plugin::app()->getOptionName( 'hidden_notices' ), true );
|
66 |
|
67 |
+
if ( empty( $notifications ) ) {
|
68 |
return;
|
69 |
}
|
70 |
|
71 |
+
$cont_notifications = sizeof( $notifications );
|
72 |
|
73 |
// Add top menu
|
74 |
+
$wp_admin_bar->add_menu( [
|
75 |
+
'id' => 'wbcr-han-notify-panel',
|
76 |
'parent' => 'top-secondary',
|
77 |
+
'title' => sprintf( __( 'Notifications %s', 'disable-admin-notices' ), '<span class="wbcr-han-adminbar-counter">' . $cont_notifications . '</span>' ),
|
78 |
+
'href' => false
|
79 |
+
] );
|
80 |
|
81 |
// loop
|
82 |
+
if ( ! empty( $notifications ) ) {
|
83 |
$i = 0;
|
84 |
+
foreach ( $notifications as $notice_id => $message ) {
|
85 |
+
$message = $this->getExcerpt( stripslashes( $message ), 0, 350 );
|
86 |
$message .= '<div class="wbcr-han-panel-restore-notify-line">';
|
87 |
+
$message .= '<a href="#" data-nonce="' . wp_create_nonce( $this->plugin->getPluginName() . '_ajax_restore_notice_nonce' );
|
88 |
+
$message .= '" data-notice-id="' . esc_attr( $notice_id ) . '" class="wbcr-han-panel-restore-notify-link">';
|
89 |
+
$message .= __( 'Restore notice', 'clearfy' ) . ( isset( $titles[ $notice_id ] ) ? ' (' . $titles[ $notice_id ] . ')' : '' );
|
90 |
$message .= '</a></div>';
|
91 |
|
92 |
+
$wp_admin_bar->add_menu( [
|
93 |
+
'id' => 'wbcr-han-notify-panel-item-' . $i,
|
94 |
'parent' => 'wbcr-han-notify-panel',
|
95 |
+
'title' => $message,
|
96 |
+
'href' => false,
|
97 |
+
'meta' => [
|
98 |
'class' => ''
|
99 |
]
|
100 |
+
] );
|
101 |
|
102 |
+
$i ++;
|
103 |
}
|
104 |
}
|
105 |
}
|
106 |
}
|
107 |
|
108 |
+
public function noticesCollection() {
|
|
|
109 |
global $wbcr_dan_plugin_all_notices;
|
110 |
|
111 |
+
if ( empty( $wbcr_dan_plugin_all_notices ) ) {
|
112 |
return;
|
113 |
}
|
114 |
?>
|
196 |
});
|
197 |
</script>
|
198 |
<?php
|
199 |
+
foreach ( $wbcr_dan_plugin_all_notices as $val ) {
|
200 |
echo $val;
|
201 |
}
|
202 |
}
|
203 |
|
204 |
+
public function catchNotices() {
|
|
|
205 |
global $wbcr_dan_plugin_all_notices;
|
206 |
|
207 |
try {
|
208 |
+
if ( is_multisite() && is_network_admin() ) {
|
209 |
+
$wp_filter_admin_notices = &$this->getWPFilter( 'network_admin_notices' );
|
210 |
} else {
|
211 |
+
$wp_filter_admin_notices = &$this->getWPFilter( 'admin_notices' );
|
212 |
}
|
213 |
//todo: Доработать all admin notices
|
214 |
|
216 |
$wp_filter_admin_notices = null;
|
217 |
}
|
218 |
|
219 |
+
$hide_notices_type = $this->getPopulateOption( 'hide_admin_notices' );
|
220 |
|
221 |
+
if ( empty( $hide_notices_type ) || $hide_notices_type == 'only_selected' ) {
|
222 |
+
$get_hidden_notices = get_user_meta( get_current_user_id(), WDN_Plugin::app()->getOptionName( 'hidden_notices' ), true );
|
223 |
|
224 |
$content = [];
|
225 |
+
foreach ( (array) $wp_filter_admin_notices as $filters ) {
|
226 |
+
foreach ( $filters as $callback_name => $callback ) {
|
227 |
|
228 |
+
if ( 'usof_hide_admin_notices_start' == $callback_name || 'usof_hide_admin_notices_end' == $callback_name ) {
|
229 |
continue;
|
230 |
}
|
231 |
|
233 |
|
234 |
// #CLRF-140 fix bug for php7
|
235 |
// when the developers forgot to delete the argument in the function of implementing the notification.
|
236 |
+
$args = [];
|
237 |
+
$accepted_args = isset( $callback['accepted_args'] ) && ! empty( $callback['accepted_args'] ) ? $callback['accepted_args'] : 0;
|
238 |
|
239 |
+
if ( $accepted_args > 0 ) {
|
240 |
+
for ( $i = 0; $i < (int) $accepted_args; $i ++ ) {
|
241 |
$args[] = null;
|
242 |
}
|
243 |
}
|
244 |
//===========
|
245 |
|
246 |
+
call_user_func_array( $callback['function'], $args );
|
247 |
$cont = ob_get_clean();
|
248 |
|
249 |
+
if ( empty( $cont ) ) {
|
250 |
continue;
|
251 |
}
|
252 |
|
253 |
+
$salt = is_multisite() ? get_current_blog_id() : '';
|
254 |
+
$uniq_id1 = md5( $cont . $salt );
|
255 |
+
$uniq_id2 = md5( $callback_name . $salt );
|
256 |
|
257 |
+
if ( is_array( $callback['function'] ) && sizeof( $callback['function'] ) == 2 ) {
|
258 |
$class = $callback['function'][0];
|
259 |
+
if ( is_object( $class ) ) {
|
260 |
+
$class_name = get_class( $class );
|
261 |
$method_name = $callback['function'][1];
|
262 |
+
$uniq_id2 = md5( $class_name . ':' . $method_name );
|
263 |
}
|
264 |
}
|
265 |
|
266 |
//838339d1a188e17fec838c2df3058603
|
267 |
//838339d1a188e17fec838c2df3058603
|
268 |
+
if ( ! empty( $get_hidden_notices ) ) {
|
269 |
|
270 |
$skip_notice = true;
|
271 |
+
foreach ( (array) $get_hidden_notices as $key => $notice ) {
|
272 |
+
$splited_notice_id = explode( '_', $key );
|
273 |
+
if ( empty( $splited_notice_id ) || sizeof( $splited_notice_id ) < 2 ) {
|
274 |
continue;
|
275 |
}
|
276 |
$compare_notice_id_1 = $splited_notice_id[0];
|
277 |
$compare_notice_id_2 = $splited_notice_id[1];
|
278 |
|
279 |
+
if ( $compare_notice_id_1 == $uniq_id1 || $compare_notice_id_2 == $uniq_id2 ) {
|
280 |
$skip_notice = false;
|
281 |
}
|
282 |
}
|
283 |
|
284 |
+
if ( ! $skip_notice ) {
|
285 |
continue;
|
286 |
}
|
287 |
}
|
288 |
|
289 |
+
$hide_link = '<a href="#" data-nonce="' . wp_create_nonce( $this->plugin->getPluginName() . '_ajax_hide_notices_nonce' ) . '" data-notice-id="' . $uniq_id1 . '_' . $uniq_id2 . '" class="wbcr-dan-hide-notice-link">[' . __( 'Hide notification forever', 'disable-admin-notices' ) . ']</a>';
|
290 |
|
291 |
// Fix for Woocommerce membership
|
292 |
+
if ( $cont != '<div class="js-wc-memberships-admin-notice-placeholder"></div>' ) {
|
293 |
+
$cont = preg_replace( '/<(script|style)([^>]+)?>(.*?)<\/(script|style)>/is', '', $cont );
|
294 |
+
$cont = rtrim( trim( $cont ) );
|
295 |
+
$cont = preg_replace( '/^(<div[^>]+>)(.*?)(<\/div>)$/is', '$1<div class="wbcr-dan-hide-notices">$2' . $hide_link . '</div>$3', $cont );
|
296 |
}
|
297 |
|
298 |
+
if ( empty( $cont ) ) {
|
299 |
continue;
|
300 |
}
|
301 |
$content[] = $cont;
|
305 |
$wbcr_dan_plugin_all_notices = $content;
|
306 |
}
|
307 |
|
308 |
+
|
309 |
try {
|
310 |
$wp_filter_user_admin_notices = &$this->getWPFilter('user_admin_notices');
|
311 |
} catch( Exception $e ) {
|
397 |
*
|
398 |
* @return String excerpt
|
399 |
*/
|
400 |
+
public function getExcerpt( $str, $startPos = 0, $maxLength = 100 ) {
|
401 |
+
if ( strlen( $str ) > $maxLength ) {
|
402 |
+
$excerpt = substr( $str, $startPos, $maxLength - 3 );
|
403 |
+
$lastSpace = strrpos( $excerpt, ' ' );
|
404 |
+
$excerpt = substr( $excerpt, 0, $lastSpace );
|
405 |
+
$excerpt .= '...';
|
|
|
406 |
} else {
|
407 |
$excerpt = $str;
|
408 |
}
|
421 |
* @return array $wp_filter callbacks array by link
|
422 |
* @throws Exception if key not exists
|
423 |
*/
|
424 |
+
private function &getWPFilter( $key ) {
|
|
|
425 |
global $wp_version, $wp_filter;
|
426 |
|
427 |
+
if ( ! isset( $wp_filter[ $key ] ) ) {
|
428 |
+
throw new Exception( 'key not exists' );
|
429 |
}
|
430 |
+
if ( version_compare( $wp_version, '4.7.0', '>=' ) ) {
|
431 |
+
return $wp_filter[ $key ]->callbacks;
|
432 |
} else {
|
433 |
+
return $wp_filter[ $key ];
|
434 |
}
|
435 |
}
|
436 |
}
|
includes/function.php
ADDED
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Helper functions
|
4 |
+
* @author Webcraftic <alex.kovalevv@gmail.com>
|
5 |
+
* @copyright (c) 05.07.2020, Webcraftic
|
6 |
+
* @version 1.0
|
7 |
+
*/
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Access to global variable $wp_filter in WP core.
|
11 |
+
* Migration from WP 4.2 to 4.9
|
12 |
+
*
|
13 |
+
* @see https://codex.wordpress.org/Version_4.7 WP 4.7 changelog (WP_Hook)
|
14 |
+
*
|
15 |
+
* @param $key string filter name
|
16 |
+
*
|
17 |
+
* @return array callbacks array by link
|
18 |
+
*/
|
19 |
+
function &wdan_get_wp_filter( $key ) {
|
20 |
+
global $wp_version, $wp_filter;
|
21 |
+
|
22 |
+
if ( version_compare( $wp_version, '4.7.0', '>=' ) ) {
|
23 |
+
return $wp_filter[ $key ]->callbacks;
|
24 |
+
} else {
|
25 |
+
return $wp_filter[ $key ];
|
26 |
+
}
|
27 |
+
}
|
28 |
+
|
29 |
+
function wdan_collect_notices( $key ) {
|
30 |
+
if ( 'admin_notices' === $key ) {
|
31 |
+
if ( is_multisite() && is_network_admin() ) {
|
32 |
+
$wp_filter = &wdan_get_wp_filter( 'network_admin_notices' );
|
33 |
+
} else {
|
34 |
+
$wp_filter = &wdan_get_wp_filter( 'admin_notices' );
|
35 |
+
}
|
36 |
+
} else {
|
37 |
+
$wp_filter = &wdan_get_wp_filter( $key );
|
38 |
+
}
|
39 |
+
|
40 |
+
$content = [];
|
41 |
+
foreach ( (array) $wp_filter as $filters ) {
|
42 |
+
foreach ( $filters as $callback_name => $callback ) {
|
43 |
+
|
44 |
+
if ( 'usof_hide_admin_notices_start' == $callback_name || 'usof_hide_admin_notices_end' == $callback_name ) {
|
45 |
+
continue;
|
46 |
+
}
|
47 |
+
|
48 |
+
ob_start();
|
49 |
+
|
50 |
+
// #CLRF-140 fix bug for php7
|
51 |
+
// when the developers forgot to delete the argument in the function of implementing the notification.
|
52 |
+
$args = [];
|
53 |
+
$accepted_args = isset( $callback['accepted_args'] ) && ! empty( $callback['accepted_args'] ) ? $callback['accepted_args'] : 0;
|
54 |
+
|
55 |
+
if ( $accepted_args > 0 ) {
|
56 |
+
for ( $i = 0; $i < (int) $accepted_args; $i ++ ) {
|
57 |
+
$args[] = null;
|
58 |
+
}
|
59 |
+
}
|
60 |
+
//===========
|
61 |
+
|
62 |
+
call_user_func_array( $callback['function'], $args );
|
63 |
+
$cont = ob_get_clean();
|
64 |
+
|
65 |
+
if ( ! empty( $cont ) ) {
|
66 |
+
$salt = is_multisite() ? get_current_blog_id() : '';
|
67 |
+
$uniq_id1 = md5( $cont . $salt );
|
68 |
+
$uniq_id2 = md5( $callback_name . $salt );
|
69 |
+
|
70 |
+
if ( is_array( $callback['function'] ) && sizeof( $callback['function'] ) == 2 ) {
|
71 |
+
$class = $callback['function'][0];
|
72 |
+
if ( is_object( $class ) ) {
|
73 |
+
$class_name = get_class( $class );
|
74 |
+
$method_name = $callback['function'][1];
|
75 |
+
$uniq_id2 = md5( $class_name . ':' . $method_name );
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
$content[ $uniq_id1 . "_" . $uniq_id2 ] = $cont;
|
80 |
+
}
|
81 |
+
}
|
82 |
+
}
|
83 |
+
|
84 |
+
return $content;
|
85 |
+
}
|
86 |
+
|
87 |
+
function wdan_clear_all_notices( $key, $excluded_classes = [], $excluded_callback_names = [] ) {
|
88 |
+
if ( 'admin_notices' === $key ) {
|
89 |
+
if ( is_multisite() && is_network_admin() ) {
|
90 |
+
$wp_filter = &wdan_get_wp_filter( 'network_admin_notices' );
|
91 |
+
} else {
|
92 |
+
$wp_filter = &wdan_get_wp_filter( 'admin_notices' );
|
93 |
+
}
|
94 |
+
} else {
|
95 |
+
$wp_filter = &wdan_get_wp_filter( $key );
|
96 |
+
}
|
97 |
+
|
98 |
+
foreach ( $wp_filter as $f_key => $f ) {
|
99 |
+
foreach ( $f as $c_name => $clback ) {
|
100 |
+
if ( is_array( $clback['function'] ) && sizeof( $clback['function'] ) == 2 ) {
|
101 |
+
$class = $clback['function'][0];
|
102 |
+
if ( is_object( $class ) ) {
|
103 |
+
$class_name = get_class( $class );
|
104 |
+
|
105 |
+
if ( in_array( $class_name, $excluded_classes ) ) {
|
106 |
+
continue;
|
107 |
+
}
|
108 |
+
}
|
109 |
+
}
|
110 |
+
|
111 |
+
if ( in_array( $c_name, $excluded_callback_names ) ) {
|
112 |
+
continue;
|
113 |
+
}
|
114 |
+
unset( $wp_filter[ $f_key ][ $c_name ] );
|
115 |
+
}
|
116 |
+
}
|
117 |
+
}
|
libs/factory/core/includes/class-factory-plugin-base.php
CHANGED
@@ -127,7 +127,7 @@ class Wbcr_Factory429_Base {
|
|
127 |
* к примеру: freemius, codecanyon, templatemonster, вам нужно указать только настройки для
|
128 |
* взаимодействия с выбранным вами провайдером. Каждая реализация провайдера лицензий может иметь
|
129 |
* индивидуальный настройки, в этом примере приведены настройки для freemius провайдера
|
130 |
-
* WBCR\Factory_429\Premium\Provider > WBCR\
|
131 |
*
|
132 |
* На текущий момент существует только реализация для freemius провайдера.
|
133 |
*
|
127 |
* к примеру: freemius, codecanyon, templatemonster, вам нужно указать только настройки для
|
128 |
* взаимодействия с выбранным вами провайдером. Каждая реализация провайдера лицензий может иметь
|
129 |
* индивидуальный настройки, в этом примере приведены настройки для freemius провайдера
|
130 |
+
* WBCR\Factory_429\Premium\Provider > WBCR\Factory_Freemius_117\Premium\Provider
|
131 |
*
|
132 |
* На текущий момент существует только реализация для freemius провайдера.
|
133 |
*
|
libs/factory/core/includes/premium/class-factory-manager.php
CHANGED
@@ -50,7 +50,7 @@ class Manager {
|
|
50 |
* @param Wbcr_Factory429_Plugin $plugin
|
51 |
* @param array $settings
|
52 |
*
|
53 |
-
* @return \WBCR\
|
54 |
* @throws Exception
|
55 |
*/
|
56 |
public static function instance( Wbcr_Factory429_Plugin $plugin, array $settings ) {
|
@@ -62,7 +62,7 @@ class Manager {
|
|
62 |
/**
|
63 |
* @param $provider_name
|
64 |
*
|
65 |
-
* @return \WBCR\
|
66 |
* @throws Exception
|
67 |
*/
|
68 |
public function instance_provider() {
|
50 |
* @param Wbcr_Factory429_Plugin $plugin
|
51 |
* @param array $settings
|
52 |
*
|
53 |
+
* @return \WBCR\Factory_Freemius_117\Premium\Provider
|
54 |
* @throws Exception
|
55 |
*/
|
56 |
public static function instance( Wbcr_Factory429_Plugin $plugin, array $settings ) {
|
62 |
/**
|
63 |
* @param $provider_name
|
64 |
*
|
65 |
+
* @return \WBCR\Factory_Freemius_117\Premium\Provider
|
66 |
* @throws Exception
|
67 |
*/
|
68 |
public function instance_provider() {
|
libs/factory/core/includes/updates/class-factory-upgrader.php
CHANGED
@@ -28,7 +28,7 @@ class Upgrader {
|
|
28 |
* @since 4.1.7
|
29 |
* @var array хранит имя репозитория и его имя класса
|
30 |
* [
|
31 |
-
* 'wordpress' => 'WBCR\
|
32 |
* 'freemius' => '\WBCR\Factory_429\Updates\Wordpress_Repository'
|
33 |
* ]
|
34 |
*/
|
28 |
* @since 4.1.7
|
29 |
* @var array хранит имя репозитория и его имя класса
|
30 |
* [
|
31 |
+
* 'wordpress' => 'WBCR\Factory_Freemius_117\Updates\Freemius_Repository',
|
32 |
* 'freemius' => '\WBCR\Factory_429\Updates\Wordpress_Repository'
|
33 |
* ]
|
34 |
*/
|
libs/factory/freemius/boot.php
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Load Freemius module.
|
4 |
+
*
|
5 |
+
* @author Webcraftic <wordpress.webraftic@gmail.com>, Alex Kovalev <alex.kovalevv@gmail.com>
|
6 |
+
* @since 1.0.0
|
7 |
+
* @package core
|
8 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
9 |
+
*
|
10 |
+
*/
|
11 |
+
|
12 |
+
// Exit if accessed directly
|
13 |
+
if( !defined('ABSPATH') ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
if( defined('FACTORY_FREEMIUS_117_LOADED') ) {
|
18 |
+
return;
|
19 |
+
}
|
20 |
+
|
21 |
+
define('FACTORY_FREEMIUS_117_VERSION', '1.1.7');
|
22 |
+
|
23 |
+
define('FACTORY_FREEMIUS_117_LOADED', true);
|
24 |
+
define('FACTORY_FREEMIUS_117_DIR', dirname(__FILE__));
|
25 |
+
define('FACTORY_FREEMIUS_117_URL', plugins_url(null, __FILE__));
|
26 |
+
|
27 |
+
#comp merge
|
28 |
+
// Freemius
|
29 |
+
require_once(FACTORY_FREEMIUS_117_DIR . '/includes/entities/class-freemius-entity.php');
|
30 |
+
require_once(FACTORY_FREEMIUS_117_DIR . '/includes/entities/class-freemius-scope.php');
|
31 |
+
require_once(FACTORY_FREEMIUS_117_DIR . '/includes/entities/class-freemius-user.php');
|
32 |
+
require_once(FACTORY_FREEMIUS_117_DIR . '/includes/entities/class-freemius-site.php');
|
33 |
+
require_once(FACTORY_FREEMIUS_117_DIR . '/includes/entities/class-freemius-license.php');
|
34 |
+
require_once(FACTORY_FREEMIUS_117_DIR . '/includes/licensing/class-freemius-provider.php');
|
35 |
+
require_once(FACTORY_FREEMIUS_117_DIR . '/includes/updates/class-freemius-repository.php');
|
36 |
+
|
37 |
+
if( !class_exists('Freemius_Api_WordPress') ) {
|
38 |
+
require_once FACTORY_FREEMIUS_117_DIR . '/includes/sdk/FreemiusWordPress.php';
|
39 |
+
}
|
40 |
+
|
41 |
+
require_once(FACTORY_FREEMIUS_117_DIR . '/includes/class-freemius-api.php');
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @param Wbcr_Factory429_Plugin $plugin
|
45 |
+
*/
|
46 |
+
add_action('wbcr_factory_freemius_117_plugin_created', function ($plugin) {
|
47 |
+
# Устанавливаем класс провайдера лицензий для премиум менеджера
|
48 |
+
$plugin->set_license_provider('freemius', 'WBCR\Factory_Freemius_117\Premium\Provider');
|
49 |
+
# Устанавливаем класс репозитория обновлений для менеджера обновлений
|
50 |
+
$plugin->set_update_repository('freemius', 'WBCR\Factory_Freemius_117\Updates\Freemius_Repository');
|
51 |
+
});
|
52 |
+
#endcomp
|
libs/factory/freemius/includes/class-freemius-api.php
ADDED
@@ -0,0 +1,416 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WBCR\Factory_Freemius_117;
|
4 |
+
|
5 |
+
use Freemius_Api_WordPress;
|
6 |
+
use Freemius_Exception;
|
7 |
+
use Wbcr_Factory429_Plugin;
|
8 |
+
|
9 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
10 |
+
exit;
|
11 |
+
}
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Class FS_Api
|
15 |
+
*
|
16 |
+
* Wraps Freemius API SDK to handle:
|
17 |
+
* 1. Clock sync.
|
18 |
+
* 2. Fallback to HTTP when HTTPS fails.
|
19 |
+
* 3. Adds caching layer to GET requests.
|
20 |
+
* 4. Adds consistency for failed requests by using last cached version.
|
21 |
+
*
|
22 |
+
* @author Webcraftic <wordpress.webraftic@gmail.com>, Alex Kovalev <alex.kovalevv@gmail.com>
|
23 |
+
* @copyright (c) 2018, Webcraftic Ltd
|
24 |
+
*
|
25 |
+
* @package core
|
26 |
+
* @since 1.0.0
|
27 |
+
*/
|
28 |
+
final class Api {
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @var Freemius_Api_WordPress
|
32 |
+
*/
|
33 |
+
private $api;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @var Wbcr_Factory429_Plugin
|
37 |
+
*/
|
38 |
+
private $plugin;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @var Api[]
|
42 |
+
*/
|
43 |
+
private static $instances = array();
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @var int Clock diff in seconds between current server to API server.
|
47 |
+
*/
|
48 |
+
private static $clock_diff;
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @param Wbcr_Factory429_Plugin $slug
|
52 |
+
* @param string $scope 'app', 'developer', 'user' or 'install'.
|
53 |
+
* @param number $id Element's id.
|
54 |
+
* @param string $public_key Public key.
|
55 |
+
* @param bool|string $secret_key Element's secret key.
|
56 |
+
* @param bool $is_sandbox
|
57 |
+
*/
|
58 |
+
private function __construct( Wbcr_Factory429_Plugin $plugin, $scope, $id, $public_key, $secret_key, $is_sandbox ) {
|
59 |
+
if ( ! class_exists( 'Freemius_Api_WordPress' ) ) {
|
60 |
+
require_once WP_FS__DIR_SDK . '/FreemiusWordPress.php';
|
61 |
+
}
|
62 |
+
|
63 |
+
$this->api = new Freemius_Api_WordPress( $scope, $id, $public_key, $secret_key, $is_sandbox );
|
64 |
+
|
65 |
+
$this->plugin = $plugin;
|
66 |
+
|
67 |
+
self::$clock_diff = $plugin->getPopulateOption( 'freemius_api_clock_diff', 0 );
|
68 |
+
Freemius_Api_WordPress::SetClockDiff( self::$clock_diff );
|
69 |
+
|
70 |
+
if ( $plugin->getPopulateOption( 'api_force_http', false ) ) {
|
71 |
+
Freemius_Api_WordPress::SetHttp();
|
72 |
+
}
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* @param Wbcr_Factory429_Plugin $plugin
|
77 |
+
* @param string $scope 'app', 'developer', 'user' or 'install'.
|
78 |
+
* @param number $id Element's id.
|
79 |
+
* @param string $public_key Public key.
|
80 |
+
* @param bool $is_sandbox
|
81 |
+
* @param bool|string $secret_key Element's secret key.
|
82 |
+
*
|
83 |
+
* @return Api
|
84 |
+
*/
|
85 |
+
public static function instance( Wbcr_Factory429_Plugin $plugin, $scope, $id, $public_key, $is_sandbox, $secret_key = false ) {
|
86 |
+
$identifier = md5( $plugin->getPluginName() . $scope . $id . $public_key . ( is_string( $secret_key ) ? $secret_key : '' ) . json_encode( $is_sandbox ) );
|
87 |
+
|
88 |
+
if ( ! isset( self::$instances[ $identifier ] ) ) {
|
89 |
+
self::$instances[ $identifier ] = new self( $plugin, $scope, $id, $public_key, $secret_key, $is_sandbox );
|
90 |
+
}
|
91 |
+
|
92 |
+
return self::$instances[ $identifier ];
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Check if valid ping request result.
|
97 |
+
*
|
98 |
+
* @author Vova Feldman (@svovaf)
|
99 |
+
* @since 1.1.1
|
100 |
+
*
|
101 |
+
* @param mixed $pong
|
102 |
+
*
|
103 |
+
* @return bool
|
104 |
+
*/
|
105 |
+
public function is_valid_ping( $pong ) {
|
106 |
+
return Freemius_Api_WordPress::Test( $pong );
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Override API call to wrap it in servers' clock sync method.
|
111 |
+
*
|
112 |
+
* @param string $path
|
113 |
+
* @param string $method
|
114 |
+
* @param array $params
|
115 |
+
*
|
116 |
+
* @return array|mixed|string
|
117 |
+
* @throws Freemius_Exception
|
118 |
+
*/
|
119 |
+
public function call( $path, $method = 'GET', $params = array() ) {
|
120 |
+
return $this->_call( $path, $method, $params );
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* @param string $path
|
125 |
+
*
|
126 |
+
* @return string
|
127 |
+
*/
|
128 |
+
public function get_url( $path = '' ) {
|
129 |
+
return Freemius_Api_WordPress::GetUrl( $path, $this->api->IsSandbox() );
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Get API request URL signed via query string.
|
134 |
+
*
|
135 |
+
* @param string $path
|
136 |
+
*
|
137 |
+
* @return string
|
138 |
+
* @throws Freemius_Exception
|
139 |
+
*/
|
140 |
+
public function get_signed_url( $path ) {
|
141 |
+
return $this->api->GetSignedUrl( $path );
|
142 |
+
}
|
143 |
+
|
144 |
+
#----------------------------------------------------------------------------------
|
145 |
+
#region Error Handling
|
146 |
+
#----------------------------------------------------------------------------------
|
147 |
+
|
148 |
+
/**
|
149 |
+
* @author Vova Feldman (@svovaf)
|
150 |
+
* @since 1.2.1.5
|
151 |
+
*
|
152 |
+
* @param mixed $result
|
153 |
+
*
|
154 |
+
* @return bool Is API result contains an error.
|
155 |
+
*/
|
156 |
+
public static function is_api_error( $result ) {
|
157 |
+
return ( is_object( $result ) && isset( $result->error ) ) || is_string( $result );
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* @author Vova Feldman (@svovaf)
|
162 |
+
* @since 2.0.0
|
163 |
+
*
|
164 |
+
* @param mixed $result
|
165 |
+
*
|
166 |
+
* @return bool Is API result contains an error.
|
167 |
+
*/
|
168 |
+
public static function is_api_error_object( $result ) {
|
169 |
+
return ( is_object( $result ) && isset( $result->error ) && isset( $result->error->message ) );
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Checks if given API result is a non-empty and not an error object.
|
174 |
+
*
|
175 |
+
* @author Vova Feldman (@svovaf)
|
176 |
+
* @since 1.2.1.5
|
177 |
+
*
|
178 |
+
* @param mixed $result
|
179 |
+
* @param string|null $required_property Optional property we want to verify that is set.
|
180 |
+
*
|
181 |
+
* @return bool
|
182 |
+
*/
|
183 |
+
public static function is_api_result_object( $result, $required_property = null ) {
|
184 |
+
return ( is_object( $result ) && ! isset( $result->error ) && ( empty( $required_property ) || isset( $result->{$required_property} ) ) );
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Checks if given API result is a non-empty entity object with non-empty ID.
|
189 |
+
*
|
190 |
+
* @author Vova Feldman (@svovaf)
|
191 |
+
* @since 1.2.1.5
|
192 |
+
*
|
193 |
+
* @param mixed $result
|
194 |
+
*
|
195 |
+
* @return bool
|
196 |
+
*/
|
197 |
+
/*static function is_api_result_entity( $result ) {
|
198 |
+
return self::is_api_result_object( $result, 'id' ) && FS_Entity::is_valid_id( $result->id );
|
199 |
+
}*/
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Get API result error code. If failed to get code, returns an empty string.
|
203 |
+
*
|
204 |
+
* @author Vova Feldman (@svovaf)
|
205 |
+
* @since 2.0.0
|
206 |
+
*
|
207 |
+
* @param mixed $result
|
208 |
+
*
|
209 |
+
* @return string
|
210 |
+
*/
|
211 |
+
public static function get_error_code( $result ) {
|
212 |
+
if ( is_object( $result ) && isset( $result->error ) && is_object( $result->error ) && ! empty( $result->error->code ) ) {
|
213 |
+
return $result->error->code;
|
214 |
+
}
|
215 |
+
|
216 |
+
return '';
|
217 |
+
}
|
218 |
+
#endregion
|
219 |
+
|
220 |
+
/**
|
221 |
+
* Find clock diff between server and API server, and store the diff locally.
|
222 |
+
*
|
223 |
+
* @param bool|int $diff
|
224 |
+
*
|
225 |
+
* @return bool|int False if clock diff didn't change, otherwise returns the clock diff in seconds.
|
226 |
+
*/
|
227 |
+
private function sync_clock_diff( $diff = false ) {
|
228 |
+
|
229 |
+
// Sync clock and store.
|
230 |
+
$new_clock_diff = ( false === $diff ) ? Freemius_Api_WordPress::FindClockDiff() : $diff;
|
231 |
+
|
232 |
+
if ( $new_clock_diff === self::$clock_diff ) {
|
233 |
+
return false;
|
234 |
+
}
|
235 |
+
|
236 |
+
self::$clock_diff = $new_clock_diff;
|
237 |
+
|
238 |
+
// Update API clock's diff.
|
239 |
+
Freemius_Api_WordPress::SetClockDiff( self::$clock_diff );
|
240 |
+
|
241 |
+
// Store new clock diff in storage.
|
242 |
+
$this->plugin->updatePopulateOption( 'freemius_api_clock_diff', self::$clock_diff );
|
243 |
+
|
244 |
+
return $new_clock_diff;
|
245 |
+
}
|
246 |
+
|
247 |
+
/**
|
248 |
+
* Override API call to enable retry with servers' clock auto sync method.
|
249 |
+
*
|
250 |
+
* @param string $path
|
251 |
+
* @param string $method
|
252 |
+
* @param array $params
|
253 |
+
* @param bool $retry Is in retry or first call attempt.
|
254 |
+
*
|
255 |
+
* @return array|mixed|string
|
256 |
+
*/
|
257 |
+
private function _call( $path, $method = 'GET', $params = array(), $retry = false ) {
|
258 |
+
|
259 |
+
$result = $this->api->Api( $path, $method, $params );
|
260 |
+
|
261 |
+
if ( null !== $result && isset( $result->error ) && isset( $result->error->code ) && 'request_expired' === $result->error->code ) {
|
262 |
+
if ( ! $retry ) {
|
263 |
+
$diff = isset( $result->error->timestamp ) ? ( time() - strtotime( $result->error->timestamp ) ) : false;
|
264 |
+
|
265 |
+
// Try to sync clock diff.
|
266 |
+
if ( false !== $this->sync_clock_diff( $diff ) ) {
|
267 |
+
// Retry call with new synced clock.
|
268 |
+
return $this->_call( $path, $method, $params, true );
|
269 |
+
}
|
270 |
+
}
|
271 |
+
}
|
272 |
+
|
273 |
+
return $result;
|
274 |
+
}
|
275 |
+
|
276 |
+
/**
|
277 |
+
* Test API connectivity.
|
278 |
+
*
|
279 |
+
* @author Vova Feldman (@svovaf)
|
280 |
+
* @since 1.0.9 If fails, try to fallback to HTTP.
|
281 |
+
* @since 1.1.6 Added a 5-min caching mechanism, to prevent from overloading the server if the API if
|
282 |
+
* temporary down.
|
283 |
+
*
|
284 |
+
* @return bool True if successful connectivity to the API.
|
285 |
+
*/
|
286 |
+
/*public static function test( $plugin ) {
|
287 |
+
self::init( $plugin );
|
288 |
+
|
289 |
+
$cache_key = 'ping_test';
|
290 |
+
|
291 |
+
$test = self::$_cache->get_valid( $cache_key, null );
|
292 |
+
|
293 |
+
if ( is_null( $test ) ) {
|
294 |
+
$test = Freemius_Api_WordPress::Test();
|
295 |
+
|
296 |
+
if ( false === $test && Freemius_Api_WordPress::IsHttps() ) {
|
297 |
+
// Fallback to HTTP, since HTTPS fails.
|
298 |
+
Freemius_Api_WordPress::SetHttp();
|
299 |
+
|
300 |
+
self::$_options->set_option( 'api_force_http', true, true );
|
301 |
+
|
302 |
+
$test = Freemius_Api_WordPress::Test();
|
303 |
+
|
304 |
+
if ( false === $test ) {
|
305 |
+
/**
|
306 |
+
* API connectivity test fail also in HTTP request, therefore,
|
307 |
+
* fallback to HTTPS to keep connection secure.
|
308 |
+
*
|
309 |
+
* @since 1.1.6
|
310 |
+
*/
|
311 |
+
/* self::$_options->set_option( 'api_force_http', false, true );
|
312 |
+
}
|
313 |
+
}
|
314 |
+
|
315 |
+
self::$_cache->set( $cache_key, $test, WP_FS__TIME_5_MIN_IN_SEC );
|
316 |
+
}
|
317 |
+
|
318 |
+
return $test;
|
319 |
+
}*/
|
320 |
+
|
321 |
+
/**
|
322 |
+
* Check if API is temporary down.
|
323 |
+
*
|
324 |
+
* @author Vova Feldman (@svovaf)
|
325 |
+
* @since 1.1.6
|
326 |
+
*
|
327 |
+
* @return bool
|
328 |
+
*/
|
329 |
+
/*public static function is_temporary_down() {
|
330 |
+
self::init();
|
331 |
+
|
332 |
+
$test = self::$_cache->get_valid( 'ping_test', null );
|
333 |
+
|
334 |
+
return ( false === $test );
|
335 |
+
}*/
|
336 |
+
|
337 |
+
/**
|
338 |
+
* @author Vova Feldman (@svovaf)
|
339 |
+
* @since 1.1.6
|
340 |
+
*
|
341 |
+
* @return object
|
342 |
+
*/
|
343 |
+
/*private function get_temporary_unavailable_error() {
|
344 |
+
return (object) array(
|
345 |
+
'error' => (object) array(
|
346 |
+
'type' => 'TemporaryUnavailable',
|
347 |
+
'message' => 'API is temporary unavailable, please retry in ' . ( self::$_cache->get_record_expiration( 'ping_test' ) - WP_FS__SCRIPT_START_TIME ) . ' sec.',
|
348 |
+
'code' => 'temporary_unavailable',
|
349 |
+
'http' => 503
|
350 |
+
)
|
351 |
+
);
|
352 |
+
}*/
|
353 |
+
|
354 |
+
/**
|
355 |
+
* Ping API for connectivity test, and return result object.
|
356 |
+
*
|
357 |
+
* @author Vova Feldman (@svovaf)
|
358 |
+
* @since 1.0.9
|
359 |
+
*
|
360 |
+
* @param null|string $unique_anonymous_id
|
361 |
+
* @param array $params
|
362 |
+
*
|
363 |
+
* @return object
|
364 |
+
*/
|
365 |
+
/*public function ping( $unique_anonymous_id = null, $params = array() ) {
|
366 |
+
if ( self::is_temporary_down() ) {
|
367 |
+
return $this->get_temporary_unavailable_error();
|
368 |
+
}
|
369 |
+
|
370 |
+
$pong = is_null( $unique_anonymous_id ) ? Freemius_Api_WordPress::Ping() : $this->_call( 'ping.json?' . http_build_query( array_merge( array( 'uid' => $unique_anonymous_id ), $params ) ) );
|
371 |
+
|
372 |
+
if ( $this->is_valid_ping( $pong ) ) {
|
373 |
+
return $pong;
|
374 |
+
}
|
375 |
+
|
376 |
+
if ( self::should_try_with_http( $pong ) ) {
|
377 |
+
// Fallback to HTTP, since HTTPS fails.
|
378 |
+
Freemius_Api_WordPress::SetHttp();
|
379 |
+
|
380 |
+
$this->plugin->updatePopulateOption( 'api_force_http', true );
|
381 |
+
|
382 |
+
$pong = is_null( $unique_anonymous_id ) ? Freemius_Api_WordPress::Ping() : $this->_call( 'ping.json?' . http_build_query( array_merge( array( 'uid' => $unique_anonymous_id ), $params ) ) );
|
383 |
+
|
384 |
+
if ( ! $this->is_valid_ping( $pong ) ) {
|
385 |
+
$this->plugin->updatePopulateOption( 'api_force_http', false );
|
386 |
+
}
|
387 |
+
}
|
388 |
+
|
389 |
+
return $pong;
|
390 |
+
}*/
|
391 |
+
|
392 |
+
/**
|
393 |
+
* Check if based on the API result we should try
|
394 |
+
* to re-run the same request with HTTP instead of HTTPS.
|
395 |
+
*
|
396 |
+
* @author Vova Feldman (@svovaf)
|
397 |
+
* @since 1.1.6
|
398 |
+
*
|
399 |
+
* @param $result
|
400 |
+
*
|
401 |
+
* @return bool
|
402 |
+
*/
|
403 |
+
/*private static function should_try_with_http( $result ) {
|
404 |
+
if ( ! Freemius_Api_WordPress::IsHttps() ) {
|
405 |
+
return false;
|
406 |
+
}
|
407 |
+
|
408 |
+
return ( ! is_object( $result ) || ! isset( $result->error ) || ! isset( $result->error->code ) || ! in_array( $result->error->code, array(
|
409 |
+
'curl_missing',
|
410 |
+
'cloudflare_ddos_protection',
|
411 |
+
'maintenance_mode',
|
412 |
+
'squid_cache_block',
|
413 |
+
'too_many_requests',
|
414 |
+
) ) );
|
415 |
+
}*/
|
416 |
+
}
|
libs/factory/freemius/includes/entities/class-freemius-entity.php
ADDED
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WBCR\Factory_Freemius_117\Entities;
|
4 |
+
|
5 |
+
use stdClass;
|
6 |
+
|
7 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
8 |
+
exit;
|
9 |
+
}
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @author Webcraftic <wordpress.webraftic@gmail.com>, Alex Kovalev <alex.kovalevv@gmail.com>
|
13 |
+
* @link https://webcraftic.com
|
14 |
+
* @copyright (c) 2018 Webraftic Ltd, Freemius, Inc.
|
15 |
+
* @version 1.0
|
16 |
+
*/
|
17 |
+
class Entity {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var number
|
21 |
+
*/
|
22 |
+
public $id;
|
23 |
+
/**
|
24 |
+
* @var string Datetime value in 'YYYY-MM-DD HH:MM:SS' format.
|
25 |
+
*/
|
26 |
+
public $updated;
|
27 |
+
/**
|
28 |
+
* @var string Datetime value in 'YYYY-MM-DD HH:MM:SS' format.
|
29 |
+
*/
|
30 |
+
public $created;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @var bool
|
34 |
+
*/
|
35 |
+
private $is_updated = false;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @param bool|object|array $entity
|
39 |
+
*/
|
40 |
+
public function __construct( $entity = false ) {
|
41 |
+
if ( ! ( $entity instanceof stdClass ) && ! is_array( $entity ) ) {
|
42 |
+
return;
|
43 |
+
}
|
44 |
+
|
45 |
+
$props = get_object_vars( $this );
|
46 |
+
|
47 |
+
foreach ( $props as $key => $def_value ) {
|
48 |
+
if ( is_object( $entity ) ) {
|
49 |
+
$this->{$key} = isset( $entity->{$key} ) ? $entity->{$key} : $def_value;
|
50 |
+
} else {
|
51 |
+
$this->{$key} = isset( $entity[ $key ] ) ? $entity[ $key ] : $def_value;
|
52 |
+
}
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
|
58 |
+
* @since 1.1
|
59 |
+
*
|
60 |
+
* @param object|array $data
|
61 |
+
*
|
62 |
+
* @return bool
|
63 |
+
*/
|
64 |
+
public function populate( $data ) {
|
65 |
+
if ( ! is_object( $data ) && ! is_array( $data ) ) {
|
66 |
+
return false;
|
67 |
+
}
|
68 |
+
|
69 |
+
$props = get_object_vars( $this );
|
70 |
+
|
71 |
+
foreach ( $props as $key => $def_value ) {
|
72 |
+
if ( is_array( $data ) ) {
|
73 |
+
$this->{$key} = isset( $data[ $key ] ) ? $data[ $key ] : $def_value;
|
74 |
+
} else {
|
75 |
+
$this->{$key} = isset( $data->{$key} ) ? $data->{$key} : $def_value;
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
return true;
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* @author Alexander Kovalev <alex.kovalevv@gmail.com>
|
84 |
+
* @since 1.0.0
|
85 |
+
* @return array
|
86 |
+
*/
|
87 |
+
public function to_array() {
|
88 |
+
return get_object_vars( $this );
|
89 |
+
}
|
90 |
+
|
91 |
+
static function get_type() {
|
92 |
+
return 'type';
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* @author Vova Feldman (@svovaf)
|
97 |
+
* @since 1.0.6
|
98 |
+
*
|
99 |
+
* @param Entity $entity1
|
100 |
+
* @param Entity $entity2
|
101 |
+
*
|
102 |
+
* @return bool
|
103 |
+
*/
|
104 |
+
static function equals( $entity1, $entity2 ) {
|
105 |
+
if ( is_null( $entity1 ) && is_null( $entity2 ) ) {
|
106 |
+
return true;
|
107 |
+
} else if ( is_object( $entity1 ) && is_object( $entity2 ) ) {
|
108 |
+
return ( $entity1->id == $entity2->id );
|
109 |
+
} else if ( is_object( $entity1 ) ) {
|
110 |
+
return is_null( $entity1->id );
|
111 |
+
} else {
|
112 |
+
return is_null( $entity2->id );
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Update object property.
|
119 |
+
*
|
120 |
+
* @author Vova Feldman (@svovaf)
|
121 |
+
* @since 1.0.9
|
122 |
+
*
|
123 |
+
* @param string|array[string]mixed $key
|
124 |
+
* @param string|bool $val
|
125 |
+
*
|
126 |
+
* @return bool
|
127 |
+
*/
|
128 |
+
function update( $key, $val = false ) {
|
129 |
+
if ( ! is_array( $key ) ) {
|
130 |
+
$key = [ $key => $val ];
|
131 |
+
}
|
132 |
+
|
133 |
+
$is_updated = false;
|
134 |
+
|
135 |
+
foreach ( $key as $k => $v ) {
|
136 |
+
if ( $this->{$k} === $v ) {
|
137 |
+
continue;
|
138 |
+
}
|
139 |
+
|
140 |
+
if ( ( is_string( $this->{$k} ) && is_numeric( $v ) || ( is_numeric( $this->{$k} ) && is_string( $v ) ) ) && $this->{$k} == $v ) {
|
141 |
+
continue;
|
142 |
+
}
|
143 |
+
|
144 |
+
// Update value.
|
145 |
+
$this->{$k} = $v;
|
146 |
+
|
147 |
+
$is_updated = true;
|
148 |
+
}
|
149 |
+
|
150 |
+
$this->is_updated = $is_updated;
|
151 |
+
|
152 |
+
return $is_updated;
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Checks if entity was updated.
|
157 |
+
*
|
158 |
+
* @author Vova Feldman (@svovaf)
|
159 |
+
* @since 1.0.9
|
160 |
+
*
|
161 |
+
* @return bool
|
162 |
+
*/
|
163 |
+
function is_updated() {
|
164 |
+
return $this->is_updated;
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* @author Vova Feldman (@svovaf)
|
169 |
+
* @since 1.1.2
|
170 |
+
*
|
171 |
+
* @param $id
|
172 |
+
*
|
173 |
+
* @return bool
|
174 |
+
*/
|
175 |
+
static function is_valid_id( $id ) {
|
176 |
+
return is_numeric( $id );
|
177 |
+
}
|
178 |
+
}
|
libs/factory/freemius/includes/entities/class-freemius-license.php
ADDED
@@ -0,0 +1,376 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WBCR\Factory_Freemius_117\Entities;
|
4 |
+
|
5 |
+
use stdClass;
|
6 |
+
|
7 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
8 |
+
exit;
|
9 |
+
}
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @author Webcraftic <wordpress.webraftic@gmail.com>, Alex Kovalev <alex.kovalevv@gmail.com>
|
13 |
+
* @link https://webcraftic.com
|
14 |
+
* @copyright (c) 2018 Webraftic Ltd, Freemius, Inc.
|
15 |
+
* @version 1.0
|
16 |
+
*/
|
17 |
+
class License extends Entity implements \WBCR\Factory_429\Premium\Interfaces\License {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var number
|
21 |
+
*/
|
22 |
+
public $plugin_id;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @var number
|
26 |
+
*/
|
27 |
+
public $user_id;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @var number
|
31 |
+
*/
|
32 |
+
public $plan_id;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @var
|
36 |
+
*/
|
37 |
+
public $plan_title;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @var
|
41 |
+
*/
|
42 |
+
public $billing_cycle;
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @var number
|
46 |
+
*/
|
47 |
+
public $pricing_id;
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @var int|null
|
51 |
+
*/
|
52 |
+
public $quota;
|
53 |
+
|
54 |
+
/**
|
55 |
+
* @var int
|
56 |
+
*/
|
57 |
+
public $activated;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @var int
|
61 |
+
*/
|
62 |
+
public $activated_local;
|
63 |
+
|
64 |
+
/**
|
65 |
+
* @var string
|
66 |
+
*/
|
67 |
+
public $expiration;
|
68 |
+
|
69 |
+
/**
|
70 |
+
* @var string
|
71 |
+
*/
|
72 |
+
public $secret_key;
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @var bool $is_free_localhost Defaults to true. If true, allow unlimited localhost installs with the same
|
76 |
+
* license.
|
77 |
+
*/
|
78 |
+
public $is_free_localhost;
|
79 |
+
|
80 |
+
/**
|
81 |
+
* @var bool $is_block_features Defaults to true. If false, don't block features after license expiry - only
|
82 |
+
* block updates and support.
|
83 |
+
*/
|
84 |
+
public $is_block_features;
|
85 |
+
|
86 |
+
/**
|
87 |
+
* @var bool
|
88 |
+
*/
|
89 |
+
public $is_cancelled;
|
90 |
+
|
91 |
+
/**
|
92 |
+
* @param stdClass|bool $license
|
93 |
+
*/
|
94 |
+
public function __construct( $license = false ) {
|
95 |
+
parent::__construct( $license );
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Get entity type.
|
100 |
+
*
|
101 |
+
* @return string
|
102 |
+
*/
|
103 |
+
public static function get_type() {
|
104 |
+
return 'license';
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Example: #sk_f=>}-5vuHp$3*wPQHxd(AD3<);1&i
|
109 |
+
*
|
110 |
+
* @return string|null
|
111 |
+
*/
|
112 |
+
public function get_key() {
|
113 |
+
return $this->secret_key;
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Example: #sk_f=>}-5vuHp$3******d(AD3<);1&i
|
118 |
+
*
|
119 |
+
* @return mixed
|
120 |
+
*/
|
121 |
+
public function get_hidden_key() {
|
122 |
+
return substr_replace( $this->get_key(), '******', 15, 6 );
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* @return string|null
|
127 |
+
*/
|
128 |
+
public function get_plan() {
|
129 |
+
return $this->plan_title;
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* @return integer|null
|
134 |
+
*/
|
135 |
+
public function get_plan_id() {
|
136 |
+
return $this->plan_id;
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* @return mixed
|
141 |
+
*/
|
142 |
+
public function get_billing_cycle() {
|
143 |
+
return $this->billing_cycle;
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* @return int
|
148 |
+
*/
|
149 |
+
public function get_sites_quota() {
|
150 |
+
return $this->quota;
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* @return int
|
155 |
+
*/
|
156 |
+
public function get_count_active_sites() {
|
157 |
+
return $this->activated;
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Check how many site activations left.
|
162 |
+
*
|
163 |
+
* @return int
|
164 |
+
* @since 1.0.5
|
165 |
+
*
|
166 |
+
* @author Vova Feldman (@svovaf)
|
167 |
+
*/
|
168 |
+
public function get_site_activations_left() {
|
169 |
+
if ( ! $this->is_active() || $this->is_expired() ) {
|
170 |
+
return 0;
|
171 |
+
}
|
172 |
+
|
173 |
+
if ( $this->is_unlimited() ) {
|
174 |
+
return 999;
|
175 |
+
}
|
176 |
+
|
177 |
+
return ( $this->quota - $this->activated - ( $this->is_free_localhost ? 0 : $this->activated_local ) );
|
178 |
+
}
|
179 |
+
|
180 |
+
/**
|
181 |
+
* @param string $format Return time in formats (time|days|date)
|
182 |
+
*
|
183 |
+
* @return float|int|string
|
184 |
+
*/
|
185 |
+
public function get_expiration_time( $format = 'time' ) {
|
186 |
+
if ( $format == 'days' ) {
|
187 |
+
if ( $this->is_lifetime() ) {
|
188 |
+
return 999;
|
189 |
+
}
|
190 |
+
|
191 |
+
$remaining = strtotime( $this->expiration ) - date( 'U' );
|
192 |
+
$days_remaining = floor( $remaining / 86400 );
|
193 |
+
|
194 |
+
return $days_remaining;
|
195 |
+
} else if ( $format == 'date' ) {
|
196 |
+
return date( 'Y-m-d', strtotime( $this->expiration ) );
|
197 |
+
}
|
198 |
+
|
199 |
+
return $this->expiration;
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* @param $actual_license_data
|
204 |
+
*/
|
205 |
+
/*public function sync( $actual_license_data ) {
|
206 |
+
$props = get_object_vars( $this );
|
207 |
+
|
208 |
+
foreach ( $props as $key => $def_value ) {
|
209 |
+
$this->{$key} = isset( $actual_license_data->{$key} ) ? $actual_license_data->{$key} : $def_value;
|
210 |
+
}
|
211 |
+
if ( isset( $actual_license_data->expiration ) and is_null( $actual_license_data->expiration ) ) {
|
212 |
+
$this->expiration = null;
|
213 |
+
}
|
214 |
+
}*/
|
215 |
+
|
216 |
+
/**
|
217 |
+
* Check if single site license.
|
218 |
+
*
|
219 |
+
* @return bool
|
220 |
+
* @since 1.1.8.1
|
221 |
+
*
|
222 |
+
* @author Vova Feldman (@svovaf)
|
223 |
+
*/
|
224 |
+
public function is_single_site() {
|
225 |
+
return ( is_numeric( $this->quota ) && 1 == $this->quota );
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* @return bool
|
230 |
+
* @since 1.0.5
|
231 |
+
*
|
232 |
+
* @author Vova Feldman (@svovaf)
|
233 |
+
*/
|
234 |
+
public function is_expired() {
|
235 |
+
return ! $this->is_lifetime() && ( strtotime( $this->expiration ) < date( 'U' ) );
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* Check if license is not expired.
|
240 |
+
*
|
241 |
+
* @return bool
|
242 |
+
* @since 1.2.1
|
243 |
+
*
|
244 |
+
* @author Vova Feldman (@svovaf)
|
245 |
+
*/
|
246 |
+
public function is_valid() {
|
247 |
+
return ! $this->is_expired();
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* @return bool
|
252 |
+
* @since 1.0.6
|
253 |
+
*
|
254 |
+
* @author Vova Feldman (@svovaf)
|
255 |
+
*/
|
256 |
+
public function is_lifetime() {
|
257 |
+
return is_null( $this->expiration );
|
258 |
+
}
|
259 |
+
|
260 |
+
/**
|
261 |
+
* @return bool
|
262 |
+
* @since 1.2.0
|
263 |
+
*
|
264 |
+
* @author Vova Feldman (@svovaf)
|
265 |
+
*/
|
266 |
+
public function is_unlimited() {
|
267 |
+
return is_null( $this->quota );
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* Check if license is fully utilized.
|
272 |
+
*
|
273 |
+
* @param bool|null $is_localhost
|
274 |
+
*
|
275 |
+
* @return bool
|
276 |
+
* @author Vova Feldman (@svovaf)
|
277 |
+
* @since 1.0.6
|
278 |
+
*
|
279 |
+
*/
|
280 |
+
public function is_utilized( $is_localhost = null ) {
|
281 |
+
if ( is_null( $is_localhost ) ) {
|
282 |
+
$is_localhost = false; // была WP_FS__IS_LOCALHOST_FOR_SERVER
|
283 |
+
}
|
284 |
+
|
285 |
+
if ( $this->is_unlimited() ) {
|
286 |
+
return false;
|
287 |
+
}
|
288 |
+
|
289 |
+
return ! ( $this->is_free_localhost && $is_localhost ) && ( $this->quota <= $this->activated + ( $this->is_free_localhost ? 0 : $this->activated_local ) );
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* Check if license can be activated.
|
294 |
+
*
|
295 |
+
* @param bool|null $is_localhost
|
296 |
+
*
|
297 |
+
* @return bool
|
298 |
+
* @author Vova Feldman (@svovaf)
|
299 |
+
* @since 2.0.0
|
300 |
+
*
|
301 |
+
*/
|
302 |
+
public function can_activate( $is_localhost = null ) {
|
303 |
+
return ! $this->is_utilized( $is_localhost ) && $this->is_features_enabled();
|
304 |
+
}
|
305 |
+
|
306 |
+
/**
|
307 |
+
* Check if license can be activated on a given number of production and localhost sites.
|
308 |
+
*
|
309 |
+
* @param int $production_count
|
310 |
+
* @param int $localhost_count
|
311 |
+
*
|
312 |
+
* @return bool
|
313 |
+
* @since 2.0.0
|
314 |
+
*
|
315 |
+
* @author Vova Feldman (@svovaf)
|
316 |
+
*/
|
317 |
+
//public function can_activate_bulk( $production_count, $localhost_count ) {
|
318 |
+
//if ( $this->is_unlimited() ) {
|
319 |
+
//return true;
|
320 |
+
//}
|
321 |
+
|
322 |
+
/**
|
323 |
+
* For simplicity, the logic will work as following: when given X sites to activate the license on, if it's
|
324 |
+
* possible to activate on ALL of them, do the activation. If it's not possible to activate on ALL of them,
|
325 |
+
* do NOT activate on any of them.
|
326 |
+
*/
|
327 |
+
//return ( $this->quota >= $this->activated + $production_count + ( $this->is_free_localhost ? 0 : $this->activated_local + $localhost_count ) );
|
328 |
+
//}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* @return bool
|
332 |
+
* @since 1.2.1
|
333 |
+
*
|
334 |
+
* @author Vova Feldman (@svovaf)
|
335 |
+
*/
|
336 |
+
public function is_active() {
|
337 |
+
return ( ! $this->is_cancelled );
|
338 |
+
}
|
339 |
+
|
340 |
+
/**
|
341 |
+
* Check if license's plan features are enabled.
|
342 |
+
*
|
343 |
+
* - Either if plan not expired
|
344 |
+
* - If expired, based on the configuration to block features or not.
|
345 |
+
*
|
346 |
+
* @return bool
|
347 |
+
* @since 1.0.6
|
348 |
+
*
|
349 |
+
* @author Vova Feldman (@svovaf)
|
350 |
+
*/
|
351 |
+
public function is_features_enabled() {
|
352 |
+
return $this->is_active() && ( ! $this->is_block_features || ! $this->is_expired() );
|
353 |
+
}
|
354 |
+
|
355 |
+
/**
|
356 |
+
* Subscription considered to be new without any payments
|
357 |
+
* if the license expires in less than 24 hours
|
358 |
+
* from the license creation.
|
359 |
+
*
|
360 |
+
* @return bool
|
361 |
+
* @since 1.0.9
|
362 |
+
*
|
363 |
+
* @author Vova Feldman (@svovaf)
|
364 |
+
*/
|
365 |
+
public function is_first_payment_pending() {
|
366 |
+
return ( 86400 >= strtotime( $this->expiration ) - strtotime( $this->created ) );
|
367 |
+
}
|
368 |
+
|
369 |
+
/**
|
370 |
+
* @return int
|
371 |
+
*/
|
372 |
+
public function total_activations() {
|
373 |
+
return ( $this->activated + $this->activated_local );
|
374 |
+
}
|
375 |
+
|
376 |
+
}
|
libs/factory/freemius/includes/entities/class-freemius-plugin.php
ADDED
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WBCR\Factory_Freemius_117\Entities;
|
4 |
+
|
5 |
+
use stdClass;
|
6 |
+
|
7 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
8 |
+
exit;
|
9 |
+
}
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @author Webcraftic <wordpress.webraftic@gmail.com>, Alex Kovalev <alex.kovalevv@gmail.com>
|
13 |
+
* @link https://webcraftic.com
|
14 |
+
* @copyright (c) 2018 Webraftic Ltd, Freemius, Inc.
|
15 |
+
* @version 1.0
|
16 |
+
*/
|
17 |
+
class Plugin extends Scope {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @since 1.0.6
|
21 |
+
* @var null|number
|
22 |
+
*/
|
23 |
+
public $parent_plugin_id;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @var string
|
27 |
+
*/
|
28 |
+
public $title;
|
29 |
+
/**
|
30 |
+
* @var string
|
31 |
+
*/
|
32 |
+
public $slug;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @var string
|
36 |
+
*/
|
37 |
+
public $premium_slug;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @var string 'plugin' or 'theme'
|
41 |
+
*/
|
42 |
+
public $type;
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @var string|false false if the module doesn't have an affiliate program or one of the following: 'selected',
|
46 |
+
* 'customers', or 'all'.
|
47 |
+
*/
|
48 |
+
public $affiliate_moderation;
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @var bool Set to true if the free version of the module is hosted on WordPress.org. Defaults to true.
|
52 |
+
*/
|
53 |
+
public $is_wp_org_compliant = true;
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @var string
|
57 |
+
*/
|
58 |
+
public $file;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @var string
|
62 |
+
*/
|
63 |
+
public $version;
|
64 |
+
|
65 |
+
/**
|
66 |
+
* @var bool
|
67 |
+
*/
|
68 |
+
public $auto_update;
|
69 |
+
|
70 |
+
/**
|
71 |
+
* @var bool
|
72 |
+
*/
|
73 |
+
public $is_premium;
|
74 |
+
|
75 |
+
/**
|
76 |
+
* @var string
|
77 |
+
*/
|
78 |
+
public $premium_suffix;
|
79 |
+
|
80 |
+
/**
|
81 |
+
* @var bool
|
82 |
+
*/
|
83 |
+
public $is_live;
|
84 |
+
|
85 |
+
const AFFILIATE_MODERATION_CUSTOMERS = 'customers';
|
86 |
+
|
87 |
+
#endregion Install Specific Properties
|
88 |
+
|
89 |
+
/**
|
90 |
+
* @param stdClass|bool $plugin
|
91 |
+
*/
|
92 |
+
function __construct( $plugin = false ) {
|
93 |
+
parent::__construct( $plugin );
|
94 |
+
|
95 |
+
$this->is_premium = false;
|
96 |
+
$this->is_live = true;
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Check if plugin is an add-on (has parent).
|
101 |
+
*
|
102 |
+
* @author Vova Feldman (@svovaf)
|
103 |
+
* @since 1.0.6
|
104 |
+
*
|
105 |
+
* @return bool
|
106 |
+
*/
|
107 |
+
function is_addon() {
|
108 |
+
return isset( $this->parent_plugin_id ) && is_numeric( $this->parent_plugin_id );
|
109 |
+
}
|
110 |
+
|
111 |
+
static function get_type() {
|
112 |
+
return 'plugin';
|
113 |
+
}
|
114 |
+
}
|
libs/factory/freemius/includes/entities/class-freemius-scope.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WBCR\Factory_Freemius_117\Entities;
|
4 |
+
|
5 |
+
use stdClass;
|
6 |
+
|
7 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
8 |
+
exit;
|
9 |
+
}
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @author Webcraftic <wordpress.webraftic@gmail.com>, Alex Kovalev <alex.kovalevv@gmail.com>
|
13 |
+
* @link https://webcraftic.com
|
14 |
+
* @copyright (c) 2018 Webraftic Ltd, Freemius, Inc.
|
15 |
+
* @version 1.0
|
16 |
+
*/
|
17 |
+
class Scope extends Entity {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
public $public_key;
|
23 |
+
/**
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
public $secret_key;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @param bool|stdClass $scope_entity
|
30 |
+
*/
|
31 |
+
function __construct( $scope_entity = false ) {
|
32 |
+
parent::__construct( $scope_entity );
|
33 |
+
}
|
34 |
+
}
|
libs/factory/freemius/includes/entities/class-freemius-site.php
ADDED
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WBCR\Factory_Freemius_117\Entities;
|
4 |
+
|
5 |
+
use stdClass;
|
6 |
+
|
7 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
8 |
+
exit;
|
9 |
+
}
|
10 |
+
|
11 |
+
/**
|
12 |
+
* @author Webcraftic <wordpress.webraftic@gmail.com>, Alex Kovalev <alex.kovalevv@gmail.com>
|
13 |
+
* @link https://webcraftic.com
|
14 |
+
* @copyright (c) 2018 Webraftic Ltd, Freemius, Inc.
|
15 |
+
* @version 1.0
|
16 |
+
*/
|
17 |
+
class Site extends Scope {
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @var number
|
21 |
+
*/
|
22 |
+
public $site_id;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @var number
|
26 |
+
*/
|
27 |
+
public $plugin_id;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @var number
|
31 |
+
*/
|
32 |
+
public $user_id;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* @var string
|
36 |
+
*/
|
37 |
+
public $title;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @var string
|
41 |
+
*/
|
42 |
+
public $url;
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @var string
|
46 |
+
*/
|
47 |
+
public $version;
|
48 |
+
|
49 |
+
/**
|
50 |
+
* @var string E.g. en-GB
|
51 |
+
*/
|
52 |
+
public $language;
|
53 |
+
|
54 |
+
/**
|
55 |
+
* @var string E.g. UTF-8
|
56 |
+
*/
|
57 |
+
public $charset;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @var string Platform version (e.g WordPress version).
|
61 |
+
*/
|
62 |
+
public $platform_version;
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Freemius SDK version
|
66 |
+
*
|
67 |
+
* @var string SDK version
|
68 |
+
*/
|
69 |
+
public $sdk_version;
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @var string Programming language version (e.g PHP version).
|
73 |
+
*/
|
74 |
+
public $programming_language_version;
|
75 |
+
|
76 |
+
/**
|
77 |
+
* @var number|null
|
78 |
+
*/
|
79 |
+
public $plan_id;
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @var number|null
|
83 |
+
*/
|
84 |
+
public $license_id;
|
85 |
+
|
86 |
+
/**
|
87 |
+
* @var number|null
|
88 |
+
*/
|
89 |
+
public $trial_plan_id;
|
90 |
+
|
91 |
+
/**
|
92 |
+
* @var string|null
|
93 |
+
*/
|
94 |
+
public $trial_ends;
|
95 |
+
|
96 |
+
/**
|
97 |
+
* @var bool
|
98 |
+
*/
|
99 |
+
public $is_premium = false;
|
100 |
+
|
101 |
+
/**
|
102 |
+
* @var bool
|
103 |
+
*/
|
104 |
+
public $is_disconnected = false;
|
105 |
+
|
106 |
+
/**
|
107 |
+
* @var bool
|
108 |
+
*/
|
109 |
+
public $is_active = true;
|
110 |
+
|
111 |
+
/**
|
112 |
+
* @var bool
|
113 |
+
*/
|
114 |
+
public $is_uninstalled = false;
|
115 |
+
|
116 |
+
/**
|
117 |
+
*
|
118 |
+
* @param stdClass|bool $site
|
119 |
+
*/
|
120 |
+
public function __construct( $site = false ) {
|
121 |
+
parent::__construct( $site );
|
122 |
+
|
123 |
+
if ( is_object( $site ) and isset( $site->plan_id ) ) {
|
124 |
+
$this->plan_id = $site->plan_id;
|
125 |
+
}
|
126 |
+
|
127 |
+
if ( ! is_bool( $this->is_disconnected ) ) {
|
128 |
+
$this->is_disconnected = false;
|
129 |
+
}
|
130 |
+
|
131 |
+
$props = get_object_vars( $this );
|
132 |
+
|
133 |
+
foreach ( $props as $key => $def_value ) {
|
134 |
+
$this->{$key} = isset( $site->{'install_' . $key} ) ? $site->{'install_' . $key} : $def_value;
|
135 |
+
}
|
136 |
+
if ( isset ( $site->install_id ) ) {
|
137 |
+
$this->site_id = $site->install_id;
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* @return string
|
143 |
+
*/
|
144 |
+
static function get_type() {
|
145 |
+
return 'install';
|
146 |
+
}
|
147 |
+
}
|
libs/factory/freemius/includes/entities/class-freemius-user.php
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WBCR\Factory_Freemius_117\Entities;
|
4 |
+
|
5 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
6 |
+
exit;
|
7 |
+
}
|
8 |
+
|
9 |
+
/**
|
10 |
+
* @author Webcraftic <wordpress.webraftic@gmail.com>, Alex Kovalev <alex.kovalevv@gmail.com>
|
11 |
+
* @link https://webcraftic.com
|
12 |
+
* @copyright (c) 2018 Webraftic Ltd, Freemius, Inc.
|
13 |
+
* @version 1.0
|
14 |
+
*/
|
15 |
+
class User extends Scope {
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
+
public $email;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var string
|
24 |
+
*/
|
25 |
+
public $first;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var string
|
29 |
+
*/
|
30 |
+
public $last;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @var bool
|
34 |
+
*/
|
35 |
+
public $is_verified;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @var string|null
|
39 |
+
*/
|
40 |
+
public $customer_id;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @var float
|
44 |
+
*/
|
45 |
+
public $gross;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* @param object|bool $user
|
49 |
+
*/
|
50 |
+
public function __construct( $user = false ) {
|
51 |
+
parent::__construct( $user );
|
52 |
+
$props = get_object_vars( $this );
|
53 |
+
|
54 |
+
foreach ( $props as $key => $def_value ) {
|
55 |
+
$this->{$key} = isset( $user->{'user_' . $key} ) ? $user->{'user_' . $key} : $def_value;
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @return string
|
61 |
+
*/
|
62 |
+
public function get_name() {
|
63 |
+
return trim( ucfirst( trim( is_string( $this->first ) ? $this->first : '' ) ) . ' ' . ucfirst( trim( is_string( $this->last ) ? $this->last : '' ) ) );
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @return bool
|
68 |
+
*/
|
69 |
+
public function is_verified() {
|
70 |
+
return ( isset( $this->is_verified ) && true === $this->is_verified );
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* @return string
|
75 |
+
*/
|
76 |
+
static function get_type() {
|
77 |
+
return 'user';
|
78 |
+
}
|
79 |
+
|
80 |
+
}
|
libs/factory/freemius/includes/entities/index.php
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Silence is golden.
|
libs/factory/freemius/includes/index.php
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Silence is golden.
|
libs/factory/freemius/includes/licensing/class-freemius-provider.php
ADDED
@@ -0,0 +1,772 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WBCR\Factory_Freemius_117\Premium;
|
4 |
+
|
5 |
+
use WBCR\Factory_Freemius_117\Entities\License;
|
6 |
+
use WBCR\Factory_Freemius_117\Entities\Plugin;
|
7 |
+
use WBCR\Factory_Freemius_117\Entities\Site;
|
8 |
+
use WBCR\Factory_Freemius_117\Entities\User;
|
9 |
+
use WBCR\Factory_429\Premium\Provider as License_Provider;
|
10 |
+
use Wbcr_Factory429_Plugin;
|
11 |
+
use WBCR\Factory_Freemius_117\Api;
|
12 |
+
use WP_Error;
|
13 |
+
use Exception;
|
14 |
+
|
15 |
+
// Exit if accessed directly
|
16 |
+
if( !defined('ABSPATH') ) {
|
17 |
+
exit;
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @author Alex Kovalev <alex.kovalevv@gmail.com>, Github: https://github.com/alexkovalevv
|
22 |
+
* @copyright (c) 2018 Webraftic Ltd, Freemius, Inc.
|
23 |
+
* @version 1.0
|
24 |
+
*/
|
25 |
+
final class Provider extends License_Provider {
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var int
|
29 |
+
*/
|
30 |
+
private $plugin_id;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @var string
|
34 |
+
*/
|
35 |
+
private $public_key;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @var string
|
39 |
+
*/
|
40 |
+
private $slug;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @var \WBCR\Factory_Freemius_117\Api
|
44 |
+
*/
|
45 |
+
private $site_api;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* @var \WBCR\Factory_Freemius_117\Api
|
49 |
+
*/
|
50 |
+
private $plugin_api;
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @var \WBCR\Factory_Freemius_117\Api
|
54 |
+
*/
|
55 |
+
private $user_api;
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @var bool
|
59 |
+
*/
|
60 |
+
private $is_activate_license = false;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* @var License|null
|
64 |
+
*/
|
65 |
+
private $license;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @var Site|null
|
69 |
+
*/
|
70 |
+
private $license_site;
|
71 |
+
|
72 |
+
/**
|
73 |
+
* @var User|null
|
74 |
+
*/
|
75 |
+
private $license_user;
|
76 |
+
|
77 |
+
/**
|
78 |
+
* @var Plugin|null
|
79 |
+
*/
|
80 |
+
private $license_plugin;
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Manager constructor.
|
84 |
+
*
|
85 |
+
* @param Wbcr_Factory429_Plugin $plugin
|
86 |
+
*
|
87 |
+
* @throws Exception
|
88 |
+
*/
|
89 |
+
public function __construct(Wbcr_Factory429_Plugin $plugin, array $settings)
|
90 |
+
{
|
91 |
+
parent::__construct($plugin, $settings);
|
92 |
+
|
93 |
+
$this->plugin_id = $this->get_setting('plugin_id', null);
|
94 |
+
$this->public_key = $this->get_setting('public_key', null);
|
95 |
+
$this->slug = $this->get_setting('slug', null);
|
96 |
+
|
97 |
+
if( empty($this->plugin_id) || empty($this->public_key) || empty($this->slug) ) {
|
98 |
+
throw new Exception('One of required (plugin_id, public_key, slug) attrs is empty.');
|
99 |
+
}
|
100 |
+
|
101 |
+
$this->init_license();
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* @return bool
|
106 |
+
* @throws Exception
|
107 |
+
*/
|
108 |
+
public function is_activate()
|
109 |
+
{
|
110 |
+
return $this->is_activate_license;
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* @return bool
|
115 |
+
* @throws Exception
|
116 |
+
*/
|
117 |
+
public function is_active()
|
118 |
+
{
|
119 |
+
if( !$this->is_activate_license ) {
|
120 |
+
return false;
|
121 |
+
}
|
122 |
+
|
123 |
+
return $this->get_license()->is_valid();
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* @return string
|
128 |
+
* @throws Exception
|
129 |
+
*/
|
130 |
+
public function get_plan()
|
131 |
+
{
|
132 |
+
if( !$this->is_activate_license ) {
|
133 |
+
return null;
|
134 |
+
}
|
135 |
+
|
136 |
+
return $this->get_license()->get_plan();
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* @return string
|
141 |
+
* @throws Exception
|
142 |
+
*/
|
143 |
+
public function get_billing_cycle()
|
144 |
+
{
|
145 |
+
if( !$this->is_activate_license ) {
|
146 |
+
return null;
|
147 |
+
}
|
148 |
+
|
149 |
+
return $this->get_license()->get_billing_cycle();
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* @return \WBCR\Factory_Freemius_117\Entities\License|null
|
154 |
+
* @throws Exception
|
155 |
+
*/
|
156 |
+
public function get_license()
|
157 |
+
{
|
158 |
+
return $this->license;
|
159 |
+
}
|
160 |
+
|
161 |
+
/**
|
162 |
+
* @return string|null
|
163 |
+
* @throws \Freemius_Exception
|
164 |
+
* @throws Exception
|
165 |
+
*/
|
166 |
+
public function get_package_download_url()
|
167 |
+
{
|
168 |
+
|
169 |
+
if( !$this->is_activate_license ) {
|
170 |
+
return null;
|
171 |
+
}
|
172 |
+
|
173 |
+
$endpoint = "/updates/latest.zip";
|
174 |
+
|
175 |
+
$endpoint = add_query_arg([
|
176 |
+
'is_premium' => json_encode(true),
|
177 |
+
//'type' => 'all'
|
178 |
+
], $endpoint);
|
179 |
+
|
180 |
+
try {
|
181 |
+
return $this->get_api_site_scope($this->license_site)->get_signed_url($endpoint);
|
182 |
+
} catch( \Freemius_Exception $e ) {
|
183 |
+
throw new Exception($e->getMessage(), $e->getCode());
|
184 |
+
}
|
185 |
+
}
|
186 |
+
|
187 |
+
/**
|
188 |
+
* @return array|mixed|string
|
189 |
+
* @throws \Freemius_Exception
|
190 |
+
* @throws Exception
|
191 |
+
*/
|
192 |
+
public function get_downloadable_package_info()
|
193 |
+
{
|
194 |
+
|
195 |
+
if( !$this->is_activate_license ) {
|
196 |
+
return null;
|
197 |
+
}
|
198 |
+
try {
|
199 |
+
$latest = $this->get_api_site_scope($this->license_site)->call("/updates/latest.json");
|
200 |
+
|
201 |
+
if( isset($latest->error) ) {
|
202 |
+
$error = $latest->error;
|
203 |
+
|
204 |
+
if( is_object($error) || is_array($error) ) {
|
205 |
+
$error = var_export($error, true);
|
206 |
+
}
|
207 |
+
|
208 |
+
throw new Exception("Freemius API ERROR:" . $error);
|
209 |
+
}
|
210 |
+
} catch( \Freemius_Exception $e ) {
|
211 |
+
throw new Exception($e->getMessage(), $e->getCode());
|
212 |
+
}
|
213 |
+
|
214 |
+
return $latest;
|
215 |
+
}
|
216 |
+
|
217 |
+
/**
|
218 |
+
* @param string $current_version
|
219 |
+
*
|
220 |
+
* @throws \Freemius_Exception
|
221 |
+
* @throws Exception
|
222 |
+
*/
|
223 |
+
public function get_package_updates($current_version)
|
224 |
+
{
|
225 |
+
|
226 |
+
if( !$this->is_activate_license ) {
|
227 |
+
return null;
|
228 |
+
}
|
229 |
+
|
230 |
+
try {
|
231 |
+
$updates = $this->get_api_site_scope($this->license_site)->call('updates.json?version=' . $current_version, 'GET');
|
232 |
+
|
233 |
+
if( isset($updates->error) ) {
|
234 |
+
throw new Exception($updates->error);
|
235 |
+
}
|
236 |
+
} catch( \Freemius_Exception $e ) {
|
237 |
+
throw new Exception($e->getMessage(), $e->getCode());
|
238 |
+
}
|
239 |
+
|
240 |
+
return $updates;
|
241 |
+
}
|
242 |
+
|
243 |
+
/**
|
244 |
+
* Активирует лицензицию
|
245 |
+
*
|
246 |
+
* @param string $key
|
247 |
+
*
|
248 |
+
* @return bool|mixed
|
249 |
+
* @throws \Freemius_Exception
|
250 |
+
* @throws Exception
|
251 |
+
*/
|
252 |
+
public function activate($key)
|
253 |
+
{
|
254 |
+
|
255 |
+
$license_key = trim(rtrim($key));
|
256 |
+
|
257 |
+
if( $this->is_activate_license ) {
|
258 |
+
if( $this->license->id == $license_key ) {
|
259 |
+
$this->sync();
|
260 |
+
|
261 |
+
return true;
|
262 |
+
}
|
263 |
+
|
264 |
+
$this->deactivate();
|
265 |
+
}
|
266 |
+
|
267 |
+
$url = 'https://wp.freemius.com/action/service/user/install/';
|
268 |
+
$request_body = [
|
269 |
+
'plugin_slug' => $this->slug,
|
270 |
+
'plugin_id' => $this->plugin_id,
|
271 |
+
'plugin_public_key' => $this->public_key,
|
272 |
+
'plugin_version' => $this->plugin->getPluginVersion(),
|
273 |
+
'is_active' => true,
|
274 |
+
'is_premium' => true,
|
275 |
+
'is_uninstalled' => false,
|
276 |
+
'is_marketing_allowed' => false,
|
277 |
+
'is_disconnected' => false,
|
278 |
+
'user_ip' => $this->get_user_ip(),
|
279 |
+
'format' => 'json',
|
280 |
+
'license_key' => $license_key,
|
281 |
+
'site_name' => get_bloginfo('name'),
|
282 |
+
'site_url' => get_home_url(), //site_uid
|
283 |
+
'site_uid' => $this->get_unique_site_id(),
|
284 |
+
'language' => get_bloginfo('language'),
|
285 |
+
'charset' => get_bloginfo('charset'),
|
286 |
+
'platform_version' => get_bloginfo('version'),
|
287 |
+
'sdk_version' => '2.2.3',
|
288 |
+
'programming_language_version' => phpversion()
|
289 |
+
];
|
290 |
+
|
291 |
+
$responce = wp_remote_post($url, [
|
292 |
+
'body' => $request_body,
|
293 |
+
'timeout' => 15,
|
294 |
+
]);
|
295 |
+
|
296 |
+
if( is_wp_error($responce) ) {
|
297 |
+
throw new Exception($responce->get_error_message());
|
298 |
+
}
|
299 |
+
|
300 |
+
if( isset($responce['response']['code']) && $responce['response']['code'] == 403 ) {
|
301 |
+
return new WP_Error('alert-danger', 'http error');
|
302 |
+
}
|
303 |
+
|
304 |
+
$responce_data = json_decode($responce['body']);
|
305 |
+
|
306 |
+
if( isset($responce_data->error) ) {
|
307 |
+
throw new Exception($responce_data->error);
|
308 |
+
}
|
309 |
+
|
310 |
+
$license_user = new User($responce_data);
|
311 |
+
$license_site = new Site($responce_data);
|
312 |
+
|
313 |
+
$user_api = $this->get_api_user_scope($license_user);
|
314 |
+
$site_api = $this->get_api_site_scope($license_site);
|
315 |
+
|
316 |
+
$user_licensies = $user_api->call($this->get_plugin_endpoint() . '/licenses.json', 'GET');
|
317 |
+
|
318 |
+
foreach($user_licensies->licenses as $user_license) {
|
319 |
+
if( $user_license->secret_key == $license_key ) {
|
320 |
+
$license = new License($user_license);
|
321 |
+
}
|
322 |
+
}
|
323 |
+
|
324 |
+
$request_plan_path = $this->get_plugin_endpoint() . '/plans/' . $license->plan_id . '.json';
|
325 |
+
$request_plan = $user_api->call($request_plan_path, 'GET');
|
326 |
+
|
327 |
+
$license->plan_title = $request_plan->title;
|
328 |
+
|
329 |
+
$request_subscriptions_path = $this->get_license_endpoint($license) . '/subscriptions.json';
|
330 |
+
$request_subscriptions = $site_api->call($request_subscriptions_path, 'GET');
|
331 |
+
|
332 |
+
if( isset($request_subscriptions->subscriptions) && isset($request_subscriptions->subscriptions[0]) ) {
|
333 |
+
$license->billing_cycle = $request_subscriptions->subscriptions[0]->billing_cycle;
|
334 |
+
}
|
335 |
+
|
336 |
+
$this->init_license($license, $license_user, $license_site);
|
337 |
+
$this->save_license_data();
|
338 |
+
|
339 |
+
$plugin_name = $this->plugin->getPluginName();
|
340 |
+
$license_info = [
|
341 |
+
'provider' => 'freemius',
|
342 |
+
'is_active' => $this->is_active(),
|
343 |
+
'license_key' => $this->get_license()->get_key(),
|
344 |
+
'expiration_time' => $this->get_license()->get_expiration_time()
|
345 |
+
];
|
346 |
+
|
347 |
+
/**
|
348 |
+
* Дейтсвие сработает после того, как лицензия будет успешно активирована
|
349 |
+
*
|
350 |
+
* @param string $provider Провайдер лицензии
|
351 |
+
* @param string $license_info Дополнительная информация о лицензии
|
352 |
+
* @since 1.0.9 Изменил имя хука на {$plugin_name}/factory/premium/license_activate
|
353 |
+
* @since 1.0.0 Добавлен
|
354 |
+
*
|
355 |
+
*/
|
356 |
+
do_action("{$plugin_name}/factory/premium/license_activate", 'freemius', $license_info);
|
357 |
+
|
358 |
+
return true;
|
359 |
+
}
|
360 |
+
|
361 |
+
/**
|
362 |
+
* Деактивирует лицензию
|
363 |
+
*
|
364 |
+
* @return bool
|
365 |
+
* @throws \Freemius_Exception
|
366 |
+
* @throws Exception
|
367 |
+
*/
|
368 |
+
public function deactivate()
|
369 |
+
{
|
370 |
+
if( !$this->is_activate_license ) {
|
371 |
+
return true;
|
372 |
+
}
|
373 |
+
|
374 |
+
$plugin_name = $this->plugin->getPluginName();
|
375 |
+
$license_info = [
|
376 |
+
'provider' => 'freemius',
|
377 |
+
'is_active' => $this->is_active(),
|
378 |
+
'license_key' => $this->get_license()->get_key(),
|
379 |
+
'expiration_time' => $this->get_license()->get_expiration_time()
|
380 |
+
];
|
381 |
+
|
382 |
+
$site_api = $this->get_api_site_scope($this->license_site);
|
383 |
+
$user_api = $this->get_api_user_scope($this->license_user);
|
384 |
+
|
385 |
+
$site_api->call($this->get_license_endpoint($this->license) . '.json?license_key=' . $this->license->get_key(), 'DELETE');
|
386 |
+
$user_api->call($this->get_plugin_endpoint() . '/installs.json?ids=' . $this->license_site->id, 'DELETE');
|
387 |
+
|
388 |
+
// todo: добавить обработку ошибок
|
389 |
+
|
390 |
+
$this->delete_license_data();
|
391 |
+
|
392 |
+
/**
|
393 |
+
* Дейтсвие сработает после того, как лицензия будет успешно деактивирована
|
394 |
+
*
|
395 |
+
* @param string $provider Провайдер лицензии
|
396 |
+
* @param string $license_info Дополнительная информация о лицензии
|
397 |
+
* @since 1.0.9 Изменил имя хука на {$plugin_name}/factory/premium/license_deactivate
|
398 |
+
* @since 1.0.0 Добавлен
|
399 |
+
*
|
400 |
+
*/
|
401 |
+
do_action("{$plugin_name}/factory/premium/license_deactivate", 'freemius', $license_info);
|
402 |
+
|
403 |
+
return true;
|
404 |
+
}
|
405 |
+
|
406 |
+
/**
|
407 |
+
* Синхронизирует данные текущей лицензии.
|
408 |
+
*
|
409 |
+
* @return bool
|
410 |
+
* @throws Exception
|
411 |
+
*/
|
412 |
+
public function sync()
|
413 |
+
{
|
414 |
+
if( !$this->is_activate_license ) {
|
415 |
+
return false;
|
416 |
+
}
|
417 |
+
|
418 |
+
$site_api = $this->get_api_site_scope($this->license_site);
|
419 |
+
$user_api = $this->get_api_user_scope($this->license_user);
|
420 |
+
|
421 |
+
$request_install = $site_api->call('/', 'GET');
|
422 |
+
|
423 |
+
if( isset($request_install->error) ) {
|
424 |
+
throw new Exception($request_install->error);
|
425 |
+
}
|
426 |
+
|
427 |
+
// Если установка не найдена или неактивна, деактивируем лицензию
|
428 |
+
if( !(isset($request_install->is_active) && $request_install->is_active) ) {
|
429 |
+
$this->deactivate();
|
430 |
+
|
431 |
+
return true;
|
432 |
+
}
|
433 |
+
|
434 |
+
$use_license_key = urlencode($this->license->secret_key);
|
435 |
+
$request_license_path = $this->get_license_endpoint($this->license) . '.json?license_key=' . $use_license_key;
|
436 |
+
$request_license = $site_api->call($request_license_path, 'GET');
|
437 |
+
|
438 |
+
if( isset($request_license->error) ) {
|
439 |
+
throw new Exception($request_license->error);
|
440 |
+
}
|
441 |
+
|
442 |
+
// Если лицензия не найдена или неактивна или тарифный план не совпадает с текущей установкой,
|
443 |
+
// деактивируем лицензию.
|
444 |
+
if( !(isset($request_license->plan_id) && $request_license->plan_id == $request_install->plan_id) ) {
|
445 |
+
$this->deactivate();
|
446 |
+
|
447 |
+
return true;
|
448 |
+
}
|
449 |
+
|
450 |
+
$request_subscriptions_path = $this->get_license_endpoint($this->license) . '/subscriptions.json';
|
451 |
+
$request_subscriptions = $site_api->call($request_subscriptions_path, 'GET');
|
452 |
+
|
453 |
+
$request_plan_path = $this->get_plugin_endpoint() . '/plans/' . $this->license->plan_id . '.json';
|
454 |
+
$request_plan = $user_api->call($request_plan_path, 'GET');
|
455 |
+
|
456 |
+
$this->license->plan_title = $request_plan->title;
|
457 |
+
|
458 |
+
if( isset($request_subscriptions->subscriptions) && isset($request_subscriptions->subscriptions[0]) ) {
|
459 |
+
if( !is_null($request_subscriptions->subscriptions[0]->next_payment) ) {
|
460 |
+
$this->license->billing_cycle = $request_subscriptions->subscriptions[0]->billing_cycle;
|
461 |
+
}
|
462 |
+
}
|
463 |
+
|
464 |
+
$this->license->populate($request_license);
|
465 |
+
$this->save_license_data();
|
466 |
+
|
467 |
+
// Обновляем информацию о сайте и сервере пользователя
|
468 |
+
$site_api->call('/', 'put', [
|
469 |
+
'id' => $this->license_site->id,
|
470 |
+
'uid' => $this->get_unique_site_id(),
|
471 |
+
'plugin_version' => $this->plugin->getPluginVersion(),
|
472 |
+
'language' => get_bloginfo('language'),
|
473 |
+
'charset' => get_bloginfo('charset'),
|
474 |
+
'platform_version' => get_bloginfo('version'),
|
475 |
+
'sdk_version' => '2.2.3',
|
476 |
+
'programming_language_version' => phpversion()
|
477 |
+
]);
|
478 |
+
|
479 |
+
$plugin_name = $this->plugin->getPluginName();
|
480 |
+
$license_info = [
|
481 |
+
'provider' => 'freemius',
|
482 |
+
'is_active' => $this->is_active(),
|
483 |
+
'license_key' => $this->get_license()->get_key(),
|
484 |
+
'expiration_time' => $this->get_license()->get_expiration_time()
|
485 |
+
];
|
486 |
+
|
487 |
+
/**
|
488 |
+
* Выполняется, когда синхронизация завершена успешно, без деактивации
|
489 |
+
*
|
490 |
+
* @param string $license_info Дополнительная информация о лицензии
|
491 |
+
* @since 1.0.0 Добавлен
|
492 |
+
*
|
493 |
+
* @since 1.0.9 Изменил имя хука на {$plugin_name}/factory/premium/license_sync
|
494 |
+
*/
|
495 |
+
do_action("{$plugin_name}/factory/premium/license_sync", $license_info);
|
496 |
+
|
497 |
+
return true;
|
498 |
+
}
|
499 |
+
|
500 |
+
/**
|
501 |
+
* Используется ли платная подписка на обновления плагина.
|
502 |
+
*
|
503 |
+
* @return bool
|
504 |
+
*/
|
505 |
+
public function has_paid_subscription()
|
506 |
+
{
|
507 |
+
if( !$this->is_activate_license ) {
|
508 |
+
return false;
|
509 |
+
}
|
510 |
+
|
511 |
+
return !empty($this->license->billing_cycle);
|
512 |
+
}
|
513 |
+
|
514 |
+
/**
|
515 |
+
* Отменяет платную подписку в freemius.com
|
516 |
+
*
|
517 |
+
* @return bool
|
518 |
+
* @throws Exception
|
519 |
+
*/
|
520 |
+
public function cancel_paid_subscription()
|
521 |
+
{
|
522 |
+
if( !$this->is_activate_license ) {
|
523 |
+
return false;
|
524 |
+
}
|
525 |
+
|
526 |
+
$site_api = $this->get_api_site_scope($this->license_site);
|
527 |
+
|
528 |
+
$request_subscriptions = $site_api->call($this->get_license_endpoint($this->license) . '/subscriptions.json', 'GET');
|
529 |
+
|
530 |
+
if( isset($request_subscriptions->subscriptions) && isset($request_subscriptions->subscriptions[0]) ) {
|
531 |
+
$site_api->call('downgrade.json', 'PUT');
|
532 |
+
$this->license->billing_cycle = null;
|
533 |
+
$this->save_license_data();
|
534 |
+
}
|
535 |
+
|
536 |
+
return true;
|
537 |
+
}
|
538 |
+
|
539 |
+
/**
|
540 |
+
* Отписывается от платной подписики на обновления
|
541 |
+
*
|
542 |
+
* @return WP_Error
|
543 |
+
*/
|
544 |
+
/*public function unsubscribe() {
|
545 |
+
|
546 |
+
}*/
|
547 |
+
|
548 |
+
// GETTERS SECTION
|
549 |
+
// -----------------------------------------------------------------------------------
|
550 |
+
|
551 |
+
/**
|
552 |
+
* Unique site identifier (Hash).
|
553 |
+
*
|
554 |
+
* @param null|int $blog_id Since 2.0.0
|
555 |
+
*
|
556 |
+
* @return string
|
557 |
+
* @author Vova Feldman (@svovaf)
|
558 |
+
* @since 1.1.0
|
559 |
+
*
|
560 |
+
*/
|
561 |
+
protected function get_unique_site_id()
|
562 |
+
{
|
563 |
+
$key = str_replace(['http://', 'https://'], '', get_site_url());
|
564 |
+
|
565 |
+
$secure_auth = SECURE_AUTH_KEY;
|
566 |
+
if( empty($secure_auth) || false !== strpos($secure_auth, ' ') ) {
|
567 |
+
// Protect against default auth key.
|
568 |
+
$secure_auth = md5(microtime());
|
569 |
+
}
|
570 |
+
|
571 |
+
/**
|
572 |
+
* Base the unique identifier on the WP secure authentication key. Which
|
573 |
+
* turns the key into a secret anonymous identifier. This will help us
|
574 |
+
* to avoid duplicate installs generation on the backend upon opt-in.
|
575 |
+
*
|
576 |
+
* @author Vova Feldman (@svovaf)
|
577 |
+
* @since 1.2.3
|
578 |
+
*/
|
579 |
+
$unique_id = md5($key . $secure_auth);
|
580 |
+
|
581 |
+
return $unique_id;
|
582 |
+
}
|
583 |
+
|
584 |
+
/**
|
585 |
+
* Get client IP.
|
586 |
+
*
|
587 |
+
* @return string|null
|
588 |
+
* @since 1.1.2
|
589 |
+
*
|
590 |
+
* @author Vova Feldman (@svovaf)
|
591 |
+
*/
|
592 |
+
protected function get_user_ip()
|
593 |
+
{
|
594 |
+
$fields = [
|
595 |
+
'HTTP_CF_CONNECTING_IP',
|
596 |
+
'HTTP_CLIENT_IP',
|
597 |
+
'HTTP_X_FORWARDED_FOR',
|
598 |
+
'HTTP_X_FORWARDED',
|
599 |
+
'HTTP_FORWARDED_FOR',
|
600 |
+
'HTTP_FORWARDED',
|
601 |
+
'REMOTE_ADDR',
|
602 |
+
];
|
603 |
+
|
604 |
+
foreach($fields as $ip_field) {
|
605 |
+
if( !empty($_SERVER[$ip_field]) ) {
|
606 |
+
return $_SERVER[$ip_field];
|
607 |
+
}
|
608 |
+
}
|
609 |
+
|
610 |
+
return null;
|
611 |
+
}
|
612 |
+
|
613 |
+
/**
|
614 |
+
* @param bool $flush
|
615 |
+
*
|
616 |
+
* @return \WBCR\Factory_Freemius_117\Api
|
617 |
+
* @throws Exception
|
618 |
+
*/
|
619 |
+
private function get_api_user_scope(User $user, $flush = false)
|
620 |
+
{
|
621 |
+
if( !isset($this->user_api) || $flush ) {
|
622 |
+
$this->user_api = Api::instance($this->plugin, 'user', $user->id, $user->public_key, false, $user->secret_key);
|
623 |
+
}
|
624 |
+
|
625 |
+
return $this->user_api;
|
626 |
+
}
|
627 |
+
|
628 |
+
/**
|
629 |
+
* @param bool $flush
|
630 |
+
*
|
631 |
+
* @return \WBCR\Factory_Freemius_117\Api
|
632 |
+
* @throws Exception
|
633 |
+
*/
|
634 |
+
private function get_api_site_scope(Site $site, $flush = false)
|
635 |
+
{
|
636 |
+
if( !isset($this->site_api) || $flush ) {
|
637 |
+
$this->site_api = Api::instance($this->plugin, 'install', $site->id, $site->public_key, false, $site->secret_key);
|
638 |
+
}
|
639 |
+
|
640 |
+
return $this->site_api;
|
641 |
+
}
|
642 |
+
|
643 |
+
/**
|
644 |
+
* Get plugin public API scope.
|
645 |
+
*
|
646 |
+
* @return \WBCR\Factory_Freemius_117\Api
|
647 |
+
* @throws Exception
|
648 |
+
*/
|
649 |
+
private function get_api_plugin_scope()
|
650 |
+
{
|
651 |
+
if( !isset($this->plugin_api) ) {
|
652 |
+
$this->plugin_api = Api::instance($this->plugin, 'plugin', $this->plugin_id, $this->public_key, false);
|
653 |
+
}
|
654 |
+
|
655 |
+
return $this->plugin_api;
|
656 |
+
}
|
657 |
+
|
658 |
+
/**
|
659 |
+
* @param License $license
|
660 |
+
*
|
661 |
+
* @return string
|
662 |
+
*/
|
663 |
+
private function get_license_endpoint(License $license)
|
664 |
+
{
|
665 |
+
return '/licenses/' . $license->id;
|
666 |
+
}
|
667 |
+
|
668 |
+
/**
|
669 |
+
* @return string
|
670 |
+
* @throws Exception
|
671 |
+
*/
|
672 |
+
private function get_plugin_endpoint()
|
673 |
+
{
|
674 |
+
return '/plugins/' . $this->plugin_id;
|
675 |
+
}
|
676 |
+
|
677 |
+
// END GETTERS SECTION
|
678 |
+
// -----------------------------------------------------------------------------------
|
679 |
+
|
680 |
+
/**
|
681 |
+
* @return void
|
682 |
+
* @throws Exception
|
683 |
+
*/
|
684 |
+
private function init_license($license = null, $license_user = null, $license_site = null, $license_plugin = null)
|
685 |
+
{
|
686 |
+
|
687 |
+
if( $this->is_activate_license ) {
|
688 |
+
return;
|
689 |
+
}
|
690 |
+
|
691 |
+
if( $license instanceof License && $license_user instanceof User && $license_site instanceof Site ) {
|
692 |
+
$this->license = $license;
|
693 |
+
$this->license_site = $license_site;
|
694 |
+
$this->license_user = $license_user;
|
695 |
+
$this->license_plugin = $license_plugin;
|
696 |
+
} else {
|
697 |
+
$license_data = $this->plugin->getPopulateOption('license', []);
|
698 |
+
|
699 |
+
if( empty($license_data) || !(isset($license_data['license']) && isset($license_data['site']) && isset($license_data['user'])) ) {
|
700 |
+
return;
|
701 |
+
}
|
702 |
+
|
703 |
+
$this->license = new License($license_data['license']);
|
704 |
+
$this->license_site = new Site($license_data['site']);
|
705 |
+
$this->license_user = new User($license_data['user']);
|
706 |
+
|
707 |
+
if( isset($license_data['plugin']) ) {
|
708 |
+
$this->license_plugin = new Plugin($license_data['plugin']);
|
709 |
+
}
|
710 |
+
}
|
711 |
+
|
712 |
+
if( $this->license->id && $this->license_site->id && $this->license_user->id ) {
|
713 |
+
$this->is_activate_license = true;
|
714 |
+
}
|
715 |
+
}
|
716 |
+
|
717 |
+
/**
|
718 |
+
* Сбрасывает всю объектную информацию о лицензии
|
719 |
+
*
|
720 |
+
* @return void
|
721 |
+
* @since 1.0.0
|
722 |
+
*/
|
723 |
+
private function flush_license_data()
|
724 |
+
{
|
725 |
+
|
726 |
+
$this->is_activate_license = false;
|
727 |
+
$this->license = null;
|
728 |
+
$this->license_site = null;
|
729 |
+
$this->license_user = null;
|
730 |
+
$this->license_plugin = null;
|
731 |
+
|
732 |
+
$this->user_api = null;
|
733 |
+
$this->site_api = null;
|
734 |
+
}
|
735 |
+
|
736 |
+
/**
|
737 |
+
* Сбрасывает всю объектную информацию о лицензии и удаляет
|
738 |
+
* данные о лицензии из базы данных.
|
739 |
+
*
|
740 |
+
* @return void
|
741 |
+
* @since 1.0.0
|
742 |
+
*/
|
743 |
+
private function delete_license_data()
|
744 |
+
{
|
745 |
+
$this->flush_license_data();
|
746 |
+
|
747 |
+
$this->plugin->deletePopulateOption('license');
|
748 |
+
}
|
749 |
+
|
750 |
+
/**
|
751 |
+
* Сохраняет лицензионные данные в базе данных, если данные
|
752 |
+
* уже есть в базе данных, метод просто обновляет их.
|
753 |
+
*/
|
754 |
+
private function save_license_data()
|
755 |
+
{
|
756 |
+
if( !$this->license || !$this->license_site || !$this->license_user ) {
|
757 |
+
return;
|
758 |
+
}
|
759 |
+
|
760 |
+
$save_data = [
|
761 |
+
'license' => $this->license->to_array(),
|
762 |
+
'site' => $this->license_site->to_array(),
|
763 |
+
'user' => $this->license_user->to_array()
|
764 |
+
];
|
765 |
+
|
766 |
+
if( !empty($this->license_plugin) ) {
|
767 |
+
$save_data['plugin'] = $this->license_plugin->to_array();
|
768 |
+
}
|
769 |
+
|
770 |
+
$this->plugin->updatePopulateOption('license', $save_data);
|
771 |
+
}
|
772 |
+
}
|
libs/factory/freemius/includes/licensing/index.php
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Silence is golden.
|
libs/factory/freemius/includes/sdk/Exceptions/ArgumentNotExistException.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( ! class_exists( 'Freemius_InvalidArgumentException' ) ) {
|
3 |
+
exit;
|
4 |
+
}
|
5 |
+
|
6 |
+
if ( ! class_exists( 'Freemius_ArgumentNotExistException' ) ) {
|
7 |
+
class Freemius_ArgumentNotExistException extends Freemius_InvalidArgumentException {
|
8 |
+
}
|
9 |
+
}
|
libs/factory/freemius/includes/sdk/Exceptions/EmptyArgumentException.php
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( ! class_exists( 'Freemius_InvalidArgumentException' ) ) {
|
3 |
+
exit;
|
4 |
+
}
|
5 |
+
|
6 |
+
if ( ! class_exists( 'Freemius_EmptyArgumentException' ) ) {
|
7 |
+
class Freemius_EmptyArgumentException extends Freemius_InvalidArgumentException {
|
8 |
+
}
|
9 |
+
}
|
libs/factory/freemius/includes/sdk/Exceptions/Exception.php
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( ! class_exists( 'Freemius_Exception' ) ) {
|
3 |
+
/**
|
4 |
+
* Thrown when an API call returns an exception.
|
5 |
+
*
|
6 |
+
*/
|
7 |
+
class Freemius_Exception extends Exception {
|
8 |
+
protected $_result;
|
9 |
+
protected $_type;
|
10 |
+
protected $_code;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Make a new API Exception with the given result.
|
14 |
+
*
|
15 |
+
* @param array $result The result from the API server.
|
16 |
+
*/
|
17 |
+
public function __construct( $result ) {
|
18 |
+
$this->_result = $result;
|
19 |
+
|
20 |
+
$code = 0;
|
21 |
+
$message = 'Unknown error, please check GetResult().';
|
22 |
+
$type = '';
|
23 |
+
|
24 |
+
if ( isset( $result['error'] ) && is_array( $result['error'] ) ) {
|
25 |
+
if ( isset( $result['error']['code'] ) ) {
|
26 |
+
$code = $result['error']['code'];
|
27 |
+
}
|
28 |
+
if ( isset( $result['error']['message'] ) ) {
|
29 |
+
$message = $result['error']['message'];
|
30 |
+
}
|
31 |
+
if ( isset( $result['error']['type'] ) ) {
|
32 |
+
$type = $result['error']['type'];
|
33 |
+
}
|
34 |
+
}
|
35 |
+
|
36 |
+
$this->_type = $type;
|
37 |
+
$this->_code = $code;
|
38 |
+
|
39 |
+
parent::__construct( $message, is_numeric( $code ) ? $code : 0 );
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Return the associated result object returned by the API server.
|
44 |
+
*
|
45 |
+
* @return array The result from the API server
|
46 |
+
*/
|
47 |
+
public function getResult() {
|
48 |
+
return $this->_result;
|
49 |
+
}
|
50 |
+
|
51 |
+
public function getStringCode() {
|
52 |
+
return $this->_code;
|
53 |
+
}
|
54 |
+
|
55 |
+
public function getType() {
|
56 |
+
return $this->_type;
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* To make debugging easier.
|
61 |
+
*
|
62 |
+
* @return string The string representation of the error
|
63 |
+
*/
|
64 |
+
public function __toString() {
|
65 |
+
$str = $this->getType() . ': ';
|
66 |
+
|
67 |
+
if ( $this->code != 0 ) {
|
68 |
+
$str .= $this->getStringCode() . ': ';
|
69 |
+
}
|
70 |
+
|
71 |
+
return $str . $this->getMessage();
|
72 |
+
}
|
73 |
+
}
|
74 |
+
}
|
libs/factory/freemius/includes/sdk/Exceptions/InvalidArgumentException.php
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( ! class_exists( 'Freemius_Exception' ) ) {
|
3 |
+
exit;
|
4 |
+
}
|
5 |
+
|
6 |
+
if ( ! class_exists( 'Freemius_InvalidArgumentException' ) ) {
|
7 |
+
class Freemius_InvalidArgumentException extends Freemius_Exception { }
|
8 |
+
}
|
libs/factory/freemius/includes/sdk/Exceptions/OAuthException.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
if ( ! class_exists( 'Freemius_Exception' ) ) {
|
3 |
+
exit;
|
4 |
+
}
|
5 |
+
|
6 |
+
if ( ! class_exists( 'Freemius_OAuthException' ) ) {
|
7 |
+
class Freemius_OAuthException extends Freemius_Exception {
|
8 |
+
public function __construct( $pResult ) {
|
9 |
+
parent::__construct( $pResult );
|
10 |
+
}
|
11 |
+
}
|
12 |
+
}
|
libs/factory/freemius/includes/sdk/Exceptions/index.php
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Silence is golden.
|
3 |
+
// Hide file structure from users on unprotected servers.
|
libs/factory/freemius/includes/sdk/FreemiusBase.php
ADDED
@@ -0,0 +1,215 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright 2014 Freemius, Inc.
|
4 |
+
*
|
5 |
+
* Licensed under the GPL v2 (the "License"); you may
|
6 |
+
* not use this file except in compliance with the License. You may obtain
|
7 |
+
* a copy of the License at
|
8 |
+
*
|
9 |
+
* http://choosealicense.com/licenses/gpl-v2/
|
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, WITHOUT
|
13 |
+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
14 |
+
* License for the specific language governing permissions and limitations
|
15 |
+
* under the License.
|
16 |
+
*/
|
17 |
+
|
18 |
+
if ( ! defined( 'FS_API__VERSION' ) ) {
|
19 |
+
define( 'FS_API__VERSION', '1' );
|
20 |
+
}
|
21 |
+
if ( ! defined( 'FS_SDK__PATH' ) ) {
|
22 |
+
define( 'FS_SDK__PATH', dirname( __FILE__ ) );
|
23 |
+
}
|
24 |
+
if ( ! defined( 'FS_SDK__EXCEPTIONS_PATH' ) ) {
|
25 |
+
define( 'FS_SDK__EXCEPTIONS_PATH', FS_SDK__PATH . '/Exceptions/' );
|
26 |
+
}
|
27 |
+
|
28 |
+
if ( ! function_exists( 'json_decode' ) ) {
|
29 |
+
throw new Exception( 'Freemius needs the JSON PHP extension.' );
|
30 |
+
}
|
31 |
+
|
32 |
+
// Include all exception files.
|
33 |
+
$exceptions = array(
|
34 |
+
'Exception',
|
35 |
+
'InvalidArgumentException',
|
36 |
+
'ArgumentNotExistException',
|
37 |
+
'EmptyArgumentException',
|
38 |
+
'OAuthException'
|
39 |
+
);
|
40 |
+
|
41 |
+
foreach ( $exceptions as $e ) {
|
42 |
+
require_once FS_SDK__EXCEPTIONS_PATH . $e . '.php';
|
43 |
+
}
|
44 |
+
|
45 |
+
if ( class_exists( 'Freemius_Api_Base' ) ) {
|
46 |
+
return;
|
47 |
+
}
|
48 |
+
|
49 |
+
abstract class Freemius_Api_Base {
|
50 |
+
const VERSION = '1.0.4';
|
51 |
+
const FORMAT = 'json';
|
52 |
+
|
53 |
+
protected $_id;
|
54 |
+
protected $_public;
|
55 |
+
protected $_secret;
|
56 |
+
protected $_scope;
|
57 |
+
protected $_isSandbox;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* @param string $pScope 'app', 'developer', 'plugin', 'user' or 'install'.
|
61 |
+
* @param number $pID Element's id.
|
62 |
+
* @param string $pPublic Public key.
|
63 |
+
* @param string $pSecret Element's secret key.
|
64 |
+
* @param bool $pIsSandbox Whether or not to run API in sandbox mode.
|
65 |
+
*/
|
66 |
+
public function Init( $pScope, $pID, $pPublic, $pSecret, $pIsSandbox = false ) {
|
67 |
+
$this->_id = $pID;
|
68 |
+
$this->_public = $pPublic;
|
69 |
+
$this->_secret = $pSecret;
|
70 |
+
$this->_scope = $pScope;
|
71 |
+
$this->_isSandbox = $pIsSandbox;
|
72 |
+
}
|
73 |
+
|
74 |
+
public function IsSandbox() {
|
75 |
+
return $this->_isSandbox;
|
76 |
+
}
|
77 |
+
|
78 |
+
function CanonizePath( $pPath ) {
|
79 |
+
$pPath = trim( $pPath, '/' );
|
80 |
+
$query_pos = strpos( $pPath, '?' );
|
81 |
+
$query = '';
|
82 |
+
|
83 |
+
if ( false !== $query_pos ) {
|
84 |
+
$query = substr( $pPath, $query_pos );
|
85 |
+
$pPath = substr( $pPath, 0, $query_pos );
|
86 |
+
}
|
87 |
+
|
88 |
+
// Trim '.json' suffix.
|
89 |
+
$format_length = strlen( '.' . self::FORMAT );
|
90 |
+
$start = $format_length * ( - 1 ); //negative
|
91 |
+
if ( substr( strtolower( $pPath ), $start ) === ( '.' . self::FORMAT ) ) {
|
92 |
+
$pPath = substr( $pPath, 0, strlen( $pPath ) - $format_length );
|
93 |
+
}
|
94 |
+
|
95 |
+
switch ( $this->_scope ) {
|
96 |
+
case 'app':
|
97 |
+
$base = '/apps/' . $this->_id;
|
98 |
+
break;
|
99 |
+
case 'developer':
|
100 |
+
$base = '/developers/' . $this->_id;
|
101 |
+
break;
|
102 |
+
case 'user':
|
103 |
+
$base = '/users/' . $this->_id;
|
104 |
+
break;
|
105 |
+
case 'plugin':
|
106 |
+
$base = '/plugins/' . $this->_id;
|
107 |
+
break;
|
108 |
+
case 'install':
|
109 |
+
$base = '/installs/' . $this->_id;
|
110 |
+
break;
|
111 |
+
default:
|
112 |
+
throw new Freemius_Exception( 'Scope not implemented.' );
|
113 |
+
}
|
114 |
+
|
115 |
+
return '/v' . FS_API__VERSION . $base .
|
116 |
+
( ! empty( $pPath ) ? '/' : '' ) . $pPath .
|
117 |
+
( ( false === strpos( $pPath, '.' ) ) ? '.' . self::FORMAT : '' ) . $query;
|
118 |
+
}
|
119 |
+
|
120 |
+
abstract function MakeRequest( $pCanonizedPath, $pMethod = 'GET', $pParams = array() );
|
121 |
+
|
122 |
+
/**
|
123 |
+
* @param string $pPath
|
124 |
+
* @param string $pMethod
|
125 |
+
* @param array $pParams
|
126 |
+
*
|
127 |
+
* @return object[]|object|null
|
128 |
+
*/
|
129 |
+
private function _Api( $pPath, $pMethod = 'GET', $pParams = array() ) {
|
130 |
+
$pMethod = strtoupper( $pMethod );
|
131 |
+
|
132 |
+
try {
|
133 |
+
$result = $this->MakeRequest( $pPath, $pMethod, $pParams );
|
134 |
+
} catch ( Freemius_Exception $e ) {
|
135 |
+
// Map to error object.
|
136 |
+
$result = (object) $e->getResult();
|
137 |
+
} catch ( Exception $e ) {
|
138 |
+
// Map to error object.
|
139 |
+
$result = (object) array(
|
140 |
+
'error' => array(
|
141 |
+
'type' => 'Unknown',
|
142 |
+
'message' => $e->getMessage() . ' (' . $e->getFile() . ': ' . $e->getLine() . ')',
|
143 |
+
'code' => 'unknown',
|
144 |
+
'http' => 402
|
145 |
+
)
|
146 |
+
);
|
147 |
+
}
|
148 |
+
|
149 |
+
return $result;
|
150 |
+
}
|
151 |
+
|
152 |
+
public function Api( $pPath, $pMethod = 'GET', $pParams = array() ) {
|
153 |
+
return $this->_Api( $this->CanonizePath( $pPath ), $pMethod, $pParams );
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Base64 decoding that does not need to be urldecode()-ed.
|
158 |
+
*
|
159 |
+
* Exactly the same as PHP base64 encode except it uses
|
160 |
+
* `-` instead of `+`
|
161 |
+
* `_` instead of `/`
|
162 |
+
* No padded =
|
163 |
+
*
|
164 |
+
* @param string $input Base64UrlEncoded() string
|
165 |
+
*
|
166 |
+
* @return string
|
167 |
+
*/
|
168 |
+
protected static function Base64UrlDecode( $input ) {
|
169 |
+
/**
|
170 |
+
* IMPORTANT NOTE:
|
171 |
+
* This is a hack suggested by @otto42 and @greenshady from
|
172 |
+
* the theme's review team. The usage of base64 for API
|
173 |
+
* signature encoding was approved in a Slack meeting
|
174 |
+
* held on Tue (10/25 2016).
|
175 |
+
*
|
176 |
+
* @todo Remove this hack once the base64 error is removed from the Theme Check.
|
177 |
+
*
|
178 |
+
* @since 1.2.2
|
179 |
+
* @author Vova Feldman (@svovaf)
|
180 |
+
*/
|
181 |
+
$fn = 'base64' . '_decode';
|
182 |
+
return $fn( strtr( $input, '-_', '+/' ) );
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Base64 encoding that does not need to be urlencode()ed.
|
187 |
+
*
|
188 |
+
* Exactly the same as base64 encode except it uses
|
189 |
+
* `-` instead of `+
|
190 |
+
* `_` instead of `/`
|
191 |
+
*
|
192 |
+
* @param string $input string
|
193 |
+
*
|
194 |
+
* @return string Base64 encoded string
|
195 |
+
*/
|
196 |
+
protected static function Base64UrlEncode( $input ) {
|
197 |
+
/**
|
198 |
+
* IMPORTANT NOTE:
|
199 |
+
* This is a hack suggested by @otto42 and @greenshady from
|
200 |
+
* the theme's review team. The usage of base64 for API
|
201 |
+
* signature encoding was approved in a Slack meeting
|
202 |
+
* held on Tue (10/25 2016).
|
203 |
+
*
|
204 |
+
* @todo Remove this hack once the base64 error is removed from the Theme Check.
|
205 |
+
*
|
206 |
+
* @since 1.2.2
|
207 |
+
* @author Vova Feldman (@svovaf)
|
208 |
+
*/
|
209 |
+
$fn = 'base64' . '_encode';
|
210 |
+
$str = strtr( $fn( $input ), '+/', '-_' );
|
211 |
+
$str = str_replace( '=', '', $str );
|
212 |
+
|
213 |
+
return $str;
|
214 |
+
}
|
215 |
+
}
|
libs/factory/freemius/includes/sdk/FreemiusWordPress.php
ADDED
@@ -0,0 +1,704 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright 2016 Freemius, Inc.
|
4 |
+
*
|
5 |
+
* Licensed under the GPL v2 (the "License"); you may
|
6 |
+
* not use this file except in compliance with the License. You may obtain
|
7 |
+
* a copy of the License at
|
8 |
+
*
|
9 |
+
* http://choosealicense.com/licenses/gpl-v2/
|
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, WITHOUT
|
13 |
+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
14 |
+
* License for the specific language governing permissions and limitations
|
15 |
+
* under the License.
|
16 |
+
*/
|
17 |
+
|
18 |
+
require_once dirname( __FILE__ ) . '/FreemiusBase.php';
|
19 |
+
|
20 |
+
if ( ! defined( 'FS_SDK__USER_AGENT' ) ) {
|
21 |
+
define( 'FS_SDK__USER_AGENT', 'fs-php-' . Freemius_Api_Base::VERSION );
|
22 |
+
}
|
23 |
+
|
24 |
+
if ( ! defined( 'FS_SDK__SIMULATE_NO_CURL' ) ) {
|
25 |
+
define( 'FS_SDK__SIMULATE_NO_CURL', false );
|
26 |
+
}
|
27 |
+
|
28 |
+
if ( ! defined( 'FS_SDK__SIMULATE_NO_API_CONNECTIVITY_CLOUDFLARE' ) ) {
|
29 |
+
define( 'FS_SDK__SIMULATE_NO_API_CONNECTIVITY_CLOUDFLARE', false );
|
30 |
+
}
|
31 |
+
|
32 |
+
if ( ! defined( 'FS_SDK__SIMULATE_NO_API_CONNECTIVITY_SQUID_ACL' ) ) {
|
33 |
+
define( 'FS_SDK__SIMULATE_NO_API_CONNECTIVITY_SQUID_ACL', false );
|
34 |
+
}
|
35 |
+
|
36 |
+
if ( ! defined( 'FS_SDK__HAS_CURL' ) ) {
|
37 |
+
if ( FS_SDK__SIMULATE_NO_CURL ) {
|
38 |
+
define( 'FS_SDK__HAS_CURL', false );
|
39 |
+
} else {
|
40 |
+
$curl_required_methods = array(
|
41 |
+
'curl_version',
|
42 |
+
'curl_exec',
|
43 |
+
'curl_init',
|
44 |
+
'curl_close',
|
45 |
+
'curl_setopt',
|
46 |
+
'curl_setopt_array',
|
47 |
+
'curl_error',
|
48 |
+
);
|
49 |
+
|
50 |
+
$has_curl = true;
|
51 |
+
foreach ( $curl_required_methods as $m ) {
|
52 |
+
if ( ! function_exists( $m ) ) {
|
53 |
+
$has_curl = false;
|
54 |
+
break;
|
55 |
+
}
|
56 |
+
}
|
57 |
+
|
58 |
+
define( 'FS_SDK__HAS_CURL', $has_curl );
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
$curl_version = FS_SDK__HAS_CURL ?
|
63 |
+
curl_version() :
|
64 |
+
array( 'version' => '7.37' );
|
65 |
+
|
66 |
+
if ( ! defined( 'FS_API__PROTOCOL' ) ) {
|
67 |
+
define( 'FS_API__PROTOCOL', version_compare( $curl_version['version'], '7.37', '>=' ) ? 'https' : 'http' );
|
68 |
+
}
|
69 |
+
|
70 |
+
if ( ! defined( 'FS_API__LOGGER_ON' ) ) {
|
71 |
+
define( 'FS_API__LOGGER_ON', false );
|
72 |
+
}
|
73 |
+
|
74 |
+
if ( ! defined( 'FS_API__ADDRESS' ) ) {
|
75 |
+
define( 'FS_API__ADDRESS', '://api.freemius.com' );
|
76 |
+
}
|
77 |
+
if ( ! defined( 'FS_API__SANDBOX_ADDRESS' ) ) {
|
78 |
+
define( 'FS_API__SANDBOX_ADDRESS', '://sandbox-api.freemius.com' );
|
79 |
+
}
|
80 |
+
|
81 |
+
if ( class_exists( 'Freemius_Api_WordPress' ) ) {
|
82 |
+
return;
|
83 |
+
}
|
84 |
+
|
85 |
+
class Freemius_Api_WordPress extends Freemius_Api_Base {
|
86 |
+
private static $_logger = array();
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @param string $pScope 'app', 'developer', 'user' or 'install'.
|
90 |
+
* @param number $pID Element's id.
|
91 |
+
* @param string $pPublic Public key.
|
92 |
+
* @param string|bool $pSecret Element's secret key.
|
93 |
+
* @param bool $pSandbox Whether or not to run API in sandbox mode.
|
94 |
+
*/
|
95 |
+
public function __construct( $pScope, $pID, $pPublic, $pSecret = false, $pSandbox = false ) {
|
96 |
+
// If secret key not provided, use public key encryption.
|
97 |
+
if ( is_bool( $pSecret ) ) {
|
98 |
+
$pSecret = $pPublic;
|
99 |
+
}
|
100 |
+
|
101 |
+
parent::Init( $pScope, $pID, $pPublic, $pSecret, $pSandbox );
|
102 |
+
}
|
103 |
+
|
104 |
+
public static function GetUrl( $pCanonizedPath = '', $pIsSandbox = false ) {
|
105 |
+
$address = ( $pIsSandbox ? FS_API__SANDBOX_ADDRESS : FS_API__ADDRESS );
|
106 |
+
|
107 |
+
if ( ':' === $address[0] ) {
|
108 |
+
$address = self::$_protocol . $address;
|
109 |
+
}
|
110 |
+
|
111 |
+
return $address . $pCanonizedPath;
|
112 |
+
}
|
113 |
+
|
114 |
+
#----------------------------------------------------------------------------------
|
115 |
+
#region Servers Clock Diff
|
116 |
+
#----------------------------------------------------------------------------------
|
117 |
+
|
118 |
+
/**
|
119 |
+
* @var int Clock diff in seconds between current server to API server.
|
120 |
+
*/
|
121 |
+
private static $_clock_diff = 0;
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Set clock diff for all API calls.
|
125 |
+
*
|
126 |
+
* @since 1.0.3
|
127 |
+
*
|
128 |
+
* @param $pSeconds
|
129 |
+
*/
|
130 |
+
public static function SetClockDiff( $pSeconds ) {
|
131 |
+
self::$_clock_diff = $pSeconds;
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Find clock diff between current server to API server.
|
136 |
+
*
|
137 |
+
* @since 1.0.2
|
138 |
+
* @return int Clock diff in seconds.
|
139 |
+
*/
|
140 |
+
public static function FindClockDiff() {
|
141 |
+
$time = time();
|
142 |
+
$pong = self::Ping();
|
143 |
+
|
144 |
+
return ( $time - strtotime( $pong->timestamp ) );
|
145 |
+
}
|
146 |
+
|
147 |
+
#endregion
|
148 |
+
|
149 |
+
/**
|
150 |
+
* @var string http or https
|
151 |
+
*/
|
152 |
+
private static $_protocol = FS_API__PROTOCOL;
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Set API connection protocol.
|
156 |
+
*
|
157 |
+
* @since 1.0.4
|
158 |
+
*/
|
159 |
+
public static function SetHttp() {
|
160 |
+
self::$_protocol = 'http';
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* @since 1.0.4
|
165 |
+
*
|
166 |
+
* @return bool
|
167 |
+
*/
|
168 |
+
public static function IsHttps() {
|
169 |
+
return ( 'https' === self::$_protocol );
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Sign request with the following HTTP headers:
|
174 |
+
* Content-MD5: MD5(HTTP Request body)
|
175 |
+
* Date: Current date (i.e Sat, 14 Feb 2016 20:24:46 +0000)
|
176 |
+
* Authorization: FS {scope_entity_id}:{scope_entity_public_key}:base64encode(sha256(string_to_sign,
|
177 |
+
* {scope_entity_secret_key}))
|
178 |
+
*
|
179 |
+
* @param string $pResourceUrl
|
180 |
+
* @param array $pWPRemoteArgs
|
181 |
+
*
|
182 |
+
* @return array
|
183 |
+
*/
|
184 |
+
function SignRequest( $pResourceUrl, $pWPRemoteArgs ) {
|
185 |
+
$auth = $this->GenerateAuthorizationParams(
|
186 |
+
$pResourceUrl,
|
187 |
+
$pWPRemoteArgs['method'],
|
188 |
+
! empty( $pWPRemoteArgs['body'] ) ? $pWPRemoteArgs['body'] : ''
|
189 |
+
);
|
190 |
+
|
191 |
+
$pWPRemoteArgs['headers']['Date'] = $auth['date'];
|
192 |
+
$pWPRemoteArgs['headers']['Authorization'] = $auth['authorization'];
|
193 |
+
|
194 |
+
if ( ! empty( $auth['content_md5'] ) ) {
|
195 |
+
$pWPRemoteArgs['headers']['Content-MD5'] = $auth['content_md5'];
|
196 |
+
}
|
197 |
+
|
198 |
+
return $pWPRemoteArgs;
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Generate Authorization request headers:
|
203 |
+
*
|
204 |
+
* Content-MD5: MD5(HTTP Request body)
|
205 |
+
* Date: Current date (i.e Sat, 14 Feb 2016 20:24:46 +0000)
|
206 |
+
* Authorization: FS {scope_entity_id}:{scope_entity_public_key}:base64encode(sha256(string_to_sign,
|
207 |
+
* {scope_entity_secret_key}))
|
208 |
+
*
|
209 |
+
* @author Vova Feldman
|
210 |
+
*
|
211 |
+
* @param string $pResourceUrl
|
212 |
+
* @param string $pMethod
|
213 |
+
* @param string $pPostParams
|
214 |
+
*
|
215 |
+
* @return array
|
216 |
+
* @throws Freemius_Exception
|
217 |
+
*/
|
218 |
+
function GenerateAuthorizationParams(
|
219 |
+
$pResourceUrl,
|
220 |
+
$pMethod = 'GET',
|
221 |
+
$pPostParams = ''
|
222 |
+
) {
|
223 |
+
$pMethod = strtoupper( $pMethod );
|
224 |
+
|
225 |
+
$eol = "\n";
|
226 |
+
$content_md5 = '';
|
227 |
+
$content_type = '';
|
228 |
+
$now = ( time() - self::$_clock_diff );
|
229 |
+
$date = date( 'r', $now );
|
230 |
+
|
231 |
+
if ( in_array( $pMethod, array( 'POST', 'PUT' ) ) && ! empty( $pPostParams ) ) {
|
232 |
+
$content_md5 = md5( $pPostParams );
|
233 |
+
$content_type = 'application/json';
|
234 |
+
}
|
235 |
+
|
236 |
+
$string_to_sign = implode( $eol, array(
|
237 |
+
$pMethod,
|
238 |
+
$content_md5,
|
239 |
+
$content_type,
|
240 |
+
$date,
|
241 |
+
$pResourceUrl
|
242 |
+
) );
|
243 |
+
|
244 |
+
// If secret and public keys are identical, it means that
|
245 |
+
// the signature uses public key hash encoding.
|
246 |
+
$auth_type = ( $this->_secret !== $this->_public ) ? 'FS' : 'FSP';
|
247 |
+
|
248 |
+
$auth = array(
|
249 |
+
'date' => $date,
|
250 |
+
'authorization' => $auth_type . ' ' . $this->_id . ':' .
|
251 |
+
$this->_public . ':' .
|
252 |
+
self::Base64UrlEncode( hash_hmac(
|
253 |
+
'sha256', $string_to_sign, $this->_secret
|
254 |
+
) )
|
255 |
+
);
|
256 |
+
|
257 |
+
if ( ! empty( $content_md5 ) ) {
|
258 |
+
$auth['content_md5'] = $content_md5;
|
259 |
+
}
|
260 |
+
|
261 |
+
return $auth;
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Get API request URL signed via query string.
|
266 |
+
*
|
267 |
+
* @since 1.2.3 Stopped using http_build_query(). Instead, use urlencode(). In some environments the encoding of http_build_query() can generate a URL that once used with a redirect, the `&` querystring separator is escaped to `&` which breaks the URL (Added by @svovaf).
|
268 |
+
*
|
269 |
+
* @param string $pPath
|
270 |
+
*
|
271 |
+
* @throws Freemius_Exception
|
272 |
+
*
|
273 |
+
* @return string
|
274 |
+
*/
|
275 |
+
function GetSignedUrl( $pPath ) {
|
276 |
+
$resource = explode( '?', $this->CanonizePath( $pPath ) );
|
277 |
+
$pResourceUrl = $resource[0];
|
278 |
+
|
279 |
+
$auth = $this->GenerateAuthorizationParams( $pResourceUrl );
|
280 |
+
|
281 |
+
return Freemius_Api_WordPress::GetUrl(
|
282 |
+
$pResourceUrl . '?' .
|
283 |
+
( 1 < count( $resource ) && ! empty( $resource[1] ) ? $resource[1] . '&' : '' ) .
|
284 |
+
'authorization=' . urlencode( $auth['authorization'] ) .
|
285 |
+
'&auth_date=' . urlencode( $auth['date'] )
|
286 |
+
, $this->_isSandbox );
|
287 |
+
}
|
288 |
+
|
289 |
+
/**
|
290 |
+
* @author Vova Feldman
|
291 |
+
*
|
292 |
+
* @param string $pUrl
|
293 |
+
* @param array $pWPRemoteArgs
|
294 |
+
*
|
295 |
+
* @return mixed
|
296 |
+
*/
|
297 |
+
private static function ExecuteRequest( $pUrl, &$pWPRemoteArgs ) {
|
298 |
+
$start = microtime( true );
|
299 |
+
|
300 |
+
$response = wp_remote_request( $pUrl, $pWPRemoteArgs );
|
301 |
+
|
302 |
+
if ( FS_API__LOGGER_ON ) {
|
303 |
+
$end = microtime( true );
|
304 |
+
|
305 |
+
$has_body = ( isset( $pWPRemoteArgs['body'] ) && ! empty( $pWPRemoteArgs['body'] ) );
|
306 |
+
$is_http_error = is_wp_error( $response );
|
307 |
+
|
308 |
+
self::$_logger[] = array(
|
309 |
+
'id' => count( self::$_logger ),
|
310 |
+
'start' => $start,
|
311 |
+
'end' => $end,
|
312 |
+
'total' => ( $end - $start ),
|
313 |
+
'method' => $pWPRemoteArgs['method'],
|
314 |
+
'path' => $pUrl,
|
315 |
+
'body' => $has_body ? $pWPRemoteArgs['body'] : null,
|
316 |
+
'result' => ! $is_http_error ?
|
317 |
+
$response['body'] :
|
318 |
+
json_encode( $response->get_error_messages() ),
|
319 |
+
'code' => ! $is_http_error ? $response['response']['code'] : null,
|
320 |
+
'backtrace' => debug_backtrace(),
|
321 |
+
);
|
322 |
+
}
|
323 |
+
|
324 |
+
return $response;
|
325 |
+
}
|
326 |
+
|
327 |
+
/**
|
328 |
+
* @return array
|
329 |
+
*/
|
330 |
+
static function GetLogger() {
|
331 |
+
return self::$_logger;
|
332 |
+
}
|
333 |
+
|
334 |
+
/**
|
335 |
+
* @param string $pCanonizedPath
|
336 |
+
* @param string $pMethod
|
337 |
+
* @param array $pParams
|
338 |
+
* @param null|array $pWPRemoteArgs
|
339 |
+
* @param bool $pIsSandbox
|
340 |
+
* @param null|callable $pBeforeExecutionFunction
|
341 |
+
*
|
342 |
+
* @return object[]|object|null
|
343 |
+
*
|
344 |
+
* @throws \Freemius_Exception
|
345 |
+
*/
|
346 |
+
private static function MakeStaticRequest(
|
347 |
+
$pCanonizedPath,
|
348 |
+
$pMethod = 'GET',
|
349 |
+
$pParams = array(),
|
350 |
+
$pWPRemoteArgs = null,
|
351 |
+
$pIsSandbox = false,
|
352 |
+
$pBeforeExecutionFunction = null
|
353 |
+
) {
|
354 |
+
// Connectivity errors simulation.
|
355 |
+
if ( FS_SDK__SIMULATE_NO_API_CONNECTIVITY_CLOUDFLARE ) {
|
356 |
+
self::ThrowCloudFlareDDoSException();
|
357 |
+
} else if ( FS_SDK__SIMULATE_NO_API_CONNECTIVITY_SQUID_ACL ) {
|
358 |
+
self::ThrowSquidAclException();
|
359 |
+
}
|
360 |
+
|
361 |
+
if ( empty( $pWPRemoteArgs ) ) {
|
362 |
+
$user_agent = 'Freemius/WordPress-SDK/' . Freemius_Api_Base::VERSION . '; ' .
|
363 |
+
home_url();
|
364 |
+
|
365 |
+
$pWPRemoteArgs = array(
|
366 |
+
'method' => strtoupper( $pMethod ),
|
367 |
+
'connect_timeout' => 10,
|
368 |
+
'timeout' => 60,
|
369 |
+
'follow_redirects' => true,
|
370 |
+
'redirection' => 5,
|
371 |
+
'user-agent' => $user_agent,
|
372 |
+
'blocking' => true,
|
373 |
+
);
|
374 |
+
}
|
375 |
+
|
376 |
+
if ( ! isset( $pWPRemoteArgs['headers'] ) ||
|
377 |
+
! is_array( $pWPRemoteArgs['headers'] )
|
378 |
+
) {
|
379 |
+
$pWPRemoteArgs['headers'] = array();
|
380 |
+
}
|
381 |
+
|
382 |
+
if ( in_array( $pMethod, array( 'POST', 'PUT' ) ) ) {
|
383 |
+
if ( is_array( $pParams ) && 0 < count( $pParams ) ) {
|
384 |
+
$pWPRemoteArgs['headers']['Content-type'] = 'application/json';
|
385 |
+
$pWPRemoteArgs['body'] = json_encode( $pParams );
|
386 |
+
}
|
387 |
+
}
|
388 |
+
|
389 |
+
$request_url = self::GetUrl( $pCanonizedPath, $pIsSandbox );
|
390 |
+
|
391 |
+
$resource = explode( '?', $pCanonizedPath );
|
392 |
+
|
393 |
+
if ( FS_SDK__HAS_CURL ) {
|
394 |
+
// Disable the 'Expect: 100-continue' behaviour. This causes cURL to wait
|
395 |
+
// for 2 seconds if the server does not support this header.
|
396 |
+
$pWPRemoteArgs['headers']['Expect'] = '';
|
397 |
+
}
|
398 |
+
|
399 |
+
if ( 'https' === substr( strtolower( $request_url ), 0, 5 ) ) {
|
400 |
+
$pWPRemoteArgs['sslverify'] = false;
|
401 |
+
}
|
402 |
+
|
403 |
+
if ( false !== $pBeforeExecutionFunction &&
|
404 |
+
is_callable( $pBeforeExecutionFunction )
|
405 |
+
) {
|
406 |
+
$pWPRemoteArgs = call_user_func( $pBeforeExecutionFunction, $resource[0], $pWPRemoteArgs );
|
407 |
+
}
|
408 |
+
|
409 |
+
$result = self::ExecuteRequest( $request_url, $pWPRemoteArgs );
|
410 |
+
|
411 |
+
if ( is_wp_error( $result ) ) {
|
412 |
+
/**
|
413 |
+
* @var WP_Error $result
|
414 |
+
*/
|
415 |
+
if ( self::IsCurlError( $result ) ) {
|
416 |
+
/**
|
417 |
+
* With dual stacked DNS responses, it's possible for a server to
|
418 |
+
* have IPv6 enabled but not have IPv6 connectivity. If this is
|
419 |
+
* the case, cURL will try IPv4 first and if that fails, then it will
|
420 |
+
* fall back to IPv6 and the error EHOSTUNREACH is returned by the
|
421 |
+
* operating system.
|
422 |
+
*/
|
423 |
+
$matches = array();
|
424 |
+
$regex = '/Failed to connect to ([^:].*): Network is unreachable/';
|
425 |
+
if ( preg_match( $regex, $result->get_error_message( 'http_request_failed' ), $matches ) ) {
|
426 |
+
/**
|
427 |
+
* Validate IP before calling `inet_pton()` to avoid PHP un-catchable warning.
|
428 |
+
* @author Vova Feldman (@svovaf)
|
429 |
+
*/
|
430 |
+
if ( filter_var( $matches[1], FILTER_VALIDATE_IP ) ) {
|
431 |
+
if ( strlen( inet_pton( $matches[1] ) ) === 16 ) {
|
432 |
+
// error_log('Invalid IPv6 configuration on server, Please disable or get native IPv6 on your server.');
|
433 |
+
// Hook to an action triggered just before cURL is executed to resolve the IP version to v4.
|
434 |
+
add_action( 'http_api_curl', 'Freemius_Api_WordPress::CurlResolveToIPv4', 10, 1 );
|
435 |
+
|
436 |
+
// Re-run request.
|
437 |
+
$result = self::ExecuteRequest( $request_url, $pWPRemoteArgs );
|
438 |
+
}
|
439 |
+
}
|
440 |
+
}
|
441 |
+
}
|
442 |
+
|
443 |
+
if ( is_wp_error( $result ) ) {
|
444 |
+
self::ThrowWPRemoteException( $result );
|
445 |
+
}
|
446 |
+
}
|
447 |
+
|
448 |
+
$response_body = $result['body'];
|
449 |
+
|
450 |
+
if ( empty( $response_body ) ) {
|
451 |
+
return null;
|
452 |
+
}
|
453 |
+
|
454 |
+
$decoded = json_decode( $response_body );
|
455 |
+
|
456 |
+
if ( is_null( $decoded ) ) {
|
457 |
+
if ( preg_match( '/Please turn JavaScript on/i', $response_body ) &&
|
458 |
+
preg_match( '/text\/javascript/', $response_body )
|
459 |
+
) {
|
460 |
+
self::ThrowCloudFlareDDoSException( $response_body );
|
461 |
+
} else if ( preg_match( '/Access control configuration prevents your request from being allowed at this time. Please contact your service provider if you feel this is incorrect./', $response_body ) &&
|
462 |
+
preg_match( '/squid/', $response_body )
|
463 |
+
) {
|
464 |
+
self::ThrowSquidAclException( $response_body );
|
465 |
+
} else {
|
466 |
+
$decoded = (object) array(
|
467 |
+
'error' => (object) array(
|
468 |
+
'type' => 'Unknown',
|
469 |
+
'message' => $response_body,
|
470 |
+
'code' => 'unknown',
|
471 |
+
'http' => 402
|
472 |
+
)
|
473 |
+
);
|
474 |
+
}
|
475 |
+
}
|
476 |
+
|
477 |
+
return $decoded;
|
478 |
+
}
|
479 |
+
|
480 |
+
|
481 |
+
/**
|
482 |
+
* Makes an HTTP request. This method can be overridden by subclasses if
|
483 |
+
* developers want to do fancier things or use something other than wp_remote_request()
|
484 |
+
* to make the request.
|
485 |
+
*
|
486 |
+
* @param string $pCanonizedPath The URL to make the request to
|
487 |
+
* @param string $pMethod HTTP method
|
488 |
+
* @param array $pParams The parameters to use for the POST body
|
489 |
+
* @param null|array $pWPRemoteArgs wp_remote_request options.
|
490 |
+
*
|
491 |
+
* @return object[]|object|null
|
492 |
+
*
|
493 |
+
* @throws Freemius_Exception
|
494 |
+
*/
|
495 |
+
public function MakeRequest(
|
496 |
+
$pCanonizedPath,
|
497 |
+
$pMethod = 'GET',
|
498 |
+
$pParams = array(),
|
499 |
+
$pWPRemoteArgs = null
|
500 |
+
) {
|
501 |
+
$resource = explode( '?', $pCanonizedPath );
|
502 |
+
|
503 |
+
// Only sign request if not ping.json connectivity test.
|
504 |
+
$sign_request = ( '/v1/ping.json' !== strtolower( substr( $resource[0], - strlen( '/v1/ping.json' ) ) ) );
|
505 |
+
|
506 |
+
return self::MakeStaticRequest(
|
507 |
+
$pCanonizedPath,
|
508 |
+
$pMethod,
|
509 |
+
$pParams,
|
510 |
+
$pWPRemoteArgs,
|
511 |
+
$this->_isSandbox,
|
512 |
+
$sign_request ? array( &$this, 'SignRequest' ) : null
|
513 |
+
);
|
514 |
+
}
|
515 |
+
|
516 |
+
/**
|
517 |
+
* Sets CURLOPT_IPRESOLVE to CURL_IPRESOLVE_V4 for cURL-Handle provided as parameter
|
518 |
+
*
|
519 |
+
* @param resource $handle A cURL handle returned by curl_init()
|
520 |
+
*
|
521 |
+
* @return resource $handle A cURL handle returned by curl_init() with CURLOPT_IPRESOLVE set to
|
522 |
+
* CURL_IPRESOLVE_V4
|
523 |
+
*
|
524 |
+
* @link https://gist.github.com/golderweb/3a2aaec2d56125cc004e
|
525 |
+
*/
|
526 |
+
static function CurlResolveToIPv4( $handle ) {
|
527 |
+
curl_setopt( $handle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
|
528 |
+
|
529 |
+
return $handle;
|
530 |
+
}
|
531 |
+
|
532 |
+
#----------------------------------------------------------------------------------
|
533 |
+
#region Connectivity Test
|
534 |
+
#----------------------------------------------------------------------------------
|
535 |
+
|
536 |
+
/**
|
537 |
+
* If successful connectivity to the API endpoint using ping.json endpoint.
|
538 |
+
*
|
539 |
+
* - OR -
|
540 |
+
*
|
541 |
+
* Validate if ping result object is valid.
|
542 |
+
*
|
543 |
+
* @param mixed $pPong
|
544 |
+
*
|
545 |
+
* @return bool
|
546 |
+
*/
|
547 |
+
public static function Test( $pPong = null ) {
|
548 |
+
$pong = is_null( $pPong ) ?
|
549 |
+
self::Ping() :
|
550 |
+
$pPong;
|
551 |
+
|
552 |
+
return (
|
553 |
+
is_object( $pong ) &&
|
554 |
+
isset( $pong->api ) &&
|
555 |
+
'pong' === $pong->api
|
556 |
+
);
|
557 |
+
}
|
558 |
+
|
559 |
+
/**
|
560 |
+
* Ping API to test connectivity.
|
561 |
+
*
|
562 |
+
* @return object
|
563 |
+
*/
|
564 |
+
public static function Ping() {
|
565 |
+
try {
|
566 |
+
$result = self::MakeStaticRequest( '/v' . FS_API__VERSION . '/ping.json' );
|
567 |
+
} catch ( Freemius_Exception $e ) {
|
568 |
+
// Map to error object.
|
569 |
+
$result = (object) $e->getResult();
|
570 |
+
} catch ( Exception $e ) {
|
571 |
+
// Map to error object.
|
572 |
+
$result = (object) array(
|
573 |
+
'error' => array(
|
574 |
+
'type' => 'Unknown',
|
575 |
+
'message' => $e->getMessage() . ' (' . $e->getFile() . ': ' . $e->getLine() . ')',
|
576 |
+
'code' => 'unknown',
|
577 |
+
'http' => 402
|
578 |
+
)
|
579 |
+
);
|
580 |
+
}
|
581 |
+
|
582 |
+
return $result;
|
583 |
+
}
|
584 |
+
|
585 |
+
#endregion
|
586 |
+
|
587 |
+
#----------------------------------------------------------------------------------
|
588 |
+
#region Connectivity Exceptions
|
589 |
+
#----------------------------------------------------------------------------------
|
590 |
+
|
591 |
+
/**
|
592 |
+
* @param \WP_Error $pError
|
593 |
+
*
|
594 |
+
* @return bool
|
595 |
+
*/
|
596 |
+
private static function IsCurlError( WP_Error $pError ) {
|
597 |
+
$message = $pError->get_error_message( 'http_request_failed' );
|
598 |
+
|
599 |
+
return ( 0 === strpos( $message, 'cURL' ) );
|
600 |
+
}
|
601 |
+
|
602 |
+
/**
|
603 |
+
* @param WP_Error $pError
|
604 |
+
*
|
605 |
+
* @throws Freemius_Exception
|
606 |
+
*/
|
607 |
+
private static function ThrowWPRemoteException( WP_Error $pError ) {
|
608 |
+
if ( self::IsCurlError( $pError ) ) {
|
609 |
+
$message = $pError->get_error_message( 'http_request_failed' );
|
610 |
+
|
611 |
+
#region Check if there are any missing cURL methods.
|
612 |
+
|
613 |
+
$curl_required_methods = array(
|
614 |
+
'curl_version',
|
615 |
+
'curl_exec',
|
616 |
+
'curl_init',
|
617 |
+
'curl_close',
|
618 |
+
'curl_setopt',
|
619 |
+
'curl_setopt_array',
|
620 |
+
'curl_error',
|
621 |
+
);
|
622 |
+
|
623 |
+
// Find all missing methods.
|
624 |
+
$missing_methods = array();
|
625 |
+
foreach ( $curl_required_methods as $m ) {
|
626 |
+
if ( ! function_exists( $m ) ) {
|
627 |
+
$missing_methods[] = $m;
|
628 |
+
}
|
629 |
+
}
|
630 |
+
|
631 |
+
if ( ! empty( $missing_methods ) ) {
|
632 |
+
throw new Freemius_Exception( array(
|
633 |
+
'error' => (object) array(
|
634 |
+
'type' => 'cUrlMissing',
|
635 |
+
'message' => $message,
|
636 |
+
'code' => 'curl_missing',
|
637 |
+
'http' => 402
|
638 |
+
),
|
639 |
+
'missing_methods' => $missing_methods,
|
640 |
+
) );
|
641 |
+
}
|
642 |
+
|
643 |
+
#endregion
|
644 |
+
|
645 |
+
// cURL error - "cURL error {{errno}}: {{error}}".
|
646 |
+
$parts = explode( ':', substr( $message, strlen( 'cURL error ' ) ), 2 );
|
647 |
+
|
648 |
+
$code = ( 0 < count( $parts ) ) ? $parts[0] : 'http_request_failed';
|
649 |
+
$message = ( 1 < count( $parts ) ) ? $parts[1] : $message;
|
650 |
+
|
651 |
+
$e = new Freemius_Exception( array(
|
652 |
+
'error' => array(
|
653 |
+
'code' => $code,
|
654 |
+
'message' => $message,
|
655 |
+
'type' => 'CurlException',
|
656 |
+
),
|
657 |
+
) );
|
658 |
+
} else {
|
659 |
+
$e = new Freemius_Exception( array(
|
660 |
+
'error' => array(
|
661 |
+
'code' => $pError->get_error_code(),
|
662 |
+
'message' => $pError->get_error_message(),
|
663 |
+
'type' => 'WPRemoteException',
|
664 |
+
),
|
665 |
+
) );
|
666 |
+
}
|
667 |
+
|
668 |
+
throw $e;
|
669 |
+
}
|
670 |
+
|
671 |
+
/**
|
672 |
+
* @param string $pResult
|
673 |
+
*
|
674 |
+
* @throws Freemius_Exception
|
675 |
+
*/
|
676 |
+
private static function ThrowCloudFlareDDoSException( $pResult = '' ) {
|
677 |
+
throw new Freemius_Exception( array(
|
678 |
+
'error' => (object) array(
|
679 |
+
'type' => 'CloudFlareDDoSProtection',
|
680 |
+
'message' => $pResult,
|
681 |
+
'code' => 'cloudflare_ddos_protection',
|
682 |
+
'http' => 402
|
683 |
+
)
|
684 |
+
) );
|
685 |
+
}
|
686 |
+
|
687 |
+
/**
|
688 |
+
* @param string $pResult
|
689 |
+
*
|
690 |
+
* @throws Freemius_Exception
|
691 |
+
*/
|
692 |
+
private static function ThrowSquidAclException( $pResult = '' ) {
|
693 |
+
throw new Freemius_Exception( array(
|
694 |
+
'error' => (object) array(
|
695 |
+
'type' => 'SquidCacheBlock',
|
696 |
+
'message' => $pResult,
|
697 |
+
'code' => 'squid_cache_block',
|
698 |
+
'http' => 402
|
699 |
+
)
|
700 |
+
) );
|
701 |
+
}
|
702 |
+
|
703 |
+
#endregion
|
704 |
+
}
|
libs/factory/freemius/includes/sdk/LICENSE.txt
ADDED
@@ -0,0 +1,340 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
GNU GENERAL PUBLIC LICENSE
|
2 |
+
Version 2, June 1991
|
3 |
+
|
4 |
+
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
|
5 |
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
6 |
+
Everyone is permitted to copy and distribute verbatim copies
|
7 |
+
of this license document, but changing it is not allowed.
|
8 |
+
|
9 |
+
Preamble
|
10 |
+
|
11 |
+
The licenses for most software are designed to take away your
|
12 |
+
freedom to share and change it. By contrast, the GNU General Public
|
13 |
+
License is intended to guarantee your freedom to share and change free
|
14 |
+
software--to make sure the software is free for all its users. This
|
15 |
+
General Public License applies to most of the Free Software
|
16 |
+
Foundation's software and to any other program whose authors commit to
|
17 |
+
using it. (Some other Free Software Foundation software is covered by
|
18 |
+
the GNU Lesser General Public License instead.) You can apply it to
|
19 |
+
your programs, too.
|
20 |
+
|
21 |
+
When we speak of free software, we are referring to freedom, not
|
22 |
+
price. Our General Public Licenses are designed to make sure that you
|
23 |
+
have the freedom to distribute copies of free software (and charge for
|
24 |
+
this service if you wish), that you receive source code or can get it
|
25 |
+
if you want it, that you can change the software or use pieces of it
|
26 |
+
in new free programs; and that you know you can do these things.
|
27 |
+
|
28 |
+
To protect your rights, we need to make restrictions that forbid
|
29 |
+
anyone to deny you these rights or to ask you to surrender the rights.
|
30 |
+
These restrictions translate to certain responsibilities for you if you
|
31 |
+
distribute copies of the software, or if you modify it.
|
32 |
+
|
33 |
+
For example, if you distribute copies of such a program, whether
|
34 |
+
gratis or for a fee, you must give the recipients all the rights that
|
35 |
+
you have. You must make sure that they, too, receive or can get the
|
36 |
+
source code. And you must show them these terms so they know their
|
37 |
+
rights.
|
38 |
+
|
39 |
+
We protect your rights with two steps: (1) copyright the software, and
|
40 |
+
(2) offer you this license which gives you legal permission to copy,
|
41 |
+
distribute and/or modify the software.
|
42 |
+
|
43 |
+
Also, for each author's protection and ours, we want to make certain
|
44 |
+
that everyone understands that there is no warranty for this free
|
45 |
+
software. If the software is modified by someone else and passed on, we
|
46 |
+
want its recipients to know that what they have is not the original, so
|
47 |
+
that any problems introduced by others will not reflect on the original
|
48 |
+
authors' reputations.
|
49 |
+
|
50 |
+
Finally, any free program is threatened constantly by software
|
51 |
+
patents. We wish to avoid the danger that redistributors of a free
|
52 |
+
program will individually obtain patent licenses, in effect making the
|
53 |
+
program proprietary. To prevent this, we have made it clear that any
|
54 |
+
patent must be licensed for everyone's free use or not licensed at all.
|
55 |
+
|
56 |
+
The precise terms and conditions for copying, distribution and
|
57 |
+
modification follow.
|
58 |
+
|
59 |
+
GNU GENERAL PUBLIC LICENSE
|
60 |
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
61 |
+
|
62 |
+
0. This License applies to any program or other work which contains
|
63 |
+
a notice placed by the copyright holder saying it may be distributed
|
64 |
+
under the terms of this General Public License. The "Program", below,
|
65 |
+
refers to any such program or work, and a "work based on the Program"
|
66 |
+
means either the Program or any derivative work under copyright law:
|
67 |
+
that is to say, a work containing the Program or a portion of it,
|
68 |
+
either verbatim or with modifications and/or translated into another
|
69 |
+
language. (Hereinafter, translation is included without limitation in
|
70 |
+
the term "modification".) Each licensee is addressed as "you".
|
71 |
+
|
72 |
+
Activities other than copying, distribution and modification are not
|
73 |
+
covered by this License; they are outside its scope. The act of
|
74 |
+
running the Program is not restricted, and the output from the Program
|
75 |
+
is covered only if its contents constitute a work based on the
|
76 |
+
Program (independent of having been made by running the Program).
|
77 |
+
Whether that is true depends on what the Program does.
|
78 |
+
|
79 |
+
1. You may copy and distribute verbatim copies of the Program's
|
80 |
+
source code as you receive it, in any medium, provided that you
|
81 |
+
conspicuously and appropriately publish on each copy an appropriate
|
82 |
+
copyright notice and disclaimer of warranty; keep intact all the
|
83 |
+
notices that refer to this License and to the absence of any warranty;
|
84 |
+
and give any other recipients of the Program a copy of this License
|
85 |
+
along with the Program.
|
86 |
+
|
87 |
+
You may charge a fee for the physical act of transferring a copy, and
|
88 |
+
you may at your option offer warranty protection in exchange for a fee.
|
89 |
+
|
90 |
+
2. You may modify your copy or copies of the Program or any portion
|
91 |
+
of it, thus forming a work based on the Program, and copy and
|
92 |
+
distribute such modifications or work under the terms of Section 1
|
93 |
+
above, provided that you also meet all of these conditions:
|
94 |
+
|
95 |
+
a) You must cause the modified files to carry prominent notices
|
96 |
+
stating that you changed the files and the date of any change.
|
97 |
+
|
98 |
+
b) You must cause any work that you distribute or publish, that in
|
99 |
+
whole or in part contains or is derived from the Program or any
|
100 |
+
part thereof, to be licensed as a whole at no charge to all third
|
101 |
+
parties under the terms of this License.
|
102 |
+
|
103 |
+
c) If the modified program normally reads commands interactively
|
104 |
+
when run, you must cause it, when started running for such
|
105 |
+
interactive use in the most ordinary way, to print or display an
|
106 |
+
announcement including an appropriate copyright notice and a
|
107 |
+
notice that there is no warranty (or else, saying that you provide
|
108 |
+
a warranty) and that users may redistribute the program under
|
109 |
+
these conditions, and telling the user how to view a copy of this
|
110 |
+
License. (Exception: if the Program itself is interactive but
|
111 |
+
does not normally print such an announcement, your work based on
|
112 |
+
the Program is not required to print an announcement.)
|
113 |
+
|
114 |
+
These requirements apply to the modified work as a whole. If
|
115 |
+
identifiable sections of that work are not derived from the Program,
|
116 |
+
and can be reasonably considered independent and separate works in
|
117 |
+
themselves, then this License, and its terms, do not apply to those
|
118 |
+
sections when you distribute them as separate works. But when you
|
119 |
+
distribute the same sections as part of a whole which is a work based
|
120 |
+
on the Program, the distribution of the whole must be on the terms of
|
121 |
+
this License, whose permissions for other licensees extend to the
|
122 |
+
entire whole, and thus to each and every part regardless of who wrote it.
|
123 |
+
|
124 |
+
Thus, it is not the intent of this section to claim rights or contest
|
125 |
+
your rights to work written entirely by you; rather, the intent is to
|
126 |
+
exercise the right to control the distribution of derivative or
|
127 |
+
collective works based on the Program.
|
128 |
+
|
129 |
+
In addition, mere aggregation of another work not based on the Program
|
130 |
+
with the Program (or with a work based on the Program) on a volume of
|
131 |
+
a storage or distribution medium does not bring the other work under
|
132 |
+
the scope of this License.
|
133 |
+
|
134 |
+
3. You may copy and distribute the Program (or a work based on it,
|
135 |
+
under Section 2) in object code or executable form under the terms of
|
136 |
+
Sections 1 and 2 above provided that you also do one of the following:
|
137 |
+
|
138 |
+
a) Accompany it with the complete corresponding machine-readable
|
139 |
+
source code, which must be distributed under the terms of Sections
|
140 |
+
1 and 2 above on a medium customarily used for software interchange; or,
|
141 |
+
|
142 |
+
b) Accompany it with a written offer, valid for at least three
|
143 |
+
years, to give any third party, for a charge no more than your
|
144 |
+
cost of physically performing source distribution, a complete
|
145 |
+
machine-readable copy of the corresponding source code, to be
|
146 |
+
distributed under the terms of Sections 1 and 2 above on a medium
|
147 |
+
customarily used for software interchange; or,
|
148 |
+
|
149 |
+
c) Accompany it with the information you received as to the offer
|
150 |
+
to distribute corresponding source code. (This alternative is
|
151 |
+
allowed only for noncommercial distribution and only if you
|
152 |
+
received the program in object code or executable form with such
|
153 |
+
an offer, in accord with Subsection b above.)
|
154 |
+
|
155 |
+
The source code for a work means the preferred form of the work for
|
156 |
+
making modifications to it. For an executable work, complete source
|
157 |
+
code means all the source code for all modules it contains, plus any
|
158 |
+
associated interface definition files, plus the scripts used to
|
159 |
+
control compilation and installation of the executable. However, as a
|
160 |
+
special exception, the source code distributed need not include
|
161 |
+
anything that is normally distributed (in either source or binary
|
162 |
+
form) with the major components (compiler, kernel, and so on) of the
|
163 |
+
operating system on which the executable runs, unless that component
|
164 |
+
itself accompanies the executable.
|
165 |
+
|
166 |
+
If distribution of executable or object code is made by offering
|
167 |
+
access to copy from a designated place, then offering equivalent
|
168 |
+
access to copy the source code from the same place counts as
|
169 |
+
distribution of the source code, even though third parties are not
|
170 |
+
compelled to copy the source along with the object code.
|
171 |
+
|
172 |
+
4. You may not copy, modify, sublicense, or distribute the Program
|
173 |
+
except as expressly provided under this License. Any attempt
|
174 |
+
otherwise to copy, modify, sublicense or distribute the Program is
|
175 |
+
void, and will automatically terminate your rights under this License.
|
176 |
+
However, parties who have received copies, or rights, from you under
|
177 |
+
this License will not have their licenses terminated so long as such
|
178 |
+
parties remain in full compliance.
|
179 |
+
|
180 |
+
5. You are not required to accept this License, since you have not
|
181 |
+
signed it. However, nothing else grants you permission to modify or
|
182 |
+
distribute the Program or its derivative works. These actions are
|
183 |
+
prohibited by law if you do not accept this License. Therefore, by
|
184 |
+
modifying or distributing the Program (or any work based on the
|
185 |
+
Program), you indicate your acceptance of this License to do so, and
|
186 |
+
all its terms and conditions for copying, distributing or modifying
|
187 |
+
the Program or works based on it.
|
188 |
+
|
189 |
+
6. Each time you redistribute the Program (or any work based on the
|
190 |
+
Program), the recipient automatically receives a license from the
|
191 |
+
original licensor to copy, distribute or modify the Program subject to
|
192 |
+
these terms and conditions. You may not impose any further
|
193 |
+
restrictions on the recipients' exercise of the rights granted herein.
|
194 |
+
You are not responsible for enforcing compliance by third parties to
|
195 |
+
this License.
|
196 |
+
|
197 |
+
7. If, as a consequence of a court judgment or allegation of patent
|
198 |
+
infringement or for any other reason (not limited to patent issues),
|
199 |
+
conditions are imposed on you (whether by court order, agreement or
|
200 |
+
otherwise) that contradict the conditions of this License, they do not
|
201 |
+
excuse you from the conditions of this License. If you cannot
|
202 |
+
distribute so as to satisfy simultaneously your obligations under this
|
203 |
+
License and any other pertinent obligations, then as a consequence you
|
204 |
+
may not distribute the Program at all. For example, if a patent
|
205 |
+
license would not permit royalty-free redistribution of the Program by
|
206 |
+
all those who receive copies directly or indirectly through you, then
|
207 |
+
the only way you could satisfy both it and this License would be to
|
208 |
+
refrain entirely from distribution of the Program.
|
209 |
+
|
210 |
+
If any portion of this section is held invalid or unenforceable under
|
211 |
+
any particular circumstance, the balance of the section is intended to
|
212 |
+
apply and the section as a whole is intended to apply in other
|
213 |
+
circumstances.
|
214 |
+
|
215 |
+
It is not the purpose of this section to induce you to infringe any
|
216 |
+
patents or other property right claims or to contest validity of any
|
217 |
+
such claims; this section has the sole purpose of protecting the
|
218 |
+
integrity of the free software distribution system, which is
|
219 |
+
implemented by public license practices. Many people have made
|
220 |
+
generous contributions to the wide range of software distributed
|
221 |
+
through that system in reliance on consistent application of that
|
222 |
+
system; it is up to the author/donor to decide if he or she is willing
|
223 |
+
to distribute software through any other system and a licensee cannot
|
224 |
+
impose that choice.
|
225 |
+
|
226 |
+
This section is intended to make thoroughly clear what is believed to
|
227 |
+
be a consequence of the rest of this License.
|
228 |
+
|
229 |
+
8. If the distribution and/or use of the Program is restricted in
|
230 |
+
certain countries either by patents or by copyrighted interfaces, the
|
231 |
+
original copyright holder who places the Program under this License
|
232 |
+
may add an explicit geographical distribution limitation excluding
|
233 |
+
those countries, so that distribution is permitted only in or among
|
234 |
+
countries not thus excluded. In such case, this License incorporates
|
235 |
+
the limitation as if written in the body of this License.
|
236 |
+
|
237 |
+
9. The Free Software Foundation may publish revised and/or new versions
|
238 |
+
of the General Public License from time to time. Such new versions will
|
239 |
+
be similar in spirit to the present version, but may differ in detail to
|
240 |
+
address new problems or concerns.
|
241 |
+
|
242 |
+
Each version is given a distinguishing version number. If the Program
|
243 |
+
specifies a version number of this License which applies to it and "any
|
244 |
+
later version", you have the option of following the terms and conditions
|
245 |
+
either of that version or of any later version published by the Free
|
246 |
+
Software Foundation. If the Program does not specify a version number of
|
247 |
+
this License, you may choose any version ever published by the Free Software
|
248 |
+
Foundation.
|
249 |
+
|
250 |
+
10. If you wish to incorporate parts of the Program into other free
|
251 |
+
programs whose distribution conditions are different, write to the author
|
252 |
+
to ask for permission. For software which is copyrighted by the Free
|
253 |
+
Software Foundation, write to the Free Software Foundation; we sometimes
|
254 |
+
make exceptions for this. Our decision will be guided by the two goals
|
255 |
+
of preserving the free status of all derivatives of our free software and
|
256 |
+
of promoting the sharing and reuse of software generally.
|
257 |
+
|
258 |
+
NO WARRANTY
|
259 |
+
|
260 |
+
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
261 |
+
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
262 |
+
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
263 |
+
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
264 |
+
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
265 |
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
266 |
+
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
267 |
+
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
268 |
+
REPAIR OR CORRECTION.
|
269 |
+
|
270 |
+
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
271 |
+
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
272 |
+
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
273 |
+
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
274 |
+
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
275 |
+
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
276 |
+
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
277 |
+
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
278 |
+
POSSIBILITY OF SUCH DAMAGES.
|
279 |
+
|
280 |
+
END OF TERMS AND CONDITIONS
|
281 |
+
|
282 |
+
How to Apply These Terms to Your New Programs
|
283 |
+
|
284 |
+
If you develop a new program, and you want it to be of the greatest
|
285 |
+
possible use to the public, the best way to achieve this is to make it
|
286 |
+
free software which everyone can redistribute and change under these terms.
|
287 |
+
|
288 |
+
To do so, attach the following notices to the program. It is safest
|
289 |
+
to attach them to the start of each source file to most effectively
|
290 |
+
convey the exclusion of warranty; and each file should have at least
|
291 |
+
the "copyright" line and a pointer to where the full notice is found.
|
292 |
+
|
293 |
+
{description}
|
294 |
+
Copyright (C) {year} {fullname}
|
295 |
+
|
296 |
+
This program is free software; you can redistribute it and/or modify
|
297 |
+
it under the terms of the GNU General Public License as published by
|
298 |
+
the Free Software Foundation; either version 2 of the License, or
|
299 |
+
(at your option) any later version.
|
300 |
+
|
301 |
+
This program is distributed in the hope that it will be useful,
|
302 |
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
303 |
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
304 |
+
GNU General Public License for more details.
|
305 |
+
|
306 |
+
You should have received a copy of the GNU General Public License along
|
307 |
+
with this program; if not, write to the Free Software Foundation, Inc.,
|
308 |
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
309 |
+
|
310 |
+
Also add information on how to contact you by electronic and paper mail.
|
311 |
+
|
312 |
+
If the program is interactive, make it output a short notice like this
|
313 |
+
when it starts in an interactive mode:
|
314 |
+
|
315 |
+
Gnomovision version 69, Copyright (C) year name of author
|
316 |
+
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
317 |
+
This is free software, and you are welcome to redistribute it
|
318 |
+
under certain conditions; type `show c' for details.
|
319 |
+
|
320 |
+
The hypothetical commands `show w' and `show c' should show the appropriate
|
321 |
+
parts of the General Public License. Of course, the commands you use may
|
322 |
+
be called something other than `show w' and `show c'; they could even be
|
323 |
+
mouse-clicks or menu items--whatever suits your program.
|
324 |
+
|
325 |
+
You should also get your employer (if you work as a programmer) or your
|
326 |
+
school, if any, to sign a "copyright disclaimer" for the program, if
|
327 |
+
necessary. Here is a sample; alter the names:
|
328 |
+
|
329 |
+
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
330 |
+
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
331 |
+
|
332 |
+
{signature of Ty Coon}, 1 April 1989
|
333 |
+
Ty Coon, President of Vice
|
334 |
+
|
335 |
+
This General Public License does not permit incorporating your program into
|
336 |
+
proprietary programs. If your program is a subroutine library, you may
|
337 |
+
consider it more useful to permit linking proprietary applications with the
|
338 |
+
library. If this is what you want to do, use the GNU Lesser General
|
339 |
+
Public License instead of this License.
|
340 |
+
|
libs/factory/freemius/includes/sdk/index.php
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Silence is golden.
|
3 |
+
// Hide file structure from users on unprotected servers.
|
libs/factory/freemius/includes/updates/class-freemius-repository.php
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WBCR\Factory_Freemius_117\Updates;
|
4 |
+
|
5 |
+
// Exit if accessed directly
|
6 |
+
use Exception;
|
7 |
+
use Wbcr_Factory429_Plugin;
|
8 |
+
use WBCR\Factory_429\Updates\Repository;
|
9 |
+
|
10 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
11 |
+
exit;
|
12 |
+
}
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @author Webcraftic <wordpress.webraftic@gmail.com>, Alex Kovalev <alex.kovalevv@gmail.com>
|
16 |
+
* @link https://webcraftic.com
|
17 |
+
* @copyright (c) 2018 Webraftic Ltd
|
18 |
+
* @version 1.0
|
19 |
+
*/
|
20 |
+
class Freemius_Repository extends Repository {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var \WBCR\Factory_Freemius_117\Premium\Provider
|
24 |
+
*/
|
25 |
+
private $premium;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Freemius constructor.
|
29 |
+
* @since 4.0.0
|
30 |
+
*
|
31 |
+
* @param Wbcr_Factory429_Plugin $plugin
|
32 |
+
*
|
33 |
+
* @throws Exception
|
34 |
+
*/
|
35 |
+
public function __construct( Wbcr_Factory429_Plugin $plugin ) {
|
36 |
+
$this->plugin = $plugin;
|
37 |
+
$this->premium = $this->plugin->premium;
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @throws Exception
|
42 |
+
*/
|
43 |
+
public function init() {
|
44 |
+
if ( ! $this->premium instanceof \WBCR\Factory_Freemius_117\Premium\Provider ) {
|
45 |
+
throw new Exception( "This repository type requires Freemius premium provider." );
|
46 |
+
}
|
47 |
+
|
48 |
+
if ( ! $this->premium->is_activate() ) {
|
49 |
+
throw new Exception( "Only premium plugins can check or receive updates via Freemius repository." );
|
50 |
+
}
|
51 |
+
|
52 |
+
$this->initialized = true;
|
53 |
+
|
54 |
+
add_filter( 'http_request_host_is_external', array(
|
55 |
+
$this,
|
56 |
+
'http_request_host_is_external_filter'
|
57 |
+
), 10, 3 );
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* @return bool
|
62 |
+
*/
|
63 |
+
public function need_check_updates() {
|
64 |
+
return true;
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* @return bool|mixed
|
69 |
+
*/
|
70 |
+
public function is_support_premium() {
|
71 |
+
return true;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* @return string|null
|
76 |
+
* @throws Exception
|
77 |
+
*/
|
78 |
+
public function get_download_url() {
|
79 |
+
return $this->premium->get_package_download_url();
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* @return string|null
|
84 |
+
* @throws Exception
|
85 |
+
*/
|
86 |
+
public function get_last_version() {
|
87 |
+
try {
|
88 |
+
$last_package = $this->premium->get_downloadable_package_info();
|
89 |
+
|
90 |
+
if ( empty( $last_package->version ) ) {
|
91 |
+
return null;
|
92 |
+
}
|
93 |
+
} catch( Exception $e ) {
|
94 |
+
if ( defined( 'FACTORY_UPDATES_DEBUG' ) && FACTORY_UPDATES_DEBUG ) {
|
95 |
+
throw new Exception( $e->getMessage(), $e->getCode() );
|
96 |
+
}
|
97 |
+
|
98 |
+
return null;
|
99 |
+
}
|
100 |
+
|
101 |
+
return $last_package->version;
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Since WP version 3.6, a new security feature was added that denies access to repository with a local ip.
|
106 |
+
* During development mode we want to be able updating plugin versions via our localhost repository. This
|
107 |
+
* filter white-list all domains including "api.freemius".
|
108 |
+
*
|
109 |
+
* @link http://www.emanueletessore.com/wordpress-download-failed-valid-url-provided/
|
110 |
+
*
|
111 |
+
* @author Vova Feldman (@svovaf)
|
112 |
+
* @since 1.0.4
|
113 |
+
*
|
114 |
+
* @param bool $allow
|
115 |
+
* @param string $host
|
116 |
+
* @param string $url
|
117 |
+
*
|
118 |
+
* @return bool
|
119 |
+
*/
|
120 |
+
function http_request_host_is_external_filter( $allow, $host, $url ) {
|
121 |
+
return ( false !== strpos( $host, 'freemius' ) ) ? true : $allow;
|
122 |
+
}
|
123 |
+
}
|
libs/factory/freemius/includes/updates/index.php
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Silence is golden.
|
libs/factory/freemius/index.php
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// Silence is golden.
|
libs/factory/pages/templates/assets/css/impressive.page.template.css
CHANGED
@@ -5,7 +5,8 @@
|
|
5 |
*/
|
6 |
#WBCR .updated,
|
7 |
#WBCR .notice,
|
8 |
-
#WBCR .error
|
|
|
9 |
display: none !important;
|
10 |
}
|
11 |
#WBCR .wbcr-factory-pages-429-impressive-page-template {
|
5 |
*/
|
6 |
#WBCR .updated,
|
7 |
#WBCR .notice,
|
8 |
+
#WBCR .error,
|
9 |
+
#WBCR .wdan-notices-compact-panel{
|
10 |
display: none !important;
|
11 |
}
|
12 |
#WBCR .wbcr-factory-pages-429-impressive-page-template {
|
readme.txt
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
=== Disable admin notices individually ===
|
2 |
Tags: hide admin notices, hide updates nags, hide nags, disable notices, disable update nags, disable nags, disable admin notices
|
3 |
Contributors: webcraftic, alexkovalevv, creativemotion
|
4 |
-
Donate link: https://
|
5 |
Requires at least: 4.8
|
6 |
Tested up to: 5.4
|
7 |
Requires PHP: 5.6
|
@@ -54,6 +54,13 @@ If you want to help with the translation, please contact me through this site or
|
|
54 |
3. Notifications panel (optional)
|
55 |
|
56 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
= 1.1.3 (01.07.2020) =
|
58 |
* Removed: Ads notices and dashboard widget
|
59 |
* Fixed: Minor bugs
|
1 |
=== Disable admin notices individually ===
|
2 |
Tags: hide admin notices, hide updates nags, hide nags, disable notices, disable update nags, disable nags, disable admin notices
|
3 |
Contributors: webcraftic, alexkovalevv, creativemotion
|
4 |
+
Donate link: https://clearfy.pro/disable-admin-notices/
|
5 |
Requires at least: 4.8
|
6 |
Tested up to: 5.4
|
7 |
Requires PHP: 5.6
|
54 |
3. Notifications panel (optional)
|
55 |
|
56 |
== Changelog ==
|
57 |
+
= 1.2.0 (16.07.2020) =
|
58 |
+
* Fixed: Minor bugs
|
59 |
+
|
60 |
+
= 1.2.0 (10.07.2020) =
|
61 |
+
* Fixed: Fixed some compatibility issues with third-party plugins.
|
62 |
+
* Added: Premium features
|
63 |
+
|
64 |
= 1.1.3 (01.07.2020) =
|
65 |
* Removed: Ads notices and dashboard widget
|
66 |
* Fixed: Minor bugs
|