PluginProbe ʕ •ᴥ•ʔ
FAPI Member / trunk
FAPI Member vtrunk
2.2.33 2.2.32 trunk 1.9.47 2.1.18 2.2.24 2.2.25 2.2.26 2.2.28 2.2.29 2.2.30 2.2.31
fapi-member / src / FapiMembershipLoader.php
fapi-member / src Last commit date
Api 2 days ago Container 2 years ago Deprecated 2 years ago Divi 1 year ago Elementor 7 months ago Email 3 years ago Email 2 2 years ago Mioweb 1 year ago Model 1 year ago Repository 3 weeks ago Service 2 days ago Templates 2 years ago Utils 2 days ago Utils 2 2 years ago services 2 2 years ago styles 2 2 years ago Bootstrap.php 2 days ago EmailTemplatesProvider.php 3 years ago FapiApi.php 2 years ago FapiClients.php 2 years ago FapiLevels.php 2 years ago FapiMemberPlugin.php 1 year ago FapiMemberTools.php 2 years ago FapiMembership.php 2 years ago FapiMembershipLoader.php 2 years ago FapiSanitization.php 2 years ago FapiTermEnvelope.php 4 years ago FapiUserUtils.php 3 years ago
FapiMembershipLoader.php
290 lines
1 <?php
2
3 namespace FapiMember;
4
5 use __PHP_Incomplete_Class;
6 use DateTimeImmutable;
7 use WP_Term;
8
9 final class FapiMembershipLoader {
10
11
12 const MEMBERSHIP_META_KEY = 'fapi_user_memberships';
13
14 const MEMBERSHIP_HISTORY_META_KEY = 'fapi_user_memberships_history';
15
16 /** @var FapiLevels */
17 private $fapiLevels;
18
19 /** @var WP_Term[] */
20 private $levels;
21
22 public function __construct( FapiLevels $levels ) {
23 $this->fapiLevels = $levels;
24 }
25
26 /**
27 * @param int $userId
28 */
29 public function extendMembershipsToParents( $userId ) {
30 $activeMemberships = $this->loadForUser( $userId );
31
32 if ( count( $activeMemberships ) === 0 ) {
33 return;
34 }
35
36 $parentsToExtend = array();
37 $extendedMemberships = $activeMemberships;
38 $newMemberships = array();
39
40 foreach ( $activeMemberships as $activeMembership ) {
41 $levelTerm = $this->fapiLevels->loadById( $activeMembership->level );
42
43 if ( ! $levelTerm ) {
44 continue;
45 }
46
47 if ( $levelTerm->parent === 0 ) {
48 continue;
49 }
50
51 $parentsToExtend[] = $this->fapiLevels->loadById( $levelTerm->parent );
52 }
53
54 foreach ( $parentsToExtend as $parentTerm ) {
55 $childLevelEnvelopes = array_filter(
56 $this->fapiLevels->loadAsTermEnvelopes(),
57 static function ( $termEnvelope ) use ( $parentTerm ) {
58 return ( $termEnvelope->getTerm()->parent === $parentTerm->term_id );
59 }
60 );
61 $childLevelsId = array_reduce(
62 $childLevelEnvelopes,
63 static function ( $carry, $m0 ) {
64 $carry[] = $m0->getTerm()->term_id;
65
66 return $carry;
67 },
68 array()
69 );
70
71 $childLevelsMemberships = array_filter(
72 $activeMemberships,
73 static function ( $membership ) use ( $childLevelsId ) {
74 return in_array( $membership->level, $childLevelsId, true );
75 }
76 );
77
78 $childIsUnlimited = false;
79 $childMaxUntil = null;
80 $childMinRegistered = null;
81
82 foreach ( $childLevelsMemberships as $m2 ) {
83 if ( $m2->isUnlimited === true ) {
84 $childIsUnlimited = true;
85 }
86
87 if ( $m2->until ) {
88 $childMaxUntil = max( $childMaxUntil, $m2->until );
89 }
90
91 if ( $m2->registered ) {
92 if ( $childMinRegistered === null ) {
93 $childMinRegistered = $m2->registered;
94 } else {
95 $childMinRegistered = min( $childMinRegistered, $m2->registered );
96 }
97 }
98 }
99
100 $wasParentTermExtended = null;
101
102 foreach ( $extendedMemberships as $m3 ) {
103 if ( $m3->level === $parentTerm->term_id ) {
104 if ( $m3->isUnlimited ) {
105 $wasParentTermExtended = true;
106 break;
107 }
108
109 if ( $childIsUnlimited ) {
110 $m3->isUnlimited = true;
111 $m3->until = null;
112 $wasParentTermExtended = true;
113 break;
114 }
115
116 $m3->until = max( $m3->until, $childMaxUntil );
117 $wasParentTermExtended = true;
118 }
119 }
120
121 if ( ! $wasParentTermExtended ) {
122 // create new membership for parent
123 $new = new FapiMembership( $parentTerm->term_id, $childMinRegistered, $childMaxUntil, $childIsUnlimited );
124 $newMemberships[] = $new;
125 $this->saveMembershipToHistory( $userId, $new );
126 }
127 }
128
129 $this->saveForUser( $userId, array_merge( $extendedMemberships, $newMemberships ) );
130 }
131
132 /**
133 * @param int $userId
134 * @param bool $removeFuture
135 * @return array
136 */
137 public function loadForUser( $userId, $removeFuture = false ) {
138 $meta = get_user_meta( $userId, self::MEMBERSHIP_META_KEY, true );
139
140 if ( $meta === '' || $meta === false ) {
141 return array();
142 }
143
144 $memberships = $this->toFapiMembership( $meta );
145 $levelIds = array();
146
147 foreach ( $this->levels() as $level ) {
148 $levelIds[] = $level->term_id;
149 }
150
151 $now = new DateTimeImmutable();
152
153 $memberships = array_filter(
154 $memberships,
155 static function ( FapiMembership $membership ) use ( $removeFuture, $levelIds, $now ) {
156 if ( ! in_array( $membership->level, $levelIds, true ) ) {
157 return false;
158 }
159
160 if ( ! $membership->isUnlimited && $membership->until < $now ) {
161 return false;
162 }
163
164 if ( $removeFuture && ( $membership->registered > $now ) ) {
165 return false;
166 }
167
168 return true;
169 }
170 );
171
172 $this->saveForUser( $userId, $memberships );
173
174 return $memberships;
175 }
176
177 /**
178 * @return WP_Term[]
179 */
180 public function levels() {
181 if ( $this->levels === null ) {
182 $termEnvelopes = $this->fapiLevels->loadAsTermEnvelopes();
183 $this->levels = array();
184
185 foreach ( $termEnvelopes as $termEnvelope ) {
186 $this->levels[] = $termEnvelope->getTerm();
187 }
188 }
189
190 return $this->levels;
191 }
192
193 /**
194 * @param int $userId
195 * @param FapiMembership[] $memberships
196 */
197 public function saveForUser( $userId, array $memberships ) {
198 if ( count( $memberships ) === 0 ) {
199 return;
200 }
201
202 $meta = array();
203
204 foreach ( $memberships as $membership ) {
205 $meta[] = $membership->jsonSerialize();
206 }
207
208 update_user_meta( $userId, self::MEMBERSHIP_META_KEY, $meta );
209
210 $user = get_users(['include' => [$userId]])[0];
211 $fapiMemberPlugin = new FapiMemberPlugin();
212 $fapiMemberPlugin->levels()->registerTaxonomy();
213 $fapiMemberPlugin->timeUnlockLevelsForUser($user);
214 }
215
216 /**
217 * @param int $userId
218 * @param FapiMembership $membership
219 */
220 public function saveMembershipToHistory( $userId, FapiMembership $membership ) {
221 $meta = get_user_meta( $userId, self::MEMBERSHIP_HISTORY_META_KEY, true );
222
223 if ( $meta === '' ) {
224 $meta = array();
225 }
226
227 $meta[] = $membership->jsonSerialize();
228 update_user_meta( $userId, self::MEMBERSHIP_HISTORY_META_KEY, $meta );
229 }
230
231 /**
232 * @param FapiMembership[] $memberships
233 * @param int $levelId
234 * @return bool
235 */
236 public function didUserHadLevelMembershipBefore( array $memberships, $levelId ) {
237 foreach ( $memberships as $membership ) {
238 if ( $membership->level === $levelId ) {
239 return true;
240 }
241 }
242
243 return false;
244 }
245
246 /**
247 * @param int $userId
248 * @return array<FapiMembership>
249 */
250 public function loadMembershipsHistory( $userId ) {
251 $meta = get_user_meta( $userId, self::MEMBERSHIP_HISTORY_META_KEY, true );
252
253 if ( $meta === '' ) {
254 $meta = array();
255 }
256
257 return $this->toFapiMembership( $meta );
258 }
259
260 private function toFapiMembership( array $meta ) {
261 $memberships = array();
262
263 foreach ( $meta as $item ) {
264 if ( $item instanceof FapiMembership ) {
265 $memberships[] = $item;
266
267 continue;
268 }
269
270 if ( $item instanceof __PHP_Incomplete_Class ) {
271 $item = (array) $item;
272 }
273
274 $memberships[] = new FapiMembership(
275 $item['level'],
276 isset( $item['registered'] )
277 ? DateTimeImmutable::createFromFormat( FapiMemberPlugin::DATE_TIME_FORMAT, $item['registered'], wp_timezone() )
278 : null,
279 isset( $item['until'] )
280 ? DateTimeImmutable::createFromFormat( FapiMemberPlugin::DATE_TIME_FORMAT, $item['until'], wp_timezone() )
281 : null,
282 (bool) $item['isUnlimited']
283 );
284 }
285
286 return $memberships;
287 }
288
289 }
290