00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 class Set extends Object {
00034
00035
00036
00037
00038 var $value = array();
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 function merge($arr1, $arr2 = null) {
00053 $args = func_get_args();
00054
00055 $r = (array)current($args);
00056 while (($arg = next($args)) !== false) {
00057 foreach ((array)$arg as $key => $val) {
00058 if (is_array($val) && isset($r[$key]) && is_array($r[$key])) {
00059 $r[$key] = Set::merge($r[$key], $val);
00060 } elseif (is_int($key)) {
00061 $r[] = $val;
00062 } else {
00063 $r[$key] = $val;
00064 }
00065 }
00066 }
00067 return $r;
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 function filter($var, $isArray = false) {
00079 if (is_array($var) && (!empty($var) || $isArray)) {
00080 return array_filter($var, array('Set', 'filter'));
00081 }
00082
00083 if ($var === 0 || $var === '0' || !empty($var)) {
00084 return true;
00085 }
00086 return false;
00087 }
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 function pushDiff($array, $array2) {
00098 if (empty($array) && !empty($array2)) {
00099 return $array2;
00100 }
00101 if (!empty($array) && !empty($array2)) {
00102 foreach ($array2 as $key => $value) {
00103 if (!array_key_exists($key, $array)) {
00104 $array[$key] = $value;
00105 } else {
00106 if (is_array($value)) {
00107 $array[$key] = Set::pushDiff($array[$key], $array2[$key]);
00108 }
00109 }
00110 }
00111 }
00112 return $array;
00113 }
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124 function map($class = 'stdClass', $tmp = 'stdClass') {
00125 if (is_array($class)) {
00126 $val = $class;
00127 $class = $tmp;
00128 }
00129
00130 if (empty($val)) {
00131 return null;
00132 }
00133 return Set::__map($val, $class);
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 function __array($array) {
00148 if (empty($array)) {
00149 $array = array();
00150 } elseif (is_object($array)) {
00151 $array = get_object_vars($array);
00152 } elseif (!is_array($array)) {
00153 $array = array($array);
00154 }
00155 return $array;
00156 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 function __map(&$array, $class, $primary = false) {
00174 if ($class === true) {
00175 $out = new stdClass;
00176 } else {
00177 $out = new $class;
00178 }
00179 if (is_array($array)) {
00180 $keys = array_keys($array);
00181 foreach ($array as $key => $value) {
00182 if ($keys[0] === $key && $class !== true) {
00183 $primary = true;
00184 }
00185 if (is_numeric($key)) {
00186 if (is_object($out)) {
00187 $out = get_object_vars($out);
00188 }
00189 $out[$key] = Set::__map($value, $class);
00190 if (is_object($out[$key])) {
00191 if ($primary !== true && is_array($value) && Set::countDim($value, true) === 2) {
00192 if (!isset($out[$key]->_name_)) {
00193 $out[$key]->_name_ = $primary;
00194 }
00195 }
00196 }
00197 } elseif (is_array($value)) {
00198 if ($primary === true) {
00199 if (!isset($out->_name_)) {
00200 $out->_name_ = $key;
00201 }
00202 $primary = false;
00203 foreach ($value as $key2 => $value2) {
00204 $out->{$key2} = Set::__map($value2, true);
00205 }
00206 } else {
00207 if (!is_numeric($key)) {
00208 $out->{$key} = Set::__map($value, true, $key);
00209 if (is_object($out->{$key}) && !is_numeric($key)) {
00210 if (!isset($out->{$key}->_name_)) {
00211 $out->{$key}->_name_ = $key;
00212 }
00213 }
00214 } else {
00215 $out->{$key} = Set::__map($value, true);
00216 }
00217 }
00218 } else {
00219 $out->{$key} = $value;
00220 }
00221 }
00222 } else {
00223 $out = $array;
00224 }
00225 return $out;
00226 }
00227
00228
00229
00230
00231
00232
00233
00234
00235 function numeric($array = null) {
00236 if (empty($array)) {
00237 return null;
00238 }
00239
00240 if ($array === range(0, count($array) - 1)) {
00241 return true;
00242 }
00243
00244 $numeric = true;
00245 $keys = array_keys($array);
00246 $count = count($keys);
00247
00248 for ($i = 0; $i < $count; $i++) {
00249 if (!is_numeric($array[$keys[$i]])) {
00250 $numeric = false;
00251 break;
00252 }
00253 }
00254 return $numeric;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 function enum($select, $list = null) {
00273 if (empty($list)) {
00274 $list = array('no', 'yes');
00275 }
00276
00277 $return = null;
00278 $list = Set::normalize($list, false);
00279
00280 if (array_key_exists($select, $list)) {
00281 $return = $list[$select];
00282 }
00283 return $return;
00284 }
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 function format($data, $format, $keys) {
00296
00297 $extracted = array();
00298 $count = count($keys);
00299
00300 if (!$count) {
00301 return;
00302 }
00303
00304 for ($i = 0; $i < $count; $i++) {
00305 $extracted[] = Set::extract($data, $keys[$i]);
00306 }
00307 $out = array();
00308 $data = $extracted;
00309 $count = count($data[0]);
00310
00311 if (preg_match_all('/\{([0-9]+)\}/msi', $format, $keys2) && isset($keys2[1])) {
00312 $keys = $keys2[1];
00313 $format = preg_split('/\{([0-9]+)\}/msi', $format);
00314 $count2 = count($format);
00315
00316 for ($j = 0; $j < $count; $j++) {
00317 $formatted = '';
00318 for ($i = 0; $i <= $count2; $i++) {
00319 if (isset($format[$i])) {
00320 $formatted .= $format[$i];
00321 }
00322 if (isset($keys[$i]) && isset($data[$keys[$i]][$j])) {
00323 $formatted .= $data[$keys[$i]][$j];
00324 }
00325 }
00326 $out[] = $formatted;
00327 }
00328 } else {
00329 $count2 = count($data);
00330 for ($j = 0; $j < $count; $j++) {
00331 $args = array();
00332 for ($i = 0; $i < $count2; $i++) {
00333 if (isset($data[$i][$j])) {
00334 $args[] = $data[$i][$j];
00335 }
00336 }
00337 $out[] = vsprintf($format, $args);
00338 }
00339 }
00340 return $out;
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 function extract($path, $data = null, $options = array()) {
00372 if (is_string($data)) {
00373 $tmp = $data;
00374 $data = $path;
00375 $path = $tmp;
00376 }
00377 if (strpos($path, '/') === false) {
00378 return Set::classicExtract($data, $path);
00379 }
00380 if (empty($data)) {
00381 return array();
00382 }
00383 if ($path === '/') {
00384 return $data;
00385 }
00386 $contexts = $data;
00387 $options = array_merge(array('flatten' => true), $options);
00388 if (!isset($contexts[0])) {
00389 $contexts = array($data);
00390 }
00391 $tokens = array_slice(preg_split('/(?<!=)\/(?![a-z-]*\])/', $path), 1);
00392
00393 do {
00394 $token = array_shift($tokens);
00395 $conditions = false;
00396 if (preg_match_all('/\[([^=]+=\/[^\/]+\/|[^\]]+)\]/', $token, $m)) {
00397 $conditions = $m[1];
00398 $token = substr($token, 0, strpos($token, '['));
00399 }
00400 $matches = array();
00401 foreach ($contexts as $key => $context) {
00402 if (!isset($context['trace'])) {
00403 $context = array('trace' => array(null), 'item' => $context, 'key' => $key);
00404 }
00405 if ($token === '..') {
00406 if (count($context['trace']) == 1) {
00407 $context['trace'][] = $context['key'];
00408 }
00409 $parent = join('/', $context['trace']) . '/.';
00410 $context['item'] = Set::extract($parent, $data);
00411 $context['key'] = array_pop($context['trace']);
00412 if (isset($context['trace'][1]) && $context['trace'][1] > 0) {
00413 $context['item'] = $context['item'][0];
00414 } else if(!empty($context['item'][$key])){
00415 $context['item'] = $context['item'][$key];
00416 } else {
00417 $context['item'] = array_shift($context['item']);
00418 }
00419 $matches[] = $context;
00420 continue;
00421 }
00422 $match = false;
00423 if ($token === '@*' && is_array($context['item'])) {
00424 $matches[] = array(
00425 'trace' => array_merge($context['trace'], (array)$key),
00426 'key' => $key,
00427 'item' => array_keys($context['item']),
00428 );
00429 } elseif (is_array($context['item']) && array_key_exists($token, $context['item'])) {
00430 $items = $context['item'][$token];
00431 if (!is_array($items)) {
00432 $items = array($items);
00433 } elseif (!isset($items[0])) {
00434 $current = current($items);
00435 if ((is_array($current) && count($items) <= 1) || !is_array($current)) {
00436 $items = array($items);
00437 }
00438 }
00439
00440 foreach ($items as $key => $item) {
00441 $ctext = array($context['key']);
00442 if (!is_numeric($key)) {
00443 $ctext[] = $token;
00444 $token = array_shift($tokens);
00445 if (isset($items[$token])) {
00446 $ctext[] = $token;
00447 $item = $items[$token];
00448 $matches[] = array(
00449 'trace' => array_merge($context['trace'], $ctext),
00450 'key' => $key,
00451 'item' => $item,
00452 );
00453 break;
00454 } else {
00455 array_unshift($tokens, $token);
00456 }
00457 } else {
00458 $key = $token;
00459 }
00460
00461 $matches[] = array(
00462 'trace' => array_merge($context['trace'], $ctext),
00463 'key' => $key,
00464 'item' => $item,
00465 );
00466 }
00467 } elseif (($key === $token || (ctype_digit($token) && $key == $token) || $token === '.')) {
00468 $context['trace'][] = $key;
00469 $matches[] = array(
00470 'trace' => $context['trace'],
00471 'key' => $key,
00472 'item' => $context['item'],
00473 );
00474 }
00475 }
00476 if ($conditions) {
00477 foreach ($conditions as $condition) {
00478 $filtered = array();
00479 $length = count($matches);
00480 foreach ($matches as $i => $match) {
00481 if (Set::matches(array($condition), $match['item'], $i + 1, $length)) {
00482 $filtered[] = $match;
00483 }
00484 }
00485 $matches = $filtered;
00486 }
00487 }
00488 $contexts = $matches;
00489
00490 if (empty($tokens)) {
00491 break;
00492 }
00493 } while(1);
00494
00495 $r = array();
00496
00497 foreach ($matches as $match) {
00498 if ((!$options['flatten'] || is_array($match['item'])) && !is_int($match['key'])) {
00499 $r[] = array($match['key'] => $match['item']);
00500 } else {
00501 $r[] = $match['item'];
00502 }
00503 }
00504 return $r;
00505 }
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516 function matches($conditions, $data = array(), $i = null, $length = null) {
00517 if (empty($conditions)) {
00518 return true;
00519 }
00520 if (is_string($conditions)) {
00521 return !!Set::extract($conditions, $data);
00522 }
00523 foreach ($conditions as $condition) {
00524 if ($condition === ':last') {
00525 if ($i != $length) {
00526 return false;
00527 }
00528 continue;
00529 } elseif ($condition === ':first') {
00530 if ($i != 1) {
00531 return false;
00532 }
00533 continue;
00534 }
00535 if (!preg_match('/(.+?)([><!]?[=]|[><])(.*)/', $condition, $match)) {
00536 if (ctype_digit($condition)) {
00537 if ($i != $condition) {
00538 return false;
00539 }
00540 } elseif (preg_match_all('/(?:^[0-9]+|(?<=,)[0-9]+)/', $condition, $matches)) {
00541 return in_array($i, $matches[0]);
00542 } elseif (!array_key_exists($condition, $data)) {
00543 return false;
00544 }
00545 continue;
00546 }
00547 list(,$key,$op,$expected) = $match;
00548 if (!isset($data[$key])) {
00549 return false;
00550 }
00551
00552 $val = $data[$key];
00553
00554 if ($op === '=' && $expected && $expected{0} === '/') {
00555 return preg_match($expected, $val);
00556 }
00557 if ($op === '=' && $val != $expected) {
00558 return false;
00559 }
00560 if ($op === '!=' && $val == $expected) {
00561 return false;
00562 }
00563 if ($op === '>' && $val <= $expected) {
00564 return false;
00565 }
00566 if ($op === '<' && $val >= $expected) {
00567 return false;
00568 }
00569 if ($op === '<=' && $val > $expected) {
00570 return false;
00571 }
00572 if ($op === '>=' && $val < $expected) {
00573 return false;
00574 }
00575 }
00576 return true;
00577 }
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 function classicExtract($data, $path = null) {
00591 if (empty($path)) {
00592 return $data;
00593 }
00594 if (is_object($data)) {
00595 $data = get_object_vars($data);
00596 }
00597 if (!is_array($data)) {
00598 return $data;
00599 }
00600
00601 if (!is_array($path)) {
00602 if (!class_exists('String')) {
00603 App::import('Core', 'String');
00604 }
00605 $path = String::tokenize($path, '.', '{', '}');
00606 }
00607 $tmp = array();
00608
00609 if (!is_array($path) || empty($path)) {
00610 return null;
00611 }
00612
00613 foreach ($path as $i => $key) {
00614 if (is_numeric($key) && intval($key) > 0 || $key === '0') {
00615 if (isset($data[intval($key)])) {
00616 $data = $data[intval($key)];
00617 } else {
00618 return null;
00619 }
00620 } elseif ($key === '{n}') {
00621 foreach ($data as $j => $val) {
00622 if (is_int($j)) {
00623 $tmpPath = array_slice($path, $i + 1);
00624 if (empty($tmpPath)) {
00625 $tmp[] = $val;
00626 } else {
00627 $tmp[] = Set::classicExtract($val, $tmpPath);
00628 }
00629 }
00630 }
00631 return $tmp;
00632 } elseif ($key === '{s}') {
00633 foreach ($data as $j => $val) {
00634 if (is_string($j)) {
00635 $tmpPath = array_slice($path, $i + 1);
00636 if (empty($tmpPath)) {
00637 $tmp[] = $val;
00638 } else {
00639 $tmp[] = Set::classicExtract($val, $tmpPath);
00640 }
00641 }
00642 }
00643 return $tmp;
00644 } elseif (false !== strpos($key,'{') && false !== strpos($key,'}')) {
00645 $pattern = substr($key, 1, -1);
00646
00647 foreach ($data as $j => $val) {
00648 if (preg_match('/^'.$pattern.'/s', $j) !== 0) {
00649 $tmpPath = array_slice($path, $i + 1);
00650 if (empty($tmpPath)) {
00651 $tmp[$j] = $val;
00652 } else {
00653 $tmp[$j] = Set::classicExtract($val, $tmpPath);
00654 }
00655 }
00656 }
00657 return $tmp;
00658 } else {
00659 if (isset($data[$key])) {
00660 $data = $data[$key];
00661 } else {
00662 return null;
00663 }
00664 }
00665 }
00666 return $data;
00667 }
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 function insert($list, $path, $data = null) {
00679 if (!is_array($path)) {
00680 $path = explode('.', $path);
00681 }
00682 $_list =& $list;
00683
00684 foreach ($path as $i => $key) {
00685 if (is_numeric($key) && intval($key) > 0 || $key === '0') {
00686 $key = intval($key);
00687 }
00688 if ($i === count($path) - 1) {
00689 $_list[$key] = $data;
00690 } else {
00691 if (!isset($_list[$key])) {
00692 $_list[$key] = array();
00693 }
00694 $_list =& $_list[$key];
00695 }
00696 }
00697 return $list;
00698 }
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708 function remove($list, $path = null) {
00709 if (empty($path)) {
00710 return $list;
00711 }
00712 if (!is_array($path)) {
00713 $path = explode('.', $path);
00714 }
00715 $_list =& $list;
00716
00717 foreach ($path as $i => $key) {
00718 if (is_numeric($key) && intval($key) > 0 || $key === '0') {
00719 $key = intval($key);
00720 }
00721 if ($i === count($path) - 1) {
00722 unset($_list[$key]);
00723 } else {
00724 if (!isset($_list[$key])) {
00725 return $list;
00726 }
00727 $_list =& $_list[$key];
00728 }
00729 }
00730 return $list;
00731 }
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741 function check($data, $path = null) {
00742 if (empty($path)) {
00743 return $data;
00744 }
00745 if (!is_array($path)) {
00746 $path = explode('.', $path);
00747 }
00748
00749 foreach ($path as $i => $key) {
00750 if (is_numeric($key) && intval($key) > 0 || $key === '0') {
00751 $key = intval($key);
00752 }
00753 if ($i === count($path) - 1) {
00754 return (is_array($data) && array_key_exists($key, $data));
00755 }
00756
00757 if (!is_array($data) || !array_key_exists($key, $data)) {
00758 return false;
00759 }
00760 $data =& $data[$key];
00761 }
00762 return true;
00763 }
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773 function diff($val1, $val2 = null) {
00774 if (empty($val1)) {
00775 return (array)$val2;
00776 }
00777 if (empty($val2)) {
00778 return (array)$val1;
00779 }
00780 $out = array();
00781
00782 foreach ($val1 as $key => $val) {
00783 $exists = array_key_exists($key, $val2);
00784
00785 if ($exists && $val2[$key] != $val) {
00786 $out[$key] = $val;
00787 } elseif (!$exists) {
00788 $out[$key] = $val;
00789 }
00790 unset($val2[$key]);
00791 }
00792
00793 foreach ($val2 as $key => $val) {
00794 if (!array_key_exists($key, $out)) {
00795 $out[$key] = $val;
00796 }
00797 }
00798 return $out;
00799 }
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809 function isEqual($val1, $val2 = null) {
00810 return ($val1 == $val2);
00811 }
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821 function contains($val1, $val2 = null) {
00822 if (empty($val1) || empty($val2)) {
00823 return false;
00824 }
00825
00826 foreach ($val2 as $key => $val) {
00827 if (is_numeric($key)) {
00828 Set::contains($val, $val1);
00829 } else {
00830 if (!isset($val1[$key]) || $val1[$key] != $val) {
00831 return false;
00832 }
00833 }
00834 }
00835 return true;
00836 }
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848 function countDim($array = null, $all = false, $count = 0) {
00849 if ($all) {
00850 $depth = array($count);
00851 if (is_array($array) && reset($array) !== false) {
00852 foreach ($array as $value) {
00853 $depth[] = Set::countDim($value, true, $count + 1);
00854 }
00855 }
00856 $return = max($depth);
00857 } else {
00858 if (is_array(reset($array))) {
00859 $return = Set::countDim(reset($array)) + 1;
00860 } else {
00861 $return = 1;
00862 }
00863 }
00864 return $return;
00865 }
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877 function normalize($list, $assoc = true, $sep = ',', $trim = true) {
00878 if (is_string($list)) {
00879 $list = explode($sep, $list);
00880 if ($trim) {
00881 foreach ($list as $key => $value) {
00882 $list[$key] = trim($value);
00883 }
00884 }
00885 if ($assoc) {
00886 return Set::normalize($list);
00887 }
00888 } elseif (is_array($list)) {
00889 $keys = array_keys($list);
00890 $count = count($keys);
00891 $numeric = true;
00892
00893 if (!$assoc) {
00894 for ($i = 0; $i < $count; $i++) {
00895 if (!is_int($keys[$i])) {
00896 $numeric = false;
00897 break;
00898 }
00899 }
00900 }
00901 if (!$numeric || $assoc) {
00902 $newList = array();
00903 for ($i = 0; $i < $count; $i++) {
00904 if (is_int($keys[$i])) {
00905 $newList[$list[$keys[$i]]] = null;
00906 } else {
00907 $newList[$keys[$i]] = $list[$keys[$i]];
00908 }
00909 }
00910 $list = $newList;
00911 }
00912 }
00913 return $list;
00914 }
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929 function combine($data, $path1 = null, $path2 = null, $groupPath = null) {
00930 if (empty($data)) {
00931 return array();
00932 }
00933
00934 if (is_object($data)) {
00935 $data = get_object_vars($data);
00936 }
00937
00938 if (is_array($path1)) {
00939 $format = array_shift($path1);
00940 $keys = Set::format($data, $format, $path1);
00941 } else {
00942 $keys = Set::extract($data, $path1);
00943 }
00944
00945 if (!empty($path2) && is_array($path2)) {
00946 $format = array_shift($path2);
00947 $vals = Set::format($data, $format, $path2);
00948
00949 } elseif (!empty($path2)) {
00950 $vals = Set::extract($data, $path2);
00951
00952 } else {
00953 $count = count($keys);
00954 for ($i = 0; $i < $count; $i++) {
00955 $vals[$i] = null;
00956 }
00957 }
00958
00959 if ($groupPath != null) {
00960 $group = Set::extract($data, $groupPath);
00961 if (!empty($group)) {
00962 $c = count($keys);
00963 for ($i = 0; $i < $c; $i++) {
00964 if (!isset($group[$i])) {
00965 $group[$i] = 0;
00966 }
00967 if (!isset($out[$group[$i]])) {
00968 $out[$group[$i]] = array();
00969 }
00970 $out[$group[$i]][$keys[$i]] = $vals[$i];
00971 }
00972 return $out;
00973 }
00974 }
00975
00976 return array_combine($keys, $vals);
00977 }
00978
00979
00980
00981
00982
00983
00984
00985
00986 function reverse($object) {
00987 $out = array();
00988 if (is_a($object, 'XmlNode')) {
00989 $out = $object->toArray();
00990 return $out;
00991 } else if (is_object($object)) {
00992 $keys = get_object_vars($object);
00993 if (isset($keys['_name_'])) {
00994 $identity = $keys['_name_'];
00995 unset($keys['_name_']);
00996 }
00997 $new = array();
00998 foreach ($keys as $key => $value) {
00999 if (is_array($value)) {
01000 $new[$key] = (array)Set::reverse($value);
01001 } else {
01002 if (isset($value->_name_)) {
01003 $new = array_merge($new, Set::reverse($value));
01004 } else {
01005 $new[$key] = Set::reverse($value);
01006 }
01007 }
01008 }
01009 if (isset($identity)) {
01010 $out[$identity] = $new;
01011 } else {
01012 $out = $new;
01013 }
01014 } elseif (is_array($object)) {
01015 foreach ($object as $key => $value) {
01016 $out[$key] = Set::reverse($value);
01017 }
01018 } else {
01019 $out = $object;
01020 }
01021 return $out;
01022 }
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034 function flatten($data, $separator = '.') {
01035 $result = array();
01036 $path = null;
01037
01038 if (is_array($separator)) {
01039 extract($separator, EXTR_OVERWRITE);
01040 }
01041
01042 if (!is_null($path)) {
01043 $path .= $separator;
01044 }
01045
01046 foreach ($data as $key => $val) {
01047 if (is_array($val)) {
01048 $result += (array)Set::flatten($val, array(
01049 'separator' => $separator,
01050 'path' => $path . $key
01051 ));
01052 } else {
01053 $result[$path . $key] = $val;
01054 }
01055 }
01056 return $result;
01057 }
01058
01059
01060
01061
01062
01063
01064
01065
01066 function __flatten($results, $key = null) {
01067 $stack = array();
01068 foreach ($results as $k => $r) {
01069 $id = $k;
01070 if (!is_null($key)) {
01071 $id = $key;
01072 }
01073 if (is_array($r)) {
01074 $stack = array_merge($stack, Set::__flatten($r, $id));
01075 } else {
01076 $stack[] = array('id' => $id, 'value' => $r);
01077 }
01078 }
01079 return $stack;
01080 }
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090 function sort($data, $path, $dir) {
01091 $result = Set::__flatten(Set::extract($data, $path));
01092 list($keys, $values) = array(Set::extract($result, '{n}.id'), Set::extract($result, '{n}.value'));
01093
01094 $dir = strtolower($dir);
01095 if ($dir === 'asc') {
01096 $dir = SORT_ASC;
01097 } elseif ($dir === 'desc') {
01098 $dir = SORT_DESC;
01099 }
01100 array_multisort($values, $dir, $keys, $dir);
01101 $sorted = array();
01102
01103 $keys = array_unique($keys);
01104
01105 foreach ($keys as $k) {
01106 $sorted[] = $data[$k];
01107 }
01108 return $sorted;
01109 }
01110
01111
01112
01113
01114 function &get() {
01115 trigger_error('get() is deprecated. Set class should be called statically', E_USER_WARNING);
01116 }
01117 }
01118 ?>