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
00034
00035 class Set extends Object {
00036
00037
00038
00039
00040
00041
00042 var $value = array();
00043
00044
00045
00046
00047
00048 function __construct() {
00049 if (func_num_args() == 1 && is_array(func_get_arg(0))) {
00050 $this->value = func_get_arg(0);
00051 } else {
00052 $this->value = func_get_args();
00053 }
00054 }
00055
00056
00057
00058
00059
00060
00061 function &get() {
00062 return $this->value;
00063 }
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 function merge($arr1, $arr2 = null) {
00077 $args = func_get_args();
00078
00079 if (is_a($this, 'set')) {
00080 $backtrace = debug_backtrace();
00081 $previousCall = strtolower($backtrace[1]['class'].'::'.$backtrace[1]['function']);
00082 if ($previousCall != 'set::merge') {
00083 $r =& $this->value;
00084 array_unshift($args, null);
00085 }
00086 }
00087 if (!isset($r)) {
00088 $r = (array)current($args);
00089 }
00090
00091 while (($arg = next($args)) !== false) {
00092 if (is_a($arg, 'set')) {
00093 $arg = $arg->get();
00094 }
00095
00096 foreach ((array)$arg as $key => $val) {
00097 if (is_array($val) && isset($r[$key]) && is_array($r[$key])) {
00098 $r[$key] = Set::merge($r[$key], $val);
00099 } elseif (is_int($key)) {
00100 $r[] = $val;
00101 } else {
00102 $r[$key] = $val;
00103 }
00104 }
00105 }
00106 return $r;
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116 function filter($var, $isArray = false) {
00117 if (is_array($var) && (!empty($var) || $isArray)) {
00118 return array_filter($var, array('Set', 'filter'));
00119 } else {
00120 if ($var === 0 || $var === '0' || !empty($var)) {
00121 return true;
00122 } else {
00123 return false;
00124 }
00125 }
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135 function pushDiff($array = null, $array2 = null) {
00136 if ($array2 !== null && is_array($array2)) {
00137 foreach ($array2 as $key => $value) {
00138 if (!array_key_exists($key, $array)) {
00139 $array[$key] = $value;
00140 } else {
00141 if (is_array($value)) {
00142 $array[$key] = Set::pushDiff($array[$key], $array2[$key]);
00143 }
00144 }
00145 }
00146 return $array;
00147 }
00148
00149 if (!isset($this->value)) {
00150 $this->value = array();
00151 }
00152 $this->value = Set::pushDiff($this->value, Set::__array($array));
00153 return $this->value;
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 function map($class = 'stdClass', $tmp = 'stdClass') {
00165 if (is_array($class)) {
00166 $val = $class;
00167 $class = $tmp;
00168 } elseif (is_a($this, 'set')) {
00169 $val = $this->get();
00170 }
00171
00172 if (empty($val) || $val == null) {
00173 return null;
00174 }
00175 return Set::__map($val, $class);
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 function __array($array) {
00190 if ($array == null) {
00191 $array = $this->value;
00192 } elseif (is_object($array) && (is_a($array, 'set'))) {
00193 $array = $array->get();
00194 } elseif (is_object($array)) {
00195 $array = get_object_vars($array);
00196 } elseif (!is_array($array)) {
00197 $array = array($array);
00198 }
00199 return $array;
00200 }
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 function __map(&$array, $class, $primary = false) {
00217 if ($class === true) {
00218 $out = new stdClass;
00219 } else {
00220 $out = new $class;
00221 }
00222 if (is_array($array)) {
00223 $keys = array_keys($array);
00224 foreach ($array as $key => $value) {
00225 if($keys[0] === $key && $class !== true) {
00226 $primary = true;
00227 }
00228 if (is_numeric($key)) {
00229 if (is_object($out) && is_array($value)) {
00230 $out = get_object_vars($out);
00231 }
00232 $out[$key] = Set::__map($value, $class, true);
00233 } elseif ($primary === true && is_array($value)) {
00234 $out->_name_ = $key;
00235 $primary = false;
00236 foreach($value as $key2 => $value2) {
00237 $out->{$key2} = Set::__map($value2, $class);
00238 }
00239 } else {
00240 $out->{$key} = Set::__map($value, $class);
00241 }
00242 }
00243 } else {
00244 $out = $array;
00245 }
00246 return $out;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255 function numeric($array = null) {
00256 if ($array == null && (is_a($this, 'set') || is_a($this, 'Set'))) {
00257 $array = $this->get();
00258 }
00259
00260 $numeric = true;
00261 $keys = array_keys($array);
00262 $count = count($keys);
00263 for ($i = 0; $i < $count; $i++) {
00264 if (!is_numeric($array[$keys[$i]])) {
00265 $numeric = false;
00266 break;
00267 }
00268 }
00269 return $numeric;
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286 function enum($select, $list = null) {
00287 if (empty($list) && is_a($this, 'Set')) {
00288 $list = $this->get();
00289 } elseif (empty($list)) {
00290 $list = array('no', 'yes');
00291 }
00292
00293 $return = null;
00294 $list = Set::normalize($list, false);
00295
00296 if (array_key_exists($select, $list)) {
00297 $return = $list[$select];
00298 }
00299 return $return;
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 function format($data, $format, $keys) {
00311
00312 $extracted = array();
00313 $count = count($keys);
00314
00315 if (!$count) {
00316 return;
00317 }
00318
00319 for ($i = 0; $i < $count; $i++) {
00320 $extracted[] = Set::extract($data, $keys[$i]);
00321 }
00322 $out = array();
00323 $data = $extracted;
00324 $count = count($data[0]);
00325
00326 if (preg_match_all('/\{([0-9]+)\}/msi', $format, $keys2) && isset($keys2[1])) {
00327 $keys = $keys2[1];
00328 $format = preg_split('/\{([0-9]+)\}/msi', $format);
00329 $count2 = count($format);
00330
00331 for ($j = 0; $j < $count; $j++) {
00332 $formatted = '';
00333 for ($i = 0; $i <= $count2; $i++) {
00334 if (isset($format[$i])) {
00335 $formatted .= $format[$i];
00336 }
00337 if (isset($keys[$i]) && isset($data[$keys[$i]][$j])) {
00338 $formatted .= $data[$keys[$i]][$j];
00339 }
00340 }
00341 $out[] = $formatted;
00342 }
00343 } else {
00344 $count2 = count($data);
00345 for ($j = 0; $j < $count; $j++) {
00346 $args = array();
00347 for ($i = 0; $i < $count2; $i++) {
00348 if (isset($data[$i][$j])) {
00349 $args[] = $data[$i][$j];
00350 }
00351 }
00352 $out[] = vsprintf($format, $args);
00353 }
00354 }
00355 return $out;
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 function extract($data, $path = null) {
00367 if ($path === null && is_a($this, 'set')) {
00368 $path = $data;
00369 $data = $this->get();
00370 }
00371 if (is_object($data)) {
00372 $data = get_object_vars($data);
00373 }
00374
00375 if (!is_array($path)) {
00376 if (strpos($path, '/') !== 0 && strpos($path, './') === false) {
00377 $path = explode('.', $path);
00378 } else {
00379 }
00380 }
00381 $tmp = array();
00382 if (!is_array($path) || empty($path)) {
00383 return null;
00384 }
00385
00386 foreach ($path as $i => $key) {
00387 if (is_numeric($key) && intval($key) > 0 || $key == '0') {
00388 if (isset($data[intval($key)])) {
00389 $data = $data[intval($key)];
00390 } else {
00391 return null;
00392 }
00393 } elseif ($key == '{n}') {
00394 foreach ($data as $j => $val) {
00395 if (is_int($j)) {
00396 $tmpPath = array_slice($path, $i + 1);
00397 if (empty($tmpPath)) {
00398 $tmp[] = $val;
00399 } else {
00400 $tmp[] = Set::extract($val, $tmpPath);
00401 }
00402 }
00403 }
00404 return $tmp;
00405 } else {
00406 if (isset($data[$key])) {
00407 $data = $data[$key];
00408 } else {
00409 return null;
00410 }
00411 }
00412 }
00413 return $data;
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 function insert($list, $path, $data = null) {
00425 if (empty($data) && is_a($this, 'Set')) {
00426 $data = $path;
00427 $path = $list;
00428 $list =& $this->get();
00429 }
00430 if (!is_array($path)) {
00431 $path = explode('.', $path);
00432 }
00433 $_list =& $list;
00434
00435 foreach ($path as $i => $key) {
00436 if (is_numeric($key) && intval($key) > 0 || $key == '0') {
00437 $key = intval($key);
00438 }
00439 if ($i == count($path) - 1) {
00440 $_list[$key] = $data;
00441 } else {
00442 if (!isset($_list[$key])) {
00443 $_list[$key] = array();
00444 }
00445 $_list =& $_list[$key];
00446 }
00447 }
00448 return $list;
00449 }
00450
00451
00452
00453
00454
00455
00456
00457
00458 function remove($list, $path = null) {
00459 if (empty($path) && is_a($this, 'Set')) {
00460 $path = $list;
00461 $list =& $this->get();
00462 }
00463 if (!is_array($path)) {
00464 $path = explode('.', $path);
00465 }
00466 $_list =& $list;
00467
00468 foreach ($path as $i => $key) {
00469 if (is_numeric($key) && intval($key) > 0 || $key == '0') {
00470 $key = intval($key);
00471 }
00472 if ($i == count($path) - 1) {
00473 unset($_list[$key]);
00474 } else {
00475 if (!isset($_list[$key])) {
00476 return $list;
00477 }
00478 $_list =& $_list[$key];
00479 }
00480 }
00481
00482 if (is_a($this, 'Set')) {
00483 $this->value = $list;
00484 return $this;
00485 } else {
00486 return $list;
00487 }
00488 }
00489
00490
00491
00492
00493
00494
00495
00496
00497 function check($data, $path = null) {
00498 if (empty($path) && is_a($this, 'Set')) {
00499 $path = $data;
00500 $data = $this->get();
00501 }
00502 if (!is_array($path)) {
00503 $path = explode('.', $path);
00504 }
00505
00506 foreach ($path as $i => $key) {
00507 if (is_numeric($key) && intval($key) > 0 || $key == '0') {
00508 $key = intval($key);
00509 }
00510 if ($i == count($path) - 1) {
00511 return isset($data[$key]);
00512 } else {
00513 if (!isset($data[$key])) {
00514 return false;
00515 }
00516 $data =& $data[$key];
00517 }
00518 }
00519 return true;
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529 function diff($val1, $val2 = null) {
00530 if ($val2 == null && (is_a($this, 'set') || is_a($this, 'Set'))) {
00531 $val2 = $val1;
00532 $val1 = $this->get();
00533 }
00534
00535 if (is_object($val2) && (is_a($val2, 'set') || is_a($val2, 'Set'))) {
00536 $val2 = $val2->get();
00537 }
00538 $out = array();
00539
00540 if (empty($val1)) {
00541 return (array)$val2;
00542 } elseif (empty($val2)) {
00543 return (array)$val1;
00544 }
00545
00546 foreach ($val1 as $key => $val) {
00547 if (array_key_exists($key, $val2) && $val2[$key] != $val) {
00548 $out[$key] = $val;
00549 } elseif (!array_key_exists($key, $val2)) {
00550 $out[$key] = $val;
00551 }
00552 unset($val2[$key]);
00553 }
00554
00555 foreach ($val2 as $key => $val) {
00556 if (!array_key_exists($key, $out)) {
00557 $out[$key] = $val;
00558 }
00559 }
00560 return $out;
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570 function isEqual($val1, $val2 = null) {
00571 if ($val2 == null && (is_a($this, 'set') || is_a($this, 'Set'))) {
00572 $val2 = $val1;
00573 $val1 = $this->get();
00574 }
00575
00576 return ($val1 == $val2);
00577 }
00578
00579
00580
00581
00582
00583
00584
00585
00586 function contains($val1, $val2 = null) {
00587 if ($val2 == null && is_a($this, 'set')) {
00588 $val2 = $val1;
00589 $val1 = $this->get();
00590 } elseif ($val2 != null && is_object($val2) && is_a($val2, 'set')) {
00591 $val2 = $val2->get();
00592 }
00593
00594 foreach ($val2 as $key => $val) {
00595 if (is_numeric($key)) {
00596 if (!in_array($val, $val1)) {
00597 return false;
00598 }
00599 } else {
00600 if (!isset($val1[$key]) || $val1[$key] != $val) {
00601 return false;
00602 }
00603 }
00604 }
00605 return true;
00606 }
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617 function countDim($array = null, $all = false, $count = 0) {
00618 if ($array === null) {
00619 $array = $this->get();
00620 } elseif (is_object($array) && is_a($array, 'set')) {
00621 $array = $array->get();
00622 }
00623 if ($all) {
00624 $depth = array($count);
00625 if (is_array($array) && reset($array) !== false) {
00626 foreach ($array as $value) {
00627 $depth[] = Set::countDim($value, true, $count + 1);
00628 }
00629 }
00630 $return = max($depth);
00631 } else {
00632 if (is_array(reset($array))) {
00633 $return = Set::countDim(reset($array)) + 1;
00634 } else {
00635 $return = 1;
00636 }
00637 }
00638 return $return;
00639 }
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650 function normalize($list, $assoc = true, $sep = ',', $trim = true) {
00651 if (is_string($list)) {
00652 $list = explode($sep, $list);
00653 if ($trim) {
00654 $list = array_map('trim', $list);
00655 }
00656 if ($assoc) {
00657 return Set::normalize($list);
00658 }
00659 } elseif (is_array($list)) {
00660 $keys = array_keys($list);
00661 $count = count($keys);
00662 $numeric = true;
00663
00664 if (!$assoc) {
00665 for ($i = 0; $i < $count; $i++) {
00666 if (!is_int($keys[$i])) {
00667 $numeric = false;
00668 break;
00669 }
00670 }
00671 }
00672 if (!$numeric || $assoc) {
00673 $newList = array();
00674 for ($i = 0; $i < $count; $i++) {
00675 if (is_int($keys[$i])) {
00676 $newList[$list[$keys[$i]]] = null;
00677 } else {
00678 $newList[$keys[$i]] = $list[$keys[$i]];
00679 }
00680 }
00681 $list = $newList;
00682 }
00683 }
00684 return $list;
00685 }
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 function combine($data, $path1 = null, $path2 = null, $groupPath = null) {
00700 if (is_a($this, 'set') && is_string($data) && is_string($path1) && is_string($path2)) {
00701 $groupPath = $path2;
00702 $path2 = $path1;
00703 $path1 = $data;
00704 $data = $this->get();
00705
00706 } elseif (is_a($this, 'set') && is_string($data) && empty($path2)) {
00707 $path2 = $path1;
00708 $path1 = $data;
00709 $data = $this->get();
00710 }
00711
00712 if (is_object($data)) {
00713 $data = get_object_vars($data);
00714 }
00715
00716 if (is_array($path1)) {
00717 $format = array_shift($path1);
00718 $keys = Set::format($data, $format, $path1);
00719 } else {
00720 $keys = Set::extract($data, $path1);
00721 }
00722
00723 if (!empty($path2) && is_array($path2)) {
00724 $format = array_shift($path2);
00725 $vals = Set::format($data, $format, $path2);
00726
00727 } elseif (!empty($path2)) {
00728 $vals = Set::extract($data, $path2);
00729
00730 } else {
00731 $count = count($keys);
00732 for ($i = 0; $i < $count; $i++) {
00733 $vals[$i] = null;
00734 }
00735 }
00736
00737 if ($groupPath != null) {
00738 $group = Set::extract($data, $groupPath);
00739 if (!empty($group)) {
00740 $c = count($keys);
00741 for ($i = 0; $i < $c; $i++) {
00742 if (!isset($group[$i])) {
00743 $group[$i] = 0;
00744 }
00745 if (!isset($out[$group[$i]])) {
00746 $out[$group[$i]] = array();
00747 }
00748 $out[$group[$i]][$keys[$i]] = $vals[$i];
00749 }
00750 return $out;
00751 }
00752 }
00753
00754 return array_combine($keys, $vals);
00755 }
00756
00757
00758
00759
00760
00761
00762 function reverse($object) {
00763 if (is_a($object, 'xmlnode') || is_a($object, 'XMLNode')) {
00764 if ($object->name != Inflector::underscore($this->name)) {
00765 if (is_object($object->child(Inflector::underscore($this->name)))) {
00766 $object = $object->child(Inflector::underscore($this->name));
00767 $object = $object->attributes;
00768 } else {
00769 return null;
00770 }
00771 }
00772 } else {
00773 $out = array();
00774 if (is_object($object)) {
00775 $keys = get_object_vars($object);
00776 if (isset($keys['_name_'])) {
00777 $identity = $keys['_name_'];
00778 unset($keys['_name_']);
00779 }
00780 $new = array();
00781 foreach ($keys as $key => $value) {
00782 if (is_array($value)) {
00783 $new[$key] = (array)Set::reverse($value);
00784 } else {
00785 $new[$key] = Set::reverse($value);
00786 }
00787 }
00788 if (isset($identity)) {
00789 $out[$identity] = $new;
00790 } else {
00791 $out = $new;
00792 }
00793 } elseif (is_array($object)) {
00794 foreach ($object as $key => $value) {
00795 $out[$key] = Set::reverse($value);
00796 }
00797 } else {
00798 $out = $object;
00799 }
00800 return $out;
00801 }
00802 return $object;
00803 }
00804 }
00805 ?>