<?php defined('C5_EXECUTE') or die("Access Denied.");

/**
 * Helpful functions for working with Arrays. Includes recursive fetching
 * @author Christiaan Baartse <anotherhero@gmail.com>
 * @copyright  Copyright (c) 2011 Concrete5. (http://www.concrete5.org)
 * @license    http://www.concrete5.org/license/     MIT License
 */
class Concrete5_Helper_Array {

	/**
	 * Fetches a value from an (multidimensional) array
	 * @param array $array
	 * @param string|int|array $keys Either one key or multiple keys
	 * @param mixedvar $default the value that is returned if key is not found
	 */
	public function get(array $array, $keys, $default = null)
	{
		$keys = $this->parseKeys($keys);
		
		if (is_array($array) && $keys) {
			$key = array_shift($keys);
			if (array_key_exists($key, $array)) {
				$value = $array[$key];
				if (!$keys) {
					return $value;
				}
				
				if (is_array($value)) {
					return $this->get($value, $keys, $default);
				}
			}
		}
		return $default;
	}
	
	/**
	 * Sets a value in an (multidimensional) array, creating the arrays recursivly
	 * @param array $array
	 * @param unknown_type $keys
	 * @param unknown_type $value
	 */
	public function set(array $array, $keys, $value)
	{
		$keys = $this->parseKeys($keys);
		
		if ($keys) {
			$key = array_shift($keys);
			
			// This is the last key we've shifted
			if (!$keys) {
				$array[$key] = $value;
			} else {
				// There are more keys so this should be an array
				if (!isset($array[$key]) || !is_array($array[$key])) {
					$array[$key] = array();
				}
				$array[$key] = $this->set(
					$array[$key], $keys, $value
				);
			}
		}
		return $array;
	}
	
	/**
	 * Turns the string keys into an array of keys
	 * @param string|array $keys
	 * @return array
	 */
	private function parseKeys($keys)
	{
		if (is_string($keys)) {
			if (strpos($keys, '[') !== false) {
				$keys = str_replace(']', '', $keys);
				$keys = explode('[', trim($keys, '['));
			} else {
				$keys = (array) $keys;
			}
		}
		return $keys;
	}

	/**
	 * Takes a multidimensional array and flattens it
	 * @param array $array
	 * @return array
	 */	
	public function flatten(array $array) { 
		$tmp = array();
		foreach($array as $a) { 
			if(is_array($a)) { 
				$tmp = array_merge($tmp, array_flat($a)); 
			} else { 
				$tmp[] = $a; 
			} 
		} 
		return $tmp; 
	} 
}
