Version Description
- Tested for 4.9.2
- Security - Added rel='noopener' for links opening in new window
- Fixed missing values on a template
Download this release
Release Info
Developer | basszje |
Plugin | WordPress Button Plugin MaxButtons |
Version | 6.27 |
Comparing to | |
See all releases |
Code changes from version 6.26.1 to 6.27
- blocks/basic.php +17 -1
- blocks/container.php +2 -3
- blocks/icon.php +1 -2
- blocks/tpl/radio.tpl +1 -1
- classes/button.php +407 -408
- classes/max-utils.php +233 -232
- classes/maxCSSParser.php +269 -266
- maxbuttons.php +3 -3
- readme.txt +14 -2
blocks/basic.php
CHANGED
@@ -146,17 +146,33 @@ class basicBlock extends maxBlock
|
|
146 |
|
147 |
$data = $this->data[$this->blockname];
|
148 |
$button_id = $this->data["id"];
|
|
|
149 |
|
150 |
$anchor = $domObj->find("a",0);
|
151 |
|
152 |
if (isset($data["nofollow"]) && $data["nofollow"] == 1)
|
153 |
-
|
|
|
|
|
|
|
|
|
154 |
// $buttonAttrs[] = "rel=nofollow";
|
|
|
155 |
if (isset($data["new_window"]) && $data["new_window"] == 1)
|
|
|
156 |
$anchor->target = "_blank";
|
|
|
|
|
|
|
157 |
if (isset($data['link_title']) && strlen($data['link_title']) > 0)
|
158 |
$anchor->title = $data['link_title'];
|
159 |
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
|
161 |
if (isset($data["url"]) && $data["url"] != '')
|
162 |
{
|
146 |
|
147 |
$data = $this->data[$this->blockname];
|
148 |
$button_id = $this->data["id"];
|
149 |
+
$rels = array();
|
150 |
|
151 |
$anchor = $domObj->find("a",0);
|
152 |
|
153 |
if (isset($data["nofollow"]) && $data["nofollow"] == 1)
|
154 |
+
{
|
155 |
+
$rels[] = 'nofollow';
|
156 |
+
$rels[] = 'noopener';
|
157 |
+
}
|
158 |
+
// $anchor->rel = "nofollow";
|
159 |
// $buttonAttrs[] = "rel=nofollow";
|
160 |
+
|
161 |
if (isset($data["new_window"]) && $data["new_window"] == 1)
|
162 |
+
{
|
163 |
$anchor->target = "_blank";
|
164 |
+
if (! in_array('noopener', $rels))
|
165 |
+
$rels[] = 'noopener';
|
166 |
+
}
|
167 |
if (isset($data['link_title']) && strlen($data['link_title']) > 0)
|
168 |
$anchor->title = $data['link_title'];
|
169 |
|
170 |
+
$rels = apply_filters('mb/button/rel', $rels);
|
171 |
+
|
172 |
+
if (count($rels) > 0)
|
173 |
+
{
|
174 |
+
$anchor->rel = implode(' ', $rels);
|
175 |
+
}
|
176 |
|
177 |
if (isset($data["url"]) && $data["url"] != '')
|
178 |
{
|
blocks/container.php
CHANGED
@@ -166,7 +166,6 @@ class containerBlock extends maxBlock
|
|
166 |
|
167 |
$admin->addField($container_width, 'start', 'end');
|
168 |
|
169 |
-
|
170 |
// Margin - trouble
|
171 |
$ptop = new maxField('number');
|
172 |
$ptop->label = __('Margin', 'maxbuttons');
|
@@ -221,11 +220,11 @@ class containerBlock extends maxBlock
|
|
221 |
$align->value= maxBlocks::getValue('container_alignment');
|
222 |
//$align->setDefault(maxBlocks::getDefault('container_alignment'));
|
223 |
$align->content = maxUtils::selectify($align->name, $maxbuttons_container_alignments, $align->value);
|
224 |
-
|
225 |
|
226 |
$admin->addField($align, 'start', 'end');
|
227 |
|
228 |
-
$admin->display_fields();
|
229 |
?>
|
230 |
|
231 |
</div>
|
166 |
|
167 |
$admin->addField($container_width, 'start', 'end');
|
168 |
|
|
|
169 |
// Margin - trouble
|
170 |
$ptop = new maxField('number');
|
171 |
$ptop->label = __('Margin', 'maxbuttons');
|
220 |
$align->value= maxBlocks::getValue('container_alignment');
|
221 |
//$align->setDefault(maxBlocks::getDefault('container_alignment'));
|
222 |
$align->content = maxUtils::selectify($align->name, $maxbuttons_container_alignments, $align->value);
|
223 |
+
//$align->output('start', 'end');
|
224 |
|
225 |
$admin->addField($align, 'start', 'end');
|
226 |
|
227 |
+
$admin->display_fields();
|
228 |
?>
|
229 |
|
230 |
</div>
|
blocks/icon.php
CHANGED
@@ -95,7 +95,6 @@ class iconBlock extends maxBlock
|
|
95 |
*/
|
96 |
$css = $this->parse_rule_textalign($css, 'mb-icon', 'normal');
|
97 |
|
98 |
-
|
99 |
return $css;
|
100 |
}
|
101 |
|
@@ -123,7 +122,7 @@ class iconBlock extends maxBlock
|
|
123 |
}
|
124 |
}
|
125 |
|
126 |
-
return $css;
|
127 |
}
|
128 |
|
129 |
public function parse_button($domObj, $mode = 'normal')
|
95 |
*/
|
96 |
$css = $this->parse_rule_textalign($css, 'mb-icon', 'normal');
|
97 |
|
|
|
98 |
return $css;
|
99 |
}
|
100 |
|
122 |
}
|
123 |
}
|
124 |
|
125 |
+
return $css;
|
126 |
}
|
127 |
|
128 |
public function parse_button($domObj, $mode = 'normal')
|
blocks/tpl/radio.tpl
CHANGED
@@ -11,6 +11,6 @@
|
|
11 |
{if:icon} <i class='dashicons %%icon%%' tabindex='0'></i> {/if:icon}
|
12 |
{if:custom_icon} <i class='%%custom_icon%%'></i>{/if:custom_icon}
|
13 |
{if:image} <img src='%%image%%' /> {/if:image}
|
14 |
-
{if:label} %%label {/if:label}
|
15 |
</label>
|
16 |
</div>
|
11 |
{if:icon} <i class='dashicons %%icon%%' tabindex='0'></i> {/if:icon}
|
12 |
{if:custom_icon} <i class='%%custom_icon%%'></i>{/if:custom_icon}
|
13 |
{if:image} <img src='%%image%%' /> {/if:image}
|
14 |
+
{if:label} %%label%% {/if:label}
|
15 |
</label>
|
16 |
</div>
|
classes/button.php
CHANGED
@@ -1,41 +1,41 @@
|
|
1 |
<?php
|
2 |
-
namespace MaxButtons;
|
3 |
defined('ABSPATH') or die('No direct access permitted');
|
4 |
|
5 |
-
/* Datamodel and base functionality for a button
|
6 |
|
7 |
*/
|
8 |
|
9 |
use \simple_html_dom as simple_html_dom;
|
10 |
-
|
11 |
class maxButton
|
12 |
{
|
13 |
-
protected $id = 0;
|
14 |
protected $document_id = 0; // an id that's not duplicated when there are multiple buttons on the same page. Preferably reliable as well.
|
15 |
-
protected $name = '';
|
16 |
-
protected $status = '';
|
17 |
-
protected $description = '';
|
18 |
-
protected $cache = '';
|
19 |
-
|
20 |
protected $button_loaded = false;
|
21 |
|
22 |
-
protected $data = array();
|
23 |
protected $blocks; // Block Classes
|
24 |
protected $templates = array(); // .tpl files
|
25 |
|
26 |
-
protected $button_css = array();
|
27 |
-
protected $button_js = array();
|
28 |
-
|
29 |
// output conditions
|
30 |
-
protected $load_css = 'footer'; // [ footer, inline, external, element ]
|
31 |
-
protected $load_js = 'footer';
|
32 |
-
|
33 |
-
protected $cssParser = false;
|
34 |
-
protected $parsed_css = '';
|
35 |
-
|
36 |
-
|
37 |
-
/* Class constructor
|
38 |
-
|
39 |
Get als loads the various blocks of which a button is built up. Blocks can be added and removed using the mb-init-blocks filter
|
40 |
*/
|
41 |
function __construct()
|
@@ -43,31 +43,31 @@ class maxButton
|
|
43 |
maxUtils::addTime("Button construct");
|
44 |
|
45 |
// the parser
|
46 |
-
|
47 |
-
// get all files from blocks map
|
48 |
-
|
49 |
-
// get all blocks via apply filters, do init. Init should not load anything big.
|
50 |
-
$this->loadBlockClasses();
|
51 |
-
|
52 |
-
}
|
53 |
-
|
54 |
/* Makes overriding block features possible by subclass
|
55 |
-
|
56 |
*/
|
57 |
private function loadBlockClasses()
|
58 |
{
|
59 |
|
60 |
-
// set blocks to the 'block name' that survived.
|
61 |
-
maxUtils::addTime("Load Block classes");
|
62 |
-
|
63 |
//$classes = apply_filters("mb_blockclassesload", $classes);
|
64 |
-
$class_array = maxBlocks::getBlockClasses();
|
65 |
-
$classes = array_map(maxUtils::namespaceit('maxUtils::array_namespace'), $class_array );
|
66 |
-
|
67 |
foreach($classes as $block => $class)
|
68 |
{
|
69 |
-
$block = new $class();
|
70 |
-
|
71 |
$this->blocks[] = $block;
|
72 |
if (is_admin())
|
73 |
{
|
@@ -75,18 +75,18 @@ class maxButton
|
|
75 |
}
|
76 |
}
|
77 |
|
78 |
-
|
79 |
$this->clear(); // init
|
80 |
-
do_action("mb\blockclasses", $class_array);
|
81 |
|
82 |
}
|
83 |
-
|
84 |
-
/** Simple function to retrieve loaded blocks - * Used by install class */
|
85 |
-
public function getBlocks()
|
86 |
{
|
87 |
return $this->blocks;
|
88 |
-
}
|
89 |
-
|
90 |
/** Get Data from Database and set variables
|
91 |
*
|
92 |
* You can pass either id or name to this function
|
@@ -102,52 +102,52 @@ class maxButton
|
|
102 |
$status = sanitize_text_field($status);
|
103 |
|
104 |
global $wpdb;
|
105 |
-
$this->clear(); // clear the internals of any previous work
|
106 |
-
|
107 |
// check to see if the value passed is NOT numeric. If it is, use title, else assume numeric
|
108 |
if($id == 0 && $name != '') {
|
109 |
$row = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . maxUtils::get_table_name() . " WHERE name = '%s' and status ='%s'", trim($name), $status ), ARRAY_A);
|
110 |
-
|
111 |
} else {
|
112 |
$row = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . maxUtils::get_table_name() . " WHERE id = %d and status ='%s'", $id, $status), ARRAY_A);
|
113 |
}
|
114 |
-
|
115 |
-
if (count($row) == 0)
|
116 |
{
|
117 |
-
return false;
|
118 |
-
}
|
119 |
|
120 |
-
/* Take the id from the query, otherwise ( when button shortcode called by name ) id might not be present properly' */
|
121 |
-
$button_id = $row["id"];
|
122 |
maxButtons::buttonLoad(array("button_id" => $button_id)); // central registration
|
123 |
-
|
124 |
return $this->setupData($row);
|
125 |
-
|
126 |
}
|
127 |
/** Clear button settings
|
128 |
*
|
129 |
* This function prevent that generated values from previous set actions will still be present.
|
130 |
-
*/
|
131 |
-
function clear()
|
132 |
{
|
133 |
unset($this->data);
|
134 |
unset($this->button_css);
|
135 |
$this->id = 0; // clear id
|
136 |
$this->button_css = array();
|
137 |
-
$this->button_js = array();
|
138 |
$this->data = array('id' => 0);
|
139 |
$this->data = $this->save(array(),false);
|
140 |
|
141 |
-
$this->cache = '';
|
142 |
$this->button_loaded = false;
|
143 |
|
144 |
foreach($this->blocks as $block)
|
145 |
{
|
146 |
-
$block->set($this->data); // reset blocks
|
147 |
}
|
148 |
|
149 |
}
|
150 |
-
|
151 |
function setupData($data)
|
152 |
{
|
153 |
|
@@ -159,54 +159,54 @@ class maxButton
|
|
159 |
if (array_key_exists($block_name, $data)) // strangely isset doesn't work
|
160 |
{
|
161 |
$this->data[$block_name] = maybe_unserialize($data[$block_name]); // allow to feed unserialized stuff not from dbase
|
162 |
-
if (! is_array($this->data[$block_name]))
|
163 |
{
|
164 |
$this->data[$block_name] = json_decode($data[$block_name], true);
|
165 |
}
|
166 |
-
|
167 |
}
|
168 |
}
|
169 |
-
|
170 |
$this->id = $data["id"];
|
171 |
|
172 |
-
// Because PHP 5.3
|
173 |
$class = maxUtils::namespaceit('maxButtons');
|
174 |
$this->document_id = $class::getDocumentID(array("button_id" => $this->id));
|
175 |
$this->cache = isset($data["cache"]) ? trim($data["cache"]) : ''; // not set at button packs / non-dbase buttons!
|
176 |
-
$this->data["id"] = $this->id; // needed for certain blocks, to be button aware.
|
177 |
-
$this->data["document_id"] = $this->document_id; // bound to JS and others.
|
178 |
-
$this->name = $data["name"];
|
179 |
$this->status = $data["status"];
|
180 |
-
$this->description = $this->data["basic"]["description"];
|
181 |
|
182 |
//do_action('mb-data-load', $this->data);
|
183 |
foreach($this->blocks as $block)
|
184 |
{
|
185 |
$block->set($this->data);
|
186 |
}
|
187 |
-
|
188 |
maxBlocks::setData($this->data);
|
189 |
|
190 |
|
191 |
return true;
|
192 |
-
|
193 |
}
|
194 |
-
|
195 |
-
function get( )
|
196 |
{
|
197 |
return $this->data;
|
198 |
-
|
199 |
}
|
200 |
-
|
201 |
-
function getID()
|
202 |
{
|
203 |
-
return $this->id;
|
204 |
}
|
205 |
-
function getDocumentID()
|
206 |
{
|
207 |
-
return $this->document_id;
|
208 |
}
|
209 |
-
function getName()
|
210 |
{
|
211 |
return $this->name;
|
212 |
}
|
@@ -214,240 +214,240 @@ class maxButton
|
|
214 |
{
|
215 |
return $this->description;
|
216 |
}
|
217 |
-
|
218 |
function getStatus()
|
219 |
{
|
220 |
-
return $this->status;
|
221 |
}
|
222 |
-
|
223 |
-
function getParsedCSS()
|
224 |
{
|
225 |
-
return $this->parsed_css;
|
226 |
}
|
227 |
-
|
228 |
function getCSSArray()
|
229 |
{
|
230 |
|
231 |
return $this->button_css;
|
232 |
}
|
233 |
-
|
234 |
function getCSSParser()
|
235 |
{
|
236 |
if (! $this->cssParser)
|
237 |
-
$this->cssParser = new maxCSSParser();
|
238 |
-
|
239 |
return $this->cssParser;
|
240 |
}
|
241 |
// get the cache
|
242 |
-
function getCache()
|
243 |
{
|
244 |
return $this->cache;
|
245 |
}
|
246 |
-
|
247 |
-
// modify the cache at own risk
|
248 |
function setCache($cache)
|
249 |
{
|
250 |
-
$this->cache = $cache;
|
251 |
-
}
|
252 |
|
253 |
/* Used by collections and import. Use sparingly. Button data is reput to blocks on display */
|
254 |
-
function setData($blockname, $data )
|
255 |
{
|
256 |
foreach($data as $key => $value)
|
257 |
{
|
258 |
-
$this->data[$blockname][$key] = $value;
|
259 |
-
|
260 |
}
|
261 |
}
|
262 |
|
263 |
-
|
264 |
/* Tell all blocks to reload the data
|
265 |
-
|
266 |
-
This function will tell all loaded blocks to reload it's data. This is needed when data is changed after the initial button load.
|
267 |
-
|
268 |
-
*/
|
269 |
function reloadData()
|
270 |
{
|
271 |
exit('reload Data - do not use');
|
272 |
//do_action('mb-data-load', $this->data);
|
273 |
-
|
274 |
-
}
|
275 |
|
276 |
/* Parse CSS from the elements
|
277 |
-
|
278 |
@param string $mode [normal,preview,editor] - The view needed.
|
279 |
-
@param string $forceCompile Recompile the CSS in any case
|
280 |
*/
|
281 |
function parse_css($mode = "normal", $forceCompile = false )
|
282 |
{
|
283 |
-
$css = $this->button_css;
|
284 |
-
|
285 |
if (isset($this->cache) && $this->cache != '' && ! $forceCompile)
|
286 |
-
{
|
287 |
-
|
288 |
$css = $this->cache;
|
289 |
// kill media queries from cache
|
290 |
if ($mode != 'normal')
|
291 |
{
|
292 |
-
$pattern = "/@media.*}/is";
|
293 |
preg_match($pattern, $css, $matches);
|
294 |
-
$css = preg_replace($pattern, '', $css);
|
295 |
}
|
296 |
|
297 |
maxUtils::addTime("Button: Cache loaded");
|
298 |
}
|
299 |
else
|
300 |
-
{
|
301 |
-
/* Internal filter, please don't use */
|
302 |
foreach($this->blocks as $block)
|
303 |
{
|
304 |
-
$css = $block->parse_css($css, $mode);
|
305 |
}
|
306 |
//$css = apply_filters('mb-css-blocks', $css, $mode);
|
307 |
-
|
308 |
/* Filter the raw CSS array before compile
|
309 |
-
|
310 |
-
This filters passes an array with all CSS element before compile time. This should be CSS elements that can be understood by the CSS parser.
|
311 |
-
@since 4.20
|
312 |
-
@param $css CSS Array - split by element and pseudo (normal/hover)
|
313 |
-
|
314 |
*/
|
315 |
-
|
316 |
-
$css = apply_filters('mb/button/rawcss', $css, $mode);
|
317 |
|
318 |
-
|
319 |
|
|
|
320 |
|
321 |
$css = $this->getCSSParser()->parse($this->button_css);
|
322 |
-
$css = apply_filters('mb/button/compiledcss', $css, $mode); // the final result.
|
323 |
-
|
324 |
if ($mode == 'normal') // only in general mode, otherwise things go amiss.
|
325 |
$this->update_cache($css);
|
326 |
|
327 |
}
|
328 |
-
|
329 |
-
$this->parsed_css = $css;
|
330 |
-
|
331 |
-
|
332 |
-
return $css;
|
333 |
-
}
|
334 |
-
|
335 |
-
/* Call blocks for javascript
|
336 |
-
|
337 |
-
Function will call for all block element to crunch the required javascript for output ( if any )
|
338 |
-
@param string $mode [normal, preview, editor]
|
339 |
-
|
340 |
*/
|
341 |
-
function parse_js($mode = "normal")
|
342 |
{
|
343 |
maxUtils::addTime("Button :: parse JS");
|
344 |
-
$js = $this->button_js;
|
345 |
foreach($this->blocks as $block)
|
346 |
{
|
347 |
-
$js = $block->parse_js($js,$mode);
|
348 |
-
|
349 |
}
|
350 |
|
351 |
-
$this->button_js = $js;
|
352 |
}
|
353 |
-
|
354 |
/* Parse the actual button
|
355 |
-
|
356 |
-
Function adds the basic button components, creates the DOM object for the button and asks all block elements to parse their additions.
|
357 |
-
|
358 |
-
@param string $mode [normal, preview, editor]
|
359 |
@return Object DomObj presentation of the button
|
360 |
*/
|
361 |
function parse_button($mode = 'normal')
|
362 |
{
|
363 |
-
$name = $this->name;
|
364 |
// non-latin breaks CSS / ID's - so move to latin.
|
365 |
$name = maxUtils::translit($name);
|
366 |
$name = sanitize_title($name);
|
367 |
|
368 |
$classes = array("maxbutton-" . $this->id,
|
369 |
"maxbutton");
|
370 |
-
|
|
|
|
|
371 |
$classes[] = "maxbutton-" . $name;
|
372 |
-
|
373 |
-
$classes = apply_filters('mb-mainclasses', $classes);
|
374 |
-
$classes = implode(' ', $classes);
|
375 |
-
|
376 |
$domObj = new simple_html_dom();
|
377 |
-
$domObj->load('<a class="' . $classes . '"></a>');
|
378 |
-
|
379 |
|
380 |
foreach($this->blocks as $block)
|
381 |
{
|
382 |
$domObj = $block->parse_button($domObj, $mode);
|
383 |
-
}
|
384 |
-
|
385 |
-
|
386 |
$domObj->load($domObj->save());
|
387 |
-
|
388 |
$cssParser = $this->getCSSParser();
|
389 |
$cssParser->loadDom($domObj);
|
390 |
|
391 |
-
return $domObj;
|
392 |
}
|
393 |
|
394 |
-
/* Display all data and html to allow users to edit button settings */
|
395 |
-
public function admin_fields()
|
396 |
{
|
397 |
foreach($this->blocks as $block)
|
398 |
{
|
399 |
-
$block->admin_fields();
|
400 |
-
|
401 |
}
|
402 |
-
//do_action('mb-admin-fields' );
|
403 |
-
|
404 |
}
|
405 |
-
|
406 |
/* Display the button */
|
407 |
public function display($args = array() )
|
408 |
-
{
|
409 |
maxUtils::startTime('button-display-'. $this->id);
|
410 |
$defaults = array(
|
411 |
"mode" => 'normal',
|
412 |
"preview_part" => "full",
|
413 |
-
"echo" => true,
|
414 |
-
"load_css" => "footer", // control how css is loaded.
|
415 |
-
"compile" => false, // possibility to force recompile if needed.
|
416 |
);
|
417 |
-
$output = ''; // init output;
|
418 |
-
|
419 |
-
$args = wp_parse_args($args, $defaults);
|
420 |
|
421 |
$cssParser = $this->getCSSParser(); // init parser
|
422 |
-
|
423 |
-
$this->load_css = $args["load_css"];
|
424 |
-
|
425 |
if ($this->id == 0) // if button doesn't exists don't display unless in editor
|
426 |
{
|
427 |
-
if (! $args["mode"] == 'editor' )
|
428 |
return;
|
429 |
-
|
430 |
-
$this->clear();
|
431 |
-
|
432 |
$this->data["id"] = 0;
|
433 |
//do_action('mb-data-load', $data);
|
434 |
}
|
435 |
-
|
436 |
-
$mode = (isset($args["mode"])) ? $args["mode"] : "normal";
|
437 |
switch($mode)
|
438 |
{
|
439 |
-
case "preview":
|
440 |
$preview = true;
|
441 |
$compile = false;
|
442 |
-
break;
|
443 |
-
case "editor":
|
444 |
-
$preview = true;
|
445 |
-
$compile = true;
|
446 |
-
// editor is both compile and preview.
|
447 |
break;
|
448 |
break;
|
449 |
-
case "normal":
|
450 |
-
$preview = false;
|
451 |
$compile = false;
|
452 |
break;
|
453 |
}
|
@@ -455,15 +455,15 @@ class maxButton
|
|
455 |
|
456 |
// Apply filters for general data override
|
457 |
|
458 |
-
$this->data = apply_filters('mb/button/data_before_display', $this->data, $mode, array('preview' => $preview, 'compile' => $compile) ); // hooks
|
|
|
|
|
459 |
|
460 |
-
|
461 |
-
|
462 |
if ( $this->load_css == "element" || $args["preview_part"] != "full" || $args["compile"] == true) { // if css output is on element, for to compile - otherwise inline styles will not be loaded.
|
463 |
$compile = true;
|
464 |
|
465 |
}
|
466 |
-
else
|
467 |
$compile = false;
|
468 |
|
469 |
// reload the data into the blocks, might have been altered by shortcode, filters etc.
|
@@ -473,232 +473,232 @@ class maxButton
|
|
473 |
$block->set($this->data);
|
474 |
}
|
475 |
|
476 |
-
$domObj = $this->parse_button($mode);
|
477 |
-
|
478 |
maxUtils::startTime('button-parse-css-'. $this->id);
|
479 |
-
$this->parse_css($mode, $compile);
|
480 |
maxUtils::endTime('button-parse-css-'. $this->id);
|
481 |
-
|
482 |
-
if (! $preview) // no js on previews
|
483 |
-
$this->parse_js($mode);
|
484 |
-
|
485 |
if ($preview) // mark it preview
|
486 |
{
|
487 |
|
488 |
$domObj->find('a',0)->class .= ' maxbutton-preview';
|
489 |
}
|
490 |
-
|
491 |
if ($preview && $args["preview_part"] != 'full')
|
492 |
{
|
493 |
-
|
494 |
if ($args["preview_part"] != 'normal')
|
495 |
{
|
496 |
-
$domObj->find('a',0)->class .= ' hover';
|
497 |
$domObj = $cssParser->outputInline($domObj,'hover');
|
498 |
|
499 |
}
|
500 |
else
|
501 |
{
|
502 |
-
$domObj->find('a',0)->class .= ' normal';
|
503 |
$domObj = $cssParser->outputInline($domObj);
|
504 |
}
|
505 |
|
506 |
}
|
507 |
-
elseif ($this->load_css == 'footer')
|
508 |
{
|
509 |
-
$css = $this->display_css(false, false);
|
510 |
-
do_action('mb-footer',$this->id, $css);
|
511 |
-
|
512 |
if (! $preview)
|
513 |
{
|
514 |
$js = $this->display_js(false, true);
|
515 |
do_action('mb-footer', $this->document_id, $js, 'js');
|
516 |
}
|
517 |
-
} elseif ($this->load_css == 'inline')
|
518 |
{
|
519 |
-
if ($args["echo"])
|
520 |
$this->display_css();
|
521 |
else
|
522 |
$output .= $this->display_css(false);
|
523 |
}
|
524 |
-
elseif ($this->load_css == 'element') // not possible to load both normal and hover to an element.
|
525 |
{
|
526 |
-
$domObj->find('a',0)->class .= ' normal';
|
527 |
-
$domObj = $this->cssParser->outputInline($domObj);
|
528 |
-
//$this->get_element_css($domObj, 'normal');
|
529 |
}
|
530 |
-
|
531 |
|
532 |
$output .= $domObj->save();
|
533 |
-
|
534 |
-
$output = apply_filters('mb-before-button-output', $output);
|
535 |
-
maxButtons::buttonDone(array("button_id" => $this->id, "document_id" => $this->document_id) );
|
536 |
-
|
537 |
maxUtils::endTime('button-display-'. $this->id);
|
538 |
-
|
539 |
if ($args["echo"])
|
540 |
-
echo $output;
|
541 |
else
|
542 |
-
return $output;
|
543 |
|
544 |
-
}
|
545 |
/* Function used to map field id's to display for Frontend Javascript
|
546 |
-
|
547 |
-
This function bundles all defined fields into a json encoded variable. This is used for the frontend javascript functions in the
|
548 |
administrator area like colorpickers and real-time updating of the button preview
|
549 |
*/
|
550 |
public function display_field_map()
|
551 |
{
|
552 |
-
$map = array();
|
553 |
foreach($this->blocks as $block)
|
554 |
{
|
555 |
-
$map = $block->map_fields($map);
|
556 |
}
|
557 |
-
//$map = apply_filters("mb-field-map",$map);
|
558 |
-
|
559 |
|
560 |
-
echo "<script language='javascript'>";
|
561 |
echo "var buttonFieldMap = '" . json_encode($map) . "';" ;
|
562 |
echo "</script>";
|
563 |
-
|
564 |
}
|
565 |
-
|
566 |
-
/* Write parsed CSS to output.
|
567 |
-
@param echo Default true. When true, outputs directly, otherwise returns output string
|
568 |
@param style_tag Default true. When true, outputs a html <style> tags around the output.
|
569 |
*/
|
570 |
public function display_css($echo = true, $style_tag = true)
|
571 |
{
|
572 |
-
$output = '';
|
573 |
-
|
574 |
if ($style_tag)
|
575 |
$output .= "<style type='text/css'>";
|
576 |
-
|
577 |
$output .= $this->parsed_css;
|
578 |
-
|
579 |
if ($style_tag)
|
580 |
$output .= "</style>";
|
581 |
-
|
582 |
-
|
583 |
-
if ($echo) echo $output;
|
584 |
-
else return $output;
|
585 |
-
|
586 |
}
|
587 |
-
|
588 |
/* Output Parsed Javascripting */
|
589 |
public function display_js($echo = true, $tag = true)
|
590 |
{
|
591 |
$output = '';
|
592 |
|
593 |
-
if (count($this->button_js) == 0)
|
594 |
return; // no output, holiday
|
595 |
-
|
596 |
-
if ($tag)
|
597 |
{
|
598 |
-
$output .= "<script type='text/javascript'> ";
|
599 |
$output .= " if (typeof maxButton" . $this->document_id . " == 'undefined') { ";
|
600 |
$output .= " function maxButton" . $this->document_id . "() { ";
|
601 |
}
|
602 |
-
|
603 |
-
foreach($this->button_js as $index => $code)
|
604 |
{
|
605 |
-
$output .= $code;
|
606 |
-
|
607 |
}
|
608 |
-
|
609 |
-
if ($tag)
|
610 |
{
|
611 |
-
$output .= " }
|
612 |
-
}
|
613 |
-
window.onload = maxButton" . $this->document_id . "();
|
614 |
-
</script> ";
|
615 |
}
|
616 |
|
617 |
-
if ($echo) echo $output;
|
618 |
-
else return $output;
|
619 |
}
|
620 |
|
621 |
|
622 |
-
/* Makes a copy of the current buttons.
|
623 |
-
|
624 |
-
The button to be copied -must- be loaded and set
|
625 |
*/
|
626 |
-
function copy()
|
627 |
-
{
|
628 |
-
$this->id = 0;
|
629 |
$data = $this->data;
|
630 |
$data["name"] = $this->name;
|
631 |
-
|
632 |
-
return $this->update($data);
|
633 |
}
|
634 |
/* Change the publication status of the button.
|
635 |
-
|
636 |
*/
|
637 |
-
function setStatus($status = "publish")
|
638 |
{
|
639 |
-
$data = $this->data;
|
640 |
-
$data["status"] = sanitize_text_field($status);
|
|
|
|
|
641 |
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
/* Remove the button from database */
|
646 |
-
public function delete($id)
|
647 |
{
|
648 |
global $wpdb;
|
649 |
$wpdb->query($wpdb->prepare("DELETE FROM " . maxUtils::get_table_name() . " WHERE id = %d", $id));
|
650 |
}
|
651 |
-
|
652 |
-
/* Save changes to the button
|
653 |
-
|
654 |
-
Updates or saves the button. Existing buttons must load their data and be set -first- or lose all not-passed data.
|
655 |
-
|
656 |
@param post Post data in field - value format (flat $_POST array)
|
657 |
-
@param boolean savedb if false do not save to database
|
658 |
*/
|
659 |
public function save($post, $savedb = true)
|
660 |
{
|
661 |
$post = stripslashes_deep($post); // don't multiply slashes please.
|
662 |
-
//$data = apply_filters('mb-save-fields',$this->data, $post);
|
663 |
$data = $this->data;
|
664 |
-
|
665 |
-
foreach($this->blocks as $block)
|
666 |
{
|
667 |
-
$data = $block->save_fields($data, $post);
|
668 |
}
|
669 |
-
|
670 |
-
if (! $savedb ) return $data;
|
671 |
-
return $this->update($data); // save to db.
|
672 |
-
|
673 |
}
|
674 |
-
|
675 |
/* Updates the button data to the database. Adds a button if it doesn't exist */
|
676 |
-
public function update($data)
|
677 |
-
{
|
678 |
-
global $wpdb;
|
679 |
-
$return = false;
|
680 |
-
|
681 |
-
$fields = array();
|
682 |
foreach($this->blocks as $block)
|
683 |
{
|
684 |
-
$block_name = $block->get_name();
|
685 |
-
|
686 |
-
if (isset($data[$block_name]))
|
687 |
{
|
688 |
-
$blockData = $data[$block_name];
|
689 |
$fields[$block_name] = json_encode($blockData);
|
690 |
}
|
691 |
-
}
|
692 |
-
if (isset($data["name"])) { // other fields.
|
693 |
-
$fields["name"] = $data["name"];
|
694 |
}
|
695 |
if (isset($data["status"])) {
|
696 |
-
$fields["status"] = $data["status"];
|
697 |
}
|
698 |
-
|
699 |
-
|
700 |
$where = array('id' => $this->id );
|
701 |
-
if ($this->id > 0)
|
702 |
{
|
703 |
$where = array('id' => $this->id);
|
704 |
$where_format = array('%d');
|
@@ -707,114 +707,114 @@ class maxButton
|
|
707 |
}
|
708 |
else
|
709 |
{
|
710 |
-
$fields['created'] = current_time('mysql',1);
|
711 |
|
712 |
$result = $wpdb->insert(maxUtils::get_table_name(), $fields);
|
713 |
$id = $wpdb->insert_id;
|
714 |
|
715 |
$this->id = $id;
|
716 |
-
$return = $id;
|
717 |
-
|
718 |
}
|
719 |
-
|
720 |
-
|
721 |
if ($result === false)
|
722 |
{
|
723 |
$error = "Database error " . $wpdb->last_error;
|
724 |
-
MB()->add_notice('error', $error);
|
725 |
-
$install = MB()->getClass("install");
|
726 |
$install::create_database_table(); // run dbdelta to try and fix.
|
727 |
-
|
728 |
}
|
729 |
-
|
730 |
-
// update the cache
|
731 |
-
$this->cache = ''; // empty cache
|
732 |
$result = $this->set($this->id); // set the newest values
|
733 |
-
|
734 |
-
if (! $result ) return false;
|
735 |
-
|
736 |
$this->display(array("echo" => false, "load_css" => "element")); // do display routing to compile.
|
737 |
-
$css = $this->parsed_css;
|
738 |
-
$this->update_cache($css);
|
739 |
|
740 |
return $return;
|
741 |
}
|
742 |
-
|
743 |
/* Updates the CSS cache. */
|
744 |
public function update_cache($css)
|
745 |
{
|
746 |
$return = false;
|
747 |
-
global $wpdb;
|
748 |
-
|
749 |
-
if ($this->id > 0)
|
750 |
{
|
751 |
-
$fields = array("cache" => $css);
|
752 |
$where = array('id' => $this->id);
|
753 |
$where_format = array('%d');
|
754 |
$wpdb->update(maxUtils::get_table_name(), $fields, $where, null, $where_format);
|
755 |
$return = true;
|
756 |
-
|
757 |
}
|
758 |
-
return $return;
|
759 |
}
|
760 |
-
|
761 |
// Resets all of the button caches.
|
762 |
public function reset_cache()
|
763 |
{
|
764 |
global $wpdb;
|
765 |
-
$fields = array("cache" => null);
|
766 |
$where = array(1 => 1);
|
767 |
//$where_format = array('%d');
|
768 |
-
$sql = "UPDATE " . maxUtils::get_table_name() . " SET cache = NULL ";
|
769 |
$wpdb->query($sql);
|
770 |
-
|
771 |
}
|
772 |
|
773 |
-
|
774 |
/* Display button via shortcode
|
775 |
-
|
776 |
Function that accepts WP shortcode arguments and displays or returns a button
|
777 |
-
|
778 |
-
@param $atts array Shortcode Atts
|
779 |
@return string HTML presentation of button
|
780 |
-
|
781 |
*/
|
782 |
public function shortcode($atts)
|
783 |
-
{
|
784 |
extract(shortcode_atts(array(
|
785 |
'id' => '',
|
786 |
'name' => '',
|
787 |
'text' => '',
|
788 |
'url' => '',
|
789 |
-
'linktitle' => '',
|
790 |
'window' => '',
|
791 |
'nofollow' => '',
|
792 |
-
'nocache' => false,
|
793 |
-
'style' => 'footer',
|
794 |
'exclude' => ''
|
795 |
|
796 |
-
), $atts));
|
797 |
|
798 |
-
$button_id = $id;
|
799 |
$button_name = $name;
|
800 |
-
|
801 |
-
if ($button_id > 0)
|
802 |
-
$result = $this->set($button_id);
|
803 |
-
elseif ($button_name != '')
|
804 |
-
$result = $this->set(0, $button_name);
|
805 |
else return; // no button id / name
|
806 |
-
|
807 |
/* Shortcode cache control
|
808 |
-
|
809 |
If true the button CSS will be recompiled again. If false the plugin will check the cache for CSS declarations. Set to true if anything is interrupting the caching mechanism. Please note, recompiling causes some load times!
|
810 |
-
|
811 |
-
@param boolean $nocache True / False
|
812 |
-
*/
|
813 |
-
$compile = apply_filters("mb/shortcode/nocache", $nocache);
|
814 |
|
815 |
-
|
|
|
|
|
|
|
|
|
816 |
return; // shortcode doesn't exist
|
817 |
-
|
818 |
// If we're not in the admin and the button is in the trash, just return nothing
|
819 |
if (!is_admin() && $this->status == 'trash') {
|
820 |
return '';
|
@@ -822,95 +822,94 @@ class maxButton
|
|
822 |
// Check to handle excludes
|
823 |
if ("{$exclude}" != '') {
|
824 |
global $post;
|
825 |
-
|
826 |
// Don't render the button if excluded from the current post/page
|
827 |
$exclude = explode(',', "{$exclude}");
|
828 |
if (in_array($post->ID, $exclude)) {
|
829 |
return '';
|
830 |
}
|
831 |
}
|
832 |
-
|
833 |
// Override shortcode options comparing to default button data.
|
834 |
-
$overrides = false;
|
835 |
-
if ($text != '')
|
836 |
-
{
|
837 |
-
$this->data["text"]["text"] = $text;
|
838 |
$overrides = true;
|
839 |
-
}
|
840 |
-
if ($url != '')
|
841 |
{
|
842 |
|
843 |
-
$this->data["basic"]["url"] = $url;
|
844 |
//$compile = true; // css change forces recompile
|
845 |
$overrides = true;
|
846 |
}
|
847 |
-
if ($window != '' && $window =='new')
|
848 |
{
|
849 |
-
$this->data["basic"]["new_window"] = 1;
|
850 |
$overrides = true;
|
851 |
}
|
852 |
-
elseif ($window != '' && $window == 'same')
|
853 |
{
|
854 |
-
$this->data["basic"]["new_window"] = 0;
|
855 |
-
$overrides = true;
|
856 |
}
|
857 |
-
|
858 |
-
if ($nofollow != '' && $nofollow == 'true')
|
859 |
{
|
860 |
-
$this->data["basic"]["nofollow"] = 1;
|
861 |
$overrides = true;
|
862 |
}
|
863 |
-
|
864 |
-
if ($linktitle != '')
|
865 |
{
|
866 |
-
$this->data['basic']['link_title'] = $linktitle;
|
867 |
$overrides = true;
|
868 |
}
|
869 |
|
870 |
switch($style)
|
871 |
{
|
872 |
-
case "inline":
|
873 |
-
$load_css = 'inline';
|
874 |
break;
|
875 |
default:
|
876 |
-
$load_css = 'footer';
|
877 |
break;
|
878 |
-
}
|
879 |
|
880 |
// allow for more flexible changes and data manipulation.
|
881 |
$data = $this->data;
|
882 |
-
$this->data = $this->shortcode_overrides($this->data, $atts);
|
883 |
-
$this->data = apply_filters('mb/shortcode/data', $this->data, $atts);
|
884 |
-
|
885 |
-
/* if ($data !== $this->data)
|
886 |
{
|
887 |
-
$overrides = true;
|
888 |
}
|
889 |
-
*/
|
890 |
/* if ($overrides)
|
891 |
{
|
892 |
do_action('mb-data-load', $this->data);
|
893 |
}
|
894 |
-
*/
|
895 |
// if there are no reasons not to display; display
|
896 |
-
$args = array("echo" => false,
|
897 |
-
"load_css" => $load_css,
|
898 |
-
"compile" => $compile,
|
899 |
);
|
900 |
-
$args = apply_filters('mb_shortcode_display_args', $args);
|
901 |
-
|
902 |
-
|
903 |
$output = $this->display($args);
|
904 |
-
|
905 |
return $output;
|
906 |
-
|
907 |
}
|
908 |
-
|
909 |
-
|
910 |
public function shortcode_overrides($data, $atts)
|
911 |
{
|
912 |
return $data;
|
913 |
}
|
914 |
-
|
915 |
-
} // class
|
916 |
|
|
1 |
<?php
|
2 |
+
namespace MaxButtons;
|
3 |
defined('ABSPATH') or die('No direct access permitted');
|
4 |
|
5 |
+
/* Datamodel and base functionality for a button
|
6 |
|
7 |
*/
|
8 |
|
9 |
use \simple_html_dom as simple_html_dom;
|
10 |
+
|
11 |
class maxButton
|
12 |
{
|
13 |
+
protected $id = 0;
|
14 |
protected $document_id = 0; // an id that's not duplicated when there are multiple buttons on the same page. Preferably reliable as well.
|
15 |
+
protected $name = '';
|
16 |
+
protected $status = '';
|
17 |
+
protected $description = '';
|
18 |
+
protected $cache = '';
|
19 |
+
|
20 |
protected $button_loaded = false;
|
21 |
|
22 |
+
protected $data = array();
|
23 |
protected $blocks; // Block Classes
|
24 |
protected $templates = array(); // .tpl files
|
25 |
|
26 |
+
protected $button_css = array();
|
27 |
+
protected $button_js = array();
|
28 |
+
|
29 |
// output conditions
|
30 |
+
protected $load_css = 'footer'; // [ footer, inline, external, element ]
|
31 |
+
protected $load_js = 'footer';
|
32 |
+
|
33 |
+
protected $cssParser = false;
|
34 |
+
protected $parsed_css = '';
|
35 |
+
|
36 |
+
|
37 |
+
/* Class constructor
|
38 |
+
|
39 |
Get als loads the various blocks of which a button is built up. Blocks can be added and removed using the mb-init-blocks filter
|
40 |
*/
|
41 |
function __construct()
|
43 |
maxUtils::addTime("Button construct");
|
44 |
|
45 |
// the parser
|
46 |
+
|
47 |
+
// get all files from blocks map
|
48 |
+
|
49 |
+
// get all blocks via apply filters, do init. Init should not load anything big.
|
50 |
+
$this->loadBlockClasses();
|
51 |
+
|
52 |
+
}
|
53 |
+
|
54 |
/* Makes overriding block features possible by subclass
|
55 |
+
|
56 |
*/
|
57 |
private function loadBlockClasses()
|
58 |
{
|
59 |
|
60 |
+
// set blocks to the 'block name' that survived.
|
61 |
+
maxUtils::addTime("Load Block classes");
|
62 |
+
|
63 |
//$classes = apply_filters("mb_blockclassesload", $classes);
|
64 |
+
$class_array = maxBlocks::getBlockClasses();
|
65 |
+
$classes = array_map(maxUtils::namespaceit('maxUtils::array_namespace'), $class_array );
|
66 |
+
|
67 |
foreach($classes as $block => $class)
|
68 |
{
|
69 |
+
$block = new $class();
|
70 |
+
|
71 |
$this->blocks[] = $block;
|
72 |
if (is_admin())
|
73 |
{
|
75 |
}
|
76 |
}
|
77 |
|
78 |
+
|
79 |
$this->clear(); // init
|
80 |
+
do_action("mb\blockclasses", $class_array);
|
81 |
|
82 |
}
|
83 |
+
|
84 |
+
/** Simple function to retrieve loaded blocks - * Used by install class */
|
85 |
+
public function getBlocks()
|
86 |
{
|
87 |
return $this->blocks;
|
88 |
+
}
|
89 |
+
|
90 |
/** Get Data from Database and set variables
|
91 |
*
|
92 |
* You can pass either id or name to this function
|
102 |
$status = sanitize_text_field($status);
|
103 |
|
104 |
global $wpdb;
|
105 |
+
$this->clear(); // clear the internals of any previous work
|
106 |
+
|
107 |
// check to see if the value passed is NOT numeric. If it is, use title, else assume numeric
|
108 |
if($id == 0 && $name != '') {
|
109 |
$row = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . maxUtils::get_table_name() . " WHERE name = '%s' and status ='%s'", trim($name), $status ), ARRAY_A);
|
110 |
+
|
111 |
} else {
|
112 |
$row = $wpdb->get_row($wpdb->prepare("SELECT * FROM " . maxUtils::get_table_name() . " WHERE id = %d and status ='%s'", $id, $status), ARRAY_A);
|
113 |
}
|
114 |
+
|
115 |
+
if (count($row) == 0)
|
116 |
{
|
117 |
+
return false;
|
118 |
+
}
|
119 |
|
120 |
+
/* Take the id from the query, otherwise ( when button shortcode called by name ) id might not be present properly' */
|
121 |
+
$button_id = $row["id"];
|
122 |
maxButtons::buttonLoad(array("button_id" => $button_id)); // central registration
|
123 |
+
|
124 |
return $this->setupData($row);
|
125 |
+
|
126 |
}
|
127 |
/** Clear button settings
|
128 |
*
|
129 |
* This function prevent that generated values from previous set actions will still be present.
|
130 |
+
*/
|
131 |
+
function clear()
|
132 |
{
|
133 |
unset($this->data);
|
134 |
unset($this->button_css);
|
135 |
$this->id = 0; // clear id
|
136 |
$this->button_css = array();
|
137 |
+
$this->button_js = array();
|
138 |
$this->data = array('id' => 0);
|
139 |
$this->data = $this->save(array(),false);
|
140 |
|
141 |
+
$this->cache = '';
|
142 |
$this->button_loaded = false;
|
143 |
|
144 |
foreach($this->blocks as $block)
|
145 |
{
|
146 |
+
$block->set($this->data); // reset blocks
|
147 |
}
|
148 |
|
149 |
}
|
150 |
+
|
151 |
function setupData($data)
|
152 |
{
|
153 |
|
159 |
if (array_key_exists($block_name, $data)) // strangely isset doesn't work
|
160 |
{
|
161 |
$this->data[$block_name] = maybe_unserialize($data[$block_name]); // allow to feed unserialized stuff not from dbase
|
162 |
+
if (! is_array($this->data[$block_name]))
|
163 |
{
|
164 |
$this->data[$block_name] = json_decode($data[$block_name], true);
|
165 |
}
|
166 |
+
|
167 |
}
|
168 |
}
|
169 |
+
|
170 |
$this->id = $data["id"];
|
171 |
|
172 |
+
// Because PHP 5.3
|
173 |
$class = maxUtils::namespaceit('maxButtons');
|
174 |
$this->document_id = $class::getDocumentID(array("button_id" => $this->id));
|
175 |
$this->cache = isset($data["cache"]) ? trim($data["cache"]) : ''; // not set at button packs / non-dbase buttons!
|
176 |
+
$this->data["id"] = $this->id; // needed for certain blocks, to be button aware.
|
177 |
+
$this->data["document_id"] = $this->document_id; // bound to JS and others.
|
178 |
+
$this->name = $data["name"];
|
179 |
$this->status = $data["status"];
|
180 |
+
$this->description = $this->data["basic"]["description"];
|
181 |
|
182 |
//do_action('mb-data-load', $this->data);
|
183 |
foreach($this->blocks as $block)
|
184 |
{
|
185 |
$block->set($this->data);
|
186 |
}
|
187 |
+
|
188 |
maxBlocks::setData($this->data);
|
189 |
|
190 |
|
191 |
return true;
|
192 |
+
|
193 |
}
|
194 |
+
|
195 |
+
function get( )
|
196 |
{
|
197 |
return $this->data;
|
198 |
+
|
199 |
}
|
200 |
+
|
201 |
+
function getID()
|
202 |
{
|
203 |
+
return $this->id;
|
204 |
}
|
205 |
+
function getDocumentID()
|
206 |
{
|
207 |
+
return $this->document_id;
|
208 |
}
|
209 |
+
function getName()
|
210 |
{
|
211 |
return $this->name;
|
212 |
}
|
214 |
{
|
215 |
return $this->description;
|
216 |
}
|
217 |
+
|
218 |
function getStatus()
|
219 |
{
|
220 |
+
return $this->status;
|
221 |
}
|
222 |
+
|
223 |
+
function getParsedCSS()
|
224 |
{
|
225 |
+
return $this->parsed_css;
|
226 |
}
|
227 |
+
|
228 |
function getCSSArray()
|
229 |
{
|
230 |
|
231 |
return $this->button_css;
|
232 |
}
|
233 |
+
|
234 |
function getCSSParser()
|
235 |
{
|
236 |
if (! $this->cssParser)
|
237 |
+
$this->cssParser = new maxCSSParser();
|
238 |
+
|
239 |
return $this->cssParser;
|
240 |
}
|
241 |
// get the cache
|
242 |
+
function getCache()
|
243 |
{
|
244 |
return $this->cache;
|
245 |
}
|
246 |
+
|
247 |
+
// modify the cache at own risk
|
248 |
function setCache($cache)
|
249 |
{
|
250 |
+
$this->cache = $cache;
|
251 |
+
}
|
252 |
|
253 |
/* Used by collections and import. Use sparingly. Button data is reput to blocks on display */
|
254 |
+
function setData($blockname, $data )
|
255 |
{
|
256 |
foreach($data as $key => $value)
|
257 |
{
|
258 |
+
$this->data[$blockname][$key] = $value;
|
259 |
+
|
260 |
}
|
261 |
}
|
262 |
|
263 |
+
|
264 |
/* Tell all blocks to reload the data
|
265 |
+
|
266 |
+
This function will tell all loaded blocks to reload it's data. This is needed when data is changed after the initial button load.
|
267 |
+
|
268 |
+
*/
|
269 |
function reloadData()
|
270 |
{
|
271 |
exit('reload Data - do not use');
|
272 |
//do_action('mb-data-load', $this->data);
|
273 |
+
|
274 |
+
}
|
275 |
|
276 |
/* Parse CSS from the elements
|
277 |
+
|
278 |
@param string $mode [normal,preview,editor] - The view needed.
|
279 |
+
@param string $forceCompile Recompile the CSS in any case
|
280 |
*/
|
281 |
function parse_css($mode = "normal", $forceCompile = false )
|
282 |
{
|
283 |
+
$css = $this->button_css;
|
284 |
+
|
285 |
if (isset($this->cache) && $this->cache != '' && ! $forceCompile)
|
286 |
+
{
|
287 |
+
|
288 |
$css = $this->cache;
|
289 |
// kill media queries from cache
|
290 |
if ($mode != 'normal')
|
291 |
{
|
292 |
+
$pattern = "/@media.*}/is";
|
293 |
preg_match($pattern, $css, $matches);
|
294 |
+
$css = preg_replace($pattern, '', $css);
|
295 |
}
|
296 |
|
297 |
maxUtils::addTime("Button: Cache loaded");
|
298 |
}
|
299 |
else
|
300 |
+
{
|
301 |
+
/* Internal filter, please don't use */
|
302 |
foreach($this->blocks as $block)
|
303 |
{
|
304 |
+
$css = $block->parse_css($css, $mode);
|
305 |
}
|
306 |
//$css = apply_filters('mb-css-blocks', $css, $mode);
|
307 |
+
|
308 |
/* Filter the raw CSS array before compile
|
309 |
+
|
310 |
+
This filters passes an array with all CSS element before compile time. This should be CSS elements that can be understood by the CSS parser.
|
311 |
+
@since 4.20
|
312 |
+
@param $css CSS Array - split by element and pseudo (normal/hover)
|
313 |
+
|
314 |
*/
|
|
|
|
|
315 |
|
316 |
+
$css = apply_filters('mb/button/rawcss', $css, $mode);
|
317 |
|
318 |
+
$this->button_css = $css;
|
319 |
|
320 |
$css = $this->getCSSParser()->parse($this->button_css);
|
321 |
+
$css = apply_filters('mb/button/compiledcss', $css, $mode); // the final result.
|
322 |
+
|
323 |
if ($mode == 'normal') // only in general mode, otherwise things go amiss.
|
324 |
$this->update_cache($css);
|
325 |
|
326 |
}
|
327 |
+
|
328 |
+
$this->parsed_css = $css;
|
329 |
+
|
330 |
+
|
331 |
+
return $css;
|
332 |
+
}
|
333 |
+
|
334 |
+
/* Call blocks for javascript
|
335 |
+
|
336 |
+
Function will call for all block element to crunch the required javascript for output ( if any )
|
337 |
+
@param string $mode [normal, preview, editor]
|
338 |
+
|
339 |
*/
|
340 |
+
function parse_js($mode = "normal")
|
341 |
{
|
342 |
maxUtils::addTime("Button :: parse JS");
|
343 |
+
$js = $this->button_js;
|
344 |
foreach($this->blocks as $block)
|
345 |
{
|
346 |
+
$js = $block->parse_js($js,$mode);
|
347 |
+
|
348 |
}
|
349 |
|
350 |
+
$this->button_js = $js;
|
351 |
}
|
352 |
+
|
353 |
/* Parse the actual button
|
354 |
+
|
355 |
+
Function adds the basic button components, creates the DOM object for the button and asks all block elements to parse their additions.
|
356 |
+
|
357 |
+
@param string $mode [normal, preview, editor]
|
358 |
@return Object DomObj presentation of the button
|
359 |
*/
|
360 |
function parse_button($mode = 'normal')
|
361 |
{
|
362 |
+
$name = $this->name;
|
363 |
// non-latin breaks CSS / ID's - so move to latin.
|
364 |
$name = maxUtils::translit($name);
|
365 |
$name = sanitize_title($name);
|
366 |
|
367 |
$classes = array("maxbutton-" . $this->id,
|
368 |
"maxbutton");
|
369 |
+
|
370 |
+
|
371 |
+
if ($name != '')
|
372 |
$classes[] = "maxbutton-" . $name;
|
373 |
+
|
374 |
+
$classes = apply_filters('mb-mainclasses', $classes);
|
375 |
+
$classes = implode(' ', $classes);
|
376 |
+
|
377 |
$domObj = new simple_html_dom();
|
378 |
+
$domObj->load('<a class="' . $classes . '"></a>');
|
|
|
379 |
|
380 |
foreach($this->blocks as $block)
|
381 |
{
|
382 |
$domObj = $block->parse_button($domObj, $mode);
|
383 |
+
}
|
384 |
+
|
385 |
+
|
386 |
$domObj->load($domObj->save());
|
387 |
+
|
388 |
$cssParser = $this->getCSSParser();
|
389 |
$cssParser->loadDom($domObj);
|
390 |
|
391 |
+
return $domObj;
|
392 |
}
|
393 |
|
394 |
+
/* Display all data and html to allow users to edit button settings */
|
395 |
+
public function admin_fields()
|
396 |
{
|
397 |
foreach($this->blocks as $block)
|
398 |
{
|
399 |
+
$block->admin_fields();
|
400 |
+
|
401 |
}
|
402 |
+
//do_action('mb-admin-fields' );
|
403 |
+
|
404 |
}
|
405 |
+
|
406 |
/* Display the button */
|
407 |
public function display($args = array() )
|
408 |
+
{
|
409 |
maxUtils::startTime('button-display-'. $this->id);
|
410 |
$defaults = array(
|
411 |
"mode" => 'normal',
|
412 |
"preview_part" => "full",
|
413 |
+
"echo" => true,
|
414 |
+
"load_css" => "footer", // control how css is loaded.
|
415 |
+
"compile" => false, // possibility to force recompile if needed.
|
416 |
);
|
417 |
+
$output = ''; // init output;
|
418 |
+
|
419 |
+
$args = wp_parse_args($args, $defaults);
|
420 |
|
421 |
$cssParser = $this->getCSSParser(); // init parser
|
422 |
+
|
423 |
+
$this->load_css = $args["load_css"];
|
424 |
+
|
425 |
if ($this->id == 0) // if button doesn't exists don't display unless in editor
|
426 |
{
|
427 |
+
if (! $args["mode"] == 'editor' )
|
428 |
return;
|
429 |
+
|
430 |
+
$this->clear();
|
431 |
+
|
432 |
$this->data["id"] = 0;
|
433 |
//do_action('mb-data-load', $data);
|
434 |
}
|
435 |
+
|
436 |
+
$mode = (isset($args["mode"])) ? $args["mode"] : "normal";
|
437 |
switch($mode)
|
438 |
{
|
439 |
+
case "preview":
|
440 |
$preview = true;
|
441 |
$compile = false;
|
442 |
+
break;
|
443 |
+
case "editor":
|
444 |
+
$preview = true;
|
445 |
+
$compile = true;
|
446 |
+
// editor is both compile and preview.
|
447 |
break;
|
448 |
break;
|
449 |
+
case "normal":
|
450 |
+
$preview = false;
|
451 |
$compile = false;
|
452 |
break;
|
453 |
}
|
455 |
|
456 |
// Apply filters for general data override
|
457 |
|
458 |
+
$this->data = apply_filters('mb/button/data_before_display', $this->data, $mode, array('preview' => $preview, 'compile' => $compile) ); // hooks
|
459 |
+
|
460 |
+
|
461 |
|
|
|
|
|
462 |
if ( $this->load_css == "element" || $args["preview_part"] != "full" || $args["compile"] == true) { // if css output is on element, for to compile - otherwise inline styles will not be loaded.
|
463 |
$compile = true;
|
464 |
|
465 |
}
|
466 |
+
else
|
467 |
$compile = false;
|
468 |
|
469 |
// reload the data into the blocks, might have been altered by shortcode, filters etc.
|
473 |
$block->set($this->data);
|
474 |
}
|
475 |
|
476 |
+
$domObj = $this->parse_button($mode);
|
477 |
+
|
478 |
maxUtils::startTime('button-parse-css-'. $this->id);
|
479 |
+
$this->parse_css($mode, $compile);
|
480 |
maxUtils::endTime('button-parse-css-'. $this->id);
|
481 |
+
|
482 |
+
if (! $preview) // no js on previews
|
483 |
+
$this->parse_js($mode);
|
484 |
+
|
485 |
if ($preview) // mark it preview
|
486 |
{
|
487 |
|
488 |
$domObj->find('a',0)->class .= ' maxbutton-preview';
|
489 |
}
|
490 |
+
|
491 |
if ($preview && $args["preview_part"] != 'full')
|
492 |
{
|
493 |
+
|
494 |
if ($args["preview_part"] != 'normal')
|
495 |
{
|
496 |
+
$domObj->find('a',0)->class .= ' hover';
|
497 |
$domObj = $cssParser->outputInline($domObj,'hover');
|
498 |
|
499 |
}
|
500 |
else
|
501 |
{
|
502 |
+
$domObj->find('a',0)->class .= ' normal';
|
503 |
$domObj = $cssParser->outputInline($domObj);
|
504 |
}
|
505 |
|
506 |
}
|
507 |
+
elseif ($this->load_css == 'footer')
|
508 |
{
|
509 |
+
$css = $this->display_css(false, false);
|
510 |
+
do_action('mb-footer',$this->id, $css);
|
511 |
+
|
512 |
if (! $preview)
|
513 |
{
|
514 |
$js = $this->display_js(false, true);
|
515 |
do_action('mb-footer', $this->document_id, $js, 'js');
|
516 |
}
|
517 |
+
} elseif ($this->load_css == 'inline')
|
518 |
{
|
519 |
+
if ($args["echo"])
|
520 |
$this->display_css();
|
521 |
else
|
522 |
$output .= $this->display_css(false);
|
523 |
}
|
524 |
+
elseif ($this->load_css == 'element') // not possible to load both normal and hover to an element.
|
525 |
{
|
526 |
+
$domObj->find('a',0)->class .= ' normal';
|
527 |
+
$domObj = $this->cssParser->outputInline($domObj);
|
528 |
+
//$this->get_element_css($domObj, 'normal');
|
529 |
}
|
530 |
+
|
531 |
|
532 |
$output .= $domObj->save();
|
533 |
+
|
534 |
+
$output = apply_filters('mb-before-button-output', $output);
|
535 |
+
maxButtons::buttonDone(array("button_id" => $this->id, "document_id" => $this->document_id) );
|
536 |
+
|
537 |
maxUtils::endTime('button-display-'. $this->id);
|
538 |
+
|
539 |
if ($args["echo"])
|
540 |
+
echo $output;
|
541 |
else
|
542 |
+
return $output;
|
543 |
|
544 |
+
}
|
545 |
/* Function used to map field id's to display for Frontend Javascript
|
546 |
+
|
547 |
+
This function bundles all defined fields into a json encoded variable. This is used for the frontend javascript functions in the
|
548 |
administrator area like colorpickers and real-time updating of the button preview
|
549 |
*/
|
550 |
public function display_field_map()
|
551 |
{
|
552 |
+
$map = array();
|
553 |
foreach($this->blocks as $block)
|
554 |
{
|
555 |
+
$map = $block->map_fields($map);
|
556 |
}
|
557 |
+
//$map = apply_filters("mb-field-map",$map);
|
558 |
+
|
559 |
|
560 |
+
echo "<script language='javascript'>";
|
561 |
echo "var buttonFieldMap = '" . json_encode($map) . "';" ;
|
562 |
echo "</script>";
|
563 |
+
|
564 |
}
|
565 |
+
|
566 |
+
/* Write parsed CSS to output.
|
567 |
+
@param echo Default true. When true, outputs directly, otherwise returns output string
|
568 |
@param style_tag Default true. When true, outputs a html <style> tags around the output.
|
569 |
*/
|
570 |
public function display_css($echo = true, $style_tag = true)
|
571 |
{
|
572 |
+
$output = '';
|
573 |
+
|
574 |
if ($style_tag)
|
575 |
$output .= "<style type='text/css'>";
|
576 |
+
|
577 |
$output .= $this->parsed_css;
|
578 |
+
|
579 |
if ($style_tag)
|
580 |
$output .= "</style>";
|
581 |
+
|
582 |
+
|
583 |
+
if ($echo) echo $output;
|
584 |
+
else return $output;
|
585 |
+
|
586 |
}
|
587 |
+
|
588 |
/* Output Parsed Javascripting */
|
589 |
public function display_js($echo = true, $tag = true)
|
590 |
{
|
591 |
$output = '';
|
592 |
|
593 |
+
if (count($this->button_js) == 0)
|
594 |
return; // no output, holiday
|
595 |
+
|
596 |
+
if ($tag)
|
597 |
{
|
598 |
+
$output .= "<script type='text/javascript'> ";
|
599 |
$output .= " if (typeof maxButton" . $this->document_id . " == 'undefined') { ";
|
600 |
$output .= " function maxButton" . $this->document_id . "() { ";
|
601 |
}
|
602 |
+
|
603 |
+
foreach($this->button_js as $index => $code)
|
604 |
{
|
605 |
+
$output .= $code;
|
606 |
+
|
607 |
}
|
608 |
+
|
609 |
+
if ($tag)
|
610 |
{
|
611 |
+
$output .= " }
|
612 |
+
}
|
613 |
+
window.onload = maxButton" . $this->document_id . "();
|
614 |
+
</script> ";
|
615 |
}
|
616 |
|
617 |
+
if ($echo) echo $output;
|
618 |
+
else return $output;
|
619 |
}
|
620 |
|
621 |
|
622 |
+
/* Makes a copy of the current buttons.
|
623 |
+
|
624 |
+
The button to be copied -must- be loaded and set
|
625 |
*/
|
626 |
+
function copy()
|
627 |
+
{
|
628 |
+
$this->id = 0;
|
629 |
$data = $this->data;
|
630 |
$data["name"] = $this->name;
|
631 |
+
|
632 |
+
return $this->update($data);
|
633 |
}
|
634 |
/* Change the publication status of the button.
|
635 |
+
|
636 |
*/
|
637 |
+
function setStatus($status = "publish")
|
638 |
{
|
639 |
+
$data = $this->data;
|
640 |
+
$data["status"] = sanitize_text_field($status);
|
641 |
+
|
642 |
+
return $this->update($data);
|
643 |
|
644 |
+
}
|
645 |
+
/* Remove the button from database */
|
646 |
+
public function delete($id)
|
|
|
|
|
647 |
{
|
648 |
global $wpdb;
|
649 |
$wpdb->query($wpdb->prepare("DELETE FROM " . maxUtils::get_table_name() . " WHERE id = %d", $id));
|
650 |
}
|
651 |
+
|
652 |
+
/* Save changes to the button
|
653 |
+
|
654 |
+
Updates or saves the button. Existing buttons must load their data and be set -first- or lose all not-passed data.
|
655 |
+
|
656 |
@param post Post data in field - value format (flat $_POST array)
|
657 |
+
@param boolean savedb if false do not save to database
|
658 |
*/
|
659 |
public function save($post, $savedb = true)
|
660 |
{
|
661 |
$post = stripslashes_deep($post); // don't multiply slashes please.
|
662 |
+
//$data = apply_filters('mb-save-fields',$this->data, $post);
|
663 |
$data = $this->data;
|
664 |
+
|
665 |
+
foreach($this->blocks as $block)
|
666 |
{
|
667 |
+
$data = $block->save_fields($data, $post);
|
668 |
}
|
669 |
+
|
670 |
+
if (! $savedb ) return $data;
|
671 |
+
return $this->update($data); // save to db.
|
672 |
+
|
673 |
}
|
674 |
+
|
675 |
/* Updates the button data to the database. Adds a button if it doesn't exist */
|
676 |
+
public function update($data)
|
677 |
+
{
|
678 |
+
global $wpdb;
|
679 |
+
$return = false;
|
680 |
+
|
681 |
+
$fields = array();
|
682 |
foreach($this->blocks as $block)
|
683 |
{
|
684 |
+
$block_name = $block->get_name();
|
685 |
+
|
686 |
+
if (isset($data[$block_name]))
|
687 |
{
|
688 |
+
$blockData = $data[$block_name];
|
689 |
$fields[$block_name] = json_encode($blockData);
|
690 |
}
|
691 |
+
}
|
692 |
+
if (isset($data["name"])) { // other fields.
|
693 |
+
$fields["name"] = $data["name"];
|
694 |
}
|
695 |
if (isset($data["status"])) {
|
696 |
+
$fields["status"] = $data["status"];
|
697 |
}
|
698 |
+
|
699 |
+
|
700 |
$where = array('id' => $this->id );
|
701 |
+
if ($this->id > 0)
|
702 |
{
|
703 |
$where = array('id' => $this->id);
|
704 |
$where_format = array('%d');
|
707 |
}
|
708 |
else
|
709 |
{
|
710 |
+
$fields['created'] = current_time('mysql',1);
|
711 |
|
712 |
$result = $wpdb->insert(maxUtils::get_table_name(), $fields);
|
713 |
$id = $wpdb->insert_id;
|
714 |
|
715 |
$this->id = $id;
|
716 |
+
$return = $id;
|
717 |
+
|
718 |
}
|
719 |
+
|
720 |
+
|
721 |
if ($result === false)
|
722 |
{
|
723 |
$error = "Database error " . $wpdb->last_error;
|
724 |
+
MB()->add_notice('error', $error);
|
725 |
+
$install = MB()->getClass("install");
|
726 |
$install::create_database_table(); // run dbdelta to try and fix.
|
727 |
+
|
728 |
}
|
729 |
+
|
730 |
+
// update the cache
|
731 |
+
$this->cache = ''; // empty cache
|
732 |
$result = $this->set($this->id); // set the newest values
|
733 |
+
|
734 |
+
if (! $result ) return false;
|
735 |
+
|
736 |
$this->display(array("echo" => false, "load_css" => "element")); // do display routing to compile.
|
737 |
+
$css = $this->parsed_css;
|
738 |
+
$this->update_cache($css);
|
739 |
|
740 |
return $return;
|
741 |
}
|
742 |
+
|
743 |
/* Updates the CSS cache. */
|
744 |
public function update_cache($css)
|
745 |
{
|
746 |
$return = false;
|
747 |
+
global $wpdb;
|
748 |
+
|
749 |
+
if ($this->id > 0)
|
750 |
{
|
751 |
+
$fields = array("cache" => $css);
|
752 |
$where = array('id' => $this->id);
|
753 |
$where_format = array('%d');
|
754 |
$wpdb->update(maxUtils::get_table_name(), $fields, $where, null, $where_format);
|
755 |
$return = true;
|
756 |
+
|
757 |
}
|
758 |
+
return $return;
|
759 |
}
|
760 |
+
|
761 |
// Resets all of the button caches.
|
762 |
public function reset_cache()
|
763 |
{
|
764 |
global $wpdb;
|
765 |
+
$fields = array("cache" => null);
|
766 |
$where = array(1 => 1);
|
767 |
//$where_format = array('%d');
|
768 |
+
$sql = "UPDATE " . maxUtils::get_table_name() . " SET cache = NULL ";
|
769 |
$wpdb->query($sql);
|
770 |
+
|
771 |
}
|
772 |
|
773 |
+
|
774 |
/* Display button via shortcode
|
775 |
+
|
776 |
Function that accepts WP shortcode arguments and displays or returns a button
|
777 |
+
|
778 |
+
@param $atts array Shortcode Atts
|
779 |
@return string HTML presentation of button
|
780 |
+
|
781 |
*/
|
782 |
public function shortcode($atts)
|
783 |
+
{
|
784 |
extract(shortcode_atts(array(
|
785 |
'id' => '',
|
786 |
'name' => '',
|
787 |
'text' => '',
|
788 |
'url' => '',
|
789 |
+
'linktitle' => '',
|
790 |
'window' => '',
|
791 |
'nofollow' => '',
|
792 |
+
'nocache' => false,
|
793 |
+
'style' => 'footer',
|
794 |
'exclude' => ''
|
795 |
|
796 |
+
), $atts));
|
797 |
|
798 |
+
$button_id = $id;
|
799 |
$button_name = $name;
|
800 |
+
|
801 |
+
if ($button_id > 0)
|
802 |
+
$result = $this->set($button_id);
|
803 |
+
elseif ($button_name != '')
|
804 |
+
$result = $this->set(0, $button_name);
|
805 |
else return; // no button id / name
|
806 |
+
|
807 |
/* Shortcode cache control
|
808 |
+
|
809 |
If true the button CSS will be recompiled again. If false the plugin will check the cache for CSS declarations. Set to true if anything is interrupting the caching mechanism. Please note, recompiling causes some load times!
|
|
|
|
|
|
|
|
|
810 |
|
811 |
+
@param boolean $nocache True / False
|
812 |
+
*/
|
813 |
+
$compile = apply_filters("mb/shortcode/nocache", $nocache);
|
814 |
+
|
815 |
+
if (! $result)
|
816 |
return; // shortcode doesn't exist
|
817 |
+
|
818 |
// If we're not in the admin and the button is in the trash, just return nothing
|
819 |
if (!is_admin() && $this->status == 'trash') {
|
820 |
return '';
|
822 |
// Check to handle excludes
|
823 |
if ("{$exclude}" != '') {
|
824 |
global $post;
|
825 |
+
|
826 |
// Don't render the button if excluded from the current post/page
|
827 |
$exclude = explode(',', "{$exclude}");
|
828 |
if (in_array($post->ID, $exclude)) {
|
829 |
return '';
|
830 |
}
|
831 |
}
|
832 |
+
|
833 |
// Override shortcode options comparing to default button data.
|
834 |
+
$overrides = false;
|
835 |
+
if ($text != '')
|
836 |
+
{
|
837 |
+
$this->data["text"]["text"] = $text;
|
838 |
$overrides = true;
|
839 |
+
}
|
840 |
+
if ($url != '')
|
841 |
{
|
842 |
|
843 |
+
$this->data["basic"]["url"] = $url;
|
844 |
//$compile = true; // css change forces recompile
|
845 |
$overrides = true;
|
846 |
}
|
847 |
+
if ($window != '' && $window =='new')
|
848 |
{
|
849 |
+
$this->data["basic"]["new_window"] = 1;
|
850 |
$overrides = true;
|
851 |
}
|
852 |
+
elseif ($window != '' && $window == 'same')
|
853 |
{
|
854 |
+
$this->data["basic"]["new_window"] = 0;
|
855 |
+
$overrides = true;
|
856 |
}
|
857 |
+
|
858 |
+
if ($nofollow != '' && $nofollow == 'true')
|
859 |
{
|
860 |
+
$this->data["basic"]["nofollow"] = 1;
|
861 |
$overrides = true;
|
862 |
}
|
863 |
+
|
864 |
+
if ($linktitle != '')
|
865 |
{
|
866 |
+
$this->data['basic']['link_title'] = $linktitle;
|
867 |
$overrides = true;
|
868 |
}
|
869 |
|
870 |
switch($style)
|
871 |
{
|
872 |
+
case "inline":
|
873 |
+
$load_css = 'inline';
|
874 |
break;
|
875 |
default:
|
876 |
+
$load_css = 'footer';
|
877 |
break;
|
878 |
+
}
|
879 |
|
880 |
// allow for more flexible changes and data manipulation.
|
881 |
$data = $this->data;
|
882 |
+
$this->data = $this->shortcode_overrides($this->data, $atts);
|
883 |
+
$this->data = apply_filters('mb/shortcode/data', $this->data, $atts);
|
884 |
+
|
885 |
+
/* if ($data !== $this->data)
|
886 |
{
|
887 |
+
$overrides = true;
|
888 |
}
|
889 |
+
*/
|
890 |
/* if ($overrides)
|
891 |
{
|
892 |
do_action('mb-data-load', $this->data);
|
893 |
}
|
894 |
+
*/
|
895 |
// if there are no reasons not to display; display
|
896 |
+
$args = array("echo" => false,
|
897 |
+
"load_css" => $load_css,
|
898 |
+
"compile" => $compile,
|
899 |
);
|
900 |
+
$args = apply_filters('mb_shortcode_display_args', $args);
|
901 |
+
|
902 |
+
|
903 |
$output = $this->display($args);
|
904 |
+
|
905 |
return $output;
|
906 |
+
|
907 |
}
|
908 |
+
|
909 |
+
|
910 |
public function shortcode_overrides($data, $atts)
|
911 |
{
|
912 |
return $data;
|
913 |
}
|
|
|
|
|
914 |
|
915 |
+
} // class
|
classes/max-utils.php
CHANGED
@@ -2,77 +2,78 @@
|
|
2 |
namespace MaxButtons;
|
3 |
defined('ABSPATH') or die('No direct access permitted');
|
4 |
|
5 |
-
// new class for the future.
|
6 |
class maxUtils
|
7 |
{
|
8 |
-
|
9 |
protected static $timings = array();
|
10 |
-
protected static $time_operations = array();
|
11 |
protected static $timer = 0;
|
12 |
-
|
13 |
-
|
14 |
-
/** Callback for array filter to prepend namepaces. **/
|
15 |
-
public static function array_namespace($var)
|
16 |
{
|
17 |
-
$namespace = __NAMESPACE__ . '\\'; // PHP 5.3
|
18 |
-
return ($namespace . $var);
|
19 |
-
}
|
20 |
-
|
21 |
public static function namespaceit($var)
|
22 |
{
|
23 |
-
$namespace = __NAMESPACE__ . '\\'; // PHP 5.3
|
24 |
return $namespace . $var;
|
25 |
}
|
26 |
-
|
27 |
-
// central ajax action handler
|
28 |
public static function ajax_action()
|
29 |
{
|
30 |
-
$status = 'error';
|
|
|
|
|
|
|
|
|
31 |
|
32 |
-
$plugin_action = isset($_POST['plugin_action']) ? sanitize_text_field($_POST['plugin_action']) : '';
|
33 |
-
$nonce = isset($_POST['nonce']) ? $_POST['nonce'] : false;
|
34 |
-
$message = __( sprintf("No Handler found for action %s ", $plugin_action), 'maxbuttons');
|
35 |
-
|
36 |
if (! wp_verify_nonce($nonce, 'maxajax') )
|
37 |
{
|
38 |
$message = __('Nonce not verified', 'maxbuttons');
|
39 |
}
|
40 |
else
|
41 |
{
|
42 |
-
do_action('maxbuttons/ajax/' . $plugin_action, $_POST);
|
43 |
}
|
44 |
-
|
45 |
-
echo json_encode( array( 'status' => $status,
|
46 |
-
'message' => $message,
|
47 |
)
|
48 |
-
);
|
49 |
-
wp_die();
|
50 |
}
|
51 |
-
|
52 |
-
public static function translit($string)
|
53 |
{
|
54 |
-
require_once(MB()->get_plugin_path() . "assets/libraries/url_slug.php");
|
55 |
-
|
|
|
56 |
return $string;
|
57 |
}
|
58 |
|
59 |
public static function selectify($name, $array, $selected, $target = '', $class = '')
|
60 |
{
|
61 |
// optional target for js updating
|
62 |
-
if ($target != '' )
|
63 |
-
$target = " data-target='$target' ";
|
64 |
-
if ($class != '')
|
65 |
-
$class = " class='$class' ";
|
66 |
$output = "<select name='$name' id='$name' $target $class>";
|
67 |
-
|
68 |
-
foreach($array as $key => $value)
|
69 |
{
|
70 |
-
$output .= "<option value='$key' " . selected($key, $selected, false) . ">$value</option>";
|
71 |
}
|
72 |
-
$output .= "</select>";
|
73 |
-
|
74 |
return $output;
|
75 |
-
|
76 |
}
|
77 |
|
78 |
|
@@ -92,10 +93,10 @@ class maxUtils
|
|
92 |
$g = hexdec(substr($hex, 2, 2));
|
93 |
$b = hexdec(substr($hex, 4, 2));
|
94 |
}
|
95 |
-
|
96 |
// The array of rgb values
|
97 |
$rgb_array = array($r, $g, $b);
|
98 |
-
|
99 |
// Catch for opacity when the button has not been saved
|
100 |
if($opacity == '') {
|
101 |
$alpha = 1;
|
@@ -106,255 +107,255 @@ class maxUtils
|
|
106 |
|
107 |
// The rgb values separated by commas
|
108 |
$rgb = implode(", ", $rgb_array);
|
109 |
-
|
110 |
// Spits out rgba(0, 0, 0, 0.5) format
|
111 |
return 'rgba(' . $rgb . ', ' . $alpha . ')';
|
112 |
}
|
113 |
-
|
114 |
static function strip_px($value) {
|
115 |
return rtrim( intval($value), 'px');
|
116 |
}
|
117 |
|
118 |
-
static function generate_font_sizes($start, $end, $step = 1)
|
119 |
{
|
120 |
-
$sizes = array();
|
121 |
-
|
122 |
for ($i = $start; $i <= $end; $i += $step)
|
123 |
{
|
124 |
-
$sizes[$i] = $i;
|
125 |
-
|
126 |
}
|
127 |
-
return $sizes;
|
128 |
-
|
129 |
}
|
130 |
|
131 |
|
132 |
static function get_media_query($get_option = 1)
|
133 |
{
|
134 |
-
|
135 |
$queries = array("phone" => "only screen and (max-width : 480px)",
|
136 |
-
"phone_land" => "only screen and (min-width : 321px) and (max-width : 480px)",
|
137 |
-
"phone_portrait" => " only screen and (max-width : 320px)",
|
138 |
"ipad" => "only screen and (min-width : 768px) and (max-width : 1024px)",
|
139 |
"medium_phone" => "only screen and (min-width: 480px) and (max-width: 768px)",
|
140 |
-
"ipad_land" => "only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape)",
|
141 |
"ipad_portrait" => "only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait)",
|
142 |
"desktop" => "only screen and (min-width : 1224px)",
|
143 |
-
"large_desktop" => "only screen and (min-width : 1824px)",
|
144 |
);
|
145 |
-
|
146 |
$query_names = array(
|
147 |
-
"phone" => __("Small phones","maxbuttons"),
|
148 |
-
"phone_land" => __("Small phones (landscape)","maxbuttons"),
|
149 |
-
"phone_portrait" => __("Small phones (portrait)","maxbuttons"),
|
150 |
"medium_phone" => __("Medium-size (smart)phone","maxbuttons"),
|
151 |
"ipad" => __("Ipad (all) / Large phones","maxbuttons"),
|
152 |
-
"ipad_land" => __("Ipad landscape","maxbuttons"),
|
153 |
"ipad_portrait" => __("Ipad portrait","maxbuttons"),
|
154 |
"desktop" => __("Desktop","maxbuttons"),
|
155 |
-
"large_desktop" => __("Large desktops","maxbuttons"),
|
156 |
-
"custom" => __("Custom size","maxbuttons"),
|
157 |
-
);
|
158 |
-
|
159 |
$query_descriptions = array(
|
160 |
"phone" => __("Optimized for small smartphones ( screen sizes under 480px )","maxbuttons"),
|
161 |
-
"phone_land" => __("Optimzed for small smartphones in landscape and higher ( screen sizes 321px - 480px)","maxbuttons"),
|
162 |
-
"phone_portrait" => __("Optimized for small phones ( screen size max 320px )","maxbuttons"),
|
163 |
-
"ipad" => __("Optimized for devices between 768px and 1024px","maxbuttons"),
|
164 |
-
"medium_phone" => __("Optimized for medium sizes devices between 480px and 768px","maxbuttons"),
|
165 |
-
"ipad_land" => __("Optimized for devices between 768px and 1024px in landscape","maxbuttons"),
|
166 |
-
"ipad_portrait" => __("Optimized for deviced between 768px and 1024 in portrait","maxbuttons"),
|
167 |
"desktop" => __("Desktop screens from 1224px","maxbuttons"),
|
168 |
"large_desktop" => __("Large desktop screens, from 1824px","maxbuttons"),
|
169 |
-
"custom" => __("Set your own breakpoints","maxbuttons"),
|
170 |
-
);
|
171 |
-
|
172 |
-
|
173 |
switch($get_option)
|
174 |
{
|
175 |
-
case 1:
|
176 |
return $query_names;
|
177 |
break;
|
178 |
-
case 2:
|
179 |
-
return $queries;
|
180 |
break;
|
181 |
-
case 3:
|
182 |
return $query_descriptions;
|
183 |
break;
|
184 |
}
|
185 |
-
|
186 |
}
|
187 |
-
|
188 |
-
static function get_buttons_table_name($old = false)
|
189 |
{
|
190 |
-
self::addTime('Legacy Function call : get_buttons_table_name');
|
191 |
return self::get_table_name($old);
|
192 |
}
|
193 |
-
|
194 |
static function get_table_name($old = false) {
|
195 |
global $wpdb;
|
196 |
if ($old)
|
197 |
return $wpdb->prefix . 'maxbuttons_buttons';
|
198 |
else
|
199 |
-
return $wpdb->prefix . 'maxbuttonsv3';
|
200 |
}
|
201 |
|
202 |
-
static function get_collection_table_name() {
|
203 |
-
global $wpdb;
|
204 |
-
return $wpdb->prefix . 'maxbuttons_collections';
|
205 |
-
|
206 |
}
|
207 |
|
208 |
-
static function get_coltrans_table_name() {
|
209 |
-
global $wpdb;
|
210 |
-
return $wpdb->prefix . 'maxbuttons_collections_trans';
|
211 |
-
|
212 |
}
|
213 |
-
|
214 |
/* Replacement function for Wordpress' transients and problematic name length. */
|
215 |
-
static function get_transient($name)
|
216 |
{
|
217 |
-
global $wpdb;
|
218 |
-
// self::removeExpiredTrans();
|
219 |
-
|
220 |
-
if ($name == '')
|
221 |
return false;
|
222 |
-
|
223 |
$table = self::get_coltrans_table_name();
|
224 |
-
|
225 |
-
$sql = "SELECT value FROM $table where name= '%s' ";
|
226 |
-
$sql = $wpdb->prepare($sql, $name);
|
227 |
-
|
228 |
-
$var = $wpdb->get_var($sql);
|
229 |
-
|
230 |
-
if (is_null($var))
|
231 |
$var = false;
|
232 |
-
|
233 |
-
return $var;
|
234 |
-
|
235 |
}
|
236 |
-
|
237 |
-
|
238 |
static function set_transient($name, $value , $expire = -1 )
|
239 |
{
|
240 |
-
global $wpdb;
|
241 |
-
|
242 |
-
|
243 |
if ($expire == -1 )
|
244 |
-
$expire = HOUR_IN_SECONDS * 4;
|
245 |
-
|
246 |
-
if ($name == '')
|
247 |
-
return false;
|
248 |
-
|
249 |
-
$expire_time = time() + $expire;
|
250 |
-
|
251 |
$table = self::get_coltrans_table_name();
|
252 |
-
|
253 |
// prevent doubles, remove any present by this name
|
254 |
-
self::delete_transient($name);
|
255 |
-
|
256 |
-
$wpdb->insert($table,
|
257 |
-
array("name" => $name,
|
258 |
-
"value" => $value,
|
259 |
"expire" => $expire_time
|
260 |
-
),
|
261 |
-
array("%s","%s","%d"));
|
262 |
-
|
263 |
-
|
264 |
-
}
|
265 |
-
|
266 |
-
static function delete_transient($name)
|
267 |
{
|
268 |
-
global $wpdb;
|
269 |
-
|
270 |
-
|
271 |
$table = self::get_coltrans_table_name();
|
272 |
-
$wpdb->delete($table, array("name" => $name), array('%s') );
|
273 |
|
274 |
}
|
275 |
-
|
276 |
-
static function removeExpiredTrans()
|
277 |
{
|
278 |
-
global $wpdb;
|
279 |
-
|
280 |
$table = self::get_coltrans_table_name();
|
281 |
-
$sql = "DELETE FROM $table WHERE expire < UNIX_TIMESTAMP(NOW())";
|
282 |
$return = $wpdb->query($sql);
|
283 |
-
|
284 |
if($return === false)
|
285 |
{
|
286 |
$error = "Database error " . $wpdb->last_error;
|
287 |
-
MB()->add_notice('error', $error);
|
288 |
$install = MB()->getClass('install');
|
289 |
-
$install->create_database_table();
|
290 |
}
|
291 |
-
|
292 |
}
|
293 |
-
|
294 |
-
/** Function will try to unload any FA scripts other than MB from WP. In case of conflict */
|
295 |
-
static function fixFAConflict()
|
296 |
{
|
297 |
-
$forcefa = get_option('maxbuttons_forcefa');
|
298 |
-
|
299 |
-
if ($forcefa != '1')
|
300 |
return;
|
301 |
-
|
302 |
global $wp_styles;
|
303 |
|
304 |
-
$our_fa_there = false;
|
305 |
-
|
306 |
-
foreach($wp_styles->registered as $script => $details)
|
307 |
{
|
308 |
-
if ($script == 'mbpro-font-awesome')
|
309 |
{
|
310 |
-
$our_fa_there = true;
|
311 |
break;
|
312 |
-
}
|
313 |
}
|
314 |
-
|
315 |
// fix nothing on pages where we are not loading.
|
316 |
-
if (! $our_fa_there)
|
317 |
-
return;
|
318 |
-
|
319 |
|
320 |
// Loop through all registered styles and remove any that appear to be Font Awesome.
|
321 |
foreach ( $wp_styles->registered as $script => $details ) {
|
322 |
$src = isset($details->src) ? $details->src : false;
|
323 |
|
324 |
-
if ($script == 'mbpro-font-awesome')
|
325 |
{
|
326 |
$mbpro_src = $src;
|
327 |
continue; // exclude us
|
328 |
}
|
329 |
-
|
330 |
if ( false !== strpos( $script, 'fontawesome' ) || false !== strpos( $script, 'font-awesome' ) ) {
|
331 |
wp_dequeue_style( $script );
|
332 |
}
|
333 |
if ($src && ( false !== strpos($src, 'font-awesome') || false !== strpos($src, 'fontawesome') ) )
|
334 |
{
|
335 |
-
wp_dequeue_style( $script );
|
336 |
}
|
337 |
|
338 |
}
|
339 |
-
|
340 |
-
// This is a fix specific for NGGallery since they load their scripts weirdly / wrongly, but do check for the presence of a style named 'fontawesome' .
|
341 |
wp_register_style('fontawesome', $src);
|
342 |
|
343 |
}
|
344 |
-
|
345 |
|
346 |
static function timeInit()
|
347 |
{
|
348 |
if ( ! defined('MAXBUTTONS_BENCHMARK') || MAXBUTTONS_BENCHMARK !== true)
|
349 |
return;
|
350 |
-
|
351 |
self::$timer = microtime(true);
|
352 |
|
353 |
-
if (is_admin())
|
354 |
-
add_filter("admin_footer",array(self::namespaceit('maxUtils'), "showTime"), 100);
|
355 |
else
|
356 |
-
add_action("wp_footer",array(self::namespaceit('maxUtils'), "showTime"));
|
357 |
-
|
358 |
}
|
359 |
|
360 |
static function addTime($msg)
|
@@ -362,28 +363,28 @@ class maxUtils
|
|
362 |
if ( ! defined('MAXBUTTONS_BENCHMARK') || MAXBUTTONS_BENCHMARK !== true)
|
363 |
return;
|
364 |
|
365 |
-
|
366 |
-
self::$timings[] = array("msg" => $msg,"time" => microtime(true));
|
367 |
}
|
368 |
-
|
369 |
static function startTime($operation)
|
370 |
{
|
371 |
if ( ! defined('MAXBUTTONS_BENCHMARK') || MAXBUTTONS_BENCHMARK !== true)
|
372 |
return;
|
373 |
-
|
374 |
-
self::$time_operations[$operation][] = array("start" => microtime(true),
|
375 |
-
"end" => 0,
|
376 |
-
);
|
377 |
-
|
378 |
}
|
379 |
-
|
380 |
-
static function endTime($operation)
|
381 |
{
|
382 |
if ( ! defined('MAXBUTTONS_BENCHMARK') || MAXBUTTONS_BENCHMARK !== true)
|
383 |
return;
|
384 |
-
|
385 |
-
$timedcount = count(self::$time_operations[$operation]);
|
386 |
-
for ($i = 0; $i < $timedcount; $i++)
|
387 |
{
|
388 |
if (self::$time_operations[$operation][$i]["end"] == 0)
|
389 |
{
|
@@ -391,79 +392,79 @@ class maxUtils
|
|
391 |
break;
|
392 |
}
|
393 |
}
|
394 |
-
|
395 |
}
|
396 |
-
|
397 |
static function showTime()
|
398 |
{
|
399 |
if ( ! defined('MAXBUTTONS_BENCHMARK') || MAXBUTTONS_BENCHMARK !== true)
|
400 |
return;
|
401 |
-
|
402 |
$timer = self::$timer;
|
403 |
-
$text = '';
|
404 |
-
$text .= "<div id='mb-timer'>";
|
405 |
-
$text .= "<p><strong>Timed Operations</strong></p>";
|
406 |
-
|
407 |
-
foreach(self::$time_operations as $operation => $operations)
|
408 |
{
|
409 |
foreach($operations as $index => $data)
|
410 |
{
|
411 |
-
$start = $data["start"];
|
412 |
-
$end = $data["end"];
|
413 |
-
$duration = $end - $start;
|
414 |
-
|
415 |
-
|
416 |
$text .= "<span class='first'>$duration</span>
|
417 |
-
<span class='second'>$operation</span>
|
418 |
-
<span class='third'> </span><br />
|
419 |
-
";
|
420 |
-
|
421 |
-
|
422 |
}
|
423 |
}
|
424 |
-
|
425 |
-
|
426 |
-
$text .= "<p><strong>" . __("MaxButtons Loading Time:","maxbuttons") . "</strong></p>";
|
427 |
$prev_time =0;
|
428 |
-
|
429 |
-
$time_array = array();
|
430 |
-
|
431 |
foreach(self::$timings as $timing)
|
432 |
{
|
433 |
-
$cum = ($timing["time"] - $prev_time);
|
434 |
-
$text .= "<span class='first'>" . ($timing["time"] - $timer) . "</span><span class='second'> " . $timing["msg"] . "</span><span class='third'>$cum</span> <br /> ";
|
435 |
-
//$time_array[$cum] = $timing["msg"];
|
436 |
$prev_time = $timing["time"];
|
437 |
}
|
438 |
|
439 |
/*ksort($time_array);
|
440 |
-
|
441 |
-
$text .= "<br><br><strong>By time taken:</strong><br>";
|
442 |
foreach($time_array as $timeline)
|
443 |
{
|
444 |
-
$text .= "$timeline <br />";
|
445 |
}
|
446 |
*/
|
447 |
$text .= "</div> ";
|
448 |
-
$text .= "<style>#mb-timer { margin-left: 180px; }
|
449 |
-
#mb-timer span {
|
450 |
display: inline-block;
|
451 |
font-size: 12px;
|
452 |
}
|
453 |
-
#mb-timer span.first {
|
454 |
-
width: 170px;
|
|
|
|
|
|
|
455 |
}
|
456 |
-
#mb-timer span.
|
457 |
-
width:
|
458 |
}
|
459 |
-
|
460 |
-
|
461 |
-
}
|
462 |
-
</style>";
|
463 |
-
|
464 |
echo $text;
|
465 |
-
|
466 |
-
|
467 |
-
//return $filter . $text;
|
468 |
}
|
469 |
}
|
2 |
namespace MaxButtons;
|
3 |
defined('ABSPATH') or die('No direct access permitted');
|
4 |
|
5 |
+
// new class for the future.
|
6 |
class maxUtils
|
7 |
{
|
8 |
+
|
9 |
protected static $timings = array();
|
10 |
+
protected static $time_operations = array();
|
11 |
protected static $timer = 0;
|
12 |
+
|
13 |
+
|
14 |
+
/** Callback for array filter to prepend namepaces. **/
|
15 |
+
public static function array_namespace($var)
|
16 |
{
|
17 |
+
$namespace = __NAMESPACE__ . '\\'; // PHP 5.3
|
18 |
+
return ($namespace . $var);
|
19 |
+
}
|
20 |
+
|
21 |
public static function namespaceit($var)
|
22 |
{
|
23 |
+
$namespace = __NAMESPACE__ . '\\'; // PHP 5.3
|
24 |
return $namespace . $var;
|
25 |
}
|
26 |
+
|
27 |
+
// central ajax action handler
|
28 |
public static function ajax_action()
|
29 |
{
|
30 |
+
$status = 'error';
|
31 |
+
|
32 |
+
$plugin_action = isset($_POST['plugin_action']) ? sanitize_text_field($_POST['plugin_action']) : '';
|
33 |
+
$nonce = isset($_POST['nonce']) ? $_POST['nonce'] : false;
|
34 |
+
$message = __( sprintf("No Handler found for action %s ", $plugin_action), 'maxbuttons');
|
35 |
|
|
|
|
|
|
|
|
|
36 |
if (! wp_verify_nonce($nonce, 'maxajax') )
|
37 |
{
|
38 |
$message = __('Nonce not verified', 'maxbuttons');
|
39 |
}
|
40 |
else
|
41 |
{
|
42 |
+
do_action('maxbuttons/ajax/' . $plugin_action, $_POST);
|
43 |
}
|
44 |
+
|
45 |
+
echo json_encode( array( 'status' => $status,
|
46 |
+
'message' => $message,
|
47 |
)
|
48 |
+
);
|
49 |
+
wp_die();
|
50 |
}
|
51 |
+
|
52 |
+
public static function translit($string)
|
53 |
{
|
54 |
+
require_once(MB()->get_plugin_path() . "assets/libraries/url_slug.php");
|
55 |
+
|
56 |
+
$string = mb_url_slug($string, array("transliterate" => true));
|
57 |
return $string;
|
58 |
}
|
59 |
|
60 |
public static function selectify($name, $array, $selected, $target = '', $class = '')
|
61 |
{
|
62 |
// optional target for js updating
|
63 |
+
if ($target != '' )
|
64 |
+
$target = " data-target='$target' ";
|
65 |
+
if ($class != '')
|
66 |
+
$class = " class='$class' ";
|
67 |
$output = "<select name='$name' id='$name' $target $class>";
|
68 |
+
|
69 |
+
foreach($array as $key => $value)
|
70 |
{
|
71 |
+
$output .= "<option value='$key' " . selected($key, $selected, false) . ">$value</option>";
|
72 |
}
|
73 |
+
$output .= "</select>";
|
74 |
+
|
75 |
return $output;
|
76 |
+
|
77 |
}
|
78 |
|
79 |
|
93 |
$g = hexdec(substr($hex, 2, 2));
|
94 |
$b = hexdec(substr($hex, 4, 2));
|
95 |
}
|
96 |
+
|
97 |
// The array of rgb values
|
98 |
$rgb_array = array($r, $g, $b);
|
99 |
+
|
100 |
// Catch for opacity when the button has not been saved
|
101 |
if($opacity == '') {
|
102 |
$alpha = 1;
|
107 |
|
108 |
// The rgb values separated by commas
|
109 |
$rgb = implode(", ", $rgb_array);
|
110 |
+
|
111 |
// Spits out rgba(0, 0, 0, 0.5) format
|
112 |
return 'rgba(' . $rgb . ', ' . $alpha . ')';
|
113 |
}
|
114 |
+
|
115 |
static function strip_px($value) {
|
116 |
return rtrim( intval($value), 'px');
|
117 |
}
|
118 |
|
119 |
+
static function generate_font_sizes($start, $end, $step = 1)
|
120 |
{
|
121 |
+
$sizes = array();
|
122 |
+
|
123 |
for ($i = $start; $i <= $end; $i += $step)
|
124 |
{
|
125 |
+
$sizes[$i] = $i;
|
126 |
+
|
127 |
}
|
128 |
+
return $sizes;
|
129 |
+
|
130 |
}
|
131 |
|
132 |
|
133 |
static function get_media_query($get_option = 1)
|
134 |
{
|
135 |
+
|
136 |
$queries = array("phone" => "only screen and (max-width : 480px)",
|
137 |
+
"phone_land" => "only screen and (min-width : 321px) and (max-width : 480px)",
|
138 |
+
"phone_portrait" => " only screen and (max-width : 320px)",
|
139 |
"ipad" => "only screen and (min-width : 768px) and (max-width : 1024px)",
|
140 |
"medium_phone" => "only screen and (min-width: 480px) and (max-width: 768px)",
|
141 |
+
"ipad_land" => "only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape)",
|
142 |
"ipad_portrait" => "only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait)",
|
143 |
"desktop" => "only screen and (min-width : 1224px)",
|
144 |
+
"large_desktop" => "only screen and (min-width : 1824px)",
|
145 |
);
|
146 |
+
|
147 |
$query_names = array(
|
148 |
+
"phone" => __("Small phones","maxbuttons"),
|
149 |
+
"phone_land" => __("Small phones (landscape)","maxbuttons"),
|
150 |
+
"phone_portrait" => __("Small phones (portrait)","maxbuttons"),
|
151 |
"medium_phone" => __("Medium-size (smart)phone","maxbuttons"),
|
152 |
"ipad" => __("Ipad (all) / Large phones","maxbuttons"),
|
153 |
+
"ipad_land" => __("Ipad landscape","maxbuttons"),
|
154 |
"ipad_portrait" => __("Ipad portrait","maxbuttons"),
|
155 |
"desktop" => __("Desktop","maxbuttons"),
|
156 |
+
"large_desktop" => __("Large desktops","maxbuttons"),
|
157 |
+
"custom" => __("Custom size","maxbuttons"),
|
158 |
+
);
|
159 |
+
|
160 |
$query_descriptions = array(
|
161 |
"phone" => __("Optimized for small smartphones ( screen sizes under 480px )","maxbuttons"),
|
162 |
+
"phone_land" => __("Optimzed for small smartphones in landscape and higher ( screen sizes 321px - 480px)","maxbuttons"),
|
163 |
+
"phone_portrait" => __("Optimized for small phones ( screen size max 320px )","maxbuttons"),
|
164 |
+
"ipad" => __("Optimized for devices between 768px and 1024px","maxbuttons"),
|
165 |
+
"medium_phone" => __("Optimized for medium sizes devices between 480px and 768px","maxbuttons"),
|
166 |
+
"ipad_land" => __("Optimized for devices between 768px and 1024px in landscape","maxbuttons"),
|
167 |
+
"ipad_portrait" => __("Optimized for deviced between 768px and 1024 in portrait","maxbuttons"),
|
168 |
"desktop" => __("Desktop screens from 1224px","maxbuttons"),
|
169 |
"large_desktop" => __("Large desktop screens, from 1824px","maxbuttons"),
|
170 |
+
"custom" => __("Set your own breakpoints","maxbuttons"),
|
171 |
+
);
|
172 |
+
|
173 |
+
|
174 |
switch($get_option)
|
175 |
{
|
176 |
+
case 1:
|
177 |
return $query_names;
|
178 |
break;
|
179 |
+
case 2:
|
180 |
+
return $queries;
|
181 |
break;
|
182 |
+
case 3:
|
183 |
return $query_descriptions;
|
184 |
break;
|
185 |
}
|
186 |
+
|
187 |
}
|
188 |
+
|
189 |
+
static function get_buttons_table_name($old = false)
|
190 |
{
|
191 |
+
self::addTime('Legacy Function call : get_buttons_table_name');
|
192 |
return self::get_table_name($old);
|
193 |
}
|
194 |
+
|
195 |
static function get_table_name($old = false) {
|
196 |
global $wpdb;
|
197 |
if ($old)
|
198 |
return $wpdb->prefix . 'maxbuttons_buttons';
|
199 |
else
|
200 |
+
return $wpdb->prefix . 'maxbuttonsv3';
|
201 |
}
|
202 |
|
203 |
+
static function get_collection_table_name() {
|
204 |
+
global $wpdb;
|
205 |
+
return $wpdb->prefix . 'maxbuttons_collections';
|
206 |
+
|
207 |
}
|
208 |
|
209 |
+
static function get_coltrans_table_name() {
|
210 |
+
global $wpdb;
|
211 |
+
return $wpdb->prefix . 'maxbuttons_collections_trans';
|
212 |
+
|
213 |
}
|
214 |
+
|
215 |
/* Replacement function for Wordpress' transients and problematic name length. */
|
216 |
+
static function get_transient($name)
|
217 |
{
|
218 |
+
global $wpdb;
|
219 |
+
// self::removeExpiredTrans();
|
220 |
+
|
221 |
+
if ($name == '')
|
222 |
return false;
|
223 |
+
|
224 |
$table = self::get_coltrans_table_name();
|
225 |
+
|
226 |
+
$sql = "SELECT value FROM $table where name= '%s' ";
|
227 |
+
$sql = $wpdb->prepare($sql, $name);
|
228 |
+
|
229 |
+
$var = $wpdb->get_var($sql);
|
230 |
+
|
231 |
+
if (is_null($var))
|
232 |
$var = false;
|
233 |
+
|
234 |
+
return $var;
|
235 |
+
|
236 |
}
|
237 |
+
|
238 |
+
|
239 |
static function set_transient($name, $value , $expire = -1 )
|
240 |
{
|
241 |
+
global $wpdb;
|
242 |
+
|
243 |
+
|
244 |
if ($expire == -1 )
|
245 |
+
$expire = HOUR_IN_SECONDS * 4;
|
246 |
+
|
247 |
+
if ($name == '')
|
248 |
+
return false;
|
249 |
+
|
250 |
+
$expire_time = time() + $expire;
|
251 |
+
|
252 |
$table = self::get_coltrans_table_name();
|
253 |
+
|
254 |
// prevent doubles, remove any present by this name
|
255 |
+
self::delete_transient($name);
|
256 |
+
|
257 |
+
$wpdb->insert($table,
|
258 |
+
array("name" => $name,
|
259 |
+
"value" => $value,
|
260 |
"expire" => $expire_time
|
261 |
+
),
|
262 |
+
array("%s","%s","%d"));
|
263 |
+
|
264 |
+
|
265 |
+
}
|
266 |
+
|
267 |
+
static function delete_transient($name)
|
268 |
{
|
269 |
+
global $wpdb;
|
270 |
+
|
271 |
+
|
272 |
$table = self::get_coltrans_table_name();
|
273 |
+
$wpdb->delete($table, array("name" => $name), array('%s') );
|
274 |
|
275 |
}
|
276 |
+
|
277 |
+
static function removeExpiredTrans()
|
278 |
{
|
279 |
+
global $wpdb;
|
280 |
+
|
281 |
$table = self::get_coltrans_table_name();
|
282 |
+
$sql = "DELETE FROM $table WHERE expire < UNIX_TIMESTAMP(NOW())";
|
283 |
$return = $wpdb->query($sql);
|
284 |
+
|
285 |
if($return === false)
|
286 |
{
|
287 |
$error = "Database error " . $wpdb->last_error;
|
288 |
+
MB()->add_notice('error', $error);
|
289 |
$install = MB()->getClass('install');
|
290 |
+
$install->create_database_table();
|
291 |
}
|
292 |
+
|
293 |
}
|
294 |
+
|
295 |
+
/** Function will try to unload any FA scripts other than MB from WP. In case of conflict */
|
296 |
+
static function fixFAConflict()
|
297 |
{
|
298 |
+
$forcefa = get_option('maxbuttons_forcefa');
|
299 |
+
|
300 |
+
if ($forcefa != '1')
|
301 |
return;
|
302 |
+
|
303 |
global $wp_styles;
|
304 |
|
305 |
+
$our_fa_there = false;
|
306 |
+
|
307 |
+
foreach($wp_styles->registered as $script => $details)
|
308 |
{
|
309 |
+
if ($script == 'mbpro-font-awesome')
|
310 |
{
|
311 |
+
$our_fa_there = true;
|
312 |
break;
|
313 |
+
}
|
314 |
}
|
315 |
+
|
316 |
// fix nothing on pages where we are not loading.
|
317 |
+
if (! $our_fa_there)
|
318 |
+
return;
|
319 |
+
|
320 |
|
321 |
// Loop through all registered styles and remove any that appear to be Font Awesome.
|
322 |
foreach ( $wp_styles->registered as $script => $details ) {
|
323 |
$src = isset($details->src) ? $details->src : false;
|
324 |
|
325 |
+
if ($script == 'mbpro-font-awesome')
|
326 |
{
|
327 |
$mbpro_src = $src;
|
328 |
continue; // exclude us
|
329 |
}
|
330 |
+
|
331 |
if ( false !== strpos( $script, 'fontawesome' ) || false !== strpos( $script, 'font-awesome' ) ) {
|
332 |
wp_dequeue_style( $script );
|
333 |
}
|
334 |
if ($src && ( false !== strpos($src, 'font-awesome') || false !== strpos($src, 'fontawesome') ) )
|
335 |
{
|
336 |
+
wp_dequeue_style( $script );
|
337 |
}
|
338 |
|
339 |
}
|
340 |
+
|
341 |
+
// This is a fix specific for NGGallery since they load their scripts weirdly / wrongly, but do check for the presence of a style named 'fontawesome' .
|
342 |
wp_register_style('fontawesome', $src);
|
343 |
|
344 |
}
|
345 |
+
|
346 |
|
347 |
static function timeInit()
|
348 |
{
|
349 |
if ( ! defined('MAXBUTTONS_BENCHMARK') || MAXBUTTONS_BENCHMARK !== true)
|
350 |
return;
|
351 |
+
|
352 |
self::$timer = microtime(true);
|
353 |
|
354 |
+
if (is_admin())
|
355 |
+
add_filter("admin_footer",array(self::namespaceit('maxUtils'), "showTime"), 100);
|
356 |
else
|
357 |
+
add_action("wp_footer",array(self::namespaceit('maxUtils'), "showTime"));
|
358 |
+
|
359 |
}
|
360 |
|
361 |
static function addTime($msg)
|
363 |
if ( ! defined('MAXBUTTONS_BENCHMARK') || MAXBUTTONS_BENCHMARK !== true)
|
364 |
return;
|
365 |
|
366 |
+
|
367 |
+
self::$timings[] = array("msg" => $msg,"time" => microtime(true));
|
368 |
}
|
369 |
+
|
370 |
static function startTime($operation)
|
371 |
{
|
372 |
if ( ! defined('MAXBUTTONS_BENCHMARK') || MAXBUTTONS_BENCHMARK !== true)
|
373 |
return;
|
374 |
+
|
375 |
+
self::$time_operations[$operation][] = array("start" => microtime(true),
|
376 |
+
"end" => 0,
|
377 |
+
);
|
378 |
+
|
379 |
}
|
380 |
+
|
381 |
+
static function endTime($operation)
|
382 |
{
|
383 |
if ( ! defined('MAXBUTTONS_BENCHMARK') || MAXBUTTONS_BENCHMARK !== true)
|
384 |
return;
|
385 |
+
|
386 |
+
$timedcount = count(self::$time_operations[$operation]);
|
387 |
+
for ($i = 0; $i < $timedcount; $i++)
|
388 |
{
|
389 |
if (self::$time_operations[$operation][$i]["end"] == 0)
|
390 |
{
|
392 |
break;
|
393 |
}
|
394 |
}
|
395 |
+
|
396 |
}
|
397 |
+
|
398 |
static function showTime()
|
399 |
{
|
400 |
if ( ! defined('MAXBUTTONS_BENCHMARK') || MAXBUTTONS_BENCHMARK !== true)
|
401 |
return;
|
402 |
+
|
403 |
$timer = self::$timer;
|
404 |
+
$text = '';
|
405 |
+
$text .= "<div id='mb-timer'>";
|
406 |
+
$text .= "<p><strong>Timed Operations</strong></p>";
|
407 |
+
|
408 |
+
foreach(self::$time_operations as $operation => $operations)
|
409 |
{
|
410 |
foreach($operations as $index => $data)
|
411 |
{
|
412 |
+
$start = $data["start"];
|
413 |
+
$end = $data["end"];
|
414 |
+
$duration = $end - $start;
|
415 |
+
|
416 |
+
|
417 |
$text .= "<span class='first'>$duration</span>
|
418 |
+
<span class='second'>$operation</span>
|
419 |
+
<span class='third'> </span><br />
|
420 |
+
";
|
421 |
+
|
422 |
+
|
423 |
}
|
424 |
}
|
425 |
+
|
426 |
+
|
427 |
+
$text .= "<p><strong>" . __("MaxButtons Loading Time:","maxbuttons") . "</strong></p>";
|
428 |
$prev_time =0;
|
429 |
+
|
430 |
+
$time_array = array();
|
431 |
+
|
432 |
foreach(self::$timings as $timing)
|
433 |
{
|
434 |
+
$cum = ($timing["time"] - $prev_time);
|
435 |
+
$text .= "<span class='first'>" . ($timing["time"] - $timer) . "</span><span class='second'> " . $timing["msg"] . "</span><span class='third'>$cum</span> <br /> ";
|
436 |
+
//$time_array[$cum] = $timing["msg"];
|
437 |
$prev_time = $timing["time"];
|
438 |
}
|
439 |
|
440 |
/*ksort($time_array);
|
441 |
+
|
442 |
+
$text .= "<br><br><strong>By time taken:</strong><br>";
|
443 |
foreach($time_array as $timeline)
|
444 |
{
|
445 |
+
$text .= "$timeline <br />";
|
446 |
}
|
447 |
*/
|
448 |
$text .= "</div> ";
|
449 |
+
$text .= "<style>#mb-timer { margin-left: 180px; }
|
450 |
+
#mb-timer span {
|
451 |
display: inline-block;
|
452 |
font-size: 12px;
|
453 |
}
|
454 |
+
#mb-timer span.first {
|
455 |
+
width: 170px;
|
456 |
+
}
|
457 |
+
#mb-timer span.second {
|
458 |
+
width: 300px;
|
459 |
}
|
460 |
+
#mb-timer span.third {
|
461 |
+
width: 150px;
|
462 |
}
|
463 |
+
</style>";
|
464 |
+
|
|
|
|
|
|
|
465 |
echo $text;
|
466 |
+
|
467 |
+
|
468 |
+
//return $filter . $text;
|
469 |
}
|
470 |
}
|
classes/maxCSSParser.php
CHANGED
@@ -2,292 +2,293 @@
|
|
2 |
namespace MaxButtons;
|
3 |
defined('ABSPATH') or die('No direct access permitted');
|
4 |
/* Class to Parse CSS. Load as array with diffent pseudo-types,
|
5 |
-
ability to add nested and new root blocks
|
6 |
parses via scss
|
7 |
ability to use complicated css stuff via scss mixins parsing like gradient
|
8 |
-
auto-discovery for -unit field types to set units (like px, or %)
|
9 |
auto-discovery of fields via domobj.
|
10 |
-
|
11 |
*/
|
12 |
|
13 |
use \Exception as Exception;
|
14 |
|
15 |
class maxCSSParser
|
16 |
{
|
17 |
-
protected $struct = array();
|
18 |
protected $domObj = '';
|
19 |
-
protected $pseudo = array("hover","active","responsive");
|
20 |
-
|
21 |
-
protected $data;
|
22 |
protected $output_css;
|
23 |
-
|
24 |
protected $inline = array();
|
25 |
protected $responsive = array();
|
26 |
-
|
27 |
-
public $anchor_class = '.maxbutton'; // used for matching buttons in parse_part
|
28 |
-
|
29 |
// settings
|
30 |
protected $elements_ignore_zero = array(
|
31 |
'text-shadow-left',
|
32 |
-
'text_shadow-top',
|
33 |
'text-shadow-width',
|
34 |
'box-shadow-offset-left',
|
35 |
-
'box-shadow-offset-top',
|
36 |
'box-shadow-width',
|
37 |
-
'box-shadow-spread',
|
38 |
-
); // items to ignore if value is zero, otherwise they become unremovable ( where 0 is still something on display)
|
39 |
-
|
40 |
protected $important = false;
|
41 |
-
|
42 |
// log possible problems and incidents for debugging;
|
43 |
protected $parse_log = array();
|
44 |
-
|
45 |
function __construct()
|
46 |
{
|
47 |
-
//$root[] = array("a" => array("hover","active","responsive"));
|
48 |
|
49 |
}
|
50 |
-
|
51 |
function loadDom($domObj)
|
52 |
-
{
|
53 |
$this->domObj = $domObj;
|
54 |
|
55 |
$root = $domObj->find(0,0);
|
56 |
-
$struct[$root->tag] = array();
|
57 |
-
|
58 |
$children = $root->children();
|
59 |
-
|
60 |
-
if (count($children) > 0)
|
61 |
$struct[$root->tag] = $this->loadRecursive(array(), $children);
|
62 |
-
|
63 |
|
64 |
$this->struct = $struct;
|
65 |
|
66 |
|
67 |
}
|
68 |
-
|
69 |
function loadRecursive($struct, $children)
|
70 |
{
|
71 |
foreach($children as $domChild)
|
72 |
{
|
73 |
|
74 |
-
$class = $domChild->class;
|
75 |
-
$class = str_replace(" ",".", $class); // combine seperate classes
|
76 |
-
|
77 |
-
$struct[$class]["tag"] = $domChild->tag;
|
78 |
-
|
79 |
-
$child_children = $domChild->children();
|
80 |
|
81 |
-
|
|
|
|
|
82 |
{
|
83 |
-
|
84 |
$struct[$class]["children"] = $this->loadRecursive(array(), $child_children);
|
85 |
}
|
86 |
}
|
87 |
-
|
88 |
return $struct;
|
89 |
}
|
90 |
-
|
91 |
-
|
92 |
function parse($data)
|
93 |
-
{
|
94 |
-
$this->clear();
|
95 |
-
|
96 |
-
$struct = $this->struct;
|
|
|
|
|
97 |
|
98 |
-
$this->data = $data;
|
99 |
|
100 |
-
|
101 |
if (isset($data["settings"])) // room for settings in parser
|
102 |
{
|
103 |
$settings = $data["settings"];
|
104 |
-
$this->important = (isset($settings["important"])) ? $settings["important"] : false;
|
105 |
-
|
106 |
-
unset($this->data["settings"]);
|
107 |
}
|
108 |
|
109 |
-
$elements = array_shift($struct); // first element is a 'stub' root.
|
110 |
|
111 |
if ( is_null($elements) )
|
112 |
-
return;
|
113 |
|
114 |
|
115 |
foreach($elements as $el => $el_data)
|
116 |
{
|
117 |
|
118 |
-
$this->parse_part($el,$el_data);
|
119 |
}
|
120 |
|
121 |
|
122 |
$this->parse_responsive();
|
123 |
-
|
124 |
maxUtils::startTime('compile CSS');
|
125 |
$css = $this->compile($this->output_css);
|
|
|
126 |
maxUtils::endTime('compile CSS');
|
127 |
|
128 |
|
129 |
return $css;
|
130 |
-
|
131 |
}
|
132 |
-
|
133 |
-
// reset output values.
|
134 |
-
protected function clear()
|
135 |
{
|
136 |
-
$this->data = '';
|
137 |
-
$this->output_css = '';
|
138 |
$this->inline = array();
|
139 |
//$this->struct = array();
|
140 |
$this->responsive = array();
|
141 |
-
|
142 |
}
|
143 |
-
|
144 |
protected function compile($css)
|
145 |
{
|
146 |
$scss = new \Leafo\ScssPhp\Compiler();
|
147 |
$scss->setImportPaths(MB()->get_plugin_path() . "assets/scss");
|
148 |
-
|
149 |
-
$minify = get_option("maxbuttons_minify", 1);
|
150 |
if ($minify == 1)
|
151 |
$scss->setFormatter('\Leafo\ScssPhp\Formatter\Compressed');
|
152 |
-
|
153 |
$compile = " @import '_mixins.scss'; " . $css;
|
154 |
//maxUtils::addTime("CSSParser: Compile start ");
|
155 |
-
|
156 |
try
|
157 |
{
|
158 |
$css = $scss->compile($compile);
|
159 |
-
} catch (Exception $e) {
|
160 |
-
|
161 |
-
$css = $this->output_css;
|
162 |
-
}
|
163 |
|
164 |
//maxUtils::addTime("CSSParser: Compile end ");
|
165 |
|
166 |
return $css;
|
167 |
}
|
168 |
-
|
169 |
function parse_part($element, $el_data, $el_add = '')
|
170 |
{
|
171 |
maxUtils::addTime("CSSParser: Parse $element ");
|
172 |
-
|
173 |
-
|
174 |
-
$tag = $el_data["tag"];
|
175 |
$element_data = $this->findData($this->data, $element);
|
176 |
-
|
177 |
-
// not using scss selectors here since there is trouble w/ the :pseudo selector, which should be put on the maxbutton / a tag.
|
178 |
if ($element != '')
|
179 |
{ $el_add .= " ." . $element;
|
180 |
-
|
181 |
}
|
182 |
-
|
183 |
-
if (isset($element_data["responsive"]))
|
184 |
{
|
185 |
$responsive = $element_data["responsive"]; // doing that at the end
|
186 |
-
unset($element_data["responsive"]);
|
187 |
|
188 |
$this->responsive[$el_add] = $responsive;
|
189 |
}
|
190 |
-
|
191 |
foreach($element_data as $pseudo => $values)
|
192 |
{
|
193 |
-
|
194 |
-
if ($pseudo != 'normal')
|
195 |
{
|
196 |
-
// select the maxbutton case, ending with either space or next class -dot.
|
197 |
// Anchor class in default situation should be .maxbutton
|
198 |
-
$anchor_class = $this->anchor_class;
|
199 |
-
|
200 |
-
$count = 0;
|
201 |
-
|
202 |
/* If PS Selector replacement doesn't match anchor class selector this probably means the parse is done in a higher level
|
203 |
-
e.g. container level, so no proper will be set. In case 0 count replacement, just put it on current */
|
204 |
$ps_selector = preg_replace('/' . $anchor_class . '$|' . $anchor_class . '([.| ])/i',"$anchor_class:$pseudo\$1",$el_add, -1, $count);
|
205 |
|
|
|
206 |
if ($count === 0)
|
207 |
{
|
208 |
-
$ps_selector = $el_add . ":" . $pseudo;
|
209 |
}
|
210 |
-
|
211 |
-
|
212 |
-
$this->output_css .= " $ps_selector { ";
|
213 |
}
|
214 |
else {
|
215 |
$this->output_css .= " $el_add { ";
|
216 |
}
|
217 |
-
|
218 |
$values = $this->doMixins($values);
|
219 |
|
220 |
foreach($values as $cssTag => $cssVal)
|
221 |
{
|
222 |
-
|
223 |
$statement = $this->parse_cssline($values, $cssTag,$cssVal); ///"$cssTag $css_sep $cssVal$unit$css_end ";
|
224 |
|
225 |
if ($statement)
|
226 |
{
|
227 |
$this->output_css .= $statement ;
|
228 |
-
|
229 |
if (! isset($this->inline[$pseudo][$element])) $this->inline[$pseudo][$element] = '';
|
230 |
$this->inline[$pseudo][$element] .= $statement;
|
231 |
-
}
|
232 |
}
|
233 |
|
234 |
-
$this->output_css .= " } ";
|
235 |
}
|
236 |
-
if (isset($el_data["children"]))
|
237 |
{
|
238 |
foreach($el_data["children"] as $child_id => $child_data)
|
239 |
{
|
240 |
-
|
241 |
$this->parse_part($child_id, $child_data, $el_add);
|
242 |
}
|
243 |
}
|
244 |
|
245 |
}
|
246 |
-
|
247 |
function parse_cssline($values, $cssTag, $cssVal, $css_end = ';')
|
248 |
{
|
249 |
|
250 |
// unit check - two ways; either unitable items is first or unit declaration.
|
251 |
-
if (isset($values[$cssTag . "_unit"]))
|
252 |
{
|
253 |
-
$unit = $values[$cssTag . "_unit"];
|
254 |
}
|
255 |
elseif(strpos($cssTag, "_unit") !== false)
|
256 |
{
|
257 |
-
return false; // no print, should be found under first def.
|
258 |
}
|
259 |
else $unit = '';
|
260 |
-
|
261 |
|
262 |
-
|
263 |
-
$important = ($
|
264 |
-
|
|
|
265 |
$css_sep = ($cssTag == '@include') ? $css_sep = '' : ':';
|
266 |
-
|
267 |
if ($cssVal == 0 && in_array($cssTag, $this->elements_ignore_zero))
|
268 |
-
return false;
|
269 |
-
|
270 |
if($cssVal !== '' && $cssTag !== '')
|
271 |
{
|
272 |
$statement = "$cssTag $css_sep $cssVal$unit$important$css_end ";
|
273 |
return $statement;
|
274 |
}
|
275 |
return false;
|
276 |
-
|
277 |
}
|
278 |
-
|
279 |
function parse_responsive()
|
280 |
{
|
281 |
|
282 |
-
$responsive = $this->responsive;
|
283 |
-
if (! is_array($responsive) || count($responsive) == 0)
|
284 |
-
return;
|
285 |
|
286 |
$media_queries = maxUtils::get_media_query(2); // query names
|
287 |
-
|
288 |
-
$output = '';
|
289 |
-
|
290 |
-
$query_array = array();
|
291 |
|
292 |
|
293 |
foreach($responsive as $element => $queries)
|
@@ -295,95 +296,95 @@ class maxCSSParser
|
|
295 |
foreach($queries as $query => $qdata)
|
296 |
foreach($qdata as $index => $data)
|
297 |
{{
|
298 |
-
$query_array[$query][$index][$element] = $data;
|
299 |
-
|
300 |
}}
|
301 |
}
|
302 |
-
|
303 |
|
304 |
-
|
|
|
305 |
foreach($query_array as $query => $vdata):
|
306 |
|
307 |
-
if ($query == 'custom')
|
308 |
{
|
309 |
|
310 |
-
// first discover the custom size properties.
|
311 |
foreach($vdata as $index => $data):
|
312 |
foreach($data as $element => $values):
|
313 |
|
314 |
-
if (isset($values["custom_maxwidth"]) || isset($values["custom_minwidth"]) )
|
315 |
{
|
316 |
-
|
317 |
$minwidth = (isset($values["custom_minwidth"])) ? intval($values["custom_minwidth"]) : -1;
|
318 |
-
$maxwidth = (isset($values["custom_maxwidth"])) ? intval($values["custom_maxwidth"]) : -1;
|
319 |
-
|
320 |
-
|
321 |
-
unset($vdata[$index][$element]["custom_minwidth"]);
|
322 |
unset($vdata[$index][$element]["custom_maxwidth"]);
|
323 |
-
|
324 |
-
|
325 |
-
// make it always an integer
|
326 |
-
if ($minwidth == '') $minwidth = 0;
|
327 |
-
if ($maxwidth == '') $maxwidth = 0;
|
328 |
-
|
329 |
-
// if minwidth is not set and maxwidth zero or not set - ignore since it would result in an empty media line.
|
330 |
-
//if ($minwidth <= 0 && $maxwidth <= 0)
|
331 |
//{
|
332 |
//continue;
|
333 |
//}
|
334 |
-
|
335 |
-
if ($minwidth > 0 && $maxwidth > 0)
|
336 |
-
$qdef = "only screen and (min-width: $minwidth" . "px) and (max-width: $maxwidth" . "px)";
|
337 |
-
if ($minwidth >= 0 && $maxwidth <= 0)
|
338 |
-
$qdef = "only screen and (min-width: $minwidth" . "px) ";
|
339 |
-
if ($minwidth <= 0 && $maxwidth > 0)
|
340 |
-
$qdef = "only screen and (max-width: $maxwidth" . "px) ";
|
341 |
-
|
342 |
//break;
|
343 |
|
344 |
-
}
|
345 |
-
endforeach; //foreach data
|
346 |
-
|
347 |
-
// The problem is that every 'custom' query needs to run with a different qdef unlike other queries.
|
348 |
-
|
349 |
$qdata = array($vdata[$index]);
|
350 |
-
|
351 |
-
$output = $this->parse_responsive_definition($output, $qdef, $qdata);
|
352 |
-
endforeach; // foreach vdata
|
353 |
}
|
354 |
else
|
355 |
{
|
356 |
-
|
357 |
-
$qdef = $media_queries[$query];
|
358 |
$output = $this->parse_responsive_definition($output, $qdef, $vdata);
|
359 |
}
|
360 |
|
361 |
endforeach;
|
362 |
-
|
363 |
-
|
364 |
$this->output_css .= $output;
|
365 |
}
|
366 |
-
|
367 |
protected function parse_responsive_definition($output, $qdef, $vdata)
|
368 |
{
|
369 |
-
|
370 |
if (! isset($qdef) || $qdef == '') {
|
371 |
-
|
372 |
-
return; // no definition.
|
373 |
}
|
374 |
|
375 |
-
|
376 |
-
$output .= "@media ". $qdef . " { ";
|
377 |
|
378 |
-
|
|
|
|
|
379 |
foreach($vdata as $index => $data)
|
380 |
{
|
381 |
-
|
382 |
foreach($data as $element => $values) {
|
383 |
//foreach($vdat as $index => $values):
|
384 |
-
$output .= $element . " { ";
|
385 |
$css_end = ';';
|
386 |
-
|
387 |
// same as parse part, maybe merge in future
|
388 |
foreach($values as $cssTag => $cssVal)
|
389 |
{
|
@@ -391,213 +392,215 @@ class maxCSSParser
|
|
391 |
$statement = $this->parse_cssline($values, $cssTag,$cssVal);
|
392 |
if($statement)
|
393 |
$output .= $statement;
|
394 |
-
|
395 |
}
|
396 |
|
397 |
-
$output .= " } ";
|
398 |
// endforeach;
|
399 |
}
|
400 |
|
401 |
-
|
402 |
}
|
403 |
-
$output .= " } ";
|
404 |
-
|
405 |
-
//endforeach;
|
406 |
-
|
407 |
return $output;
|
408 |
}
|
409 |
-
|
410 |
private function is_important()
|
411 |
{
|
412 |
|
413 |
if ($this->important == 1)
|
414 |
return true;
|
415 |
-
else
|
416 |
return false;
|
417 |
}
|
418 |
-
|
419 |
function findData($data, $el)
|
420 |
{
|
421 |
-
$classes = explode(".", $el);
|
422 |
|
423 |
-
foreach($data as $part => $values)
|
424 |
{
|
425 |
if (in_array($part, $classes))
|
|
|
426 |
return $data[$part];
|
|
|
427 |
}
|
428 |
return array();
|
429 |
}
|
430 |
-
|
431 |
function doMixins($values)
|
432 |
{
|
433 |
$mixins = array("gradient", "box-shadow", "text-shadow");
|
434 |
-
|
435 |
-
foreach($mixins as $mixin)
|
436 |
{
|
437 |
|
438 |
$results = preg_grep("/^$mixin/i",array_keys($values) );
|
439 |
-
if (count($results) === 0)
|
440 |
-
continue; // no mixins.
|
441 |
-
|
442 |
$mixin_array = array();
|
443 |
foreach($results as $result)
|
444 |
{
|
445 |
-
$mixin_array[$result] = $values[$result];
|
446 |
}
|
447 |
|
448 |
if (count($mixin_array) > 0)
|
449 |
{
|
450 |
switch($mixin)
|
451 |
{
|
452 |
-
case "gradient":
|
453 |
$values = $this->mixin_gradient($mixin_array, $values);
|
454 |
-
|
455 |
break;
|
456 |
-
case "box-shadow":
|
457 |
$values = $this->mixin_boxshadow($mixin_array, $values);
|
458 |
-
break;
|
459 |
-
case "text-shadow":
|
460 |
$values = $this->mixin_textshadow($mixin_array, $values);
|
461 |
break;
|
462 |
}
|
463 |
}
|
464 |
|
465 |
-
|
466 |
-
}
|
467 |
return $values;
|
468 |
}
|
469 |
-
|
470 |
function mixin_gradient($results, $values)
|
471 |
{
|
472 |
|
473 |
$start = isset($results["gradient-start-color"]) ? $results["gradient-start-color"] : '';
|
474 |
-
$end = isset( $results["gradient-end-color"] ) ? $results["gradient-end-color"] : '';
|
475 |
-
$start_opacity = isset( $results["gradient-start-opacity"] ) ? $results["gradient-start-opacity"] : '';
|
476 |
-
$end_opacity = isset( $results["gradient-end-opacity"] ) ? $results["gradient-end-opacity"] : '';
|
477 |
-
$stop = (isset( $results["gradient-stop"]) && $results["gradient-stop"] != '') ? $results["gradient-stop"] . "%" : '45%';
|
478 |
// default to use ( old situation )
|
479 |
$use_gradient = (isset($results['gradient-use-gradient']) && $results['gradient-use-gradient'] != '') ? $results['gradient-use-gradient'] : 1;
|
480 |
-
|
481 |
$start = maxUtils::hex2rgba($start, $start_opacity);
|
482 |
-
$end = maxUtils::hex2rgba($end, $end_opacity);
|
483 |
-
|
484 |
$important = ($this->is_important()) ? "!important" : "";
|
485 |
-
//$values = $this->add_include($values, "linear-gradient($start,$end,$stop,$important)");
|
486 |
|
487 |
if ($use_gradient == 1)
|
488 |
{
|
489 |
-
$values = $this->add_include($values, "linear-gradient($start,$end,$stop,$important)");
|
490 |
}
|
491 |
else {
|
492 |
-
$values['background-color'] = $start;
|
493 |
}
|
494 |
|
495 |
-
// remove the non-css keys from the value array ( field names )
|
496 |
$values = array_diff_key($values, $results);
|
497 |
|
498 |
return $values;
|
499 |
-
|
500 |
}
|
501 |
-
|
502 |
function mixin_boxshadow($results, $values)
|
503 |
{
|
504 |
-
$width = $results["box-shadow-width"];
|
505 |
-
$left = $results["box-shadow-offset-left"];
|
506 |
-
$top = $results["box-shadow-offset-top"];
|
507 |
-
$spread = isset($results['box-shadow-spread']) ? $results['box-shadow-spread'] : 0;
|
508 |
-
$color = isset($results["box-shadow-color"]) ? $results["box-shadow-color"] : '';
|
509 |
-
|
510 |
-
$important = ($this->is_important()) ? "!important" : "";
|
511 |
-
|
512 |
-
if ($width == 0 && $left == 0 && $top == 0)
|
513 |
-
return $values;
|
514 |
-
|
515 |
-
$values = $this->add_include($values, "box-shadow($left, $top, $width, $color,$spread, false, $important) ");
|
516 |
$values = array_diff_key($values, $results);
|
517 |
|
518 |
-
return $values;
|
519 |
}
|
520 |
-
|
521 |
function mixin_textshadow($results, $values)
|
522 |
{
|
523 |
-
$width = isset($results["text-shadow-width"]) ? $results["text-shadow-width"] : 0;
|
524 |
-
$left = isset($results["text-shadow-left"]) ? $results["text-shadow-left"] : 0;
|
525 |
-
$top = isset($results["text-shadow-top"]) ? $results["text-shadow-top"] : 0;
|
526 |
-
$color = isset($results["text-shadow-color"]) ? $results["text-shadow-color"] : '';
|
527 |
-
$important = ($this->is_important()) ? "!important" : "";
|
528 |
-
|
529 |
-
if ($width == 0 && $left == 0 && $top == 0)
|
530 |
{
|
531 |
$values = array_diff_key($values, $results); // remove them from the values, prevent incorrect output.
|
532 |
-
return $values;
|
533 |
}
|
534 |
-
|
535 |
-
$values = $this->add_include($values, "text-shadow ($left,$top,$width,$color $important)");
|
536 |
-
|
537 |
$values = array_diff_key($values, $results);
|
538 |
-
|
539 |
return $values;
|
540 |
}
|
541 |
-
|
542 |
private function add_include($values, $include)
|
543 |
{
|
544 |
-
if (isset($values["@include"]))
|
545 |
-
$values["@include"] .= "; @include " . $include;
|
546 |
else
|
547 |
-
$values["@include"] = $include;
|
548 |
-
return $values;
|
549 |
}
|
550 |
-
|
551 |
function outputInline($domObj, $pseudo = 'normal')
|
552 |
{
|
553 |
$domObj = $domObj->load($domObj->save());
|
554 |
-
|
555 |
$inline = $this->inline;
|
556 |
-
|
557 |
-
// ISSUE #43 Sometimes this breaks
|
558 |
-
if (! isset($inline[$pseudo]))
|
559 |
return $domObj;
|
560 |
|
561 |
$elements = array_keys($inline[$pseudo]);
|
562 |
if ($pseudo != 'normal') // gather all elements
|
563 |
$elements = array_merge($elements, array_keys($inline["normal"]));
|
564 |
-
|
565 |
foreach($elements as $element )
|
566 |
{
|
567 |
-
$styles = isset($inline[$pseudo][$element]) ? $inline[$pseudo][$element] : '';
|
568 |
-
|
569 |
if ($pseudo != 'normal') // parse all possible missing styles from pseudo el.
|
570 |
-
$normstyle = $this->compile($inline['normal'][$element]);
|
571 |
-
|
572 |
-
$normstyle = '';
|
573 |
if ($pseudo != 'normal') // parse all possible missing styles from pseudo el.
|
574 |
-
$normstyle = $this->compile($inline['normal'][$element]);
|
575 |
-
|
576 |
maxUtils::addTime("CSSParser: Parse inline done");
|
577 |
-
|
578 |
$styles = $normstyle . $this->compile($styles);
|
579 |
-
|
580 |
-
$element = trim(str_replace("."," ", $element)); // molten css class, seperator.
|
581 |
-
|
582 |
$el = $domObj->find('[class*="' . $element . '"]', 0);
|
583 |
-
|
584 |
$el->style = $styles;
|
585 |
-
|
586 |
}
|
587 |
-
|
588 |
return $domObj;
|
589 |
-
|
590 |
-
}
|
591 |
-
|
592 |
-
function output()
|
593 |
{
|
594 |
-
|
595 |
-
|
596 |
}
|
597 |
-
|
598 |
}
|
599 |
|
600 |
-
class compileException extends Exception {
|
601 |
protected $code = -1;
|
602 |
|
603 |
}
|
2 |
namespace MaxButtons;
|
3 |
defined('ABSPATH') or die('No direct access permitted');
|
4 |
/* Class to Parse CSS. Load as array with diffent pseudo-types,
|
5 |
+
ability to add nested and new root blocks
|
6 |
parses via scss
|
7 |
ability to use complicated css stuff via scss mixins parsing like gradient
|
8 |
+
auto-discovery for -unit field types to set units (like px, or %)
|
9 |
auto-discovery of fields via domobj.
|
10 |
+
|
11 |
*/
|
12 |
|
13 |
use \Exception as Exception;
|
14 |
|
15 |
class maxCSSParser
|
16 |
{
|
17 |
+
protected $struct = array();
|
18 |
protected $domObj = '';
|
19 |
+
protected $pseudo = array("hover","active","responsive");
|
20 |
+
|
21 |
+
protected $data;
|
22 |
protected $output_css;
|
23 |
+
|
24 |
protected $inline = array();
|
25 |
protected $responsive = array();
|
26 |
+
|
27 |
+
public $anchor_class = '.maxbutton'; // used for matching buttons in parse_part
|
28 |
+
|
29 |
// settings
|
30 |
protected $elements_ignore_zero = array(
|
31 |
'text-shadow-left',
|
32 |
+
'text_shadow-top',
|
33 |
'text-shadow-width',
|
34 |
'box-shadow-offset-left',
|
35 |
+
'box-shadow-offset-top',
|
36 |
'box-shadow-width',
|
37 |
+
'box-shadow-spread',
|
38 |
+
); // items to ignore if value is zero, otherwise they become unremovable ( where 0 is still something on display)
|
39 |
+
|
40 |
protected $important = false;
|
41 |
+
|
42 |
// log possible problems and incidents for debugging;
|
43 |
protected $parse_log = array();
|
44 |
+
|
45 |
function __construct()
|
46 |
{
|
47 |
+
//$root[] = array("a" => array("hover","active","responsive"));
|
48 |
|
49 |
}
|
50 |
+
|
51 |
function loadDom($domObj)
|
52 |
+
{
|
53 |
$this->domObj = $domObj;
|
54 |
|
55 |
$root = $domObj->find(0,0);
|
56 |
+
$struct[$root->tag] = array();
|
57 |
+
|
58 |
$children = $root->children();
|
59 |
+
|
60 |
+
if (count($children) > 0)
|
61 |
$struct[$root->tag] = $this->loadRecursive(array(), $children);
|
62 |
+
|
63 |
|
64 |
$this->struct = $struct;
|
65 |
|
66 |
|
67 |
}
|
68 |
+
|
69 |
function loadRecursive($struct, $children)
|
70 |
{
|
71 |
foreach($children as $domChild)
|
72 |
{
|
73 |
|
74 |
+
$class = $domChild->class;
|
75 |
+
$class = str_replace(" ",".", $class); // combine seperate classes
|
76 |
+
$struct[$class]["tag"] = $domChild->tag;
|
|
|
|
|
|
|
77 |
|
78 |
+
$child_children = $domChild->children();
|
79 |
+
|
80 |
+
if (count($child_children) > 0)
|
81 |
{
|
82 |
+
|
83 |
$struct[$class]["children"] = $this->loadRecursive(array(), $child_children);
|
84 |
}
|
85 |
}
|
86 |
+
|
87 |
return $struct;
|
88 |
}
|
89 |
+
|
90 |
+
|
91 |
function parse($data)
|
92 |
+
{
|
93 |
+
$this->clear();
|
94 |
+
|
95 |
+
$struct = $this->struct;
|
96 |
+
|
97 |
+
$this->data = $data;
|
98 |
|
|
|
99 |
|
|
|
100 |
if (isset($data["settings"])) // room for settings in parser
|
101 |
{
|
102 |
$settings = $data["settings"];
|
103 |
+
$this->important = (isset($settings["important"])) ? $settings["important"] : false;
|
104 |
+
|
105 |
+
unset($this->data["settings"]);
|
106 |
}
|
107 |
|
108 |
+
$elements = array_shift($struct); // first element is a 'stub' root.
|
109 |
|
110 |
if ( is_null($elements) )
|
111 |
+
return;
|
112 |
|
113 |
|
114 |
foreach($elements as $el => $el_data)
|
115 |
{
|
116 |
|
117 |
+
$this->parse_part($el,$el_data);
|
118 |
}
|
119 |
|
120 |
|
121 |
$this->parse_responsive();
|
122 |
+
|
123 |
maxUtils::startTime('compile CSS');
|
124 |
$css = $this->compile($this->output_css);
|
125 |
+
|
126 |
maxUtils::endTime('compile CSS');
|
127 |
|
128 |
|
129 |
return $css;
|
130 |
+
|
131 |
}
|
132 |
+
|
133 |
+
// reset output values.
|
134 |
+
protected function clear()
|
135 |
{
|
136 |
+
$this->data = '';
|
137 |
+
$this->output_css = '';
|
138 |
$this->inline = array();
|
139 |
//$this->struct = array();
|
140 |
$this->responsive = array();
|
141 |
+
|
142 |
}
|
143 |
+
|
144 |
protected function compile($css)
|
145 |
{
|
146 |
$scss = new \Leafo\ScssPhp\Compiler();
|
147 |
$scss->setImportPaths(MB()->get_plugin_path() . "assets/scss");
|
148 |
+
|
149 |
+
$minify = get_option("maxbuttons_minify", 1);
|
150 |
if ($minify == 1)
|
151 |
$scss->setFormatter('\Leafo\ScssPhp\Formatter\Compressed');
|
152 |
+
|
153 |
$compile = " @import '_mixins.scss'; " . $css;
|
154 |
//maxUtils::addTime("CSSParser: Compile start ");
|
155 |
+
|
156 |
try
|
157 |
{
|
158 |
$css = $scss->compile($compile);
|
159 |
+
} catch (Exception $e) {
|
160 |
+
|
161 |
+
$css = $this->output_css;
|
162 |
+
}
|
163 |
|
164 |
//maxUtils::addTime("CSSParser: Compile end ");
|
165 |
|
166 |
return $css;
|
167 |
}
|
168 |
+
|
169 |
function parse_part($element, $el_data, $el_add = '')
|
170 |
{
|
171 |
maxUtils::addTime("CSSParser: Parse $element ");
|
172 |
+
|
173 |
+
|
174 |
+
$tag = $el_data["tag"];
|
175 |
$element_data = $this->findData($this->data, $element);
|
176 |
+
|
177 |
+
// not using scss selectors here since there is trouble w/ the :pseudo selector, which should be put on the maxbutton / a tag.
|
178 |
if ($element != '')
|
179 |
{ $el_add .= " ." . $element;
|
180 |
+
|
181 |
}
|
182 |
+
|
183 |
+
if (isset($element_data["responsive"]))
|
184 |
{
|
185 |
$responsive = $element_data["responsive"]; // doing that at the end
|
186 |
+
unset($element_data["responsive"]);
|
187 |
|
188 |
$this->responsive[$el_add] = $responsive;
|
189 |
}
|
190 |
+
|
191 |
foreach($element_data as $pseudo => $values)
|
192 |
{
|
193 |
+
|
194 |
+
if ($pseudo != 'normal')
|
195 |
{
|
196 |
+
// select the maxbutton case, ending with either space or next class -dot.
|
197 |
// Anchor class in default situation should be .maxbutton
|
198 |
+
$anchor_class = $this->anchor_class;
|
199 |
+
|
200 |
+
$count = 0;
|
201 |
+
|
202 |
/* If PS Selector replacement doesn't match anchor class selector this probably means the parse is done in a higher level
|
203 |
+
e.g. container level, so no proper will be set. In case 0 count replacement, just put it on current */
|
204 |
$ps_selector = preg_replace('/' . $anchor_class . '$|' . $anchor_class . '([.| ])/i',"$anchor_class:$pseudo\$1",$el_add, -1, $count);
|
205 |
|
206 |
+
|
207 |
if ($count === 0)
|
208 |
{
|
209 |
+
$ps_selector = $el_add . ":" . $pseudo;
|
210 |
}
|
211 |
+
|
212 |
+
|
213 |
+
$this->output_css .= " $ps_selector { ";
|
214 |
}
|
215 |
else {
|
216 |
$this->output_css .= " $el_add { ";
|
217 |
}
|
218 |
+
|
219 |
$values = $this->doMixins($values);
|
220 |
|
221 |
foreach($values as $cssTag => $cssVal)
|
222 |
{
|
223 |
+
|
224 |
$statement = $this->parse_cssline($values, $cssTag,$cssVal); ///"$cssTag $css_sep $cssVal$unit$css_end ";
|
225 |
|
226 |
if ($statement)
|
227 |
{
|
228 |
$this->output_css .= $statement ;
|
229 |
+
|
230 |
if (! isset($this->inline[$pseudo][$element])) $this->inline[$pseudo][$element] = '';
|
231 |
$this->inline[$pseudo][$element] .= $statement;
|
232 |
+
}
|
233 |
}
|
234 |
|
235 |
+
$this->output_css .= " } ";
|
236 |
}
|
237 |
+
if (isset($el_data["children"]))
|
238 |
{
|
239 |
foreach($el_data["children"] as $child_id => $child_data)
|
240 |
{
|
241 |
+
|
242 |
$this->parse_part($child_id, $child_data, $el_add);
|
243 |
}
|
244 |
}
|
245 |
|
246 |
}
|
247 |
+
|
248 |
function parse_cssline($values, $cssTag, $cssVal, $css_end = ';')
|
249 |
{
|
250 |
|
251 |
// unit check - two ways; either unitable items is first or unit declaration.
|
252 |
+
if (isset($values[$cssTag . "_unit"]))
|
253 |
{
|
254 |
+
$unit = $values[$cssTag . "_unit"];
|
255 |
}
|
256 |
elseif(strpos($cssTag, "_unit") !== false)
|
257 |
{
|
258 |
+
return false; // no print, should be found under first def.
|
259 |
}
|
260 |
else $unit = '';
|
|
|
261 |
|
262 |
+
|
263 |
+
$important = ($this->is_important()) ? " !important" : "";
|
264 |
+
$important = ($cssTag == '@include') ? "" : $important; // mixin's problem, no checking here.
|
265 |
+
|
266 |
$css_sep = ($cssTag == '@include') ? $css_sep = '' : ':';
|
267 |
+
|
268 |
if ($cssVal == 0 && in_array($cssTag, $this->elements_ignore_zero))
|
269 |
+
return false;
|
270 |
+
|
271 |
if($cssVal !== '' && $cssTag !== '')
|
272 |
{
|
273 |
$statement = "$cssTag $css_sep $cssVal$unit$important$css_end ";
|
274 |
return $statement;
|
275 |
}
|
276 |
return false;
|
277 |
+
|
278 |
}
|
279 |
+
|
280 |
function parse_responsive()
|
281 |
{
|
282 |
|
283 |
+
$responsive = $this->responsive;
|
284 |
+
if (! is_array($responsive) || count($responsive) == 0)
|
285 |
+
return;
|
286 |
|
287 |
$media_queries = maxUtils::get_media_query(2); // query names
|
288 |
+
|
289 |
+
$output = '';
|
290 |
+
|
291 |
+
$query_array = array();
|
292 |
|
293 |
|
294 |
foreach($responsive as $element => $queries)
|
296 |
foreach($queries as $query => $qdata)
|
297 |
foreach($qdata as $index => $data)
|
298 |
{{
|
299 |
+
$query_array[$query][$index][$element] = $data;
|
300 |
+
|
301 |
}}
|
302 |
}
|
|
|
303 |
|
304 |
+
|
305 |
+
|
306 |
foreach($query_array as $query => $vdata):
|
307 |
|
308 |
+
if ($query == 'custom')
|
309 |
{
|
310 |
|
311 |
+
// first discover the custom size properties.
|
312 |
foreach($vdata as $index => $data):
|
313 |
foreach($data as $element => $values):
|
314 |
|
315 |
+
if (isset($values["custom_maxwidth"]) || isset($values["custom_minwidth"]) )
|
316 |
{
|
317 |
+
|
318 |
$minwidth = (isset($values["custom_minwidth"])) ? intval($values["custom_minwidth"]) : -1;
|
319 |
+
$maxwidth = (isset($values["custom_maxwidth"])) ? intval($values["custom_maxwidth"]) : -1;
|
320 |
+
|
321 |
+
|
322 |
+
unset($vdata[$index][$element]["custom_minwidth"]);
|
323 |
unset($vdata[$index][$element]["custom_maxwidth"]);
|
324 |
+
|
325 |
+
|
326 |
+
// make it always an integer
|
327 |
+
if ($minwidth == '') $minwidth = 0;
|
328 |
+
if ($maxwidth == '') $maxwidth = 0;
|
329 |
+
|
330 |
+
// if minwidth is not set and maxwidth zero or not set - ignore since it would result in an empty media line.
|
331 |
+
//if ($minwidth <= 0 && $maxwidth <= 0)
|
332 |
//{
|
333 |
//continue;
|
334 |
//}
|
335 |
+
|
336 |
+
if ($minwidth > 0 && $maxwidth > 0)
|
337 |
+
$qdef = "only screen and (min-width: $minwidth" . "px) and (max-width: $maxwidth" . "px)";
|
338 |
+
if ($minwidth >= 0 && $maxwidth <= 0)
|
339 |
+
$qdef = "only screen and (min-width: $minwidth" . "px) ";
|
340 |
+
if ($minwidth <= 0 && $maxwidth > 0)
|
341 |
+
$qdef = "only screen and (max-width: $maxwidth" . "px) ";
|
342 |
+
|
343 |
//break;
|
344 |
|
345 |
+
}
|
346 |
+
endforeach; //foreach data
|
347 |
+
|
348 |
+
// The problem is that every 'custom' query needs to run with a different qdef unlike other queries.
|
349 |
+
|
350 |
$qdata = array($vdata[$index]);
|
351 |
+
|
352 |
+
$output = $this->parse_responsive_definition($output, $qdef, $qdata);
|
353 |
+
endforeach; // foreach vdata
|
354 |
}
|
355 |
else
|
356 |
{
|
357 |
+
|
358 |
+
$qdef = $media_queries[$query];
|
359 |
$output = $this->parse_responsive_definition($output, $qdef, $vdata);
|
360 |
}
|
361 |
|
362 |
endforeach;
|
363 |
+
|
364 |
+
|
365 |
$this->output_css .= $output;
|
366 |
}
|
367 |
+
|
368 |
protected function parse_responsive_definition($output, $qdef, $vdata)
|
369 |
{
|
370 |
+
|
371 |
if (! isset($qdef) || $qdef == '') {
|
372 |
+
|
373 |
+
return; // no definition.
|
374 |
}
|
375 |
|
|
|
|
|
376 |
|
377 |
+
$output .= "@media ". $qdef . " { ";
|
378 |
+
|
379 |
+
|
380 |
foreach($vdata as $index => $data)
|
381 |
{
|
382 |
+
|
383 |
foreach($data as $element => $values) {
|
384 |
//foreach($vdat as $index => $values):
|
385 |
+
$output .= $element . " { ";
|
386 |
$css_end = ';';
|
387 |
+
|
388 |
// same as parse part, maybe merge in future
|
389 |
foreach($values as $cssTag => $cssVal)
|
390 |
{
|
392 |
$statement = $this->parse_cssline($values, $cssTag,$cssVal);
|
393 |
if($statement)
|
394 |
$output .= $statement;
|
395 |
+
|
396 |
}
|
397 |
|
398 |
+
$output .= " } ";
|
399 |
// endforeach;
|
400 |
}
|
401 |
|
402 |
+
|
403 |
}
|
404 |
+
$output .= " } ";
|
405 |
+
|
406 |
+
//endforeach;
|
407 |
+
|
408 |
return $output;
|
409 |
}
|
410 |
+
|
411 |
private function is_important()
|
412 |
{
|
413 |
|
414 |
if ($this->important == 1)
|
415 |
return true;
|
416 |
+
else
|
417 |
return false;
|
418 |
}
|
419 |
+
|
420 |
function findData($data, $el)
|
421 |
{
|
422 |
+
$classes = explode(".", $el);
|
423 |
|
424 |
+
foreach($data as $part => $values)
|
425 |
{
|
426 |
if (in_array($part, $classes))
|
427 |
+
{
|
428 |
return $data[$part];
|
429 |
+
}
|
430 |
}
|
431 |
return array();
|
432 |
}
|
433 |
+
|
434 |
function doMixins($values)
|
435 |
{
|
436 |
$mixins = array("gradient", "box-shadow", "text-shadow");
|
437 |
+
|
438 |
+
foreach($mixins as $mixin)
|
439 |
{
|
440 |
|
441 |
$results = preg_grep("/^$mixin/i",array_keys($values) );
|
442 |
+
if (count($results) === 0)
|
443 |
+
continue; // no mixins.
|
444 |
+
|
445 |
$mixin_array = array();
|
446 |
foreach($results as $result)
|
447 |
{
|
448 |
+
$mixin_array[$result] = $values[$result];
|
449 |
}
|
450 |
|
451 |
if (count($mixin_array) > 0)
|
452 |
{
|
453 |
switch($mixin)
|
454 |
{
|
455 |
+
case "gradient":
|
456 |
$values = $this->mixin_gradient($mixin_array, $values);
|
457 |
+
|
458 |
break;
|
459 |
+
case "box-shadow":
|
460 |
$values = $this->mixin_boxshadow($mixin_array, $values);
|
461 |
+
break;
|
462 |
+
case "text-shadow":
|
463 |
$values = $this->mixin_textshadow($mixin_array, $values);
|
464 |
break;
|
465 |
}
|
466 |
}
|
467 |
|
468 |
+
|
469 |
+
}
|
470 |
return $values;
|
471 |
}
|
472 |
+
|
473 |
function mixin_gradient($results, $values)
|
474 |
{
|
475 |
|
476 |
$start = isset($results["gradient-start-color"]) ? $results["gradient-start-color"] : '';
|
477 |
+
$end = isset( $results["gradient-end-color"] ) ? $results["gradient-end-color"] : '';
|
478 |
+
$start_opacity = isset( $results["gradient-start-opacity"] ) ? $results["gradient-start-opacity"] : '';
|
479 |
+
$end_opacity = isset( $results["gradient-end-opacity"] ) ? $results["gradient-end-opacity"] : '';
|
480 |
+
$stop = (isset( $results["gradient-stop"]) && $results["gradient-stop"] != '') ? $results["gradient-stop"] . "%" : '45%';
|
481 |
// default to use ( old situation )
|
482 |
$use_gradient = (isset($results['gradient-use-gradient']) && $results['gradient-use-gradient'] != '') ? $results['gradient-use-gradient'] : 1;
|
483 |
+
|
484 |
$start = maxUtils::hex2rgba($start, $start_opacity);
|
485 |
+
$end = maxUtils::hex2rgba($end, $end_opacity);
|
486 |
+
|
487 |
$important = ($this->is_important()) ? "!important" : "";
|
488 |
+
//$values = $this->add_include($values, "linear-gradient($start,$end,$stop,$important)");
|
489 |
|
490 |
if ($use_gradient == 1)
|
491 |
{
|
492 |
+
$values = $this->add_include($values, "linear-gradient($start,$end,$stop,$important)");
|
493 |
}
|
494 |
else {
|
495 |
+
$values['background-color'] = $start;
|
496 |
}
|
497 |
|
498 |
+
// remove the non-css keys from the value array ( field names )
|
499 |
$values = array_diff_key($values, $results);
|
500 |
|
501 |
return $values;
|
502 |
+
|
503 |
}
|
504 |
+
|
505 |
function mixin_boxshadow($results, $values)
|
506 |
{
|
507 |
+
$width = $results["box-shadow-width"];
|
508 |
+
$left = $results["box-shadow-offset-left"];
|
509 |
+
$top = $results["box-shadow-offset-top"];
|
510 |
+
$spread = isset($results['box-shadow-spread']) ? $results['box-shadow-spread'] : 0;
|
511 |
+
$color = isset($results["box-shadow-color"]) ? $results["box-shadow-color"] : '';
|
512 |
+
|
513 |
+
$important = ($this->is_important()) ? "!important" : "";
|
514 |
+
|
515 |
+
if ($width == 0 && $left == 0 && $top == 0)
|
516 |
+
return $values;
|
517 |
+
|
518 |
+
$values = $this->add_include($values, "box-shadow($left, $top, $width, $color,$spread, false, $important) ");
|
519 |
$values = array_diff_key($values, $results);
|
520 |
|
521 |
+
return $values;
|
522 |
}
|
523 |
+
|
524 |
function mixin_textshadow($results, $values)
|
525 |
{
|
526 |
+
$width = isset($results["text-shadow-width"]) ? $results["text-shadow-width"] : 0;
|
527 |
+
$left = isset($results["text-shadow-left"]) ? $results["text-shadow-left"] : 0;
|
528 |
+
$top = isset($results["text-shadow-top"]) ? $results["text-shadow-top"] : 0;
|
529 |
+
$color = isset($results["text-shadow-color"]) ? $results["text-shadow-color"] : '';
|
530 |
+
$important = ($this->is_important()) ? "!important" : "";
|
531 |
+
|
532 |
+
if ($width == 0 && $left == 0 && $top == 0)
|
533 |
{
|
534 |
$values = array_diff_key($values, $results); // remove them from the values, prevent incorrect output.
|
535 |
+
return $values;
|
536 |
}
|
537 |
+
|
538 |
+
$values = $this->add_include($values, "text-shadow ($left,$top,$width,$color $important)");
|
539 |
+
|
540 |
$values = array_diff_key($values, $results);
|
541 |
+
|
542 |
return $values;
|
543 |
}
|
544 |
+
|
545 |
private function add_include($values, $include)
|
546 |
{
|
547 |
+
if (isset($values["@include"]))
|
548 |
+
$values["@include"] .= "; @include " . $include;
|
549 |
else
|
550 |
+
$values["@include"] = $include;
|
551 |
+
return $values;
|
552 |
}
|
553 |
+
|
554 |
function outputInline($domObj, $pseudo = 'normal')
|
555 |
{
|
556 |
$domObj = $domObj->load($domObj->save());
|
557 |
+
|
558 |
$inline = $this->inline;
|
559 |
+
|
560 |
+
// ISSUE #43 Sometimes this breaks
|
561 |
+
if (! isset($inline[$pseudo]))
|
562 |
return $domObj;
|
563 |
|
564 |
$elements = array_keys($inline[$pseudo]);
|
565 |
if ($pseudo != 'normal') // gather all elements
|
566 |
$elements = array_merge($elements, array_keys($inline["normal"]));
|
567 |
+
|
568 |
foreach($elements as $element )
|
569 |
{
|
570 |
+
$styles = isset($inline[$pseudo][$element]) ? $inline[$pseudo][$element] : '';
|
571 |
+
|
572 |
if ($pseudo != 'normal') // parse all possible missing styles from pseudo el.
|
573 |
+
$normstyle = $this->compile($inline['normal'][$element]);
|
574 |
+
|
575 |
+
$normstyle = '';
|
576 |
if ($pseudo != 'normal') // parse all possible missing styles from pseudo el.
|
577 |
+
$normstyle = $this->compile($inline['normal'][$element]);
|
578 |
+
|
579 |
maxUtils::addTime("CSSParser: Parse inline done");
|
580 |
+
|
581 |
$styles = $normstyle . $this->compile($styles);
|
582 |
+
|
583 |
+
$element = trim(str_replace("."," ", $element)); // molten css class, seperator.
|
584 |
+
|
585 |
$el = $domObj->find('[class*="' . $element . '"]', 0);
|
586 |
+
|
587 |
$el->style = $styles;
|
588 |
+
|
589 |
}
|
590 |
+
|
591 |
return $domObj;
|
592 |
+
|
593 |
+
}
|
594 |
+
|
595 |
+
function output()
|
596 |
{
|
597 |
+
|
598 |
+
|
599 |
}
|
600 |
+
|
601 |
}
|
602 |
|
603 |
+
class compileException extends Exception {
|
604 |
protected $code = -1;
|
605 |
|
606 |
}
|
maxbuttons.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: MaxButtons
|
4 |
Plugin URI: http://maxbuttons.com
|
5 |
Description: The best WordPress button generator. This is the free version; the Pro version <a href="http://maxbuttons.com/?ref=mbfree">can be found here</a>.
|
6 |
-
Version: 6.
|
7 |
Author: Max Foundry
|
8 |
Author URI: http://maxfoundry.com
|
9 |
Text Domain: maxbuttons
|
@@ -16,9 +16,9 @@ namespace MaxButtons;
|
|
16 |
if (! defined('MAXBUTTONS_ROOT_FILE'))
|
17 |
define("MAXBUTTONS_ROOT_FILE", __FILE__);
|
18 |
if (! defined('MAXBUTTONS_VERSION_NUM'))
|
19 |
-
define('MAXBUTTONS_VERSION_NUM', '6.
|
20 |
|
21 |
-
define('MAXBUTTONS_RELEASE',"
|
22 |
|
23 |
|
24 |
if (! function_exists('MaxButtons\maxbutton_double_load'))
|
3 |
Plugin Name: MaxButtons
|
4 |
Plugin URI: http://maxbuttons.com
|
5 |
Description: The best WordPress button generator. This is the free version; the Pro version <a href="http://maxbuttons.com/?ref=mbfree">can be found here</a>.
|
6 |
+
Version: 6.27
|
7 |
Author: Max Foundry
|
8 |
Author URI: http://maxfoundry.com
|
9 |
Text Domain: maxbuttons
|
16 |
if (! defined('MAXBUTTONS_ROOT_FILE'))
|
17 |
define("MAXBUTTONS_ROOT_FILE", __FILE__);
|
18 |
if (! defined('MAXBUTTONS_VERSION_NUM'))
|
19 |
+
define('MAXBUTTONS_VERSION_NUM', '6.27');
|
20 |
|
21 |
+
define('MAXBUTTONS_RELEASE',"17 Jan 2018");
|
22 |
|
23 |
|
24 |
if (! function_exists('MaxButtons\maxbutton_double_load'))
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Tags: wordpress button plugin, share button, wordpress buttons, css3 button gene
|
|
4 |
Requires at least: 4.0
|
5 |
Tested up to: 4.9.1
|
6 |
Requires PHP: 5.3
|
7 |
-
Stable tag: 6.
|
8 |
|
9 |
WordPress button plugin so powerful and easy to use anyone can create beautiful buttons, share buttons and social icons.
|
10 |
|
@@ -243,11 +243,23 @@ By default WordPress can't display shortcodes in a menu. You can use this [plugi
|
|
243 |
|
244 |
This depends on the slider plugin you are using. Most of the well-known ones are allowing the use of shortcodes within the slides. To find out if your plugin can handle that, please ask the slider vendor.
|
245 |
|
|
|
|
|
|
|
|
|
|
|
|
|
246 |
== Changelog ==
|
247 |
|
|
|
|
|
|
|
|
|
|
|
|
|
248 |
= 6.26.1 =
|
249 |
|
250 |
-
* Fixed - Advanced options
|
251 |
|
252 |
= 6.26 =
|
253 |
|
4 |
Requires at least: 4.0
|
5 |
Tested up to: 4.9.1
|
6 |
Requires PHP: 5.3
|
7 |
+
Stable tag: 6.27
|
8 |
|
9 |
WordPress button plugin so powerful and easy to use anyone can create beautiful buttons, share buttons and social icons.
|
10 |
|
243 |
|
244 |
This depends on the slider plugin you are using. Most of the well-known ones are allowing the use of shortcodes within the slides. To find out if your plugin can handle that, please ask the slider vendor.
|
245 |
|
246 |
+
= Non-Latin language users =
|
247 |
+
|
248 |
+
The plugin works with users of non-lating languages with a few exceptions. First, the character set of the Database Table should be in UTF-8. If you see '????' characters in the plugin, go to Settings -> Advanced. There is a button to set the tabel to UTF-8
|
249 |
+
|
250 |
+
Secondly, please use latin only characters for button name ( Basic settings) and extra classes ( Advanced settings ). Not doing so might prevent the styling output from working correctly.
|
251 |
+
|
252 |
== Changelog ==
|
253 |
|
254 |
+
= 6.27 =
|
255 |
+
|
256 |
+
* Tested for 4.9.2
|
257 |
+
* Security - Added rel='noopener' for links opening in new window
|
258 |
+
* Fixed missing values on a template
|
259 |
+
|
260 |
= 6.26.1 =
|
261 |
|
262 |
+
* Fixed - Advanced options
|
263 |
|
264 |
= 6.26 =
|
265 |
|