/** * Encode a Json while providing encoding functionnalities. * * Options may contain: * - *from_encoding* * /default to "UTF-8"/ * Encoding of the source array * - *to_encoding* * /default to "UTF-8"/ * Encoding of the returned string (JSON is serialize in UTF-8 and then encoded) * - *pretty* * /default to boolean "false"/ * Format a JSON string with carriage returns and tabulations * * @param array $array Array to encode * @param array $options[optional] Options used to alter the method behavior * * @return string Encoded JSON string */ public static function encode(array $array,array $options=array()){ if(!isset($options['from_encoding'])) $options['from_encoding'] = 'UTF-8'; if(!isset($options['to_encoding'])) $options['to_encoding'] = 'UTF-8'; if(strtoupper($options['from_encoding'])!='UTF-8') $array = PurArray::encode($array,'UTF-8',$options['from_encoding']); $array = json_encode($array); if(isset($options['pretty'])){ $array = PurJson::pretty($array); } if(strtoupper($options['to_encoding'])!='UTF-8') $array = mb_convert_encoding($array,$options['to_encoding'],'UTF-8'); return $array; }
/** * Options may include: * - *bare* Intialize a bare Git repository * - *bin* Path to the Git command * - *cwd* Directory or list of directories to initialize * * @param array $options required Must include the "cwd" setting. * @return true Return true on success, otherwise an exception is thrown * * @param string $cwd required Path to the directory to initialize * @param array $options optional All parameters are optional * @return true Return true on success, otherwise an exception is thrown */ public static function init(){ $args = func_get_args(); switch(count($args)){ case 1: if(is_string($args[0])){ $options = array( 'cwd' => array($args[0]=>true)); }else if(is_array($args[0])){ $options = PurArray::sanitize($args[0]); if(!isset($options['cwd'])){ throw new InvalidArgumentException('Options must include the "cwd" key'); }else if(is_string($options['cwd'])){ $options['cwd'] = array($options['cwd']=>true); }else if(!is_array($options['cwd'])){ throw new InvalidArgumentException('Invalid "cwd" option: "'.PurLang::toString($options['cwd']).'"'); } }else{ throw new InvalidArgumentException('Invalid Arguments: "'.PurLang::toString($args).'"'); } break; case 2: if(is_string($args[0])&&is_array($args[1])){ $options = PurArray::sanitize($args[1]); if(!isset($options[1]['cwd'])){ $options['cwd'] = array(); } $options['cwd'][$args[0]] = true; }else{ throw new InvalidArgumentException('Invalid Arguments: "'.PurLang::toString($args).'"'); } break; default: throw new InvalidArgumentException('Invalid Arguments Count: '.PurLang::toString($args)); } unset($args); if(empty($options['bin'])){ $options['bin'] = self::$bin; } while(list($cwd,) = each($options['cwd'])){ if(!is_string($cwd)){ throw new InvalidArgumentException('Invalid "cwd" option: "'.PurLang::toString($cwd).'"'); } $command = $options['bin']; $command .= ' init'; if(!empty($options['bare'])){ $command .= ' --bare'; } if(!is_dir($cwd)){ PurFile::mkdir($cwd); } PurCli::exec($command,array_merge($options,array('cwd'=>$cwd))); } return true; }
/** * Provide a readable string for any type of argument. * * The return value is formated with the type of the argument and * when possible a readable representation of the argument. * * Exemples: * * * PurLang::toString('my string'); // return string(my string); * * PurLang::toString(null); // return NULL; * * PurLang::toString(1); // return int(1); * * PurLang::toString(array('my_key','my value')); // return array(my_key=>string(my value)); * * @return * @param object $mixed */ public static function toString($mixed){ $type = gettype($mixed); switch($type){ case 'NULL': return 'NULL'; case 'object': $mixed = get_class($mixed); break; case 'array': $content = array(); $count = count($mixed); foreach($mixed as $k=>$v){ //if($count++>10) break; $content[] = $k. '=>'. (is_array($v)? 'array('.(PurArray::indexed($mixed)?'indexed':'associated').')': self::toString($v)); } $mixed = implode(',',$content); break; case 'boolean': $mixed = $mixed?'true':'false'; break; default: $mixed = strval($mixed); break; } return $type.'('.strval($mixed).')'; }
/** * Filter an array according to include and exclude filters. * * Possible options include: * - include: multidimentional array of keys to be included * - exclude: multidimentional array of keys to be excluded * - preserve_indexes: Wether indexes should be preserve or recomputed (default behavior) * * Include and exclude values may be a string (as a list of keys separated by commas) or * a multidimentional array. * * Exemple: multidimentional include * * assert( * array( * 'param_b'=>array( * 'param_b_2'=>2, * 'param_b_3'=>3 * ) * ), * PurArray::filter(array( * 'param_a'=>true, * 'param_b'=>array( * 'param_b_1'=>1, * 'param_b_2'=>2, * 'param_b_3'=>3 ), * 'param_c'=>'c', * ),array( * 'param_b'=>array( * 'param_b_2','param_b_3')))); * * Tip: Any value with a key different than "include", "exclude" or "preserve_indexes" * and present in the filters array is considered an "include" value, so as an exemple: * * * $options = array('my_param_1','include'=>'my_param_2','exclude'=>'my_param_3'); * * // is similar to * * $options = array('include'=>array('my_param_1','my_param_2'),'exclude'=>'my_param_3'); * * Note: this method is not yet coded with a non-recursive implementation. * * @return array Filtered array * @param $array Source array * @param $filters Filters and options array */ public static function filter(array $array,array $filters){ // Prepare options for config mode foreach($filters as $k=>$v){ if(is_int($k)){ unset($filters[$k]); $filters['include'][] = $v; }else{ switch($k){ case 'include': case 'exclude': case 'preserve_indexes': continue; default: unset($filters[$k]); $filters['include'][$k] = $v; } } } // Sanitize option "include" if(!empty($filters['include'])){ if(is_string($filters['include'])){ $filters['include'] = explode(',',$filters['include']); } if(is_array($filters['include'])){ $includeKeys = array(); foreach($filters['include'] as $key=>$value){ if(is_int($key)){ $includeKeys[$value] = true; }else if(is_array($value)){ $includeKeys[$key] = $value; } } }else{ $includeKeys = false; } }else{ $includeKeys = false; } // Sanitize option "exclude" if(!empty($filters['exclude'])){ if(is_string($filters['exclude'])){ $filters['exclude'] = explode(',',$filters['exclude']); } if(is_array($filters['exclude'])){ $excludeKeys = array(); foreach($filters['exclude'] as $key=>$value){ if(is_int($key)){ $excludeKeys[$value] = true; }else if(is_array($value)){ $excludeKeys[$key] = $value; } } }else{ $excludeKeys = false; } }else{ $excludeKeys = false; } foreach($array as $key=>$value){ if($excludeKeys && !empty($excludeKeys[$key]) && !is_array($excludeKeys[$key])){ unset($array[$key]); }else if($includeKeys && empty($includeKeys[$key])){ unset($array[$key]); }else if( ($includeKeys && isset($includeKeys[$key])&&is_array($includeKeys[$key])) || ($excludeKeys && isset($excludeKeys[$key])&&is_array($excludeKeys[$key])) ){ $mergedOptions = array(); if($includeKeys) $mergedOptions['include'] = $includeKeys[$key]; if($excludeKeys) $mergedOptions['exclude'] = $excludeKeys[$key]; $array[$key] = PurArray::filter($array[$key],array_merge($filters,$mergedOptions)); } } if(empty($filters['preserve_indexes'])){ $result = array(); foreach($array as $key=>$value){ if(is_int($key)){ $result[] = $value; }else{ $result[$key] = $value; } } return $result; }else{ return $array; } }
/** * Write a string to a file. If file does not exist, it will be created. If file exists, * its current content will be overwritten unless the "append" option is provided. Parent * directories will be created if they do not already exist. * * Exemples: * * * // Touching a file * * PurFile::write('/path/to/file.txt'); * * * // (Over)Write content to a file * * PurFile::write('/path/to/file.txt','my content'); * * * // Add or write (if new) content to a file * * PurFile::write('/path/to/file.txt','my content',array('append')); * * Options may include: * - permissions: chmod mask, apply only when the file is created, default to php 0644 * - append: boolean If true, new content will be appended to the destination file if it exists * * @return boolean true * @param mixed(string or resource) $path Target file path * @param string $content Content to write * @param object $options[optional] */ public static function write($path,$content='',$options=array()){ $options = PurArray::sanitize($options); switch(gettype($path)){ case 'string': if(!file_exists($path)){ $dir = dirname($path); PurFile::mkdir($dir); //if(!is_writable($dir)) throw new Exception('File Not Writable in Dir: '.$dir); $isNew = true; }else if(!is_writable($path)) throw new Exception('File Not Writable: '.$path); $resource = fopen($path,empty($options['append'])?'w':'a'); if(isset($isNew)&&isset($options['permissions'])){ chmod($path,$options['permissions']); } break; case 'resource': $resource = $path; break; default: throw new InvalidArgumentException('Path is expected to be a string or a resource'); } flock($resource,LOCK_EX); fwrite($resource,$content); flock($resource,LOCK_UN); fclose($resource); return true; }
/** * Convert a one level array with property like keys to a multidimensional array. * * Options may include: * - *source* * array * Source array to be enriched and returned. * - *separator* * string * Character use to split properties keys (default to "."). * - *from_encoding* * string, default to utf-8 * Source encoding. * - *to_encoding* * string, default to utf-8 * Destination encoding. * * @return array Multidimensional array * @param array $properties * @param array $options[optional] */ public static function propertiesToArray(array $properties,array $options=array()){ if(!is_array($properties)) throw new InvalidArgumentException('First parameter is not an array'); $return = isset($options['source'])?$options['source']:array(); $separator = isset($options['separator'])?$options['separator']:'.'; $fromEncoding = isset($options['from_encoding'])?$options['from_encoding']:'utf-8'; $toEncoding = isset($options['to_encoding'])?$options['to_encoding']:'utf-8'; while(list($key,$value) = each($properties)){ $steps = explode($separator,$key); $lastStep = array_pop($steps); $tempArray = &$return; while(list(,$step) = each($steps)){ if(!array_key_exists($step,$tempArray)){ $tempArray[$step] = array(); } $tempArray = &$tempArray[$step]; } switch(gettype($value)){ case 'array': if(isset($tempArray[$lastStep])){ //$tempArray[$lastStep] = $value; // print_r($tempArray[$lastStep]); // print_r($value); // print_r(PurArray::merge($tempArray[$lastStep],$value)); if(is_string($tempArray[$lastStep])){ //$tempArray[$lastStep] = array(); //unset($tempArray[$lastStep]); echo $lastStep."\n"; $tempArray[$lastStep] = $value; }else{ $tempArray[$lastStep] = PurArray::merge($tempArray[$lastStep],$value); } //$tempArray[$lastStep] = PurArray::merge($tempArray[$lastStep],$value); }else{ $tempArray[$lastStep] = $value; } break; case 'string': if($fromEncoding!=$toEncoding){ $tempArray[$lastStep] = mb_convert_encoding($value,$toEncoding,$fromEncoding); }else{ $tempArray[$lastStep] = $value; } break; default: $tempArray[$lastStep] = $value; break; } } return $return; }