PluginProbe
MaxButtons – Create buttons / 6.26
MaxButtons – Create buttons v6.26
6.23 6.24 6.25 6.26 6.26.1 6.27 6.28 6.3 6.4 6.5 6.6 6.7 6.8 6.9 7.0 7.1 7.1.1 7.1.2 7.1.3 7.10 7.11 7.13 7.13.1 7.13.2 7.13.3 All 100 releases
maxbuttons / classes / collection.php

collection.php in MaxButtons – Create buttons 6.26, at classes/collection.php

769 lines 17.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace MaxButtons;
3 defined('ABSPATH') or die('No direct access permitted');
4
5 use \simple_html_dom as simple_html_dom;
6
7 class maxCollection
8 {
9 protected $collection_type = 'none';
10 protected $uses_blocks = array();
11 protected $blocks = array(); // array of objects
12
13 protected $collection_id = 0;
14
15 // layout functions
16 protected $cssParser;
17 protected $collection_js;
18
19 // derived from button class, prepare for maxcss parser
20 //protected $collection_css = array('normal' => array() ,':hover' => array() ,':visited' => array(), "responsive" => array());
21 protected $buttons = array(); // array of buttons, ready for display - pre parse
22
23
24 /* Constructor
25 Sets the blocks used in this collection. These are mostly derived from subclasses of the specific collection types.
26 */
27 public function __construct()
28 {
29 maxCollections::checkExpireTrans();
30
31 foreach($this->uses_blocks as $block_name )
32 {
33 $block = maxCollections::getBlock($block_name);
34 if ($block)
35 {
36 $block->setCollection($this);
37 $block->set(array()); // defaults
38 $this->blocks[$block_name] = $block;
39 }
40 }
41
42
43 }
44 /* Get all buttons that are currently loaded */
45 public function getLoadedButtons()
46 {
47 return $this->buttons;
48 }
49
50
51
52 /* Get a certain block class by name */
53 public function getBlock($blockname)
54 {
55
56 if (isset($this->blocks[$blockname]))
57 return $this->blocks[$blockname];
58 else
59 return false;
60 }
61
62 /* Get the type of the collection */
63 public function getType()
64 {
65 return $this->collection_type;
66 }
67
68 /* Get the ID of the collection */
69 public function getID()
70 {
71 return $this->collection_id;
72 }
73
74 /** Get the MaxCSSParser classes which handles SCSS. This function is derived from the one in Button class */
75 public function getCSSParser()
76 {
77 if (! $this->cssParser)
78 $this->cssParser = new maxCSSParser();
79
80 return $this->cssParser;
81 }
82
83 /** Set the collection by ID
84 @param $collection_id ID of the collection stored in database
85 */
86 public function set($collection_id)
87 {
88 $this->collection_id = $collection_id;
89
90 // make every block set it's stuff.
91 $values = $this->get_meta($collection_id);
92
93 foreach($this->blocks as $block)
94 {
95
96 $block->set($values);
97 // run every blocks setter
98
99 }
100 }
101
102
103 /** Interface for handling AJAX requests to communicate with the seperate blocks.
104 @param $result The initial (default) result to JSON back
105 @param $block_name The name of the block in question
106 @param $action The name of the block function to call
107 @param $data Data specified by JS to use for this function
108 @return $result - Standardized result block including error, body
109 */
110 public function doBlockAJAX($result, $block_name, $action, $data)
111 {
112 // core class is being called.
113 if ($block_name == 'collection')
114 {
115 $result = $this->$action($result, $data);
116 return $result;
117 }
118
119 if (isset($this->blocks[$block_name]))
120 {
121 $block= $this->blocks[$block_name];
122 $result = $block->$action($result, $data);
123 return $result;
124
125 }
126
127 $result["error"] = true;
128 $result["title"] = __("Error : Block was not there","maxbuttons");
129 return $result;
130 }
131
132 /** Save the collection data to the database. This will invoke the save functions of the blocks itself to gather, verify and manipulate data */
133 public function save($post)
134 {
135 $data = array();
136
137 // Collection id needed to save meta data and others.
138 if ($this->collection_id == 0) // assume new
139 {
140 $collection_id = $this->getNewCollectionID();
141
142 $this->collection_id = $collection_id;
143 }
144
145 // run this by each block and collect data
146 foreach($this->blocks as $block)
147 {
148 $data = $block->save_fields($data, $post);
149 }
150
151 $data = apply_filters("mb_col_save_collection_data", $data, $post);
152
153 // clean what was not set
154 $this->clean_meta($data);
155
156 // write data as a per block per key value into the database
157 foreach($data as $blockname => $blockdata)
158 {
159 // seems dangerous
160 $meta_id = $this->update_meta($this->collection_id, $blockname, $blockdata);
161
162 }
163
164 return $this->collection_id;
165
166 }
167
168 // remove post meta not in data post.
169 public function clean_meta($data)
170 {
171 $data_blocks = array_keys($data);
172
173
174 $meta = $this->get_meta($this->collection_id);
175
176
177 foreach($meta as $meta_key => $values)
178 {
179 if (! in_array($meta_key, $data_blocks))
180 {
181 $this->delete_meta($this->collection_id, $meta_key);
182 }
183
184 }
185
186 }
187
188 protected function update_meta($collection_id, $collection_key, $collection_value)
189 {
190 global $wpdb;
191 $table = maxUtils::get_collection_table_name();
192
193 if ($collection_value == '') return; // no data no database entry
194 if (is_array($collection_value) && count($collection_value) == 0) return; // same for empty arrays
195
196 if (is_array($collection_value))
197 $collection_value = json_encode($collection_value);
198
199 if ($collection_id == 0) // assume new
200 {
201 $collection_id = $this->getNewCollectionID();
202
203 $this->collection_id = $collection_id;
204 }
205
206 $sql = "SELECT meta_id from $table where collection_id = %d and collection_key = %s ";
207 $sql = $wpdb->prepare($sql, $collection_id, $collection_key);
208
209 $results = $wpdb->get_results($sql, ARRAY_A);
210
211 if (count($results) == 1)
212 {
213 $meta_id = $results[0]["meta_id"];
214 $data = array("collection_value" => $collection_value); // what's being updated
215 $where = array("meta_id" => $meta_id);
216
217 $wpdb->update($table, $data, $where);
218 return $meta_id;
219 }
220 if (count($results) == 0)
221 {
222 $data = array("collection_value" => $collection_value,
223 "collection_key" => $collection_key,
224 "collection_id" => $collection_id,
225 );
226
227 $meta_id = $wpdb->insert($table, $data);
228
229 return $meta_id;
230 }
231 else
232 {
233 MB()->add_notice("error", __("Update Collection meta has multiple rows, this should not be possible.","maxbuttons"));
234
235 }
236 }
237
238
239 /** Determine the next ID for collection */
240 protected function getNewCollectionID()
241 {
242 global $wpdb;
243 $table = maxUtils::get_collection_table_name();
244
245 $sql = "SELECT max(collection_id) as max from $table";
246
247 $max = intval($wpdb->get_var($sql));
248
249 $max = $max + 1;
250 return $max;
251 }
252
253 protected function delete_meta($collection_id, $collection_key)
254 {
255 if (intval($collection_id) > 0 && $collection_key != "")
256 {
257 global $wpdb;
258 // delete_post_meta($collection_id, $collection_key);
259 $table = maxUtils::get_collection_table_name();
260 $where = array("collection_id" => $collection_id,
261 "collection_key" => $collection_key
262 );
263 $where_format = array("%d", "%s");
264 $wpdb->delete($table, $where, $format);
265
266 }
267 }
268
269
270 /** Delete the collection. This is done via AJAX request */
271 public function delete($result, $data)
272 {
273 global $wpdb;
274 if(! $this->collection_id > 0)
275 return false;
276
277 $picker = $this->getBlock("picker");
278 $picker_data = $picker->get();
279 $buttons = $picker_data["selection"];
280 $button = MB()->getClass("button");
281
282 $buttons_removed = 0;
283
284 foreach($buttons as $button_id)
285 {
286 $deleted = $this->maybe_delete_button($button_id);
287 if ($deleted)
288 $buttons_removed++;
289
290 }
291
292 $table = maxUtils::get_collection_table_name();
293 $where = array("collection_id" => $this->collection_id);
294 $where_format = array("%d");
295 $wpdb->delete($table, $where, $where_format);
296
297 $result["data"]["body"] = __("The collection is removed","maxbuttons");
298 $result["data"]["title"] = __("Removed","maxbuttons");
299 $result["data"]["buttons_removed"] = $buttons_removed;
300 $result["data"]["collection_id"] = $this->collection_id;
301 return $result;
302
303
304 }
305
306 /** On deletion of a collection check for each button if this is an auto-generated button just made for this collection and if
307 no changes where made to this button. If both conditions are true, remove the button */
308 function maybe_delete_button($button_id)
309 {
310 $button = MB()->getClass("button");
311
312 $button->set($button_id);
313 $button_data = $button->get();
314
315 $collection_id= $this->collection_id;
316
317 // remove unedited buttons created for this collection - use with care.
318 if (isset($button_data["meta"]["user_edited"]))
319 {
320 $created_source = (isset($button_data["meta"]["created_source"])) ? $button_data["meta"]["created_source"] : '';
321 if ($button_data["meta"]["user_edited"] === false && $created_source == 'collection')
322 {
323 $in_collections = $button_data["meta"]["in_collections"];
324
325 $key = array_search($collection_id, $in_collections);
326
327 if ($key !== false)
328 {
329 unset($button_data["meta"]["in_collections"][$key]);
330
331 if (count($button_data["meta"]["in_collections"]) == 0)
332 { $button->delete($button_id);
333 return true;
334 }
335 else
336 {
337 if ($button_id > 0) // safety.
338 $button->update($button_data);
339 }
340 }
341 }
342
343
344 }
345 return false;
346 }
347
348 function get_meta ($collection_id, $collection_key = '')
349 {
350 global $wpdb;
351 $table = maxUtils::get_collection_table_name();
352
353 $prepare = array($collection_id);
354
355 $sql = "SELECT * from $table where collection_id = %d ";
356 if ($collection_key != '')
357 {
358 $sql .= " and collection_key = %s ";
359 array_push($prepare, $collection_key);
360
361 }
362
363 $sql = $wpdb->prepare($sql, $prepare);
364
365 $results = $wpdb->get_results($sql, ARRAY_A);
366
367 $result_array = array(); // format array by field name = values to feed blocks and others.
368 if (! is_null($results))
369 {
370 $nr = array();
371 foreach($results as $row)
372 {
373 $key = $row["collection_key"];
374 /* A field can be either plain text or JSON */
375 if(json_decode($row["collection_value"]))
376 $value = json_decode($row["collection_value"], true);
377 else
378 $value = $row["collection_value"];
379 $result_array[$key] = $value;
380
381 //$row["collection_value"] = unserialize($row["collection_value"]);
382 }
383
384 return $result_array;
385 }
386 else
387 {
388 return false;
389 }
390 }
391
392 function display($args = array())
393 {
394 maxUtils::startTime('collection-display');
395 $defaults = array(
396 "preview" => false,
397 "echo" => true,
398 "style_tag" => false,
399 "compile" => false,
400 "js_tag" => true,
401 "load_type" => "footer",
402 );
403
404 $args = wp_parse_args($args, $defaults);
405
406 $cache = MaxCollections::checkCachedCollection($this->collection_id);
407
408 if (! $cache)
409 {
410 $cssParser = $this->getCSSParser();
411 $domObj = $this->parse($args);
412 $css = $this->parseCSS($args);
413
414 $js = $this->parseJS($args);
415
416 $output = $domObj->save();
417 unset($domObj);
418
419
420 // CSS & JS output control
421 $output .= $this->displayCSS($css, $args);
422 $output .= $this->displayJS($js, $args);
423 }
424 else
425 $output = $cache;
426
427 MaxCollections::addCachedCollection($this->collection_id, $output);
428
429 maxUtils::endTime('collection-display');
430
431 if ($args["echo"])
432 {
433 echo $output;
434 }
435 else
436 {
437 return $output;
438 }
439
440 }
441
442 public function displayCSS($css, $args = array() ) // $echo = true, $style_tag = true)
443 {
444
445 $default = array(
446 "echo" => true,
447 "style_tag" => true,
448 "load_type" => "footer",
449 );
450 $args = wp_parse_args($args, $default);
451 if ($args['load_type'] == 'inline')
452 $args['style_tag'] =true;
453
454 $output = '';
455
456 if ($args["style_tag"])
457 $output .= "<style type='text/css'>";
458
459 $output .= $css;
460
461 if ($args["style_tag"])
462 $output .= "</style>";
463
464
465 if ($args["load_type"] == 'footer')
466 {
467
468 do_action('mb-footer','collection-' . $this->collection_id, $output);
469 }
470 elseif ($args["load_type"] == 'inline')
471 {
472 if ($args["echo"]) echo $output;
473 else return $output;
474
475 }
476
477 }
478
479 public function displayJS($js, $args = array() ) // $echo = true, $style_tag = true)
480 {
481 $default = array(
482 "echo" => true,
483 "js_tag" => true,
484 "load_type" => "footer",
485 "preview" => false,
486 );
487
488
489 $args = wp_parse_args($args, $default);
490
491 if ($args["preview"])
492 return; // no js on previews.
493
494 $output = '';
495
496 if (count($js) == 0)
497 return; // no output, holiday
498
499 if ($args["js_tag"])
500 {
501 $output .= "<script type='text/javascript'> ";
502
503 }
504
505 foreach($js as $index => $code)
506 {
507 $output .= $code;
508 }
509
510 if ($args["js_tag"])
511 {
512 $output .= " // }
513 // }
514 // window.onload = MBcollection" . $this->collection_id . "();
515 </script> ";
516 }
517
518
519 if ($args["load_type"] == 'footer')
520 {
521
522 do_action('mb-footer','collection-' . $this->collection_id, $output, "js");
523 }
524 elseif ($args["load_type"] == 'inline')
525 {
526 if ($args["echo"]) echo $output;
527 else return $output;
528
529 }
530 }
531
532 public function display_field_map()
533 {
534 $map = array();
535 foreach ($this->blocks as $block)
536 {
537 $map = $block->map_fields($map);
538 }
539 echo "<script language='javascript'>";
540 echo "var collectionFieldMap = '" . json_encode($map) . "';" ;
541 echo "</script>";
542 }
543
544 /* Parses the collection, via the blocks */
545 function parse($args)
546 {
547 $preview = isset($args["preview"]) ? $args["preview"] : false;
548
549 $domObj = new simple_html_dom();
550 $collection_id = $this->collection_id;
551
552 $node = "<div class='maxcollection maxcollection-" . $collection_id . "' data-collection='" . $collection_id . "'>
553 </div>";
554 $node = apply_filters("mb-col-basic-container",$node);
555 $domObj->load($node);
556
557 // use picker to get button classes in array
558 $picker = $this->getBlock("picker");
559 $this->buttons = $picker->getButtons();
560
561 // changes to buttons in this function
562 maxUtils::startTime('collection-parse-parsebuttons');
563 foreach($this->blocks as $block)
564 {
565 $block->setPreview($preview);
566 $this->buttons = $block->parseButtons($this->buttons);
567
568
569 }
570 maxUtils::endTime('collection-parse-parsebuttons');
571
572 maxUtils::startTime('collection-parse-blockparse');
573 // general parsing
574
575 foreach($this->blocks as $block)
576 {
577 $domObj = $block->parse($domObj, $args);
578 }
579 maxUtils::endTime('collection-parse-blockparse');
580
581 $this->buttons = array();
582
583 $cssParser = $this->getCSSParser();
584 $domObj->load($domObj->save() );
585 $cssParser->loadDom($domObj);
586
587 return $domObj;
588 }
589 function parseCSS($args)
590 {
591 $css = array();
592
593 foreach($this->blocks as $block)
594 {
595 $css = $block->parseCSS($css, $args);
596 }
597
598 $css = $this->getCSSParser()->parse($css);
599
600 return $css;
601 }
602
603 function parseJS($args)
604 {
605 $js = array();
606
607 $defaults = array("preview" => false,
608 );
609
610 $args = wp_parse_args($args, $defaults);
611
612 if ($args["preview"])
613 return false; // no js on previews
614
615 foreach($this->blocks as $block)
616 {
617 $js = $block->parseJS($js, $args);
618
619 }
620
621 return $js;
622 }
623
624
625 function shortcode($atts, $content = null)
626 {
627
628 // ugly -need to rework logic here.
629 //$collection = maxCollections::getCollection('social');
630 $display_args = shortcode_atts(array(
631 "echo" => false,
632 "mode" => "normal",
633 "nocache" => false,
634 "style" => 'footer',
635 ),
636
637 $atts);
638
639 $collection_id = $this->collection_id;
640
641 //$this->set($collection_id);
642 $display_args["compile"] = $display_args["nocache"];
643 $display_args['load_type'] = $display_args['style'];
644 unset($display_args['style']);
645 unset($display_args["nocache"]);
646
647 $output = $this->display($display_args);
648
649 return $output;
650 }
651
652
653 // Get the pack definition that are present in the system.
654 function editor_getPacks()
655 {
656 //$pack_paths = apply_filters('mb-col-pack-paths', array(MB()->get_plugin_path() . "/") );
657 $packs["maxbuttons"]["func"] = array($this, 'editor_getButtons');
658 $packs["maxbuttons"]["tab"] = __("Your MaxButtons","maxbuttons");
659 return $packs;
660
661 }
662
663 public function ajax_getButtons($result, $data)
664 {
665 $packs = $this->editor_getPacks();
666 $req_pack= $data["pack"];
667
668 foreach($packs as $index => $pack_data)
669 {
670 if ($req_pack == $index)
671 {
672 $buttons = call_user_func($pack_data["func"], $index, $data);
673
674 }
675 }
676 $output = '';
677
678
679 $page_args = array();
680 if (isset($data["paged"]))
681 {
682 $page_args["paged"] = $data["paged"];
683 }
684
685 if ($req_pack == 'maxbuttons')
686 {
687 $page_args["limit"] = 18;
688 ob_start();
689 do_action("mb-display-meta");
690 do_action("mb-display-pagination", $page_args);
691 $pagination = "<div class='tablenav top'>" .ob_get_contents() . "</div>";
692 ob_end_clean();
693
694 $output .= $pagination;
695 }
696
697 foreach($buttons as $button)
698 {
699 $button_data = $button->get();
700
701 $button_id = $button->getID();
702 $name = $button->getName();
703
704 $meta = isset($button_data["meta"]) ? $button_data["meta"] : array();
705 //do_action('mb-data-load',$button_data); // weakness of the bubbling filter model
706
707 $output .= "<div class='item shortcode-container' data-id='$button_id'> ";
708 $output .= $button->display(array("mode" => "preview", 'echo' => false, 'load_css' => 'inline') ); //"mode" => "preview", "compile" => true,
709 $output .= "<span class='button_data'>" . base64_encode(json_encode($button_data)) . "</span>";
710 $output .= "<span class='button_name'>" . $name . "</span>";
711 $output .= "</div>";
712
713 }
714
715 if ($req_pack == 'maxbuttons')
716 {
717 $output .= $pagination;
718 }
719
720 $result["body"] = $output;
721 return $result;
722
723 }
724
725 // show the available buttons
726 function editor_getButtons($pack, $data)
727 {
728 $button_array = array();
729
730 $admin = MB()->getClass("admin");
731 $button = MB()->getClass("button");
732
733 $paged = (isset($data["paged"])) ? $data["paged"] : 1;
734
735 $buttons = $admin->getButtons(array(
736 "orderby" => "id",
737 "order" => "DESC",
738 "paged" => $paged,
739 "limit" => 18,
740 ));
741
742
743 foreach($buttons as $btn)
744 {
745 $id = $btn["id"];
746 $b = MB()->getClass('button');
747 $b->clear();
748 $b->set($id);
749 $button_data = $b->get();
750 // exclude auto-generated non-user edited buttons.
751 if ( ! isset($button_data["meta"]["user_edited"]) || ($button_data["meta"]["user_edited"] == true || $button_data["meta"]["created_source"] != "collection"))
752 $button_array[] = $b; // the object
753 }
754 return $button_array;
755 }
756
757 function showBlocks()
758 {
759
760 foreach($this->blocks as $block)
761 {
762 echo $block->admin_fields();
763
764 }
765
766 }
767 } //class
768
769