PluginProbe
YayMail – WooCommerce Email Customizer / trunk
YayMail – WooCommerce Email Customizer vtrunk
4.4.4 4.4.3 4.4.2 4.4.1 trunk 1.9.6 2.1.4 2.1.5 3.2.2 3.2.6 3.2.7.1 3.2.8.1 3.2.9 3.3 3.3.1 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9 3.4 3.4.1 3.4.2 3.4.3 All 55 releases
yaymail / src / Models / PostModel.php

PostModel.php in YayMail – WooCommerce Email Customizer trunk, at src/Models/PostModel.php

313 lines 9.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace YayMail\Models;
4
5 use YayMail\Utils\SingletonTrait;
6
7 /**
8 * Post Model
9 *
10 * @method static PostModel get_instance()
11 */
12 class PostModel {
13
14 use SingletonTrait;
15
16 const DEFAULT_LIMIT = 4;
17
18 const COMMON_WP_QUERY_ARGUMENTS = [
19 'post_type' => 'post',
20 'post_status' => 'publish',
21 ];
22
23 /**
24 * Retrieves terms (categories, tags, or posts) for the entities selector.
25 *
26 * @param array $params Query parameters.
27 * @param array $field_mapping Field mapping for term IDs.
28 * @return array
29 */
30 public function get_terms( $params, $field_mapping = [
31 'id' => 'id',
32 'name' => 'name',
33 ] ) {
34 $page_data = $this->get_terms_page(
35 isset( $params['term_type'] ) ? $params['term_type'] : '',
36 $params['search_string'] ?? '',
37 $params['page_num'] ?? 1,
38 $params['page_size'] ?? 20
39 );
40
41 $result = [
42 'list' => array_map(
43 function( $item ) use ( $field_mapping ) {
44 $id_field = $field_mapping['id'] ?? 'id';
45 $name_field = $field_mapping['name'] ?? 'name';
46 return [
47 'id' => strval( isset( $item->{$id_field} ) ? $item->{$id_field} : $item->id ),
48 'name' => isset( $item->{$name_field} ) ? $item->{$name_field} : $item->name,
49 ];
50 },
51 $page_data['list']
52 ),
53 'next_page' => $page_data['next_page'],
54 ];
55
56 return $result;
57 }
58
59 /**
60 * Retrieves featured posts based on the provided parameters.
61 *
62 * @param array $params Query parameters.
63 * @return array
64 */
65 public function get_featured_posts( $params ) {
66 $post_type = isset( $params['post_type'] ) ? $params['post_type'] : 'newest';
67 unset( $params['post_type'] );
68
69 switch ( $post_type ) {
70 case 'newest':
71 $posts = $this->get_newest_posts( $params );
72 break;
73 case 'category_selections':
74 $posts = $this->get_by_categories( $params );
75 break;
76 case 'tag_selections':
77 $posts = $this->get_by_tags( $params );
78 break;
79 case 'post_selections':
80 $posts = $this->get_by_post_ids( $params );
81 break;
82 default:
83 $posts = [];
84 break;
85 }
86
87 $posts_response = array_map( [ $this, 'get_post_response' ], $posts );
88
89 $result = [];
90
91 foreach ( $posts_response as $post_response ) {
92 if ( ! empty( $post_response ) ) {
93 $result[] = $post_response;
94 }
95 }
96
97 return $result;
98 }
99
100 /**
101 * Maps a WP_Post to API response format.
102 *
103 * @param \WP_Post $post Post object.
104 * @return array
105 */
106 public function get_post_response( $post ) {
107 if ( ! $post instanceof \WP_Post ) {
108 return [];
109 }
110
111 $thumbnail_src = get_the_post_thumbnail_url( $post, 'medium' );
112 $excerpt = has_excerpt( $post )
113 ? $post->post_excerpt
114 : wp_trim_words( wp_strip_all_tags( $post->post_content ), 55, '...' );
115
116 return [
117 'id' => $post->ID,
118 'title' => get_the_title( $post ),
119 'excerpt' => $excerpt,
120 'date' => date_i18n( get_option( 'date_format' ), strtotime( $post->post_date ) ),
121 'date_timestamp' => strtotime( $post->post_date ),
122 'author' => get_the_author_meta( 'display_name', $post->post_author ),
123 'permalink' => get_permalink( $post ),
124 'thumbnail_src' => $thumbnail_src ? $thumbnail_src : '',
125 ];
126 }
127
128 /**
129 * Retrieves newest published posts.
130 *
131 * @param array $criteria Query criteria.
132 * @param array $optional_args Optional WP_Query arguments.
133 * @return \WP_Post[]
134 */
135 private function get_newest_posts( $criteria, $optional_args = [] ) {
136 $args = array_merge(
137 self::COMMON_WP_QUERY_ARGUMENTS,
138 [
139 'posts_per_page' => isset( $criteria['number_of_posts'] ) ? (int) $criteria['number_of_posts'] : self::DEFAULT_LIMIT,
140 'orderby' => 'date',
141 'order' => 'DESC',
142 ]
143 );
144
145 if ( isset( $criteria['sorted_by'] ) && 'random' === $criteria['sorted_by'] ) {
146 $args['orderby'] = 'rand';
147 }
148
149 if ( ! empty( $optional_args ) ) {
150 $args = wp_parse_args( $args, $optional_args );
151 }
152
153 $query = new \WP_Query( $args );
154 return $query->posts;
155 }
156
157 /**
158 * Retrieves posts by category IDs.
159 *
160 * @param array $criteria Query criteria.
161 * @param array $optional_args Optional WP_Query arguments.
162 * @return \WP_Post[]
163 */
164 private function get_by_categories( $criteria, $optional_args = [] ) {
165 if ( empty( $criteria['category_ids'] ) ) {
166 return [];
167 }
168
169 $args = array_merge(
170 self::COMMON_WP_QUERY_ARGUMENTS,
171 [
172 'posts_per_page' => isset( $criteria['number_of_posts'] ) ? (int) $criteria['number_of_posts'] : self::DEFAULT_LIMIT,
173 'category__in' => array_map( 'intval', $criteria['category_ids'] ),
174 ]
175 );
176
177 if ( isset( $criteria['sorted_by'] ) && 'random' === $criteria['sorted_by'] ) {
178 $args['orderby'] = 'rand';
179 }
180
181 if ( ! empty( $optional_args ) ) {
182 $args = wp_parse_args( $args, $optional_args );
183 }
184
185 $query = new \WP_Query( $args );
186 return $query->posts;
187 }
188
189 /**
190 * Retrieves posts by tag IDs.
191 *
192 * @param array $criteria Query criteria.
193 * @param array $optional_args Optional WP_Query arguments.
194 * @return \WP_Post[]
195 */
196 private function get_by_tags( $criteria, $optional_args = [] ) {
197 if ( empty( $criteria['tag_ids'] ) ) {
198 return [];
199 }
200
201 $args = array_merge(
202 self::COMMON_WP_QUERY_ARGUMENTS,
203 [
204 'posts_per_page' => isset( $criteria['number_of_posts'] ) ? (int) $criteria['number_of_posts'] : self::DEFAULT_LIMIT,
205 'tag__in' => array_map( 'intval', $criteria['tag_ids'] ),
206 ]
207 );
208
209 if ( isset( $criteria['sorted_by'] ) && 'random' === $criteria['sorted_by'] ) {
210 $args['orderby'] = 'rand';
211 }
212
213 if ( ! empty( $optional_args ) ) {
214 $args = wp_parse_args( $args, $optional_args );
215 }
216
217 $query = new \WP_Query( $args );
218 return $query->posts;
219 }
220
221 /**
222 * Retrieves posts by specific post IDs.
223 *
224 * @param array $criteria Query criteria.
225 * @param array $optional_args Optional WP_Query arguments.
226 * @return \WP_Post[]
227 */
228 private function get_by_post_ids( $criteria, $optional_args = [] ) {
229 if ( empty( $criteria['post_ids'] ) ) {
230 return [];
231 }
232
233 $args = array_merge(
234 self::COMMON_WP_QUERY_ARGUMENTS,
235 [
236 'posts_per_page' => -1,
237 'post__in' => array_map( 'intval', $criteria['post_ids'] ),
238 'orderby' => 'post__in',
239 ]
240 );
241
242 if ( isset( $criteria['sorted_by'] ) && 'random' === $criteria['sorted_by'] ) {
243 $args['orderby'] = 'rand';
244 }
245
246 if ( ! empty( $optional_args ) ) {
247 $args = wp_parse_args( $args, $optional_args );
248 }
249
250 $query = new \WP_Query( $args );
251 return $query->posts;
252 }
253
254 /**
255 * Retrieves a paginated list of terms or posts.
256 *
257 * @param string $taxonomy Taxonomy slug or empty string for posts.
258 * @param string $search_string Search string.
259 * @param int $page_num Page number.
260 * @param int $page_size Page size.
261 * @return array
262 */
263 private function get_terms_page( $taxonomy, $search_string = '', $page_num = 1, $page_size = 10 ) {
264 $limit = $page_size + 1;
265 $offset = ( $page_num - 1 ) * $page_size;
266
267 if ( empty( $taxonomy ) ) {
268 global $wpdb;
269 $query = $wpdb->prepare(
270 "SELECT id, post_title AS name
271 FROM {$wpdb->prefix}posts
272 WHERE {$wpdb->prefix}posts.post_type = 'post'
273 AND {$wpdb->prefix}posts.post_status = 'publish'
274 AND {$wpdb->prefix}posts.post_title LIKE %s
275 ORDER BY post_title ASC
276 LIMIT %d OFFSET %d",
277 "%{$search_string}%",
278 $limit,
279 $offset
280 );
281 $list = $wpdb->get_results( $query ); //phpcs:ignore
282 } else {
283 $args = [
284 'taxonomy' => $taxonomy,
285 'orderby' => 'name',
286 'show_count' => 0,
287 'pad_counts' => 0,
288 'hierarchical' => 1,
289 'hide_empty' => 0,
290 'number' => $limit,
291 'offset' => $offset,
292 ];
293
294 if ( ! empty( $search_string ) ) {
295 $args['name__like'] = $search_string;
296 }
297
298 $list = array_values( \get_categories( $args ) );
299 }//end if
300
301 $next_page = count( $list ) > $page_size ? $page_num + 1 : false;
302
303 if ( $next_page ) {
304 array_pop( $list );
305 }
306
307 return [
308 'list' => $list,
309 'next_page' => $next_page,
310 ];
311 }
312 }
313