Skip to content

Instantly share code, notes, and snippets.

@asvae
Last active August 29, 2015 14:17
Show Gist options
  • Save asvae/9e71b0894649b5940f47 to your computer and use it in GitHub Desktop.
Save asvae/9e71b0894649b5940f47 to your computer and use it in GitHub Desktop.
Readable HTML from array and pattern (mergeWithPattern)
class sf
{
/**
* Make readable text|html from array
*
* Example:
* $data = [1,2,3];
* $pattern = ['(',', ',')'];
* sf::mergeWithPattern($data, $pattern)
* // '(1, 2, 3)'
*
* @param array|string $data Data to wrap
* @param array|string $pattern Wrapper pattern
*
* @return string
*/
public static function mergeWithPattern($data = [], $pattern = [])
{
// Find depth
// 0: empty, 1: string, 2: array, 3: 2-D array etc.
$data_depth = sf::arrayDepth($data);
$pattern_depth = sf::arrayDepth($pattern);
//$v = print_r($pattern, true);
//echo ('Data: '.$data_depth.'/'.$pattern_depth.'; "'.$v.'"";');
switch ($data_depth)
{
case 0: // empty: ''
case 1: // string
switch ($pattern_depth) {
case 0:
case 1:
return $data;
case 2:
if (count($pattern) > 1)
return $pattern[0].$data.end($pattern);
else
return $data;
default:
foreach ($pattern as $pat)
$data = sf::mergeWithPattern($data, $pat);
return $data;
}
case 2: // array
switch ($pattern_depth) {
case 0:
case 1:
if (count($data) > 1) {
$data = implode($data, $pattern);
}
return $data;
case 2:
$end = count($pattern) - 1;
// If $pattern is one element array
if ($end === 0) {
return (implode($data, $pattern[0]));
}
// Complex wrap if two or more elements
$counter = 1;
foreach ($data as $i => &$piece)
{
// First element
if ($i === 0) {
$piece = $pattern[0] . $piece;
}
// Last element
if ($i === count($data) - 1) {
$piece = $piece . $pattern[$end];
} else {
// Skip middle if no middle
if ($end === 1) {
continue;
}
// Middle elements
$piece = $piece . $pattern[$counter];
// If there is several middle elements in the pattern
// we go through all af them,
// then we repeat next-to-last element
if ($counter < count($pattern) - 2) {
$counter++;
}
}
}
return implode($data);
default:
$first_pattern = array_shift($pattern);
foreach ($data as $i => &$piece) {
$piece = sf::mergeWithPattern($piece, $first_pattern);
}
foreach ($pattern as $pat)
$data = sf::mergeWithPattern($data, $pat);
return($data);
}
case 3:
switch ($pattern_depth)
{
case 0:
case 1:
case 2:
foreach ($data as &$piece)
$piece = sf::mergeWithPattern($piece, $pattern);
return implode($data);
case 3:
$first_pattern = array_shift($pattern);
foreach ($data as &$piece)
$piece = sf::mergeWithPattern($piece, $first_pattern);
foreach ($pattern as $pat)
$data = sf::mergeWithPattern($data, $pat);
return $data;
default:
$first_pattern = array_shift($pattern);
if (count ($first_pattern) === 1)
foreach ($data as &$piece)
$piece = sf::mergeWithPattern($piece, $first_pattern);
else
foreach ($data as $i => &$piece)
{
if ($i <= count ($first_pattern) - 1)
$piece = sf::mergeWithPattern($piece, $first_pattern[$i]);
else
$piece = sf::mergeWithPattern($piece, end($first_pattern));
}
foreach ($pattern as $pat)
$data = sf::mergeWithPattern($data, $pat);
return $data;
}
default:
if (count ($pattern) > 1)
$first_pattern = array_pop($pattern);
foreach ($data as $i => &$piece)
$piece = sf::mergeWithPattern($piece, $pattern);
$data = sf::mergeWithPattern($data, $first_pattern);
return $data;
}
}
/**
* Finds array depth, returns 0 if not array
*
* @param array|string $data
* @return int
*/
public static function arrayDepth(&$data = '')
{
if (!$data){
$data = '';
return 0;
}
if (! is_array($data))
return 1;
$max_indentation = 1;
$array_str = print_r($data, true);
$lines = explode("\n", $array_str);
foreach ($lines as $line)
{
$indentation = (strlen($line) - strlen(ltrim($line))) / 4;
if ($indentation > $max_indentation)
{
$max_indentation = $indentation;
}
}
//echo (ceil(($max_indentation - 1) / 2) + 1);
return ceil(($max_indentation - 1) / 2) + 2;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment