PluginProbe
wpForo Forum / 2.3.1
wpForo Forum v2.3.1
3.1.5 3.1.4 3.1.2 3.1.1 3.1.0 3.0.9 3.0.8 3.0.7 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 1.4.13 1.4.2 All 137 releases
wpforo / classes / PostMeta.php

PostMeta.php in wpForo Forum 2.3.1, at classes/PostMeta.php

656 lines 24.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace wpforo\classes;
4
5 use stdClass;
6
7 // Exit if accessed directly
8 if( ! defined( 'ABSPATH' ) ) exit;
9
10 class PostMeta {
11 private $default;
12
13 public function __construct() {
14 $this->init_defaults();
15 $this->init_hooks();
16 }
17
18 private function init_hooks() {
19 add_action( 'wpforo_after_add_topic', [ $this, 'after_add_topic' ], 10, 2 );
20 add_action( 'wpforo_after_edit_topic', [ $this, 'after_edit_topic' ], 10, 3 );
21 add_action( 'wpforo_after_add_post', [ $this, 'after_add_post' ], 10, 3 );
22 add_action( 'wpforo_after_edit_post', [ $this, 'after_edit_post' ], 10, 4 );
23 add_action( 'wpforo_after_move_topic', [ $this, 'after_move_topic' ], 10, 2 );
24 add_action( 'wpforo_after_merge_topic', [ $this, 'after_merge_topic' ], 10, 3 );
25 add_action( 'wpforo_after_delete_post', [ $this, 'after_delete_post' ] );
26 add_action( 'wpforo_post_status_update', [ $this, 'after_post_status_update' ], 10, 2 );
27 add_action( 'wpforo_topic_private_update', [ $this, 'after_topic_private_update' ], 10, 2 );
28 add_action( 'wpforo_after_is_first_post_update', [ $this, 'after_is_first_post_update' ], 10, 2 );
29 }
30
31 private function init_defaults() {
32 $this->default = new stdClass();
33 $this->default->postmeta = [
34 'metaid' => 0,
35 'postid' => 0,
36 'metakey' => '',
37 'metavalue' => '',
38 'forumid' => 0,
39 'topicid' => 0,
40 'status' => 0,
41 'private' => 0,
42 'is_first_post' => 0,
43 ];
44 $this->default->postmeta_format = [
45 'metaid' => '%d',
46 'postid' => '%d',
47 'metakey' => '%s',
48 'metavalue' => '%s',
49 'forumid' => '%d',
50 'topicid' => '%d',
51 'status' => '%d',
52 'private' => '%d',
53 'is_first_post' => '%d',
54 ];
55 $this->default->sql_select_args = [
56 'include' => [],
57 'exclude' => [],
58 'postids_include' => [],
59 'postids_exclude' => [],
60 'metakeys_include' => [],
61 'metakeys_exclude' => [],
62 'metavalues_include' => [],
63 'metavalues_exclude' => [],
64 'metavalue_like' => null,
65 'metavalue_notlike' => null,
66 'forumids_include' => [],
67 'forumids_exclude' => [],
68 'topicids_include' => [],
69 'topicids_exclude' => [],
70 'is_first_post' => null,
71 'status' => null,
72 'private' => null,
73 'orderby' => null,
74 'offset' => null,
75 'row_count' => null,
76 ];
77 }
78
79 public function fix_postmeta( $postmeta ) {
80 $postmeta = wpforo_array_args_cast_and_merge( $postmeta, $this->default->postmeta );
81 $postmeta['metavalue'] = wpforo_is_json( $postmeta['metavalue'] ) ? json_decode( $postmeta['metavalue'], true ) : $postmeta['metavalue'];
82
83 return $postmeta;
84 }
85
86 /**
87 * @param array $postmeta
88 *
89 * @return bool|int
90 */
91 public function add( $postmeta ) {
92 if( ! wpfval( $postmeta, 'postid' ) || ! wpfval( $postmeta, 'metakey' ) ) return false;
93
94 if( ! wpfkey( $postmeta, 'topicid' ) || ! wpfkey( $postmeta, 'forumid' ) || ! wpfkey( $postmeta, 'status' ) || ! wpfkey( $postmeta, 'private' ) || ! wpfkey( $postmeta, 'is_first_post' ) ) {
95 if( ! $post = WPF()->post->get_post( $postmeta['postid'], false ) ) return false;
96 $postmeta['topicid'] = wpforo_bigintval( wpfval( $post, 'topicid' ) );
97 $postmeta['forumid'] = intval( wpfval( $post, 'forumid' ) );
98 $postmeta['status'] = intval( wpfval( $post, 'status' ) );
99 $postmeta['private'] = intval( wpfval( $post, 'private' ) );
100 $postmeta['is_first_post'] = intval( wpfval( $post, 'is_first_post' ) );
101 }
102
103 $postmeta = wpforo_array_args_cast_and_merge( (array) $postmeta, $this->default->postmeta );
104 unset( $postmeta['metaid'] );
105
106 if( is_null( $postmeta['metavalue'] ) ) $postmeta['metavalue'] = '';
107 $postmeta['metavalue'] = wp_unslash( $postmeta['metavalue'] );
108 if( ! is_scalar( $postmeta['metavalue'] ) ) $postmeta['metavalue'] = json_encode( (array) $postmeta['metavalue'] );
109
110 $postmeta = wpforo_array_ordered_intersect_key( $postmeta, $this->default->postmeta_format );
111 if( WPF()->db->insert(
112 WPF()->tables->postmeta,
113 $postmeta,
114 wpforo_array_ordered_intersect_key( $this->default->postmeta_format, $postmeta )
115 ) ) {
116 $metaid = WPF()->db->insert_id;
117 do_action( 'wpforo_after_add_postmeta', $postmeta, $metaid );
118 return $metaid;
119 }
120
121 return false;
122 }
123
124 /**
125 * @param array $postmeta
126 * @param array|int $where
127 *
128 * @return bool
129 */
130 public function edit( $postmeta, $where ) {
131 if( empty( $postmeta ) || empty( $where ) ) return false;
132 if( is_numeric( $where ) ) $where = [ 'metaid' => $where ];
133 $postmeta = (array) $postmeta;
134 $where = (array) $where;
135
136 if( wpfkey( $postmeta, 'metavalue' ) ) {
137 if( is_null( $postmeta['metavalue'] ) ) $postmeta['metavalue'] = '';
138 $postmeta['metavalue'] = wp_unslash( $postmeta['metavalue'] );
139 if( ! is_scalar( $postmeta['metavalue'] ) ) $postmeta['metavalue'] = json_encode( (array) $postmeta['metavalue'] );
140 }
141
142 $postmeta = wpforo_array_ordered_intersect_key( $postmeta, $this->default->postmeta_format );
143 $where = wpforo_array_ordered_intersect_key( $where, $this->default->postmeta_format );
144 if( false !== WPF()->db->update(
145 WPF()->tables->postmeta,
146 $postmeta,
147 $where,
148 wpforo_array_ordered_intersect_key( $this->default->postmeta_format, $postmeta ),
149 wpforo_array_ordered_intersect_key( $this->default->postmeta_format, $where )
150 ) ) {
151 do_action( 'wpforo_after_edit_postmeta', $postmeta, $where );
152 return true;
153 }
154
155 return false;
156 }
157
158 /**
159 * @param array|int $where
160 *
161 * @return bool
162 */
163 public function delete( $where ) {
164 if( empty( $where ) ) return false;
165 if( is_numeric( $where ) ) $where = [ 'metaid' => $where ];
166 $where = (array) $where;
167
168 $where = wpforo_array_ordered_intersect_key( $where, $this->default->postmeta_format );
169 if( false !== WPF()->db->delete(
170 WPF()->tables->postmeta,
171 $where,
172 wpforo_array_ordered_intersect_key( $this->default->postmeta_format, $where )
173 ) ) {
174 do_action( 'wpforo_after_delete_postmeta', $where );
175 return true;
176 }
177
178 return false;
179 }
180
181 private function parse_args( $args ) {
182 $args = wpforo_parse_args( $args, $this->default->sql_select_args );
183 $args = wpforo_array_ordered_intersect_key( $args, $this->default->sql_select_args );
184 $args['include'] = wpforo_parse_args( $args['include'] );
185 $args['exclude'] = wpforo_parse_args( $args['exclude'] );
186 $args['postids_include'] = wpforo_parse_args( $args['postids_include'] );
187 $args['postids_exclude'] = wpforo_parse_args( $args['postids_exclude'] );
188 $args['metakeys_include'] = wpforo_parse_args( $args['metakeys_include'] );
189 $args['metakeys_exclude'] = wpforo_parse_args( $args['metakeys_exclude'] );
190 $args['metavalues_include'] = wpforo_parse_args( $args['metavalues_include'] );
191 $args['metavalues_exclude'] = wpforo_parse_args( $args['metavalues_exclude'] );
192 $args['forumids_include'] = wpforo_parse_args( $args['forumids_include'] );
193 $args['forumids_exclude'] = wpforo_parse_args( $args['forumids_exclude'] );
194 $args['topicids_include'] = wpforo_parse_args( $args['topicids_include'] );
195 $args['topicids_exclude'] = wpforo_parse_args( $args['topicids_exclude'] );
196
197 return $args;
198 }
199
200 private function build_sql_select( $args, $select = '' ) {
201 $args = $this->parse_args( $args );
202 if( ! $select ) $select = '*';
203
204 $wheres = [];
205
206 if( ! is_null( $args['is_first_post'] ) ) $wheres[] = "`is_first_post` = '" . intval( $args['is_first_post'] ) . "'";
207 if( ! is_null( $args['status'] ) ) $wheres[] = "`status` = '" . intval( $args['status'] ) . "'";
208 if( ! is_null( $args['private'] ) ) $wheres[] = "`private` = " . intval( $args['private'] );
209
210 if( ! empty( $args['include'] ) ) $wheres[] = "`metaid` IN(" . implode( ',', array_map( 'wpforo_bigintval', $args['include'] ) ) . ")";
211 if( ! empty( $args['exclude'] ) ) $wheres[] = "`metaid` NOT IN(" . implode( ',', array_map( 'wpforo_bigintval', $args['exclude'] ) ) . ")";
212
213 if( ! empty( $args['postids_include'] ) ) $wheres[] = "`postid` IN(" . implode( ',', array_map( 'wpforo_bigintval', $args['postids_include'] ) ) . ")";
214 if( ! empty( $args['postids_exclude'] ) ) $wheres[] = "`postid` NOT IN(" . implode( ',', array_map( 'wpforo_bigintval', $args['postids_exclude'] ) ) . ")";
215
216 if( ! empty( $args['metakeys_include'] ) ) $wheres[] = "`metakey` IN('" . implode( "','", array_map( 'trim', $args['metakeys_include'] ) ) . "')";
217 if( ! empty( $args['metakeys_exclude'] ) ) $wheres[] = "`metakey` NOT IN('" . implode( "','", array_map( 'trim', $args['metakeys_exclude'] ) ) . "')";
218
219 if( ! empty( $args['metavalues_include'] ) ) $wheres[] = "`metavalue` IN('" . implode( "','", array_map( 'trim', $args['metavalues_include'] ) ) . "')";
220 if( ! empty( $args['metavalues_exclude'] ) ) $wheres[] = "`metavalue` NOT IN('" . implode( "','", array_map( 'trim', $args['metavalues_exclude'] ) ) . "')";
221
222 if( ! is_null( $args['metavalue_like'] ) ) $wheres[] = "`metavalue` LIKE '" . esc_sql( $args['metavalue_like'] ) . "'";
223 if( ! is_null( $args['metavalue_notlike'] ) ) $wheres[] = "`metavalue` NOT LIKE '" . esc_sql( $args['metavalue_notlike'] ) . "'";
224
225 if( ! empty( $args['forumids_include'] ) ) $wheres[] = "`forumid` IN(" . implode( ',', array_map( 'intval', $args['forumids_include'] ) ) . ")";
226 if( ! empty( $args['forumids_exclude'] ) ) $wheres[] = "`forumid` NOT IN(" . implode( ',', array_map( 'intval', $args['forumids_exclude'] ) ) . ")";
227
228 if( ! empty( $args['topicids_include'] ) ) $wheres[] = "`topicid` IN(" . implode( ',', array_map( 'wpforo_bigintval', $args['topicids_include'] ) ) . ")";
229 if( ! empty( $args['topicids_exclude'] ) ) $wheres[] = "`topicid` NOT IN(" . implode( ',', array_map( 'wpforo_bigintval', $args['topicids_exclude'] ) ) . ")";
230
231 $sql = "SELECT $select FROM " . WPF()->tables->postmeta;
232 if( $wheres ) $sql .= " WHERE " . implode( " AND ", $wheres );
233 if( $args['orderby'] ) $sql .= " ORDER BY " . $args['orderby'];
234 if( $args['row_count'] ) $sql .= " LIMIT " . wpforo_bigintval( $args['offset'] ) . "," . wpforo_bigintval( $args['row_count'] );
235
236 return $sql;
237 }
238
239 /**
240 * @param int $metaid
241 *
242 * @return array|mixed
243 */
244 public function get_postmeta_by_id( $metaid ) {
245 if( ! $metaid = wpforo_bigintval( $metaid ) ) return null;
246
247 $key = 'get_postmeta_by_id_' . $metaid;
248 if( WPF()->ram_cache->exists( $key ) ) return WPF()->ram_cache->get( $key );
249
250 if( $postmeta = (array) WPF()->db->get_row( $this->build_sql_select( [ 'include' => $metaid ] ), ARRAY_A ) ) {
251 $postmeta = $this->fix_postmeta( $postmeta );
252 }
253
254 WPF()->ram_cache->set( $key, $postmeta );
255
256 return $postmeta;
257 }
258
259 /**
260 * @param int $postid
261 * @param string $metakey
262 *
263 * @return bool
264 */
265 public function exists( $postid, $metakey ) {
266 if( ! $metakey || ! ( $postid = wpforo_bigintval( $postid ) ) ) return false;
267 $sql = "SELECT EXISTS(
268 SELECT * FROM `" . WPF()->tables->postmeta . "`
269 WHERE `postid` = %d
270 AND `metakey` = %s
271 ) AS is_exists";
272
273 return (bool) WPF()->db->get_var( WPF()->db->prepare( $sql, $postid, $metakey ) );
274 }
275
276 /**
277 * @param array $args
278 * @param string $field
279 *
280 * @return array
281 */
282 public function get_postmetas_col( $args, $field ) {
283 $args = wpforo_array_ordered_intersect_key( (array) $args, $this->default->sql_select_args );
284 if( empty( $args ) ) return [];
285
286 $key = 'get_postmetas_' . json_encode( $args ) . '_' . $field;
287 if( WPF()->ram_cache->exists( $key ) ) return WPF()->ram_cache->get( $key );
288
289 $postmetas = WPF()->db->get_col( $this->build_sql_select( $args, "`$field`" ) );
290
291 WPF()->ram_cache->set( $key, $postmetas );
292
293 return $postmetas;
294 }
295
296 /**
297 * @param array $args
298 *
299 * @return array
300 */
301 public function get_postmetas( $args ) {
302 $args = wpforo_array_ordered_intersect_key( (array) $args, $this->default->sql_select_args );
303 if( empty( $args ) ) return [];
304
305 $key = 'get_postmetas_' . json_encode( $args );
306 if( WPF()->ram_cache->exists( $key ) ) return WPF()->ram_cache->get( $key );
307
308 if( $postmetas = (array) WPF()->db->get_results( $this->build_sql_select( $args ), ARRAY_A ) ) {
309 $postmetas = array_map( [ $this, 'fix_postmeta' ], $postmetas );
310 }
311
312 WPF()->ram_cache->set( $key, $postmetas );
313
314 return $postmetas;
315 }
316
317 /**
318 * @param int $postid
319 * @param string|array $metakeys
320 * @param bool $single
321 *
322 * @return array|mixed|null
323 */
324 public function get_postmeta( $postid, $metakeys = '', $single = false ) {
325 if( ! $postid = wpforo_bigintval( $postid ) ) return null;
326 $metakeys = array_filter( (array) $metakeys );
327
328 $key = 'get_postmeta_' . $postid . '_' . json_encode( $metakeys ) . '_' . $single;
329 if( WPF()->ram_cache->exists( $key ) ) return WPF()->ram_cache->get( $key );
330
331 $postmeta = null;
332
333 $args = [
334 'postids_include' => $postid,
335 'metakeys_include' => $metakeys,
336 'orderby' => '`metaid` ASC',
337 'row_count' => $single && $metakeys ? 1 : null,
338 ];
339 if( $postmetas = $this->get_postmetas( $args ) ) {
340 if( count( $metakeys ) === 1 ) {
341 if( $single ) {
342 $first = current( $postmetas );
343 $postmeta = $first['metavalue'];
344 } else {
345 $postmeta = [];
346 foreach( $postmetas as $p ) $postmeta[] = $p['metavalue'];
347 }
348 } else {
349 $postmeta = [];
350 foreach( $postmetas as $p ) {
351 if( $single ) {
352 if( ! array_key_exists( $p['metakey'], $postmeta ) ) $postmeta[ $p['metakey'] ] = $p['metavalue'];
353 } else {
354 $postmeta[ $p['metakey'] ][] = $p['metavalue'];
355 }
356 }
357 }
358 }
359
360 WPF()->ram_cache->set( $key, $postmeta );
361
362 return $postmeta;
363 }
364
365 public function search( $args ) {
366 $args = array_filter( (array) $args );
367 if( ! $args ) return [];
368
369 $selects = [];
370 foreach( $args as $key => $value ) {
371 if( $field = WPF()->post->get_field( $key ) ) {
372 $value = (array) $value;
373 $wheres = [];
374 if( in_array( $field['type'], [ 'text', 'textarea', 'email', 'search', 'tel' ] ) ) {
375 foreach( $value as $v ) $wheres[] = "`metavalue` LIKE '%" . esc_sql( wp_unslash( $v ) ) . "%'";
376 } elseif( $field['type'] === 'checkbox' || ( $field['type'] === 'select' && wpfval( $field, 'isMultiChoice' ) ) || ( $field['type'] === 'autocomplete' && wpfval( $field, 'isMultiChoice' ) ) ) {
377 foreach( $value as $v ) {
378 $v = preg_quote( preg_quote( wp_unslash( $v ) ) );
379 $wheres[] = "`metavalue` REGEXP '[\\\[,]\"" . $v . "\"[,\\\]]'";
380 }
381 } else {
382 foreach( $value as $v ) $wheres[] = "`metavalue` LIKE '" . esc_sql( wp_unslash( $v ) ) . "'";
383 }
384 if( $wheres ) {
385 $selects[] = "SELECT `postid`, `metakey` FROM `" . WPF()->tables->postmeta . "`
386 WHERE `metakey` = '" . esc_sql( $key ) . "' AND " . implode( ' AND ', $wheres );
387 }
388 }
389 }
390
391 if( $selects ) {
392 $sql = "SELECT `postid`, COUNT(`postid`) AS pcount FROM
393 (" . implode( ' UNION ', $selects ) . ") AS pm
394 GROUP BY `postid` HAVING pcount = " . count( $selects );
395
396 return WPF()->db->get_col( $sql );
397 }
398
399 return [];
400 }
401
402 private function delete_file( $postid, $metakey ) {
403 $postid = wpforo_bigintval( $postid );
404 if( $postid && $metakey ) {
405 if( $postmeta = $this->get_postmeta( $postid, $metakey ) ) {
406 foreach( $postmeta as $file ) {
407 $mediaid = (int) wpfval( $file, 'mediaid' );
408 $fileurl = (string) wpfval( $file, 'fileurl' );
409 $filedir = wpforo_fix_upload_dir( $fileurl );
410 if( $mediaid ) wp_delete_attachment( $mediaid );
411 wp_delete_file( $filedir );
412 }
413 $this->delete( [ 'postid' => $postid, 'metakey' => $metakey ] );
414 }
415 }
416 }
417
418 private function add_file( $type, $post ) {
419 $postid = (int) ( wpfval( $post, 'first_postid' ) ? $post['first_postid'] : wpfval( $post, 'postid' ) );
420
421 if( $wpftcf_delete = array_filter( (array) wpfval( $_POST, 'wpftcf_delete' ) ) ) {
422 foreach( $wpftcf_delete as $metakey ) {
423 $this->delete_file( $postid, $metakey );
424 }
425 }
426
427 if( ! empty( wpfval( $_FILES, 'data', 'type' ) ) ) {
428 $forum = WPF()->forum->get_forum( $post['forumid'] );
429 $fields_list = WPF()->post->get_topic_fields_list( false, $forum, ! WPF()->current_userid );
430 $mime_types = wp_get_mime_types();
431 $allowed_mime_types = get_allowed_mime_types();
432 foreach( $_FILES['data']['type'] as $k => $mime_type ) {
433 if( in_array( $k, $fields_list ) ) {
434 $field = WPF()->post->get_field( $k, $type, $forum );
435 $label = ( $field['label'] ?: $field['fieldKey'] );
436
437 if( $error = intval( wpfval( $_FILES, 'data', 'error', $k ) ) ) {
438 $phpFileUploadErrors = [
439 0 => 'There is no error, the file uploaded with success',
440 1 => 'The uploaded file size is too big',
441 2 => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
442 3 => 'The uploaded file was only partially uploaded',
443 // 4 => 'No file was uploaded',
444 6 => 'Missing a temporary folder',
445 7 => 'Failed to write file to disk.',
446 8 => 'A PHP extension stopped the file upload.',
447 ];
448 if( $n = wpfval( $phpFileUploadErrors, $error ) ) WPF()->notice->add( $n, 'error' );
449 } else {
450 $name = wpfval( $_FILES, 'data', 'name', $k );
451 $tmp_name = wpfval( $_FILES, 'data', 'tmp_name', $k );
452 $ext = pathinfo( $name, PATHINFO_EXTENSION );
453 $size = intval( $field['fileSize'] );
454 $fileExtensions = array_filter( (array) is_scalar( $field['fileExtensions'] ) ? explode( ',', trim( (string) $field['fileExtensions'] ) ) : $field['fileExtensions'] );
455 if( $fileExtensions ) {
456 if( in_array( $ext, $fileExtensions ) ) {
457 $extensions = explode( '|', array_search( $mime_type, $mime_types ) );
458 $e = in_array( $ext, $extensions );
459 } else {
460 $e = false;
461 }
462 } else {
463 $extensions = explode( '|', array_search( $mime_type, $allowed_mime_types ) );
464 $e = in_array( $ext, $extensions );
465 }
466
467 if( ! empty( $e ) ) {
468 if( wpfval( $_FILES, 'data', 'size', $k ) <= ( $size * 1024 * 1024 ) ) {
469 $attach_dir = WPF()->folders['default_attachments']['dir'] . DIRECTORY_SEPARATOR . WPF()->current_userid;
470 $attach_url = WPF()->folders['default_attachments']['url//'] . "/" . WPF()->current_userid;
471 if( ! is_dir( $attach_dir ) ) wp_mkdir_p( $attach_dir );
472
473 $fnm = pathinfo( $name, PATHINFO_FILENAME );
474 $fnm = str_replace( ' ', '-', $fnm );
475 while( strpos( (string) $fnm, '--' ) !== false ) $fnm = str_replace( '--', '-', $fnm );
476 $fnm = preg_replace( "/[^-a-zA-Z0-9_]/", "", (string) $fnm );
477 $fnm = trim( (string) $fnm, "-" );
478 $fnm_empty = ! $fnm;
479
480 $file_name = $fnm . "." . $ext;
481
482 $attach_fname = time() . ( ! $fnm_empty ? '-' : '' ) . $file_name;
483 $attach_path = $attach_dir . DIRECTORY_SEPARATOR . $attach_fname;
484
485 if( is_dir( $attach_dir ) && move_uploaded_file( $tmp_name, $attach_path ) ) {
486 $this->delete_file( $postid, $field['fieldKey'] );
487
488 $attach_id = wpforo_insert_to_media_library( $attach_path, $fnm );
489 $file = [
490 'fileurl' => $attach_url . '/' . $attach_fname,
491 'filename' => basename( (string) $name ),
492 'mediaid' => $attach_id,
493 ];
494
495 $postmeta = [
496 'postid' => $postid,
497 'metakey' => $field['fieldKey'],
498 'metavalue' => $file,
499 'forumid' => $post['forumid'],
500 'topicid' => $post['topicid'],
501 'is_first_post' => 1,
502 'status' => $post['status'],
503 'private' => $post['private'],
504 ];
505 $this->add( $postmeta );
506
507 } else {
508 WPF()->notice->add( 'Can\'t upload file', 'error' );
509 }
510
511 } else {
512 WPF()->notice->add( '%1$s - File is too large. Maximum allowed file size is %2$s MB', 'error', [ $label, $size ] );
513 }
514 } else {
515 WPF()->notice->add( '%1$s - File type is not allowed.', 'error', $label );
516 }
517 }
518 }
519 }
520 }
521 }
522
523 public function after_add_topic( $topic, $forum ) {
524 $this->add_file( 'topic', $topic );
525
526 if( ! empty( $topic['postmetas'] ) ) {
527 $fields_list = WPF()->post->get_topic_fields_list( false, $forum, ! WPF()->current_userid );
528 foreach( $topic['postmetas'] as $metakey => $metavalue ) {
529 if( in_array( $metakey, $fields_list ) ) {
530 $postmeta = [
531 'postid' => $topic['first_postid'],
532 'metakey' => $metakey,
533 'metavalue' => $metavalue,
534 'forumid' => $topic['forumid'],
535 'topicid' => $topic['topicid'],
536 'is_first_post' => 1,
537 'status' => $topic['status'],
538 'private' => $topic['private'],
539 ];
540 $this->add( $postmeta );
541 }
542 }
543 }
544 }
545
546 public function after_edit_topic( $topic, $args, $forum ) {
547 $this->add_file( 'topic', $topic );
548
549 if( ! empty( $args['postmetas'] ) ) {
550 $fields_list = WPF()->post->get_topic_fields_list( false, $forum, ! WPF()->current_userid );
551 foreach( $args['postmetas'] as $metakey => $metavalue ) {
552 if( in_array( $metakey, $fields_list ) ) {
553 $postmeta = [
554 'metavalue' => $metavalue,
555 'forumid' => $topic['forumid'],
556 'topicid' => $topic['topicid'],
557 'is_first_post' => 1,
558 'status' => $topic['status'],
559 'private' => $topic['private'],
560 ];
561 if( $this->exists( $topic['first_postid'], $metakey ) ) {
562 $this->edit( $postmeta, [
563 'postid' => $topic['first_postid'],
564 'metakey' => $metakey,
565 ] );
566 } else {
567 $postmeta['postid'] = $topic['first_postid'];
568 $postmeta['metakey'] = $metakey;
569 $this->add( $postmeta );
570 }
571 }
572 }
573 }
574 }
575
576 public function after_add_post( $post, $topic, $forum ) {
577 $this->add_file( 'post', $post );
578
579 if( ! empty( $post['postmetas'] ) ) {
580 $fields_list = WPF()->post->get_post_fields_list( false, $forum, ! WPF()->current_userid );
581 foreach( $post['postmetas'] as $metakey => $metavalue ) {
582 if( in_array( $metakey, $fields_list ) ) {
583 $postmeta = [
584 'postid' => $post['postid'],
585 'metakey' => $metakey,
586 'metavalue' => $metavalue,
587 'forumid' => $post['forumid'],
588 'topicid' => $post['topicid'],
589 'is_first_post' => 0,
590 'status' => $post['status'],
591 'private' => $post['private'],
592 ];
593 $this->add( $postmeta );
594 }
595 }
596 }
597 }
598
599 public function after_edit_post( $post, $topic, $forum, $args ) {
600 $this->add_file( 'post', $post );
601
602 if( ! empty( $args['postmetas'] ) ) {
603 $fields_list = WPF()->post->get_post_fields_list( false, $forum, ! WPF()->current_userid );
604 foreach( $args['postmetas'] as $metakey => $metavalue ) {
605 if( in_array( $metakey, $fields_list ) ) {
606 $postmeta = [
607 'metavalue' => $metavalue,
608 'forumid' => $post['forumid'],
609 'topicid' => $post['topicid'],
610 'is_first_post' => 0,
611 'status' => $post['status'],
612 'private' => $post['private'],
613 ];
614 if( $this->exists( $post['postid'], $metakey ) ) {
615 $this->edit( $postmeta, [
616 'postid' => $post['postid'],
617 'metakey' => $metakey,
618 ] );
619 } else {
620 $postmeta['postid'] = $post['postid'];
621 $postmeta['metakey'] = $metakey;
622 $this->add( $postmeta );
623 }
624 }
625 }
626 }
627 }
628
629 public function after_move_topic( $topic, $forumid ) {
630 $this->edit( [ 'forumid' => $forumid ], [ 'topicid' => $topic['topicid'] ] );
631 }
632
633 public function after_merge_topic( $target, $current, $postids ) {
634 $sql = "UPDATE `" . WPF()->tables->postmeta . "` SET `topicid` = %d, `forumid` = %d, `private` = %d, `is_first_post` = 0 WHERE `topicid` = %d";
635 $sql = WPF()->db->prepare( $sql, $target['topicid'], $target['forumid'], (int) wpfval( $target, 'private' ), $current['topicid'] );
636 if( $postids ) $sql .= " AND `postid` IN(" . implode( ',', array_map( 'wpforo_bigintval', (array) $postids ) ) . ")";
637 WPF()->db->query( $sql );
638 }
639
640 public function after_delete_post( $post ) {
641 $this->delete( [ 'postid' => $post['postid'] ] );
642 }
643
644 public function after_post_status_update( $post, $status ) {
645 $this->edit( [ 'status' => $status ], [ 'postid' => $post['postid'] ] );
646 }
647
648 public function after_topic_private_update( $topicid, $private ) {
649 $this->edit( [ 'private' => $private ], [ 'topicid' => $topicid ] );
650 }
651
652 public function after_is_first_post_update( $postid, $is_first_post ) {
653 $this->edit( [ 'is_first_post' => $is_first_post ], [ 'postid' => $postid ] );
654 }
655 }
656