<?php
class Recipe {
/**
* Get a Website favicon image.
*
* @param string $url website url
* @param array $attributes Optional, additional key/value attributes to include in the IMG tag
*
* @return string containing complete image tag
*/
public static function getFavicon($url, $attributes = []) {
$attr = trim(self::arrayToString($attributes));
if (!empty($attr)) {
$attr = " $attr";
}
return sprintf(
"<img src=\"https://www.google.com/s2/favicons?domain=%s\"%s/>", urlencode($url), $attr
);
}
/**
* Get a QR code.
*
* @param string $string String to generate QR code for.
* @param int $width QR code width
* @param int $height QR code height
* @param array $attributes Optional, additional key/value attributes to include in the IMG tag
*
* @return string containing complete image tag
*/
public static function getQRcode($string, $width = 150, $height = 150, $attributes = []) {
$protocol = 'http://';
if (self::isHttps()) {
$protocol = 'https://';
}
$attr = trim(self::arrayToString($attributes));
$apiUrl = $protocol . 'chart.apis.google.com/chart?chs=' . $width . 'x' . $height . '&cht=qr&chl=' . urlencode($string);
return '<img src="' . $apiUrl . '" ' . $attr . ' />';
}
/**
* Get file extension.
*
* @param string $filename File path
*
* @return string file extension
*/
public static function getFileExtension($filename) {
return pathinfo($filename, PATHINFO_EXTENSION);
}
/**
* Get a Gravatar for email.
*
* @param string $email The email address
* @param int $size Size in pixels, defaults to 80 (in px), available values from 1 to 2048
* @param string $default Default imageset to use, available values: 404, mm, identicon, monsterid, wavatar
* @param string $rating Maximum rating (inclusive), available values: g, pg, r, x
* @param array $attributes Optional, additional key/value attributes to include in the IMG tag
*
* @return string containing complete image tag
*/
public static function getGravatar($email, $size = 80, $default = 'mm', $rating = 'g', $attributes = []) {
$attr = trim(self::arrayToString($attributes));
$url = 'https://www.gravatar.com/';
return sprintf(
"<img src=\"%savatar.php?gravatar_id=%s&default=%s&size=%s&rating=%s\" width=\"%spx\" height=\"%spx\" %s />", $url, md5(strtolower(trim($email))), $default, $size, $rating, $size, $size, $attr
);
}
/**
* Create HTML A Tag.
*
* @param string $link URL or Email address
* @param string $text Optional, If link text is empty, $link variable value will be used by default
* @param array $attributes Optional, additional key/value attributes to include in the IMG tag
*
* @return string containing complete a tag
*/
public static function createLinkTag($link, $text = '', $attributes = []) {
$linkTag = '<a href="' . $link . '"';
if (self::validateEmail($link)) {
$linkTag = '<a href="mailto:' . $link . '"';
}
if (!isset($attributes['title']) && !empty($text)) {
$linkTag .= ' title="' . str_replace('"', '', strip_tags($text)) . '" ';
}
if (empty($text)) {
$text = $link;
}
$attr = trim(self::arrayToString($attributes));
$linkTag .= $attr . '>' . htmlspecialchars($text, ENT_QUOTES, 'UTF-8') . '</a>';
return $linkTag;
}
/**
* Validate Email address.
*
* @param string $address Email address to validate
* @param bool $tempEmailAllowed Allow Temporary email addresses?
*
* @return bool True if email address is valid, false is returned otherwise
*/
public static function validateEmail($address, $tempEmailAllowed = true) {
strpos($address, '@') ? list(, $mailDomain) = explode('@', $address) : $mailDomain = null;
if (filter_var($address, FILTER_VALIDATE_EMAIL) &&
!is_null($mailDomain) &&
checkdnsrr($mailDomain, 'MX')
) {
if ($tempEmailAllowed) {
return true;
} else {
$handle = fopen(__DIR__ . '/banned.txt', 'r');
$temp = [];
while (($line = fgets($handle)) !== false) {
$temp[] = trim($line);
}
if (in_array($mailDomain, $temp)) {
return false;
}
return true;
}
}
return false;
}
/**
* Validate URL.
*
* @param string $url Website URL
*
* @return bool True if URL is valid, false is returned otherwise
*/
public static function validateURL($url) {
return (bool) filter_var($url, FILTER_VALIDATE_URL);
}
/**
* Read RSS feed as array.
* requires simplexml.
*
* @see http://php.net/manual/en/simplexml.installation.php
*
* @param string $url RSS feed URL
*
* @return array Representation of XML feed
*/
public static function rssReader($url) {
if (strpos($url, 'http') !== 0) {
$url = 'http://' . $url;
}
$feed = self::curl($url);
$xml = simplexml_load_string($feed, 'SimpleXMLElement', LIBXML_NOCDATA);
return self::objectToArray($xml);
}
/**
* Convert object to the array.
*
* @param object $object PHP object
* @return array
* @throws \Exception
*/
public static function objectToArray($object) {
if (is_object($object)) {
return (array) $object;
} else {
throw new \Exception("Not an object");
}
}
/**
* Convert array to the object.
*
* @param array $array PHP array
* @return object
* @throws \Exception
*/
public static function arrayToObject(array $array = []) {
if (!is_array($array)) {
throw new \Exception("Not an array");
}
$object = new \stdClass();
if (is_array($array) && count($array) > 0) {
foreach ($array as $name => $value) {
if (is_array($value)) {
$object->{$name} = self::arrayToObject($value);
} else {
$object->{$name} = $value;
}
}
return $object;
}
}
/**
* Convert Array to string.
*
* @param array $array array to convert to string
* @return string <key1>="value1" <key2>="value2"
* @throws \Exception
*/
public static function arrayToString(array $array = array()) {
$pairs = array();
foreach ($array as $key => $value) {
$pairs[] = "$key=\"$value\"";
}
return implode(' ', $pairs);
}
/**
* Takes HEX color code value and converts to a RGB value.
*
* @param string $color Color hex value, example: #000000, #000 or 000000, 000
*
* @return string color rbd value
*/
public static function hex2rgb($color) {
$color = str_replace('#', '', $color);
$hex = strlen($color) == 3 ? [$color[0] . $color[0], $color[1] . $color[1], $color[2] . $color[2]] : [$color[0] . $color[1], $color[2] . $color[3], $color[4] . $color[5]];
list($r, $g, $b) = $hex;
return sprintf(
"rgb(%s, %s, %s)", hexdec($r), hexdec($g), hexdec($b)
);
}
/**
* Takes RGB color value and converts to a HEX color code
* Could be used as Recipe::rgb2hex("rgb(0,0,0)") or Recipe::rgb2hex(0,0,0).
*
* @param mixed $r Full rgb,rgba string or red color segment
* @param mixed $g null or green color segment
* @param mixed $b null or blue color segment
*
* @return string hex color value
*/
public static function rgb2hex($r, $g = null, $b = null) {
if (strpos($r, 'rgb') !== false || strpos($r, 'rgba') !== false) {
if (preg_match_all('/\(([^\)]*)\)/', $r, $matches) && isset($matches[1][0])) {
list($r, $g, $b) = explode(',', $matches[1][0]);
} else {
return false;
}
}
$result = '';
foreach ([$r, $g, $b] as $c) {
$hex = base_convert($c, 10, 16);
$result .= ($c < 16) ? ('0' . $hex) : $hex;
}
return '#' . $result;
}
/**
* Generate Simple Random Password.
*
* @param int $length length of generated password, default 8
*
* @return string Generated Password
*/
public static function generateRandomPassword($length = 8) {
$pass = [];
$alphabet = 'abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789';
$alphaLength = strlen($alphabet) - 1;
for ($i = 0; $i < $length; ++$i) {
$n = rand(0, $alphaLength);
$pass[] = $alphabet[$n];
}
return implode($pass);
}
/**
* Simple Encode string.
*
* @param string $string String you would like to encode
* @param string $passkey salt for encoding
*
* @return string
*/
public static function simpleEncode($string, $passkey = null) {
$key = $passkey;
if (!isset($passkey) || empty($passkey)) {
$key = self::generateServerSpecificHash();
}
$result = '';
for ($i = 0; $i < strlen($string); $i++) {
$char = substr($string, $i, 1);
$keychar = substr($key, ($i % strlen($key)) - 1, 1);
$char = chr(ord($char) + ord($keychar));
$result .= $char;
}
return base64_encode($result);
}
/**
* Simple Decode string.
*
* @param string $string String encoded via Recipe::simpleEncode()
* @param string $passkey salt for encoding
*
* @return string
*/
public static function simpleDecode($string, $passkey = null) {
$key = $passkey;
if (!isset($passkey) || empty($passkey)) {
$key = self::generateServerSpecificHash();
}
$result = '';
$string = base64_decode($string);
for ($i = 0; $i < strlen($string); $i++) {
$char = substr($string, $i, 1);
$keychar = substr($key, ($i % strlen($key)) - 1, 1);
$char = chr(ord($char) - ord($keychar));
$result .= $char;
}
return $result;
}
/**
* Generate Server Specific hash.
*
* @method generateServerSpecificHash
*
* @return string
*/
public static function generateServerSpecificHash() {
return (isset($_SERVER['SERVER_NAME']) && !empty($_SERVER['SERVER_NAME'])) ? md5($_SERVER['SERVER_NAME']) : md5(pathinfo(__FILE__, PATHINFO_FILENAME));
}
/**
* Check to see if the current page is being served over SSL.
*
* @return bool
*/
public static function isHttps() {
return isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
}
/**
* Determine if current page request type is ajax.
*
* @return bool
*/
public static function isAjax() {
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
return true;
}
return false;
}
/**
* Check if number is odd.
*
* @param int $num integer to check
*
* @return bool
*/
public static function isNumberOdd($num) {
return $num % 2 !== 0;
}
/**
* Check if number is even.
*
* @param int $num integer to check
*
* @return bool
*/
public static function isNumberEven($num) {
return $num % 2 == 0;
}
/**
* Return the current URL.
*
* @return string
*/
public static function getCurrentURL() {
$url = 'http://';
if (self::isHttps()) {
$url = 'https://';
}
if (isset($_SERVER['PHP_AUTH_USER'])) {
$url .= $_SERVER['PHP_AUTH_USER'];
if (isset($_SERVER['PHP_AUTH_PW'])) {
$url .= ':' . $_SERVER['PHP_AUTH_PW'];
}
$url .= '@';
}
if (isset($_SERVER['HTTP_HOST'])) {
$url .= $_SERVER['HTTP_HOST'];
}
if (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] != 80) {
$url .= ':' . $_SERVER['SERVER_PORT'];
}
if (!isset($_SERVER['REQUEST_URI'])) {
$url .= substr($_SERVER['PHP_SELF'], 1);
if (isset($_SERVER['QUERY_STRING'])) {
$url .= '?' . $_SERVER['QUERY_STRING'];
}
return $url;
}
$url .= $_SERVER['REQUEST_URI'];
return $url;
}
/**
* Returns the IP address of the client.
*
* @param bool $headerContainingIPAddress Default false
*
* @return string
*/
public static function getClientIP($headerContainingIPAddress = null) {
if (!empty($headerContainingIPAddress)) {
return isset($_SERVER[$headerContainingIPAddress]) ? trim($_SERVER[$headerContainingIPAddress]) : false;
}
$knowIPkeys = [
'HTTP_CLIENT_IP',
'HTTP_X_FORWARDED_FOR',
'HTTP_X_FORWARDED',
'HTTP_X_CLUSTER_CLIENT_IP',
'HTTP_FORWARDED_FOR',
'HTTP_FORWARDED',
'REMOTE_ADDR'
];
foreach ($knowIPkeys as $key) {
if (array_key_exists($key, $_SERVER) !== true) {
continue;
}
foreach (explode(',', $_SERVER[$key]) as $ip) {
$ip = trim($ip);
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) {
return $ip;
}
}
}
return false;
}
/**
* Detect if user is on mobile device.
*
* @return bool
* @todo Put everything to an array & then implode it?
*/
public static function isMobile() {
if (preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop'
. '|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i'
. '|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)'
. '|vodafone|wap|windows ce|xda|xiino/i', $_SERVER['HTTP_USER_AGENT']) || preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)'
. '|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi'
. '(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co'
. '(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)'
. '|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|'
. 'haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|'
. 'i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|'
. 'kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|'
. 'm1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|'
. 't(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)'
. '\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|'
. 'phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|'
. 'r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|'
. 'mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy'
. '(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)'
. '|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|'
. '70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i', substr($_SERVER['HTTP_USER_AGENT'], 0, 4))) {
return true;
}
return false;
}
/**
* Get user browser.
*
* @return string
*/
public static function getBrowser() {
$u_agent = $_SERVER['HTTP_USER_AGENT'];
$browserName = $ub = $platform = 'Unknown';
if (preg_match('/linux/i', $u_agent)) {
$platform = 'Linux';
} elseif (preg_match('/macintosh|mac os x/i', $u_agent)) {
$platform = 'Mac OS';
} elseif (preg_match('/windows|win32/i', $u_agent)) {
$platform = 'Windows';
}
if (preg_match('/MSIE/i', $u_agent) && !preg_match('/Opera/i', $u_agent)) {
$browserName = 'Internet Explorer';
$ub = 'MSIE';
} elseif (preg_match('/Firefox/i', $u_agent)) {
$browserName = 'Mozilla Firefox';
$ub = 'Firefox';
} elseif (preg_match('/Chrome/i', $u_agent)) {
$browserName = 'Google Chrome';
$ub = 'Chrome';
} elseif (preg_match('/Safari/i', $u_agent)) {
$browserName = 'Apple Safari';
$ub = 'Safari';
} elseif (preg_match('/Opera/i', $u_agent)) {
$browserName = 'Opera';
$ub = 'Opera';
} elseif (preg_match('/Netscape/i', $u_agent)) {
$browserName = 'Netscape';
$ub = 'Netscape';
}
$known = ['Version', $ub, 'other'];
$pattern = '#(?<browser>' . implode('|', $known) . ')[/ ]+(?<version>[0-9.|a-zA-Z.]*)#';
preg_match_all($pattern, $u_agent, $matches);
$i = count($matches['browser']);
$version = $matches['version'][0];
if ($i != 1 && strripos($u_agent, 'Version') >= strripos($u_agent, $ub)) {
$version = $matches['version'][1];
}
if ($version == null || $version == '') {
$version = '?';
}
return implode(', ', [$browserName, 'Version: ' . $version, $platform]);
}
/**
* Get client location.
*
* @return string|false
*/
public static function getClientLocation() {
$result = false;
$ip_data = @json_decode(self::curl('http://www.geoplugin.net/json.gp?ip=' . self::getClientIP()));
if (isset($ip_data) && $ip_data->geoplugin_countryName != null) {
$result = $ip_data->geoplugin_city . ', ' . $ip_data->geoplugin_countryCode;
}
return $result;
}
/**
* Convert number to word representation.
*
* @param int $number number to convert to word
* @return string converted string
* @throws \Exception
*/
public static function numberToWord($number) {
$hyphen = '-';
$conjunction = ' and ';
$separator = ', ';
$negative = 'negative ';
$decimal = ' point ';
$fraction = null;
$dictionary = [
0 => 'zero',
1 => 'one',
2 => 'two',
3 => 'three',
4 => 'four',
5 => 'five',
6 => 'six',
7 => 'seven',
8 => 'eight',
9 => 'nine',
10 => 'ten',
11 => 'eleven',
12 => 'twelve',
13 => 'thirteen',
14 => 'fourteen',
15 => 'fifteen',
16 => 'sixteen',
17 => 'seventeen',
18 => 'eighteen',
19 => 'nineteen',
20 => 'twenty',
30 => 'thirty',
40 => 'fourty',
50 => 'fifty',
60 => 'sixty',
70 => 'seventy',
80 => 'eighty',
90 => 'ninety',
100 => 'hundred',
1000 => 'thousand',
1000000 => 'million',
1000000000 => 'billion',
1000000000000 => 'trillion',
1000000000000000 => 'quadrillion',
1000000000000000000 => 'quintillion'
];
if (!is_numeric($number)) {
throw new \Exception("NaN");
}
if (($number >= 0 && (int) $number < 0) || (int) $number < 0 - PHP_INT_MAX) {
throw new \Exception('numberToWord only accepts numbers between -' . PHP_INT_MAX . ' and ' . PHP_INT_MAX);
}
if ($number < 0) {
return $negative . self::numberToWord(abs($number));
}
if (strpos($number, '.') !== false) {
list($number, $fraction) = explode('.', $number);
}
switch (true) {
case $number < 21:
$string = $dictionary[$number];
break;
case $number < 100:
$tens = ((int) ($number / 10)) * 10;
$units = $number % 10;
$string = $dictionary[$tens];
if ($units) {
$string .= $hyphen . $dictionary[$units];
}
break;
case $number < 1000:
$hundreds = $number / 100;
$remainder = $number % 100;
$string = $dictionary[$hundreds] . ' ' . $dictionary[100];
if ($remainder) {
$string .= $conjunction . self::numberToWord($remainder);
}
break;
default:
$baseUnit = pow(1000, floor(log($number, 1000)));
$numBaseUnits = (int) ($number / $baseUnit);
$remainder = $number % $baseUnit;
$string = self::numberToWord($numBaseUnits) . ' ' . $dictionary[$baseUnit];
if ($remainder) {
$string .= $remainder < 100 ? $conjunction : $separator;
$string .= self::numberToWord($remainder);
}
break;
}
if (null !== $fraction && is_numeric($fraction)) {
$string .= $decimal;
$words = [];
foreach (str_split((string) $fraction) as $number) {
$words[] = $dictionary[$number];
}
$string .= implode(' ', $words);
}
return $string;
}
/**
* Convert seconds to real time.
*
* @param int $seconds time in seconds
* @param bool $returnAsWords return time in words (example one minute and 20 seconds) if value is True or (1 minute and 20 seconds) if value is false, default false
*
* @return string
*/
public static function secondsToText($seconds, $returnAsWords = false) {
$periods = [
'year' => 3.156e+7,
'month' => 2.63e+6,
'week' => 604800,
'day' => 86400,
'hour' => 3600,
'minute' => 60,
'second' => 1
];
$parts = [];
foreach ($periods as $name => $dur) {
$div = floor($seconds / $dur);
if ($div == 0) {
continue;
}
if ($div == 1) {
$parts[] = ($returnAsWords ? self::numberToWord($div) : $div) . ' ' . $name;
} else {
$parts[] = ($returnAsWords ? self::numberToWord($div) : $div) . ' ' . $name . 's';
}
$seconds %= $dur;
}
$last = array_pop($parts);
if (empty($parts)) {
return $last;
}
return implode(', ', $parts) . ' and ' . $last;
}
/**
* Convert minutes to real time.
*
* @param int $minutes time in minutes
* @param bool $returnAsWords return time in words (example one hour and 20 minutes) if value is True or (1 hour and 20 minutes) if value is false, default false
*
* @return string
*/
public static function minutesToText($minutes, $returnAsWords = false) {
return self::secondsToText($minutes * 60, $returnAsWords);
}
/**
* Convert hours to real time.
*
* @param int $hours time in hours
* @param bool $returnAsWords return time in words (example one hour) if value is True or (1 hour) if value is false, default false
*
* @return string
*/
public static function hoursToText($hours, $returnAsWords = false) {
return self::secondsToText($hours * 3600, $returnAsWords);
}
/**
* Truncate String (shorten) with or without ellipsis.
*
* @param string $string String to truncate
* @param int $maxLength Maximum length of string
* @param bool $addEllipsis if True, "..." is added in the end of the string, default true
* @param bool $wordsafe if True, Words will not be cut in the middle
*
* @return string Shortened Text
*/
public static function shortenString($string, $maxLength, $addEllipsis = true, $wordsafe = false) {
$ellipsis = '';
$maxLength = max($maxLength, 0);
if (mb_strlen($string) <= $maxLength) {
return $string;
}
if ($addEllipsis) {
$ellipsis = mb_substr('...', 0, $maxLength);
$maxLength -= mb_strlen($ellipsis);
$maxLength = max($maxLength, 0);
}
$string = mb_substr($string, 0, $maxLength);
if ($wordsafe) {
$string = preg_replace('/\s+?(\S+)?$/', '', mb_substr($string, 0, $maxLength));
}
if ($addEllipsis) {
$string .= $ellipsis;
}
return $string;
}
/**
* Make a Curl call.
*
* @param string $url URL to curl
* @param string $method GET or POST, Default GET
* @param mixed $data Data to post, Default false
* @param mixed $headers Additional headers, example: array ("Accept: application/json")
* @param bool $returnInfo Whether or not to retrieve curl_getinfo()
* @param bool|array $auth Basic authentication params. If array with keys 'username' and 'password' specified, CURLOPT_USERPWD cURL option will be set
*
* @return array|string if $returnInfo is set to True, array is returned with two keys, contents (will contain response) and info (information regarding a specific transfer), otherwise response content is returned
*/
public static function curl($url, $method = 'GET', $data = false, $headers = false, $returnInfo = false, $auth = false) {
$ch = curl_init();
$info = null;
if (strtoupper($method) == 'POST') {
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
if ($data !== false) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}
} else {
if ($data !== false) {
if (is_array($data)) {
$dataTokens = [];
foreach ($data as $key => $value) {
array_push($dataTokens, urlencode($key) . '=' . urlencode($value));
}
$data = implode('&', $dataTokens);
}
curl_setopt($ch, CURLOPT_URL, $url . '?' . $data);
} else {
curl_setopt($ch, CURLOPT_URL, $url);
}
}
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
if ($headers !== false) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
if ($auth !== false && strlen($auth['username']) > 0 && strlen($auth['password']) > 0) {
curl_setopt($ch, CURLOPT_USERPWD, $auth['username'] . ':' . $auth['password']);
}
$contents = curl_exec($ch);
if ($returnInfo) {
$info = curl_getinfo($ch);
}
curl_close($ch);
if ($returnInfo) {
return ['contents' => $contents, 'info' => $info];
}
return $contents;
}
/**
* Get information on a short URL. Find out where it forwards.
*
* @param string $shortURL shortened URL
*
* @return mixed full url or false
*/
public static function expandShortUrl($shortURL) {
if (empty($shortURL)) {
return false;
}
$headers = get_headers($shortURL, 1);
if (isset($headers['Location'])) {
return $headers['Location'];
}
$data = self::curl($shortURL);
preg_match_all('/<[\s]*meta[\s]*http-equiv="?' . '([^>"]*)"?[\s]*' . 'content="?([^>"]*)"?[\s]*[\/]?[\s]*>/si', $data, $match);
if (isset($match) && is_array($match) && count($match) == 3) {
$originals = $match[0];
$names = $match[1];
$values = $match[2];
if ((isset($originals) && isset($names) && isset($values)) && count($originals) == count($names) && count($names) == count($values)) {
$metaTags = [];
for ($i = 0, $limit = count($names); $i < $limit; $i++) {
$metaTags[$names[$i]] = ['html' => htmlentities($originals[$i]), 'value' => $values[$i]];
}
}
}
if (isset($metaTags['refresh']['value']) && !empty($metaTags['refresh']['value'])) {
$returnData = explode('=', $metaTags['refresh']['value']);
if (isset($returnData[1]) && !empty($returnData[1])) {
return $returnData[1];
}
}
return false;
}
/**
* Get Alexa ranking for a domain name.
*
* @param string $domain Domain name to get ranking for
*
* @return mixed false if ranking is found, otherwise integer
*/
public static function getAlexaRank($domain) {
$domain = preg_replace('~^https?://~', '', $domain);
$alexa = 'http://data.alexa.com/data?cli=10&dat=s&url=%s';
$request_url = sprintf($alexa, urlencode($domain));
$xml = simplexml_load_file($request_url);
if (!isset($xml->SD[1])) {
return false;
}
$nodeAttributes = $xml->SD[1]->POPULARITY->attributes();
$text = (int) $nodeAttributes['TEXT'];
return $text;
}
/**
* Shorten URL via tinyurl.com service.
*
* @param string $url URL to shorten
*
* @return mixed shortened url or false
*/
public static function getTinyUrl($url) {
if (strpos($url, 'http') !== 0) {
$url = 'http://' . $url;
}
$gettiny = self::curl('http://tinyurl.com/api-create.php?url=' . $url);
if (isset($gettiny) && !empty($gettiny)) {
return $gettiny;
}
return false;
}
/**
* Get keyword suggestion from Google.
*
* @param string $keyword keyword to get suggestions for
*
* @return mixed array of keywords or false
*/
public static function getKeywordSuggestionsFromGoogle($keyword) {
$data = self::curl('http://suggestqueries.google.com/complete/search?output=firefox&client=firefox&hl=en-US&q=' . urlencode($keyword));
if (($data = json_decode($data, true)) !== null && !empty($data[1])) {
return $data[1];
}
return false;
}
/**
* Search wikipedia.
*
* @param string $keyword Keywords to search in wikipedia
*
* @return mixed Array or false
*/
public static function wikiSearch($keyword) {
$apiurl = 'http://wikipedia.org/w/api.php?action=opensearch&search=' . urlencode($keyword) . '&format=xml&limit=1';
$data = self::curl($apiurl);
$xml = simplexml_load_string($data);
if ((string) $xml->Section->Item->Description) {
$array = [];
$array['title'] = (string) $xml->Section->Item->Text;
$array['description'] = (string) $xml->Section->Item->Description;
$array['url'] = (string) $xml->Section->Item->Url;
if (isset($xml->Section->Item->Image)) {
$img = (string) $xml->Section->Item->Image->attributes()->source;
$array['image'] = str_replace('/50px-', '/200px-', $img);
}
return $array;
}
return false;
}
/**
* Build (HTML) notification message.
*
* @param string $notification Text to display in notification
* @param string $type Notification type, available notifications: success, warning, error and info
* @param array $attributes Optional, additional key/value attributes to include in the DIV tag
*
* @return string containing complete div tag
*/
public static function notification($notification, $type = null, $attributes = []) {
$attr = self::arrayToString($attributes);
if (isset($notification) && !empty($notification)) {
switch (strtolower($type)) {
case 'success':
$css = 'border-color: #bdf2a6;color: #2a760a;background-color: #eefde7;';
break;
case 'warning':
$css = 'border-color: #f2e5a6;color: #76640a;background-color: #fdf9e7;';
break;
case 'error':
$css = 'border-color: #f2a6a6;color: #760a0a;background-color: #fde7e7;';
break;
case 'info':
default:
$css = 'border-color: #a6d9f2;color: #0a5276;background-color: #e7f6fd;';
break;
}
return '<div style="display: block;padding: 0.5em;border: solid 1px;border-radius: 0.125em;margin-bottom: 1em; ' . $css . '" ' . $attr . ' role="alert">' . $notification . '</div>';
}
return false;
}
/**
* Parse text to find URL's for embed enabled services like: youtube.com, blip.tv, vimeo.com, dailymotion.com, flickr.com, smugmug.com, hulu.com, revision3.com, wordpress.tv, funnyordie.com, soundcloud.com, slideshare.net and instagram.com and embed elements automatically.
*
* @param string $string text to parse
* @param string $width max width of embedded element
* @param string $height max height of embedded element
*
* @return string
*/
public static function autoEmbed($string, $width = '560', $height = '315') {
$providers = ['~https?://(?:[0-9A-Z-]+\.)?(?:youtu\.be/|youtube(?:-nocookie)?\.com\S*[^\w\s-])([\w-]{11})(?=[^\w-]|$)[?=&+%\w.-]*~ix' => 'http://www.youtube.com/oembed', '#https?://blip\.tv/(.+)#i' => 'http://blip.tv/oembed/', '~https?://(?:[0-9A-Z-]+\.)?(?:vimeo.com\S*[^\w\s-])([\w-]{1,20})(?=[^\w-]|$)[?=&+%\w.-]*~ix' => 'http://vimeo.com/api/oembed.{format}', '#https?://(www\.)?dailymotion\.com/.*#i' => 'http://www.dailymotion.com/services/oembed', '#https?://(www\.)?flickr\.com/.*#i' => 'http://www.flickr.com/services/oembed/', '#https?://(.+\.)?smugmug\.com/.*#i' => 'http://api.smugmug.com/services/oembed/', '#https?://(www\.)?hulu\.com/watch/.*#i' => 'http://www.hulu.com/api/oembed.{format}', '#https?://revision3\.com/(.+)#i' => 'http://revision3.com/api/oembed/', '#https?://wordpress\.tv/(.+)#i' => 'http://wordpress.tv/oembed/', '#https?://(www\.)?funnyordie\.com/videos/.*#i' => 'http://www.funnyordie.com/oembed', '#https?://(www\.)?soundcloud\.com/.*#i' => 'http://soundcloud.com/oembed', '#https?://(www\.)?slideshare.net/*#' => 'http://www.slideshare.net/api/oembed/2', '#http://instagr(\.am|am\.com)/p/.*#i' => 'http://api.instagram.com/oembed'];
$string = preg_replace_callback('@(^|[^"|^\'])(https?://?([-\w]+\.[-\w\.]+)+\w(:\d+)?(/([-\w/_\.]*(\?\S+)?)?)*)@', function ($matches) use ($providers, $width, $height) {
$url = trim($matches[0]);
$url = explode('#', $url);
$url = reset($url);
$requestURL = false;
foreach ($providers as $pattern => $provider) {
if (preg_match($pattern, $url)) {
if ($provider == 'http://www.youtube.com/oembed') {
$url = str_replace('www.youtu.be/', 'www.youtube.com/watch?v=', $url);
}
$requestURL = str_replace('{format}', 'json', $provider);
break;
}
}
if ($requestURL !== false) {
$params = ['maxwidth' => $width, 'maxheight' => $height, 'format' => 'json'];
$requestURL = $requestURL . '?url=' . $url . '&' . http_build_query($params);
$data = json_decode(self::curl($requestURL), true);
switch ($data['type']) {
case 'photo':
if (empty($data['url']) || empty($data['width']) || empty($data['height']) || !is_string($data['url']) || !is_numeric($data['width']) || !is_numeric($data['height'])) {
return $matches[0];
}
$title = !empty($data['title']) && is_string($data['title']) ? $data['title'] : '';
return '<a href="' . $url . '"><img src="' . htmlspecialchars($data['url'], ENT_QUOTES, 'UTF-8') . '" alt="' . htmlspecialchars($title, ENT_QUOTES, 'UTF-8') . '" width="' . htmlspecialchars($data['width'], ENT_QUOTES, 'UTF-8') . '" height="' . htmlspecialchars($data['height'], ENT_QUOTES, 'UTF-8') . '" /></a>';
case 'video':
case 'rich':
if (!empty($data['html']) && is_string($data['html'])) {
return $data['html'];
}
break;
case 'link':
if (!empty($data['title']) && is_string($data['title'])) {
return self::createLinkTag($url, $data['title']);
}
break;
default:
return $matches[0];
}
}
return $matches[0];
}, $string);
return $string;
}
/**
* Parse text to find all URLs that are not linked and create A tag.
*
* @param string $string Text to parse
* @param array $attributes Optional, additional key/value attributes to include in the A tag
*
* @return string
*/
public static function makeClickableLinks($string, $attributes = []) {
return preg_replace('@(https?://([-\w\.]+[-\w])+(:\d+)?(/([\w/_\.#-]*(\?\S+)?[^\.\s])?)?)@', '<a href="$1" ' . self::arrayToString($attributes) . '>$1</a>', $string);
}
/**
* Dump information about a variable.
*
* @param mixed $variable Variable to debug
*
* @return void
*/
public static function debug($variable) {
ob_start();
var_dump($variable);
$output = ob_get_clean();
$maps = ['string' => "/(string\((?P<length>\d+)\)) (?P<value>\"(?<!\\\).*\")/i", 'array' => "/\[\"(?P<key>.+)\"(?:\:\"(?P<class>[a-z0-9_\\\]+)\")?(?:\:(?P<scope>public|protected|private))?\]=>/Ui", 'countable' => "/(?P<type>array|int|string)\((?P<count>\d+)\)/", 'resource' => "/resource\((?P<count>\d+)\) of type \((?P<class>[a-z0-9_\\\]+)\)/", 'bool' => "/bool\((?P<value>true|false)\)/", 'float' => "/float\((?P<value>[0-9\.]+)\)/", 'object' => "/object\((?P<class>\S+)\)\#(?P<id>\d+) \((?P<count>\d+)\)/i"];
foreach ($maps as $function => $pattern) {
$output = preg_replace_callback($pattern, function ($matches) use ($function) {
switch ($function) {
case 'string':
$matches['value'] = htmlspecialchars($matches['value']);
return '<span style="color: #0000FF;">string</span>(<span style="color: #1287DB;">' . $matches['length'] . ')</span> <span style="color: #6B6E6E;">' . $matches['value'] . '</span>';
case 'array':
$key = '<span style="color: #008000;">"' . $matches['key'] . '"</span>';
$class = '';
$scope = '';
if (isset($matches['class']) && !empty($matches['class'])) {
$class = ':<span style="color: #4D5D94;">"' . $matches['class'] . '"</span>';
}
if (isset($matches['scope']) && !empty($matches['scope'])) {
$scope = ':<span style="color: #666666;">' . $matches['scope'] . '</span>';
}
return '[' . $key . $class . $scope . ']=>';
case 'countable':
$type = '<span style="color: #0000FF;">' . $matches['type'] . '</span>';
$count = '(<span style="color: #1287DB;">' . $matches['count'] . '</span>)';
return $type . $count;
case 'bool':
return '<span style="color: #0000FF;">bool</span>(<span style="color: #0000FF;">' . $matches['value'] . '</span>)';
case 'float':
return '<span style="color: #0000FF;">float</span>(<span style="color: #1287DB;">' . $matches['value'] . '</span>)';
case 'resource':
return '<span style="color: #0000FF;">resource</span>(<span style="color: #1287DB;">' . $matches['count'] . '</span>) of type (<span style="color: #4D5D94;">' . $matches['class'] . '</span>)';
case 'object':
return '<span style="color: #0000FF;">object</span>(<span style="color: #4D5D94;">' . $matches['class'] . '</span>)#' . $matches['id'] . ' (<span style="color: #1287DB;">' . $matches['count'] . '</span>)';
}
}, $output);
}
$header = '';
list($debugfile) = debug_backtrace();
if (!empty($debugfile['file'])) {
$header = '<h4 style="border-bottom:1px solid #bbb;font-weight:bold;margin:0 0 10px 0;padding:3px 0 10px 0">' . $debugfile['file'] . '</h4>';
}
echo '<pre style="background-color: #CDDCF4;border: 1px solid #bbb;border-radius: 4px;-moz-border-radius:4px;-webkit-border-radius\:4px;font-size:12px;line-height:1.4em;margin:30px;padding:7px">' . $header . $output . '</pre>';
}
/**
* Return referer page.
*
* @return string|false
*/
public static function getReferer() {
return isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : false;
}
/**
* Captures output via ob_get_contents(), tries to enable gzip, removes whitespace from captured output and echos back
*
* @return string whitespace stripped output
*/
public static function compressPage() {
register_shutdown_function(function () {
$buffer = preg_replace(['/\>[^\S ]+/s', '/[^\S ]\</s', '/(?![^<]*<\/script>)[\n\r\t]+/', '/ {2,}/', '/>[\n]+/'], ['>', '<', '', ' ', '>'], ob_get_contents());
ob_end_clean();
if (!((ini_get('zlib.output_compression') == 'On' ||
ini_get('zlib.output_compression_level') > 0) ||
ini_get('output_handler') == 'ob_gzhandler') &&
!empty($_SERVER['HTTP_ACCEPT_ENCODING']) &&
extension_loaded('zlib') &&
strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false
) {
ob_start('ob_gzhandler');
}
echo $buffer;
});
}
public static function compressPageMax() {
register_shutdown_function(function () {
$buffer = preg_replace(['/\>[^\S ]+/s', '/[^\S ]+\</s', '/(\s)+/s'], ['>', '<', '\\1'], ob_get_contents());
ob_end_clean();
if (!((ini_get('zlib.output_compression') == 'On' ||
ini_get('zlib.output_compression_level') > 0) ||
ini_get('output_handler') == 'ob_gzhandler') &&
!empty($_SERVER['HTTP_ACCEPT_ENCODING']) &&
extension_loaded('zlib') &&
strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== false
) {
ob_start('ob_gzhandler');
}
echo $buffer;
});
}
/**
* Takes a number and adds “th, st, nd, rd, th” after it
*
* @param int $cardinal Number to add termination
*
* @return string
*/
public static function ordinal($cardinal) {
$test_c = abs($cardinal) % 10;
$ext = ((abs($cardinal) % 100 < 21 && abs($cardinal) % 100 > 4) ? 'th' : (($test_c < 4) ? ($test_c < 3) ? ($test_c < 2) ? ($test_c < 1) ? 'th' : 'st' : 'nd' : 'rd' : 'th'));
return $cardinal . $ext;
}
/**
* Returns the number of days for the given month and year
*
* @param int $month Month to check
* @param int $year Year to check
*
* @return int
*/
public static function numberOfDaysInMonth($month = 0, $year = 0) {
if ($month < 1 or $month > 12) {
return 0;
}
if (!is_numeric($year) or strlen($year) != 4) {
$year = date('Y');
}
if ($month == 2) {
if ($year % 400 == 0 or ($year % 4 == 0 and $year % 100 != 0)) {
return 29;
}
}
$days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
return $days_in_month[$month - 1];
}
/**
* print_r's Variable in <pre> tags.
*
* @param mixed $variable variable to print_r
*
* @return void
*/
public static function pr($variable) {
echo '<pre>';
print_r($variable);
echo '</pre>';
}
public static function sanitizeFileName($filename) {
return str_replace(array(" ", '"', "'", "&", "/", "\\", "?", "#"), '_', $filename);
}
}