PluginProbe
Filter Everything — WordPress & WooCommerce Filters / trunk
Filter Everything — WordPress & WooCommerce Filters vtrunk
1.9.6 1.9.5 1.9.4 1.9.3 1.9.2.2 1.9.2.1 trunk 1.2.1 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.4.1 1.4.4 1.4.5 1.4.8 1.4.9 1.5.0 1.5.1 1.6.0 1.6.1 1.6.2 1.6.3 All 51 releases
filter-everything / src / Entities / AuthorEntity.php

AuthorEntity.php in Filter Everything — WordPress & WooCommerce Filters trunk, at src/Entities/AuthorEntity.php

309 lines 9.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FilterEverything\Filter;
4
5 if ( ! defined('ABSPATH') ) {
6 exit;
7 }
8
9 class AuthorEntity implements Entity
10 {
11 public $items = [];
12 /**
13 * Declared explicitly: assigned from the outside in
14 * EntityManager::prepareEntitiesToDisplay(); dynamic properties are
15 * deprecated since PHP 8.2.
16 */
17 public $items_sort = [];
18
19 public $filter = [];
20
21 public $excludedTerms = [];
22
23 public $isInclude = false;
24
25 private $name = '';
26
27 private $postTypes = [];
28
29 public function __construct( $name, $postType ){
30 $this->name = $name;
31
32 if( $postType ){
33 $this->setPostTypes( array( $postType ) );
34 }
35
36 $this->getAllExistingTerms();
37 }
38
39 public function setPostTypes( $postTypes )
40 {
41 $this->postTypes = $postTypes;
42 }
43
44 public function setExcludedTerms( $excludedTerms, $isInclude )
45 {
46 $this->excludedTerms = $excludedTerms;
47 $this->isInclude = $isInclude;
48 }
49
50 public function getName()
51 {
52 return $this->name;
53 }
54
55 public function getTermId( $termSlug )
56 {
57 foreach ( $this->getAllExistingTerms() as $term ){
58 if( $termSlug == $term->slug ){
59 return $term->term_id;
60 }
61 }
62
63 return false;
64 }
65
66 function populateTermsWithPostIds( $setId, $post_type )
67 {
68 $wpManager = Container::instance()->getWpManager();
69 $wp_queried_object = $wpManager->getQueryVar( 'wp_queried_object' );
70 $wp_queried_author_slug = (isset( $wp_queried_object['author'] ) && $wp_queried_object['author'] ) ? $wp_queried_object['author'] : 0;
71
72 foreach( $this->items as $index => $term ){
73
74 foreach( $term->post_types as $post_id => $term_post_type ){
75 if( $term_post_type !== $post_type ){
76 $position = array_search( $post_id, $term->posts );
77 // To avoid unset $this->items[$index]->posts[0] when $position === false
78 if( $position !== false ){
79 unset( $this->items[$index]->posts[$position] );
80 }
81 }
82 }
83
84 if( $wp_queried_author_slug === $term->slug ){
85 $this->items[$index]->wp_queried = true;
86 }
87 }
88 }
89
90 public function getTerm( $id ){
91 if( ! $id ){
92 return false;
93 }
94
95 foreach ( $this->getAllExistingTerms() as $term ){
96 if( $id == $term->term_id ){
97 return $term;
98 }
99 }
100
101 return false;
102 }
103
104 public function getTerms()
105 {
106 return $this->excludeTerms( $this->getAllExistingTerms() );
107 }
108
109 function excludeTerms( $terms )
110 {
111 $exclude = [];
112
113 if( ! empty( $this->excludedTerms ) ){
114 $exclude = $this->excludedTerms;
115 }
116
117 $exclude_flipped = array_flip( $exclude );
118 if( $this->isInclude ){
119 $included_terms = [];
120 foreach( $terms as $index => $term ){
121 if( isset( $exclude_flipped[$term->term_id] ) ){
122 $included_terms[$index] = $term;
123 }
124 }
125 $terms = $included_terms;
126 }else{
127 foreach( $terms as $index => $term ){
128 if( isset( $exclude_flipped[$term->term_id] ) ){
129 unset( $terms[$index] );
130 }
131 }
132 }
133
134 return $terms;
135 }
136
137 /**
138 * @return array list of term_id and names useful to create Select dropdown
139 */
140 public function getTermsForSelect()
141 {
142 $toSelect = [];
143 foreach ( $this->getTerms() as $term ) {
144 $toSelect[$term->term_id] = $term->name;
145 }
146
147 return $toSelect;
148 }
149
150 public function getTermsForSelect2()
151 {
152 $toSelect = [];
153 foreach ( $this->getTerms() as $term ) {
154 $toSelect[] = array( 'id' => $term->term_id, 'text' =>$term->name );
155 }
156
157 return $toSelect;
158 }
159
160 function getAllExistingTerms($force = false)
161 {
162 if( empty( $this->items ) || $force ) {
163 $this->items = $this->getAuthors();
164 }
165
166 return $this->items;
167 }
168
169 private function getAuthors()
170 {
171 $transient_key = flrt_get_terms_transient_key( 'author_' . $this->getName() );
172
173 if ( false === ( $result = flrt_get_transient( $transient_key ) ) ) {
174
175 global $wpdb;
176 $this->postTypes = apply_filters('wpc_filter_author_query_post_types', get_post_types(array('public' => true)));
177
178 $IN = [];
179
180 if (!empty($this->postTypes)) {
181 foreach ($this->postTypes as $postType) {
182 $pieces[] = $wpdb->prepare("%s", $postType);
183 }
184
185 $IN = implode(", ", $pieces);
186 }
187
188 $sql[] = "SELECT {$wpdb->users}.ID,{$wpdb->users}.user_nicename,{$wpdb->users}.display_name,{$wpdb->posts}.post_type,{$wpdb->posts}.ID AS post_id";
189 $sql[] = "FROM {$wpdb->users}";
190 $sql[] = "LEFT JOIN {$wpdb->posts} ON ( {$wpdb->users}.ID = {$wpdb->posts}.post_author )";
191
192 if (flrt_wpml_active() && defined('ICL_LANGUAGE_CODE')) {
193 $sql[] = "LEFT JOIN {$wpdb->prefix}icl_translations AS wpml_translations";
194 $sql[] = "ON {$wpdb->posts}.ID = wpml_translations.element_id";
195
196 if (!empty($this->postTypes)) {
197
198 $sql[] = "AND wpml_translations.element_type IN(";
199
200 foreach ($this->postTypes as $type) {
201 $LANG_IN[] = $wpdb->prepare("CONCAT('post_', '%s')", $type);
202 }
203 $sql[] = implode(",", $LANG_IN);
204
205 $sql[] = ")";
206
207 }
208 }
209
210 $sql[] = "WHERE 1=1";
211
212 if (!empty($IN)) {
213 $sql[] = "AND {$wpdb->posts}.post_type IN( {$IN} )";
214 }
215
216 $sql[] = "AND {$wpdb->posts}.post_status = 'publish'";
217
218 if (flrt_wpml_active() && defined('ICL_LANGUAGE_CODE')) {
219 $sql[] = $wpdb->prepare("AND wpml_translations.language_code = '%s'", ICL_LANGUAGE_CODE);
220 }
221
222 /**
223 * Filters terms SQL-query and allows to modify it
224 */
225 $sql = apply_filters( 'wpc_filter_get_author_terms_sql', $sql );
226
227 $sql = implode(' ', $sql );
228
229 $result = $wpdb->get_results($sql, ARRAY_A);
230
231 $result = $this->convertToStandardTerms($result);
232
233 flrt_set_transient( $transient_key, $result, FLRT_TRANSIENT_PERIOD_HOURS * HOUR_IN_SECONDS );
234 }
235
236 return $result;
237 }
238
239 private function convertToStandardTerms( $users ){
240 $terms = [];
241
242 if( ! is_array( $users ) ){
243 return $terms;
244 }
245
246 // To make standard format for terms array;
247 foreach ( $users as $index => $user ){
248
249 $user_id = $user['ID'];
250
251 if( isset( $terms[ $user_id ] ) ){
252 $terms[ $user_id ]->posts[] = $user['post_id'];
253 $terms[ $user_id ]->count++;
254 $terms[ $user_id ]->post_types[$user['post_id']] = $user['post_type'];
255 }else{
256 $termObject = new \stdClass();
257 $termObject->slug = $user['user_nicename']; // slug for URL
258 $termObject->name = apply_filters( 'wpc_filter_author_term_name', $user['display_name'], $this->getName() ); // Name to display
259 $termObject->term_id = $user_id; // Term ID.
260 $termObject->posts = array( $user['post_id'] ); // All post IDs for this term (in all post types)
261 $termObject->count = 1; // Total count of posts for this term (in all post types)
262 $termObject->cross_count = 0; // Count of this term intersect posts with all filtered posts
263 $termObject->post_types[$user['post_id']] = $user['post_type']; // map terms post_types and their IDs
264 $termObject->wp_queried = false;
265
266 $terms[ $user_id ] = $termObject;
267 }
268 }
269
270 return $terms;
271 }
272
273 /**
274 * @param $queried_value
275 * @param $wp_query
276 * @return mixed object WP_Query | false
277 */
278 function addTermsToWpQuery( $queried_value, $wp_query )
279 {
280 $author__in = [];
281 $em = Container::instance()->getEntityManager();
282 $post_type = isset( $this->postTypes[0] ) ? $this->postTypes[0] : '';
283 $authorEntity = $em->createEntity( 'author#author', $post_type );
284
285 // if author already exists in query we have to return false
286 $maybeAlreadyExists = $wp_query->get( 'author_name' );
287 if( in_array( $maybeAlreadyExists, $queried_value['values'], true ) ){
288 /**
289 * @todo replace with with just false. Or better - show this only in debug mode.
290 */
291 return 'Author is already in query';
292 }
293
294 if( $maybeAlreadyExists ){
295 $queried_value['values'][] = $maybeAlreadyExists;
296 $wp_query->set( 'author_name', '');
297 $wp_query->set( 'author', $authorEntity->getTermId($maybeAlreadyExists) );
298 }
299
300 foreach ( $queried_value['values'] as $user_nicename ) {
301 $author__in[] = $authorEntity->getTermId($user_nicename);
302 }
303
304 $wp_query->set( 'author__in', $author__in );
305
306 // If ok return $wp_query;
307 return $wp_query;
308 }
309 }