Functions

Useful little functions I use all the time.

Text-fixing and adjusting functions

Create a proper proper-noun name. DAVE -> Dave | dave -> Dave | deVille -> deVille | McDave -> McDave

function fix_name($name)
{
	if (strtoupper($name) == $name) return ucwords(strtolower($name)); // Is all caps, so make it lowercase and uc the first letter of every word.
	elseif (strtolower($name) == $name) return ucwords($name); // Has no caps, so uc the first letter of every word.
	else return $name; // Has _some_ caps, so we respect the input.
}

Fix and remove invalid characters from a filename.

// Create Unix-style filename.
function fix_filename($name)
{
	return preg_replace(array('/[^a-z0-9_\-]/', '/ /'), array('', '_'),  strtolower($name));
}

Fix and remove invalid characters from an email address.

function fix_email($email)
{
	return preg_replace('/[^a-z0-9_\-\.@]/', '', strtolower(substr($email, 0, 50)));
}

Fix and remove invalid characters from a domain name.

function fix_domain($domain)
{
	$domain = strtolower(substr($domain, 0, 50));
	if (substr($domain, 0, 7) == 'http://') $domain = substr($domain, 7); // Remove http from the start.
	$domain = preg_replace('/[^a-z0-9\-\.\/]/', '', $domain);

	$bits = explode('/', $domain);
	$domain = $bits[0]; // Only take before the first slash.

	return $domain;
}

Remove invalid characters and spaces from a phone number.

function fix_phone($phone)
{
	// No spaces. Numbers and pluses only.
	return preg_replace('/[^0-9\+]/', '', substr($phone, 0, 16));
}

Add ordinals to numbers (1 -> 1st | 2 -> 2nd | 3 -> 3rd).

function ordinal($num)
{
    // Special case "teenth"
    if ( ($num / 10) % 10 != 1 )
    {
        // Handle 1st, 2nd, 3rd
        switch( $num % 10 )
        {
            case 1: return $num . 'st';
            case 2: return $num . 'nd';
            case 3: return $num . 'rd';
        }
    }
    // Everything else is "nth"
    return $num . 'th';
}

Output functions

Transform plain text into HTML by turning each line into a paragraph.

function text_to_html($text)
{
	$lines = preg_split('(\\r\\n|\\n\\r|\\r|\\n)', $text, -1, PREG_SPLIT_NO_EMPTY);
	foreach ($lines as $line) $html .= '<p>' . $line . '</p>' . EOL;
	return $html;
}

Scan text for URLs and change them into links.

function urls_to_links($text)
{
	$pattern = '(http\://[a-zA-Z0-9_\+%\.\-\/\?\&\=%]*)';
	$replacement = '<a href="$0" rel="external">$0</a>';
	return preg_replace($pattern, $replacement, $text);
}

Validity functions

Check an email address by checking for existance of MX records for the domain.

function valid_email($email)
{
	if (empty($email) || !strpos($email, '@')) return false;

	list($username, $domain) = split('@', $email);
	if (checkdnsrr($domain, 'MX')) return true;
	else return false;
}

Date and time functions

Show spread of two dates without repeating month or year if they are unnecessary, such as '1–3 March 2003' or '18 July – 12 April 2007'.

function date_spread($start_date, $end_date)
{
	$start_day = date('j', $start_date);
	$end_day = date('j', $end_date);

	$start_month = ' ' . date('F', $start_date);
	$end_month = ' ' . date('F', $end_date);

	$start_year = ' ' . date('Y', $start_date);
	$end_year = ' ' . date('Y', $end_date);

	if ($start_year == $end_year)
	{
		if ($start_month == $end_month)
		{
			$start_month = '';
			$start_year = '–';
		}
		else $start_year = ' – ';
	}

	return $start_day . $start_month . $start_year . $end_day . $end_month . $end_year;
}

Show a date in plain English, such as '3 years ago', 'in five minutes' or 'yesterday'. Answers the questions 'When is it?' or 'When was it?'

function rough_date($target_date, $start_date = false)
{
	if (!$start_date) $start_date = time();

	if ($start_date < $target_date)
	{
		$future = true;
		$pre = 'in ';
		$dif = $target_date - $start_date;
	}
	else
	{
		$post = ' ago';
		$dif = $start_date - $target_date;
	}

	if ($dif > 46656000) // 18 months
	{
		$num = round($dif / 31536000);
		$type = 'year';
	}
	elseif ($dif > 5184000) // Two months.
	{
		$num = round($dif / 2592000);
		$type = 'month';
	}
	elseif ($dif > 1209600) // Two weeks.
	{
		$num = round($dif / 604800);
		$type = 'week';
	}
	elseif ($dif > 86400) // One day.
	{
		$num = round($dif / 86400);
		$type = 'day';
	}
	else
	{
		if (date('Ynd', $target_date) == date('Ynd', $start_date)) return 'today';
		elseif ($future) return 'tomorrow';
		else return 'yesterday';
	}

	if ($num == 1) return $pre . '1 ' . $type . $post;
	else return $pre . $num . ' ' . $type . 's' . $post;
}

Show time between two dates, such as '4 days', '30 minutes' or '5 hours', etc. Answers the question 'How long does it last?'

function rough_time($target_date, $start_date = false)
{
	if (!$target_date) $start_date = time();

	if ($start_date < $target_date)
	{
		$future = true;
		$dif = $target_date - $start_date;
	}
	else $dif = $start_date - $target_date;

	if ($dif > 46656000) // 18 months
	{
		$num = round($dif / 31536000);
		$type = 'year';
	}
	elseif ($dif > 5184000) // Two months.
	{
		$num = round($dif / 2592000);
		$type = 'month';
	}
	elseif ($dif > 1209600) // Two weeks.
	{
		$num = round($dif / 604800);
		$type = 'week';
	}
	elseif ($dif > 172800) // One day.
	{
		$num = round($dif / 86400);
		$type = 'day';
	}
	elseif ($dif > 3559)
	{
		$num = round($dif / 3600);
		$type = 'hour';
	}
	elseif ($dif > 90)
	{
		$num = round($dif / 60);
		$type = 'minute';
	}
	else
	{
		$num = $dif;
		$type = 'second';
	}

	if ($num == 1) return '1 ' . $type . $post;
	else return $num . ' ' . $type . 's' . $post;
}

Return Unix timestamp for midnight of a given day.

function midnight($ts = false)
{
	if (!$ts) $ts = time();
	$now = explode('-', date('j-n-Y', $ts));
	return mktime(0, 0, 0, $now[1], $now[0], $now[2]);
}

Return Unix timestamp for the first day in a given month.

//
function first_day($ts = false)
{
	if (!$ts) $ts = time();
	$now = explode('-', date('n-Y', $ts));
	return mktime(0, 0, 0, $now[0], 1, $now[1]);
}

Return Unix timestamp for the last day in a given month.

function last_day($ts = false)
{
	if (!$ts) $ts = time();
	$now = explode('-', date('n-Y-t', $ts));
	return mktime(0, 0, 0, $now[0], $now[2], $now[1]);
}

Other functions

Send a redirect header and exit

function redirect($redirect)
{
	header('Location: ' . $redirect);
	exit('<a href="' . $redirect . '">' . $redirect . '</a>');
}

Turn a two-dimensional array into equivalent XML.

function array_to_xml($array, $num_tabs = 0)
{
	if ($num_tabs) $tabs = str_repeat("\t", $num_tabs);

	if (is_array($array)) foreach ($array as $name => $value)
	{
		if (is_array($value)) $return .= $tabs . '<' . $name . '>' . EOL . array_to_xml($value, $num_tabs + 1) . $tabs . '</' . $name . '>' . EOL;
		else $return .= $tabs . '<' . $name . '>' . $value . '</' . $name . '>' . EOL;
	}
	return $return;
}

Turn an array into a string.

// Array to string.
function a2s($array, $tabs = false)
{
	if (is_array($array))
	{
		foreach ($array as $key => $value)
		{
			if (is_array($value))
			{
				$string .= $tabs . "'" . $key . "' => array(" . EOL . a2s($value, $tabs . "\t") . $tabs . ")," . EOL;
			}
			elseif (is_numeric($value)) $string .= $tabs . "'" . $key . "' => " . $value . "," . EOL;
			elseif ($value === true) $string .= $tabs . "'" . $key . "' => true," . EOL;
			elseif ($value === false) $string .= $tabs . "'" . $key . "' => false," . EOL;
			else $string .= $tabs . "'" . $key . "' => '" . $value . "'," . EOL;
		}
		return $string;
	}
	else return $array . ' (not an array)';
}

Echo an array. Like print_r() but formatted better inside a <pre>.

function e_a2s($array)
{
	echo '<pre>' . EOL;
	echo a2s($array);
	echo '</pre>' . EOL;
}