PluginProbe
CatFolders – WordPress Media Library Folders & Categories / trunk
CatFolders – WordPress Media Library Folders & Categories vtrunk
2.5.6 2.5.5 trunk 1.6.1 1.8 1.9 2.0 2.2 2.3.1 2.3.2 2.4.4 2.4.7 2.4.8 2.4.9 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4
catfolders / includes / Models / FolderModel.php

FolderModel.php in CatFolders – WordPress Media Library Folders & Categories trunk, at includes/Models/FolderModel.php

592 lines 14.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace CatFolders\Models;
3
4 use TenQuality\WP\Database\Abstracts\DataModel;
5 use TenQuality\WP\Database\Traits\DataModelTrait;
6 use TenQuality\WP\Database\QueryBuilder;
7
8 use CatFolders\Core\Base;
9
10 defined( 'ABSPATH' ) || exit;
11
12 class FolderModel extends DataModel {
13 use DataModelTrait;
14
15 const TABLE = Base::CAT_FOLDERS_TABLE;
16 const TABLE_RELATIONSHIP = Base::CAT_FOLDERS_TABLE_POSTS;
17
18 protected $table = self::TABLE;
19 protected $primary_key = 'id';
20
21 protected $attributes = array(
22 'title',
23 'parent',
24 'type',
25 'ord',
26 'created_by',
27 );
28
29 protected function protected_properties() {
30 return array( 'created_at', 'updated_at' );
31 }
32
33 public static function createFolder( $attributes = array() ) {
34 $defaults = array(
35 'id' => null,
36 'title' => '',
37 'parent' => 0,
38 'type' => 'attachment',
39 'ord' => null,
40 'created_by' => null,
41 );
42
43 $attributes = wp_parse_args( $attributes, $defaults );
44 $ordMax = self::builder()
45 ->select( 'IFNULL((MAX(ord) + 1),0)' )
46 ->where(
47 array(
48 'parent' => $attributes['parent'],
49 'created_by' => apply_filters( 'catf_folder_created_by', 0 ),
50 )
51 )
52 ->value();
53
54 $insertArr = array(
55 'title' => $attributes['title'],
56 'parent' => $attributes['parent'],
57 'type' => $attributes['type'],
58 'ord' => is_null( $attributes['ord'] ) ? $ordMax : $attributes['ord'],
59 'created_by' => is_null( $attributes['created_by'] ) ? apply_filters( 'catf_folder_created_by', 0 ) : $attributes['created_by'],
60 );
61
62 if ( ! is_null( $attributes['id'] ) ) {
63 $insertArr['id'] = $attributes['id'];
64 }
65
66 $insert = self::insert( $insertArr );
67
68 return array(
69 'title' => $attributes['title'],
70 'id' => strval( $insert->id ),
71 'key' => strval( $insert->id ),
72 'value' => strval( $insert->id ),
73 'type' => $attributes['type'],
74 'parent' => $attributes['parent'],
75 'children' => array(),
76 'data-count' => 0,
77 'data-parent' => $attributes['parent'],
78 'data-id' => strval( $insert->id ),
79 );
80 }
81
82 public static function updateToMaxOrd( $folder_id, $parent ) {
83 $ordMax = self::builder()
84 ->select( 'MAX(ord) + 1' )
85 ->where(
86 array(
87 'parent' => $parent,
88 'created_by' => apply_filters( 'catf_folder_created_by', 0 ),
89 )
90 )
91 ->value();
92
93 self::builder()
94 ->set( array( 'ord' => $ordMax ) )
95 ->where( array( 'id' => $folder_id ) )
96 ->update();
97 // $wpdb->query(
98 // $wpdb->prepare( "UPDATE {$wpdb->prefix}catf_folder SET ord = (SELECT MAX(ord) + 1 FROM {$wpdb->prefix}catf_folder where parent = %d) where id = %d", $parentId, $nodeId )
99 // );
100 }
101
102 public static function create_or_get( $name, $parent ) {
103 $check = self::detail( $name, $parent );
104 if ( is_null( $check ) ) {
105 $new = self::createFolder(
106 array(
107 'title' => $name,
108 'parent' => $parent,
109 'ord' => 0,
110 )
111 );
112 return $new['id'];
113 } else {
114 return (int) $check->id;
115 }
116 }
117
118 public static function updateFolder( $id, $attrs ) {
119 return self::builder()
120 ->set( $attrs )
121 ->where( array( 'id' => $id ) )
122 ->update();
123 }
124
125 public static function updatePositionAndParent( $folder_id, $new_position, $new_parent ) {
126 $old_data = self::builder()
127 ->select( 'parent, ord' )
128 ->where(
129 array(
130 'id' => $folder_id,
131 )
132 )
133 ->first();
134 if ( isset( $old_data->parent ) && isset( $old_data->ord ) ) {
135 $update_data = array();
136 if ( $old_data->ord != $new_position ) {
137 $update_data['ord'] = $new_position;
138 }
139 if ( $old_data->parent != $new_parent ) {
140 $update_data['parent'] = $new_parent;
141 }
142
143 if ( count( $update_data ) > 0 ) {
144 // Update that folder first
145 self::builder()
146 ->set( $update_data )
147 ->where( array( 'id' => $folder_id ) )
148 ->update();
149 }
150
151 if ( $old_data->ord != $new_position ) {
152 // Then update ord of folders related to that folder
153 $raw_update = '';
154 $where_ord = array();
155 if ( $new_position < $old_data->ord ) {
156 $raw_update = 'ord = ord + 1';
157 $where_ord = array(
158 'operator' => 'BETWEEN',
159 'key' => $new_position,
160 'key_b' => $old_data->ord,
161 );
162 } elseif ( $new_position > $old_data->ord ) {
163 $raw_update = 'ord = ord - 1';
164 $where_ord = array(
165 'operator' => 'BETWEEN',
166 'key' => $old_data->ord,
167 'key_b' => $new_position,
168 );
169 }
170 if ( '' != $raw_update ) {
171 self::builder()
172 ->set(
173 array(
174 'raw' => $raw_update,
175 )
176 )
177 ->where(
178 array(
179 'ord' => $where_ord,
180 'id' => array(
181 'operator' => '<>',
182 'value' => $folder_id,
183 ),
184 'created_by' => apply_filters( 'catf_folder_created_by', 0 ),
185 )
186 )
187 ->update();
188 }
189 }
190 }
191 return false;
192 }
193
194 public static function deleteFolder( $ids ) {
195 if ( is_array( $ids ) && count( $ids ) > 0 ) {
196 $ids = array_map( 'intval', $ids );
197
198 // Get children
199 $all_ids = array_merge( $ids, self::get_children_ids( $ids ) );
200
201 if ( count( $all_ids ) > 0 ) {
202 $all_ids = implode( ',', $all_ids );
203
204 //delete folder
205 self::builder()
206 ->from( self::TABLE )
207 ->where(
208 array( 'raw' => 'id IN (' . $all_ids . ')' )
209 )
210 ->delete();
211
212 //delete relationship
213 self::builder()
214 ->from( self::TABLE_RELATIONSHIP )
215 ->where(
216 array( 'raw' => 'folder_id IN (' . $all_ids . ')' )
217 )
218 ->delete();
219 }
220 }
221 return self::get_folders_counter( true );
222 }
223
224 public static function get_children_ids( $folder_ids ) {
225 if ( is_array( $folder_ids ) ) {
226 $folder_ids = array_map( 'intval', $folder_ids );
227 //remove duplicates
228 $folder_ids = array_unique( $folder_ids );
229 //remove 0
230 $folder_ids = array_filter( $folder_ids, function( $value ) {
231 return $value !== 0;
232 } );
233 $folder_ids = implode( ',', $folder_ids );
234 } else {
235 $folder_ids = explode( ',', $folder_ids );
236 $folder_ids = array_map( 'intval', $folder_ids );
237 $folder_ids = array_unique( $folder_ids );
238 $folder_ids = array_filter( $folder_ids, function( $value ) {
239 return $value !== 0;
240 } );
241 $folder_ids = implode( ',', $folder_ids );
242 }
243 $res = array();
244
245 $children = self::builder()
246 ->select( 'id' )
247 ->from( self::TABLE )
248 ->where(
249 array( 'raw' => 'parent IN (' . $folder_ids . ')' )
250 )
251 ->col();
252 if ( count( $children ) > 0 ) {
253 $res = array_merge( $children, self::get_children_ids( $children ) );
254 }
255
256 return $res;
257 }
258
259 public static function getFolderCount() {
260 return self::builder()
261 ->select( 'COUNT(id)' )
262 ->from( self::TABLE )
263 ->where(
264 array(
265 'created_by' => apply_filters( 'catf_folder_created_by', 0 ),
266 )
267 )
268 ->value();
269 }
270
271 public static function get_folders_counter( $format = false ) {
272 $catf_table = self::TABLE;
273 $catf_posts_table = self::TABLE_RELATIONSHIP;
274
275 $query = self::builder()
276 ->select( 'folder_id, count(post_id) as counter' )
277 ->from( "{$catf_posts_table} as `catf_posts`" )
278 ->join(
279 "{$catf_table} as `catf`",
280 array(
281 array(
282 'key_a' => 'catf_posts.folder_id',
283 'key_b' => 'catf.id',
284 ),
285 array(
286 'key' => 'catf.created_by',
287 'value' => apply_filters( 'catf_folder_created_by', 0 ),
288 ),
289 ),
290 'INNER'
291 )
292 ->group_by( 'folder_id' );
293
294 $query = apply_filters( 'catf_folder_counter_query', $query );
295
296 $counters = $query->get( OBJECT_K );
297
298 if ( $format ) {
299 $countersFormat = array();
300 foreach ( $counters as $counter ) {
301 $countersFormat[ $counter->folder_id ] = $counter->counter;
302 }
303 return $countersFormat;
304 }
305
306 return $counters;
307 }
308
309 public static function get_all_counter() {
310 $query = QueryBuilder::create();
311
312 $query = $query->select( 'COUNT(ID)' )
313 ->from( 'posts as `posts`' )
314 ->where(
315 array(
316 'posts.post_type' => 'attachment',
317 'raw' => "(posts.post_status = 'inherit' OR posts.post_status = 'private')",
318 )
319 );
320
321 $query = apply_filters( 'catf_all_counter_query', $query );
322
323 return $query->value();
324 }
325
326 public static function group_parent_folders( $tree, $counters ) {
327 $group = array();
328 foreach ( $tree as $node ) {
329 $node->key = $node->id;
330 $node->{'data-count'} = isset( $counters[ $node->id ] ) ? $counters[ $node->id ]->counter : 0;
331 $node->{'data-parent'} = $node->parent;
332 $node->{'data-id'} = $node->id;
333 $node->value = $node->id;
334 $group[ $node->parent ][] = $node;
335 }
336
337 return $group;
338 }
339
340 public static function get_all( $order = null, $flat = false ) {
341 $results = self::builder()
342 ->select( '*' )
343 ->where(
344 array(
345 'created_by' => apply_filters( 'catf_folder_created_by', 0 ),
346 )
347 )
348 ->order_by( 'ord+0' )
349 ->get();
350
351 if ( is_array( $order ) && isset( $order['orderBy'] ) && isset( $order['orderType'] ) ) {
352 if ( 'name' == $order['orderBy'] ) {
353 if ( 'asc' == $order['orderType'] ) {
354 usort( $results, array( __CLASS__, 'sort_natural_asc' ) );
355 }
356 if ( 'desc' == $order['orderType'] ) {
357 usort( $results, array( __CLASS__, 'sort_natural_desc' ) );
358 }
359 }
360 }
361
362 $tree = array();
363
364 if ( $flat ) {
365 foreach ( $results as $result ) {
366 $result->key = $result->id;
367 $tree[] = $result;
368 }
369 return array(
370 'tree' => $tree,
371 );
372 }
373
374 $counters = self::get_folders_counter();
375 $group = self::group_parent_folders( $results, $counters );
376
377 $tree = self::get_nested_tree( $group, 0, $counters );
378 $json = array(
379 'allCounter' => self::get_all_counter(),
380 'tree' => $tree,
381 );
382
383 return $json;
384 }
385 private static function sort_natural_asc( $a, $b ) {
386 return strnatcasecmp( $a->title, $b->title );
387 }
388 private static function sort_natural_desc( $a, $b ) {
389 return strnatcasecmp( $a->title, $b->title ) * -1;
390 }
391 public static function set_attachments( $folderId, $imgIds, $getCounter = true ) {
392 global $wpdb;
393
394 $imgIds = apply_filters( 'catf_attachment_ids_to_folder', $imgIds );
395
396 if ( is_array( $imgIds ) && is_numeric( $folderId ) ) {
397 $imgIds = array_map( 'intval', $imgIds );
398 //remove duplicates
399 $imgIds = array_unique( $imgIds );
400 //remove 0
401 $imgIds = array_filter( $imgIds, function( $value ) {
402 return $value !== 0;
403 } );
404
405 $attachmentIds = implode( ',', $imgIds );
406 //get folders of these attachment ids
407 $old_folder_ids = self::builder()
408 ->select( 'folder_id' )
409 ->from( self::TABLE_RELATIONSHIP )
410 ->where(
411 array(
412 'raw' => 'post_id IN (' . $attachmentIds . ')',
413 )
414 )
415 ->col();
416 if ( count( $old_folder_ids ) > 0 ) {
417 $folder_ids_in_this_mode = self::builder()
418 ->select( 'id' )
419 ->where(
420 array(
421 'raw' => 'id IN (' . implode( ',', $old_folder_ids ) . ')',
422 'created_by' => apply_filters( 'catf_folder_created_by', 0 ),
423 )
424 )
425 ->col();
426 if ( count( $folder_ids_in_this_mode ) > 0 ) {
427 self::builder()->from( self::TABLE_RELATIONSHIP )
428 ->where(
429 array(
430 'raw' => 'post_id IN (' . $attachmentIds . ') AND folder_id IN (' . implode( ',', $folder_ids_in_this_mode ) . ')',
431 )
432 )
433 ->delete();
434 }
435 }
436
437 if ( $folderId > 0 ) {
438 $prepareInsert = '';
439 foreach ( $imgIds as $imgId ) {
440 $prepareInsert .= "( $folderId, $imgId ),";
441 }
442 $prepareInsert = rtrim( $prepareInsert, ',' );
443
444 // For performance reasons, we have to use raw function instead of self::insert
445 self::builder()->raw( 'INSERT INTO ' . $wpdb->prefix . self::TABLE_RELATIONSHIP . " ( folder_id, post_id ) VALUES $prepareInsert" );
446 }
447 }
448
449 if ( $getCounter ) {
450 $folderCounters = self::get_folders_counter( true );
451 return $folderCounters;
452 }
453 }
454
455 public static function unset_attachment( $postId ) {
456
457 self::builder()
458 ->from( self::TABLE_RELATIONSHIP )
459 ->where(
460 array( 'post_id' => (int) $postId )
461 )
462 ->delete();
463 }
464
465 private static function get_nested_tree( $group, $parent = 0 ) {
466 $tree = array();
467
468 if ( empty( $group ) ) {
469 return $tree;
470 }
471
472 if ( isset( $group[ $parent ] ) ) {
473 foreach ( $group[ $parent ] as $node ) {
474 $node->children = isset( $group[ $node->id ] ) ? self::get_nested_tree( $group, $node->id ) : array();
475 $tree[] = $node;
476 }
477 }
478
479 return $tree;
480 }
481
482 public static function getRelationsWithFolderUser( $clauses ) {
483 global $wpdb;
484
485 $attachment_in_folder = $wpdb->prepare(
486 "SELECT post_id
487 FROM {$wpdb->prefix}catfolders_posts AS catf_af
488 JOIN {$wpdb->prefix}catfolders AS catf ON catf_af . folder_id = catf . id
489 GROUP BY post_id
490 HAVING FIND_IN_SET(%d, GROUP_CONCAT( created_by ) )",
491 apply_filters( 'catf_folder_created_by', 0 )
492 );
493
494 $clauses['where'] .= " AND {$wpdb->posts} . ID NOT IN( $attachment_in_folder ) ";
495
496 return $clauses;
497 }
498
499 public static function getAttachmentRelationship() {
500 $res = array();
501
502 $relations = self::builder()
503 ->select( 'post_id' )
504 ->select( 'GROUP_CONCAT(`folder_id`) as folders' )
505 ->from( self::TABLE_RELATIONSHIP )
506 ->group_by( 'folder_id' )
507 ->get();
508
509 foreach ( $relations as $k => $v ) {
510 $res[ $v->post_id ] = array_map( 'intval', explode( ',', $v->folders ) );
511 }
512 return $res;
513 }
514
515 public static function detail( $name, $parent ) {
516 return self::builder()
517 ->select( '*' )
518 ->where(
519 array(
520 'title' => $name,
521 'parent' => $parent,
522 'created_by' => apply_filters( 'catf_folder_created_by', 0 ),
523 )
524 )
525 ->first();
526 }
527
528 public static function isFolderExist( $folderId ) {
529 $isExist = self::builder()
530 ->from( self::TABLE )
531 ->where(
532 array( 'id' => (int) $folderId )
533 )
534 ->value();
535 return is_null( $isExist ) ? false : true;
536 }
537
538 public static function getFolderFromPostId( $postId ) {
539 return self::builder()
540 ->select( 'folder_id' )
541 ->from( self::TABLE_RELATIONSHIP )
542 ->where(
543 array( 'post_id' => intval( $postId ) )
544 )->group_by( 'folder_id' )->value();
545 }
546
547 public static function getPostIdsFromFolder( $folderIds ) {
548 $folderIds = \implode( ',', $folderIds );
549 $query = self::builder()
550 ->select( 'post_id' )
551 ->from( self::TABLE_RELATIONSHIP )
552 ->where(
553 array( 'raw' => 'folder_id IN (' . $folderIds . ')' )
554 );
555 return $query->get( ARRAY_A );
556 }
557
558 /**
559 * Static function isExistingFolderName
560 *
561 * @param mixed $folderId if $folderId = 0, it would be created a new folder, else it would be update an exist folder
562 * @param mixed $title
563 * @param mixed $parent
564 * @return void
565 */
566 public static function isExistingFolderName( $folderId, $title, $parent ) {
567 $isExist = self::builder()
568 ->from( self::TABLE )
569 ->where(
570 array(
571 'title' => $title,
572 'parent' => intval( $parent ),
573 'id' => array(
574 'operator' => '<>',
575 'value' => $folderId,
576 ),
577 )
578 )
579 ->value();
580
581 return is_null( $isExist ) ? false : true;
582 }
583 public static function getFolderFromFolderId( $folderId ) {
584 return self::builder()
585 ->select( 'title' )
586 ->from( self::TABLE )
587 ->where(
588 array( 'id' => intval( $folderId ) )
589 )->value();
590 }
591 }
592