]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/utils/array_utils.php
Release 6.5.0
[Github/sugarcrm.git] / include / utils / array_utils.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM Community Edition is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38
39
40 //to_string methods to get strings for values
41
42  // var_export gets rid of the empty values that we use to display None
43  // thishelper function fixes that
44  // *This is no longer the case in php 5. var_export will now preserve empty keys.
45 function var_export_helper($tempArray) {
46                 return var_export($tempArray, true);
47         }
48
49
50
51 /*
52  * this function is used to overide a value in an array and returns the string code to write
53  * @params : $array_name - a String containing the name of an array.
54  * @params : $value_name - a String containing the name of a variable in the array.
55  * @params : $value      - a String containing the associated value with $value_name.
56  * 
57  * @returns: String. Example - override_value_to_string($name, 'b', 1) = '$name['b'] = 1;'
58  */
59
60 function override_value_to_string($array_name, $value_name, $value){
61         $string = "\${$array_name}[". var_export($value_name, true). "] = ";
62         $string .= var_export_helper($value,true);
63         return $string . ";";
64 }
65
66 function add_blank_option($options){
67         if(is_array($options)) {
68                 if(!isset($options['']) && !isset($options['0'])) {
69                 $options = array_merge(array(''=>''), $options);
70                 }
71         } else {
72                 $options = array(''=>'');
73         }
74         return $options;
75 }
76
77 /*
78  * Given an array and key names, return a string in the form of $array_name[$key_name[0]][$key_name[1]]... = $value recursively.
79  * @params : $key_names - array of keys
80  *                       $array_name- name of the array
81  *                       $value -value of the array
82  *                       $eval - evals the generated string if true, note that the array name must be in the global space!
83  * @return : example - string $array_name['a']['b']['c'][.] = 'hello'
84  */
85 function override_value_to_string_recursive($key_names, $array_name, $value, $eval=false){
86         if ($eval) return eval( "\${$array_name}". override_recursive_helper($key_names, $array_name, $value));
87         else return "\${$array_name}". override_recursive_helper($key_names, $array_name, $value);
88 }
89
90 function override_recursive_helper($key_names, $array_name, $value){
91         if( empty( $key_names ) )
92                 return "=".var_export_helper($value,true).";";
93         else{
94                 $key = array_shift($key_names);
95                 return "[".var_export($key,true)."]". override_recursive_helper($key_names, $array_name,$value);
96         }
97 }
98
99 function override_value_to_string_recursive2($array_name, $value_name, $value, $save_empty = true) {
100         if (is_array($value)) {
101                 $str = '';
102                 $newArrayName = $array_name . "['$value_name']";
103                 foreach($value as $key=>$val) {
104                         $str.= override_value_to_string_recursive2($newArrayName, $key, $val, $save_empty);
105                 }
106                 return $str;
107         } else {
108                 if(!$save_empty && empty($value)){
109                         return;
110                 }else{
111                         return "\$$array_name" . "['$value_name'] = " . var_export($value, true) . ";\n";
112                 }
113         }
114 }
115
116 /**
117  * This function will attempt to convert an object to an array.
118  * Loops are not checked for so this function should be used with caution.
119  * 
120  * @param $obj
121  * @return array representation of $obj
122  */
123 function object_to_array_recursive($obj)
124 {
125         if (!is_object($obj))
126            return $obj;
127
128         $ret = get_object_vars($obj);
129         foreach($ret as $key => $val)
130         {
131                 if (is_object($val)) {
132                         $ret[$key] = object_to_array_recursive($val);
133                 }
134                 
135         }
136         return $ret;
137 }
138 /**
139          * This function returns an array of all the key=>value pairs in $array1 
140          * that are wither not present, or different in $array2.
141          * If a key exists in $array2 but not $array1, it will not be reported.
142          * Values which are arrays are traced further and reported only if thier is a difference
143          * in one or more of thier children.
144          * 
145          * @param array $array1, the array which contains all the key=>values you wish to check againts
146          * @param array $array2, the array which 
147          * @param array $allowEmpty, will return the value if it is empty in $array1 and not in $array2,
148          * otherwise empty values in $array1 are ignored.
149          * @return array containing the differences between the two arrays
150          */
151         function deepArrayDiff($array1, $array2, $allowEmpty = false) {
152                 $diff = array();
153                 foreach($array1 as $key=>$value) {
154                         if (is_array($value)) {
155                                 if ((!isset($array2[$key]) || !is_array($array2[$key])) && (isset($value) || $allowEmpty)) {
156                                         $diff[$key] = $value;
157                                 } else {
158                                         $value = deepArrayDiff($array1[$key], $array2[$key], $allowEmpty);
159                                         if (!empty($value) || $allowEmpty)
160                                                 $diff[$key] = $value;
161                                 }
162                         } else if ((!isset($array2[$key]) || $value != $array2[$key]) && (isset($value) || $allowEmpty)){
163                                 $diff[$key] = $value;
164                         }
165                 }
166                 return $diff;
167         }
168         
169         /**
170          * Recursivly set a value in an array, creating sub arrays as necessary
171          *
172          * @param unknown_type $array
173          * @param unknown_type $key
174          */
175         function setDeepArrayValue(&$array, $key, $value) {
176                 //if _ is at position zero, that is invalid.
177                 if (strrpos($key, "_")) {
178                 list ($key, $remkey) = explode('_', $key, 2);
179                         if (!isset($array[$key]) || !is_array($array[$key])) {
180                                 $array[$key] = array();
181                         }
182                         setDeepArrayValue($array[$key], $remkey, $value);
183                 }
184                 else {
185                         $array[$key] = $value;
186                 }
187         }
188
189
190 // This function iterates through the given arrays and combines the values of each key, to form one array
191 // Returns FALSE if number of elements in the arrays do not match; otherwise, returns merged array
192 // Example: array("a", "b", "c") and array("x", "y", "z") are passed in; array("ax", "by", "cz") is returned
193 function array_merge_values($arr1, $arr2) {
194         if (count($arr1) != count($arr2)) {
195                 return FALSE;
196         }
197
198         for ($i = 0; $i < count($arr1); $i++) {
199                 $arr1[$i] .= $arr2[$i];
200         }
201
202         return $arr1;
203 }
204
205 /**
206  * Search an array for a given value ignorning case sensitivity
207  *
208  * @param unknown_type $key
209  * @param unknown_type $haystack
210  */
211 function array_search_insensitive($key, $haystack)
212 {
213     if(!is_array($haystack))
214         return FALSE;
215
216     $found = FALSE;
217     foreach($haystack as $k => $v)
218     {
219         if(strtolower($v) == strtolower($key))
220         {
221             $found = TRUE;
222             break;
223         }
224     }
225
226     return $found;
227 }
228
229 /**
230  * Wrapper around PHP's ArrayObject class that provides dot-notation recursive searching
231  * for multi-dimensional arrays
232  */
233 class SugarArray extends ArrayObject
234 {
235     /**
236      * Return the value matching $key if exists, otherwise $default value
237      *
238      * This method uses dot notation to look through multi-dimensional arrays
239      *
240      * @param string $key key to look up
241      * @param mixed $default value to return if $key does not exist
242      * @return mixed
243      */
244     public function get($key, $default = null) {
245         return $this->_getFromSource($key, $default);
246     }
247
248     /**
249      * Provided as a convinience method for fetching a value within an existing
250      * array without instantiating a SugarArray
251      *
252      * NOTE: This should only used where refactoring an array into a SugarArray
253      *       is unfeasible.  This operation is more expensive than a direct
254      *       SugarArray as each time it creates and throws away a new instance
255      *
256      * @param array $haystack haystack
257      * @param string $needle needle
258      * @param mixed $default default value to return
259      * @return mixed
260      */
261     static public function staticGet($haystack, $needle, $default = null) {
262         if (empty($haystack)) {
263             return $default;
264         }
265         $array = new self($haystack);
266         return $array->get($needle, $default);
267     }
268
269     private function _getFromSource($key, $default) {
270         if (strpos($key, '.') === false) {
271             return isset($this[$key]) ? $this[$key] : $default;
272         }
273
274         $exploded = explode('.', $key);
275         $current_key = array_shift($exploded);
276         return $this->_getRecursive($this->_getFromSource($current_key, $default), $exploded, $default);
277     }
278
279     private function _getRecursive($raw_config, $children, $default) {
280         if ($raw_config === $default) {
281             return $default;
282         } elseif (count($children) == 0) {
283             return $raw_config;
284         } else {
285             $next_key = array_shift($children);
286             return isset($raw_config[$next_key]) ?
287                 $this->_getRecursive($raw_config[$next_key], $children, $default) :
288                 $default;
289         }
290     }
291 }
292
293 ?>