PluginProbe ʕ •ᴥ•ʔ
Tracking Code Manager / 2.2.0
Tracking Code Manager v2.2.0
trunk 1.11.8 1.11.9 1.12.0 1.12.1 1.12.2 1.12.3 1.4 1.5 2.0.0 2.0.1 2.0.13 2.0.14 2.0.15 2.0.16 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.2.0 2.3.0 2.4.0 2.5.0 2.6.0
tracking-code-manager / includes / classes / core / Manager.php
tracking-code-manager / includes / classes / core Last commit date
Manager.php 2 years ago Singleton.php 3 years ago
Manager.php
699 lines
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 exit;
4 }
5
6 class TCMP_Manager {
7 public function __construct() {
8 }
9 public function init() {
10 add_action( 'wp_ajax_TCMP_changeOrder', array( &$this, 'change_order' ) );
11 }
12 public function is_limit_reached( $notice = true ) {
13 global $tcmp;
14 $cnt = $this->codes_count();
15 $result = ( $cnt >= TCMP_SNIPPETS_LIMIT );
16 if ( $result && $notice ) {
17 $tcmp->options->pushWarningMessage( 'SnippetsLimitReached', TCMP_SNIPPETS_LIMIT, TCMP_PAGE_PREMIUM );
18 } elseif ( $notice && $cnt > 0 ) {
19 $tcmp->options->pushSuccessMessage( 'SnippetsLimitNotice', $cnt, TCMP_SNIPPETS_LIMIT, TCMP_PAGE_PREMIUM );
20 }
21 return $result;
22 }
23 public function change_order() {
24 if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'change_order' ) ) {
25 wp_send_json_error( 'Invalid nonce' );
26 }
27
28 if ( ! current_user_can( 'edit_plugins' ) ) {
29 return;
30 }
31
32 if ( ! isset( $_POST['order'] ) ) {
33 return;
34 }
35
36 $data = array();
37 parse_str( tcmp_sqs( 'order' ), $data );
38
39 if ( isset( $data['row'] ) ) {
40 $snippets = $this->values();
41 foreach ( $snippets as $id => $v ) {
42 $v['order'] = 0;
43 $snippets[ $id ] = $v;
44 }
45
46 $index = 1;
47 foreach ( $data['row'] as $order => $id ) {
48 $v = $snippets[ $id ];
49 $v['order'] = $index;
50 $snippets[ $id ] = $v;
51 ++$index;
52 }
53
54 foreach ( $snippets as $id => $v ) {
55 $this->put( $id, $v );
56 }
57 }
58 echo 'OK';
59 wp_die();
60 }
61
62 public function match_device_type( $snippet ) {
63 global $tcmp;
64 $device_type = $tcmp->utils->get( $snippet, 'deviceType', false );
65 $device_type = $tcmp->utils->to_array( $device_type );
66 if ( false == $device_type || 0 == count( $device_type ) ) {
67 return true;
68 }
69
70 $detect = new TCMP_Mobile_Detect();
71 if ( $detect->isMobile() ) {
72 $type = TCMP_DEVICE_TYPE_MOBILE;
73 } elseif ( $detect->isTablet() ) {
74 $type = TCMP_DEVICE_TYPE_TABLET;
75 } else { //if(!$detect->isMobile() && !$detect->isTablet()) {
76 $type = TCMP_DEVICE_TYPE_DESKTOP;
77 }
78
79 $result = false;
80 if ( in_array( TCMP_DEVICE_TYPE_ALL, $device_type ) || in_array( $type, $device_type ) ) {
81 $result = true;
82 }
83 return $result;
84 }
85 public function is_mode_script( $snippet ) {
86 global $tcmp;
87 $result = $tcmp->utils->iget( $snippet, 'trackMode', 0 );
88 return ( 0 == $result );
89 }
90 public function is_mode_conversion( $snippet ) {
91 global $tcmp;
92 $result = $tcmp->utils->iget( $snippet, 'trackMode', 0 );
93 return ( 0 != $result );
94 }
95 public function is_page_everywhere( $snippet ) {
96 global $tcmp;
97 if ( ! $this->is_mode_script( $snippet ) ) {
98 return false;
99 }
100
101 $result = $tcmp->utils->iget( $snippet, 'trackPage', 0 );
102 return ( TCMP_TRACK_PAGE_ALL == $result );
103 }
104 public function is_page_specific( $snippet ) {
105 global $tcmp;
106 if ( ! $this->is_mode_script( $snippet ) ) {
107 return false;
108 }
109
110 $result = $tcmp->utils->iget( $snippet, 'trackPage', 0 );
111 return ( TCMP_TRACK_PAGE_SPECIFIC == $result );
112 }
113
114 public function exists( $name ) {
115 $snippets = $this->values();
116 $result = null;
117 $name = strtoupper( $name );
118 if ( isset( $snippets[ $name ] ) ) {
119 $result = $snippets[ $name ];
120 }
121 return $result;
122 }
123
124 //get a code snippet
125 public function get( $id, $new = false ) {
126 global $tcmp;
127
128 $snippet = $tcmp->options->getSnippet( $id );
129 if ( ! $snippet && $new ) {
130 $snippet = array();
131 $snippet['active'] = 1;
132 $snippet['trackMode'] = -1;
133 $snippet['trackPage'] = -1;
134 }
135
136 $snippet = $this->sanitize( $id, $snippet );
137 return $snippet;
138 }
139
140 public function sanitize( $id, $snippet ) {
141 global $tcmp;
142 if ( null == $snippet || ! is_array( $snippet ) ) {
143 return null;
144 }
145
146 $page = 0;
147 if ( isset( $snippet['includeEverywhereActive'] ) ) {
148 $page = ( intval( 1 == $snippet['includeEverywhereActive'] ) ? 0 : 1 );
149 }
150 $defaults = array(
151 'id' => $id,
152 'active' => 0,
153 'name' => '',
154 'code' => '',
155 'order' => 1000,
156 'position' => TCMP_POSITION_HEAD,
157 'trackMode' => TCMP_TRACK_MODE_CODE,
158 'trackPage' => $page,
159 'includeEverywhereActive' => 0,
160 'includeCategoriesActive' => 0,
161 'includeCategories' => array(),
162 'includeTagsActive' => 0,
163 'includeTags' => array(),
164 'exceptCategoriesActive' => 0,
165 'exceptCategories' => array(),
166 'exceptTagsActive' => 0,
167 'exceptTags' => array(),
168 'deviceType' => TCMP_DEVICE_TYPE_ALL,
169 );
170
171 $types = $tcmp->utils->query( TCMP_QUERY_POST_TYPES );
172 foreach ( $types as $v ) {
173 $defaults[ 'includePostsOfType_' . $v['id'] . '_Active' ] = 0;
174 $defaults[ 'includePostsOfType_' . $v['id'] ] = array();
175 $defaults[ 'exceptPostsOfType_' . $v['id'] . '_Active' ] = 0;
176 $defaults[ 'exceptPostsOfType_' . $v['id'] ] = array();
177 }
178
179 $types = $tcmp->utils->query( TCMP_QUERY_CONVERSION_PLUGINS );
180 foreach ( $types as $v ) {
181 //CP stands for ConversionTrackingCode
182 //$defaults['CTC_'.$v['id'].'_Active']=0;
183 $defaults[ 'CTC_' . $v['id'] . '_ProductsIds' ] = array();
184 $defaults[ 'CTC_' . $v['id'] . '_CategoriesIds' ] = array();
185 $defaults[ 'CTC_' . $v['id'] . '_TagsIds' ] = array();
186 }
187 $snippet = $tcmp->utils->parseArgs( $snippet, $defaults );
188
189 foreach ( $snippet as $k => $v ) {
190 if ( stripos( $k, 'active' ) != false ) {
191 $snippet[ $k ] = intval( $v );
192 } elseif ( is_array( $v ) ) {
193 switch ( $k ) {
194 /*
195 case 'includePostsTypes':
196 case 'excludePostsTypes':
197 //keys are string and not number
198 $result=$this->uarray($snippet, $k, FALSE);
199 break;
200 */
201 default:
202 //keys are number
203 $result = $this->uarray( $snippet, $k, true );
204 break;
205 }
206 }
207 }
208 $snippet['name'] = sanitize_text_field( $snippet['name'] );
209 $snippet['code'] = trim( $snippet['code'] );
210 $snippet['position'] = intval( $snippet['position'] );
211 if ( '' == $snippet['trackMode'] ) {
212 $snippet['trackMode'] = TCMP_TRACK_MODE_CODE;
213 } else {
214 $snippet['trackMode'] = intval( $snippet['trackMode'] );
215 }
216 if ( '' == $snippet['trackPage'] ) {
217 $snippet['trackPage'] = $page;
218 } else {
219 $snippet['trackPage'] = intval( $snippet['trackPage'] );
220 }
221
222 $snippet['includeEverywhereActive'] = 0;
223 if ( TCMP_TRACK_PAGE_ALL == $snippet['trackPage'] ) {
224 $snippet['includeEverywhereActive'] = 1;
225 }
226
227 $code = strtolower( $snippet['code'] );
228 $cnt = substr_count( $code, '<iframe' ) + substr_count( $code, '<script' );
229 if ( $cnt <= 0 ) {
230 $cnt = 1;
231 }
232 $snippet['codes_count'] = $cnt;
233 return $snippet;
234 }
235 private function uarray( $snippet, $key, $is_integer = true ) {
236 $array = $snippet[ $key ];
237 if ( ! is_array( $array ) ) {
238 $array = explode( ',', $array );
239 }
240
241 if ( $is_integer ) {
242 for ( $i = 0; $i < count( $array ); $i++ ) {
243 if ( isset( $array[ $i ]) ) {
244 $array[ $i ] = intval( $array[ $i ] );
245 }
246 }
247 }
248
249 $array = array_unique( $array );
250 $snippet[ $key ] = $array;
251 return $snippet;
252 }
253
254 //add or update a snippet (html tracking code)
255 public function put( $id, $snippet ) {
256 global $tcmp;
257
258 if ( '' == $id || intval( $id ) <= 0 ) {
259 //if is a new code create a new unique id
260 $id = $this->get_last_id() + 1;
261 $snippet['id'] = $id;
262 }
263 $snippet = $this->sanitize( $id, $snippet );
264 $tcmp->options->setSnippet( $id, $snippet );
265
266 $keys = $this->keys();
267 if ( is_array( $keys ) && ! in_array( $id, $keys ) ) {
268 $keys[] = $id;
269 $this->keys( $keys );
270 }
271 return $snippet;
272 }
273
274 //remove the id snippet
275 public function remove( $id ) {
276 global $tcmp;
277 $tcmp->options->remove_snippet( $id );
278 $keys = $this->keys();
279 $result = false;
280 if ( is_array( $keys ) && in_array( $id, $keys ) ) {
281 $keys = array_diff( $keys, array( $id ) );
282 $this->keys( $keys );
283 $result = true;
284 }
285 return $result;
286 }
287
288 //verify if match with this snippet
289 private function match_snippet( $post_id, $post_type, $categories_ids, $tags_ids, $prefix, $snippet ) {
290 global $tcmp;
291 if ( ! $this->match_device_type( $snippet ) ) {
292 return false;
293 }
294
295 $include = false;
296 $post_id = intval( $post_id );
297 if ( $post_id > 0 ) {
298 $what = $prefix . 'PostsOfType_' . $post_type;
299 //echo '<textarea cols="100" rows="4">DEBUG:'.'Post Id = '.$post_id .' $what = '. $what .' What = '.$snippet[$what.'_Active'] .' Active = '.$snippet[$what.'_Active']. ' InAllArray = ' . $tcmp->utils->in_all_array( $post_id, $snippet[$what] ) . '</textarea>';
300 if ( isset( $snippet[ $what . '_Active' ] ) && isset( $snippet[ $what ] ) && $snippet[ $what . '_Active' ] && $tcmp->utils->in_all_array( $post_id, $snippet[ $what ] ) ) {
301 $tcmp->log->debug(
302 'MATCH=%s SNIPPET=%s[%s] DUE TO POST=%s OF TYPE=%s IN [%s]',
303 $prefix,
304 $snippet['id'],
305 $snippet['name'],
306 $post_id,
307 $post_type,
308 $snippet[ $what ]
309 );
310 $include = true;
311 //echo '<p>DEBUG: snippet matched</p>';
312 }
313 }
314
315 return $include;
316 }
317
318 public function write_codes( $position ) {
319 global $tcmp;
320
321 $text = '';
322 $position_text = '';
323 switch ( $position ) {
324 case TCMP_POSITION_HEAD:
325 $position_text = 'HEAD';
326 break;
327 case TCMP_POSITION_BODY:
328 $position_text = 'BODY';
329 break;
330 case TCMP_POSITION_FOOTER:
331 $position_text = 'FOOTER';
332 break;
333 case TCMP_POSITION_CONVERSION:
334 $position_text = 'CONVERSION';
335 break;
336 }
337
338 $post = $tcmp->options->getPostShown();
339 $args = array( 'field' => 'code' );
340 $codes = $tcmp->manager->get_codes( $position, $post, $args );
341 if ( is_array( $codes ) && count( $codes ) > 0 ) {
342 $version = TCMP_PLUGIN_VERSION;
343 $text = "\n<!--BEGIN: TRACKING CODE MANAGER (v$version) BY INTELLYWP.COM IN $position_text//-->";
344 foreach ( $codes as $v ) {
345 $text .= "\n$v";
346 }
347 $text .= "\n<!--END: https://wordpress.org/plugins/tracking-code-manager IN $position_text//-->";
348
349 $purchase = $tcmp->options->getEcommercePurchase();
350 if ( false != $purchase && intval( $tcmp->options->getLicenseSiteCount() ) > 0 ) {
351 $text = $this->insert_dynamic_conversion_values( $purchase, $text );
352 }
353 echo $this->esc_js_code( $text );
354 }
355 }
356
357 private function esc_js_code( $text ) {
358 global $tcmp;
359 global $tcmp_allowed_html_tags;
360
361 if ( ! $tcmp->options->getSkipCodeSanitization() ) {
362 $text = wp_kses( $text, $tcmp_allowed_html_tags );
363 }
364 $text = str_replace( '&lt;', '<', $text );
365 $text = str_replace( '&gt;', '>', $text );
366 $text = str_replace( '&amp;', '&', $text );
367 $text = str_replace( '&quot;', '"', $text );
368 $text = str_replace( '&#039;', "'", $text );
369 return $text;
370 }
371
372 private function insert_dynamic_conversion_values( $purchase, $text ) {
373 global $tcmp;
374 $purchase->user_id = intval( $purchase->user_id );
375 if ( $purchase->user_id > 0 ) {
376 $user = get_user_by( 'id', $purchase->user_id );
377 if ( ! is_null( $user ) && false != $user && get_class( $user ) == 'WP_User' ) {
378 /* @var $user WP_User */
379 $purchase->email = $user->user_email;
380 $purchase->fullname = $user->user_firstname;
381 if ( '' != $user->user_lastname ) {
382 $purchase->fullname .= ' ' . $user->user_lastname;
383 }
384 }
385 }
386
387 $purchase->total = floatval( $purchase->total );
388 $purchase->amount = floatval( $purchase->amount );
389 $purchase->tax = floatval( $purchase->tax );
390
391 $fields = array(
392 'ORDERID' => $purchase->order_id,
393 'CURRENCY' => $purchase->currency,
394 'FULLNAME' => $purchase->fullname,
395 'EMAIL' => $purchase->email,
396 'PRODUCTS' => $purchase->products,
397 'AMOUNT' => $purchase->amount,
398 'TOTAL' => $purchase->total,
399 'TAX' => $purchase->tax,
400 );
401
402 $sep = '@@';
403 $buffer = '';
404 $previous = 0;
405 $start = strpos( $text, $sep );
406 if ( false == $start ) {
407 $buffer = $text;
408 } else {
409 while ( false != $start ) {
410 $buffer .= $tcmp->utils->substr( $text, $previous, $start );
411 $end = strpos( $text, $sep, $start + strlen( $sep ) );
412 if ( false != $end ) {
413 $code = $tcmp->utils->substr( $text, $start + strlen( $sep ), $end );
414 $code = $tcmp->utils->to_array( $code );
415 if ( 1 == count( $code ) ) {
416 $code[] = '';
417 }
418
419 $v = false;
420 if ( isset( $fields[ $code[0] ] ) ) {
421 $v = $fields[ $code[0] ];
422 }
423 if ( is_null( $v ) || false == $v ) {
424 $v = $code[1];
425 }
426 if ( is_numeric( $v ) ) {
427 $v = floatval( $v );
428 $v = round( $v, 2 );
429 switch ( $code[0] ) {
430 case 'TOTAL':
431 case 'AMOUNT':
432 case 'TAX':
433 $v = number_format( $v, 2, '.', '' );
434 break;
435 default:
436 $v = intval( $v );
437 break;
438 }
439 } elseif ( is_array( $v ) ) {
440 $a = '';
441 foreach ( $v as $t ) {
442 $t = str_replace( ',', '', $t );
443 if ( '' != $a ) {
444 $a .= ',';
445 }
446 $a .= $t;
447 }
448 $v = $a;
449 }
450 $v = str_replace( "'", '', $v );
451 $v = str_replace( '"', '', $v );
452 $buffer .= $v;
453
454 $previous = $end + strlen( $sep );
455 $start = strpos( $text, $sep, $previous );
456 } else {
457 $buffer .= $tcmp->utils->substr( $text, $start );
458 $previous = false;
459 $start = false;
460 }
461 }
462
463 if ( false != $previous && $previous < strlen( $text ) ) {
464 $code = $tcmp->utils->substr( $text, $previous );
465 $buffer .= $code;
466 }
467 }
468 return $buffer;
469 }
470
471 //return snippets that match with options
472 public function get_conversion_snippets( $options = null ) {
473 global $tcmp;
474
475 $defaults = array(
476 'pluginId' => 0,
477 'categoriesIds' => array(),
478 'productsIds' => array(),
479 'tagsIds' => array(),
480 );
481 $options = $tcmp->utils->parseArgs( $options, $defaults );
482
483 $result = array();
484 $plugin_id = intval( $options['pluginId'] );
485 $values = $this->values();
486
487 foreach ( $values as $snippet ) {
488 $snippet['trackMode'] = intval( $snippet['trackMode'] );
489 if ( $snippet && $snippet['trackMode'] > 0 && $snippet['trackMode'] == $plugin_id ) {
490 $match = false;
491
492 $match = ( $match || $this->match_conversion( $snippet, $plugin_id, 'ProductsIds', $options['productsIds'] ) );
493 $match = ( $match && $this->match_device_type( $snippet ) );
494 if ( ! $match ) {
495 //no selected so..all match! :)
496 if ( 0 == count( $snippet[ 'CTC_' . $plugin_id . '_ProductsIds' ] )
497 && 0 == count( $snippet[ 'CTC_' . $plugin_id . '_CategoriesIds' ] )
498 && 0 == count( $snippet[ 'CTC_' . $plugin_id . '_TagsIds' ] ) ) {
499 $match = true;
500 }
501 }
502
503 if ( $match ) {
504 $result[] = $snippet;
505 }
506 }
507 }
508 return $result;
509 }
510 private function match_conversion( $snippet, $plugin_id, $suffix, $current_ids ) {
511 global $tcmp;
512
513 $settings_ids = 'CTC_' . $plugin_id . '_' . $suffix;
514 if ( isset( $snippet[ $settings_ids ] ) ) {
515 $settings_ids = $snippet[ $settings_ids ];
516 } else {
517 $settings_ids = array();
518 }
519
520 $result = $tcmp->utils->in_all_array( $current_ids, $settings_ids );
521 return $result;
522 }
523
524 //from a post retrieve the html code that is needed to insert into the page code
525 public function get_codes( $position, $post, $args = array() ) {
526 global $tcmp;
527
528 $defaults = array( 'field' => 'code' );
529 $args = $tcmp->utils->parseArgs( $args, $defaults );
530
531 $post_id = 0;
532 $post_type = 'page';
533 $tags_ids = array();
534 $categories_ids = array();
535 if ( $post ) {
536 $post_id = $tcmp->utils->get( $post, 'ID', false );
537 if ( false == $post_id ) {
538 $post_id = $tcmp->utils->get( $post, 'post_ID' );
539 }
540 $post_type = $tcmp->utils->get( $post, 'post_type' );
541
542 $options = array(
543 'orderby' => 'name',
544 'order' => 'ASC',
545 'fields' => 'ids',
546 );
547 if ( isset( $post->ID ) ) {
548 $tags_ids = wp_get_post_tags( $post->ID, $options );
549 $categories_ids = wp_get_post_categories( $post->ID );
550 } else {
551 $tags_ids = array();
552 $categories_ids = array();
553 }
554 }
555
556 $tcmp->options->clearSnippetsWritten();
557 if ( TCMP_POSITION_CONVERSION == $position ) {
558 //write snippets previously appended
559 $ids = $tcmp->options->get_conversion_snippet_ids();
560 if ( false != $ids && count( $ids ) > 0 ) {
561 foreach ( $ids as $id ) {
562 $snippet = $tcmp->manager->get( $id );
563 if ( $snippet ) {
564 $tcmp->options->pushSnippetWritten( $snippet );
565 }
566 }
567 }
568 } else {
569 $snippets = $this->values();
570 foreach ( $snippets as $v ) {
571 if ( ! $v || ( $position > -1 && $v['position'] != $position ) || '' == $v['code'] || ! $v['active'] ) {
572 continue;
573 }
574 if ( TCMP_TRACK_MODE_CODE != $v['trackMode'] ) {
575 continue;
576 }
577 if ( $tcmp->options->hasSnippetWritten( $v ) ) {
578 $tcmp->log->debug( 'SKIPPED SNIPPET=%s[%s] DUE TO ALREADY WRITTEN', $v['id'], $v['name'] );
579 continue;
580 }
581
582 $match = false;
583 if ( ! $match && ( TCMP_TRACK_PAGE_ALL == $v['trackPage'] || $v['includeEverywhereActive'] ) ) {
584 $tcmp->log->debug( 'INCLUDED SNIPPET=%s[%s] DUE TO EVERYWHERE', $v['id'], $v['name'] );
585 $match = true;
586 }
587 if ( ! $match && $post_id > 0 && $this->match_snippet( $post_id, $post_type, $categories_ids, $tags_ids, 'include', $v ) ) {
588 $match = true;
589 }
590
591 if ( $match && $post_id > 0 ) {
592 //echo '<textarea cols="100" rows="4">check for exclude' . print_r($v, true) . '</textarea>';
593 if ( $this->match_snippet( $post_id, $post_type, $categories_ids, $tags_ids, 'except', $v ) ) {
594 //echo '<textarea cols="100" rows="4">exclude ' . print_r($v, true) . '</textarea>';
595 $tcmp->log->debug( 'FOUND AT LEAST ONE EXCEPT TO EXCLUDE SNIPPET=%s [%s]', $v['id'], $v['name'] );
596 $match = false;
597 }
598 }
599
600 if ( $match ) {
601 $tcmp->options->pushSnippetWritten( $v );
602 }
603 }
604 }
605
606 //obtain result as snippets or array of one field (tipically "id")
607 $result = $tcmp->options->getSnippetsWritten();
608 if ( 'all' != $args['field'] ) {
609 $array = array();
610 foreach ( $result as $k => $v ) {
611 $k = $args['field'];
612 if ( isset( $v[ $k ] ) ) {
613 $array[] = $v[ $k ];
614 } else {
615 $tcmp->log->error( 'SNIPPET=%s [%s] WITHOUT FIELD=%s', $v['id'], $v['name'], $k );
616 }
617 }
618 $result = $array;
619 }
620 return $result;
621 }
622
623 //ottiene o salva tutte le chiavi dei tracking code utilizzati ordinati per id
624 public function keys( $keys = null ) {
625 global $tcmp;
626
627 if ( is_array( $keys ) ) {
628 $tcmp->options->setSnippetList( $keys );
629 $result = $keys;
630 } else {
631 $result = $tcmp->options->getSnippetList();
632 }
633
634 if ( ! is_array( $result ) ) {
635 $result = array();
636 } else {
637 sort( $result );
638 }
639 return $result;
640 }
641
642 //ottiene il conteggio attuale dei tracking code
643 public function count() {
644 $result = count( $this->keys() );
645 return $result;
646 }
647 public function codes_count() {
648 $result = 0;
649 $ids = $this->keys();
650 foreach ( $ids as $id ) {
651 $snippet = $this->get( $id );
652 if ( $snippet ) {
653 $result += 1;
654 }
655 }
656 return $result;
657 }
658 public function get_last_id() {
659 $result = 0;
660 $list = $this->keys();
661 foreach ( $list as $v ) {
662 $v = intval( $v );
663 if ( $v > $result ) {
664 $result = $v;
665 }
666 }
667 return $result;
668 }
669
670 public function values() {
671 $keys = $this->keys();
672 $array = array();
673 foreach ( $keys as $k ) {
674 $v = $this->get( $k );
675 $array[] = $v;
676 }
677 usort( $array, array( $this, 'values_compare' ) );
678
679 $result = array();
680 foreach ( $array as $v ) {
681 $id = $v['id'];
682 $result[ $id ] = $v;
683 }
684 return $result;
685 }
686 public function values_compare( $o1, $o2 ) {
687 global $tcmp;
688 $v1 = $tcmp->utils->iget( $o1, 'order', false );
689 $v2 = $tcmp->utils->iget( $o2, 'order', false );
690 $result = ( $v1 - $v2 );
691 if ( 0 == $result ) {
692 $v1 = $tcmp->utils->get( $o1, 'name', false );
693 $v2 = $tcmp->utils->get( $o2, 'name', false );
694 $result = strcasecmp( $v1, $v2 );
695 }
696 return $result;
697 }
698 }
699